/**
  ******************************************************************************
  * @file    stm32l4xx_hal_swpmi.c
  * @author  MCD Application Team
  * @brief   SWPMI HAL module driver.
  *          This file provides firmware functions to manage the following
  *          functionalities of the Single Wire Protocol Master Interface (SWPMI).
  *           + Initialization and Configuration
  *           + Data transfers functions
  *           + DMA transfers management
  *           + Interrupts and flags management
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2017 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  @verbatim
 ===============================================================================
                        ##### How to use this driver #####
 ===============================================================================
  [..]
     The SWPMI HAL driver can be used as follows:

    (#) Declare a SWPMI_HandleTypeDef handle structure (eg. SWPMI_HandleTypeDef hswpmi).

    (#) Initialize the SWPMI low level resources by implementing the HAL_SWPMI_MspInit() API:
        (##) Enable the SWPMIx interface clock with __HAL_RCC_SWPMIx_CLK_ENABLE().
        (##) SWPMI IO configuration:
            (+++) Enable the clock for the SWPMI GPIO.
            (+++) Configure these SWPMI pins as alternate function pull-up.
        (##) NVIC configuration if you need to use interrupt process (HAL_SWPMI_Transmit_IT()
             and HAL_SWPMI_Receive_IT() APIs):
            (+++) Configure the SWPMIx interrupt priority with HAL_NVIC_SetPriority().
            (+++) Enable the NVIC SWPMI IRQ handle with HAL_NVIC_EnableIRQ().

        (##) DMA Configuration if you need to use DMA process (HAL_SWPMI_Transmit_DMA()
             and HAL_SWPMI_Receive_DMA() APIs):
            (+++) Declare a DMA handle structure for the Tx/Rx channels.
            (+++) Enable the DMAx interface clock.
            (+++) Configure the declared DMA handle structure with the required
                  Tx/Rx parameters.
            (+++) Configure the DMA Tx/Rx channels and requests.
            (+++) Associate the initialized DMA handle to the SWPMI DMA Tx/Rx handle.
            (+++) Configure the priority and enable the NVIC for the transfer complete
                  interrupt on the DMA Tx/Rx channels.

    (#) Program the Bite Rate, Tx Buffering mode, Rx Buffering mode in the Init structure.

    (#) Enable the SWPMI peripheral by calling the HAL_SWPMI_Init() function.

  [..]
    Three operation modes are available within this driver :

    *** Polling mode IO operation ***
    =================================
    [..]
      (+) Send an amount of data in blocking mode using HAL_SWPMI_Transmit()
      (+) Receive an amount of data in blocking mode using HAL_SWPMI_Receive()

    *** Interrupt mode IO operation ***
    ===================================
    [..]
      (+) Send an amount of data in non-blocking mode using HAL_SWPMI_Transmit_IT()
      (+) At transmission end of transfer HAL_SWPMI_TxCpltCallback() is executed and user can
          add his own code by customization of function pointer HAL_SWPMI_TxCpltCallback()
      (+) Receive an amount of data in non-blocking mode using HAL_SWPMI_Receive_IT()
      (+) At reception end of transfer HAL_SWPMI_RxCpltCallback() is executed and user can
          add his own code by customization of function pointer HAL_SWPMI_RxCpltCallback()
      (+) In case of flag error, HAL_SWPMI_ErrorCallback() function is executed and user can
          add his own code by customization of function pointer HAL_SWPMI_ErrorCallback()

    *** DMA mode IO operation ***
    =============================
    [..]
      (+) Send an amount of data in non-blocking mode (DMA) using HAL_SWPMI_Transmit_DMA()
      (+) At transmission end of transfer HAL_SWPMI_TxCpltCallback() is executed and user can
          add his own code by customization of function pointer HAL_SWPMI_TxCpltCallback()
      (+) Receive an amount of data in non-blocking mode (DMA) using HAL_SWPMI_Receive_DMA()
      (+) At reception end of transfer HAL_SWPMI_RxCpltCallback() is executed and user can
          add his own code by customization of function pointer HAL_SWPMI_RxCpltCallback()
      (+) In case of flag error, HAL_SWPMI_ErrorCallback() function is executed and user can
          add his own code by customization of function pointer HAL_SWPMI_ErrorCallback()
      (+) Stop the DMA Transfer using HAL_SWPMI_DMAStop()

    *** SWPMI HAL driver additional function list ***
    ===============================================
    [..]
      Below the list the others API available SWPMI HAL driver :

      (+) HAL_SWPMI_EnableLoopback(): Enable the loopback mode for test purpose only
      (+) HAL_SWPMI_DisableLoopback(): Disable the loopback mode

    *** SWPMI HAL driver macros list ***
    ==================================
    [..]
      Below the list of most used macros in SWPMI HAL driver :

      (+) __HAL_SWPMI_ENABLE(): Enable the SWPMI peripheral
      (+) __HAL_SWPMI_DISABLE(): Disable the SWPMI peripheral
      (+) __HAL_SWPMI_ENABLE_IT(): Enable the specified SWPMI interrupts
      (+) __HAL_SWPMI_DISABLE_IT(): Disable the specified SWPMI interrupts
      (+) __HAL_SWPMI_GET_IT_SOURCE(): Check if the specified SWPMI interrupt source is
          enabled or disabled
      (+) __HAL_SWPMI_GET_FLAG(): Check whether the specified SWPMI flag is set or not

    *** Callback registration ***
    =============================
    [..]
      The compilation define USE_HAL_SWPMI_REGISTER_CALLBACKS when set to 1
      allows the user to configure dynamically the driver callbacks.
    [..]
      Use function HAL_SWPMI_RegisterCallback() to register a user callback. It allows
      to register the following callbacks:
      (+) RxCpltCallback     : SWPMI receive complete.
      (+) RxHalfCpltCallback : SWPMI receive half complete.
      (+) TxCpltCallback     : SWPMI transmit complete.
      (+) TxHalfCpltCallback : SWPMI transmit half complete.
      (+) ErrorCallback      : SWPMI error.
      (+) MspInitCallback    : SWPMI MspInit.
      (+) MspDeInitCallback  : SWPMI MspDeInit.
    [..]
    This function takes as parameters the HAL peripheral handle, the callback ID
    and a pointer to the user callback function.
    [..]
    Use function HAL_SWPMI_UnRegisterCallback() to reset a callback to the default
    weak (surcharged) function.
    HAL_SWPMI_UnRegisterCallback() takes as parameters the HAL peripheral handle,
    and the callback ID.
    This function allows to reset following callbacks:
      (+) RxCpltCallback     : SWPMI receive complete.
      (+) RxHalfCpltCallback : SWPMI receive half complete.
      (+) TxCpltCallback     : SWPMI transmit complete.
      (+) TxHalfCpltCallback : SWPMI transmit half complete.
      (+) ErrorCallback      : SWPMI error.
      (+) MspInitCallback    : SWPMI MspInit.
      (+) MspDeInitCallback  : SWPMI MspDeInit.
    [..]
    By default, after the HAL_SWPMI_Init and if the state is HAL_SWPMI_STATE_RESET
    all callbacks are reset to the corresponding legacy weak (surcharged) functions:
    examples HAL_SWPMI_RxCpltCallback(), HAL_SWPMI_ErrorCallback().
    Exception done for MspInit and MspDeInit callbacks that are respectively
    reset to the legacy weak (surcharged) functions in the HAL_SWPMI_Init
    and HAL_SWPMI_DeInit only when these callbacks are null (not registered beforehand).
    If not, MspInit or MspDeInit are not null, the HAL_SWPMI_Init and HAL_SWPMI_DeInit
    keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
    [..]
    Callbacks can be registered/unregistered in READY state only.
    Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
    in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
    during the Init/DeInit.
    In that case first register the MspInit/MspDeInit user callbacks
    using HAL_SWPMI_RegisterCallback before calling HAL_SWPMI_DeInit
    or HAL_SWPMI_Init function.
    [..]
    When the compilation define USE_HAL_SWPMI_REGISTER_CALLBACKS is set to 0 or
    not defined, the callback registering feature is not available
    and weak (surcharged) callbacks are used.

  @endverbatim
  */

