Subversion Repositories DashDisplay

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
  * @version V1.0.1
6
  * @date    31-July-2015
7
  * @brief   CEC HAL module driver.
8
  *          This file provides firmware functions to manage the following
9
  *          functionalities of the High Definition Multimedia Interface
10
  *          Consumer Electronics Control Peripheral (CEC).
11
  *           + Initialization and de-initialization functions
12
  *           + IO operation functions
13
  *           + Peripheral Control functions
14
  *          
15
  *  @verbatim    
16
  ==============================================================================
17
                        ##### How to use this driver #####
18
  ==============================================================================
19
    [..]  
20
    The CEC HAL driver can be used as follows:
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
        (##) Enable the clock for the CEC GPIOs.
25
        (##) Configure these CEC pins as alternate function pull-up.
26
        (##) NVIC configuration if you need to use interrupt process (HAL_CEC_Transmit_IT()
27
             and HAL_CEC_Receive_IT() APIs):
28
        (##) Configure the CEC interrupt priority.
29
        (##) Enable the NVIC CEC IRQ handle.
30
        (##) The CEC interrupt is activated/deactivated by the HAL driver
31
 
32
    (#) Program the Bit Timing Error Mode and the Bit Period Error Mode in the hcec Init structure.
33
 
34
    (#) Initialize the CEC registers by calling the HAL_CEC_Init() API.
35
 
36
    (#) This API (HAL_CEC_Init()) configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
37
        by calling the customized HAL_CEC_MspInit() API.
38
 
39
  @endverbatim
40
  ******************************************************************************
41
  * @attention
42
  *
43
  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
44
  *
45
  * Redistribution and use in source and binary forms, with or without modification,
46
  * are permitted provided that the following conditions are met:
47
  *   1. Redistributions of source code must retain the above copyright notice,
48
  *      this list of conditions and the following disclaimer.
49
  *   2. Redistributions in binary form must reproduce the above copyright notice,
50
  *      this list of conditions and the following disclaimer in the documentation
51
  *      and/or other materials provided with the distribution.
52
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
53
  *      may be used to endorse or promote products derived from this software
54
  *      without specific prior written permission.
55
  *
56
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
57
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
60
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
62
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
63
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
64
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
65
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
66
  *
67
  ******************************************************************************  
68
  */
69
 
70
/* Includes ------------------------------------------------------------------*/
71
#include "stm32f1xx_hal.h"
72
 
73
#ifdef HAL_CEC_MODULE_ENABLED
74
 
75
#if defined(STM32F100xB) || defined(STM32F100xE)
76
 
77
/** @addtogroup STM32F1xx_HAL_Driver
78
  * @{
79
  */
80
 
81
/** @defgroup CEC CEC
82
  * @brief HAL CEC module driver
83
  * @{
84
  */
85
 
86
/* Private typedef -----------------------------------------------------------*/
87
/* Private define ------------------------------------------------------------*/
88
/** @defgroup CEC_Private_Constants CEC Private Constants
89
  * @{
90
  */
91
#define CEC_CFGR_FIELDS (CEC_CFGR_BTEM | CEC_CFGR_BPEM )
92
#define CEC_FLAG_TRANSMIT_MASK (CEC_FLAG_TSOM|CEC_FLAG_TEOM|CEC_FLAG_TBTRF)
93
#define CEC_FLAG_RECEIVE_MASK (CEC_FLAG_RSOM|CEC_FLAG_REOM|CEC_FLAG_RBTF)
94
#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)
95
#define CEC_RXXFERSIZE_INITIALIZE 0xFFFF /*!< Value used to initialise the RxXferSize of the handle */
96
/**
97
 * @}
98
 */
99
 
100
/* Private macro -------------------------------------------------------------*/
101
/* Private variables ---------------------------------------------------------*/
102
/* Private function prototypes -----------------------------------------------*/
103
/** @defgroup CEC_Private_Functions CEC Private Functions
104
  * @{
105
  */
106
static HAL_StatusTypeDef CEC_Transmit_IT(CEC_HandleTypeDef *hcec);
107
static HAL_StatusTypeDef CEC_Receive_IT(CEC_HandleTypeDef *hcec);
108
/**
109
 * @}
110
 */
111
 
112
/* Exported functions ---------------------------------------------------------*/
113
 
114
/** @defgroup CEC_Exported_Functions CEC Exported Functions
115
  * @{
116
  */
117
 
118
/** @defgroup CEC_Exported_Functions_Group1 Initialization and de-initialization functions
119
  *  @brief    Initialization and Configuration functions
120
  *
121
@verbatim                                              
122
===============================================================================
123
            ##### Initialization and Configuration functions #####
124
 ===============================================================================  
125
    [..]
126
    This subsection provides a set of functions allowing to initialize the CEC
127
      (+) The following parameters need to be configured:
128
        (++) TimingErrorFree
129
        (++) PeriodErrorFree
130
        (++) InitiatorAddress
131
 
132
@endverbatim
133
  * @{
134
  */
135
 
136
/**
137
  * @brief Initializes the CEC mode according to the specified
138
  *         parameters in the CEC_InitTypeDef and creates the associated handle .
139
  * @param hcec: CEC handle
140
  * @retval HAL status
141
  */
142
HAL_StatusTypeDef HAL_CEC_Init(CEC_HandleTypeDef *hcec)
143
{
144
  /* Check the CEC handle allocation */
145
  if(hcec == NULL)
146
  {
147
    return HAL_ERROR;
148
  }
149
 
150
  /* Check the parameters */
151
  assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance));
152
  assert_param(IS_CEC_BIT_TIMING_ERROR_MODE(hcec->Init.TimingErrorFree));
153
  assert_param(IS_CEC_BIT_PERIOD_ERROR_MODE(hcec->Init.PeriodErrorFree));
154
  assert_param(IS_CEC_ADDRESS(hcec->Init.InitiatorAddress));
155
 
156
  if(hcec->State == HAL_CEC_STATE_RESET)
157
  {
158
    /* Allocate lock resource and initialize it */
159
    hcec->Lock = HAL_UNLOCKED;
160
    /* Init the low level hardware : GPIO, CLOCK */
161
    HAL_CEC_MspInit(hcec);
162
  }
163
 
164
  hcec->State = HAL_CEC_STATE_BUSY;
165
 
166
  /* Disable the Peripheral */
167
  __HAL_CEC_DISABLE(hcec);
168
 
169
  /* Write to CEC Control Register */
170
  MODIFY_REG(hcec->Instance->CFGR, CEC_CFGR_FIELDS, hcec->Init.TimingErrorFree|hcec->Init.PeriodErrorFree);
171
 
172
  /* Write to CEC Own Address Register */
173
  MODIFY_REG(hcec->Instance->OAR, CEC_OAR_OA, hcec->Init.InitiatorAddress);
174
 
175
  /* Configure the prescaler to generate the required 50 microseconds time base.*/
176
  MODIFY_REG(hcec->Instance->PRES, CEC_PRES_PRES, 50*(HAL_RCC_GetPCLK1Freq()/1000000)-1);
177
 
178
  /* Enable the Peripheral */
179
  __HAL_CEC_ENABLE(hcec);
180
 
181
  hcec->State = HAL_CEC_STATE_READY;
182
 
183
  return HAL_OK;
184
}
185
 
186
 
187
 
188
/**
189
  * @brief DeInitializes the CEC peripheral
190
  * @param hcec: CEC handle
191
  * @retval HAL status
192
  */
193
HAL_StatusTypeDef HAL_CEC_DeInit(CEC_HandleTypeDef *hcec)
194
{
195
  /* Check the CEC handle allocation */
196
  if(hcec == NULL)
197
  {
198
    return HAL_ERROR;
199
  }
200
 
201
  /* Check the parameters */
202
  assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance));
203
 
204
  hcec->State = HAL_CEC_STATE_BUSY;
205
 
206
  /* Set peripheral to reset state */
207
  hcec->Instance->CFGR = 0x0;
208
  hcec->Instance->OAR = 0x0;
209
  hcec->Instance->PRES = 0x0;
210
  hcec->Instance->CFGR = 0x0;
211
  hcec->Instance->ESR = 0x0;
212
  hcec->Instance->CSR = 0x0;
213
  hcec->Instance->TXD = 0x0;
214
  hcec->Instance->RXD = 0x0;
215
 
216
  /* Disable the Peripheral */
217
  __HAL_CEC_DISABLE(hcec);
218
 
219
  /* DeInit the low level hardware */
220
  HAL_CEC_MspDeInit(hcec);
221
 
222
  hcec->ErrorCode = HAL_CEC_ERROR_NONE;
223
  hcec->State = HAL_CEC_STATE_RESET;
224
 
225
  /* Process Unlock */
226
  __HAL_UNLOCK(hcec);
227
 
228
  return HAL_OK;
229
}
230
 
231
/**
232
  * @brief CEC MSP Init
233
  * @param hcec: CEC handle
234
  * @retval None
235
  */
236
 __weak void HAL_CEC_MspInit(CEC_HandleTypeDef *hcec)
237
{
238
  /* NOTE : This function should not be modified, when the callback is needed,
239
            the HAL_CEC_MspInit can be implemented in the user file
240
   */
241
}
242
 
243
/**
244
  * @brief CEC MSP DeInit
245
  * @param hcec: CEC handle
246
  * @retval None
247
  */
248
 __weak void HAL_CEC_MspDeInit(CEC_HandleTypeDef *hcec)
249
{
250
  /* NOTE : This function should not be modified, when the callback is needed,
251
            the HAL_CEC_MspDeInit can be implemented in the user file
252
   */
253
}
254
 
255
/**
256
  * @}
257
  */
258
 
259
/** @defgroup CEC_Exported_Functions_Group2 Input and Output operation functions
260
  *  @brief CEC Transmit/Receive functions
261
  *
262
@verbatim  
263
 ===============================================================================
264
                      ##### IO operation functions #####
265
 ===============================================================================  
266
    [..]
267
    This subsection provides a set of functions allowing to manage the CEC data transfers.
268
 
269
    (#) There are two modes of transfer:
270
       (##) Blocking mode: The communication is performed in polling mode.
271
            The HAL status of all data processing is returned by the same function
272
            after finishing transfer.  
273
       (##) No-Blocking mode: The communication is performed using Interrupts.
274
           These API's return the HAL status.
275
           The end of the data processing will be indicated through the
276
           dedicated CEC IRQ when using Interrupt mode.
277
           The HAL_CEC_TxCpltCallback(), HAL_CEC_RxCpltCallback() user callbacks
278
           will be executed respectivelly at the end of the Transmit or Receive process.
279
           The HAL_CEC_ErrorCallback()user callback will be executed when a communication
280
           error is detected
281
    (#) Blocking mode API's are :
282
        (##) HAL_CEC_Transmit()
283
        (##) HAL_CEC_Receive()
284
    (#) Non-Blocking mode API's with Interrupt are :
285
        (##) HAL_CEC_Transmit_IT()
286
        (##) HAL_CEC_Receive_IT()
287
        (##) HAL_CEC_IRQHandler()
288
    (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
289
        (##) HAL_CEC_TxCpltCallback()
290
        (##) HAL_CEC_RxCpltCallback()
291
        (##) HAL_CEC_ErrorCallback()
292
 
293
@endverbatim
294
  * @{
295
  */
296
 
297
/**
298
  * @brief Send data in blocking mode
299
  * @param hcec: CEC handle
300
  * @param DestinationAddress: destination logical address      
301
  * @param pData: pointer to input byte data buffer
302
  * @param Size: amount of data to be sent in bytes (without counting the header).
303
  *              0 means only the header is sent (ping operation).
304
  *              Maximum TX size is 15 bytes (1 opcode and up to 14 operands).    
305
  * @param  Timeout: Timeout duration.
306
  * @retval HAL status
307
  */
308
HAL_StatusTypeDef HAL_CEC_Transmit(CEC_HandleTypeDef *hcec, uint8_t DestinationAddress, uint8_t *pData, uint32_t Size, uint32_t Timeout)
309
{
310
  uint8_t  temp = 0;
311
  uint32_t tickstart = 0;
312
 
313
  /* If the IP is ready */
314
  if((hcec->State == HAL_CEC_STATE_READY)
315
     && (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) == RESET))
316
  {
317
    /* Basic check on pData pointer */
318
    if(((pData == NULL) && (Size > 0)) || (! IS_CEC_MSGSIZE(Size)))
319
    {
320
      return  HAL_ERROR;
321
    }
322
 
323
    assert_param(IS_CEC_ADDRESS(DestinationAddress));
324
 
325
    /* Process Locked */
326
    __HAL_LOCK(hcec);
327
 
328
    /* Enter the transmit mode */
329
    hcec->State = HAL_CEC_STATE_BUSY_TX;
330
    hcec->ErrorCode = HAL_CEC_ERROR_NONE;
331
 
332
    /* Initialize the number of bytes to send,
333
     * 0 means only one header is sent (ping operation) */
334
    hcec->TxXferCount = Size;
335
 
336
    /* Send header block */
337
    temp = (uint8_t)((uint32_t)(hcec->Init.InitiatorAddress) << CEC_INITIATOR_LSB_POS) | DestinationAddress;
338
    hcec->Instance->TXD = temp;
339
 
340
    /* In case no data to be sent, sender is only pinging the system */
341
    if (Size != 0)
342
    {    
343
      /* Set TX Start of Message (TXSOM) bit */
344
      hcec->Instance->CSR = CEC_FLAG_TSOM;
345
    }
346
    else
347
    {
348
      /* Send a ping command */
349
      hcec->Instance->CSR = CEC_FLAG_TEOM|CEC_FLAG_TSOM;
350
    }
351
 
352
    /* Polling TBTRF bit with timeout handling*/
353
    while (hcec->TxXferCount > 0)
354
    {
355
      /* Decreasing of the number of remaining data to receive */
356
      hcec->TxXferCount--;
357
 
358
      /* Timeout handling */
359
      tickstart = HAL_GetTick();
360
 
361
      /* Waiting for the next data transmission */
362
      while(HAL_IS_BIT_CLR(hcec->Instance->CSR, CEC_FLAG_TBTRF))
363
      {
364
        /* Timeout handling */
365
        if(Timeout != HAL_MAX_DELAY)
366
        {
367
          if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
368
          {
369
            hcec->State = HAL_CEC_STATE_READY;
370
            /* Process Unlocked */
371
            __HAL_UNLOCK(hcec);  
372
            return HAL_TIMEOUT;
373
          }
374
        }        
375
 
376
        /* Check if an error occured */
377
        if(HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_TERR) || HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_RERR))
378
        {
379
          /* Copy ESR for error handling purposes */
380
          hcec->ErrorCode = READ_BIT(hcec->Instance->ESR, CEC_ESR_ALL_ERROR);
381
 
382
          /* Acknowledgement of the error */
383
          __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TERR);
384
          __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RERR);
385
 
386
          hcec->State = HAL_CEC_STATE_READY;
387
          __HAL_UNLOCK(hcec);
388
          return  HAL_ERROR;                                    
389
        }
390
      }
391
 
392
      /* Write the next data to TX buffer */
393
      hcec->Instance->TXD = *pData++;
394
 
395
      /* If this is the last byte of the ongoing transmission */
396
      if (hcec->TxXferCount == 0)
397
      {
398
        /* Acknowledge byte request and signal end of message */
399
        MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, CEC_FLAG_TEOM);
400
      }
401
      else
402
      {
403
        /* Acknowledge byte request by writing 0x00 */
404
        MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, 0x00);
405
      }
