1 /**
2   ******************************************************************************
3   * @file    stm32h7xx_hal_cec.c
4   * @author  MCD Application Team
5   * @brief   CEC HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the High Definition Multimedia Interface
8   *          Consumer Electronics Control Peripheral (CEC).
9   *           + Initialization and de-initialization function
10   *           + IO operation function
11   *           + Peripheral Control function
12   *
13   *
14   ******************************************************************************
15   * @attention
16   *
17   * Copyright (c) 2017 STMicroelectronics.
18   * All rights reserved.
19   *
20   * This software is licensed under terms that can be found in the LICENSE file
21   * in the root directory of this software component.
22   * If no LICENSE file comes with this software, it is provided AS-IS.
23   *
24   ******************************************************************************
25   @verbatim
26  ===============================================================================
27                         ##### How to use this driver #####
28  ===============================================================================
29     [..]
30     The CEC HAL driver can be used as follow:
31 
32     (#) Declare a CEC_HandleTypeDef handle structure.
33     (#) Initialize the CEC low level resources by implementing the HAL_CEC_MspInit ()API:
34         (##) Enable the CEC interface clock.
35         (##) CEC pins configuration:
36             (+++) Enable the clock for the CEC GPIOs.
37             (+++) Configure these CEC pins as alternate function pull-up.
38         (##) NVIC configuration if you need to use interrupt process (HAL_CEC_Transmit_IT()
39              and HAL_CEC_Receive_IT() APIs):
40             (+++) Configure the CEC interrupt priority.
41             (+++) Enable the NVIC CEC IRQ handle.
42             (+++) The specific CEC interrupts (Transmission complete interrupt,
43                   RXNE interrupt and Error Interrupts) will be managed using the macros
44                   __HAL_CEC_ENABLE_IT() and __HAL_CEC_DISABLE_IT() inside the transmit
45                   and receive process.
46 
47     (#) Program the Signal Free Time (SFT) and SFT option, Tolerance, reception stop in
48         in case of Bit Rising Error, Error-Bit generation conditions, device logical
49         address and Listen mode in the hcec Init structure.
50 
51     (#) Initialize the CEC registers by calling the HAL_CEC_Init() API.
52 
53   [..]
54     (@) This API (HAL_CEC_Init()) configures also the low level Hardware (GPIO, CLOCK, CORTEX...etc)
55         by calling the customed HAL_CEC_MspInit() API.
56   *** Callback registration ***
57   =============================================
58 
59   The compilation define  USE_HAL_CEC_REGISTER_CALLBACKS when set to 1
60   allows the user to configure dynamically the driver callbacks.
61   Use Functions HAL_CEC_RegisterCallback() or HAL_CEC_RegisterXXXCallback()
62   to register an interrupt callback.
63 
64   Function HAL_CEC_RegisterCallback() allows to register following callbacks:
65     (+) TxCpltCallback     : Tx Transfer completed callback.
66     (+) ErrorCallback      : callback for error detection.
67     (+) MspInitCallback    : CEC MspInit.
68     (+) MspDeInitCallback  : CEC MspDeInit.
69   This function takes as parameters the HAL peripheral handle, the Callback ID
70   and a pointer to the user callback function.
71 
72   For specific callback HAL_CEC_RxCpltCallback use dedicated register callbacks
73   HAL_CEC_RegisterRxCpltCallback().
74 
75   Use function HAL_CEC_UnRegisterCallback() to reset a callback to the default
76   weak function.
77   HAL_CEC_UnRegisterCallback() takes as parameters the HAL peripheral handle,
78   and the Callback ID.
79   This function allows to reset following callbacks:
80     (+) TxCpltCallback     : Tx Transfer completed callback.
81     (+) ErrorCallback      : callback for error detection.
82     (+) MspInitCallback    : CEC MspInit.
83     (+) MspDeInitCallback  : CEC MspDeInit.
84 
85   For callback HAL_CEC_RxCpltCallback use dedicated unregister callback :
86   HAL_CEC_UnRegisterRxCpltCallback().
87 
88   By default, after the HAL_CEC_Init() and when the state is HAL_CEC_STATE_RESET
89   all callbacks are set to the corresponding weak functions :
90   examples HAL_CEC_TxCpltCallback() , HAL_CEC_RxCpltCallback().
91   Exception done for MspInit and MspDeInit functions that are
92   reset to the legacy weak function in the HAL_CEC_Init()/ HAL_CEC_DeInit() only when
93   these callbacks are null (not registered beforehand).
94   if not, MspInit or MspDeInit are not null, the HAL_CEC_Init() / HAL_CEC_DeInit()
95   keep and use the user MspInit/MspDeInit functions (registered beforehand)
96 
97   Callbacks can be registered/unregistered in HAL_CEC_STATE_READY state only.
98   Exception done MspInit/MspDeInit callbacks that can be registered/unregistered
99   in HAL_CEC_STATE_READY or HAL_CEC_STATE_RESET state,
100   thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
101   In that case first register the MspInit/MspDeInit user callbacks
102   using HAL_CEC_RegisterCallback() before calling HAL_CEC_DeInit()
103   or HAL_CEC_Init() function.
104 
105   When the compilation define USE_HAL_CEC_REGISTER_CALLBACKS is set to 0 or
106   not defined, the callback registration feature is not available and all callbacks
107   are set to the corresponding weak functions.
108   @endverbatim
109   ******************************************************************************
110   */
111 
112 /* Includes ------------------------------------------------------------------*/
113 #include "stm32h7xx_hal.h"
114 
115 /** @addtogroup STM32H7xx_HAL_Driver
116   * @{
117   */
118 
119 /** @defgroup CEC CEC
120   * @brief HAL CEC module driver
121   * @{
122   */
123 #ifdef HAL_CEC_MODULE_ENABLED
124 #if defined (CEC)
125 
126 /* Private typedef -----------------------------------------------------------*/
127 /* Private define ------------------------------------------------------------*/
128 /** @defgroup CEC_Private_Constants CEC Private Constants
129   * @{
130   */
131 /**
132   * @}
133   */
134 
135 /* Private macro -------------------------------------------------------------*/
136 /* Private variables ---------------------------------------------------------*/
137 /* Private function prototypes -----------------------------------------------*/
138 /** @defgroup CEC_Private_Functions CEC Private Functions
139   * @{
140   */
141 /**
142   * @}
143   */
144 
145 /* Exported functions ---------------------------------------------------------*/
146 
147 /** @defgroup CEC_Exported_Functions CEC Exported Functions
148   * @{
149   */
150 
151 /** @defgroup CEC_Exported_Functions_Group1 Initialization and de-initialization functions
152   *  @brief    Initialization and Configuration functions
153   *
154 @verbatim
155 ===============================================================================
156             ##### Initialization and Configuration functions #####
157  ===============================================================================
158     [..]
159     This subsection provides a set of functions allowing to initialize the CEC
160       (+) The following parameters need to be configured:
161         (++) SignalFreeTime
162         (++) Tolerance
163         (++) BRERxStop                 (RX stopped or not upon Bit Rising Error)
164         (++) BREErrorBitGen            (Error-Bit generation in case of Bit Rising Error)
165         (++) LBPEErrorBitGen           (Error-Bit generation in case of Long Bit Period Error)
166         (++) BroadcastMsgNoErrorBitGen (Error-bit generation in case of broadcast message error)
167         (++) SignalFreeTimeOption      (SFT Timer start definition)
168         (++) OwnAddress                (CEC device address)
169         (++) ListenMode
170 
171 @endverbatim
172   * @{
173   */
174 
175 /**
176   * @brief Initializes the CEC mode according to the specified
177   *         parameters in the CEC_InitTypeDef and creates the associated handle .
178   * @param hcec CEC handle
179   * @retval HAL status
180   */
HAL_CEC_Init(CEC_HandleTypeDef * hcec)181 HAL_StatusTypeDef HAL_CEC_Init(CEC_HandleTypeDef *hcec)
182 {
183   /* Check the CEC handle allocation */
184   if ((hcec == NULL) || (hcec->Init.RxBuffer == NULL))
185   {
186     return HAL_ERROR;
187   }
188 
189   /* Check the parameters */
190   assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance));
191   assert_param(IS_CEC_SIGNALFREETIME(hcec->Init.SignalFreeTime));
192   assert_param(IS_CEC_TOLERANCE(hcec->Init.Tolerance));
193   assert_param(IS_CEC_BRERXSTOP(hcec->Init.BRERxStop));
194   assert_param(IS_CEC_BREERRORBITGEN(hcec->Init.BREErrorBitGen));
195   assert_param(IS_CEC_LBPEERRORBITGEN(hcec->Init.LBPEErrorBitGen));
196   assert_param(IS_CEC_BROADCASTERROR_NO_ERRORBIT_GENERATION(hcec->Init.BroadcastMsgNoErrorBitGen));
197   assert_param(IS_CEC_SFTOP(hcec->Init.SignalFreeTimeOption));
198   assert_param(IS_CEC_LISTENING_MODE(hcec->Init.ListenMode));
199   assert_param(IS_CEC_OWN_ADDRESS(hcec->Init.OwnAddress));
200 
201 #if (USE_HAL_CEC_REGISTER_CALLBACKS == 1)
202   if (hcec->gState == HAL_CEC_STATE_RESET)
203   {
204     /* Allocate lock resource and initialize it */
205     hcec->Lock = HAL_UNLOCKED;
206 
207     hcec->TxCpltCallback  = HAL_CEC_TxCpltCallback;  /* Legacy weak TxCpltCallback  */
208     hcec->RxCpltCallback = HAL_CEC_RxCpltCallback;   /* Legacy weak RxCpltCallback */
209     hcec->ErrorCallback = HAL_CEC_ErrorCallback;     /* Legacy weak ErrorCallback */
210 
211     if (hcec->MspInitCallback == NULL)
212     {
213       hcec->MspInitCallback = HAL_CEC_MspInit; /* Legacy weak MspInit  */
214     }
215 
216     /* Init the low level hardware */
217     hcec->MspInitCallback(hcec);
218   }
219 #else
220   if (hcec->gState == HAL_CEC_STATE_RESET)
221   {
222     /* Allocate lock resource and initialize it */
223     hcec->Lock = HAL_UNLOCKED;
224     /* Init the low level hardware : GPIO, CLOCK */
225     HAL_CEC_MspInit(hcec);
226   }
227 #endif /* USE_HAL_CEC_REGISTER_CALLBACKS */
228 
229   hcec->gState = HAL_CEC_STATE_BUSY;
230 
231   /* Disable the Peripheral */
232   __HAL_CEC_DISABLE(hcec);
233 
234   /* Write to CEC Control Register */
235   hcec->Instance->CFGR = hcec->Init.SignalFreeTime | hcec->Init.Tolerance | hcec->Init.BRERxStop | \
236                          hcec->Init.BREErrorBitGen | hcec->Init.LBPEErrorBitGen | \
237                          hcec->Init.BroadcastMsgNoErrorBitGen | \
238                          hcec->Init.SignalFreeTimeOption | ((uint32_t)(hcec->Init.OwnAddress) << 16U) | \
239                          hcec->Init.ListenMode;
240 
241   /* Enable the following CEC Transmission/Reception interrupts as
242     * well as the following CEC Transmission/Reception Errors interrupts
243     * Rx Byte Received IT
244     * End of Reception IT
245     * Rx overrun
246     * Rx bit rising error
247     * Rx short bit period error
248     * Rx long bit period error
249     * Rx missing acknowledge
250     * Tx Byte Request IT
251     * End of Transmission IT
252     * Tx Missing Acknowledge IT
253     * Tx-Error IT
254     * Tx-Buffer Underrun IT
255     * Tx arbitration lost   */
256   __HAL_CEC_ENABLE_IT(hcec, CEC_IT_RXBR | CEC_IT_RXEND | CEC_IER_RX_ALL_ERR | CEC_IT_TXBR | CEC_IT_TXEND |
257                       CEC_IER_TX_ALL_ERR);
258 
259   /* Enable the CEC Peripheral */
260   __HAL_CEC_ENABLE(hcec);
261 
262   hcec->ErrorCode = HAL_CEC_ERROR_NONE;
263   hcec->gState = HAL_CEC_STATE_READY;
264   hcec->RxState = HAL_CEC_STATE_READY;
265 
266   return HAL_OK;
267 }
268 
269 /**
270   * @brief DeInitializes the CEC peripheral
271   * @param hcec CEC handle
272   * @retval HAL status
273   */
HAL_CEC_DeInit(CEC_HandleTypeDef * hcec)274 HAL_StatusTypeDef HAL_CEC_DeInit(CEC_HandleTypeDef *hcec)
275 {
276   /* Check the CEC handle allocation */
277   if (hcec == NULL)
278   {
279     return HAL_ERROR;
280   }
281 
282   /* Check the parameters */
283   assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance));
284 
285   hcec->gState = HAL_CEC_STATE_BUSY;
286 
287 #if (USE_HAL_CEC_REGISTER_CALLBACKS == 1)
288   if (hcec->MspDeInitCallback == NULL)
289   {
290     hcec->MspDeInitCallback = HAL_CEC_MspDeInit; /* Legacy weak MspDeInit  */
291   }
292 
293   /* DeInit the low level hardware */
294   hcec->MspDeInitCallback(hcec);
295 
296 #else
297   /* DeInit the low level hardware */
298   HAL_CEC_MspDeInit(hcec);
299 #endif /* USE_HAL_CEC_REGISTER_CALLBACKS */
300 
301   /* Disable the Peripheral */
302   __HAL_CEC_DISABLE(hcec);
303 
304   /* Clear Flags */
305   __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXEND | CEC_FLAG_TXBR | CEC_FLAG_RXBR | CEC_FLAG_RXEND | CEC_ISR_ALL_ERROR);
306 
307   /* Disable the following CEC Transmission/Reception interrupts as
308     * well as the following CEC Transmission/Reception Errors interrupts
309     * Rx Byte Received IT
310     * End of Reception IT
311     * Rx overrun
312     * Rx bit rising error
313     * Rx short bit period error
314     * Rx long bit period error
315     * Rx missing acknowledge
316     * Tx Byte Request IT
317     * End of Transmission IT
318     * Tx Missing Acknowledge IT
319     * Tx-Error IT
320     * Tx-Buffer Underrun IT
321     * Tx arbitration lost   */
322   __HAL_CEC_DISABLE_IT(hcec, CEC_IT_RXBR | CEC_IT_RXEND | CEC_IER_RX_ALL_ERR | CEC_IT_TXBR | CEC_IT_TXEND |
323                        CEC_IER_TX_ALL_ERR);
324 
325   hcec->ErrorCode = HAL_CEC_ERROR_NONE;
326   hcec->gState = HAL_CEC_STATE_RESET;
327   hcec->RxState = HAL_CEC_STATE_RESET;
328 
329   /* Process Unlock */
330   __HAL_UNLOCK(hcec);
331 
332   return HAL_OK;
333 }
334 
335 /**
336   * @brief Initializes the Own Address of the CEC device
337   * @param hcec CEC handle
338   * @param  CEC_OwnAddress The CEC own address.
339   * @retval HAL status
340   */
HAL_CEC_SetDeviceAddress(CEC_HandleTypeDef * hcec,uint16_t CEC_OwnAddress)341 HAL_StatusTypeDef HAL_CEC_SetDeviceAddress(CEC_HandleTypeDef *hcec, uint16_t CEC_OwnAddress)
342 {
343   /* Check the parameters */
344   assert_param(IS_CEC_OWN_ADDRESS(CEC_OwnAddress));
345 
346   if ((hcec->gState == HAL_CEC_STATE_READY) && (hcec->RxState == HAL_CEC_STATE_READY))
347   {
348     /* Process Locked */
349     __HAL_LOCK(hcec);
350 
351     hcec->gState = HAL_CEC_STATE_BUSY;
352 
353     /* Disable the Peripheral */
354     __HAL_CEC_DISABLE(hcec);
355 
356     if (CEC_OwnAddress != CEC_OWN_ADDRESS_NONE)
357     {
358       hcec->Instance->CFGR |= ((uint32_t)CEC_OwnAddress << 16);
359     }
360     else
361     {
362       hcec->Instance->CFGR &= ~(CEC_CFGR_OAR);
363     }
364 
365     hcec->gState = HAL_CEC_STATE_READY;
366     hcec->ErrorCode = HAL_CEC_ERROR_NONE;
367 
368     /* Process Unlocked */
369     __HAL_UNLOCK(hcec);
370 
371     /* Enable the Peripheral */
372     __HAL_CEC_ENABLE(hcec);
373 
374     return  HAL_OK;
375   }
376   else
377   {
378     return HAL_BUSY;
379   }
380 }
381 
382 /**
383   * @brief CEC MSP Init
384   * @param hcec CEC handle
385   * @retval None
386   */
HAL_CEC_MspInit(CEC_HandleTypeDef * hcec)387 __weak void HAL_CEC_MspInit(CEC_HandleTypeDef *hcec)
388 {
389   /* Prevent unused argument(s) compilation warning */
390   UNUSED(hcec);
391   /* NOTE : This function should not be modified, when the callback is needed,
392             the HAL_CEC_MspInit can be implemented in the user file
393    */
394 }
395 
396 /**
397   * @brief CEC MSP DeInit
398   * @param hcec CEC handle
399   * @retval None
400   */
HAL_CEC_MspDeInit(CEC_HandleTypeDef * hcec)401 __weak void HAL_CEC_MspDeInit(CEC_HandleTypeDef *hcec)
402 {
403   /* Prevent unused argument(s) compilation warning */
404   UNUSED(hcec);
405   /* NOTE : This function should not be modified, when the callback is needed,
406             the HAL_CEC_MspDeInit can be implemented in the user file
407    */
408 }
409 #if (USE_HAL_CEC_REGISTER_CALLBACKS == 1)
410 /**
411   * @brief  Register a User CEC Callback
412   *         To be used instead of the weak predefined callback
413   * @param  hcec CEC handle
414   * @param  CallbackID ID of the callback to be registered
415   *         This parameter can be one of the following values:
416   *          @arg HAL_CEC_TX_CPLT_CB_ID Tx Complete callback ID
417   *          @arg HAL_CEC_ERROR_CB_ID Error callback ID
418   *          @arg HAL_CEC_MSPINIT_CB_ID MspInit callback ID
419   *          @arg HAL_CEC_MSPDEINIT_CB_ID MspDeInit callback ID
420   * @param  pCallback pointer to the Callback function
421   * @retval HAL status
422   */
HAL_CEC_RegisterCallback(CEC_HandleTypeDef * hcec,HAL_CEC_CallbackIDTypeDef CallbackID,pCEC_CallbackTypeDef pCallback)423 HAL_StatusTypeDef HAL_CEC_RegisterCallback(CEC_HandleTypeDef *hcec, HAL_CEC_CallbackIDTypeDef CallbackID,
424                                            pCEC_CallbackTypeDef pCallback)
425 {
426   HAL_StatusTypeDef status = HAL_OK;
427 
428   if (pCallback == NULL)
429   {
430     /* Update the error code */
431     hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
432     return HAL_ERROR;
433   }
434   /* Process locked */
435   __HAL_LOCK(hcec);
436 
437   if (hcec->gState == HAL_CEC_STATE_READY)
438   {
439     switch (CallbackID)
440     {
441       case HAL_CEC_TX_CPLT_CB_ID :
442         hcec->TxCpltCallback = pCallback;
443         break;
444 
445       case HAL_CEC_ERROR_CB_ID :
446         hcec->ErrorCallback = pCallback;
447         break;
448 
449       case HAL_CEC_MSPINIT_CB_ID :
450         hcec->MspInitCallback = pCallback;
451         break;
452 
453       case HAL_CEC_MSPDEINIT_CB_ID :
454         hcec->MspDeInitCallback = pCallback;
455         break;
456 
457       default :
458         /* Update the error code */
459         hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
460         /* Return error status */
461         status =  HAL_ERROR;
462         break;
463     }
464   }
465   else if (hcec->gState == HAL_CEC_STATE_RESET)
466   {
467     switch (CallbackID)
468     {
469       case HAL_CEC_MSPINIT_CB_ID :
470         hcec->MspInitCallback = pCallback;
471         break;
472 
473       case HAL_CEC_MSPDEINIT_CB_ID :
474         hcec->MspDeInitCallback = pCallback;
475         break;
476 
477       default :
478         /* Update the error code */
479         hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
480         /* Return error status */
481         status =  HAL_ERROR;
482         break;
483     }
484   }
485   else
486   {
487     /* Update the error code */
488     hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
489     /* Return error status */
490     status =  HAL_ERROR;
491   }
492 
493   /* Release Lock */
494   __HAL_UNLOCK(hcec);
495 
496   return status;
497 }
498 
499 /**
500   * @brief  Unregister an CEC Callback
501   *         CEC callback is redirected to the weak predefined callback
502   * @param hcec uart handle
503   * @param CallbackID ID of the callback to be unregistered
504   *         This parameter can be one of the following values:
505   *          @arg HAL_CEC_TX_CPLT_CB_ID Tx Complete callback ID
506   *          @arg HAL_CEC_ERROR_CB_ID Error callback ID
507   *          @arg HAL_CEC_MSPINIT_CB_ID MspInit callback ID
508   *          @arg HAL_CEC_MSPDEINIT_CB_ID MspDeInit callback ID
509   * @retval status
510   */
HAL_CEC_UnRegisterCallback(CEC_HandleTypeDef * hcec,HAL_CEC_CallbackIDTypeDef CallbackID)511 HAL_StatusTypeDef HAL_CEC_UnRegisterCallback(CEC_HandleTypeDef *hcec, HAL_CEC_CallbackIDTypeDef CallbackID)
512 {
513   HAL_StatusTypeDef status = HAL_OK;
514 
515   /* Process locked */
516   __HAL_LOCK(hcec);
517 
518   if (hcec->gState == HAL_CEC_STATE_READY)
519   {
520     switch (CallbackID)
521     {
522       case HAL_CEC_TX_CPLT_CB_ID :
523         hcec->TxCpltCallback = HAL_CEC_TxCpltCallback;  /* Legacy weak  TxCpltCallback */
524         break;
525 
526       case HAL_CEC_ERROR_CB_ID :
527         hcec->ErrorCallback = HAL_CEC_ErrorCallback;  /* Legacy weak ErrorCallback   */
528         break;
529 
530       case HAL_CEC_MSPINIT_CB_ID :
531         hcec->MspInitCallback = HAL_CEC_MspInit;
532         break;
533 
534       case HAL_CEC_MSPDEINIT_CB_ID :
535         hcec->MspDeInitCallback = HAL_CEC_MspDeInit;
536         break;
537 
538       default :
539         /* Update the error code */
540         hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
541         /* Return error status */
542         status =  HAL_ERROR;
543         break;
544     }
545   }
546   else if (hcec->gState == HAL_CEC_STATE_RESET)
547   {
548     switch (CallbackID)
549     {
550       case HAL_CEC_MSPINIT_CB_ID :
551         hcec->MspInitCallback = HAL_CEC_MspInit;
552         break;
553 
554       case HAL_CEC_MSPDEINIT_CB_ID :
555         hcec->MspDeInitCallback = HAL_CEC_MspDeInit;
556         break;
557 
558       default :
559         /* Update the error code */
560         hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
561         /* Return error status */
562         status =  HAL_ERROR;
563         break;
564     }
565   }
566   else
567   {
568     /* Update the error code */
569     hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
570     /* Return error status */
571     status =  HAL_ERROR;
572   }
573 
574   /* Release Lock */
575   __HAL_UNLOCK(hcec);
576 
577   return status;
578 }
579 
580 /**
581   * @brief  Register CEC RX complete Callback
582   *         To be used instead of the weak HAL_CEC_RxCpltCallback() predefined callback
583   * @param  hcec CEC handle
584   * @param  pCallback pointer to the Rx transfer compelete Callback function
585   * @retval HAL status
586   */
HAL_CEC_RegisterRxCpltCallback(CEC_HandleTypeDef * hcec,pCEC_RxCallbackTypeDef pCallback)587 HAL_StatusTypeDef HAL_CEC_RegisterRxCpltCallback(CEC_HandleTypeDef *hcec, pCEC_RxCallbackTypeDef pCallback)
588 {
589   HAL_StatusTypeDef status = HAL_OK;
590 
591   if (pCallback == NULL)
592   {
593     /* Update the error code */
594     hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
595     return HAL_ERROR;
596   }
597   /* Process locked */
598   __HAL_LOCK(hcec);
599 
600   if (HAL_CEC_STATE_READY == hcec->RxState)
601   {
602     hcec->RxCpltCallback = pCallback;
603   }
604   else
605   {
606     /* Update the error code */
607     hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
608     /* Return error status */
609     status =  HAL_ERROR;
610   }
611 
612   /* Release Lock */
613   __HAL_UNLOCK(hcec);
614   return status;
615 }
616 
617 /**
618   * @brief  UnRegister CEC RX complete Callback
619   *         CEC RX complete Callback is redirected to the weak HAL_CEC_RxCpltCallback() predefined callback
620   * @param  hcec CEC handle
621   * @retval HAL status
622   */
HAL_CEC_UnRegisterRxCpltCallback(CEC_HandleTypeDef * hcec)623 HAL_StatusTypeDef HAL_CEC_UnRegisterRxCpltCallback(CEC_HandleTypeDef *hcec)
624 {
625   HAL_StatusTypeDef status = HAL_OK;
626 
627   /* Process locked */
628   __HAL_LOCK(hcec);
629 
630   if (HAL_CEC_STATE_READY == hcec->RxState)
631   {
632     hcec->RxCpltCallback = HAL_CEC_RxCpltCallback; /* Legacy weak  CEC RxCpltCallback  */
633   }
634   else
635   {
636     /* Update the error code */
637     hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
638     /* Return error status */
639     status =  HAL_ERROR;
640   }
641 
642   /* Release Lock */
643   __HAL_UNLOCK(hcec);
644   return status;
645 }
646 #endif /* USE_HAL_CEC_REGISTER_CALLBACKS */
647 
648 /**
649   * @}
650   */
651 
652 /** @defgroup CEC_Exported_Functions_Group2 Input and Output operation functions
653   *  @brief CEC Transmit/Receive functions
654   *
655 @verbatim
656  ===============================================================================
657                       ##### IO operation functions #####
658  ===============================================================================
659     This subsection provides a set of functions allowing to manage the CEC data transfers.
660 
661     (#) The CEC handle must contain the initiator (TX side) and the destination (RX side)
662         logical addresses (4-bit long addresses, 0xF for broadcast messages destination)
663 
664     (#) The communication is performed using Interrupts.
665            These API's return the HAL status.
666            The end of the data processing will be indicated through the
667            dedicated CEC IRQ when using Interrupt mode.
668            The HAL_CEC_TxCpltCallback(), HAL_CEC_RxCpltCallback() user callbacks
669            will be executed respectively at the end of the transmit or Receive process
670            The HAL_CEC_ErrorCallback() user callback will be executed when a communication
671            error is detected
672 
673     (#) API's with Interrupt are :
674          (+) HAL_CEC_Transmit_IT()
675          (+) HAL_CEC_IRQHandler()
676 
677     (#) A set of User Callbacks are provided:
678          (+) HAL_CEC_TxCpltCallback()
679          (+) HAL_CEC_RxCpltCallback()
680          (+) HAL_CEC_ErrorCallback()
681 
682 @endverbatim
683   * @{
684   */
685 
686 /**
687   * @brief Send data in interrupt mode
688   * @param hcec CEC handle
689   * @param InitiatorAddress Initiator address
690   * @param DestinationAddress destination logical address
691   * @param pData pointer to input byte data buffer
692   * @param Size amount of data to be sent in bytes (without counting the header).
693   *              0 means only the header is sent (ping operation).
694   *              Maximum TX size is 15 bytes (1 opcode and up to 14 operands).
695   * @retval HAL status
696   */
HAL_CEC_Transmit_IT(CEC_HandleTypeDef * hcec,uint8_t InitiatorAddress,uint8_t DestinationAddress,const uint8_t * pData,uint32_t Size)697 HAL_StatusTypeDef HAL_CEC_Transmit_IT(CEC_HandleTypeDef *hcec, uint8_t InitiatorAddress, uint8_t DestinationAddress,
698                                       const uint8_t *pData, uint32_t Size)
699 {
700   /* if the peripheral isn't already busy and if there is no previous transmission
701      already pending due to arbitration lost */
702   if (hcec->gState == HAL_CEC_STATE_READY)
703   {
704     if ((pData == NULL) && (Size > 0U))
705     {
706       return  HAL_ERROR;
707     }
708 
709     assert_param(IS_CEC_ADDRESS(DestinationAddress));
710     assert_param(IS_CEC_ADDRESS(InitiatorAddress));
711     assert_param(IS_CEC_MSGSIZE(Size));
712 
713     /* Process Locked */
714     __HAL_LOCK(hcec);
715     hcec->pTxBuffPtr = pData;
716     hcec->gState = HAL_CEC_STATE_BUSY_TX;
717     hcec->ErrorCode = HAL_CEC_ERROR_NONE;
718 
719     /* initialize the number of bytes to send,
720       * 0 means only one header is sent (ping operation) */
721     hcec->TxXferCount = (uint16_t)Size;
722 
723     /* in case of no payload (Size = 0), sender is only pinging the system;
724        Set TX End of Message (TXEOM) bit, must be set before writing data to TXDR */
725     if (Size == 0U)
726     {
727       __HAL_CEC_LAST_BYTE_TX_SET(hcec);
728     }
729 
730     /* send header block */
731     hcec->Instance->TXDR = (uint32_t)(((uint32_t)InitiatorAddress << CEC_INITIATOR_LSB_POS) | DestinationAddress);
732 
733     /* Set TX Start of Message  (TXSOM) bit */
734     __HAL_CEC_FIRST_BYTE_TX_SET(hcec);
735 
736     /* Process Unlocked */
737     __HAL_UNLOCK(hcec);
738 
739     return HAL_OK;
740 
741   }
742   else
743   {
744     return HAL_BUSY;
745   }
746 }
747 
748 /**
749   * @brief Get size of the received frame.
750   * @param hcec CEC handle
751   * @retval Frame size
752   */
HAL_CEC_GetLastReceivedFrameSize(const CEC_HandleTypeDef * hcec)753 uint32_t HAL_CEC_GetLastReceivedFrameSize(const CEC_HandleTypeDef *hcec)
754 {
755   return hcec->RxXferSize;
756 }
757 
758 /**
759   * @brief Change Rx Buffer.
760   * @param hcec CEC handle
761   * @param Rxbuffer Rx Buffer
762   * @note  This function can be called only inside the HAL_CEC_RxCpltCallback()
763   * @retval Frame size
764   */
HAL_CEC_ChangeRxBuffer(CEC_HandleTypeDef * hcec,uint8_t * Rxbuffer)765 void HAL_CEC_ChangeRxBuffer(CEC_HandleTypeDef *hcec, uint8_t *Rxbuffer)
766 {
767   hcec->Init.RxBuffer = Rxbuffer;
768 }
769 
770 /**
771   * @brief This function handles CEC interrupt requests.
772   * @param hcec CEC handle
773   * @retval None
774   */
HAL_CEC_IRQHandler(CEC_HandleTypeDef * hcec)775 void HAL_CEC_IRQHandler(CEC_HandleTypeDef *hcec)
776 {
777 
778   /* save interrupts register for further error or interrupts handling purposes */
779   uint32_t itflag;
780   itflag = hcec->Instance->ISR;
781 
782 
783   /* ----------------------------Arbitration Lost Management----------------------------------*/
784   /* CEC TX arbitration error interrupt occurred --------------------------------------*/
785   if (HAL_IS_BIT_SET(itflag, CEC_FLAG_ARBLST))
786   {
787     hcec->ErrorCode = HAL_CEC_ERROR_ARBLST;
788     __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_ARBLST);
789   }
790 
791   /* ----------------------------Rx Management----------------------------------*/
792   /* CEC RX byte received interrupt  ---------------------------------------------------*/
793   if (HAL_IS_BIT_SET(itflag, CEC_FLAG_RXBR))
794   {
795     /* reception is starting */
796     hcec->RxState = HAL_CEC_STATE_BUSY_RX;
797     hcec->RxXferSize++;
798     /* read received byte */
799     *hcec->Init.RxBuffer = (uint8_t) hcec->Instance->RXDR;
800     hcec->Init.RxBuffer++;
801     __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXBR);
802   }
803 
804   /* CEC RX end received interrupt  ---------------------------------------------------*/
805   if (HAL_IS_BIT_SET(itflag, CEC_FLAG_RXEND))
806   {
807     /* clear IT */
808     __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXEND);
809 
810     /* Rx process is completed, restore hcec->RxState to Ready */
811     hcec->RxState = HAL_CEC_STATE_READY;
812     hcec->ErrorCode = HAL_CEC_ERROR_NONE;
813     hcec->Init.RxBuffer -= hcec->RxXferSize;
814 #if (USE_HAL_CEC_REGISTER_CALLBACKS == 1U)
815     hcec->RxCpltCallback(hcec, hcec->RxXferSize);
816 #else
817     HAL_CEC_RxCpltCallback(hcec, hcec->RxXferSize);
818 #endif /* USE_HAL_CEC_REGISTER_CALLBACKS */
819     hcec->RxXferSize = 0U;
820   }
821 
822   /* ----------------------------Tx Management----------------------------------*/
823   /* CEC TX byte request interrupt ------------------------------------------------*/
824   if (HAL_IS_BIT_SET(itflag, CEC_FLAG_TXBR))
825   {
826     --hcec->TxXferCount;
827     if (hcec->TxXferCount == 0U)
828     {
829       /* if this is the last byte transmission, set TX End of Message (TXEOM) bit */
830       __HAL_CEC_LAST_BYTE_TX_SET(hcec);
831     }
832     /* In all cases transmit the byte */
833     hcec->Instance->TXDR = (uint8_t) * hcec->pTxBuffPtr;
834     hcec->pTxBuffPtr++;
835     /* clear Tx-Byte request flag */
836     __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXBR);
837   }
838 
839   /* CEC TX end interrupt ------------------------------------------------*/
840   if (HAL_IS_BIT_SET(itflag, CEC_FLAG_TXEND))
841   {
842     __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXEND);
843 
844     /* Tx process is ended, restore hcec->gState to Ready */
845     hcec->gState = HAL_CEC_STATE_READY;
846     /* Call the Process Unlocked before calling the Tx call back API to give the possibility to
847     start again the Transmission under the Tx call back API */
848     __HAL_UNLOCK(hcec);
849     hcec->ErrorCode = HAL_CEC_ERROR_NONE;
850 #if (USE_HAL_CEC_REGISTER_CALLBACKS == 1U)
851     hcec->TxCpltCallback(hcec);
852 #else
853     HAL_CEC_TxCpltCallback(hcec);
854 #endif /* USE_HAL_CEC_REGISTER_CALLBACKS */
855   }
856 
857   /* ----------------------------Rx/Tx Error Management----------------------------------*/
858   if ((itflag & (CEC_ISR_RXOVR | CEC_ISR_BRE | CEC_ISR_SBPE | CEC_ISR_LBPE | CEC_ISR_RXACKE | CEC_ISR_TXUDR |
859                  CEC_ISR_TXERR | CEC_ISR_TXACKE)) != 0U)
860   {
861     hcec->ErrorCode = itflag;
862     __HAL_CEC_CLEAR_FLAG(hcec, HAL_CEC_ERROR_RXOVR | HAL_CEC_ERROR_BRE | CEC_FLAG_LBPE | CEC_FLAG_SBPE |
863                          HAL_CEC_ERROR_RXACKE | HAL_CEC_ERROR_TXUDR | HAL_CEC_ERROR_TXERR | HAL_CEC_ERROR_TXACKE);
864 
865 
866     if ((itflag & (CEC_ISR_RXOVR | CEC_ISR_BRE | CEC_ISR_SBPE | CEC_ISR_LBPE | CEC_ISR_RXACKE)) != 0U)
867     {
868       hcec->Init.RxBuffer -= hcec->RxXferSize;
869       hcec->RxXferSize = 0U;
870       hcec->RxState = HAL_CEC_STATE_READY;
871     }
872     else if (((itflag & CEC_ISR_ARBLST) == 0U) && ((itflag & (CEC_ISR_TXUDR | CEC_ISR_TXERR | CEC_ISR_TXACKE)) != 0U))
873     {
874       /* Set the CEC state ready to be able to start again the process */
875       hcec->gState = HAL_CEC_STATE_READY;
876     }
877     else
878     {
879       /* Nothing todo*/
880     }
881 #if (USE_HAL_CEC_REGISTER_CALLBACKS == 1U)
882     hcec->ErrorCallback(hcec);
883 #else
884     /* Error  Call Back */
885     HAL_CEC_ErrorCallback(hcec);
886 #endif /* USE_HAL_CEC_REGISTER_CALLBACKS */
887   }
888   else
889   {
890     /* Nothing todo*/
891   }
892 }
893 
894 /**
895   * @brief Tx Transfer completed callback
896   * @param hcec CEC handle
897   * @retval None
898   */
HAL_CEC_TxCpltCallback(CEC_HandleTypeDef * hcec)899 __weak void HAL_CEC_TxCpltCallback(CEC_HandleTypeDef *hcec)
900 {
901   /* Prevent unused argument(s) compilation warning */
902   UNUSED(hcec);
903   /* NOTE : This function should not be modified, when the callback is needed,
904             the HAL_CEC_TxCpltCallback can be implemented in the user file
905    */
906 }
907 
908 /**
909   * @brief Rx Transfer completed callback
910   * @param hcec CEC handle
911   * @param RxFrameSize Size of frame
912   * @retval None
913   */
HAL_CEC_RxCpltCallback(CEC_HandleTypeDef * hcec,uint32_t RxFrameSize)914 __weak void HAL_CEC_RxCpltCallback(CEC_HandleTypeDef *hcec, uint32_t RxFrameSize)
915 {
916   /* Prevent unused argument(s) compilation warning */
917   UNUSED(hcec);
918   UNUSED(RxFrameSize);
919   /* NOTE : This function should not be modified, when the callback is needed,
920             the HAL_CEC_RxCpltCallback can be implemented in the user file
921    */
922 }
923 
924 /**
925   * @brief CEC error callbacks
926   * @param hcec CEC handle
927   * @retval None
928   */
HAL_CEC_ErrorCallback(CEC_HandleTypeDef * hcec)929 __weak void HAL_CEC_ErrorCallback(CEC_HandleTypeDef *hcec)
930 {
931   /* Prevent unused argument(s) compilation warning */
932   UNUSED(hcec);
933   /* NOTE : This function should not be modified, when the callback is needed,
934             the HAL_CEC_ErrorCallback can be implemented in the user file
935    */
936 }
937 /**
938   * @}
939   */
940 
941 /** @defgroup CEC_Exported_Functions_Group3 Peripheral Control function
942   *  @brief   CEC control functions
943   *
944 @verbatim
945  ===============================================================================
946                       ##### Peripheral Control function #####
947  ===============================================================================
948     [..]
949     This subsection provides a set of functions allowing to control the CEC.
950      (+) HAL_CEC_GetState() API can be helpful to check in run-time the state of the CEC peripheral.
951      (+) HAL_CEC_GetError() API can be helpful to check in run-time the error of the CEC peripheral.
952 @endverbatim
953   * @{
954   */
955 /**
956   * @brief return the CEC state
957   * @param hcec pointer to a CEC_HandleTypeDef structure that contains
958   *              the configuration information for the specified CEC module.
959   * @retval HAL state
960   */
HAL_CEC_GetState(const CEC_HandleTypeDef * hcec)961 HAL_CEC_StateTypeDef HAL_CEC_GetState(const CEC_HandleTypeDef *hcec)
962 {
963   uint32_t temp1;
964   uint32_t temp2;
965   temp1 = hcec->gState;
966   temp2 = hcec->RxState;
967 
968   return (HAL_CEC_StateTypeDef)(temp1 | temp2);
969 }
970 
971 /**
972   * @brief  Return the CEC error code
973   * @param  hcec  pointer to a CEC_HandleTypeDef structure that contains
974   *              the configuration information for the specified CEC.
975   * @retval CEC Error Code
976   */
HAL_CEC_GetError(const CEC_HandleTypeDef * hcec)977 uint32_t HAL_CEC_GetError(const CEC_HandleTypeDef *hcec)
978 {
979   return hcec->ErrorCode;
980 }
981 
982 /**
983   * @}
984   */
985 
986 /**
987   * @}
988   */
989 #endif /* CEC */
990 #endif /* HAL_CEC_MODULE_ENABLED */
991 /**
992   * @}
993   */
994 
995 /**
996   * @}
997   */
998