/* Includes ------------------------------------------------------------------*/
#include "stm32l4xx_hal.h"

/** @addtogroup STM32L4xx_HAL_Driver
  * @{
  */

#if defined(SWPMI1)

/** @defgroup SWPMI SWPMI
  * @brief HAL SWPMI module driver
  * @{
  */
#ifdef HAL_SWPMI_MODULE_ENABLED

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/** @addtogroup SWPMI_Private_Constants SWPMI Private Constants
  * @{
  */
#define SWPMI_TIMEOUT_VALUE                   22000U   /* End of transmission timeout */

/**
  * @}
  */

/* Private macros ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
static void SWPMI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
static void SWPMI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
static void SWPMI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
static void SWPMI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
static void SWPMI_DMAError(DMA_HandleTypeDef *hdma);
static void SWPMI_DMAAbortOnError(DMA_HandleTypeDef *hdma);
static void SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi);
static void SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef *hswpmi);
static void SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi);
static void SWPMI_EndReceive_IT(SWPMI_HandleTypeDef *hswpmi);
static void SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef *hswpmi);
static HAL_StatusTypeDef SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef *hswpmi, uint32_t Flag, uint32_t Tickstart, uint32_t Timeout);

/* Exported functions --------------------------------------------------------*/

/** @defgroup SWPMI_Exported_Functions SWPMI Exported Functions
  * @{
  */

/** @defgroup SWPMI_Exported_Group1 Initialization/de-initialization methods
  *  @brief    Initialization and Configuration functions
  *
@verbatim
 ===============================================================================
            ##### Initialization and Configuration functions #####
 ===============================================================================
    [..]  This section provides functions allowing to:
      (+) Initialize and configure the SWPMI peripheral.
      (+) De-initialize the SWPMI peripheral.

@endverbatim
  * @{
  */

/**
  * @brief Initialize the SWPMI peripheral according to the specified parameters in the SWPMI_InitTypeDef.
  * @param hswpmi SWPMI handle
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SWPMI_Init(SWPMI_HandleTypeDef *hswpmi)
{
  HAL_StatusTypeDef status = HAL_OK;
  __IO uint32_t wait_loop_index = 0U;

  /* Check the SWPMI handle allocation */
  if (hswpmi == NULL)
  {
    status = HAL_ERROR;
  }
  else
  {
    /* Check the parameters */
    assert_param(IS_SWPMI_VOLTAGE_CLASS(hswpmi->Init.VoltageClass));
    assert_param(IS_SWPMI_BITRATE_VALUE(hswpmi->Init.BitRate));
    assert_param(IS_SWPMI_TX_BUFFERING_MODE(hswpmi->Init.TxBufferingMode));
    assert_param(IS_SWPMI_RX_BUFFERING_MODE(hswpmi->Init.RxBufferingMode));

    if (hswpmi->State == HAL_SWPMI_STATE_RESET)
    {
      /* Allocate lock resource and initialize it */
      hswpmi->Lock = HAL_UNLOCKED;

#if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
      /* Reset callback pointers to the weak predefined callbacks */
      hswpmi->RxCpltCallback     = HAL_SWPMI_RxCpltCallback;
      hswpmi->RxHalfCpltCallback = HAL_SWPMI_RxHalfCpltCallback;
      hswpmi->TxCpltCallback     = HAL_SWPMI_TxCpltCallback;
      hswpmi->TxHalfCpltCallback = HAL_SWPMI_TxHalfCpltCallback;
      hswpmi->ErrorCallback      = HAL_SWPMI_ErrorCallback;

      /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
      if (hswpmi->MspInitCallback == NULL)
      {
        hswpmi->MspInitCallback = HAL_SWPMI_MspInit;
      }
      hswpmi->MspInitCallback(hswpmi);
#else
      /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
      HAL_SWPMI_MspInit(hswpmi);
#endif
    }

    hswpmi->State = HAL_SWPMI_STATE_BUSY;

    /* Disable SWPMI interface */
    CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);

    /* Clear all SWPMI interface flags */
    WRITE_REG(hswpmi->Instance->ICR, 0x019F);

    /* Apply Voltage class selection */
    MODIFY_REG(hswpmi->Instance->OR, SWPMI_OR_CLASS, hswpmi->Init.VoltageClass);

    /* If Voltage class B, apply 300us delay */
    if (hswpmi->Init.VoltageClass == SWPMI_VOLTAGE_CLASS_B)
    {
      /* Insure 300us wait to insure SWPMI_IO output not higher than 1.8V */
      /* Wait loop initialization and execution                            */
      /* Note: Variable divided by 4 to compensate partially CPU processing cycles. */
      wait_loop_index = (300U * (SystemCoreClock / (1000000U * 4U))) + 150U;
      while (wait_loop_index != 0U)
      {
        wait_loop_index--;
      }
    }

    /* Configure the BRR register (Bitrate) */
    WRITE_REG(hswpmi->Instance->BRR, hswpmi->Init.BitRate);

    /* Apply SWPMI CR configuration */
    MODIFY_REG(hswpmi->Instance->CR, \
               SWPMI_CR_RXDMA | SWPMI_CR_TXDMA  | SWPMI_CR_RXMODE | SWPMI_CR_TXMODE, \
               hswpmi->Init.TxBufferingMode | hswpmi->Init.RxBufferingMode);

    hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
    hswpmi->State = HAL_SWPMI_STATE_READY;

    /* Enable SWPMI peripheral */
    SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  }

  return status;
}

/**
  * @brief De-initialize the SWPMI peripheral.
  * @param hswpmi SWPMI handle
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SWPMI_DeInit(SWPMI_HandleTypeDef *hswpmi)
{
  HAL_StatusTypeDef status = HAL_OK;

  /* Check the SWPMI handle allocation */
  if (hswpmi == NULL)
  {
    status = HAL_ERROR;
  }
  else
  {
    /* Check the parameters */
    assert_param(IS_SWPMI_INSTANCE(hswpmi->Instance));

    hswpmi->State = HAL_SWPMI_STATE_BUSY;

    /* Disable SWPMI interface */
    CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);

    /* Disable Loopback mode */
    CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);


    /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
#if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
    if (hswpmi->MspDeInitCallback == NULL)
    {
      hswpmi->MspDeInitCallback = HAL_SWPMI_MspDeInit;
    }
    hswpmi->MspDeInitCallback(hswpmi);
#else
    HAL_SWPMI_MspDeInit(hswpmi);
#endif

    hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
    hswpmi->State = HAL_SWPMI_STATE_RESET;

    /* Release Lock */
    __HAL_UNLOCK(hswpmi);
  }

  return status;
}

/**
  * @brief Initialize the SWPMI MSP.
  * @param hswpmi SWPMI handle
  * @retval None
  */
__weak void HAL_SWPMI_MspInit(SWPMI_HandleTypeDef *hswpmi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hswpmi);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_SWPMI_MspInit can be implemented in the user file
   */
}