406
    }
407
 
408
    /* Timeout handling */
409
    tickstart = HAL_GetTick();
410
 
411
    /* Wait for message transmission completion (TBTRF is set) */
412
    while (HAL_IS_BIT_CLR(hcec->Instance->CSR, CEC_FLAG_TBTRF))
413
    {
414
      /* Timeout handling */
415
      if(Timeout != HAL_MAX_DELAY)
416
      {
417
        if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
418
        {
419
          hcec->State = HAL_CEC_STATE_READY;
420
          __HAL_UNLOCK(hcec);            
421
          return HAL_TIMEOUT;
422
        }
423
      }
424
 
425
      /* Check of error during transmission of the last byte */
426
      if(HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_TERR) || HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_RERR))
427
      {
428
        /* Copy ESR for error handling purposes */
429
        hcec->ErrorCode = READ_BIT(hcec->Instance->ESR, CEC_ESR_ALL_ERROR);
430
 
431
        /* Acknowledgement of the error */
432
        __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TERR);
433
        __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RERR);
434
 
435
        hcec->State = HAL_CEC_STATE_READY;
436
        __HAL_UNLOCK(hcec);
437
        return  HAL_ERROR;                                    
438
      }
439
    }
440
 
441
    /* Check of error after the last byte transmission */
442
    if(HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_TERR) || HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_RERR))
