1 /*!
2 \file gd32f3x0_cec.c
3 \brief CEC driver
4
5 \version 2017-06-06, V1.0.0, firmware for GD32F3x0
6 \version 2019-06-01, V2.0.0, firmware for GD32F3x0
7 \version 2020-09-30, V2.1.0, firmware for GD32F3x0
8 */
9
10 /*
11 Copyright (c) 2020, GigaDevice Semiconductor Inc.
12
13 Redistribution and use in source and binary forms, with or without modification,
14 are permitted provided that the following conditions are met:
15
16 1. Redistributions of source code must retain the above copyright notice, this
17 list of conditions and the following disclaimer.
18 2. Redistributions in binary form must reproduce the above copyright notice,
19 this list of conditions and the following disclaimer in the documentation
20 and/or other materials provided with the distribution.
21 3. Neither the name of the copyright holder nor the names of its contributors
22 may be used to endorse or promote products derived from this software without
23 specific prior written permission.
24
25 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
34 OF SUCH DAMAGE.
35 */
36
37 #ifdef GD32F350
38
39 #include "gd32f3x0_cec.h"
40
41 /*!
42 \brief reset HDMI-CEC controller
43 \param[in] none
44 \param[out] none
45 \retval none
46 */
cec_deinit(void)47 void cec_deinit(void)
48 {
49 rcu_periph_reset_enable(RCU_CECRST);
50 rcu_periph_reset_disable(RCU_CECRST);
51 }
52
53 /*!
54 \brief configure signal free time,the signal free time counter start option,own address
55 \param[in] sftmopt: signal free time counter start option
56 only one parameter can be selected which is shown as below:
57 \arg CEC_SFT_START_STAOM: signal free time counter starts counting when STAOM is asserted
58 \arg CEC_SFT_START_LAST: signal free time counter starts automatically after transmission/reception end
59 \param[in] sft: signal free time
60 only one parameter can be selected which is shown as below:
61 \arg CEC_SFT_PROTOCOL_PERIOD: the signal free time will perform as HDMI-CEC protocol description
62 \arg CEC_SFT_1POINT5_PERIOD: 1.5 nominal data bit periods
63 \arg CEC_SFT_2POINT5_PERIOD: 2.5 nominal data bit periods
64 \arg CEC_SFT_3POINT5_PERIOD: 3.5 nominal data bit periods
65 \arg CEC_SFT_4POINT5_PERIOD: 4.5 nominal data bit periods
66 \arg CEC_SFT_5POINT5_PERIOD: 5.5 nominal data bit periods
67 \arg CEC_SFT_6POINT5_PERIOD: 6.5 nominal data bit periods
68 \arg CEC_SFT_7POINT5_PERIOD: 7.5 nominal data bit periods
69 \param[in] address: own address
70 only one parameter can be selected which is shown as below:
71 \arg CEC_OWN_ADDRESS_CLEAR: own address is cleared
72 \arg CEC_OWN_ADDRESSx(x=0..14): own address is x
73 \param[out] none
74 \retval none
75 */
cec_init(uint32_t sftmopt,uint32_t sft,uint32_t address)76 void cec_init(uint32_t sftmopt, uint32_t sft, uint32_t address)
77 {
78 uint32_t cfg;
79 cfg = CEC_CFG;
80 /* clear SFTMOPT bit,SFT[2:0] */
81 cfg &= ~(CEC_CFG_SFTOPT | CEC_CFG_SFT);
82 /* assign SFTMOPT bit,SFT[2:0] */
83 cfg |= (sftmopt | sft);
84 CEC_CFG = cfg;
85 if(CEC_OWN_ADDRESS_CLEAR == address){
86 CEC_CFG &= ~CEC_CFG_OAD;
87 }else{
88 CEC_CFG |= address;
89 }
90 }
91
92 /*!
93 \brief configure generate Error-bit when detected some abnormal situation or not,
94 whether stop receive message when detected bit rising error
95 \param[in] broadcast:
96 only one parameter can be selected which is shown as below:
97 \arg CEC_BROADCAST_ERROR_BIT_ON:generate Error-bit in broadcast
98 \arg CEC_BROADCAST_ERROR_BIT_OFF:do not generate Error-bit in broadcast
99 \param[in] singlecast_lbpe:
100 only one parameter can be selected which is shown as below:
101 \arg CEC_LONG_PERIOD_ERROR_BIT_ON:generate Error-bit on long bit period error
102 \arg CEC_LONG_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on long bit period error
103 \param[in] singlecast_bre:
104 only one parameter can be selected which is shown as below:
105 \arg CEC_RISING_PERIOD_ERROR_BIT_ON:generate Error-bit on bit rising error
106 \arg CEC_RISING_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on bit rising error
107 \param[in] rxbrestp:
108 only one parameter can be selected which is shown as below:
109 \arg CEC_STOP_RISING_ERROR_BIT_ON: stop reception when detected bit rising error
110 \arg CEC_STOP_RISING_ERROR_BIT_OFF: do not stop reception when detected bit rising error
111 \param[out] none
112 \retval none
113 */
cec_error_config(uint32_t broadcast,uint32_t singlecast_lbpe,uint32_t singlecast_bre,uint32_t rxbrestp)114 void cec_error_config(uint32_t broadcast, uint32_t singlecast_lbpe, uint32_t singlecast_bre, uint32_t rxbrestp)
115 {
116 uint32_t cfg;
117 cfg = CEC_CFG;
118 /* clear BCNG bit, BPLEG bit, BREG bit */
119 cfg &= ~(CEC_CFG_BCNG | CEC_CFG_BPLEG | CEC_CFG_BREG);
120 /* assign BCNG bit, BPLEG bit, BREG bit */
121 cfg |= (broadcast | singlecast_lbpe | singlecast_bre);
122 CEC_CFG = cfg;
123 if(CEC_STOP_RISING_ERROR_BIT_ON == rxbrestp){
124 CEC_CFG |= CEC_CFG_BRES;
125 }else{
126 CEC_CFG &= ~CEC_CFG_BRES;
127 }
128 }
129
130 /*!
131 \brief enable HDMI-CEC controller
132 \param[in] none
133 \param[out] none
134 \retval none
135 */
cec_enable(void)136 void cec_enable(void)
137 {
138 CEC_CTL |= CEC_CTL_CECEN;
139 }
140
141 /*!
142 \brief disable HDMI-CEC controller
143 \param[in] none
144 \param[out] none
145 \retval none
146 */
cec_disable(void)147 void cec_disable(void)
148 {
149 CEC_CTL &= ~CEC_CTL_CECEN;
150 }
151
152 /*!
153 \brief start CEC message transmission
154 \param[in] none
155 \param[out] none
156 \retval none
157 */
cec_transmission_start(void)158 void cec_transmission_start(void)
159 {
160 CEC_CTL |= CEC_CTL_STAOM;
161 }
162
163 /*!
164 \brief end CEC message transmission
165 \param[in] none
166 \param[out] none
167 \retval none
168 */
cec_transmission_end(void)169 void cec_transmission_end(void)
170 {
171 CEC_CTL |= CEC_CTL_ENDOM;
172 }
173
174 /*!
175 \brief enable CEC listen mode.
176 \param[in] none
177 \param[out] none
178 \retval none
179 */
cec_listen_mode_enable(void)180 void cec_listen_mode_enable(void)
181 {
182 CEC_CFG |= CEC_CFG_LMEN;
183 }
184
185 /*!
186 \brief disable CEC listen mode.
187 \param[in] none
188 \param[out] none
189 \retval none
190 */
cec_listen_mode_disable(void)191 void cec_listen_mode_disable(void)
192 {
193 CEC_CFG &= ~CEC_CFG_LMEN;
194 }
195
196 /*!
197 \brief configure and clear own address.the controller can be configured to multiple own address
198 \param[in] address: own address
199 one or more parameters can be selected which are shown as below:
200 \arg CEC_OWN_ADDRESS_CLEAR: own address is cleared
201 \arg CEC_OWN_ADDRESSx(x=0..14): own address is x
202 \param[out] none
203 \retval none
204 */
cec_own_address_config(uint32_t address)205 void cec_own_address_config(uint32_t address)
206 {
207 if(CEC_OWN_ADDRESS_CLEAR == address){
208 CEC_CFG &= ~CEC_CFG_OAD;
209 } else {
210 CEC_CFG |= address;
211 }
212 }
213
214 /*!
215 \brief configure signal free time and the signal free time counter start option
216 \param[in] sftmopt: signal free time counter start option
217 only one parameter can be selected which is shown as below:
218 \arg CEC_SFT_START_STAOM: signal free time counter starts counting when STAOM is asserted
219 \arg CEC_SFT_START_LAST: signal free time counter starts automatically after transmission/reception end
220 \param[in] sft: signal free time
221 only one parameter can be selected which is shown as below:
222 \arg CEC_SFT_PROTOCOL_PERIOD: the signal free time will perform as HDMI-CEC protocol description
223 \arg CEC_SFT_1POINT5_PERIOD: 1.5 nominal data bit periods
224 \arg CEC_SFT_2POINT5_PERIOD: 2.5 nominal data bit periods
225 \arg CEC_SFT_3POINT5_PERIOD: 3.5 nominal data bit periods
226 \arg CEC_SFT_4POINT5_PERIOD: 4.5 nominal data bit periods
227 \arg CEC_SFT_5POINT5_PERIOD: 5.5 nominal data bit periods
228 \arg CEC_SFT_6POINT5_PERIOD: 6.5 nominal data bit periods
229 \arg CEC_SFT_7POINT5_PERIOD: 7.5 nominal data bit periods
230 \param[out] none
231 \retval none
232 */
cec_sft_config(uint32_t sftmopt,uint32_t sft)233 void cec_sft_config(uint32_t sftmopt, uint32_t sft)
234 {
235 uint32_t cfg;
236 cfg = CEC_CFG;
237 /* clear SFTMOPT bit,SFT[2:0] */
238 cfg &= ~(CEC_CFG_SFTOPT | CEC_CFG_SFT);
239 /* assign SFTMOPT bit,SFT[2:0] */
240 cfg |= (sftmopt | sft);
241 CEC_CFG = cfg;
242 }
243
244 /*!
245 \brief configure generate Error-bit when detected some abnormal situation or not
246 \param[in] broadcast:
247 only one parameter can be selected which is shown as below:
248 \arg CEC_BROADCAST_ERROR_BIT_ON:generate Error-bit in broadcast
249 \arg CEC_BROADCAST_ERROR_BIT_OFF:do not generate Error-bit in broadcast
250 \param[in] singlecast_lbpe:
251 only one parameter can be selected which is shown as below:
252 \arg CEC_LONG_PERIOD_ERROR_BIT_ON:generate Error-bit on long bit period error
253 \arg CEC_LONG_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on long bit period error
254 \param[in] singlecast_bre:
255 only one parameter can be selected which is shown as below:
256 \arg CEC_RISING_PERIOD_ERROR_BIT_ON:generate Error-bit on bit rising error
257 \arg CEC_RISING_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on bit rising error
258 \param[out] none
259 \retval none
260 */
cec_generate_errorbit_config(uint32_t broadcast,uint32_t singlecast_lbpe,uint32_t singlecast_bre)261 void cec_generate_errorbit_config(uint32_t broadcast, uint32_t singlecast_lbpe, uint32_t singlecast_bre)
262 {
263 uint32_t cfg;
264 cfg = CEC_CFG;
265 /* clear BCNG bit, RLBPEGEN bit, RBREGEN bit */
266 cfg &= ~(CEC_CFG_BCNG | CEC_CFG_BPLEG | CEC_CFG_BREG);
267 /* assign BCNG bit, RLBPEGEN bit, RBREGEN bit */
268 cfg |= (broadcast | singlecast_lbpe | singlecast_bre);
269 CEC_CFG = cfg;
270 }
271
272 /*!
273 \brief whether stop receive message when detected bit rising error
274 \param[in] rxbrestp:
275 only one parameter can be selected which is shown as below:
276 \arg CEC_STOP_RISING_ERROR_BIT_ON: stop reception when detected bit rising error
277 \arg CEC_STOP_RISING_ERROR_BIT_OFF: do not stop reception when detected bit rising error
278 \param[out] none
279 \retval none
280 */
cec_stop_receive_bre_config(uint32_t rxbrestp)281 void cec_stop_receive_bre_config(uint32_t rxbrestp)
282 {
283 if(CEC_STOP_RISING_ERROR_BIT_ON == rxbrestp){
284 CEC_CFG |= CEC_CFG_BRES;
285 } else {
286 CEC_CFG &= ~CEC_CFG_BRES;
287 }
288 }
289
290 /*!
291 \brief enable reception bit timing tolerance
292 \param[in] none
293 \param[out] none
294 \retval none
295 */
cec_reception_tolerance_enable(void)296 void cec_reception_tolerance_enable(void)
297 {
298 CEC_CFG |= CEC_CFG_RTOL;
299 }
300
301 /*!
302 \brief disable reception bit timing tolerance
303 \param[in] none
304 \param[out] none
305 \retval none
306 */
cec_reception_tolerance_disable(void)307 void cec_reception_tolerance_disable(void)
308 {
309 CEC_CFG &= ~CEC_CFG_RTOL;
310 }
311
312 /*!
313 \brief send a data by the CEC peripheral
314 \param[in] data: the data to transmit
315 \param[out] none
316 \retval none
317 */
cec_data_send(uint8_t data)318 void cec_data_send(uint8_t data)
319 {
320 CEC_TDATA = (uint32_t)data;
321 }
322
323 /*!
324 \brief receive a data by the CEC peripheral
325 \param[in] data: the data to receive
326 \param[out] none
327 \retval none
328 */
cec_data_receive(void)329 uint8_t cec_data_receive(void)
330 {
331 return (uint8_t)CEC_RDATA;
332 }
333
334
335 /*!
336 \brief enable interrupt
337 \param[in] flag: specify which flag
338 one or more parameters can be selected which are shown as below:
339 \arg CEC_INT_BR: enable Rx-byte data received interrupt
340 \arg CEC_INT_REND: enable end of reception interrupt
341 \arg CEC_INT_RO: enable RX overrun interrupt
342 \arg CEC_INT_BRE: enable bit rising error interrupt
343 \arg CEC_INT_BPSE: enable short bit period error interrupt
344 \arg CEC_INT_BPLE: enable long bit period error interrupt
345 \arg CEC_INT_RAE: enable Rx ACK error interrupt
346 \arg CEC_INT_ARBF: enable arbitration lost interrupt
347 \arg CEC_INT_TBR: enable Tx-byte data request interrupt
348 \arg CEC_INT_TEND: enable transmission successfully end interrupt
349 \arg CEC_INT_TU: enable Tx data buffer underrun interrupt
350 \arg CEC_INT_TERR: enable Tx-error interrupt
351 \arg CEC_INT_TAERR: enable Tx ACK error interrupt
352 \param[out] none
353 \retval none
354 */
cec_interrupt_enable(uint32_t flag)355 void cec_interrupt_enable(uint32_t flag)
356 {
357 CEC_INTEN |= flag;
358 }
359
360 /*!
361 \brief disable interrupt
362 \param[in] flag: specify which flag
363 one or more parameters can be selected which are shown as below:
364 \arg CEC_INT_BR: disable Rx-byte data received interrupt
365 \arg CEC_INT_REND: disable end of reception interrupt
366 \arg CEC_INT_RO: disable RX overrun interrupt
367 \arg CEC_INT_BRE: disable bit rising error interrupt
368 \arg CEC_INT_BPSE: disable short bit period error interrupt
369 \arg CEC_INT_BPLE: disable long bit period error interrupt
370 \arg CEC_INT_RAE: disable Rx ACK error interrupt
371 \arg CEC_INT_ARBF: disable arbitration lost interrupt
372 \arg CEC_INT_TBR: disable Tx-byte data request interrupt
373 \arg CEC_INT_TEND: disable transmission successfully end interrupt
374 \arg CEC_INT_TU: disable Tx data buffer underrun interrupt
375 \arg CEC_INT_TERR: disable Tx-error interrupt
376 \arg CEC_INT_TAERR: disable Tx ACK error interrupt
377
378 \param[out] none
379 \retval none
380 */
cec_interrupt_disable(uint32_t flag)381 void cec_interrupt_disable(uint32_t flag)
382 {
383 CEC_INTEN &= ~flag;
384 }
385
386
387 /*!
388 \brief get CEC status
389 \param[in] flag: specify which flag
390 one or more parameters can be selected which are shown as below:
391 \arg CEC_FLAG_BR: Rx-byte data received
392 \arg CEC_FLAG_REND: end of reception
393 \arg CEC_FLAG_RO: RX overrun
394 \arg CEC_FLAG_BRE: bit rising error
395 \arg CEC_FLAG_BPSE: short bit period error
396 \arg CEC_FLAG_BPLE: long bit period error
397 \arg CEC_FLAG_RAE: Rx ACK error
398 \arg CEC_FLAG_ARBF: arbitration lost
399 \arg CEC_FLAG_TBR: Tx-byte data request
400 \arg CEC_FLAG_TEND: transmission successfully end
401 \arg CEC_FLAG_TU: Tx data buffer underrun
402 \arg CEC_FLAG_TERR: Tx-error
403 \arg CEC_FLAG_TAERR Tx ACK error flag
404 \param[out] none
405 \retval FlagStatus: SET or RESET
406 */
cec_flag_get(uint32_t flag)407 FlagStatus cec_flag_get(uint32_t flag)
408 {
409 if(CEC_INTF & flag){
410 return SET;
411 }else{
412 return RESET;
413 }
414 }
415
416 /*!
417 \brief clear CEC status
418 \param[in] flag: specify which flag
419 one or more parameters can be selected which are shown as below:
420 \arg CEC_FLAG_BR: Rx-byte data received
421 \arg CEC_FLAG_REND: end of reception
422 \arg CEC_FLAG_RO: RX overrun
423 \arg CEC_FLAG_BRE: bit rising error
424 \arg CEC_FLAG_BPSE: short bit period error
425 \arg CEC_FLAG_BPLE: long bit period error
426 \arg CEC_FLAG_RAE: Rx ACK error
427 \arg CEC_FLAG_ARBF: arbitration lost
428 \arg CEC_FLAG_TBR: Tx-byte data request
429 \arg CEC_FLAG_TEND: transmission successfully end
430 \arg CEC_FLAG_TU: Tx data buffer underrun
431 \arg CEC_FLAG_TERR: Tx-error
432 \arg CEC_FLAG_TAERR: Tx ACK error flag
433
434 \param[out] none
435 \retval FlagStatus: SET or RESET
436 */
cec_flag_clear(uint32_t flag)437 void cec_flag_clear(uint32_t flag)
438 {
439 CEC_INTF |= flag;
440 }
441
442 /*!
443 \brief get CEC int flag and status
444 \param[in] flag: specify which flag
445 one or more parameters can be selected which are shown as below:
446 \arg CEC_INT_FLAG_BR: Rx-byte data received
447 \arg CEC_INT_FLAG_REND: end of reception
448 \arg CEC_INT_FLAG_RO: RX overrun
449 \arg CEC_INT_FLAG_BRE: bit rising error
450 \arg CEC_INT_FLAG_BPSE: short bit period error
451 \arg CEC_INT_FLAG_BPLE: long bit period error
452 \arg CEC_INT_FLAG_RAE: Rx ACK error
453 \arg CEC_INT_FLAG_ARBF: arbitration lost
454 \arg CEC_INT_FLAG_TBR: Tx-byte data request
455 \arg CEC_INT_FLAG_TEND: transmission successfully end
456 \arg CEC_INT_FLAG_TU: Tx data buffer underrun
457 \arg CEC_INT_FLAG_TERR: Tx-error
458 \arg CEC_INT_FLAG_TAERR: Tx ACK error flag
459 \param[out] none
460 \retval FlagStatus: SET or RESET
461 */
cec_interrupt_flag_get(uint32_t flag)462 FlagStatus cec_interrupt_flag_get(uint32_t flag)
463 {
464 uint32_t interrupt_enable = 0U,interrupt_flag = 0U;
465 interrupt_flag = (CEC_INTF & flag);
466 interrupt_enable = (CEC_INTEN & flag);
467 if(interrupt_flag && interrupt_enable){
468 return SET;
469 }else{
470 return RESET;
471 }
472 }
473
474 /*!
475 \brief clear CEC int flag and status
476 \param[in] flag: specify which flag
477 one or more parameters can be selected which are shown as below:
478 \arg CEC_INT_FLAG_BR: Rx-byte data received
479 \arg CEC_INT_FLAG_REND: end of reception
480 \arg CEC_INT_FLAG_RO: RX overrun
481 \arg CEC_INT_FLAG_BRE: bit rising error
482 \arg CEC_INT_FLAG_BPSE: short bit period error
483 \arg CEC_INT_FLAG_BPLE: long bit period error
484 \arg CEC_INT_FLAG_RAE: Rx ACK error
485 \arg CEC_INT_FLAG_ARBF: arbitration lost
486 \arg CEC_INT_FLAG_TBR: Tx-byte data request
487 \arg CEC_INT_FLAG_TEND: transmission successfully end
488 \arg CEC_INT_FLAG_TU: Tx data buffer underrun
489 \arg CEC_INT_FLAG_TERR: Tx-error
490 \arg CEC_INT_FLAG_TAERR: Tx ACK error flag
491 \param[out] none
492 \retval none
493 */
cec_interrupt_flag_clear(uint32_t flag)494 void cec_interrupt_flag_clear(uint32_t flag)
495 {
496 CEC_INTF = flag;
497 }
498
499
500 #endif
501