/**
  * @brief DeInitialize the SWPMI MSP.
  * @param hswpmi SWPMI handle
  * @retval None
  */
__weak void HAL_SWPMI_MspDeInit(SWPMI_HandleTypeDef *hswpmi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hswpmi);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_SWPMI_MspDeInit can be implemented in the user file
   */
}

#if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
/**
  * @brief  Register a user SWPMI callback
  *         to be used instead of the weak predefined callback.
  * @param  hswpmi SWPMI handle.
  * @param  CallbackID ID of the callback to be registered.
  *         This parameter can be one of the following values:
  *           @arg @ref HAL_SWPMI_RX_COMPLETE_CB_ID receive complete callback ID.
  *           @arg @ref HAL_SWPMI_RX_HALFCOMPLETE_CB_ID receive half complete callback ID.
  *           @arg @ref HAL_SWPMI_TX_COMPLETE_CB_ID transmit complete callback ID.
  *           @arg @ref HAL_SWPMI_TX_HALFCOMPLETE_CB_ID transmit half complete callback ID.
  *           @arg @ref HAL_SWPMI_ERROR_CB_ID error callback ID.
  *           @arg @ref HAL_SWPMI_MSPINIT_CB_ID MSP init callback ID.
  *           @arg @ref HAL_SWPMI_MSPDEINIT_CB_ID MSP de-init callback ID.
  * @param  pCallback pointer to the callback function.
  * @retval HAL status.
  */
HAL_StatusTypeDef HAL_SWPMI_RegisterCallback(SWPMI_HandleTypeDef        *hswpmi,
                                             HAL_SWPMI_CallbackIDTypeDef CallbackID,
                                             pSWPMI_CallbackTypeDef      pCallback)
{
  HAL_StatusTypeDef status = HAL_OK;

  if (pCallback == NULL)
  {
    /* update the error code */
    hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
    /* update return status */
    status = HAL_ERROR;
  }
  else
  {
    if (hswpmi->State == HAL_SWPMI_STATE_READY)
    {
      switch (CallbackID)
      {
        case HAL_SWPMI_RX_COMPLETE_CB_ID :
          hswpmi->RxCpltCallback = pCallback;
          break;
        case HAL_SWPMI_RX_HALFCOMPLETE_CB_ID :
          hswpmi->RxHalfCpltCallback = pCallback;
          break;
        case HAL_SWPMI_TX_COMPLETE_CB_ID :
          hswpmi->TxCpltCallback = pCallback;
          break;
        case HAL_SWPMI_TX_HALFCOMPLETE_CB_ID :
          hswpmi->TxHalfCpltCallback = pCallback;
          break;
        case HAL_SWPMI_ERROR_CB_ID :
          hswpmi->ErrorCallback = pCallback;
          break;
        case HAL_SWPMI_MSPINIT_CB_ID :
          hswpmi->MspInitCallback = pCallback;
          break;
        case HAL_SWPMI_MSPDEINIT_CB_ID :
          hswpmi->MspDeInitCallback = pCallback;
          break;
        default :
          /* update the error code */
          hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
          /* update return status */
          status = HAL_ERROR;
          break;
      }
    }
    else if (hswpmi->State == HAL_SWPMI_STATE_RESET)
    {
      switch (CallbackID)
      {
        case HAL_SWPMI_MSPINIT_CB_ID :
          hswpmi->MspInitCallback = pCallback;
          break;
        case HAL_SWPMI_MSPDEINIT_CB_ID :
          hswpmi->MspDeInitCallback = pCallback;
          break;
        default :
          /* update the error code */
          hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
          /* update return status */
          status = HAL_ERROR;
          break;
      }
    }
    else
    {
      /* update the error code */
      hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
      /* update return status */
      status = HAL_ERROR;
    }
  }
  return status;
}

/**
  * @brief  Unregister a user SWPMI callback.
  *         SWPMI callback is redirected to the weak predefined callback.
  * @param  hswpmi SWPMI handle.
  * @param  CallbackID ID of the callback to be unregistered.
  *         This parameter can be one of the following values:
  *           @arg @ref HAL_SWPMI_RX_COMPLETE_CB_ID receive complete callback ID.
  *           @arg @ref HAL_SWPMI_RX_HALFCOMPLETE_CB_ID receive half complete callback ID.
  *           @arg @ref HAL_SWPMI_TX_COMPLETE_CB_ID transmit complete callback ID.
  *           @arg @ref HAL_SWPMI_TX_HALFCOMPLETE_CB_ID transmit half complete callback ID.
  *           @arg @ref HAL_SWPMI_ERROR_CB_ID error callback ID.
  *           @arg @ref HAL_SWPMI_MSPINIT_CB_ID MSP init callback ID.
  *           @arg @ref HAL_SWPMI_MSPDEINIT_CB_ID MSP de-init callback ID.
  * @retval HAL status.
  */
HAL_StatusTypeDef HAL_SWPMI_UnRegisterCallback(SWPMI_HandleTypeDef        *hswpmi,
                                               HAL_SWPMI_CallbackIDTypeDef CallbackID)
{
  HAL_StatusTypeDef status = HAL_OK;

  if (hswpmi->State == HAL_SWPMI_STATE_READY)
  {
    switch (CallbackID)
    {
      case HAL_SWPMI_RX_COMPLETE_CB_ID :
        hswpmi->RxCpltCallback = HAL_SWPMI_RxCpltCallback;
        break;
      case HAL_SWPMI_RX_HALFCOMPLETE_CB_ID :
        hswpmi->RxHalfCpltCallback = HAL_SWPMI_RxHalfCpltCallback;
        break;
      case HAL_SWPMI_TX_COMPLETE_CB_ID :
        hswpmi->TxCpltCallback = HAL_SWPMI_TxCpltCallback;
        break;
      case HAL_SWPMI_TX_HALFCOMPLETE_CB_ID :
        hswpmi->TxHalfCpltCallback = HAL_SWPMI_TxHalfCpltCallback;
        break;
      case HAL_SWPMI_ERROR_CB_ID :
        hswpmi->ErrorCallback = HAL_SWPMI_ErrorCallback;
        break;
      case HAL_SWPMI_MSPINIT_CB_ID :
        hswpmi->MspInitCallback = HAL_SWPMI_MspInit;
        break;
      case HAL_SWPMI_MSPDEINIT_CB_ID :
        hswpmi->MspDeInitCallback = HAL_SWPMI_MspDeInit;
        break;
      default :
        /* update the error code */
        hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
        /* update return status */
        status = HAL_ERROR;
        break;
    }
  }
  else if (hswpmi->State == HAL_SWPMI_STATE_RESET)
  {
    switch (CallbackID)
    {
      case HAL_SWPMI_MSPINIT_CB_ID :
        hswpmi->MspInitCallback = HAL_SWPMI_MspInit;
        break;
      case HAL_SWPMI_MSPDEINIT_CB_ID :
        hswpmi->MspDeInitCallback = HAL_SWPMI_MspDeInit;
        break;
      default :
        /* update the error code */
        hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
        /* update return status */
        status = HAL_ERROR;
        break;
    }
  }
  else
  {
    /* update the error code */
    hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
    /* update return status */
    status = HAL_ERROR;
  }
  return status;
}
#endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */

/**
  * @}
  */

