Subversion Repositories dashGPS

Rev

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