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