Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
stm32l4xx_hal_irda.c
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_irda.c 00004 * @author MCD Application Team 00005 * @version V1.5.1 00006 * @date 31-May-2016 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) 2016 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 Tickstart, 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 (++) Power mode 00210 (++) Prescaler setting 00211 (++) Receiver/transmitter modes 00212 00213 [..] 00214 The HAL_IRDA_Init() API follows the USART asynchronous configuration procedures 00215 (details for the procedures are available in reference manual). 00216 00217 @endverbatim 00218 00219 Depending on the frame length defined by the M1 and M0 bits (7-bit, 00220 8-bit or 9-bit), the possible IRDA frame formats are listed in the 00221 following table. 00222 00223 Table 1. IRDA frame format. 00224 +-----------------------------------------------------------------------+ 00225 | M1 bit | M0 bit | PCE bit | IRDA frame | 00226 |---------|---------|-----------|---------------------------------------| 00227 | 0 | 0 | 0 | | SB | 8 bit data | STB | | 00228 |---------|---------|-----------|---------------------------------------| 00229 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | 00230 |---------|---------|-----------|---------------------------------------| 00231 | 0 | 1 | 0 | | SB | 9 bit data | STB | | 00232 |---------|---------|-----------|---------------------------------------| 00233 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | 00234 |---------|---------|-----------|---------------------------------------| 00235 | 1 | 0 | 0 | | SB | 7 bit data | STB | | 00236 |---------|---------|-----------|---------------------------------------| 00237 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | 00238 +-----------------------------------------------------------------------+ 00239 00240 * @{ 00241 */ 00242 00243 /** 00244 * @brief Initialize the IRDA mode according to the specified 00245 * parameters in the IRDA_InitTypeDef and initialize the associated handle. 00246 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00247 * the configuration information for the specified IRDA module. 00248 * @retval HAL status 00249 */ 00250 HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda) 00251 { 00252 /* Check the IRDA handle allocation */ 00253 if(hirda == NULL) 00254 { 00255 return HAL_ERROR; 00256 } 00257 00258 /* Check the USART/UART associated to the IRDA handle */ 00259 assert_param(IS_IRDA_INSTANCE(hirda->Instance)); 00260 00261 if(hirda->gState == HAL_IRDA_STATE_RESET) 00262 { 00263 /* Allocate lock resource and initialize it */ 00264 hirda->Lock = HAL_UNLOCKED; 00265 00266 /* Init the low level hardware : GPIO, CLOCK */ 00267 HAL_IRDA_MspInit(hirda); 00268 } 00269 00270 hirda->gState = HAL_IRDA_STATE_BUSY; 00271 00272 /* Disable the Peripheral to update the configuration registers */ 00273 __HAL_IRDA_DISABLE(hirda); 00274 00275 /* Set the IRDA Communication parameters */ 00276 if (IRDA_SetConfig(hirda) == HAL_ERROR) 00277 { 00278 return HAL_ERROR; 00279 } 00280 00281 /* In IRDA mode, the following bits must be kept cleared: 00282 - LINEN, STOP and CLKEN bits in the USART_CR2 register, 00283 - SCEN and HDSEL bits in the USART_CR3 register.*/ 00284 hirda->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP); 00285 hirda->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL); 00286 00287 /* set the UART/USART in IRDA mode */ 00288 hirda->Instance->CR3 |= USART_CR3_IREN; 00289 00290 /* Enable the Peripheral */ 00291 __HAL_IRDA_ENABLE(hirda); 00292 00293 /* TEACK and/or REACK to check before moving hirda->gState and hirda->RxState to Ready */ 00294 return (IRDA_CheckIdleState(hirda)); 00295 } 00296 00297 /** 00298 * @brief DeInitialize the IRDA peripheral. 00299 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00300 * the configuration information for the specified IRDA module. 00301 * @retval HAL status 00302 */ 00303 HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda) 00304 { 00305 /* Check the IRDA handle allocation */ 00306 if(hirda == NULL) 00307 { 00308 return HAL_ERROR; 00309 } 00310 00311 /* Check the USART/UART associated to the IRDA handle */ 00312 assert_param(IS_IRDA_INSTANCE(hirda->Instance)); 00313 00314 hirda->gState = HAL_IRDA_STATE_BUSY; 00315 00316 /* DeInit the low level hardware */ 00317 HAL_IRDA_MspDeInit(hirda); 00318 /* Disable the Peripheral */ 00319 __HAL_IRDA_DISABLE(hirda); 00320 00321 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 00322 hirda->gState = HAL_IRDA_STATE_RESET; 00323 hirda->RxState = HAL_IRDA_STATE_RESET; 00324 00325 /* Process Unlock */ 00326 __HAL_UNLOCK(hirda); 00327 00328 return HAL_OK; 00329 } 00330 00331 /** 00332 * @brief Initialize the IRDA MSP. 00333 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00334 * the configuration information for the specified IRDA module. 00335 * @retval None 00336 */ 00337 __weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda) 00338 { 00339 /* Prevent unused argument(s) compilation warning */ 00340 UNUSED(hirda); 00341 00342 /* NOTE: This function should not be modified, when the callback is needed, 00343 the HAL_IRDA_MspInit can be implemented in the user file 00344 */ 00345 } 00346 00347 /** 00348 * @brief DeInitialize the IRDA MSP. 00349 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00350 * the configuration information for the specified IRDA module. 00351 * @retval None 00352 */ 00353 __weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda) 00354 { 00355 /* Prevent unused argument(s) compilation warning */ 00356 UNUSED(hirda); 00357 00358 /* NOTE: This function should not be modified, when the callback is needed, 00359 the HAL_IRDA_MspDeInit can be implemented in the user file 00360 */ 00361 } 00362 00363 /** 00364 * @} 00365 */ 00366 00367 /** @defgroup IRDA_Exported_Functions_Group2 IO operation functions 00368 * @brief IRDA Transmit and Receive functions 00369 * 00370 @verbatim 00371 ============================================================================== 00372 ##### IO operation functions ##### 00373 ============================================================================== 00374 [..] 00375 This subsection provides a set of functions allowing to manage the IRDA data transfers. 00376 00377 [..] 00378 IrDA is a half duplex communication protocol. If the Transmitter is busy, any data 00379 on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver 00380 is busy, data on the TX from the USART to IrDA will not be encoded by IrDA. 00381 While receiving data, transmission should be avoided as the data to be transmitted 00382 could be corrupted. 00383 00384 (#) There are two modes of transfer: 00385 (++) Blocking mode: the communication is performed in polling mode. 00386 The HAL status of all data processing is returned by the same function 00387 after finishing transfer. 00388 (++) No-Blocking mode: the communication is performed using Interrupts 00389 or DMA, these API's return the HAL status. 00390 The end of the data processing will be indicated through the 00391 dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when 00392 using DMA mode. 00393 The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks 00394 will be executed respectively at the end of the Transmit or Receive process 00395 The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected 00396 00397 (#) Blocking mode APIs are : 00398 (++) HAL_IRDA_Transmit() 00399 (++) HAL_IRDA_Receive() 00400 00401 (#) Non Blocking mode APIs with Interrupt are : 00402 (++) HAL_IRDA_Transmit_IT() 00403 (++) HAL_IRDA_Receive_IT() 00404 (++) HAL_IRDA_IRQHandler() 00405 00406 (#) Non Blocking mode functions with DMA are : 00407 (++) HAL_IRDA_Transmit_DMA() 00408 (++) HAL_IRDA_Receive_DMA() 00409 (++) HAL_IRDA_DMAPause() 00410 (++) HAL_IRDA_DMAResume() 00411 (++) HAL_IRDA_DMAStop() 00412 00413 (#) A set of Transfer Complete Callbacks are provided in Non Blocking mode: 00414 (++) HAL_IRDA_TxHalfCpltCallback() 00415 (++) HAL_IRDA_TxCpltCallback() 00416 (++) HAL_IRDA_RxHalfCpltCallback() 00417 (++) HAL_IRDA_RxCpltCallback() 00418 (++) HAL_IRDA_ErrorCallback() 00419 00420 @endverbatim 00421 * @{ 00422 */ 00423 00424 /** 00425 * @brief Send an amount of data in blocking mode. 00426 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00427 * the configuration information for the specified IRDA module. 00428 * @param pData: Pointer to data buffer. 00429 * @param Size: Amount of data to be sent. 00430 * @param Timeout: Specify timeout value. 00431 * @retval HAL status 00432 */ 00433 HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout) 00434 { 00435 uint16_t* tmp; 00436 uint32_t tickstart = 0; 00437 00438 /* Check that a Tx process is not already ongoing */ 00439 if(hirda->gState == HAL_IRDA_STATE_READY) 00440 { 00441 if((pData == NULL) || (Size == 0)) 00442 { 00443 return HAL_ERROR; 00444 } 00445 00446 /* Process Locked */ 00447 __HAL_LOCK(hirda); 00448 00449 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 00450 00451 hirda->gState = HAL_IRDA_STATE_BUSY_TX; 00452 00453 /* Init tickstart for timeout managment*/ 00454 tickstart = HAL_GetTick(); 00455 00456 hirda->TxXferSize = Size; 00457 hirda->TxXferCount = Size; 00458 while(hirda->TxXferCount > 0) 00459 { 00460 hirda->TxXferCount--; 00461 00462 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) 00463 { 00464 return HAL_TIMEOUT; 00465 } 00466 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) 00467 { 00468 tmp = (uint16_t*) pData; 00469 hirda->Instance->TDR = (*tmp & (uint16_t)0x01FF); 00470 pData +=2; 00471 } 00472 else 00473 { 00474 hirda->Instance->TDR = (*pData++ & (uint8_t)0xFF); 00475 } 00476 } 00477 00478 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) 00479 { 00480 return HAL_TIMEOUT; 00481 } 00482 00483 /* At end of Tx process, restore hirda->gState to Ready */ 00484 hirda->gState = HAL_IRDA_STATE_READY; 00485 00486 /* Process Unlocked */ 00487 __HAL_UNLOCK(hirda); 00488 00489 return HAL_OK; 00490 } 00491 else 00492 { 00493 return HAL_BUSY; 00494 } 00495 } 00496 00497 /** 00498 * @brief Receive an amount of data in blocking mode. 00499 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00500 * the configuration information for the specified IRDA module. 00501 * @param pData: Pointer to data buffer. 00502 * @param Size: Amount of data to be received. 00503 * @param Timeout: Specify timeout value. 00504 * @retval HAL status 00505 */ 00506 HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout) 00507 { 00508 uint16_t* tmp; 00509 uint16_t uhMask; 00510 uint32_t tickstart = 0; 00511 00512 /* Check that a Rx process is not already ongoing */ 00513 if(hirda->RxState == HAL_IRDA_STATE_READY) 00514 { 00515 if((pData == NULL) || (Size == 0)) 00516 { 00517 return HAL_ERROR; 00518 } 00519 00520 /* Process Locked */ 00521 __HAL_LOCK(hirda); 00522 00523 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 00524 00525 hirda->RxState = HAL_IRDA_STATE_BUSY_RX; 00526 00527 /* Init tickstart for timeout managment*/ 00528 tickstart = HAL_GetTick(); 00529 00530 hirda->RxXferSize = Size; 00531 hirda->RxXferCount = Size; 00532 00533 /* Computation of the mask to apply to the RDR register 00534 of the UART associated to the IRDA */ 00535 IRDA_MASK_COMPUTATION(hirda); 00536 uhMask = hirda->Mask; 00537 00538 /* Check data remaining to be received */ 00539 while(hirda->RxXferCount > 0) 00540 { 00541 hirda->RxXferCount--; 00542 00543 if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) 00544 { 00545 return HAL_TIMEOUT; 00546 } 00547 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) 00548 { 00549 tmp = (uint16_t*) pData ; 00550 *tmp = (uint16_t)(hirda->Instance->RDR & uhMask); 00551 pData +=2; 00552 } 00553 else 00554 { 00555 *pData++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask); 00556 } 00557 } 00558 00559 /* At end of Rx process, restore hirda->RxState to Ready */ 00560 hirda->RxState = HAL_IRDA_STATE_READY; 00561 00562 /* Process Unlocked */ 00563 __HAL_UNLOCK(hirda); 00564 00565 return HAL_OK; 00566 } 00567 else 00568 { 00569 return HAL_BUSY; 00570 } 00571 } 00572 00573 /** 00574 * @brief Send an amount of data in interrupt mode. 00575 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00576 * the configuration information for the specified IRDA module. 00577 * @param pData: Pointer to data buffer. 00578 * @param Size: Amount of data to be sent. 00579 * @retval HAL status 00580 */ 00581 HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) 00582 { 00583 /* Check that a Tx process is not already ongoing */ 00584 if(hirda->gState == HAL_IRDA_STATE_READY) 00585 { 00586 if((pData == NULL) || (Size == 0)) 00587 { 00588 return HAL_ERROR; 00589 } 00590 00591 /* Process Locked */ 00592 __HAL_LOCK(hirda); 00593 00594 hirda->pTxBuffPtr = pData; 00595 hirda->TxXferSize = Size; 00596 hirda->TxXferCount = Size; 00597 00598 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 00599 00600 hirda->gState = HAL_IRDA_STATE_BUSY_TX; 00601 00602 /* Process Unlocked */ 00603 __HAL_UNLOCK(hirda); 00604 00605 /* Enable the IRDA Transmit Data Register Empty Interrupt */ 00606 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TXE); 00607 00608 return HAL_OK; 00609 } 00610 else 00611 { 00612 return HAL_BUSY; 00613 } 00614 } 00615 00616 /** 00617 * @brief Receive an amount of data in interrupt mode. 00618 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00619 * the configuration information for the specified IRDA module. 00620 * @param pData: Pointer to data buffer. 00621 * @param Size: Amount of data to be received. 00622 * @retval HAL status 00623 */ 00624 HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) 00625 { 00626 /* Check that a Rx process is not already ongoing */ 00627 if(hirda->RxState == HAL_IRDA_STATE_READY) 00628 { 00629 if((pData == NULL) || (Size == 0)) 00630 { 00631 return HAL_ERROR; 00632 } 00633 00634 /* Process Locked */ 00635 __HAL_LOCK(hirda); 00636 00637 hirda->pRxBuffPtr = pData; 00638 hirda->RxXferSize = Size; 00639 hirda->RxXferCount = Size; 00640 00641 /* Computation of the mask to apply to the RDR register 00642 of the UART associated to the IRDA */ 00643 IRDA_MASK_COMPUTATION(hirda); 00644 00645 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 00646 00647 hirda->RxState = HAL_IRDA_STATE_BUSY_RX; 00648 00649 /* Process Unlocked */ 00650 __HAL_UNLOCK(hirda); 00651 00652 /* Enable the IRDA Data Register not empty Interrupt */ 00653 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_RXNE); 00654 00655 /* Enable the IRDA Parity Error Interrupt */ 00656 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_PE); 00657 00658 /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ 00659 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_ERR); 00660 00661 return HAL_OK; 00662 } 00663 else 00664 { 00665 return HAL_BUSY; 00666 } 00667 } 00668 00669 /** 00670 * @brief Send an amount of data in DMA mode. 00671 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00672 * the configuration information for the specified IRDA module. 00673 * @param pData: pointer to data buffer. 00674 * @param Size: amount of data to be sent. 00675 * @retval HAL status 00676 */ 00677 HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) 00678 { 00679 uint32_t *tmp; 00680 00681 /* Check that a Tx process is not already ongoing */ 00682 if(hirda->gState == HAL_IRDA_STATE_READY) 00683 { 00684 if((pData == NULL) || (Size == 0)) 00685 { 00686 return HAL_ERROR; 00687 } 00688 00689 /* Process Locked */ 00690 __HAL_LOCK(hirda); 00691 00692 hirda->pTxBuffPtr = pData; 00693 hirda->TxXferSize = Size; 00694 hirda->TxXferCount = Size; 00695 00696 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 00697 00698 hirda->gState = HAL_IRDA_STATE_BUSY_TX; 00699 00700 /* Set the IRDA DMA transfer complete callback */ 00701 hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt; 00702 00703 /* Set the IRDA DMA half transfer complete callback */ 00704 hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt; 00705 00706 /* Set the DMA error callback */ 00707 hirda->hdmatx->XferErrorCallback = IRDA_DMAError; 00708 00709 /* Enable the IRDA transmit DMA channel */ 00710 tmp = (uint32_t*)&pData; 00711 HAL_DMA_Start_IT(hirda->hdmatx, *(uint32_t*)tmp, (uint32_t)&hirda->Instance->TDR, Size); 00712 00713 /* Clear the TC flag in the ICR register */ 00714 __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_TCF); 00715 00716 /* Enable the DMA transfer for transmit request by setting the DMAT bit 00717 in the USART CR3 register */ 00718 hirda->Instance->CR3 |= USART_CR3_DMAT; 00719 00720 /* Process Unlocked */ 00721 __HAL_UNLOCK(hirda); 00722 00723 return HAL_OK; 00724 } 00725 else 00726 { 00727 return HAL_BUSY; 00728 } 00729 } 00730 00731 /** 00732 * @brief Receive an amount of data in DMA mode. 00733 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00734 * the configuration information for the specified IRDA module. 00735 * @param pData: Pointer to data buffer. 00736 * @param Size: Amount of data to be received. 00737 * @note When the IRDA parity is enabled (PCE = 1) the received data contains 00738 * the parity bit (MSB position). 00739 * @retval HAL status 00740 */ 00741 HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) 00742 { 00743 uint32_t *tmp; 00744 00745 /* Check that a Rx process is not already ongoing */ 00746 if(hirda->RxState == HAL_IRDA_STATE_READY) 00747 { 00748 if((pData == NULL) || (Size == 0)) 00749 { 00750 return HAL_ERROR; 00751 } 00752 00753 /* Process Locked */ 00754 __HAL_LOCK(hirda); 00755 00756 hirda->pRxBuffPtr = pData; 00757 hirda->RxXferSize = Size; 00758 00759 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 00760 00761 hirda->RxState = HAL_IRDA_STATE_BUSY_RX; 00762 00763 /* Set the IRDA DMA transfer complete callback */ 00764 hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt; 00765 00766 /* Set the IRDA DMA half transfer complete callback */ 00767 hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt; 00768 00769 /* Set the DMA error callback */ 00770 hirda->hdmarx->XferErrorCallback = IRDA_DMAError; 00771 00772 /* Enable the DMA channel */ 00773 tmp = (uint32_t*)&pData; 00774 HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->RDR, *(uint32_t*)tmp, Size); 00775 00776 /* Enable the DMA transfer for the receiver request by setting the DMAR bit 00777 in the USART CR3 register */ 00778 hirda->Instance->CR3 |= USART_CR3_DMAR; 00779 00780 /* Process Unlocked */ 00781 __HAL_UNLOCK(hirda); 00782 00783 return HAL_OK; 00784 } 00785 else 00786 { 00787 return HAL_BUSY; 00788 } 00789 } 00790 00791 00792 /** 00793 * @brief Pause the DMA Transfer. 00794 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00795 * the configuration information for the specified IRDA module. 00796 * @retval HAL status 00797 */ 00798 HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda) 00799 { 00800 /* Process Locked */ 00801 __HAL_LOCK(hirda); 00802 00803 if(hirda->gState == HAL_IRDA_STATE_BUSY_TX) 00804 { 00805 /* Disable the IRDA DMA Tx request */ 00806 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); 00807 } 00808 if(hirda->RxState == HAL_IRDA_STATE_BUSY_RX) 00809 { 00810 /* Disable the IRDA DMA Rx request */ 00811 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); 00812 } 00813 00814 /* Process Unlocked */ 00815 __HAL_UNLOCK(hirda); 00816 00817 return HAL_OK; 00818 } 00819 00820 /** 00821 * @brief Resume the DMA Transfer. 00822 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00823 * the configuration information for the specified UART module. 00824 * @retval HAL status 00825 */ 00826 HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda) 00827 { 00828 /* Process Locked */ 00829 __HAL_LOCK(hirda); 00830 00831 if(hirda->gState == HAL_IRDA_STATE_BUSY_TX) 00832 { 00833 /* Enable the IRDA DMA Tx request */ 00834 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT); 00835 } 00836 if(hirda->RxState == HAL_IRDA_STATE_BUSY_RX) 00837 { 00838 /* Clear the Overrun flag before resuming the Rx transfer*/ 00839 __HAL_IRDA_CLEAR_OREFLAG(hirda); 00840 /* Enable the IRDA DMA Rx request */ 00841 SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR); 00842 } 00843 00844 /* Process Unlocked */ 00845 __HAL_UNLOCK(hirda); 00846 00847 return HAL_OK; 00848 } 00849 00850 /** 00851 * @brief Stop the DMA Transfer. 00852 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00853 * the configuration information for the specified UART module. 00854 * @retval HAL status 00855 */ 00856 HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda) 00857 { 00858 /* The Lock is not implemented on this API to allow the user application 00859 to call the HAL IRDA API under callbacks HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback() / 00860 HAL_IRDA_TxHalfCpltCallback / HAL_IRDA_RxHalfCpltCallback: 00861 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete 00862 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of 00863 the stream and the corresponding call back is executed. */ 00864 00865 /* Disable the IRDA Tx/Rx DMA requests */ 00866 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); 00867 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); 00868 00869 /* Abort the IRDA DMA tx channel */ 00870 if(hirda->hdmatx != NULL) 00871 { 00872 HAL_DMA_Abort(hirda->hdmatx); 00873 } 00874 /* Abort the IRDA DMA rx channel */ 00875 if(hirda->hdmarx != NULL) 00876 { 00877 HAL_DMA_Abort(hirda->hdmarx); 00878 } 00879 00880 hirda->gState = HAL_IRDA_STATE_READY; 00881 hirda->RxState = HAL_IRDA_STATE_READY; 00882 00883 return HAL_OK; 00884 } 00885 00886 00887 /** 00888 * @brief Handle IRDA interrupt request. 00889 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00890 * the configuration information for the specified IRDA module. 00891 * @retval None 00892 */ 00893 void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda) 00894 { 00895 /* IRDA parity error interrupt occurred -------------------------------------*/ 00896 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_PE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_PE) != RESET)) 00897 { 00898 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_PEF); 00899 00900 hirda->ErrorCode |= HAL_IRDA_ERROR_PE; 00901 /* Set the IRDA Rx state ready to be able to start again the process */ 00902 hirda->RxState = HAL_IRDA_STATE_READY; 00903 } 00904 00905 /* IRDA frame error interrupt occurred --------------------------------------*/ 00906 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_FE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET)) 00907 { 00908 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_FEF); 00909 00910 hirda->ErrorCode |= HAL_IRDA_ERROR_FE; 00911 /* Set the IRDA Rx state ready to be able to start again the process */ 00912 hirda->RxState = HAL_IRDA_STATE_READY; 00913 } 00914 00915 /* IRDA noise error interrupt occurred --------------------------------------*/ 00916 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_NE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET)) 00917 { 00918 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_NEF); 00919 00920 hirda->ErrorCode |= HAL_IRDA_ERROR_NE; 00921 /* Set the IRDA Rx state ready to be able to start again the process */ 00922 hirda->RxState = HAL_IRDA_STATE_READY; 00923 } 00924 00925 /* IRDA Over-Run interrupt occurred -----------------------------------------*/ 00926 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_ORE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR) != RESET)) 00927 { 00928 __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF); 00929 00930 hirda->ErrorCode |= HAL_IRDA_ERROR_ORE; 00931 /* Set the IRDA Rx state ready to be able to start again the process */ 00932 hirda->RxState = HAL_IRDA_STATE_READY; 00933 } 00934 00935 /* Call IRDA Error Call back function if need be --------------------------*/ 00936 if(hirda->ErrorCode != HAL_IRDA_ERROR_NONE) 00937 { 00938 HAL_IRDA_ErrorCallback(hirda); 00939 } 00940 00941 /* IRDA in mode Receiver ---------------------------------------------------*/ 00942 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_RXNE) != RESET) && (__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_RXNE) != RESET)) 00943 { 00944 IRDA_Receive_IT(hirda); 00945 } 00946 00947 00948 /* IRDA in mode Transmitter ------------------------------------------------*/ 00949 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_TXE) != RESET) &&(__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TXE) != RESET)) 00950 { 00951 IRDA_Transmit_IT(hirda); 00952 } 00953 00954 /* IRDA in mode Transmitter (transmission end) -----------------------------*/ 00955 if((__HAL_IRDA_GET_IT(hirda, IRDA_IT_TC) != RESET) &&(__HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TC) != RESET)) 00956 { 00957 IRDA_EndTransmit_IT(hirda); 00958 } 00959 00960 } 00961 00962 /** 00963 * @brief Tx Transfer completed callback. 00964 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00965 * the configuration information for the specified IRDA module. 00966 * @retval None 00967 */ 00968 __weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda) 00969 { 00970 /* Prevent unused argument(s) compilation warning */ 00971 UNUSED(hirda); 00972 00973 /* NOTE: This function should not be modified, when the callback is needed, 00974 the HAL_IRDA_TxCpltCallback can be implemented in the user file. 00975 */ 00976 } 00977 00978 /** 00979 * @brief Tx Half Transfer completed callback. 00980 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00981 * the configuration information for the specified USART module. 00982 * @retval None 00983 */ 00984 __weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda) 00985 { 00986 /* Prevent unused argument(s) compilation warning */ 00987 UNUSED(hirda); 00988 00989 /* NOTE: This function should not be modified, when the callback is needed, 00990 the HAL_IRDA_TxHalfCpltCallback can be implemented in the user file. 00991 */ 00992 } 00993 00994 /** 00995 * @brief Rx Transfer completed callback. 00996 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 00997 * the configuration information for the specified IRDA module. 00998 * @retval None 00999 */ 01000 __weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda) 01001 { 01002 /* Prevent unused argument(s) compilation warning */ 01003 UNUSED(hirda); 01004 01005 /* NOTE: This function should not be modified, when the callback is needed, 01006 the HAL_IRDA_RxCpltCallback can be implemented in the user file. 01007 */ 01008 } 01009 01010 /** 01011 * @brief Rx Half Transfer complete callback. 01012 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01013 * the configuration information for the specified IRDA module. 01014 * @retval None 01015 */ 01016 __weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda) 01017 { 01018 /* Prevent unused argument(s) compilation warning */ 01019 UNUSED(hirda); 01020 01021 /* NOTE : This function should not be modified, when the callback is needed, 01022 the HAL_IRDA_RxHalfCpltCallback can be implemented in the user file. 01023 */ 01024 } 01025 01026 /** 01027 * @brief IRDA error callback. 01028 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01029 * the configuration information for the specified IRDA module. 01030 * @retval None 01031 */ 01032 __weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda) 01033 { 01034 /* Prevent unused argument(s) compilation warning */ 01035 UNUSED(hirda); 01036 01037 /* NOTE: This function should not be modified, when the callback is needed, 01038 the HAL_IRDA_ErrorCallback can be implemented in the user file. 01039 */ 01040 } 01041 01042 /** 01043 * @} 01044 */ 01045 01046 /** @defgroup IRDA_Exported_Functions_Group4 Peripheral State and Error functions 01047 * @brief IRDA State and Errors functions 01048 * 01049 @verbatim 01050 ============================================================================== 01051 ##### Peripheral State and Errors functions ##### 01052 ============================================================================== 01053 [..] 01054 This subsection provides a set of functions allowing to return the State of IrDA 01055 communication process and also return Peripheral Errors occurred during communication process 01056 (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state 01057 of the IRDA peripheral handle. 01058 (+) HAL_IRDA_GetError() checks in run-time errors that could occur during 01059 communication. 01060 01061 @endverbatim 01062 * @{ 01063 */ 01064 01065 /** 01066 * @brief Return the IRDA handle state. 01067 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01068 * the configuration information for the specified IRDA module. 01069 * @retval HAL state 01070 */ 01071 HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda) 01072 { 01073 /* Return IRDA handle state */ 01074 uint32_t temp1= 0x00, temp2 = 0x00; 01075 temp1 = hirda->gState; 01076 temp2 = hirda->RxState; 01077 01078 return (HAL_IRDA_StateTypeDef)(temp1 | temp2); 01079 } 01080 01081 /** 01082 * @brief Return the IRDA handle error code. 01083 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01084 * the configuration information for the specified IRDA module. 01085 * @retval IRDA Error Code 01086 */ 01087 uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda) 01088 { 01089 return hirda->ErrorCode; 01090 } 01091 01092 /** 01093 * @} 01094 */ 01095 01096 /** 01097 * @} 01098 */ 01099 01100 /** @defgroup IRDA_Private_Functions IRDA Private Functions 01101 * @{ 01102 */ 01103 01104 /** 01105 * @brief DMA IRDA transmit process complete callback. 01106 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains 01107 * the configuration information for the specified DMA module. 01108 * @retval None 01109 */ 01110 static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma) 01111 { 01112 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01113 01114 /* DMA Normal mode */ 01115 if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) 01116 { 01117 hirda->TxXferCount = 0; 01118 01119 /* Disable the DMA transfer for transmit request by resetting the DMAT bit 01120 in the IRDA CR3 register */ 01121 hirda->Instance->CR3 &= ~(USART_CR3_DMAT); 01122 01123 /* Enable the IRDA Transmit Complete Interrupt */ 01124 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC); 01125 } 01126 /* DMA Circular mode */ 01127 else 01128 { 01129 HAL_IRDA_TxCpltCallback(hirda); 01130 } 01131 } 01132 01133 /** 01134 * @brief DMA IRDA receive process half complete callback. 01135 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains 01136 * the configuration information for the specified DMA module. 01137 * @retval None 01138 */ 01139 static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma) 01140 { 01141 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01142 01143 HAL_IRDA_TxHalfCpltCallback(hirda); 01144 } 01145 01146 /** 01147 * @brief DMA IRDA receive process complete callback. 01148 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains 01149 * the configuration information for the specified DMA module. 01150 * @retval None 01151 */ 01152 static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma) 01153 { 01154 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01155 01156 /* DMA Normal mode */ 01157 if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) 01158 { 01159 hirda->RxXferCount = 0; 01160 01161 /* Disable the DMA transfer for the receiver request by resetting the DMAR bit 01162 in the IRDA CR3 register */ 01163 hirda->Instance->CR3 &= ~(USART_CR3_DMAR); 01164 01165 /* At end of Rx process, restore hirda->RxState to Ready */ 01166 hirda->RxState = HAL_IRDA_STATE_READY; 01167 } 01168 01169 HAL_IRDA_RxCpltCallback(hirda); 01170 } 01171 01172 /** 01173 * @brief DMA IRDA receive process half complete callback. 01174 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains 01175 * the configuration information for the specified DMA module. 01176 * @retval None 01177 */ 01178 static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma) 01179 { 01180 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01181 01182 HAL_IRDA_RxHalfCpltCallback(hirda); 01183 } 01184 01185 /** 01186 * @brief DMA IRDA communication error callback. 01187 * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains 01188 * the configuration information for the specified DMA module. 01189 * @retval None 01190 */ 01191 static void IRDA_DMAError(DMA_HandleTypeDef *hdma) 01192 { 01193 IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01194 01195 hirda->RxXferCount = 0; 01196 hirda->TxXferCount = 0; 01197 hirda->ErrorCode |= HAL_IRDA_ERROR_DMA; 01198 hirda->gState = HAL_IRDA_STATE_READY; 01199 hirda->RxState = HAL_IRDA_STATE_READY; 01200 01201 HAL_IRDA_ErrorCallback(hirda); 01202 } 01203 01204 /** 01205 * @brief Handle IRDA Communication Timeout. 01206 * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains 01207 * the configuration information for the specified IRDA module. 01208 * @param Flag Specifies the IRDA flag to check. 01209 * @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. 01210 * @param Tickstart Tick start value 01211 * @param Timeout Timeout duration 01212 * @retval HAL status 01213 */ 01214 static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout) 01215 { 01216 /* Wait until flag is set */ 01217 while((__HAL_IRDA_GET_FLAG(hirda, Flag) ? SET : RESET) == Status) 01218 { 01219 /* Check for the Timeout */ 01220 if(Timeout != HAL_MAX_DELAY) 01221 { 01222 if((Timeout == 0) || ((HAL_GetTick()-Tickstart) > Timeout)) 01223 { 01224 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ 01225 CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE)); 01226 CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); 01227 01228 hirda->gState= HAL_IRDA_STATE_READY; 01229 hirda->RxState= HAL_IRDA_STATE_READY; 01230 01231 /* Process Unlocked */ 01232 __HAL_UNLOCK(hirda); 01233 01234 return HAL_TIMEOUT; 01235 } 01236 } 01237 } 01238 return HAL_OK; 01239 } 01240 01241 /** 01242 * @brief Send an amount of data in non-blocking mode. 01243 * @note Function is called under interruption only, once 01244 * interruptions have been enabled by HAL_IRDA_Transmit_IT(). 01245 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01246 * the configuration information for the specified IRDA module. 01247 * @retval HAL status 01248 */ 01249 static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda) 01250 { 01251 uint16_t* tmp; 01252 01253 /* Check that a Tx process is ongoing */ 01254 if(hirda->gState == HAL_IRDA_STATE_BUSY_TX) 01255 { 01256 if(hirda->TxXferCount == 0) 01257 { 01258 /* Disable the IRDA Transmit Data Register Empty Interrupt */ 01259 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE); 01260 01261 /* Enable the IRDA Transmit Complete Interrupt */ 01262 __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC); 01263 01264 return HAL_OK; 01265 } 01266 else 01267 { 01268 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) 01269 { 01270 tmp = (uint16_t*) hirda->pTxBuffPtr; 01271 hirda->Instance->TDR = (*tmp & (uint16_t)0x01FF); 01272 hirda->pTxBuffPtr += 2; 01273 } 01274 else 01275 { 01276 hirda->Instance->TDR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0xFF); 01277 } 01278 hirda->TxXferCount--; 01279 01280 return HAL_OK; 01281 } 01282 } 01283 else 01284 { 01285 return HAL_BUSY; 01286 } 01287 } 01288 01289 /** 01290 * @brief Wrap up transmission in non-blocking mode. 01291 * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains 01292 * the configuration information for the specified IRDA module. 01293 * @retval HAL status 01294 */ 01295 static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda) 01296 { 01297 /* Disable the IRDA Transmit Complete Interrupt */ 01298 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TC); 01299 01300 /* Tx process is ended, restore hirda->gState to Ready */ 01301 hirda->gState = HAL_IRDA_STATE_READY; 01302 01303 HAL_IRDA_TxCpltCallback(hirda); 01304 01305 return HAL_OK; 01306 } 01307 01308 01309 /** 01310 * @brief Receive an amount of data in non-blocking mode. 01311 * Function is called under interruption only, once 01312 * interruptions have been enabled by HAL_IRDA_Receive_IT(). 01313 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01314 * the configuration information for the specified IRDA module. 01315 * @retval HAL status 01316 */ 01317 static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda) 01318 { 01319 uint16_t* tmp; 01320 uint16_t uhMask = hirda->Mask; 01321 01322 /* Check that a Rx process is ongoing */ 01323 if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX) 01324 { 01325 01326 if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) 01327 { 01328 tmp = (uint16_t*) hirda->pRxBuffPtr ; 01329 *tmp = (uint16_t)(hirda->Instance->RDR & uhMask); 01330 hirda->pRxBuffPtr +=2; 01331 } 01332 else 01333 { 01334 *hirda->pRxBuffPtr++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask); 01335 } 01336 01337 if(--hirda->RxXferCount == 0) 01338 { 01339 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE); 01340 01341 /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ 01342 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR); 01343 01344 /* Disable the IRDA Parity Error Interrupt */ 01345 __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE); 01346 01347 /* Rx process is completed, restore hirda->RxState to Ready */ 01348 hirda->RxState = HAL_IRDA_STATE_READY; 01349 01350 HAL_IRDA_RxCpltCallback(hirda); 01351 01352 return HAL_OK; 01353 } 01354 01355 return HAL_OK; 01356 } 01357 else 01358 { 01359 /* Clear RXNE interrupt flag */ 01360 __HAL_IRDA_SEND_REQ(hirda, IRDA_RXDATA_FLUSH_REQUEST); 01361 01362 return HAL_BUSY; 01363 } 01364 } 01365 01366 /** 01367 * @brief Configure the IRDA peripheral. 01368 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01369 * the configuration information for the specified IRDA module. 01370 * @retval None 01371 */ 01372 static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda) 01373 { 01374 uint32_t tmpreg = 0x00000000; 01375 IRDA_ClockSourceTypeDef clocksource = IRDA_CLOCKSOURCE_UNDEFINED; 01376 HAL_StatusTypeDef ret = HAL_OK; 01377 01378 /* Check the communication parameters */ 01379 assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate)); 01380 assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength)); 01381 assert_param(IS_IRDA_PARITY(hirda->Init.Parity)); 01382 assert_param(IS_IRDA_TX_RX_MODE(hirda->Init.Mode)); 01383 assert_param(IS_IRDA_PRESCALER(hirda->Init.Prescaler)); 01384 assert_param(IS_IRDA_POWERMODE(hirda->Init.PowerMode)); 01385 01386 /*-------------------------- USART CR1 Configuration -----------------------*/ 01387 /* Configure the IRDA Word Length, Parity and transfer Mode: 01388 Set the M bits according to hirda->Init.WordLength value 01389 Set PCE and PS bits according to hirda->Init.Parity value 01390 Set TE and RE bits according to hirda->Init.Mode value */ 01391 tmpreg = (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode ; 01392 01393 MODIFY_REG(hirda->Instance->CR1, IRDA_CR1_FIELDS, tmpreg); 01394 01395 /*-------------------------- USART CR3 Configuration -----------------------*/ 01396 MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.PowerMode); 01397 01398 /*-------------------------- USART GTPR Configuration ----------------------*/ 01399 MODIFY_REG(hirda->Instance->GTPR, USART_GTPR_PSC, hirda->Init.Prescaler); 01400 01401 /*-------------------------- USART BRR Configuration -----------------------*/ 01402 IRDA_GETCLOCKSOURCE(hirda, clocksource); 01403 switch (clocksource) 01404 { 01405 case IRDA_CLOCKSOURCE_PCLK1: 01406 hirda->Instance->BRR = (uint16_t)((HAL_RCC_GetPCLK1Freq() + (hirda->Init.BaudRate/2)) / hirda->Init.BaudRate); 01407 break; 01408 case IRDA_CLOCKSOURCE_PCLK2: 01409 hirda->Instance->BRR = (uint16_t)((HAL_RCC_GetPCLK2Freq() + (hirda->Init.BaudRate/2)) / hirda->Init.BaudRate); 01410 break; 01411 case IRDA_CLOCKSOURCE_HSI: 01412 hirda->Instance->BRR = (uint16_t)((HSI_VALUE + (hirda->Init.BaudRate/2)) / hirda->Init.BaudRate); 01413 break; 01414 case IRDA_CLOCKSOURCE_SYSCLK: 01415 hirda->Instance->BRR = (uint16_t)((HAL_RCC_GetSysClockFreq() + (hirda->Init.BaudRate/2)) / hirda->Init.BaudRate); 01416 break; 01417 case IRDA_CLOCKSOURCE_LSE: 01418 hirda->Instance->BRR = (uint16_t)((LSE_VALUE + (hirda->Init.BaudRate/2)) / hirda->Init.BaudRate); 01419 break; 01420 case IRDA_CLOCKSOURCE_UNDEFINED: 01421 default: 01422 ret = HAL_ERROR; 01423 break; 01424 } 01425 01426 return ret; 01427 } 01428 01429 /** 01430 * @brief Check the IRDA Idle State. 01431 * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains 01432 * the configuration information for the specified IRDA module. 01433 * @retval HAL status 01434 */ 01435 static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda) 01436 { 01437 uint32_t tickstart = 0; 01438 01439 /* Initialize the IRDA ErrorCode */ 01440 hirda->ErrorCode = HAL_IRDA_ERROR_NONE; 01441 01442 /* Init tickstart for timeout managment*/ 01443 tickstart = HAL_GetTick(); 01444 01445 /* Check if the Transmitter is enabled */ 01446 if((hirda->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) 01447 { 01448 /* Wait until TEACK flag is set */ 01449 if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK) 01450 { 01451 /* Timeout occurred */ 01452 return HAL_TIMEOUT; 01453 } 01454 } 01455 /* Check if the Receiver is enabled */ 01456 if((hirda->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) 01457 { 01458 if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK) 01459 { 01460 /* Timeout occurred */ 01461 return HAL_TIMEOUT; 01462 } 01463 } 01464 01465 /* Initialize the IRDA state*/ 01466 hirda->gState= HAL_IRDA_STATE_READY; 01467 hirda->RxState= HAL_IRDA_STATE_READY; 01468 01469 /* Process Unlocked */ 01470 __HAL_UNLOCK(hirda); 01471 01472 return HAL_OK; 01473 } 01474 01475 /** 01476 * @} 01477 */ 01478 01479 #endif /* HAL_IRDA_MODULE_ENABLED */ 01480 /** 01481 * @} 01482 */ 01483 01484 /** 01485 * @} 01486 */ 01487 01488 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Tue Jul 12 2022 10:59:58 by