443
    {
444
      /* Copy ESR for error handling purposes */
445
      hcec->ErrorCode = READ_BIT(hcec->Instance->ESR, CEC_ESR_ALL_ERROR);
446
 
447
      /* Acknowledgement of the error */
448
      __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TERR);
449
      __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RERR);
450
 
451
      hcec->State = HAL_CEC_STATE_READY;
452
      __HAL_UNLOCK(hcec);
453
      return  HAL_ERROR;
454
    }
455
 
456
    /* Acknowledge successful completion by writing 0x00 */
457
    MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, 0x00);
458
 
459
    hcec->State = HAL_CEC_STATE_READY;
460
    __HAL_UNLOCK(hcec);
461
 
462
    return HAL_OK;
463
  }
464
  else
465
  {
466
    return HAL_BUSY;  
467
  }
468
}
469
 
470
/**
471
  * @brief Receive data in blocking mode.
472
  * @param hcec: CEC handle
473
  * @param pData: pointer to received data buffer.
474
  * @param Timeout: Timeout duration.
475
  * @note  The received data size is not known beforehand, the latter is known
476
  *        when the reception is complete and is stored in hcec->RxXferSize.  
477
  *        hcec->RxXferSize is the sum of opcodes + operands (0 to 14 operands max).
478
  *        If only a header is received, hcec->RxXferSize = 0    
479
  * @retval HAL status
480
  */
