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