/** @defgroup SWPMI_Exported_Group2 IO operation methods
  *  @brief SWPMI Transmit/Receive functions
  *
@verbatim
 ===============================================================================
                      ##### IO operation methods #####
 ===============================================================================
 [..]
    This subsection provides a set of functions allowing to manage the SWPMI
     data transfers.

    (#) There are two modes of transfer:
       (++) Blocking mode: The communication is performed in polling mode.
            The HAL status of all data processing is returned by the same function
            after finishing transfer.
       (++) Non-Blocking mode: The communication is performed using Interrupts
           or DMA. The end of the data processing will be indicated through the
           dedicated SWPMI Interrupt handler (HAL_SWPMI_IRQHandler()) when using Interrupt mode or
           the selected DMA channel interrupt handler when using DMA mode.
           The HAL_SWPMI_TxCpltCallback(), HAL_SWPMI_RxCpltCallback() user callbacks
           will be executed respectively at the end of the transmit or receive process.
           The HAL_SWPMI_ErrorCallback() user callback will be executed when a communication error is detected.

    (#) Blocking mode API's are:
        (++) HAL_SWPMI_Transmit()
        (++) HAL_SWPMI_Receive()

    (#) Non-Blocking mode API's with Interrupt are:
        (++) HAL_SWPMI_Transmit_IT()
        (++) HAL_SWPMI_Receive_IT()
        (++) HAL_SWPMI_IRQHandler()

    (#) Non-Blocking mode API's with DMA are:
        (++) HAL_SWPMI_Transmit_DMA()
        (++) HAL_SWPMI_Receive_DMA()
        (++) HAL_SWPMI_DMAPause()
        (++) HAL_SWPMI_DMAResume()
        (++) HAL_SWPMI_DMAStop()

    (#) A set of Transfer Complete Callbacks are provided in Non-Blocking mode:
        (++) HAL_SWPMI_TxHalfCpltCallback()
        (++) HAL_SWPMI_TxCpltCallback()
        (++) HAL_SWPMI_RxHalfCpltCallback()
        (++) HAL_SWPMI_RxCpltCallback()
        (++) HAL_SWPMI_ErrorCallback()

    (#) The capability to launch the above IO operations in loopback mode for
        user application verification:
        (++) HAL_SWPMI_EnableLoopback()
        (++) HAL_SWPMI_DisableLoopback()

@endverbatim
  * @{
  */

/**
  * @brief  Transmit an amount of data in blocking mode.
  * @param  hswpmi pointer to a SWPMI_HandleTypeDef structure that contains
  *                the configuration information for SWPMI module.
  * @param  pData Pointer to data buffer
  * @param  Size Amount of data to be sent
  * @param  Timeout Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SWPMI_Transmit(SWPMI_HandleTypeDef *hswpmi, const uint32_t *pData, uint16_t Size, uint32_t Timeout)
{
  uint32_t tickstart = HAL_GetTick();
  HAL_StatusTypeDef status = HAL_OK;
  HAL_SWPMI_StateTypeDef tmp_state;
  const uint32_t *ptmp_data;
  uint32_t tmp_size;

  if ((pData == NULL) || (Size == 0U))
  {
    status = HAL_ERROR;
  }
  else
  {
    /* Process Locked */
    __HAL_LOCK(hswpmi);

    tmp_state = hswpmi->State;
    if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_RX))
    {
      /* Check if a non-blocking receive process is ongoing or not */
      if (tmp_state == HAL_SWPMI_STATE_READY)
      {
        hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;

        /* Disable any transmitter interrupts */
        __HAL_SWPMI_DISABLE_IT(hswpmi, SWPMI_IT_TCIE | SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE);

        /* Disable any transmitter flags */
        __HAL_SWPMI_CLEAR_FLAG(hswpmi, SWPMI_FLAG_TXBEF | SWPMI_FLAG_TXUNRF | SWPMI_FLAG_TCF);

        /* Enable SWPMI peripheral if not */
        SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
      }
      else
      {
        hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
      }

      ptmp_data = pData;
      tmp_size = Size;
      do
      {
        /* Wait the TXE to write data */
        if (HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_TXE))
        {
          hswpmi->Instance->TDR = *ptmp_data;
          ptmp_data++;
          tmp_size--;
        }
        else
        {
          /* Check for the Timeout */
          if (Timeout != HAL_MAX_DELAY)
          {
            if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
            {
              status = HAL_TIMEOUT;
              break;
            }
          }
        }
      }
      while (tmp_size != 0U);

      /* Wait on TXBEF flag to be able to start a second transfer */
      if (SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, tickstart, Timeout) != HAL_OK)
      {
        /* Timeout occurred */
        hswpmi->ErrorCode |= HAL_SWPMI_ERROR_TXBEF_TIMEOUT;

        status = HAL_TIMEOUT;
      }

      if (status == HAL_OK)
      {
        /* Check if a non-blocking receive Process is ongoing or not */
        if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
        {
          hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
        }
        else
        {
          hswpmi->State = HAL_SWPMI_STATE_READY;
        }
      }
    }
    else
    {
      status = HAL_BUSY;
    }
  }

  if ((status != HAL_OK) && (status != HAL_BUSY))
  {
    hswpmi->State = HAL_SWPMI_STATE_READY;
  }
  /* Process Unlocked */
  __HAL_UNLOCK(hswpmi);

  return status;
}

/**
  * @brief  Receive an amount of data in blocking mode.
  * @param  hswpmi pointer to a SWPMI_HandleTypeDef structure that contains
  *                the configuration information for SWPMI module.
  * @param  pData Pointer to data buffer
  * @param  Size Amount of data to be received
  * @param  Timeout Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SWPMI_Receive(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size, uint32_t Timeout)
{
  uint32_t tickstart = HAL_GetTick();
  HAL_StatusTypeDef status = HAL_OK;
  HAL_SWPMI_StateTypeDef tmp_state;
  uint32_t *ptmp_data;
  uint32_t tmp_size;

  if ((pData == NULL) || (Size == 0U))
  {
    status = HAL_ERROR;
  }
  else
  {
    /* Process Locked */
    __HAL_LOCK(hswpmi);

    tmp_state = hswpmi->State;
    if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX))
    {
      /* Check if a non-blocking transmit process is ongoing or not */
      if (tmp_state == HAL_SWPMI_STATE_READY)
      {
        hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;

        /* Disable any receiver interrupts */
        CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_SRIE | SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);

        /* Enable SWPMI peripheral if not */
        SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
      }
      else
      {
        hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
      }

      ptmp_data = pData;
      tmp_size = Size;
      do
      {
        /* Wait the RXNE to read data */
        if (HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXNE))
        {
          *ptmp_data = hswpmi->Instance->RDR;
          ptmp_data++;
          tmp_size--;
        }
        else
        {
          /* Check for the Timeout */
          if (Timeout != HAL_MAX_DELAY)
          {
            if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
            {
              status = HAL_TIMEOUT;
              break;
            }
          }
        }
      }
      while (tmp_size != 0U);

      if (status == HAL_OK)
      {
        if (HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXBFF))
        {
          /* Clear RXBFF at end of reception */
          WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF);
        }

        /* Check if a non-blocking transmit Process is ongoing or not */
        if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
        {
          hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
        }
        else
        {
          hswpmi->State = HAL_SWPMI_STATE_READY;
        }
      }
    }
    else
    {
      status = HAL_BUSY;
    }
  }

  if ((status != HAL_OK) && (status != HAL_BUSY))
  {
    hswpmi->State = HAL_SWPMI_STATE_READY;
  }
  /* Process Unlocked */
  __HAL_UNLOCK(hswpmi);

  return status;
}