481
HAL_StatusTypeDef HAL_CEC_Receive(CEC_HandleTypeDef *hcec, uint8_t *pData, uint32_t Timeout)
482
{
483
  uint32_t temp = 0;
484
  uint32_t tickstart = 0;  
485
 
486
  if(hcec->State == HAL_CEC_STATE_READY)
487
  {
488
    if(pData == NULL)
489
    {
490
      return HAL_ERROR;
491
    }
492
 
493
    /* When a ping is received, RxXferSize is 0*/
494
    /* When a message is received, RxXferSize contains the number of received bytes */
495
    hcec->RxXferSize = CEC_RXXFERSIZE_INITIALIZE;
496
 
497
    /* Process Locked */
498
    __HAL_LOCK(hcec);
499
 
500
    hcec->ErrorCode = HAL_CEC_ERROR_NONE;
501
 
502
    /* Continue the reception until the End Of Message is received (CEC_FLAG_REOM) */
503
    do
504
    {
505
      /* Timeout handling */
506
      tickstart = HAL_GetTick();
507
 
508
      /* Wait for next byte to be received */
509
      while (HAL_IS_BIT_CLR(hcec->Instance->CSR, CEC_FLAG_RBTF))
510
      {
511
        /* Timeout handling */
512
        if(Timeout != HAL_MAX_DELAY)
513
        {
514
          if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
515
          {
516
            hcec->State = HAL_CEC_STATE_READY;
517
            __HAL_UNLOCK(hcec);    
518
            return HAL_TIMEOUT;
519
          }
520
        }
521
 
522
        /* Check if an error occured during the reception */
523
        if(HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_RERR))
524
        {
525
          /* Copy ESR for error handling purposes */
526
          hcec->ErrorCode = READ_BIT(hcec->Instance->ESR, CEC_ESR_ALL_ERROR);
527
 
528
          /* Acknowledgement of the error */
529
          __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RERR);
530
 
531
          hcec->State = HAL_CEC_STATE_READY;
532
          __HAL_UNLOCK(hcec);
533
          return  HAL_ERROR;
534
        }
535
      }
536
 
537
      /* Keep the value of CSR register as the register is cleared during reception process */
538
      temp = hcec->Instance->CSR;
539
 
540
      /* Read received data */
541
      *pData++ = hcec->Instance->RXD;
542
 
543
      /* Acknowledge received byte by writing 0x00 */
544
      CLEAR_BIT(hcec->Instance->CSR, CEC_FLAG_RECEIVE_MASK);
545
 
546
      /* Increment the number of received data */
547
      if(hcec->RxXferSize == CEC_RXXFERSIZE_INITIALIZE)
548
      {
549
        hcec->RxXferSize = 0;
550
      }
551
      else
552
      {
553
        hcec->RxXferSize++;
554
      }
555
 
556
    }while (HAL_IS_BIT_CLR(temp, CEC_FLAG_REOM));
