1 /*
2 * Copyright 2020-2022 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_dcic.h"
9
10 /*******************************************************************************
11 * Definitions
12 ******************************************************************************/
13
14 /* Component ID definition, used by tools. */
15 #ifndef FSL_COMPONENT_ID
16 #define FSL_COMPONENT_ID "platform.drivers.dcic"
17 #endif
18
19 /*******************************************************************************
20 * Prototypes
21 ******************************************************************************/
22
23 /*!
24 * @brief Get instance number for DCIC module.
25 *
26 * @param base DCIC peripheral base address.
27 */
28 static uint32_t DCIC_GetInstance(const DCIC_Type *base);
29
30 static void DCIC_ResetRegister(DCIC_Type *base);
31
32 /*******************************************************************************
33 * Variables
34 ******************************************************************************/
35
36 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
37 /*! @brief Pointers to dcic clocks for each instance. */
38 static const clock_ip_name_t s_dcicClocks[] = DCIC_CLOCKS;
39 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
40
41 /*******************************************************************************
42 * Code
43 ******************************************************************************/
DCIC_GetInstance(const DCIC_Type * base)44 static uint32_t DCIC_GetInstance(const DCIC_Type *base)
45 {
46 static DCIC_Type *const s_dcicBases[] = DCIC_BASE_PTRS;
47
48 uint32_t instance;
49
50 /* Find the instance index from base address mappings. */
51 for (instance = 0; instance < ARRAY_SIZE(s_dcicBases); instance++)
52 {
53 if (s_dcicBases[instance] == base)
54 {
55 break;
56 }
57 }
58
59 assert(instance < ARRAY_SIZE(s_dcicBases));
60
61 return instance;
62 }
63
64 #define DCIC_DCCIC_RESET_VALUE (DCIC_DCICC_VSYNC_POL_MASK | DCIC_DCICC_HSYNC_POL_MASK | DCIC_DCICC_DE_POL_MASK)
65 #define DCIC_DCICIC_RESET_VALUE (DCIC_DCICIC_FI_MASK_MASK | DCIC_DCICIC_EI_MASK_MASK)
66
DCIC_ResetRegister(DCIC_Type * base)67 static void DCIC_ResetRegister(DCIC_Type *base)
68 {
69 uint32_t i;
70
71 base->DCICC = DCIC_DCCIC_RESET_VALUE;
72 base->DCICIC = DCIC_DCICIC_RESET_VALUE;
73
74 /* Reset region registers. */
75 for (i = 0; i < DCIC_REGION_COUNT; i++)
76 {
77 base->REGION[i].DCICRC = 0UL;
78 base->REGION[i].DCICRS = 0UL;
79 base->REGION[i].DCICRRS = 0UL;
80 }
81
82 /* Clear all status. */
83 base->DCICS = (DCIC_DCICS_EI_STAT_MASK | DCIC_DCICS_FI_STAT_MASK | DCIC_DCICS_ROI_MATCH_STAT_MASK);
84 }
85
86 /*
87 * brief Initializes the DCIC.
88 *
89 * param base DCIC peripheral base address.
90 * param config Pointer to the configuration.
91 */
DCIC_Init(DCIC_Type * base,const dcic_config_t * config)92 void DCIC_Init(DCIC_Type *base, const dcic_config_t *config)
93 {
94 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && (0 != FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
95 /* Enable the clock. */
96 (void)CLOCK_EnableClock(s_dcicClocks[DCIC_GetInstance(base)]);
97 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
98
99 DCIC_ResetRegister(base);
100
101 base->DCICC = config->polarityFlags;
102
103 DCIC_EnableMismatchExternalSignal(base, config->enableExternalSignal);
104 DCIC_EnableInterrupts(base, config->enableInterrupts);
105 }
106
107 /*
108 * brief Disable the DCIC.
109 *
110 * param base DCIC peripheral base address.
111 */
DCIC_Deinit(DCIC_Type * base)112 void DCIC_Deinit(DCIC_Type *base)
113 {
114 base->DCICC = 0U;
115
116 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && (0 != FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
117 /* Disable the clock. */
118 (void)CLOCK_DisableClock(s_dcicClocks[DCIC_GetInstance(base)]);
119 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
120 }
121
122 /*!
123 * Get the default configuration to initialize DCIC.
124 *
125 * The default configuration is:
126 *
127 config->polarityFlags = kDCIC_VsyncActiveLow | kDCIC_HsyncActiveLow |
128 kDCIC_DataEnableActiveLow | kDCIC_DriveDataOnFallingClkEdge;
129 config->enableExternalSignal = false;
130 config->enableInterrupts = 0;
131 *
132 * param config Pointer to the configuration.
133 */
DCIC_GetDefaultConfig(dcic_config_t * config)134 void DCIC_GetDefaultConfig(dcic_config_t *config)
135 {
136 assert(NULL != config);
137
138 config->polarityFlags = (uint8_t)kDCIC_VsyncActiveLow | (uint8_t)kDCIC_HsyncActiveLow |
139 (uint8_t)kDCIC_DataEnableActiveLow | (uint8_t)kDCIC_DriveDataOnFallingClkEdge;
140 config->enableExternalSignal = false;
141 config->enableInterrupts = 0;
142 }
143
144 /*
145 * brief Enable the region of interest (ROI) with configuration.
146 *
147 * Enable the ROI with configuration. To change the configuration except reference
148 * CRC value, the region should be disabled first by ref DCIC_DisableRegion,
149 * then call this function again. The reference CRC value could be changed by
150 * ref DCIC_SetRegionRefCrc without disabling the region.
151 * If the configuration is locked, only the reference CRC value could be changed,
152 * the region size and position, enable status could not be changed until reset.
153 *
154 * param base DCIC peripheral base address.
155 * param regionIdx Region index, from 0 to (DCIC_REGION_COUNT - 1).
156 * param config Pointer to the configuration.
157 */
DCIC_EnableRegion(DCIC_Type * base,uint8_t regionIdx,const dcic_region_config_t * config)158 void DCIC_EnableRegion(DCIC_Type *base, uint8_t regionIdx, const dcic_region_config_t *config)
159 {
160 assert(regionIdx < DCIC_REGION_COUNT);
161 assert(NULL != config);
162
163 if (regionIdx < DCIC_REGION_COUNT)
164 {
165 base->REGION[regionIdx].DCICRRS = config->refCrc;
166
167 base->REGION[regionIdx].DCICRS = (((uint32_t)config->lowerRightX << DCIC_DCICRS_END_OFFSET_X_SHIFT) |
168 ((uint32_t)config->lowerRightY << DCIC_DCICRS_END_OFFSET_Y_SHIFT));
169
170 base->REGION[regionIdx].DCICRC = (((uint32_t)config->upperLeftX << DCIC_DCICRC_START_OFFSET_X_SHIFT) |
171 ((uint32_t)config->upperLeftY << DCIC_DCICRC_START_OFFSET_Y_SHIFT) |
172 (config->lock ? DCIC_DCICRC_ROI_FREEZE_MASK : 0UL) | DCIC_DCICRC_ROI_EN_MASK);
173 }
174 }
175