1 /*
2 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3 */
4
5 #include "k_api.h"
6 //#include "aos/kernel.h"
7 #include "ch395_spi.h"
8 #include "hal_iomux.h"
9 #include "hal_spi.h"
10 #include "hal_trace.h"
11 #include "hal_gpio.h"
12 #include "hal_iomux_haas1000.h"
13 #include "hal_cache.h"
14 #include "cmsis_os.h"
15 #include "cmsis.h"
16
17 #define SPI_DMA_MAX 4095
18
19 osSemaphoreDef(ch395_spi1_dma_semaphore);
20
21 osMutexDef(ch395_spi1_mutex);
22
23 static void spi1_dma_irq(uint32_t error);
24
25 typedef struct
26 {
27 enum HAL_IOMUX_PIN_T spi_pin_DI0;
28 enum HAL_IOMUX_PIN_T spi_pin_CLK;
29 enum HAL_IOMUX_PIN_T spi_pin_CS0;
30 enum HAL_IOMUX_PIN_T spi_pin_DIO;
31 enum HAL_IOMUX_FUNCTION_T spi_fun_DI0;
32 enum HAL_IOMUX_FUNCTION_T spi_fun_CLK;
33 enum HAL_IOMUX_FUNCTION_T spi_fun_CS0;
34 enum HAL_IOMUX_FUNCTION_T spi_fun_DIO;
35 osSemaphoreId spi_dma_semaphore;
36 osMutexId spi_mutex_id;
37 int (*spi_open)(const struct HAL_SPI_CFG_T *cfg);
38 int (*spi_dma_send)(const void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler);
39 int (*spi_dma_recv)(const void *cmd, void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler);
40 int (*spi_send)(const void *data, uint32_t len);
41 int (*spi_recv)(const void *cmd, void *data, uint32_t len);
42 void (*spi_dma_irq)(uint32_t error);
43 int (*spi_close)(uint32_t cs);
44 } spi_ctx_obj_t;
45
46 static spi_ctx_obj_t spi_ctx[1] =
47 {
48 {
49 .spi_pin_DI0 = HAL_IOMUX_PIN_P3_4,
50 .spi_pin_CLK = HAL_IOMUX_PIN_P3_7,
51 .spi_pin_CS0 = HAL_IOMUX_PIN_P3_6,
52 .spi_pin_DIO = HAL_IOMUX_PIN_P3_5,
53 .spi_fun_DI0 = HAL_IOMUX_FUNC_SPILCD_DI0,
54 .spi_fun_CLK = HAL_IOMUX_FUNC_SPILCD_CLK,
55 .spi_fun_CS0 = HAL_IOMUX_FUNC_AS_GPIO,
56 .spi_fun_DIO = HAL_IOMUX_FUNC_SPILCD_DIO,
57 .spi_dma_semaphore = NULL,
58 .spi_mutex_id = 0,
59 .spi_open = hal_spilcd_open,
60 .spi_dma_send = hal_spilcd_dma_send,
61 .spi_dma_recv = hal_spilcd_dma_recv,
62 .spi_send = hal_spilcd_send,
63 .spi_recv = hal_spilcd_recv,
64 .spi_dma_irq = spi1_dma_irq,
65 .spi_close = hal_spilcd_close
66 }
67 };
68
ch395_device_dereset(void)69 void ch395_device_dereset(void)
70 {
71 /*dereset the ch395 chip*/
72 hal_gpio_pin_set_dir(HAL_IOMUX_PIN_P3_3, HAL_GPIO_DIR_OUT, 0);
73
74 aos_msleep(1000);
75
76 hal_gpio_pin_set_dir(HAL_IOMUX_PIN_P3_3, HAL_GPIO_DIR_OUT, 1);
77
78 aos_msleep(50);
79 }
80
81 /**
82 * Initialises the SPI interface for a given SPI device
83 *
84 * @param[in] spi the spi device
85 *
86 * @return 0 : on success, EIO : if the SPI device could not be initialised
87 */
hal_ch395_spi_init(spi_dev_t * spi)88 int32_t hal_ch395_spi_init(spi_dev_t *spi)
89 {
90 int ret = -1;
91 spi_config_t cfg_spi = spi->config;
92
93 if (spi->port >= (sizeof(spi_ctx) / sizeof(spi_ctx_obj_t))) {
94 return -1;
95 }
96
97 static struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_spi[] = {
98 {0, 0, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL},
99 {0, 0, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL},
100 {0, 0, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL},
101 {0, 0, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL},
102 };
103 pinmux_spi[0].pin = spi_ctx[spi->port].spi_pin_DI0;
104 pinmux_spi[1].pin = spi_ctx[spi->port].spi_pin_CLK;
105 pinmux_spi[2].pin = spi_ctx[spi->port].spi_pin_CS0;
106 pinmux_spi[3].pin = spi_ctx[spi->port].spi_pin_DIO;
107
108 pinmux_spi[0].function = spi_ctx[spi->port].spi_fun_DI0;
109 pinmux_spi[1].function = spi_ctx[spi->port].spi_fun_CLK;
110 pinmux_spi[2].function = spi_ctx[spi->port].spi_fun_CS0;
111 pinmux_spi[3].function = spi_ctx[spi->port].spi_fun_DIO;
112
113 hal_iomux_init(pinmux_spi, ARRAY_SIZE(pinmux_spi));
114 struct HAL_SPI_CFG_T spi_cfg;
115 switch (cfg_spi.mode)
116 {
117 case SPI_WORK_MODE_0:
118 spi_cfg.clk_delay_half = false;
119 spi_cfg.clk_polarity = false;
120 break;
121 case SPI_WORK_MODE_1:
122 spi_cfg.clk_delay_half = true;
123 spi_cfg.clk_polarity = false;
124 break;
125 case SPI_WORK_MODE_2:
126 spi_cfg.clk_delay_half = false;
127 spi_cfg.clk_polarity = true;
128 break;
129 case SPI_WORK_MODE_3:
130 spi_cfg.clk_delay_half = true;
131 spi_cfg.clk_polarity = true;
132 break;
133 default:
134 spi_cfg.clk_delay_half = true;
135 spi_cfg.clk_polarity = true;
136 }
137 spi_cfg.slave = 0;
138 if (cfg_spi.t_mode == SPI_TRANSFER_DMA)
139 {
140 spi_cfg.dma_rx = true;
141 spi_cfg.dma_tx = true;
142 }
143 else
144 {
145 spi_cfg.dma_rx = false;
146 spi_cfg.dma_tx = false;
147 }
148 spi_cfg.rate = cfg_spi.freq;
149 if (spi_cfg.rate > 26000000)
150 spi_cfg.rate = 26000000;
151 spi_cfg.cs = 0;
152 spi_cfg.rx_bits = cfg_spi.data_size;
153 spi_cfg.tx_bits = cfg_spi.data_size;
154 spi_cfg.rx_frame_bits = 0;
155 ret = spi_ctx[spi->port].spi_open(&spi_cfg);
156 if (ret != 0)
157 {
158 TRACE("spi %d open error", spi->port);
159 return ret;
160 }
161
162 TRACE("spi %d open succ", spi->port);
163 /*if cs use as gpio ,pull up at first*/
164 if (spi_ctx[spi->port].spi_fun_CS0 == HAL_IOMUX_FUNC_AS_GPIO) {
165 hal_gpio_pin_set_dir(spi_ctx[spi->port].spi_pin_CS0, HAL_GPIO_DIR_OUT, 1);
166 }
167
168 if (!spi_ctx[spi->port].spi_dma_semaphore)
169 {
170 spi_ctx[spi->port].spi_dma_semaphore = osSemaphoreCreate(osSemaphore(ch395_spi1_dma_semaphore), 0);
171 }
172
173 if (!spi_ctx[spi->port].spi_dma_semaphore)
174 {
175 TRACE("spi%d_dma_semaphore create failed!", spi->port);
176 return -1;
177 }
178
179 if (!spi_ctx[spi->port].spi_mutex_id)
180 {
181 spi_ctx[spi->port].spi_mutex_id = osMutexCreate((osMutex(ch395_spi1_mutex)));
182 }
183
184 if (!spi_ctx[spi->port].spi_mutex_id)
185 {
186 TRACE("spi%d_mutex create failed!", spi->port);
187 return -1;
188 }
189
190 return ret;
191 }
192
spi1_dma_irq(uint32_t error)193 static void spi1_dma_irq(uint32_t error)
194 {
195 if (osOK != osSemaphoreRelease(spi_ctx[0].spi_dma_semaphore))
196 {
197 TRACE("spi0dmairq osSemaphoreRelease failed!");
198 }
199 }
200
201 /**
202 * Spi send
203 *
204 * @param[in] spi the spi device
205 * @param[in] data spi send data
206 * @param[in] size spi send data size
207 * @param[in] timeout timeout in milisecond, set this value to HAL_WAIT_FOREVER
208 * if you want to wait forever
209 *
210 * @return 0 : on success, EIO : if the SPI device could not be initialised
211 */
hal_spi_send_ch395(spi_dev_t * spi,const uint8_t * data,uint16_t size,uint32_t timeout)212 int32_t hal_spi_send_ch395(spi_dev_t *spi, const uint8_t *data, uint16_t size, uint32_t timeout)
213 {
214 int32_t ret = 0;
215 uint32_t len = size;
216 uint32_t i = 0;
217 uint8_t *buf = data;
218 osStatus status = osErrorOS;
219
220 if (NULL == spi || NULL == data || 0 == size)
221 {
222 TRACE("spi input para err");
223 return -3;
224 }
225
226 status = osMutexWait(spi_ctx[spi->port].spi_mutex_id, osWaitForever);
227 if (osOK != status)
228 {
229 TRACE("%s spi_mutex wait error = 0x%X!", __func__, status);
230 return -2;
231 }
232
233 hal_cache_sync(HAL_CACHE_ID_D_CACHE);
234 /*if cs use as gpio, pull down cs at first*/
235 if (spi_ctx[spi->port].spi_fun_CS0 == HAL_IOMUX_FUNC_AS_GPIO)
236 {
237 hal_gpio_pin_set_dir(spi_ctx[spi->port].spi_pin_CS0, HAL_GPIO_DIR_OUT, 0);
238 }
239
240 /* send cmd at first */
241 if (spi->config.t_mode == SPI_TRANSFER_DMA)
242 {
243 ret = spi_ctx[spi->port].spi_dma_send(data, 1, spi_ctx[spi->port].spi_dma_irq);
244 if (osSemaphoreWait(spi_ctx[spi->port].spi_dma_semaphore, timeout) <= 0)
245 {
246 TRACE("spi dma tail send timeout");
247 goto OUT;
248 }
249 }
250 else
251 {
252 ret = spi_ctx[spi->port].spi_send(data, 1);
253 }
254
255 if (ret)
256 {
257 TRACE("spi mode %d send fail %d, size %d", spi->config.t_mode, ret, size);
258 goto OUT;
259 }
260
261 /* send cmd param */
262 if (size > 1)
263 {
264 if (spi->config.t_mode == SPI_TRANSFER_DMA)
265 {
266 ret = spi_ctx[spi->port].spi_dma_send(data + 1, size - 1, spi_ctx[spi->port].spi_dma_irq);
267 if (osSemaphoreWait(spi_ctx[spi->port].spi_dma_semaphore, timeout) <= 0)
268 {
269 TRACE("spi dma tail send timeout");
270 goto OUT;
271 }
272 }
273 else
274 {
275 ret = spi_ctx[spi->port].spi_send(data + 1, size - 1);
276 }
277
278 if (ret)
279 {
280 TRACE("spi mode %d send fail %d, size %d", spi->config.t_mode, ret, size);
281 goto OUT;
282 }
283
284 }
285
286 OUT:
287 /*if cs use as gpio, pull pull up cs at the end*/
288 if (spi_ctx[spi->port].spi_fun_CS0 == HAL_IOMUX_FUNC_AS_GPIO)
289 {
290 hal_gpio_pin_set_dir(spi_ctx[spi->port].spi_pin_CS0, HAL_GPIO_DIR_OUT, 1);
291 }
292 osMutexRelease(spi_ctx[spi->port].spi_mutex_id);
293 return ret;
294 }
295
296 /**
297 * Spi send
298 *
299 * @param[in] spi the spi device
300 * @param[in] data spi send data
301 * @param[in] size spi send data size
302 * @param[in] timeout timeout in milisecond, set this value to HAL_WAIT_FOREVER
303 * if you want to wait forever
304 *
305 * @return 0 : on success, EIO : if the SPI device could not be initialised
306 */
hal_spi_send_ch395_sockdata(spi_dev_t * spi,const uint8_t * data,uint16_t size,uint32_t timeout)307 int32_t hal_spi_send_ch395_sockdata(spi_dev_t *spi, const uint8_t *data, uint16_t size, uint32_t timeout)
308 {
309 int32_t ret = 0;
310 uint32_t len = size;
311 uint32_t i = 0;
312 uint8_t *buf = data;
313 osStatus status = osErrorOS;
314
315 if (NULL == spi || NULL == data || size <=4 )
316 {
317 TRACE("spi input para err");
318 return -3;
319 }
320
321 status = osMutexWait(spi_ctx[spi->port].spi_mutex_id, osWaitForever);
322 if (osOK != status)
323 {
324 TRACE("%s spi_mutex wait error = 0x%X!", __func__, status);
325 return -2;
326 }
327
328 hal_cache_sync(HAL_CACHE_ID_D_CACHE);
329 /*if cs use as gpio, pull down cs at first*/
330 if (spi_ctx[spi->port].spi_fun_CS0 == HAL_IOMUX_FUNC_AS_GPIO)
331 {
332 hal_gpio_pin_set_dir(spi_ctx[spi->port].spi_pin_CS0, HAL_GPIO_DIR_OUT, 0);
333 }
334
335 /* send cmd at first */
336 if (spi->config.t_mode == SPI_TRANSFER_DMA)
337 {
338 ret = spi_ctx[spi->port].spi_dma_send(data, 1, spi_ctx[spi->port].spi_dma_irq);
339 if (osSemaphoreWait(spi_ctx[spi->port].spi_dma_semaphore, timeout) <= 0)
340 {
341 TRACE("spi dma tail send timeout");
342 goto OUT;
343 }
344 }
345 else
346 {
347 ret = spi_ctx[spi->port].spi_send(data, 1);
348 }
349
350 if (ret)
351 {
352 TRACE("spi mode %d send fail %d, size %d", spi->config.t_mode, ret, size);
353 goto OUT;
354 }
355
356 /* send cmd param : sock + datalen */
357 if (spi->config.t_mode == SPI_TRANSFER_DMA)
358 {
359 ret = spi_ctx[spi->port].spi_dma_send(data + 1, 3, spi_ctx[spi->port].spi_dma_irq);
360 if (osSemaphoreWait(spi_ctx[spi->port].spi_dma_semaphore, timeout) <= 0)
361 {
362 TRACE("spi dma tail send timeout");
363 goto OUT;
364 }
365 }
366 else
367 {
368 ret = spi_ctx[spi->port].spi_send(data + 1, 3);
369 }
370
371 if (ret)
372 {
373 TRACE("spi mode %d send fail %d, size %d", spi->config.t_mode, ret, size);
374 goto OUT;
375 }
376
377 /* send sock data */
378 if (spi->config.t_mode == SPI_TRANSFER_DMA)
379 {
380 ret = spi_ctx[spi->port].spi_dma_send(data + 4, size - 4, spi_ctx[spi->port].spi_dma_irq);
381 if (osSemaphoreWait(spi_ctx[spi->port].spi_dma_semaphore, timeout) <= 0)
382 {
383 TRACE("spi dma tail send timeout");
384 goto OUT;
385 }
386 }
387 else
388 {
389 ret = spi_ctx[spi->port].spi_send(data + 4, size - 4);
390 }
391
392 if (ret)
393 {
394 TRACE("spi mode %d send fail %d, size %d", spi->config.t_mode, ret, size);
395 goto OUT;
396 }
397
398 OUT:
399 /*if cs use as gpio, pull pull up cs at the end*/
400 if (spi_ctx[spi->port].spi_fun_CS0 == HAL_IOMUX_FUNC_AS_GPIO)
401 {
402 hal_gpio_pin_set_dir(spi_ctx[spi->port].spi_pin_CS0, HAL_GPIO_DIR_OUT, 1);
403 }
404 osMutexRelease(spi_ctx[spi->port].spi_mutex_id);
405 return ret;
406 }
407
408 //full duplex recev
hal_spi_send_and_recv_ch395_normal(spi_dev_t * spi,uint8_t * tx_data,uint16_t tx_size,uint8_t * rx_data,uint16_t rx_size,uint32_t timeout)409 int32_t hal_spi_send_and_recv_ch395_normal(spi_dev_t *spi, uint8_t *tx_data, uint16_t tx_size, uint8_t *rx_data,
410 uint16_t rx_size, uint32_t timeout)
411 {
412 int32_t ret = 0;
413 uint32_t len = rx_size;
414 uint32_t remainder = 0;
415 osStatus status = 0;
416 uint8_t *cmd;
417
418 if (NULL == spi || NULL == tx_data || 0 == tx_size || NULL == rx_data || 0 == rx_size)
419 {
420 TRACE("spi input para err");
421 return -3;
422 }
423
424 cmd = (uint8_t *)malloc(len);
425 if (cmd == NULL)
426 {
427 TRACE("%s malloc size %d error\r", __FUNCTION__, len);
428 return -1;
429 }
430
431 memset(cmd, 0, len);
432
433 status = osMutexWait(spi_ctx[spi->port].spi_mutex_id, osWaitForever);
434 if (osOK != status)
435 {
436 TRACE("%s spi_mutex wait error = 0x%X!", __func__, status);
437 free(cmd);
438 return -2;
439 }
440
441 /*if cs use as gpio, pull down cs at first*/
442 if (spi_ctx[spi->port].spi_fun_CS0 == HAL_IOMUX_FUNC_AS_GPIO)
443 {
444 hal_gpio_pin_set_dir(spi_ctx[spi->port].spi_pin_CS0, HAL_GPIO_DIR_OUT, 0);
445 }
446
447 hal_cache_sync(HAL_CACHE_ID_D_CACHE);
448 /* send cmd at first */
449 if (spi->config.t_mode == SPI_TRANSFER_DMA)
450 {
451 ret = spi_ctx[spi->port].spi_dma_send(tx_data, 1, spi_ctx[spi->port].spi_dma_irq);
452 if (osSemaphoreWait(spi_ctx[spi->port].spi_dma_semaphore, timeout) <= 0)
453 {
454 TRACE("spi dma tail send timeout");
455 goto OUT;
456 }
457 }
458 else
459 {
460 ret = spi_ctx[spi->port].spi_send(tx_data, 1);
461 }
462
463 if (ret)
464 {
465 TRACE("spi mode %d send fail %d, size %d", spi->config.t_mode, ret, tx_size);
466 goto OUT;
467 }
468 /* send cmd param */
469 if (tx_size > 1)
470 {
471 if (spi->config.t_mode == SPI_TRANSFER_DMA)
472 {
473 ret = spi_ctx[spi->port].spi_dma_send(tx_data + 1, tx_size - 1, spi_ctx[spi->port].spi_dma_irq);
474 if (osSemaphoreWait(spi_ctx[spi->port].spi_dma_semaphore, timeout) <= 0)
475 {
476 TRACE("spi dma tail send timeout");
477 goto OUT;
478 }
479 }
480 else
481 {
482 ret = spi_ctx[spi->port].spi_send(tx_data + 1, tx_size - 1);
483 }
484
485 if (ret)
486 {
487 TRACE("spi mode %d send fail %d, size %d", spi->config.t_mode, ret, tx_size);
488 goto OUT;
489 }
490
491 }
492
493 /*then recv data*/
494 do
495 {
496 remainder = len <= SPI_DMA_MAX ? len : SPI_DMA_MAX;
497 hal_cache_sync(HAL_CACHE_ID_I_CACHE);//PSRAM must sync cache to memory when used dma
498 if (spi->config.t_mode == SPI_TRANSFER_DMA)
499 {
500 ret = spi_ctx[spi->port].spi_dma_recv(cmd, rx_data, remainder, spi_ctx[spi->port].spi_dma_irq);
501 if (osSemaphoreWait(spi_ctx[spi->port].spi_dma_semaphore, timeout) <= 0)
502 {
503 TRACE("SPI Read timeout!");
504 goto OUT;
505 }
506 }
507 else
508 {
509 ret = spi_ctx[spi->port].spi_recv(cmd, rx_data, remainder);
510 }
511 len -= remainder;
512 rx_data += remainder;
513
514 if (ret)
515 {
516 TRACE("spi mode %d recv fail %d, size %d", spi->config.t_mode, ret, rx_size);
517 goto OUT;
518 }
519 } while (len);
520
521 OUT:
522 /*if cs use as gpio, pull pull up cs at the end*/
523 if (spi_ctx[spi->port].spi_fun_CS0 == HAL_IOMUX_FUNC_AS_GPIO)
524 {
525 hal_gpio_pin_set_dir(spi_ctx[spi->port].spi_pin_CS0, HAL_GPIO_DIR_OUT, 1);
526 }
527
528 osMutexRelease(spi_ctx[spi->port].spi_mutex_id);
529 free(cmd);
530 return ret;
531 }
532
hal_spi_send_and_recv_ch395_exist(spi_dev_t * spi,uint8_t * tx_data,uint16_t tx_size,uint8_t * rx_data,uint16_t rx_size,uint32_t timeout)533 int32_t hal_spi_send_and_recv_ch395_exist(spi_dev_t *spi, uint8_t *tx_data, uint16_t tx_size, uint8_t *rx_data,
534 uint16_t rx_size, uint32_t timeout)
535 {
536 int32_t ret = 0;
537 uint32_t len = rx_size;
538 uint32_t remainder = 0;
539 osStatus status = osOK;
540
541 if (NULL == spi || NULL == tx_data || 2 != tx_size || NULL == rx_data || 1 != rx_size)
542 {
543 TRACE("spi input para err");
544 return -3;
545 }
546
547 status = osMutexWait(spi_ctx[spi->port].spi_mutex_id, osWaitForever);
548 if (osOK != status)
549 {
550 TRACE("%s spi_mutex wait error = 0x%X!", __func__, status);
551 return -2;
552 }
553
554 /*if cs use as gpio, pull down cs at first*/
555 if (spi_ctx[spi->port].spi_fun_CS0 == HAL_IOMUX_FUNC_AS_GPIO)
556 {
557 hal_gpio_pin_set_dir(spi_ctx[spi->port].spi_pin_CS0, HAL_GPIO_DIR_OUT, 0);
558 }
559
560 /*send cmd at first*/
561 if (spi->config.t_mode == SPI_TRANSFER_DMA)
562 {
563 ret = spi_ctx[spi->port].spi_dma_send(&tx_data[0], 1, spi_ctx[spi->port].spi_dma_irq);
564 if (osSemaphoreWait(spi_ctx[spi->port].spi_dma_semaphore, timeout) <= 0)
565 {
566 TRACE("spi dma tail send timeout");
567 goto OUT;
568 }
569 }
570 else
571 {
572 ret = spi_ctx[spi->port].spi_send(&tx_data[0], 1);
573 }
574
575 if (ret) {
576 TRACE("spi mode %d send fail %d, size %d",
577 spi->config.t_mode, ret, tx_size);
578 goto OUT;
579 }
580
581 /*send test data at the same time need to recv data*/
582 hal_cache_sync(HAL_CACHE_ID_I_CACHE);//PSRAM must sync cache to memory when used dma
583 if (spi->config.t_mode == SPI_TRANSFER_DMA)
584 {
585 ret = spi_ctx[spi->port].spi_dma_recv(&tx_data[1], rx_data, 1, spi_ctx[spi->port].spi_dma_irq);
586 if (osSemaphoreWait(spi_ctx[spi->port].spi_dma_semaphore, timeout) <= 0)
587 {
588 TRACE("SPI Read timeout!");
589 goto OUT;
590 }
591 }
592 else
593 {
594 ret = spi_ctx[spi->port].spi_recv(&tx_data[1], rx_data, 1);
595 }
596
597 OUT:
598 /*if cs use as gpio, pull pull up cs at the end*/
599 if (spi_ctx[spi->port].spi_fun_CS0 == HAL_IOMUX_FUNC_AS_GPIO)
600 {
601 hal_gpio_pin_set_dir(spi_ctx[spi->port].spi_pin_CS0, HAL_GPIO_DIR_OUT, 1);
602 }
603
604 osMutexRelease(spi_ctx[spi->port].spi_mutex_id);
605 return ret;
606
607 }
608
609