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