/**
  * @brief  Transmit an amount of data in non-blocking mode with interrupt.
  * @param  hswpmi pointer to a SWPMI_HandleTypeDef structure that contains
  *                the configuration information for SWPMI module.
  * @param  pData Pointer to data buffer
  * @param  Size Amount of data to be sent
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi, const uint32_t *pData, uint16_t Size)
{
  HAL_StatusTypeDef status = HAL_OK;
  HAL_SWPMI_StateTypeDef tmp_state;

  if ((pData == NULL) || (Size == 0U))
  {
    status =  HAL_ERROR;
  }
  else
  {
    /* Process Locked */
    __HAL_LOCK(hswpmi);

    tmp_state = hswpmi->State;
    if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_RX))
    {
      /* Update handle */
      hswpmi->pTxBuffPtr = pData;
      hswpmi->TxXferSize = Size;
      hswpmi->TxXferCount = Size;
      hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;

      /* Check if a receive process is ongoing or not */
      if (tmp_state == HAL_SWPMI_STATE_READY)
      {
        hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;

        /* Enable SWPMI peripheral if not */
        SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
      }
      else
      {
        hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
      }

      /* Enable the SWPMI transmit underrun error */
      __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TXUNRIE);

      /* Process Unlocked */
      __HAL_UNLOCK(hswpmi);

      /* Enable the SWPMI interrupts:      */
      /* - Transmit data register empty    */
      /* - Transmit buffer empty           */
      /* - Transmit/Reception completion   */
      __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TIE | SWPMI_IT_TXBEIE | SWPMI_IT_TCIE);
    }
    else
    {
      status =  HAL_BUSY;

      /* Process Unlocked */
      __HAL_UNLOCK(hswpmi);
    }
  }

  return status;
}

/**
  * @brief  Receive an amount of data in non-blocking mode with interrupt.
  * @param  hswpmi SWPMI handle
  * @param  pData Pointer to data buffer
  * @param  Size Amount of data to be received
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
{
  HAL_StatusTypeDef status = HAL_OK;
  HAL_SWPMI_StateTypeDef tmp_state;

  if ((pData == NULL) || (Size == 0U))
  {
    status =  HAL_ERROR;
  }
  else
  {
    /* Process Locked */
    __HAL_LOCK(hswpmi);

    tmp_state = hswpmi->State;
    if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX))
    {
      /* Update handle */
      hswpmi->pRxBuffPtr = pData;
      hswpmi->RxXferSize = Size;
      hswpmi->RxXferCount = Size;
      hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;

      /* Check if a transmit process is ongoing or not */
      if (tmp_state == HAL_SWPMI_STATE_READY)
      {
        hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;

        /* Enable SWPMI peripheral if not */
        SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
      }
      else
      {
        hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
      }

      /* Process Unlocked */
      __HAL_UNLOCK(hswpmi);

      /* Enable the SWPMI slave resume */
      /* Enable the SWPMI Data Register not empty Interrupt, receive CRC Error, receive overrun and RxBuf Interrupt */
      /*  Enable the SWPMI Transmit/Reception completion   */
      __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
    }
    else
    {
      status = HAL_BUSY;

      /* Process Unlocked */
      __HAL_UNLOCK(hswpmi);
    }
  }

  return status;
}

/**
  * @brief  Transmit an amount of data in non-blocking mode with DMA interrupt.
  * @param  hswpmi SWPMI handle
  * @param  pData Pointer to data buffer
  * @param  Size Amount of data to be sent
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SWPMI_Transmit_DMA(SWPMI_HandleTypeDef *hswpmi, const uint32_t *pData, uint16_t Size)
{
  HAL_StatusTypeDef status = HAL_OK;
  HAL_SWPMI_StateTypeDef tmp_state;

  if ((pData == NULL) || (Size == 0U))
  {
    status =  HAL_ERROR;
  }
  else
  {
    /* Process Locked */
    __HAL_LOCK(hswpmi);

    tmp_state = hswpmi->State;
    if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_RX))
    {
      /* Update handle */
      hswpmi->pTxBuffPtr = pData;
      hswpmi->TxXferSize = Size;
      hswpmi->TxXferCount = Size;
      hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;

      /* Check if a receive process is ongoing or not */
      if (tmp_state == HAL_SWPMI_STATE_READY)
      {
        hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;

        /* Enable SWPMI peripheral if not */
        SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
      }
      else
      {
        hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
      }

      /* Set the SWPMI DMA transfer complete callback */
      hswpmi->hdmatx->XferCpltCallback = SWPMI_DMATransmitCplt;

      /* Set the SWPMI DMA Half transfer complete callback */
      hswpmi->hdmatx->XferHalfCpltCallback = SWPMI_DMATxHalfCplt;

      /* Set the DMA error callback */
      hswpmi->hdmatx->XferErrorCallback = SWPMI_DMAError;

      /* Enable the SWPMI transmit DMA channel */
      if (HAL_DMA_Start_IT(hswpmi->hdmatx, (uint32_t)hswpmi->pTxBuffPtr, (uint32_t)&hswpmi->Instance->TDR, Size) != HAL_OK)
      {
        hswpmi->State = tmp_state;    /* Back to previous state */
        hswpmi->ErrorCode = HAL_SWPMI_ERROR_DMA;
        status = HAL_ERROR;

        /* Process Unlocked */
        __HAL_UNLOCK(hswpmi);
      }
      else
      {
        /* Process Unlocked */
        __HAL_UNLOCK(hswpmi);

        /* Enable the SWPMI transmit underrun error */
        __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TXUNRIE);

        /* Enable the DMA transfer for transmit request by setting the TXDMA bit
           in the SWPMI CR register */
        SET_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);
      }
    }
    else
    {
      status = HAL_BUSY;

      /* Process Unlocked */
      __HAL_UNLOCK(hswpmi);
    }
  }

  return status;
}

/**
  * @brief  Receive an amount of data in non-blocking mode with DMA interrupt.
  * @param  hswpmi SWPMI handle
  * @param  pData Pointer to data buffer
  * @param  Size Amount of data to be received
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SWPMI_Receive_DMA(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
{
  HAL_StatusTypeDef status = HAL_OK;
  HAL_SWPMI_StateTypeDef tmp_state;

  if ((pData == NULL) || (Size == 0U))
  {
    status =  HAL_ERROR;
  }
  else
  {
    /* Process Locked */
    __HAL_LOCK(hswpmi);

    tmp_state = hswpmi->State;
    if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX))
    {
      /* Update handle */
      hswpmi->pRxBuffPtr = pData;
      hswpmi->RxXferSize = Size;
      hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;

      /* Check if a transmit process is ongoing or not */
      if (tmp_state == HAL_SWPMI_STATE_READY)
      {
        hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;

        /* Enable SWPMI peripheral if not */
        SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
      }
      else
      {
        hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
      }

      /* Set the SWPMI DMA transfer complete callback */
      hswpmi->hdmarx->XferCpltCallback = SWPMI_DMAReceiveCplt;

      /* Set the SWPMI DMA Half transfer complete callback */
      hswpmi->hdmarx->XferHalfCpltCallback = SWPMI_DMARxHalfCplt;

      /* Set the DMA error callback */
      hswpmi->hdmarx->XferErrorCallback = SWPMI_DMAError;

      /* Enable the DMA request */
      if (HAL_DMA_Start_IT(hswpmi->hdmarx, (uint32_t)&hswpmi->Instance->RDR, (uint32_t)hswpmi->pRxBuffPtr, Size) != HAL_OK)
      {
        hswpmi->State = tmp_state;    /* Back to previous state */
        hswpmi->ErrorCode = HAL_SWPMI_ERROR_DMA;
        status = HAL_ERROR;

        /* Process Unlocked */
        __HAL_UNLOCK(hswpmi);
      }
      else
      {
        /* Process Unlocked */
        __HAL_UNLOCK(hswpmi);

        /* Enable the SWPMI receive CRC Error and receive overrun interrupts */
        __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE);

        /* Enable the DMA transfer for the receiver request by setting the RXDMA bit
           in the SWPMI CR register */
        SET_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);
      }
    }
    else
    {
      status = HAL_BUSY;

      /* Process Unlocked */
      __HAL_UNLOCK(hswpmi);
    }
  }

  return status;
}