557
 
558
    hcec->State = HAL_CEC_STATE_READY;
559
    __HAL_UNLOCK(hcec);  
560
 
561
    if(IS_CEC_MSGSIZE(hcec->RxXferSize))
562
    {
563
      return HAL_OK;
564
    }
565
    else
566
    {
567
      return HAL_ERROR;
568
    }
569
  }
570
  else
571
  {
572
    return HAL_BUSY;
573
  }
574
}
575
 
576
 
577
/**
578
  * @brief Send data in interrupt mode
579
  * @param hcec: CEC handle
580
  * @param DestinationAddress: destination logical address      
581
  * @param pData: pointer to input byte data buffer
582
  * @param Size: amount of data to be sent in bytes (without counting the header).
583
  *              0 means only the header is sent (ping operation).
584
  *              Maximum TX size is 15 bytes (1 opcode and up to 14 operands).    
585
  * @retval HAL status
586
  */
587
HAL_StatusTypeDef HAL_CEC_Transmit_IT(CEC_HandleTypeDef *hcec, uint8_t DestinationAddress, uint8_t *pData, uint32_t Size)
588
{
589
  uint8_t  temp = 0;
590
  uint32_t tmp_state = 0;
591
 
592
  tmp_state = hcec->State;
593
  if(((tmp_state == HAL_CEC_STATE_READY) || (tmp_state == HAL_CEC_STATE_BUSY_RX))
594
     && (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) == RESET))
