1 /**
2 ******************************************************************************
3 * @file stm32l4xx_hal_swpmi.c
4 * @author MCD Application Team
5 * @brief SWPMI HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Single Wire Protocol Master Interface (SWPMI).
8 * + Initialization and Configuration
9 * + Data transfers functions
10 * + DMA transfers management
11 * + Interrupts and flags management
12 @verbatim
13 ===============================================================================
14 ##### How to use this driver #####
15 ===============================================================================
16 [..]
17 The SWPMI HAL driver can be used as follows:
18
19 (#) Declare a SWPMI_HandleTypeDef handle structure (eg. SWPMI_HandleTypeDef hswpmi).
20
21 (#) Initialize the SWPMI low level resources by implementing the HAL_SWPMI_MspInit() API:
22 (##) Enable the SWPMIx interface clock with __HAL_RCC_SWPMIx_CLK_ENABLE().
23 (##) SWPMI IO configuration:
24 (+++) Enable the clock for the SWPMI GPIO.
25 (+++) Configure these SWPMI pins as alternate function pull-up.
26 (##) NVIC configuration if you need to use interrupt process (HAL_SWPMI_Transmit_IT()
27 and HAL_SWPMI_Receive_IT() APIs):
28 (+++) Configure the SWPMIx interrupt priority with HAL_NVIC_SetPriority().
29 (+++) Enable the NVIC SWPMI IRQ handle with HAL_NVIC_EnableIRQ().
30
31 (##) DMA Configuration if you need to use DMA process (HAL_SWPMI_Transmit_DMA()
32 and HAL_SWPMI_Receive_DMA() APIs):
33 (+++) Declare a DMA handle structure for the Tx/Rx channels.
34 (+++) Enable the DMAx interface clock.
35 (+++) Configure the declared DMA handle structure with the required
36 Tx/Rx parameters.
37 (+++) Configure the DMA Tx/Rx channels and requests.
38 (+++) Associate the initialized DMA handle to the SWPMI DMA Tx/Rx handle.
39 (+++) Configure the priority and enable the NVIC for the transfer complete
40 interrupt on the DMA Tx/Rx channels.
41
42 (#) Program the Bite Rate, Tx Buffering mode, Rx Buffering mode in the Init structure.
43
44 (#) Enable the SWPMI peripheral by calling the HAL_SWPMI_Init() function.
45
46 [..]
47 Three operation modes are available within this driver :
48
49 *** Polling mode IO operation ***
50 =================================
51 [..]
52 (+) Send an amount of data in blocking mode using HAL_SWPMI_Transmit()
53 (+) Receive an amount of data in blocking mode using HAL_SWPMI_Receive()
54
55 *** Interrupt mode IO operation ***
56 ===================================
57 [..]
58 (+) Send an amount of data in non-blocking mode using HAL_SWPMI_Transmit_IT()
59 (+) At transmission end of transfer HAL_SWPMI_TxCpltCallback() is executed and user can
60 add his own code by customization of function pointer HAL_SWPMI_TxCpltCallback()
61 (+) Receive an amount of data in non-blocking mode using HAL_SWPMI_Receive_IT()
62 (+) At reception end of transfer HAL_SWPMI_RxCpltCallback() is executed and user can
63 add his own code by customization of function pointer HAL_SWPMI_RxCpltCallback()
64 (+) In case of flag error, HAL_SWPMI_ErrorCallback() function is executed and user can
65 add his own code by customization of function pointer HAL_SWPMI_ErrorCallback()
66
67 *** DMA mode IO operation ***
68 =============================
69 [..]
70 (+) Send an amount of data in non-blocking mode (DMA) using HAL_SWPMI_Transmit_DMA()
71 (+) At transmission end of transfer HAL_SWPMI_TxCpltCallback() is executed and user can
72 add his own code by customization of function pointer HAL_SWPMI_TxCpltCallback()
73 (+) Receive an amount of data in non-blocking mode (DMA) using HAL_SWPMI_Receive_DMA()
74 (+) At reception end of transfer HAL_SWPMI_RxCpltCallback() is executed and user can
75 add his own code by customization of function pointer HAL_SWPMI_RxCpltCallback()
76 (+) In case of flag error, HAL_SWPMI_ErrorCallback() function is executed and user can
77 add his own code by customization of function pointer HAL_SWPMI_ErrorCallback()
78 (+) Stop the DMA Transfer using HAL_SWPMI_DMAStop()
79
80 *** SWPMI HAL driver additional function list ***
81 ===============================================
82 [..]
83 Below the list the others API available SWPMI HAL driver :
84
85 (+) HAL_SWPMI_EnableLoopback(): Enable the loopback mode for test purpose only
86 (+) HAL_SWPMI_DisableLoopback(): Disable the loopback mode
87
88 *** SWPMI HAL driver macros list ***
89 ==================================
90 [..]
91 Below the list of most used macros in SWPMI HAL driver :
92
93 (+) __HAL_SWPMI_ENABLE(): Enable the SWPMI peripheral
94 (+) __HAL_SWPMI_DISABLE(): Disable the SWPMI peripheral
95 (+) __HAL_SWPMI_ENABLE_IT(): Enable the specified SWPMI interrupts
96 (+) __HAL_SWPMI_DISABLE_IT(): Disable the specified SWPMI interrupts
97 (+) __HAL_SWPMI_GET_IT_SOURCE(): Check if the specified SWPMI interrupt source is
98 enabled or disabled
99 (+) __HAL_SWPMI_GET_FLAG(): Check whether the specified SWPMI flag is set or not
100
101 *** Callback registration ***
102 =============================
103 [..]
104 The compilation define USE_HAL_SWPMI_REGISTER_CALLBACKS when set to 1
105 allows the user to configure dynamically the driver callbacks.
106 [..]
107 Use function HAL_SWPMI_RegisterCallback() to register a user callback. It allows
108 to register the following callbacks:
109 (+) RxCpltCallback : SWPMI receive complete.
110 (+) RxHalfCpltCallback : SWPMI receive half complete.
111 (+) TxCpltCallback : SWPMI transmit complete.
112 (+) TxHalfCpltCallback : SWPMI transmit half complete.
113 (+) ErrorCallback : SWPMI error.
114 (+) MspInitCallback : SWPMI MspInit.
115 (+) MspDeInitCallback : SWPMI MspDeInit.
116 [..]
117 This function takes as parameters the HAL peripheral handle, the callback ID
118 and a pointer to the user callback function.
119 [..]
120 Use function HAL_SWPMI_UnRegisterCallback() to reset a callback to the default
121 weak (surcharged) function.
122 HAL_SWPMI_UnRegisterCallback() takes as parameters the HAL peripheral handle,
123 and the callback ID.
124 This function allows to reset following callbacks:
125 (+) RxCpltCallback : SWPMI receive complete.
126 (+) RxHalfCpltCallback : SWPMI receive half complete.
127 (+) TxCpltCallback : SWPMI transmit complete.
128 (+) TxHalfCpltCallback : SWPMI transmit half complete.
129 (+) ErrorCallback : SWPMI error.
130 (+) MspInitCallback : SWPMI MspInit.
131 (+) MspDeInitCallback : SWPMI MspDeInit.
132 [..]
133 By default, after the HAL_SWPMI_Init and if the state is HAL_SWPMI_STATE_RESET
134 all callbacks are reset to the corresponding legacy weak (surcharged) functions:
135 examples HAL_SWPMI_RxCpltCallback(), HAL_SWPMI_ErrorCallback().
136 Exception done for MspInit and MspDeInit callbacks that are respectively
137 reset to the legacy weak (surcharged) functions in the HAL_SWPMI_Init
138 and HAL_SWPMI_DeInit only when these callbacks are null (not registered beforehand).
139 If not, MspInit or MspDeInit are not null, the HAL_SWPMI_Init and HAL_SWPMI_DeInit
140 keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
141 [..]
142 Callbacks can be registered/unregistered in READY state only.
143 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
144 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
145 during the Init/DeInit.
146 In that case first register the MspInit/MspDeInit user callbacks
147 using HAL_SWPMI_RegisterCallback before calling @ref HAL_SWPMI_DeInit
148 or HAL_SWPMI_Init function.
149 [..]
150 When the compilation define USE_HAL_SWPMI_REGISTER_CALLBACKS is set to 0 or
151 not defined, the callback registering feature is not available
152 and weak (surcharged) callbacks are used.
153
154 @endverbatim
155 ******************************************************************************
156 * @attention
157 *
158 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
159 *
160 * Redistribution and use in source and binary forms, with or without modification,
161 * are permitted provided that the following conditions are met:
162 * 1. Redistributions of source code must retain the above copyright notice,
163 * this list of conditions and the following disclaimer.
164 * 2. Redistributions in binary form must reproduce the above copyright notice,
165 * this list of conditions and the following disclaimer in the documentation
166 * and/or other materials provided with the distribution.
167 * 3. Neither the name of STMicroelectronics nor the names of its contributors
168 * may be used to endorse or promote products derived from this software
169 * without specific prior written permission.
170 *
171 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
172 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
173 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
174 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
175 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
176 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
177 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
178 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
179 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
180 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
181 *
182 ******************************************************************************
183 */
184
185 /* Includes ------------------------------------------------------------------*/
186 #include "stm32l4xx_hal.h"
187
188 /** @addtogroup STM32L4xx_HAL_Driver
189 * @{
190 */
191
192 #if defined(SWPMI1)
193
194 /** @defgroup SWPMI SWPMI
195 * @brief HAL SWPMI module driver
196 * @{
197 */
198 #ifdef HAL_SWPMI_MODULE_ENABLED
199
200 /* Private typedef -----------------------------------------------------------*/
201 /* Private define ------------------------------------------------------------*/
202 /* Private constants ---------------------------------------------------------*/
203 /** @addtogroup SWPMI_Private_Constants SWPMI Private Constants
204 * @{
205 */
206 #define SWPMI_TIMEOUT_VALUE 22000U /* End of transmission timeout */
207
208 /**
209 * @}
210 */
211
212 /* Private macros ------------------------------------------------------------*/
213 /* Private variables ---------------------------------------------------------*/
214 /* Private function prototypes -----------------------------------------------*/
215 static void SWPMI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
216 static void SWPMI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
217 static void SWPMI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
218 static void SWPMI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
219 static void SWPMI_DMAError(DMA_HandleTypeDef *hdma);
220 static void SWPMI_DMAAbortOnError(DMA_HandleTypeDef *hdma);
221 static void SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi);
222 static void SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef *hswpmi);
223 static void SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi);
224 static void SWPMI_EndReceive_IT(SWPMI_HandleTypeDef *hswpmi);
225 static void SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef *hswpmi);
226 static HAL_StatusTypeDef SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef *hswpmi, uint32_t Flag, uint32_t Tickstart, uint32_t Timeout);
227
228 /* Exported functions --------------------------------------------------------*/
229
230 /** @defgroup SWPMI_Exported_Functions SWPMI Exported Functions
231 * @{
232 */
233
234 /** @defgroup SWPMI_Exported_Group1 Initialization/de-initialization methods
235 * @brief Initialization and Configuration functions
236 *
237 @verbatim
238 ===============================================================================
239 ##### Initialization and Configuration functions #####
240 ===============================================================================
241 [..] This section provides functions allowing to:
242 (+) Initialize and configure the SWPMI peripheral.
243 (+) De-initialize the SWPMI peripheral.
244
245 @endverbatim
246 * @{
247 */
248
249 /**
250 * @brief Initialize the SWPMI peripheral according to the specified parameters in the SWPMI_InitTypeDef.
251 * @param hswpmi SWPMI handle
252 * @retval HAL status
253 */
HAL_SWPMI_Init(SWPMI_HandleTypeDef * hswpmi)254 HAL_StatusTypeDef HAL_SWPMI_Init(SWPMI_HandleTypeDef *hswpmi)
255 {
256 HAL_StatusTypeDef status = HAL_OK;
257 __IO uint32_t wait_loop_index = 0U;
258
259 /* Check the SWPMI handle allocation */
260 if(hswpmi == NULL)
261 {
262 status = HAL_ERROR;
263 }
264 else
265 {
266 /* Check the parameters */
267 assert_param(IS_SWPMI_VOLTAGE_CLASS(hswpmi->Init.VoltageClass));
268 assert_param(IS_SWPMI_BITRATE_VALUE(hswpmi->Init.BitRate));
269 assert_param(IS_SWPMI_TX_BUFFERING_MODE(hswpmi->Init.TxBufferingMode));
270 assert_param(IS_SWPMI_RX_BUFFERING_MODE(hswpmi->Init.RxBufferingMode));
271
272 if(hswpmi->State == HAL_SWPMI_STATE_RESET)
273 {
274 /* Allocate lock resource and initialize it */
275 hswpmi->Lock = HAL_UNLOCKED;
276
277 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
278 /* Reset callback pointers to the weak predefined callbacks */
279 hswpmi->RxCpltCallback = HAL_SWPMI_RxCpltCallback;
280 hswpmi->RxHalfCpltCallback = HAL_SWPMI_RxHalfCpltCallback;
281 hswpmi->TxCpltCallback = HAL_SWPMI_TxCpltCallback;
282 hswpmi->TxHalfCpltCallback = HAL_SWPMI_TxHalfCpltCallback;
283 hswpmi->ErrorCallback = HAL_SWPMI_ErrorCallback;
284
285 /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
286 if(hswpmi->MspInitCallback == NULL)
287 {
288 hswpmi->MspInitCallback = HAL_SWPMI_MspInit;
289 }
290 hswpmi->MspInitCallback(hswpmi);
291 #else
292 /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
293 HAL_SWPMI_MspInit(hswpmi);
294 #endif
295 }
296
297 hswpmi->State = HAL_SWPMI_STATE_BUSY;
298
299 /* Disable SWPMI interface */
300 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
301
302 /* Clear all SWPMI interface flags */
303 WRITE_REG(hswpmi->Instance->ICR, 0x019F);
304
305 /* Apply Voltage class selection */
306 MODIFY_REG(hswpmi->Instance->OR, SWPMI_OR_CLASS, hswpmi->Init.VoltageClass);
307
308 /* If Voltage class B, apply 300 �s delay */
309 if(hswpmi->Init.VoltageClass == SWPMI_VOLTAGE_CLASS_B)
310 {
311 /* Insure 300 �s wait to insure SWPMI_IO output not higher than 1.8V */
312 /* Wait loop initialization and execution */
313 /* Note: Variable divided by 4 to compensate partially CPU processing cycles. */
314 wait_loop_index = (300U * (SystemCoreClock / (1000000U * 4U))) + 150U;
315 while(wait_loop_index != 0U)
316 {
317 wait_loop_index--;
318 }
319 }
320
321 /* Configure the BRR register (Bitrate) */
322 WRITE_REG(hswpmi->Instance->BRR, hswpmi->Init.BitRate);
323
324 /* Apply SWPMI CR configuration */
325 MODIFY_REG(hswpmi->Instance->CR, \
326 SWPMI_CR_RXDMA | SWPMI_CR_TXDMA | SWPMI_CR_RXMODE | SWPMI_CR_TXMODE, \
327 hswpmi->Init.TxBufferingMode | hswpmi->Init.RxBufferingMode);
328
329 hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
330 hswpmi->State = HAL_SWPMI_STATE_READY;
331
332 /* Enable SWPMI peripheral */
333 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
334 }
335
336 return status;
337 }
338
339 /**
340 * @brief De-initialize the SWPMI peripheral.
341 * @param hswpmi SWPMI handle
342 * @retval HAL status
343 */
HAL_SWPMI_DeInit(SWPMI_HandleTypeDef * hswpmi)344 HAL_StatusTypeDef HAL_SWPMI_DeInit(SWPMI_HandleTypeDef *hswpmi)
345 {
346 HAL_StatusTypeDef status = HAL_OK;
347
348 /* Check the SWPMI handle allocation */
349 if(hswpmi == NULL)
350 {
351 status = HAL_ERROR;
352 }
353 else
354 {
355 /* Check the parameters */
356 assert_param(IS_SWPMI_INSTANCE(hswpmi->Instance));
357
358 hswpmi->State = HAL_SWPMI_STATE_BUSY;
359
360 /* Disable SWPMI interface */
361 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
362
363 /* Disable Loopback mode */
364 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);
365
366
367 /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
368 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
369 if(hswpmi->MspDeInitCallback == NULL)
370 {
371 hswpmi->MspDeInitCallback = HAL_SWPMI_MspDeInit;
372 }
373 hswpmi->MspDeInitCallback(hswpmi);
374 #else
375 HAL_SWPMI_MspDeInit(hswpmi);
376 #endif
377
378 hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
379 hswpmi->State = HAL_SWPMI_STATE_RESET;
380
381 /* Release Lock */
382 __HAL_UNLOCK(hswpmi);
383 }
384
385 return status;
386 }
387
388 /**
389 * @brief Initialize the SWPMI MSP.
390 * @param hswpmi SWPMI handle
391 * @retval None
392 */
HAL_SWPMI_MspInit(SWPMI_HandleTypeDef * hswpmi)393 __weak void HAL_SWPMI_MspInit(SWPMI_HandleTypeDef *hswpmi)
394 {
395 /* Prevent unused argument(s) compilation warning */
396 UNUSED(hswpmi);
397
398 /* NOTE : This function should not be modified, when the callback is needed,
399 the HAL_SWPMI_MspInit can be implemented in the user file
400 */
401 }
402
403 /**
404 * @brief DeInitialize the SWPMI MSP.
405 * @param hswpmi SWPMI handle
406 * @retval None
407 */
HAL_SWPMI_MspDeInit(SWPMI_HandleTypeDef * hswpmi)408 __weak void HAL_SWPMI_MspDeInit(SWPMI_HandleTypeDef *hswpmi)
409 {
410 /* Prevent unused argument(s) compilation warning */
411 UNUSED(hswpmi);
412
413 /* NOTE : This function should not be modified, when the callback is needed,
414 the HAL_SWPMI_MspDeInit can be implemented in the user file
415 */
416 }
417
418 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
419 /**
420 * @brief Register a user SWPMI callback
421 * to be used instead of the weak predefined callback.
422 * @param hswpmi SWPMI handle.
423 * @param CallbackID ID of the callback to be registered.
424 * This parameter can be one of the following values:
425 * @arg @ref HAL_SWPMI_RX_COMPLETE_CB_ID receive complete callback ID.
426 * @arg @ref HAL_SWPMI_RX_HALFCOMPLETE_CB_ID receive half complete callback ID.
427 * @arg @ref HAL_SWPMI_TX_COMPLETE_CB_ID transmit complete callback ID.
428 * @arg @ref HAL_SWPMI_TX_HALFCOMPLETE_CB_ID transmit half complete callback ID.
429 * @arg @ref HAL_SWPMI_ERROR_CB_ID error callback ID.
430 * @arg @ref HAL_SWPMI_MSPINIT_CB_ID MSP init callback ID.
431 * @arg @ref HAL_SWPMI_MSPDEINIT_CB_ID MSP de-init callback ID.
432 * @param pCallback pointer to the callback function.
433 * @retval HAL status.
434 */
HAL_SWPMI_RegisterCallback(SWPMI_HandleTypeDef * hswpmi,HAL_SWPMI_CallbackIDTypeDef CallbackID,pSWPMI_CallbackTypeDef pCallback)435 HAL_StatusTypeDef HAL_SWPMI_RegisterCallback(SWPMI_HandleTypeDef *hswpmi,
436 HAL_SWPMI_CallbackIDTypeDef CallbackID,
437 pSWPMI_CallbackTypeDef pCallback)
438 {
439 HAL_StatusTypeDef status = HAL_OK;
440
441 if(pCallback == NULL)
442 {
443 /* update the error code */
444 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
445 /* update return status */
446 status = HAL_ERROR;
447 }
448 else
449 {
450 if(hswpmi->State == HAL_SWPMI_STATE_READY)
451 {
452 switch (CallbackID)
453 {
454 case HAL_SWPMI_RX_COMPLETE_CB_ID :
455 hswpmi->RxCpltCallback = pCallback;
456 break;
457 case HAL_SWPMI_RX_HALFCOMPLETE_CB_ID :
458 hswpmi->RxHalfCpltCallback = pCallback;
459 break;
460 case HAL_SWPMI_TX_COMPLETE_CB_ID :
461 hswpmi->TxCpltCallback = pCallback;
462 break;
463 case HAL_SWPMI_TX_HALFCOMPLETE_CB_ID :
464 hswpmi->TxHalfCpltCallback = pCallback;
465 break;
466 case HAL_SWPMI_ERROR_CB_ID :
467 hswpmi->ErrorCallback = pCallback;
468 break;
469 case HAL_SWPMI_MSPINIT_CB_ID :
470 hswpmi->MspInitCallback = pCallback;
471 break;
472 case HAL_SWPMI_MSPDEINIT_CB_ID :
473 hswpmi->MspDeInitCallback = pCallback;
474 break;
475 default :
476 /* update the error code */
477 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
478 /* update return status */
479 status = HAL_ERROR;
480 break;
481 }
482 }
483 else if(hswpmi->State == HAL_SWPMI_STATE_RESET)
484 {
485 switch (CallbackID)
486 {
487 case HAL_SWPMI_MSPINIT_CB_ID :
488 hswpmi->MspInitCallback = pCallback;
489 break;
490 case HAL_SWPMI_MSPDEINIT_CB_ID :
491 hswpmi->MspDeInitCallback = pCallback;
492 break;
493 default :
494 /* update the error code */
495 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
496 /* update return status */
497 status = HAL_ERROR;
498 break;
499 }
500 }
501 else
502 {
503 /* update the error code */
504 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
505 /* update return status */
506 status = HAL_ERROR;
507 }
508 }
509 return status;
510 }
511
512 /**
513 * @brief Unregister a user SWPMI callback.
514 * SWPMI callback is redirected to the weak predefined callback.
515 * @param hswpmi SWPMI handle.
516 * @param CallbackID ID of the callback to be unregistered.
517 * This parameter can be one of the following values:
518 * @arg @ref HAL_SWPMI_RX_COMPLETE_CB_ID receive complete callback ID.
519 * @arg @ref HAL_SWPMI_RX_HALFCOMPLETE_CB_ID receive half complete callback ID.
520 * @arg @ref HAL_SWPMI_TX_COMPLETE_CB_ID transmit complete callback ID.
521 * @arg @ref HAL_SWPMI_TX_HALFCOMPLETE_CB_ID transmit half complete callback ID.
522 * @arg @ref HAL_SWPMI_ERROR_CB_ID error callback ID.
523 * @arg @ref HAL_SWPMI_MSPINIT_CB_ID MSP init callback ID.
524 * @arg @ref HAL_SWPMI_MSPDEINIT_CB_ID MSP de-init callback ID.
525 * @retval HAL status.
526 */
HAL_SWPMI_UnRegisterCallback(SWPMI_HandleTypeDef * hswpmi,HAL_SWPMI_CallbackIDTypeDef CallbackID)527 HAL_StatusTypeDef HAL_SWPMI_UnRegisterCallback(SWPMI_HandleTypeDef *hswpmi,
528 HAL_SWPMI_CallbackIDTypeDef CallbackID)
529 {
530 HAL_StatusTypeDef status = HAL_OK;
531
532 if(hswpmi->State == HAL_SWPMI_STATE_READY)
533 {
534 switch (CallbackID)
535 {
536 case HAL_SWPMI_RX_COMPLETE_CB_ID :
537 hswpmi->RxCpltCallback = HAL_SWPMI_RxCpltCallback;
538 break;
539 case HAL_SWPMI_RX_HALFCOMPLETE_CB_ID :
540 hswpmi->RxHalfCpltCallback = HAL_SWPMI_RxHalfCpltCallback;
541 break;
542 case HAL_SWPMI_TX_COMPLETE_CB_ID :
543 hswpmi->TxCpltCallback = HAL_SWPMI_TxCpltCallback;
544 break;
545 case HAL_SWPMI_TX_HALFCOMPLETE_CB_ID :
546 hswpmi->TxHalfCpltCallback = HAL_SWPMI_TxHalfCpltCallback;
547 break;
548 case HAL_SWPMI_ERROR_CB_ID :
549 hswpmi->ErrorCallback = HAL_SWPMI_ErrorCallback;
550 break;
551 case HAL_SWPMI_MSPINIT_CB_ID :
552 hswpmi->MspInitCallback = HAL_SWPMI_MspInit;
553 break;
554 case HAL_SWPMI_MSPDEINIT_CB_ID :
555 hswpmi->MspDeInitCallback = HAL_SWPMI_MspDeInit;
556 break;
557 default :
558 /* update the error code */
559 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
560 /* update return status */
561 status = HAL_ERROR;
562 break;
563 }
564 }
565 else if(hswpmi->State == HAL_SWPMI_STATE_RESET)
566 {
567 switch (CallbackID)
568 {
569 case HAL_SWPMI_MSPINIT_CB_ID :
570 hswpmi->MspInitCallback = HAL_SWPMI_MspInit;
571 break;
572 case HAL_SWPMI_MSPDEINIT_CB_ID :
573 hswpmi->MspDeInitCallback = HAL_SWPMI_MspDeInit;
574 break;
575 default :
576 /* update the error code */
577 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
578 /* update return status */
579 status = HAL_ERROR;
580 break;
581 }
582 }
583 else
584 {
585 /* update the error code */
586 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
587 /* update return status */
588 status = HAL_ERROR;
589 }
590 return status;
591 }
592 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
593
594 /**
595 * @}
596 */
597
598 /** @defgroup SWPMI_Exported_Group2 IO operation methods
599 * @brief SWPMI Transmit/Receive functions
600 *
601 @verbatim
602 ===============================================================================
603 ##### IO operation methods #####
604 ===============================================================================
605 [..]
606 This subsection provides a set of functions allowing to manage the SWPMI
607 data transfers.
608
609 (#) There are two modes of transfer:
610 (++) Blocking mode: The communication is performed in polling mode.
611 The HAL status of all data processing is returned by the same function
612 after finishing transfer.
613 (++) Non-Blocking mode: The communication is performed using Interrupts
614 or DMA. The end of the data processing will be indicated through the
615 dedicated SWPMI Interrupt handler (HAL_SWPMI_IRQHandler()) when using Interrupt mode or
616 the selected DMA channel interrupt handler when using DMA mode.
617 The HAL_SWPMI_TxCpltCallback(), HAL_SWPMI_RxCpltCallback() user callbacks
618 will be executed respectively at the end of the transmit or receive process.
619 The HAL_SWPMI_ErrorCallback() user callback will be executed when a communication error is detected.
620
621 (#) Blocking mode API's are:
622 (++) HAL_SWPMI_Transmit()
623 (++) HAL_SWPMI_Receive()
624
625 (#) Non-Blocking mode API's with Interrupt are:
626 (++) HAL_SWPMI_Transmit_IT()
627 (++) HAL_SWPMI_Receive_IT()
628 (++) HAL_SWPMI_IRQHandler()
629
630 (#) Non-Blocking mode API's with DMA are:
631 (++) HAL_SWPMI_Transmit_DMA()
632 (++) HAL_SWPMI_Receive_DMA()
633 (++) HAL_SWPMI_DMAPause()
634 (++) HAL_SWPMI_DMAResume()
635 (++) HAL_SWPMI_DMAStop()
636
637 (#) A set of Transfer Complete Callbacks are provided in Non-Blocking mode:
638 (++) HAL_SWPMI_TxHalfCpltCallback()
639 (++) HAL_SWPMI_TxCpltCallback()
640 (++) HAL_SWPMI_RxHalfCpltCallback()
641 (++) HAL_SWPMI_RxCpltCallback()
642 (++) HAL_SWPMI_ErrorCallback()
643
644 (#) The capability to launch the above IO operations in loopback mode for
645 user application verification:
646 (++) HAL_SWPMI_EnableLoopback()
647 (++) HAL_SWPMI_DisableLoopback()
648
649 @endverbatim
650 * @{
651 */
652
653 /**
654 * @brief Transmit an amount of data in blocking mode.
655 * @param hswpmi pointer to a SWPMI_HandleTypeDef structure that contains
656 * the configuration information for SWPMI module.
657 * @param pData Pointer to data buffer
658 * @param Size Amount of data to be sent
659 * @param Timeout Timeout duration
660 * @retval HAL status
661 */
HAL_SWPMI_Transmit(SWPMI_HandleTypeDef * hswpmi,uint32_t * pData,uint16_t Size,uint32_t Timeout)662 HAL_StatusTypeDef HAL_SWPMI_Transmit(SWPMI_HandleTypeDef *hswpmi, uint32_t* pData, uint16_t Size, uint32_t Timeout)
663 {
664 uint32_t tickstart = HAL_GetTick();
665 HAL_StatusTypeDef status = HAL_OK;
666 HAL_SWPMI_StateTypeDef tmp_state;
667 uint32_t *ptmp_data;
668 uint32_t tmp_size;
669
670 if((pData == NULL ) || (Size == 0U))
671 {
672 status = HAL_ERROR;
673 }
674 else
675 {
676 /* Process Locked */
677 __HAL_LOCK(hswpmi);
678
679 tmp_state = hswpmi->State;
680 if((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_RX))
681 {
682 /* Check if a non-blocking receive process is ongoing or not */
683 if(tmp_state == HAL_SWPMI_STATE_READY)
684 {
685 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
686
687 /* Disable any transmitter interrupts */
688 __HAL_SWPMI_DISABLE_IT(hswpmi, SWPMI_IT_TCIE | SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE);
689
690 /* Disable any transmitter flags */
691 __HAL_SWPMI_CLEAR_FLAG(hswpmi, SWPMI_FLAG_TXBEF | SWPMI_FLAG_TXUNRF | SWPMI_FLAG_TCF);
692
693 /* Enable SWPMI peripheral if not */
694 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
695 }
696 else
697 {
698 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
699 }
700
701 ptmp_data = pData;
702 tmp_size = Size;
703 do
704 {
705 /* Wait the TXE to write data */
706 if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_TXE))
707 {
708 hswpmi->Instance->TDR = *ptmp_data;
709 ptmp_data++;
710 tmp_size--;
711 }
712 else
713 {
714 /* Check for the Timeout */
715 if(Timeout != HAL_MAX_DELAY)
716 {
717 if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
718 {
719 status = HAL_TIMEOUT;
720 break;
721 }
722 }
723 }
724 } while(tmp_size != 0U);
725
726 /* Wait on TXBEF flag to be able to start a second transfer */
727 if(SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, tickstart, Timeout) != HAL_OK)
728 {
729 /* Timeout occurred */
730 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_TXBEF_TIMEOUT;
731
732 status = HAL_TIMEOUT;
733 }
734
735 if(status == HAL_OK)
736 {
737 /* Check if a non-blocking receive Process is ongoing or not */
738 if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
739 {
740 hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
741 }
742 else
743 {
744 hswpmi->State = HAL_SWPMI_STATE_READY;
745 }
746 }
747 }
748 else
749 {
750 status = HAL_BUSY;
751 }
752 }
753
754 if((status != HAL_OK) && (status != HAL_BUSY))
755 {
756 hswpmi->State = HAL_SWPMI_STATE_READY;
757 }
758 /* Process Unlocked */
759 __HAL_UNLOCK(hswpmi);
760
761 return status;
762 }
763
764 /**
765 * @brief Receive an amount of data in blocking mode.
766 * @param hswpmi pointer to a SWPMI_HandleTypeDef structure that contains
767 * the configuration information for SWPMI module.
768 * @param pData Pointer to data buffer
769 * @param Size Amount of data to be received
770 * @param Timeout Timeout duration
771 * @retval HAL status
772 */
HAL_SWPMI_Receive(SWPMI_HandleTypeDef * hswpmi,uint32_t * pData,uint16_t Size,uint32_t Timeout)773 HAL_StatusTypeDef HAL_SWPMI_Receive(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size, uint32_t Timeout)
774 {
775 uint32_t tickstart = HAL_GetTick();
776 HAL_StatusTypeDef status = HAL_OK;
777 HAL_SWPMI_StateTypeDef tmp_state;
778 uint32_t *ptmp_data;
779 uint32_t tmp_size;
780
781 if((pData == NULL ) || (Size == 0U))
782 {
783 status = HAL_ERROR;
784 }
785 else
786 {
787 /* Process Locked */
788 __HAL_LOCK(hswpmi);
789
790 tmp_state = hswpmi->State;
791 if((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX))
792 {
793 /* Check if a non-blocking transmit process is ongoing or not */
794 if(tmp_state == HAL_SWPMI_STATE_READY)
795 {
796 hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
797
798 /* Disable any receiver interrupts */
799 CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_SRIE | SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
800
801 /* Enable SWPMI peripheral if not */
802 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
803 }
804 else
805 {
806 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
807 }
808
809 ptmp_data = pData;
810 tmp_size = Size;
811 do
812 {
813 /* Wait the RXNE to read data */
814 if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXNE))
815 {
816 *ptmp_data = hswpmi->Instance->RDR;
817 ptmp_data++;
818 tmp_size--;
819 }
820 else
821 {
822 /* Check for the Timeout */
823 if(Timeout != HAL_MAX_DELAY)
824 {
825 if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
826 {
827 status = HAL_TIMEOUT;
828 break;
829 }
830 }
831 }
832 } while(tmp_size != 0U);
833
834 if(status == HAL_OK)
835 {
836 if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXBFF))
837 {
838 /* Clear RXBFF at end of reception */
839 WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF);
840 }
841
842 /* Check if a non-blocking transmit Process is ongoing or not */
843 if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
844 {
845 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
846 }
847 else
848 {
849 hswpmi->State = HAL_SWPMI_STATE_READY;
850 }
851 }
852 }
853 else
854 {
855 status = HAL_BUSY;
856 }
857 }
858
859 if((status != HAL_OK) && (status != HAL_BUSY))
860 {
861 hswpmi->State = HAL_SWPMI_STATE_READY;
862 }
863 /* Process Unlocked */
864 __HAL_UNLOCK(hswpmi);
865
866 return status;
867 }
868
869 /**
870 * @brief Transmit an amount of data in non-blocking mode with interrupt.
871 * @param hswpmi pointer to a SWPMI_HandleTypeDef structure that contains
872 * the configuration information for SWPMI module.
873 * @param pData Pointer to data buffer
874 * @param Size Amount of data to be sent
875 * @retval HAL status
876 */
HAL_SWPMI_Transmit_IT(SWPMI_HandleTypeDef * hswpmi,uint32_t * pData,uint16_t Size)877 HAL_StatusTypeDef HAL_SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
878 {
879 HAL_StatusTypeDef status = HAL_OK;
880 HAL_SWPMI_StateTypeDef tmp_state;
881
882 if((pData == NULL ) || (Size == 0U))
883 {
884 status = HAL_ERROR;
885 }
886 else
887 {
888 /* Process Locked */
889 __HAL_LOCK(hswpmi);
890
891 tmp_state = hswpmi->State;
892 if((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_RX))
893 {
894 /* Update handle */
895 hswpmi->pTxBuffPtr = pData;
896 hswpmi->TxXferSize = Size;
897 hswpmi->TxXferCount = Size;
898 hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
899
900 /* Check if a receive process is ongoing or not */
901 if(tmp_state == HAL_SWPMI_STATE_READY)
902 {
903 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
904
905 /* Enable SWPMI peripheral if not */
906 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
907 }
908 else
909 {
910 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
911 }
912
913 /* Enable the SWPMI transmit underrun error */
914 __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TXUNRIE);
915
916 /* Process Unlocked */
917 __HAL_UNLOCK(hswpmi);
918
919 /* Enable the SWPMI interrupts: */
920 /* - Transmit data register empty */
921 /* - Transmit buffer empty */
922 /* - Transmit/Reception completion */
923 __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TIE | SWPMI_IT_TXBEIE | SWPMI_IT_TCIE);
924 }
925 else
926 {
927 status = HAL_BUSY;
928
929 /* Process Unlocked */
930 __HAL_UNLOCK(hswpmi);
931 }
932 }
933
934 return status;
935 }
936
937 /**
938 * @brief Receive an amount of data in non-blocking mode with interrupt.
939 * @param hswpmi SWPMI handle
940 * @param pData Pointer to data buffer
941 * @param Size Amount of data to be received
942 * @retval HAL status
943 */
HAL_SWPMI_Receive_IT(SWPMI_HandleTypeDef * hswpmi,uint32_t * pData,uint16_t Size)944 HAL_StatusTypeDef HAL_SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
945 {
946 HAL_StatusTypeDef status = HAL_OK;
947 HAL_SWPMI_StateTypeDef tmp_state;
948
949 if((pData == NULL ) || (Size == 0U))
950 {
951 status = HAL_ERROR;
952 }
953 else
954 {
955 /* Process Locked */
956 __HAL_LOCK(hswpmi);
957
958 tmp_state = hswpmi->State;
959 if((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX))
960 {
961 /* Update handle */
962 hswpmi->pRxBuffPtr = pData;
963 hswpmi->RxXferSize = Size;
964 hswpmi->RxXferCount = Size;
965 hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
966
967 /* Check if a transmit process is ongoing or not */
968 if(tmp_state == HAL_SWPMI_STATE_READY)
969 {
970 hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
971
972 /* Enable SWPMI peripheral if not */
973 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
974 }
975 else
976 {
977 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
978 }
979
980 /* Process Unlocked */
981 __HAL_UNLOCK(hswpmi);
982
983 /* Enable the SWPMI slave resume */
984 /* Enable the SWPMI Data Register not empty Interrupt, receive CRC Error, receive overrun and RxBuf Interrupt */
985 /* Enable the SWPMI Transmit/Reception completion */
986 __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
987 }
988 else
989 {
990 status = HAL_BUSY;
991
992 /* Process Unlocked */
993 __HAL_UNLOCK(hswpmi);
994 }
995 }
996
997 return status;
998 }
999
1000 /**
1001 * @brief Transmit an amount of data in non-blocking mode with DMA interrupt.
1002 * @param hswpmi SWPMI handle
1003 * @param pData Pointer to data buffer
1004 * @param Size Amount of data to be sent
1005 * @retval HAL status
1006 */
HAL_SWPMI_Transmit_DMA(SWPMI_HandleTypeDef * hswpmi,uint32_t * pData,uint16_t Size)1007 HAL_StatusTypeDef HAL_SWPMI_Transmit_DMA(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
1008 {
1009 HAL_StatusTypeDef status = HAL_OK;
1010 HAL_SWPMI_StateTypeDef tmp_state;
1011
1012 if((pData == NULL ) || (Size == 0U))
1013 {
1014 status = HAL_ERROR;
1015 }
1016 else
1017 {
1018 /* Process Locked */
1019 __HAL_LOCK(hswpmi);
1020
1021 tmp_state = hswpmi->State;
1022 if((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_RX))
1023 {
1024 /* Update handle */
1025 hswpmi->pTxBuffPtr = pData;
1026 hswpmi->TxXferSize = Size;
1027 hswpmi->TxXferCount = Size;
1028 hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
1029
1030 /* Check if a receive process is ongoing or not */
1031 if(tmp_state == HAL_SWPMI_STATE_READY)
1032 {
1033 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
1034
1035 /* Enable SWPMI peripheral if not */
1036 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1037 }
1038 else
1039 {
1040 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
1041 }
1042
1043 /* Set the SWPMI DMA transfer complete callback */
1044 hswpmi->hdmatx->XferCpltCallback = SWPMI_DMATransmitCplt;
1045
1046 /* Set the SWPMI DMA Half transfer complete callback */
1047 hswpmi->hdmatx->XferHalfCpltCallback = SWPMI_DMATxHalfCplt;
1048
1049 /* Set the DMA error callback */
1050 hswpmi->hdmatx->XferErrorCallback = SWPMI_DMAError;
1051
1052 /* Enable the SWPMI transmit DMA channel */
1053 if(HAL_DMA_Start_IT(hswpmi->hdmatx, (uint32_t)hswpmi->pTxBuffPtr, (uint32_t)&hswpmi->Instance->TDR, Size) != HAL_OK)
1054 {
1055 hswpmi->State = tmp_state; /* Back to previous state */
1056 hswpmi->ErrorCode = HAL_SWPMI_ERROR_DMA;
1057 status = HAL_ERROR;
1058
1059 /* Process Unlocked */
1060 __HAL_UNLOCK(hswpmi);
1061 }
1062 else
1063 {
1064 /* Process Unlocked */
1065 __HAL_UNLOCK(hswpmi);
1066
1067 /* Enable the SWPMI transmit underrun error */
1068 __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TXUNRIE);
1069
1070 /* Enable the DMA transfer for transmit request by setting the TXDMA bit
1071 in the SWPMI CR register */
1072 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);
1073 }
1074 }
1075 else
1076 {
1077 status = HAL_BUSY;
1078
1079 /* Process Unlocked */
1080 __HAL_UNLOCK(hswpmi);
1081 }
1082 }
1083
1084 return status;
1085 }
1086
1087 /**
1088 * @brief Receive an amount of data in non-blocking mode with DMA interrupt.
1089 * @param hswpmi SWPMI handle
1090 * @param pData Pointer to data buffer
1091 * @param Size Amount of data to be received
1092 * @retval HAL status
1093 */
HAL_SWPMI_Receive_DMA(SWPMI_HandleTypeDef * hswpmi,uint32_t * pData,uint16_t Size)1094 HAL_StatusTypeDef HAL_SWPMI_Receive_DMA(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
1095 {
1096 HAL_StatusTypeDef status = HAL_OK;
1097 HAL_SWPMI_StateTypeDef tmp_state;
1098
1099 if((pData == NULL ) || (Size == 0U))
1100 {
1101 status = HAL_ERROR;
1102 }
1103 else
1104 {
1105 /* Process Locked */
1106 __HAL_LOCK(hswpmi);
1107
1108 tmp_state = hswpmi->State;
1109 if((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX))
1110 {
1111 /* Update handle */
1112 hswpmi->pRxBuffPtr = pData;
1113 hswpmi->RxXferSize = Size;
1114 hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
1115
1116 /* Check if a transmit process is ongoing or not */
1117 if(tmp_state == HAL_SWPMI_STATE_READY)
1118 {
1119 hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
1120
1121 /* Enable SWPMI peripheral if not */
1122 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1123 }
1124 else
1125 {
1126 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
1127 }
1128
1129 /* Set the SWPMI DMA transfer complete callback */
1130 hswpmi->hdmarx->XferCpltCallback = SWPMI_DMAReceiveCplt;
1131
1132 /* Set the SWPMI DMA Half transfer complete callback */
1133 hswpmi->hdmarx->XferHalfCpltCallback = SWPMI_DMARxHalfCplt;
1134
1135 /* Set the DMA error callback */
1136 hswpmi->hdmarx->XferErrorCallback = SWPMI_DMAError;
1137
1138 /* Enable the DMA request */
1139 if(HAL_DMA_Start_IT(hswpmi->hdmarx, (uint32_t)&hswpmi->Instance->RDR, (uint32_t)hswpmi->pRxBuffPtr, Size) != HAL_OK)
1140 {
1141 hswpmi->State = tmp_state; /* Back to previous state */
1142 hswpmi->ErrorCode = HAL_SWPMI_ERROR_DMA;
1143 status = HAL_ERROR;
1144
1145 /* Process Unlocked */
1146 __HAL_UNLOCK(hswpmi);
1147 }
1148 else
1149 {
1150 /* Process Unlocked */
1151 __HAL_UNLOCK(hswpmi);
1152
1153 /* Enable the SWPMI receive CRC Error and receive overrun interrupts */
1154 __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE);
1155
1156 /* Enable the DMA transfer for the receiver request by setting the RXDMA bit
1157 in the SWPMI CR register */
1158 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);
1159 }
1160 }
1161 else
1162 {
1163 status = HAL_BUSY;
1164
1165 /* Process Unlocked */
1166 __HAL_UNLOCK(hswpmi);
1167 }
1168 }
1169
1170 return status;
1171 }
1172
1173 /**
1174 * @brief Stop all DMA transfers.
1175 * @param hswpmi SWPMI handle
1176 * @retval HAL status
1177 */
HAL_SWPMI_DMAStop(SWPMI_HandleTypeDef * hswpmi)1178 HAL_StatusTypeDef HAL_SWPMI_DMAStop(SWPMI_HandleTypeDef *hswpmi)
1179 {
1180 HAL_StatusTypeDef status = HAL_OK;
1181
1182 /* Process Locked */
1183 __HAL_LOCK(hswpmi);
1184
1185 /* Disable the SWPMI Tx/Rx DMA requests */
1186 CLEAR_BIT(hswpmi->Instance->CR, (SWPMI_CR_TXDMA | SWPMI_CR_RXDMA));
1187
1188 /* Abort the SWPMI DMA tx channel */
1189 if(hswpmi->hdmatx != NULL)
1190 {
1191 if(HAL_DMA_Abort(hswpmi->hdmatx) != HAL_OK)
1192 {
1193 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA;
1194 status = HAL_ERROR;
1195 }
1196 }
1197 /* Abort the SWPMI DMA rx channel */
1198 if(hswpmi->hdmarx != NULL)
1199 {
1200 if(HAL_DMA_Abort(hswpmi->hdmarx) != HAL_OK)
1201 {
1202 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA;
1203 status = HAL_ERROR;
1204 }
1205 }
1206
1207 /* Disable SWPMI interface */
1208 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1209
1210 hswpmi->State = HAL_SWPMI_STATE_READY;
1211
1212 /* Process Unlocked */
1213 __HAL_UNLOCK(hswpmi);
1214
1215 return status;
1216 }
1217
1218
1219 /**
1220 * @brief Enable the Loopback mode.
1221 * @param hswpmi SWPMI handle
1222 * @note Loopback mode is to be used only for test purposes
1223 * @retval HAL_OK / HAL_BUSY
1224 */
HAL_SWPMI_EnableLoopback(SWPMI_HandleTypeDef * hswpmi)1225 HAL_StatusTypeDef HAL_SWPMI_EnableLoopback(SWPMI_HandleTypeDef *hswpmi)
1226 {
1227 HAL_StatusTypeDef status = HAL_OK;
1228
1229 /* Process Locked */
1230 __HAL_LOCK(hswpmi);
1231
1232 /* Make sure the SWPMI interface is not enabled to set the loopback mode */
1233 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1234
1235 /* Set Loopback */
1236 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);
1237
1238 /* Enable SWPMI interface in loopback mode */
1239 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1240
1241 /* Process Unlocked */
1242 __HAL_UNLOCK(hswpmi);
1243
1244 return status;
1245 }
1246
1247 /**
1248 * @brief Disable the Loopback mode.
1249 * @param hswpmi SWPMI handle
1250 * @note Loopback mode is to be used only for test purposes
1251 * @retval HAL_OK / HAL_BUSY
1252 */
HAL_SWPMI_DisableLoopback(SWPMI_HandleTypeDef * hswpmi)1253 HAL_StatusTypeDef HAL_SWPMI_DisableLoopback(SWPMI_HandleTypeDef *hswpmi)
1254 {
1255 HAL_StatusTypeDef status = HAL_OK;
1256
1257 /* Process Locked */
1258 __HAL_LOCK(hswpmi);
1259
1260 /* Make sure the SWPMI interface is not enabled to reset the loopback mode */
1261 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1262
1263 /* Reset Loopback */
1264 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);
1265
1266 /* Re-enable SWPMI interface in normal mode */
1267 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1268
1269 /* Process Unlocked */
1270 __HAL_UNLOCK(hswpmi);
1271
1272 return status;
1273 }
1274
1275 /**
1276 * @}
1277 */
1278
1279 /** @defgroup SWPMI_Exported_Group3 SWPMI IRQ handler and callbacks
1280 * @brief SWPMI IRQ handler.
1281 *
1282 @verbatim
1283 ==============================================================================
1284 ##### SWPMI IRQ handler and callbacks #####
1285 ==============================================================================
1286 [..] This section provides SWPMI IRQ handler and callback functions called within
1287 the IRQ handler.
1288
1289 @endverbatim
1290 * @{
1291 */
1292
1293 /**
1294 * @brief Handle SWPMI interrupt request.
1295 * @param hswpmi SWPMI handle
1296 * @retval None
1297 */
HAL_SWPMI_IRQHandler(SWPMI_HandleTypeDef * hswpmi)1298 void HAL_SWPMI_IRQHandler(SWPMI_HandleTypeDef *hswpmi)
1299 {
1300 uint32_t regisr = READ_REG(hswpmi->Instance->ISR);
1301 uint32_t regier = READ_REG(hswpmi->Instance->IER);
1302 uint32_t errcode = HAL_SWPMI_ERROR_NONE;
1303
1304 /* SWPMI CRC error interrupt occurred --------------------------------------*/
1305 if(((regisr & SWPMI_FLAG_RXBERF) != 0U) && ((regier & SWPMI_IT_RXBERIE) != 0U))
1306 {
1307 /* Disable Receive CRC interrupt */
1308 CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RXBERIE | SWPMI_IT_RXBFIE);
1309 /* Clear Receive CRC and Receive buffer full flag */
1310 WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBERF | SWPMI_FLAG_RXBFF);
1311
1312 errcode |= HAL_SWPMI_ERROR_CRC;
1313 }
1314
1315 /* SWPMI Over-Run interrupt occurred -----------------------------------------*/
1316 if(((regisr & SWPMI_FLAG_RXOVRF) != 0U) && ((regier & SWPMI_IT_RXOVRIE) != 0U))
1317 {
1318 /* Disable Receive overrun interrupt */
1319 CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RXOVRIE);
1320 /* Clear Receive overrun flag */
1321 WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXOVRF);
1322
1323 errcode |= HAL_SWPMI_ERROR_OVR;
1324 }
1325
1326 /* SWPMI Under-Run interrupt occurred -----------------------------------------*/
1327 if(((regisr & SWPMI_FLAG_TXUNRF) != 0U) && ((regier & SWPMI_IT_TXUNRIE) != 0U))
1328 {
1329 /* Disable Transmit under run interrupt */
1330 CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TXUNRIE);
1331 /* Clear Transmit under run flag */
1332 WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TXUNRF);
1333
1334 errcode |= HAL_SWPMI_ERROR_UDR;
1335 }
1336
1337 /* Call SWPMI Error Call back function if needed --------------------------*/
1338 if(errcode != HAL_SWPMI_ERROR_NONE)
1339 {
1340 hswpmi->ErrorCode |= errcode;
1341
1342 if((errcode & HAL_SWPMI_ERROR_UDR) != 0U)
1343 {
1344 /* Check TXDMA transfer to abort */
1345 if(HAL_IS_BIT_SET(hswpmi->Instance->CR, SWPMI_CR_TXDMA))
1346 {
1347 /* Disable DMA TX at SWPMI level */
1348 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);
1349
1350 /* Abort the USART DMA Tx channel */
1351 if(hswpmi->hdmatx != NULL)
1352 {
1353 /* Set the SWPMI Tx DMA Abort callback :
1354 will lead to call HAL_SWPMI_ErrorCallback() at end of DMA abort procedure */
1355 hswpmi->hdmatx->XferAbortCallback = SWPMI_DMAAbortOnError;
1356 /* Abort DMA TX */
1357 if(HAL_DMA_Abort_IT(hswpmi->hdmatx) != HAL_OK)
1358 {
1359 /* Call Directly hswpmi->hdmatx->XferAbortCallback function in case of error */
1360 hswpmi->hdmatx->XferAbortCallback(hswpmi->hdmatx);
1361 }
1362 }
1363 else
1364 {
1365 /* Set the SWPMI state ready to be able to start again the process */
1366 hswpmi->State = HAL_SWPMI_STATE_READY;
1367
1368 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1369 hswpmi->ErrorCallback(hswpmi);
1370 #else
1371 HAL_SWPMI_ErrorCallback(hswpmi);
1372 #endif
1373 }
1374 }
1375 else
1376 {
1377 /* Set the SWPMI state ready to be able to start again the process */
1378 hswpmi->State = HAL_SWPMI_STATE_READY;
1379
1380 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1381 hswpmi->ErrorCallback(hswpmi);
1382 #else
1383 HAL_SWPMI_ErrorCallback(hswpmi);
1384 #endif
1385 }
1386 }
1387 else
1388 {
1389 /* Check RXDMA transfer to abort */
1390 if(HAL_IS_BIT_SET(hswpmi->Instance->CR, SWPMI_CR_RXDMA))
1391 {
1392 /* Disable DMA RX at SWPMI level */
1393 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);
1394
1395 /* Abort the USART DMA Rx channel */
1396 if(hswpmi->hdmarx != NULL)
1397 {
1398 /* Set the SWPMI Rx DMA Abort callback :
1399 will lead to call HAL_SWPMI_ErrorCallback() at end of DMA abort procedure */
1400 hswpmi->hdmarx->XferAbortCallback = SWPMI_DMAAbortOnError;
1401 /* Abort DMA RX */
1402 if(HAL_DMA_Abort_IT(hswpmi->hdmarx) != HAL_OK)
1403 {
1404 /* Call Directly hswpmi->hdmarx->XferAbortCallback function in case of error */
1405 hswpmi->hdmarx->XferAbortCallback(hswpmi->hdmarx);
1406 }
1407 }
1408 else
1409 {
1410 /* Set the SWPMI state ready to be able to start again the process */
1411 hswpmi->State = HAL_SWPMI_STATE_READY;
1412
1413 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1414 hswpmi->ErrorCallback(hswpmi);
1415 #else
1416 HAL_SWPMI_ErrorCallback(hswpmi);
1417 #endif
1418 }
1419 }
1420 else
1421 {
1422 /* Set the SWPMI state ready to be able to start again the process */
1423 hswpmi->State = HAL_SWPMI_STATE_READY;
1424
1425 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1426 hswpmi->ErrorCallback(hswpmi);
1427 #else
1428 HAL_SWPMI_ErrorCallback(hswpmi);
1429 #endif
1430 }
1431 }
1432 }
1433
1434 /* SWPMI in mode Receiver ---------------------------------------------------*/
1435 if(((regisr & SWPMI_FLAG_RXNE) != 0U) && ((regier & SWPMI_IT_RIE) != 0U))
1436 {
1437 SWPMI_Receive_IT(hswpmi);
1438 }
1439
1440 /* SWPMI in mode Transmitter ------------------------------------------------*/
1441 if(((regisr & SWPMI_FLAG_TXE) != 0U) && ((regier & SWPMI_IT_TIE) != 0U))
1442 {
1443 SWPMI_Transmit_IT(hswpmi);
1444 }
1445
1446 /* SWPMI in mode Transmitter (Transmit buffer empty) ------------------------*/
1447 if(((regisr & SWPMI_FLAG_TXBEF) != 0U) && ((regier & SWPMI_IT_TXBEIE) != 0U))
1448 {
1449 SWPMI_EndTransmit_IT(hswpmi);
1450 }
1451
1452 /* SWPMI in mode Receiver (Receive buffer full) -----------------------------*/
1453 if(((regisr & SWPMI_FLAG_RXBFF) != 0U) && ((regier & SWPMI_IT_RXBFIE) != 0U))
1454 {
1455 SWPMI_EndReceive_IT(hswpmi);
1456 }
1457
1458 /* Both Transmission and reception complete ---------------------------------*/
1459 if(((regisr & SWPMI_FLAG_TCF) != 0U) && ((regier & SWPMI_IT_TCIE) != 0U))
1460 {
1461 SWPMI_EndTransmitReceive_IT(hswpmi);
1462 }
1463 }
1464
1465 /**
1466 * @brief Tx Transfer completed callback.
1467 * @param hswpmi SWPMI handle
1468 * @retval None
1469 */
HAL_SWPMI_TxCpltCallback(SWPMI_HandleTypeDef * hswpmi)1470 __weak void HAL_SWPMI_TxCpltCallback(SWPMI_HandleTypeDef *hswpmi)
1471 {
1472 /* Prevent unused argument(s) compilation warning */
1473 UNUSED(hswpmi);
1474
1475 /* NOTE : This function should not be modified, when the callback is needed,
1476 the HAL_SWPMI_TxCpltCallback is to be implemented in the user file
1477 */
1478 }
1479
1480 /**
1481 * @brief Tx Half Transfer completed callback.
1482 * @param hswpmi SWPMI handle
1483 * @retval None
1484 */
HAL_SWPMI_TxHalfCpltCallback(SWPMI_HandleTypeDef * hswpmi)1485 __weak void HAL_SWPMI_TxHalfCpltCallback(SWPMI_HandleTypeDef *hswpmi)
1486 {
1487 /* Prevent unused argument(s) compilation warning */
1488 UNUSED(hswpmi);
1489
1490 /* NOTE: This function should not be modified, when the callback is needed,
1491 the HAL_SWPMI_TxHalfCpltCallback is to be implemented in the user file
1492 */
1493 }
1494
1495 /**
1496 * @brief Rx Transfer completed callback.
1497 * @param hswpmi SWPMI handle
1498 * @retval None
1499 */
HAL_SWPMI_RxCpltCallback(SWPMI_HandleTypeDef * hswpmi)1500 __weak void HAL_SWPMI_RxCpltCallback(SWPMI_HandleTypeDef *hswpmi)
1501 {
1502 /* Prevent unused argument(s) compilation warning */
1503 UNUSED(hswpmi);
1504
1505 /* NOTE : This function should not be modified, when the callback is needed,
1506 the HAL_SWPMI_RxCpltCallback is to be implemented in the user file
1507 */
1508 }
1509
1510 /**
1511 * @brief Rx Half Transfer completed callback.
1512 * @param hswpmi SWPMI handle
1513 * @retval None
1514 */
HAL_SWPMI_RxHalfCpltCallback(SWPMI_HandleTypeDef * hswpmi)1515 __weak void HAL_SWPMI_RxHalfCpltCallback(SWPMI_HandleTypeDef *hswpmi)
1516 {
1517 /* Prevent unused argument(s) compilation warning */
1518 UNUSED(hswpmi);
1519
1520 /* NOTE: This function should not be modified, when the callback is needed,
1521 the HAL_SWPMI_RxHalfCpltCallback is to be implemented in the user file
1522 */
1523 }
1524
1525 /**
1526 * @brief SWPMI error callback.
1527 * @param hswpmi SWPMI handle
1528 * @retval None
1529 */
HAL_SWPMI_ErrorCallback(SWPMI_HandleTypeDef * hswpmi)1530 __weak void HAL_SWPMI_ErrorCallback(SWPMI_HandleTypeDef *hswpmi)
1531 {
1532 /* Prevent unused argument(s) compilation warning */
1533 UNUSED(hswpmi);
1534
1535 /* NOTE : This function should not be modified, when the callback is needed,
1536 the HAL_SWPMI_ErrorCallback is to be implemented in the user file
1537 */
1538 }
1539
1540 /**
1541 * @}
1542 */
1543
1544 /** @defgroup SWPMI_Exported_Group4 Peripheral Control methods
1545 * @brief SWPMI control functions
1546 *
1547 @verbatim
1548 ===============================================================================
1549 ##### Peripheral Control methods #####
1550 ===============================================================================
1551 [..]
1552 This subsection provides a set of functions allowing to control the SWPMI.
1553 (+) HAL_SWPMI_GetState() API is helpful to check in run-time the state of the SWPMI peripheral
1554 (+) HAL_SWPMI_GetError() API is helpful to check in run-time the error state of the SWPMI peripheral
1555 @endverbatim
1556 * @{
1557 */
1558
1559 /**
1560 * @brief Return the SWPMI handle state.
1561 * @param hswpmi SWPMI handle
1562 * @retval HAL state
1563 */
HAL_SWPMI_GetState(SWPMI_HandleTypeDef * hswpmi)1564 HAL_SWPMI_StateTypeDef HAL_SWPMI_GetState(SWPMI_HandleTypeDef *hswpmi)
1565 {
1566 /* Return SWPMI handle state */
1567 return hswpmi->State;
1568 }
1569
1570 /**
1571 * @brief Return the SWPMI error code.
1572 * @param hswpmi : pointer to a SWPMI_HandleTypeDef structure that contains
1573 * the configuration information for the specified SWPMI.
1574 * @retval SWPMI Error Code
1575 */
HAL_SWPMI_GetError(SWPMI_HandleTypeDef * hswpmi)1576 uint32_t HAL_SWPMI_GetError(SWPMI_HandleTypeDef *hswpmi)
1577 {
1578 return hswpmi->ErrorCode;
1579 }
1580
1581 /**
1582 * @}
1583 */
1584
1585 /**
1586 * @}
1587 */
1588
1589 /* Private functions ---------------------------------------------------------*/
1590
1591 /** @defgroup SWPMI_Private_Functions SWPMI Private Functions
1592 * @{
1593 */
1594
1595 /**
1596 * @brief Transmit an amount of data in interrupt mode.
1597 * @note Function called under interruption only, once interruptions have been enabled by HAL_SWPMI_Transmit_IT()
1598 * @param hswpmi SWPMI handle
1599 * @retval None
1600 */
SWPMI_Transmit_IT(SWPMI_HandleTypeDef * hswpmi)1601 static void SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi)
1602 {
1603 HAL_SWPMI_StateTypeDef tmp_state = hswpmi->State;
1604
1605 if ((tmp_state == HAL_SWPMI_STATE_BUSY_TX) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX_RX))
1606 {
1607 if(hswpmi->TxXferCount == 0U)
1608 {
1609 /* Disable the SWPMI TXE and Underrun Interrupts */
1610 CLEAR_BIT(hswpmi->Instance->IER, (SWPMI_IT_TIE | SWPMI_IT_TXUNRIE));
1611 }
1612 else
1613 {
1614 hswpmi->Instance->TDR = (uint32_t)*hswpmi->pTxBuffPtr;
1615 hswpmi->pTxBuffPtr++;
1616 hswpmi->TxXferCount--;
1617 }
1618 }
1619 else
1620 {
1621 /* nothing to do */
1622 }
1623 }
1624
1625 /**
1626 * @brief Wraps up transmission in non-blocking mode.
1627 * @param hswpmi SWPMI handle
1628 * @retval None
1629 */
SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef * hswpmi)1630 static void SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef *hswpmi)
1631 {
1632 /* Clear the SWPMI Transmit buffer empty Flag */
1633 WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TXBEF);
1634 /* Disable the all SWPMI Transmit Interrupts */
1635 CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE);
1636
1637 /* Check if a receive Process is ongoing or not */
1638 if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
1639 {
1640 hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
1641 }
1642 else
1643 {
1644 hswpmi->State = HAL_SWPMI_STATE_READY;
1645 }
1646
1647 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1648 hswpmi->TxCpltCallback(hswpmi);
1649 #else
1650 HAL_SWPMI_TxCpltCallback(hswpmi);
1651 #endif
1652 }
1653
1654 /**
1655 * @brief Receive an amount of data in interrupt mode.
1656 * @note Function called under interruption only, once interruptions have been enabled by HAL_SWPMI_Receive_IT()
1657 * @param hswpmi SWPMI handle
1658 * @retval None
1659 */
SWPMI_Receive_IT(SWPMI_HandleTypeDef * hswpmi)1660 static void SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi)
1661 {
1662 HAL_SWPMI_StateTypeDef tmp_state = hswpmi->State;
1663
1664 if((tmp_state == HAL_SWPMI_STATE_BUSY_RX) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX_RX))
1665 {
1666 *hswpmi->pRxBuffPtr = (uint32_t)(hswpmi->Instance->RDR);
1667 hswpmi->pRxBuffPtr++;
1668
1669 --hswpmi->RxXferCount;
1670 if(hswpmi->RxXferCount == 0U)
1671 {
1672 /* Wait for RXBFF flag to update state */
1673 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1674 hswpmi->RxCpltCallback(hswpmi);
1675 #else
1676 HAL_SWPMI_RxCpltCallback(hswpmi);
1677 #endif
1678 }
1679 }
1680 else
1681 {
1682 /* nothing to do */
1683 }
1684 }
1685
1686 /**
1687 * @brief Wraps up reception in non-blocking mode.
1688 * @param hswpmi SWPMI handle
1689 * @retval None
1690 */
SWPMI_EndReceive_IT(SWPMI_HandleTypeDef * hswpmi)1691 static void SWPMI_EndReceive_IT(SWPMI_HandleTypeDef *hswpmi)
1692 {
1693 /* Clear the SWPMI Receive buffer full Flag */
1694 WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF);
1695 /* Disable the all SWPMI Receive Interrupts */
1696 CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
1697
1698 /* Check if a transmit Process is ongoing or not */
1699 if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
1700 {
1701 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
1702 }
1703 else
1704 {
1705 hswpmi->State = HAL_SWPMI_STATE_READY;
1706 }
1707 }
1708
1709 /**
1710 * @brief Wraps up transmission and reception in non-blocking mode.
1711 * @param hswpmi SWPMI handle
1712 * @retval None
1713 */
SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef * hswpmi)1714 static void SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef *hswpmi)
1715 {
1716 /* Clear the SWPMI Transmission Complete Flag */
1717 WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TCF);
1718 /* Disable the SWPMI Transmission Complete Interrupt */
1719 CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TCIE);
1720
1721 /* Check if a receive Process is ongoing or not */
1722 if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
1723 {
1724 hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
1725 }
1726 else if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX)
1727 {
1728 hswpmi->State = HAL_SWPMI_STATE_READY;
1729 }
1730 else
1731 {
1732 /* nothing to do */
1733 }
1734 }
1735
1736 /**
1737 * @brief DMA SWPMI transmit process complete callback.
1738 * @param hdma DMA handle
1739 * @retval None
1740 */
SWPMI_DMATransmitCplt(DMA_HandleTypeDef * hdma)1741 static void SWPMI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1742 {
1743 SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1744 uint32_t tickstart;
1745
1746 /* DMA Normal mode*/
1747 if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
1748 {
1749 hswpmi->TxXferCount = 0U;
1750
1751 /* Disable the DMA transfer for transmit request by setting the TXDMA bit
1752 in the SWPMI CR register */
1753 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);
1754
1755 /* Init tickstart for timeout managment*/
1756 tickstart = HAL_GetTick();
1757
1758 /* Wait the TXBEF */
1759 if(SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, tickstart, SWPMI_TIMEOUT_VALUE) != HAL_OK)
1760 {
1761 /* Timeout occurred */
1762 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_TXBEF_TIMEOUT;
1763
1764 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1765 hswpmi->ErrorCallback(hswpmi);
1766 #else
1767 HAL_SWPMI_ErrorCallback(hswpmi);
1768 #endif
1769 }
1770 else
1771 {
1772 /* No Timeout */
1773 /* Check if a receive process is ongoing or not */
1774 if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
1775 {
1776 hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
1777 }
1778 else
1779 {
1780 hswpmi->State = HAL_SWPMI_STATE_READY;
1781 }
1782
1783 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1784 hswpmi->TxCpltCallback(hswpmi);
1785 #else
1786 HAL_SWPMI_TxCpltCallback(hswpmi);
1787 #endif
1788 }
1789 }
1790 /* DMA Circular mode */
1791 else
1792 {
1793 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1794 hswpmi->TxCpltCallback(hswpmi);
1795 #else
1796 HAL_SWPMI_TxCpltCallback(hswpmi);
1797 #endif
1798 }
1799 }
1800
1801 /**
1802 * @brief DMA SWPMI transmit process half complete callback.
1803 * @param hdma DMA handle
1804 * @retval None
1805 */
SWPMI_DMATxHalfCplt(DMA_HandleTypeDef * hdma)1806 static void SWPMI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1807 {
1808 SWPMI_HandleTypeDef* hswpmi = (SWPMI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1809
1810 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1811 hswpmi->TxHalfCpltCallback(hswpmi);
1812 #else
1813 HAL_SWPMI_TxHalfCpltCallback(hswpmi);
1814 #endif
1815 }
1816
1817
1818 /**
1819 * @brief DMA SWPMI receive process complete callback.
1820 * @param hdma DMA handle
1821 * @retval None
1822 */
SWPMI_DMAReceiveCplt(DMA_HandleTypeDef * hdma)1823 static void SWPMI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1824 {
1825 SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1826
1827 /* DMA Normal mode*/
1828 if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
1829 {
1830 hswpmi->RxXferCount = 0U;
1831
1832 /* Disable the DMA transfer for the receiver request by setting the RXDMA bit
1833 in the SWPMI CR register */
1834 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);
1835
1836 /* Check if a transmit Process is ongoing or not */
1837 if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
1838 {
1839 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
1840 }
1841 else
1842 {
1843 hswpmi->State = HAL_SWPMI_STATE_READY;
1844 }
1845 }
1846 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1847 hswpmi->RxCpltCallback(hswpmi);
1848 #else
1849 HAL_SWPMI_RxCpltCallback(hswpmi);
1850 #endif
1851 }
1852
1853 /**
1854 * @brief DMA SWPMI receive process half complete callback.
1855 * @param hdma DMA handle
1856 * @retval None
1857 */
SWPMI_DMARxHalfCplt(DMA_HandleTypeDef * hdma)1858 static void SWPMI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1859 {
1860 SWPMI_HandleTypeDef* hswpmi = (SWPMI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1861
1862 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1863 hswpmi->RxHalfCpltCallback(hswpmi);
1864 #else
1865 HAL_SWPMI_RxHalfCpltCallback(hswpmi);
1866 #endif
1867 }
1868
1869 /**
1870 * @brief DMA SWPMI communication error callback.
1871 * @param hdma DMA handle
1872 * @retval None
1873 */
SWPMI_DMAError(DMA_HandleTypeDef * hdma)1874 static void SWPMI_DMAError(DMA_HandleTypeDef *hdma)
1875 {
1876 SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1877
1878 /* Update handle */
1879 hswpmi->RxXferCount = 0U;
1880 hswpmi->TxXferCount = 0U;
1881 hswpmi->State= HAL_SWPMI_STATE_READY;
1882 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA;
1883
1884 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1885 hswpmi->ErrorCallback(hswpmi);
1886 #else
1887 HAL_SWPMI_ErrorCallback(hswpmi);
1888 #endif
1889 }
1890
1891 /**
1892 * @brief DMA SWPMI communication abort callback.
1893 * @param hdma DMA handle
1894 * @retval None
1895 */
SWPMI_DMAAbortOnError(DMA_HandleTypeDef * hdma)1896 static void SWPMI_DMAAbortOnError(DMA_HandleTypeDef *hdma)
1897 {
1898 SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1899
1900 /* Update handle */
1901 hswpmi->RxXferCount = 0U;
1902 hswpmi->TxXferCount = 0U;
1903 hswpmi->State= HAL_SWPMI_STATE_READY;
1904
1905 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1906 hswpmi->ErrorCallback(hswpmi);
1907 #else
1908 HAL_SWPMI_ErrorCallback(hswpmi);
1909 #endif
1910 }
1911
1912 /**
1913 * @brief Handle SWPMI Communication Timeout.
1914 * @param hswpmi SWPMI handle
1915 * @param Flag: specifies the SWPMI flag to check.
1916 * @param Tickstart Tick start value
1917 * @param Timeout timeout duration.
1918 * @retval HAL status
1919 */
SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef * hswpmi,uint32_t Flag,uint32_t Tickstart,uint32_t Timeout)1920 static HAL_StatusTypeDef SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef *hswpmi, uint32_t Flag, uint32_t Tickstart, uint32_t Timeout)
1921 {
1922 HAL_StatusTypeDef status = HAL_OK;
1923
1924 /* Wait until flag is set */
1925 while(!(HAL_IS_BIT_SET(hswpmi->Instance->ISR, Flag)))
1926 {
1927 /* Check for the Timeout */
1928 if ((((HAL_GetTick() - Tickstart) > Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1929 {
1930 /* Set the SWPMI state ready to be able to start again the process */
1931 hswpmi->State = HAL_SWPMI_STATE_READY;
1932
1933 status = HAL_TIMEOUT;
1934 break;
1935 }
1936 }
1937
1938 return status;
1939 }
1940
1941 /**
1942 * @}
1943 */
1944
1945 #endif /* HAL_SWPMI_MODULE_ENABLED */
1946
1947 /**
1948 * @}
1949 */
1950
1951 #endif /* SWPMI1 */
1952
1953 /**
1954 * @}
1955 */
1956
1957 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1958