Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:09

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_swpmi.c
0004   * @author  MCD Application Team
0005   * @brief   SWPMI HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the Single Wire Protocol Master Interface (SWPMI).
0008   *           + Initialization and Configuration
0009   *           + Data transfers functions
0010   *           + DMA transfers management
0011   *           + Interrupts and flags management
0012   ******************************************************************************
0013   * @attention
0014   *
0015   * Copyright (c) 2017 STMicroelectronics.
0016   * All rights reserved.
0017   *
0018   * This software is licensed under terms that can be found in the LICENSE file
0019   * in the root directory of this software component.
0020   * If no LICENSE file comes with this software, it is provided AS-IS.
0021   *
0022   ******************************************************************************
0023   @verbatim
0024  ===============================================================================
0025                         ##### How to use this driver #####
0026  ===============================================================================
0027   [..]
0028      The SWPMI HAL driver can be used as follows:
0029 
0030     (#) Declare a SWPMI_HandleTypeDef handle structure (eg. SWPMI_HandleTypeDef hswpmi).
0031 
0032     (#) Initialize the SWPMI low level resources by implementing the HAL_SWPMI_MspInit() API:
0033         (##) Enable the SWPMIx interface clock with __HAL_RCC_SWPMIx_CLK_ENABLE().
0034         (##) SWPMI IO configuration:
0035             (+++) Enable the clock for the SWPMI GPIO.
0036             (+++) Configure these SWPMI pins as alternate function pull-up.
0037         (##) NVIC configuration if you need to use interrupt process (HAL_SWPMI_Transmit_IT()
0038              and HAL_SWPMI_Receive_IT() APIs):
0039             (+++) Configure the SWPMIx interrupt priority with HAL_NVIC_SetPriority().
0040             (+++) Enable the NVIC SWPMI IRQ handle with HAL_NVIC_EnableIRQ().
0041 
0042         (##) DMA Configuration if you need to use DMA process (HAL_SWPMI_Transmit_DMA()
0043              and HAL_SWPMI_Receive_DMA() APIs):
0044             (+++) Declare a DMA handle structure for the Tx/Rx streams.
0045             (+++) Enable the DMAx interface clock.
0046             (+++) Configure the declared DMA handle structure with the required
0047                   Tx/Rx parameters.
0048             (+++) Configure the DMA Tx/Rx streams and requests.
0049             (+++) Associate the initialized DMA handle to the SWPMI DMA Tx/Rx handle.
0050             (+++) Configure the priority and enable the NVIC for the transfer complete
0051                   interrupt on the DMA Tx/Rx streams.
0052 
0053     (#) Program the Bite Rate, Tx Buffering mode, Rx Buffering mode in the Init structure.
0054 
0055     (#) Enable the SWPMI peripheral by calling the HAL_SWPMI_Init() function.
0056 
0057   [..]
0058     Three operation modes are available within this driver :
0059 
0060     *** Polling mode IO operation ***
0061     =================================
0062     [..]
0063       (+) Send an amount of data in blocking mode using HAL_SWPMI_Transmit()
0064       (+) Receive an amount of data in blocking mode using HAL_SWPMI_Receive()
0065 
0066     *** Interrupt mode IO operation ***
0067     ===================================
0068     [..]
0069       (+) Send an amount of data in non-blocking mode using HAL_SWPMI_Transmit_IT()
0070       (+) At transmission end of transfer HAL_SWPMI_TxCpltCallback() is executed and user can
0071           add his own code by customization of function pointer HAL_SWPMI_TxCpltCallback()
0072       (+) Receive an amount of data in non-blocking mode using HAL_SWPMI_Receive_IT()
0073       (+) At reception end of transfer HAL_SWPMI_RxCpltCallback() is executed and user can
0074           add his own code by customization of function pointer HAL_SWPMI_RxCpltCallback()
0075       (+) In case of flag error, HAL_SWPMI_ErrorCallback() function is executed and user can
0076           add his own code by customization of function pointer HAL_SWPMI_ErrorCallback()
0077 
0078     *** DMA mode IO operation ***
0079     =============================
0080     [..]
0081       (+) Send an amount of data in non-blocking mode (DMA) using HAL_SWPMI_Transmit_DMA()
0082       (+) At transmission end of transfer HAL_SWPMI_TxCpltCallback() is executed and user can
0083           add his own code by customization of function pointer HAL_SWPMI_TxCpltCallback()
0084       (+) Receive an amount of data in non-blocking mode (DMA) using HAL_SWPMI_Receive_DMA()
0085       (+) At reception end of transfer HAL_SWPMI_RxCpltCallback() is executed and user can
0086           add his own code by customization of function pointer HAL_SWPMI_RxCpltCallback()
0087       (+) In case of flag error, HAL_SWPMI_ErrorCallback() function is executed and user can
0088           add his own code by customization of function pointer HAL_SWPMI_ErrorCallback()
0089       (+) Stop the DMA Transfer using HAL_SWPMI_DMAStop()
0090 
0091     *** SWPMI HAL driver additional function list ***
0092     ===============================================
0093     [..]
0094       Below the list the others API available SWPMI HAL driver :
0095 
0096       (+) HAL_SWPMI_EnableLoopback(): Enable the loopback mode for test purpose only
0097       (+) HAL_SWPMI_DisableLoopback(): Disable the loopback mode
0098 
0099     *** SWPMI HAL driver macros list ***
0100     ==================================
0101     [..]
0102       Below the list of most used macros in SWPMI HAL driver :
0103 
0104       (+) __HAL_SWPMI_ENABLE(): Enable the SWPMI peripheral
0105       (+) __HAL_SWPMI_DISABLE(): Disable the SWPMI peripheral
0106       (+) __HAL_SWPMI_TRANSCEIVER_ENABLE(): Enable the SWPMI peripheral transceiver
0107       (+) __HAL_SWPMI_TRANSCEIVER_DISABLE(): Disable the SWPMI peripheral transceiver
0108       (+) __HAL_SWPMI_ENABLE_IT(): Enable the specified SWPMI interrupts
0109       (+) __HAL_SWPMI_DISABLE_IT(): Disable the specified SWPMI interrupts
0110       (+) __HAL_SWPMI_GET_IT_SOURCE(): Check if the specified SWPMI interrupt source is
0111           enabled or disabled
0112       (+) __HAL_SWPMI_GET_FLAG(): Check whether the specified SWPMI flag is set or not
0113 
0114     *** Callback registration ***
0115     =============================
0116     [..]
0117       The compilation define USE_HAL_SWPMI_REGISTER_CALLBACKS when set to 1
0118       allows the user to configure dynamically the driver callbacks.
0119     [..]
0120       Use function HAL_SWPMI_RegisterCallback() to register a user callback. It allows
0121       to register the following callbacks:
0122       (+) RxCpltCallback     : SWPMI receive complete.
0123       (+) RxHalfCpltCallback : SWPMI receive half complete.
0124       (+) TxCpltCallback     : SWPMI transmit complete.
0125       (+) TxHalfCpltCallback : SWPMI transmit half complete.
0126       (+) ErrorCallback      : SWPMI error.
0127       (+) MspInitCallback    : SWPMI MspInit.
0128       (+) MspDeInitCallback  : SWPMI MspDeInit.
0129     [..]
0130     This function takes as parameters the HAL peripheral handle, the callback ID
0131     and a pointer to the user callback function.
0132     [..]
0133     Use function HAL_SWPMI_UnRegisterCallback() to reset a callback to the default
0134     weak (surcharged) function.
0135     HAL_SWPMI_UnRegisterCallback() takes as parameters the HAL peripheral handle,
0136     and the callback ID.
0137     This function allows to reset following callbacks:
0138       (+) RxCpltCallback     : SWPMI receive complete.
0139       (+) RxHalfCpltCallback : SWPMI receive half complete.
0140       (+) TxCpltCallback     : SWPMI transmit complete.
0141       (+) TxHalfCpltCallback : SWPMI transmit half complete.
0142       (+) ErrorCallback      : SWPMI error.
0143       (+) MspInitCallback    : SWPMI MspInit.
0144       (+) MspDeInitCallback  : SWPMI MspDeInit.
0145     [..]
0146     By default, after the HAL_SWPMI_Init and if the state is HAL_SWPMI_STATE_RESET
0147     all callbacks are reset to the corresponding legacy weak (surcharged) functions:
0148     examples HAL_SWPMI_RxCpltCallback(), HAL_SWPMI_ErrorCallback().
0149     Exception done for MspInit and MspDeInit callbacks that are respectively
0150     reset to the legacy weak (surcharged) functions in the HAL_SWPMI_Init
0151     and HAL_SWPMI_DeInit only when these callbacks are null (not registered beforehand).
0152     If not, MspInit or MspDeInit are not null, the HAL_SWPMI_Init and HAL_SWPMI_DeInit
0153     keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
0154     [..]
0155     Callbacks can be registered/unregistered in READY state only.
0156     Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
0157     in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
0158     during the Init/DeInit.
0159     In that case first register the MspInit/MspDeInit user callbacks
0160     using HAL_SWPMI_RegisterCallback before calling HAL_SWPMI_DeInit
0161     or HAL_SWPMI_Init function.
0162     [..]
0163     When the compilation define USE_HAL_SWPMI_REGISTER_CALLBACKS is set to 0 or
0164     not defined, the callback registering feature is not available
0165     and weak (surcharged) callbacks are used.
0166 
0167   @endverbatim
0168   */
0169 
0170 /* Includes ------------------------------------------------------------------*/
0171 #include "stm32h7xx_hal.h"
0172 
0173 /** @addtogroup STM32H7xx_HAL_Driver
0174   * @{
0175   */
0176 
0177 
0178 /** @defgroup SWPMI SWPMI
0179   * @ingroup RTEMSBSPsARMSTM32H7
0180   * @brief HAL SWPMI module driver
0181   * @{
0182   */
0183 #ifdef HAL_SWPMI_MODULE_ENABLED
0184 
0185 /* Private typedef -----------------------------------------------------------*/
0186 /* Private define ------------------------------------------------------------*/
0187 /* Private constants ---------------------------------------------------------*/
0188 /** @addtogroup SWPMI_Private_Constants SWPMI Private Constants
0189   * @{
0190   */
0191 #define SWPMI_TIMEOUT_VALUE                   22000U   /* End of transmission timeout */
0192 #define SWPMI_TRANSCEIVER_RDY_TIMEOUT_VALUE    2000U   /* Transceiver ready timeout */
0193 
0194 /**
0195   * @}
0196   */
0197 
0198 /* Private macros ------------------------------------------------------------*/
0199 /* Private variables ---------------------------------------------------------*/
0200 /* Private function prototypes -----------------------------------------------*/
0201 static void SWPMI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
0202 static void SWPMI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
0203 static void SWPMI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
0204 static void SWPMI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
0205 static void SWPMI_DMAError(DMA_HandleTypeDef *hdma);
0206 static void SWPMI_DMAAbortOnError(DMA_HandleTypeDef *hdma);
0207 static void SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi);
0208 static void SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef *hswpmi);
0209 static void SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi);
0210 static void SWPMI_EndReceive_IT(SWPMI_HandleTypeDef *hswpmi);
0211 static void SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef *hswpmi);
0212 static HAL_StatusTypeDef SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef *hswpmi, uint32_t Flag, uint32_t Tickstart, uint32_t Timeout);
0213 
0214 /* Exported functions --------------------------------------------------------*/
0215 
0216 /** @defgroup SWPMI_Exported_Functions SWPMI Exported Functions
0217   * @ingroup RTEMSBSPsARMSTM32H7
0218   * @{
0219   */
0220 
0221 /** @defgroup SWPMI_Exported_Group1 Initialization/de-initialization methods
0222   * @ingroup RTEMSBSPsARMSTM32H7
0223   *  @brief    Initialization and Configuration functions
0224   *
0225 @verbatim
0226  ===============================================================================
0227             ##### Initialization and Configuration functions #####
0228  ===============================================================================
0229     [..]  This section provides functions allowing to:
0230       (+) Initialize and configure the SWPMI peripheral.
0231       (+) De-initialize the SWPMI peripheral.
0232 
0233 @endverbatim
0234   * @{
0235   */
0236 
0237 /**
0238   * @brief Initialize the SWPMI peripheral according to the specified parameters in the SWPMI_InitTypeDef.
0239   * @param hswpmi SWPMI handle
0240   * @retval HAL status
0241   */
0242 HAL_StatusTypeDef HAL_SWPMI_Init(SWPMI_HandleTypeDef *hswpmi)
0243 {
0244   HAL_StatusTypeDef status = HAL_OK;
0245   uint32_t tickstart = HAL_GetTick();
0246 
0247   /* Check the SWPMI handle allocation */
0248   if (hswpmi == NULL)
0249   {
0250     status = HAL_ERROR;
0251   }
0252   else
0253   {
0254     /* Check the parameters */
0255     assert_param(IS_SWPMI_VOLTAGE_CLASS(hswpmi->Init.VoltageClass));
0256     assert_param(IS_SWPMI_BITRATE_VALUE(hswpmi->Init.BitRate));
0257     assert_param(IS_SWPMI_TX_BUFFERING_MODE(hswpmi->Init.TxBufferingMode));
0258     assert_param(IS_SWPMI_RX_BUFFERING_MODE(hswpmi->Init.RxBufferingMode));
0259 
0260     if (hswpmi->State == HAL_SWPMI_STATE_RESET)
0261     {
0262       /* Allocate lock resource and initialize it */
0263       hswpmi->Lock = HAL_UNLOCKED;
0264 
0265 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
0266       /* Reset callback pointers to the weak predefined callbacks */
0267       hswpmi->RxCpltCallback     = HAL_SWPMI_RxCpltCallback;
0268       hswpmi->RxHalfCpltCallback = HAL_SWPMI_RxHalfCpltCallback;
0269       hswpmi->TxCpltCallback     = HAL_SWPMI_TxCpltCallback;
0270       hswpmi->TxHalfCpltCallback = HAL_SWPMI_TxHalfCpltCallback;
0271       hswpmi->ErrorCallback      = HAL_SWPMI_ErrorCallback;
0272 
0273       /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
0274       if (hswpmi->MspInitCallback == NULL)
0275       {
0276         hswpmi->MspInitCallback = HAL_SWPMI_MspInit;
0277       }
0278       hswpmi->MspInitCallback(hswpmi);
0279 #else
0280       /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
0281       HAL_SWPMI_MspInit(hswpmi);
0282 #endif
0283     }
0284 
0285     hswpmi->State = HAL_SWPMI_STATE_BUSY;
0286 
0287     /* Disable SWPMI interface */
0288     CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
0289 
0290     /* Clear all SWPMI interface flags */
0291     WRITE_REG(hswpmi->Instance->ICR, 0x099F);
0292 
0293     /* Apply Voltage class selection */
0294     MODIFY_REG(hswpmi->Instance->OR, SWPMI_OR_CLASS, hswpmi->Init.VoltageClass);
0295 
0296 
0297     /* Configure the BRR register (Bitrate) */
0298     WRITE_REG(hswpmi->Instance->BRR, hswpmi->Init.BitRate);
0299 
0300     /* Apply SWPMI CR configuration */
0301     MODIFY_REG(hswpmi->Instance->CR, \
0302                SWPMI_CR_RXDMA | SWPMI_CR_TXDMA  | SWPMI_CR_RXMODE | SWPMI_CR_TXMODE, \
0303                hswpmi->Init.TxBufferingMode | hswpmi->Init.RxBufferingMode);
0304 
0305     /* Enable the SWPMI transceiver */
0306     SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPEN);
0307     /* Wait on RDYF flag to activate SWPMI */
0308     if (SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_RDYF, tickstart, SWPMI_TRANSCEIVER_RDY_TIMEOUT_VALUE) != HAL_OK)
0309     {
0310       status = HAL_TIMEOUT;
0311     }
0312 
0313     if (status == HAL_OK)
0314     {
0315       hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
0316       hswpmi->State = HAL_SWPMI_STATE_READY;
0317 
0318       /* Enable SWPMI peripheral */
0319       SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
0320     }
0321     else
0322     {
0323       hswpmi->ErrorCode = HAL_SWPMI_ERROR_TRANSCEIVER_NOT_READY;
0324       hswpmi->State = HAL_SWPMI_STATE_ERROR;
0325     }
0326   }
0327 
0328   return status;
0329 }
0330 
0331 /**
0332   * @brief De-initialize the SWPMI peripheral.
0333   * @param hswpmi SWPMI handle
0334   * @retval HAL status
0335   */
0336 HAL_StatusTypeDef HAL_SWPMI_DeInit(SWPMI_HandleTypeDef *hswpmi)
0337 {
0338   HAL_StatusTypeDef status = HAL_OK;
0339 
0340   /* Check the SWPMI handle allocation */
0341   if (hswpmi == NULL)
0342   {
0343     status = HAL_ERROR;
0344   }
0345   else
0346   {
0347     /* Check the parameters */
0348     assert_param(IS_SWPMI_INSTANCE(hswpmi->Instance));
0349 
0350     hswpmi->State = HAL_SWPMI_STATE_BUSY;
0351 
0352     /* Disable SWPMI interface */
0353     CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
0354 
0355     /* Disable Loopback mode */
0356     CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);
0357 
0358     /* Disable SWPMI transceiver */
0359     CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPEN);
0360 
0361 
0362     /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
0363 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
0364     if (hswpmi->MspDeInitCallback == NULL)
0365     {
0366       hswpmi->MspDeInitCallback = HAL_SWPMI_MspDeInit;
0367     }
0368     hswpmi->MspDeInitCallback(hswpmi);
0369 #else
0370     HAL_SWPMI_MspDeInit(hswpmi);
0371 #endif
0372 
0373     hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
0374     hswpmi->State = HAL_SWPMI_STATE_RESET;
0375 
0376     /* Release Lock */
0377     __HAL_UNLOCK(hswpmi);
0378   }
0379 
0380   return status;
0381 }
0382 
0383 /**
0384   * @brief Initialize the SWPMI MSP.
0385   * @param hswpmi SWPMI handle
0386   * @retval None
0387   */
0388 __weak void HAL_SWPMI_MspInit(SWPMI_HandleTypeDef *hswpmi)
0389 {
0390   /* Prevent unused argument(s) compilation warning */
0391   UNUSED(hswpmi);
0392 
0393   /* NOTE : This function should not be modified, when the callback is needed,
0394             the HAL_SWPMI_MspInit can be implemented in the user file
0395    */
0396 }
0397 
0398 /**
0399   * @brief DeInitialize the SWPMI MSP.
0400   * @param hswpmi SWPMI handle
0401   * @retval None
0402   */
0403 __weak void HAL_SWPMI_MspDeInit(SWPMI_HandleTypeDef *hswpmi)
0404 {
0405   /* Prevent unused argument(s) compilation warning */
0406   UNUSED(hswpmi);
0407 
0408   /* NOTE : This function should not be modified, when the callback is needed,
0409             the HAL_SWPMI_MspDeInit can be implemented in the user file
0410    */
0411 }
0412 
0413 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
0414 /**
0415   * @brief  Register a user SWPMI callback
0416   *         to be used instead of the weak predefined callback.
0417   * @param  hswpmi SWPMI handle.
0418   * @param  CallbackID ID of the callback to be registered.
0419   *         This parameter can be one of the following values:
0420   *           @arg @ref HAL_SWPMI_RX_COMPLETE_CB_ID receive complete callback ID.
0421   *           @arg @ref HAL_SWPMI_RX_HALFCOMPLETE_CB_ID receive half complete callback ID.
0422   *           @arg @ref HAL_SWPMI_TX_COMPLETE_CB_ID transmit complete callback ID.
0423   *           @arg @ref HAL_SWPMI_TX_HALFCOMPLETE_CB_ID transmit half complete callback ID.
0424   *           @arg @ref HAL_SWPMI_ERROR_CB_ID error callback ID.
0425   *           @arg @ref HAL_SWPMI_MSPINIT_CB_ID MSP init callback ID.
0426   *           @arg @ref HAL_SWPMI_MSPDEINIT_CB_ID MSP de-init callback ID.
0427   * @param  pCallback pointer to the callback function.
0428   * @retval HAL status.
0429   */
0430 HAL_StatusTypeDef HAL_SWPMI_RegisterCallback(SWPMI_HandleTypeDef        *hswpmi,
0431                                              HAL_SWPMI_CallbackIDTypeDef CallbackID,
0432                                              pSWPMI_CallbackTypeDef      pCallback)
0433 {
0434   HAL_StatusTypeDef status = HAL_OK;
0435 
0436   if (pCallback == NULL)
0437   {
0438     /* update the error code */
0439     hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
0440     /* update return status */
0441     status = HAL_ERROR;
0442   }
0443   else
0444   {
0445     if (hswpmi->State == HAL_SWPMI_STATE_READY)
0446     {
0447       switch (CallbackID)
0448       {
0449         case HAL_SWPMI_RX_COMPLETE_CB_ID :
0450           hswpmi->RxCpltCallback = pCallback;
0451           break;
0452         case HAL_SWPMI_RX_HALFCOMPLETE_CB_ID :
0453           hswpmi->RxHalfCpltCallback = pCallback;
0454           break;
0455         case HAL_SWPMI_TX_COMPLETE_CB_ID :
0456           hswpmi->TxCpltCallback = pCallback;
0457           break;
0458         case HAL_SWPMI_TX_HALFCOMPLETE_CB_ID :
0459           hswpmi->TxHalfCpltCallback = pCallback;
0460           break;
0461         case HAL_SWPMI_ERROR_CB_ID :
0462           hswpmi->ErrorCallback = pCallback;
0463           break;
0464         case HAL_SWPMI_MSPINIT_CB_ID :
0465           hswpmi->MspInitCallback = pCallback;
0466           break;
0467         case HAL_SWPMI_MSPDEINIT_CB_ID :
0468           hswpmi->MspDeInitCallback = pCallback;
0469           break;
0470         default :
0471           /* update the error code */
0472           hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
0473           /* update return status */
0474           status = HAL_ERROR;
0475           break;
0476       }
0477     }
0478     else if (hswpmi->State == HAL_SWPMI_STATE_RESET)
0479     {
0480       switch (CallbackID)
0481       {
0482         case HAL_SWPMI_MSPINIT_CB_ID :
0483           hswpmi->MspInitCallback = pCallback;
0484           break;
0485         case HAL_SWPMI_MSPDEINIT_CB_ID :
0486           hswpmi->MspDeInitCallback = pCallback;
0487           break;
0488         default :
0489           /* update the error code */
0490           hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
0491           /* update return status */
0492           status = HAL_ERROR;
0493           break;
0494       }
0495     }
0496     else
0497     {
0498       /* update the error code */
0499       hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
0500       /* update return status */
0501       status = HAL_ERROR;
0502     }
0503   }
0504   return status;
0505 }
0506 
0507 /**
0508   * @brief  Unregister a user SWPMI callback.
0509   *         SWPMI callback is redirected to the weak predefined callback.
0510   * @param  hswpmi SWPMI handle.
0511   * @param  CallbackID ID of the callback to be unregistered.
0512   *         This parameter can be one of the following values:
0513   *           @arg @ref HAL_SWPMI_RX_COMPLETE_CB_ID receive complete callback ID.
0514   *           @arg @ref HAL_SWPMI_RX_HALFCOMPLETE_CB_ID receive half complete callback ID.
0515   *           @arg @ref HAL_SWPMI_TX_COMPLETE_CB_ID transmit complete callback ID.
0516   *           @arg @ref HAL_SWPMI_TX_HALFCOMPLETE_CB_ID transmit half complete callback ID.
0517   *           @arg @ref HAL_SWPMI_ERROR_CB_ID error callback ID.
0518   *           @arg @ref HAL_SWPMI_MSPINIT_CB_ID MSP init callback ID.
0519   *           @arg @ref HAL_SWPMI_MSPDEINIT_CB_ID MSP de-init callback ID.
0520   * @retval HAL status.
0521   */
0522 HAL_StatusTypeDef HAL_SWPMI_UnRegisterCallback(SWPMI_HandleTypeDef        *hswpmi,
0523                                                HAL_SWPMI_CallbackIDTypeDef CallbackID)
0524 {
0525   HAL_StatusTypeDef status = HAL_OK;
0526 
0527   if (hswpmi->State == HAL_SWPMI_STATE_READY)
0528   {
0529     switch (CallbackID)
0530     {
0531       case HAL_SWPMI_RX_COMPLETE_CB_ID :
0532         hswpmi->RxCpltCallback = HAL_SWPMI_RxCpltCallback;
0533         break;
0534       case HAL_SWPMI_RX_HALFCOMPLETE_CB_ID :
0535         hswpmi->RxHalfCpltCallback = HAL_SWPMI_RxHalfCpltCallback;
0536         break;
0537       case HAL_SWPMI_TX_COMPLETE_CB_ID :
0538         hswpmi->TxCpltCallback = HAL_SWPMI_TxCpltCallback;
0539         break;
0540       case HAL_SWPMI_TX_HALFCOMPLETE_CB_ID :
0541         hswpmi->TxHalfCpltCallback = HAL_SWPMI_TxHalfCpltCallback;
0542         break;
0543       case HAL_SWPMI_ERROR_CB_ID :
0544         hswpmi->ErrorCallback = HAL_SWPMI_ErrorCallback;
0545         break;
0546       case HAL_SWPMI_MSPINIT_CB_ID :
0547         hswpmi->MspInitCallback = HAL_SWPMI_MspInit;
0548         break;
0549       case HAL_SWPMI_MSPDEINIT_CB_ID :
0550         hswpmi->MspDeInitCallback = HAL_SWPMI_MspDeInit;
0551         break;
0552       default :
0553         /* update the error code */
0554         hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
0555         /* update return status */
0556         status = HAL_ERROR;
0557         break;
0558     }
0559   }
0560   else if (hswpmi->State == HAL_SWPMI_STATE_RESET)
0561   {
0562     switch (CallbackID)
0563     {
0564       case HAL_SWPMI_MSPINIT_CB_ID :
0565         hswpmi->MspInitCallback = HAL_SWPMI_MspInit;
0566         break;
0567       case HAL_SWPMI_MSPDEINIT_CB_ID :
0568         hswpmi->MspDeInitCallback = HAL_SWPMI_MspDeInit;
0569         break;
0570       default :
0571         /* update the error code */
0572         hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
0573         /* update return status */
0574         status = HAL_ERROR;
0575         break;
0576     }
0577   }
0578   else
0579   {
0580     /* update the error code */
0581     hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
0582     /* update return status */
0583     status = HAL_ERROR;
0584   }
0585   return status;
0586 }
0587 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
0588 
0589 /**
0590   * @}
0591   */
0592 
0593 /** @defgroup SWPMI_Exported_Group2 IO operation methods
0594   * @ingroup RTEMSBSPsARMSTM32H7
0595   *  @brief SWPMI Transmit/Receive functions
0596   *
0597 @verbatim
0598  ===============================================================================
0599                       ##### IO operation methods #####
0600  ===============================================================================
0601  [..]
0602     This subsection provides a set of functions allowing to manage the SWPMI
0603      data transfers.
0604 
0605     (#) There are two modes of transfer:
0606        (++) Blocking mode: The communication is performed in polling mode.
0607             The HAL status of all data processing is returned by the same function
0608             after finishing transfer.
0609        (++) Non-Blocking mode: The communication is performed using Interrupts
0610            or DMA. The end of the data processing will be indicated through the
0611            dedicated SWPMI Interrupt handler (HAL_SWPMI_IRQHandler()) when using Interrupt mode or
0612            the selected DMA stream interrupt handler when using DMA mode.
0613            The HAL_SWPMI_TxCpltCallback(), HAL_SWPMI_RxCpltCallback() user callbacks
0614            will be executed respectively at the end of the transmit or receive process.
0615            The HAL_SWPMI_ErrorCallback() user callback will be executed when a communication error is detected.
0616 
0617     (#) Blocking mode API's are:
0618         (++) HAL_SWPMI_Transmit()
0619         (++) HAL_SWPMI_Receive()
0620 
0621     (#) Non-Blocking mode API's with Interrupt are:
0622         (++) HAL_SWPMI_Transmit_IT()
0623         (++) HAL_SWPMI_Receive_IT()
0624         (++) HAL_SWPMI_IRQHandler()
0625 
0626     (#) Non-Blocking mode API's with DMA are:
0627         (++) HAL_SWPMI_Transmit_DMA()
0628         (++) HAL_SWPMI_Receive_DMA()
0629         (++) HAL_SWPMI_DMAPause()
0630         (++) HAL_SWPMI_DMAResume()
0631         (++) HAL_SWPMI_DMAStop()
0632 
0633     (#) A set of Transfer Complete Callbacks are provided in Non-Blocking mode:
0634         (++) HAL_SWPMI_TxHalfCpltCallback()
0635         (++) HAL_SWPMI_TxCpltCallback()
0636         (++) HAL_SWPMI_RxHalfCpltCallback()
0637         (++) HAL_SWPMI_RxCpltCallback()
0638         (++) HAL_SWPMI_ErrorCallback()
0639 
0640     (#) The capability to launch the above IO operations in loopback mode for
0641         user application verification:
0642         (++) HAL_SWPMI_EnableLoopback()
0643         (++) HAL_SWPMI_DisableLoopback()
0644 
0645 @endverbatim
0646   * @{
0647   */
0648 
0649 /**
0650   * @brief  Transmit an amount of data in blocking mode.
0651   * @param  hswpmi pointer to a SWPMI_HandleTypeDef structure that contains
0652   *                the configuration information for SWPMI module.
0653   * @param  pData Pointer to data buffer
0654   * @param  Size Amount of data to be sent
0655   * @param  Timeout Timeout duration
0656   * @retval HAL status
0657   */
0658 HAL_StatusTypeDef HAL_SWPMI_Transmit(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size, uint32_t Timeout)
0659 {
0660   uint32_t tickstart = HAL_GetTick();
0661   HAL_StatusTypeDef status = HAL_OK;
0662   HAL_SWPMI_StateTypeDef tmp_state;
0663   uint32_t *ptmp_data;
0664   uint32_t tmp_size;
0665 
0666   if ((pData == NULL) || (Size == 0U))
0667   {
0668     status = HAL_ERROR;
0669   }
0670   else
0671   {
0672     /* Process Locked */
0673     __HAL_LOCK(hswpmi);
0674 
0675     tmp_state = hswpmi->State;
0676     if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_RX))
0677     {
0678       /* Check if a non-blocking receive process is ongoing or not */
0679       if (tmp_state == HAL_SWPMI_STATE_READY)
0680       {
0681         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
0682 
0683         /* Disable any transmitter interrupts */
0684         __HAL_SWPMI_DISABLE_IT(hswpmi, SWPMI_IT_TCIE | SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE);
0685 
0686         /* Disable any transmitter flags */
0687         __HAL_SWPMI_CLEAR_FLAG(hswpmi, SWPMI_FLAG_TXBEF | SWPMI_FLAG_TXUNRF | SWPMI_FLAG_TCF);
0688 
0689         /* Enable SWPMI peripheral if not */
0690         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
0691       }
0692       else
0693       {
0694         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
0695       }
0696 
0697       ptmp_data = pData;
0698       tmp_size = Size;
0699       do
0700       {
0701         /* Wait the TXE to write data */
0702         if (HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_TXE))
0703         {
0704           hswpmi->Instance->TDR = *ptmp_data;
0705           ptmp_data++;
0706           tmp_size--;
0707         }
0708         else
0709         {
0710           /* Check for the Timeout */
0711           if (Timeout != HAL_MAX_DELAY)
0712           {
0713             if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
0714             {
0715               status = HAL_TIMEOUT;
0716               break;
0717             }
0718           }
0719         }
0720       }
0721       while (tmp_size != 0U);
0722 
0723       /* Wait on TXBEF flag to be able to start a second transfer */
0724       if (SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, tickstart, Timeout) != HAL_OK)
0725       {
0726         /* Timeout occurred */
0727         hswpmi->ErrorCode |= HAL_SWPMI_ERROR_TXBEF_TIMEOUT;
0728 
0729         status = HAL_TIMEOUT;
0730       }
0731 
0732       if (status == HAL_OK)
0733       {
0734         /* Check if a non-blocking receive Process is ongoing or not */
0735         if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
0736         {
0737           hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
0738         }
0739         else
0740         {
0741           hswpmi->State = HAL_SWPMI_STATE_READY;
0742         }
0743       }
0744     }
0745     else
0746     {
0747       status = HAL_BUSY;
0748     }
0749   }
0750 
0751   if ((status != HAL_OK) && (status != HAL_BUSY))
0752   {
0753     hswpmi->State = HAL_SWPMI_STATE_READY;
0754   }
0755   /* Process Unlocked */
0756   __HAL_UNLOCK(hswpmi);
0757 
0758   return status;
0759 }
0760 
0761 /**
0762   * @brief  Receive an amount of data in blocking mode.
0763   * @param  hswpmi pointer to a SWPMI_HandleTypeDef structure that contains
0764   *                the configuration information for SWPMI module.
0765   * @param  pData Pointer to data buffer
0766   * @param  Size Amount of data to be received
0767   * @param  Timeout Timeout duration
0768   * @retval HAL status
0769   */
0770 HAL_StatusTypeDef HAL_SWPMI_Receive(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size, uint32_t Timeout)
0771 {
0772   uint32_t tickstart = HAL_GetTick();
0773   HAL_StatusTypeDef status = HAL_OK;
0774   HAL_SWPMI_StateTypeDef tmp_state;
0775   uint32_t *ptmp_data;
0776   uint32_t tmp_size;
0777 
0778   if ((pData == NULL) || (Size == 0U))
0779   {
0780     status = HAL_ERROR;
0781   }
0782   else
0783   {
0784     /* Process Locked */
0785     __HAL_LOCK(hswpmi);
0786 
0787     tmp_state = hswpmi->State;
0788     if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX))
0789     {
0790       /* Check if a non-blocking transmit process is ongoing or not */
0791       if (tmp_state == HAL_SWPMI_STATE_READY)
0792       {
0793         hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
0794 
0795         /* Disable any receiver interrupts */
0796         CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_SRIE | SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
0797 
0798         /* Enable SWPMI peripheral if not */
0799         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
0800       }
0801       else
0802       {
0803         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
0804       }
0805 
0806       ptmp_data = pData;
0807       tmp_size = Size;
0808       do
0809       {
0810         /* Wait the RXNE to read data */
0811         if (HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXNE))
0812         {
0813           *ptmp_data = hswpmi->Instance->RDR;
0814           ptmp_data++;
0815           tmp_size--;
0816         }
0817         else
0818         {
0819           /* Check for the Timeout */
0820           if (Timeout != HAL_MAX_DELAY)
0821           {
0822             if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
0823             {
0824               status = HAL_TIMEOUT;
0825               break;
0826             }
0827           }
0828         }
0829       }
0830       while (tmp_size != 0U);
0831 
0832       if (status == HAL_OK)
0833       {
0834         if (HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXBFF))
0835         {
0836           /* Clear RXBFF at end of reception */
0837           WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF);
0838         }
0839 
0840         /* Check if a non-blocking transmit Process is ongoing or not */
0841         if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
0842         {
0843           hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
0844         }
0845         else
0846         {
0847           hswpmi->State = HAL_SWPMI_STATE_READY;
0848         }
0849       }
0850     }
0851     else
0852     {
0853       status = HAL_BUSY;
0854     }
0855   }
0856 
0857   if ((status != HAL_OK) && (status != HAL_BUSY))
0858   {
0859     hswpmi->State = HAL_SWPMI_STATE_READY;
0860   }
0861   /* Process Unlocked */
0862   __HAL_UNLOCK(hswpmi);
0863 
0864   return status;
0865 }
0866 
0867 /**
0868   * @brief  Transmit an amount of data in non-blocking mode with interrupt.
0869   * @param  hswpmi pointer to a SWPMI_HandleTypeDef structure that contains
0870   *                the configuration information for SWPMI module.
0871   * @param  pData Pointer to data buffer
0872   * @param  Size Amount of data to be sent
0873   * @retval HAL status
0874   */
0875 HAL_StatusTypeDef HAL_SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
0876 {
0877   HAL_StatusTypeDef status = HAL_OK;
0878   HAL_SWPMI_StateTypeDef tmp_state;
0879 
0880   if ((pData == NULL) || (Size == 0U))
0881   {
0882     status =  HAL_ERROR;
0883   }
0884   else
0885   {
0886     /* Process Locked */
0887     __HAL_LOCK(hswpmi);
0888 
0889     tmp_state = hswpmi->State;
0890     if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_RX))
0891     {
0892       /* Update handle */
0893       hswpmi->pTxBuffPtr = pData;
0894       hswpmi->TxXferSize = Size;
0895       hswpmi->TxXferCount = Size;
0896       hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
0897 
0898       /* Check if a receive process is ongoing or not */
0899       if (tmp_state == HAL_SWPMI_STATE_READY)
0900       {
0901         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
0902 
0903         /* Enable SWPMI peripheral if not */
0904         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
0905       }
0906       else
0907       {
0908         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
0909       }
0910 
0911       /* Enable the SWPMI transmit underrun error */
0912       __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TXUNRIE);
0913 
0914       /* Process Unlocked */
0915       __HAL_UNLOCK(hswpmi);
0916 
0917       /* Enable the SWPMI interrupts:      */
0918       /* - Transmit data register empty    */
0919       /* - Transmit buffer empty           */
0920       /* - Transmit/Reception completion   */
0921       __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TIE | SWPMI_IT_TXBEIE | SWPMI_IT_TCIE);
0922     }
0923     else
0924     {
0925       status =  HAL_BUSY;
0926 
0927       /* Process Unlocked */
0928       __HAL_UNLOCK(hswpmi);
0929     }
0930   }
0931 
0932   return status;
0933 }
0934 
0935 /**
0936   * @brief  Receive an amount of data in non-blocking mode with interrupt.
0937   * @param  hswpmi SWPMI handle
0938   * @param  pData Pointer to data buffer
0939   * @param  Size Amount of data to be received
0940   * @retval HAL status
0941   */
0942 HAL_StatusTypeDef HAL_SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
0943 {
0944   HAL_StatusTypeDef status = HAL_OK;
0945   HAL_SWPMI_StateTypeDef tmp_state;
0946 
0947   if ((pData == NULL) || (Size == 0U))
0948   {
0949     status =  HAL_ERROR;
0950   }
0951   else
0952   {
0953     /* Process Locked */
0954     __HAL_LOCK(hswpmi);
0955 
0956     tmp_state = hswpmi->State;
0957     if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX))
0958     {
0959       /* Update handle */
0960       hswpmi->pRxBuffPtr = pData;
0961       hswpmi->RxXferSize = Size;
0962       hswpmi->RxXferCount = Size;
0963       hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
0964 
0965       /* Check if a transmit process is ongoing or not */
0966       if (tmp_state == HAL_SWPMI_STATE_READY)
0967       {
0968         hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
0969 
0970         /* Enable SWPMI peripheral if not */
0971         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
0972       }
0973       else
0974       {
0975         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
0976       }
0977 
0978       /* Process Unlocked */
0979       __HAL_UNLOCK(hswpmi);
0980 
0981       /* Enable the SWPMI slave resume */
0982       /* Enable the SWPMI Data Register not empty Interrupt, receive CRC Error, receive overrun and RxBuf Interrupt */
0983       /*  Enable the SWPMI Transmit/Reception completion   */
0984       __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
0985     }
0986     else
0987     {
0988       status = HAL_BUSY;
0989 
0990       /* Process Unlocked */
0991       __HAL_UNLOCK(hswpmi);
0992     }
0993   }
0994 
0995   return status;
0996 }
0997 
0998 /**
0999   * @brief  Transmit an amount of data in non-blocking mode with DMA interrupt.
1000   * @param  hswpmi SWPMI handle
1001   * @param  pData Pointer to data buffer
1002   * @param  Size Amount of data to be sent
1003   * @retval HAL status
1004   */
1005 HAL_StatusTypeDef HAL_SWPMI_Transmit_DMA(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
1006 {
1007   HAL_StatusTypeDef status = HAL_OK;
1008   HAL_SWPMI_StateTypeDef tmp_state;
1009 
1010   if ((pData == NULL) || (Size == 0U))
1011   {
1012     status =  HAL_ERROR;
1013   }
1014   else
1015   {
1016     /* Process Locked */
1017     __HAL_LOCK(hswpmi);
1018 
1019     tmp_state = hswpmi->State;
1020     if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_RX))
1021     {
1022       /* Update handle */
1023       hswpmi->pTxBuffPtr = pData;
1024       hswpmi->TxXferSize = Size;
1025       hswpmi->TxXferCount = Size;
1026       hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
1027 
1028       /* Check if a receive process is ongoing or not */
1029       if (tmp_state == HAL_SWPMI_STATE_READY)
1030       {
1031         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
1032 
1033         /* Enable SWPMI peripheral if not */
1034         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1035       }
1036       else
1037       {
1038         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
1039       }
1040 
1041       /* Set the SWPMI DMA transfer complete callback */
1042       hswpmi->hdmatx->XferCpltCallback = SWPMI_DMATransmitCplt;
1043 
1044       /* Set the SWPMI DMA Half transfer complete callback */
1045       hswpmi->hdmatx->XferHalfCpltCallback = SWPMI_DMATxHalfCplt;
1046 
1047       /* Set the DMA error callback */
1048       hswpmi->hdmatx->XferErrorCallback = SWPMI_DMAError;
1049 
1050       /* Enable the SWPMI transmit DMA stream */
1051       if (HAL_DMA_Start_IT(hswpmi->hdmatx, (uint32_t)hswpmi->pTxBuffPtr, (uint32_t)&hswpmi->Instance->TDR, Size) != HAL_OK)
1052       {
1053         hswpmi->State = tmp_state;    /* Back to previous state */
1054         hswpmi->ErrorCode = HAL_SWPMI_ERROR_DMA;
1055         status = HAL_ERROR;
1056 
1057         /* Process Unlocked */
1058         __HAL_UNLOCK(hswpmi);
1059       }
1060       else
1061       {
1062         /* Process Unlocked */
1063         __HAL_UNLOCK(hswpmi);
1064 
1065         /* Enable the SWPMI transmit underrun error */
1066         __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TXUNRIE);
1067 
1068         /* Enable the DMA transfer for transmit request by setting the TXDMA bit
1069            in the SWPMI CR register */
1070         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);
1071       }
1072     }
1073     else
1074     {
1075       status = HAL_BUSY;
1076 
1077       /* Process Unlocked */
1078       __HAL_UNLOCK(hswpmi);
1079     }
1080   }
1081 
1082   return status;
1083 }
1084 
1085 /**
1086   * @brief  Receive an amount of data in non-blocking mode with DMA interrupt.
1087   * @param  hswpmi SWPMI handle
1088   * @param  pData Pointer to data buffer
1089   * @param  Size Amount of data to be received
1090   * @retval HAL status
1091   */
1092 HAL_StatusTypeDef HAL_SWPMI_Receive_DMA(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
1093 {
1094   HAL_StatusTypeDef status = HAL_OK;
1095   HAL_SWPMI_StateTypeDef tmp_state;
1096 
1097   if ((pData == NULL) || (Size == 0U))
1098   {
1099     status =  HAL_ERROR;
1100   }
1101   else
1102   {
1103     /* Process Locked */
1104     __HAL_LOCK(hswpmi);
1105 
1106     tmp_state = hswpmi->State;
1107     if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX))
1108     {
1109       /* Update handle */
1110       hswpmi->pRxBuffPtr = pData;
1111       hswpmi->RxXferSize = Size;
1112       hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
1113 
1114       /* Check if a transmit process is ongoing or not */
1115       if (tmp_state == HAL_SWPMI_STATE_READY)
1116       {
1117         hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
1118 
1119         /* Enable SWPMI peripheral if not */
1120         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1121       }
1122       else
1123       {
1124         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
1125       }
1126 
1127       /* Set the SWPMI DMA transfer complete callback */
1128       hswpmi->hdmarx->XferCpltCallback = SWPMI_DMAReceiveCplt;
1129 
1130       /* Set the SWPMI DMA Half transfer complete callback */
1131       hswpmi->hdmarx->XferHalfCpltCallback = SWPMI_DMARxHalfCplt;
1132 
1133       /* Set the DMA error callback */
1134       hswpmi->hdmarx->XferErrorCallback = SWPMI_DMAError;
1135 
1136       /* Enable the DMA request */
1137       if (HAL_DMA_Start_IT(hswpmi->hdmarx, (uint32_t)&hswpmi->Instance->RDR, (uint32_t)hswpmi->pRxBuffPtr, Size) != HAL_OK)
1138       {
1139         hswpmi->State = tmp_state;    /* Back to previous state */
1140         hswpmi->ErrorCode = HAL_SWPMI_ERROR_DMA;
1141         status = HAL_ERROR;
1142 
1143         /* Process Unlocked */
1144         __HAL_UNLOCK(hswpmi);
1145       }
1146       else
1147       {
1148         /* Process Unlocked */
1149         __HAL_UNLOCK(hswpmi);
1150 
1151         /* Enable the SWPMI receive CRC Error and receive overrun interrupts */
1152         __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE);
1153 
1154         /* Enable the DMA transfer for the receiver request by setting the RXDMA bit
1155            in the SWPMI CR register */
1156         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);
1157       }
1158     }
1159     else
1160     {
1161       status = HAL_BUSY;
1162 
1163       /* Process Unlocked */
1164       __HAL_UNLOCK(hswpmi);
1165     }
1166   }
1167 
1168   return status;
1169 }
1170 
1171 /**
1172   * @brief Stop all DMA transfers.
1173   * @param hswpmi SWPMI handle
1174   * @retval HAL status
1175   */
1176 HAL_StatusTypeDef HAL_SWPMI_DMAStop(SWPMI_HandleTypeDef *hswpmi)
1177 {
1178   HAL_StatusTypeDef status = HAL_OK;
1179 
1180   /* Process Locked */
1181   __HAL_LOCK(hswpmi);
1182 
1183   /* Disable the SWPMI Tx/Rx DMA requests */
1184   CLEAR_BIT(hswpmi->Instance->CR, (SWPMI_CR_TXDMA | SWPMI_CR_RXDMA));
1185 
1186   /* Abort the SWPMI DMA tx stream */
1187   if (hswpmi->hdmatx != NULL)
1188   {
1189     if (HAL_DMA_Abort(hswpmi->hdmatx) != HAL_OK)
1190     {
1191       hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA;
1192       status = HAL_ERROR;
1193     }
1194   }
1195   /* Abort the SWPMI DMA rx stream */
1196   if (hswpmi->hdmarx != NULL)
1197   {
1198     if (HAL_DMA_Abort(hswpmi->hdmarx) != HAL_OK)
1199     {
1200       hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA;
1201       status = HAL_ERROR;
1202     }
1203   }
1204 
1205   /* Disable SWPMI interface */
1206   CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1207 
1208   hswpmi->State = HAL_SWPMI_STATE_READY;
1209 
1210   /* Process Unlocked */
1211   __HAL_UNLOCK(hswpmi);
1212 
1213   return status;
1214 }
1215 
1216 
1217 /**
1218   * @brief Enable the Loopback mode.
1219   * @param hswpmi SWPMI handle
1220   * @note  Loopback mode is to be used only for test purposes
1221   * @retval HAL_OK / HAL_BUSY
1222   */
1223 HAL_StatusTypeDef HAL_SWPMI_EnableLoopback(SWPMI_HandleTypeDef *hswpmi)
1224 {
1225   HAL_StatusTypeDef  status = HAL_OK;
1226 
1227   /* Process Locked */
1228   __HAL_LOCK(hswpmi);
1229 
1230   /* Make sure the SWPMI interface is not enabled to set the loopback mode */
1231   CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1232 
1233   /* Set Loopback */
1234   SET_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);
1235 
1236   /* Enable SWPMI interface in loopback mode */
1237   SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1238 
1239   /* Process Unlocked */
1240   __HAL_UNLOCK(hswpmi);
1241 
1242   return status;
1243 }
1244 
1245 /**
1246   * @brief Disable the Loopback mode.
1247   * @param hswpmi SWPMI handle
1248   * @note  Loopback mode is to be used only for test purposes
1249   * @retval HAL_OK / HAL_BUSY
1250   */
1251 HAL_StatusTypeDef HAL_SWPMI_DisableLoopback(SWPMI_HandleTypeDef *hswpmi)
1252 {
1253   HAL_StatusTypeDef  status = HAL_OK;
1254 
1255   /* Process Locked */
1256   __HAL_LOCK(hswpmi);
1257 
1258   /* Make sure the SWPMI interface is not enabled to reset the loopback mode */
1259   CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1260 
1261   /* Reset Loopback */
1262   CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);
1263 
1264   /* Re-enable SWPMI interface in normal mode */
1265   SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1266 
1267   /* Process Unlocked */
1268   __HAL_UNLOCK(hswpmi);
1269 
1270   return status;
1271 }
1272 
1273 /**
1274   * @}
1275   */
1276 
1277 /** @defgroup SWPMI_Exported_Group3 SWPMI IRQ handler and callbacks
1278   * @ingroup RTEMSBSPsARMSTM32H7
1279  *  @brief  SWPMI  IRQ handler.
1280  *
1281 @verbatim
1282   ==============================================================================
1283                       ##### SWPMI IRQ handler and callbacks  #####
1284   ==============================================================================
1285 [..]  This section provides SWPMI IRQ handler and callback functions called within
1286       the IRQ handler.
1287 
1288 @endverbatim
1289   * @{
1290   */
1291 
1292 /**
1293   * @brief Handle SWPMI interrupt request.
1294   * @param hswpmi SWPMI handle
1295   * @retval None
1296   */
1297 void HAL_SWPMI_IRQHandler(SWPMI_HandleTypeDef *hswpmi)
1298 {
1299   uint32_t regisr = READ_REG(hswpmi->Instance->ISR);
1300   uint32_t regier = READ_REG(hswpmi->Instance->IER);
1301   uint32_t errcode = HAL_SWPMI_ERROR_NONE;
1302 
1303   /* SWPMI CRC error interrupt occurred --------------------------------------*/
1304   if (((regisr & SWPMI_FLAG_RXBERF) != 0U) && ((regier & SWPMI_IT_RXBERIE) != 0U))
1305   {
1306     /* Disable Receive CRC interrupt */
1307     CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RXBERIE | SWPMI_IT_RXBFIE);
1308     /* Clear Receive CRC and Receive buffer full flag */
1309     WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBERF | SWPMI_FLAG_RXBFF);
1310 
1311     errcode |= HAL_SWPMI_ERROR_CRC;
1312   }
1313 
1314   /* SWPMI Over-Run interrupt occurred -----------------------------------------*/
1315   if (((regisr & SWPMI_FLAG_RXOVRF) != 0U) && ((regier & SWPMI_IT_RXOVRIE) != 0U))
1316   {
1317     /* Disable Receive overrun interrupt */
1318     CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RXOVRIE);
1319     /* Clear Receive overrun flag */
1320     WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXOVRF);
1321 
1322     errcode |= HAL_SWPMI_ERROR_OVR;
1323   }
1324 
1325   /* SWPMI Under-Run interrupt occurred -----------------------------------------*/
1326   if (((regisr & SWPMI_FLAG_TXUNRF) != 0U) && ((regier & SWPMI_IT_TXUNRIE) != 0U))
1327   {
1328     /* Disable Transmit under run interrupt */
1329     CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TXUNRIE);
1330     /* Clear Transmit under run flag */
1331     WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TXUNRF);
1332 
1333     errcode |= HAL_SWPMI_ERROR_UDR;
1334   }
1335 
1336   /* Call SWPMI Error Call back function if needed --------------------------*/
1337   if (errcode != HAL_SWPMI_ERROR_NONE)
1338   {
1339     hswpmi->ErrorCode |= errcode;
1340 
1341     if ((errcode & HAL_SWPMI_ERROR_UDR) != 0U)
1342     {
1343       /* Check TXDMA transfer to abort */
1344       if (HAL_IS_BIT_SET(hswpmi->Instance->CR, SWPMI_CR_TXDMA))
1345       {
1346         /* Disable DMA TX at SWPMI level */
1347         CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);
1348 
1349         /* Abort the USART DMA Tx stream */
1350         if (hswpmi->hdmatx != NULL)
1351         {
1352           /* Set the SWPMI Tx DMA Abort callback :
1353              will lead to call HAL_SWPMI_ErrorCallback() at end of DMA abort procedure */
1354           hswpmi->hdmatx->XferAbortCallback = SWPMI_DMAAbortOnError;
1355           /* Abort DMA TX */
1356           if (HAL_DMA_Abort_IT(hswpmi->hdmatx) != HAL_OK)
1357           {
1358             /* Call Directly hswpmi->hdmatx->XferAbortCallback function in case of error */
1359             hswpmi->hdmatx->XferAbortCallback(hswpmi->hdmatx);
1360           }
1361         }
1362         else
1363         {
1364           /* Set the SWPMI state ready to be able to start again the process */
1365           hswpmi->State = HAL_SWPMI_STATE_READY;
1366 
1367 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1368           hswpmi->ErrorCallback(hswpmi);
1369 #else
1370           HAL_SWPMI_ErrorCallback(hswpmi);
1371 #endif
1372         }
1373       }
1374       else
1375       {
1376         /* Set the SWPMI state ready to be able to start again the process */
1377         hswpmi->State = HAL_SWPMI_STATE_READY;
1378 
1379 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1380         hswpmi->ErrorCallback(hswpmi);
1381 #else
1382         HAL_SWPMI_ErrorCallback(hswpmi);
1383 #endif
1384       }
1385     }
1386     else
1387     {
1388       /* Check RXDMA transfer to abort */
1389       if (HAL_IS_BIT_SET(hswpmi->Instance->CR, SWPMI_CR_RXDMA))
1390       {
1391         /* Disable DMA RX at SWPMI level */
1392         CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);
1393 
1394         /* Abort the USART DMA Rx stream */
1395         if (hswpmi->hdmarx != NULL)
1396         {
1397           /* Set the SWPMI Rx DMA Abort callback :
1398              will lead to call HAL_SWPMI_ErrorCallback() at end of DMA abort procedure */
1399           hswpmi->hdmarx->XferAbortCallback = SWPMI_DMAAbortOnError;
1400           /* Abort DMA RX */
1401           if (HAL_DMA_Abort_IT(hswpmi->hdmarx) != HAL_OK)
1402           {
1403             /* Call Directly hswpmi->hdmarx->XferAbortCallback function in case of error */
1404             hswpmi->hdmarx->XferAbortCallback(hswpmi->hdmarx);
1405           }
1406         }
1407         else
1408         {
1409           /* Set the SWPMI state ready to be able to start again the process */
1410           hswpmi->State = HAL_SWPMI_STATE_READY;
1411 
1412 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1413           hswpmi->ErrorCallback(hswpmi);
1414 #else
1415           HAL_SWPMI_ErrorCallback(hswpmi);
1416 #endif
1417         }
1418       }
1419       else
1420       {
1421         /* Set the SWPMI state ready to be able to start again the process */
1422         hswpmi->State = HAL_SWPMI_STATE_READY;
1423 
1424 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1425         hswpmi->ErrorCallback(hswpmi);
1426 #else
1427         HAL_SWPMI_ErrorCallback(hswpmi);
1428 #endif
1429       }
1430     }
1431   }
1432 
1433   /* SWPMI in mode Receiver ---------------------------------------------------*/
1434   if (((regisr & SWPMI_FLAG_RXNE) != 0U) && ((regier & SWPMI_IT_RIE)  != 0U))
1435   {
1436     SWPMI_Receive_IT(hswpmi);
1437   }
1438 
1439   /* SWPMI in mode Transmitter ------------------------------------------------*/
1440   if (((regisr & SWPMI_FLAG_TXE) != 0U) && ((regier & SWPMI_IT_TIE) != 0U))
1441   {
1442     SWPMI_Transmit_IT(hswpmi);
1443   }
1444 
1445   /* SWPMI in mode Transmitter (Transmit buffer empty) ------------------------*/
1446   if (((regisr & SWPMI_FLAG_TXBEF) != 0U) && ((regier & SWPMI_IT_TXBEIE) != 0U))
1447   {
1448     SWPMI_EndTransmit_IT(hswpmi);
1449   }
1450 
1451   /* SWPMI in mode Receiver (Receive buffer full) -----------------------------*/
1452   if (((regisr & SWPMI_FLAG_RXBFF) != 0U) && ((regier & SWPMI_IT_RXBFIE) != 0U))
1453   {
1454     SWPMI_EndReceive_IT(hswpmi);
1455   }
1456 
1457   /* Both Transmission and reception complete ---------------------------------*/
1458   if (((regisr & SWPMI_FLAG_TCF) != 0U) && ((regier & SWPMI_IT_TCIE) != 0U))
1459   {
1460     SWPMI_EndTransmitReceive_IT(hswpmi);
1461   }
1462 }
1463 
1464 /**
1465   * @brief Tx Transfer completed callback.
1466   * @param hswpmi SWPMI handle
1467   * @retval None
1468   */
1469 __weak void HAL_SWPMI_TxCpltCallback(SWPMI_HandleTypeDef *hswpmi)
1470 {
1471   /* Prevent unused argument(s) compilation warning */
1472   UNUSED(hswpmi);
1473 
1474   /* NOTE : This function should not be modified, when the callback is needed,
1475             the HAL_SWPMI_TxCpltCallback is to be implemented in the user file
1476    */
1477 }
1478 
1479 /**
1480   * @brief  Tx Half Transfer completed callback.
1481   * @param  hswpmi SWPMI handle
1482   * @retval None
1483   */
1484 __weak void HAL_SWPMI_TxHalfCpltCallback(SWPMI_HandleTypeDef *hswpmi)
1485 {
1486   /* Prevent unused argument(s) compilation warning */
1487   UNUSED(hswpmi);
1488 
1489   /* NOTE: This function should not be modified, when the callback is needed,
1490            the HAL_SWPMI_TxHalfCpltCallback is to be implemented in the user file
1491    */
1492 }
1493 
1494 /**
1495   * @brief Rx Transfer completed callback.
1496   * @param hswpmi SWPMI handle
1497   * @retval None
1498   */
1499 __weak void HAL_SWPMI_RxCpltCallback(SWPMI_HandleTypeDef *hswpmi)
1500 {
1501   /* Prevent unused argument(s) compilation warning */
1502   UNUSED(hswpmi);
1503 
1504   /* NOTE : This function should not be modified, when the callback is needed,
1505             the HAL_SWPMI_RxCpltCallback is to be implemented in the user file
1506    */
1507 }
1508 
1509 /**
1510   * @brief  Rx Half Transfer completed callback.
1511   * @param  hswpmi SWPMI handle
1512   * @retval None
1513   */
1514 __weak void HAL_SWPMI_RxHalfCpltCallback(SWPMI_HandleTypeDef *hswpmi)
1515 {
1516   /* Prevent unused argument(s) compilation warning */
1517   UNUSED(hswpmi);
1518 
1519   /* NOTE: This function should not be modified, when the callback is needed,
1520            the HAL_SWPMI_RxHalfCpltCallback is to be implemented in the user file
1521    */
1522 }
1523 
1524 /**
1525   * @brief SWPMI error callback.
1526   * @param hswpmi SWPMI handle
1527   * @retval None
1528   */
1529 __weak void HAL_SWPMI_ErrorCallback(SWPMI_HandleTypeDef *hswpmi)
1530 {
1531   /* Prevent unused argument(s) compilation warning */
1532   UNUSED(hswpmi);
1533 
1534   /* NOTE : This function should not be modified, when the callback is needed,
1535             the HAL_SWPMI_ErrorCallback is to be implemented in the user file
1536    */
1537 }
1538 
1539 /**
1540   * @}
1541   */
1542 
1543 /** @defgroup SWPMI_Exported_Group4 Peripheral Control methods
1544   * @ingroup RTEMSBSPsARMSTM32H7
1545   *  @brief   SWPMI control functions
1546   *
1547 @verbatim
1548  ===============================================================================
1549                       ##### Peripheral Control methods #####
1550  ===============================================================================
1551     [..]
1552     This subsection provides a set of functions allowing to control the SWPMI.
1553      (+) HAL_SWPMI_GetState() API is helpful to check in run-time the state of the SWPMI peripheral
1554      (+) HAL_SWPMI_GetError() API is helpful to check in run-time the error state of the SWPMI peripheral
1555 @endverbatim
1556   * @{
1557   */
1558 
1559 /**
1560   * @brief Return the SWPMI handle state.
1561   * @param hswpmi SWPMI handle
1562   * @retval HAL state
1563   */
1564 HAL_SWPMI_StateTypeDef HAL_SWPMI_GetState(SWPMI_HandleTypeDef *hswpmi)
1565 {
1566   /* Return SWPMI handle state */
1567   return hswpmi->State;
1568 }
1569 
1570 /**
1571 * @brief  Return the SWPMI error code.
1572 * @param  hswpmi : pointer to a SWPMI_HandleTypeDef structure that contains
1573   *              the configuration information for the specified SWPMI.
1574 * @retval SWPMI Error Code
1575 */
1576 uint32_t HAL_SWPMI_GetError(SWPMI_HandleTypeDef *hswpmi)
1577 {
1578   return hswpmi->ErrorCode;
1579 }
1580 
1581 /**
1582   * @}
1583   */
1584 
1585 /**
1586   * @}
1587   */
1588 
1589 /* Private functions ---------------------------------------------------------*/
1590 
1591 /** @defgroup SWPMI_Private_Functions SWPMI Private Functions
1592   * @ingroup RTEMSBSPsARMSTM32H7
1593   * @{
1594   */
1595 
1596 /**
1597   * @brief Transmit an amount of data in interrupt mode.
1598   * @note  Function called under interruption only, once interruptions have been enabled by HAL_SWPMI_Transmit_IT()
1599   * @param  hswpmi SWPMI handle
1600   * @retval None
1601   */
1602 static void SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi)
1603 {
1604   HAL_SWPMI_StateTypeDef tmp_state = hswpmi->State;
1605 
1606   if ((tmp_state == HAL_SWPMI_STATE_BUSY_TX) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX_RX))
1607   {
1608     if (hswpmi->TxXferCount == 0U)
1609     {
1610       /* Disable the SWPMI TXE and Underrun Interrupts */
1611       CLEAR_BIT(hswpmi->Instance->IER, (SWPMI_IT_TIE | SWPMI_IT_TXUNRIE));
1612     }
1613     else
1614     {
1615       hswpmi->Instance->TDR = (uint32_t) * hswpmi->pTxBuffPtr;
1616       hswpmi->pTxBuffPtr++;
1617       hswpmi->TxXferCount--;
1618     }
1619   }
1620   else
1621   {
1622     /* nothing to do */
1623   }
1624 }
1625 
1626 /**
1627   * @brief  Wraps up transmission in non-blocking mode.
1628   * @param  hswpmi SWPMI handle
1629   * @retval None
1630   */
1631 static void SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef *hswpmi)
1632 {
1633   /* Clear the SWPMI Transmit buffer empty Flag */
1634   WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TXBEF);
1635   /* Disable the all SWPMI Transmit Interrupts  */
1636   CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE);
1637 
1638   /* Check if a receive Process is ongoing or not */
1639   if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
1640   {
1641     hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
1642   }
1643   else
1644   {
1645     hswpmi->State = HAL_SWPMI_STATE_READY;
1646   }
1647 
1648 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1649   hswpmi->TxCpltCallback(hswpmi);
1650 #else
1651   HAL_SWPMI_TxCpltCallback(hswpmi);
1652 #endif
1653 }
1654 
1655 /**
1656   * @brief Receive an amount of data in interrupt mode.
1657   * @note  Function called under interruption only, once interruptions have been enabled by HAL_SWPMI_Receive_IT()
1658   * @param  hswpmi SWPMI handle
1659   * @retval None
1660   */
1661 static void SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi)
1662 {
1663   HAL_SWPMI_StateTypeDef tmp_state = hswpmi->State;
1664 
1665   if ((tmp_state == HAL_SWPMI_STATE_BUSY_RX) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX_RX))
1666   {
1667     *hswpmi->pRxBuffPtr = (uint32_t)(hswpmi->Instance->RDR);
1668     hswpmi->pRxBuffPtr++;
1669 
1670     --hswpmi->RxXferCount;
1671     if (hswpmi->RxXferCount == 0U)
1672     {
1673       /* Wait for RXBFF flag to update state */
1674 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1675       hswpmi->RxCpltCallback(hswpmi);
1676 #else
1677       HAL_SWPMI_RxCpltCallback(hswpmi);
1678 #endif
1679     }
1680   }
1681   else
1682   {
1683     /* nothing to do */
1684   }
1685 }
1686 
1687 /**
1688   * @brief  Wraps up reception in non-blocking mode.
1689   * @param  hswpmi SWPMI handle
1690   * @retval None
1691   */
1692 static void SWPMI_EndReceive_IT(SWPMI_HandleTypeDef *hswpmi)
1693 {
1694   /* Clear the SWPMI Receive buffer full Flag */
1695   WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF);
1696   /* Disable the all SWPMI Receive Interrupts  */
1697   CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
1698 
1699   /* Check if a transmit Process is ongoing or not */
1700   if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
1701   {
1702     hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
1703   }
1704   else
1705   {
1706     hswpmi->State = HAL_SWPMI_STATE_READY;
1707   }
1708 }
1709 
1710 /**
1711   * @brief  Wraps up transmission and reception in non-blocking mode.
1712   * @param  hswpmi SWPMI handle
1713   * @retval None
1714   */
1715 static void SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef *hswpmi)
1716 {
1717   /* Clear the SWPMI Transmission Complete Flag */
1718   WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TCF);
1719   /* Disable the SWPMI Transmission  Complete Interrupt */
1720   CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TCIE);
1721 
1722   /* Check if a receive Process is ongoing or not */
1723   if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
1724   {
1725     hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
1726   }
1727   else if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX)
1728   {
1729     hswpmi->State = HAL_SWPMI_STATE_READY;
1730   }
1731   else
1732   {
1733     /* nothing to do */
1734   }
1735 }
1736 
1737 /**
1738   * @brief DMA SWPMI transmit process complete callback.
1739   * @param hdma DMA handle
1740   * @retval None
1741   */
1742 static void SWPMI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1743 {
1744   SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1745   uint32_t tickstart;
1746 
1747   /* DMA Normal mode*/
1748   if (((((DMA_Stream_TypeDef *)hdma->Instance)->CR) & DMA_SxCR_CIRC) == 0U)
1749   {
1750     hswpmi->TxXferCount = 0U;
1751 
1752     /* Disable the DMA transfer for transmit request by setting the TXDMA bit
1753     in the SWPMI CR register */
1754     CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);
1755 
1756     /* Init tickstart for timeout management*/
1757     tickstart = HAL_GetTick();
1758 
1759     /* Wait the TXBEF */
1760     if (SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, tickstart, SWPMI_TIMEOUT_VALUE) != HAL_OK)
1761     {
1762       /* Timeout occurred */
1763       hswpmi->ErrorCode |= HAL_SWPMI_ERROR_TXBEF_TIMEOUT;
1764 
1765 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1766       hswpmi->ErrorCallback(hswpmi);
1767 #else
1768       HAL_SWPMI_ErrorCallback(hswpmi);
1769 #endif
1770     }
1771     else
1772     {
1773       /* No Timeout */
1774       /* Check if a receive process is ongoing or not */
1775       if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
1776       {
1777         hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
1778       }
1779       else
1780       {
1781         hswpmi->State = HAL_SWPMI_STATE_READY;
1782       }
1783 
1784 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1785       hswpmi->TxCpltCallback(hswpmi);
1786 #else
1787       HAL_SWPMI_TxCpltCallback(hswpmi);
1788 #endif
1789     }
1790   }
1791   /* DMA Circular mode */
1792   else
1793   {
1794 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1795     hswpmi->TxCpltCallback(hswpmi);
1796 #else
1797     HAL_SWPMI_TxCpltCallback(hswpmi);
1798 #endif
1799   }
1800 }
1801 
1802 /**
1803   * @brief DMA SWPMI transmit process half complete callback.
1804   * @param hdma DMA handle
1805   * @retval None
1806   */
1807 static void SWPMI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1808 {
1809   SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1810 
1811 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1812   hswpmi->TxHalfCpltCallback(hswpmi);
1813 #else
1814   HAL_SWPMI_TxHalfCpltCallback(hswpmi);
1815 #endif
1816 }
1817 
1818 
1819 /**
1820   * @brief DMA SWPMI receive process complete callback.
1821   * @param hdma DMA handle
1822   * @retval None
1823   */
1824 static void SWPMI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1825 {
1826   SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1827 
1828   /* DMA Normal mode*/
1829   if (((((DMA_Stream_TypeDef *)hdma->Instance)->CR) & DMA_SxCR_CIRC) == 0U)
1830   {
1831     hswpmi->RxXferCount = 0U;
1832 
1833     /* Disable the DMA transfer for the receiver request by setting the RXDMA bit
1834     in the SWPMI CR register */
1835     CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);
1836 
1837     /* Check if a transmit Process is ongoing or not */
1838     if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
1839     {
1840       hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
1841     }
1842     else
1843     {
1844       hswpmi->State = HAL_SWPMI_STATE_READY;
1845     }
1846   }
1847 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1848   hswpmi->RxCpltCallback(hswpmi);
1849 #else
1850   HAL_SWPMI_RxCpltCallback(hswpmi);
1851 #endif
1852 }
1853 
1854 /**
1855   * @brief DMA SWPMI receive process half complete callback.
1856   * @param hdma DMA handle
1857   * @retval None
1858   */
1859 static void SWPMI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1860 {
1861   SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1862 
1863 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1864   hswpmi->RxHalfCpltCallback(hswpmi);
1865 #else
1866   HAL_SWPMI_RxHalfCpltCallback(hswpmi);
1867 #endif
1868 }
1869 
1870 /**
1871   * @brief DMA SWPMI communication error callback.
1872   * @param hdma DMA handle
1873   * @retval None
1874   */
1875 static void SWPMI_DMAError(DMA_HandleTypeDef *hdma)
1876 {
1877   SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1878 
1879   /* Update handle */
1880   hswpmi->RxXferCount = 0U;
1881   hswpmi->TxXferCount = 0U;
1882   hswpmi->State = HAL_SWPMI_STATE_READY;
1883   hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA;
1884 
1885 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1886   hswpmi->ErrorCallback(hswpmi);
1887 #else
1888   HAL_SWPMI_ErrorCallback(hswpmi);
1889 #endif
1890 }
1891 
1892 /**
1893   * @brief DMA SWPMI communication abort callback.
1894   * @param hdma DMA handle
1895   * @retval None
1896   */
1897 static void SWPMI_DMAAbortOnError(DMA_HandleTypeDef *hdma)
1898 {
1899   SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1900 
1901   /* Update handle */
1902   hswpmi->RxXferCount = 0U;
1903   hswpmi->TxXferCount = 0U;
1904   hswpmi->State = HAL_SWPMI_STATE_READY;
1905 
1906 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1907   hswpmi->ErrorCallback(hswpmi);
1908 #else
1909   HAL_SWPMI_ErrorCallback(hswpmi);
1910 #endif
1911 }
1912 
1913 /**
1914   * @brief  Handle SWPMI Communication Timeout.
1915   * @param  hswpmi SWPMI handle
1916   * @param  Flag specifies the SWPMI flag to check.
1917   * @param  Tickstart Tick start value
1918   * @param  Timeout timeout duration.
1919   * @retval HAL status
1920   */
1921 static HAL_StatusTypeDef SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef *hswpmi, uint32_t Flag, uint32_t Tickstart, uint32_t Timeout)
1922 {
1923   HAL_StatusTypeDef status = HAL_OK;
1924 
1925   /* Wait until flag is set */
1926   while (!(HAL_IS_BIT_SET(hswpmi->Instance->ISR, Flag)))
1927   {
1928     /* Check for the Timeout */
1929     if ((((HAL_GetTick() - Tickstart) >  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1930     {
1931       /* Set the SWPMI state ready to be able to start again the process */
1932       hswpmi->State = HAL_SWPMI_STATE_READY;
1933 
1934       status = HAL_TIMEOUT;
1935       break;
1936     }
1937   }
1938 
1939   return status;
1940 }
1941 
1942 /**
1943   * @}
1944   */
1945 
1946 #endif /* HAL_SWPMI_MODULE_ENABLED */
1947 
1948 /**
1949   * @}
1950   */
1951 
1952 
1953 /**
1954   * @}
1955   */