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