595
  {
596
 
597
    /* Basic check on pData pointer */
598
    if(((pData == NULL) && (Size > 0)) || (! IS_CEC_MSGSIZE(Size)))
599
    {
600
      return  HAL_ERROR;
601
    }
602
 
603
    assert_param(IS_CEC_ADDRESS(DestinationAddress));
604
 
605
    /* Process Locked */
606
    __HAL_LOCK(hcec);
607
    hcec->pTxBuffPtr = pData;
608
 
609
    /* Check if a receive process is ongoing or not */
610
    if(hcec->State == HAL_CEC_STATE_BUSY_RX)
611
    {
612
      hcec->State = HAL_CEC_STATE_BUSY_TX_RX;
613
 
614
      /* Interrupt are not enabled here because they are already enabled in the Reception process */
615
    }
616
    else
617
    {
618
      hcec->State = HAL_CEC_STATE_BUSY_TX;    
619
 
620
      /* Enable the CEC interrupt */
621
      __HAL_CEC_ENABLE_IT(hcec, CEC_IT_IE);
622
    }    
623
 
624
    hcec->ErrorCode = HAL_CEC_ERROR_NONE;
625
 
626
    /* initialize the number of bytes to send,
627
     * 0 means only one header is sent (ping operation) */
628
    hcec->TxXferCount = Size;
629
 
630
    /* send header block */
631
    temp = (uint8_t)((uint32_t)(hcec->Init.InitiatorAddress) << CEC_INITIATOR_LSB_POS) | DestinationAddress;
632
    hcec->Instance->TXD = temp;
633
 
634
    /* Process Unlocked */
635
    __HAL_UNLOCK(hcec);
636
 
637
    /* case no data to be sent, sender is only pinging the system */
638
    if (Size != 0)
639
    {    
640
      /* Set TX Start of Message (TXSOM) bit */
641
      MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, CEC_FLAG_TSOM);
642
    }
643
    else
644
    {
645
      /* Send a ping command */
646
      MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, CEC_FLAG_TEOM|CEC_FLAG_TSOM);
647
    }
648
    return HAL_OK;
649
  }
650
  else
651
  {
652
    return HAL_BUSY;  
653
  }
654
}
655
 
656
 
657
/**
658
  * @brief Receive data in interrupt mode.
659
  * @param hcec: CEC handle
660
  * @param pData: pointer to received data buffer.
661
  * @note  The received data size is not known beforehand, the latter is known
662
  *        when the reception is complete and is stored in hcec->RxXferSize.  
663
  *        hcec->RxXferSize is the sum of opcodes + operands (0 to 14 operands max).
664
  *        If only a header is received, hcec->RxXferSize = 0    
665
  * @retval HAL status
666
  */
667
HAL_StatusTypeDef HAL_CEC_Receive_IT(CEC_HandleTypeDef *hcec, uint8_t *pData)
668
{
669
  uint32_t tmp_state = 0;
670
  tmp_state = hcec->State;
671
  if((tmp_state == HAL_CEC_STATE_READY) || (tmp_state == HAL_CEC_STATE_BUSY_TX))
672
  {
673
    if(pData == NULL)
674
    {
675
      return HAL_ERROR;                                    
676
    }
677
 
678
    /* When a ping is received, RxXferSize is 0 */
679
    /* When a message is received, RxXferSize contains the number of received bytes */
680
    hcec->RxXferSize = CEC_RXXFERSIZE_INITIALIZE;
681
 
682
    /* Process Locked */
683
    __HAL_LOCK(hcec);
684
 
685
    hcec->pRxBuffPtr = pData;
686
    hcec->ErrorCode = HAL_CEC_ERROR_NONE;
687
 
688
    /* Process Unlocked */
689
    __HAL_UNLOCK(hcec);
690
 
691
    /* Check if a transmit process is ongoing or not */
692
    if(hcec->State == HAL_CEC_STATE_BUSY_TX)
693
    {
694
      hcec->State = HAL_CEC_STATE_BUSY_TX_RX;
695
    }
696
    else
697
    {
698
      hcec->State = HAL_CEC_STATE_BUSY_RX;    
699
 
700
      /* Enable CEC interrupt */
701
      __HAL_CEC_ENABLE_IT(hcec, CEC_IT_IE);
702
    }
703
 
704
    return HAL_OK;
705
  }
706
  else
707
  {
708
    return HAL_BUSY;
709
  }
710
}
711
 
712
/**
713
  * @brief Get size of the received frame.
714
  * @param hcec: CEC handle
715
  * @retval Frame size
716
  */
717
uint32_t HAL_CEC_GetReceivedFrameSize(CEC_HandleTypeDef *hcec)
718
{
719
  return hcec->RxXferSize;
720
}
721
 
722
/**
723
  * @brief This function handles CEC interrupt requests.
724
  * @param hcec: CEC handle
725
  * @retval None
726
  */
727
void HAL_CEC_IRQHandler(CEC_HandleTypeDef *hcec)
728
{
729
  /* Save error status register for further error handling purposes */
730
  hcec->ErrorCode = READ_BIT(hcec->Instance->ESR, CEC_ESR_ALL_ERROR);
731
 
732
  /* Transmit error */
733
  if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TERR) != RESET))
