1 /*
2 * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Change Logs:
19 * Date Author Notes
20 * 2019-11-01 wangyq update libraries
21 * 2020-01-14 wangyq the first version
22 * 2021-04-20 liuhy the second version
23 */
24
25 #include <rtthread.h>
26 #include <rtdevice.h>
27 #include <string.h>
28 #include <rthw.h>
29 #include "board.h"
30 #include "drv_spi.h"
31
32
33 #ifdef RT_USING_SPI
34
35 #define SPITIMEOUT 0xFFFF
36
spi_configure(struct rt_spi_device * device,struct rt_spi_configuration * cfg)37 rt_err_t spi_configure(struct rt_spi_device *device,
38 struct rt_spi_configuration *cfg)
39 {
40 spi_handle_t *hspi;
41 hspi = (spi_handle_t *)device->bus->parent.user_data;
42
43 hspi->init.ss_en = DISABLE;
44 hspi->init.crc_calc = DISABLE;
45 hspi->init.frame = SPI_FRAME_MOTOROLA;
46
47 /* config spi mode */
48 if (cfg->mode & RT_SPI_SLAVE)
49 {
50 hspi->init.mode = SPI_MODE_SLAVER;
51 }
52 else
53 {
54 hspi->init.mode = SPI_MODE_MASTER;
55 }
56 if (cfg->mode & RT_SPI_3WIRE)
57 {
58 hspi->init.dir = SPI_DIRECTION_1LINE;
59 }
60 else
61 {
62 hspi->init.dir = SPI_DIRECTION_2LINES;
63 }
64 if (cfg->data_width == 8)
65 {
66 hspi->init.data_size = SPI_DATA_SIZE_8;
67 }
68 else if (cfg->data_width == 16)
69 {
70 hspi->init.data_size = SPI_DATA_SIZE_16;
71 }
72
73 if (cfg->mode & RT_SPI_CPHA)
74 {
75 hspi->init.phase = SPI_CPHA_SECOND;
76 }
77 else
78 {
79 hspi->init.phase = SPI_CPHA_FIRST;
80 }
81 if (cfg->mode & RT_SPI_MSB)
82 {
83 hspi->init.first_bit = SPI_FIRSTBIT_MSB;
84 }
85 else
86 {
87 hspi->init.first_bit = SPI_FIRSTBIT_LSB;
88 }
89
90 if (cfg->mode & RT_SPI_CPOL)
91 {
92 hspi->init.polarity = SPI_CPOL_HIGH;
93 }
94 else
95 {
96 hspi->init.polarity = SPI_CPOL_LOW;
97 }
98 if (cfg->mode & RT_SPI_NO_CS)
99 {
100 hspi->init.ss_en = DISABLE;
101 }
102 else
103 {
104 hspi->init.ss_en = ENABLE;
105 }
106
107 /* config spi clock */
108 if (cfg->max_hz >= ald_cmu_get_pclk1_clock() / 2)
109 {
110 /* pclk1 max speed 48MHz, spi master max speed 10MHz */
111 if (ald_cmu_get_pclk1_clock() / 2 <= 10000000)
112 {
113 hspi->init.baud = SPI_BAUD_2;
114 }
115 else if (ald_cmu_get_pclk1_clock() / 4 <= 10000000)
116 {
117 hspi->init.baud = SPI_BAUD_4;
118 }
119 else
120 {
121 hspi->init.baud = SPI_BAUD_8;
122 }
123 }
124 else if (cfg->max_hz >= ald_cmu_get_pclk1_clock() / 4)
125 {
126 /* pclk1 max speed 48MHz, spi master max speed 10MHz */
127 if (ald_cmu_get_pclk1_clock() / 4 <= 10000000)
128 {
129 hspi->init.baud = SPI_BAUD_4;
130 }
131 else
132 {
133 hspi->init.baud = SPI_BAUD_8;
134 }
135 }
136 else if (cfg->max_hz >= ald_cmu_get_pclk1_clock() / 8)
137 {
138 hspi->init.baud = SPI_BAUD_8;
139 }
140 else if (cfg->max_hz >= ald_cmu_get_pclk1_clock() / 16)
141 {
142 hspi->init.baud = SPI_BAUD_16;
143 }
144 else if (cfg->max_hz >= ald_cmu_get_pclk1_clock() / 32)
145 {
146 hspi->init.baud = SPI_BAUD_32;
147 }
148 else if (cfg->max_hz >= ald_cmu_get_pclk1_clock() / 64)
149 {
150 hspi->init.baud = SPI_BAUD_64;
151 }
152 else if (cfg->max_hz >= ald_cmu_get_pclk1_clock() / 128)
153 {
154 hspi->init.baud = SPI_BAUD_128;
155 }
156 else
157 {
158 hspi->init.baud = SPI_BAUD_256;
159 }
160
161 ald_spi_init(hspi);
162 return RT_EOK;
163 }
164
spixfer(struct rt_spi_device * device,struct rt_spi_message * message)165 static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
166 {
167 rt_err_t res;
168 spi_handle_t *hspi;
169 struct es32f3_hw_spi_cs *cs;
170
171 RT_ASSERT(device != RT_NULL);
172 RT_ASSERT(device->bus != RT_NULL);
173 RT_ASSERT(device->bus->parent.user_data != RT_NULL);
174
175 hspi = (spi_handle_t *)device->bus->parent.user_data;
176 cs = device->parent.user_data;
177
178 if (message->cs_take)
179 {
180 rt_pin_write(cs->pin, ES_SPI_CS_LEVEL);
181 }
182
183 if(message->send_buf != RT_NULL || message->recv_buf != RT_NULL)
184 {
185 /* send & receive */
186 if ((message->send_buf != RT_NULL) && (message->recv_buf != RT_NULL))
187 {
188 res = ald_spi_send_recv(hspi, (rt_uint8_t *)message->send_buf, (rt_uint8_t *)message->recv_buf,
189 (rt_int32_t)message->length, SPITIMEOUT);
190 }
191 else
192 {
193 /* only send data */
194 if (message->recv_buf == RT_NULL)
195 {
196 res = ald_spi_send(hspi, (rt_uint8_t *)message->send_buf, (rt_int32_t)message->length, SPITIMEOUT);
197 }
198 /* only receive data */
199 if (message->send_buf == RT_NULL)
200 {
201 res = ald_spi_recv(hspi, (rt_uint8_t *)message->recv_buf, (rt_int32_t)message->length, SPITIMEOUT);
202 }
203 }
204
205 if (message->cs_release)
206 {
207 rt_pin_write(cs->pin, !ES_SPI_CS_LEVEL);
208 }
209
210 if (res != RT_EOK)
211 return -RT_ERROR;
212 else
213 return message->length;
214
215 }
216 else
217 {
218
219 if (message->cs_release)
220 {
221 rt_pin_write(cs->pin, !ES_SPI_CS_LEVEL);
222 }
223 return RT_EOK;
224 }
225
226 }
227
228 const struct rt_spi_ops es32f3_spi_ops =
229 {
230 spi_configure,
231 spixfer,
232 };
233
es32f3_spi_device_attach(rt_uint32_t pin,const char * bus_name,const char * device_name)234 rt_err_t es32f3_spi_device_attach(rt_uint32_t pin, const char *bus_name, const char *device_name)
235 {
236 int result;
237 /* define spi Instance */
238 struct rt_spi_device *spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
239 RT_ASSERT(spi_device != RT_NULL);
240 struct es32f3_hw_spi_cs *cs_pin = (struct es32f3_hw_spi_cs *)rt_malloc(sizeof(struct es32f3_hw_spi_cs));
241 RT_ASSERT(cs_pin != RT_NULL);
242 cs_pin->pin = pin;
243 rt_pin_mode(pin, PIN_MODE_OUTPUT);
244 rt_pin_write(pin, 1);
245
246 result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
247
248 #ifdef BSP_USING_SPI0
249 if(!(strcmp(bus_name,ES_DEVICE_NAME_SPI0_BUS)))SPI_BUS_CONFIG(spi_device->config,0);
250 #endif
251 #ifdef BSP_USING_SPI1
252 if(!(strcmp(bus_name,ES_DEVICE_NAME_SPI1_BUS)))SPI_BUS_CONFIG(spi_device->config,1);
253 #endif
254 #ifdef BSP_USING_SPI2
255 if(!(strcmp(bus_name,ES_DEVICE_NAME_SPI2_BUS)))SPI_BUS_CONFIG(spi_device->config,2);
256 #endif
257
258 return result;
259 }
260
261 #ifdef BSP_USING_SPI0
262 static struct rt_spi_bus _spi_bus0;
263 static spi_handle_t _spi0;
264 #endif
265
266 #ifdef BSP_USING_SPI1
267 static struct rt_spi_bus _spi_bus1;
268 static spi_handle_t _spi1;
269 #endif
270
271 #ifdef BSP_USING_SPI2
272 static struct rt_spi_bus _spi_bus2;
273 static spi_handle_t _spi2;
274 #endif
275
rt_hw_spi_init(void)276 int rt_hw_spi_init(void)
277 {
278 int result = RT_EOK;
279
280 struct rt_spi_bus *spi_bus;
281 spi_handle_t *spi;
282 gpio_init_t gpio_instruct;
283
284 gpio_instruct.pupd = GPIO_PUSH_UP_DOWN;
285 gpio_instruct.odos = GPIO_PUSH_PULL;
286 gpio_instruct.podrv = GPIO_OUT_DRIVE_6;
287 gpio_instruct.nodrv = GPIO_OUT_DRIVE_6;
288 gpio_instruct.type = GPIO_TYPE_TTL;
289 gpio_instruct.flt = GPIO_FILTER_DISABLE;
290
291 #ifdef BSP_USING_SPI0
292 _spi0.perh = SPI0;
293 spi_bus = &_spi_bus0;
294 spi = &_spi0;
295
296 /* SPI0 gpio init */
297 gpio_instruct.mode = GPIO_MODE_OUTPUT;
298
299 #if defined(ES_SPI0_SCK_GPIO_FUNC)&&defined(ES_SPI0_SCK_GPIO_PORT)&&defined(ES_SPI0_SCK_GPIO_PIN)
300 gpio_instruct.func = ES_SPI0_SCK_GPIO_FUNC;
301 ald_gpio_init(ES_SPI0_SCK_GPIO_PORT, ES_SPI0_SCK_GPIO_PIN, &gpio_instruct);
302 #endif
303
304 #if defined(ES_SPI0_MOSI_GPIO_FUNC)&&defined(ES_SPI0_MOSI_GPIO_PORT)&&defined(ES_SPI0_MOSI_GPIO_PIN)
305 gpio_instruct.func = ES_SPI0_MOSI_GPIO_FUNC;
306 ald_gpio_init(ES_SPI0_MOSI_GPIO_PORT, ES_SPI0_MOSI_GPIO_PIN, &gpio_instruct);
307 #endif
308
309 gpio_instruct.mode = GPIO_MODE_INPUT;
310
311 #if defined(ES_SPI0_MISO_GPIO_FUNC)&&defined(ES_SPI0_MISO_GPIO_PORT)&&defined(ES_SPI0_MISO_GPIO_PIN)
312 gpio_instruct.func = ES_SPI0_MISO_GPIO_FUNC;
313 ald_gpio_init(ES_SPI0_MISO_GPIO_PORT, ES_SPI0_MISO_GPIO_PIN, &gpio_instruct);
314 #endif
315
316 spi_bus->parent.user_data = spi;
317 result = rt_spi_bus_register(spi_bus, ES_DEVICE_NAME_SPI0_BUS, &es32f3_spi_ops);
318 if (result != RT_EOK)
319 {
320 return result;
321 }
322
323 result = es32f3_spi_device_attach(ES_SPI0_NSS_PIN, ES_DEVICE_NAME_SPI0_BUS, ES_DEVICE_NAME_SPI0_DEV0);
324
325 if (result != RT_EOK)
326 {
327 return result;
328 }
329
330 #endif
331
332 #ifdef BSP_USING_SPI1
333 _spi1.perh = SPI1;
334 spi_bus = &_spi_bus1;
335 spi = &_spi1;
336
337 /* SPI1 gpio init */
338 gpio_instruct.mode = GPIO_MODE_OUTPUT;
339
340 #if defined(ES_SPI1_SCK_GPIO_FUNC)&&defined(ES_SPI1_SCK_GPIO_PORT)&&defined(ES_SPI1_SCK_GPIO_PIN)
341 gpio_instruct.func = ES_SPI1_SCK_GPIO_FUNC;
342 ald_gpio_init(ES_SPI1_SCK_GPIO_PORT, ES_SPI1_SCK_GPIO_PIN, &gpio_instruct);
343 #endif
344
345 #if defined(ES_SPI1_MOSI_GPIO_FUNC)&&defined(ES_SPI1_MOSI_GPIO_PORT)&&defined(ES_SPI1_MOSI_GPIO_PIN)
346 gpio_instruct.func = ES_SPI1_MOSI_GPIO_FUNC;
347 ald_gpio_init(ES_SPI1_MOSI_GPIO_PORT, ES_SPI1_MOSI_GPIO_PIN, &gpio_instruct);
348 #endif
349
350 gpio_instruct.mode = GPIO_MODE_INPUT;
351
352 #if defined(ES_SPI1_MISO_GPIO_FUNC)&&defined(ES_SPI1_MISO_GPIO_PORT)&&defined(ES_SPI1_MISO_GPIO_PIN)
353 gpio_instruct.func = ES_SPI1_MISO_GPIO_FUNC;
354 ald_gpio_init(ES_SPI1_MISO_GPIO_PORT, ES_SPI1_MISO_GPIO_PIN, &gpio_instruct);
355 #endif
356
357 spi_bus->parent.user_data = spi;
358 result = rt_spi_bus_register(spi_bus, ES_DEVICE_NAME_SPI1_BUS, &es32f3_spi_ops);
359 if (result != RT_EOK)
360 {
361 return result;
362 }
363
364 result = es32f3_spi_device_attach(ES_SPI1_NSS_PIN, ES_DEVICE_NAME_SPI1_BUS, ES_DEVICE_NAME_SPI1_DEV0);
365
366 if (result != RT_EOK)
367 {
368 return result;
369 }
370
371 #endif
372
373 #ifdef BSP_USING_SPI2
374 _spi2.perh = SPI2;
375 spi_bus = &_spi_bus2;
376 spi = &_spi2;
377
378 /* SPI2 gpio init */
379 gpio_instruct.mode = GPIO_MODE_OUTPUT;
380
381 #if defined(ES_SPI2_SCK_GPIO_FUNC)&&defined(ES_SPI2_SCK_GPIO_PORT)&&defined(ES_SPI2_SCK_GPIO_PIN)
382 gpio_instruct.func = ES_SPI2_SCK_GPIO_FUNC;
383 ald_gpio_init(ES_SPI2_SCK_GPIO_PORT, ES_SPI2_SCK_GPIO_PIN, &gpio_instruct);
384 #endif
385
386 #if defined(ES_SPI2_MOSI_GPIO_FUNC)&&defined(ES_SPI2_MOSI_GPIO_PORT)&&defined(ES_SPI2_MOSI_GPIO_PIN)
387 gpio_instruct.func = ES_SPI2_MOSI_GPIO_FUNC;
388 ald_gpio_init(ES_SPI2_MOSI_GPIO_PORT, ES_SPI2_MOSI_GPIO_PIN, &gpio_instruct);
389 #endif
390
391 gpio_instruct.mode = GPIO_MODE_INPUT;
392
393 #if defined(ES_SPI2_MISO_GPIO_FUNC)&&defined(ES_SPI2_MISO_GPIO_PORT)&&defined(ES_SPI2_MISO_GPIO_PIN)
394 gpio_instruct.func = ES_SPI2_MISO_GPIO_FUNC;
395 ald_gpio_init(ES_SPI2_MISO_GPIO_PORT, ES_SPI2_MISO_GPIO_PIN, &gpio_instruct);
396 #endif
397
398 spi_bus->parent.user_data = spi;
399 result = rt_spi_bus_register(spi_bus, ES_DEVICE_NAME_SPI2_BUS, &es32f3_spi_ops);
400 if (result != RT_EOK)
401 {
402 return result;
403 }
404
405 result = es32f3_spi_device_attach(ES_SPI2_NSS_PIN, ES_DEVICE_NAME_SPI2_BUS, ES_DEVICE_NAME_SPI1_DEV0);
406
407 if (result != RT_EOK)
408 {
409 return result;
410 }
411
412 #endif
413 return result;
414 }
415 INIT_BOARD_EXPORT(rt_hw_spi_init);
416
417 #endif
418