STM32L486xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_irda.c 00004 * @author MCD Application Team 00005 * @brief IRDA HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the IrDA (Infrared Data Association) Peripheral 00008 * (IRDA) 00009 * + Initialization and de-initialization functions 00010 * + IO operation functions 00011 * + Peripheral State and Errors functions 00012 * + Peripheral Control functions 00013 * 00014 @verbatim 00015 ============================================================================== 00016 ##### How to use this driver ##### 00017 ============================================================================== 00018 [..] 00019 The IRDA HAL driver can be used as follows: 00020 00021 (#) Declare a IRDA_HandleTypeDef handle structure (eg. IRDA_HandleTypeDef hirda). 00022 (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API 00023 in setting the associated USART or UART in IRDA mode: 00024 (++) Enable the USARTx/UARTx interface clock. 00025 (++) USARTx/UARTx pins configuration: 00026 (+++) Enable the clock for the USARTx/UARTx GPIOs. 00027 (+++) Configure these USARTx/UARTx pins (TX as alternate function pull-up, RX as alternate function Input). 00028 (++) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT() 00029 and HAL_IRDA_Receive_IT() APIs): 00030 (+++) Configure the USARTx/UARTx interrupt priority. 00031 (+++) Enable the NVIC USARTx/UARTx IRQ handle. 00032 (+++) The specific IRDA interrupts (Transmission complete interrupt, 00033 RXNE interrupt and Error Interrupts) will be managed using the macros 00034 __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process. 00035 00036 (++) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA() 00037 and HAL_IRDA_Receive_DMA() APIs): 00038 (+++) Declare a DMA handle structure for the Tx/Rx channel. 00039 (+++) Enable the DMAx interface clock. 00040 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. 00041 (+++) Configure the DMA Tx/Rx channel. 00042 (+++) Associate the initialized DMA handle to the IRDA DMA Tx/Rx handle. 00043 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel. 00044 00045 (#) Program the Baud Rate, Word Length and Parity and Mode(Receiver/Transmitter), 00046 the normal or low power mode and the clock prescaler in the hirda handle Init structure. 00047 00048 (#) Initialize the IRDA registers by calling the HAL_IRDA_Init() API: 00049 (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) 00050 by calling the customized HAL_IRDA_MspInit() API. 00051 00052 -@@- The specific IRDA interrupts (Transmission complete interrupt, 00053 RXNE interrupt and Error Interrupts) will be managed using the macros 00054 __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process. 00055 00056 (#) Three operation modes are available within this driver : 00057 00058 *** Polling mode IO operation *** 00059 ================================= 00060 [..] 00061 (+) Send an amount of data in blocking mode using HAL_IRDA_Transmit() 00062 (+) Receive an amount of data in blocking mode using HAL_IRDA_Receive() 00063 00064 *** Interrupt mode IO operation *** 00065 =================================== 00066 [..] 00067 (+) Send an amount of data in non-blocking mode using HAL_IRDA_Transmit_IT() 00068 (+) At transmission end of transfer HAL_IRDA_TxCpltCallback() is executed and user can 00069 add his own code by customization of function pointer HAL_IRDA_TxCpltCallback() 00070 (+) Receive an amount of data in non-blocking mode using HAL_IRDA_Receive_IT() 00071 (+) At reception end of transfer HAL_IRDA_RxCpltCallback() is executed and user can 00072 add his own code by customization of function pointer HAL_IRDA_RxCpltCallback() 00073 (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can 00074 add his own code by customization of function pointer HAL_IRDA_ErrorCallback() 00075 00076 *** DMA mode IO operation *** 00077 ============================== 00078 [..] 00079 (+) Send an amount of data in non-blocking mode (DMA) using HAL_IRDA_Transmit_DMA() 00080 (+) At transmission half of transfer HAL_IRDA_TxHalfCpltCallback() is executed and user can 00081 add his own code by customization of function pointer HAL_IRDA_TxHalfCpltCallback() 00082 (+) At transmission end of transfer HAL_IRDA_TxCpltCallback() is executed and user can 00083 add his own code by customization of function pointer HAL_IRDA_TxCpltCallback() 00084 (+) Receive an amount of data in non-blocking mode (DMA) using HAL_IRDA_Receive_DMA() 00085 (+) At reception half of transfer HAL_IRDA_RxHalfCpltCallback() is executed and user can 00086 add his own code by customization of function pointer HAL_IRDA_RxHalfCpltCallback() 00087 (+) At reception end of transfer HAL_IRDA_RxCpltCallback() is executed and user can 00088 add his own code by customization of function pointer HAL_IRDA_RxCpltCallback() 00089 (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can 00090 add his own code by customization of function pointer HAL_IRDA_ErrorCallback() 00091 00092 *** IRDA HAL driver macros list *** 00093 ==================================== 00094 [..] 00095 Below the list of most used macros in IRDA HAL driver. 00096 00097 (+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral 00098 (+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral 00099 (+) __HAL_IRDA_GET_FLAG : Check whether the specified IRDA flag is set or not 00100 (+) __HAL_IRDA_CLEAR_FLAG : Clear the specified IRDA pending flag 00101 (+) __HAL_IRDA_ENABLE_IT: Enable the specified IRDA interrupt 00102 (+) __HAL_IRDA_DISABLE_IT: Disable the specified IRDA interrupt 00103 (+) __HAL_IRDA_GET_IT_SOURCE: Check whether or not the specified IRDA interrupt is enabled 00104 00105 [..] 00106 (@) You can refer to the IRDA HAL driver header file for more useful macros 00107 00108 ##### Callback registration ##### 00109 ================================== 00110 00111 [..] 00112 The compilation define USE_HAL_IRDA_REGISTER_CALLBACKS when set to 1 00113 allows the user to configure dynamically the driver callbacks. 00114 00115 [..] 00116 Use Function @ref HAL_IRDA_RegisterCallback() to register a user callback. 00117 Function @ref HAL_IRDA_RegisterCallback() allows to register following callbacks: 00118 (+) TxHalfCpltCallback : Tx Half Complete Callback. 00119 (+) TxCpltCallback : Tx Complete Callback. 00120 (+) RxHalfCpltCallback : Rx Half Complete Callback. 00121 (+) RxCpltCallback : Rx Complete Callback. 00122 (+) ErrorCallback : Error Callback. 00123 (+) AbortCpltCallback : Abort Complete Callback. 00124 (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback. 00125 (+) AbortReceiveCpltCallback : Abort Receive Complete Callback. 00126 (+) MspInitCallback : IRDA MspInit. 00127 (+) MspDeInitCallback : IRDA MspDeInit. 00128 This function takes as parameters the HAL peripheral handle, the Callback ID 00129 and a pointer to the user callback function. 00130 00131 [..] 00132 Use function @ref HAL_IRDA_UnRegisterCallback() to reset a callback to the default 00133 weak (surcharged) function. 00134 @ref HAL_IRDA_UnRegisterCallback() takes as parameters the HAL peripheral handle, 00135 and the Callback ID. 00136 This function allows to reset following callbacks: 00137 (+) TxHalfCpltCallback : Tx Half Complete Callback. 00138 (+) TxCpltCallback : Tx Complete Callback. 00139 (+) RxHalfCpltCallback : Rx Half Complete Callback. 00140 (+) RxCpltCallback : Rx Complete Callback. 00141 (+) ErrorCallback : Error Callback. 00142 (+) AbortCpltCallback : Abort Complete Callback. 00143 (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback. 00144 (+) AbortReceiveCpltCallback : Abort Receive Complete Callback. 00145 (+) MspInitCallback : IRDA MspInit. 00146 (+) MspDeInitCallback : IRDA MspDeInit. 00147 00148 [..] 00149 By default, after the @ref HAL_IRDA_Init() and when the state is HAL_IRDA_STATE_RESET 00150 all callbacks are set to the corresponding weak (surcharged) functions: 00151 examples @ref HAL_IRDA_TxCpltCallback(), @ref HAL_IRDA_RxHalfCpltCallback(). 00152 Exception done for MspInit and MspDeInit functions that are respectively 00153 reset to the legacy weak (surcharged) functions in the @ref HAL_IRDA_Init() 00154 and @ref HAL_IRDA_DeInit() only when these callbacks are null (not registered beforehand). 00155 If not, MspInit or MspDeInit are not null, the @ref HAL_IRDA_Init() and @ref HAL_IRDA_DeInit() 00156 keep and use the user MspInit/MspDeInit callbacks (registered beforehand). 00157 00158 [..] 00159 Callbacks can be registered/unregistered in HAL_IRDA_STATE_READY state only. 00160 Exception done MspInit/MspDeInit that can be registered/unregistered 00161 in HAL_IRDA_STATE_READY or HAL_IRDA_STATE_RESET state, thus registered (user) 00162 MspInit/DeInit callbacks can be used during the Init/DeInit. 00163 In that case first register the MspInit/MspDeInit user callbacks 00164 using @ref HAL_IRDA_RegisterCallback() before calling @ref HAL_IRDA_DeInit() 00165 or @ref HAL_IRDA_Init() function. 00166 00167 [..] 00168 When The compilation define USE_HAL_IRDA_REGISTER_CALLBACKS is set to 0 or 00169 not defined, the callback registration feature is not available 00170 and weak (surcharged) callbacks are used. 00171 00172 00173 @endverbatim 00174 ****************************************************************************** 00175 * @attention 00176 * 00177 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> 00178 * 00179 * Redistribution and use in source and binary forms, with or without modification, 00180 * are permitted provided that the following conditions are met: 00181 * 1. Redistributions of source code must retain the above copyright notice, 00182 * this list of conditions and the following disclaimer. 00183 * 2. Redistributions in binary form must reproduce the above copyright notice, 00184 * this list of conditions and the following disclaimer in the documentation 00185 * and/or other materials provided with the distribution. 00186 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00187 * may be used to endorse or promote products derived from this software 00188 * without specific prior written permission. 00189 * 00190 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00191 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00192 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00193 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00194 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00195 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00196 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00197 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00198 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00199 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00200 * 00201 ****************************************************************************** 00202 */ 00203 00204 /* Includes ------------------------------------------------------------------*/ 00205 #include "stm32l4xx_hal.h" 00206 00207 /** @addtogroup STM32L4xx_HAL_Driver 00208 * @{ 00209 */ 00210 00211 /** @defgroup IRDA IRDA 00212 * @brief HAL IRDA module driver 00213 * @{ 00214 */ 00215 00216 #ifdef HAL_IRDA_MODULE_ENABLED 00217 00218 /* Private typedef -----------------------------------------------------------*/ 00219 /* Private define ------------------------------------------------------------*/ 00220 /** @defgroup IRDA_Private_Constants IRDA Private Constants 00221 * @{ 00222 */ 00223 #define IRDA_TEACK_REACK_TIMEOUT 1000U /*!< IRDA TX or RX enable acknowledge time-out value */ 00224 00225 #define IRDA_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE \ 00226 | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE)) /*!< UART or USART CR1 fields of parameters set by IRDA_SetConfig API */ 00227 00228 #define USART_BRR_MIN 0x10U /*!< USART BRR minimum authorized value */ 00229 00230 #define USART_BRR_MAX 0x0000FFFFU /*!< USART BRR maximum authorized value */ 00231 /** 00232 * @} 00233 */ 00234 00235 /* Private macros ------------------------------------------------------------*/ 00236 /** @defgroup IRDA_Private_Macros IRDA Private Macros 00237 * @{ 00238 */ 00239 #if defined(USART_PRESC_PRESCALER) 00240 /** @brief BRR division operation to set BRR register in 16-bit oversampling mode. 00241 * @param __PCLK__ IRDA clock source. 00242 * @param __BAUD__ Baud rate set by the user. 00243 * @param __PRESCALER__ IRDA clock prescaler value. 00244 * @retval Division result 00245 */ 00246 #define IRDA_DIV_SAMPLING16(__PCLK__, __BAUD__, __PRESCALER__) ((((__PCLK__)/IRDAPrescTable[(__PRESCALER__)]) + ((__BAUD__)/2U)) / (__BAUD__)) 00247 #else 00248 /** @brief BRR division operation to set BRR register in 16-bit oversampling mode. 00249 * @param __PCLK__ IRDA clock source. 00250 * @param __BAUD__ Baud rate set by the user. 00251 * @retval Division result 00252 */ 00253 #define IRDA_DIV_SAMPLING16(__PCLK__, __BAUD__) (((__PCLK__) + ((__BAUD__)/2U)) / (__BAUD__)) 00254 #endif 00255 /** 00256 * @} 00257 */ 00258 00259 /* Private variables ---------------------------------------------------------*/ 00260 /** @defgroup IRDA_Private_Variables IRDA Private Variables 00261 * @{ 00262 */ 00263 #if defined(USART_PRESC_PRESCALER) 00264 static const uint16_t IRDAPrescTable[12] = {1, 2, 4, 6, 8, 10, 12, 16, 32, 64, 128, 256}; 00265 #else 00266 #endif 00267 /** 00268 * @} 00269 */ 00270 00271 /* Private function prototypes -----------------------------------------------*/ 00272 /** @addtogroup IRDA_Private_Functions 00273 * @{ 00274 */ 00275 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 00276 void IRDA_InitCallbacksToDefault(IRDA_HandleTypeDef *hirda); 00277 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ 00278 static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda); 00279 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda); 00280 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout); 00281 static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda); 00282 static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda); 00283 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma); 00284 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma); 00285 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma); 00286 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma); 00287 static void IRDA_DMAError(DMA_HandleTypeDef *hdma); 00288 static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma); 00289 static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma); 00290 static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma); 00291 static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma); 00292 static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma); 00293 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda); 00294 static void IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda); 00295 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda); 00296 /** 00297 * @} 00298 */ 00299 00300 /* Exported functions --------------------------------------------------------*/ 00301 00302 /** @defgroup IRDA_Exported_Functions IRDA Exported Functions 00303 * @{ 00304 */ 00305 00306 /** @defgroup IRDA_Exported_Functions_Group1 Initialization and de-initialization functions 00307 * @brief Initialization and Configuration functions 00308 * 00309 @verbatim 00310 ============================================================================== 00311 ##### Initialization and Configuration functions ##### 00312 ============================================================================== 00313 [..] 00314 This subsection provides a set of functions allowing to initialize the USARTx 00315 in asynchronous IRDA mode. 00316 (+) For the asynchronous mode only these parameters can be configured: 00317 (++) Baud Rate 00318 (++) Word Length 00319 (++) Parity: If the parity is enabled, then the MSB bit of the data written 00320 in the data register is transmitted but is changed by the parity bit. 00321 (++) Power mode 00322 (++) Prescaler setting 00323 (++) Receiver/transmitter modes 00324 00325 [..] 00326 The HAL_IRDA_Init() API follows the USART asynchronous configuration procedures 00327 (details for the procedures are available in reference manual). 00328 00329 @endverbatim 00330 00331 Depending on the frame length defined by the M1 and M0 bits (7-bit, 00332 8-bit or 9-bit), the possible IRDA frame formats are listed in the 00333 following table. 00334 00335 Table 1. IRDA frame format. 00336 +-----------------------------------------------------------------------+ 00337 | M1 bit | M0 bit | PCE bit | IRDA frame | 00338 |---------|---------|-----------|---------------------------------------| 00339 | 0 | 0 | 0 | | SB | 8 bit data | STB | | 00340 |---------|---------|-----------|---------------------------------------| 00341 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | 00342 |---------|---------|-----------|---------------------------------------| 00343 | 0 | 1 | 0 | | SB | 9 bit data | STB | | 00344 |---------|---------|-----------|---------------------------------------| 00345 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | 00346 |---------|---------|-----------|---------------------------------------| 00347 | 1 | 0 | 0 | | SB | 7 bit data | STB | | 00348 |---------|---------|-----------|---------------------------------------| 00349 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | 00350 +-----------------------------------------------------------------------+ 00351 00352 * @{ 00353 */ 00354 00355 /** 00356 * @brief Initialize the IRDA mode according to the specified 00357 * parameters in the IRDA_InitTypeDef and initialize the associated handle. 00358 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 00359 * the configuration information for the specified IRDA module. 00360 * @retval HAL status 00361 */ 00362 HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda) 00363 { 00364 /* Check the IRDA handle allocation */ 00365 if (hirda == NULL) 00366 { 00367 return HAL_ERROR; 00368 } 00369 00370 /* Check the USART/UART associated to the IRDA handle */ 00371 assert_param(IS_IRDA_INSTANCE(hirda->Instance)); 00372 00373 if (hirda->gState == HAL_IRDA_STATE_RESET) 00374 { 00375 /* Allocate lock resource and initialize it */ 00376 hirda->Lock = HAL_UNLOCKED; 00377 00378 #if USE_HAL_IRDA_REGISTER_CALLBACKS == 1 00379 IRDA_InitCallbacksToDefault(hirda); 00380 00381 if (hirda->MspInitCallback == NULL) 00382 { 00383 hirda->MspInitCallback = HAL_IRDA_MspInit; 00384 } 00385 00386 /* Init the low level hardware */ 00387 hirda->MspInitCallback(hirda); 00388 #else 00389 /* Init the low level hardware : GPIO, CLOCK */ 00390 HAL_IRDA_MspInit(hirda); 00391 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ 00392 } 00393 00394 hirda->gState = HAL_IRDA_STATE_BUSY; 00395 00396 /* Disable the Peripheral to update the configuration registers */ 00397 __HAL_IRDA_DISABLE(hirda); 00398 00399 /* Set the IRDA Communication parameters */ 00400 if (IRDA_SetConfig(hirda) == HAL_ERROR) 00401 { 00402 return HAL_ERROR; 00403 } 00404 00405 /* In IRDA mode, the following bits must be kept cleared: 00406 - LINEN, STOP and CLKEN bits in the USART_CR2 register, 00407 - SCEN and HDSEL bits in the USART_CR3 register.*/ 00408 CLEAR_BIT(hirda->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP)); 00409 CLEAR_BIT(hirda->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL)); 00410 00411 /* set the UART/USART in IRDA mode */ 00412 hirda->Instance->CR3 |= USART_CR3_IREN; 00413 00414 /* Enable the Peripheral */ 00415 __HAL_IRDA_ENABLE(hirda); 00416 00417 /* TEACK and/or REACK to check before moving hirda->gState and hirda->RxState to Ready */ 00418 return (IRDA_CheckIdleState(hirda)); 00419 } 00420 00421 /** 00422 * @brief DeInitialize the IRDA peripheral. 00423 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 00424 * the configuration information for the specified IRDA module. 00425 * @retval HAL status 00426 */ 00427 HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda) 00428 { 00429 /* Check the IRDA handle allocation */ 00430 if (hirda == NULL) 00431 { 00432 return HAL_ERROR; 00433 } 00434 00435 /* Check the USART/UART associated to the IRDA handle */ 00436 assert_param(IS_IRDA_INSTANCE(hirda->Instance)); 00437 00438 hirda->gState = HAL_IRDA_STATE_BUSY; 00439 00440 /* DeInit the low level hardware */ 00441 #if USE_HAL_IRDA_REGISTER_CALLBACKS == 1 00442 if (hirda->MspDeInitCallback == NULL) 00443 { 00444 hirda->MspDeInitCallback = HAL_IRDA_MspDeInit; 00445 } 00446 /* DeInit the low level hardware */ 00447 hirda->MspDeInitCallback(hirda); 00448 #else 00449 HAL_IRDA_MspDeInit(hirda); 00450 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ 00451 /* Disable the Peripheral */ 00452 __HAL_IRDA_DISABLE(hirda); 00453 00454 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 00455 hirda->gState = HAL_IRDA_STATE_RESET; 00456 hirda->RxState = HAL_IRDA_STATE_RESET; 00457 00458 /* Process Unlock */ 00459 __HAL_UNLOCK(hirda); 00460 00461 return HAL_OK; 00462 } 00463 00464 /** 00465 * @brief Initialize the IRDA MSP. 00466 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 00467 * the configuration information for the specified IRDA module. 00468 * @retval None 00469 */ 00470 __weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda) 00471 { 00472 /* Prevent unused argument(s) compilation warning */ 00473 UNUSED(hirda); 00474 00475 /* NOTE: This function should not be modified, when the callback is needed, 00476 the HAL_IRDA_MspInit can be implemented in the user file 00477 */ 00478 } 00479 00480 /** 00481 * @brief DeInitialize the IRDA MSP. 00482 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 00483 * the configuration information for the specified IRDA module. 00484 * @retval None 00485 */ 00486 __weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda) 00487 { 00488 /* Prevent unused argument(s) compilation warning */ 00489 UNUSED(hirda); 00490 00491 /* NOTE: This function should not be modified, when the callback is needed, 00492 the HAL_IRDA_MspDeInit can be implemented in the user file 00493 */ 00494 } 00495 00496 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 00497 /** 00498 * @brief Register a User IRDA Callback 00499 * To be used instead of the weak predefined callback 00500 * @param hirda irda handle 00501 * @param CallbackID ID of the callback to be registered 00502 * This parameter can be one of the following values: 00503 * @arg @ref HAL_IRDA_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID 00504 * @arg @ref HAL_IRDA_TX_COMPLETE_CB_ID Tx Complete Callback ID 00505 * @arg @ref HAL_IRDA_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID 00506 * @arg @ref HAL_IRDA_RX_COMPLETE_CB_ID Rx Complete Callback ID 00507 * @arg @ref HAL_IRDA_ERROR_CB_ID Error Callback ID 00508 * @arg @ref HAL_IRDA_ABORT_COMPLETE_CB_ID Abort Complete Callback ID 00509 * @arg @ref HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID 00510 * @arg @ref HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID 00511 * @arg @ref HAL_IRDA_MSPINIT_CB_ID MspInit Callback ID 00512 * @arg @ref HAL_IRDA_MSPDEINIT_CB_ID MspDeInit Callback ID 00513 * @param pCallback pointer to the Callback function 00514 * @retval HAL status 00515 */ 00516 HAL_StatusTypeDef HAL_IRDA_RegisterCallback(IRDA_HandleTypeDef *hirda, HAL_IRDA_CallbackIDTypeDef CallbackID, pIRDA_CallbackTypeDef pCallback) 00517 { 00518 HAL_StatusTypeDef status = HAL_OK; 00519 00520 if (pCallback == NULL) 00521 { 00522 /* Update the error code */ 00523 hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK; 00524 00525 return HAL_ERROR; 00526 } 00527 /* Process locked */ 00528 __HAL_LOCK(hirda); 00529 00530 if (hirda->gState == HAL_IRDA_STATE_READY) 00531 { 00532 switch (CallbackID) 00533 { 00534 case HAL_IRDA_TX_HALFCOMPLETE_CB_ID : 00535 hirda->TxHalfCpltCallback = pCallback; 00536 break; 00537 00538 case HAL_IRDA_TX_COMPLETE_CB_ID : 00539 hirda->TxCpltCallback = pCallback; 00540 break; 00541 00542 case HAL_IRDA_RX_HALFCOMPLETE_CB_ID : 00543 hirda->RxHalfCpltCallback = pCallback; 00544 break; 00545 00546 case HAL_IRDA_RX_COMPLETE_CB_ID : 00547 hirda->RxCpltCallback = pCallback; 00548 break; 00549 00550 case HAL_IRDA_ERROR_CB_ID : 00551 hirda->ErrorCallback = pCallback; 00552 break; 00553 00554 case HAL_IRDA_ABORT_COMPLETE_CB_ID : 00555 hirda->AbortCpltCallback = pCallback; 00556 break; 00557 00558 case HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID : 00559 hirda->AbortTransmitCpltCallback = pCallback; 00560 break; 00561 00562 case HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID : 00563 hirda->AbortReceiveCpltCallback = pCallback; 00564 break; 00565 00566 case HAL_IRDA_MSPINIT_CB_ID : 00567 hirda->MspInitCallback = pCallback; 00568 break; 00569 00570 case HAL_IRDA_MSPDEINIT_CB_ID : 00571 hirda->MspDeInitCallback = pCallback; 00572 break; 00573 00574 default : 00575 /* Update the error code */ 00576 hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK; 00577 00578 /* Return error status */ 00579 status = HAL_ERROR; 00580 break; 00581 } 00582 } 00583 else if (hirda->gState == HAL_IRDA_STATE_RESET) 00584 { 00585 switch (CallbackID) 00586 { 00587 case HAL_IRDA_MSPINIT_CB_ID : 00588 hirda->MspInitCallback = pCallback; 00589 break; 00590 00591 case HAL_IRDA_MSPDEINIT_CB_ID : 00592 hirda->MspDeInitCallback = pCallback; 00593 break; 00594 00595 default : 00596 /* Update the error code */ 00597 hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK; 00598 00599 /* Return error status */ 00600 status = HAL_ERROR; 00601 break; 00602 } 00603 } 00604 else 00605 { 00606 /* Update the error code */ 00607 hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK; 00608 00609 /* Return error status */ 00610 status = HAL_ERROR; 00611 } 00612 00613 /* Release Lock */ 00614 __HAL_UNLOCK(hirda); 00615 00616 return status; 00617 } 00618 00619 /** 00620 * @brief Unregister an IRDA callback 00621 * IRDA callback is redirected to the weak predefined callback 00622 * @param hirda irda handle 00623 * @param CallbackID ID of the callback to be unregistered 00624 * This parameter can be one of the following values: 00625 * @arg @ref HAL_IRDA_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID 00626 * @arg @ref HAL_IRDA_TX_COMPLETE_CB_ID Tx Complete Callback ID 00627 * @arg @ref HAL_IRDA_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID 00628 * @arg @ref HAL_IRDA_RX_COMPLETE_CB_ID Rx Complete Callback ID 00629 * @arg @ref HAL_IRDA_ERROR_CB_ID Error Callback ID 00630 * @arg @ref HAL_IRDA_ABORT_COMPLETE_CB_ID Abort Complete Callback ID 00631 * @arg @ref HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID 00632 * @arg @ref HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID 00633 * @arg @ref HAL_IRDA_MSPINIT_CB_ID MspInit Callback ID 00634 * @arg @ref HAL_IRDA_MSPDEINIT_CB_ID MspDeInit Callback ID 00635 * @retval HAL status 00636 */ 00637 HAL_StatusTypeDef HAL_IRDA_UnRegisterCallback(IRDA_HandleTypeDef *hirda, HAL_IRDA_CallbackIDTypeDef CallbackID) 00638 { 00639 HAL_StatusTypeDef status = HAL_OK; 00640 00641 /* Process locked */ 00642 __HAL_LOCK(hirda); 00643 00644 if (HAL_IRDA_STATE_READY == hirda->gState) 00645 { 00646 switch (CallbackID) 00647 { 00648 case HAL_IRDA_TX_HALFCOMPLETE_CB_ID : 00649 hirda->TxHalfCpltCallback = HAL_IRDA_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ 00650 break; 00651 00652 case HAL_IRDA_TX_COMPLETE_CB_ID : 00653 hirda->TxCpltCallback = HAL_IRDA_TxCpltCallback; /* Legacy weak TxCpltCallback */ 00654 break; 00655 00656 case HAL_IRDA_RX_HALFCOMPLETE_CB_ID : 00657 hirda->RxHalfCpltCallback = HAL_IRDA_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ 00658 break; 00659 00660 case HAL_IRDA_RX_COMPLETE_CB_ID : 00661 hirda->RxCpltCallback = HAL_IRDA_RxCpltCallback; /* Legacy weak RxCpltCallback */ 00662 break; 00663 00664 case HAL_IRDA_ERROR_CB_ID : 00665 hirda->ErrorCallback = HAL_IRDA_ErrorCallback; /* Legacy weak ErrorCallback */ 00666 break; 00667 00668 case HAL_IRDA_ABORT_COMPLETE_CB_ID : 00669 hirda->AbortCpltCallback = HAL_IRDA_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ 00670 break; 00671 00672 case HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID : 00673 hirda->AbortTransmitCpltCallback = HAL_IRDA_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */ 00674 break; 00675 00676 case HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID : 00677 hirda->AbortReceiveCpltCallback = HAL_IRDA_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */ 00678 break; 00679 00680 case HAL_IRDA_MSPINIT_CB_ID : 00681 hirda->MspInitCallback = HAL_IRDA_MspInit; /* Legacy weak MspInitCallback */ 00682 break; 00683 00684 case HAL_IRDA_MSPDEINIT_CB_ID : 00685 hirda->MspDeInitCallback = HAL_IRDA_MspDeInit; /* Legacy weak MspDeInitCallback */ 00686 break; 00687 00688 default : 00689 /* Update the error code */ 00690 hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK; 00691 00692 /* Return error status */ 00693 status = HAL_ERROR; 00694 break; 00695 } 00696 } 00697 else if (HAL_IRDA_STATE_RESET == hirda->gState) 00698 { 00699 switch (CallbackID) 00700 { 00701 case HAL_IRDA_MSPINIT_CB_ID : 00702 hirda->MspInitCallback = HAL_IRDA_MspInit; 00703 break; 00704 00705 case HAL_IRDA_MSPDEINIT_CB_ID : 00706 hirda->MspDeInitCallback = HAL_IRDA_MspDeInit; 00707 break; 00708 00709 default : 00710 /* Update the error code */ 00711 hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK; 00712 00713 /* Return error status */ 00714 status = HAL_ERROR; 00715 break; 00716 } 00717 } 00718 else 00719 { 00720 /* Update the error code */ 00721 hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK; 00722 00723 /* Return error status */ 00724 status = HAL_ERROR; 00725 } 00726 00727 /* Release Lock */ 00728 __HAL_UNLOCK(hirda); 00729 00730 return status; 00731 } 00732 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ 00733 00734 /** 00735 * @} 00736 */ 00737 00738 /** @defgroup IRDA_Exported_Functions_Group2 IO operation functions 00739 * @brief IRDA Transmit and Receive functions 00740 * 00741 @verbatim 00742 =============================================================================== 00743 ##### IO operation functions ##### 00744 =============================================================================== 00745 [..] 00746 This subsection provides a set of functions allowing to manage the IRDA data transfers. 00747 00748 [..] 00749 IrDA is a half duplex communication protocol. If the Transmitter is busy, any data 00750 on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver 00751 is busy, data on the TX from the USART to IrDA will not be encoded by IrDA. 00752 While receiving data, transmission should be avoided as the data to be transmitted 00753 could be corrupted. 00754 00755 (#) There are two modes of transfer: 00756 (++) Blocking mode: the communication is performed in polling mode. 00757 The HAL status of all data processing is returned by the same function 00758 after finishing transfer. 00759 (++) Non-Blocking mode: the communication is performed using Interrupts 00760 or DMA, these API's return the HAL status. 00761 The end of the data processing will be indicated through the 00762 dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when 00763 using DMA mode. 00764 The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks 00765 will be executed respectively at the end of the Transmit or Receive process 00766 The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected 00767 00768 (#) Blocking mode APIs are : 00769 (++) HAL_IRDA_Transmit() 00770 (++) HAL_IRDA_Receive() 00771 00772 (#) Non Blocking mode APIs with Interrupt are : 00773 (++) HAL_IRDA_Transmit_IT() 00774 (++) HAL_IRDA_Receive_IT() 00775 (++) HAL_IRDA_IRQHandler() 00776 00777 (#) Non Blocking mode functions with DMA are : 00778 (++) HAL_IRDA_Transmit_DMA() 00779 (++) HAL_IRDA_Receive_DMA() 00780 (++) HAL_IRDA_DMAPause() 00781 (++) HAL_IRDA_DMAResume() 00782 (++) HAL_IRDA_DMAStop() 00783 00784 (#) A set of Transfer Complete Callbacks are provided in Non Blocking mode: 00785 (++) HAL_IRDA_TxHalfCpltCallback() 00786 (++) HAL_IRDA_TxCpltCallback() 00787 (++) HAL_IRDA_RxHalfCpltCallback() 00788 (++) HAL_IRDA_RxCpltCallback() 00789 (++) HAL_IRDA_ErrorCallback() 00790 00791 (#) Non-Blocking mode transfers could be aborted using Abort API's : 00792 (+) HAL_IRDA_Abort() 00793 (+) HAL_IRDA_AbortTransmit() 00794 (+) HAL_IRDA_AbortReceive() 00795 (+) HAL_IRDA_Abort_IT() 00796 (+) HAL_IRDA_AbortTransmit_IT() 00797 (+) HAL_IRDA_AbortReceive_IT() 00798 00799 (#) For Abort services based on interrupts (HAL_IRDA_Abortxxx_IT), a set of Abort Complete Callbacks are provided: 00800 (+) HAL_IRDA_AbortCpltCallback() 00801 (+) HAL_IRDA_AbortTransmitCpltCallback() 00802 (+) HAL_IRDA_AbortReceiveCpltCallback() 00803 00804 (#) In Non-Blocking mode transfers, possible errors are split into 2 categories. 00805 Errors are handled as follows : 00806 (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is 00807 to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception . 00808 Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type, 00809 and HAL_IRDA_ErrorCallback() user callback is executed. Transfer is kept ongoing on IRDA side. 00810 If user wants to abort it, Abort services should be called by user. 00811 (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted. 00812 This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode. 00813 Error code is set to allow user to identify error type, and HAL_IRDA_ErrorCallback() user callback is executed. 00814 00815 @endverbatim 00816 * @{ 00817 */ 00818 00819 /** 00820 * @brief Send an amount of data in blocking mode. 00821 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 00822 * the configuration information for the specified IRDA module. 00823 * @param pData Pointer to data buffer. 00824 * @param Size Amount of data to be sent. 00825 * @param Timeout Specify timeout value. 00826 * @retval HAL status 00827 */ 00828 HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout) 00829 { 00830 uint16_t *tmp; 00831 uint32_t tickstart = 0U; 00832 00833 /* Check that a Tx process is not already ongoing */ 00834 if (hirda->gState == HAL_IRDA_STATE_READY) 00835 { 00836 if ((pData == NULL) || (Size == 0U)) 00837 { 00838 return HAL_ERROR; 00839 } 00840 00841 /* Process Locked */ 00842 __HAL_LOCK(hirda); 00843 00844 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 00845 hirda->gState = HAL_IRDA_STATE_BUSY_TX; 00846 00847 /* Init tickstart for timeout managment*/ 00848 tickstart = HAL_GetTick(); 00849 00850 hirda->TxXferSize = Size; 00851 hirda->TxXferCount = Size; 00852 while (hirda->TxXferCount > 0U) 00853 { 00854 hirda->TxXferCount--; 00855 00856 if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) 00857 { 00858 return HAL_TIMEOUT; 00859 } 00860 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) 00861 { 00862 tmp = (uint16_t *) pData; 00863 hirda->Instance->TDR = (*tmp & (uint16_t)0x01FF); 00864 pData += 2U; 00865 } 00866 else 00867 { 00868 hirda->Instance->TDR = (*pData++ & (uint8_t)0xFF); 00869 } 00870 } 00871 00872 if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) 00873 { 00874 return HAL_TIMEOUT; 00875 } 00876 00877 /* At end of Tx process, restore hirda->gState to Ready */ 00878 hirda->gState = HAL_IRDA_STATE_READY; 00879 00880 /* Process Unlocked */ 00881 __HAL_UNLOCK(hirda); 00882 00883 return HAL_OK; 00884 } 00885 else 00886 { 00887 return HAL_BUSY; 00888 } 00889 } 00890 00891 /** 00892 * @brief Receive an amount of data in blocking mode. 00893 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 00894 * the configuration information for the specified IRDA module. 00895 * @param pData Pointer to data buffer. 00896 * @param Size Amount of data to be received. 00897 * @param Timeout Specify timeout value. 00898 * @retval HAL status 00899 */ 00900 HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout) 00901 { 00902 uint16_t *tmp; 00903 uint16_t uhMask; 00904 uint32_t tickstart = 0U; 00905 00906 /* Check that a Rx process is not already ongoing */ 00907 if (hirda->RxState == HAL_IRDA_STATE_READY) 00908 { 00909 if ((pData == NULL) || (Size == 0U)) 00910 { 00911 return HAL_ERROR; 00912 } 00913 00914 /* Process Locked */ 00915 __HAL_LOCK(hirda); 00916 00917 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 00918 hirda->RxState = HAL_IRDA_STATE_BUSY_RX; 00919 00920 /* Init tickstart for timeout managment*/ 00921 tickstart = HAL_GetTick(); 00922 00923 hirda->RxXferSize = Size; 00924 hirda->RxXferCount = Size; 00925 00926 /* Computation of the mask to apply to RDR register 00927 of the UART associated to the IRDA */ 00928 IRDA_MASK_COMPUTATION(hirda); 00929 uhMask = hirda->Mask; 00930 00931 /* Check data remaining to be received */ 00932 while (hirda->RxXferCount > 0U) 00933 { 00934 hirda->RxXferCount--; 00935 00936 if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) 00937 { 00938 return HAL_TIMEOUT; 00939 } 00940 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) 00941 { 00942 tmp = (uint16_t *) pData ; 00943 *tmp = (uint16_t)(hirda->Instance->RDR & uhMask); 00944 pData += 2U; 00945 } 00946 else 00947 { 00948 *pData++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask); 00949 } 00950 } 00951 00952 /* At end of Rx process, restore hirda->RxState to Ready */ 00953 hirda->RxState = HAL_IRDA_STATE_READY; 00954 00955 /* Process Unlocked */ 00956 __HAL_UNLOCK(hirda); 00957 00958 return HAL_OK; 00959 } 00960 else 00961 { 00962 return HAL_BUSY; 00963 } 00964 } 00965 00966 /** 00967 * @brief Send an amount of data in interrupt mode. 00968 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 00969 * the configuration information for the specified IRDA module. 00970 * @param pData Pointer to data buffer. 00971 * @param Size Amount of data to be sent. 00972 * @retval HAL status 00973 */ 00974 HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) 00975 { 00976 /* Check that a Tx process is not already ongoing */ 00977 if (hirda->gState == HAL_IRDA_STATE_READY) 00978 { 00979 if ((pData == NULL) || (Size == 0U)) 00980 { 00981 return HAL_ERROR; 00982 } 00983 00984 /* Process Locked */ 00985 __HAL_LOCK(hirda); 00986 00987 hirda->pTxBuffPtr = pData; 00988 hirda->TxXferSize = Size; 00989 hirda->TxXferCount = Size; 00990 00991 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 00992 hirda->gState = HAL_IRDA_STATE_BUSY_TX; 00993 00994 /* Process Unlocked */ 00995 __HAL_UNLOCK(hirda); 00996 00997 /* Enable the IRDA Transmit Data Register Empty Interrupt */ 00998 #if defined(USART_CR1_FIFOEN) 00999 SET_BIT(hirda->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); 01000 #else 01001 SET_BIT(hirda->Instance->CR1, USART_CR1_TXEIE); 01002 #endif 01003 01004 return HAL_OK; 01005 } 01006 else 01007 { 01008 return HAL_BUSY; 01009 } 01010 } 01011 01012 /** 01013 * @brief Receive an amount of data in interrupt mode. 01014 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 01015 * the configuration information for the specified IRDA module. 01016 * @param pData Pointer to data buffer. 01017 * @param Size Amount of data to be received. 01018 * @retval HAL status 01019 */ 01020 HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) 01021 { 01022 /* Check that a Rx process is not already ongoing */ 01023 if (hirda->RxState == HAL_IRDA_STATE_READY) 01024 { 01025 if ((pData == NULL) || (Size == 0U)) 01026 { 01027 return HAL_ERROR; 01028 } 01029 01030 /* Process Locked */ 01031 __HAL_LOCK(hirda); 01032 01033 hirda->pRxBuffPtr = pData; 01034 hirda->RxXferSize = Size; 01035 hirda->RxXferCount = Size; 01036 01037 /* Computation of the mask to apply to the RDR register 01038 of the UART associated to the IRDA */ 01039 IRDA_MASK_COMPUTATION(hirda); 01040 01041 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 01042 hirda->RxState = HAL_IRDA_STATE_BUSY_RX; 01043 01044 /* Process Unlocked */ 01045 __HAL_UNLOCK(hirda); 01046 01047 /* Enable the IRDA Parity Error and Data Register not empty Interrupts */ 01048 #if defined(USART_CR1_FIFOEN) 01049 SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE); 01050 #else 01051 SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE); 01052 #endif 01053 01054 /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ 01055 SET_BIT(hirda->Instance->CR3, USART_CR3_EIE); 01056 01057 return HAL_OK; 01058 } 01059 else 01060 { 01061 return HAL_BUSY; 01062 } 01063 } 01064 01065 /** 01066 * @brief Send an amount of data in DMA mode. 01067 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 01068 * the configuration information for the specified IRDA module. 01069 * @param pData pointer to data buffer. 01070 * @param Size amount of data to be sent. 01071 * @retval HAL status 01072 */ 01073 HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) 01074 { 01075 /* Check that a Tx process is not already ongoing */ 01076 if (hirda->gState == HAL_IRDA_STATE_READY) 01077 { 01078 if ((pData == NULL) || (Size == 0U)) 01079 { 01080 return HAL_ERROR; 01081 } 01082 01083 /* Process Locked */ 01084 __HAL_LOCK(hirda); 01085 01086 hirda->pTxBuffPtr = pData; 01087 hirda->TxXferSize = Size; 01088 hirda->TxXferCount = Size; 01089 01090 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 01091 hirda->gState = HAL_IRDA_STATE_BUSY_TX; 01092 01093 /* Set the IRDA DMA transfer complete callback */ 01094 hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt; 01095 01096 /* Set the IRDA DMA half transfer complete callback */ 01097 hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt; 01098 01099 /* Set the DMA error callback */ 01100 hirda->hdmatx->XferErrorCallback = IRDA_DMAError; 01101 01102 /* Set the DMA abort callback */ 01103 hirda->hdmatx->XferAbortCallback = NULL; 01104 01105 /* Enable the IRDA transmit DMA channel */ 01106 HAL_DMA_Start_IT(hirda->hdmatx, (uint32_t)hirda->pTxBuffPtr, (uint32_t)&hirda->Instance->TDR, Size); 01107 01108 /* Clear the TC flag in the ICR register */ 01109 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_TCF); 01110 01111 /* Process Unlocked */ 01112 __HAL_UNLOCK(hirda); 01113 01114 /* Enable the DMA transfer for transmit request by setting the DMAT bit 01115 in the USART CR3 register */ 01116 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT); 01117 01118 return HAL_OK; 01119 } 01120 else 01121 { 01122 return HAL_BUSY; 01123 } 01124 } 01125 01126 /** 01127 * @brief Receive an amount of data in DMA mode. 01128 * @note When the IRDA parity is enabled (PCE = 1), the received data contains 01129 * the parity bit (MSB position). 01130 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 01131 * the configuration information for the specified IRDA module. 01132 * @param pData Pointer to data buffer. 01133 * @param Size Amount of data to be received. 01134 * @retval HAL status 01135 */ 01136 HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) 01137 { 01138 /* Check that a Rx process is not already ongoing */ 01139 if (hirda->RxState == HAL_IRDA_STATE_READY) 01140 { 01141 if ((pData == NULL) || (Size == 0U)) 01142 { 01143 return HAL_ERROR; 01144 } 01145 01146 /* Process Locked */ 01147 __HAL_LOCK(hirda); 01148 01149 hirda->pRxBuffPtr = pData; 01150 hirda->RxXferSize = Size; 01151 01152 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 01153 hirda->RxState = HAL_IRDA_STATE_BUSY_RX; 01154 01155 /* Set the IRDA DMA transfer complete callback */ 01156 hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt; 01157 01158 /* Set the IRDA DMA half transfer complete callback */ 01159 hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt; 01160 01161 /* Set the DMA error callback */ 01162 hirda->hdmarx->XferErrorCallback = IRDA_DMAError; 01163 01164 /* Set the DMA abort callback */ 01165 hirda->hdmarx->XferAbortCallback = NULL; 01166 01167 /* Enable the DMA channel */ 01168 HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->RDR, (uint32_t)hirda->pRxBuffPtr, Size); 01169 01170 /* Process Unlocked */ 01171 __HAL_UNLOCK(hirda); 01172 01173 /* Enable the UART Parity Error Interrupt */ 01174 SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE); 01175 01176 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ 01177 SET_BIT(hirda->Instance->CR3, USART_CR3_EIE); 01178 01179 /* Enable the DMA transfer for the receiver request by setting the DMAR bit 01180 in the USART CR3 register */ 01181 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR); 01182 01183 return HAL_OK; 01184 } 01185 else 01186 { 01187 return HAL_BUSY; 01188 } 01189 } 01190 01191 01192 /** 01193 * @brief Pause the DMA Transfer. 01194 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 01195 * the configuration information for the specified IRDA module. 01196 * @retval HAL status 01197 */ 01198 HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda) 01199 { 01200 /* Process Locked */ 01201 __HAL_LOCK(hirda); 01202 01203 if ((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && 01204 (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))) 01205 { 01206 /* Disable the IRDA DMA Tx request */ 01207 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); 01208 } 01209 if ((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && 01210 (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))) 01211 { 01212 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ 01213 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE); 01214 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); 01215 01216 /* Disable the IRDA DMA Rx request */ 01217 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); 01218 } 01219 01220 /* Process Unlocked */ 01221 __HAL_UNLOCK(hirda); 01222 01223 return HAL_OK; 01224 } 01225 01226 /** 01227 * @brief Resume the DMA Transfer. 01228 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 01229 * the configuration information for the specified UART module. 01230 * @retval HAL status 01231 */ 01232 HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda) 01233 { 01234 /* Process Locked */ 01235 __HAL_LOCK(hirda); 01236 01237 if (hirda->gState == HAL_IRDA_STATE_BUSY_TX) 01238 { 01239 /* Enable the IRDA DMA Tx request */ 01240 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT); 01241 } 01242 if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX) 01243 { 01244 /* Clear the Overrun flag before resuming the Rx transfer*/ 01245 __HAL_IRDA_CLEAR_OREFLAG(hirda); 01246 01247 /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */ 01248 SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE); 01249 SET_BIT(hirda->Instance->CR3, USART_CR3_EIE); 01250 01251 /* Enable the IRDA DMA Rx request */ 01252 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR); 01253 } 01254 01255 /* Process Unlocked */ 01256 __HAL_UNLOCK(hirda); 01257 01258 return HAL_OK; 01259 } 01260 01261 /** 01262 * @brief Stop the DMA Transfer. 01263 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 01264 * the configuration information for the specified UART module. 01265 * @retval HAL status 01266 */ 01267 HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda) 01268 { 01269 /* The Lock is not implemented on this API to allow the user application 01270 to call the HAL IRDA API under callbacks HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback() / 01271 HAL_IRDA_TxHalfCpltCallback / HAL_IRDA_RxHalfCpltCallback: 01272 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete 01273 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of 01274 the stream and the corresponding call back is executed. */ 01275 01276 /* Stop IRDA DMA Tx request if ongoing */ 01277 if ((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && 01278 (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))) 01279 { 01280 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); 01281 01282 /* Abort the IRDA DMA Tx channel */ 01283 if (hirda->hdmatx != NULL) 01284 { 01285 HAL_DMA_Abort(hirda->hdmatx); 01286 } 01287 01288 IRDA_EndTxTransfer(hirda); 01289 } 01290 01291 /* Stop IRDA DMA Rx request if ongoing */ 01292 if ((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && 01293 (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))) 01294 { 01295 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); 01296 01297 /* Abort the IRDA DMA Rx channel */ 01298 if (hirda->hdmarx != NULL) 01299 { 01300 HAL_DMA_Abort(hirda->hdmarx); 01301 } 01302 01303 IRDA_EndRxTransfer(hirda); 01304 } 01305 01306 return HAL_OK; 01307 } 01308 01309 /** 01310 * @brief Abort ongoing transfers (blocking mode). 01311 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 01312 * the configuration information for the specified UART module. 01313 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. 01314 * This procedure performs following operations : 01315 * - Disable IRDA Interrupts (Tx and Rx) 01316 * - Disable the DMA transfer in the peripheral register (if enabled) 01317 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) 01318 * - Set handle State to READY 01319 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. 01320 * @retval HAL status 01321 */ 01322 HAL_StatusTypeDef HAL_IRDA_Abort(IRDA_HandleTypeDef *hirda) 01323 { 01324 /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ 01325 #if defined(USART_CR1_FIFOEN) 01326 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); 01327 #else 01328 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); 01329 #endif 01330 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); 01331 01332 /* Disable the IRDA DMA Tx request if enabled */ 01333 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) 01334 { 01335 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); 01336 01337 /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */ 01338 if (hirda->hdmatx != NULL) 01339 { 01340 /* Set the IRDA DMA Abort callback to Null. 01341 No call back execution at end of DMA abort procedure */ 01342 hirda->hdmatx->XferAbortCallback = NULL; 01343 01344 HAL_DMA_Abort(hirda->hdmatx); 01345 } 01346 } 01347 01348 /* Disable the IRDA DMA Rx request if enabled */ 01349 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) 01350 { 01351 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); 01352 01353 /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */ 01354 if (hirda->hdmarx != NULL) 01355 { 01356 /* Set the IRDA DMA Abort callback to Null. 01357 No call back execution at end of DMA abort procedure */ 01358 hirda->hdmarx->XferAbortCallback = NULL; 01359 01360 HAL_DMA_Abort(hirda->hdmarx); 01361 } 01362 } 01363 01364 /* Reset Tx and Rx transfer counters */ 01365 hirda->TxXferCount = 0U; 01366 hirda->RxXferCount = 0U; 01367 01368 /* Clear the Error flags in the ICR register */ 01369 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); 01370 01371 /* Restore hirda->gState and hirda->RxState to Ready */ 01372 hirda->gState = HAL_IRDA_STATE_READY; 01373 hirda->RxState = HAL_IRDA_STATE_READY; 01374 01375 /* Reset Handle ErrorCode to No Error */ 01376 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 01377 01378 return HAL_OK; 01379 } 01380 01381 /** 01382 * @brief Abort ongoing Transmit transfer (blocking mode). 01383 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 01384 * the configuration information for the specified UART module. 01385 * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. 01386 * This procedure performs following operations : 01387 * - Disable IRDA Interrupts (Tx) 01388 * - Disable the DMA transfer in the peripheral register (if enabled) 01389 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) 01390 * - Set handle State to READY 01391 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. 01392 * @retval HAL status 01393 */ 01394 HAL_StatusTypeDef HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef *hirda) 01395 { 01396 /* Disable TXEIE and TCIE interrupts */ 01397 #if defined(USART_CR1_FIFOEN) 01398 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); 01399 #else 01400 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); 01401 #endif 01402 01403 /* Disable the IRDA DMA Tx request if enabled */ 01404 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) 01405 { 01406 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); 01407 01408 /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */ 01409 if (hirda->hdmatx != NULL) 01410 { 01411 /* Set the IRDA DMA Abort callback to Null. 01412 No call back execution at end of DMA abort procedure */ 01413 hirda->hdmatx->XferAbortCallback = NULL; 01414 01415 HAL_DMA_Abort(hirda->hdmatx); 01416 } 01417 } 01418 01419 /* Reset Tx transfer counter */ 01420 hirda->TxXferCount = 0U; 01421 01422 /* Restore hirda->gState to Ready */ 01423 hirda->gState = HAL_IRDA_STATE_READY; 01424 01425 return HAL_OK; 01426 } 01427 01428 /** 01429 * @brief Abort ongoing Receive transfer (blocking mode). 01430 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 01431 * the configuration information for the specified UART module. 01432 * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. 01433 * This procedure performs following operations : 01434 * - Disable IRDA Interrupts (Rx) 01435 * - Disable the DMA transfer in the peripheral register (if enabled) 01436 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) 01437 * - Set handle State to READY 01438 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. 01439 * @retval HAL status 01440 */ 01441 HAL_StatusTypeDef HAL_IRDA_AbortReceive(IRDA_HandleTypeDef *hirda) 01442 { 01443 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ 01444 #if defined(USART_CR1_FIFOEN) 01445 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); 01446 #else 01447 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); 01448 #endif 01449 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); 01450 01451 /* Disable the IRDA DMA Rx request if enabled */ 01452 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) 01453 { 01454 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); 01455 01456 /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */ 01457 if (hirda->hdmarx != NULL) 01458 { 01459 /* Set the IRDA DMA Abort callback to Null. 01460 No call back execution at end of DMA abort procedure */ 01461 hirda->hdmarx->XferAbortCallback = NULL; 01462 01463 HAL_DMA_Abort(hirda->hdmarx); 01464 } 01465 } 01466 01467 /* Reset Rx transfer counter */ 01468 hirda->RxXferCount = 0U; 01469 01470 /* Clear the Error flags in the ICR register */ 01471 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); 01472 01473 /* Restore hirda->RxState to Ready */ 01474 hirda->RxState = HAL_IRDA_STATE_READY; 01475 01476 return HAL_OK; 01477 } 01478 01479 /** 01480 * @brief Abort ongoing transfers (Interrupt mode). 01481 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 01482 * the configuration information for the specified UART module. 01483 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. 01484 * This procedure performs following operations : 01485 * - Disable IRDA Interrupts (Tx and Rx) 01486 * - Disable the DMA transfer in the peripheral register (if enabled) 01487 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) 01488 * - Set handle State to READY 01489 * - At abort completion, call user abort complete callback 01490 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be 01491 * considered as completed only when user abort complete callback is executed (not when exiting function). 01492 * @retval HAL status 01493 */ 01494 HAL_StatusTypeDef HAL_IRDA_Abort_IT(IRDA_HandleTypeDef *hirda) 01495 { 01496 uint32_t abortcplt = 1U; 01497 01498 /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ 01499 #if defined(USART_CR1_FIFOEN) 01500 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); 01501 #else 01502 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); 01503 #endif 01504 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); 01505 01506 /* If DMA Tx and/or DMA Rx Handles are associated to IRDA Handle, DMA Abort complete callbacks should be initialised 01507 before any call to DMA Abort functions */ 01508 /* DMA Tx Handle is valid */ 01509 if (hirda->hdmatx != NULL) 01510 { 01511 /* Set DMA Abort Complete callback if IRDA DMA Tx request if enabled. 01512 Otherwise, set it to NULL */ 01513 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) 01514 { 01515 hirda->hdmatx->XferAbortCallback = IRDA_DMATxAbortCallback; 01516 } 01517 else 01518 { 01519 hirda->hdmatx->XferAbortCallback = NULL; 01520 } 01521 } 01522 /* DMA Rx Handle is valid */ 01523 if (hirda->hdmarx != NULL) 01524 { 01525 /* Set DMA Abort Complete callback if IRDA DMA Rx request if enabled. 01526 Otherwise, set it to NULL */ 01527 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) 01528 { 01529 hirda->hdmarx->XferAbortCallback = IRDA_DMARxAbortCallback; 01530 } 01531 else 01532 { 01533 hirda->hdmarx->XferAbortCallback = NULL; 01534 } 01535 } 01536 01537 /* Disable the IRDA DMA Tx request if enabled */ 01538 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) 01539 { 01540 /* Disable DMA Tx at UART level */ 01541 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); 01542 01543 /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */ 01544 if (hirda->hdmatx != NULL) 01545 { 01546 /* IRDA Tx DMA Abort callback has already been initialised : 01547 will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */ 01548 01549 /* Abort DMA TX */ 01550 if (HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK) 01551 { 01552 hirda->hdmatx->XferAbortCallback = NULL; 01553 } 01554 else 01555 { 01556 abortcplt = 0U; 01557 } 01558 } 01559 } 01560 01561 /* Disable the IRDA DMA Rx request if enabled */ 01562 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) 01563 { 01564 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); 01565 01566 /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */ 01567 if (hirda->hdmarx != NULL) 01568 { 01569 /* IRDA Rx DMA Abort callback has already been initialised : 01570 will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */ 01571 01572 /* Abort DMA RX */ 01573 if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK) 01574 { 01575 hirda->hdmarx->XferAbortCallback = NULL; 01576 abortcplt = 1U; 01577 } 01578 else 01579 { 01580 abortcplt = 0U; 01581 } 01582 } 01583 } 01584 01585 /* if no DMA abort complete callback execution is required => call user Abort Complete callback */ 01586 if (abortcplt == 1U) 01587 { 01588 /* Reset Tx and Rx transfer counters */ 01589 hirda->TxXferCount = 0U; 01590 hirda->RxXferCount = 0U; 01591 01592 /* Reset errorCode */ 01593 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 01594 01595 /* Clear the Error flags in the ICR register */ 01596 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); 01597 01598 /* Restore hirda->gState and hirda->RxState to Ready */ 01599 hirda->gState = HAL_IRDA_STATE_READY; 01600 hirda->RxState = HAL_IRDA_STATE_READY; 01601 01602 /* As no DMA to be aborted, call directly user Abort complete callback */ 01603 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 01604 /* Call registered Abort complete callback */ 01605 hirda->AbortCpltCallback(hirda); 01606 #else 01607 /* Call legacy weak Abort complete callback */ 01608 HAL_IRDA_AbortCpltCallback(hirda); 01609 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ 01610 } 01611 01612 return HAL_OK; 01613 } 01614 01615 /** 01616 * @brief Abort ongoing Transmit transfer (Interrupt mode). 01617 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 01618 * the configuration information for the specified UART module. 01619 * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. 01620 * This procedure performs following operations : 01621 * - Disable IRDA Interrupts (Tx) 01622 * - Disable the DMA transfer in the peripheral register (if enabled) 01623 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) 01624 * - Set handle State to READY 01625 * - At abort completion, call user abort complete callback 01626 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be 01627 * considered as completed only when user abort complete callback is executed (not when exiting function). 01628 * @retval HAL status 01629 */ 01630 HAL_StatusTypeDef HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef *hirda) 01631 { 01632 /* Disable TXEIE and TCIE interrupts */ 01633 #if defined(USART_CR1_FIFOEN) 01634 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); 01635 #else 01636 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); 01637 #endif 01638 01639 /* Disable the IRDA DMA Tx request if enabled */ 01640 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) 01641 { 01642 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); 01643 01644 /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */ 01645 if (hirda->hdmatx != NULL) 01646 { 01647 /* Set the IRDA DMA Abort callback : 01648 will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */ 01649 hirda->hdmatx->XferAbortCallback = IRDA_DMATxOnlyAbortCallback; 01650 01651 /* Abort DMA TX */ 01652 if (HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK) 01653 { 01654 /* Call Directly hirda->hdmatx->XferAbortCallback function in case of error */ 01655 hirda->hdmatx->XferAbortCallback(hirda->hdmatx); 01656 } 01657 } 01658 else 01659 { 01660 /* Reset Tx transfer counter */ 01661 hirda->TxXferCount = 0U; 01662 01663 /* Restore hirda->gState to Ready */ 01664 hirda->gState = HAL_IRDA_STATE_READY; 01665 01666 /* As no DMA to be aborted, call directly user Abort complete callback */ 01667 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 01668 /* Call registered Abort Transmit Complete Callback */ 01669 hirda->AbortTransmitCpltCallback(hirda); 01670 #else 01671 /* Call legacy weak Abort Transmit Complete Callback */ 01672 HAL_IRDA_AbortTransmitCpltCallback(hirda); 01673 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ 01674 } 01675 } 01676 else 01677 { 01678 /* Reset Tx transfer counter */ 01679 hirda->TxXferCount = 0U; 01680 01681 /* Restore hirda->gState to Ready */ 01682 hirda->gState = HAL_IRDA_STATE_READY; 01683 01684 /* As no DMA to be aborted, call directly user Abort complete callback */ 01685 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 01686 /* Call registered Abort Transmit Complete Callback */ 01687 hirda->AbortTransmitCpltCallback(hirda); 01688 #else 01689 /* Call legacy weak Abort Transmit Complete Callback */ 01690 HAL_IRDA_AbortTransmitCpltCallback(hirda); 01691 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ 01692 } 01693 01694 return HAL_OK; 01695 } 01696 01697 /** 01698 * @brief Abort ongoing Receive transfer (Interrupt mode). 01699 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 01700 * the configuration information for the specified UART module. 01701 * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. 01702 * This procedure performs following operations : 01703 * - Disable IRDA Interrupts (Rx) 01704 * - Disable the DMA transfer in the peripheral register (if enabled) 01705 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) 01706 * - Set handle State to READY 01707 * - At abort completion, call user abort complete callback 01708 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be 01709 * considered as completed only when user abort complete callback is executed (not when exiting function). 01710 * @retval HAL status 01711 */ 01712 HAL_StatusTypeDef HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef *hirda) 01713 { 01714 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ 01715 #if defined(USART_CR1_FIFOEN) 01716 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); 01717 #else 01718 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); 01719 #endif 01720 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); 01721 01722 /* Disable the IRDA DMA Rx request if enabled */ 01723 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) 01724 { 01725 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); 01726 01727 /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */ 01728 if (hirda->hdmarx != NULL) 01729 { 01730 /* Set the IRDA DMA Abort callback : 01731 will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */ 01732 hirda->hdmarx->XferAbortCallback = IRDA_DMARxOnlyAbortCallback; 01733 01734 /* Abort DMA RX */ 01735 if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK) 01736 { 01737 /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */ 01738 hirda->hdmarx->XferAbortCallback(hirda->hdmarx); 01739 } 01740 } 01741 else 01742 { 01743 /* Reset Rx transfer counter */ 01744 hirda->RxXferCount = 0U; 01745 01746 /* Clear the Error flags in the ICR register */ 01747 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); 01748 01749 /* Restore hirda->RxState to Ready */ 01750 hirda->RxState = HAL_IRDA_STATE_READY; 01751 01752 /* As no DMA to be aborted, call directly user Abort complete callback */ 01753 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 01754 /* Call registered Abort Receive Complete Callback */ 01755 hirda->AbortReceiveCpltCallback(hirda); 01756 #else 01757 /* Call legacy weak Abort Receive Complete Callback */ 01758 HAL_IRDA_AbortReceiveCpltCallback(hirda); 01759 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ 01760 } 01761 } 01762 else 01763 { 01764 /* Reset Rx transfer counter */ 01765 hirda->RxXferCount = 0U; 01766 01767 /* Clear the Error flags in the ICR register */ 01768 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); 01769 01770 /* Restore hirda->RxState to Ready */ 01771 hirda->RxState = HAL_IRDA_STATE_READY; 01772 01773 /* As no DMA to be aborted, call directly user Abort complete callback */ 01774 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 01775 /* Call registered Abort Receive Complete Callback */ 01776 hirda->AbortReceiveCpltCallback(hirda); 01777 #else 01778 /* Call legacy weak Abort Receive Complete Callback */ 01779 HAL_IRDA_AbortReceiveCpltCallback(hirda); 01780 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ 01781 } 01782 01783 return HAL_OK; 01784 } 01785 01786 /** 01787 * @brief Handle IRDA interrupt request. 01788 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 01789 * the configuration information for the specified IRDA module. 01790 * @retval None 01791 */ 01792 void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda) 01793 { 01794 uint32_t isrflags = READ_REG(hirda->Instance->ISR); 01795 uint32_t cr1its = READ_REG(hirda->Instance->CR1); 01796 uint32_t cr3its; 01797 uint32_t errorflags; 01798 01799 /* If no error occurs */ 01800 errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE)); 01801 if (errorflags == RESET) 01802 { 01803 /* IRDA in mode Receiver ---------------------------------------------------*/ 01804 #if defined(USART_CR1_FIFOEN) 01805 if (((isrflags & USART_ISR_RXNE_RXFNE) != RESET) && ((cr1its & USART_CR1_RXNEIE_RXFNEIE) != RESET)) 01806 #else 01807 if (((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) 01808 #endif 01809 { 01810 IRDA_Receive_IT(hirda); 01811 return; 01812 } 01813 } 01814 01815 /* If some errors occur */ 01816 cr3its = READ_REG(hirda->Instance->CR3); 01817 if ((errorflags != RESET) 01818 && (((cr3its & USART_CR3_EIE) != RESET) 01819 #if defined(USART_CR1_FIFOEN) 01820 || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)) != RESET))) 01821 #else 01822 || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET))) 01823 #endif 01824 { 01825 /* IRDA parity error interrupt occurred -------------------------------------*/ 01826 if (((isrflags & USART_ISR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET)) 01827 { 01828 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_PEF); 01829 01830 hirda->ErrorCode |= HAL_IRDA_ERROR_PE; 01831 } 01832 01833 /* IRDA frame error interrupt occurred --------------------------------------*/ 01834 if (((isrflags & USART_ISR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) 01835 { 01836 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_FEF); 01837 01838 hirda->ErrorCode |= HAL_IRDA_ERROR_FE; 01839 } 01840 01841 /* IRDA noise error interrupt occurred --------------------------------------*/ 01842 if (((isrflags & USART_ISR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) 01843 { 01844 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_NEF); 01845 01846 hirda->ErrorCode |= HAL_IRDA_ERROR_NE; 01847 } 01848 01849 /* IRDA Over-Run interrupt occurred -----------------------------------------*/ 01850 if (((isrflags & USART_ISR_ORE) != RESET) && 01851 #if defined(USART_CR1_FIFOEN) 01852 (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != RESET) || ((cr3its & USART_CR3_EIE) != RESET))) 01853 #else 01854 (((cr1its & USART_CR1_RXNEIE) != RESET) || ((cr3its & USART_CR3_EIE) != RESET))) 01855 #endif 01856 { 01857 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF); 01858 01859 hirda->ErrorCode |= HAL_IRDA_ERROR_ORE; 01860 } 01861 01862 /* Call IRDA Error Call back function if need be --------------------------*/ 01863 if (hirda->ErrorCode != HAL_IRDA_ERROR_NONE) 01864 { 01865 /* IRDA in mode Receiver ---------------------------------------------------*/ 01866 #if defined(USART_CR1_FIFOEN) 01867 if (((isrflags & USART_ISR_RXNE_RXFNE) != RESET) && ((cr1its & USART_CR1_RXNEIE_RXFNEIE) != RESET)) 01868 #else 01869 if (((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) 01870 #endif 01871 { 01872 IRDA_Receive_IT(hirda); 01873 } 01874 01875 /* If Overrun error occurs, or if any error occurs in DMA mode reception, 01876 consider error as blocking */ 01877 if (((hirda->ErrorCode & HAL_IRDA_ERROR_ORE) != RESET) || 01878 (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))) 01879 { 01880 /* Blocking error : transfer is aborted 01881 Set the IRDA state ready to be able to start again the process, 01882 Disable Rx Interrupts, and disable Rx DMA request, if ongoing */ 01883 IRDA_EndRxTransfer(hirda); 01884 01885 /* Disable the IRDA DMA Rx request if enabled */ 01886 if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) 01887 { 01888 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); 01889 01890 /* Abort the IRDA DMA Rx channel */ 01891 if (hirda->hdmarx != NULL) 01892 { 01893 /* Set the IRDA DMA Abort callback : 01894 will lead to call HAL_IRDA_ErrorCallback() at end of DMA abort procedure */ 01895 hirda->hdmarx->XferAbortCallback = IRDA_DMAAbortOnError; 01896 01897 /* Abort DMA RX */ 01898 if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK) 01899 { 01900 /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */ 01901 hirda->hdmarx->XferAbortCallback(hirda->hdmarx); 01902 } 01903 } 01904 else 01905 { 01906 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 01907 /* Call registered user error callback */ 01908 hirda->ErrorCallback(hirda); 01909 #else 01910 /* Call legacy weak user error callback */ 01911 HAL_IRDA_ErrorCallback(hirda); 01912 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ 01913 } 01914 } 01915 else 01916 { 01917 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 01918 /* Call registered user error callback */ 01919 hirda->ErrorCallback(hirda); 01920 #else 01921 /* Call legacy weak user error callback */ 01922 HAL_IRDA_ErrorCallback(hirda); 01923 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ 01924 } 01925 } 01926 else 01927 { 01928 /* Non Blocking error : transfer could go on. 01929 Error is notified to user through user error callback */ 01930 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 01931 /* Call registered user error callback */ 01932 hirda->ErrorCallback(hirda); 01933 #else 01934 /* Call legacy weak user error callback */ 01935 HAL_IRDA_ErrorCallback(hirda); 01936 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ 01937 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 01938 } 01939 } 01940 return; 01941 01942 } /* End if some error occurs */ 01943 01944 /* IRDA in mode Transmitter ------------------------------------------------*/ 01945 #if defined(USART_CR1_FIFOEN) 01946 if (((isrflags & USART_ISR_TXE_TXFNF) != RESET) && ((cr1its & USART_CR1_TXEIE_TXFNFIE) != RESET)) 01947 #else 01948 if (((isrflags & USART_ISR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)) 01949 #endif 01950 { 01951 IRDA_Transmit_IT(hirda); 01952 return; 01953 } 01954 01955 /* IRDA in mode Transmitter (transmission end) -----------------------------*/ 01956 if (((isrflags & USART_ISR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET)) 01957 { 01958 IRDA_EndTransmit_IT(hirda); 01959 return; 01960 } 01961 01962 } 01963 01964 /** 01965 * @brief Tx Transfer completed callback. 01966 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 01967 * the configuration information for the specified IRDA module. 01968 * @retval None 01969 */ 01970 __weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda) 01971 { 01972 /* Prevent unused argument(s) compilation warning */ 01973 UNUSED(hirda); 01974 01975 /* NOTE : This function should not be modified, when the callback is needed, 01976 the HAL_IRDA_TxCpltCallback can be implemented in the user file. 01977 */ 01978 } 01979 01980 /** 01981 * @brief Tx Half Transfer completed callback. 01982 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 01983 * the configuration information for the specified USART module. 01984 * @retval None 01985 */ 01986 __weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda) 01987 { 01988 /* Prevent unused argument(s) compilation warning */ 01989 UNUSED(hirda); 01990 01991 /* NOTE : This function should not be modified, when the callback is needed, 01992 the HAL_IRDA_TxHalfCpltCallback can be implemented in the user file. 01993 */ 01994 } 01995 01996 /** 01997 * @brief Rx Transfer completed callback. 01998 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 01999 * the configuration information for the specified IRDA module. 02000 * @retval None 02001 */ 02002 __weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda) 02003 { 02004 /* Prevent unused argument(s) compilation warning */ 02005 UNUSED(hirda); 02006 02007 /* NOTE : This function should not be modified, when the callback is needed, 02008 the HAL_IRDA_RxCpltCallback can be implemented in the user file. 02009 */ 02010 } 02011 02012 /** 02013 * @brief Rx Half Transfer complete callback. 02014 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 02015 * the configuration information for the specified IRDA module. 02016 * @retval None 02017 */ 02018 __weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda) 02019 { 02020 /* Prevent unused argument(s) compilation warning */ 02021 UNUSED(hirda); 02022 02023 /* NOTE : This function should not be modified, when the callback is needed, 02024 the HAL_IRDA_RxHalfCpltCallback can be implemented in the user file. 02025 */ 02026 } 02027 02028 /** 02029 * @brief IRDA error callback. 02030 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 02031 * the configuration information for the specified IRDA module. 02032 * @retval None 02033 */ 02034 __weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda) 02035 { 02036 /* Prevent unused argument(s) compilation warning */ 02037 UNUSED(hirda); 02038 02039 /* NOTE : This function should not be modified, when the callback is needed, 02040 the HAL_IRDA_ErrorCallback can be implemented in the user file. 02041 */ 02042 } 02043 02044 /** 02045 * @brief IRDA Abort Complete callback. 02046 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 02047 * the configuration information for the specified IRDA module. 02048 * @retval None 02049 */ 02050 __weak void HAL_IRDA_AbortCpltCallback(IRDA_HandleTypeDef *hirda) 02051 { 02052 /* Prevent unused argument(s) compilation warning */ 02053 UNUSED(hirda); 02054 02055 /* NOTE : This function should not be modified, when the callback is needed, 02056 the HAL_IRDA_AbortCpltCallback can be implemented in the user file. 02057 */ 02058 } 02059 02060 /** 02061 * @brief IRDA Abort Complete callback. 02062 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 02063 * the configuration information for the specified IRDA module. 02064 * @retval None 02065 */ 02066 __weak void HAL_IRDA_AbortTransmitCpltCallback(IRDA_HandleTypeDef *hirda) 02067 { 02068 /* Prevent unused argument(s) compilation warning */ 02069 UNUSED(hirda); 02070 02071 /* NOTE : This function should not be modified, when the callback is needed, 02072 the HAL_IRDA_AbortTransmitCpltCallback can be implemented in the user file. 02073 */ 02074 } 02075 02076 /** 02077 * @brief IRDA Abort Receive Complete callback. 02078 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 02079 * the configuration information for the specified IRDA module. 02080 * @retval None 02081 */ 02082 __weak void HAL_IRDA_AbortReceiveCpltCallback(IRDA_HandleTypeDef *hirda) 02083 { 02084 /* Prevent unused argument(s) compilation warning */ 02085 UNUSED(hirda); 02086 02087 /* NOTE : This function should not be modified, when the callback is needed, 02088 the HAL_IRDA_AbortReceiveCpltCallback can be implemented in the user file. 02089 */ 02090 } 02091 02092 /** 02093 * @} 02094 */ 02095 02096 /** @defgroup IRDA_Exported_Functions_Group4 Peripheral State and Error functions 02097 * @brief IRDA State and Errors functions 02098 * 02099 @verbatim 02100 ============================================================================== 02101 ##### Peripheral State and Error functions ##### 02102 ============================================================================== 02103 [..] 02104 This subsection provides a set of functions allowing to return the State of IrDA 02105 communication process and also return Peripheral Errors occurred during communication process 02106 (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state 02107 of the IRDA peripheral handle. 02108 (+) HAL_IRDA_GetError() checks in run-time errors that could occur during 02109 communication. 02110 02111 @endverbatim 02112 * @{ 02113 */ 02114 02115 /** 02116 * @brief Return the IRDA handle state. 02117 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 02118 * the configuration information for the specified IRDA module. 02119 * @retval HAL state 02120 */ 02121 HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda) 02122 { 02123 /* Return IRDA handle state */ 02124 uint32_t temp1 = 0x00U, temp2 = 0x00U; 02125 temp1 = hirda->gState; 02126 temp2 = hirda->RxState; 02127 02128 return (HAL_IRDA_StateTypeDef)(temp1 | temp2); 02129 } 02130 02131 /** 02132 * @brief Return the IRDA handle error code. 02133 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 02134 * the configuration information for the specified IRDA module. 02135 * @retval IRDA Error Code 02136 */ 02137 uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda) 02138 { 02139 return hirda->ErrorCode; 02140 } 02141 02142 /** 02143 * @} 02144 */ 02145 02146 /** 02147 * @} 02148 */ 02149 02150 /** @defgroup IRDA_Private_Functions IRDA Private Functions 02151 * @{ 02152 */ 02153 02154 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 02155 /** 02156 * @brief Initialize the callbacks to their default values. 02157 * @param hirda IRDA handle. 02158 * @retval none 02159 */ 02160 void IRDA_InitCallbacksToDefault(IRDA_HandleTypeDef *hirda) 02161 { 02162 /* Init the IRDA Callback settings */ 02163 hirda->TxHalfCpltCallback = HAL_IRDA_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ 02164 hirda->TxCpltCallback = HAL_IRDA_TxCpltCallback; /* Legacy weak TxCpltCallback */ 02165 hirda->RxHalfCpltCallback = HAL_IRDA_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ 02166 hirda->RxCpltCallback = HAL_IRDA_RxCpltCallback; /* Legacy weak RxCpltCallback */ 02167 hirda->ErrorCallback = HAL_IRDA_ErrorCallback; /* Legacy weak ErrorCallback */ 02168 hirda->AbortCpltCallback = HAL_IRDA_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ 02169 hirda->AbortTransmitCpltCallback = HAL_IRDA_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */ 02170 hirda->AbortReceiveCpltCallback = HAL_IRDA_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */ 02171 02172 } 02173 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ 02174 02175 /** 02176 * @brief Configure the IRDA peripheral. 02177 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 02178 * the configuration information for the specified IRDA module. 02179 * @retval HAL status 02180 */ 02181 static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda) 02182 { 02183 uint32_t tmpreg = 0x00000000U; 02184 IRDA_ClockSourceTypeDef clocksource = IRDA_CLOCKSOURCE_UNDEFINED; 02185 HAL_StatusTypeDef ret = HAL_OK; 02186 02187 /* Check the communication parameters */ 02188 assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate)); 02189 assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength)); 02190 assert_param(IS_IRDA_PARITY(hirda->Init.Parity)); 02191 assert_param(IS_IRDA_TX_RX_MODE(hirda->Init.Mode)); 02192 assert_param(IS_IRDA_PRESCALER(hirda->Init.Prescaler)); 02193 assert_param(IS_IRDA_POWERMODE(hirda->Init.PowerMode)); 02194 #if defined(USART_PRESC_PRESCALER) 02195 assert_param(IS_IRDA_CLOCKPRESCALER(hirda->Init.ClockPrescaler)); 02196 #endif 02197 02198 /*-------------------------- USART CR1 Configuration -----------------------*/ 02199 /* Configure the IRDA Word Length, Parity and transfer Mode: 02200 Set the M bits according to hirda->Init.WordLength value 02201 Set PCE and PS bits according to hirda->Init.Parity value 02202 Set TE and RE bits according to hirda->Init.Mode value */ 02203 tmpreg = (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode ; 02204 02205 MODIFY_REG(hirda->Instance->CR1, IRDA_CR1_FIELDS, tmpreg); 02206 02207 /*-------------------------- USART CR3 Configuration -----------------------*/ 02208 MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.PowerMode); 02209 02210 #if defined(USART_PRESC_PRESCALER) 02211 /*--------------------- USART clock PRESC Configuration ----------------*/ 02212 /* Configure 02213 * - IRDA Clock Prescaler: set PRESCALER according to hirda->Init.ClockPrescaler value */ 02214 MODIFY_REG(hirda->Instance->PRESC, USART_PRESC_PRESCALER, hirda->Init.ClockPrescaler); 02215 #endif 02216 02217 /*-------------------------- USART GTPR Configuration ----------------------*/ 02218 MODIFY_REG(hirda->Instance->GTPR, USART_GTPR_PSC, hirda->Init.Prescaler); 02219 02220 /*-------------------------- USART BRR Configuration -----------------------*/ 02221 IRDA_GETCLOCKSOURCE(hirda, clocksource); 02222 tmpreg = 0U; 02223 switch (clocksource) 02224 { 02225 case IRDA_CLOCKSOURCE_PCLK1: 02226 #if defined(USART_PRESC_PRESCALER) 02227 tmpreg = (uint16_t)(IRDA_DIV_SAMPLING16(HAL_RCC_GetPCLK1Freq(), hirda->Init.BaudRate, hirda->Init.ClockPrescaler)); 02228 #else 02229 tmpreg = (uint16_t)(IRDA_DIV_SAMPLING16(HAL_RCC_GetPCLK1Freq(), hirda->Init.BaudRate)); 02230 #endif 02231 break; 02232 case IRDA_CLOCKSOURCE_PCLK2: 02233 #if defined(USART_PRESC_PRESCALER) 02234 tmpreg = (uint16_t)(IRDA_DIV_SAMPLING16(HAL_RCC_GetPCLK2Freq(), hirda->Init.BaudRate, hirda->Init.ClockPrescaler)); 02235 #else 02236 tmpreg = (uint16_t)(IRDA_DIV_SAMPLING16(HAL_RCC_GetPCLK2Freq(), hirda->Init.BaudRate)); 02237 #endif 02238 break; 02239 case IRDA_CLOCKSOURCE_HSI: 02240 #if defined(USART_PRESC_PRESCALER) 02241 tmpreg = (uint16_t)(IRDA_DIV_SAMPLING16(HSI_VALUE, hirda->Init.BaudRate, hirda->Init.ClockPrescaler)); 02242 #else 02243 tmpreg = (uint16_t)(IRDA_DIV_SAMPLING16(HSI_VALUE, hirda->Init.BaudRate)); 02244 #endif 02245 break; 02246 case IRDA_CLOCKSOURCE_SYSCLK: 02247 #if defined(USART_PRESC_PRESCALER) 02248 tmpreg = (uint16_t)(IRDA_DIV_SAMPLING16(HAL_RCC_GetSysClockFreq(), hirda->Init.BaudRate, hirda->Init.ClockPrescaler)); 02249 #else 02250 tmpreg = (uint16_t)(IRDA_DIV_SAMPLING16(HAL_RCC_GetSysClockFreq(), hirda->Init.BaudRate)); 02251 #endif 02252 break; 02253 case IRDA_CLOCKSOURCE_LSE: 02254 #if defined(USART_PRESC_PRESCALER) 02255 tmpreg = (uint16_t)(IRDA_DIV_SAMPLING16(LSE_VALUE, hirda->Init.BaudRate, hirda->Init.ClockPrescaler)); 02256 #else 02257 tmpreg = (uint16_t)(IRDA_DIV_SAMPLING16(LSE_VALUE, hirda->Init.BaudRate)); 02258 #endif 02259 break; 02260 case IRDA_CLOCKSOURCE_UNDEFINED: 02261 default: 02262 ret = HAL_ERROR; 02263 break; 02264 } 02265 02266 /* USARTDIV must be greater than or equal to 0d16 */ 02267 if ((tmpreg >= USART_BRR_MIN) && (tmpreg <= USART_BRR_MAX)) 02268 { 02269 hirda->Instance->BRR = tmpreg; 02270 } 02271 else 02272 { 02273 ret = HAL_ERROR; 02274 } 02275 02276 return ret; 02277 } 02278 02279 /** 02280 * @brief Check the IRDA Idle State. 02281 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 02282 * the configuration information for the specified IRDA module. 02283 * @retval HAL status 02284 */ 02285 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda) 02286 { 02287 uint32_t tickstart = 0U; 02288 02289 /* Initialize the IRDA ErrorCode */ 02290 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 02291 02292 /* Init tickstart for timeout managment*/ 02293 tickstart = HAL_GetTick(); 02294 02295 /* Check if the Transmitter is enabled */ 02296 if ((hirda->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) 02297 { 02298 /* Wait until TEACK flag is set */ 02299 if (IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK) 02300 { 02301 /* Timeout occurred */ 02302 return HAL_TIMEOUT; 02303 } 02304 } 02305 /* Check if the Receiver is enabled */ 02306 if ((hirda->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) 02307 { 02308 /* Wait until REACK flag is set */ 02309 if (IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK) 02310 { 02311 /* Timeout occurred */ 02312 return HAL_TIMEOUT; 02313 } 02314 } 02315 02316 /* Initialize the IRDA state*/ 02317 hirda->gState = HAL_IRDA_STATE_READY; 02318 hirda->RxState = HAL_IRDA_STATE_READY; 02319 02320 /* Process Unlocked */ 02321 __HAL_UNLOCK(hirda); 02322 02323 return HAL_OK; 02324 } 02325 02326 /** 02327 * @brief Handle IRDA Communication Timeout. 02328 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 02329 * the configuration information for the specified IRDA module. 02330 * @param Flag Specifies the IRDA flag to check. 02331 * @param Status Flag status (SET or RESET) 02332 * @param Tickstart Tick start value 02333 * @param Timeout Timeout duration 02334 * @retval HAL status 02335 */ 02336 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout) 02337 { 02338 /* Wait until flag is set */ 02339 while ((__HAL_IRDA_GET_FLAG(hirda, Flag) ? SET : RESET) == Status) 02340 { 02341 /* Check for the Timeout */ 02342 if (Timeout != HAL_MAX_DELAY) 02343 { 02344 if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) 02345 { 02346 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ 02347 #if defined(USART_CR1_FIFOEN) 02348 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE)); 02349 #else 02350 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE)); 02351 #endif 02352 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); 02353 02354 hirda->gState = HAL_IRDA_STATE_READY; 02355 hirda->RxState = HAL_IRDA_STATE_READY; 02356 02357 /* Process Unlocked */ 02358 __HAL_UNLOCK(hirda); 02359 return HAL_TIMEOUT; 02360 } 02361 } 02362 } 02363 return HAL_OK; 02364 } 02365 02366 02367 /** 02368 * @brief End ongoing Tx transfer on IRDA peripheral (following error detection or Transmit completion). 02369 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 02370 * the configuration information for the specified IRDA module. 02371 * @retval None 02372 */ 02373 static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda) 02374 { 02375 /* Disable TXEIE and TCIE interrupts */ 02376 #if defined(USART_CR1_FIFOEN) 02377 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); 02378 #else 02379 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); 02380 #endif 02381 02382 /* At end of Tx process, restore hirda->gState to Ready */ 02383 hirda->gState = HAL_IRDA_STATE_READY; 02384 } 02385 02386 02387 /** 02388 * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion). 02389 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 02390 * the configuration information for the specified IRDA module. 02391 * @retval None 02392 */ 02393 static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda) 02394 { 02395 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ 02396 #if defined(USART_CR1_FIFOEN) 02397 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); 02398 #else 02399 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); 02400 #endif 02401 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); 02402 02403 /* At end of Rx process, restore hirda->RxState to Ready */ 02404 hirda->RxState = HAL_IRDA_STATE_READY; 02405 } 02406 02407 02408 /** 02409 * @brief DMA IRDA transmit process complete callback. 02410 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains 02411 * the configuration information for the specified DMA module. 02412 * @retval None 02413 */ 02414 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma) 02415 { 02416 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent); 02417 02418 /* DMA Normal mode */ 02419 if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC)) 02420 { 02421 hirda->TxXferCount = 0U; 02422 02423 /* Disable the DMA transfer for transmit request by resetting the DMAT bit 02424 in the IRDA CR3 register */ 02425 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); 02426 02427 /* Enable the IRDA Transmit Complete Interrupt */ 02428 SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE); 02429 } 02430 /* DMA Circular mode */ 02431 else 02432 { 02433 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 02434 /* Call registered Tx complete callback */ 02435 hirda->TxCpltCallback(hirda); 02436 #else 02437 /* Call legacy weak Tx complete callback */ 02438 HAL_IRDA_TxCpltCallback(hirda); 02439 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ 02440 } 02441 02442 } 02443 02444 /** 02445 * @brief DMA IRDA transmit process half complete callback. 02446 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains 02447 * the configuration information for the specified DMA module. 02448 * @retval None 02449 */ 02450 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma) 02451 { 02452 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent); 02453 02454 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 02455 /* Call registered Tx Half complete callback */ 02456 hirda->TxHalfCpltCallback(hirda); 02457 #else 02458 /* Call legacy weak Tx complete callback */ 02459 HAL_IRDA_TxHalfCpltCallback(hirda); 02460 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ 02461 } 02462 02463 /** 02464 * @brief DMA IRDA receive process complete callback. 02465 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains 02466 * the configuration information for the specified DMA module. 02467 * @retval None 02468 */ 02469 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma) 02470 { 02471 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent); 02472 02473 /* DMA Normal mode */ 02474 if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC)) 02475 { 02476 hirda->RxXferCount = 0U; 02477 02478 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ 02479 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE); 02480 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); 02481 02482 /* Disable the DMA transfer for the receiver request by resetting the DMAR bit 02483 in the IRDA CR3 register */ 02484 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); 02485 02486 /* At end of Rx process, restore hirda->RxState to Ready */ 02487 hirda->RxState = HAL_IRDA_STATE_READY; 02488 } 02489 02490 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 02491 /* Call registered Rx complete callback */ 02492 hirda->RxCpltCallback(hirda); 02493 #else 02494 /* Call legacy weak Rx complete callback */ 02495 HAL_IRDA_RxCpltCallback(hirda); 02496 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ 02497 } 02498 02499 /** 02500 * @brief DMA IRDA receive process half complete callback. 02501 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains 02502 * the configuration information for the specified DMA module. 02503 * @retval None 02504 */ 02505 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma) 02506 { 02507 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent); 02508 02509 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 02510 /*Call registered Rx Half complete callback*/ 02511 hirda->RxHalfCpltCallback(hirda); 02512 #else 02513 /* Call legacy weak Rx Half complete callback */ 02514 HAL_IRDA_RxHalfCpltCallback(hirda); 02515 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ 02516 } 02517 02518 /** 02519 * @brief DMA IRDA communication error callback. 02520 * @param hdma Pointer to a DMA_HandleTypeDef structure that contains 02521 * the configuration information for the specified DMA module. 02522 * @retval None 02523 */ 02524 static void IRDA_DMAError(DMA_HandleTypeDef *hdma) 02525 { 02526 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent); 02527 02528 /* Stop IRDA DMA Tx request if ongoing */ 02529 if ((hirda->gState == HAL_IRDA_STATE_BUSY_TX) 02530 && (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))) 02531 { 02532 hirda->TxXferCount = 0U; 02533 IRDA_EndTxTransfer(hirda); 02534 } 02535 02536 /* Stop IRDA DMA Rx request if ongoing */ 02537 if ((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) 02538 && (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))) 02539 { 02540 hirda->RxXferCount = 0U; 02541 IRDA_EndRxTransfer(hirda); 02542 } 02543 02544 hirda->ErrorCode |= HAL_IRDA_ERROR_DMA; 02545 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 02546 /* Call registered user error callback */ 02547 hirda->ErrorCallback(hirda); 02548 #else 02549 /* Call legacy weak user error callback */ 02550 HAL_IRDA_ErrorCallback(hirda); 02551 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ 02552 } 02553 02554 /** 02555 * @brief DMA IRDA communication abort callback, when initiated by HAL services on Error 02556 * (To be called at end of DMA Abort procedure following error occurrence). 02557 * @param hdma DMA handle. 02558 * @retval None 02559 */ 02560 static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma) 02561 { 02562 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent); 02563 hirda->RxXferCount = 0U; 02564 hirda->TxXferCount = 0U; 02565 02566 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 02567 /* Call registered user error callback */ 02568 hirda->ErrorCallback(hirda); 02569 #else 02570 /* Call legacy weak user error callback */ 02571 HAL_IRDA_ErrorCallback(hirda); 02572 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ 02573 } 02574 02575 /** 02576 * @brief DMA IRDA Tx communication abort callback, when initiated by user 02577 * (To be called at end of DMA Tx Abort procedure following user abort request). 02578 * @note When this callback is executed, User Abort complete call back is called only if no 02579 * Abort still ongoing for Rx DMA Handle. 02580 * @param hdma DMA handle. 02581 * @retval None 02582 */ 02583 static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma) 02584 { 02585 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent); 02586 02587 hirda->hdmatx->XferAbortCallback = NULL; 02588 02589 /* Check if an Abort process is still ongoing */ 02590 if (hirda->hdmarx != NULL) 02591 { 02592 if (hirda->hdmarx->XferAbortCallback != NULL) 02593 { 02594 return; 02595 } 02596 } 02597 02598 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ 02599 hirda->TxXferCount = 0U; 02600 hirda->RxXferCount = 0U; 02601 02602 /* Reset errorCode */ 02603 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 02604 02605 /* Clear the Error flags in the ICR register */ 02606 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); 02607 02608 /* Restore hirda->gState and hirda->RxState to Ready */ 02609 hirda->gState = HAL_IRDA_STATE_READY; 02610 hirda->RxState = HAL_IRDA_STATE_READY; 02611 02612 /* Call user Abort complete callback */ 02613 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 02614 /* Call registered Abort complete callback */ 02615 hirda->AbortCpltCallback(hirda); 02616 #else 02617 /* Call legacy weak Abort complete callback */ 02618 HAL_IRDA_AbortCpltCallback(hirda); 02619 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ 02620 } 02621 02622 02623 /** 02624 * @brief DMA IRDA Rx communication abort callback, when initiated by user 02625 * (To be called at end of DMA Rx Abort procedure following user abort request). 02626 * @note When this callback is executed, User Abort complete call back is called only if no 02627 * Abort still ongoing for Tx DMA Handle. 02628 * @param hdma DMA handle. 02629 * @retval None 02630 */ 02631 static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma) 02632 { 02633 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent); 02634 02635 hirda->hdmarx->XferAbortCallback = NULL; 02636 02637 /* Check if an Abort process is still ongoing */ 02638 if (hirda->hdmatx != NULL) 02639 { 02640 if (hirda->hdmatx->XferAbortCallback != NULL) 02641 { 02642 return; 02643 } 02644 } 02645 02646 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ 02647 hirda->TxXferCount = 0U; 02648 hirda->RxXferCount = 0U; 02649 02650 /* Reset errorCode */ 02651 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 02652 02653 /* Clear the Error flags in the ICR register */ 02654 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); 02655 02656 /* Restore hirda->gState and hirda->RxState to Ready */ 02657 hirda->gState = HAL_IRDA_STATE_READY; 02658 hirda->RxState = HAL_IRDA_STATE_READY; 02659 02660 /* Call user Abort complete callback */ 02661 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 02662 /* Call registered Abort complete callback */ 02663 hirda->AbortCpltCallback(hirda); 02664 #else 02665 /* Call legacy weak Abort complete callback */ 02666 HAL_IRDA_AbortCpltCallback(hirda); 02667 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ 02668 } 02669 02670 02671 /** 02672 * @brief DMA IRDA Tx communication abort callback, when initiated by user by a call to 02673 * HAL_IRDA_AbortTransmit_IT API (Abort only Tx transfer) 02674 * (This callback is executed at end of DMA Tx Abort procedure following user abort request, 02675 * and leads to user Tx Abort Complete callback execution). 02676 * @param hdma DMA handle. 02677 * @retval None 02678 */ 02679 static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma) 02680 { 02681 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent); 02682 02683 hirda->TxXferCount = 0U; 02684 02685 /* Restore hirda->gState to Ready */ 02686 hirda->gState = HAL_IRDA_STATE_READY; 02687 02688 /* Call user Abort complete callback */ 02689 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 02690 /* Call registered Abort Transmit Complete Callback */ 02691 hirda->AbortTransmitCpltCallback(hirda); 02692 #else 02693 /* Call legacy weak Abort Transmit Complete Callback */ 02694 HAL_IRDA_AbortTransmitCpltCallback(hirda); 02695 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ 02696 } 02697 02698 /** 02699 * @brief DMA IRDA Rx communication abort callback, when initiated by user by a call to 02700 * HAL_IRDA_AbortReceive_IT API (Abort only Rx transfer) 02701 * (This callback is executed at end of DMA Rx Abort procedure following user abort request, 02702 * and leads to user Rx Abort Complete callback execution). 02703 * @param hdma DMA handle. 02704 * @retval None 02705 */ 02706 static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma) 02707 { 02708 IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 02709 02710 hirda->RxXferCount = 0U; 02711 02712 /* Clear the Error flags in the ICR register */ 02713 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); 02714 02715 /* Restore hirda->RxState to Ready */ 02716 hirda->RxState = HAL_IRDA_STATE_READY; 02717 02718 /* Call user Abort complete callback */ 02719 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 02720 /* Call registered Abort Receive Complete Callback */ 02721 hirda->AbortReceiveCpltCallback(hirda); 02722 #else 02723 /* Call legacy weak Abort Receive Complete Callback */ 02724 HAL_IRDA_AbortReceiveCpltCallback(hirda); 02725 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ 02726 } 02727 02728 /** 02729 * @brief Send an amount of data in interrupt mode. 02730 * @note Function is called under interruption only, once 02731 * interruptions have been enabled by HAL_IRDA_Transmit_IT(). 02732 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 02733 * the configuration information for the specified IRDA module. 02734 * @retval HAL status 02735 */ 02736 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda) 02737 { 02738 uint16_t *tmp; 02739 02740 /* Check that a Tx process is ongoing */ 02741 if (hirda->gState == HAL_IRDA_STATE_BUSY_TX) 02742 { 02743 if (hirda->TxXferCount == 0U) 02744 { 02745 /* Disable the IRDA Transmit Data Register Empty Interrupt */ 02746 #if defined(USART_CR1_FIFOEN) 02747 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); 02748 #else 02749 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TXEIE); 02750 #endif 02751 02752 /* Enable the IRDA Transmit Complete Interrupt */ 02753 SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE); 02754 02755 return HAL_OK; 02756 } 02757 else 02758 { 02759 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) 02760 { 02761 tmp = (uint16_t *) hirda->pTxBuffPtr; 02762 hirda->Instance->TDR = (*tmp & (uint16_t)0x01FF); 02763 hirda->pTxBuffPtr += 2U; 02764 } 02765 else 02766 { 02767 hirda->Instance->TDR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0xFF); 02768 } 02769 hirda->TxXferCount--; 02770 02771 return HAL_OK; 02772 } 02773 } 02774 else 02775 { 02776 return HAL_BUSY; 02777 } 02778 } 02779 02780 /** 02781 * @brief Wrap up transmission in non-blocking mode. 02782 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 02783 * the configuration information for the specified IRDA module. 02784 * @retval None 02785 */ 02786 static void IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda) 02787 { 02788 /* Disable the IRDA Transmit Complete Interrupt */ 02789 CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TCIE); 02790 02791 /* Tx process is ended, restore hirda->gState to Ready */ 02792 hirda->gState = HAL_IRDA_STATE_READY; 02793 02794 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 02795 /* Call registered Tx complete callback */ 02796 hirda->TxCpltCallback(hirda); 02797 #else 02798 /* Call legacy weak Tx complete callback */ 02799 HAL_IRDA_TxCpltCallback(hirda); 02800 #endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ 02801 } 02802 02803 /** 02804 * @brief Receive an amount of data in interrupt mode. 02805 * @note Function is called under interruption only, once 02806 * interruptions have been enabled by HAL_IRDA_Receive_IT() 02807 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 02808 * the configuration information for the specified IRDA module. 02809 * @retval HAL status 02810 */ 02811 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda) 02812 { 02813 uint16_t *tmp; 02814 uint16_t uhMask = hirda->Mask; 02815 uint16_t uhdata; 02816 02817 /* Check that a Rx process is ongoing */ 02818 if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX) 02819 { 02820 uhdata = (uint16_t) READ_REG(hirda->Instance->RDR); 02821 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) 02822 { 02823 tmp = (uint16_t *) hirda->pRxBuffPtr ; 02824 *tmp = (uint16_t)(uhdata & uhMask); 02825 hirda->pRxBuffPtr += 2U; 02826 } 02827 else 02828 { 02829 *hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)uhMask); 02830 } 02831 02832 if (--hirda->RxXferCount == 0U) 02833 { 02834 /* Disable the IRDA Parity Error Interrupt and RXNE interrupt */ 02835 #if defined(USART_CR1_FIFOEN) 02836 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); 02837 #else 02838 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); 02839 #endif 02840 02841 /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ 02842 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); 02843 02844 /* Rx process is completed, restore hirda->RxState to Ready */ 02845 hirda->RxState = HAL_IRDA_STATE_READY; 02846 02847 #if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) 02848 /* Call registered Rx complete callback */ 02849 hirda->RxCpltCallback(hirda); 02850 #else 02851 /* Call legacy weak Rx complete callback */ 02852 HAL_IRDA_RxCpltCallback(hirda); 02853 #endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ 02854 02855 return HAL_OK; 02856 } 02857 02858 return HAL_OK; 02859 } 02860 else 02861 { 02862 /* Clear RXNE interrupt flag */ 02863 __HAL_IRDA_SEND_REQ(hirda, IRDA_RXDATA_FLUSH_REQUEST); 02864 02865 return HAL_BUSY; 02866 } 02867 } 02868 02869 /** 02870 * @} 02871 */ 02872 02873 #endif /* HAL_IRDA_MODULE_ENABLED */ 02874 /** 02875 * @} 02876 */ 02877 02878 /** 02879 * @} 02880 */ 02881 02882 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/