1 /*
2 * Copyright 2017, 2019-2020 NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #ifndef FSL_MIPI_CSI2RX_H_
10 #define FSL_MIPI_CSI2RX_H_
11
12 #include "fsl_common.h"
13
14 /*!
15 * @addtogroup csi2rx
16 * @{
17 */
18
19 /*******************************************************************************
20 * Definitions
21 ******************************************************************************/
22
23 /*! @name Driver version */
24 /*! @{ */
25 /*! @brief CSI2RX driver version. */
26 #define FSL_CSI2RX_DRIVER_VERSION (MAKE_VERSION(2, 0, 4))
27 /*! @} */
28
29 #if (defined(FSL_FEATURE_CSI2RX_HAS_NO_REG_PREFIX) && FSL_FEATURE_CSI2RX_HAS_NO_REG_PREFIX)
30
31 #define CSI2RX_REG_CFG_NUM_LANES(base) (base)->CFG_NUM_LANES
32 #define CSI2RX_REG_CFG_DISABLE_DATA_LANES(base) (base)->CFG_DISABLE_DATA_LANES
33 #define CSI2RX_REG_BIT_ERR(base) (base)->BIT_ERR
34 #define CSI2RX_REG_IRQ_STATUS(base) (base)->IRQ_STATUS
35 #define CSI2RX_REG_IRQ_MASK(base) (base)->IRQ_MASK
36 #define CSI2RX_REG_ULPS_STATUS(base) (base)->ULPS_STATUS
37 #define CSI2RX_REG_PPI_ERRSOT_HS(base) (base)->PPI_ERRSOT_HS
38 #define CSI2RX_REG_PPI_ERRSOTSYNC_HS(base) (base)->PPI_ERRSOTSYNC_HS
39 #define CSI2RX_REG_PPI_ERRESC(base) (base)->PPI_ERRESC
40 #define CSI2RX_REG_PPI_ERRSYNCESC(base) (base)->PPI_ERRSYNCESC
41 #define CSI2RX_REG_PPI_ERRCONTROL(base) (base)->PPI_ERRCONTROL
42 #define CSI2RX_REG_CFG_DISABLE_PAYLOAD_0(base) (base)->CFG_DISABLE_PAYLOAD_0
43 #define CSI2RX_REG_CFG_DISABLE_PAYLOAD_1(base) (base)->CFG_DISABLE_PAYLOAD_1
44 #define CSI2RX_REG_CFG_IGNORE_VC(base) (base)->CFG_IGNORE_VC
45 #define CSI2RX_REG_CFG_VID_VC(base) (base)->CFG_VID_VC
46 #define CSI2RX_REG_CFG_VID_P_FIFO_SEND_LEVEL(base) (base)->CFG_VID_P_FIFO_SEND_LEVEL
47 #define CSI2RX_REG_CFG_VID_VSYNC(base) (base)->CFG_VID_VSYNC
48 #define CSI2RX_REG_CFG_VID_HSYNC_FP(base) (base)->CFG_VID_HSYNC_FP
49 #define CSI2RX_REG_CFG_VID_HSYNC(base) (base)->CFG_VID_HSYNC
50 #define CSI2RX_REG_CFG_VID_HSYNC_BP(base) (base)->CFG_VID_HSYNC_BP
51
52 #else
53
54 #define CSI2RX_REG_CFG_NUM_LANES(base) (base)->CSI2RX_CFG_NUM_LANES
55 #define CSI2RX_REG_CFG_DISABLE_DATA_LANES(base) (base)->CSI2RX_CFG_DISABLE_DATA_LANES
56 #define CSI2RX_REG_BIT_ERR(base) (base)->CSI2RX_BIT_ERR
57 #define CSI2RX_REG_IRQ_STATUS(base) (base)->CSI2RX_IRQ_STATUS
58 #define CSI2RX_REG_IRQ_MASK(base) (base)->CSI2RX_IRQ_MASK
59 #define CSI2RX_REG_ULPS_STATUS(base) (base)->CSI2RX_ULPS_STATUS
60 #define CSI2RX_REG_PPI_ERRSOT_HS(base) (base)->CSI2RX_PPI_ERRSOT_HS
61 #define CSI2RX_REG_PPI_ERRSOTSYNC_HS(base) (base)->CSI2RX_PPI_ERRSOTSYNC_HS
62 #define CSI2RX_REG_PPI_ERRESC(base) (base)->CSI2RX_PPI_ERRESC
63 #define CSI2RX_REG_PPI_ERRSYNCESC(base) (base)->CSI2RX_PPI_ERRSYNCESC
64 #define CSI2RX_REG_PPI_ERRCONTROL(base) (base)->CSI2RX_PPI_ERRCONTROL
65 #define CSI2RX_REG_CFG_DISABLE_PAYLOAD_0(base) (base)->CSI2RX_CFG_DISABLE_PAYLOAD_0
66 #define CSI2RX_REG_CFG_DISABLE_PAYLOAD_1(base) (base)->CSI2RX_CFG_DISABLE_PAYLOAD_1
67 #define CSI2RX_REG_CFG_IGNORE_VC(base) (base)->CSI2RX_CFG_IGNORE_VC
68 #define CSI2RX_REG_CFG_VID_VC(base) (base)->CSI2RX_CFG_VID_VC
69 #define CSI2RX_REG_CFG_VID_P_FIFO_SEND_LEVEL(base) (base)->CSI2RX_CFG_VID_P_FIFO_SEND_LEVEL
70 #define CSI2RX_REG_CFG_VID_VSYNC(base) (base)->CSI2RX_CFG_VID_VSYNC
71 #define CSI2RX_REG_CFG_VID_HSYNC_FP(base) (base)->CSI2RX_CFG_VID_HSYNC_FP
72 #define CSI2RX_REG_CFG_VID_HSYNC(base) (base)->CSI2RX_CFG_VID_HSYNC
73 #define CSI2RX_REG_CFG_VID_HSYNC_BP(base) (base)->CSI2RX_CFG_VID_HSYNC_BP
74
75 #endif
76
77 #ifndef MIPI_CSI2RX_CSI2RX_CFG_NUM_LANES_csi2rx_cfg_num_lanes_MASK
78 #define MIPI_CSI2RX_CSI2RX_CFG_NUM_LANES_csi2rx_cfg_num_lanes_MASK MIPI_CSI2RX_CFG_NUM_LANES_CFG_NUM_LANES_MASK
79 #endif
80
81 #ifndef MIPI_CSI2RX_CSI2RX_IRQ_MASK_csi2rx_irq_mask_MASK
82 #define MIPI_CSI2RX_CSI2RX_IRQ_MASK_csi2rx_irq_mask_MASK MIPI_CSI2RX_IRQ_MASK_IRQ_MASK_MASK
83 #endif
84
85 /*! @brief CSI2RX data lanes. */
86 enum _csi2rx_data_lane
87 {
88 kCSI2RX_DataLane0 = (1U << 0U), /*!< Data lane 0. */
89 kCSI2RX_DataLane1 = (1U << 1U), /*!< Data lane 1. */
90 kCSI2RX_DataLane2 = (1U << 2U), /*!< Data lane 2. */
91 kCSI2RX_DataLane3 = (1U << 3U) /*!< Data lane 3. */
92 };
93
94 /*! @brief CSI2RX payload type. */
95 enum _csi2rx_payload
96 {
97 kCSI2RX_PayloadGroup0Null = (1U << 0U), /*!< NULL. */
98 kCSI2RX_PayloadGroup0Blank = (1U << 1U), /*!< Blank. */
99 kCSI2RX_PayloadGroup0Embedded = (1U << 2U), /*!< Embedded. */
100 kCSI2RX_PayloadGroup0YUV420_8Bit = (1U << 10U), /*!< Legacy YUV420 8 bit. */
101 kCSI2RX_PayloadGroup0YUV422_8Bit = (1U << 14U), /*!< YUV422 8 bit. */
102 kCSI2RX_PayloadGroup0YUV422_10Bit = (1U << 15U), /*!< YUV422 10 bit. */
103 kCSI2RX_PayloadGroup0RGB444 = (1U << 16U), /*!< RGB444. */
104 kCSI2RX_PayloadGroup0RGB555 = (1U << 17U), /*!< RGB555. */
105 kCSI2RX_PayloadGroup0RGB565 = (1U << 18U), /*!< RGB565. */
106 kCSI2RX_PayloadGroup0RGB666 = (1U << 19U), /*!< RGB666. */
107 kCSI2RX_PayloadGroup0RGB888 = (1U << 20U), /*!< RGB888. */
108 kCSI2RX_PayloadGroup0Raw6 = (1U << 24U), /*!< Raw 6. */
109 kCSI2RX_PayloadGroup0Raw7 = (1U << 25U), /*!< Raw 7. */
110 kCSI2RX_PayloadGroup0Raw8 = (1U << 26U), /*!< Raw 8. */
111 kCSI2RX_PayloadGroup0Raw10 = (1U << 27U), /*!< Raw 10. */
112 kCSI2RX_PayloadGroup0Raw12 = (1U << 28U), /*!< Raw 12. */
113 kCSI2RX_PayloadGroup0Raw14 = (1U << 29U), /*!< Raw 14. */
114 kCSI2RX_PayloadGroup1UserDefined1 = (1U << 0U), /*!< User defined 8-bit data type 1, 0x30. */
115 kCSI2RX_PayloadGroup1UserDefined2 = (1U << 1U), /*!< User defined 8-bit data type 2, 0x31. */
116 kCSI2RX_PayloadGroup1UserDefined3 = (1U << 2U), /*!< User defined 8-bit data type 3, 0x32. */
117 kCSI2RX_PayloadGroup1UserDefined4 = (1U << 3U), /*!< User defined 8-bit data type 4, 0x33. */
118 kCSI2RX_PayloadGroup1UserDefined5 = (1U << 4U), /*!< User defined 8-bit data type 5, 0x34. */
119 kCSI2RX_PayloadGroup1UserDefined6 = (1U << 5U), /*!< User defined 8-bit data type 6, 0x35. */
120 kCSI2RX_PayloadGroup1UserDefined7 = (1U << 6U), /*!< User defined 8-bit data type 7, 0x36. */
121 kCSI2RX_PayloadGroup1UserDefined8 = (1U << 7U) /*!< User defined 8-bit data type 8, 0x37. */
122 };
123
124 /*! @brief CSI2RX configuration. */
125 typedef struct _csi2rx_config
126 {
127 uint8_t laneNum; /*!< Number of active lanes used for receiving data. */
128 uint8_t tHsSettle_EscClk; /*!< Number of rx_clk_esc clock periods for T_HS_SETTLE.
129 The T_HS_SETTLE should be in the range of
130 85ns + 6UI to 145ns + 10UI. */
131 } csi2rx_config_t;
132
133 /*! @brief MIPI CSI2RX bit errors. */
134 enum _csi2rx_bit_error
135 {
136 kCSI2RX_BitErrorEccTwoBit = (1U << 0U), /*!< ECC two bit error has occurred. */
137 kCSI2RX_BitErrorEccOneBit = (1U << 1U) /*!< ECC one bit error has occurred. */
138 };
139
140 /*! @brief MIPI CSI2RX PPI error types. */
141 typedef enum _csi2rx_ppi_error
142 {
143 kCSI2RX_PpiErrorSotHs, /*!< CSI2RX DPHY PPI error ErrSotHS. */
144 kCSI2RX_PpiErrorSotSyncHs, /*!< CSI2RX DPHY PPI error ErrSotSync_HS. */
145 kCSI2RX_PpiErrorEsc, /*!< CSI2RX DPHY PPI error ErrEsc. */
146 kCSI2RX_PpiErrorSyncEsc, /*!< CSI2RX DPHY PPI error ErrSyncEsc. */
147 kCSI2RX_PpiErrorControl, /*!< CSI2RX DPHY PPI error ErrControl. */
148 } csi2rx_ppi_error_t;
149
150 /*! @brief MIPI CSI2RX interrupt. */
151 enum _csi2rx_interrupt
152 {
153 kCSI2RX_InterruptCrcError = (1U << 0U), /* CRC error. */
154 kCSI2RX_InterruptEccOneBitError = (1U << 1U), /* One bit ECC error. */
155 kCSI2RX_InterruptEccTwoBitError = (1U << 2U), /* One bit ECC error. */
156 kCSI2RX_InterruptUlpsStatusChange = (1U << 3U), /* ULPS status changed. */
157 kCSI2RX_InterruptErrorSotHs = (1U << 4U), /* D-PHY ErrSotHS occurred. */
158 kCSI2RX_InterruptErrorSotSyncHs = (1U << 5U), /* D-PHY ErrSotSync_HS occurred. */
159 kCSI2RX_InterruptErrorEsc = (1U << 6U), /* D-PHY ErrEsc occurred. */
160 kCSI2RX_InterruptErrorSyncEsc = (1U << 7U), /* D-PHY ErrSyncEsc occurred. */
161 kCSI2RX_InterruptErrorControl = (1U << 8U), /* D-PHY ErrControl occurred. */
162 };
163
164 /*! @brief MIPI CSI2RX D-PHY ULPS state. */
165 enum _csi2rx_ulps_status
166 {
167 kCSI2RX_ClockLaneUlps = (1U << 0U), /*!< Clock lane is in ULPS state. */
168 kCSI2RX_DataLane0Ulps = (1U << 1U), /*!< Data lane 0 is in ULPS state. */
169 kCSI2RX_DataLane1Ulps = (1U << 2U), /*!< Data lane 1 is in ULPS state. */
170 kCSI2RX_DataLane2Ulps = (1U << 3U), /*!< Data lane 2 is in ULPS state. */
171 kCSI2RX_DataLane3Ulps = (1U << 4U), /*!< Data lane 3 is in ULPS state. */
172 kCSI2RX_ClockLaneMark = (1U << 5U), /*!< Clock lane is in mark state. */
173 kCSI2RX_DataLane0Mark = (1U << 6U), /*!< Data lane 0 is in mark state. */
174 kCSI2RX_DataLane1Mark = (1U << 7U), /*!< Data lane 1 is in mark state. */
175 kCSI2RX_DataLane2Mark = (1U << 8U), /*!< Data lane 2 is in mark state. */
176 kCSI2RX_DataLane3Mark = (1U << 9U), /*!< Data lane 3 is in mark state. */
177 };
178
179 /*******************************************************************************
180 * API
181 ******************************************************************************/
182 #if defined(__cplusplus)
183 extern "C" {
184 #endif
185
186 /*!
187 * @brief Enables and configures the CSI2RX peripheral module.
188 *
189 * @param base CSI2RX peripheral address.
190 * @param config CSI2RX module configuration structure.
191 */
192 void CSI2RX_Init(MIPI_CSI2RX_Type *base, const csi2rx_config_t *config);
193
194 /*!
195 * @brief Disables the CSI2RX peripheral module.
196 *
197 * @param base CSI2RX peripheral address.
198 */
199 void CSI2RX_Deinit(MIPI_CSI2RX_Type *base);
200
201 /*!
202 * @brief Gets the MIPI CSI2RX bit error status.
203 *
204 * This function gets the RX bit error status, the return value could be compared
205 * with @ref _csi2rx_bit_error. If one bit ECC error detected, the return value
206 * could be passed to the function @ref CSI2RX_GetEccBitErrorPosition to get the
207 * position of the ECC error bit.
208 *
209 * Example:
210 * @code
211 uint32_t bitError;
212 uint32_t bitErrorPosition;
213
214 bitError = CSI2RX_GetBitError(MIPI_CSI2RX);
215
216 if (kCSI2RX_BitErrorEccTwoBit & bitError)
217 {
218 Two bits error;
219 }
220 else if (kCSI2RX_BitErrorEccOneBit & bitError)
221 {
222 One bits error;
223 bitErrorPosition = CSI2RX_GetEccBitErrorPosition(bitError);
224 }
225 @endcode
226 *
227 * @param base CSI2RX peripheral address.
228 * @return The RX bit error status.
229 */
CSI2RX_GetBitError(MIPI_CSI2RX_Type * base)230 static inline uint32_t CSI2RX_GetBitError(MIPI_CSI2RX_Type *base)
231 {
232 return CSI2RX_REG_BIT_ERR(base);
233 }
234
235 /*!
236 * @brief Get ECC one bit error bit position.
237 *
238 * If @ref CSI2RX_GetBitError detects ECC one bit error, this function could
239 * extract the error bit position from the return value of @ref CSI2RX_GetBitError.
240 *
241 * @param bitError The bit error returned by @ref CSI2RX_GetBitError.
242 * @return The position of error bit.
243 */
CSI2RX_GetEccBitErrorPosition(uint32_t bitError)244 static inline uint32_t CSI2RX_GetEccBitErrorPosition(uint32_t bitError)
245 {
246 return (bitError >> 2U) & 0x1FU;
247 }
248
249 /*!
250 * @brief Gets the MIPI CSI2RX D-PHY ULPS status.
251 *
252 * Example to check whether data lane 0 is in ULPS status.
253 * @code
254 uint32_t status = CSI2RX_GetUlpsStatus(MIPI_CSI2RX);
255
256 if (kCSI2RX_DataLane0Ulps & status)
257 {
258 Data lane 0 is in ULPS status.
259 }
260 @endcode
261 *
262 * @param base CSI2RX peripheral address.
263 * @return The MIPI CSI2RX D-PHY ULPS status, it is OR'ed value or @ref _csi2rx_ulps_status.
264 */
CSI2RX_GetUlpsStatus(MIPI_CSI2RX_Type * base)265 static inline uint32_t CSI2RX_GetUlpsStatus(MIPI_CSI2RX_Type *base)
266 {
267 return CSI2RX_REG_ULPS_STATUS(base);
268 }
269
270 /*!
271 * @brief Gets the MIPI CSI2RX D-PHY PPI error lanes.
272 *
273 * This function checks the PPI error occurred on which data lanes, the returned
274 * value is OR'ed value of @ref csi2rx_ppi_error_t. For example, if the ErrSotHS
275 * is detected, to check the ErrSotHS occurred on which data lanes, use like this:
276 *
277 * @code
278 uint32_t errorDataLanes = CSI2RX_GetPpiErrorDataLanes(MIPI_CSI2RX, kCSI2RX_PpiErrorSotHs);
279
280 if (kCSI2RX_DataLane0 & errorDataLanes)
281 {
282 ErrSotHS occurred on data lane 0.
283 }
284
285 if (kCSI2RX_DataLane1 & errorDataLanes)
286 {
287 ErrSotHS occurred on data lane 1.
288 }
289 @endcode
290 *
291 * @param base CSI2RX peripheral address.
292 * @param errorType What kind of error to check.
293 * @return The data lane mask that error @p errorType occurred.
294 */
CSI2RX_GetPpiErrorDataLanes(MIPI_CSI2RX_Type * base,csi2rx_ppi_error_t errorType)295 static inline uint32_t CSI2RX_GetPpiErrorDataLanes(MIPI_CSI2RX_Type *base, csi2rx_ppi_error_t errorType)
296 {
297 uint32_t errorLanes;
298
299 if (kCSI2RX_PpiErrorSotHs == errorType)
300 {
301 errorLanes = CSI2RX_REG_PPI_ERRSOT_HS(base);
302 }
303 else if (kCSI2RX_PpiErrorSotSyncHs == errorType)
304 {
305 errorLanes = CSI2RX_REG_PPI_ERRSOTSYNC_HS(base);
306 }
307 else if (kCSI2RX_PpiErrorEsc == errorType)
308 {
309 errorLanes = CSI2RX_REG_PPI_ERRESC(base);
310 }
311 else if (kCSI2RX_PpiErrorSyncEsc == errorType)
312 {
313 errorLanes = CSI2RX_REG_PPI_ERRSYNCESC(base);
314 }
315 else
316 {
317 errorLanes = CSI2RX_REG_PPI_ERRCONTROL(base);
318 }
319
320 return errorLanes;
321 }
322
323 /*!
324 * @brief Enable the MIPI CSI2RX interrupts.
325 *
326 * This function enables the MIPI CSI2RX interrupts. The interrupts to enable
327 * are passed in as an OR'ed value of @ref _csi2rx_interrupt. For example, to enable
328 * one bit and two bit ECC error interrupts, use like this:
329 *
330 * @code
331 CSI2RX_EnableInterrupts(MIPI_CSI2RX, kCSI2RX_InterruptEccOneBitError | kCSI2RX_InterruptEccTwoBitError);
332 @endcode
333 *
334 * @param base CSI2RX peripheral address.
335 * @param mask OR'ed value of @ref _csi2rx_interrupt.
336 */
CSI2RX_EnableInterrupts(MIPI_CSI2RX_Type * base,uint32_t mask)337 static inline void CSI2RX_EnableInterrupts(MIPI_CSI2RX_Type *base, uint32_t mask)
338 {
339 CSI2RX_REG_IRQ_MASK(base) &= ~mask;
340 }
341
342 /*!
343 * @brief Disable the MIPI CSI2RX interrupts.
344 *
345 * This function disables the MIPI CSI2RX interrupts. The interrupts to disable
346 * are passed in as an OR'ed value of @ref _csi2rx_interrupt. For example, to disable
347 * one bit and two bit ECC error interrupts, use like this:
348 *
349 * @code
350 CSI2RX_DisableInterrupts(MIPI_CSI2RX, kCSI2RX_InterruptEccOneBitError | kCSI2RX_InterruptEccTwoBitError);
351 @endcode
352 *
353 * @param base CSI2RX peripheral address.
354 * @param mask OR'ed value of @ref _csi2rx_interrupt.
355 */
CSI2RX_DisableInterrupts(MIPI_CSI2RX_Type * base,uint32_t mask)356 static inline void CSI2RX_DisableInterrupts(MIPI_CSI2RX_Type *base, uint32_t mask)
357 {
358 CSI2RX_REG_IRQ_MASK(base) |= mask;
359 }
360
361 /*!
362 * @brief Get the MIPI CSI2RX interrupt status.
363 *
364 * This function returns the MIPI CSI2RX interrupts status as an OR'ed value
365 * of @ref _csi2rx_interrupt.
366 *
367 * @param base CSI2RX peripheral address.
368 * @return OR'ed value of @ref _csi2rx_interrupt.
369 */
CSI2RX_GetInterruptStatus(MIPI_CSI2RX_Type * base)370 static inline uint32_t CSI2RX_GetInterruptStatus(MIPI_CSI2RX_Type *base)
371 {
372 return CSI2RX_REG_IRQ_STATUS(base);
373 }
374
375 #if defined(__cplusplus)
376 }
377 #endif
378
379 /*!
380 *@}
381 */
382
383 #endif /* FSL_MIPI_CSI2RX_H_ */
384