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