STM32L443xx HAL User Manual
stm32l4xx_hal_swpmi.c
Go to the documentation of this file.
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   */