| /** |
| ****************************************************************************** |
| * @file stm32l4xx_hal_swpmi.c |
| * @author MCD Application Team |
| * @brief SWPMI HAL module driver. |
| * This file provides firmware functions to manage the following |
| * functionalities of the Single Wire Protocol Master Interface (SWPMI). |
| * + Initialization and Configuration |
| * + Data transfers functions |
| * + DMA transfers management |
| * + Interrupts and flags management |
| @verbatim |
| =============================================================================== |
| ##### How to use this driver ##### |
| =============================================================================== |
| [..] |
| The SWPMI HAL driver can be used as follows: |
| |
| (#) Declare a SWPMI_HandleTypeDef handle structure (eg. SWPMI_HandleTypeDef hswpmi). |
| |
| (#) Initialize the SWPMI low level resources by implementing the HAL_SWPMI_MspInit() API: |
| (##) Enable the SWPMIx interface clock with __HAL_RCC_SWPMIx_CLK_ENABLE(). |
| (##) SWPMI IO configuration: |
| (+++) Enable the clock for the SWPMI GPIO. |
| (+++) Configure these SWPMI pins as alternate function pull-up. |
| (##) NVIC configuration if you need to use interrupt process (HAL_SWPMI_Transmit_IT() |
| and HAL_SWPMI_Receive_IT() APIs): |
| (+++) Configure the SWPMIx interrupt priority with HAL_NVIC_SetPriority(). |
| (+++) Enable the NVIC SWPMI IRQ handle with HAL_NVIC_EnableIRQ(). |
| |
| (##) DMA Configuration if you need to use DMA process (HAL_SWPMI_Transmit_DMA() |
| and HAL_SWPMI_Receive_DMA() APIs): |
| (+++) Declare a DMA handle structure for the Tx/Rx channels. |
| (+++) Enable the DMAx interface clock. |
| (+++) Configure the declared DMA handle structure with the required |
| Tx/Rx parameters. |
| (+++) Configure the DMA Tx/Rx channels and requests. |
| (+++) Associate the initialized DMA handle to the SWPMI DMA Tx/Rx handle. |
| (+++) Configure the priority and enable the NVIC for the transfer complete |
| interrupt on the DMA Tx/Rx channels. |
| |
| (#) Program the Bite Rate, Tx Buffering mode, Rx Buffering mode in the Init structure. |
| |
| (#) Enable the SWPMI peripheral by calling the HAL_SWPMI_Init() function. |
| |
| @endverbatim |
| ****************************************************************************** |
| * @attention |
| * |
| * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> |
| * |
| * Redistribution and use in source and binary forms, with or without modification, |
| * are permitted provided that the following conditions are met: |
| * 1. Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * 3. Neither the name of STMicroelectronics nor the names of its contributors |
| * may be used to endorse or promote products derived from this software |
| * without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| ****************************************************************************** |
| */ |
| |
| /* Includes ------------------------------------------------------------------*/ |
| #include "stm32l4xx_hal.h" |
| |
| #if defined(STM32L431xx) || defined(STM32L432xx) || defined(STM32L433xx) || defined(STM32L442xx) || defined(STM32L443xx) || \ |
| defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx) || \ |
| defined(STM32L496xx) || defined(STM32L4A6xx) |
| |
| /** @addtogroup STM32L4xx_HAL_Driver |
| * @{ |
| */ |
| |
| /** @defgroup SWPMI SWPMI |
| * @brief HAL SWPMI module driver |
| * @{ |
| */ |
| #ifdef HAL_SWPMI_MODULE_ENABLED |
| |
| /* Private typedef -----------------------------------------------------------*/ |
| /* Private define ------------------------------------------------------------*/ |
| /* Private constants ---------------------------------------------------------*/ |
| /** @addtogroup SWPMI_Private_Constants SWPMI Private Constants |
| * @{ |
| */ |
| #define SWPMI_TIMEOUT_VALUE ((uint32_t) 22000) |
| |
| /** |
| * @} |
| */ |
| |
| /* Private macros ------------------------------------------------------------*/ |
| /* Private variables ---------------------------------------------------------*/ |
| /* Private function prototypes -----------------------------------------------*/ |
| static void SWPMI_DMATransmitCplt(DMA_HandleTypeDef *hdma); |
| static void SWPMI_DMATxHalfCplt(DMA_HandleTypeDef *hdma); |
| static void SWPMI_DMAReceiveCplt(DMA_HandleTypeDef *hdma); |
| static void SWPMI_DMARxHalfCplt(DMA_HandleTypeDef *hdma); |
| static void SWPMI_DMAError(DMA_HandleTypeDef *hdma); |
| static void SWPMI_DMAAbortOnError(DMA_HandleTypeDef *hdma); |
| static HAL_StatusTypeDef SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi); |
| static HAL_StatusTypeDef SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef *hswpmi); |
| static HAL_StatusTypeDef SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi); |
| static HAL_StatusTypeDef SWPMI_EndReceive_IT(SWPMI_HandleTypeDef *hswpmi); |
| static HAL_StatusTypeDef SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef *hswpmi); |
| static HAL_StatusTypeDef SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef *hswpmi, uint32_t Flag, uint32_t Tickstart, uint32_t Timeout); |
| |
| /* Exported functions --------------------------------------------------------*/ |
| |
| /** @defgroup SWPMI_Exported_Functions SWPMI Exported Functions |
| * @{ |
| */ |
| |
| /** @defgroup SWPMI_Exported_Group1 Initialization/de-initialization methods |
| * @brief Initialization and Configuration functions |
| * |
| @verbatim |
| =============================================================================== |
| ##### Initialization and Configuration functions ##### |
| =============================================================================== |
| [..] This section provides functions allowing to: |
| (+) Initialize and configure the SWPMI peripheral. |
| (+) De-initialize the SWPMI peripheral. |
| |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief Initialize the SWPMI peripheral according to the specified parameters in the SWPMI_InitTypeDef. |
| * @param hswpmi: SWPMI handle |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_SWPMI_Init(SWPMI_HandleTypeDef *hswpmi) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| __IO uint32_t wait_loop_index = 0; |
| |
| /* Check the SWPMI handle allocation */ |
| if(hswpmi == NULL) |
| { |
| status = HAL_ERROR; |
| } |
| else |
| { |
| /* Check the parameters */ |
| assert_param(IS_SWPMI_VOLTAGE_CLASS(hswpmi->Init.VoltageClass)); |
| assert_param(IS_SWPMI_BITRATE_VALUE(hswpmi->Init.BitRate)); |
| assert_param(IS_SWPMI_TX_BUFFERING_MODE(hswpmi->Init.TxBufferingMode)); |
| assert_param(IS_SWPMI_RX_BUFFERING_MODE(hswpmi->Init.RxBufferingMode)); |
| |
| if(hswpmi->State == HAL_SWPMI_STATE_RESET) |
| { |
| /* Allocate lock resource and initialize it */ |
| hswpmi->Lock = HAL_UNLOCKED; |
| |
| /* Init the low level hardware : GPIO, CLOCK, CORTEX */ |
| HAL_SWPMI_MspInit(hswpmi); |
| } |
| |
| hswpmi->State = HAL_SWPMI_STATE_BUSY; |
| |
| /* Disable SWPMI interface */ |
| CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); |
| |
| /* Clear all SWPMI interface flags */ |
| WRITE_REG(hswpmi->Instance->ICR, 0x019F); |
| |
| /* Apply Voltage class selection */ |
| MODIFY_REG(hswpmi->Instance->OR, SWPMI_OR_CLASS, hswpmi->Init.VoltageClass); |
| |
| /* If Voltage class B, apply 300 µs delay */ |
| if(hswpmi->Init.VoltageClass == SWPMI_VOLTAGE_CLASS_B) |
| { |
| /* Insure 300 µs wait to insure SWPMI_IO output not higher than 1.8V */ |
| /* Wait loop initialization and execution */ |
| /* Note: Variable divided by 4 to compensate partially CPU processing cycles. */ |
| wait_loop_index = (300 * (SystemCoreClock / (1000000 * 4))) + 150; |
| while(wait_loop_index != 0) |
| { |
| wait_loop_index--; |
| } |
| } |
| |
| /* Configure the BRR register (Bitrate) */ |
| WRITE_REG(hswpmi->Instance->BRR, hswpmi->Init.BitRate); |
| |
| /* Apply SWPMI CR configuration */ |
| MODIFY_REG(hswpmi->Instance->CR, \ |
| SWPMI_CR_RXDMA | SWPMI_CR_TXDMA | SWPMI_CR_RXMODE | SWPMI_CR_TXMODE, \ |
| hswpmi->Init.TxBufferingMode | hswpmi->Init.RxBufferingMode); |
| |
| hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE; |
| hswpmi->State = HAL_SWPMI_STATE_READY; |
| |
| /* Enable SWPMI peripheral if not */ |
| SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); |
| } |
| |
| return status; |
| } |
| |
| /** |
| * @brief De-initialize the SWPMI peripheral. |
| * @param hswpmi: SWPMI handle |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_SWPMI_DeInit(SWPMI_HandleTypeDef *hswpmi) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| /* Check the SWPMI handle allocation */ |
| if(hswpmi == NULL) |
| { |
| status = HAL_ERROR; |
| } |
| else |
| { |
| /* Check the parameters */ |
| assert_param(IS_SWPMI_INSTANCE(hswpmi->Instance)); |
| |
| hswpmi->State = HAL_SWPMI_STATE_BUSY; |
| |
| /* Disable SWPMI interface */ |
| CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); |
| |
| /* DeInit the low level hardware */ |
| HAL_SWPMI_MspDeInit(hswpmi); |
| |
| hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE; |
| |
| hswpmi->State = HAL_SWPMI_STATE_RESET; |
| |
| /* Release Lock */ |
| __HAL_UNLOCK(hswpmi); |
| } |
| |
| return status; |
| } |
| |
| /** |
| * @brief Initialize the SWPMI MSP. |
| * @param hswpmi: SWPMI handle |
| * @retval None |
| */ |
| __weak void HAL_SWPMI_MspInit(SWPMI_HandleTypeDef *hswpmi) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hswpmi); |
| |
| /* NOTE : This function should not be modified, when the callback is needed, |
| the HAL_SWPMI_MspInit can be implemented in the user file |
| */ |
| } |
| |
| /** |
| * @brief DeInitialize the SWPMI MSP. |
| * @param hswpmi: SWPMI handle |
| * @retval None |
| */ |
| __weak void HAL_SWPMI_MspDeInit(SWPMI_HandleTypeDef *hswpmi) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hswpmi); |
| |
| /* NOTE : This function should not be modified, when the callback is needed, |
| the HAL_SWPMI_MspDeInit can be implemented in the user file |
| */ |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** @defgroup SWPMI_Exported_Group2 IO operation methods |
| * @brief SWPMI Transmit/Receive functions |
| * |
| @verbatim |
| =============================================================================== |
| ##### IO operation methods ##### |
| =============================================================================== |
| [..] |
| This subsection provides a set of functions allowing to manage the SWPMI |
| data transfers. |
| |
| (#) There are two modes of transfer: |
| (++) Blocking mode: The communication is performed in polling mode. |
| The HAL status of all data processing is returned by the same function |
| after finishing transfer. |
| (++) Non-Blocking mode: The communication is performed using Interrupts |
| or DMA. The end of the data processing will be indicated through the |
| dedicated SWPMI Interrupt handler (HAL_SWPMI_IRQHandler()) when using Interrupt mode or |
| the selected DMA channel interrupt handler when using DMA mode. |
| The HAL_SWPMI_TxCpltCallback(), HAL_SWPMI_RxCpltCallback() user callbacks |
| will be executed respectively at the end of the transmit or receive process. |
| The HAL_SWPMI_ErrorCallback() user callback will be executed when a communication error is detected. |
| |
| (#) Blocking mode API's are: |
| (++) HAL_SWPMI_Transmit() |
| (++) HAL_SWPMI_Receive() |
| |
| (#) Non-Blocking mode API's with Interrupt are: |
| (++) HAL_SWPMI_Transmit_IT() |
| (++) HAL_SWPMI_Receive_IT() |
| (++) HAL_SWPMI_IRQHandler() |
| |
| (#) Non-Blocking mode API's with DMA are: |
| (++) HAL_SWPMI_Transmit_DMA() |
| (++) HAL_SWPMI_Receive_DMA() |
| (++) HAL_SWPMI_DMAPause() |
| (++) HAL_SWPMI_DMAResume() |
| (++) HAL_SWPMI_DMAStop() |
| |
| (#) A set of Transfer Complete Callbacks are provided in Non-Blocking mode: |
| (++) HAL_SWPMI_TxHalfCpltCallback() |
| (++) HAL_SWPMI_TxCpltCallback() |
| (++) HAL_SWPMI_RxHalfCpltCallback() |
| (++) HAL_SWPMI_RxCpltCallback() |
| (++) HAL_SWPMI_ErrorCallback() |
| |
| (#) The capability to launch the above IO operations in loopback mode for |
| user application verification: |
| (++) HAL_SWPMI_EnableLoopback() |
| (++) HAL_SWPMI_DisableLoopback() |
| |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief Transmit an amount of data in blocking mode. |
| * @param hswpmi: pointer to a SWPMI_HandleTypeDef structure that contains |
| * the configuration information for SWPMI module. |
| * @param pData: Pointer to data buffer |
| * @param Size: Amount of data to be sent |
| * @param Timeout: Timeout duration |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_SWPMI_Transmit(SWPMI_HandleTypeDef *hswpmi, uint32_t* pData, uint16_t Size, uint32_t Timeout) |
| { |
| uint32_t tickstart = HAL_GetTick(); |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| if((pData == NULL ) || (Size == 0)) |
| { |
| status = HAL_ERROR; |
| } |
| else |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hswpmi); |
| |
| if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_RX)) |
| { |
| /* Check if a non-blocking receive process is ongoing or not */ |
| if(hswpmi->State == HAL_SWPMI_STATE_READY) |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_TX; |
| |
| /* Disable any transmitter interrupts */ |
| __HAL_SWPMI_DISABLE_IT(hswpmi, SWPMI_IT_TCIE | SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE); |
| |
| /* Disable any transmitter flags */ |
| __HAL_SWPMI_CLEAR_FLAG(hswpmi, SWPMI_FLAG_TXBEF | SWPMI_FLAG_TXUNRF | SWPMI_FLAG_TCF); |
| |
| /* Enable SWPMI peripheral if not */ |
| SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); |
| } |
| else |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX; |
| } |
| |
| do |
| { |
| /* Wait the TXE to write data */ |
| if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_TXE)) |
| { |
| hswpmi->Instance->TDR = (*pData++); |
| Size--; |
| } |
| else |
| { |
| /* Check for the Timeout */ |
| if(Timeout != HAL_MAX_DELAY) |
| { |
| if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout)) |
| { |
| status = HAL_TIMEOUT; |
| break; |
| } |
| } |
| } |
| } while(Size != 0); |
| |
| /* Wait on TXBEF flag to be able to start a second transfer */ |
| if(SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, tickstart, Timeout) != HAL_OK) |
| { |
| status = HAL_TIMEOUT; |
| } |
| |
| if(status == HAL_OK) |
| { |
| /* Check if a non-blocking receive Process is ongoing or not */ |
| if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX) |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_RX; |
| } |
| else |
| { |
| hswpmi->State = HAL_SWPMI_STATE_READY; |
| } |
| } |
| } |
| else |
| { |
| status = HAL_BUSY; |
| } |
| } |
| |
| if((status != HAL_OK) && (status != HAL_BUSY)) |
| { |
| hswpmi->State = HAL_SWPMI_STATE_READY; |
| } |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hswpmi); |
| |
| return status; |
| } |
| |
| /** |
| * @brief Receive an amount of data in blocking mode. |
| * @param hswpmi: pointer to a SWPMI_HandleTypeDef structure that contains |
| * the configuration information for SWPMI module. |
| * @param pData: Pointer to data buffer |
| * @param Size: Amount of data to be received |
| * @param Timeout: Timeout duration |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_SWPMI_Receive(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size, uint32_t Timeout) |
| { |
| uint32_t tickstart = HAL_GetTick(); |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| if((pData == NULL ) || (Size == 0)) |
| { |
| status = HAL_ERROR; |
| } |
| else |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hswpmi); |
| |
| if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX)) |
| { |
| /* Check if a non-blocking transmit process is ongoing or not */ |
| if(hswpmi->State == HAL_SWPMI_STATE_READY) |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_RX; |
| |
| /* Disable any receiver interrupts */ |
| CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_SRIE | SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE); |
| |
| /* Enable SWPMI peripheral if not */ |
| SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); |
| } |
| else |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX; |
| } |
| |
| do |
| { |
| /* Wait the RXNE to read data */ |
| if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXNE)) |
| { |
| (*pData++) = hswpmi->Instance->RDR; |
| Size--; |
| } |
| else |
| { |
| /* Check for the Timeout */ |
| if(Timeout != HAL_MAX_DELAY) |
| { |
| if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout)) |
| { |
| status = HAL_TIMEOUT; |
| break; |
| } |
| } |
| } |
| } while(Size != 0); |
| |
| if(status == HAL_OK) |
| { |
| if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXBFF)) |
| { |
| /* Clear RXBFF at end of reception */ |
| WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF); |
| } |
| |
| /* Check if a non-blocking transmit Process is ongoing or not */ |
| if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX) |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_TX; |
| } |
| else |
| { |
| hswpmi->State = HAL_SWPMI_STATE_READY; |
| } |
| } |
| } |
| else |
| { |
| status = HAL_BUSY; |
| } |
| } |
| |
| if((status != HAL_OK) && (status != HAL_BUSY)) |
| { |
| hswpmi->State = HAL_SWPMI_STATE_READY; |
| } |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hswpmi); |
| |
| return status; |
| } |
| |
| /** |
| * @brief Transmit an amount of data in non-blocking mode with interrupt. |
| * @param hswpmi: pointer to a SWPMI_HandleTypeDef structure that contains |
| * the configuration information for SWPMI module. |
| * @param pData: Pointer to data buffer |
| * @param Size: Amount of data to be sent |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| if((pData == NULL ) || (Size == 0)) |
| { |
| status = HAL_ERROR; |
| } |
| else |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hswpmi); |
| |
| if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_RX)) |
| { |
| /* Update handle */ |
| hswpmi->pTxBuffPtr = pData; |
| hswpmi->TxXferSize = Size; |
| hswpmi->TxXferCount = Size; |
| hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE; |
| |
| /* Check if a receive process is ongoing or not */ |
| if(hswpmi->State == HAL_SWPMI_STATE_READY) |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_TX; |
| |
| /* Enable SWPMI peripheral if not */ |
| SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); |
| } |
| else |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX; |
| } |
| |
| /* Enable the SWPMI transmit underrun error */ |
| __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TXUNRIE); |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hswpmi); |
| |
| /* Enable the SWPMI interrupts: */ |
| /* - Transmit data register empty */ |
| /* - Transmit buffer empty */ |
| /* - Transmit/Reception completion */ |
| __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TIE | SWPMI_IT_TXBEIE | SWPMI_IT_TCIE); |
| } |
| else |
| { |
| status = HAL_BUSY; |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hswpmi); |
| } |
| } |
| |
| return status; |
| } |
| |
| /** |
| * @brief Receive an amount of data in non-blocking mode with interrupt. |
| * @param hswpmi: SWPMI handle |
| * @param pData: pointer to data buffer |
| * @param Size: amount of data to be received |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| if((pData == NULL ) || (Size == 0)) |
| { |
| status = HAL_ERROR; |
| } |
| else |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hswpmi); |
| |
| if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX)) |
| { |
| /* Update handle */ |
| hswpmi->pRxBuffPtr = pData; |
| hswpmi->RxXferSize = Size; |
| hswpmi->RxXferCount = Size; |
| hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE; |
| |
| /* Check if a transmit process is ongoing or not */ |
| if(hswpmi->State == HAL_SWPMI_STATE_READY) |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_RX; |
| |
| /* Enable SWPMI peripheral if not */ |
| SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); |
| } |
| else |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX; |
| } |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hswpmi); |
| |
| /* Enable the SWPMI slave resume */ |
| /* Enable the SWPMI Data Register not empty Interrupt, receive CRC Error, receive overrun and RxBuf Interrupt */ |
| /* Enable the SWPMI Transmit/Reception completion */ |
| __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE); |
| } |
| else |
| { |
| status = HAL_BUSY; |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hswpmi); |
| } |
| } |
| |
| return status; |
| } |
| |
| /** |
| * @brief Transmit an amount of data in non-blocking mode with DMA interrupt. |
| * @param hswpmi: SWPMI handle |
| * @param pData: pointer to data buffer |
| * @param Size: amount of data to be sent |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_SWPMI_Transmit_DMA(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| if((pData == NULL ) || (Size == 0)) |
| { |
| status = HAL_ERROR; |
| } |
| else |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hswpmi); |
| |
| if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_RX)) |
| { |
| /* Update handle */ |
| hswpmi->pTxBuffPtr = pData; |
| hswpmi->TxXferSize = Size; |
| hswpmi->TxXferCount = Size; |
| hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE; |
| |
| /* Check if a receive process is ongoing or not */ |
| if(hswpmi->State == HAL_SWPMI_STATE_READY) |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_TX; |
| |
| /* Enable SWPMI peripheral if not */ |
| SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); |
| } |
| else |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX; |
| } |
| |
| /* Set the SWPMI DMA transfer complete callback */ |
| hswpmi->hdmatx->XferCpltCallback = SWPMI_DMATransmitCplt; |
| |
| /* Set the SWPMI DMA Half transfer complete callback */ |
| hswpmi->hdmatx->XferHalfCpltCallback = SWPMI_DMATxHalfCplt; |
| |
| /* Set the DMA error callback */ |
| hswpmi->hdmatx->XferErrorCallback = SWPMI_DMAError; |
| |
| /* Enable the SWPMI transmit DMA Channel */ |
| HAL_DMA_Start_IT(hswpmi->hdmatx, (uint32_t)hswpmi->pTxBuffPtr, (uint32_t)&hswpmi->Instance->TDR, Size); |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hswpmi); |
| |
| /* Enable the SWPMI transmit underrun error */ |
| __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TXUNRIE); |
| |
| /* Enable the DMA transfer for transmit request by setting the TXDMA bit |
| in the SWPMI CR register */ |
| SET_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA); |
| } |
| else |
| { |
| status = HAL_BUSY; |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hswpmi); |
| } |
| } |
| |
| return status; |
| } |
| |
| /** |
| * @brief Receive an amount of data in non-blocking mode with DMA interrupt. |
| * @param hswpmi: SWPMI handle |
| * @param pData: pointer to data buffer |
| * @param Size: amount of data to be received |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_SWPMI_Receive_DMA(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| if((pData == NULL ) || (Size == 0)) |
| { |
| status = HAL_ERROR; |
| } |
| else |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hswpmi); |
| |
| if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX)) |
| { |
| /* Update handle */ |
| hswpmi->pRxBuffPtr = pData; |
| hswpmi->RxXferSize = Size; |
| hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE; |
| |
| /* Check if a transmit process is ongoing or not */ |
| if(hswpmi->State == HAL_SWPMI_STATE_READY) |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_RX; |
| |
| /* Enable SWPMI peripheral if not */ |
| SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); |
| } |
| else |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX; |
| } |
| |
| /* Set the SWPMI DMA transfer complete callback */ |
| hswpmi->hdmarx->XferCpltCallback = SWPMI_DMAReceiveCplt; |
| |
| /* Set the SWPMI DMA Half transfer complete callback */ |
| hswpmi->hdmarx->XferHalfCpltCallback = SWPMI_DMARxHalfCplt; |
| |
| /* Set the DMA error callback */ |
| hswpmi->hdmarx->XferErrorCallback = SWPMI_DMAError; |
| |
| /* Enable the DMA request */ |
| HAL_DMA_Start_IT(hswpmi->hdmarx, (uint32_t)&hswpmi->Instance->RDR, (uint32_t)hswpmi->pRxBuffPtr, Size); |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hswpmi); |
| |
| /* Enable the SWPMI receive CRC Error and receive overrun interrupts */ |
| __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE); |
| |
| /* Enable the DMA transfer for the receiver request by setting the RXDMA bit |
| in the SWPMI CR register */ |
| SET_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA); |
| } |
| else |
| { |
| status = HAL_BUSY; |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hswpmi); |
| } |
| } |
| |
| return status; |
| } |
| |
| /** |
| * @brief Stop all DMA transfers. |
| * @param hswpmi: SWPMI handle |
| * @retval HAL_OK |
| */ |
| HAL_StatusTypeDef HAL_SWPMI_DMAStop(SWPMI_HandleTypeDef *hswpmi) |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hswpmi); |
| |
| /* Disable the SWPMI Tx/Rx DMA requests */ |
| CLEAR_BIT(hswpmi->Instance->CR, (SWPMI_CR_TXDMA | SWPMI_CR_RXDMA)); |
| |
| /* Abort the SWPMI DMA tx channel */ |
| if(hswpmi->hdmatx != NULL) |
| { |
| HAL_DMA_Abort(hswpmi->hdmatx); |
| } |
| /* Abort the SWPMI DMA rx channel */ |
| if(hswpmi->hdmarx != NULL) |
| { |
| HAL_DMA_Abort(hswpmi->hdmarx); |
| } |
| |
| /* Disable SWPMI interface */ |
| CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); |
| |
| hswpmi->State = HAL_SWPMI_STATE_READY; |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hswpmi); |
| |
| return HAL_OK; |
| } |
| |
| |
| /** |
| * @brief Enable the Loopback mode. |
| * @param hswpmi: SWPMI handle |
| * @note Loopback mode is to be used only for test purposes |
| * @retval HAL_OK / HAL_BUSY |
| */ |
| HAL_StatusTypeDef HAL_SWPMI_EnableLoopback(SWPMI_HandleTypeDef *hswpmi) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| /* Process Locked */ |
| __HAL_LOCK(hswpmi); |
| |
| /* Check SWPMI not enabled */ |
| if(READ_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT) != RESET) |
| { |
| status = HAL_BUSY; |
| } |
| else |
| { |
| /* Set Loopback */ |
| SET_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK); |
| } |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hswpmi); |
| |
| return status; |
| } |
| |
| /** |
| * @brief Disable the Loopback mode. |
| * @param hswpmi: SWPMI handle |
| * @note Loopback mode is to be used only for test purposes |
| * @retval HAL_OK / HAL_BUSY |
| */ |
| HAL_StatusTypeDef HAL_SWPMI_DisableLoopback(SWPMI_HandleTypeDef *hswpmi) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| /* Process Locked */ |
| __HAL_LOCK(hswpmi); |
| |
| /* Check SWPMI not enabled */ |
| if(READ_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT) != RESET) |
| { |
| status = HAL_BUSY; |
| } |
| else |
| { |
| /* Reset Loopback */ |
| CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK); |
| } |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(hswpmi); |
| |
| return status; |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** @defgroup SWPMI_Exported_Group3 SWPMI IRQ handler and callbacks |
| * @brief SWPMI IRQ handler. |
| * |
| @verbatim |
| ============================================================================== |
| ##### SWPMI IRQ handler and callbacks ##### |
| ============================================================================== |
| [..] This section provides SWPMI IRQ handler and callback functions called within |
| the IRQ handler. |
| |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief Handle SWPMI interrupt request. |
| * @param hswpmi: SWPMI handle |
| * @retval None |
| */ |
| void HAL_SWPMI_IRQHandler(SWPMI_HandleTypeDef *hswpmi) |
| { |
| uint32_t regisr = READ_REG(hswpmi->Instance->ISR); |
| uint32_t regier = READ_REG(hswpmi->Instance->IER); |
| uint32_t errcode = HAL_SWPMI_ERROR_NONE; |
| |
| /* SWPMI CRC error interrupt occurred --------------------------------------*/ |
| if(((regisr & SWPMI_FLAG_RXBERF) != RESET) && ((regier & SWPMI_IT_RXBERIE) != RESET)) |
| { |
| /* Disable Receive CRC interrupt */ |
| CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RXBERIE | SWPMI_IT_RXBFIE); |
| /* Clear Receive CRC and Receive buffer full flag */ |
| WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBERF | SWPMI_FLAG_RXBFF); |
| |
| errcode |= HAL_SWPMI_ERROR_CRC; |
| } |
| |
| /* SWPMI Over-Run interrupt occurred -----------------------------------------*/ |
| if(((regisr & SWPMI_FLAG_RXOVRF) != RESET) && ((regier & SWPMI_IT_RXOVRIE) != RESET)) |
| { |
| /* Disable Receive overrun interrupt */ |
| CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RXOVRIE); |
| /* Clear Receive overrun flag */ |
| WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXOVRF); |
| |
| errcode |= HAL_SWPMI_ERROR_OVR; |
| } |
| |
| /* SWPMI Under-Run interrupt occurred -----------------------------------------*/ |
| if(((regisr & SWPMI_FLAG_TXUNRF) != RESET) && ((regier & SWPMI_IT_TXUNRIE) != RESET)) |
| { |
| /* Disable Transmit under run interrupt */ |
| CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TXUNRIE); |
| /* Clear Transmit under run flag */ |
| WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TXUNRF); |
| |
| errcode |= HAL_SWPMI_ERROR_UDR; |
| } |
| |
| /* Call SWPMI Error Call back function if needed --------------------------*/ |
| if(errcode != HAL_SWPMI_ERROR_NONE) |
| { |
| hswpmi->ErrorCode |= errcode; |
| |
| if((errcode & HAL_SWPMI_ERROR_UDR) != RESET) |
| { |
| /* Check TXDMA transfer to abort */ |
| if(HAL_IS_BIT_SET(hswpmi->Instance->CR, SWPMI_CR_TXDMA)) |
| { |
| /* Disable DMA TX at SWPMI level */ |
| CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA); |
| |
| /* Abort the USART DMA Tx channel */ |
| if(hswpmi->hdmatx != NULL) |
| { |
| /* Set the SWPMI Tx DMA Abort callback : |
| will lead to call HAL_SWPMI_ErrorCallback() at end of DMA abort procedure */ |
| hswpmi->hdmatx->XferAbortCallback = SWPMI_DMAAbortOnError; |
| /* Abort DMA TX */ |
| if(HAL_DMA_Abort_IT(hswpmi->hdmatx) != HAL_OK) |
| { |
| /* Call Directly hswpmi->hdmatx->XferAbortCallback function in case of error */ |
| hswpmi->hdmatx->XferAbortCallback(hswpmi->hdmatx); |
| } |
| } |
| else |
| { |
| /* Set the SWPMI state ready to be able to start again the process */ |
| hswpmi->State = HAL_SWPMI_STATE_READY; |
| |
| HAL_SWPMI_ErrorCallback(hswpmi); |
| } |
| } |
| else |
| { |
| /* Set the SWPMI state ready to be able to start again the process */ |
| hswpmi->State = HAL_SWPMI_STATE_READY; |
| |
| HAL_SWPMI_ErrorCallback(hswpmi); |
| } |
| } |
| else |
| { |
| /* Check RXDMA transfer to abort */ |
| if(HAL_IS_BIT_SET(hswpmi->Instance->CR, SWPMI_CR_RXDMA)) |
| { |
| /* Disable DMA RX at SWPMI level */ |
| CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA); |
| |
| /* Abort the USART DMA Rx channel */ |
| if(hswpmi->hdmarx != NULL) |
| { |
| /* Set the SWPMI Rx DMA Abort callback : |
| will lead to call HAL_SWPMI_ErrorCallback() at end of DMA abort procedure */ |
| hswpmi->hdmarx->XferAbortCallback = SWPMI_DMAAbortOnError; |
| /* Abort DMA RX */ |
| if(HAL_DMA_Abort_IT(hswpmi->hdmarx) != HAL_OK) |
| { |
| /* Call Directly hswpmi->hdmarx->XferAbortCallback function in case of error */ |
| hswpmi->hdmarx->XferAbortCallback(hswpmi->hdmarx); |
| } |
| } |
| else |
| { |
| /* Set the SWPMI state ready to be able to start again the process */ |
| hswpmi->State = HAL_SWPMI_STATE_READY; |
| |
| HAL_SWPMI_ErrorCallback(hswpmi); |
| } |
| } |
| else |
| { |
| /* Set the SWPMI state ready to be able to start again the process */ |
| hswpmi->State = HAL_SWPMI_STATE_READY; |
| |
| HAL_SWPMI_ErrorCallback(hswpmi); |
| } |
| } |
| } |
| |
| /* SWPMI in mode Receiver ---------------------------------------------------*/ |
| if(((regisr & SWPMI_FLAG_RXNE) != RESET) && ((regier & SWPMI_IT_RIE) != RESET)) |
| { |
| SWPMI_Receive_IT(hswpmi); |
| } |
| |
| /* SWPMI in mode Transmitter ------------------------------------------------*/ |
| if(((regisr & SWPMI_FLAG_TXE) != RESET) && ((regier & SWPMI_IT_TIE) != RESET)) |
| { |
| SWPMI_Transmit_IT(hswpmi); |
| } |
| |
| /* SWPMI in mode Transmitter (Transmit buffer empty) ------------------------*/ |
| if(((regisr & SWPMI_FLAG_TXBEF) != RESET) && ((regier & SWPMI_IT_TXBEIE) != RESET)) |
| { |
| SWPMI_EndTransmit_IT(hswpmi); |
| } |
| |
| /* SWPMI in mode Receiver (Receive buffer full) -----------------------------*/ |
| if(((regisr & SWPMI_FLAG_RXBFF) != RESET) && ((regier & SWPMI_IT_RXBFIE) != RESET)) |
| { |
| SWPMI_EndReceive_IT(hswpmi); |
| } |
| |
| /* Both Transmission and reception complete ---------------------------------*/ |
| if(((regisr & SWPMI_FLAG_TCF) != RESET) && ((regier & SWPMI_IT_TCIE) != RESET)) |
| { |
| SWPMI_EndTransmitReceive_IT(hswpmi); |
| } |
| } |
| |
| /** |
| * @brief Tx Transfer completed callback. |
| * @param hswpmi: SWPMI handle |
| * @retval None |
| */ |
| __weak void HAL_SWPMI_TxCpltCallback(SWPMI_HandleTypeDef *hswpmi) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hswpmi); |
| |
| /* NOTE : This function should not be modified, when the callback is needed, |
| the HAL_SWPMI_TxCpltCallback is to be implemented in the user file |
| */ |
| } |
| |
| /** |
| * @brief Tx Half Transfer completed callback. |
| * @param hswpmi: SWPMI handle |
| * @retval None |
| */ |
| __weak void HAL_SWPMI_TxHalfCpltCallback(SWPMI_HandleTypeDef *hswpmi) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hswpmi); |
| |
| /* NOTE: This function should not be modified, when the callback is needed, |
| the HAL_SWPMI_TxHalfCpltCallback is to be implemented in the user file |
| */ |
| } |
| |
| /** |
| * @brief Rx Transfer completed callback. |
| * @param hswpmi: SWPMI handle |
| * @retval None |
| */ |
| __weak void HAL_SWPMI_RxCpltCallback(SWPMI_HandleTypeDef *hswpmi) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hswpmi); |
| |
| /* NOTE : This function should not be modified, when the callback is needed, |
| the HAL_SWPMI_RxCpltCallback is to be implemented in the user file |
| */ |
| } |
| |
| /** |
| * @brief Rx Half Transfer completed callback. |
| * @param hswpmi: SWPMI handle |
| * @retval None |
| */ |
| __weak void HAL_SWPMI_RxHalfCpltCallback(SWPMI_HandleTypeDef *hswpmi) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hswpmi); |
| |
| /* NOTE: This function should not be modified, when the callback is needed, |
| the HAL_SWPMI_RxHalfCpltCallback is to be implemented in the user file |
| */ |
| } |
| |
| /** |
| * @brief SWPMI error callback. |
| * @param hswpmi: SWPMI handle |
| * @retval None |
| */ |
| __weak void HAL_SWPMI_ErrorCallback(SWPMI_HandleTypeDef *hswpmi) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hswpmi); |
| |
| /* NOTE : This function should not be modified, when the callback is needed, |
| the HAL_SWPMI_ErrorCallback is to be implemented in the user file |
| */ |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** @defgroup SWPMI_Exported_Group4 Peripheral Control methods |
| * @brief SWPMI control functions |
| * |
| @verbatim |
| =============================================================================== |
| ##### Peripheral Control methods ##### |
| =============================================================================== |
| [..] |
| This subsection provides a set of functions allowing to control the SWPMI. |
| (+) HAL_SWPMI_GetState() API is helpful to check in run-time the state of the SWPMI peripheral |
| (+) HAL_SWPMI_GetError() API is helpful to check in run-time the error state of the SWPMI peripheral |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief Return the SWPMI handle state. |
| * @param hswpmi: SWPMI handle |
| * @retval HAL state |
| */ |
| HAL_SWPMI_StateTypeDef HAL_SWPMI_GetState(SWPMI_HandleTypeDef *hswpmi) |
| { |
| /* Return SWPMI handle state */ |
| return hswpmi->State; |
| } |
| |
| /** |
| * @brief Return the SWPMI error code. |
| * @param hswpmi : pointer to a SWPMI_HandleTypeDef structure that contains |
| * the configuration information for the specified SWPMI. |
| * @retval SWPMI Error Code |
| */ |
| uint32_t HAL_SWPMI_GetError(SWPMI_HandleTypeDef *hswpmi) |
| { |
| return hswpmi->ErrorCode; |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** |
| * @} |
| */ |
| |
| /* Private functions ---------------------------------------------------------*/ |
| |
| /** @defgroup SWPMI_Private_Functions SWPMI Private Functions |
| * @{ |
| */ |
| |
| /** |
| * @brief Transmit an amount of data in interrupt mode. |
| * @note Function called under interruption only, once interruptions have been enabled by HAL_SWPMI_Transmit_IT() |
| * @param hswpmi: SWPMI handle |
| * @retval HAL status |
| */ |
| static HAL_StatusTypeDef SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| if ((hswpmi->State == HAL_SWPMI_STATE_BUSY_TX) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)) |
| { |
| if(hswpmi->TxXferCount == 0) |
| { |
| /* Disable the SWPMI TXE and Underrun Interrupts */ |
| CLEAR_BIT(hswpmi->Instance->IER, (SWPMI_IT_TIE | SWPMI_IT_TXUNRIE)); |
| } |
| else |
| { |
| hswpmi->Instance->TDR = (uint32_t)(*hswpmi->pTxBuffPtr++); |
| hswpmi->TxXferCount--; |
| } |
| } |
| else |
| { |
| status = HAL_BUSY; |
| } |
| |
| return status; |
| } |
| |
| /** |
| * @brief Wraps up transmission in non-blocking mode. |
| * @param hswpmi: SWPMI handle |
| * @retval HAL status |
| * @retval HAL status |
| */ |
| static HAL_StatusTypeDef SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef *hswpmi) |
| { |
| /* Clear the SWPMI Transmit buffer empty Flag */ |
| WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TXBEF); |
| /* Disable the all SWPMI Transmit Interrupts */ |
| CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE); |
| |
| /* Check if a receive Process is ongoing or not */ |
| if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX) |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_RX; |
| } |
| else |
| { |
| hswpmi->State = HAL_SWPMI_STATE_READY; |
| } |
| |
| HAL_SWPMI_TxCpltCallback(hswpmi); |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Receive an amount of data in interrupt mode. |
| * @note Function called under interruption only, once interruptions have been enabled by HAL_SWPMI_Receive_IT() |
| * @param hswpmi: SWPMI handle |
| * @retval HAL status |
| */ |
| static HAL_StatusTypeDef SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| if((hswpmi->State == HAL_SWPMI_STATE_BUSY_RX) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)) |
| { |
| *hswpmi->pRxBuffPtr++ = (uint32_t)(hswpmi->Instance->RDR); |
| |
| if(--hswpmi->RxXferCount == 0) |
| { |
| /* Wait for RXBFF flag to update state */ |
| HAL_SWPMI_RxCpltCallback(hswpmi); |
| } |
| } |
| else |
| { |
| status = HAL_BUSY; |
| } |
| |
| return status; |
| } |
| |
| /** |
| * @brief Wraps up reception in non-blocking mode. |
| * @param hswpmi: SWPMI handle |
| * @retval HAL status |
| * @retval HAL status |
| */ |
| static HAL_StatusTypeDef SWPMI_EndReceive_IT(SWPMI_HandleTypeDef *hswpmi) |
| { |
| /* Clear the SWPMI Receive buffer full Flag */ |
| WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF); |
| /* Disable the all SWPMI Receive Interrupts */ |
| CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE); |
| |
| /* Check if a transmit Process is ongoing or not */ |
| if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX) |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_TX; |
| } |
| else |
| { |
| hswpmi->State = HAL_SWPMI_STATE_READY; |
| } |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Wraps up transmission and reception in non-blocking mode. |
| * @param hswpmi: SWPMI handle |
| * @retval HAL status |
| * @retval HAL status |
| */ |
| static HAL_StatusTypeDef SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef *hswpmi) |
| { |
| /* Clear the SWPMI Transmission Complete Flag */ |
| WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TCF); |
| /* Disable the SWPMI Transmission Complete Interrupt */ |
| CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TCIE); |
| |
| /* Check if a receive Process is ongoing or not */ |
| if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX) |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_RX; |
| } |
| else if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX) |
| { |
| hswpmi->State = HAL_SWPMI_STATE_READY; |
| } |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief DMA SWPMI transmit process complete callback. |
| * @param hdma: DMA handle |
| * @retval None |
| */ |
| static void SWPMI_DMATransmitCplt(DMA_HandleTypeDef *hdma) |
| { |
| SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; |
| uint32_t tickstart = 0; |
| |
| /* DMA Normal mode*/ |
| if((hdma->Instance->CCR & DMA_CCR_CIRC) != SET) |
| { |
| hswpmi->TxXferCount = 0; |
| |
| /* Disable the DMA transfer for transmit request by setting the TXDMA bit |
| in the SWPMI CR register */ |
| CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA); |
| |
| /* Init tickstart for timeout managment*/ |
| tickstart = HAL_GetTick(); |
| |
| /* Wait the TXBEF */ |
| if(SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, tickstart, SWPMI_TIMEOUT_VALUE) != HAL_OK) |
| { |
| /* Timeout occurred */ |
| HAL_SWPMI_ErrorCallback(hswpmi); |
| } |
| else |
| { |
| /* No Timeout */ |
| /* Check if a receive process is ongoing or not */ |
| if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX) |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_RX; |
| } |
| else |
| { |
| hswpmi->State = HAL_SWPMI_STATE_READY; |
| } |
| |
| HAL_SWPMI_TxCpltCallback(hswpmi); |
| } |
| } |
| /* DMA Circular mode */ |
| else |
| { |
| HAL_SWPMI_TxCpltCallback(hswpmi); |
| } |
| } |
| |
| /** |
| * @brief DMA SWPMI transmit process half complete callback. |
| * @param hdma : DMA handle |
| * @retval None |
| */ |
| static void SWPMI_DMATxHalfCplt(DMA_HandleTypeDef *hdma) |
| { |
| SWPMI_HandleTypeDef* hswpmi = (SWPMI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; |
| |
| HAL_SWPMI_TxHalfCpltCallback(hswpmi); |
| } |
| |
| |
| /** |
| * @brief DMA SWPMI receive process complete callback. |
| * @param hdma: DMA handle |
| * @retval None |
| */ |
| static void SWPMI_DMAReceiveCplt(DMA_HandleTypeDef *hdma) |
| { |
| SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; |
| |
| /* DMA Normal mode*/ |
| if((hdma->Instance->CCR & DMA_CCR_CIRC) == RESET) |
| { |
| hswpmi->RxXferCount = 0; |
| |
| /* Disable the DMA transfer for the receiver request by setting the RXDMA bit |
| in the SWPMI CR register */ |
| CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA); |
| |
| /* Check if a transmit Process is ongoing or not */ |
| if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX) |
| { |
| hswpmi->State = HAL_SWPMI_STATE_BUSY_TX; |
| } |
| else |
| { |
| hswpmi->State = HAL_SWPMI_STATE_READY; |
| } |
| } |
| HAL_SWPMI_RxCpltCallback(hswpmi); |
| } |
| |
| /** |
| * @brief DMA SWPMI receive process half complete callback. |
| * @param hdma : DMA handle |
| * @retval None |
| */ |
| static void SWPMI_DMARxHalfCplt(DMA_HandleTypeDef *hdma) |
| { |
| SWPMI_HandleTypeDef* hswpmi = (SWPMI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; |
| |
| HAL_SWPMI_RxHalfCpltCallback(hswpmi); |
| } |
| |
| /** |
| * @brief DMA SWPMI communication error callback. |
| * @param hdma: DMA handle |
| * @retval None |
| */ |
| static void SWPMI_DMAError(DMA_HandleTypeDef *hdma) |
| { |
| SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; |
| |
| /* Update handle */ |
| hswpmi->RxXferCount = 0; |
| hswpmi->TxXferCount = 0; |
| hswpmi->State= HAL_SWPMI_STATE_READY; |
| hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA; |
| |
| HAL_SWPMI_ErrorCallback(hswpmi); |
| } |
| |
| /** |
| * @brief DMA SWPMI communication abort callback. |
| * @param hdma: DMA handle |
| * @retval None |
| */ |
| static void SWPMI_DMAAbortOnError(DMA_HandleTypeDef *hdma) |
| { |
| SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; |
| |
| /* Update handle */ |
| hswpmi->RxXferCount = 0; |
| hswpmi->TxXferCount = 0; |
| hswpmi->State= HAL_SWPMI_STATE_READY; |
| |
| HAL_SWPMI_ErrorCallback(hswpmi); |
| } |
| |
| /** |
| * @brief Handle SWPMI Communication Timeout. |
| * @param hswpmi: SWPMI handle |
| * @param Flag: specifies the SWPMI flag to check. |
| * @param Tickstart Tick start value |
| * @param Timeout timeout duration. |
| * @retval HAL status |
| */ |
| static HAL_StatusTypeDef SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef *hswpmi, uint32_t Flag, uint32_t Tickstart, uint32_t Timeout) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| /* Wait until flag is set */ |
| while(!(HAL_IS_BIT_SET(hswpmi->Instance->ISR, Flag))) |
| { |
| /* Check for the Timeout */ |
| if(Timeout != HAL_MAX_DELAY) |
| { |
| if((Timeout == 0) || ((HAL_GetTick()-Tickstart) > Timeout)) |
| { |
| hswpmi->State = HAL_SWPMI_STATE_READY; |
| |
| status = HAL_TIMEOUT; |
| break; |
| } |
| } |
| } |
| |
| return status; |
| } |
| |
| /** |
| * @} |
| */ |
| |
| #endif /* HAL_SWPMI_MODULE_ENABLED */ |
| /** |
| * @} |
| */ |
| |
| /** |
| * @} |
| */ |
| |
| #endif /* STM32L431xx || STM32L432xx || STM32L433xx || STM32L442xx || STM32L443xx || */ |
| /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L485xx || STM32L486xx || */ |
| /* STM32L496xx || STM32L4A6xx */ |
| |
| /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |