1 /*!
2     \file    gd32f4xx_dci.c
3     \brief   DCI driver
4 
5     \version 2016-08-15, V1.0.0, firmware for GD32F4xx
6     \version 2018-12-12, V2.0.0, firmware for GD32F4xx
7     \version 2020-09-30, V2.1.0, firmware for GD32F4xx
8     \version 2022-03-09, V3.0.0, firmware for GD32F4xx
9 */
10 
11 /*
12     Copyright (c) 2022, GigaDevice Semiconductor Inc.
13 
14     Redistribution and use in source and binary forms, with or without modification,
15 are permitted provided that the following conditions are met:
16 
17     1. Redistributions of source code must retain the above copyright notice, this
18        list of conditions and the following disclaimer.
19     2. Redistributions in binary form must reproduce the above copyright notice,
20        this list of conditions and the following disclaimer in the documentation
21        and/or other materials provided with the distribution.
22     3. Neither the name of the copyright holder nor the names of its contributors
23        may be used to endorse or promote products derived from this software without
24        specific prior written permission.
25 
26     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
35 OF SUCH DAMAGE.
36 */
37 
38 #include "gd32f4xx_dci.h"
39 
40 /*!
41     \brief    DCI deinit
42     \param[in]  none
43     \param[out] none
44     \retval     none
45 */
dci_deinit(void)46 void dci_deinit(void)
47 {
48     rcu_periph_reset_enable(RCU_DCIRST);
49     rcu_periph_reset_disable(RCU_DCIRST);
50 }
51 
52 /*!
53     \brief    initialize DCI registers
54     \param[in]  dci_struct: DCI parameter initialization structure
55                 members of the structure and the member values are shown as below:
56                 capture_mode    : DCI_CAPTURE_MODE_CONTINUOUS, DCI_CAPTURE_MODE_SNAPSHOT
57                 colck_polarity  : DCI_CK_POLARITY_FALLING, DCI_CK_POLARITY_RISING
58                 hsync_polarity  : DCI_HSYNC_POLARITY_LOW, DCI_HSYNC_POLARITY_HIGH
59                 vsync_polarity  : DCI_VSYNC_POLARITY_LOW, DCI_VSYNC_POLARITY_HIGH
60                 frame_rate      : DCI_FRAME_RATE_ALL, DCI_FRAME_RATE_1_2, DCI_FRAME_RATE_1_4
61                 interface_format: DCI_INTERFACE_FORMAT_8BITS, DCI_INTERFACE_FORMAT_10BITS,
62                                       DCI_INTERFACE_FORMAT_12BITS, DCI_INTERFACE_FORMAT_14BITS
63     \param[out] none
64     \retval     none
65 */
dci_init(dci_parameter_struct * dci_struct)66 void dci_init(dci_parameter_struct *dci_struct)
67 {
68     uint32_t reg = 0U;
69     /* disable capture function and DCI */
70     DCI_CTL &= ~(DCI_CTL_CAP | DCI_CTL_DCIEN);
71     /* configure DCI parameter */
72     reg |= dci_struct->capture_mode;
73     reg |= dci_struct->clock_polarity;
74     reg |= dci_struct->hsync_polarity;
75     reg |= dci_struct->vsync_polarity;
76     reg |= dci_struct->frame_rate;
77     reg |= dci_struct->interface_format;
78 
79     DCI_CTL = reg;
80 }
81 
82 /*!
83     \brief    enable DCI function
84     \param[in]  none
85     \param[out] none
86     \retval     none
87 */
dci_enable(void)88 void dci_enable(void)
89 {
90     DCI_CTL |= DCI_CTL_DCIEN;
91 }
92 
93 /*!
94     \brief    disable DCI function
95     \param[in]  none
96     \param[out] none
97     \retval     none
98 */
dci_disable(void)99 void dci_disable(void)
100 {
101     DCI_CTL &= ~DCI_CTL_DCIEN;
102 }
103 
104 /*!
105     \brief    enable DCI capture
106     \param[in]  none
107     \param[out] none
108     \retval     none
109 */
dci_capture_enable(void)110 void dci_capture_enable(void)
111 {
112     DCI_CTL |= DCI_CTL_CAP;
113 }
114 
115 /*!
116     \brief    disable DCI capture
117     \param[in]  none
118     \param[out] none
119     \retval     none
120 */
dci_capture_disable(void)121 void dci_capture_disable(void)
122 {
123     DCI_CTL &= ~DCI_CTL_CAP;
124 }
125 
126 /*!
127     \brief    enable DCI jpeg mode
128     \param[in]  none
129     \param[out] none
130     \retval     none
131 */
dci_jpeg_enable(void)132 void dci_jpeg_enable(void)
133 {
134     DCI_CTL |= DCI_CTL_JM;
135 }
136 
137 /*!
138     \brief    disable DCI jpeg mode
139     \param[in]  none
140     \param[out] none
141     \retval     none
142 */
dci_jpeg_disable(void)143 void dci_jpeg_disable(void)
144 {
145     DCI_CTL &= ~DCI_CTL_JM;
146 }
147 
148 /*!
149     \brief    enable cropping window function
150     \param[in]  none
151     \param[out] none
152     \retval     none
153 */
dci_crop_window_enable(void)154 void dci_crop_window_enable(void)
155 {
156     DCI_CTL |= DCI_CTL_WDEN;
157 }
158 
159 /*!
160     \brief    disable cropping window function
161     \param[in]  none
162     \param[out] none
163     \retval     none
164 */
dci_crop_window_disable(void)165 void dci_crop_window_disable(void)
166 {
167     DCI_CTL &= ~DCI_CTL_WDEN;
168 }
169 
170 /*!
171     \brief    configure DCI cropping window
172     \param[in]  start_x: window horizontal start position
173     \param[in]  start_y: window vertical start position
174     \param[in]  size_width: window horizontal size
175     \param[in]  size_height: window vertical size
176     \param[out] none
177     \retval     none
178 */
dci_crop_window_config(uint16_t start_x,uint16_t start_y,uint16_t size_width,uint16_t size_height)179 void dci_crop_window_config(uint16_t start_x, uint16_t start_y, uint16_t size_width, uint16_t size_height)
180 {
181     DCI_CWSPOS = ((uint32_t)start_x | ((uint32_t)start_y << 16));
182     DCI_CWSZ = ((uint32_t)size_width | ((uint32_t)size_height << 16));
183 }
184 
185 /*!
186     \brief    enable embedded synchronous mode
187     \param[in]  none
188     \param[out] none
189     \retval     none
190 */
dci_embedded_sync_enable(void)191 void dci_embedded_sync_enable(void)
192 {
193     DCI_CTL |= DCI_CTL_ESM;
194 }
195 
196 /*!
197     \brief    disble embedded synchronous mode
198     \param[in]  none
199     \param[out] none
200     \retval     none
201 */
dci_embedded_sync_disable(void)202 void dci_embedded_sync_disable(void)
203 {
204     DCI_CTL &= ~DCI_CTL_ESM;
205 }
206 /*!
207     \brief    config synchronous codes in embedded synchronous mode
208     \param[in]  frame_start: frame start code in embedded synchronous mode
209     \param[in]  line_start: line start code in embedded synchronous mode
210     \param[in]  line_end: line end code in embedded synchronous mode
211     \param[in]  frame_end: frame end code in embedded synchronous mode
212     \param[out] none
213     \retval     none
214 */
dci_sync_codes_config(uint8_t frame_start,uint8_t line_start,uint8_t line_end,uint8_t frame_end)215 void dci_sync_codes_config(uint8_t frame_start, uint8_t line_start, uint8_t line_end, uint8_t frame_end)
216 {
217     DCI_SC = ((uint32_t)frame_start | ((uint32_t)line_start << 8) | ((uint32_t)line_end << 16) | ((uint32_t)frame_end << 24));
218 }
219 
220 /*!
221     \brief    config synchronous codes unmask in embedded synchronous mode
222     \param[in]  frame_start: frame start code unmask bits in embedded synchronous mode
223     \param[in]  line_start: line start code unmask bits in embedded synchronous mode
224     \param[in]  line_end: line end code unmask bits in embedded synchronous mode
225     \param[in]  frame_end: frame end code unmask bits in embedded synchronous mode
226     \param[out] none
227     \retval     none
228 */
dci_sync_codes_unmask_config(uint8_t frame_start,uint8_t line_start,uint8_t line_end,uint8_t frame_end)229 void dci_sync_codes_unmask_config(uint8_t frame_start, uint8_t line_start, uint8_t line_end, uint8_t frame_end)
230 {
231     DCI_SCUMSK = ((uint32_t)frame_start | ((uint32_t)line_start << 8) | ((uint32_t)line_end << 16) | ((uint32_t)frame_end << 24));
232 }
233 
234 /*!
235     \brief    read DCI data register
236     \param[in]  none
237     \param[out] none
238     \retval     data
239 */
dci_data_read(void)240 uint32_t dci_data_read(void)
241 {
242     return DCI_DATA;
243 }
244 
245 /*!
246     \brief    get specified flag
247     \param[in]  flag:
248       \arg         DCI_FLAG_HS: HS line status
249       \arg         DCI_FLAG_VS: VS line status
250       \arg         DCI_FLAG_FV:FIFO valid
251       \arg         DCI_FLAG_EF: end of frame flag
252       \arg         DCI_FLAG_OVR: FIFO overrun flag
253       \arg         DCI_FLAG_ESE: embedded synchronous error flag
254       \arg         DCI_FLAG_VSYNC: vsync flag
255       \arg         DCI_FLAG_EL: end of line flag
256     \param[out] none
257     \retval     FlagStatus: SET or RESET
258 */
dci_flag_get(uint32_t flag)259 FlagStatus dci_flag_get(uint32_t flag)
260 {
261     uint32_t stat = 0U;
262 
263     if(flag >> 31) {
264         /* get flag status from DCI_STAT1 register */
265         stat = DCI_STAT1;
266     } else {
267         /* get flag status from DCI_STAT0 register */
268         stat = DCI_STAT0;
269     }
270 
271     if(flag & stat) {
272         return SET;
273     } else {
274         return RESET;
275     }
276 }
277 
278 /*!
279     \brief    enable specified DCI interrupt
280     \param[in]  interrupt:
281       \arg         DCI_INT_EF: end of frame interrupt
282       \arg         DCI_INT_OVR: FIFO overrun interrupt
283       \arg         DCI_INT_ESE: embedded synchronous error interrupt
284       \arg         DCI_INT_VSYNC: vsync interrupt
285       \arg         DCI_INT_EL: end of line interrupt
286     \param[out] none
287     \retval     none
288 */
dci_interrupt_enable(uint32_t interrupt)289 void dci_interrupt_enable(uint32_t interrupt)
290 {
291     DCI_INTEN |= interrupt;
292 }
293 
294 /*!
295     \brief    disable specified DCI interrupt
296     \param[in]  interrupt:
297       \arg         DCI_INT_EF: end of frame interrupt
298       \arg         DCI_INT_OVR: FIFO overrun interrupt
299       \arg         DCI_INT_ESE: embedded synchronous error interrupt
300       \arg         DCI_INT_VSYNC: vsync interrupt
301       \arg         DCI_INT_EL: end of line interrupt
302     \param[out] none
303     \retval     none
304 */
dci_interrupt_disable(uint32_t interrupt)305 void dci_interrupt_disable(uint32_t interrupt)
306 {
307     DCI_INTEN &= ~interrupt;
308 }
309 
310 /*!
311     \brief    clear specified interrupt flag
312     \param[in]  int_flag:
313       \arg         DCI_INT_EF: end of frame interrupt
314       \arg         DCI_INT_OVR: FIFO overrun interrupt
315       \arg         DCI_INT_ESE: embedded synchronous error interrupt
316       \arg         DCI_INT_VSYNC: vsync interrupt
317       \arg         DCI_INT_EL: end of line interrupt
318     \param[out] none
319     \retval     none
320 */
dci_interrupt_flag_clear(uint32_t int_flag)321 void dci_interrupt_flag_clear(uint32_t int_flag)
322 {
323     DCI_INTC |= int_flag;
324 }
325 
326 /*!
327     \brief    get specified interrupt flag
328     \param[in]  int_flag:
329       \arg         DCI_INT_FLAG_EF: end of frame interrupt flag
330       \arg         DCI_INT_FLAG_OVR: FIFO overrun interrupt flag
331       \arg         DCI_INT_FLAG_ESE: embedded synchronous error interrupt flag
332       \arg         DCI_INT_FLAG_VSYNC: vsync interrupt flag
333       \arg         DCI_INT_FLAG_EL: end of line interrupt flag
334     \param[out] none
335     \retval     FlagStatus: SET or RESET
336 */
dci_interrupt_flag_get(uint32_t int_flag)337 FlagStatus dci_interrupt_flag_get(uint32_t int_flag)
338 {
339     if(RESET == (DCI_INTF & int_flag)) {
340         return RESET;
341     } else {
342         return SET;
343     }
344 }
345 
346 
347