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