/**
  * @brief Stop all DMA transfers.
  * @param hswpmi SWPMI handle
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SWPMI_DMAStop(SWPMI_HandleTypeDef *hswpmi)
{
  HAL_StatusTypeDef status = HAL_OK;

  /* Process Locked */
  __HAL_LOCK(hswpmi);

  /* Disable the SWPMI Tx/Rx DMA requests */
  CLEAR_BIT(hswpmi->Instance->CR, (SWPMI_CR_TXDMA | SWPMI_CR_RXDMA));

  /* Abort the SWPMI DMA tx channel */
  if (hswpmi->hdmatx != NULL)
  {
    if (HAL_DMA_Abort(hswpmi->hdmatx) != HAL_OK)
    {
      hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA;
      status = HAL_ERROR;
    }
  }
  /* Abort the SWPMI DMA rx channel */
  if (hswpmi->hdmarx != NULL)
  {
    if (HAL_DMA_Abort(hswpmi->hdmarx) != HAL_OK)
    {
      hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA;
      status = HAL_ERROR;
    }
  }

  /* Disable SWPMI interface */
  CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);

  hswpmi->State = HAL_SWPMI_STATE_READY;

  /* Process Unlocked */
  __HAL_UNLOCK(hswpmi);

  return status;
}


/**
  * @brief Enable the Loopback mode.
  * @param hswpmi SWPMI handle
  * @note  Loopback mode is to be used only for test purposes
  * @retval HAL_OK / HAL_BUSY
  */
HAL_StatusTypeDef HAL_SWPMI_EnableLoopback(SWPMI_HandleTypeDef *hswpmi)
{
  HAL_StatusTypeDef  status = HAL_OK;

  /* Process Locked */
  __HAL_LOCK(hswpmi);

  /* Make sure the SWPMI interface is not enabled to set the loopback mode */
  CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);

  /* Set Loopback */
  SET_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);

  /* Enable SWPMI interface in loopback mode */
  SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);

  /* Process Unlocked */
  __HAL_UNLOCK(hswpmi);

  return status;
}

/**
  * @brief Disable the Loopback mode.
  * @param hswpmi SWPMI handle
  * @note  Loopback mode is to be used only for test purposes
  * @retval HAL_OK / HAL_BUSY
  */
HAL_StatusTypeDef HAL_SWPMI_DisableLoopback(SWPMI_HandleTypeDef *hswpmi)
{
  HAL_StatusTypeDef  status = HAL_OK;

  /* Process Locked */
  __HAL_LOCK(hswpmi);

  /* Make sure the SWPMI interface is not enabled to reset the loopback mode */
  CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);

  /* Reset Loopback */
  CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);

  /* Re-enable SWPMI interface in normal mode */
  SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);

  /* Process Unlocked */
  __HAL_UNLOCK(hswpmi);

  return status;
}

/**
  * @}
  */

/** @defgroup SWPMI_Exported_Group3 SWPMI IRQ handler and callbacks
 *  @brief  SWPMI  IRQ handler.
 *
@verbatim
  ==============================================================================
                      ##### SWPMI IRQ handler and callbacks  #####
  ==============================================================================
[..]  This section provides SWPMI IRQ handler and callback functions called within
      the IRQ handler.

@endverbatim
  * @{
  */

/**
  * @brief Handle SWPMI interrupt request.
  * @param hswpmi SWPMI handle
  * @retval None
  */
void HAL_SWPMI_IRQHandler(SWPMI_HandleTypeDef *hswpmi)
{
  uint32_t regisr = READ_REG(hswpmi->Instance->ISR);
  uint32_t regier = READ_REG(hswpmi->Instance->IER);
  uint32_t errcode = HAL_SWPMI_ERROR_NONE;

  /* SWPMI CRC error interrupt occurred --------------------------------------*/
  if (((regisr & SWPMI_FLAG_RXBERF) != 0U) && ((regier & SWPMI_IT_RXBERIE) != 0U))
  {
    /* Disable Receive CRC interrupt */
    CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RXBERIE | SWPMI_IT_RXBFIE);
    /* Clear Receive CRC and Receive buffer full flag */
    WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBERF | SWPMI_FLAG_RXBFF);

    errcode |= HAL_SWPMI_ERROR_CRC;
  }

  /* SWPMI Over-Run interrupt occurred -----------------------------------------*/
  if (((regisr & SWPMI_FLAG_RXOVRF) != 0U) && ((regier & SWPMI_IT_RXOVRIE) != 0U))
  {
    /* Disable Receive overrun interrupt */
    CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RXOVRIE);
    /* Clear Receive overrun flag */
    WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXOVRF);

    errcode |= HAL_SWPMI_ERROR_OVR;
  }

  /* SWPMI Under-Run interrupt occurred -----------------------------------------*/
  if (((regisr & SWPMI_FLAG_TXUNRF) != 0U) && ((regier & SWPMI_IT_TXUNRIE) != 0U))
  {
    /* Disable Transmit under run interrupt */
    CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TXUNRIE);
    /* Clear Transmit under run flag */
    WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TXUNRF);

    errcode |= HAL_SWPMI_ERROR_UDR;
  }

  /* Call SWPMI Error Call back function if needed --------------------------*/
  if (errcode != HAL_SWPMI_ERROR_NONE)
  {
    hswpmi->ErrorCode |= errcode;

    if ((errcode & HAL_SWPMI_ERROR_UDR) != 0U)
    {
      /* Check TXDMA transfer to abort */
      if (HAL_IS_BIT_SET(hswpmi->Instance->CR, SWPMI_CR_TXDMA))
      {
        /* Disable DMA TX at SWPMI level */
        CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);

        /* Abort the USART DMA Tx channel */
        if (hswpmi->hdmatx != NULL)
        {
          /* Set the SWPMI Tx DMA Abort callback :
             will lead to call HAL_SWPMI_ErrorCallback() at end of DMA abort procedure */
          hswpmi->hdmatx->XferAbortCallback = SWPMI_DMAAbortOnError;
          /* Abort DMA TX */
          if (HAL_DMA_Abort_IT(hswpmi->hdmatx) != HAL_OK)
          {
            /* Call Directly hswpmi->hdmatx->XferAbortCallback function in case of error */
            hswpmi->hdmatx->XferAbortCallback(hswpmi->hdmatx);
          }
        }
        else
        {
          /* Set the SWPMI state ready to be able to start again the process */
          hswpmi->State = HAL_SWPMI_STATE_READY;

#if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
          hswpmi->ErrorCallback(hswpmi);
#else
          HAL_SWPMI_ErrorCallback(hswpmi);
#endif
        }
      }
      else
      {
        /* Set the SWPMI state ready to be able to start again the process */
        hswpmi->State = HAL_SWPMI_STATE_READY;

#if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
        hswpmi->ErrorCallback(hswpmi);
#else
        HAL_SWPMI_ErrorCallback(hswpmi);
#endif
      }
    }
    else
    {
      /* Check RXDMA transfer to abort */
      if (HAL_IS_BIT_SET(hswpmi->Instance->CR, SWPMI_CR_RXDMA))
      {
        /* Disable DMA RX at SWPMI level */
        CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);

        /* Abort the USART DMA Rx channel */
        if (hswpmi->hdmarx != NULL)
        {
          /* Set the SWPMI Rx DMA Abort callback :
             will lead to call HAL_SWPMI_ErrorCallback() at end of DMA abort procedure */
          hswpmi->hdmarx->XferAbortCallback = SWPMI_DMAAbortOnError;
          /* Abort DMA RX */
          if (HAL_DMA_Abort_IT(hswpmi->hdmarx) != HAL_OK)
          {
            /* Call Directly hswpmi->hdmarx->XferAbortCallback function in case of error */
            hswpmi->hdmarx->XferAbortCallback(hswpmi->hdmarx);
          }
        }
        else
        {
          /* Set the SWPMI state ready to be able to start again the process */
          hswpmi->State = HAL_SWPMI_STATE_READY;

#if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
          hswpmi->ErrorCallback(hswpmi);
#else
          HAL_SWPMI_ErrorCallback(hswpmi);
#endif
        }
      }
      else
      {
        /* Set the SWPMI state ready to be able to start again the process */
        hswpmi->State = HAL_SWPMI_STATE_READY;

#if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
        hswpmi->ErrorCallback(hswpmi);
#else
        HAL_SWPMI_ErrorCallback(hswpmi);
#endif
      }
    }
  }

  /* SWPMI in mode Receiver ---------------------------------------------------*/
  if (((regisr & SWPMI_FLAG_RXNE) != 0U) && ((regier & SWPMI_IT_RIE)  != 0U))
  {
    SWPMI_Receive_IT(hswpmi);
  }

  /* SWPMI in mode Transmitter ------------------------------------------------*/
  if (((regisr & SWPMI_FLAG_TXE) != 0U) && ((regier & SWPMI_IT_TIE) != 0U))
  {
    SWPMI_Transmit_IT(hswpmi);
  }

  /* SWPMI in mode Transmitter (Transmit buffer empty) ------------------------*/
  if (((regisr & SWPMI_FLAG_TXBEF) != 0U) && ((regier & SWPMI_IT_TXBEIE) != 0U))
  {
    SWPMI_EndTransmit_IT(hswpmi);
  }

  /* SWPMI in mode Receiver (Receive buffer full) -----------------------------*/
  if (((regisr & SWPMI_FLAG_RXBFF) != 0U) && ((regier & SWPMI_IT_RXBFIE) != 0U))
  {
    SWPMI_EndReceive_IT(hswpmi);
  }

  /* Both Transmission and reception complete ---------------------------------*/
  if (((regisr & SWPMI_FLAG_TCF) != 0U) && ((regier & SWPMI_IT_TCIE) != 0U))
  {
    SWPMI_EndTransmitReceive_IT(hswpmi);
  }
}

