STM32F103xB HAL User Manual
stm32f1xx_hal_cec.c
Go to the documentation of this file.
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>&copy; 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****/