734
  {
735
    /* Acknowledgement of the error */
736
    __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TERR);
737
 
738
    /* Check if a receive process is ongoing or not */
739
    if(hcec->State == HAL_CEC_STATE_BUSY_TX_RX)
740
    {
741
      /* Interrupts are not disabled due to reception still ongoing */
742
 
743
      hcec->State = HAL_CEC_STATE_BUSY_RX;
744
    }
745
    else
746
    {
747
      /* Disable the CEC Transmission Interrupts */
748
      __HAL_CEC_DISABLE_IT(hcec, CEC_IT_IE);
749
 
750
      hcec->State = HAL_CEC_STATE_READY;
751
    }    
752
  }
753
 
754
  /* Receive error */
755
  if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_RERR) != RESET))
756
  {
757
    /* Acknowledgement of the error */
758
    __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RERR);
759
 
760
    /* Check if a transmit process is ongoing or not */
761
    if(hcec->State == HAL_CEC_STATE_BUSY_TX_RX)
762
    {
763
      /* Interrupts are not disabled due to reception still ongoing */
764
 
765
      hcec->State = HAL_CEC_STATE_BUSY_TX;
766
    }
767
    else
768
    {
769
      /* Disable the CEC Transmission Interrupts */
770
      __HAL_CEC_DISABLE_IT(hcec, CEC_IT_IE);
771
 
772
      hcec->State = HAL_CEC_STATE_READY;
773
    }
774
  }
775
 
776
  if ((hcec->ErrorCode & CEC_ESR_ALL_ERROR) != 0)
777
  {
778
    HAL_CEC_ErrorCallback(hcec);
779
  }
780
 
781
  /* Transmit byte request or block transfer finished */
782
  if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TBTRF) != RESET))
783
  {
784
    CEC_Transmit_IT(hcec);
785
  }  
786
 
787
  /* Receive byte or block transfer finished */
788
  if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_RBTF) != RESET))
789
  {
790
    CEC_Receive_IT(hcec);
791
  }
792
}
793
 
794
 
795
/**
796
  * @brief Tx Transfer completed callback
797
  * @param hcec: CEC handle
798
  * @retval None
799
  */
800
 __weak void HAL_CEC_TxCpltCallback(CEC_HandleTypeDef *hcec)
801
{
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
  * @retval None
811
  */
812
__weak void HAL_CEC_RxCpltCallback(CEC_HandleTypeDef *hcec)
813
{
814
  /* NOTE : This function should not be modified, when the callback is needed,
815
            the HAL_CEC_RxCpltCallback can be implemented in the user file
816
   */
817
}
818
 
819
/**
820
  * @brief CEC error callbacks
821
  * @param hcec: CEC handle
822
  * @retval None
823
  */
824
 __weak void HAL_CEC_ErrorCallback(CEC_HandleTypeDef *hcec)
825
{
826
  /* NOTE : This function should not be modified, when the callback is needed,
827
            the HAL_CEC_ErrorCallback can be implemented in the user file
828
   */
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 functions #####
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 get the error code of a failed transmission or reception.
846
@endverbatim
847
  * @{
848
  */
849
 
850
/**
851
  * @brief return the CEC state
852
  * @param hcec: CEC handle
853
  * @retval HAL state
854
  */
855
HAL_CEC_StateTypeDef HAL_CEC_GetState(CEC_HandleTypeDef *hcec)
856
{
857
  return hcec->State;
858
}
859
 
860
/**
861
* @brief  Return the CEC error code
862
* @param  hcec : pointer to a CEC_HandleTypeDef structure that contains
863
  *              the configuration information for the specified CEC.
864
* @retval CEC Error Code
865
*/
866
uint32_t HAL_CEC_GetError(CEC_HandleTypeDef *hcec)
867
{
868
  return hcec->ErrorCode;
869
}
870
 
871
/**
872
  * @}
873
  */
874
 
875
/**
876
  * @}
877
  */
878
 
879
/** @addtogroup CEC_Private_Functions
880
  * @{
881
  */
882
 
883
 /**
884
  * @brief Send data in interrupt mode
885
  * @param hcec: CEC handle.
886
  *         Function called under interruption only, once
887
  *         interruptions have been enabled by HAL_CEC_Transmit_IT()  
888
  * @retval HAL status
889
  */  
890
static HAL_StatusTypeDef CEC_Transmit_IT(CEC_HandleTypeDef *hcec)
891
{
892
  uint32_t tmp_state = 0;
893
 
894
  tmp_state = hcec->State;
895
  /* if the IP is already busy or if there is a previous transmission
896
     already pending due to arbitration loss */
897
  if(((tmp_state == HAL_CEC_STATE_BUSY_TX) || (tmp_state == HAL_CEC_STATE_BUSY_TX_RX))
898
        || (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) != RESET))
899
  {
900
    /* if all data have been sent */
901
    if(hcec->TxXferCount == 0)
902
    {
903
      /* Acknowledge successful completion by writing 0x00 */
904
      MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, 0x00);
905
 
906
      /* Check if a receive process is ongoing or not */
907
      if(hcec->State == HAL_CEC_STATE_BUSY_TX_RX)
908
      {
909
        /* Interrupts are not disabled due to reception still ongoing */
910
 
911
        hcec->State = HAL_CEC_STATE_BUSY_RX;
912
      }
913
      else
914
      {
915
        /* Disable the CEC Transmission Interrupts */
916
        __HAL_CEC_DISABLE_IT(hcec, CEC_IT_IE);
917
 
918
        hcec->State = HAL_CEC_STATE_READY;
919
      }
920
 
921
      HAL_CEC_TxCpltCallback(hcec);
922
 
923
      return HAL_OK;
924
    }
925
    else
926
    {
927
      /* Reduce the number of bytes to transfer by one */
928
      hcec->TxXferCount--;
929
 
930
      /* Write data to TX buffer*/
931
      hcec->Instance->TXD = *hcec->pTxBuffPtr++;
932
 
933
      /* If this is the last byte of the ongoing transmission */
934
      if (hcec->TxXferCount == 0)
935
      {
936
        /* Acknowledge byte request and signal end of message */
937
        MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, CEC_FLAG_TEOM);
938
      }
939
      else
940
      {
941
        /* Acknowledge byte request by writing 0x00 */
942
        MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, 0x00);
943
      }  
944
 
945
      return HAL_OK;
946
    }
947
  }
