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