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