948
  else
949
  {
950
    return HAL_BUSY;  
951
  }
952
}
953
 
954
/**
955
  * @brief Receive data in interrupt mode.
956
  * @param hcec: CEC handle.
957
  *         Function called under interruption only, once
958
  *         interruptions have been enabled by HAL_CEC_Receive_IT()  
959
  * @retval HAL status
960
  */  
961
static HAL_StatusTypeDef CEC_Receive_IT(CEC_HandleTypeDef *hcec)
962
{
963
  static uint32_t temp;
964
  uint32_t tmp_state = 0;
965
 
966
  tmp_state = hcec->State;
967
  if((tmp_state == HAL_CEC_STATE_BUSY_RX) || (tmp_state == HAL_CEC_STATE_BUSY_TX_RX))
968
  {
969
    temp = hcec->Instance->CSR;
970
 
971
    /* Store received data */
972
    *hcec->pRxBuffPtr++ = hcec->Instance->RXD;
973
 
974
    /* Acknowledge received byte by writing 0x00 */
975
    MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_RECEIVE_MASK, 0x00);
976
 
977
    /* Increment the number of received data */
978
    if(hcec->RxXferSize == CEC_RXXFERSIZE_INITIALIZE)
979
    {
980
      hcec->RxXferSize = 0;
981
    }
982
    else
983
    {
984
      hcec->RxXferSize++;
985
    }
986
 
987
    /* If the End Of Message is reached */
988
    if(HAL_IS_BIT_SET(temp, CEC_FLAG_REOM))
989
    {
990
      if(hcec->State == HAL_CEC_STATE_BUSY_TX_RX)
991
      {
992
        /* Interrupts are not disabled due to transmission still ongoing */
993
 
994
        hcec->State = HAL_CEC_STATE_BUSY_TX;
995
      }
996
      else
997
      {
998
        /* Disable the CEC Transmission Interrupts */
999
        __HAL_CEC_DISABLE_IT(hcec, CEC_IT_IE);
1000
 
1001
        hcec->State = HAL_CEC_STATE_READY;
1002
      }
1003
 
1004
      HAL_CEC_RxCpltCallback(hcec);
1005
 
1006
      return HAL_OK;
1007
    }    
1008
    else
1009
    {
1010
      return HAL_BUSY;
1011
    }
1012
  }
1013
  else
1014
  {
1015
    return HAL_BUSY;
1016
  }
1017
}
1018
 
1019
/**
1020
 * @}
1021
 */
1022
 
1023
/**
1024
  * @}
1025
  */
1026
 
1027
#endif /* defined(STM32F100xB) || defined(STM32F100xE) */
1028
 
1029
#endif /* HAL_CEC_MODULE_ENABLED */
1030
/**
1031
  * @}
1032
  */
1033
 
1034
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/