L4 HAL Drivers
Embed:
(wiki syntax)
Show/hide line numbers
stm32l4xx_hal_irda.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_irda.c 00004 * @author MCD Application Team 00005 * @version V1.1.0 00006 * @date 16-September-2015 00007 * @brief IRDA HAL module driver. 00008 * This file provides firmware functions to manage the following 00009 * functionalities of the IrDA (Infrared Data Association) Peripheral 00010 * (IRDA) 00011 * + Initialization and de-initialization functions 00012 * + IO operation functions 00013 * + Peripheral State and Errors functions 00014 * + Peripheral Control functions 00015 * 00016 @verbatim 00017 ============================================================================== 00018 ##### How to use this driver ##### 00019 ============================================================================== 00020 [..] 00021 The IRDA HAL driver can be used as follows: 00022 00023 (#) Declare a IRDA_HandleTypeDef handle structure (eg. IRDA_HandleTypeDef hirda). 00024 (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API 00025 in setting the associated USART or UART in IRDA mode: 00026 (++) Enable the USARTx/UARTx interface clock. 00027 (++) USARTx/UARTx pins configuration: 00028 (+++) Enable the clock for the USARTx/UARTx GPIOs. 00029 (+++) Configure these USARTx/UARTx pins (TX as alternate function pull-up, RX as alternate function Input). 00030 (++) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT() 00031 and HAL_IRDA_Receive_IT() APIs): 00032 (+++) Configure the USARTx/UARTx interrupt priority. 00033 (+++) Enable the NVIC USARTx/UARTx IRQ handle. 00034 (+++) The specific IRDA interrupts (Transmission complete interrupt, 00035 RXNE interrupt and Error Interrupts) will be managed using the macros 00036 __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process. 00037 00038 (++) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA() 00039 and HAL_IRDA_Receive_DMA() APIs): 00040 (+++) Declare a DMA handle structure for the Tx/Rx channel. 00041 (+++) Enable the DMAx interface clock. 00042 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. 00043 (+++) Configure the DMA Tx/Rx channel. 00044 (+++) Associate the initialized DMA handle to the IRDA DMA Tx/Rx handle. 00045 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel. 00046 00047 (#) Program the Baud Rate, Word Length and Parity and Mode(Receiver/Transmitter), 00048 the normal or low power mode and the clock prescaler in the hirda handle Init structure. 00049 00050 (#) Initialize the IRDA registers by calling the HAL_IRDA_Init() API: 00051 (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) 00052 by calling the customized HAL_IRDA_MspInit() API. 00053 00054 -@@- The specific IRDA interrupts (Transmission complete interrupt, 00055 RXNE interrupt and Error Interrupts) will be managed using the macros 00056 __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process. 00057 00058 (#) Three operation modes are available within this driver : 00059 00060 *** Polling mode IO operation *** 00061 ================================= 00062 [..] 00063 (+) Send an amount of data in blocking mode using HAL_IRDA_Transmit() 00064 (+) Receive an amount of data in blocking mode using HAL_IRDA_Receive() 00065 00066 *** Interrupt mode IO operation *** 00067 =================================== 00068 [..] 00069 (+) Send an amount of data in non-blocking mode using HAL_IRDA_Transmit_IT() 00070 (+) At transmission end of transfer HAL_IRDA_TxCpltCallback() is executed and user can 00071 add his own code by customization of function pointer HAL_IRDA_TxCpltCallback() 00072 (+) Receive an amount of data in non-blocking mode using HAL_IRDA_Receive_IT() 00073 (+) At reception end of transfer HAL_IRDA_RxCpltCallback() is executed and user can 00074 add his own code by customization of function pointer HAL_IRDA_RxCpltCallback() 00075 (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can 00076 add his own code by customization of function pointer HAL_IRDA_ErrorCallback() 00077 00078 *** DMA mode IO operation *** 00079 ============================== 00080 [..] 00081 (+) Send an amount of data in non-blocking mode (DMA) using HAL_IRDA_Transmit_DMA() 00082 (+) At transmission half of transfer HAL_IRDA_TxHalfCpltCallback() is executed and user can 00083 add his own code by customization of function pointer HAL_IRDA_TxHalfCpltCallback() 00084 (+) At transmission end of transfer HAL_IRDA_TxCpltCallback() is executed and user can 00085 add his own code by customization of function pointer HAL_IRDA_TxCpltCallback() 00086 (+) Receive an amount of data in non-blocking mode (DMA) using HAL_IRDA_Receive_DMA() 00087 (+) At reception half of transfer HAL_IRDA_RxHalfCpltCallback() is executed and user can 00088 add his own code by customization of function pointer HAL_IRDA_RxHalfCpltCallback() 00089 (+) At reception end of transfer HAL_IRDA_RxCpltCallback() is executed and user can 00090 add his own code by customization of function pointer HAL_IRDA_RxCpltCallback() 00091 (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can 00092 add his own code by customization of function pointer HAL_IRDA_ErrorCallback() 00093 00094 *** IRDA HAL driver macros list *** 00095 ==================================== 00096 [..] 00097 Below the list of most used macros in IRDA HAL driver. 00098 00099 (+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral 00100 (+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral 00101 (+) __HAL_IRDA_GET_FLAG : Check whether the specified IRDA flag is set or not 00102 (+) __HAL_IRDA_CLEAR_FLAG : Clear the specified IRDA pending flag 00103 (+) __HAL_IRDA_ENABLE_IT: Enable the specified IRDA interrupt 00104 (+) __HAL_IRDA_DISABLE_IT: Disable the specified IRDA interrupt 00105 (+) __HAL_IRDA_GET_IT_SOURCE: Check whether or not the specified IRDA interrupt is enabled 00106 00107 [..] 00108 (@) You can refer to the IRDA HAL driver header file for more useful macros 00109 00110 @endverbatim 00111 ****************************************************************************** 00112 * @attention 00113 * 00114 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> 00115 * 00116 * Redistribution and use in source and binary forms, with or without modification, 00117 * are permitted provided that the following conditions are met: 00118 * 1. Redistributions of source code must retain the above copyright notice, 00119 * this list of conditions and the following disclaimer. 00120 * 2. Redistributions in binary form must reproduce the above copyright notice, 00121 * this list of conditions and the following disclaimer in the documentation 00122 * and/or other materials provided with the distribution. 00123 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00124 * may be used to endorse or promote products derived from this software 00125 * without specific prior written permission. 00126 * 00127 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00128 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00129 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00130 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00131 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00132 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00133 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00134 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00135 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00136 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00137 * 00138 ****************************************************************************** 00139 */ 00140 00141 /* Includes ------------------------------------------------------------------*/ 00142 #include "stm32l4xx_hal.h" 00143 00144 /** @addtogroup STM32L4xx_HAL_Driver 00145 * @{ 00146 */ 00147 00148 /** @defgroup IRDA IRDA 00149 * @brief HAL IRDA module driver 00150 * @{ 00151 */ 00152 00153 #ifdef HAL_IRDA_MODULE_ENABLED 00154 00155 /* Private typedef -----------------------------------------------------------*/ 00156 /* Private define ------------------------------------------------------------*/ 00157 /** @defgroup IRDA_Private_Constants IRDA Private Constants 00158 * @{ 00159 */ 00160 #define IRDA_TEACK_REACK_TIMEOUT 1000 /*!< IRDA TX or RX enable acknowledge time-out value */ 00161 #define IRDA_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE \ 00162 | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE)) /*!< UART or USART CR1 fields of parameters set by IRDA_SetConfig API */ 00163 /** 00164 * @} 00165 */ 00166 00167 /* Private macros ------------------------------------------------------------*/ 00168 /* Private variables ---------------------------------------------------------*/ 00169 /* Private function prototypes -----------------------------------------------*/ 00170 /** @addtogroup IRDA_Private_Functions 00171 * @{ 00172 */ 00173 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda); 00174 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda); 00175 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda); 00176 static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda); 00177 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda); 00178 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma); 00179 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma); 00180 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma); 00181 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma); 00182 static void IRDA_DMAError(DMA_HandleTypeDef *hdma); 00183 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Timeout); 00184 /** 00185 * @} 00186 */ 00187 00188 /* Exported functions --------------------------------------------------------*/ 00189 00190 /** @defgroup IRDA_Exported_Functions IRDA Exported Functions 00191 * @{ 00192 */ 00193 00194 /** @defgroup IRDA_Exported_Functions_Group1 Initialization and de-initialization functions 00195 * @brief Initialization and Configuration functions 00196 * 00197 @verbatim 00198 ============================================================================== 00199 ##### Initialization and Configuration functions ##### 00200 ============================================================================== 00201 [..] 00202 This subsection provides a set of functions allowing to initialize the USARTx 00203 in asynchronous IRDA mode. 00204 (+) For the asynchronous mode only these parameters can be configured: 00205 (++) Baud Rate 00206 (++) Word Length 00207 (++) Parity: If the parity is enabled, then the MSB bit of the data written 00208 in the data register is transmitted but is changed by the parity bit. 00209 Depending on the frame length defined by the M1 and M0 bits (7-bit, 00210 8-bit or 9-bit), the possible IRDA frame formats are listed in the 00211 following table. 00212 (+++) Table 1. IRDA frame format. 00213 (+++) +-----------------------------------------------------------------------+ 00214 (+++) | M1 bit | M0 bit | PCE bit | IRDA frame | 00215 (+++) |---------|---------|-----------|---------------------------------------| 00216 (+++) | 0 | 0 | 0 | | SB | 8 bit data | STB | | 00217 (+++) |---------|---------|-----------|---------------------------------------| 00218 (+++) | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | 00219 (+++) |---------|---------|-----------|---------------------------------------| 00220 (+++) | 0 | 1 | 0 | | SB | 9 bit data | STB | | 00221 (+++) |---------|---------|-----------|---------------------------------------| 00222 (+++) | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | 00223 (+++) |---------|---------|-----------|---------------------------------------| 00224 (+++) | 1 | 0 | 0 | | SB | 7 bit data | STB | | 00225 (+++) |---------|---------|-----------|---------------------------------------| 00226 (+++) | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | 00227 (+++) +-----------------------------------------------------------------------+ 00228 00229 (++) Power mode 00230 (++) Prescaler setting 00231 (++) Receiver/transmitter modes 00232 00233 [..] 00234 The HAL_IRDA_Init() API follows the USART asynchronous configuration procedures 00235 (details for the procedures are available in reference manual). 00236 00237 @endverbatim 00238 * @{ 00239 */ 00240 00241 /** 00242 * @brief Initialize the IRDA mode according to the specified 00243 * parameters in the IRDA_InitTypeDef and initialize the associated handle. 00244 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00245 * the configuration information for the specified IRDA module. 00246 * @retval HAL status 00247 */ 00248 HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda) 00249 { 00250 /* Check the IRDA handle allocation */ 00251 if(hirda == NULL) 00252 { 00253 return HAL_ERROR; 00254 } 00255 00256 /* Check the USART/UART associated to the IRDA handle */ 00257 assert_param(IS_IRDA_INSTANCE(hirda->Instance)); 00258 00259 if(hirda->State == HAL_IRDA_STATE_RESET) 00260 { 00261 /* Allocate lock resource and initialize it */ 00262 hirda->Lock = HAL_UNLOCKED; 00263 00264 /* Init the low level hardware : GPIO, CLOCK */ 00265 HAL_IRDA_MspInit(hirda); 00266 } 00267 00268 hirda->State = HAL_IRDA_STATE_BUSY; 00269 00270 /* Disable the Peripheral to update the configuration registers */ 00271 __HAL_IRDA_DISABLE(hirda); 00272 00273 /* Set the IRDA Communication parameters */ 00274 if (IRDA_SetConfig(hirda) == HAL_ERROR) 00275 { 00276 return HAL_ERROR; 00277 } 00278 00279 /* In IRDA mode, the following bits must be kept cleared: 00280 - LINEN, STOP and CLKEN bits in the USART_CR2 register, 00281 - SCEN and HDSEL bits in the USART_CR3 register.*/ 00282 hirda->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP); 00283 hirda->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL); 00284 00285 /* set the UART/USART in IRDA mode */ 00286 hirda->Instance->CR3 |= USART_CR3_IREN; 00287 00288 /* Enable the Peripheral */ 00289 __HAL_IRDA_ENABLE(hirda); 00290 00291 /* TEACK and/or REACK to check before moving hirda->State to Ready */ 00292 return (IRDA_CheckIdleState(hirda)); 00293 } 00294 00295 /** 00296 * @brief DeInitialize the IRDA peripheral. 00297 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00298 * the configuration information for the specified IRDA module. 00299 * @retval HAL status 00300 */ 00301 HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda) 00302 { 00303 /* Check the IRDA handle allocation */ 00304 if(hirda == NULL) 00305 { 00306 return HAL_ERROR; 00307 } 00308 00309 /* Check the USART/UART associated to the IRDA handle */ 00310 assert_param(IS_IRDA_INSTANCE(hirda->Instance)); 00311 00312 hirda->State = HAL_IRDA_STATE_BUSY; 00313 00314 /* DeInit the low level hardware */ 00315 HAL_IRDA_MspDeInit(hirda); 00316 /* Disable the Peripheral */ 00317 __HAL_IRDA_DISABLE(hirda); 00318 00319 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 00320 hirda->State = HAL_IRDA_STATE_RESET; 00321 00322 /* Process Unlock */ 00323 __HAL_UNLOCK(hirda); 00324 00325 return HAL_OK; 00326 } 00327 00328 /** 00329 * @brief Initialize the IRDA MSP. 00330 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00331 * the configuration information for the specified IRDA module. 00332 * @retval None 00333 */ 00334 __weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda) 00335 { 00336 /* NOTE: This function should not be modified, when the callback is needed, 00337 the HAL_IRDA_MspInit can be implemented in the user file 00338 */ 00339 } 00340 00341 /** 00342 * @brief DeInitialize the IRDA MSP. 00343 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00344 * the configuration information for the specified IRDA module. 00345 * @retval None 00346 */ 00347 __weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda) 00348 { 00349 /* NOTE: This function should not be modified, when the callback is needed, 00350 the HAL_IRDA_MspDeInit can be implemented in the user file 00351 */ 00352 } 00353 00354 /** 00355 * @} 00356 */ 00357 00358 /** @defgroup IRDA_Exported_Functions_Group2 IO operation functions 00359 * @brief IRDA Transmit and Receive functions 00360 * 00361 @verbatim 00362 ============================================================================== 00363 ##### IO operation functions ##### 00364 ============================================================================== 00365 [..] 00366 This subsection provides a set of functions allowing to manage the IRDA data transfers. 00367 00368 [..] 00369 IrDA is a half duplex communication protocol. If the Transmitter is busy, any data 00370 on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver 00371 is busy, data on the TX from the USART to IrDA will not be encoded by IrDA. 00372 While receiving data, transmission should be avoided as the data to be transmitted 00373 could be corrupted. 00374 00375 (#) There are two modes of transfer: 00376 (++) Blocking mode: the communication is performed in polling mode. 00377 The HAL status of all data processing is returned by the same function 00378 after finishing transfer. 00379 (++) No-Blocking mode: the communication is performed using Interrupts 00380 or DMA, these API's return the HAL status. 00381 The end of the data processing will be indicated through the 00382 dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when 00383 using DMA mode. 00384 The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks 00385 will be executed respectively at the end of the Transmit or Receive process 00386 The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected 00387 00388 (#) Blocking mode APIs are : 00389 (++) HAL_IRDA_Transmit() 00390 (++) HAL_IRDA_Receive() 00391 00392 (#) Non Blocking mode APIs with Interrupt are : 00393 (++) HAL_IRDA_Transmit_IT() 00394 (++) HAL_IRDA_Receive_IT() 00395 (++) HAL_IRDA_IRQHandler() 00396 00397 (#) Non Blocking mode functions with DMA are : 00398 (++) HAL_IRDA_Transmit_DMA() 00399 (++) HAL_IRDA_Receive_DMA() 00400 (++) HAL_IRDA_DMAPause() 00401 (++) HAL_IRDA_DMAResume() 00402 (++) HAL_IRDA_DMAStop() 00403 00404 (#) A set of Transfer Complete Callbacks are provided in Non Blocking mode: 00405 (++) HAL_IRDA_TxHalfCpltCallback() 00406 (++) HAL_IRDA_TxCpltCallback() 00407 (++) HAL_IRDA_RxHalfCpltCallback() 00408 (++) HAL_IRDA_RxCpltCallback() 00409 (++) HAL_IRDA_ErrorCallback() 00410 00411 @endverbatim 00412 * @{ 00413 */ 00414 00415 /** 00416 * @brief Send an amount of data in blocking mode. 00417 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00418 * the configuration information for the specified IRDA module. 00419 * @param pData: Pointer to data buffer. 00420 * @param Size: Amount of data to be sent. 00421 * @param Timeout: Specify timeout value. 00422 * @retval HAL status 00423 */ 00424 HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout) 00425 { 00426 uint16_t* tmp; 00427 00428 if((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX)) 00429 { 00430 if((pData == NULL) || (Size == 0)) 00431 { 00432 return HAL_ERROR; 00433 } 00434 00435 /* Process Locked */ 00436 __HAL_LOCK(hirda); 00437 00438 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 00439 00440 if(hirda->State == HAL_IRDA_STATE_BUSY_RX) 00441 { 00442 hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; 00443 } 00444 else 00445 { 00446 hirda->State = HAL_IRDA_STATE_BUSY_TX; 00447 } 00448 00449 hirda->TxXferSize = Size; 00450 hirda->TxXferCount = Size; 00451 while(hirda->TxXferCount > 0) 00452 { 00453 hirda->TxXferCount--; 00454 00455 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, Timeout) != HAL_OK) 00456 { 00457 return HAL_TIMEOUT; 00458 } 00459 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) 00460 { 00461 tmp = (uint16_t*) pData; 00462 hirda->Instance->TDR = (*tmp & (uint16_t)0x01FF); 00463 pData +=2; 00464 } 00465 else 00466 { 00467 hirda->Instance->TDR = (*pData++ & (uint8_t)0xFF); 00468 } 00469 } 00470 00471 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, Timeout) != HAL_OK) 00472 { 00473 return HAL_TIMEOUT; 00474 } 00475 00476 if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) 00477 { 00478 hirda->State = HAL_IRDA_STATE_BUSY_RX; 00479 } 00480 else 00481 { 00482 hirda->State = HAL_IRDA_STATE_READY; 00483 } 00484 00485 /* Process Unlocked */ 00486 __HAL_UNLOCK(hirda); 00487 00488 return HAL_OK; 00489 } 00490 else 00491 { 00492 return HAL_BUSY; 00493 } 00494 } 00495 00496 /** 00497 * @brief Receive an amount of data in blocking mode. 00498 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00499 * the configuration information for the specified IRDA module. 00500 * @param pData: Pointer to data buffer. 00501 * @param Size: Amount of data to be received. 00502 * @param Timeout: Specify timeout value. 00503 * @retval HAL status 00504 */ 00505 HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout) 00506 { 00507 uint16_t* tmp; 00508 uint16_t uhMask; 00509 00510 if((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX)) 00511 { 00512 if((pData == NULL) || (Size == 0)) 00513 { 00514 return HAL_ERROR; 00515 } 00516 00517 /* Process Locked */ 00518 __HAL_LOCK(hirda); 00519 00520 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 00521 00522 if(hirda->State == HAL_IRDA_STATE_BUSY_TX) 00523 { 00524 hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; 00525 } 00526 else 00527 { 00528 hirda->State = HAL_IRDA_STATE_BUSY_RX; 00529 } 00530 00531 hirda->RxXferSize = Size; 00532 hirda->RxXferCount = Size; 00533 00534 /* Computation of the mask to apply to the RDR register 00535 of the UART associated to the IRDA */ 00536 IRDA_MASK_COMPUTATION(hirda); 00537 uhMask = hirda->Mask; 00538 00539 /* Check data remaining to be received */ 00540 while(hirda->RxXferCount > 0) 00541 { 00542 hirda->RxXferCount--; 00543 00544 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, Timeout) != HAL_OK) 00545 { 00546 return HAL_TIMEOUT; 00547 } 00548 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) 00549 { 00550 tmp = (uint16_t*) pData ; 00551 *tmp = (uint16_t)(hirda->Instance->RDR & uhMask); 00552 pData +=2; 00553 } 00554 else 00555 { 00556 *pData++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask); 00557 } 00558 } 00559 00560 if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) 00561 { 00562 hirda->State = HAL_IRDA_STATE_BUSY_TX; 00563 } 00564 else 00565 { 00566 hirda->State = HAL_IRDA_STATE_READY; 00567 } 00568 00569 /* Process Unlocked */ 00570 __HAL_UNLOCK(hirda); 00571 00572 return HAL_OK; 00573 } 00574 else 00575 { 00576 return HAL_BUSY; 00577 } 00578 } 00579 00580 /** 00581 * @brief Send an amount of data in interrupt mode. 00582 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00583 * the configuration information for the specified IRDA module. 00584 * @param pData: Pointer to data buffer. 00585 * @param Size: Amount of data to be sent. 00586 * @retval HAL status 00587 */ 00588 HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) 00589 { 00590 if((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX)) 00591 { 00592 if((pData == NULL) || (Size == 0)) 00593 { 00594 return HAL_ERROR; 00595 } 00596 00597 /* Process Locked */ 00598 __HAL_LOCK(hirda); 00599 00600 hirda->pTxBuffPtr = pData; 00601 hirda->TxXferSize = Size; 00602 hirda->TxXferCount = Size; 00603 00604 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 00605 00606 if(hirda->State == HAL_IRDA_STATE_BUSY_RX) 00607 { 00608 hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; 00609 } 00610 else 00611 { 00612 hirda->State = HAL_IRDA_STATE_BUSY_TX; 00613 } 00614 00615 /* Process Unlocked */ 00616 __HAL_UNLOCK(hirda); 00617 00618 /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ 00619 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_ERR); 00620 /* Enable the IRDA Transmit Data Register Empty Interrupt */ 00621 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TXE); 00622 00623 return HAL_OK; 00624 } 00625 else 00626 { 00627 return HAL_BUSY; 00628 } 00629 } 00630 00631 /** 00632 * @brief Receive an amount of data in interrupt mode. 00633 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00634 * the configuration information for the specified IRDA module. 00635 * @param pData: Pointer to data buffer. 00636 * @param Size: Amount of data to be received. 00637 * @retval HAL status 00638 */ 00639 HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) 00640 { 00641 if((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX)) 00642 { 00643 if((pData == NULL) || (Size == 0)) 00644 { 00645 return HAL_ERROR; 00646 } 00647 00648 /* Process Locked */ 00649 __HAL_LOCK(hirda); 00650 00651 hirda->pRxBuffPtr = pData; 00652 hirda->RxXferSize = Size; 00653 hirda->RxXferCount = Size; 00654 00655 /* Computation of the mask to apply to the RDR register 00656 of the UART associated to the IRDA */ 00657 IRDA_MASK_COMPUTATION(hirda); 00658 00659 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 00660 00661 if(hirda->State == HAL_IRDA_STATE_BUSY_TX) 00662 { 00663 hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; 00664 } 00665 else 00666 { 00667 hirda->State = HAL_IRDA_STATE_BUSY_RX; 00668 } 00669 00670 /* Process Unlocked */ 00671 __HAL_UNLOCK(hirda); 00672 00673 /* Enable the IRDA Data Register not empty Interrupt */ 00674 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_RXNE); 00675 00676 /* Enable the IRDA Parity Error Interrupt */ 00677 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_PE); 00678 00679 /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ 00680 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_ERR); 00681 00682 return HAL_OK; 00683 } 00684 else 00685 { 00686 return HAL_BUSY; 00687 } 00688 } 00689 00690 /** 00691 * @brief Send an amount of data in DMA mode. 00692 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00693 * the configuration information for the specified IRDA module. 00694 * @param pData: pointer to data buffer. 00695 * @param Size: amount of data to be sent. 00696 * @retval HAL status 00697 */ 00698 HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) 00699 { 00700 uint32_t *tmp; 00701 00702 if((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX)) 00703 { 00704 if((pData == NULL) || (Size == 0)) 00705 { 00706 return HAL_ERROR; 00707 } 00708 00709 /* Process Locked */ 00710 __HAL_LOCK(hirda); 00711 00712 hirda->pTxBuffPtr = pData; 00713 hirda->TxXferSize = Size; 00714 hirda->TxXferCount = Size; 00715 00716 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 00717 00718 if(hirda->State == HAL_IRDA_STATE_BUSY_RX) 00719 { 00720 hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; 00721 } 00722 else 00723 { 00724 hirda->State = HAL_IRDA_STATE_BUSY_TX; 00725 } 00726 00727 /* Set the IRDA DMA transfer complete callback */ 00728 hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt; 00729 00730 /* Set the IRDA DMA half transfer complete callback */ 00731 hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt; 00732 00733 /* Set the DMA error callback */ 00734 hirda->hdmatx->XferErrorCallback = IRDA_DMAError; 00735 00736 /* Enable the IRDA transmit DMA channel */ 00737 tmp = (uint32_t*)&pData; 00738 HAL_DMA_Start_IT(hirda->hdmatx, *(uint32_t*)tmp, (uint32_t)&hirda->Instance->TDR, Size); 00739 00740 /* Clear the TC flag in the ICR register */ 00741 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_TCF); 00742 00743 /* Enable the DMA transfer for transmit request by setting the DMAT bit 00744 in the USART CR3 register */ 00745 hirda->Instance->CR3 |= USART_CR3_DMAT; 00746 00747 /* Process Unlocked */ 00748 __HAL_UNLOCK(hirda); 00749 00750 return HAL_OK; 00751 } 00752 else 00753 { 00754 return HAL_BUSY; 00755 } 00756 } 00757 00758 /** 00759 * @brief Receive an amount of data in DMA mode. 00760 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00761 * the configuration information for the specified IRDA module. 00762 * @param pData: Pointer to data buffer. 00763 * @param Size: Amount of data to be received. 00764 * @note When the IRDA parity is enabled (PCE = 1) the received data contains 00765 * the parity bit (MSB position). 00766 * @retval HAL status 00767 */ 00768 HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) 00769 { 00770 uint32_t *tmp; 00771 00772 if((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX)) 00773 { 00774 if((pData == NULL) || (Size == 0)) 00775 { 00776 return HAL_ERROR; 00777 } 00778 00779 /* Process Locked */ 00780 __HAL_LOCK(hirda); 00781 00782 hirda->pRxBuffPtr = pData; 00783 hirda->RxXferSize = Size; 00784 00785 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 00786 00787 if(hirda->State == HAL_IRDA_STATE_BUSY_TX) 00788 { 00789 hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; 00790 } 00791 else 00792 { 00793 hirda->State = HAL_IRDA_STATE_BUSY_RX; 00794 } 00795 00796 /* Set the IRDA DMA transfer complete callback */ 00797 hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt; 00798 00799 /* Set the IRDA DMA half transfer complete callback */ 00800 hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt; 00801 00802 /* Set the DMA error callback */ 00803 hirda->hdmarx->XferErrorCallback = IRDA_DMAError; 00804 00805 /* Enable the DMA channel */ 00806 tmp = (uint32_t*)&pData; 00807 HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->RDR, *(uint32_t*)tmp, Size); 00808 00809 /* Enable the DMA transfer for the receiver request by setting the DMAR bit 00810 in the USART CR3 register */ 00811 hirda->Instance->CR3 |= USART_CR3_DMAR; 00812 00813 /* Process Unlocked */ 00814 __HAL_UNLOCK(hirda); 00815 00816 return HAL_OK; 00817 } 00818 else 00819 { 00820 return HAL_BUSY; 00821 } 00822 } 00823 00824 00825 /** 00826 * @brief Pause the DMA Transfer. 00827 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00828 * the configuration information for the specified IRDA module. 00829 * @retval HAL status 00830 */ 00831 HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda) 00832 { 00833 /* Process Locked */ 00834 __HAL_LOCK(hirda); 00835 00836 if(hirda->State == HAL_IRDA_STATE_BUSY_TX) 00837 { 00838 /* Disable the IRDA DMA Tx request */ 00839 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); 00840 } 00841 else if(hirda->State == HAL_IRDA_STATE_BUSY_RX) 00842 { 00843 /* Disable the IRDA DMA Rx request */ 00844 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); 00845 } 00846 else if (hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) 00847 { 00848 /* Disable the IRDA DMA Tx & Rx requests */ 00849 CLEAR_BIT(hirda->Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR)); 00850 } 00851 else 00852 { 00853 /* Process Unlocked */ 00854 __HAL_UNLOCK(hirda); 00855 00856 return HAL_ERROR; 00857 } 00858 00859 /* Process Unlocked */ 00860 __HAL_UNLOCK(hirda); 00861 00862 return HAL_OK; 00863 } 00864 00865 /** 00866 * @brief Resume the DMA Transfer. 00867 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00868 * the configuration information for the specified UART module. 00869 * @retval HAL status 00870 */ 00871 HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda) 00872 { 00873 /* Process Locked */ 00874 __HAL_LOCK(hirda); 00875 00876 if(hirda->State == HAL_IRDA_STATE_BUSY_TX) 00877 { 00878 /* Enable the IRDA DMA Tx request */ 00879 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT); 00880 } 00881 else if(hirda->State == HAL_IRDA_STATE_BUSY_RX) 00882 { 00883 /* Clear the Overrun flag before resuming the Rx transfer*/ 00884 __HAL_IRDA_CLEAR_OREFLAG(hirda); 00885 /* Enable the IRDA DMA Rx request */ 00886 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR); 00887 } 00888 else if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) 00889 { 00890 /* Clear the Overrun flag before resuming the Rx transfer*/ 00891 __HAL_IRDA_CLEAR_OREFLAG(hirda); 00892 /* Enable the IRDA DMA Tx & Rx request */ 00893 SET_BIT(hirda->Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR)); 00894 } 00895 else 00896 { 00897 /* Process Unlocked */ 00898 __HAL_UNLOCK(hirda); 00899 00900 return HAL_ERROR; 00901 } 00902 00903 /* Process Unlocked */ 00904 __HAL_UNLOCK(hirda); 00905 00906 return HAL_OK; 00907 } 00908 00909 /** 00910 * @brief Stop the DMA Transfer. 00911 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00912 * the configuration information for the specified UART module. 00913 * @retval HAL status 00914 */ 00915 HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda) 00916 { 00917 /* The Lock is not implemented on this API to allow the user application 00918 to call the HAL IRDA API under callbacks HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback() / 00919 HAL_IRDA_TxHalfCpltCallback / HAL_IRDA_RxHalfCpltCallback: 00920 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete 00921 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of 00922 the stream and the corresponding call back is executed. */ 00923 00924 /* Disable the IRDA Tx/Rx DMA requests */ 00925 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); 00926 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); 00927 00928 /* Abort the IRDA DMA tx channel */ 00929 if(hirda->hdmatx != NULL) 00930 { 00931 HAL_DMA_Abort(hirda->hdmatx); 00932 } 00933 /* Abort the IRDA DMA rx channel */ 00934 if(hirda->hdmarx != NULL) 00935 { 00936 HAL_DMA_Abort(hirda->hdmarx); 00937 } 00938 00939 hirda->State = HAL_IRDA_STATE_READY; 00940 00941 return HAL_OK; 00942 } 00943 00944 00945 /** 00946 * @brief Handle IRDA interrupt request. 00947 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00948 * the configuration information for the specified IRDA module. 00949 * @retval None 00950 */ 00951 void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda) 00952 { 00953 /* IRDA parity error interrupt occurred -------------------------------------*/ 00954 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_PE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_PE) != RESET)) 00955 { 00956 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_PEF); 00957 00958 hirda->ErrorCode |= HAL_IRDA_ERROR_PE; 00959 /* Set the IRDA state ready to be able to start again the process */ 00960 hirda->State = HAL_IRDA_STATE_READY; 00961 } 00962 00963 /* IRDA frame error interrupt occurred --------------------------------------*/ 00964 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_FE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET)) 00965 { 00966 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_FEF); 00967 00968 hirda->ErrorCode |= HAL_IRDA_ERROR_FE; 00969 /* Set the IRDA state ready to be able to start again the process */ 00970 hirda->State = HAL_IRDA_STATE_READY; 00971 } 00972 00973 /* IRDA noise error interrupt occurred --------------------------------------*/ 00974 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_NE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET)) 00975 { 00976 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_NEF); 00977 00978 hirda->ErrorCode |= HAL_IRDA_ERROR_NE; 00979 /* Set the IRDA state ready to be able to start again the process */ 00980 hirda->State = HAL_IRDA_STATE_READY; 00981 } 00982 00983 /* IRDA Over-Run interrupt occurred -----------------------------------------*/ 00984 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_ORE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET)) 00985 { 00986 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF); 00987 00988 hirda->ErrorCode |= HAL_IRDA_ERROR_ORE; 00989 /* Set the IRDA state ready to be able to start again the process */ 00990 hirda->State = HAL_IRDA_STATE_READY; 00991 } 00992 00993 /* Call IRDA Error Call back function if need be --------------------------*/ 00994 if(hirda->ErrorCode != HAL_IRDA_ERROR_NONE) 00995 { 00996 HAL_IRDA_ErrorCallback(hirda); 00997 } 00998 00999 /* IRDA in mode Receiver ---------------------------------------------------*/ 01000 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_RXNE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_RXNE) != RESET)) 01001 { 01002 IRDA_Receive_IT(hirda); 01003 /* Clear RXNE interrupt flag */ 01004 __HAL_IRDA_SEND_REQ(hirda, IRDA_RXDATA_FLUSH_REQUEST); 01005 } 01006 01007 01008 /* IRDA in mode Transmitter ------------------------------------------------*/ 01009 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_TXE) != RESET) &&(__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TXE) != RESET)) 01010 { 01011 IRDA_Transmit_IT(hirda); 01012 } 01013 01014 /* IRDA in mode Transmitter (transmission end) -----------------------------*/ 01015 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_TC) != RESET) &&(__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TC) != RESET)) 01016 { 01017 IRDA_EndTransmit_IT(hirda); 01018 } 01019 01020 } 01021 01022 /** 01023 * @brief Tx Transfer completed callback. 01024 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01025 * the configuration information for the specified IRDA module. 01026 * @retval None 01027 */ 01028 __weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda) 01029 { 01030 /* NOTE: This function should not be modified, when the callback is needed, 01031 the HAL_IRDA_TxCpltCallback can be implemented in the user file. 01032 */ 01033 } 01034 01035 /** 01036 * @brief Tx Half Transfer completed callback. 01037 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01038 * the configuration information for the specified USART module. 01039 * @retval None 01040 */ 01041 __weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda) 01042 { 01043 /* NOTE: This function should not be modified, when the callback is needed, 01044 the HAL_IRDA_TxHalfCpltCallback can be implemented in the user file. 01045 */ 01046 } 01047 01048 /** 01049 * @brief Rx Transfer completed callback. 01050 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01051 * the configuration information for the specified IRDA module. 01052 * @retval None 01053 */ 01054 __weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda) 01055 { 01056 /* NOTE: This function should not be modified, when the callback is needed, 01057 the HAL_IRDA_RxCpltCallback can be implemented in the user file. 01058 */ 01059 } 01060 01061 /** 01062 * @brief Rx Half Transfer complete callback. 01063 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01064 * the configuration information for the specified IRDA module. 01065 * @retval None 01066 */ 01067 __weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda) 01068 { 01069 /* NOTE : This function should not be modified, when the callback is needed, 01070 the HAL_IRDA_RxHalfCpltCallback can be implemented in the user file. 01071 */ 01072 } 01073 01074 /** 01075 * @brief IRDA error callback. 01076 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01077 * the configuration information for the specified IRDA module. 01078 * @retval None 01079 */ 01080 __weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda) 01081 { 01082 /* NOTE: This function should not be modified, when the callback is needed, 01083 the HAL_IRDA_ErrorCallback can be implemented in the user file. 01084 */ 01085 } 01086 01087 /** 01088 * @} 01089 */ 01090 01091 /** @defgroup IRDA_Exported_Functions_Group4 Peripheral State and Error functions 01092 * @brief IRDA State and Errors functions 01093 * 01094 @verbatim 01095 ============================================================================== 01096 ##### Peripheral State and Errors functions ##### 01097 ============================================================================== 01098 [..] 01099 This subsection provides a set of functions allowing to return the State of IrDA 01100 communication process and also return Peripheral Errors occurred during communication process 01101 (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state 01102 of the IRDA peripheral handle. 01103 (+) HAL_IRDA_GetError() checks in run-time errors that could occur during 01104 communication. 01105 01106 @endverbatim 01107 * @{ 01108 */ 01109 01110 /** 01111 * @brief Return the IRDA handle state. 01112 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01113 * the configuration information for the specified IRDA module. 01114 * @retval HAL state 01115 */ 01116 HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda) 01117 { 01118 /* Return IRDA handle state */ 01119 return hirda->State; 01120 } 01121 01122 /** 01123 * @brief Return the IRDA handle error code. 01124 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01125 * the configuration information for the specified IRDA module. 01126 * @retval IRDA Error Code 01127 */ 01128 uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda) 01129 { 01130 return hirda->ErrorCode; 01131 } 01132 01133 /** 01134 * @} 01135 */ 01136 01137 /** 01138 * @} 01139 */ 01140 01141 /** @defgroup IRDA_Private_Functions IRDA Private Functions 01142 * @{ 01143 */ 01144 01145 /** 01146 * @brief DMA IRDA transmit process complete callback. 01147 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains 01148 * the configuration information for the specified DMA module. 01149 * @retval None 01150 */ 01151 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma) 01152 { 01153 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01154 01155 /* DMA Normal mode */ 01156 if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) 01157 { 01158 hirda->TxXferCount = 0; 01159 01160 /* Disable the DMA transfer for transmit request by resetting the DMAT bit 01161 in the IRDA CR3 register */ 01162 hirda->Instance->CR3 &= ~(USART_CR3_DMAT); 01163 01164 /* Enable the IRDA Transmit Complete Interrupt */ 01165 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC); 01166 } 01167 /* DMA Circular mode */ 01168 else 01169 { 01170 HAL_IRDA_TxCpltCallback(hirda); 01171 } 01172 } 01173 01174 /** 01175 * @brief DMA IRDA receive process half complete callback. 01176 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains 01177 * the configuration information for the specified DMA module. 01178 * @retval None 01179 */ 01180 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma) 01181 { 01182 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01183 01184 HAL_IRDA_TxHalfCpltCallback(hirda); 01185 } 01186 01187 /** 01188 * @brief DMA IRDA receive process complete callback. 01189 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains 01190 * the configuration information for the specified DMA module. 01191 * @retval None 01192 */ 01193 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma) 01194 { 01195 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01196 01197 /* DMA Normal mode */ 01198 if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) 01199 { 01200 hirda->RxXferCount = 0; 01201 01202 /* Disable the DMA transfer for the receiver request by resetting the DMAR bit 01203 in the IRDA CR3 register */ 01204 hirda->Instance->CR3 &= ~(USART_CR3_DMAR); 01205 01206 if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) 01207 { 01208 hirda->State = HAL_IRDA_STATE_BUSY_TX; 01209 } 01210 else 01211 { 01212 hirda->State = HAL_IRDA_STATE_READY; 01213 } 01214 } 01215 01216 HAL_IRDA_RxCpltCallback(hirda); 01217 } 01218 01219 /** 01220 * @brief DMA IRDA receive process half complete callback. 01221 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains 01222 * the configuration information for the specified DMA module. 01223 * @retval None 01224 */ 01225 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma) 01226 { 01227 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01228 01229 HAL_IRDA_RxHalfCpltCallback(hirda); 01230 } 01231 01232 /** 01233 * @brief DMA IRDA communication error callback. 01234 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains 01235 * the configuration information for the specified DMA module. 01236 * @retval None 01237 */ 01238 static void IRDA_DMAError(DMA_HandleTypeDef *hdma) 01239 { 01240 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01241 01242 hirda->RxXferCount = 0; 01243 hirda->TxXferCount = 0; 01244 hirda->ErrorCode |= HAL_IRDA_ERROR_DMA; 01245 hirda->State= HAL_IRDA_STATE_READY; 01246 01247 HAL_IRDA_ErrorCallback(hirda); 01248 } 01249 01250 /** 01251 * @brief Handle IRDA Communication Timeout. 01252 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01253 * the configuration information for the specified IRDA module. 01254 * @param Flag: specifies the IRDA flag to check. 01255 * @param Status: the new flag status (SET or RESET). The function is locked in a while loop as long as the flag remains set to Status. 01256 * @param Timeout: Timeout duration 01257 * @retval HAL status 01258 */ 01259 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Timeout) 01260 { 01261 uint32_t tickstart = HAL_GetTick(); 01262 01263 /* Wait until flag is set */ 01264 if(Status == RESET) 01265 { 01266 while(__HAL_IRDA_GET_FLAG(hirda, Flag) == RESET) 01267 { 01268 /* Check for the Timeout */ 01269 if(Timeout != HAL_MAX_DELAY) 01270 { 01271 if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout)) 01272 { 01273 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ 01274 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE); 01275 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE); 01276 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE); 01277 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR); 01278 01279 hirda->State= HAL_IRDA_STATE_READY; 01280 01281 /* Process Unlocked */ 01282 __HAL_UNLOCK(hirda); 01283 01284 return HAL_TIMEOUT; 01285 } 01286 } 01287 } 01288 } 01289 else 01290 { 01291 while(__HAL_IRDA_GET_FLAG(hirda, Flag) != RESET) 01292 { 01293 /* Check for the Timeout */ 01294 if(Timeout != HAL_MAX_DELAY) 01295 { 01296 if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout)) 01297 { 01298 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ 01299 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE); 01300 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE); 01301 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE); 01302 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR); 01303 01304 hirda->State= HAL_IRDA_STATE_READY; 01305 01306 /* Process Unlocked */ 01307 __HAL_UNLOCK(hirda); 01308 01309 return HAL_TIMEOUT; 01310 } 01311 } 01312 } 01313 } 01314 return HAL_OK; 01315 } 01316 01317 /** 01318 * @brief Send an amount of data in non-blocking mode. 01319 * @note Function is called under interruption only, once 01320 * interruptions have been enabled by HAL_IRDA_Transmit_IT(). 01321 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01322 * the configuration information for the specified IRDA module. 01323 * @retval HAL status 01324 */ 01325 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda) 01326 { 01327 uint16_t* tmp; 01328 01329 if((hirda->State == HAL_IRDA_STATE_BUSY_TX) || (hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)) 01330 { 01331 if(hirda->TxXferCount == 0) 01332 { 01333 /* Disable the IRDA Transmit Data Register Empty Interrupt */ 01334 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE); 01335 01336 /* Enable the IRDA Transmit Complete Interrupt */ 01337 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC); 01338 01339 return HAL_OK; 01340 } 01341 else 01342 { 01343 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) 01344 { 01345 tmp = (uint16_t*) hirda->pTxBuffPtr; 01346 hirda->Instance->TDR = (*tmp & (uint16_t)0x01FF); 01347 hirda->pTxBuffPtr += 2; 01348 } 01349 else 01350 { 01351 hirda->Instance->TDR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0xFF); 01352 } 01353 hirda->TxXferCount--; 01354 01355 return HAL_OK; 01356 } 01357 } 01358 else 01359 { 01360 return HAL_BUSY; 01361 } 01362 } 01363 01364 /** 01365 * @brief Wrap up transmission in non-blocking mode. 01366 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains 01367 * the configuration information for the specified IRDA module. 01368 * @retval HAL status 01369 */ 01370 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda) 01371 { 01372 /* Disable the IRDA Transmit Complete Interrupt */ 01373 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TC); 01374 01375 /* Check if a receive process is ongoing or not */ 01376 if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) 01377 { 01378 hirda->State = HAL_IRDA_STATE_BUSY_RX; 01379 } 01380 else 01381 { 01382 /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ 01383 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR); 01384 01385 hirda->State = HAL_IRDA_STATE_READY; 01386 } 01387 01388 HAL_IRDA_TxCpltCallback(hirda); 01389 01390 return HAL_OK; 01391 } 01392 01393 01394 /** 01395 * @brief Receive an amount of data in non-blocking mode. 01396 * Function is called under interruption only, once 01397 * interruptions have been enabled by HAL_IRDA_Receive_IT(). 01398 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01399 * the configuration information for the specified IRDA module. 01400 * @retval HAL status 01401 */ 01402 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda) 01403 { 01404 uint16_t* tmp; 01405 uint16_t uhMask = hirda->Mask; 01406 01407 if ((hirda->State == HAL_IRDA_STATE_BUSY_RX) || (hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)) 01408 { 01409 01410 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) 01411 { 01412 tmp = (uint16_t*) hirda->pRxBuffPtr ; 01413 *tmp = (uint16_t)(hirda->Instance->RDR & uhMask); 01414 hirda->pRxBuffPtr +=2; 01415 } 01416 else 01417 { 01418 *hirda->pRxBuffPtr++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask); 01419 } 01420 01421 if(--hirda->RxXferCount == 0) 01422 { 01423 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE); 01424 01425 if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) 01426 { 01427 hirda->State = HAL_IRDA_STATE_BUSY_TX; 01428 } 01429 else 01430 { 01431 /* Disable the IRDA Parity Error Interrupt */ 01432 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE); 01433 01434 /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ 01435 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR); 01436 01437 hirda->State = HAL_IRDA_STATE_READY; 01438 } 01439 01440 HAL_IRDA_RxCpltCallback(hirda); 01441 01442 return HAL_OK; 01443 } 01444 01445 return HAL_OK; 01446 } 01447 else 01448 { 01449 return HAL_BUSY; 01450 } 01451 } 01452 01453 /** 01454 * @brief Configure the IRDA peripheral. 01455 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01456 * the configuration information for the specified IRDA module. 01457 * @retval None 01458 */ 01459 static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda) 01460 { 01461 uint32_t tmpreg = 0x00000000; 01462 IRDA_ClockSourceTypeDef clocksource = IRDA_CLOCKSOURCE_UNDEFINED; 01463 HAL_StatusTypeDef ret = HAL_OK; 01464 01465 /* Check the communication parameters */ 01466 assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate)); 01467 assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength)); 01468 assert_param(IS_IRDA_PARITY(hirda->Init.Parity)); 01469 assert_param(IS_IRDA_TX_RX_MODE(hirda->Init.Mode)); 01470 assert_param(IS_IRDA_PRESCALER(hirda->Init.Prescaler)); 01471 assert_param(IS_IRDA_POWERMODE(hirda->Init.PowerMode)); 01472 01473 /*-------------------------- USART CR1 Configuration -----------------------*/ 01474 /* Configure the IRDA Word Length, Parity and transfer Mode: 01475 Set the M bits according to hirda->Init.WordLength value 01476 Set PCE and PS bits according to hirda->Init.Parity value 01477 Set TE and RE bits according to hirda->Init.Mode value */ 01478 tmpreg = (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode ; 01479 01480 MODIFY_REG(hirda->Instance->CR1, IRDA_CR1_FIELDS, tmpreg); 01481 01482 /*-------------------------- USART CR3 Configuration -----------------------*/ 01483 MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.PowerMode); 01484 01485 /*-------------------------- USART GTPR Configuration ----------------------*/ 01486 MODIFY_REG(hirda->Instance->GTPR, USART_GTPR_PSC, hirda->Init.Prescaler); 01487 01488 /*-------------------------- USART BRR Configuration -----------------------*/ 01489 IRDA_GETCLOCKSOURCE(hirda, clocksource); 01490 switch (clocksource) 01491 { 01492 case IRDA_CLOCKSOURCE_PCLK1: 01493 hirda->Instance->BRR = (uint16_t)(HAL_RCC_GetPCLK1Freq() / hirda->Init.BaudRate); 01494 break; 01495 case IRDA_CLOCKSOURCE_PCLK2: 01496 hirda->Instance->BRR = (uint16_t)(HAL_RCC_GetPCLK2Freq() / hirda->Init.BaudRate); 01497 break; 01498 case IRDA_CLOCKSOURCE_HSI: 01499 hirda->Instance->BRR = (uint16_t)(HSI_VALUE / hirda->Init.BaudRate); 01500 break; 01501 case IRDA_CLOCKSOURCE_SYSCLK: 01502 hirda->Instance->BRR = (uint16_t)(HAL_RCC_GetSysClockFreq() / hirda->Init.BaudRate); 01503 break; 01504 case IRDA_CLOCKSOURCE_LSE: 01505 hirda->Instance->BRR = (uint16_t)(LSE_VALUE / hirda->Init.BaudRate); 01506 break; 01507 case IRDA_CLOCKSOURCE_UNDEFINED: 01508 default: 01509 ret = HAL_ERROR; 01510 break; 01511 } 01512 01513 return ret; 01514 } 01515 01516 /** 01517 * @brief Check the IRDA Idle State. 01518 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01519 * the configuration information for the specified IRDA module. 01520 * @retval HAL status 01521 */ 01522 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda) 01523 { 01524 01525 /* Initialize the IRDA ErrorCode */ 01526 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 01527 01528 /* Check if the Transmitter is enabled */ 01529 if((hirda->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) 01530 { 01531 /* Wait until TEACK flag is set */ 01532 if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK) 01533 { 01534 /* Timeout occurred */ 01535 return HAL_TIMEOUT; 01536 } 01537 } 01538 /* Check if the Receiver is enabled */ 01539 if((hirda->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) 01540 { 01541 if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK) 01542 { 01543 /* Timeout occurred */ 01544 return HAL_TIMEOUT; 01545 } 01546 } 01547 01548 /* Initialize the IRDA state*/ 01549 hirda->State= HAL_IRDA_STATE_READY; 01550 /* Process Unlocked */ 01551 __HAL_UNLOCK(hirda); 01552 01553 return HAL_OK; 01554 } 01555 01556 /** 01557 * @} 01558 */ 01559 01560 #endif /* HAL_IRDA_MODULE_ENABLED */ 01561 /** 01562 * @} 01563 */ 01564 01565 /** 01566 * @} 01567 */ 01568 01569 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 01570
Generated on Tue Jul 12 2022 10:58:09 by 1.7.2