source: asp3_wo_tecs/trunk/arch/arm_m_gcc/stm32f4xx_stm32cube/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cec.c@ 303

Last change on this file since 303 was 303, checked in by ertl-honda, 7 years ago

nucleo_f401re依存部の追加

File size: 36.8 KB
Line 
1/**
2 ******************************************************************************
3 * @file stm32f4xx_hal_cec.c
4 * @author MCD Application Team
5 * @version V1.4.1
6 * @date 09-October-2015
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 follow:
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) 2015 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 "stm32f4xx_hal.h"
81
82/** @addtogroup STM32F4xx_HAL_Driver
83 * @{
84 */
85
86/** @defgroup CEC CEC
87 * @brief HAL CEC module driver
88 * @{
89 */
90#ifdef HAL_CEC_MODULE_ENABLED
91
92#if defined(STM32F446xx)
93
94/* Private typedef -----------------------------------------------------------*/
95/* Private define ------------------------------------------------------------*/
96/** @defgroup CEC_Private_Constants 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
106/* Private macro -------------------------------------------------------------*/
107/* Private variables ---------------------------------------------------------*/
108/* Private function prototypes -----------------------------------------------*/
109/** @defgroup CEC_Private_Functions CEC Private Functions
110 * @{
111 */
112static HAL_StatusTypeDef CEC_Transmit_IT(CEC_HandleTypeDef *hcec);
113static HAL_StatusTypeDef CEC_Receive_IT(CEC_HandleTypeDef *hcec);
114/**
115 * @}
116 */
117
118/* Exported functions ---------------------------------------------------------*/
119/** @defgroup CEC_Exported_Functions CEC Exported Functions
120 * @{
121 */
122
123/** @defgroup CEC_Exported_Functions_Group1 Initialization and de-initialization functions
124 * @brief Initialization and Configuration functions
125 *
126@verbatim
127===============================================================================
128 ##### Initialization and Configuration functions #####
129 ===============================================================================
130 [..]
131 This subsection provides a set of functions allowing to initialize the CEC
132 (+) The following parameters need to be configured:
133 (++) SignalFreeTime
134 (++) Tolerance
135 (++) BRERxStop (RX stopped or not upon Bit Rising Error)
136 (++) BREErrorBitGen (Error-Bit generation in case of Bit Rising Error)
137 (++) LBPEErrorBitGen (Error-Bit generation in case of Long Bit Period Error)
138 (++) BroadcastMsgNoErrorBitGen (Error-bit generation in case of broadcast message error)
139 (++) SignalFreeTimeOption (SFT Timer start definition)
140 (++) OwnAddress (CEC device address)
141 (++) ListenMode
142
143@endverbatim
144 * @{
145 */
146
147/**
148 * @brief Initializes the CEC mode according to the specified
149 * parameters in the CEC_InitTypeDef and creates the associated handle .
150 * @param hcec: CEC handle
151 * @retval HAL status
152 */
153HAL_StatusTypeDef HAL_CEC_Init(CEC_HandleTypeDef *hcec)
154{
155 uint32_t tmpreg = 0x0;
156
157 /* Check the CEC handle allocation */
158 if(hcec == NULL)
159 {
160 return HAL_ERROR;
161 }
162
163 /* Check the parameters */
164 assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance));
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 /* Allocate lock resource and initialize it */
180 hcec->Lock = HAL_UNLOCKED;
181 /* Init the low level hardware : GPIO, CLOCK */
182 HAL_CEC_MspInit(hcec);
183 }
184
185 hcec->State = HAL_CEC_STATE_BUSY;
186
187 /* Disable the Peripheral */
188 __HAL_CEC_DISABLE(hcec);
189
190 tmpreg = hcec->Init.SignalFreeTime;
191 tmpreg |= hcec->Init.Tolerance;
192 tmpreg |= hcec->Init.BRERxStop;
193 tmpreg |= hcec->Init.BREErrorBitGen;
194 tmpreg |= hcec->Init.LBPEErrorBitGen;
195 tmpreg |= hcec->Init.BroadcastMsgNoErrorBitGen;
196 tmpreg |= hcec->Init.SignalFreeTimeOption;
197 tmpreg |= (hcec->Init.OwnAddress << CEC_CFGR_OAR_LSB_POS);
198 tmpreg |= hcec->Init.ListenMode;
199
200 /* Write to CEC Control Register */
201 MODIFY_REG(hcec->Instance->CFGR, CEC_CFGR_FIELDS, tmpreg);
202
203 /* Enable the Peripheral */
204 __HAL_CEC_ENABLE(hcec);
205
206 hcec->State = HAL_CEC_STATE_READY;
207
208 return HAL_OK;
209}
210
211/**
212 * @brief DeInitializes the CEC peripheral
213 * @param hcec: CEC handle
214 * @retval HAL status
215 */
216HAL_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/** @defgroup CEC_Exported_Functions_Group2 Input and Output operation functions
271 * @brief CEC Transmit/Receive functions
272 *
273@verbatim
274 ===============================================================================
275 ##### IO operation functions #####
276 ===============================================================================
277 This subsection provides a set of functions allowing to manage the CEC data transfers.
278
279 (#) The CEC handle must contain the initiator (TX side) and the destination (RX side)
280 logical addresses (4-bit long addresses, 0xF for broadcast messages destination)
281
282 (#) There are two mode of transfer:
283 (+) Blocking mode: The communication is performed in polling mode.
284 The HAL status of all data processing is returned by the same function
285 after finishing transfer.
286 (+) No-Blocking mode: The communication is performed using Interrupts.
287 These API's return the HAL status.
288 The end of the data processing will be indicated through the
289 dedicated CEC IRQ when using Interrupt mode.
290 The HAL_CEC_TxCpltCallback(), HAL_CEC_RxCpltCallback() user callbacks
291 will be executed respectivelly at the end of the transmit or Receive process
292 The HAL_CEC_ErrorCallback()user callback will be executed when a communication
293 error is detected
294
295 (#) Blocking mode API's are :
296 (+) HAL_CEC_Transmit()
297 (+) HAL_CEC_Receive()
298
299 (#) Non-Blocking mode API's with Interrupt are :
300 (+) HAL_CEC_Transmit_IT()
301 (+) HAL_CEC_Receive_IT()
302 (+) HAL_CEC_IRQHandler()
303
304 (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
305 (+) HAL_CEC_TxCpltCallback()
306 (+) HAL_CEC_RxCpltCallback()
307 (+) HAL_CEC_ErrorCallback()
308
309@endverbatim
310 * @{
311 */
312
313/**
314 * @brief Send data in blocking mode
315 * @param hcec: CEC handle
316 * @param DestinationAddress: destination logical address
317 * @param pData: pointer to input byte data buffer
318 * @param Size: amount of data to be sent in bytes (without counting the header).
319 * 0 means only the header is sent (ping operation).
320 * Maximum TX size is 15 bytes (1 opcode and up to 14 operands).
321 * @param Timeout: Timeout duration.
322 * @retval HAL status
323 */
324HAL_StatusTypeDef HAL_CEC_Transmit(CEC_HandleTypeDef *hcec, uint8_t DestinationAddress, uint8_t *pData, uint32_t Size, uint32_t Timeout)
325{
326 uint8_t temp = 0;
327 uint32_t tempisr = 0;
328 uint32_t tickstart = 0;
329
330 if((hcec->State == HAL_CEC_STATE_READY) && (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) == RESET))
331 {
332 hcec->ErrorCode = HAL_CEC_ERROR_NONE;
333 if((pData == NULL ) && (Size > 0))
334 {
335 hcec->State = HAL_CEC_STATE_ERROR;
336 return HAL_ERROR;
337 }
338
339 assert_param(IS_CEC_ADDRESS(DestinationAddress));
340 assert_param(IS_CEC_MSGSIZE(Size));
341
342 /* Process Locked */
343 __HAL_LOCK(hcec);
344
345 hcec->State = HAL_CEC_STATE_BUSY_TX;
346
347 hcec->TxXferCount = Size;
348
349 /* case no data to be sent, sender is only pinging the system */
350 if (Size == 0)
351 {
352 /* Set TX End of Message (TXEOM) bit, must be set before writing data to TXDR */
353 __HAL_CEC_LAST_BYTE_TX_SET(hcec);
354 }
355
356 /* send header block */
357 temp = ((uint32_t)hcec->Init.InitiatorAddress << CEC_INITIATOR_LSB_POS) | DestinationAddress;
358 hcec->Instance->TXDR = temp;
359 /* Set TX Start of Message (TXSOM) bit */
360 __HAL_CEC_FIRST_BYTE_TX_SET(hcec);
361
362 while (hcec->TxXferCount > 0)
363 {
364 hcec->TxXferCount--;
365
366 tickstart = HAL_GetTick();
367 while(HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_FLAG_TXBR))
368 {
369 if(Timeout != HAL_MAX_DELAY)
370 {
371 if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
372 {
373 hcec->State = HAL_CEC_STATE_TIMEOUT;
374 /* Process Unlocked */
375 __HAL_UNLOCK(hcec);
376 return HAL_TIMEOUT;
377 }
378 }
379
380 /* check whether error occured while waiting for TXBR to be set:
381 * has Tx underrun occurred ?
382 * has Tx error occurred ?
383 * has Tx Missing Acknowledge error occurred ?
384 * has Arbitration Loss error occurred ? */
385 tempisr = hcec->Instance->ISR;
386 if ((tempisr & (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE|CEC_FLAG_ARBLST)) != 0)
387 {
388 /* copy ISR for error handling purposes */
389 hcec->ErrorCode = tempisr;
390 /* clear all error flags by default */
391 __HAL_CEC_CLEAR_FLAG(hcec, (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE|CEC_FLAG_ARBLST));
392 hcec->State = HAL_CEC_STATE_ERROR;
393 __HAL_UNLOCK(hcec);
394 return HAL_ERROR;
395 }
396 }
397 /* TXBR to clear BEFORE writing TXDR register */
398 __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXBR);
399 if (hcec->TxXferCount == 0)
400 {
401 /* if last byte transmission, set TX End of Message (TXEOM) bit */
402 __HAL_CEC_LAST_BYTE_TX_SET(hcec);
403 }
404 hcec->Instance->TXDR = *pData++;
405
406 /* error check after TX byte write up */
407 tempisr = hcec->Instance->ISR;
408 if ((tempisr & (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE|CEC_FLAG_ARBLST)) != 0)
409 {
410 /* copy ISR for error handling purposes */
411 hcec->ErrorCode = tempisr;
412 /* clear all error flags by default */
413 __HAL_CEC_CLEAR_FLAG(hcec, (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE|CEC_FLAG_ARBLST));
414 hcec->State = HAL_CEC_STATE_ERROR;
415 __HAL_UNLOCK(hcec);
416 return HAL_ERROR;
417 }
418 } /* end while (while (hcec->TxXferCount > 0)) */
419
420 /* if no error up to this point, check that transmission is
421 * complete, that is wait until TXEOM is reset */
422 tickstart = HAL_GetTick();
423
424 while (HAL_IS_BIT_SET(hcec->Instance->CR, CEC_CR_TXEOM))
425 {
426 if(Timeout != HAL_MAX_DELAY)
427 {
428 if((HAL_GetTick() - tickstart) > Timeout)
429 {
430 hcec->State = HAL_CEC_STATE_ERROR;
431 __HAL_UNLOCK(hcec);
432 return HAL_TIMEOUT;
433 }
434 }
435 }
436
437 /* Final error check once all bytes have been transmitted */
438 tempisr = hcec->Instance->ISR;
439 if ((tempisr & (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE)) != 0)
440 {
441 /* copy ISR for error handling purposes */
442 hcec->ErrorCode = tempisr;
443 /* clear all error flags by default */
444 __HAL_CEC_CLEAR_FLAG(hcec, (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE));
445 hcec->State = HAL_CEC_STATE_ERROR;
446 __HAL_UNLOCK(hcec);
447 return HAL_ERROR;
448 }
449
450 hcec->State = HAL_CEC_STATE_READY;
451 __HAL_UNLOCK(hcec);
452
453 return HAL_OK;
454 }
455 else
456 {
457 return HAL_BUSY;
458 }
459}
460
461/**
462 * @brief Receive data in blocking mode. Must be invoked when RXBR has been set.
463 * @param hcec: CEC handle
464 * @param pData: pointer to received data buffer.
465 * @param Timeout: Timeout duration.
466 * Note that the received data size is not known beforehand, the latter is known
467 * when the reception is complete and is stored in hcec->RxXferSize.
468 * hcec->RxXferSize is the sum of opcodes + operands (0 to 14 operands max).
469 * If only a header is received, hcec->RxXferSize = 0
470 * @retval HAL status
471 */
472HAL_StatusTypeDef HAL_CEC_Receive(CEC_HandleTypeDef *hcec, uint8_t *pData, uint32_t Timeout)
473{
474 uint32_t temp;
475 uint32_t tickstart = 0;
476
477 if (hcec->State == HAL_CEC_STATE_READY)
478 {
479 hcec->ErrorCode = HAL_CEC_ERROR_NONE;
480 if (pData == NULL )
481 {
482 hcec->State = HAL_CEC_STATE_ERROR;
483 return HAL_ERROR;
484 }
485
486 hcec->RxXferSize = 0;
487 /* Process Locked */
488 __HAL_LOCK(hcec);
489
490 /* Rx loop until CEC_ISR_RXEND is set */
491 while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_FLAG_RXEND))
492 {
493 tickstart = HAL_GetTick();
494 /* Wait for next byte to be received */
495 while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_FLAG_RXBR))
496 {
497 if(Timeout != HAL_MAX_DELAY)
498 {
499 if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
500 {
501 hcec->State = HAL_CEC_STATE_TIMEOUT;
502 __HAL_UNLOCK(hcec);
503 return HAL_TIMEOUT;
504 }
505 }
506 /* any error so far ?
507 * has Rx Missing Acknowledge occurred ?
508 * has Rx Long Bit Period error occurred ?
509 * has Rx Short Bit Period error occurred ?
510 * has Rx Bit Rising error occurred ?
511 * has Rx Overrun error occurred ? */
512 temp = (uint32_t) (hcec->Instance->ISR);
513 if ((temp & (CEC_FLAG_RXACKE|CEC_FLAG_LBPE|CEC_FLAG_SBPE|CEC_FLAG_BRE|CEC_FLAG_RXOVR)) != 0)
514 {
515 /* copy ISR for error handling purposes */
516 hcec->ErrorCode = temp;
517 /* clear all error flags by default */
518 __HAL_CEC_CLEAR_FLAG(hcec,(CEC_FLAG_RXACKE|CEC_FLAG_LBPE|CEC_FLAG_SBPE|CEC_FLAG_BRE|CEC_FLAG_RXOVR));
519 hcec->State = HAL_CEC_STATE_ERROR;
520 __HAL_UNLOCK(hcec);
521 return HAL_ERROR;
522 }
523 } /* while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_ISR_RXBR)) */
524
525 /* read received data */
526 *pData++ = hcec->Instance->RXDR;
527 temp = (uint32_t) (hcec->Instance->ISR);
528 /* end of message ? */
529 if ((temp & CEC_ISR_RXEND) != 0)
530 {
531 assert_param(IS_CEC_MSGSIZE(hcec->RxXferSize));
532 __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_RXEND);
533 hcec->State = HAL_CEC_STATE_READY;
534 __HAL_UNLOCK(hcec);
535 return HAL_OK;
536 }
537
538 /* clear Rx-Byte Received flag */
539 __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_RXBR);
540 /* increment payload byte counter */
541 hcec->RxXferSize++;
542 } /* while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_ISR_RXEND)) */
543
544 /* if the instructions below are executed, it means RXEND was set when RXBR was
545 * set for the first time:
546 * the code within the "while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_ISR_RXEND))"
547 * loop has not been executed and this means a single byte has been sent */
548 *pData++ = hcec->Instance->RXDR;
549 /* only one header is received: RxXferSize is set to 0 (no operand, no opcode) */
550 hcec->RxXferSize = 0;
551 __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXEND);
552
553 hcec->State = HAL_CEC_STATE_READY;
554 __HAL_UNLOCK(hcec);
555 return HAL_OK;
556 }
557 else
558 {
559 return HAL_BUSY;
560 }
561}
562
563/**
564 * @brief Send data in interrupt mode
565 * @param hcec: CEC handle
566 * @param DestinationAddress: destination logical address
567 * @param pData: pointer to input byte data buffer
568 * @param Size: amount of data to be sent in bytes (without counting the header).
569 * 0 means only the header is sent (ping operation).
570 * Maximum TX size is 15 bytes (1 opcode and up to 14 operands).
571 * @retval HAL status
572 */
573HAL_StatusTypeDef HAL_CEC_Transmit_IT(CEC_HandleTypeDef *hcec, uint8_t DestinationAddress, uint8_t *pData, uint32_t Size)
574{
575 uint8_t temp = 0;
576 /* if the IP isn't already busy and if there is no previous transmission
577 already pending due to arbitration lost */
578 if (((hcec->State == HAL_CEC_STATE_READY) || (hcec->State == HAL_CEC_STATE_STANDBY_RX))
579 && (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) == RESET))
580 {
581 if((pData == NULL) && (Size > 0))
582 {
583 hcec->State = HAL_CEC_STATE_ERROR;
584 return HAL_ERROR;
585 }
586
587 assert_param(IS_CEC_ADDRESS(DestinationAddress));
588 assert_param(IS_CEC_MSGSIZE(Size));
589
590 /* Process Locked */
591 __HAL_LOCK(hcec);
592 hcec->pTxBuffPtr = pData;
593 hcec->State = HAL_CEC_STATE_BUSY_TX;
594 hcec->ErrorCode = HAL_CEC_ERROR_NONE;
595
596 /* Disable Peripheral to write CEC_IER register */
597 __HAL_CEC_DISABLE(hcec);
598
599 /* Enable the following two CEC Transmission interrupts as
600 * well as the following CEC Transmission Errors interrupts:
601 * Tx Byte Request IT
602 * End of Transmission IT
603 * Tx Missing Acknowledge IT
604 * Tx-Error IT
605 * Tx-Buffer Underrun IT
606 * Tx arbitration lost */
607 __HAL_CEC_ENABLE_IT(hcec, CEC_IT_TXBR|CEC_IT_TXEND|CEC_IER_TX_ALL_ERR);
608
609 /* Enable the Peripheral */
610 __HAL_CEC_ENABLE(hcec);
611
612 /* initialize the number of bytes to send,
613 * 0 means only one header is sent (ping operation) */
614 hcec->TxXferCount = Size;
615
616 /* Process Unlocked */
617 __HAL_UNLOCK(hcec);
618
619 /* in case of no payload (Size = 0), sender is only pinging the system;
620 * Set TX End of Message (TXEOM) bit, must be set before writing data to TXDR */
621 if (Size == 0)
622 {
623 __HAL_CEC_LAST_BYTE_TX_SET(hcec);
624 }
625
626 /* send header block */
627 temp = (uint8_t)((uint32_t)(hcec->Init.InitiatorAddress) << CEC_INITIATOR_LSB_POS) | DestinationAddress;
628 hcec->Instance->TXDR = temp;
629 /* Set TX Start of Message (TXSOM) bit */
630 __HAL_CEC_FIRST_BYTE_TX_SET(hcec);
631
632 return HAL_OK;
633 }
634 /* if the IP is already busy or if there is a previous transmission
635 already pending due to arbitration loss */
636 else if ((hcec->State == HAL_CEC_STATE_BUSY_TX) || (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) != RESET))
637 {
638 __HAL_LOCK(hcec);
639 /* set state to BUSY TX, in case it wasn't set already (case
640 * of transmission new attempt after arbitration loss) */
641 if (hcec->State != HAL_CEC_STATE_BUSY_TX)
642 {
643 hcec->State = HAL_CEC_STATE_BUSY_TX;
644 }
645
646 /* if all data have been sent */
647 if(hcec->TxXferCount == 0)
648 {
649 /* Disable Peripheral to write CEC_IER register */
650 __HAL_CEC_DISABLE(hcec);
651
652 /* Disable the CEC Transmission Interrupts */
653 __HAL_CEC_DISABLE_IT(hcec, CEC_IT_TXBR|CEC_IT_TXEND);
654 /* Disable the CEC Transmission Error Interrupts */
655 __HAL_CEC_DISABLE_IT(hcec, CEC_IER_TX_ALL_ERR);
656
657 /* Enable the Peripheral */
658 __HAL_CEC_ENABLE(hcec);
659
660 __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXBR|CEC_FLAG_TXEND);
661
662 hcec->State = HAL_CEC_STATE_READY;
663 /* Call the Process Unlocked before calling the Tx call back API to give the possibility to
664 start again the Transmission under the Tx call back API */
665 __HAL_UNLOCK(hcec);
666
667 HAL_CEC_TxCpltCallback(hcec);
668
669 return HAL_OK;
670 }
671 else
672 {
673 if (hcec->TxXferCount == 1)
674 {
675 /* if this is the last byte transmission, set TX End of Message (TXEOM) bit */
676 __HAL_CEC_LAST_BYTE_TX_SET(hcec);
677 }
678 /* clear Tx-Byte request flag */
679 __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXBR);
680 hcec->Instance->TXDR = *hcec->pTxBuffPtr++;
681 hcec->TxXferCount--;
682
683 /* Process Unlocked */
684 __HAL_UNLOCK(hcec);
685
686 return HAL_OK;
687 }
688 }
689 else
690 {
691 return HAL_BUSY;
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 */
705HAL_StatusTypeDef HAL_CEC_Receive_IT(CEC_HandleTypeDef *hcec, uint8_t *pData)
706{
707 if(hcec->State == HAL_CEC_STATE_READY)
708 {
709 if(pData == 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_IT_RXBR|CEC_IT_RXEND);
741
742 __HAL_CEC_ENABLE(hcec);
743
744 return HAL_OK;
745 }
746 else
747 {
748 return HAL_BUSY;
749 }
750}
751
752/**
753 * @brief Get size of the received frame.
754 * @param hcec: CEC handle
755 * @retval Frame size
756 */
757uint32_t HAL_CEC_GetReceivedFrameSize(CEC_HandleTypeDef *hcec)
758{
759 return hcec->RxXferSize;
760}
761
762/**
763 * @brief This function handles CEC interrupt requests.
764 * @param hcec: CEC handle
765 * @retval None
766 */
767void HAL_CEC_IRQHandler(CEC_HandleTypeDef *hcec)
768{
769 /* save interrupts register for further error or interrupts handling purposes */
770 hcec->ErrorCode = hcec->Instance->ISR;
771 /* CEC TX missing acknowledge error interrupt occurred -------------------------------------*/
772 if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TXACKE) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_TXACKE) != RESET))
773 {
774 __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXACKE);
775 hcec->State = HAL_CEC_STATE_ERROR;
776 }
777
778 /* CEC transmit error interrupt occured --------------------------------------*/
779 if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TXERR) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_TXERR) != RESET))
780 {
781 __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXERR);
782 hcec->State = HAL_CEC_STATE_ERROR;
783 }
784
785 /* CEC TX underrun error interrupt occured --------------------------------------*/
786 if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TXUDR) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_TXUDR) != RESET))
787 {
788 __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXUDR);
789 hcec->State = HAL_CEC_STATE_ERROR;
790 }
791
792 /* CEC TX arbitration error interrupt occured --------------------------------------*/
793 if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_ARBLST) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_ARBLST) != RESET))
794 {
795 __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_ARBLST);
796 hcec->State = HAL_CEC_STATE_ERROR;
797 }
798
799 /* CEC RX overrun error interrupt occured --------------------------------------*/
800 if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_RXOVR) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_RXOVR) != RESET))
801 {
802 __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXOVR);
803 hcec->State = HAL_CEC_STATE_ERROR;
804 }
805
806 /* CEC RX bit rising error interrupt occured -------------------------------*/
807 if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_BRE) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_BRE) != RESET))
808 {
809 __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_BRE);
810 hcec->State = HAL_CEC_STATE_ERROR;
811 }
812
813 /* CEC RX short bit period error interrupt occured -------------------------*/
814 if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_SBPE) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_SBPE) != RESET))
815 {
816 __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_SBPE);
817 hcec->State = HAL_CEC_STATE_ERROR;
818 }
819
820 /* CEC RX long bit period error interrupt occured --------------------------*/
821 if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_LBPE) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_LBPE) != RESET))
822 {
823 __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_LBPE);
824 hcec->State = HAL_CEC_STATE_ERROR;
825 }
826
827 /* CEC RX missing acknowledge error interrupt occured ----------------------*/
828 if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_RXACKE) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_RXACKE) != RESET))
829 {
830 __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXACKE);
831 hcec->State = HAL_CEC_STATE_ERROR;
832 }
833
834 if ((hcec->ErrorCode & CEC_ISR_ALL_ERROR) != 0)
835 {
836 HAL_CEC_ErrorCallback(hcec);
837 }
838
839 /* CEC RX byte received interrupt -----------------------------------------*/
840 if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_RXBR) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_RXBR) != RESET))
841 {
842 /* RXBR IT is cleared during HAL_CEC_Transmit_IT processing */
843 CEC_Receive_IT(hcec);
844 }
845
846 /* CEC RX end received interrupt ------------------------------------------*/
847 if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_RXEND) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_RXEND) != RESET))
848 {
849 /* RXBR IT is cleared during HAL_CEC_Transmit_IT processing */
850 CEC_Receive_IT(hcec);
851 }
852
853 /* CEC TX byte request interrupt -------------------------------------------*/
854 if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TXBR) != RESET) &&(__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_TXBR) != 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_FLAG(hcec, CEC_FLAG_TXEND) != RESET) &&(__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_TXEND) != RESET))
862 {
863 /* TXEND IT is cleared during HAL_CEC_Transmit_IT processing */
864 CEC_Transmit_IT(hcec);
865 }
866}
867
868/**
869 * @brief Tx Transfer completed callback
870 * @param hcec: CEC handle
871 * @retval None
872 */
873 __weak void HAL_CEC_TxCpltCallback(CEC_HandleTypeDef *hcec)
874{
875 /* NOTE : This function should not be modified, when the callback is needed,
876 the HAL_CEC_TxCpltCallback can be implemented in the user file
877 */
878}
879
880/**
881 * @brief Rx Transfer completed callback
882 * @param hcec: CEC handle
883 * @retval None
884 */
885__weak void HAL_CEC_RxCpltCallback(CEC_HandleTypeDef *hcec)
886{
887 /* NOTE : This function should not be modified, when the callback is needed,
888 the HAL_CEC_TxCpltCallback can be implemented in the user file
889 */
890}
891
892/**
893 * @brief CEC error callbacks
894 * @param hcec: CEC handle
895 * @retval None
896 */
897 __weak void HAL_CEC_ErrorCallback(CEC_HandleTypeDef *hcec)
898{
899 /* NOTE : This function should not be modified, when the callback is needed,
900 the HAL_CEC_ErrorCallback can be implemented in the user file
901 */
902}
903/**
904 * @}
905 */
906
907/** @defgroup CEC_Exported_Functions_Group3 Peripheral Control function
908 * @brief CEC control functions
909 *
910@verbatim
911 ===============================================================================
912 ##### Peripheral Control function #####
913 ===============================================================================
914 [..]
915 This subsection provides a set of functions allowing to control the CEC.
916 (+) HAL_CEC_GetState() API can be helpful to check in run-time the state of the CEC peripheral.
917@endverbatim
918 * @{
919 */
920/**
921 * @brief return the CEC state
922 * @param hcec: CEC handle
923 * @retval HAL state
924 */
925HAL_CEC_StateTypeDef HAL_CEC_GetState(CEC_HandleTypeDef *hcec)
926{
927 return hcec->State;
928}
929
930/**
931* @brief Return the CEC error code
932* @param hcec : pointer to a CEC_HandleTypeDef structure that contains
933 * the configuration information for the specified CEC.
934* @retval CEC Error Code
935*/
936uint32_t HAL_CEC_GetError(CEC_HandleTypeDef *hcec)
937{
938 return hcec->ErrorCode;
939}
940
941/**
942 * @}
943 */
944
945/**
946 * @brief Send data in interrupt mode
947 * @param hcec: CEC handle.
948 * Function called under interruption only, once
949 * interruptions have been enabled by HAL_CEC_Transmit_IT()
950 * @retval HAL status
951 */
952static HAL_StatusTypeDef CEC_Transmit_IT(CEC_HandleTypeDef *hcec)
953{
954 /* if the IP is already busy or if there is a previous transmission
955 already pending due to arbitration loss */
956 if ((hcec->State == HAL_CEC_STATE_BUSY_TX)
957 || (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) != RESET))
958 {
959 __HAL_LOCK(hcec);
960 /* set state to BUSY TX, in case it wasn't set already (case
961 * of transmission new attempt after arbitration loss) */
962 if (hcec->State != HAL_CEC_STATE_BUSY_TX)
963 {
964 hcec->State = HAL_CEC_STATE_BUSY_TX;
965 }
966
967 /* if all data have been sent */
968 if(hcec->TxXferCount == 0)
969 {
970 /* Disable Peripheral to write CEC_IER register */
971 __HAL_CEC_DISABLE(hcec);
972
973 /* Disable the CEC Transmission Interrupts */
974 __HAL_CEC_DISABLE_IT(hcec, CEC_IT_TXBR|CEC_IT_TXEND);
975 /* Disable the CEC Transmission Error Interrupts */
976 __HAL_CEC_DISABLE_IT(hcec, CEC_IER_TX_ALL_ERR);
977
978 /* Enable the Peripheral */
979 __HAL_CEC_ENABLE(hcec);
980
981 __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_TXBR|CEC_FLAG_TXEND);
982
983 hcec->State = HAL_CEC_STATE_READY;
984 /* Call the Process Unlocked before calling the Tx call back API to give the possibility to
985 start again the Transmission under the Tx call back API */
986 __HAL_UNLOCK(hcec);
987
988 HAL_CEC_TxCpltCallback(hcec);
989
990 return HAL_OK;
991 }
992 else
993 {
994 if (hcec->TxXferCount == 1)
995 {
996 /* if this is the last byte transmission, set TX End of Message (TXEOM) bit */
997 __HAL_CEC_LAST_BYTE_TX_SET(hcec);
998 }
999 /* clear Tx-Byte request flag */
1000 __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_TXBR);
1001 hcec->Instance->TXDR = *hcec->pTxBuffPtr++;
1002 hcec->TxXferCount--;
1003
1004 /* Process Unlocked */
1005 __HAL_UNLOCK(hcec);
1006
1007 return HAL_OK;
1008 }
1009 }
1010 else
1011 {
1012 return HAL_BUSY;
1013 }
1014}
1015
1016
1017/**
1018 * @brief Receive data in interrupt mode.
1019 * @param hcec: CEC handle.
1020 * Function called under interruption only, once
1021 * interruptions have been enabled by HAL_CEC_Receive_IT()
1022 * @retval HAL status
1023 */
1024static HAL_StatusTypeDef CEC_Receive_IT(CEC_HandleTypeDef *hcec)
1025{
1026 uint32_t tempisr;
1027
1028 /* Three different conditions are tested to carry out the RX IT processing:
1029 * - the IP is in reception stand-by (the IP state is HAL_CEC_STATE_STANDBY_RX) and
1030 * the reception of the first byte is starting
1031 * - a message reception is already on-going (the IP state is HAL_CEC_STATE_BUSY_RX)
1032 * and a new byte is being received
1033 * - a transmission has just been started (the IP state is HAL_CEC_STATE_BUSY_TX)
1034 * but has been interrupted by a new message reception or discarded due to
1035 * arbitration loss: the reception of the first or higher priority message
1036 * (the arbitration winner) is starting */
1037 if ((hcec->State == HAL_CEC_STATE_STANDBY_RX)
1038 || (hcec->State == HAL_CEC_STATE_BUSY_RX)
1039 || (hcec->State == HAL_CEC_STATE_BUSY_TX))
1040 {
1041 /* reception is starting */
1042 hcec->State = HAL_CEC_STATE_BUSY_RX;
1043 tempisr = (uint32_t) (hcec->Instance->ISR);
1044 if ((tempisr & CEC_FLAG_RXBR) != 0)
1045 {
1046 /* Process Locked */
1047 __HAL_LOCK(hcec);
1048 /* read received byte */
1049 *hcec->pRxBuffPtr++ = hcec->Instance->RXDR;
1050 /* if last byte has been received */
1051 if ((tempisr & CEC_FLAG_RXEND) != 0)
1052 {
1053 /* clear IT */
1054 __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_RXBR|CEC_FLAG_RXEND);
1055 /* RX interrupts are not disabled at this point.
1056 * Indeed, to disable the IT, the IP must be disabled first
1057 * which resets the TXSOM flag. In case of arbitration loss,
1058 * this leads to a transmission abort.
1059 * Therefore, RX interruptions disabling if so required,
1060 * is done in HAL_CEC_RxCpltCallback */
1061
1062 /* IP state is moved to READY.
1063 * If the IP must remain in standby mode to listen
1064 * any new message, it is up to HAL_CEC_RxCpltCallback
1065 * to move it again to HAL_CEC_STATE_STANDBY_RX */
1066 hcec->State = HAL_CEC_STATE_READY;
1067
1068 /* Call the Process Unlocked before calling the Rx call back API */
1069 __HAL_UNLOCK(hcec);
1070 HAL_CEC_RxCpltCallback(hcec);
1071
1072 return HAL_OK;
1073 }
1074 __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXBR);
1075
1076 hcec->RxXferSize++;
1077 /* Process Unlocked */
1078 __HAL_UNLOCK(hcec);
1079
1080 return HAL_OK;
1081 }
1082 else
1083 {
1084 return HAL_BUSY;
1085 }
1086 }
1087 else
1088 {
1089 return HAL_BUSY;
1090 }
1091}
1092/**
1093 * @}
1094 */
1095
1096#endif /* STM32F446xx */
1097
1098#endif /* HAL_CEC_MODULE_ENABLED */
1099/**
1100 * @}
1101 */
1102
1103/**
1104 * @}
1105 */
1106
1107/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Note: See TracBrowser for help on using the repository browser.