STM32F103xB HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f1xx_hal_cec.c 00004 * @author MCD Application Team 00005 * @brief CEC HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the High Definition Multimedia Interface 00008 * Consumer Electronics Control Peripheral (CEC). 00009 * + Initialization and de-initialization function 00010 * + IO operation function 00011 * + Peripheral Control function 00012 * 00013 * 00014 @verbatim 00015 =============================================================================== 00016 ##### How to use this driver ##### 00017 =============================================================================== 00018 [..] 00019 The CEC HAL driver can be used as follow: 00020 00021 (#) Declare a CEC_HandleTypeDef handle structure. 00022 (#) Initialize the CEC low level resources by implementing the HAL_CEC_MspInit ()API: 00023 (##) Enable the CEC interface clock. 00024 (##) CEC pins configuration: 00025 (+++) Enable the clock for the CEC GPIOs. 00026 (+++) Configure these CEC pins as alternate function pull-up. 00027 (##) NVIC configuration if you need to use interrupt process (HAL_CEC_Transmit_IT() 00028 and HAL_CEC_Receive_IT() APIs): 00029 (+++) Configure the CEC interrupt priority. 00030 (+++) Enable the NVIC CEC IRQ handle. 00031 (+++) The specific CEC interrupts (Transmission complete interrupt, 00032 RXNE interrupt and Error Interrupts) will be managed using the macros 00033 __HAL_CEC_ENABLE_IT() and __HAL_CEC_DISABLE_IT() inside the transmit 00034 and receive process. 00035 00036 (#) Program the Bit Timing Error Mode and the Bit Period Error Mode in the hcec Init structure. 00037 00038 (#) Initialize the CEC registers by calling the HAL_CEC_Init() API. 00039 00040 [..] 00041 (@) This API (HAL_CEC_Init()) configures also the low level Hardware (GPIO, CLOCK, CORTEX...etc) 00042 by calling the customed HAL_CEC_MspInit() API. 00043 *** Callback registration *** 00044 ============================================= 00045 The compilation define USE_HAL_CEC_REGISTER_CALLBACKS when set to 1 00046 allows the user to configure dynamically the driver callbacks. 00047 Use Functions @ref HAL_CEC_RegisterCallback() or HAL_CEC_RegisterXXXCallback() 00048 to register an interrupt callback. 00049 00050 Function @ref HAL_CEC_RegisterCallback() allows to register following callbacks: 00051 (+) TxCpltCallback : Tx Transfer completed callback. 00052 (+) ErrorCallback : callback for error detection. 00053 (+) MspInitCallback : CEC MspInit. 00054 (+) MspDeInitCallback : CEC MspDeInit. 00055 This function takes as parameters the HAL peripheral handle, the Callback ID 00056 and a pointer to the user callback function. 00057 00058 For specific callback HAL_CEC_RxCpltCallback use dedicated register callbacks 00059 @ref HAL_CEC_RegisterRxCpltCallback(). 00060 00061 Use function @ref HAL_CEC_UnRegisterCallback() to reset a callback to the default 00062 weak function. 00063 @ref HAL_CEC_UnRegisterCallback() takes as parameters the HAL peripheral handle, 00064 and the Callback ID. 00065 This function allows to reset following callbacks: 00066 (+) TxCpltCallback : Tx Transfer completed callback. 00067 (+) ErrorCallback : callback for error detection. 00068 (+) MspInitCallback : CEC MspInit. 00069 (+) MspDeInitCallback : CEC MspDeInit. 00070 00071 For callback HAL_CEC_RxCpltCallback use dedicated unregister callback : 00072 @ref HAL_CEC_UnRegisterRxCpltCallback(). 00073 00074 By default, after the @ref HAL_CEC_Init() and when the state is HAL_CEC_STATE_RESET 00075 all callbacks are set to the corresponding weak functions : 00076 examples @ref HAL_CEC_TxCpltCallback() , @ref HAL_CEC_RxCpltCallback(). 00077 Exception done for MspInit and MspDeInit functions that are 00078 reset to the legacy weak function in the @ref HAL_CEC_Init()/ @ref HAL_CEC_DeInit() only when 00079 these callbacks are null (not registered beforehand). 00080 if not, MspInit or MspDeInit are not null, the @ref HAL_CEC_Init() / @ref HAL_CEC_DeInit() 00081 keep and use the user MspInit/MspDeInit functions (registered beforehand) 00082 00083 Callbacks can be registered/unregistered in HAL_CEC_STATE_READY state only. 00084 Exception done MspInit/MspDeInit callbacks that can be registered/unregistered 00085 in HAL_CEC_STATE_READY or HAL_CEC_STATE_RESET state, 00086 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. 00087 In that case first register the MspInit/MspDeInit user callbacks 00088 using @ref HAL_CEC_RegisterCallback() before calling @ref HAL_CEC_DeInit() 00089 or @ref HAL_CEC_Init() function. 00090 00091 When the compilation define USE_HAL_CEC_REGISTER_CALLBACKS is set to 0 or 00092 not defined, the callback registration feature is not available and all callbacks 00093 are set to the corresponding weak functions. 00094 @endverbatim 00095 ****************************************************************************** 00096 * @attention 00097 * 00098 * <h2><center>© Copyright (c) 2016 STMicroelectronics. 00099 * All rights reserved.</center></h2> 00100 * 00101 * This software component is licensed by ST under BSD 3-Clause license, 00102 * the "License"; You may not use this file except in compliance with the 00103 * License. You may obtain a copy of the License at: 00104 * opensource.org/licenses/BSD-3-Clause 00105 * 00106 ****************************************************************************** 00107 */ 00108 00109 /* Includes ------------------------------------------------------------------*/ 00110 #include "stm32f1xx_hal.h" 00111 00112 #ifdef HAL_CEC_MODULE_ENABLED 00113 00114 #if defined (CEC) 00115 00116 /** @addtogroup STM32F1xx_HAL_Driver 00117 * @{ 00118 */ 00119 00120 /** @defgroup CEC CEC 00121 * @brief HAL CEC module driver 00122 * @{ 00123 */ 00124 00125 /* Private typedef -----------------------------------------------------------*/ 00126 /* Private define ------------------------------------------------------------*/ 00127 /** @defgroup CEC_Private_Constants CEC Private Constants 00128 * @{ 00129 */ 00130 #define CEC_CFGR_FIELDS (CEC_CFGR_BTEM | CEC_CFGR_BPEM ) 00131 #define CEC_FLAG_TRANSMIT_MASK (CEC_FLAG_TSOM|CEC_FLAG_TEOM|CEC_FLAG_TBTRF) 00132 #define CEC_FLAG_RECEIVE_MASK (CEC_FLAG_RSOM|CEC_FLAG_REOM|CEC_FLAG_RBTF) 00133 #define CEC_ESR_ALL_ERROR (CEC_ESR_BTE|CEC_ESR_BPE|CEC_ESR_RBTFE|CEC_ESR_SBE|CEC_ESR_ACKE|CEC_ESR_LINE|CEC_ESR_TBTFE) 00134 #define CEC_RXXFERSIZE_INITIALIZE 0xFFFF /*!< Value used to initialise the RxXferSize of the handle */ 00135 /** 00136 * @} 00137 */ 00138 00139 /* Private macro -------------------------------------------------------------*/ 00140 /* Private variables ---------------------------------------------------------*/ 00141 /* Private function prototypes -----------------------------------------------*/ 00142 /** @defgroup CEC_Private_Functions CEC Private Functions 00143 * @{ 00144 */ 00145 static HAL_StatusTypeDef CEC_Transmit_IT(CEC_HandleTypeDef *hcec); 00146 static HAL_StatusTypeDef CEC_Receive_IT(CEC_HandleTypeDef *hcec); 00147 /** 00148 * @} 00149 */ 00150 00151 /* Exported functions ---------------------------------------------------------*/ 00152 00153 /** @defgroup CEC_Exported_Functions CEC Exported Functions 00154 * @{ 00155 */ 00156 00157 /** @defgroup CEC_Exported_Functions_Group1 Initialization and de-initialization functions 00158 * @brief Initialization and Configuration functions 00159 * 00160 @verbatim 00161 =============================================================================== 00162 ##### Initialization and Configuration functions ##### 00163 =============================================================================== 00164 [..] 00165 This subsection provides a set of functions allowing to initialize the CEC 00166 (+) The following parameters need to be configured: 00167 (++) TimingErrorFree 00168 (++) PeriodErrorFree 00169 (++) InitiatorAddress 00170 00171 @endverbatim 00172 * @{ 00173 */ 00174 00175 /** 00176 * @brief Initializes the CEC mode according to the specified 00177 * parameters in the CEC_InitTypeDef and creates the associated handle . 00178 * @param hcec: CEC handle 00179 * @retval HAL status 00180 */ 00181 HAL_StatusTypeDef HAL_CEC_Init(CEC_HandleTypeDef *hcec) 00182 { 00183 /* Check the CEC handle allocation */ 00184 if((hcec == NULL) ||(hcec->Init.RxBuffer == NULL)) 00185 { 00186 return HAL_ERROR; 00187 } 00188 00189 /* Check the parameters */ 00190 assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance)); 00191 assert_param(IS_CEC_BIT_TIMING_ERROR_MODE(hcec->Init.TimingErrorFree)); 00192 assert_param(IS_CEC_BIT_PERIOD_ERROR_MODE(hcec->Init.PeriodErrorFree)); 00193 assert_param(IS_CEC_ADDRESS(hcec->Init.OwnAddress)); 00194 #if (USE_HAL_CEC_REGISTER_CALLBACKS == 1) 00195 if(hcec->gState == HAL_CEC_STATE_RESET) 00196 { 00197 /* Allocate lock resource and initialize it */ 00198 hcec->Lock = HAL_UNLOCKED; 00199 00200 hcec->TxCpltCallback = HAL_CEC_TxCpltCallback; /* Legacy weak TxCpltCallback */ 00201 hcec->RxCpltCallback = HAL_CEC_RxCpltCallback; /* Legacy weak RxCpltCallback */ 00202 hcec->ErrorCallback = HAL_CEC_ErrorCallback; /* Legacy weak ErrorCallback */ 00203 00204 if(hcec->MspInitCallback == NULL) 00205 { 00206 hcec->MspInitCallback = HAL_CEC_MspInit; /* Legacy weak MspInit */ 00207 } 00208 00209 /* Init the low level hardware */ 00210 hcec->MspInitCallback(hcec); 00211 } 00212 #else 00213 if(hcec->gState == HAL_CEC_STATE_RESET) 00214 { 00215 /* Allocate lock resource and initialize it */ 00216 hcec->Lock = HAL_UNLOCKED; 00217 /* Init the low level hardware : GPIO, CLOCK */ 00218 HAL_CEC_MspInit(hcec); 00219 } 00220 #endif /* USE_HAL_CEC_REGISTER_CALLBACKS */ 00221 00222 hcec->gState = HAL_CEC_STATE_BUSY; 00223 00224 /* Disable the Peripheral */ 00225 __HAL_CEC_DISABLE(hcec); 00226 00227 /* Write to CEC Control Register */ 00228 MODIFY_REG(hcec->Instance->CFGR, CEC_CFGR_FIELDS, hcec->Init.TimingErrorFree | hcec->Init.PeriodErrorFree); 00229 00230 /* Write to CEC Own Address Register */ 00231 MODIFY_REG(hcec->Instance->OAR, CEC_OAR_OA, hcec->Init.OwnAddress); 00232 00233 /* Configure the prescaler to generate the required 50 microseconds time base.*/ 00234 MODIFY_REG(hcec->Instance->PRES, CEC_PRES_PRES, 50U * (HAL_RCC_GetPCLK1Freq()/1000000U) - 1U); 00235 00236 /* Enable the following CEC Interrupt */ 00237 __HAL_CEC_ENABLE_IT(hcec, CEC_IT_IE); 00238 00239 /* Enable the CEC Peripheral */ 00240 __HAL_CEC_ENABLE(hcec); 00241 00242 hcec->ErrorCode = HAL_CEC_ERROR_NONE; 00243 hcec->gState = HAL_CEC_STATE_READY; 00244 hcec->RxState = HAL_CEC_STATE_READY; 00245 00246 return HAL_OK; 00247 } 00248 00249 /** 00250 * @brief DeInitializes the CEC peripheral 00251 * @param hcec: CEC handle 00252 * @retval HAL status 00253 */ 00254 HAL_StatusTypeDef HAL_CEC_DeInit(CEC_HandleTypeDef *hcec) 00255 { 00256 /* Check the CEC handle allocation */ 00257 if(hcec == NULL) 00258 { 00259 return HAL_ERROR; 00260 } 00261 00262 /* Check the parameters */ 00263 assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance)); 00264 00265 hcec->gState = HAL_CEC_STATE_BUSY; 00266 00267 #if (USE_HAL_CEC_REGISTER_CALLBACKS == 1) 00268 if(hcec->MspDeInitCallback == NULL) 00269 { 00270 hcec->MspDeInitCallback = HAL_CEC_MspDeInit; /* Legacy weak MspDeInit */ 00271 } 00272 00273 /* DeInit the low level hardware */ 00274 hcec->MspDeInitCallback(hcec); 00275 00276 #else 00277 /* DeInit the low level hardware */ 00278 HAL_CEC_MspDeInit(hcec); 00279 #endif /* USE_HAL_CEC_REGISTER_CALLBACKS */ 00280 00281 __HAL_RCC_CEC_FORCE_RESET(); 00282 __HAL_RCC_CEC_RELEASE_RESET(); 00283 00284 hcec->ErrorCode = HAL_CEC_ERROR_NONE; 00285 hcec->gState = HAL_CEC_STATE_RESET; 00286 hcec->RxState = HAL_CEC_STATE_RESET; 00287 00288 /* Process Unlock */ 00289 __HAL_UNLOCK(hcec); 00290 00291 return HAL_OK; 00292 } 00293 00294 /** 00295 * @brief Initializes the Own Address of the CEC device 00296 * @param hcec: CEC handle 00297 * @param CEC_OwnAddress: The CEC own address. 00298 * @retval HAL status 00299 */ 00300 HAL_StatusTypeDef HAL_CEC_SetDeviceAddress(CEC_HandleTypeDef *hcec, uint16_t CEC_OwnAddress) 00301 { 00302 /* Check the parameters */ 00303 assert_param(IS_CEC_OWN_ADDRESS(CEC_OwnAddress)); 00304 00305 if ((hcec->gState == HAL_CEC_STATE_READY) && (hcec->RxState == HAL_CEC_STATE_READY)) 00306 { 00307 /* Process Locked */ 00308 __HAL_LOCK(hcec); 00309 00310 hcec->gState = HAL_CEC_STATE_BUSY; 00311 00312 /* Disable the Peripheral */ 00313 __HAL_CEC_DISABLE(hcec); 00314 00315 if(CEC_OwnAddress != CEC_OWN_ADDRESS_NONE) 00316 { 00317 MODIFY_REG(hcec->Instance->OAR, CEC_OAR_OA, hcec->Init.OwnAddress); 00318 } 00319 else 00320 { 00321 CLEAR_BIT(hcec->Instance->OAR, CEC_OAR_OA); 00322 } 00323 00324 hcec->gState = HAL_CEC_STATE_READY; 00325 hcec->ErrorCode = HAL_CEC_ERROR_NONE; 00326 00327 /* Process Unlocked */ 00328 __HAL_UNLOCK(hcec); 00329 00330 /* Enable the Peripheral */ 00331 __HAL_CEC_ENABLE(hcec); 00332 00333 return HAL_OK; 00334 } 00335 else 00336 { 00337 return HAL_BUSY; 00338 } 00339 } 00340 00341 /** 00342 * @brief CEC MSP Init 00343 * @param hcec: CEC handle 00344 * @retval None 00345 */ 00346 __weak void HAL_CEC_MspInit(CEC_HandleTypeDef *hcec) 00347 { 00348 /* Prevent unused argument(s) compilation warning */ 00349 UNUSED(hcec); 00350 /* NOTE : This function should not be modified, when the callback is needed, 00351 the HAL_CEC_MspInit can be implemented in the user file 00352 */ 00353 } 00354 00355 /** 00356 * @brief CEC MSP DeInit 00357 * @param hcec: CEC handle 00358 * @retval None 00359 */ 00360 __weak void HAL_CEC_MspDeInit(CEC_HandleTypeDef *hcec) 00361 { 00362 /* Prevent unused argument(s) compilation warning */ 00363 UNUSED(hcec); 00364 /* NOTE : This function should not be modified, when the callback is needed, 00365 the HAL_CEC_MspDeInit can be implemented in the user file 00366 */ 00367 } 00368 00369 #if (USE_HAL_CEC_REGISTER_CALLBACKS == 1) 00370 /** 00371 * @brief Register a User CEC Callback 00372 * To be used instead of the weak predefined callback 00373 * @param hcec CEC handle 00374 * @param CallbackID ID of the callback to be registered 00375 * This parameter can be one of the following values: 00376 * @arg @ref HAL_CEC_TX_CPLT_CB_ID Tx Complete callback ID 00377 * @arg @ref HAL_CEC_ERROR_CB_ID Error callback ID 00378 * @arg @ref HAL_CEC_MSPINIT_CB_ID MspInit callback ID 00379 * @arg @ref HAL_CEC_MSPDEINIT_CB_ID MspDeInit callback ID 00380 * @param pCallback pointer to the Callback function 00381 * @retval HAL status 00382 */ 00383 HAL_StatusTypeDef HAL_CEC_RegisterCallback(CEC_HandleTypeDef *hcec, HAL_CEC_CallbackIDTypeDef CallbackID, pCEC_CallbackTypeDef pCallback) 00384 { 00385 HAL_StatusTypeDef status = HAL_OK; 00386 00387 if(pCallback == NULL) 00388 { 00389 /* Update the error code */ 00390 hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; 00391 return HAL_ERROR; 00392 } 00393 /* Process locked */ 00394 __HAL_LOCK(hcec); 00395 00396 if(hcec->gState == HAL_CEC_STATE_READY) 00397 { 00398 switch (CallbackID) 00399 { 00400 case HAL_CEC_TX_CPLT_CB_ID : 00401 hcec->TxCpltCallback = pCallback; 00402 break; 00403 00404 case HAL_CEC_ERROR_CB_ID : 00405 hcec->ErrorCallback = pCallback; 00406 break; 00407 00408 case HAL_CEC_MSPINIT_CB_ID : 00409 hcec->MspInitCallback = pCallback; 00410 break; 00411 00412 case HAL_CEC_MSPDEINIT_CB_ID : 00413 hcec->MspDeInitCallback = pCallback; 00414 break; 00415 00416 default : 00417 /* Update the error code */ 00418 hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; 00419 /* Return error status */ 00420 status = HAL_ERROR; 00421 break; 00422 } 00423 } 00424 else if(hcec->gState == HAL_CEC_STATE_RESET) 00425 { 00426 switch (CallbackID) 00427 { 00428 case HAL_CEC_MSPINIT_CB_ID : 00429 hcec->MspInitCallback = pCallback; 00430 break; 00431 00432 case HAL_CEC_MSPDEINIT_CB_ID : 00433 hcec->MspDeInitCallback = pCallback; 00434 break; 00435 00436 default : 00437 /* Update the error code */ 00438 hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; 00439 /* Return error status */ 00440 status = HAL_ERROR; 00441 break; 00442 } 00443 } 00444 else 00445 { 00446 /* Update the error code */ 00447 hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; 00448 /* Return error status */ 00449 status = HAL_ERROR; 00450 } 00451 00452 /* Release Lock */ 00453 __HAL_UNLOCK(hcec); 00454 00455 return status; 00456 } 00457 00458 /** 00459 * @brief Unregister an CEC Callback 00460 * CEC callabck is redirected to the weak predefined callback 00461 * @param hcec uart handle 00462 * @param CallbackID ID of the callback to be unregistered 00463 * This parameter can be one of the following values: 00464 * @arg @ref HAL_CEC_TX_CPLT_CB_ID Tx Complete callback IDD 00465 * @arg @ref HAL_CEC_ERROR_CB_ID Error callback ID 00466 * @arg @ref HAL_CEC_MSPINIT_CB_ID MspInit callback ID 00467 * @arg @ref HAL_CEC_MSPDEINIT_CB_ID MspDeInit callback ID 00468 * @retval status 00469 */ 00470 HAL_StatusTypeDef HAL_CEC_UnRegisterCallback(CEC_HandleTypeDef *hcec, HAL_CEC_CallbackIDTypeDef CallbackID) 00471 { 00472 HAL_StatusTypeDef status = HAL_OK; 00473 00474 /* Process locked */ 00475 __HAL_LOCK(hcec); 00476 00477 if(hcec->gState == HAL_CEC_STATE_READY) 00478 { 00479 switch (CallbackID) 00480 { 00481 case HAL_CEC_TX_CPLT_CB_ID : 00482 hcec->TxCpltCallback = HAL_CEC_TxCpltCallback; /* Legacy weak TxCpltCallback */ 00483 break; 00484 00485 case HAL_CEC_ERROR_CB_ID : 00486 hcec->ErrorCallback = HAL_CEC_ErrorCallback; /* Legacy weak ErrorCallback */ 00487 break; 00488 00489 case HAL_CEC_MSPINIT_CB_ID : 00490 hcec->MspInitCallback = HAL_CEC_MspInit; 00491 break; 00492 00493 case HAL_CEC_MSPDEINIT_CB_ID : 00494 hcec->MspDeInitCallback = HAL_CEC_MspDeInit; 00495 break; 00496 00497 default : 00498 /* Update the error code */ 00499 hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; 00500 /* Return error status */ 00501 status = HAL_ERROR; 00502 break; 00503 } 00504 } 00505 else if(hcec->gState == HAL_CEC_STATE_RESET) 00506 { 00507 switch (CallbackID) 00508 { 00509 case HAL_CEC_MSPINIT_CB_ID : 00510 hcec->MspInitCallback = HAL_CEC_MspInit; 00511 break; 00512 00513 case HAL_CEC_MSPDEINIT_CB_ID : 00514 hcec->MspDeInitCallback = HAL_CEC_MspDeInit; 00515 break; 00516 00517 default : 00518 /* Update the error code */ 00519 hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; 00520 /* Return error status */ 00521 status = HAL_ERROR; 00522 break; 00523 } 00524 } 00525 else 00526 { 00527 /* Update the error code */ 00528 hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; 00529 /* Return error status */ 00530 status = HAL_ERROR; 00531 } 00532 00533 /* Release Lock */ 00534 __HAL_UNLOCK(hcec); 00535 00536 return status; 00537 } 00538 00539 /** 00540 * @brief Register CEC RX complete Callback 00541 * To be used instead of the weak HAL_CEC_RxCpltCallback() predefined callback 00542 * @param hcec CEC handle 00543 * @param pCallback pointer to the Rx transfer compelete Callback function 00544 * @retval HAL status 00545 */ 00546 HAL_StatusTypeDef HAL_CEC_RegisterRxCpltCallback(CEC_HandleTypeDef *hcec, pCEC_RxCallbackTypeDef pCallback) 00547 { 00548 HAL_StatusTypeDef status = HAL_OK; 00549 00550 if(pCallback == NULL) 00551 { 00552 /* Update the error code */ 00553 hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; 00554 return HAL_ERROR; 00555 } 00556 /* Process locked */ 00557 __HAL_LOCK(hcec); 00558 00559 if(HAL_CEC_STATE_READY == hcec->RxState) 00560 { 00561 hcec->RxCpltCallback = pCallback; 00562 } 00563 else 00564 { 00565 /* Update the error code */ 00566 hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; 00567 /* Return error status */ 00568 status = HAL_ERROR; 00569 } 00570 00571 /* Release Lock */ 00572 __HAL_UNLOCK(hcec); 00573 return status; 00574 } 00575 00576 /** 00577 * @brief UnRegister CEC RX complete Callback 00578 * CEC RX complete Callback is redirected to the weak HAL_CEC_RxCpltCallback() predefined callback 00579 * @param hcec CEC handle 00580 * @retval HAL status 00581 */ 00582 HAL_StatusTypeDef HAL_CEC_UnRegisterRxCpltCallback(CEC_HandleTypeDef *hcec) 00583 { 00584 HAL_StatusTypeDef status = HAL_OK; 00585 00586 /* Process locked */ 00587 __HAL_LOCK(hcec); 00588 00589 if(HAL_CEC_STATE_READY == hcec->RxState) 00590 { 00591 hcec->RxCpltCallback = HAL_CEC_RxCpltCallback; /* Legacy weak CEC RxCpltCallback */ 00592 } 00593 else 00594 { 00595 /* Update the error code */ 00596 hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; 00597 /* Return error status */ 00598 status = HAL_ERROR; 00599 } 00600 00601 /* Release Lock */ 00602 __HAL_UNLOCK(hcec); 00603 return status; 00604 } 00605 #endif /* USE_HAL_CEC_REGISTER_CALLBACKS */ 00606 00607 /** 00608 * @} 00609 */ 00610 00611 /** @defgroup CEC_Exported_Functions_Group2 Input and Output operation functions 00612 * @brief CEC Transmit/Receive functions 00613 * 00614 @verbatim 00615 =============================================================================== 00616 ##### IO operation functions ##### 00617 =============================================================================== 00618 [..] 00619 This subsection provides a set of functions allowing to manage the CEC data transfers. 00620 00621 (#) The CEC handle must contain the initiator (TX side) and the destination (RX side) 00622 logical addresses (4-bit long addresses, 0xF for broadcast messages destination) 00623 00624 (#) The communication is performed using Interrupts. 00625 These API's return the HAL status. 00626 The end of the data processing will be indicated through the 00627 dedicated CEC IRQ when using Interrupt mode. 00628 The HAL_CEC_TxCpltCallback(), HAL_CEC_RxCpltCallback() user callbacks 00629 will be executed respectively at the end of the transmit or Receive process 00630 The HAL_CEC_ErrorCallback() user callback will be executed when a communication 00631 error is detected 00632 00633 (#) API's with Interrupt are : 00634 (+) HAL_CEC_Transmit_IT() 00635 (+) HAL_CEC_IRQHandler() 00636 00637 (#) A set of User Callbacks are provided: 00638 (+) HAL_CEC_TxCpltCallback() 00639 (+) HAL_CEC_RxCpltCallback() 00640 (+) HAL_CEC_ErrorCallback() 00641 00642 @endverbatim 00643 * @{ 00644 */ 00645 00646 /** 00647 * @brief Send data in interrupt mode 00648 * @param hcec: CEC handle 00649 * @param InitiatorAddress: Initiator address 00650 * @param DestinationAddress: destination logical address 00651 * @param pData: pointer to input byte data buffer 00652 * @param Size: amount of data to be sent in bytes (without counting the header). 00653 * 0 means only the header is sent (ping operation). 00654 * Maximum TX size is 15 bytes (1 opcode and up to 14 operands). 00655 * @retval HAL status 00656 */ 00657 HAL_StatusTypeDef HAL_CEC_Transmit_IT(CEC_HandleTypeDef *hcec, uint8_t InitiatorAddress,uint8_t DestinationAddress, uint8_t *pData, uint32_t Size) 00658 { 00659 /* if the IP isn't already busy and if there is no previous transmission 00660 already pending due to arbitration lost */ 00661 if(hcec->gState == HAL_CEC_STATE_READY) 00662 { 00663 if((pData == NULL ) && (Size > 0U)) 00664 { 00665 return HAL_ERROR; 00666 } 00667 00668 assert_param(IS_CEC_ADDRESS(DestinationAddress)); 00669 assert_param(IS_CEC_ADDRESS(InitiatorAddress)); 00670 assert_param(IS_CEC_MSGSIZE(Size)); 00671 00672 /* Process Locked */ 00673 __HAL_LOCK(hcec); 00674 hcec->pTxBuffPtr = pData; 00675 hcec->gState = HAL_CEC_STATE_BUSY_TX; 00676 hcec->ErrorCode = HAL_CEC_ERROR_NONE; 00677 00678 /* initialize the number of bytes to send, 00679 * 0 means only one header is sent (ping operation) */ 00680 hcec->TxXferCount = Size; 00681 00682 /* send header block */ 00683 hcec->Instance->TXD = (uint8_t)((uint32_t)InitiatorAddress << CEC_INITIATOR_LSB_POS) | DestinationAddress; 00684 00685 /* Process Unlocked */ 00686 __HAL_UNLOCK(hcec); 00687 00688 /* case no data to be sent, sender is only pinging the system */ 00689 if (Size != 0) 00690 { 00691 /* Set TX Start of Message (TXSOM) bit */ 00692 MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, CEC_FLAG_TSOM); 00693 } 00694 else 00695 { 00696 /* Send a ping command */ 00697 MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, CEC_FLAG_TEOM|CEC_FLAG_TSOM); 00698 } 00699 return HAL_OK; 00700 00701 } 00702 else 00703 { 00704 return HAL_BUSY; 00705 } 00706 } 00707 00708 /** 00709 * @brief Get size of the received frame. 00710 * @param hcec: CEC handle 00711 * @retval Frame size 00712 */ 00713 uint32_t HAL_CEC_GetLastReceivedFrameSize(CEC_HandleTypeDef *hcec) 00714 { 00715 return hcec->RxXferSize; 00716 } 00717 00718 /** 00719 * @brief Change Rx Buffer. 00720 * @param hcec: CEC handle 00721 * @param Rxbuffer: Rx Buffer 00722 * @note This function can be called only inside the HAL_CEC_RxCpltCallback() 00723 * @retval Frame size 00724 */ 00725 void HAL_CEC_ChangeRxBuffer(CEC_HandleTypeDef *hcec, uint8_t* Rxbuffer) 00726 { 00727 hcec->Init.RxBuffer = Rxbuffer; 00728 } 00729 00730 /** 00731 * @brief This function handles CEC interrupt requests. 00732 * @param hcec: CEC handle 00733 * @retval None 00734 */ 00735 void HAL_CEC_IRQHandler(CEC_HandleTypeDef *hcec) 00736 { 00737 /* Save error status register for further error handling purposes */ 00738 hcec->ErrorCode = READ_BIT(hcec->Instance->ESR, CEC_ESR_ALL_ERROR); 00739 00740 /* Transmit error */ 00741 if(__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TERR) != RESET) 00742 { 00743 /* Acknowledgement of the error */ 00744 __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TERR); 00745 00746 hcec->gState = HAL_CEC_STATE_READY; 00747 } 00748 00749 /* Receive error */ 00750 if(__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_RERR) != RESET) 00751 { 00752 /* Acknowledgement of the error */ 00753 __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RERR); 00754 hcec->Init.RxBuffer-=hcec->RxXferSize; 00755 hcec->RxXferSize = 0U; 00756 hcec->RxState = HAL_CEC_STATE_READY; 00757 } 00758 00759 if((hcec->ErrorCode & CEC_ESR_ALL_ERROR) != 0U) 00760 { 00761 /* Error Call Back */ 00762 #if (USE_HAL_CEC_REGISTER_CALLBACKS == 1) 00763 hcec->ErrorCallback(hcec); 00764 #else 00765 HAL_CEC_ErrorCallback(hcec); 00766 #endif /* USE_HAL_CEC_REGISTER_CALLBACKS */ 00767 } 00768 00769 /* Transmit byte request or block transfer finished */ 00770 if(__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TBTRF) != RESET) 00771 { 00772 CEC_Transmit_IT(hcec); 00773 } 00774 00775 /* Receive byte or block transfer finished */ 00776 if(__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_RBTF) != RESET) 00777 { 00778 if(hcec->RxXferSize == 0U) 00779 { 00780 /* reception is starting */ 00781 hcec->RxState = HAL_CEC_STATE_BUSY_RX; 00782 } 00783 CEC_Receive_IT(hcec); 00784 } 00785 } 00786 00787 00788 /** 00789 * @brief Tx Transfer completed callback 00790 * @param hcec: CEC handle 00791 * @retval None 00792 */ 00793 __weak void HAL_CEC_TxCpltCallback(CEC_HandleTypeDef *hcec) 00794 { 00795 /* Prevent unused argument(s) compilation warning */ 00796 UNUSED(hcec); 00797 /* NOTE : This function should not be modified, when the callback is needed, 00798 the HAL_CEC_TxCpltCallback can be implemented in the user file 00799 */ 00800 } 00801 00802 /** 00803 * @brief Rx Transfer completed callback 00804 * @param hcec: CEC handle 00805 * @param RxFrameSize: Size of frame 00806 * @retval None 00807 */ 00808 __weak void HAL_CEC_RxCpltCallback(CEC_HandleTypeDef *hcec, uint32_t RxFrameSize) 00809 { 00810 /* Prevent unused argument(s) compilation warning */ 00811 UNUSED(hcec); 00812 UNUSED(RxFrameSize); 00813 /* NOTE : This function should not be modified, when the callback is needed, 00814 the HAL_CEC_RxCpltCallback can be implemented in the user file 00815 */ 00816 } 00817 00818 /** 00819 * @brief CEC error callbacks 00820 * @param hcec: CEC handle 00821 * @retval None 00822 */ 00823 __weak void HAL_CEC_ErrorCallback(CEC_HandleTypeDef *hcec) 00824 { 00825 /* Prevent unused argument(s) compilation warning */ 00826 UNUSED(hcec); 00827 /* NOTE : This function should not be modified, when the callback is needed, 00828 the HAL_CEC_ErrorCallback can be implemented in the user file 00829 */ 00830 } 00831 /** 00832 * @} 00833 */ 00834 00835 /** @defgroup CEC_Exported_Functions_Group3 Peripheral Control functions 00836 * @brief CEC control functions 00837 * 00838 @verbatim 00839 =============================================================================== 00840 ##### Peripheral Control function ##### 00841 =============================================================================== 00842 [..] 00843 This subsection provides a set of functions allowing to control the CEC. 00844 (+) HAL_CEC_GetState() API can be helpful to check in run-time the state of the CEC peripheral. 00845 (+) HAL_CEC_GetError() API can be helpful to check in run-time the error of the CEC peripheral. 00846 @endverbatim 00847 * @{ 00848 */ 00849 /** 00850 * @brief return the CEC state 00851 * @param hcec: pointer to a CEC_HandleTypeDef structure that contains 00852 * the configuration information for the specified CEC module. 00853 * @retval HAL state 00854 */ 00855 HAL_CEC_StateTypeDef HAL_CEC_GetState(CEC_HandleTypeDef *hcec) 00856 { 00857 uint32_t temp1= 0x00U, temp2 = 0x00U; 00858 temp1 = hcec->gState; 00859 temp2 = hcec->RxState; 00860 00861 return (HAL_CEC_StateTypeDef)(temp1 | temp2); 00862 } 00863 00864 /** 00865 * @brief Return the CEC error code 00866 * @param hcec : pointer to a CEC_HandleTypeDef structure that contains 00867 * the configuration information for the specified CEC. 00868 * @retval CEC Error Code 00869 */ 00870 uint32_t HAL_CEC_GetError(CEC_HandleTypeDef *hcec) 00871 { 00872 return hcec->ErrorCode; 00873 } 00874 00875 /** 00876 * @} 00877 */ 00878 00879 /** 00880 * @} 00881 */ 00882 00883 /** @addtogroup CEC_Private_Functions 00884 * @{ 00885 */ 00886 00887 /** 00888 * @brief Send data in interrupt mode 00889 * @param hcec: CEC handle. 00890 * Function called under interruption only, once 00891 * interruptions have been enabled by HAL_CEC_Transmit_IT() 00892 * @retval HAL status 00893 */ 00894 static HAL_StatusTypeDef CEC_Transmit_IT(CEC_HandleTypeDef *hcec) 00895 { 00896 /* if the IP is already busy or if there is a previous transmission 00897 already pending due to arbitration loss */ 00898 if((hcec->gState == HAL_CEC_STATE_BUSY_TX) || (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) != RESET)) 00899 { 00900 /* if all data have been sent */ 00901 if(hcec->TxXferCount == 0U) 00902 { 00903 /* Acknowledge successful completion by writing 0x00 */ 00904 MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, 0x00U); 00905 00906 hcec->gState = HAL_CEC_STATE_READY; 00907 #if (USE_HAL_CEC_REGISTER_CALLBACKS == 1) 00908 hcec->TxCpltCallback(hcec); 00909 #else 00910 HAL_CEC_TxCpltCallback(hcec); 00911 #endif /* USE_HAL_CEC_REGISTER_CALLBACKS */ 00912 00913 return HAL_OK; 00914 } 00915 else 00916 { 00917 /* Reduce the number of bytes to transfer by one */ 00918 hcec->TxXferCount--; 00919 00920 /* Write data to TX buffer*/ 00921 hcec->Instance->TXD = *hcec->pTxBuffPtr++; 00922 00923 /* If this is the last byte of the ongoing transmission */ 00924 if(hcec->TxXferCount == 0U) 00925 { 00926 /* Acknowledge byte request and signal end of message */ 00927 MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, CEC_FLAG_TEOM); 00928 } 00929 else 00930 { 00931 /* Acknowledge byte request by writing 0x00 */ 00932 MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, 0x00U); 00933 } 00934 00935 return HAL_OK; 00936 } 00937 } 00938 else 00939 { 00940 return HAL_BUSY; 00941 } 00942 } 00943 00944 /** 00945 * @brief Receive data in interrupt mode. 00946 * @param hcec: CEC handle. 00947 * Function called under interruption only, once 00948 * interruptions have been enabled by HAL_CEC_Receive_IT() 00949 * @retval HAL status 00950 */ 00951 static HAL_StatusTypeDef CEC_Receive_IT(CEC_HandleTypeDef *hcec) 00952 { 00953 static uint32_t temp; 00954 00955 if(hcec->RxState == HAL_CEC_STATE_BUSY_RX) 00956 { 00957 temp = hcec->Instance->CSR; 00958 00959 /* Store received data */ 00960 hcec->RxXferSize++; 00961 *hcec->Init.RxBuffer++ = hcec->Instance->RXD; 00962 00963 /* Acknowledge received byte by writing 0x00 */ 00964 MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_RECEIVE_MASK, 0x00U); 00965 00966 /* If the End Of Message is reached */ 00967 if(HAL_IS_BIT_SET(temp, CEC_FLAG_REOM)) 00968 { 00969 /* Interrupts are not disabled due to transmission still ongoing */ 00970 hcec->RxState = HAL_CEC_STATE_READY; 00971 #if (USE_HAL_CEC_REGISTER_CALLBACKS == 1) 00972 hcec->RxCpltCallback(hcec, hcec->RxXferSize); 00973 #else 00974 HAL_CEC_RxCpltCallback(hcec, hcec->RxXferSize); 00975 #endif /* USE_HAL_CEC_REGISTER_CALLBACKS */ 00976 00977 return HAL_OK; 00978 } 00979 else 00980 { 00981 return HAL_BUSY; 00982 } 00983 } 00984 else 00985 { 00986 return HAL_BUSY; 00987 } 00988 } 00989 00990 /** 00991 * @} 00992 */ 00993 00994 /** 00995 * @} 00996 */ 00997 00998 #endif /* CEC */ 00999 01000 #endif /* HAL_CEC_MODULE_ENABLED */ 01001 /** 01002 * @} 01003 */ 01004 01005 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/