1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-03-28 qiujingbao first version
*/
#ifndef __DRV_SPI_H__
#define __DRV_SPI_H__
#include "rtdevice.h"
#include <rthw.h>
#include <rtthread.h>
#include "mmio.h"
#include "pinctrl.h"
#define SPI0 0x0
#define SPI1 0x1
#define SPI2 0x2
#define SPI3 0x3
#define SPI0_BASE 0x04180000
#define SPI1_BASE 0x04190000
#define SPI2_BASE 0x041A0000
#define SPI3_BASE 0x041B0000
#define SPI_IRQ_MSAK 0x3e
#define SPI_FREQUENCY 187500000
/* Transmit FiFO Threshold Level */
#define SPI_TXFTLR 0xf
#define SPI_CTRL0_DATA_FREAM_SHIFT 0
#define SPI_CTRL0_FREAM_FORMAT_SHIFT 4
#define SPI_CTRL0_CPHA_SHIFT 6
#define SPI_CTRL0_CPOL_SHIFT 7
#define SPI_CTRL0_TRANS_MODE 8
#define SPI_CTRL0_LOOP_SHIFT 11
#define SPI_CTRL0_CTRL_FREAM_SHIFT 12
struct cv1800_spi {
uint8_t spi_id;
char *device_name;
uint8_t fifo_len;
uint8_t data_width;
const void *send_buf;
void *recv_buf;
const void *send_end;
void *recv_end;
struct rt_spi_bus spi_bus;
struct spi_regs *reg;
};
struct spi_regs {
uint32_t spi_ctrl0; // 0x00
uint32_t spi_ctrl1; // 0x04
uint32_t spi_ssienr; // 0x08
uint32_t spi_mwcr; // 0x0c
uint32_t spi_ser; // 0x10
uint32_t spi_baudr; // 0x14
uint32_t spi_txftlr; // 0x18
uint32_t spi_rxftlr; // 0x1c
uint32_t spi_txflr; // 0x20
uint32_t spi_rxflr; // 0x24
uint32_t spi_sr; // 0x28
uint32_t spi_imr; // 0x2c
uint32_t spi_isr; // 0x30
uint32_t spi_risr; // 0x34
uint32_t spi_txoicr; // 0x38
uint32_t spi_rxoicr; // 0x3c
uint32_t spi_rxuicr; // 0x40
uint32_t spi_msticr; // 0x44
uint32_t spi_icr; // 0x48
uint32_t spi_dmacr; // 0x4c
uint32_t spi_dmatdlr; // 0x50
uint32_t spi_dmardlr; // 0x54
uint32_t spi_idr; // 0x58
uint32_t spi_version; // 0x5c
uint32_t spi_dr; // 0x60
uint32_t spi_rx_sample_dly; // 0xf0
uint32_t spi_cs_override; // 0xf4
};
uint32_t gen_spi_mode(struct rt_spi_configuration *cfg, uint32_t *mode)
{
uint32_t value = 0;
if (cfg->data_width != 8 && cfg->data_width != 16)
return -1;
value |= (cfg->data_width - 1) >> SPI_CTRL0_DATA_FREAM_SHIFT;
value |= cfg->mode >> SPI_CTRL0_CPHA_SHIFT;
*mode = value;
return 0;
}
/* set spi mode */
static inline void spi_set_mode(struct spi_regs *reg, uint32_t mode)
{
mmio_write_32((uintptr_t)®->spi_ctrl0, mode);
}
/* clear irq */
static inline void spi_clear_irq(struct spi_regs *reg, uint32_t mode)
{
mmio_write_32((uintptr_t)®->spi_imr, mode);
}
static inline void spi_enable_cs(struct spi_regs *reg, uint32_t enable)
{
if (enable)
enable = 0x1;
else
enable = 0x0;
mmio_write_32((uintptr_t)®->spi_ser, enable);
}
/* set spi frequency*/
static inline rt_err_t spi_set_frequency(struct spi_regs *reg, uint32_t speed)
{
uint16_t value;
/* The value of the BAUDR register must be an even number between 2-65534 */
value = SPI_FREQUENCY / speed;
if (value % 2 != 0)
value++;
if (value < 4 || value > 65534)
value = 4;
mmio_write_32((uintptr_t)®->spi_baudr, value);
return RT_EOK;
}
static inline void spi_enable(struct spi_regs *reg, uint32_t enable)
{
if (enable)
enable = 0x1;
else
enable = 0x0;
mmio_write_32((uintptr_t)®->spi_ssienr, enable);
}
#endif /* __DRV_SPI_H__ */
|