STM32L443xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_swpmi.c 00004 * @author MCD Application Team 00005 * @brief SWPMI HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the Single Wire Protocol Master Interface (SWPMI). 00008 * + Initialization and Configuration 00009 * + Data transfers functions 00010 * + DMA transfers management 00011 * + Interrupts and flags management 00012 ****************************************************************************** 00013 * @attention 00014 * 00015 * Copyright (c) 2017 STMicroelectronics. 00016 * All rights reserved. 00017 * 00018 * This software is licensed under terms that can be found in the LICENSE file 00019 * in the root directory of this software component. 00020 * If no LICENSE file comes with this software, it is provided AS-IS. 00021 * 00022 ****************************************************************************** 00023 @verbatim 00024 =============================================================================== 00025 ##### How to use this driver ##### 00026 =============================================================================== 00027 [..] 00028 The SWPMI HAL driver can be used as follows: 00029 00030 (#) Declare a SWPMI_HandleTypeDef handle structure (eg. SWPMI_HandleTypeDef hswpmi). 00031 00032 (#) Initialize the SWPMI low level resources by implementing the HAL_SWPMI_MspInit() API: 00033 (##) Enable the SWPMIx interface clock with __HAL_RCC_SWPMIx_CLK_ENABLE(). 00034 (##) SWPMI IO configuration: 00035 (+++) Enable the clock for the SWPMI GPIO. 00036 (+++) Configure these SWPMI pins as alternate function pull-up. 00037 (##) NVIC configuration if you need to use interrupt process (HAL_SWPMI_Transmit_IT() 00038 and HAL_SWPMI_Receive_IT() APIs): 00039 (+++) Configure the SWPMIx interrupt priority with HAL_NVIC_SetPriority(). 00040 (+++) Enable the NVIC SWPMI IRQ handle with HAL_NVIC_EnableIRQ(). 00041 00042 (##) DMA Configuration if you need to use DMA process (HAL_SWPMI_Transmit_DMA() 00043 and HAL_SWPMI_Receive_DMA() APIs): 00044 (+++) Declare a DMA handle structure for the Tx/Rx channels. 00045 (+++) Enable the DMAx interface clock. 00046 (+++) Configure the declared DMA handle structure with the required 00047 Tx/Rx parameters. 00048 (+++) Configure the DMA Tx/Rx channels and requests. 00049 (+++) Associate the initialized DMA handle to the SWPMI DMA Tx/Rx handle. 00050 (+++) Configure the priority and enable the NVIC for the transfer complete 00051 interrupt on the DMA Tx/Rx channels. 00052 00053 (#) Program the Bite Rate, Tx Buffering mode, Rx Buffering mode in the Init structure. 00054 00055 (#) Enable the SWPMI peripheral by calling the HAL_SWPMI_Init() function. 00056 00057 [..] 00058 Three operation modes are available within this driver : 00059 00060 *** Polling mode IO operation *** 00061 ================================= 00062 [..] 00063 (+) Send an amount of data in blocking mode using HAL_SWPMI_Transmit() 00064 (+) Receive an amount of data in blocking mode using HAL_SWPMI_Receive() 00065 00066 *** Interrupt mode IO operation *** 00067 =================================== 00068 [..] 00069 (+) Send an amount of data in non-blocking mode using HAL_SWPMI_Transmit_IT() 00070 (+) At transmission end of transfer HAL_SWPMI_TxCpltCallback() is executed and user can 00071 add his own code by customization of function pointer HAL_SWPMI_TxCpltCallback() 00072 (+) Receive an amount of data in non-blocking mode using HAL_SWPMI_Receive_IT() 00073 (+) At reception end of transfer HAL_SWPMI_RxCpltCallback() is executed and user can 00074 add his own code by customization of function pointer HAL_SWPMI_RxCpltCallback() 00075 (+) In case of flag error, HAL_SWPMI_ErrorCallback() function is executed and user can 00076 add his own code by customization of function pointer HAL_SWPMI_ErrorCallback() 00077 00078 *** DMA mode IO operation *** 00079 ============================= 00080 [..] 00081 (+) Send an amount of data in non-blocking mode (DMA) using HAL_SWPMI_Transmit_DMA() 00082 (+) At transmission end of transfer HAL_SWPMI_TxCpltCallback() is executed and user can 00083 add his own code by customization of function pointer HAL_SWPMI_TxCpltCallback() 00084 (+) Receive an amount of data in non-blocking mode (DMA) using HAL_SWPMI_Receive_DMA() 00085 (+) At reception end of transfer HAL_SWPMI_RxCpltCallback() is executed and user can 00086 add his own code by customization of function pointer HAL_SWPMI_RxCpltCallback() 00087 (+) In case of flag error, HAL_SWPMI_ErrorCallback() function is executed and user can 00088 add his own code by customization of function pointer HAL_SWPMI_ErrorCallback() 00089 (+) Stop the DMA Transfer using HAL_SWPMI_DMAStop() 00090 00091 *** SWPMI HAL driver additional function list *** 00092 =============================================== 00093 [..] 00094 Below the list the others API available SWPMI HAL driver : 00095 00096 (+) HAL_SWPMI_EnableLoopback(): Enable the loopback mode for test purpose only 00097 (+) HAL_SWPMI_DisableLoopback(): Disable the loopback mode 00098 00099 *** SWPMI HAL driver macros list *** 00100 ================================== 00101 [..] 00102 Below the list of most used macros in SWPMI HAL driver : 00103 00104 (+) __HAL_SWPMI_ENABLE(): Enable the SWPMI peripheral 00105 (+) __HAL_SWPMI_DISABLE(): Disable the SWPMI peripheral 00106 (+) __HAL_SWPMI_ENABLE_IT(): Enable the specified SWPMI interrupts 00107 (+) __HAL_SWPMI_DISABLE_IT(): Disable the specified SWPMI interrupts 00108 (+) __HAL_SWPMI_GET_IT_SOURCE(): Check if the specified SWPMI interrupt source is 00109 enabled or disabled 00110 (+) __HAL_SWPMI_GET_FLAG(): Check whether the specified SWPMI flag is set or not 00111 00112 *** Callback registration *** 00113 ============================= 00114 [..] 00115 The compilation define USE_HAL_SWPMI_REGISTER_CALLBACKS when set to 1 00116 allows the user to configure dynamically the driver callbacks. 00117 [..] 00118 Use function HAL_SWPMI_RegisterCallback() to register a user callback. It allows 00119 to register the following callbacks: 00120 (+) RxCpltCallback : SWPMI receive complete. 00121 (+) RxHalfCpltCallback : SWPMI receive half complete. 00122 (+) TxCpltCallback : SWPMI transmit complete. 00123 (+) TxHalfCpltCallback : SWPMI transmit half complete. 00124 (+) ErrorCallback : SWPMI error. 00125 (+) MspInitCallback : SWPMI MspInit. 00126 (+) MspDeInitCallback : SWPMI MspDeInit. 00127 [..] 00128 This function takes as parameters the HAL peripheral handle, the callback ID 00129 and a pointer to the user callback function. 00130 [..] 00131 Use function HAL_SWPMI_UnRegisterCallback() to reset a callback to the default 00132 weak (surcharged) function. 00133 HAL_SWPMI_UnRegisterCallback() takes as parameters the HAL peripheral handle, 00134 and the callback ID. 00135 This function allows to reset following callbacks: 00136 (+) RxCpltCallback : SWPMI receive complete. 00137 (+) RxHalfCpltCallback : SWPMI receive half complete. 00138 (+) TxCpltCallback : SWPMI transmit complete. 00139 (+) TxHalfCpltCallback : SWPMI transmit half complete. 00140 (+) ErrorCallback : SWPMI error. 00141 (+) MspInitCallback : SWPMI MspInit. 00142 (+) MspDeInitCallback : SWPMI MspDeInit. 00143 [..] 00144 By default, after the HAL_SWPMI_Init and if the state is HAL_SWPMI_STATE_RESET 00145 all callbacks are reset to the corresponding legacy weak (surcharged) functions: 00146 examples HAL_SWPMI_RxCpltCallback(), HAL_SWPMI_ErrorCallback(). 00147 Exception done for MspInit and MspDeInit callbacks that are respectively 00148 reset to the legacy weak (surcharged) functions in the HAL_SWPMI_Init 00149 and HAL_SWPMI_DeInit only when these callbacks are null (not registered beforehand). 00150 If not, MspInit or MspDeInit are not null, the HAL_SWPMI_Init and HAL_SWPMI_DeInit 00151 keep and use the user MspInit/MspDeInit callbacks (registered beforehand). 00152 [..] 00153 Callbacks can be registered/unregistered in READY state only. 00154 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered 00155 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used 00156 during the Init/DeInit. 00157 In that case first register the MspInit/MspDeInit user callbacks 00158 using HAL_SWPMI_RegisterCallback before calling HAL_SWPMI_DeInit 00159 or HAL_SWPMI_Init function. 00160 [..] 00161 When the compilation define USE_HAL_SWPMI_REGISTER_CALLBACKS is set to 0 or 00162 not defined, the callback registering feature is not available 00163 and weak (surcharged) callbacks are used. 00164 00165 @endverbatim 00166 */ 00167 00168 /* Includes ------------------------------------------------------------------*/ 00169 #include "stm32l4xx_hal.h" 00170 00171 /** @addtogroup STM32L4xx_HAL_Driver 00172 * @{ 00173 */ 00174 00175 #if defined(SWPMI1) 00176 00177 /** @defgroup SWPMI SWPMI 00178 * @brief HAL SWPMI module driver 00179 * @{ 00180 */ 00181 #ifdef HAL_SWPMI_MODULE_ENABLED 00182 00183 /* Private typedef -----------------------------------------------------------*/ 00184 /* Private define ------------------------------------------------------------*/ 00185 /* Private constants ---------------------------------------------------------*/ 00186 /** @addtogroup SWPMI_Private_Constants SWPMI Private Constants 00187 * @{ 00188 */ 00189 #define SWPMI_TIMEOUT_VALUE 22000U /* End of transmission timeout */ 00190 00191 /** 00192 * @} 00193 */ 00194 00195 /* Private macros ------------------------------------------------------------*/ 00196 /* Private variables ---------------------------------------------------------*/ 00197 /* Private function prototypes -----------------------------------------------*/ 00198 static void SWPMI_DMATransmitCplt(DMA_HandleTypeDef *hdma); 00199 static void SWPMI_DMATxHalfCplt(DMA_HandleTypeDef *hdma); 00200 static void SWPMI_DMAReceiveCplt(DMA_HandleTypeDef *hdma); 00201 static void SWPMI_DMARxHalfCplt(DMA_HandleTypeDef *hdma); 00202 static void SWPMI_DMAError(DMA_HandleTypeDef *hdma); 00203 static void SWPMI_DMAAbortOnError(DMA_HandleTypeDef *hdma); 00204 static void SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi); 00205 static void SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef *hswpmi); 00206 static void SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi); 00207 static void SWPMI_EndReceive_IT(SWPMI_HandleTypeDef *hswpmi); 00208 static void SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef *hswpmi); 00209 static HAL_StatusTypeDef SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef *hswpmi, uint32_t Flag, uint32_t Tickstart, uint32_t Timeout); 00210 00211 /* Exported functions --------------------------------------------------------*/ 00212 00213 /** @defgroup SWPMI_Exported_Functions SWPMI Exported Functions 00214 * @{ 00215 */ 00216 00217 /** @defgroup SWPMI_Exported_Group1 Initialization/de-initialization methods 00218 * @brief Initialization and Configuration functions 00219 * 00220 @verbatim 00221 =============================================================================== 00222 ##### Initialization and Configuration functions ##### 00223 =============================================================================== 00224 [..] This section provides functions allowing to: 00225 (+) Initialize and configure the SWPMI peripheral. 00226 (+) De-initialize the SWPMI peripheral. 00227 00228 @endverbatim 00229 * @{ 00230 */ 00231 00232 /** 00233 * @brief Initialize the SWPMI peripheral according to the specified parameters in the SWPMI_InitTypeDef. 00234 * @param hswpmi SWPMI handle 00235 * @retval HAL status 00236 */ 00237 HAL_StatusTypeDef HAL_SWPMI_Init(SWPMI_HandleTypeDef *hswpmi) 00238 { 00239 HAL_StatusTypeDef status = HAL_OK; 00240 __IO uint32_t wait_loop_index = 0U; 00241 00242 /* Check the SWPMI handle allocation */ 00243 if (hswpmi == NULL) 00244 { 00245 status = HAL_ERROR; 00246 } 00247 else 00248 { 00249 /* Check the parameters */ 00250 assert_param(IS_SWPMI_VOLTAGE_CLASS(hswpmi->Init.VoltageClass)); 00251 assert_param(IS_SWPMI_BITRATE_VALUE(hswpmi->Init.BitRate)); 00252 assert_param(IS_SWPMI_TX_BUFFERING_MODE(hswpmi->Init.TxBufferingMode)); 00253 assert_param(IS_SWPMI_RX_BUFFERING_MODE(hswpmi->Init.RxBufferingMode)); 00254 00255 if (hswpmi->State == HAL_SWPMI_STATE_RESET) 00256 { 00257 /* Allocate lock resource and initialize it */ 00258 hswpmi->Lock = HAL_UNLOCKED; 00259 00260 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1) 00261 /* Reset callback pointers to the weak predefined callbacks */ 00262 hswpmi->RxCpltCallback = HAL_SWPMI_RxCpltCallback; 00263 hswpmi->RxHalfCpltCallback = HAL_SWPMI_RxHalfCpltCallback; 00264 hswpmi->TxCpltCallback = HAL_SWPMI_TxCpltCallback; 00265 hswpmi->TxHalfCpltCallback = HAL_SWPMI_TxHalfCpltCallback; 00266 hswpmi->ErrorCallback = HAL_SWPMI_ErrorCallback; 00267 00268 /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ 00269 if (hswpmi->MspInitCallback == NULL) 00270 { 00271 hswpmi->MspInitCallback = HAL_SWPMI_MspInit; 00272 } 00273 hswpmi->MspInitCallback(hswpmi); 00274 #else 00275 /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ 00276 HAL_SWPMI_MspInit(hswpmi); 00277 #endif 00278 } 00279 00280 hswpmi->State = HAL_SWPMI_STATE_BUSY; 00281 00282 /* Disable SWPMI interface */ 00283 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); 00284 00285 /* Clear all SWPMI interface flags */ 00286 WRITE_REG(hswpmi->Instance->ICR, 0x019F); 00287 00288 /* Apply Voltage class selection */ 00289 MODIFY_REG(hswpmi->Instance->OR, SWPMI_OR_CLASS, hswpmi->Init.VoltageClass); 00290 00291 /* If Voltage class B, apply 300us delay */ 00292 if (hswpmi->Init.VoltageClass == SWPMI_VOLTAGE_CLASS_B) 00293 { 00294 /* Insure 300us wait to insure SWPMI_IO output not higher than 1.8V */ 00295 /* Wait loop initialization and execution */ 00296 /* Note: Variable divided by 4 to compensate partially CPU processing cycles. */ 00297 wait_loop_index = (300U * (SystemCoreClock / (1000000U * 4U))) + 150U; 00298 while (wait_loop_index != 0U) 00299 { 00300 wait_loop_index--; 00301 } 00302 } 00303 00304 /* Configure the BRR register (Bitrate) */ 00305 WRITE_REG(hswpmi->Instance->BRR, hswpmi->Init.BitRate); 00306 00307 /* Apply SWPMI CR configuration */ 00308 MODIFY_REG(hswpmi->Instance->CR, \ 00309 SWPMI_CR_RXDMA | SWPMI_CR_TXDMA | SWPMI_CR_RXMODE | SWPMI_CR_TXMODE, \ 00310 hswpmi->Init.TxBufferingMode | hswpmi->Init.RxBufferingMode); 00311 00312 hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE; 00313 hswpmi->State = HAL_SWPMI_STATE_READY; 00314 00315 /* Enable SWPMI peripheral */ 00316 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); 00317 } 00318 00319 return status; 00320 } 00321 00322 /** 00323 * @brief De-initialize the SWPMI peripheral. 00324 * @param hswpmi SWPMI handle 00325 * @retval HAL status 00326 */ 00327 HAL_StatusTypeDef HAL_SWPMI_DeInit(SWPMI_HandleTypeDef *hswpmi) 00328 { 00329 HAL_StatusTypeDef status = HAL_OK; 00330 00331 /* Check the SWPMI handle allocation */ 00332 if (hswpmi == NULL) 00333 { 00334 status = HAL_ERROR; 00335 } 00336 else 00337 { 00338 /* Check the parameters */ 00339 assert_param(IS_SWPMI_INSTANCE(hswpmi->Instance)); 00340 00341 hswpmi->State = HAL_SWPMI_STATE_BUSY; 00342 00343 /* Disable SWPMI interface */ 00344 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); 00345 00346 /* Disable Loopback mode */ 00347 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK); 00348 00349 00350 /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */ 00351 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1) 00352 if (hswpmi->MspDeInitCallback == NULL) 00353 { 00354 hswpmi->MspDeInitCallback = HAL_SWPMI_MspDeInit; 00355 } 00356 hswpmi->MspDeInitCallback(hswpmi); 00357 #else 00358 HAL_SWPMI_MspDeInit(hswpmi); 00359 #endif 00360 00361 hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE; 00362 hswpmi->State = HAL_SWPMI_STATE_RESET; 00363 00364 /* Release Lock */ 00365 __HAL_UNLOCK(hswpmi); 00366 } 00367 00368 return status; 00369 } 00370 00371 /** 00372 * @brief Initialize the SWPMI MSP. 00373 * @param hswpmi SWPMI handle 00374 * @retval None 00375 */ 00376 __weak void HAL_SWPMI_MspInit(SWPMI_HandleTypeDef *hswpmi) 00377 { 00378 /* Prevent unused argument(s) compilation warning */ 00379 UNUSED(hswpmi); 00380 00381 /* NOTE : This function should not be modified, when the callback is needed, 00382 the HAL_SWPMI_MspInit can be implemented in the user file 00383 */ 00384 } 00385 00386 /** 00387 * @brief DeInitialize the SWPMI MSP. 00388 * @param hswpmi SWPMI handle 00389 * @retval None 00390 */ 00391 __weak void HAL_SWPMI_MspDeInit(SWPMI_HandleTypeDef *hswpmi) 00392 { 00393 /* Prevent unused argument(s) compilation warning */ 00394 UNUSED(hswpmi); 00395 00396 /* NOTE : This function should not be modified, when the callback is needed, 00397 the HAL_SWPMI_MspDeInit can be implemented in the user file 00398 */ 00399 } 00400 00401 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1) 00402 /** 00403 * @brief Register a user SWPMI callback 00404 * to be used instead of the weak predefined callback. 00405 * @param hswpmi SWPMI handle. 00406 * @param CallbackID ID of the callback to be registered. 00407 * This parameter can be one of the following values: 00408 * @arg @ref HAL_SWPMI_RX_COMPLETE_CB_ID receive complete callback ID. 00409 * @arg @ref HAL_SWPMI_RX_HALFCOMPLETE_CB_ID receive half complete callback ID. 00410 * @arg @ref HAL_SWPMI_TX_COMPLETE_CB_ID transmit complete callback ID. 00411 * @arg @ref HAL_SWPMI_TX_HALFCOMPLETE_CB_ID transmit half complete callback ID. 00412 * @arg @ref HAL_SWPMI_ERROR_CB_ID error callback ID. 00413 * @arg @ref HAL_SWPMI_MSPINIT_CB_ID MSP init callback ID. 00414 * @arg @ref HAL_SWPMI_MSPDEINIT_CB_ID MSP de-init callback ID. 00415 * @param pCallback pointer to the callback function. 00416 * @retval HAL status. 00417 */ 00418 HAL_StatusTypeDef HAL_SWPMI_RegisterCallback(SWPMI_HandleTypeDef *hswpmi, 00419 HAL_SWPMI_CallbackIDTypeDef CallbackID, 00420 pSWPMI_CallbackTypeDef pCallback) 00421 { 00422 HAL_StatusTypeDef status = HAL_OK; 00423 00424 if (pCallback == NULL) 00425 { 00426 /* update the error code */ 00427 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK; 00428 /* update return status */ 00429 status = HAL_ERROR; 00430 } 00431 else 00432 { 00433 if (hswpmi->State == HAL_SWPMI_STATE_READY) 00434 { 00435 switch (CallbackID) 00436 { 00437 case HAL_SWPMI_RX_COMPLETE_CB_ID : 00438 hswpmi->RxCpltCallback = pCallback; 00439 break; 00440 case HAL_SWPMI_RX_HALFCOMPLETE_CB_ID : 00441 hswpmi->RxHalfCpltCallback = pCallback; 00442 break; 00443 case HAL_SWPMI_TX_COMPLETE_CB_ID : 00444 hswpmi->TxCpltCallback = pCallback; 00445 break; 00446 case HAL_SWPMI_TX_HALFCOMPLETE_CB_ID : 00447 hswpmi->TxHalfCpltCallback = pCallback; 00448 break; 00449 case HAL_SWPMI_ERROR_CB_ID : 00450 hswpmi->ErrorCallback = pCallback; 00451 break; 00452 case HAL_SWPMI_MSPINIT_CB_ID : 00453 hswpmi->MspInitCallback = pCallback; 00454 break; 00455 case HAL_SWPMI_MSPDEINIT_CB_ID : 00456 hswpmi->MspDeInitCallback = pCallback; 00457 break; 00458 default : 00459 /* update the error code */ 00460 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK; 00461 /* update return status */ 00462 status = HAL_ERROR; 00463 break; 00464 } 00465 } 00466 else if (hswpmi->State == HAL_SWPMI_STATE_RESET) 00467 { 00468 switch (CallbackID) 00469 { 00470 case HAL_SWPMI_MSPINIT_CB_ID : 00471 hswpmi->MspInitCallback = pCallback; 00472 break; 00473 case HAL_SWPMI_MSPDEINIT_CB_ID : 00474 hswpmi->MspDeInitCallback = pCallback; 00475 break; 00476 default : 00477 /* update the error code */ 00478 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK; 00479 /* update return status */ 00480 status = HAL_ERROR; 00481 break; 00482 } 00483 } 00484 else 00485 { 00486 /* update the error code */ 00487 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK; 00488 /* update return status */ 00489 status = HAL_ERROR; 00490 } 00491 } 00492 return status; 00493 } 00494 00495 /** 00496 * @brief Unregister a user SWPMI callback. 00497 * SWPMI callback is redirected to the weak predefined callback. 00498 * @param hswpmi SWPMI handle. 00499 * @param CallbackID ID of the callback to be unregistered. 00500 * This parameter can be one of the following values: 00501 * @arg @ref HAL_SWPMI_RX_COMPLETE_CB_ID receive complete callback ID. 00502 * @arg @ref HAL_SWPMI_RX_HALFCOMPLETE_CB_ID receive half complete callback ID. 00503 * @arg @ref HAL_SWPMI_TX_COMPLETE_CB_ID transmit complete callback ID. 00504 * @arg @ref HAL_SWPMI_TX_HALFCOMPLETE_CB_ID transmit half complete callback ID. 00505 * @arg @ref HAL_SWPMI_ERROR_CB_ID error callback ID. 00506 * @arg @ref HAL_SWPMI_MSPINIT_CB_ID MSP init callback ID. 00507 * @arg @ref HAL_SWPMI_MSPDEINIT_CB_ID MSP de-init callback ID. 00508 * @retval HAL status. 00509 */ 00510 HAL_StatusTypeDef HAL_SWPMI_UnRegisterCallback(SWPMI_HandleTypeDef *hswpmi, 00511 HAL_SWPMI_CallbackIDTypeDef CallbackID) 00512 { 00513 HAL_StatusTypeDef status = HAL_OK; 00514 00515 if (hswpmi->State == HAL_SWPMI_STATE_READY) 00516 { 00517 switch (CallbackID) 00518 { 00519 case HAL_SWPMI_RX_COMPLETE_CB_ID : 00520 hswpmi->RxCpltCallback = HAL_SWPMI_RxCpltCallback; 00521 break; 00522 case HAL_SWPMI_RX_HALFCOMPLETE_CB_ID : 00523 hswpmi->RxHalfCpltCallback = HAL_SWPMI_RxHalfCpltCallback; 00524 break; 00525 case HAL_SWPMI_TX_COMPLETE_CB_ID : 00526 hswpmi->TxCpltCallback = HAL_SWPMI_TxCpltCallback; 00527 break; 00528 case HAL_SWPMI_TX_HALFCOMPLETE_CB_ID : 00529 hswpmi->TxHalfCpltCallback = HAL_SWPMI_TxHalfCpltCallback; 00530 break; 00531 case HAL_SWPMI_ERROR_CB_ID : 00532 hswpmi->ErrorCallback = HAL_SWPMI_ErrorCallback; 00533 break; 00534 case HAL_SWPMI_MSPINIT_CB_ID : 00535 hswpmi->MspInitCallback = HAL_SWPMI_MspInit; 00536 break; 00537 case HAL_SWPMI_MSPDEINIT_CB_ID : 00538 hswpmi->MspDeInitCallback = HAL_SWPMI_MspDeInit; 00539 break; 00540 default : 00541 /* update the error code */ 00542 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK; 00543 /* update return status */ 00544 status = HAL_ERROR; 00545 break; 00546 } 00547 } 00548 else if (hswpmi->State == HAL_SWPMI_STATE_RESET) 00549 { 00550 switch (CallbackID) 00551 { 00552 case HAL_SWPMI_MSPINIT_CB_ID : 00553 hswpmi->MspInitCallback = HAL_SWPMI_MspInit; 00554 break; 00555 case HAL_SWPMI_MSPDEINIT_CB_ID : 00556 hswpmi->MspDeInitCallback = HAL_SWPMI_MspDeInit; 00557 break; 00558 default : 00559 /* update the error code */ 00560 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK; 00561 /* update return status */ 00562 status = HAL_ERROR; 00563 break; 00564 } 00565 } 00566 else 00567 { 00568 /* update the error code */ 00569 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK; 00570 /* update return status */ 00571 status = HAL_ERROR; 00572 } 00573 return status; 00574 } 00575 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */ 00576 00577 /** 00578 * @} 00579 */ 00580 00581 /** @defgroup SWPMI_Exported_Group2 IO operation methods 00582 * @brief SWPMI Transmit/Receive functions 00583 * 00584 @verbatim 00585 =============================================================================== 00586 ##### IO operation methods ##### 00587 =============================================================================== 00588 [..] 00589 This subsection provides a set of functions allowing to manage the SWPMI 00590 data transfers. 00591 00592 (#) There are two modes of transfer: 00593 (++) Blocking mode: The communication is performed in polling mode. 00594 The HAL status of all data processing is returned by the same function 00595 after finishing transfer. 00596 (++) Non-Blocking mode: The communication is performed using Interrupts 00597 or DMA. The end of the data processing will be indicated through the 00598 dedicated SWPMI Interrupt handler (HAL_SWPMI_IRQHandler()) when using Interrupt mode or 00599 the selected DMA channel interrupt handler when using DMA mode. 00600 The HAL_SWPMI_TxCpltCallback(), HAL_SWPMI_RxCpltCallback() user callbacks 00601 will be executed respectively at the end of the transmit or receive process. 00602 The HAL_SWPMI_ErrorCallback() user callback will be executed when a communication error is detected. 00603 00604 (#) Blocking mode API's are: 00605 (++) HAL_SWPMI_Transmit() 00606 (++) HAL_SWPMI_Receive() 00607 00608 (#) Non-Blocking mode API's with Interrupt are: 00609 (++) HAL_SWPMI_Transmit_IT() 00610 (++) HAL_SWPMI_Receive_IT() 00611 (++) HAL_SWPMI_IRQHandler() 00612 00613 (#) Non-Blocking mode API's with DMA are: 00614 (++) HAL_SWPMI_Transmit_DMA() 00615 (++) HAL_SWPMI_Receive_DMA() 00616 (++) HAL_SWPMI_DMAPause() 00617 (++) HAL_SWPMI_DMAResume() 00618 (++) HAL_SWPMI_DMAStop() 00619 00620 (#) A set of Transfer Complete Callbacks are provided in Non-Blocking mode: 00621 (++) HAL_SWPMI_TxHalfCpltCallback() 00622 (++) HAL_SWPMI_TxCpltCallback() 00623 (++) HAL_SWPMI_RxHalfCpltCallback() 00624 (++) HAL_SWPMI_RxCpltCallback() 00625 (++) HAL_SWPMI_ErrorCallback() 00626 00627 (#) The capability to launch the above IO operations in loopback mode for 00628 user application verification: 00629 (++) HAL_SWPMI_EnableLoopback() 00630 (++) HAL_SWPMI_DisableLoopback() 00631 00632 @endverbatim 00633 * @{ 00634 */ 00635 00636 /** 00637 * @brief Transmit an amount of data in blocking mode. 00638 * @param hswpmi pointer to a SWPMI_HandleTypeDef structure that contains 00639 * the configuration information for SWPMI module. 00640 * @param pData Pointer to data buffer 00641 * @param Size Amount of data to be sent 00642 * @param Timeout Timeout duration 00643 * @retval HAL status 00644 */ 00645 HAL_StatusTypeDef HAL_SWPMI_Transmit(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size, uint32_t Timeout) 00646 { 00647 uint32_t tickstart = HAL_GetTick(); 00648 HAL_StatusTypeDef status = HAL_OK; 00649 HAL_SWPMI_StateTypeDef tmp_state; 00650 uint32_t *ptmp_data; 00651 uint32_t tmp_size; 00652 00653 if ((pData == NULL) || (Size == 0U)) 00654 { 00655 status = HAL_ERROR; 00656 } 00657 else 00658 { 00659 /* Process Locked */ 00660 __HAL_LOCK(hswpmi); 00661 00662 tmp_state = hswpmi->State; 00663 if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_RX)) 00664 { 00665 /* Check if a non-blocking receive process is ongoing or not */ 00666 if (tmp_state == HAL_SWPMI_STATE_READY) 00667 { 00668 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX; 00669 00670 /* Disable any transmitter interrupts */ 00671 __HAL_SWPMI_DISABLE_IT(hswpmi, SWPMI_IT_TCIE | SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE); 00672 00673 /* Disable any transmitter flags */ 00674 __HAL_SWPMI_CLEAR_FLAG(hswpmi, SWPMI_FLAG_TXBEF | SWPMI_FLAG_TXUNRF | SWPMI_FLAG_TCF); 00675 00676 /* Enable SWPMI peripheral if not */ 00677 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); 00678 } 00679 else 00680 { 00681 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX; 00682 } 00683 00684 ptmp_data = pData; 00685 tmp_size = Size; 00686 do 00687 { 00688 /* Wait the TXE to write data */ 00689 if (HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_TXE)) 00690 { 00691 hswpmi->Instance->TDR = *ptmp_data; 00692 ptmp_data++; 00693 tmp_size--; 00694 } 00695 else 00696 { 00697 /* Check for the Timeout */ 00698 if (Timeout != HAL_MAX_DELAY) 00699 { 00700 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) 00701 { 00702 status = HAL_TIMEOUT; 00703 break; 00704 } 00705 } 00706 } 00707 } 00708 while (tmp_size != 0U); 00709 00710 /* Wait on TXBEF flag to be able to start a second transfer */ 00711 if (SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, tickstart, Timeout) != HAL_OK) 00712 { 00713 /* Timeout occurred */ 00714 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_TXBEF_TIMEOUT; 00715 00716 status = HAL_TIMEOUT; 00717 } 00718 00719 if (status == HAL_OK) 00720 { 00721 /* Check if a non-blocking receive Process is ongoing or not */ 00722 if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX) 00723 { 00724 hswpmi->State = HAL_SWPMI_STATE_BUSY_RX; 00725 } 00726 else 00727 { 00728 hswpmi->State = HAL_SWPMI_STATE_READY; 00729 } 00730 } 00731 } 00732 else 00733 { 00734 status = HAL_BUSY; 00735 } 00736 } 00737 00738 if ((status != HAL_OK) && (status != HAL_BUSY)) 00739 { 00740 hswpmi->State = HAL_SWPMI_STATE_READY; 00741 } 00742 /* Process Unlocked */ 00743 __HAL_UNLOCK(hswpmi); 00744 00745 return status; 00746 } 00747 00748 /** 00749 * @brief Receive an amount of data in blocking mode. 00750 * @param hswpmi pointer to a SWPMI_HandleTypeDef structure that contains 00751 * the configuration information for SWPMI module. 00752 * @param pData Pointer to data buffer 00753 * @param Size Amount of data to be received 00754 * @param Timeout Timeout duration 00755 * @retval HAL status 00756 */ 00757 HAL_StatusTypeDef HAL_SWPMI_Receive(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size, uint32_t Timeout) 00758 { 00759 uint32_t tickstart = HAL_GetTick(); 00760 HAL_StatusTypeDef status = HAL_OK; 00761 HAL_SWPMI_StateTypeDef tmp_state; 00762 uint32_t *ptmp_data; 00763 uint32_t tmp_size; 00764 00765 if ((pData == NULL) || (Size == 0U)) 00766 { 00767 status = HAL_ERROR; 00768 } 00769 else 00770 { 00771 /* Process Locked */ 00772 __HAL_LOCK(hswpmi); 00773 00774 tmp_state = hswpmi->State; 00775 if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX)) 00776 { 00777 /* Check if a non-blocking transmit process is ongoing or not */ 00778 if (tmp_state == HAL_SWPMI_STATE_READY) 00779 { 00780 hswpmi->State = HAL_SWPMI_STATE_BUSY_RX; 00781 00782 /* Disable any receiver interrupts */ 00783 CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_SRIE | SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE); 00784 00785 /* Enable SWPMI peripheral if not */ 00786 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); 00787 } 00788 else 00789 { 00790 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX; 00791 } 00792 00793 ptmp_data = pData; 00794 tmp_size = Size; 00795 do 00796 { 00797 /* Wait the RXNE to read data */ 00798 if (HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXNE)) 00799 { 00800 *ptmp_data = hswpmi->Instance->RDR; 00801 ptmp_data++; 00802 tmp_size--; 00803 } 00804 else 00805 { 00806 /* Check for the Timeout */ 00807 if (Timeout != HAL_MAX_DELAY) 00808 { 00809 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) 00810 { 00811 status = HAL_TIMEOUT; 00812 break; 00813 } 00814 } 00815 } 00816 } 00817 while (tmp_size != 0U); 00818 00819 if (status == HAL_OK) 00820 { 00821 if (HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXBFF)) 00822 { 00823 /* Clear RXBFF at end of reception */ 00824 WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF); 00825 } 00826 00827 /* Check if a non-blocking transmit Process is ongoing or not */ 00828 if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX) 00829 { 00830 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX; 00831 } 00832 else 00833 { 00834 hswpmi->State = HAL_SWPMI_STATE_READY; 00835 } 00836 } 00837 } 00838 else 00839 { 00840 status = HAL_BUSY; 00841 } 00842 } 00843 00844 if ((status != HAL_OK) && (status != HAL_BUSY)) 00845 { 00846 hswpmi->State = HAL_SWPMI_STATE_READY; 00847 } 00848 /* Process Unlocked */ 00849 __HAL_UNLOCK(hswpmi); 00850 00851 return status; 00852 } 00853 00854 /** 00855 * @brief Transmit an amount of data in non-blocking mode with interrupt. 00856 * @param hswpmi pointer to a SWPMI_HandleTypeDef structure that contains 00857 * the configuration information for SWPMI module. 00858 * @param pData Pointer to data buffer 00859 * @param Size Amount of data to be sent 00860 * @retval HAL status 00861 */ 00862 HAL_StatusTypeDef HAL_SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size) 00863 { 00864 HAL_StatusTypeDef status = HAL_OK; 00865 HAL_SWPMI_StateTypeDef tmp_state; 00866 00867 if ((pData == NULL) || (Size == 0U)) 00868 { 00869 status = HAL_ERROR; 00870 } 00871 else 00872 { 00873 /* Process Locked */ 00874 __HAL_LOCK(hswpmi); 00875 00876 tmp_state = hswpmi->State; 00877 if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_RX)) 00878 { 00879 /* Update handle */ 00880 hswpmi->pTxBuffPtr = pData; 00881 hswpmi->TxXferSize = Size; 00882 hswpmi->TxXferCount = Size; 00883 hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE; 00884 00885 /* Check if a receive process is ongoing or not */ 00886 if (tmp_state == HAL_SWPMI_STATE_READY) 00887 { 00888 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX; 00889 00890 /* Enable SWPMI peripheral if not */ 00891 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); 00892 } 00893 else 00894 { 00895 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX; 00896 } 00897 00898 /* Enable the SWPMI transmit underrun error */ 00899 __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TXUNRIE); 00900 00901 /* Process Unlocked */ 00902 __HAL_UNLOCK(hswpmi); 00903 00904 /* Enable the SWPMI interrupts: */ 00905 /* - Transmit data register empty */ 00906 /* - Transmit buffer empty */ 00907 /* - Transmit/Reception completion */ 00908 __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TIE | SWPMI_IT_TXBEIE | SWPMI_IT_TCIE); 00909 } 00910 else 00911 { 00912 status = HAL_BUSY; 00913 00914 /* Process Unlocked */ 00915 __HAL_UNLOCK(hswpmi); 00916 } 00917 } 00918 00919 return status; 00920 } 00921 00922 /** 00923 * @brief Receive an amount of data in non-blocking mode with interrupt. 00924 * @param hswpmi SWPMI handle 00925 * @param pData Pointer to data buffer 00926 * @param Size Amount of data to be received 00927 * @retval HAL status 00928 */ 00929 HAL_StatusTypeDef HAL_SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size) 00930 { 00931 HAL_StatusTypeDef status = HAL_OK; 00932 HAL_SWPMI_StateTypeDef tmp_state; 00933 00934 if ((pData == NULL) || (Size == 0U)) 00935 { 00936 status = HAL_ERROR; 00937 } 00938 else 00939 { 00940 /* Process Locked */ 00941 __HAL_LOCK(hswpmi); 00942 00943 tmp_state = hswpmi->State; 00944 if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX)) 00945 { 00946 /* Update handle */ 00947 hswpmi->pRxBuffPtr = pData; 00948 hswpmi->RxXferSize = Size; 00949 hswpmi->RxXferCount = Size; 00950 hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE; 00951 00952 /* Check if a transmit process is ongoing or not */ 00953 if (tmp_state == HAL_SWPMI_STATE_READY) 00954 { 00955 hswpmi->State = HAL_SWPMI_STATE_BUSY_RX; 00956 00957 /* Enable SWPMI peripheral if not */ 00958 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); 00959 } 00960 else 00961 { 00962 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX; 00963 } 00964 00965 /* Process Unlocked */ 00966 __HAL_UNLOCK(hswpmi); 00967 00968 /* Enable the SWPMI slave resume */ 00969 /* Enable the SWPMI Data Register not empty Interrupt, receive CRC Error, receive overrun and RxBuf Interrupt */ 00970 /* Enable the SWPMI Transmit/Reception completion */ 00971 __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE); 00972 } 00973 else 00974 { 00975 status = HAL_BUSY; 00976 00977 /* Process Unlocked */ 00978 __HAL_UNLOCK(hswpmi); 00979 } 00980 } 00981 00982 return status; 00983 } 00984 00985 /** 00986 * @brief Transmit an amount of data in non-blocking mode with DMA interrupt. 00987 * @param hswpmi SWPMI handle 00988 * @param pData Pointer to data buffer 00989 * @param Size Amount of data to be sent 00990 * @retval HAL status 00991 */ 00992 HAL_StatusTypeDef HAL_SWPMI_Transmit_DMA(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size) 00993 { 00994 HAL_StatusTypeDef status = HAL_OK; 00995 HAL_SWPMI_StateTypeDef tmp_state; 00996 00997 if ((pData == NULL) || (Size == 0U)) 00998 { 00999 status = HAL_ERROR; 01000 } 01001 else 01002 { 01003 /* Process Locked */ 01004 __HAL_LOCK(hswpmi); 01005 01006 tmp_state = hswpmi->State; 01007 if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_RX)) 01008 { 01009 /* Update handle */ 01010 hswpmi->pTxBuffPtr = pData; 01011 hswpmi->TxXferSize = Size; 01012 hswpmi->TxXferCount = Size; 01013 hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE; 01014 01015 /* Check if a receive process is ongoing or not */ 01016 if (tmp_state == HAL_SWPMI_STATE_READY) 01017 { 01018 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX; 01019 01020 /* Enable SWPMI peripheral if not */ 01021 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); 01022 } 01023 else 01024 { 01025 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX; 01026 } 01027 01028 /* Set the SWPMI DMA transfer complete callback */ 01029 hswpmi->hdmatx->XferCpltCallback = SWPMI_DMATransmitCplt; 01030 01031 /* Set the SWPMI DMA Half transfer complete callback */ 01032 hswpmi->hdmatx->XferHalfCpltCallback = SWPMI_DMATxHalfCplt; 01033 01034 /* Set the DMA error callback */ 01035 hswpmi->hdmatx->XferErrorCallback = SWPMI_DMAError; 01036 01037 /* Enable the SWPMI transmit DMA channel */ 01038 if (HAL_DMA_Start_IT(hswpmi->hdmatx, (uint32_t)hswpmi->pTxBuffPtr, (uint32_t)&hswpmi->Instance->TDR, Size) != HAL_OK) 01039 { 01040 hswpmi->State = tmp_state; /* Back to previous state */ 01041 hswpmi->ErrorCode = HAL_SWPMI_ERROR_DMA; 01042 status = HAL_ERROR; 01043 01044 /* Process Unlocked */ 01045 __HAL_UNLOCK(hswpmi); 01046 } 01047 else 01048 { 01049 /* Process Unlocked */ 01050 __HAL_UNLOCK(hswpmi); 01051 01052 /* Enable the SWPMI transmit underrun error */ 01053 __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TXUNRIE); 01054 01055 /* Enable the DMA transfer for transmit request by setting the TXDMA bit 01056 in the SWPMI CR register */ 01057 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA); 01058 } 01059 } 01060 else 01061 { 01062 status = HAL_BUSY; 01063 01064 /* Process Unlocked */ 01065 __HAL_UNLOCK(hswpmi); 01066 } 01067 } 01068 01069 return status; 01070 } 01071 01072 /** 01073 * @brief Receive an amount of data in non-blocking mode with DMA interrupt. 01074 * @param hswpmi SWPMI handle 01075 * @param pData Pointer to data buffer 01076 * @param Size Amount of data to be received 01077 * @retval HAL status 01078 */ 01079 HAL_StatusTypeDef HAL_SWPMI_Receive_DMA(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size) 01080 { 01081 HAL_StatusTypeDef status = HAL_OK; 01082 HAL_SWPMI_StateTypeDef tmp_state; 01083 01084 if ((pData == NULL) || (Size == 0U)) 01085 { 01086 status = HAL_ERROR; 01087 } 01088 else 01089 { 01090 /* Process Locked */ 01091 __HAL_LOCK(hswpmi); 01092 01093 tmp_state = hswpmi->State; 01094 if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX)) 01095 { 01096 /* Update handle */ 01097 hswpmi->pRxBuffPtr = pData; 01098 hswpmi->RxXferSize = Size; 01099 hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE; 01100 01101 /* Check if a transmit process is ongoing or not */ 01102 if (tmp_state == HAL_SWPMI_STATE_READY) 01103 { 01104 hswpmi->State = HAL_SWPMI_STATE_BUSY_RX; 01105 01106 /* Enable SWPMI peripheral if not */ 01107 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); 01108 } 01109 else 01110 { 01111 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX; 01112 } 01113 01114 /* Set the SWPMI DMA transfer complete callback */ 01115 hswpmi->hdmarx->XferCpltCallback = SWPMI_DMAReceiveCplt; 01116 01117 /* Set the SWPMI DMA Half transfer complete callback */ 01118 hswpmi->hdmarx->XferHalfCpltCallback = SWPMI_DMARxHalfCplt; 01119 01120 /* Set the DMA error callback */ 01121 hswpmi->hdmarx->XferErrorCallback = SWPMI_DMAError; 01122 01123 /* Enable the DMA request */ 01124 if (HAL_DMA_Start_IT(hswpmi->hdmarx, (uint32_t)&hswpmi->Instance->RDR, (uint32_t)hswpmi->pRxBuffPtr, Size) != HAL_OK) 01125 { 01126 hswpmi->State = tmp_state; /* Back to previous state */ 01127 hswpmi->ErrorCode = HAL_SWPMI_ERROR_DMA; 01128 status = HAL_ERROR; 01129 01130 /* Process Unlocked */ 01131 __HAL_UNLOCK(hswpmi); 01132 } 01133 else 01134 { 01135 /* Process Unlocked */ 01136 __HAL_UNLOCK(hswpmi); 01137 01138 /* Enable the SWPMI receive CRC Error and receive overrun interrupts */ 01139 __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE); 01140 01141 /* Enable the DMA transfer for the receiver request by setting the RXDMA bit 01142 in the SWPMI CR register */ 01143 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA); 01144 } 01145 } 01146 else 01147 { 01148 status = HAL_BUSY; 01149 01150 /* Process Unlocked */ 01151 __HAL_UNLOCK(hswpmi); 01152 } 01153 } 01154 01155 return status; 01156 } 01157 01158 /** 01159 * @brief Stop all DMA transfers. 01160 * @param hswpmi SWPMI handle 01161 * @retval HAL status 01162 */ 01163 HAL_StatusTypeDef HAL_SWPMI_DMAStop(SWPMI_HandleTypeDef *hswpmi) 01164 { 01165 HAL_StatusTypeDef status = HAL_OK; 01166 01167 /* Process Locked */ 01168 __HAL_LOCK(hswpmi); 01169 01170 /* Disable the SWPMI Tx/Rx DMA requests */ 01171 CLEAR_BIT(hswpmi->Instance->CR, (SWPMI_CR_TXDMA | SWPMI_CR_RXDMA)); 01172 01173 /* Abort the SWPMI DMA tx channel */ 01174 if (hswpmi->hdmatx != NULL) 01175 { 01176 if (HAL_DMA_Abort(hswpmi->hdmatx) != HAL_OK) 01177 { 01178 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA; 01179 status = HAL_ERROR; 01180 } 01181 } 01182 /* Abort the SWPMI DMA rx channel */ 01183 if (hswpmi->hdmarx != NULL) 01184 { 01185 if (HAL_DMA_Abort(hswpmi->hdmarx) != HAL_OK) 01186 { 01187 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA; 01188 status = HAL_ERROR; 01189 } 01190 } 01191 01192 /* Disable SWPMI interface */ 01193 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); 01194 01195 hswpmi->State = HAL_SWPMI_STATE_READY; 01196 01197 /* Process Unlocked */ 01198 __HAL_UNLOCK(hswpmi); 01199 01200 return status; 01201 } 01202 01203 01204 /** 01205 * @brief Enable the Loopback mode. 01206 * @param hswpmi SWPMI handle 01207 * @note Loopback mode is to be used only for test purposes 01208 * @retval HAL_OK / HAL_BUSY 01209 */ 01210 HAL_StatusTypeDef HAL_SWPMI_EnableLoopback(SWPMI_HandleTypeDef *hswpmi) 01211 { 01212 HAL_StatusTypeDef status = HAL_OK; 01213 01214 /* Process Locked */ 01215 __HAL_LOCK(hswpmi); 01216 01217 /* Make sure the SWPMI interface is not enabled to set the loopback mode */ 01218 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); 01219 01220 /* Set Loopback */ 01221 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK); 01222 01223 /* Enable SWPMI interface in loopback mode */ 01224 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); 01225 01226 /* Process Unlocked */ 01227 __HAL_UNLOCK(hswpmi); 01228 01229 return status; 01230 } 01231 01232 /** 01233 * @brief Disable the Loopback mode. 01234 * @param hswpmi SWPMI handle 01235 * @note Loopback mode is to be used only for test purposes 01236 * @retval HAL_OK / HAL_BUSY 01237 */ 01238 HAL_StatusTypeDef HAL_SWPMI_DisableLoopback(SWPMI_HandleTypeDef *hswpmi) 01239 { 01240 HAL_StatusTypeDef status = HAL_OK; 01241 01242 /* Process Locked */ 01243 __HAL_LOCK(hswpmi); 01244 01245 /* Make sure the SWPMI interface is not enabled to reset the loopback mode */ 01246 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); 01247 01248 /* Reset Loopback */ 01249 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK); 01250 01251 /* Re-enable SWPMI interface in normal mode */ 01252 SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); 01253 01254 /* Process Unlocked */ 01255 __HAL_UNLOCK(hswpmi); 01256 01257 return status; 01258 } 01259 01260 /** 01261 * @} 01262 */ 01263 01264 /** @defgroup SWPMI_Exported_Group3 SWPMI IRQ handler and callbacks 01265 * @brief SWPMI IRQ handler. 01266 * 01267 @verbatim 01268 ============================================================================== 01269 ##### SWPMI IRQ handler and callbacks ##### 01270 ============================================================================== 01271 [..] This section provides SWPMI IRQ handler and callback functions called within 01272 the IRQ handler. 01273 01274 @endverbatim 01275 * @{ 01276 */ 01277 01278 /** 01279 * @brief Handle SWPMI interrupt request. 01280 * @param hswpmi SWPMI handle 01281 * @retval None 01282 */ 01283 void HAL_SWPMI_IRQHandler(SWPMI_HandleTypeDef *hswpmi) 01284 { 01285 uint32_t regisr = READ_REG(hswpmi->Instance->ISR); 01286 uint32_t regier = READ_REG(hswpmi->Instance->IER); 01287 uint32_t errcode = HAL_SWPMI_ERROR_NONE; 01288 01289 /* SWPMI CRC error interrupt occurred --------------------------------------*/ 01290 if (((regisr & SWPMI_FLAG_RXBERF) != 0U) && ((regier & SWPMI_IT_RXBERIE) != 0U)) 01291 { 01292 /* Disable Receive CRC interrupt */ 01293 CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RXBERIE | SWPMI_IT_RXBFIE); 01294 /* Clear Receive CRC and Receive buffer full flag */ 01295 WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBERF | SWPMI_FLAG_RXBFF); 01296 01297 errcode |= HAL_SWPMI_ERROR_CRC; 01298 } 01299 01300 /* SWPMI Over-Run interrupt occurred -----------------------------------------*/ 01301 if (((regisr & SWPMI_FLAG_RXOVRF) != 0U) && ((regier & SWPMI_IT_RXOVRIE) != 0U)) 01302 { 01303 /* Disable Receive overrun interrupt */ 01304 CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RXOVRIE); 01305 /* Clear Receive overrun flag */ 01306 WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXOVRF); 01307 01308 errcode |= HAL_SWPMI_ERROR_OVR; 01309 } 01310 01311 /* SWPMI Under-Run interrupt occurred -----------------------------------------*/ 01312 if (((regisr & SWPMI_FLAG_TXUNRF) != 0U) && ((regier & SWPMI_IT_TXUNRIE) != 0U)) 01313 { 01314 /* Disable Transmit under run interrupt */ 01315 CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TXUNRIE); 01316 /* Clear Transmit under run flag */ 01317 WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TXUNRF); 01318 01319 errcode |= HAL_SWPMI_ERROR_UDR; 01320 } 01321 01322 /* Call SWPMI Error Call back function if needed --------------------------*/ 01323 if (errcode != HAL_SWPMI_ERROR_NONE) 01324 { 01325 hswpmi->ErrorCode |= errcode; 01326 01327 if ((errcode & HAL_SWPMI_ERROR_UDR) != 0U) 01328 { 01329 /* Check TXDMA transfer to abort */ 01330 if (HAL_IS_BIT_SET(hswpmi->Instance->CR, SWPMI_CR_TXDMA)) 01331 { 01332 /* Disable DMA TX at SWPMI level */ 01333 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA); 01334 01335 /* Abort the USART DMA Tx channel */ 01336 if (hswpmi->hdmatx != NULL) 01337 { 01338 /* Set the SWPMI Tx DMA Abort callback : 01339 will lead to call HAL_SWPMI_ErrorCallback() at end of DMA abort procedure */ 01340 hswpmi->hdmatx->XferAbortCallback = SWPMI_DMAAbortOnError; 01341 /* Abort DMA TX */ 01342 if (HAL_DMA_Abort_IT(hswpmi->hdmatx) != HAL_OK) 01343 { 01344 /* Call Directly hswpmi->hdmatx->XferAbortCallback function in case of error */ 01345 hswpmi->hdmatx->XferAbortCallback(hswpmi->hdmatx); 01346 } 01347 } 01348 else 01349 { 01350 /* Set the SWPMI state ready to be able to start again the process */ 01351 hswpmi->State = HAL_SWPMI_STATE_READY; 01352 01353 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1) 01354 hswpmi->ErrorCallback(hswpmi); 01355 #else 01356 HAL_SWPMI_ErrorCallback(hswpmi); 01357 #endif 01358 } 01359 } 01360 else 01361 { 01362 /* Set the SWPMI state ready to be able to start again the process */ 01363 hswpmi->State = HAL_SWPMI_STATE_READY; 01364 01365 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1) 01366 hswpmi->ErrorCallback(hswpmi); 01367 #else 01368 HAL_SWPMI_ErrorCallback(hswpmi); 01369 #endif 01370 } 01371 } 01372 else 01373 { 01374 /* Check RXDMA transfer to abort */ 01375 if (HAL_IS_BIT_SET(hswpmi->Instance->CR, SWPMI_CR_RXDMA)) 01376 { 01377 /* Disable DMA RX at SWPMI level */ 01378 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA); 01379 01380 /* Abort the USART DMA Rx channel */ 01381 if (hswpmi->hdmarx != NULL) 01382 { 01383 /* Set the SWPMI Rx DMA Abort callback : 01384 will lead to call HAL_SWPMI_ErrorCallback() at end of DMA abort procedure */ 01385 hswpmi->hdmarx->XferAbortCallback = SWPMI_DMAAbortOnError; 01386 /* Abort DMA RX */ 01387 if (HAL_DMA_Abort_IT(hswpmi->hdmarx) != HAL_OK) 01388 { 01389 /* Call Directly hswpmi->hdmarx->XferAbortCallback function in case of error */ 01390 hswpmi->hdmarx->XferAbortCallback(hswpmi->hdmarx); 01391 } 01392 } 01393 else 01394 { 01395 /* Set the SWPMI state ready to be able to start again the process */ 01396 hswpmi->State = HAL_SWPMI_STATE_READY; 01397 01398 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1) 01399 hswpmi->ErrorCallback(hswpmi); 01400 #else 01401 HAL_SWPMI_ErrorCallback(hswpmi); 01402 #endif 01403 } 01404 } 01405 else 01406 { 01407 /* Set the SWPMI state ready to be able to start again the process */ 01408 hswpmi->State = HAL_SWPMI_STATE_READY; 01409 01410 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1) 01411 hswpmi->ErrorCallback(hswpmi); 01412 #else 01413 HAL_SWPMI_ErrorCallback(hswpmi); 01414 #endif 01415 } 01416 } 01417 } 01418 01419 /* SWPMI in mode Receiver ---------------------------------------------------*/ 01420 if (((regisr & SWPMI_FLAG_RXNE) != 0U) && ((regier & SWPMI_IT_RIE) != 0U)) 01421 { 01422 SWPMI_Receive_IT(hswpmi); 01423 } 01424 01425 /* SWPMI in mode Transmitter ------------------------------------------------*/ 01426 if (((regisr & SWPMI_FLAG_TXE) != 0U) && ((regier & SWPMI_IT_TIE) != 0U)) 01427 { 01428 SWPMI_Transmit_IT(hswpmi); 01429 } 01430 01431 /* SWPMI in mode Transmitter (Transmit buffer empty) ------------------------*/ 01432 if (((regisr & SWPMI_FLAG_TXBEF) != 0U) && ((regier & SWPMI_IT_TXBEIE) != 0U)) 01433 { 01434 SWPMI_EndTransmit_IT(hswpmi); 01435 } 01436 01437 /* SWPMI in mode Receiver (Receive buffer full) -----------------------------*/ 01438 if (((regisr & SWPMI_FLAG_RXBFF) != 0U) && ((regier & SWPMI_IT_RXBFIE) != 0U)) 01439 { 01440 SWPMI_EndReceive_IT(hswpmi); 01441 } 01442 01443 /* Both Transmission and reception complete ---------------------------------*/ 01444 if (((regisr & SWPMI_FLAG_TCF) != 0U) && ((regier & SWPMI_IT_TCIE) != 0U)) 01445 { 01446 SWPMI_EndTransmitReceive_IT(hswpmi); 01447 } 01448 } 01449 01450 /** 01451 * @brief Tx Transfer completed callback. 01452 * @param hswpmi SWPMI handle 01453 * @retval None 01454 */ 01455 __weak void HAL_SWPMI_TxCpltCallback(SWPMI_HandleTypeDef *hswpmi) 01456 { 01457 /* Prevent unused argument(s) compilation warning */ 01458 UNUSED(hswpmi); 01459 01460 /* NOTE : This function should not be modified, when the callback is needed, 01461 the HAL_SWPMI_TxCpltCallback is to be implemented in the user file 01462 */ 01463 } 01464 01465 /** 01466 * @brief Tx Half Transfer completed callback. 01467 * @param hswpmi SWPMI handle 01468 * @retval None 01469 */ 01470 __weak void HAL_SWPMI_TxHalfCpltCallback(SWPMI_HandleTypeDef *hswpmi) 01471 { 01472 /* Prevent unused argument(s) compilation warning */ 01473 UNUSED(hswpmi); 01474 01475 /* NOTE: This function should not be modified, when the callback is needed, 01476 the HAL_SWPMI_TxHalfCpltCallback is to be implemented in the user file 01477 */ 01478 } 01479 01480 /** 01481 * @brief Rx Transfer completed callback. 01482 * @param hswpmi SWPMI handle 01483 * @retval None 01484 */ 01485 __weak void HAL_SWPMI_RxCpltCallback(SWPMI_HandleTypeDef *hswpmi) 01486 { 01487 /* Prevent unused argument(s) compilation warning */ 01488 UNUSED(hswpmi); 01489 01490 /* NOTE : This function should not be modified, when the callback is needed, 01491 the HAL_SWPMI_RxCpltCallback is to be implemented in the user file 01492 */ 01493 } 01494 01495 /** 01496 * @brief Rx Half Transfer completed callback. 01497 * @param hswpmi SWPMI handle 01498 * @retval None 01499 */ 01500 __weak void HAL_SWPMI_RxHalfCpltCallback(SWPMI_HandleTypeDef *hswpmi) 01501 { 01502 /* Prevent unused argument(s) compilation warning */ 01503 UNUSED(hswpmi); 01504 01505 /* NOTE: This function should not be modified, when the callback is needed, 01506 the HAL_SWPMI_RxHalfCpltCallback is to be implemented in the user file 01507 */ 01508 } 01509 01510 /** 01511 * @brief SWPMI error callback. 01512 * @param hswpmi SWPMI handle 01513 * @retval None 01514 */ 01515 __weak void HAL_SWPMI_ErrorCallback(SWPMI_HandleTypeDef *hswpmi) 01516 { 01517 /* Prevent unused argument(s) compilation warning */ 01518 UNUSED(hswpmi); 01519 01520 /* NOTE : This function should not be modified, when the callback is needed, 01521 the HAL_SWPMI_ErrorCallback is to be implemented in the user file 01522 */ 01523 } 01524 01525 /** 01526 * @} 01527 */ 01528 01529 /** @defgroup SWPMI_Exported_Group4 Peripheral Control methods 01530 * @brief SWPMI control functions 01531 * 01532 @verbatim 01533 =============================================================================== 01534 ##### Peripheral Control methods ##### 01535 =============================================================================== 01536 [..] 01537 This subsection provides a set of functions allowing to control the SWPMI. 01538 (+) HAL_SWPMI_GetState() API is helpful to check in run-time the state of the SWPMI peripheral 01539 (+) HAL_SWPMI_GetError() API is helpful to check in run-time the error state of the SWPMI peripheral 01540 @endverbatim 01541 * @{ 01542 */ 01543 01544 /** 01545 * @brief Return the SWPMI handle state. 01546 * @param hswpmi SWPMI handle 01547 * @retval HAL state 01548 */ 01549 HAL_SWPMI_StateTypeDef HAL_SWPMI_GetState(SWPMI_HandleTypeDef *hswpmi) 01550 { 01551 /* Return SWPMI handle state */ 01552 return hswpmi->State; 01553 } 01554 01555 /** 01556 * @brief Return the SWPMI error code. 01557 * @param hswpmi : pointer to a SWPMI_HandleTypeDef structure that contains 01558 * the configuration information for the specified SWPMI. 01559 * @retval SWPMI Error Code 01560 */ 01561 uint32_t HAL_SWPMI_GetError(SWPMI_HandleTypeDef *hswpmi) 01562 { 01563 return hswpmi->ErrorCode; 01564 } 01565 01566 /** 01567 * @} 01568 */ 01569 01570 /** 01571 * @} 01572 */ 01573 01574 /* Private functions ---------------------------------------------------------*/ 01575 01576 /** @defgroup SWPMI_Private_Functions SWPMI Private Functions 01577 * @{ 01578 */ 01579 01580 /** 01581 * @brief Transmit an amount of data in interrupt mode. 01582 * @note Function called under interruption only, once interruptions have been enabled by HAL_SWPMI_Transmit_IT() 01583 * @param hswpmi SWPMI handle 01584 * @retval None 01585 */ 01586 static void SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi) 01587 { 01588 HAL_SWPMI_StateTypeDef tmp_state = hswpmi->State; 01589 01590 if ((tmp_state == HAL_SWPMI_STATE_BUSY_TX) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX_RX)) 01591 { 01592 if (hswpmi->TxXferCount == 0U) 01593 { 01594 /* Disable the SWPMI TXE and Underrun Interrupts */ 01595 CLEAR_BIT(hswpmi->Instance->IER, (SWPMI_IT_TIE | SWPMI_IT_TXUNRIE)); 01596 } 01597 else 01598 { 01599 hswpmi->Instance->TDR = (uint32_t) * hswpmi->pTxBuffPtr; 01600 hswpmi->pTxBuffPtr++; 01601 hswpmi->TxXferCount--; 01602 } 01603 } 01604 else 01605 { 01606 /* nothing to do */ 01607 } 01608 } 01609 01610 /** 01611 * @brief Wraps up transmission in non-blocking mode. 01612 * @param hswpmi SWPMI handle 01613 * @retval None 01614 */ 01615 static void SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef *hswpmi) 01616 { 01617 /* Clear the SWPMI Transmit buffer empty Flag */ 01618 WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TXBEF); 01619 /* Disable the all SWPMI Transmit Interrupts */ 01620 CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE); 01621 01622 /* Check if a receive Process is ongoing or not */ 01623 if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX) 01624 { 01625 hswpmi->State = HAL_SWPMI_STATE_BUSY_RX; 01626 } 01627 else 01628 { 01629 hswpmi->State = HAL_SWPMI_STATE_READY; 01630 } 01631 01632 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1) 01633 hswpmi->TxCpltCallback(hswpmi); 01634 #else 01635 HAL_SWPMI_TxCpltCallback(hswpmi); 01636 #endif 01637 } 01638 01639 /** 01640 * @brief Receive an amount of data in interrupt mode. 01641 * @note Function called under interruption only, once interruptions have been enabled by HAL_SWPMI_Receive_IT() 01642 * @param hswpmi SWPMI handle 01643 * @retval None 01644 */ 01645 static void SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi) 01646 { 01647 HAL_SWPMI_StateTypeDef tmp_state = hswpmi->State; 01648 01649 if ((tmp_state == HAL_SWPMI_STATE_BUSY_RX) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX_RX)) 01650 { 01651 *hswpmi->pRxBuffPtr = (uint32_t)(hswpmi->Instance->RDR); 01652 hswpmi->pRxBuffPtr++; 01653 01654 --hswpmi->RxXferCount; 01655 if (hswpmi->RxXferCount == 0U) 01656 { 01657 /* Wait for RXBFF flag to update state */ 01658 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1) 01659 hswpmi->RxCpltCallback(hswpmi); 01660 #else 01661 HAL_SWPMI_RxCpltCallback(hswpmi); 01662 #endif 01663 } 01664 } 01665 else 01666 { 01667 /* nothing to do */ 01668 } 01669 } 01670 01671 /** 01672 * @brief Wraps up reception in non-blocking mode. 01673 * @param hswpmi SWPMI handle 01674 * @retval None 01675 */ 01676 static void SWPMI_EndReceive_IT(SWPMI_HandleTypeDef *hswpmi) 01677 { 01678 /* Clear the SWPMI Receive buffer full Flag */ 01679 WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF); 01680 /* Disable the all SWPMI Receive Interrupts */ 01681 CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE); 01682 01683 /* Check if a transmit Process is ongoing or not */ 01684 if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX) 01685 { 01686 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX; 01687 } 01688 else 01689 { 01690 hswpmi->State = HAL_SWPMI_STATE_READY; 01691 } 01692 } 01693 01694 /** 01695 * @brief Wraps up transmission and reception in non-blocking mode. 01696 * @param hswpmi SWPMI handle 01697 * @retval None 01698 */ 01699 static void SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef *hswpmi) 01700 { 01701 /* Clear the SWPMI Transmission Complete Flag */ 01702 WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TCF); 01703 /* Disable the SWPMI Transmission Complete Interrupt */ 01704 CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TCIE); 01705 01706 /* Check if a receive Process is ongoing or not */ 01707 if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX) 01708 { 01709 hswpmi->State = HAL_SWPMI_STATE_BUSY_RX; 01710 } 01711 else if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX) 01712 { 01713 hswpmi->State = HAL_SWPMI_STATE_READY; 01714 } 01715 else 01716 { 01717 /* nothing to do */ 01718 } 01719 } 01720 01721 /** 01722 * @brief DMA SWPMI transmit process complete callback. 01723 * @param hdma DMA handle 01724 * @retval None 01725 */ 01726 static void SWPMI_DMATransmitCplt(DMA_HandleTypeDef *hdma) 01727 { 01728 SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 01729 uint32_t tickstart; 01730 01731 /* DMA Normal mode*/ 01732 if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U) 01733 { 01734 hswpmi->TxXferCount = 0U; 01735 01736 /* Disable the DMA transfer for transmit request by setting the TXDMA bit 01737 in the SWPMI CR register */ 01738 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA); 01739 01740 /* Init tickstart for timeout management*/ 01741 tickstart = HAL_GetTick(); 01742 01743 /* Wait the TXBEF */ 01744 if (SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, tickstart, SWPMI_TIMEOUT_VALUE) != HAL_OK) 01745 { 01746 /* Timeout occurred */ 01747 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_TXBEF_TIMEOUT; 01748 01749 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1) 01750 hswpmi->ErrorCallback(hswpmi); 01751 #else 01752 HAL_SWPMI_ErrorCallback(hswpmi); 01753 #endif 01754 } 01755 else 01756 { 01757 /* No Timeout */ 01758 /* Check if a receive process is ongoing or not */ 01759 if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX) 01760 { 01761 hswpmi->State = HAL_SWPMI_STATE_BUSY_RX; 01762 } 01763 else 01764 { 01765 hswpmi->State = HAL_SWPMI_STATE_READY; 01766 } 01767 01768 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1) 01769 hswpmi->TxCpltCallback(hswpmi); 01770 #else 01771 HAL_SWPMI_TxCpltCallback(hswpmi); 01772 #endif 01773 } 01774 } 01775 /* DMA Circular mode */ 01776 else 01777 { 01778 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1) 01779 hswpmi->TxCpltCallback(hswpmi); 01780 #else 01781 HAL_SWPMI_TxCpltCallback(hswpmi); 01782 #endif 01783 } 01784 } 01785 01786 /** 01787 * @brief DMA SWPMI transmit process half complete callback. 01788 * @param hdma DMA handle 01789 * @retval None 01790 */ 01791 static void SWPMI_DMATxHalfCplt(DMA_HandleTypeDef *hdma) 01792 { 01793 SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 01794 01795 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1) 01796 hswpmi->TxHalfCpltCallback(hswpmi); 01797 #else 01798 HAL_SWPMI_TxHalfCpltCallback(hswpmi); 01799 #endif 01800 } 01801 01802 01803 /** 01804 * @brief DMA SWPMI receive process complete callback. 01805 * @param hdma DMA handle 01806 * @retval None 01807 */ 01808 static void SWPMI_DMAReceiveCplt(DMA_HandleTypeDef *hdma) 01809 { 01810 SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 01811 01812 /* DMA Normal mode*/ 01813 if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U) 01814 { 01815 hswpmi->RxXferCount = 0U; 01816 01817 /* Disable the DMA transfer for the receiver request by setting the RXDMA bit 01818 in the SWPMI CR register */ 01819 CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA); 01820 01821 /* Check if a transmit Process is ongoing or not */ 01822 if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX) 01823 { 01824 hswpmi->State = HAL_SWPMI_STATE_BUSY_TX; 01825 } 01826 else 01827 { 01828 hswpmi->State = HAL_SWPMI_STATE_READY; 01829 } 01830 } 01831 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1) 01832 hswpmi->RxCpltCallback(hswpmi); 01833 #else 01834 HAL_SWPMI_RxCpltCallback(hswpmi); 01835 #endif 01836 } 01837 01838 /** 01839 * @brief DMA SWPMI receive process half complete callback. 01840 * @param hdma DMA handle 01841 * @retval None 01842 */ 01843 static void SWPMI_DMARxHalfCplt(DMA_HandleTypeDef *hdma) 01844 { 01845 SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 01846 01847 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1) 01848 hswpmi->RxHalfCpltCallback(hswpmi); 01849 #else 01850 HAL_SWPMI_RxHalfCpltCallback(hswpmi); 01851 #endif 01852 } 01853 01854 /** 01855 * @brief DMA SWPMI communication error callback. 01856 * @param hdma DMA handle 01857 * @retval None 01858 */ 01859 static void SWPMI_DMAError(DMA_HandleTypeDef *hdma) 01860 { 01861 SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 01862 01863 /* Update handle */ 01864 hswpmi->RxXferCount = 0U; 01865 hswpmi->TxXferCount = 0U; 01866 hswpmi->State = HAL_SWPMI_STATE_READY; 01867 hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA; 01868 01869 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1) 01870 hswpmi->ErrorCallback(hswpmi); 01871 #else 01872 HAL_SWPMI_ErrorCallback(hswpmi); 01873 #endif 01874 } 01875 01876 /** 01877 * @brief DMA SWPMI communication abort callback. 01878 * @param hdma DMA handle 01879 * @retval None 01880 */ 01881 static void SWPMI_DMAAbortOnError(DMA_HandleTypeDef *hdma) 01882 { 01883 SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 01884 01885 /* Update handle */ 01886 hswpmi->RxXferCount = 0U; 01887 hswpmi->TxXferCount = 0U; 01888 hswpmi->State = HAL_SWPMI_STATE_READY; 01889 01890 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1) 01891 hswpmi->ErrorCallback(hswpmi); 01892 #else 01893 HAL_SWPMI_ErrorCallback(hswpmi); 01894 #endif 01895 } 01896 01897 /** 01898 * @brief Handle SWPMI Communication Timeout. 01899 * @param hswpmi SWPMI handle 01900 * @param Flag specifies the SWPMI flag to check. 01901 * @param Tickstart Tick start value 01902 * @param Timeout timeout duration. 01903 * @retval HAL status 01904 */ 01905 static HAL_StatusTypeDef SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef *hswpmi, uint32_t Flag, uint32_t Tickstart, uint32_t Timeout) 01906 { 01907 HAL_StatusTypeDef status = HAL_OK; 01908 01909 /* Wait until flag is set */ 01910 while (!(HAL_IS_BIT_SET(hswpmi->Instance->ISR, Flag))) 01911 { 01912 /* Check for the Timeout */ 01913 if ((((HAL_GetTick() - Tickstart) > Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) 01914 { 01915 /* Set the SWPMI state ready to be able to start again the process */ 01916 hswpmi->State = HAL_SWPMI_STATE_READY; 01917 01918 status = HAL_TIMEOUT; 01919 break; 01920 } 01921 } 01922 01923 return status; 01924 } 01925 01926 /** 01927 * @} 01928 */ 01929 01930 #endif /* HAL_SWPMI_MODULE_ENABLED */ 01931 01932 /** 01933 * @} 01934 */ 01935 01936 #endif /* SWPMI1 */ 01937 01938 /** 01939 * @} 01940 */