1 /*
2  * Copyright 2020-2022 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef FSL_DCIC_H_
9 #define FSL_DCIC_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup DCIC
15  * @{
16  */
17 
18 /*******************************************************************************
19  * Definitions
20  ******************************************************************************/
21 #ifndef DCIC_REGION_COUNT
22 #define DCIC_REGION_COUNT DCIC_DCICRCS_COUNT
23 #endif
24 
25 /*! @brief DCIC driver version. */
26 #define FSL_DCIC_DRIVER_VERSION (MAKE_VERSION(2, 0, 3))
27 
28 /*! @brief CRC32 calculation polynomial. */
29 #define DCIC_CRC32_POLYNOMIAL 0x04C11DB7UL
30 
31 /*! @brief CRC32 calculation initialize value. */
32 #define DCIC_CRC32_INIT_VALUE 0UL
33 
34 /*! @brief ROI CRC32 value mismatch status. */
35 #define DCIC_REGION_MISMATCH_STATUS(region) (1UL << (DCIC_DCICS_ROI_MATCH_STAT_SHIFT + (region)))
36 
37 /*!
38  * @brief DCIC display signal polarity flags
39  * @anchor _DCIC_polarity_flags
40  */
41 enum _DCIC_polarity_flags
42 {
43     kDCIC_VsyncActiveHigh           = 0U, /*!< VSYNC active high. */
44     kDCIC_HsyncActiveHigh           = 0U, /*!< HSYNC active high. */
45     kDCIC_DataEnableActiveHigh      = 0U, /*!< Data enable line active high. */
46     kDCIC_DriveDataOnFallingClkEdge = 0U, /*!< Output data on rising clock edge, capture data
47                                               on falling clock edge. */
48 
49     kDCIC_VsyncActiveLow           = DCIC_DCICC_VSYNC_POL_MASK, /*!< VSYNC active low. */
50     kDCIC_HsyncActiveLow           = DCIC_DCICC_HSYNC_POL_MASK, /*!< HSYNC active low. */
51     kDCIC_DataEnableActiveLow      = DCIC_DCICC_DE_POL_MASK,    /*!< Data enable line active low. */
52     kDCIC_DriveDataOnRisingClkEdge = DCIC_DCICC_CLK_POL_MASK,   /*!< Output data on falling clock edge, capture data
53                                                                     on rising clock edge. */
54 };
55 
56 /*!
57  * @brief Status flags.
58  * @anchor _DCIC_status_flags
59  */
60 enum _DCIC_status_flags
61 {
62     kDCIC_FunctionalInterruptStatus = DCIC_DCICS_FI_STAT_MASK, /*!< Asserted when match results ready. */
63     kDCIC_ErrorInterruptStatus      = DCIC_DCICS_EI_STAT_MASK, /*!< Asserted when there is a signature mismatch. */
64     kDCIC_Region0MismatchStatus     = DCIC_REGION_MISMATCH_STATUS(0U),  /*!< Region 0  CRC32 value mismatch. */
65     kDCIC_Region1MismatchStatus     = DCIC_REGION_MISMATCH_STATUS(1U),  /*!< Region 1  CRC32 value mismatch. */
66     kDCIC_Region2MismatchStatus     = DCIC_REGION_MISMATCH_STATUS(2U),  /*!< Region 2  CRC32 value mismatch. */
67     kDCIC_Region3MismatchStatus     = DCIC_REGION_MISMATCH_STATUS(3U),  /*!< Region 3  CRC32 value mismatch. */
68     kDCIC_Region4MismatchStatus     = DCIC_REGION_MISMATCH_STATUS(4U),  /*!< Region 4  CRC32 value mismatch. */
69     kDCIC_Region5MismatchStatus     = DCIC_REGION_MISMATCH_STATUS(5U),  /*!< Region 5  CRC32 value mismatch. */
70     kDCIC_Region6MismatchStatus     = DCIC_REGION_MISMATCH_STATUS(6U),  /*!< Region 6  CRC32 value mismatch. */
71     kDCIC_Region7MismatchStatus     = DCIC_REGION_MISMATCH_STATUS(7U),  /*!< Region 7  CRC32 value mismatch. */
72     kDCIC_Region8MismatchStatus     = DCIC_REGION_MISMATCH_STATUS(8U),  /*!< Region 8  CRC32 value mismatch. */
73     kDCIC_Region9MismatchStatus     = DCIC_REGION_MISMATCH_STATUS(9U),  /*!< Region 9  CRC32 value mismatch. */
74     kDCIC_Region10MismatchStatus    = DCIC_REGION_MISMATCH_STATUS(10U), /*!< Region 10 CRC32 value mismatch. */
75     kDCIC_Region11MismatchStatus    = DCIC_REGION_MISMATCH_STATUS(11U), /*!< Region 11 CRC32 value mismatch. */
76     kDCIC_Region12MismatchStatus    = DCIC_REGION_MISMATCH_STATUS(12U), /*!< Region 12 CRC32 value mismatch. */
77     kDCIC_Region13MismatchStatus    = DCIC_REGION_MISMATCH_STATUS(13U), /*!< Region 13 CRC32 value mismatch. */
78     kDCIC_Region14MismatchStatus    = DCIC_REGION_MISMATCH_STATUS(14U), /*!< Region 14 CRC32 value mismatch. */
79     kDCIC_Region15MismatchStatus    = DCIC_REGION_MISMATCH_STATUS(15U), /*!< Region 15 CRC32 value mismatch. */
80 };
81 
82 /*!
83  * @brief Interrupts.
84  * @anchor _dcic_interrupt_enable
85  */
86 enum _dcic_interrupt_enable
87 {
88     kDCIC_FunctionalInterruptEnable = DCIC_DCICIC_FI_MASK_MASK, /*!< Interrupt when match results ready. */
89     kDCIC_ErrorInterruptEnable      = DCIC_DCICIC_EI_MASK_MASK, /*!< Interrupt when there is a signature mismatch. */
90 };
91 
92 /*!
93  * @brief DCIC configuration.
94  */
95 typedef struct _dcic_config
96 {
97     bool enableExternalSignal; /*!< Enable the mismatch external signal. When enabled, the mismatch status could
98                                  be monitored from the extern pin. */
99     uint8_t polarityFlags;     /*!< Display signal polarity, logical OR'ed of @ref _DCIC_polarity_flags. */
100     uint32_t enableInterrupts; /*!< Interrupts to enable, should be OR'ed of @ref _dcic_interrupt_enable. */
101 } dcic_config_t;
102 
103 /*!
104  * @brief Region of interest (ROI) configuration.
105  */
106 typedef struct _dcic_region_config
107 {
108     bool lock;            /*!< Lock the region configuration except reference CRC32 value setting. */
109     uint16_t upperLeftX;  /*!< X of upper left corner. Range: 0 to 2^13-1. */
110     uint16_t upperLeftY;  /*!< Y of upper left corner. Range: 0 to 2^12-1. */
111     uint16_t lowerRightX; /*!< X of lower right corner. Range: 0 to 2^13-1. */
112     uint16_t lowerRightY; /*!< Y of lower right corner. Range: 0 to 2^12-1. */
113     uint32_t refCrc;      /*!< Reference CRC32 value. */
114 } dcic_region_config_t;
115 
116 #if defined(__cplusplus)
117 extern "C" {
118 #endif
119 
120 /*******************************************************************************
121  * API
122  ******************************************************************************/
123 
124 /*!
125  * @name Initialization and deinitialization
126  * @{
127  */
128 
129 /*!
130  * @brief Initializes the DCIC.
131  *
132  * This function resets DCIC registers to default value, then
133  * set the configurations. This function does not start the
134  * DCIC to work, application should call @ref DCIC_DisableRegion
135  * to configure regions, then call @ref DCIC_Enable to start the
136  * DCIC to work.
137  *
138  * @param base   DCIC peripheral base address.
139  * @param config Pointer to the configuration.
140  */
141 void DCIC_Init(DCIC_Type *base, const dcic_config_t *config);
142 
143 /*!
144  * @brief Deinitialize the DCIC.
145  *
146  * Disable the DCIC functions.
147  *
148  * @param base DCIC peripheral base address.
149  */
150 void DCIC_Deinit(DCIC_Type *base);
151 
152 /*!
153  * @brief Get the default configuration to initialize DCIC.
154  *
155  * The default configuration is:
156  *
157  * @code
158     config->polarityFlags = kDCIC_VsyncActiveLow | kDCIC_HsyncActiveLow |
159                             kDCIC_DataEnableActiveLow | kDCIC_DriveDataOnFallingClkEdge;
160     config->enableExternalSignal = false;
161     config->enableInterrupts = 0;
162    @endcode
163  *
164  * @param config Pointer to the configuration.
165  */
166 void DCIC_GetDefaultConfig(dcic_config_t *config);
167 
168 /*!
169  * @brief Enable or disable the DCIC module.
170  *
171  * @param base DCIC peripheral base address.
172  * @param enable Use true to enable, false to disable.
173  */
DCIC_Enable(DCIC_Type * base,bool enable)174 static inline void DCIC_Enable(DCIC_Type *base, bool enable)
175 {
176     if (enable)
177     {
178         base->DCICC |= DCIC_DCICC_IC_EN_MASK;
179     }
180     else
181     {
182         base->DCICC &= ~DCIC_DCICC_IC_EN_MASK;
183     }
184 }
185 
186 /*! @} */
187 
188 /*!
189  * @name Status
190  * @{
191  */
192 
193 /*!
194  * @brief Get status flags.
195  *
196  * The flag @ref kDCIC_ErrorInterruptStatus is asserted if any region mismatch
197  * flag asserted.
198  *
199  * @brief base DCIC peripheral base address.
200  * @return Masks of asserted status flags, @ref _DCIC_status_flags.
201  */
DCIC_GetStatusFlags(DCIC_Type * base)202 static inline uint32_t DCIC_GetStatusFlags(DCIC_Type *base)
203 {
204     return base->DCICS;
205 }
206 
207 /*!
208  * @brief Clear status flags.
209  *
210  * The flag @ref kDCIC_ErrorInterruptStatus should be cleared by clearing all
211  * asserted region mismatch flags.
212  *
213  * @brief base DCIC peripheral base address.
214  * @brief mask Mask of status values that would be cleared, @ref _DCIC_status_flags.
215  */
DCIC_ClearStatusFlags(DCIC_Type * base,uint32_t mask)216 static inline void DCIC_ClearStatusFlags(DCIC_Type *base, uint32_t mask)
217 {
218     base->DCICS = (mask & (DCIC_DCICS_FI_STAT_MASK | DCIC_DCICS_ROI_MATCH_STAT_MASK));
219 }
220 
221 /*! @} */
222 
223 /*!
224  * @name Interrupts
225  * @{
226  */
227 
228 /*!
229  * @brief Lock the interrupt enabled status.
230  *
231  * Once this function is called, the interrupt enabled status could not be changed
232  * until reset.
233  *
234  * @param base DCIC peripheral base address.
235  */
DCIC_LockInterruptEnabledStatus(DCIC_Type * base)236 static inline void DCIC_LockInterruptEnabledStatus(DCIC_Type *base)
237 {
238     base->DCICIC |= DCIC_DCICIC_FREEZE_MASK_MASK;
239 }
240 
241 /*!
242  * @brief Enable interrupts.
243  *
244  * @param base DCIC peripheral base address.
245  * @param mask Mask of interrupt events that would be enabled. See to "_dcic_interrupt_enable_t".
246  */
DCIC_EnableInterrupts(DCIC_Type * base,uint32_t mask)247 static inline void DCIC_EnableInterrupts(DCIC_Type *base, uint32_t mask)
248 {
249     base->DCICIC &= ~mask;
250 }
251 
252 /*!
253  * @brief Disable interrupts.
254  *
255  * @param base DCIC peripheral base address.
256  * @param mask Mask of interrupt events that would be disabled. See to "_dcic_interrupt_enable_t".
257  */
DCIC_DisableInterrupts(DCIC_Type * base,uint32_t mask)258 static inline void DCIC_DisableInterrupts(DCIC_Type *base, uint32_t mask)
259 {
260     base->DCICIC |= mask;
261 }
262 
263 /*! @} */
264 
265 /*!
266  * @name Region
267  * @{
268  */
269 
270 /*!
271  * @brief Enable the region of interest (ROI) with configuration.
272  *
273  * Enable the ROI with configuration. To change the configuration except reference
274  * CRC value, the region should be disabled first by @ref DCIC_DisableRegion,
275  * then call this function again. The reference CRC value could be changed by
276  * @ref DCIC_SetRegionRefCrc without disabling the region.
277  * If the configuration is locked, only the reference CRC value could be changed,
278  * the region size and position, enable status could not be changed until reset.
279  *
280  * @param base DCIC peripheral base address.
281  * @param regionIdx Region index, from 0 to (DCIC_REGION_COUNT - 1).
282  * @param config Pointer to the configuration.
283  */
284 void DCIC_EnableRegion(DCIC_Type *base, uint8_t regionIdx, const dcic_region_config_t *config);
285 
286 /*!
287  * @brief Disable the region of interest (ROI).
288  *
289  * @param base DCIC peripheral base address.
290  * @param regionIdx Region index, from 0 to (DCIC_REGION_COUNT - 1).
291  */
DCIC_DisableRegion(DCIC_Type * base,uint8_t regionIdx)292 static inline void DCIC_DisableRegion(DCIC_Type *base, uint8_t regionIdx)
293 {
294     assert(regionIdx < DCIC_REGION_COUNT);
295 
296     if (regionIdx < DCIC_REGION_COUNT)
297     {
298         base->REGION[regionIdx].DCICRC &= ~DCIC_DCICRC_ROI_EN_MASK;
299     }
300 }
301 
302 /*!
303  * @brief Set the reference CRC of interest (ROI).
304  *
305  * @param base DCIC peripheral base address.
306  * @param regionIdx Region index, from 0 to (DCIC_REGION_COUNT - 1).
307  * @param crc The reference CRC value.
308  */
DCIC_SetRegionRefCrc(DCIC_Type * base,uint8_t regionIdx,uint32_t crc)309 static inline void DCIC_SetRegionRefCrc(DCIC_Type *base, uint8_t regionIdx, uint32_t crc)
310 {
311     assert(regionIdx < DCIC_REGION_COUNT);
312 
313     if (regionIdx < DCIC_REGION_COUNT)
314     {
315         base->REGION[regionIdx].DCICRRS = crc;
316     }
317 }
318 
319 /*!
320  * @brief Get the DCIC calculated CRC.
321  *
322  * @param base DCIC peripheral base address.
323  * @param regionIdx Region index, from 0 to (DCIC_REGION_COUNT - 1).
324  * @return The calculated CRC value.
325  */
DCIC_GetRegionCalculatedCrc(DCIC_Type * base,uint8_t regionIdx)326 static inline uint32_t DCIC_GetRegionCalculatedCrc(DCIC_Type *base, uint8_t regionIdx)
327 {
328     uint32_t localdcicrcs = 0U;
329 
330     assert(regionIdx < DCIC_REGION_COUNT);
331 
332     if (regionIdx < DCIC_REGION_COUNT)
333     {
334         localdcicrcs = base->REGION[regionIdx].DCICRCS;
335     }
336 
337     return localdcicrcs;
338 }
339 
340 /*! @} */
341 
342 /*!
343  * @name Misc control.
344  * @{
345  */
346 
347 /*!
348  * @brief Enable or disable output the mismatch external signal.
349  *
350  * The mismatch status can be output to external pins. If enabled:
351  *   - If @ref kDCIC_ErrorInterruptStatus asserted, the output signal
352  *     frequency is DCIC clock / 16.
353  *   - If @ref kDCIC_ErrorInterruptStatus not asserted, the output signal
354  *     frequency is DCIC clock / 4.
355  *   - If integrity check is disabled, the signal is idle.
356  *
357  * @param base DCIC peripheral base address.
358  * @param enable Use true to enable, false to disable.
359  */
DCIC_EnableMismatchExternalSignal(DCIC_Type * base,bool enable)360 static inline void DCIC_EnableMismatchExternalSignal(DCIC_Type *base, bool enable)
361 {
362     if (enable)
363     {
364         base->DCICIC |= DCIC_DCICIC_EXT_SIG_EN_MASK;
365     }
366     else
367     {
368         base->DCICIC &= ~DCIC_DCICIC_EXT_SIG_EN_MASK;
369     }
370 }
371 
372 /*! @} */
373 
374 #if defined(__cplusplus)
375 }
376 #endif
377 /*!
378  * @}
379  */
380 #endif /* FSL_DCIC_H_ */
381