Subversion Repositories AFRtranscoder

Rev

Details | Last modification | View Log | RSS feed

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