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