]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F3/stm32f3xx_hal_cec.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32F3 / stm32f3xx_hal_cec.c
1 /**
2   ******************************************************************************
3   * @file    stm32f3xx_hal_cec.c
4   * @author  MCD Application Team
5   * @version V1.1.0
6   * @date    12-Sept-2014
7   * @brief   CEC HAL module driver.
8   * 
9   *          This file provides firmware functions to manage the following 
10   *          functionalities of the High Definition Multimedia Interface 
11   *          Consumer Electronics Control Peripheral (CEC).
12   *           + Initialization and de-initialization functions
13   *           + IO operation functions
14   *           + Peripheral Control functions
15   *
16   *           
17   @verbatim       
18  ===============================================================================
19                         ##### How to use this driver #####
20  ===============================================================================
21     [..]
22     The CEC HAL driver can be used as follows:
23     
24     (#) Declare a CEC_HandleTypeDef handle structure.
25     (#) Initialize the CEC low level resources by implementing the HAL_CEC_MspInit ()API:
26         (##) Enable the CEC interface clock.
27         (##) CEC pins configuration:
28             (+) Enable the clock for the CEC GPIOs.
29             (+) Configure these CEC pins as alternate function pull-up.
30         (##) NVIC configuration if you need to use interrupt process (HAL_CEC_Transmit_IT()
31              and HAL_CEC_Receive_IT() APIs):
32             (+) Configure the CEC interrupt priority.
33             (+) Enable the NVIC CEC IRQ handle.
34             (@) The specific CEC interrupts (Transmission complete interrupt, 
35                 RXNE interrupt and Error Interrupts) will be managed using the macros
36                 __HAL_CEC_ENABLE_IT() and __HAL_CEC_DISABLE_IT() inside the transmit 
37                 and receive process.
38
39     (#) Program the Signal Free Time (SFT) and SFT option, Tolerance, reception stop in
40         in case of Bit Rising Error, Error-Bit generation conditions, device logical
41         address and Listen mode in the hcec Init structure.
42
43     (#) Initialize the CEC registers by calling the HAL_CEC_Init() API.
44         
45     (@) This API (HAL_CEC_Init()) configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
46         by calling the customed HAL_CEC_MspInit() API.
47
48   @endverbatim
49   ******************************************************************************
50   * @attention
51   *
52   * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
53   *
54   * Redistribution and use in source and binary forms, with or without modification,
55   * are permitted provided that the following conditions are met:
56   *   1. Redistributions of source code must retain the above copyright notice,
57   *      this list of conditions and the following disclaimer.
58   *   2. Redistributions in binary form must reproduce the above copyright notice,
59   *      this list of conditions and the following disclaimer in the documentation
60   *      and/or other materials provided with the distribution.
61   *   3. Neither the name of STMicroelectronics nor the names of its contributors
62   *      may be used to endorse or promote products derived from this software
63   *      without specific prior written permission.
64   *
65   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
66   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
67   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
68   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
69   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
70   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
71   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
72   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
73   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
74   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75   *
76   ******************************************************************************  
77   */
78
79 /* Includes ------------------------------------------------------------------*/
80 #include "stm32f3xx_hal.h"
81
82 /** @addtogroup STM32F3xx_HAL_Driver
83   * @{
84   */
85
86 #ifdef HAL_CEC_MODULE_ENABLED
87
88 #if defined(STM32F373xC) || defined(STM32F378xx)
89 /** @defgroup CEC CEC HAL module driver
90   * @brief HAL CEC module driver
91   * @{
92   */
93     
94 /* Private typedef -----------------------------------------------------------*/
95 /* Private define ------------------------------------------------------------*/
96 /** @defgroup CEC_Private CEC Private Constants
97   * @{
98   */
99 #define CEC_CFGR_FIELDS     (CEC_CFGR_SFT | CEC_CFGR_RXTOL | CEC_CFGR_BRESTP \
100                            | CEC_CFGR_BREGEN | CEC_CFGR_LBPEGEN | CEC_CFGR_SFTOPT \
101                            | CEC_CFGR_BRDNOGEN | CEC_CFGR_OAR | CEC_CFGR_LSTN)
102 /**
103  * @}
104  */ 
105 /* Private macro -------------------------------------------------------------*/
106 /* Private variables ---------------------------------------------------------*/
107 /* Private function prototypes -----------------------------------------------*/
108 static HAL_StatusTypeDef CEC_Transmit_IT(CEC_HandleTypeDef *hcec);
109 static HAL_StatusTypeDef CEC_Receive_IT(CEC_HandleTypeDef *hcec);
110 /* Exported functions ---------------------------------------------------------*/
111
112 /** @defgroup CEC_Exported_Functions CEC Exported Functions
113   * @{
114   */
115
116 /** @defgroup CEC_Exported_Functions_Group1 Initialization and de-initialization functions
117   *  @brief    Initialization and Configuration functions 
118   *
119 @verbatim                                               
120 ===============================================================================
121             ##### Initialization and Configuration functions #####
122  ===============================================================================  
123     [..]
124     This subsection provides a set of functions allowing to initialize the CEC
125       (+) The following parameters need to be configured: 
126         (++) SignalFreeTime
127         (++) Tolerance 
128         (++) BRERxStop                 (RX stopped or not upon Bit Rising Error)
129         (++) BREErrorBitGen            (Error-Bit generation in case of Bit Rising Error)
130         (++) LBPEErrorBitGen           (Error-Bit generation in case of Long Bit Period Error)
131         (++) BroadcastMsgNoErrorBitGen (Error-bit generation in case of broadcast message error)
132         (++) SignalFreeTimeOption      (SFT Timer start definition)
133         (++) OwnAddress                (CEC device address)
134         (++) ListenMode
135
136 @endverbatim
137   * @{
138   */
139
140 /**
141   * @brief Initializes the CEC mode according to the specified
142   *         parameters in the CEC_InitTypeDef and creates the associated handle .
143   * @param hcec: CEC handle
144   * @retval HAL status
145   */
146 HAL_StatusTypeDef HAL_CEC_Init(CEC_HandleTypeDef *hcec)
147 {
148   uint32_t tmpreg = 0x0;
149   
150   /* Check the CEC handle allocation */
151   if(hcec == HAL_NULL)
152   {
153     return HAL_ERROR;
154   }
155
156   /* Check the parameters */ 
157   assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance));
158   assert_param(IS_CEC_SIGNALFREETIME(hcec->Init.SignalFreeTime));
159   assert_param(IS_CEC_TOLERANCE(hcec->Init.Tolerance));  
160   assert_param(IS_CEC_BRERXSTOP(hcec->Init.BRERxStop));
161   assert_param(IS_CEC_BREERRORBITGEN(hcec->Init.BREErrorBitGen));
162   assert_param(IS_CEC_LBPEERRORBITGEN(hcec->Init.LBPEErrorBitGen));
163   assert_param(IS_CEC_BROADCASTERROR_NO_ERRORBIT_GENERATION(hcec->Init.BroadcastMsgNoErrorBitGen));
164   assert_param(IS_CEC_SFTOP(hcec->Init.SignalFreeTimeOption)); 
165   assert_param(IS_CEC_OAR_ADDRESS(hcec->Init.OwnAddress)); 
166   assert_param(IS_CEC_LISTENING_MODE(hcec->Init.ListenMode));
167   assert_param(IS_CEC_ADDRESS(hcec->Init.InitiatorAddress));  
168
169   
170   if(hcec->State == HAL_CEC_STATE_RESET)
171   {   
172     /* Init the low level hardware : GPIO, CLOCK */
173     HAL_CEC_MspInit(hcec);
174   }
175   
176   hcec->State = HAL_CEC_STATE_BUSY;
177   
178   /* Disable the Peripheral */
179   __HAL_CEC_DISABLE(hcec);
180   
181   tmpreg = hcec->Init.SignalFreeTime;
182   tmpreg |= hcec->Init.Tolerance;
183   tmpreg |= hcec->Init.BRERxStop;
184   tmpreg |= hcec->Init.BREErrorBitGen;
185   tmpreg |= hcec->Init.LBPEErrorBitGen;
186   tmpreg |= hcec->Init.BroadcastMsgNoErrorBitGen;
187   tmpreg |= hcec->Init.SignalFreeTimeOption;
188   tmpreg |= (hcec->Init.OwnAddress << CEC_CFGR_OAR_LSB_POS);
189   tmpreg |= hcec->Init.ListenMode;
190   
191   /* Write to CEC Control Register */
192   MODIFY_REG(hcec->Instance->CFGR, CEC_CFGR_FIELDS, tmpreg);
193
194   /* Enable the Peripheral */
195   __HAL_CEC_ENABLE(hcec);
196   
197   hcec->State = HAL_CEC_STATE_READY;
198   
199   return HAL_OK;
200 }
201
202
203
204 /**
205   * @brief DeInitializes the CEC peripheral 
206   * @param hcec: CEC handle
207   * @retval HAL status
208   */
209 HAL_StatusTypeDef HAL_CEC_DeInit(CEC_HandleTypeDef *hcec)
210 {
211   /* Check the CEC handle allocation */
212   if(hcec == HAL_NULL)
213   {
214     return HAL_ERROR;
215   }
216
217   /* Check the parameters */
218   assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance));
219
220   hcec->State = HAL_CEC_STATE_BUSY;
221   
222   /* DeInit the low level hardware */
223   HAL_CEC_MspDeInit(hcec);
224   /* Disable the Peripheral */
225   __HAL_CEC_DISABLE(hcec);
226   
227   hcec->ErrorCode = HAL_CEC_ERROR_NONE;
228   hcec->State = HAL_CEC_STATE_RESET;
229   
230   /* Process Unlock */
231   __HAL_UNLOCK(hcec);
232   
233   return HAL_OK;
234 }
235
236 /**
237   * @brief CEC MSP Init
238   * @param hcec: CEC handle
239   * @retval None
240   */
241  __weak void HAL_CEC_MspInit(CEC_HandleTypeDef *hcec)
242 {
243   /* NOTE : This function should not be modified, when the callback is needed,
244             the HAL_CEC_MspInit can be implemented in the user file
245    */ 
246 }
247
248 /**
249   * @brief CEC MSP DeInit
250   * @param hcec: CEC handle
251   * @retval None
252   */
253  __weak void HAL_CEC_MspDeInit(CEC_HandleTypeDef *hcec)
254 {
255   /* NOTE : This function should not be modified, when the callback is needed,
256             the HAL_CEC_MspDeInit can be implemented in the user file
257    */ 
258 }
259
260 /**
261   * @}
262   */
263
264 /** @defgroup CEC_Exported_Functions_Group2 Input and Output operation functions 
265   *  @brief CEC Transmit/Receive functions 
266   *
267 @verbatim   
268  ===============================================================================
269                       ##### I/O operation functions ##### 
270  ===============================================================================  
271     This subsection provides a set of functions allowing to manage the CEC data transfers.
272     
273     (#) The CEC handle must contain the initiator (TX side) and the destination (RX side)
274         logical addresses (4-bit long addresses, 0xF for broadcast messages destination)
275     
276     (#) There are two mode of transfer:
277        (+) Blocking mode: The communication is performed in polling mode. 
278             The HAL status of all data processing is returned by the same function 
279             after finishing transfer.  
280        (+) No-Blocking mode: The communication is performed using Interrupts. 
281            These API's return the HAL status.
282            The end of the data processing will be indicated through the 
283            dedicated CEC IRQ when using Interrupt mode.
284            The HAL_CEC_TxCpltCallback(), HAL_CEC_RxCpltCallback() user callbacks 
285            will be executed respectivelly at the end of the transmit or Receive process
286            The HAL_CEC_ErrorCallback()user callback will be executed when a communication 
287            error is detected
288
289     (#) Blocking mode API's are :
290         (+) HAL_CEC_Transmit()
291         (+) HAL_CEC_Receive() 
292         
293     (#) Non-Blocking mode API's with Interrupt are :
294         (+) HAL_CEC_Transmit_IT()
295         (+) HAL_CEC_Receive_IT()
296         (+) HAL_CEC_IRQHandler()
297
298     (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
299         (+) HAL_CEC_TxCpltCallback()
300         (+) HAL_CEC_RxCpltCallback()
301         (+) HAL_CEC_ErrorCallback()
302       
303 @endverbatim
304   * @{
305   */
306
307 /**
308   * @brief Send data in blocking mode 
309   * @param hcec: CEC handle
310   * @param DestinationAddress: destination logical address      
311   * @param pData: pointer to input byte data buffer
312   * @param Size: amount of data to be sent in bytes (without counting the header).
313   *              0 means only the header is sent (ping operation).
314   *              Maximum TX size is 15 bytes (1 opcode and up to 14 operands).    
315   * @param  Timeout: Timeout duration.
316   * @retval HAL status
317   */
318 HAL_StatusTypeDef HAL_CEC_Transmit(CEC_HandleTypeDef *hcec, uint8_t DestinationAddress, uint8_t *pData, uint32_t Size, uint32_t Timeout)
319 {
320   uint8_t  temp = 0;  
321   uint32_t tempisr = 0;   
322   uint32_t tickstart = 0;
323
324   if((hcec->State == HAL_CEC_STATE_READY) && (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) == RESET)) 
325   {
326     hcec->ErrorCode = HAL_CEC_ERROR_NONE;
327     if((pData == HAL_NULL) && (Size > 0)) 
328     {
329       hcec->State = HAL_CEC_STATE_ERROR;
330       return  HAL_ERROR;                                    
331     }
332
333     assert_param(IS_CEC_ADDRESS(DestinationAddress)); 
334     assert_param(IS_CEC_MSGSIZE(Size));
335     
336     /* Process Locked */
337     __HAL_LOCK(hcec);
338     
339     hcec->State = HAL_CEC_STATE_BUSY_TX;
340
341     hcec->TxXferCount = Size;
342     
343     /* case no data to be sent, sender is only pinging the system */
344     if (Size == 0)
345     {
346       /* Set TX End of Message (TXEOM) bit, must be set before writing data to TXDR */
347       __HAL_CEC_LAST_BYTE_TX_SET(hcec);
348     }
349     
350     /* send header block */
351     temp = (uint8_t)((uint32_t)(hcec->Init.InitiatorAddress) << CEC_INITIATOR_LSB_POS) | DestinationAddress;
352     hcec->Instance->TXDR = temp;
353     /* Set TX Start of Message  (TXSOM) bit */
354     __HAL_CEC_FIRST_BYTE_TX_SET(hcec);
355     
356     while (hcec->TxXferCount > 0)
357     {
358       hcec->TxXferCount--;
359
360       tickstart = HAL_GetTick();
361       while(HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_ISR_TXBR))
362       {
363         if(Timeout != HAL_MAX_DELAY)
364         {
365           if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
366           {
367             hcec->State = HAL_CEC_STATE_TIMEOUT; 
368             /* Process Unlocked */
369             __HAL_UNLOCK(hcec);  
370             return HAL_TIMEOUT;
371           }
372         }        
373
374         /* check whether error occured while waiting for TXBR to be set:
375          * has Tx underrun occurred ?
376          * has Tx error occurred ?
377          * has Tx Missing Acknowledge error occurred ? 
378          * has Arbitration Loss error occurred ? */
379         tempisr = hcec->Instance->ISR;
380         if ((tempisr & (CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE|CEC_ISR_ARBLST)) != 0)
381         {
382           /* copy ISR for error handling purposes */
383           hcec->ErrorCode = tempisr;
384          /* clear all error flags by default */
385          __HAL_CEC_CLEAR_FLAG(hcec, (CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE|CEC_ISR_ARBLST));
386          hcec->State = HAL_CEC_STATE_ERROR;
387          __HAL_UNLOCK(hcec);
388          return  HAL_ERROR;                                    
389         }
390       } 
391       /* TXBR to clear BEFORE writing TXDR register */
392       __HAL_CEC_CLEAR_FLAG(hcec,CEC_ISR_TXBR);
393       if (hcec->TxXferCount == 0)
394       {
395         /* if last byte transmission, set TX End of Message (TXEOM) bit */
396         __HAL_CEC_LAST_BYTE_TX_SET(hcec);
397       }
398       hcec->Instance->TXDR = *pData++;
399       
400       /* error check after TX byte write up */
401       tempisr = hcec->Instance->ISR;
402       if ((tempisr & (CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE|CEC_ISR_ARBLST)) != 0)
403       {
404         /* copy ISR for error handling purposes */
405         hcec->ErrorCode = tempisr;
406         /* clear all error flags by default */
407         __HAL_CEC_CLEAR_FLAG(hcec, (CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE|CEC_ISR_ARBLST));
408         hcec->State = HAL_CEC_STATE_ERROR;
409         __HAL_UNLOCK(hcec);
410         return  HAL_ERROR;                                    
411       }
412     } /* end while (while (hcec->TxXferCount > 0)) */
413     
414    
415     /* if no error up to this point, check that transmission is  
416      * complete, that is wait until TXEOM is reset */
417     tickstart = HAL_GetTick();
418
419     while (HAL_IS_BIT_SET(hcec->Instance->CR, CEC_CR_TXEOM))
420     {
421       if(Timeout != HAL_MAX_DELAY)
422       {
423         if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
424         {
425           hcec->State = HAL_CEC_STATE_ERROR;
426           __HAL_UNLOCK(hcec);             
427           return HAL_TIMEOUT;
428         }
429       } 
430     }
431
432     /* Final error check once all bytes have been transmitted */
433     tempisr = hcec->Instance->ISR;
434     if ((tempisr & (CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE)) != 0)
435     {
436       /* copy ISR for error handling purposes */
437       hcec->ErrorCode = tempisr;
438       /* clear all error flags by default */
439       __HAL_CEC_CLEAR_FLAG(hcec, (CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE));
440       hcec->State = HAL_CEC_STATE_ERROR;
441       __HAL_UNLOCK(hcec);
442       return  HAL_ERROR;                                    
443     } 
444
445     hcec->State = HAL_CEC_STATE_READY;
446     __HAL_UNLOCK(hcec);
447     
448     return HAL_OK;
449   }
450   else
451   {
452     return HAL_BUSY;   
453   }
454 }
455
456 /**
457   * @brief Receive data in blocking mode. Must be invoked when RXBR has been set. 
458   * @param hcec: CEC handle
459   * @param pData: pointer to received data buffer.
460   * @param Timeout: Timeout duration.
461   *       Note that the received data size is not known beforehand, the latter is known
462   *       when the reception is complete and is stored in hcec->RxXferSize.  
463   *       hcec->RxXferSize is the sum of opcodes + operands (0 to 14 operands max).
464   *       If only a header is received, hcec->RxXferSize = 0    
465   * @retval HAL status
466   */
467 HAL_StatusTypeDef HAL_CEC_Receive(CEC_HandleTypeDef *hcec, uint8_t *pData, uint32_t Timeout)
468
469   uint32_t temp;
470   uint32_t tickstart = 0;   
471
472   if (hcec->State == HAL_CEC_STATE_READY)
473   { 
474     hcec->ErrorCode = HAL_CEC_ERROR_NONE;
475     if (pData == HAL_NULL) 
476     {
477       hcec->State = HAL_CEC_STATE_ERROR;
478       return  HAL_ERROR;                                    
479     }
480     
481     hcec->RxXferSize = 0;
482     /* Process Locked */
483     __HAL_LOCK(hcec);
484     
485     
486     /* Rx loop until CEC_ISR_RXEND  is set */
487     while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_ISR_RXEND))
488     {
489       tickstart = HAL_GetTick();
490       /* Wait for next byte to be received */
491       while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_ISR_RXBR))
492       {
493         if(Timeout != HAL_MAX_DELAY)
494         {
495           if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
496           {
497             hcec->State = HAL_CEC_STATE_TIMEOUT;
498             __HAL_UNLOCK(hcec);    
499             return HAL_TIMEOUT;
500           }
501         }
502         /* any error so far ? 
503          * has Rx Missing Acknowledge occurred ?
504          * has Rx Long Bit Period error occurred ?
505          * has Rx Short Bit Period error occurred ? 
506          * has Rx Bit Rising error occurred ?             
507          * has Rx Overrun error occurred ? */
508         temp = (uint32_t) (hcec->Instance->ISR);
509         if ((temp & (CEC_ISR_RXACKE|CEC_ISR_LBPE|CEC_ISR_SBPE|CEC_ISR_BRE|CEC_ISR_RXOVR)) != 0)
510         {
511           /* copy ISR for error handling purposes */
512           hcec->ErrorCode = temp;
513           /* clear all error flags by default */
514           __HAL_CEC_CLEAR_FLAG(hcec, (CEC_ISR_RXACKE|CEC_ISR_LBPE|CEC_ISR_SBPE|CEC_ISR_BRE|CEC_ISR_RXOVR));
515           hcec->State = HAL_CEC_STATE_ERROR;
516           __HAL_UNLOCK(hcec);
517           return  HAL_ERROR;                                    
518         }
519       } /* while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_ISR_RXBR)) */
520   
521
522       /* read received data */
523       *pData++ = hcec->Instance->RXDR;
524       temp = (uint32_t) (hcec->Instance->ISR);
525       /* end of message ? */
526       if ((temp &  CEC_ISR_RXEND) != 0)      
527       {
528          assert_param(IS_CEC_MSGSIZE(hcec->RxXferSize));
529          __HAL_CEC_CLEAR_FLAG(hcec,CEC_ISR_RXEND);
530           hcec->State = HAL_CEC_STATE_READY;  
531          __HAL_UNLOCK(hcec);  
532          return HAL_OK; 
533       }
534       
535       /* clear Rx-Byte Received flag */
536       __HAL_CEC_CLEAR_FLAG(hcec,CEC_ISR_RXBR); 
537       /* increment payload byte counter */
538        hcec->RxXferSize++;
539     } /* while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_ISR_RXEND)) */ 
540     
541     /* if the instructions below are executed, it means RXEND was set when RXBR was 
542      * set for the first time:
543      * the code within the "while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_ISR_RXEND))"
544      * loop has not been executed and this means a single byte has been sent */
545     *pData++ = hcec->Instance->RXDR;
546      /* only one header is received: RxXferSize is set to 0 (no operand, no opcode) */ 
547      hcec->RxXferSize = 0;
548      __HAL_CEC_CLEAR_FLAG(hcec,CEC_ISR_RXEND);
549                              
550     hcec->State = HAL_CEC_STATE_READY;  
551     __HAL_UNLOCK(hcec);  
552     return HAL_OK;
553   }
554   else
555   {
556     return HAL_BUSY;   
557   }
558 }
559
560
561 /**
562   * @brief Send data in interrupt mode 
563   * @param hcec: CEC handle 
564   * @param DestinationAddress: destination logical address      
565   * @param pData: pointer to input byte data buffer
566   * @param Size: amount of data to be sent in bytes (without counting the header).
567   *              0 means only the header is sent (ping operation).
568   *              Maximum TX size is 15 bytes (1 opcode and up to 14 operands).    
569   * @retval HAL status
570   */  
571 HAL_StatusTypeDef HAL_CEC_Transmit_IT(CEC_HandleTypeDef *hcec, uint8_t DestinationAddress, uint8_t *pData, uint32_t Size)
572 {
573   uint8_t  temp = 0; 
574   /* if the IP isn't already busy and if there is no previous transmission
575      already pending due to arbitration lost */
576   if (((hcec->State == HAL_CEC_STATE_READY) || (hcec->State == HAL_CEC_STATE_STANDBY_RX)) 
577   &&   (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) == RESET)) 
578   {    
579     if((pData == HAL_NULL) && (Size > 0)) 
580     {
581       hcec->State = HAL_CEC_STATE_ERROR;
582       return  HAL_ERROR;                                    
583     }
584
585     assert_param(IS_CEC_ADDRESS(DestinationAddress)); 
586     assert_param(IS_CEC_MSGSIZE(Size));
587     
588     /* Process Locked */
589     __HAL_LOCK(hcec);
590     hcec->pTxBuffPtr = pData;
591     hcec->State = HAL_CEC_STATE_BUSY_TX;
592     hcec->ErrorCode = HAL_CEC_ERROR_NONE;
593     
594     /* Disable Peripheral to write CEC_IER register */
595     __HAL_CEC_DISABLE(hcec);
596     
597     /* Enable the following two CEC Transmission interrupts as
598      * well as the following CEC Transmission Errors interrupts: 
599      * Tx Byte Request IT 
600      * End of Transmission IT
601      * Tx Missing Acknowledge IT
602      * Tx-Error IT
603      * Tx-Buffer Underrun IT 
604      * Tx arbitration lost     */
605     __HAL_CEC_ENABLE_IT(hcec, CEC_IER_TXBRIE|CEC_IER_TXENDIE|CEC_IER_TX_ALL_ERR);
606                                      
607     /* Enable the Peripheral */
608     __HAL_CEC_ENABLE(hcec);
609   
610     /* initialize the number of bytes to send,
611      * 0 means only one header is sent (ping operation) */
612     hcec->TxXferCount = Size;
613     
614     /* Process Unlocked */
615     __HAL_UNLOCK(hcec); 
616     
617     /* in case of no payload (Size = 0), sender is only pinging the system;
618      * Set TX End of Message (TXEOM) bit, must be set before writing data to TXDR */
619     if (Size == 0)
620     {
621       __HAL_CEC_LAST_BYTE_TX_SET(hcec);
622     }
623     
624     /* send header block */
625     temp = (uint8_t)((uint32_t)(hcec->Init.InitiatorAddress) << CEC_INITIATOR_LSB_POS) | DestinationAddress;
626     hcec->Instance->TXDR = temp;
627     /* Set TX Start of Message  (TXSOM) bit */
628     __HAL_CEC_FIRST_BYTE_TX_SET(hcec);
629     
630     return HAL_OK;
631   }
632     /* if the IP is already busy or if there is a previous transmission
633      already pending due to arbitration loss */
634   else if ((hcec->State == HAL_CEC_STATE_BUSY_TX)
635         || (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) != RESET))
636   {
637     __HAL_LOCK(hcec);
638     /* set state to BUSY TX, in case it wasn't set already (case
639      * of transmission new attempt after arbitration loss) */
640     if (hcec->State != HAL_CEC_STATE_BUSY_TX)
641     {
642       hcec->State = HAL_CEC_STATE_BUSY_TX;
643     }
644
645     /* if all data have been sent */
646     if(hcec->TxXferCount == 0)
647     {
648       /* Disable Peripheral to write CEC_IER register */
649       __HAL_CEC_DISABLE(hcec);
650       
651       /* Disable the CEC Transmission Interrupts */
652       __HAL_CEC_DISABLE_IT(hcec, CEC_IER_TXBRIE|CEC_IER_TXENDIE);
653       /* Disable the CEC Transmission Error Interrupts */
654       __HAL_CEC_DISABLE_IT(hcec, CEC_IER_TX_ALL_ERR);
655       
656       /* Enable the Peripheral */
657       __HAL_CEC_ENABLE(hcec);
658     
659       __HAL_CEC_CLEAR_FLAG(hcec,CEC_ISR_TXBR|CEC_ISR_TXEND);
660           
661       hcec->State = HAL_CEC_STATE_READY;
662       /* Call the Process Unlocked before calling the Tx call back API to give the possibility to
663       start again the Transmission under the Tx call back API */
664       __HAL_UNLOCK(hcec);
665       
666       HAL_CEC_TxCpltCallback(hcec);
667       
668       return HAL_OK;
669     }
670     else
671     {
672       if (hcec->TxXferCount == 1)
673       {
674         /* if this is the last byte transmission, set TX End of Message (TXEOM) bit */
675         __HAL_CEC_LAST_BYTE_TX_SET(hcec);
676       }
677       /* clear Tx-Byte request flag */
678        __HAL_CEC_CLEAR_FLAG(hcec,CEC_ISR_TXBR); 
679        hcec->Instance->TXDR = *hcec->pTxBuffPtr++;
680       hcec->TxXferCount--;
681       
682       /* Process Unlocked */
683       __HAL_UNLOCK(hcec);
684   
685       return HAL_OK;
686     }
687   }
688   else
689   {
690     return HAL_BUSY;   
691   }
692 }
693
694
695 /**
696   * @brief Receive data in interrupt mode. 
697   * @param hcec: CEC handle
698   * @param pData: pointer to received data buffer.
699   * Note that the received data size is not known beforehand, the latter is known
700   * when the reception is complete and is stored in hcec->RxXferSize.  
701   * hcec->RxXferSize is the sum of opcodes + operands (0 to 14 operands max).
702   * If only a header is received, hcec->RxXferSize = 0    
703   * @retval HAL status
704   */  
705 HAL_StatusTypeDef HAL_CEC_Receive_IT(CEC_HandleTypeDef *hcec, uint8_t *pData)
706 {  
707   if(hcec->State == HAL_CEC_STATE_READY)
708   {
709     if(pData == HAL_NULL) 
710     {
711       hcec->State = HAL_CEC_STATE_ERROR;
712       return HAL_ERROR;                                    
713     }
714     
715     /* Process Locked */
716     __HAL_LOCK(hcec);
717     hcec->RxXferSize = 0;
718     hcec->pRxBuffPtr = pData;
719     hcec->ErrorCode = HAL_CEC_ERROR_NONE;
720     /* the IP is moving to a ready to receive state */
721     hcec->State = HAL_CEC_STATE_STANDBY_RX;
722
723     /* Disable Peripheral to write CEC_IER register */
724     __HAL_CEC_DISABLE(hcec);
725     
726     /* Enable the following CEC Reception Error Interrupts: 
727      * Rx overrun
728      * Rx bit rising error
729      * Rx short bit period error
730      * Rx long bit period error
731      * Rx missing acknowledge  */
732     __HAL_CEC_ENABLE_IT(hcec, CEC_IER_RX_ALL_ERR);
733     
734     /* Process Unlocked */
735     __HAL_UNLOCK(hcec);
736     
737     /* Enable the following two CEC Reception interrupts: 
738      * Rx Byte Received IT 
739      * End of Reception IT */
740     __HAL_CEC_ENABLE_IT(hcec, CEC_IER_RXBRIE|CEC_IER_RXENDIE);
741     
742     __HAL_CEC_ENABLE(hcec);
743
744     return HAL_OK;
745   }
746   else
747   {
748     return HAL_BUSY; 
749   }
750 }
751
752
753     
754 /**
755   * @brief This function handles CEC interrupt requests.
756   * @param hcec: CEC handle
757   * @retval None
758   */
759 void HAL_CEC_IRQHandler(CEC_HandleTypeDef *hcec)
760 {
761   /* save interrupts register for further error or interrupts handling purposes */
762   hcec->ErrorCode = hcec->Instance->ISR;
763   /* CEC TX missing acknowledge error interrupt occurred -------------------------------------*/
764   if((__HAL_CEC_GET_IT(hcec, CEC_ISR_TXACKE) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IER_TXACKEIE) != RESET))
765   { 
766     __HAL_CEC_CLEAR_FLAG(hcec, CEC_ISR_TXACKE);
767     hcec->State = HAL_CEC_STATE_ERROR;
768   }
769   
770   /* CEC transmit error interrupt occured --------------------------------------*/
771   if((__HAL_CEC_GET_IT(hcec, CEC_ISR_TXERR) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IER_TXERRIE) != RESET))
772   { 
773     __HAL_CEC_CLEAR_FLAG(hcec, CEC_ISR_TXERR);
774     hcec->State = HAL_CEC_STATE_ERROR;
775   }
776   
777   /* CEC TX underrun error interrupt occured --------------------------------------*/
778   if((__HAL_CEC_GET_IT(hcec, CEC_ISR_TXUDR) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IER_TXUDRIE) != RESET))
779   { 
780     __HAL_CEC_CLEAR_FLAG(hcec, CEC_ISR_TXUDR);
781     hcec->State = HAL_CEC_STATE_ERROR;
782   }
783   
784   /* CEC TX arbitration error interrupt occured --------------------------------------*/
785   if((__HAL_CEC_GET_IT(hcec, CEC_ISR_ARBLST) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IER_ARBLSTIE) != RESET))
786   { 
787     __HAL_CEC_CLEAR_FLAG(hcec, CEC_ISR_ARBLST);
788     hcec->State = HAL_CEC_STATE_ERROR;
789   }
790   
791   /* CEC RX overrun error interrupt occured --------------------------------------*/
792   if((__HAL_CEC_GET_IT(hcec, CEC_ISR_RXOVR) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IER_RXOVRIE) != RESET))
793   { 
794     __HAL_CEC_CLEAR_FLAG(hcec, CEC_ISR_RXOVR);
795     hcec->State = HAL_CEC_STATE_ERROR;
796   } 
797   
798   /* CEC RX bit rising error interrupt occured --------------------------------------*/
799   if((__HAL_CEC_GET_IT(hcec, CEC_ISR_BRE) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IER_BREIE) != RESET))
800   { 
801     __HAL_CEC_CLEAR_FLAG(hcec, CEC_ISR_BRE);
802     hcec->State = HAL_CEC_STATE_ERROR;
803   }   
804   
805   /* CEC RX short bit period error interrupt occured --------------------------------------*/
806   if((__HAL_CEC_GET_IT(hcec, CEC_ISR_SBPE) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IER_SBPEIE) != RESET))
807   { 
808     __HAL_CEC_CLEAR_FLAG(hcec, CEC_ISR_SBPE);
809     hcec->State = HAL_CEC_STATE_ERROR;
810   }   
811   
812   /* CEC RX long bit period error interrupt occured --------------------------------------*/
813   if((__HAL_CEC_GET_IT(hcec, CEC_ISR_LBPE) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IER_LBPEIE) != RESET))
814   { 
815     __HAL_CEC_CLEAR_FLAG(hcec, CEC_ISR_LBPE);
816     hcec->State = HAL_CEC_STATE_ERROR;
817   }   
818   
819   /* CEC RX missing acknowledge error interrupt occured --------------------------------------*/
820   if((__HAL_CEC_GET_IT(hcec, CEC_ISR_RXACKE) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IER_RXACKEIE) != RESET))
821   { 
822     __HAL_CEC_CLEAR_FLAG(hcec, CEC_ISR_RXACKE);
823     hcec->State = HAL_CEC_STATE_ERROR;
824   }   
825
826   if ((hcec->ErrorCode & CEC_ISR_ALL_ERROR) != 0)
827   {
828     HAL_CEC_ErrorCallback(hcec);
829   }
830
831   /* CEC RX byte received interrupt  ---------------------------------------------------*/
832   if((__HAL_CEC_GET_IT(hcec, CEC_ISR_RXBR) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IER_RXBRIE) != RESET))
833   { 
834     /* RXBR IT is cleared during HAL_CEC_Transmit_IT processing */
835     CEC_Receive_IT(hcec);
836   }
837   
838   /* CEC RX end received interrupt  ---------------------------------------------------*/
839   if((__HAL_CEC_GET_IT(hcec, CEC_ISR_RXEND) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IER_RXENDIE) != RESET))
840   { 
841     /* RXBR IT is cleared during HAL_CEC_Transmit_IT processing */
842     CEC_Receive_IT(hcec);
843   }
844   
845   
846   /* CEC TX byte request interrupt ------------------------------------------------*/
847   if((__HAL_CEC_GET_IT(hcec, CEC_ISR_TXBR) != RESET) &&(__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IER_TXBRIE) != RESET))
848   {
849     /* TXBR IT is cleared during HAL_CEC_Transmit_IT processing */
850     CEC_Transmit_IT(hcec);
851   } 
852   
853   /* CEC TX end interrupt ------------------------------------------------*/
854   if((__HAL_CEC_GET_IT(hcec, CEC_ISR_TXEND) != RESET) &&(__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IER_TXENDIE) != RESET))
855   {
856    /* TXEND IT is cleared during HAL_CEC_Transmit_IT processing */
857     CEC_Transmit_IT(hcec);
858   } 
859   
860 }
861
862
863 /**
864   * @brief Tx Transfer completed callback
865   * @param hcec: CEC handle
866   * @retval None
867   */
868  __weak void HAL_CEC_TxCpltCallback(CEC_HandleTypeDef *hcec)
869 {
870   /* NOTE : This function should not be modified, when the callback is needed,
871             the HAL_CEC_TxCpltCallback can be implemented in the user file
872    */ 
873 }
874
875 /**
876   * @brief Rx Transfer completed callback
877   * @param hcec: CEC handle
878   * @retval None
879   */
880 __weak void HAL_CEC_RxCpltCallback(CEC_HandleTypeDef *hcec)
881 {
882   /* NOTE : This function should not be modified, when the callback is needed,
883             the HAL_CEC_TxCpltCallback can be implemented in the user file
884    */
885 }
886
887 /**
888   * @brief CEC error callbacks
889   * @param hcec: CEC handle
890   * @retval None
891   */
892  __weak void HAL_CEC_ErrorCallback(CEC_HandleTypeDef *hcec)
893 {
894   /* NOTE : This function should not be modified, when the callback is needed,
895             the HAL_CEC_ErrorCallback can be implemented in the user file
896    */ 
897 }
898
899 /**
900   * @}
901   */
902
903 /** @defgroup CEC_Exported_Functions_Group3 Peripheral Control functions 
904   *  @brief   CEC control functions 
905   *
906 @verbatim   
907  ===============================================================================
908                       ##### Peripheral Control functions #####
909  ===============================================================================  
910     [..]
911     This subsection provides a set of functions allowing to control the CEC.
912      (+) HAL_CEC_GetState() API can be helpful to check in run-time the state of the CEC peripheral. 
913 @endverbatim
914   * @{
915   */
916
917
918
919
920
921 /**
922   * @brief return the CEC state
923   * @param hcec: CEC handle
924   * @retval HAL state
925   */
926 HAL_CEC_StateTypeDef HAL_CEC_GetState(CEC_HandleTypeDef *hcec)
927 {
928   return hcec->State;
929 }
930
931 /**
932 * @brief  Return the CEC error code
933 * @param  hcec : pointer to a CEC_HandleTypeDef structure that contains
934   *              the configuration information for the specified CEC.
935 * @retval CEC Error Code
936 */
937 uint32_t HAL_CEC_GetError(CEC_HandleTypeDef *hcec)
938 {
939   return hcec->ErrorCode;
940 }
941
942 /**
943   * @}
944   */
945
946 /**
947   * @}
948   */
949
950 /** @defgroup CEC_Private_Functions CEC Private Functions
951   * @{
952   */
953
954  /**
955   * @brief Send data in interrupt mode 
956   * @param hcec: CEC handle. 
957   *         Function called under interruption only, once
958   *         interruptions have been enabled by HAL_CEC_Transmit_IT()   
959   * @retval HAL status
960   */  
961 static HAL_StatusTypeDef CEC_Transmit_IT(CEC_HandleTypeDef *hcec)
962 {
963   /* if the IP is already busy or if there is a previous transmission
964      already pending due to arbitration loss */
965   if ((hcec->State == HAL_CEC_STATE_BUSY_TX)
966         || (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) != RESET))
967   {
968
969     /* set state to BUSY TX, in case it wasn't set already (case
970      * of transmission new attempt after arbitration loss) */
971     if (hcec->State != HAL_CEC_STATE_BUSY_TX)
972     {
973       hcec->State = HAL_CEC_STATE_BUSY_TX;
974     }
975
976     /* if all data have been sent */
977     if(hcec->TxXferCount == 0)
978     {
979       /* Disable Peripheral to write CEC_IER register */
980       __HAL_CEC_DISABLE(hcec);
981       
982       /* Disable the CEC Transmission Interrupts */
983       __HAL_CEC_DISABLE_IT(hcec, CEC_IER_TXBRIE|CEC_IER_TXENDIE);
984       /* Disable the CEC Transmission Error Interrupts */
985       __HAL_CEC_DISABLE_IT(hcec, CEC_IER_TX_ALL_ERR);
986       
987       /* Enable the Peripheral */
988       __HAL_CEC_ENABLE(hcec);
989     
990       __HAL_CEC_CLEAR_FLAG(hcec,CEC_ISR_TXBR|CEC_ISR_TXEND);
991           
992       hcec->State = HAL_CEC_STATE_READY;
993       
994       HAL_CEC_TxCpltCallback(hcec);
995       
996       return HAL_OK;
997     }
998     else
999     {
1000       if (hcec->TxXferCount == 1)
1001       {
1002         /* if this is the last byte transmission, set TX End of Message (TXEOM) bit */
1003         __HAL_CEC_LAST_BYTE_TX_SET(hcec);
1004       }
1005       /* clear Tx-Byte request flag */
1006        __HAL_CEC_CLEAR_FLAG(hcec,CEC_ISR_TXBR); 
1007        hcec->Instance->TXDR = *hcec->pTxBuffPtr++;
1008       hcec->TxXferCount--;
1009   
1010       return HAL_OK;
1011     }
1012   }
1013   else
1014   {
1015     return HAL_BUSY;   
1016   }
1017 }
1018
1019
1020 /**
1021   * @brief Receive data in interrupt mode. 
1022   * @param hcec: CEC handle.
1023   *         Function called under interruption only, once
1024   *         interruptions have been enabled by HAL_CEC_Receive_IT()   
1025   * @retval HAL status
1026   */  
1027 static HAL_StatusTypeDef CEC_Receive_IT(CEC_HandleTypeDef *hcec)
1028 {
1029   uint32_t tempisr;
1030   
1031   /* Three different conditions are tested to carry out the RX IT processing:
1032    * - the IP is in reception stand-by (the IP state is HAL_CEC_STATE_STANDBY_RX) and 
1033    *   the reception of the first byte is starting
1034    * - a message reception is already on-going (the IP state is HAL_CEC_STATE_BUSY_RX)
1035    *   and a new byte is being received
1036    * - a transmission has just been started (the IP state is HAL_CEC_STATE_BUSY_TX)
1037    *   but has been interrupted by a new message reception or discarded due to 
1038    *   arbitration loss: the reception of the first or higher priority message 
1039    *   (the arbitration winner) is starting */
1040   if ((hcec->State == HAL_CEC_STATE_STANDBY_RX) 
1041   ||  (hcec->State == HAL_CEC_STATE_BUSY_RX)
1042   ||  (hcec->State == HAL_CEC_STATE_BUSY_TX)) 
1043   {
1044     /* reception is starting */ 
1045     hcec->State = HAL_CEC_STATE_BUSY_RX;
1046     tempisr =  (uint32_t) (hcec->Instance->ISR);
1047     if ((tempisr & CEC_ISR_RXBR) != 0)
1048     {
1049       /* read received byte */
1050       *hcec->pRxBuffPtr++ = hcec->Instance->RXDR;
1051       /* if last byte has been received */      
1052       if ((tempisr & CEC_ISR_RXEND) != 0)
1053       {
1054         /* clear IT */
1055         __HAL_CEC_CLEAR_FLAG(hcec,CEC_ISR_RXBR|CEC_ISR_RXEND);
1056         /* RX interrupts are not disabled at this point.
1057          * Indeed, to disable the IT, the IP must be disabled first
1058          * which resets the TXSOM flag. In case of arbitration loss,
1059          * this leads to a transmission abort.
1060          * Therefore, RX interruptions disabling if so required,
1061          * is done in HAL_CEC_RxCpltCallback */
1062  
1063         /* IP state is moved to READY.
1064          * If the IP must remain in standby mode to listen
1065          * any new message, it is up to HAL_CEC_RxCpltCallback
1066          * to move it again to HAL_CEC_STATE_STANDBY_RX */  
1067         hcec->State = HAL_CEC_STATE_READY; 
1068
1069         HAL_CEC_RxCpltCallback(hcec);
1070         
1071         return HAL_OK;
1072       } 
1073       __HAL_CEC_CLEAR_FLAG(hcec, CEC_ISR_RXBR);  
1074
1075       hcec->RxXferSize++;
1076       
1077       return HAL_OK;
1078     }
1079     else
1080     {
1081       return HAL_BUSY; 
1082     }
1083   }
1084   else
1085   {
1086     return HAL_BUSY; 
1087   }
1088 }
1089
1090 /**
1091  * @}
1092  */ 
1093  
1094 /**
1095   * @}
1096   */
1097
1098 #endif /* defined(STM32F373xC) || defined(STM32F378xx) */
1099
1100 #endif /* HAL_CEC_MODULE_ENABLED */
1101 /**
1102   * @}
1103   */
1104
1105 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/