/**
  * @brief Tx Transfer completed callback.
  * @param hswpmi SWPMI handle
  * @retval None
  */
__weak void HAL_SWPMI_TxCpltCallback(SWPMI_HandleTypeDef *hswpmi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hswpmi);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_SWPMI_TxCpltCallback is to be implemented in the user file
   */
}

/**
  * @brief  Tx Half Transfer completed callback.
  * @param  hswpmi SWPMI handle
  * @retval None
  */
__weak void HAL_SWPMI_TxHalfCpltCallback(SWPMI_HandleTypeDef *hswpmi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hswpmi);

  /* NOTE: This function should not be modified, when the callback is needed,
           the HAL_SWPMI_TxHalfCpltCallback is to be implemented in the user file
   */
}

/**
  * @brief Rx Transfer completed callback.
  * @param hswpmi SWPMI handle
  * @retval None
  */
__weak void HAL_SWPMI_RxCpltCallback(SWPMI_HandleTypeDef *hswpmi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hswpmi);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_SWPMI_RxCpltCallback is to be implemented in the user file
   */
}

/**
  * @brief  Rx Half Transfer completed callback.
  * @param  hswpmi SWPMI handle
  * @retval None
  */
__weak void HAL_SWPMI_RxHalfCpltCallback(SWPMI_HandleTypeDef *hswpmi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hswpmi);

  /* NOTE: This function should not be modified, when the callback is needed,
           the HAL_SWPMI_RxHalfCpltCallback is to be implemented in the user file
   */
}

/**
  * @brief SWPMI error callback.
  * @param hswpmi SWPMI handle
  * @retval None
  */
__weak void HAL_SWPMI_ErrorCallback(SWPMI_HandleTypeDef *hswpmi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hswpmi);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_SWPMI_ErrorCallback is to be implemented in the user file
   */
}

/**
  * @}
  */

/** @defgroup SWPMI_Exported_Group4 Peripheral Control methods
  *  @brief   SWPMI control functions
  *
@verbatim
 ===============================================================================
                      ##### Peripheral Control methods #####
 ===============================================================================
    [..]
    This subsection provides a set of functions allowing to control the SWPMI.
     (+) HAL_SWPMI_GetState() API is helpful to check in run-time the state of the SWPMI peripheral
     (+) HAL_SWPMI_GetError() API is helpful to check in run-time the error state of the SWPMI peripheral
@endverbatim
  * @{
  */

/**
  * @brief Return the SWPMI handle state.
  * @param hswpmi SWPMI handle
  * @retval HAL state
  */
HAL_SWPMI_StateTypeDef HAL_SWPMI_GetState(const SWPMI_HandleTypeDef *hswpmi)
{
  /* Return SWPMI handle state */
  return hswpmi->State;
}

/**
* @brief  Return the SWPMI error code.
* @param  hswpmi : pointer to a SWPMI_HandleTypeDef structure that contains
  *              the configuration information for the specified SWPMI.
* @retval SWPMI Error Code
*/
uint32_t HAL_SWPMI_GetError(const SWPMI_HandleTypeDef *hswpmi)
{
  return hswpmi->ErrorCode;
}

/**
  * @}
  */

/**
  * @}
  */

/* Private functions ---------------------------------------------------------*/

/** @defgroup SWPMI_Private_Functions SWPMI Private Functions
  * @{
  */

/**
  * @brief Transmit an amount of data in interrupt mode.
  * @note  Function called under interruption only, once interruptions have been enabled by HAL_SWPMI_Transmit_IT()
  * @param  hswpmi SWPMI handle
  * @retval None
  */
static void SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi)
{
  HAL_SWPMI_StateTypeDef tmp_state = hswpmi->State;

  if ((tmp_state == HAL_SWPMI_STATE_BUSY_TX) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX_RX))
  {
    if (hswpmi->TxXferCount == 0U)
    {
      /* Disable the SWPMI TXE and Underrun Interrupts */
      CLEAR_BIT(hswpmi->Instance->IER, (SWPMI_IT_TIE | SWPMI_IT_TXUNRIE));
    }
    else
    {
      hswpmi->Instance->TDR = (uint32_t) * hswpmi->pTxBuffPtr;
      hswpmi->pTxBuffPtr++;
      hswpmi->TxXferCount--;
    }
  }
  else
  {
    /* nothing to do */
  }
}

/**
  * @brief  Wraps up transmission in non-blocking mode.
  * @param  hswpmi SWPMI handle
  * @retval None
  */
static void SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef *hswpmi)
{
  /* Clear the SWPMI Transmit buffer empty Flag */
  WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TXBEF);
  /* Disable the all SWPMI Transmit Interrupts  */
  CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE);

  /* Check if a receive Process is ongoing or not */
  if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
  {
    hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
  }
  else
  {
    hswpmi->State = HAL_SWPMI_STATE_READY;
  }

