• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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