Hal Drivers for L4

Dependents:   BSP OneHopeOnePrayer FINAL_AUDIO_RECORD AudioDemo

Fork of STM32L4xx_HAL_Driver by Senior Design: Sound Monitor

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32l4xx_hal_swpmi.c Source File

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   * @version V1.1.0
00006   * @date    16-September-2015
00007   * @brief   SWPMI HAL module driver.
00008   *          This file provides firmware functions to manage the following
00009   *          functionalities of the Single Wire Protocol Master Interface (SWPMI).
00010   *           + Initialization and Configuration
00011   *           + Data transfers functions
00012   *           + DMA transfers management
00013   *           + Interrupts and flags management
00014   @verbatim
00015  ===============================================================================
00016                         ##### How to use this driver #####
00017  ===============================================================================
00018   [..]
00019      The SWPMI HAL driver can be used as follows:
00020 
00021     (#) Declare a SWPMI_HandleTypeDef handle structure (eg. SWPMI_HandleTypeDef hswpmi).
00022 
00023     (#) Initialize the SWPMI low level resources by implementing the HAL_SWPMI_MspInit() API:
00024         (##) Enable the SWPMIx interface clock with __HAL_RCC_SWPMIx_CLK_ENABLE().
00025         (##) SWPMI IO configuration:
00026             (+++) Enable the clock for the SWPMI GPIO.
00027             (+++) Configure these SWPMI pins as alternate function pull-up.
00028         (##) NVIC configuration if you need to use interrupt process (HAL_SWPMI_Transmit_IT()
00029              and HAL_SWPMI_Receive_IT() APIs):
00030             (+++) Configure the SWPMIx interrupt priority with HAL_NVIC_SetPriority().
00031             (+++) Enable the NVIC SWPMI IRQ handle with HAL_NVIC_EnableIRQ().
00032 
00033         (##) DMA Configuration if you need to use DMA process (HAL_SWPMI_Transmit_DMA()
00034              and HAL_SWPMI_Receive_DMA() APIs):
00035             (+++) Declare a DMA handle structure for the Tx/Rx channels.
00036             (+++) Enable the DMAx interface clock.
00037             (+++) Configure the declared DMA handle structure with the required
00038                   Tx/Rx parameters.
00039             (+++) Configure the DMA Tx/Rx channels and requests.
00040             (+++) Associate the initialized DMA handle to the SWPMI DMA Tx/Rx handle.
00041             (+++) Configure the priority and enable the NVIC for the transfer complete
00042                   interrupt on the DMA Tx/Rx channels.
00043 
00044     (#) Program the Bite Rate, Tx Buffering mode, Rx Buffering mode in the Init structure.
00045 
00046     (#) Enable the SWPMI peripheral by calling the HAL_SWPMI_Init() function.
00047     
00048   @endverbatim
00049   ******************************************************************************
00050   * @attention
00051   *
00052   * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
00053   *
00054   * Redistribution and use in source and binary forms, with or without modification,
00055   * are permitted provided that the following conditions are met:
00056   *   1. Redistributions of source code must retain the above copyright notice,
00057   *      this list of conditions and the following disclaimer.
00058   *   2. Redistributions in binary form must reproduce the above copyright notice,
00059   *      this list of conditions and the following disclaimer in the documentation
00060   *      and/or other materials provided with the distribution.
00061   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00062   *      may be used to endorse or promote products derived from this software
00063   *      without specific prior written permission.
00064   *
00065   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00066   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00067   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00068   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00069   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00070   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00071   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00072   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00073   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00074   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00075   *
00076   ******************************************************************************
00077   */
00078 
00079 /* Includes ------------------------------------------------------------------*/
00080 #include "stm32l4xx_hal.h"
00081 
00082 /** @addtogroup STM32L4xx_HAL_Driver
00083   * @{
00084   */
00085 
00086 /** @defgroup SWPMI SWPMI
00087   * @brief HAL SWPMI module driver
00088   * @{
00089   */
00090 #ifdef HAL_SWPMI_MODULE_ENABLED
00091 
00092 /* Private typedef -----------------------------------------------------------*/
00093 /* Private define ------------------------------------------------------------*/
00094 /* Private constants ---------------------------------------------------------*/
00095 /** @addtogroup SWPMI_Private_Constants SWPMI Private Constants
00096   * @{
00097   */
00098 #define SWPMI_TIMEOUT_VALUE       ((uint32_t) 22000)
00099 
00100 /**
00101   * @}
00102   */
00103 
00104 /* Private macros ------------------------------------------------------------*/
00105 /* Private variables ---------------------------------------------------------*/
00106 /* Private function prototypes -----------------------------------------------*/
00107 static void SWPMI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
00108 static void SWPMI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
00109 static void SWPMI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
00110 static void SWPMI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
00111 static void SWPMI_DMAError(DMA_HandleTypeDef *hdma);
00112 static HAL_StatusTypeDef SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi);
00113 static HAL_StatusTypeDef SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef *hswpmi);
00114 static HAL_StatusTypeDef SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi);
00115 static HAL_StatusTypeDef SWPMI_EndReceive_IT(SWPMI_HandleTypeDef *hswpmi);
00116 static HAL_StatusTypeDef SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef *hswpmi);
00117 static HAL_StatusTypeDef SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef *hswpmi, uint32_t Flag, uint32_t Timeout);
00118 
00119 /* Exported functions --------------------------------------------------------*/
00120 
00121 /** @defgroup SWPMI_Exported_Functions SWPMI Exported Functions
00122   * @{
00123   */
00124 
00125 /** @defgroup SWPMI_Exported_Group1 Initialization/de-initialization methods
00126   *  @brief    Initialization and Configuration functions
00127   *
00128 @verbatim
00129  ===============================================================================
00130             ##### Initialization and Configuration functions #####
00131  ===============================================================================
00132     [..]  This section provides functions allowing to:
00133       (+) Initialize and configure the SWPMI peripheral.
00134       (+) De-initialize the SWPMI peripheral.
00135 
00136 @endverbatim
00137   * @{
00138   */
00139 
00140 /**
00141   * @brief Initialize the SWPMI peripheral according to the specified parameters in the SWPMI_InitTypeDef.
00142   * @param hswpmi: SWPMI handle
00143   * @retval HAL status
00144   */
00145 HAL_StatusTypeDef HAL_SWPMI_Init(SWPMI_HandleTypeDef *hswpmi)
00146 {
00147   HAL_StatusTypeDef status = HAL_OK;
00148 
00149   /* Check the SWPMI handle allocation */
00150   if(hswpmi == NULL)
00151   {
00152     status = HAL_ERROR;
00153   }
00154   else
00155   {
00156     /* Check the parameters */
00157     assert_param(IS_SWPMI_VOLTAGE_CLASS(hswpmi->Init.VoltageClass));
00158     assert_param(IS_SWPMI_BITRATE_VALUE(hswpmi->Init.BitRate));
00159     assert_param(IS_SWPMI_TX_BUFFERING_MODE(hswpmi->Init.TxBufferingMode));
00160     assert_param(IS_SWPMI_RX_BUFFERING_MODE(hswpmi->Init.RxBufferingMode));
00161 
00162     if(hswpmi->State == HAL_SWPMI_STATE_RESET)
00163     {
00164       /* Allocate lock resource and initialize it */
00165       hswpmi->Lock = HAL_UNLOCKED;
00166 
00167       /* Init the low level hardware : GPIO, CLOCK, CORTEX */
00168       HAL_SWPMI_MspInit(hswpmi);
00169     }
00170 
00171     hswpmi->State = HAL_SWPMI_STATE_BUSY;
00172 
00173     /* Disable SWPMI interface */
00174     CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
00175 
00176     /* Clear all SWPMI interface flags */
00177     WRITE_REG(hswpmi->Instance->ICR, 0x019F);
00178 
00179     /* Apply Voltage class selection */
00180     MODIFY_REG(hswpmi->Instance->OR, SWPMI_OR_CLASS, hswpmi->Init.VoltageClass);
00181 
00182     /* Configure the BRR register (Bitrate) */
00183     WRITE_REG(hswpmi->Instance->BRR, hswpmi->Init.BitRate);
00184 
00185     /* Apply SWPMI CR configuration */
00186     MODIFY_REG(hswpmi->Instance->CR, \
00187                SWPMI_CR_RXDMA | SWPMI_CR_TXDMA  | SWPMI_CR_RXMODE | SWPMI_CR_TXMODE, \
00188                hswpmi->Init.TxBufferingMode | hswpmi->Init.RxBufferingMode);
00189 
00190     hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
00191     hswpmi->State = HAL_SWPMI_STATE_READY;
00192 
00193     /* Enable SWPMI peripheral if not */
00194     SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
00195   }
00196 
00197   return status;
00198 }
00199 
00200 /**
00201   * @brief De-initialize the SWPMI peripheral.
00202   * @param hswpmi: SWPMI handle
00203   * @retval HAL status
00204   */
00205 HAL_StatusTypeDef HAL_SWPMI_DeInit(SWPMI_HandleTypeDef *hswpmi)
00206 {
00207   HAL_StatusTypeDef status = HAL_OK;
00208 
00209   /* Check the SWPMI handle allocation */
00210   if(hswpmi == NULL)
00211   {
00212     status = HAL_ERROR;
00213   }
00214   else
00215   {
00216     /* Check the parameters */
00217     assert_param(IS_SWPMI_INSTANCE(hswpmi->Instance));
00218 
00219     hswpmi->State = HAL_SWPMI_STATE_BUSY;
00220 
00221     /* Disable SWPMI interface */
00222     CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
00223 
00224     /* DeInit the low level hardware */
00225     HAL_SWPMI_MspDeInit(hswpmi);
00226 
00227     hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
00228 
00229     hswpmi->State = HAL_SWPMI_STATE_RESET;
00230 
00231     /* Release Lock */
00232     __HAL_UNLOCK(hswpmi);
00233   }
00234 
00235   return status;
00236 }
00237 
00238 /**
00239   * @brief Initialize the SWPMI MSP.
00240   * @param hswpmi: SWPMI handle
00241   * @retval None
00242   */
00243  __weak void HAL_SWPMI_MspInit(SWPMI_HandleTypeDef *hswpmi)
00244 {
00245   /* NOTE : This function should not be modified, when the callback is needed,
00246             the HAL_SWPMI_MspInit can be implemented in the user file
00247    */
00248 }
00249 
00250 /**
00251   * @brief DeInitialize the SWPMI MSP.
00252   * @param hswpmi: SWPMI handle
00253   * @retval None
00254   */
00255  __weak void HAL_SWPMI_MspDeInit(SWPMI_HandleTypeDef *hswpmi)
00256 {
00257   /* NOTE : This function should not be modified, when the callback is needed,
00258             the HAL_SWPMI_MspDeInit can be implemented in the user file
00259    */
00260 }
00261 
00262 /**
00263   * @}
00264   */
00265 
00266 /** @defgroup SWPMI_Exported_Group2 IO operation methods
00267   *  @brief SWPMI Transmit/Receive functions
00268   *
00269 @verbatim
00270  ===============================================================================
00271                       ##### IO operation methods #####
00272  ===============================================================================
00273  [..]
00274     This subsection provides a set of functions allowing to manage the SWPMI
00275      data transfers.
00276 
00277     (#) There are two modes of transfer:
00278        (++) Blocking mode: The communication is performed in polling mode.
00279             The HAL status of all data processing is returned by the same function
00280             after finishing transfer.
00281        (++) Non-Blocking mode: The communication is performed using Interrupts
00282            or DMA. The end of the data processing will be indicated through the
00283            dedicated SWPMI Interrupt handler (HAL_SWPMI_IRQHandler()) when using Interrupt mode or
00284            the selected DMA channel interrupt handler when using DMA mode.
00285            The HAL_SWPMI_TxCpltCallback(), HAL_SWPMI_RxCpltCallback() user callbacks
00286            will be executed respectively at the end of the transmit or receive process.
00287            The HAL_SWPMI_ErrorCallback() user callback will be executed when a communication error is detected.
00288 
00289     (#) Blocking mode API's are:
00290         (++) HAL_SWPMI_Transmit()
00291         (++) HAL_SWPMI_Receive()
00292 
00293     (#) Non-Blocking mode API's with Interrupt are:
00294         (++) HAL_SWPMI_Transmit_IT()
00295         (++) HAL_SWPMI_Receive_IT()
00296         (++) HAL_SWPMI_IRQHandler()
00297 
00298     (#) Non-Blocking mode API's with DMA are:
00299         (++) HAL_SWPMI_Transmit_DMA()
00300         (++) HAL_SWPMI_Receive_DMA()
00301         (++) HAL_SWPMI_DMAPause()
00302         (++) HAL_SWPMI_DMAResume()
00303         (++) HAL_SWPMI_DMAStop()
00304 
00305     (#) A set of Transfer Complete Callbacks are provided in Non-Blocking mode:
00306         (++) HAL_SWPMI_TxHalfCpltCallback()
00307         (++) HAL_SWPMI_TxCpltCallback()
00308         (++) HAL_SWPMI_RxHalfCpltCallback()
00309         (++) HAL_SWPMI_RxCpltCallback()
00310         (++) HAL_SWPMI_ErrorCallback()
00311 
00312     (#) The capability to launch the above IO operations in loopback mode for 
00313         user application verification:    
00314         (++) HAL_SWPMI_EnableLoopback()
00315         (++) HAL_SWPMI_DisableLoopback()
00316         
00317 @endverbatim
00318   * @{
00319   */
00320 
00321 /**
00322   * @brief  Transmit an amount of data in blocking mode.
00323   * @param  hswpmi: pointer to a SWPMI_HandleTypeDef structure that contains
00324   *                the configuration information for SWPMI module.
00325   * @param  pData: Pointer to data buffer
00326   * @param  Size: Amount of data to be sent
00327   * @param  Timeout: Timeout duration
00328   * @retval HAL status
00329   */
00330 HAL_StatusTypeDef HAL_SWPMI_Transmit(SWPMI_HandleTypeDef *hswpmi, uint32_t* pData, uint16_t Size, uint32_t Timeout)
00331 {
00332   uint32_t tickstart = HAL_GetTick();
00333   HAL_StatusTypeDef status = HAL_OK;
00334 
00335   if((pData == NULL ) || (Size == 0))
00336   {
00337     status = HAL_ERROR;
00338   }
00339   else
00340   {
00341     /* Process Locked */
00342     __HAL_LOCK(hswpmi);
00343 
00344     if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_RX))
00345     {
00346       /* Check if a non-blocking receive process is ongoing or not */
00347       if(hswpmi->State == HAL_SWPMI_STATE_READY)
00348       {
00349         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
00350 
00351         /* Disable any transmitter interrupts */
00352         __HAL_SWPMI_DISABLE_IT(hswpmi, SWPMI_IT_TCIE | SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE);
00353 
00354         /* Disable any transmitter flags */
00355         __HAL_SWPMI_CLEAR_FLAG(hswpmi, SWPMI_FLAG_TXBEF | SWPMI_FLAG_TXUNRF | SWPMI_FLAG_TCF);
00356 
00357         /* Enable SWPMI peripheral if not */
00358         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
00359       }
00360       else
00361       {
00362         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
00363       }
00364 
00365       do
00366       {
00367         /* Wait the TXE to write data */
00368         if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_TXE))
00369         {
00370           hswpmi->Instance->TDR = (*pData++);
00371           Size--;
00372         }
00373         else
00374         {
00375           /* Check for the Timeout */
00376           if(Timeout != HAL_MAX_DELAY)
00377           {
00378             if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
00379             {
00380               status = HAL_TIMEOUT;
00381               break;
00382             }
00383           }
00384         }
00385       } while(Size != 0);
00386 
00387       /* Wait on TXBEF flag to be able to start a second transfer */
00388       if(SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, Timeout) != HAL_OK)
00389       {
00390         status = HAL_TIMEOUT;
00391       }
00392 
00393       if(status == HAL_OK)
00394       {
00395         /* Check if a non-blocking receive Process is ongoing or not */
00396         if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
00397         {
00398           hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
00399         }
00400         else
00401         {
00402           hswpmi->State = HAL_SWPMI_STATE_READY;
00403         }
00404       }
00405     }
00406     else
00407     {
00408       status = HAL_BUSY;
00409     }
00410   }
00411 
00412   if((status != HAL_OK) && (status != HAL_BUSY))
00413   {
00414     hswpmi->State = HAL_SWPMI_STATE_READY;
00415   }
00416   /* Process Unlocked */
00417   __HAL_UNLOCK(hswpmi);
00418 
00419   return status;
00420 }
00421 
00422 /**
00423   * @brief  Receive an amount of data in blocking mode.
00424   * @param  hswpmi: pointer to a SWPMI_HandleTypeDef structure that contains
00425   *                the configuration information for SWPMI module.
00426   * @param  pData: Pointer to data buffer
00427   * @param  Size: Amount of data to be received
00428   * @param  Timeout: Timeout duration
00429   * @retval HAL status
00430   */
00431 HAL_StatusTypeDef HAL_SWPMI_Receive(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size, uint32_t Timeout)
00432 {
00433   uint32_t tickstart = HAL_GetTick();
00434   HAL_StatusTypeDef status = HAL_OK;
00435 
00436   if((pData == NULL ) || (Size == 0))
00437   {
00438     status = HAL_ERROR;
00439   }
00440   else
00441   {
00442     /* Process Locked */
00443     __HAL_LOCK(hswpmi);
00444 
00445     if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX))
00446     {
00447       /* Check if a non-blocking transmit process is ongoing or not */
00448       if(hswpmi->State == HAL_SWPMI_STATE_READY)
00449       {
00450         hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
00451 
00452         /* Disable any receiver interrupts */
00453         CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_SRIE | SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
00454 
00455         /* Enable SWPMI peripheral if not */
00456         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
00457       }
00458       else
00459       {
00460         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
00461       }
00462 
00463       do
00464       {
00465         /* Wait the RXNE to read data */
00466         if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXNE))
00467         {
00468           (*pData++) = hswpmi->Instance->RDR;
00469           Size--;
00470         }
00471         else
00472         {
00473           /* Check for the Timeout */
00474           if(Timeout != HAL_MAX_DELAY)
00475           {
00476             if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
00477             {
00478               status = HAL_TIMEOUT;
00479               break;
00480             }
00481           }
00482         }
00483       } while(Size != 0);
00484       
00485       if(status == HAL_OK)
00486       {
00487         if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXBFF))
00488         {
00489           /* Clear RXBFF at end of reception */
00490           WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF);
00491         }
00492 
00493         /* Check if a non-blocking transmit Process is ongoing or not */
00494         if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
00495         {
00496           hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
00497         }
00498         else
00499         {
00500           hswpmi->State = HAL_SWPMI_STATE_READY;
00501         }
00502       }
00503     }
00504     else
00505     {
00506       status = HAL_BUSY;
00507     }
00508   }
00509 
00510   if((status != HAL_OK) && (status != HAL_BUSY))
00511   {
00512     hswpmi->State = HAL_SWPMI_STATE_READY;
00513   }
00514   /* Process Unlocked */
00515   __HAL_UNLOCK(hswpmi);
00516 
00517   return status;
00518 }
00519 
00520 /**
00521   * @brief  Transmit an amount of data in non-blocking mode with interrupt.
00522   * @param  hswpmi: pointer to a SWPMI_HandleTypeDef structure that contains
00523   *                the configuration information for SWPMI module.
00524   * @param  pData: Pointer to data buffer
00525   * @param  Size: Amount of data to be sent
00526   * @retval HAL status
00527   */
00528 HAL_StatusTypeDef HAL_SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
00529 {
00530   HAL_StatusTypeDef status = HAL_OK;
00531 
00532   if((pData == NULL ) || (Size == 0))
00533   {
00534     status =  HAL_ERROR;
00535   }
00536   else
00537   {
00538     /* Process Locked */
00539     __HAL_LOCK(hswpmi);
00540 
00541     if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_RX))
00542     {
00543       /* Update handle */
00544       hswpmi->pTxBuffPtr = pData;
00545       hswpmi->TxXferSize = Size;
00546       hswpmi->TxXferCount = Size;
00547       hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
00548 
00549       /* Check if a receive process is ongoing or not */
00550       if(hswpmi->State == HAL_SWPMI_STATE_READY)
00551       {
00552         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
00553 
00554         /* Enable SWPMI peripheral if not */
00555         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
00556       }
00557       else
00558       {
00559         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
00560       }
00561 
00562       /* Enable the SWPMI transmit underrun error */
00563       __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TXUNRIE);
00564 
00565       /* Process Unlocked */
00566       __HAL_UNLOCK(hswpmi);
00567 
00568       /* Enable the SWPMI interrupts:      */
00569       /* - Transmit data register empty    */
00570       /* - Transmit buffer empty           */
00571       /* - Transmit/Reception completion   */
00572       __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TIE | SWPMI_IT_TXBEIE | SWPMI_IT_TCIE);
00573     }
00574     else
00575     {
00576       status =  HAL_BUSY;
00577       
00578       /* Process Unlocked */
00579       __HAL_UNLOCK(hswpmi);
00580     }
00581   }
00582 
00583   return status;
00584 }
00585 
00586 /**
00587   * @brief Receive an amount of data in non-blocking mode with interrupt.
00588   * @param hswpmi: SWPMI handle
00589   * @param pData: pointer to data buffer
00590   * @param Size: amount of data to be received
00591   * @retval HAL status
00592   */
00593 HAL_StatusTypeDef HAL_SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
00594 {
00595   HAL_StatusTypeDef status = HAL_OK;
00596 
00597   if((pData == NULL ) || (Size == 0))
00598   {
00599     status =  HAL_ERROR;
00600   }
00601   else
00602   {
00603     /* Process Locked */
00604     __HAL_LOCK(hswpmi);
00605 
00606     if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX))
00607     {
00608       /* Update handle */
00609       hswpmi->pRxBuffPtr = pData;
00610       hswpmi->RxXferSize = Size;
00611       hswpmi->RxXferCount = Size;
00612       hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
00613 
00614       /* Check if a transmit process is ongoing or not */
00615       if(hswpmi->State == HAL_SWPMI_STATE_READY)
00616       {
00617         hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
00618 
00619         /* Enable SWPMI peripheral if not */
00620         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
00621       }
00622       else
00623       {
00624         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
00625       }
00626 
00627       /* Process Unlocked */
00628       __HAL_UNLOCK(hswpmi);
00629 
00630       /* Enable the SWPMI slave resume */
00631       /* Enable the SWPMI Data Register not empty Interrupt, receive CRC Error, receive overrun and RxBuf Interrupt */
00632       /*  Enable the SWPMI Transmit/Reception completion   */
00633       __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
00634     }
00635     else
00636     {
00637       status = HAL_BUSY;
00638       
00639       /* Process Unlocked */
00640       __HAL_UNLOCK(hswpmi);
00641     }
00642   }
00643 
00644   return status;
00645 }
00646 
00647 /**
00648   * @brief Transmit an amount of data in non-blocking mode with DMA interrupt.
00649   * @param hswpmi: SWPMI handle
00650   * @param pData: pointer to data buffer
00651   * @param Size: amount of data to be sent
00652   * @retval HAL status
00653   */
00654 HAL_StatusTypeDef HAL_SWPMI_Transmit_DMA(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
00655 {
00656   HAL_StatusTypeDef status = HAL_OK;
00657 
00658   if((pData == NULL ) || (Size == 0))
00659   {
00660     status =  HAL_ERROR;
00661   }
00662   else
00663   {
00664     /* Process Locked */
00665     __HAL_LOCK(hswpmi);
00666 
00667     if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_RX))
00668     {
00669       /* Update handle */
00670       hswpmi->pTxBuffPtr = pData;
00671       hswpmi->TxXferSize = Size;
00672       hswpmi->TxXferCount = Size;
00673       hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
00674 
00675       /* Check if a receive process is ongoing or not */
00676       if(hswpmi->State == HAL_SWPMI_STATE_READY)
00677       {
00678         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
00679 
00680         /* Enable SWPMI peripheral if not */
00681         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
00682       }
00683       else
00684       {
00685         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
00686       }
00687 
00688       /* Set the SWPMI DMA transfer complete callback */
00689       hswpmi->hdmatx->XferCpltCallback = SWPMI_DMATransmitCplt;
00690 
00691       /* Set the SWPMI DMA Half transfer complete callback */
00692       hswpmi->hdmatx->XferHalfCpltCallback = SWPMI_DMATxHalfCplt;
00693 
00694       /* Set the DMA error callback */
00695       hswpmi->hdmatx->XferErrorCallback = SWPMI_DMAError;
00696 
00697       /* Enable the SWPMI transmit DMA Stream */
00698       HAL_DMA_Start_IT(hswpmi->hdmatx, (uint32_t)hswpmi->pTxBuffPtr, (uint32_t)&hswpmi->Instance->TDR, Size);
00699 
00700       /* Process Unlocked */
00701       __HAL_UNLOCK(hswpmi);
00702 
00703       /* Enable the DMA transfer for transmit request by setting the TXDMA bit
00704          in the SWPMI CR register */
00705       SET_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);
00706     }
00707     else
00708     {
00709       status = HAL_BUSY;
00710       
00711       /* Process Unlocked */
00712       __HAL_UNLOCK(hswpmi);
00713     }
00714   }
00715 
00716   return status;
00717 }
00718 
00719 /**
00720   * @brief Receive an amount of data in non-blocking mode with DMA interrupt.
00721   * @param hswpmi: SWPMI handle
00722   * @param pData: pointer to data buffer
00723   * @param Size: amount of data to be received
00724   * @retval HAL status
00725   */
00726 HAL_StatusTypeDef HAL_SWPMI_Receive_DMA(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
00727 {
00728   HAL_StatusTypeDef status = HAL_OK;
00729 
00730   if((pData == NULL ) || (Size == 0))
00731   {
00732     status =  HAL_ERROR;
00733   }
00734   else
00735   {
00736     /* Process Locked */
00737     __HAL_LOCK(hswpmi);
00738 
00739     if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX))
00740     {
00741       /* Update handle */
00742       hswpmi->pRxBuffPtr = pData;
00743       hswpmi->RxXferSize = Size;
00744       hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
00745 
00746       /* Check if a transmit process is ongoing or not */
00747       if(hswpmi->State == HAL_SWPMI_STATE_READY)
00748       {
00749         hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
00750 
00751         /* Enable SWPMI peripheral if not */
00752         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
00753       }
00754       else
00755       {
00756         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
00757       }
00758 
00759       /* Set the SWPMI DMA transfer complete callback */
00760       hswpmi->hdmarx->XferCpltCallback = SWPMI_DMAReceiveCplt;
00761 
00762       /* Set the SWPMI DMA Half transfer complete callback */
00763       hswpmi->hdmarx->XferHalfCpltCallback = SWPMI_DMARxHalfCplt;
00764 
00765       /* Set the DMA error callback */
00766       hswpmi->hdmarx->XferErrorCallback = SWPMI_DMAError;
00767 
00768       /* Enable the DMA request */
00769       HAL_DMA_Start_IT(hswpmi->hdmarx, (uint32_t)&hswpmi->Instance->RDR, (uint32_t)hswpmi->pRxBuffPtr, Size);
00770 
00771       /* Process Unlocked */
00772       __HAL_UNLOCK(hswpmi);
00773 
00774       /* Enable the DMA transfer for the receiver request by setting the RXDMA bit
00775          in the SWPMI CR register */
00776       SET_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);
00777     }
00778     else
00779     {
00780       status = HAL_BUSY;
00781 
00782       /* Process Unlocked */
00783       __HAL_UNLOCK(hswpmi);
00784     }
00785   }
00786 
00787   return status;
00788 }
00789 
00790 /**
00791   * @brief Stop all DMA transfers.
00792   * @param hswpmi: SWPMI handle
00793   * @retval HAL_OK
00794   */
00795 HAL_StatusTypeDef HAL_SWPMI_DMAStop(SWPMI_HandleTypeDef *hswpmi)
00796 {
00797   /* Process Locked */
00798   __HAL_LOCK(hswpmi);
00799 
00800   /* Disable the SWPMI Tx/Rx DMA requests */
00801   CLEAR_BIT(hswpmi->Instance->CR, (SWPMI_CR_TXDMA | SWPMI_CR_RXDMA));
00802 
00803   /* Abort the SWPMI DMA tx channel */
00804   if(hswpmi->hdmatx != NULL)
00805   {
00806     HAL_DMA_Abort(hswpmi->hdmatx);
00807   }
00808   /* Abort the SWPMI DMA rx channel */
00809   if(hswpmi->hdmarx != NULL)
00810   {
00811     HAL_DMA_Abort(hswpmi->hdmarx);
00812   }
00813 
00814   /* Disable SWPMI interface */
00815   CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
00816 
00817   hswpmi->State = HAL_SWPMI_STATE_READY;
00818 
00819   /* Process Unlocked */
00820   __HAL_UNLOCK(hswpmi);
00821 
00822   return HAL_OK;
00823 }
00824 
00825 
00826 /**
00827   * @brief Enable the Loopback mode.
00828   * @param hswpmi: SWPMI handle
00829   * @note  Loopback mode is to be used only for test purposes
00830   * @retval HAL_OK / HAL_BUSY
00831   */
00832 HAL_StatusTypeDef HAL_SWPMI_EnableLoopback(SWPMI_HandleTypeDef *hswpmi)
00833 {
00834   HAL_StatusTypeDef  status = HAL_OK;
00835 
00836   /* Process Locked */
00837   __HAL_LOCK(hswpmi);
00838 
00839   /* Check SWPMI not enabled */
00840   if(READ_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT) != RESET)
00841   {
00842     status = HAL_BUSY;
00843   }
00844   else
00845   {
00846     /* Set Loopback */
00847     SET_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);
00848   }
00849 
00850   /* Process Unlocked */
00851   __HAL_UNLOCK(hswpmi);
00852 
00853   return status;
00854 }
00855 
00856 /**
00857   * @brief Disable the Loopback mode.
00858   * @param hswpmi: SWPMI handle
00859   * @note  Loopback mode is to be used only for test purposes
00860   * @retval HAL_OK / HAL_BUSY
00861   */
00862 HAL_StatusTypeDef HAL_SWPMI_DisableLoopback(SWPMI_HandleTypeDef *hswpmi)
00863 {
00864   HAL_StatusTypeDef  status = HAL_OK;
00865 
00866   /* Process Locked */
00867   __HAL_LOCK(hswpmi);
00868 
00869   /* Check SWPMI not enabled */
00870   if(READ_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT) != RESET)
00871   {
00872     status = HAL_BUSY;
00873   }
00874   else
00875   {
00876     /* Reset Loopback */
00877     CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);
00878   }
00879 
00880   /* Process Unlocked */
00881   __HAL_UNLOCK(hswpmi);
00882 
00883   return status;
00884 }
00885 
00886 /**
00887   * @}
00888   */
00889 
00890 /** @defgroup SWPMI_Exported_Group3 SWPMI IRQ handler and callbacks
00891  *  @brief  SWPMI  IRQ handler.
00892  *
00893 @verbatim   
00894   ==============================================================================
00895                       ##### SWPMI IRQ handler and callbacks  #####
00896   ==============================================================================  
00897 [..]  This section provides SWPMI IRQ handler and callback functions called within 
00898       the IRQ handler.
00899 
00900 @endverbatim
00901   * @{
00902   */
00903 
00904 /**
00905   * @brief Handle SWPMI interrupt request.
00906   * @param hswpmi: SWPMI handle
00907   * @retval None
00908   */
00909 void HAL_SWPMI_IRQHandler(SWPMI_HandleTypeDef *hswpmi)
00910 {
00911   uint32_t regisr = READ_REG(hswpmi->Instance->ISR);
00912   uint32_t regier = READ_REG(hswpmi->Instance->IER);
00913 
00914   /* SWPMI CRC error interrupt occurred --------------------------------------*/
00915   if(((regisr & SWPMI_FLAG_RXBERF) != RESET) && ((regier & SWPMI_IT_RXBERIE) != RESET))
00916   {
00917     /* Disable Receive CRC interrupt */
00918     CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RXBERIE | SWPMI_IT_RXBFIE);
00919     /* Clear Receive CRC and Receive buffer full flag */
00920     WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBERF | SWPMI_FLAG_RXBFF);
00921 
00922     hswpmi->ErrorCode |= HAL_SWPMI_ERROR_CRC;
00923   }
00924 
00925   /* SWPMI Over-Run interrupt occurred -----------------------------------------*/
00926   if(((regisr & SWPMI_FLAG_RXOVRF) != RESET) && ((regier & SWPMI_IT_RXOVRIE) != RESET))
00927   {
00928     /* Disable Receive overrun interrupt */
00929     CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RXOVRIE);
00930     /* Clear Receive overrun flag */
00931     WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXOVRF);
00932 
00933     hswpmi->ErrorCode |= HAL_SWPMI_ERROR_OVR;
00934   }
00935 
00936   /* SWPMI Under-Run interrupt occurred -----------------------------------------*/
00937   if(((regisr & SWPMI_FLAG_TXUNRF) != RESET) && ((regier & SWPMI_IT_TXUNRIE) != RESET))
00938   {
00939     /* Disable Transmit under run interrupt */
00940     CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TXUNRIE);
00941     /* Clear Transmit under run flag */
00942     WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TXUNRF);
00943 
00944     hswpmi->ErrorCode |= HAL_SWPMI_ERROR_UDR;
00945   }
00946 
00947    /* Call SWPMI Error Call back function if need be --------------------------*/
00948   if(hswpmi->ErrorCode != HAL_SWPMI_ERROR_NONE)
00949   {
00950     /* Set the SWPMI state ready to be able to start again the process */
00951     hswpmi->State = HAL_SWPMI_STATE_READY;
00952 
00953     HAL_SWPMI_ErrorCallback(hswpmi);
00954   }
00955 
00956   /* SWPMI in mode Receiver ---------------------------------------------------*/
00957   if(((regisr & SWPMI_FLAG_RXNE) != RESET) && ((regier & SWPMI_IT_RIE)  != RESET))
00958   {
00959     SWPMI_Receive_IT(hswpmi);
00960   }
00961 
00962   /* SWPMI in mode Transmitter ------------------------------------------------*/
00963   if(((regisr & SWPMI_FLAG_TXE) != RESET) && ((regier & SWPMI_IT_TIE) != RESET))
00964   {
00965     SWPMI_Transmit_IT(hswpmi);
00966   }
00967 
00968   /* SWPMI in mode Transmitter (Transmit buffer empty) ------------------------*/
00969   if(((regisr & SWPMI_FLAG_TXBEF) != RESET) && ((regier & SWPMI_IT_TXBEIE) != RESET))
00970   {
00971     SWPMI_EndTransmit_IT(hswpmi);
00972   }
00973 
00974   /* SWPMI in mode Receiver (Receive buffer full) -----------------------------*/
00975   if(((regisr & SWPMI_FLAG_RXBFF) != RESET) && ((regier & SWPMI_IT_RXBFIE) != RESET))
00976   {
00977     SWPMI_EndReceive_IT(hswpmi);
00978   }
00979 
00980   /* Both Transmission and reception complete ---------------------------------*/
00981   if(((regisr & SWPMI_FLAG_TCF) != RESET) && ((regier & SWPMI_IT_TCIE) != RESET))
00982   {
00983     SWPMI_EndTransmitReceive_IT(hswpmi);
00984   }
00985 }
00986 
00987 /**
00988   * @brief Tx Transfer completed callback.
00989   * @param hswpmi: SWPMI handle
00990   * @retval None
00991   */
00992  __weak void HAL_SWPMI_TxCpltCallback(SWPMI_HandleTypeDef *hswpmi)
00993 {
00994   /* NOTE : This function should not be modified, when the callback is needed,
00995             the HAL_SWPMI_TxCpltCallback is to be implemented in the user file
00996    */
00997 }
00998 
00999 /**
01000   * @brief  Tx Half Transfer completed callback.
01001   * @param  hswpmi: SWPMI handle
01002   * @retval None
01003   */
01004  __weak void HAL_SWPMI_TxHalfCpltCallback(SWPMI_HandleTypeDef *hswpmi)
01005 {
01006   /* NOTE: This function should not be modified, when the callback is needed,
01007            the HAL_SWPMI_TxHalfCpltCallback is to be implemented in the user file
01008    */
01009 }
01010 
01011 /**
01012   * @brief Rx Transfer completed callback.
01013   * @param hswpmi: SWPMI handle
01014   * @retval None
01015   */
01016 __weak void HAL_SWPMI_RxCpltCallback(SWPMI_HandleTypeDef *hswpmi)
01017 {
01018   /* NOTE : This function should not be modified, when the callback is needed,
01019             the HAL_SWPMI_RxCpltCallback is to be implemented in the user file
01020    */
01021 }
01022 
01023 /**
01024   * @brief  Rx Half Transfer completed callback.
01025   * @param  hswpmi: SWPMI handle
01026   * @retval None
01027   */
01028 __weak void HAL_SWPMI_RxHalfCpltCallback(SWPMI_HandleTypeDef *hswpmi)
01029 {
01030   /* NOTE: This function should not be modified, when the callback is needed,
01031            the HAL_SWPMI_RxHalfCpltCallback is to be implemented in the user file
01032    */
01033 }
01034 
01035 /**
01036   * @brief SWPMI error callback.
01037   * @param hswpmi: SWPMI handle
01038   * @retval None
01039   */
01040  __weak void HAL_SWPMI_ErrorCallback(SWPMI_HandleTypeDef *hswpmi)
01041 {
01042   /* NOTE : This function should not be modified, when the callback is needed,
01043             the HAL_SWPMI_ErrorCallback is to be implemented in the user file
01044    */
01045 }
01046 
01047 /**
01048   * @}
01049   */
01050 
01051 /** @defgroup SWPMI_Exported_Group4 Peripheral Control methods
01052   *  @brief   SWPMI control functions
01053   *
01054 @verbatim
01055  ===============================================================================
01056                       ##### Peripheral Control methods #####
01057  ===============================================================================
01058     [..]
01059     This subsection provides a set of functions allowing to control the SWPMI.
01060      (+) HAL_SWPMI_GetState() API is helpful to check in run-time the state of the SWPMI peripheral
01061      (+) HAL_SWPMI_GetError() API is helpful to check in run-time the error state of the SWPMI peripheral
01062 @endverbatim
01063   * @{
01064   */
01065 
01066 /**
01067   * @brief Return the SWPMI handle state.
01068   * @param hswpmi: SWPMI handle
01069   * @retval HAL state
01070   */
01071 HAL_SWPMI_StateTypeDef HAL_SWPMI_GetState(SWPMI_HandleTypeDef *hswpmi)
01072 {
01073   /* Return SWPMI handle state */
01074   return hswpmi->State;
01075 }
01076 
01077 /**
01078 * @brief  Return the SWPMI error code.
01079 * @param  hswpmi : pointer to a SWPMI_HandleTypeDef structure that contains
01080   *              the configuration information for the specified SWPMI.
01081 * @retval SWPMI Error Code
01082 */
01083 uint32_t HAL_SWPMI_GetError(SWPMI_HandleTypeDef *hswpmi)
01084 {
01085   return hswpmi->ErrorCode;
01086 }
01087 
01088 /**
01089   * @}
01090   */
01091 
01092 /**
01093   * @}
01094   */
01095 
01096 /* Private functions ---------------------------------------------------------*/
01097 
01098 /** @defgroup SWPMI_Private_Functions SWPMI Private Functions
01099   * @{
01100   */
01101 
01102 /**
01103   * @brief Transmit an amount of data in interrupt mode.
01104   * @note  Function called under interruption only, once interruptions have been enabled by HAL_SWPMI_Transmit_IT()
01105   * @param  hswpmi: SWPMI handle
01106   * @retval HAL status
01107   */
01108 static HAL_StatusTypeDef SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi)
01109 {
01110   HAL_StatusTypeDef status = HAL_OK;
01111 
01112   if ((hswpmi->State == HAL_SWPMI_STATE_BUSY_TX) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX))
01113   {
01114     if(hswpmi->TxXferCount == 0)
01115     {
01116       /* Disable the SWPMI TXE and Underrun Interrupts */
01117       CLEAR_BIT(hswpmi->Instance->IER, (SWPMI_IT_TIE | SWPMI_IT_TXUNRIE));
01118     }
01119     else
01120     {
01121       hswpmi->Instance->TDR = (uint32_t)(*hswpmi->pTxBuffPtr++);
01122       hswpmi->TxXferCount--;
01123     }
01124   }
01125   else
01126   {
01127     status = HAL_BUSY;
01128   }
01129 
01130   return status;
01131 }
01132 
01133 /**
01134   * @brief  Wraps up transmission in non-blocking mode.
01135   * @param  hswpmi: SWPMI handle
01136   * @retval HAL status
01137   * @retval HAL status
01138   */
01139 static HAL_StatusTypeDef SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef *hswpmi)
01140 {
01141   /* Clear the SWPMI Transmit buffer empty Flag */
01142   WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TXBEF);
01143   /* Disable the all SWPMI Transmit Interrupts  */
01144   CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE);
01145 
01146   /* Check if a receive Process is ongoing or not */
01147   if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
01148   {
01149     hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
01150   }
01151   else
01152   {
01153     hswpmi->State = HAL_SWPMI_STATE_READY;
01154   }
01155   
01156   HAL_SWPMI_TxCpltCallback(hswpmi);
01157 
01158   return HAL_OK;
01159 }
01160 
01161 /**
01162   * @brief Receive an amount of data in interrupt mode.
01163   * @note  Function called under interruption only, once interruptions have been enabled by HAL_SWPMI_Receive_IT()
01164   * @param  hswpmi: SWPMI handle
01165   * @retval HAL status
01166   */
01167 static HAL_StatusTypeDef SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi)
01168 {
01169   HAL_StatusTypeDef status = HAL_OK;
01170 
01171   if((hswpmi->State == HAL_SWPMI_STATE_BUSY_RX) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX))
01172   {
01173     *hswpmi->pRxBuffPtr++ = (uint32_t)(hswpmi->Instance->RDR);
01174 
01175     if(--hswpmi->RxXferCount == 0)
01176     {
01177       /* Wait for RXBFF flag to update state */
01178       HAL_SWPMI_RxCpltCallback(hswpmi);
01179     }
01180   }
01181   else
01182   {
01183     status = HAL_BUSY;
01184   }
01185 
01186   return status;
01187 }
01188 
01189 /**
01190   * @brief  Wraps up reception in non-blocking mode.
01191   * @param  hswpmi: SWPMI handle
01192   * @retval HAL status
01193   * @retval HAL status
01194   */
01195 static HAL_StatusTypeDef SWPMI_EndReceive_IT(SWPMI_HandleTypeDef *hswpmi)
01196 {
01197   /* Clear the SWPMI Receive buffer full Flag */
01198   WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF);
01199   /* Disable the all SWPMI Receive Interrupts  */
01200   CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
01201 
01202   /* Check if a transmit Process is ongoing or not */
01203   if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
01204   {
01205     hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
01206   }
01207   else
01208   {
01209     hswpmi->State = HAL_SWPMI_STATE_READY;
01210   }
01211 
01212   return HAL_OK;
01213 }
01214 
01215 /**
01216   * @brief  Wraps up transmission and reception in non-blocking mode.
01217   * @param  hswpmi: SWPMI handle
01218   * @retval HAL status
01219   * @retval HAL status
01220   */
01221 static HAL_StatusTypeDef SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef *hswpmi)
01222 {
01223   /* Clear the SWPMI Transmission Complete Flag */
01224   WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TCF);
01225   /* Disable the SWPMI Transmission  Complete Interrupt */
01226   CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TCIE);
01227 
01228   /* Check if a receive Process is ongoing or not */
01229   if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
01230   {
01231     hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
01232   }
01233   else if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX)
01234   {
01235     hswpmi->State = HAL_SWPMI_STATE_READY;
01236   }
01237 
01238   return HAL_OK;
01239 }
01240 
01241 /**
01242   * @brief DMA SWPMI transmit process complete callback.
01243   * @param hdma: DMA handle
01244   * @retval None
01245   */
01246 static void SWPMI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
01247 {
01248   SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01249 
01250   /* DMA Normal mode*/
01251   if((hdma->Instance->CCR & DMA_CCR_CIRC) != SET)
01252   {
01253     hswpmi->TxXferCount = 0;
01254 
01255     /* Disable the DMA transfer for transmit request by setting the TXDMA bit
01256     in the SWPMI CR register */
01257     CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);
01258 
01259     /* Wait the TXBEF */
01260     if(SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, SWPMI_TIMEOUT_VALUE) != HAL_OK)
01261     {
01262       /* Timeout occurred */
01263       HAL_SWPMI_ErrorCallback(hswpmi);
01264     }
01265     else
01266     {
01267       /* No Timeout */
01268       /* Check if a receive process is ongoing or not */
01269       if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
01270       {
01271         hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
01272       }
01273       else
01274       {
01275         hswpmi->State = HAL_SWPMI_STATE_READY;
01276       }
01277 
01278       HAL_SWPMI_TxCpltCallback(hswpmi);
01279     }
01280   }
01281   /* DMA Circular mode */
01282   else
01283   {
01284     HAL_SWPMI_TxCpltCallback(hswpmi);
01285   }
01286 }
01287 
01288 /**
01289   * @brief DMA SWPMI transmit process half complete callback.
01290   * @param hdma : DMA handle
01291   * @retval None
01292   */
01293 static void SWPMI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
01294 {
01295   SWPMI_HandleTypeDef* hswpmi = (SWPMI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
01296 
01297   HAL_SWPMI_TxHalfCpltCallback(hswpmi);
01298 }
01299 
01300 
01301 /**
01302   * @brief DMA SWPMI receive process complete callback.
01303   * @param hdma: DMA handle
01304   * @retval None
01305   */
01306 static void SWPMI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
01307 {
01308   SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01309 
01310   /* DMA Normal mode*/
01311   if((hdma->Instance->CCR & DMA_CCR_CIRC) == RESET)
01312   {
01313     hswpmi->RxXferCount = 0;
01314 
01315     /* Disable the DMA transfer for the receiver request by setting the RXDMA bit
01316     in the SWPMI CR register */
01317     CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);
01318 
01319     /* Check if a transmit Process is ongoing or not */
01320     if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
01321     {
01322       hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
01323     }
01324     else
01325     {
01326       hswpmi->State = HAL_SWPMI_STATE_READY;
01327     }
01328   }
01329   HAL_SWPMI_RxCpltCallback(hswpmi);
01330 }
01331 
01332 /**
01333   * @brief DMA SWPMI receive process half complete callback.
01334   * @param hdma : DMA handle
01335   * @retval None
01336   */
01337 static void SWPMI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
01338 {
01339   SWPMI_HandleTypeDef* hswpmi = (SWPMI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
01340 
01341   HAL_SWPMI_RxHalfCpltCallback(hswpmi);
01342 }
01343 
01344 /**
01345   * @brief DMA SWPMI communication error callback.
01346   * @param hdma: DMA handle
01347   * @retval None
01348   */
01349 static void SWPMI_DMAError(DMA_HandleTypeDef *hdma)
01350 {
01351   SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
01352 
01353   /* Update handle */
01354   hswpmi->RxXferCount = 0;
01355   hswpmi->TxXferCount = 0;
01356   hswpmi->State= HAL_SWPMI_STATE_READY;
01357   hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA;
01358 
01359   HAL_SWPMI_ErrorCallback(hswpmi);
01360 }
01361 
01362 /**
01363   * @brief  Handle SWPMI Communication Timeout.
01364   * @param  hswpmi: SWPMI handle
01365   * @param  Flag: specifies the SWPMI flag to check.
01366   * @param  Timeout: Timeout duration
01367   * @retval HAL status
01368   */
01369 static HAL_StatusTypeDef SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef *hswpmi, uint32_t Flag, uint32_t Timeout)
01370 {
01371   uint32_t tickstart = HAL_GetTick();
01372   HAL_StatusTypeDef status = HAL_OK;
01373 
01374   /* Wait until flag is set */
01375   while(!(HAL_IS_BIT_SET(hswpmi->Instance->ISR, Flag)))
01376   {
01377     /* Check for the Timeout */
01378     if(Timeout != HAL_MAX_DELAY)
01379     {
01380       if((HAL_GetTick() - tickstart ) > Timeout)
01381       {
01382         hswpmi->State = HAL_SWPMI_STATE_TIMEOUT;
01383 
01384         status = HAL_TIMEOUT;
01385         break;
01386       }
01387     }
01388   }
01389 
01390   return status;
01391 }
01392 
01393 /**
01394   * @}
01395   */
01396 
01397 #endif /* HAL_SWPMI_MODULE_ENABLED */
01398 /**
01399   * @}
01400   */
01401 
01402 /**
01403   * @}
01404   */
01405 
01406 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
01407