#if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  hswpmi->TxCpltCallback(hswpmi);
#else
  HAL_SWPMI_TxCpltCallback(hswpmi);
#endif
}

/**
  * @brief Receive an amount of data in interrupt mode.
  * @note  Function called under interruption only, once interruptions have been enabled by HAL_SWPMI_Receive_IT()
  * @param  hswpmi SWPMI handle
  * @retval None
  */
static void SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi)
{
  HAL_SWPMI_StateTypeDef tmp_state = hswpmi->State;

  if ((tmp_state == HAL_SWPMI_STATE_BUSY_RX) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX_RX))
  {
    *hswpmi->pRxBuffPtr = (uint32_t)(hswpmi->Instance->RDR);
    hswpmi->pRxBuffPtr++;

    --hswpmi->RxXferCount;
    if (hswpmi->RxXferCount == 0U)
    {
      /* Wait for RXBFF flag to update state */
#if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
      hswpmi->RxCpltCallback(hswpmi);
#else
      HAL_SWPMI_RxCpltCallback(hswpmi);
#endif
    }
  }
  else
  {
    /* nothing to do */
  }
}

/**
  * @brief  Wraps up reception in non-blocking mode.
  * @param  hswpmi SWPMI handle
  * @retval None
  */
static void SWPMI_EndReceive_IT(SWPMI_HandleTypeDef *hswpmi)
{
  /* Clear the SWPMI Receive buffer full Flag */
  WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF);
  /* Disable the all SWPMI Receive Interrupts  */
  CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);

  /* Check if a transmit Process is ongoing or not */
  if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
  {
    hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
  }
  else
  {
    hswpmi->State = HAL_SWPMI_STATE_READY;
  }
}

/**
  * @brief  Wraps up transmission and reception in non-blocking mode.
  * @param  hswpmi SWPMI handle
  * @retval None
  */
static void SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef *hswpmi)
{
  /* Clear the SWPMI Transmission Complete Flag */
  WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TCF);
  /* Disable the SWPMI Transmission  Complete Interrupt */
  CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TCIE);

  /* Check if a receive Process is ongoing or not */
  if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
  {
    hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
  }
  else if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX)
  {
    hswpmi->State = HAL_SWPMI_STATE_READY;
  }
  else
  {
    /* nothing to do */
  }
}

/**
  * @brief DMA SWPMI transmit process complete callback.
  * @param hdma DMA handle
  * @retval None
  */
static void SWPMI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
  SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
  uint32_t tickstart;

  /* DMA Normal mode*/
  if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
  {
    hswpmi->TxXferCount = 0U;

    /* Disable the DMA transfer for transmit request by setting the TXDMA bit
    in the SWPMI CR register */
    CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);

    /* Init tickstart for timeout management*/
    tickstart = HAL_GetTick();

    /* Wait the TXBEF */
    if (SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, tickstart, SWPMI_TIMEOUT_VALUE) != HAL_OK)
    {
      /* Timeout occurred */
      hswpmi->ErrorCode |= HAL_SWPMI_ERROR_TXBEF_TIMEOUT;

#if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
      hswpmi->ErrorCallback(hswpmi);
#else
      HAL_SWPMI_ErrorCallback(hswpmi);
#endif
    }
    else
    {
      /* No Timeout */
      /* Check if a receive process is ongoing or not */
      if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
      {
        hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
      }
      else
      {
        hswpmi->State = HAL_SWPMI_STATE_READY;
      }

#if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
      hswpmi->TxCpltCallback(hswpmi);
#else
      HAL_SWPMI_TxCpltCallback(hswpmi);
#endif
    }
  }
  /* DMA Circular mode */
  else
  {
#if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
    hswpmi->TxCpltCallback(hswpmi);
#else
    HAL_SWPMI_TxCpltCallback(hswpmi);
#endif
  }
}

/**
  * @brief DMA SWPMI transmit process half complete callback.
  * @param hdma DMA handle
  * @retval None
  */
static void SWPMI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
{
  SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;

#if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  hswpmi->TxHalfCpltCallback(hswpmi);
#else
  HAL_SWPMI_TxHalfCpltCallback(hswpmi);
#endif
}


/**
  * @brief DMA SWPMI receive process complete callback.
  * @param hdma DMA handle
  * @retval None
  */
static void SWPMI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
{
  SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;

  /* DMA Normal mode*/
  if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
  {
    hswpmi->RxXferCount = 0U;

    /* Disable the DMA transfer for the receiver request by setting the RXDMA bit
    in the SWPMI CR register */
    CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);

    /* Check if a transmit Process is ongoing or not */
    if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
    {
      hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
    }
    else
    {
      hswpmi->State = HAL_SWPMI_STATE_READY;
    }
  }
#if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  hswpmi->RxCpltCallback(hswpmi);
#else
  HAL_SWPMI_RxCpltCallback(hswpmi);
#endif
}

/**
  * @brief DMA SWPMI receive process half complete callback.
  * @param hdma DMA handle
  * @retval None
  */
static void SWPMI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
{
  SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;

#if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  hswpmi->RxHalfCpltCallback(hswpmi);
#else
  HAL_SWPMI_RxHalfCpltCallback(hswpmi);
#endif
}

/**
  * @brief DMA SWPMI communication error callback.
  * @param hdma DMA handle
  * @retval None
  */
static void SWPMI_DMAError(DMA_HandleTypeDef *hdma)
{
  SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;

  /* Update handle */
  hswpmi->RxXferCount = 0U;
  hswpmi->TxXferCount = 0U;
  hswpmi->State = HAL_SWPMI_STATE_READY;
  hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA;

#if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  hswpmi->ErrorCallback(hswpmi);
#else
  HAL_SWPMI_ErrorCallback(hswpmi);
#endif
}

/**
  * @brief DMA SWPMI communication abort callback.
  * @param hdma DMA handle
  * @retval None
  */
static void SWPMI_DMAAbortOnError(DMA_HandleTypeDef *hdma)
{
  SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;

  /* Update handle */
  hswpmi->RxXferCount = 0U;
  hswpmi->TxXferCount = 0U;
  hswpmi->State = HAL_SWPMI_STATE_READY;

#if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  hswpmi->ErrorCallback(hswpmi);
#else
  HAL_SWPMI_ErrorCallback(hswpmi);
#endif
}

/**
  * @brief  Handle SWPMI Communication Timeout.
  * @param  hswpmi SWPMI handle
  * @param  Flag specifies the SWPMI flag to check.
  * @param  Tickstart Tick start value
  * @param  Timeout timeout duration.
  * @retval HAL status
  */
static HAL_StatusTypeDef SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef *hswpmi, uint32_t Flag, uint32_t Tickstart, uint32_t Timeout)
{
  HAL_StatusTypeDef status = HAL_OK;

  /* Wait until flag is set */
  while (!(HAL_IS_BIT_SET(hswpmi->Instance->ISR, Flag)))
  {
    /* Check for the Timeout */
    if ((((HAL_GetTick() - Tickstart) >  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
    {
      /* Set the SWPMI state ready to be able to start again the process */
      hswpmi->State = HAL_SWPMI_STATE_READY;

      status = HAL_TIMEOUT;
      break;
    }
  }

  return status;
}

/**
  * @}
  */

#endif /* HAL_SWPMI_MODULE_ENABLED */

/**
  * @}
  */

#endif /* SWPMI1 */

/**
  * @}
  */
