1 /**
2 ****************************************************************************************
3 * @file app_spi.c
4 * @author BLE Driver Team
5 * @brief HAL APP module driver.
6 ****************************************************************************************
7 * @attention
8 #####Copyright (c) 2019 GOODIX
9 All rights reserved.
10
11 Redistribution and use in source and binary forms, with or without
12 modification, are permitted provided that the following conditions are met:
13 * Redistributions of source code must retain the above copyright
14 notice, this list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright
16 notice, this list of conditions and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18 * Neither the name of GOODIX nor the names of its contributors may be used
19 to endorse or promote products derived from this software without
20 specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
26 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 POSSIBILITY OF SUCH DAMAGE.
33 ****************************************************************************************
34 */
35
36 /*
37 * INCLUDE FILES
38 *****************************************************************************************
39 */
40 #include <string.h>
41 #include "app_dma.h"
42 #include "app_pwr_mgmt.h"
43 #include "app_systick.h"
44 #include "platform_sdk.h"
45 #include "app_spi.h"
46
47 #if defined(HAL_SPI_V2_MODULE_ENABLED)
48 #error "Please undef HAL_SPI_V2_MODULE_ENABLED in gr55xx_hal_conf.h"
49 #endif
50
51 #ifdef HAL_SPI_MODULE_ENABLED
52
53 /*
54 * DEFINES
55 *****************************************************************************************
56 */
57 #define MS_1000 1000
58
59 /*
60 * STRUCT DEFINE
61 *****************************************************************************************
62 */
63
64 /**@brief App spi state types. */
65 typedef enum {
66 APP_SPI_INVALID = 0,
67 APP_SPI_ENABLE,
68 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
69 APP_SPI_SLEEP,
70 #endif
71 } app_spi_state_t;
72
73 struct spi_env_t {
74 app_spi_evt_handler_t evt_handler;
75 spi_handle_t handle;
76 app_spi_mode_t use_mode;
77 app_spi_pin_cfg_t pin_cfg;
78 int16_t dma_id[2];
79 app_spi_state_t spi_state;
80 bool start_flag;
81 volatile uint8_t rx_done;
82 volatile uint8_t tx_done;
83 volatile uint8_t user_mode;
84 #ifdef ENV_RTOS_USE_SEMP
85 APP_DRV_SEM_DECL(sem_tx);
86 APP_DRV_SEM_DECL(sem_rx);
87 APP_DRV_SEM_DECL(sem_tx_rx);
88 #endif
89
90 #ifdef ENV_RTOS_USE_MUTEX
91 APP_DRV_MUTEX_DECL(mutex_sync);
92 APP_DRV_MUTEX_DECL(mutex_async);
93 #endif
94 };
95
96 /*
97 * LOCAL FUNCTION DECLARATION
98 *****************************************************************************************
99 */
100 static bool spi_prepare_for_sleep(void);
101 static void spi_sleep_canceled(void);
102 static void spi_wake_up_ind(void);
103 static uint16_t spi_gpio_config(app_spi_id_t id, app_spi_pin_cfg_t pin_cfg);
104
105 /*
106 * LOCAL VARIABLE DEFINITIONS
107 *****************************************************************************************
108 */
109 static const IRQn_Type s_spi_irq[APP_SPI_ID_MAX] = {SPI_S_IRQn, SPI_M_IRQn};
110 static const uint32_t s_spi_instance[APP_SPI_ID_MAX] = {SPIS_BASE, SPIM_BASE};
111
112 struct spi_env_t s_spi_env[APP_SPI_ID_MAX] = {
113 {
114 .evt_handler = NULL,
115 #ifdef ENV_RTOS_USE_SEMP
116 .sem_tx = NULL,
117 .sem_rx = NULL,
118 .sem_tx_rx = NULL,
119 #endif
120 #ifdef ENV_RTOS_USE_MUTEX
121 .mutex_sync = NULL,
122 .mutex_async = NULL,
123 #endif
124 },
125 {
126 .evt_handler = NULL,
127 #ifdef ENV_RTOS_USE_SEMP
128 .sem_tx = NULL,
129 .sem_rx = NULL,
130 .sem_tx_rx = NULL,
131 #endif
132 #ifdef ENV_RTOS_USE_MUTEX
133 .mutex_sync = NULL,
134 .mutex_async = NULL,
135 #endif
136 }
137 };
138 static bool s_sleep_cb_registered_flag = false;
139 static int16_t s_spi_pwr_id;
140
141 static const app_sleep_callbacks_t spi_sleep_cb = {
142 .app_prepare_for_sleep = spi_prepare_for_sleep,
143 .app_sleep_canceled = spi_sleep_canceled,
144 .app_wake_up_ind = spi_wake_up_ind
145 };
146
147 static inline void SPI_SMART_CS_LOW(uint8_t id);
148 static inline void SPI_SMART_CS_HIGH(uint8_t id);
149
SPI_SMART_CS_LOW(uint8_t id)150 static inline void SPI_SMART_CS_LOW(uint8_t id)
151 {
152 if ((APP_SPI_ID_SLAVE != id) &&
153 (s_spi_env[id].pin_cfg.cs.enable == APP_SPI_PIN_ENABLE)) {
154 app_io_write_pin(s_spi_env[id].pin_cfg.cs.type,
155 s_spi_env[id].pin_cfg.cs.pin,
156 APP_IO_PIN_RESET);
157 }
158 }
159
SPI_SMART_CS_HIGH(uint8_t id)160 static inline void SPI_SMART_CS_HIGH(uint8_t id)
161 {
162 if ((APP_SPI_ID_SLAVE != id) &&
163 (s_spi_env[id].pin_cfg.cs.enable == APP_SPI_PIN_ENABLE)) {
164 app_io_write_pin(s_spi_env[id].pin_cfg.cs.type,
165 s_spi_env[id].pin_cfg.cs.pin,
166 APP_IO_PIN_SET);
167 }
168 }
169
170 #ifdef ENV_RTOS_USE_MUTEX
171 static inline void APP_SPI_DRV_SYNC_MUTEX_LOCK(uint8_t id);
172 static inline void APP_SPI_DRV_SYNC_MUTEX_UNLOCK(uint8_t id);
173 static inline void APP_SPI_DRV_ASYNC_MUTEX_LOCK(uint8_t id);
174 static inline void APP_SPI_DRV_ASYNC_MUTEX_UNLOCK(uint8_t id);
175
APP_SPI_DRV_SYNC_MUTEX_LOCK(uint8_t id)176 static inline void APP_SPI_DRV_SYNC_MUTEX_LOCK(uint8_t id)
177 {
178 app_driver_mutex_pend(s_spi_env[id].mutex_sync, MUTEX_WAIT_FOREVER);
179 }
180
APP_SPI_DRV_SYNC_MUTEX_UNLOCK(uint8_t id)181 static inline void APP_SPI_DRV_SYNC_MUTEX_UNLOCK(uint8_t id)
182 {
183 app_driver_mutex_post(s_spi_env[id].mutex_sync);
184 }
185
APP_SPI_DRV_ASYNC_MUTEX_LOCK(uint8_t id)186 static inline void APP_SPI_DRV_ASYNC_MUTEX_LOCK(uint8_t id)
187 {
188 app_driver_mutex_pend(s_spi_env[id].mutex_async, MUTEX_WAIT_FOREVER);
189 }
190
APP_SPI_DRV_ASYNC_MUTEX_UNLOCK(uint8_t id)191 static inline void APP_SPI_DRV_ASYNC_MUTEX_UNLOCK(uint8_t id)
192 {
193 app_driver_mutex_post(s_spi_env[id].mutex_async);
194 }
195 #endif
196
197 /*
198 * LOCAL FUNCTION DEFINITIONS
199 *****************************************************************************************
200 */
spi_prepare_for_sleep(void)201 static bool spi_prepare_for_sleep(void)
202 {
203 hal_spi_state_t state;
204 uint8_t i;
205
206 for (i = 0; i < APP_SPI_ID_MAX; i++) {
207 if (s_spi_env[i].spi_state == APP_SPI_ENABLE) {
208 state = hal_spi_get_state(&s_spi_env[i].handle);
209 if ((state != HAL_SPI_STATE_READY) && (state != HAL_SPI_STATE_RESET)) {
210 return false;
211 }
212
213 GLOBAL_EXCEPTION_DISABLE();
214 hal_spi_suspend_reg(&s_spi_env[i].handle);
215 GLOBAL_EXCEPTION_ENABLE();
216 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
217 s_spi_env[i].spi_state = APP_SPI_SLEEP;
218 #endif
219 }
220 }
221
222 return true;
223 }
224
spi_sleep_canceled(void)225 static void spi_sleep_canceled(void)
226 {
227 }
228
spi_wake_up_ind(void)229 SECTION_RAM_CODE static void spi_wake_up_ind(void)
230 {
231 #ifndef APP_DRIVER_WAKEUP_CALL_FUN
232 uint8_t i;
233
234 for (i = 0; i < APP_SPI_ID_MAX; i++) {
235 if (s_spi_env[i].spi_state == APP_SPI_ENABLE) {
236 GLOBAL_EXCEPTION_DISABLE();
237 hal_spi_resume_reg(&s_spi_env[i].handle);
238 GLOBAL_EXCEPTION_ENABLE();
239 if (s_spi_env[i].use_mode.type == APP_SPI_TYPE_INTERRUPT ||
240 s_spi_env[i].use_mode.type == APP_SPI_TYPE_DMA) {
241 hal_nvic_clear_pending_irq(s_spi_irq[i]);
242 hal_nvic_enable_irq(s_spi_irq[i]);
243 }
244 }
245 }
246 #endif
247 }
248
249 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
spi_wake_up(app_spi_id_t id)250 static void spi_wake_up(app_spi_id_t id)
251 {
252 if (s_spi_env[id].spi_state == APP_SPI_SLEEP) {
253 GLOBAL_EXCEPTION_DISABLE();
254 hal_spi_resume_reg(&s_spi_env[id].handle);
255 GLOBAL_EXCEPTION_ENABLE();
256
257 if (s_spi_env[id].use_mode.type == APP_SPI_TYPE_INTERRUPT ||
258 s_spi_env[id].use_mode.type == APP_SPI_TYPE_DMA) {
259 hal_nvic_clear_pending_irq(s_spi_irq[id]);
260 hal_nvic_enable_irq(s_spi_irq[id]);
261 }
262 s_spi_env[id].spi_state = APP_SPI_ENABLE;
263 }
264
265 if (s_spi_env[id].use_mode.type == APP_SPI_TYPE_DMA) {
266 dma_wake_up(s_spi_env[id].dma_id[0]);
267 dma_wake_up(s_spi_env[id].dma_id[1]);
268 }
269 }
270 #endif
271
spi_gpio_config(app_spi_id_t id,app_spi_pin_cfg_t pin_cfg)272 static uint16_t spi_gpio_config(app_spi_id_t id, app_spi_pin_cfg_t pin_cfg)
273 {
274 app_io_init_t io_init = APP_IO_DEFAULT_CONFIG;
275 uint16_t err_code = APP_DRV_SUCCESS;
276
277 if (pin_cfg.cs.enable == APP_SPI_PIN_ENABLE) {
278 if (id == APP_SPI_ID_SLAVE) {
279 io_init.pull = pin_cfg.cs.pull;
280 io_init.mode = APP_IO_MODE_MUX;
281 io_init.pin = pin_cfg.cs.pin;
282 io_init.mux = pin_cfg.cs.mux;
283 err_code = app_io_init(pin_cfg.cs.type, &io_init);
284 APP_DRV_ERR_CODE_CHECK(err_code);
285 } else {
286 io_init.pull = pin_cfg.cs.pull;
287 io_init.mode = APP_IO_MODE_OUT_PUT;
288 io_init.pin = pin_cfg.cs.pin;
289 io_init.mux = APP_IO_MUX_7;
290 err_code = app_io_init(pin_cfg.cs.type, &io_init);
291 app_io_write_pin(pin_cfg.cs.type, pin_cfg.cs.pin, APP_IO_PIN_SET);
292 APP_DRV_ERR_CODE_CHECK(err_code);
293 }
294 }
295 if (pin_cfg.clk.enable == APP_SPI_PIN_ENABLE) {
296 io_init.pull = pin_cfg.clk.pull;
297 io_init.mode = APP_IO_MODE_MUX;
298 io_init.pin = pin_cfg.clk.pin;
299 io_init.mux = pin_cfg.clk.mux;
300 err_code = app_io_init(pin_cfg.clk.type, &io_init);
301 APP_DRV_ERR_CODE_CHECK(err_code);
302 }
303 if (pin_cfg.mosi.enable == APP_SPI_PIN_ENABLE) {
304 io_init.pull = pin_cfg.mosi.pull;
305 io_init.pin = pin_cfg.mosi.pin;
306 io_init.mux = pin_cfg.mosi.mux;
307 err_code = app_io_init(pin_cfg.mosi.type, &io_init);
308 APP_DRV_ERR_CODE_CHECK(err_code);
309 }
310 if (pin_cfg.miso.enable == APP_SPI_PIN_ENABLE) {
311 io_init.pull = pin_cfg.miso.pull;
312 io_init.pin = pin_cfg.miso.pin;
313 io_init.mux = pin_cfg.miso.mux;
314 err_code = app_io_init(pin_cfg.miso.type, &io_init);
315 APP_DRV_ERR_CODE_CHECK(err_code);
316 }
317
318 return err_code;
319 }
320
spi_tx_dma_config(app_spi_params_t * p_params)321 static uint16_t spi_tx_dma_config(app_spi_params_t *p_params)
322 {
323 app_dma_params_t tx_dma_params;
324
325 tx_dma_params.channel_number = p_params->use_mode.tx_dma_channel;
326 tx_dma_params.init.src_request = DMA_REQUEST_MEM;
327 tx_dma_params.init.dst_request = (p_params->id == APP_SPI_ID_SLAVE) ? \
328 DMA_REQUEST_SPIS_TX : DMA_REQUEST_SPIM_TX;
329 tx_dma_params.init.direction = DMA_MEMORY_TO_PERIPH;
330 tx_dma_params.init.src_increment = DMA_SRC_INCREMENT;
331 tx_dma_params.init.dst_increment = DMA_DST_NO_CHANGE;
332 if (p_params->init.data_size <= SPI_DATASIZE_8BIT) {
333 tx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_BYTE;
334 tx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_BYTE;
335 } else if (p_params->init.data_size <= SPI_DATASIZE_16BIT) {
336 tx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_HALFWORD;
337 tx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_HALFWORD;
338 } else {
339 tx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_WORD;
340 tx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_WORD;
341 }
342 tx_dma_params.init.mode = DMA_NORMAL;
343 tx_dma_params.init.priority = DMA_PRIORITY_LOW;
344
345 s_spi_env[p_params->id].dma_id[0] = app_dma_init(&tx_dma_params, NULL);
346
347 if (s_spi_env[p_params->id].dma_id[0] < 0) {
348 return APP_DRV_ERR_INVALID_PARAM;
349 }
350 s_spi_env[p_params->id].handle.p_dmatx = app_dma_get_handle(s_spi_env[p_params->id].dma_id[0]);
351 s_spi_env[p_params->id].handle.p_dmatx->p_parent = (void*)&s_spi_env[p_params->id].handle;
352
353 return APP_DRV_SUCCESS;
354 }
355
spi_rx_dma_config(app_spi_params_t * p_params)356 static uint16_t spi_rx_dma_config(app_spi_params_t *p_params)
357 {
358 app_dma_params_t rx_dma_params;
359
360 rx_dma_params.channel_number = p_params->use_mode.rx_dma_channel;
361 rx_dma_params.init.src_request = (p_params->id == APP_SPI_ID_SLAVE) ? \
362 DMA_REQUEST_SPIS_RX : DMA_REQUEST_SPIM_TX;
363 rx_dma_params.init.dst_request = DMA_REQUEST_MEM;
364 rx_dma_params.init.direction = DMA_PERIPH_TO_MEMORY;
365 rx_dma_params.init.src_increment = DMA_SRC_NO_CHANGE;
366 rx_dma_params.init.dst_increment = DMA_DST_INCREMENT;
367 if (p_params->init.data_size <= SPI_DATASIZE_8BIT) {
368 rx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_BYTE;
369 rx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_BYTE;
370 } else if (p_params->init.data_size <= SPI_DATASIZE_16BIT) {
371 rx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_HALFWORD;
372 rx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_HALFWORD;
373 } else {
374 rx_dma_params.init.src_data_alignment = DMA_SDATAALIGN_WORD;
375 rx_dma_params.init.dst_data_alignment = DMA_DDATAALIGN_WORD;
376 }
377 rx_dma_params.init.mode = DMA_NORMAL;
378 rx_dma_params.init.priority = DMA_PRIORITY_LOW;
379
380 s_spi_env[p_params->id].dma_id[1] = app_dma_init(&rx_dma_params, NULL);
381
382 if (s_spi_env[p_params->id].dma_id[1] < 0) {
383 return APP_DRV_ERR_INVALID_PARAM;
384 }
385 s_spi_env[p_params->id].handle.p_dmarx = app_dma_get_handle(s_spi_env[p_params->id].dma_id[1]);
386 s_spi_env[p_params->id].handle.p_dmarx->p_parent = (void*)&s_spi_env[p_params->id].handle;
387
388 return APP_DRV_SUCCESS;
389 }
390
app_spi_config_dma(app_spi_params_t * p_params)391 static uint16_t app_spi_config_dma(app_spi_params_t *p_params)
392 {
393 uint16_t err_code = APP_DRV_SUCCESS;
394
395 err_code = spi_tx_dma_config(p_params);
396 APP_DRV_ERR_CODE_CHECK(err_code);
397
398 err_code = spi_rx_dma_config(p_params);
399 APP_DRV_ERR_CODE_CHECK(err_code);
400
401 return APP_DRV_SUCCESS;
402 }
403
app_spi_event_call(spi_handle_t * p_spi,app_spi_evt_type_t evt_type)404 static void app_spi_event_call(spi_handle_t *p_spi, app_spi_evt_type_t evt_type)
405 {
406 app_spi_evt_t spi_evt;
407 app_spi_id_t id = APP_SPI_ID_MAX;
408
409 if (p_spi->p_instance == SPIS) {
410 id = APP_SPI_ID_SLAVE;
411 } else if (p_spi->p_instance == SPIM) {
412 id = APP_SPI_ID_MASTER;
413 }
414
415 spi_evt.type = evt_type;
416 if (evt_type == APP_SPI_EVT_ERROR) {
417 spi_evt.data.error_code = p_spi->error_code;
418 #ifdef ENV_RTOS_USE_SEMP
419 if (!s_spi_env[id].user_mode) {
420 app_driver_sem_post_from_isr(s_spi_env[id].sem_tx);
421 app_driver_sem_post_from_isr(s_spi_env[id].sem_rx);
422 }
423 #endif
424 s_spi_env[id].rx_done = 1;
425 s_spi_env[id].tx_done = 1;
426 } else if (evt_type == APP_SPI_EVT_TX_CPLT) {
427 spi_evt.data.size = p_spi->tx_xfer_size - p_spi->tx_xfer_count;
428 #ifdef ENV_RTOS_USE_SEMP
429 if (!s_spi_env[id].user_mode) {
430 app_driver_sem_post_from_isr(s_spi_env[id].sem_tx);
431 }
432 #endif
433 s_spi_env[id].tx_done = 1;
434 } else if (evt_type == APP_SPI_EVT_RX_DATA) {
435 spi_evt.data.size = p_spi->rx_xfer_size - p_spi->rx_xfer_count;
436 #ifdef ENV_RTOS_USE_SEMP
437 if (!s_spi_env[id].user_mode) {
438 app_driver_sem_post_from_isr(s_spi_env[id].sem_rx);
439 }
440 #endif
441 s_spi_env[id].rx_done = 1;
442 } else if (evt_type == APP_SPI_EVT_TX_RX) {
443 spi_evt.data.size = p_spi->rx_xfer_size - p_spi->rx_xfer_count;
444 }
445
446 s_spi_env[id].start_flag = false;
447 SPI_SMART_CS_HIGH(id);
448
449 if (s_spi_env[id].evt_handler != NULL) {
450 s_spi_env[id].evt_handler(&spi_evt);
451 }
452 }
453
params_check(app_spi_params_t * p_params)454 static uint16_t params_check(app_spi_params_t *p_params)
455 {
456 uint8_t id = p_params->id;
457
458 if (p_params == NULL) {
459 return APP_DRV_ERR_POINTER_NULL;
460 }
461
462 if (id >= APP_SPI_ID_MAX) {
463 return APP_DRV_ERR_INVALID_ID;
464 }
465
466 return APP_DRV_SUCCESS;
467 }
468
469 #ifdef ENV_RTOS_USE_SEMP
semp_init_config(uint8_t id)470 static uint16_t semp_init_config(uint8_t id)
471 {
472 uint16_t err_code = APP_DRV_SUCCESS;
473
474 if (s_spi_env[id].sem_rx == NULL) {
475 err_code = app_driver_sem_init(&s_spi_env[id].sem_rx);
476 APP_DRV_ERR_CODE_CHECK(err_code);
477 }
478 if (s_spi_env[id].sem_tx == NULL) {
479 err_code = app_driver_sem_init(&s_spi_env[id].sem_tx);
480 APP_DRV_ERR_CODE_CHECK(err_code);
481 }
482 if (s_spi_env[id].sem_tx_rx == NULL) {
483 err_code = app_driver_sem_init(&s_spi_env[id].sem_tx_rx);
484 APP_DRV_ERR_CODE_CHECK(err_code);
485 }
486
487 return APP_DRV_SUCCESS;
488 }
489 #endif
490
491 #ifdef ENV_RTOS_USE_MUTEX
mutex_init_config(uint8_t id)492 static uint16_t mutex_init_config(uint8_t id)
493 {
494 uint16_t err_code = APP_DRV_SUCCESS;
495
496 if (s_spi_env[id].mutex_async == NULL) {
497 err_code = app_driver_mutex_init(&s_spi_env[id].mutex_async);
498 APP_DRV_ERR_CODE_CHECK(err_code);
499 }
500 if (s_spi_env[id].mutex_sync == NULL) {
501 err_code = app_driver_mutex_init(&s_spi_env[id].mutex_sync);
502 APP_DRV_ERR_CODE_CHECK(err_code);
503 }
504
505 return APP_DRV_SUCCESS;
506 }
507 #endif
508
sync_params_to_env(app_spi_params_t * p_params,app_spi_evt_handler_t evt_handler,uint8_t id)509 static void sync_params_to_env(app_spi_params_t *p_params, app_spi_evt_handler_t evt_handler, uint8_t id)
510 {
511 s_spi_env[id].use_mode.type = p_params->use_mode.type;
512 s_spi_env[id].use_mode.rx_dma_channel = p_params->use_mode.rx_dma_channel;
513 s_spi_env[id].use_mode.tx_dma_channel = p_params->use_mode.tx_dma_channel;
514 memcpy_s(&s_spi_env[id].pin_cfg, sizeof (s_spi_env[id].pin_cfg), &p_params->pin_cfg, sizeof(app_spi_pin_cfg_t));
515 s_spi_env[id].evt_handler = evt_handler;
516
517 memcpy_s(&s_spi_env[id].handle.init, sizeof (s_spi_env[id].handle.init), &p_params->init, sizeof(spi_init_t));
518 s_spi_env[id].handle.p_instance = (ssi_regs_t *)s_spi_instance[id];
519 }
520
register_cb(void)521 static uint16_t register_cb(void)
522 {
523 if (s_sleep_cb_registered_flag == false) { // register sleep callback
524 s_sleep_cb_registered_flag = true;
525 s_spi_pwr_id = pwr_register_sleep_cb(&spi_sleep_cb, APP_DRIVER_SPI_WAPEUP_PRIORITY);
526 if (s_spi_pwr_id < 0) {
527 return APP_DRV_ERR_INVALID_PARAM;
528 }
529 }
530
531 return APP_DRV_SUCCESS;
532 }
533
534 /*
535 * GLOBAL FUNCTION DEFINITIONS
536 ****************************************************************************************
537 */
app_spi_init(app_spi_params_t * p_params,app_spi_evt_handler_t evt_handler)538 uint16_t app_spi_init(app_spi_params_t *p_params, app_spi_evt_handler_t evt_handler)
539 {
540 uint8_t id = p_params->id;
541 uint16_t err_code = APP_DRV_SUCCESS;
542
543 err_code = params_check(p_params);
544 APP_DRV_ERR_CODE_CHECK(err_code);
545
546 #ifdef ENV_RTOS_USE_SEMP
547 err_code = semp_init_config(id);
548 APP_DRV_ERR_CODE_CHECK(err_code);
549 #endif
550
551 #ifdef ENV_RTOS_USE_MUTEX
552 err_code = mutex_init_config(id);
553 APP_DRV_ERR_CODE_CHECK(err_code);
554 #endif
555
556 app_systick_init();
557
558 err_code = spi_gpio_config(p_params->id, p_params->pin_cfg);
559 APP_DRV_ERR_CODE_CHECK(err_code);
560
561 if (p_params->use_mode.type == APP_SPI_TYPE_DMA) {
562 GLOBAL_EXCEPTION_DISABLE();
563 err_code = app_spi_config_dma(p_params);
564 GLOBAL_EXCEPTION_ENABLE();
565 APP_DRV_ERR_CODE_CHECK(err_code);
566 }
567
568 if (p_params->use_mode.type != APP_SPI_TYPE_POLLING) {
569 hal_nvic_clear_pending_irq(s_spi_irq[id]);
570 hal_nvic_enable_irq(s_spi_irq[id]);
571 }
572
573 sync_params_to_env(p_params, evt_handler, id);
574
575 hal_spi_deinit(&s_spi_env[id].handle);
576 hal_spi_init(&s_spi_env[id].handle);
577
578 err_code = register_cb();
579 APP_DRV_ERR_CODE_CHECK(err_code);
580
581 s_spi_env[id].spi_state = APP_SPI_ENABLE;
582 s_spi_env[id].start_flag = false;
583
584 return APP_DRV_SUCCESS;
585 }
586
587 #ifdef ENV_RTOS_USE_SEMP
semp_deinit_config(uint8_t id)588 static void semp_deinit_config(uint8_t id)
589 {
590 if (s_spi_env[id].sem_tx != NULL) {
591 app_driver_sem_deinit(s_spi_env[id].sem_tx);
592 s_spi_env[id].sem_tx = NULL;
593 }
594 if (s_spi_env[id].sem_rx != NULL) {
595 app_driver_sem_deinit(s_spi_env[id].sem_rx);
596 s_spi_env[id].sem_rx = NULL;
597 }
598 if (s_spi_env[id].sem_tx_rx != NULL) {
599 app_driver_sem_deinit(s_spi_env[id].sem_tx_rx);
600 s_spi_env[id].sem_tx_rx = NULL;
601 }
602 }
603 #endif
604
605 #ifdef ENV_RTOS_USE_MUTEX
mutex_deinit_config(uint8_t id)606 static uint16_t mutex_deinit_config(uint8_t id)
607 {
608 if (s_spi_env[id].mutex_sync != NULL) {
609 app_driver_mutex_deinit(s_spi_env[id].mutex_sync);
610 s_spi_env[id].mutex_sync = NULL;
611 }
612 if (s_spi_env[id].mutex_async != NULL) {
613 app_driver_mutex_deinit(s_spi_env[id].mutex_async);
614 s_spi_env[id].mutex_async = NULL;
615 }
616 }
617 #endif
618
unregister_cb(void)619 static void unregister_cb(void)
620 {
621 GLOBAL_EXCEPTION_DISABLE();
622 if (s_spi_env[APP_SPI_ID_SLAVE].spi_state == APP_SPI_INVALID &&
623 s_spi_env[APP_SPI_ID_MASTER].spi_state == APP_SPI_INVALID) {
624 pwr_unregister_sleep_cb(s_spi_pwr_id);
625 s_sleep_cb_registered_flag = false;
626 }
627 GLOBAL_EXCEPTION_ENABLE();
628 }
629
app_spi_deinit(app_spi_id_t id)630 uint16_t app_spi_deinit(app_spi_id_t id)
631 {
632 if ((id >= APP_SPI_ID_MAX) || (s_spi_env[id].spi_state == APP_SPI_INVALID)) {
633 return APP_DRV_ERR_INVALID_ID;
634 }
635
636 #ifdef ENV_RTOS_USE_SEMP
637 semp_deinit_config(id);
638 #endif
639
640 #ifdef ENV_RTOS_USE_MUTEX
641 mutex_deinit_config(id);
642 #endif
643
644 if (s_spi_env[id].pin_cfg.cs.enable == APP_SPI_PIN_ENABLE) {
645 app_io_deinit(s_spi_env[id].pin_cfg.cs.type, s_spi_env[id].pin_cfg.cs.pin);
646 }
647 if (s_spi_env[id].pin_cfg.clk.enable == APP_SPI_PIN_ENABLE) {
648 app_io_deinit(s_spi_env[id].pin_cfg.clk.type, s_spi_env[id].pin_cfg.clk.pin);
649 }
650 if (s_spi_env[id].pin_cfg.mosi.enable == APP_SPI_PIN_ENABLE) {
651 app_io_deinit(s_spi_env[id].pin_cfg.mosi.type, s_spi_env[id].pin_cfg.mosi.pin);
652 }
653 if (s_spi_env[id].pin_cfg.miso.enable == APP_SPI_PIN_ENABLE) {
654 app_io_deinit(s_spi_env[id].pin_cfg.miso.type, s_spi_env[id].pin_cfg.miso.pin);
655 }
656
657 hal_nvic_disable_irq(s_spi_irq[id]);
658 if (s_spi_env[id].use_mode.type == APP_SPI_TYPE_DMA) {
659 app_dma_deinit(s_spi_env[id].dma_id[0]);
660 app_dma_deinit(s_spi_env[id].dma_id[1]);
661 }
662 s_spi_env[id].spi_state = APP_SPI_INVALID;
663 s_spi_env[id].start_flag = false;
664
665 unregister_cb();
666
667 app_systick_deinit();
668
669 hal_spi_deinit(&s_spi_env[id].handle);
670
671 return APP_DRV_SUCCESS;
672 }
673
app_spi_receive_async(app_spi_id_t id,uint8_t * p_data,uint16_t size)674 uint16_t app_spi_receive_async(app_spi_id_t id, uint8_t *p_data, uint16_t size)
675 {
676 hal_status_t err_code;
677
678 if (id >= APP_SPI_ID_MAX ||
679 p_data == NULL ||
680 size == 0 ||
681 s_spi_env[id].spi_state == APP_SPI_INVALID ||
682 s_spi_env[id].use_mode.type == APP_SPI_TYPE_POLLING) {
683 return APP_DRV_ERR_INVALID_PARAM;
684 }
685
686 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
687 spi_wake_up(id);
688 #endif
689
690 if (s_spi_env[id].start_flag == false) {
691 s_spi_env[id].start_flag = true;
692 switch (s_spi_env[id].use_mode.type) {
693 case APP_SPI_TYPE_INTERRUPT:
694 SPI_SMART_CS_LOW(id);
695 err_code = hal_spi_receive_it(&s_spi_env[id].handle, p_data, size);
696 break;
697
698 case APP_SPI_TYPE_DMA:
699 SPI_SMART_CS_LOW(id);
700 err_code = hal_spi_receive_dma(&s_spi_env[id].handle, p_data, size);
701 break;
702
703 default:
704 break;
705 }
706 if (err_code != HAL_OK) {
707 s_spi_env[id].start_flag = false;
708 return (uint16_t)err_code;
709 }
710 } else {
711 return APP_DRV_ERR_BUSY;
712 }
713
714 return APP_DRV_SUCCESS;
715 }
716
app_spi_receive_sync(app_spi_id_t id,uint8_t * p_data,uint16_t size,uint32_t timeout)717 uint16_t app_spi_receive_sync(app_spi_id_t id, uint8_t *p_data, uint16_t size, uint32_t timeout)
718 {
719 hal_status_t err_code;
720
721 if (id >= APP_SPI_ID_MAX ||
722 p_data == NULL ||
723 size == 0 ||
724 s_spi_env[id].spi_state == APP_SPI_INVALID) {
725 return APP_DRV_ERR_INVALID_PARAM;
726 }
727
728 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
729 spi_wake_up(id);
730 #endif
731
732 SPI_SMART_CS_LOW(id);
733 err_code = hal_spi_receive(&s_spi_env[id].handle, p_data, size, timeout);
734 SPI_SMART_CS_HIGH(id);
735
736 if (err_code != HAL_OK) {
737 return (uint16_t)err_code;
738 }
739
740 return APP_DRV_SUCCESS;
741 }
742
743 #ifdef ENV_RTOS_USE_SEMP
app_spi_receive_sem_sync(app_spi_id_t id,uint8_t * p_data,uint16_t size)744 uint16_t app_spi_receive_sem_sync(app_spi_id_t id, uint8_t *p_data, uint16_t size)
745 {
746 hal_status_t err_code;
747
748 #ifdef ENV_RTOS_USE_MUTEX
749 APP_SPI_DRV_ASYNC_MUTEX_LOCK(id);
750 #endif
751
752 if (id >= APP_SPI_ID_MAX ||
753 p_data == NULL ||
754 size == 0 ||
755 s_spi_env[id].spi_state == APP_SPI_INVALID ||
756 s_spi_env[id].use_mode.type == APP_SPI_TYPE_POLLING) {
757 #ifdef ENV_RTOS_USE_MUTEX
758 APP_SPI_DRV_ASYNC_MUTEX_UNLOCK(id);
759 #endif
760 return APP_DRV_ERR_INVALID_PARAM;
761 }
762
763 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
764 spi_wake_up(id);
765 #endif
766
767 if (s_spi_env[id].start_flag == false) {
768 s_spi_env[id].start_flag = true;
769 switch (s_spi_env[id].use_mode.type) {
770 case APP_SPI_TYPE_INTERRUPT:
771 SPI_SMART_CS_LOW(id);
772 err_code = hal_spi_receive_it(&s_spi_env[id].handle, p_data, size);
773 break;
774
775 case APP_SPI_TYPE_DMA:
776 SPI_SMART_CS_LOW(id);
777 err_code = hal_spi_receive_dma(&s_spi_env[id].handle, p_data, size);
778 break;
779
780 default:
781 break;
782 }
783 if (err_code != HAL_OK) {
784 #ifdef ENV_RTOS_USE_MUTEX
785 APP_SPI_DRV_ASYNC_MUTEX_UNLOCK(id);
786 #endif
787 s_spi_env[id].start_flag = false;
788 return (uint16_t)err_code;
789 }
790 } else {
791 #ifdef ENV_RTOS_USE_MUTEX
792 APP_SPI_DRV_ASYNC_MUTEX_UNLOCK(id);
793 #endif
794 return APP_DRV_ERR_BUSY;
795 }
796
797 app_driver_sem_pend(s_spi_env[id].sem_rx, OS_WAIT_FOREVER);
798
799 #ifdef ENV_RTOS_USE_MUTEX
800 APP_SPI_DRV_ASYNC_MUTEX_UNLOCK(id);
801 #endif
802
803 return APP_DRV_SUCCESS;
804 }
805 #endif
806
app_spi_receive_high_speed_sync(app_spi_id_t id,uint8_t * p_data,uint16_t size)807 uint16_t app_spi_receive_high_speed_sync(app_spi_id_t id, uint8_t *p_data, uint16_t size)
808 {
809 uint16_t app_err_code = APP_DRV_SUCCESS;
810 hal_status_t hal_err_code = HAL_OK;
811
812 if (id >= APP_SPI_ID_MAX ||
813 p_data == NULL ||
814 size == 0 ||
815 s_spi_env[id].spi_state == APP_SPI_INVALID ||
816 s_spi_env[id].use_mode.type == APP_SPI_TYPE_POLLING) {
817 return APP_DRV_ERR_INVALID_PARAM;
818 }
819
820 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
821 spi_wake_up(id);
822 #endif
823
824 s_spi_env[id].user_mode = 0x1;
825
826 BLE_INT_DISABLE();
827 s_spi_env[id].rx_done = 0;
828
829 if (s_spi_env[id].start_flag == false) {
830 s_spi_env[id].start_flag = true;
831 switch (s_spi_env[id].use_mode.type) {
832 case APP_SPI_TYPE_INTERRUPT:
833 SPI_SMART_CS_LOW(id);
834 hal_err_code = hal_spi_receive_it(&s_spi_env[id].handle, p_data, size);
835 break;
836
837 case APP_SPI_TYPE_DMA:
838 SPI_SMART_CS_LOW(id);
839 hal_err_code = hal_spi_receive_dma(&s_spi_env[id].handle, p_data, size);
840 break;
841
842 default:
843 break;
844 }
845 if (hal_err_code != HAL_OK) {
846 s_spi_env[id].start_flag = false;
847 SPI_SMART_CS_HIGH(id);
848 app_err_code = (uint16_t)hal_err_code;
849 goto exit;
850 }
851 } else {
852 app_err_code = APP_DRV_ERR_BUSY;
853 goto exit;
854 }
855
856 while (s_spi_env[id].rx_done == 0);
857
858 exit:
859 s_spi_env[id].user_mode = 0x0;
860 BLE_INT_RESTORE();
861
862 return app_err_code;
863 }
864
app_spi_transmit_high_speed_sync(app_spi_id_t id,uint8_t * p_data,uint16_t size)865 uint16_t app_spi_transmit_high_speed_sync(app_spi_id_t id, uint8_t *p_data, uint16_t size)
866 {
867 uint16_t app_err_code = APP_DRV_SUCCESS;
868 hal_status_t hal_err_code = HAL_OK;
869
870 if (id >= APP_SPI_ID_MAX ||
871 p_data == NULL ||
872 size == 0 ||
873 s_spi_env[id].spi_state == APP_SPI_INVALID ||
874 s_spi_env[id].use_mode.type == APP_SPI_TYPE_POLLING) {
875 return APP_DRV_ERR_INVALID_PARAM;
876 }
877
878 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
879 spi_wake_up(id);
880 #endif
881
882 s_spi_env[id].user_mode = 0x1;
883
884 BLE_INT_DISABLE();
885 s_spi_env[id].tx_done = 0;
886
887 if (s_spi_env[id].start_flag == false) {
888 s_spi_env[id].start_flag = true;
889 switch (s_spi_env[id].use_mode.type) {
890 case APP_SPI_TYPE_INTERRUPT:
891 SPI_SMART_CS_LOW(id);
892 hal_err_code = hal_spi_transmit_it(&s_spi_env[id].handle, p_data, size);
893 break;
894
895 case APP_SPI_TYPE_DMA:
896 SPI_SMART_CS_LOW(id);
897 hal_err_code = hal_spi_transmit_dma(&s_spi_env[id].handle, p_data, size);
898 break;
899
900 default:
901 break;
902 }
903 if (hal_err_code != HAL_OK) {
904 s_spi_env[id].start_flag = false;
905 SPI_SMART_CS_HIGH(id);
906 app_err_code = (uint16_t)hal_err_code;
907
908 goto exit;
909 }
910 } else {
911 app_err_code = APP_DRV_ERR_BUSY;
912 goto exit;
913 }
914
915 while (s_spi_env[id].tx_done == 0);
916
917 exit:
918 s_spi_env[id].user_mode = 0x0;
919 BLE_INT_RESTORE();
920
921 return app_err_code;
922 }
923
app_spi_transmit_async(app_spi_id_t id,uint8_t * p_data,uint16_t size)924 uint16_t app_spi_transmit_async(app_spi_id_t id, uint8_t *p_data, uint16_t size)
925 {
926 hal_status_t err_code;
927
928 if (id >= APP_SPI_ID_MAX ||
929 p_data == NULL ||
930 size == 0 ||
931 s_spi_env[id].spi_state == APP_SPI_INVALID ||
932 s_spi_env[id].use_mode.type == APP_SPI_TYPE_POLLING) {
933 return APP_DRV_ERR_INVALID_PARAM;
934 }
935
936 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
937 spi_wake_up(id);
938 #endif
939
940 if (s_spi_env[id].start_flag == false) {
941 s_spi_env[id].start_flag = true;
942 switch (s_spi_env[id].use_mode.type) {
943 case APP_SPI_TYPE_INTERRUPT:
944 SPI_SMART_CS_LOW(id);
945 err_code = hal_spi_transmit_it(&s_spi_env[id].handle, p_data, size);
946 break;
947
948 case APP_SPI_TYPE_DMA:
949 SPI_SMART_CS_LOW(id);
950 err_code = hal_spi_transmit_dma(&s_spi_env[id].handle, p_data, size);
951 break;
952
953 default:
954 break;
955 }
956 if (err_code != HAL_OK) {
957 s_spi_env[id].start_flag = false;
958 SPI_SMART_CS_HIGH(id);
959
960 return (uint16_t)err_code;
961 }
962 } else {
963 return APP_DRV_ERR_BUSY;
964 }
965
966 return APP_DRV_SUCCESS;
967 }
968
app_spi_transmit_sync(app_spi_id_t id,uint8_t * p_data,uint16_t size,uint32_t timeout)969 uint16_t app_spi_transmit_sync(app_spi_id_t id, uint8_t *p_data, uint16_t size, uint32_t timeout)
970 {
971 hal_status_t err_code;
972
973 if (id >= APP_SPI_ID_MAX ||
974 p_data == NULL ||
975 size == 0 ||
976 s_spi_env[id].spi_state == APP_SPI_INVALID) {
977 return APP_DRV_ERR_INVALID_PARAM;
978 }
979
980 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
981 spi_wake_up(id);
982 #endif
983
984 SPI_SMART_CS_LOW(id);
985 err_code = hal_spi_transmit(&s_spi_env[id].handle, p_data, size, timeout);
986 SPI_SMART_CS_HIGH(id);
987
988 if (err_code != HAL_OK) {
989 return (uint16_t)err_code;
990 }
991
992 return APP_DRV_SUCCESS;
993 }
994
995 #ifdef ENV_RTOS_USE_SEMP
app_spi_transmit_sem_sync(app_spi_id_t id,uint8_t * p_data,uint16_t size)996 uint16_t app_spi_transmit_sem_sync(app_spi_id_t id, uint8_t *p_data, uint16_t size)
997 {
998 hal_status_t err_code;
999
1000 #ifdef ENV_RTOS_USE_MUTEX
1001 APP_SPI_DRV_ASYNC_MUTEX_LOCK(id);
1002 #endif
1003
1004 if (id >= APP_SPI_ID_MAX ||
1005 p_data == NULL ||
1006 size == 0 ||
1007 s_spi_env[id].spi_state == APP_SPI_INVALID ||
1008 s_spi_env[id].use_mode.type == APP_SPI_TYPE_POLLING) {
1009 #ifdef ENV_RTOS_USE_MUTEX
1010 APP_SPI_DRV_ASYNC_MUTEX_UNLOCK(id);
1011 #endif
1012 return APP_DRV_ERR_INVALID_PARAM;
1013 }
1014
1015 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
1016 spi_wake_up(id);
1017 #endif
1018
1019 if (s_spi_env[id].start_flag == false) {
1020 s_spi_env[id].start_flag = true;
1021 switch (s_spi_env[id].use_mode.type) {
1022 case APP_SPI_TYPE_INTERRUPT:
1023 SPI_SMART_CS_LOW(id);
1024 err_code = hal_spi_transmit_it(&s_spi_env[id].handle, p_data, size);
1025 break;
1026
1027 case APP_SPI_TYPE_DMA:
1028 SPI_SMART_CS_LOW(id);
1029 err_code = hal_spi_transmit_dma(&s_spi_env[id].handle, p_data, size);
1030 break;
1031
1032 default:
1033 break;
1034 }
1035 if (err_code != HAL_OK) {
1036 #ifdef ENV_RTOS_USE_MUTEX
1037 APP_SPI_DRV_ASYNC_MUTEX_UNLOCK(id);
1038 #endif
1039 s_spi_env[id].start_flag = false;
1040 SPI_SMART_CS_HIGH(id);
1041 return (uint16_t)err_code;
1042 }
1043 } else {
1044 #ifdef ENV_RTOS_USE_MUTEX
1045 APP_SPI_DRV_ASYNC_MUTEX_UNLOCK(id);
1046 #endif
1047 return APP_DRV_ERR_BUSY;
1048 }
1049
1050 app_driver_sem_pend(s_spi_env[id].sem_tx, OS_WAIT_FOREVER);
1051
1052 #ifdef ENV_RTOS_USE_MUTEX
1053 APP_SPI_DRV_ASYNC_MUTEX_UNLOCK(id);
1054 #endif
1055
1056 return APP_DRV_SUCCESS;
1057 }
1058 #endif
1059
app_spi_transmit_receive_sync(app_spi_id_t id,uint8_t * p_tx_data,uint8_t * p_rx_data,uint32_t size,uint32_t timeout)1060 uint16_t app_spi_transmit_receive_sync(app_spi_id_t id, uint8_t *p_tx_data, \
1061 uint8_t *p_rx_data, uint32_t size, uint32_t timeout)
1062 {
1063 hal_status_t err_code;
1064
1065 if (id >= APP_SPI_ID_MAX ||
1066 p_tx_data == NULL ||
1067 p_rx_data == NULL ||
1068 size == 0 ||
1069 s_spi_env[id].spi_state == APP_SPI_INVALID) {
1070 return APP_DRV_ERR_INVALID_PARAM;
1071 }
1072
1073 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
1074 spi_wake_up(id);
1075 #endif
1076
1077 SPI_SMART_CS_LOW(id);
1078 err_code = hal_spi_transmit_receive(&s_spi_env[id].handle, p_tx_data, p_rx_data, size, timeout);
1079 SPI_SMART_CS_HIGH(id);
1080
1081 if (err_code != HAL_OK) {
1082 return (uint16_t)err_code;
1083 }
1084
1085 return APP_DRV_SUCCESS;
1086 }
1087
app_spi_transmit_receive_async(app_spi_id_t id,uint8_t * p_tx_data,uint8_t * p_rx_data,uint32_t size)1088 uint16_t app_spi_transmit_receive_async(app_spi_id_t id, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t size)
1089 {
1090 hal_status_t err_code;
1091
1092 if (id >= APP_SPI_ID_MAX ||
1093 p_tx_data == NULL ||
1094 p_rx_data == NULL ||
1095 size == 0 ||
1096 s_spi_env[id].spi_state == APP_SPI_INVALID ||
1097 s_spi_env[id].use_mode.type == APP_SPI_TYPE_POLLING) {
1098 return APP_DRV_ERR_INVALID_PARAM;
1099 }
1100
1101 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
1102 spi_wake_up(id);
1103 #endif
1104
1105 if (s_spi_env[id].start_flag == false) {
1106 s_spi_env[id].start_flag = true;
1107 switch (s_spi_env[id].use_mode.type) {
1108 case APP_SPI_TYPE_INTERRUPT:
1109 SPI_SMART_CS_LOW(id);
1110 err_code = hal_spi_transmit_receive_it(&s_spi_env[id].handle, p_tx_data, p_rx_data, size);
1111 break;
1112
1113 case APP_SPI_TYPE_DMA:
1114 SPI_SMART_CS_LOW(id);
1115 err_code = hal_spi_transmit_receive_dma(&s_spi_env[id].handle, p_tx_data, p_rx_data, size);
1116 break;
1117
1118 default:
1119 break;
1120 }
1121 if (err_code != HAL_OK) {
1122 s_spi_env[id].start_flag = false;
1123 SPI_SMART_CS_HIGH(id);
1124 return (uint16_t)err_code;
1125 }
1126 }
1127
1128 return APP_DRV_SUCCESS;
1129 }
1130
1131 #ifdef ENV_RTOS_USE_SEMP
app_spi_transmit_receive_sem_sync(app_spi_id_t id,uint8_t * p_tx_data,uint8_t * p_rx_data,uint32_t size)1132 uint16_t app_spi_transmit_receive_sem_sync(app_spi_id_t id, uint8_t *p_tx_data, uint8_t *p_rx_data, uint32_t size)
1133 {
1134 hal_status_t err_code;
1135
1136 #ifdef ENV_RTOS_USE_MUTEX
1137 APP_SPI_DRV_ASYNC_MUTEX_LOCK(id);
1138 #endif
1139
1140 if (id >= APP_SPI_ID_MAX ||
1141 p_tx_data == NULL ||
1142 p_rx_data == NULL ||
1143 size == 0 ||
1144 s_spi_env[id].spi_state == APP_SPI_INVALID ||
1145 s_spi_env[id].use_mode.type == APP_SPI_TYPE_POLLING) {
1146 #ifdef ENV_RTOS_USE_MUTEX
1147 APP_SPI_DRV_ASYNC_MUTEX_UNLOCK(id);
1148 #endif
1149 return APP_DRV_ERR_INVALID_PARAM;
1150 }
1151
1152 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
1153 spi_wake_up(id);
1154 #endif
1155
1156 if (s_spi_env[id].start_flag == false) {
1157 s_spi_env[id].start_flag = true;
1158 switch (s_spi_env[id].use_mode.type) {
1159 case APP_SPI_TYPE_INTERRUPT:
1160 SPI_SMART_CS_LOW(id);
1161 err_code = hal_spi_transmit_receive_it(&s_spi_env[id].handle, p_tx_data, p_rx_data, size);
1162 break;
1163
1164 case APP_SPI_TYPE_DMA:
1165 SPI_SMART_CS_LOW(id);
1166 err_code = hal_spi_transmit_receive_dma(&s_spi_env[id].handle, p_tx_data, p_rx_data, size);
1167 break;
1168
1169 default:
1170 break;
1171 }
1172 if (err_code != HAL_OK) {
1173 #ifdef ENV_RTOS_USE_MUTEX
1174 APP_SPI_DRV_ASYNC_MUTEX_UNLOCK(id);
1175 #endif
1176 s_spi_env[id].start_flag = false;
1177 SPI_SMART_CS_HIGH(id);
1178 return (uint16_t)err_code;
1179 }
1180 }
1181
1182 app_driver_sem_pend(s_spi_env[id].sem_tx_rx, OS_WAIT_FOREVER);
1183
1184 #ifdef ENV_RTOS_USE_MUTEX
1185 APP_SPI_DRV_ASYNC_MUTEX_UNLOCK(id);
1186 #endif
1187
1188 return APP_DRV_SUCCESS;
1189 }
1190 #endif
1191
app_spi_read_eeprom_async(app_spi_id_t id,uint8_t * p_tx_data,uint8_t * p_rx_data,uint32_t tx_size,uint32_t rx_size)1192 uint16_t app_spi_read_eeprom_async(app_spi_id_t id, uint8_t *p_tx_data, \
1193 uint8_t *p_rx_data, uint32_t tx_size, uint32_t rx_size)
1194 {
1195 hal_status_t err_code;
1196
1197 if (id >= APP_SPI_ID_MAX ||
1198 p_tx_data == NULL ||
1199 p_rx_data == NULL ||
1200 tx_size == 0 ||
1201 rx_size == 0 ||
1202 s_spi_env[id].spi_state == APP_SPI_INVALID ||
1203 s_spi_env[id].use_mode.type == APP_SPI_TYPE_POLLING) {
1204 return APP_DRV_ERR_INVALID_PARAM;
1205 }
1206
1207 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
1208 spi_wake_up(id);
1209 #endif
1210
1211 if (s_spi_env[id].start_flag == false) {
1212 s_spi_env[id].start_flag = true;
1213 switch (s_spi_env[id].use_mode.type) {
1214 case APP_SPI_TYPE_INTERRUPT:
1215 SPI_SMART_CS_LOW(id);
1216 err_code = hal_spi_read_eeprom_it(&s_spi_env[id].handle, p_tx_data, p_rx_data, tx_size, rx_size);
1217 break;
1218
1219 case APP_SPI_TYPE_DMA:
1220 SPI_SMART_CS_LOW(id);
1221 err_code = hal_spi_read_eeprom_dma(&s_spi_env[id].handle, p_tx_data, p_rx_data, tx_size, rx_size);
1222 break;
1223
1224 default:
1225 break;
1226 }
1227 if (err_code != HAL_OK) {
1228 s_spi_env[id].start_flag = false;
1229 SPI_SMART_CS_HIGH(id);
1230 return (uint16_t)err_code;
1231 }
1232 } else {
1233 return APP_DRV_ERR_BUSY;
1234 }
1235
1236 return APP_DRV_SUCCESS;
1237 }
1238
app_spi_read_eeprom_sync(app_spi_id_t id,uint8_t * p_tx_data,uint8_t * p_rx_data,uint32_t tx_size,uint32_t rx_size,uint32_t timeout)1239 uint16_t app_spi_read_eeprom_sync(app_spi_id_t id, uint8_t *p_tx_data, \
1240 uint8_t *p_rx_data, uint32_t tx_size, uint32_t rx_size, uint32_t timeout)
1241 {
1242 hal_status_t err_code;
1243
1244 if (id >= APP_SPI_ID_MAX ||
1245 p_tx_data == NULL ||
1246 p_rx_data == NULL ||
1247 tx_size == 0 ||
1248 rx_size == 0 ||
1249 s_spi_env[id].spi_state == APP_SPI_INVALID) {
1250 return APP_DRV_ERR_INVALID_PARAM;
1251 }
1252
1253 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
1254 spi_wake_up(id);
1255 #endif
1256
1257 SPI_SMART_CS_LOW(id);
1258 err_code = hal_spi_read_eeprom(&s_spi_env[id].handle, p_tx_data, p_rx_data, tx_size, rx_size, timeout);
1259 SPI_SMART_CS_HIGH(id);
1260
1261 if (err_code != HAL_OK) {
1262 return (uint16_t)err_code;
1263 }
1264
1265 return APP_DRV_SUCCESS;
1266 }
1267
app_spi_read_memory_async(app_spi_id_t id,uint8_t * p_cmd_data,uint8_t * p_rx_data,uint32_t cmd_size,uint32_t rx_size)1268 uint16_t app_spi_read_memory_async(app_spi_id_t id, uint8_t *p_cmd_data, \
1269 uint8_t *p_rx_data, uint32_t cmd_size, uint32_t rx_size)
1270 {
1271 hal_status_t err_code;
1272
1273 if (id >= APP_SPI_ID_MAX ||
1274 p_cmd_data == NULL ||
1275 p_rx_data == NULL ||
1276 cmd_size == 0 ||
1277 rx_size == 0 ||
1278 s_spi_env[id].spi_state == APP_SPI_INVALID ||
1279 s_spi_env[id].use_mode.type == APP_SPI_TYPE_POLLING) {
1280 return APP_DRV_ERR_INVALID_PARAM;
1281 }
1282
1283 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
1284 spi_wake_up(id);
1285 #endif
1286
1287 if (s_spi_env[id].start_flag == false) {
1288 s_spi_env[id].start_flag = true;
1289
1290 SPI_SMART_CS_LOW(id);
1291 err_code = hal_spi_transmit(&s_spi_env[id].handle, p_cmd_data, cmd_size, MS_1000);
1292 if (err_code != HAL_OK) {
1293 SPI_SMART_CS_HIGH(id);
1294 s_spi_env[id].start_flag = false;
1295 return (uint16_t)err_code;
1296 }
1297 switch (s_spi_env[id].use_mode.type) {
1298 case APP_SPI_TYPE_INTERRUPT:
1299 err_code = hal_spi_receive_it(&s_spi_env[id].handle, p_rx_data, rx_size);
1300 break;
1301
1302 case APP_SPI_TYPE_DMA:
1303 err_code = hal_spi_receive_dma(&s_spi_env[id].handle, p_rx_data, rx_size);
1304 break;
1305
1306 default:
1307 break;
1308 }
1309 if (err_code != HAL_OK) {
1310 s_spi_env[id].start_flag = false;
1311 SPI_SMART_CS_HIGH(id);
1312 return (uint16_t)err_code;
1313 }
1314 } else {
1315 return APP_DRV_ERR_BUSY;
1316 }
1317
1318 return APP_DRV_SUCCESS;
1319 }
1320
app_spi_write_memory_async(app_spi_id_t id,uint8_t * p_cmd_data,uint8_t * p_tx_data,uint32_t cmd_size,uint32_t tx_size)1321 uint16_t app_spi_write_memory_async(app_spi_id_t id, uint8_t *p_cmd_data, \
1322 uint8_t *p_tx_data, uint32_t cmd_size, uint32_t tx_size)
1323 {
1324 hal_status_t err_code;
1325
1326 if (id >= APP_SPI_ID_MAX ||
1327 p_cmd_data == NULL ||
1328 p_tx_data == NULL ||
1329 cmd_size == 0 ||
1330 tx_size == 0 ||
1331 s_spi_env[id].spi_state == APP_SPI_INVALID ||
1332 s_spi_env[id].use_mode.type == APP_SPI_TYPE_POLLING) {
1333 return APP_DRV_ERR_INVALID_PARAM;
1334 }
1335
1336 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
1337 spi_wake_up(id);
1338 #endif
1339
1340 if (s_spi_env[id].start_flag == false) {
1341 s_spi_env[id].start_flag = true;
1342
1343 SPI_SMART_CS_LOW(id);
1344 err_code = hal_spi_transmit(&s_spi_env[id].handle, p_cmd_data, cmd_size, MS_1000);
1345 if (err_code != HAL_OK) {
1346 SPI_SMART_CS_HIGH(id);
1347 s_spi_env[id].start_flag = false;
1348 return (uint16_t)err_code;
1349 }
1350
1351 switch (s_spi_env[id].use_mode.type) {
1352 case APP_SPI_TYPE_INTERRUPT:
1353 err_code = hal_spi_transmit_it(&s_spi_env[id].handle, p_tx_data, tx_size);
1354 break;
1355
1356 case APP_SPI_TYPE_DMA:
1357 err_code = hal_spi_transmit_dma(&s_spi_env[id].handle, p_tx_data, tx_size);
1358 break;
1359
1360 default:
1361 break;
1362 }
1363 if (err_code != HAL_OK) {
1364 s_spi_env[id].start_flag = false;
1365 SPI_SMART_CS_HIGH(id);
1366 return (uint16_t)err_code;
1367 }
1368 } else {
1369 return APP_DRV_ERR_BUSY;
1370 }
1371
1372 return APP_DRV_SUCCESS;
1373 }
1374
app_spi_get_handle(app_spi_id_t id)1375 spi_handle_t *app_spi_get_handle(app_spi_id_t id)
1376 {
1377 if (id >= APP_SPI_ID_MAX ||
1378 s_spi_env[id].spi_state == APP_SPI_INVALID) {
1379 return NULL;
1380 }
1381
1382 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
1383 spi_wake_up(id);
1384 #endif
1385
1386 return &s_spi_env[id].handle;
1387 }
1388
hal_spi_tx_cplt_callback(spi_handle_t * p_spi)1389 void hal_spi_tx_cplt_callback(spi_handle_t *p_spi)
1390 {
1391 app_spi_event_call(p_spi, APP_SPI_EVT_TX_CPLT);
1392 }
1393
hal_spi_rx_cplt_callback(spi_handle_t * p_spi)1394 void hal_spi_rx_cplt_callback(spi_handle_t *p_spi)
1395 {
1396 app_spi_event_call(p_spi, APP_SPI_EVT_RX_DATA);
1397 }
1398
hal_spi_tx_rx_cplt_callback(spi_handle_t * p_spi)1399 void hal_spi_tx_rx_cplt_callback(spi_handle_t *p_spi)
1400 {
1401 app_spi_event_call(p_spi, APP_SPI_EVT_TX_RX);
1402 }
1403
hal_spi_error_callback(spi_handle_t * p_spi)1404 void hal_spi_error_callback(spi_handle_t *p_spi)
1405 {
1406 app_spi_event_call(p_spi, APP_SPI_EVT_ERROR);
1407 }
1408
SPI_S_IRQHandler(void)1409 SECTION_RAM_CODE void SPI_S_IRQHandler(void)
1410 {
1411 #if FLASH_PROTECT_PRIORITY
1412 platform_interrupt_protection_push();
1413 #endif
1414 hal_spi_irq_handler(&s_spi_env[APP_SPI_ID_SLAVE].handle);
1415 #if FLASH_PROTECT_PRIORITY
1416 platform_interrupt_protection_pop();
1417 #endif
1418 }
1419
SPI_M_IRQHandler(void)1420 SECTION_RAM_CODE void SPI_M_IRQHandler(void)
1421 {
1422 #if FLASH_PROTECT_PRIORITY
1423 platform_interrupt_protection_push();
1424 #endif
1425 hal_spi_irq_handler(&s_spi_env[APP_SPI_ID_MASTER].handle);
1426 #if FLASH_PROTECT_PRIORITY
1427 platform_interrupt_protection_pop();
1428 #endif
1429 }
1430
1431 #endif
1432
1433