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