1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2017-11-02 勤为本 first version
9 * 2018-06-09 zhuangwei add spi0 cs0 support,remove msd_init
10 */
11
12 #include <rtthread.h>
13 #include "drivers/dev_spi.h"
14 #include <rthw.h>
15 #include "drv_spi.h"
16 #include "ls1c_public.h"
17 #include "dev_spi_msd.h"
18 #include "dfs_fs.h"
19 #include "../libraries/ls1c_pin.h"
20
21 #ifdef RT_USING_SPI
22 #ifdef DEBUG
23 #define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__)
24 #else
25 #define DEBUG_PRINTF(...)
26 #endif
27
28
29 static rt_err_t configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration);
30 static rt_uint32_t xfer(struct rt_spi_device *device, struct rt_spi_message *message);
31
32
33 static struct rt_spi_ops ls1c_spi_ops =
34 {
35 .configure = configure,
36 .xfer = xfer
37 };
38
39
configure(struct rt_spi_device * device,struct rt_spi_configuration * configuration)40 static rt_err_t configure(struct rt_spi_device *device,
41 struct rt_spi_configuration *configuration)
42 {
43 struct rt_spi_bus *spi_bus = NULL;
44 struct ls1c_spi *ls1c_spi = NULL;
45 unsigned char SPIx = 0;
46 void *spi_base = NULL;
47 unsigned char cpol = 0;
48 unsigned char cpha = 0;
49 unsigned char val = 0;
50
51 RT_ASSERT(NULL != device);
52 RT_ASSERT(NULL != configuration);
53
54 spi_bus = device->bus;
55 ls1c_spi = (struct ls1c_spi *)spi_bus->parent.user_data;
56 SPIx = ls1c_spi->SPIx;
57 spi_base = ls1c_spi_get_base(SPIx);
58
59 {
60 // 使能SPI控制器,master模式,关闭中断
61 reg_write_8(0x53, spi_base + LS1C_SPI_SPCR_OFFSET);
62
63 // 清空状态寄存器
64 reg_write_8(0xc0, spi_base + LS1C_SPI_SPSR_OFFSET);
65
66 // 1字节产生中断,采样(读)与发送(写)时机同时
67 reg_write_8(0x03, spi_base + LS1C_SPI_SPER_OFFSET);
68
69 // 关闭SPI flash
70 val = reg_read_8(spi_base + LS1C_SPI_SFC_PARAM_OFFSET);
71 val &= 0xfe;
72 reg_write_8(val, spi_base + LS1C_SPI_SFC_PARAM_OFFSET);
73
74 // spi flash时序控制寄存器
75 reg_write_8(0x05, spi_base + LS1C_SPI_SFC_TIMING_OFFSET);
76 }
77
78 // baudrate
79 ls1c_spi_set_clock(spi_base, configuration->max_hz);
80
81 // 设置通信模式(时钟极性和相位)
82 if (configuration->mode & RT_SPI_CPOL) // cpol
83 {
84 cpol = SPI_CPOL_1;
85 }
86 else
87 {
88 cpol = SPI_CPOL_0;
89 }
90 if (configuration->mode & RT_SPI_CPHA) // cpha
91 {
92 cpha = SPI_CPHA_1;
93 }
94 else
95 {
96 cpha = SPI_CPHA_0;
97 }
98 ls1c_spi_set_mode(spi_base, cpol, cpha);
99
100 DEBUG_PRINTF("ls1c spi%d configuration\n", SPIx);
101
102 return RT_EOK;
103 }
104
105
xfer(struct rt_spi_device * device,struct rt_spi_message * message)106 static rt_uint32_t xfer(struct rt_spi_device *device,
107 struct rt_spi_message *message)
108 {
109 struct rt_spi_bus *spi_bus = NULL;
110 struct ls1c_spi *ls1c_spi = NULL;
111 void *spi_base = NULL;
112 unsigned char SPIx = 0;
113 struct ls1c_spi_cs *ls1c_spi_cs = NULL;
114 unsigned char cs = 0;
115 rt_uint32_t size = 0;
116 const rt_uint8_t *send_ptr = NULL;
117 rt_uint8_t *recv_ptr = NULL;
118 rt_uint8_t data = 0;
119
120 RT_ASSERT(NULL != device);
121 RT_ASSERT(NULL != message);
122
123 spi_bus = device->bus;
124 ls1c_spi = spi_bus->parent.user_data;
125 SPIx = ls1c_spi->SPIx;
126 spi_base = ls1c_spi_get_base(SPIx);
127 ls1c_spi_cs = device->parent.user_data;
128 cs = ls1c_spi_cs->cs;
129 size = message->length;
130
131 DEBUG_PRINTF("[%s] SPIx=%d, cs=%d\n", __FUNCTION__, SPIx, cs);
132
133 // take cs
134 if (message->cs_take)
135 {
136 ls1c_spi_set_cs(spi_base, cs, 0);
137 }
138
139 // 收发数据
140 send_ptr = message->send_buf;
141 recv_ptr = message->recv_buf;
142 while (size--)
143 {
144 data = 0xFF;
145 if (NULL != send_ptr)
146 {
147 data = *send_ptr++;
148 }
149
150 if (NULL != recv_ptr)
151 {
152 *recv_ptr++ = ls1c_spi_txrx_byte(spi_base, data);
153 }
154 else
155 {
156 ls1c_spi_txrx_byte(spi_base, data);
157 }
158 }
159
160 // release cs
161 if (message->cs_release)
162 {
163 ls1c_spi_set_cs(spi_base, cs, 1);
164 }
165
166 return message->length;
167 }
168
169
170 #ifdef RT_USING_SPI0
171 struct ls1c_spi ls1c_spi0 =
172 {
173 .SPIx = LS1C_SPI_0,
174 };
175
176 static struct rt_spi_bus spi0_bus;
177 #endif
178
179
180 #ifdef RT_USING_SPI1
181 struct ls1c_spi ls1c_spi1 =
182 {
183 .SPIx = LS1C_SPI_1,
184 };
185
186 static struct rt_spi_bus spi1_bus;
187 #endif
188
189
190 /*
191 * 初始化并注册龙芯1c的spi总线
192 * @SPI SPI总线,比如LS1C_SPI_0, LS1C_SPI_1
193 * @spi_bus_name 总线名字
194 * @ret
195 */
ls1c_spi_bus_register(rt_uint8_t SPI,const char * spi_bus_name)196 rt_err_t ls1c_spi_bus_register(rt_uint8_t SPI, const char *spi_bus_name)
197 {
198 struct rt_spi_bus *spi_bus = NULL;
199
200 #ifdef RT_USING_SPI0
201 if (LS1C_SPI_0 == SPI)
202 {
203 spi_bus = &spi0_bus;
204 spi_bus->parent.user_data = &ls1c_spi0;
205 }
206 #endif
207
208 #ifdef RT_USING_SPI1
209 if (LS1C_SPI_1 == SPI)
210 {
211 spi_bus = &spi1_bus;
212 spi_bus->parent.user_data = &ls1c_spi1;
213 }
214 #endif
215
216 return rt_spi_bus_register(spi_bus, spi_bus_name, &ls1c_spi_ops);
217 }
218
ls1c_hw_spi_init(void)219 int ls1c_hw_spi_init(void)
220 {
221 #ifdef RT_USING_SPI0
222 pin_set_purpose(78, PIN_PURPOSE_OTHER);
223 pin_set_purpose(79, PIN_PURPOSE_OTHER);
224 pin_set_purpose(80, PIN_PURPOSE_OTHER);
225 pin_set_purpose(83, PIN_PURPOSE_OTHER);//cs2 - SD card
226 pin_set_purpose(82, PIN_PURPOSE_OTHER);//cs1
227 pin_set_purpose(81, PIN_PURPOSE_OTHER);//cs0
228
229 pin_set_remap(78, PIN_REMAP_DEFAULT);
230 pin_set_remap(79, PIN_REMAP_DEFAULT);
231 pin_set_remap(80, PIN_REMAP_DEFAULT);
232 pin_set_remap(83, PIN_REMAP_DEFAULT);//cs2 - SD card
233 pin_set_remap(82, PIN_REMAP_DEFAULT);//CS1
234 pin_set_remap(81, PIN_REMAP_DEFAULT);//cs0
235 ls1c_spi_bus_register(LS1C_SPI_0, "spi0");
236 #endif
237
238 #ifdef RT_USING_SPI1
239 pin_set_purpose(46, PIN_PURPOSE_OTHER);
240 pin_set_purpose(47, PIN_PURPOSE_OTHER);
241 pin_set_purpose(48, PIN_PURPOSE_OTHER);
242 pin_set_purpose(49, PIN_PURPOSE_OTHER);//CS0 - touch screen
243 pin_set_remap(46, PIN_REMAP_THIRD);
244 pin_set_remap(47, PIN_REMAP_THIRD);
245 pin_set_remap(48, PIN_REMAP_THIRD);
246 pin_set_remap(49, PIN_REMAP_THIRD);//CS0 - touch screen
247 ls1c_spi_bus_register(LS1C_SPI_1, "spi1");
248
249 #endif
250
251
252 #ifdef RT_USING_SPI0
253 /* attach cs */
254 {
255 static struct rt_spi_device spi_device0;
256 static struct rt_spi_device spi_device1;
257 static struct rt_spi_device spi_device2;
258 static struct rt_spi_device spi_device3;
259 static struct ls1c_spi_cs spi_cs0;
260 static struct ls1c_spi_cs spi_cs1;
261 static struct ls1c_spi_cs spi_cs2;
262 static struct ls1c_spi_cs spi_cs3;
263 /* spi02: CS2 SD Card*/
264 spi_cs2.cs = LS1C_SPI_CS_2;
265 rt_spi_bus_attach_device(&spi_device2, "spi02", "spi0", (void *)&spi_cs2);
266 spi_cs1.cs = LS1C_SPI_CS_1;
267 rt_spi_bus_attach_device(&spi_device1, "spi01", "spi0", (void *)&spi_cs1);
268 spi_cs0.cs = LS1C_SPI_CS_0;
269 rt_spi_bus_attach_device(&spi_device0, "spi00", "spi0", (void *)&spi_cs0);
270 spi_cs3.cs = LS1C_SPI_CS_3;
271 rt_spi_bus_attach_device(&spi_device3, "spi03", "spi0", (void*)&spi_cs3);
272 msd_init("sd0", "spi02");
273 }
274 #endif
275 #ifdef RT_USING_SPI1
276 {
277 static struct rt_spi_device spi_device;
278 static struct ls1c_spi_cs spi_cs;
279
280 /* spi10: CS0 Touch*/
281 spi_cs.cs = LS1C_SPI_CS_0;
282 rt_spi_bus_attach_device(&spi_device, "spi10", "spi1", (void *)&spi_cs);
283 }
284 #endif
285 }
286
287
288 INIT_BOARD_EXPORT(ls1c_hw_spi_init);
289
board_sd_init(void)290 static int board_sd_init(void)
291 {
292 #if defined(RT_USING_DFS) && defined(RT_USING_DFS_ELMFAT)
293 /* mount sd card fat partition 1 as root directory */
294 if( dfs_mount("sd0", "/", "elm", 0, 0) == 0)
295 {
296 rt_kprintf("File System initialized!\n");
297 }
298 else
299 {
300 rt_kprintf("File System initialzation failed!\n");
301 }
302 #endif /* RT_USING_DFS && RT_USING_DFS_ELMFAT */
303 }
304 INIT_APP_EXPORT(board_sd_init);
305
306 #endif
307
308