1 /*
2 * Copyright 2020-2021 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #ifndef _FSL_MIPI_DSI_H_
9 #define _FSL_MIPI_DSI_H_
10
11 #include "fsl_common.h"
12
13 /*!
14 * @addtogroup mipi_dsi
15 * @{
16 */
17
18 /*******************************************************************************
19 * Definitions
20 ******************************************************************************/
21
22 /*! @name Driver version */
23 /*@{*/
24 #define FSL_MIPI_DSI_DRIVER_VERSION (MAKE_VERSION(2, 2, 0))
25 /*@}*/
26
27 /* The max APB transfer size. */
28 #define FSL_DSI_TX_MAX_PAYLOAD_BYTE (64U * 4U)
29 #define FSL_DSI_RX_MAX_PAYLOAD_BYTE (64U * 4U)
30
31 /*! @brief MIPI DSI structure definition. */
32 typedef struct
33 {
34 DSI_HOST_Type *host; /*!< Pointer to HOST registers. */
35 DSI_HOST_APB_PKT_IF_Type *apb; /*!< Pointer to APB registers. */
36 DSI_HOST_DPI_INTFC_Type *dpi; /*!< Pointer to DPI registers. */
37 DSI_HOST_NXP_FDSOI28_DPHY_INTFC_Type *dphy; /*!< Pointer to DPHY registers. */
38 } MIPI_DSI_Type;
39
40 /*! @brief Error codes for the MIPI DSI driver. */
41 enum
42 {
43 kStatus_DSI_Busy = MAKE_STATUS(kStatusGroup_MIPI_DSI, 0), /*!< DSI is busy. */
44 kStatus_DSI_RxDataError = MAKE_STATUS(kStatusGroup_MIPI_DSI, 1), /*!< Read data error. */
45 kStatus_DSI_ErrorReportReceived = MAKE_STATUS(kStatusGroup_MIPI_DSI, 2), /*!< Error report package received. */
46 kStatus_DSI_NotSupported = MAKE_STATUS(kStatusGroup_MIPI_DSI, 3), /*!< The transfer type not supported. */
47 };
48
49 /*! @brief MIPI DSI controller configuration. */
50 typedef struct _dsi_config
51 {
52 uint8_t numLanes; /*!< Number of lanes. */
53 bool enableNonContinuousHsClk; /*!< In enabled, the high speed clock will enter
54 low power mode between transmissions. */
55 bool enableTxUlps; /*!< Enable the TX ULPS. */
56 bool autoInsertEoTp; /*!< Insert an EoTp short package when switching from HS to LP. */
57 uint8_t numExtraEoTp; /*!< How many extra EoTp to send after the end of a packet. */
58 uint32_t htxTo_ByteClk; /*!< HS TX timeout count (HTX_TO) in byte clock. */
59 uint32_t lrxHostTo_ByteClk; /*!< LP RX host timeout count (LRX-H_TO) in byte clock. */
60 uint32_t btaTo_ByteClk; /*!< Bus turn around timeout count (TA_TO) in byte clock. */
61 } dsi_config_t;
62
63 /*! @brief MIPI DPI interface color coding. */
64 typedef enum _dsi_dpi_color_coding
65 {
66 kDSI_Dpi16BitConfig1 = 0U, /*!< 16-bit configuration 1. RGB565: XXXXXXXX_RRRRRGGG_GGGBBBBB. */
67 kDSI_Dpi16BitConfig2 = 1U, /*!< 16-bit configuration 2. RGB565: XXXRRRRR_XXGGGGGG_XXXBBBBB. */
68 kDSI_Dpi16BitConfig3 = 2U, /*!< 16-bit configuration 3. RGB565: XXRRRRRX_XXGGGGGG_XXBBBBBX. */
69 kDSI_Dpi18BitConfig1 = 3U, /*!< 18-bit configuration 1. RGB666: XXXXXXRR_RRRRGGGG_GGBBBBBB. */
70 kDSI_Dpi18BitConfig2 = 4U, /*!< 18-bit configuration 2. RGB666: XXRRRRRR_XXGGGGGG_XXBBBBBB. */
71 kDSI_Dpi24Bit = 5U, /*!< 24-bit. */
72 } dsi_dpi_color_coding_t;
73
74 /*! @brief MIPI DSI pixel packet type send through DPI interface. */
75 typedef enum _dsi_dpi_pixel_packet
76 {
77 kDSI_PixelPacket16Bit = 0U, /*!< 16 bit RGB565. */
78 kDSI_PixelPacket18Bit = 1U, /*!< 18 bit RGB666 packed. */
79 kDSI_PixelPacket18BitLoosely = 2U, /*!< 18 bit RGB666 loosely packed into three bytes. */
80 kDSI_PixelPacket24Bit = 3U, /*!< 24 bit RGB888, each pixel uses three bytes. */
81 } dsi_dpi_pixel_packet_t;
82
83 /*! @brief _dsi_dpi_polarity_flag DPI signal polarity. */
84 enum
85 {
86 kDSI_DpiVsyncActiveLow = 0U, /*!< VSYNC active low. */
87 kDSI_DpiHsyncActiveLow = 0U, /*!< HSYNC active low. */
88 kDSI_DpiVsyncActiveHigh = (1U << 0U), /*!< VSYNC active high. */
89 kDSI_DpiHsyncActiveHigh = (1U << 1U), /*!< HSYNC active high. */
90 };
91
92 /*! @brief DPI video mode. */
93 typedef enum _dsi_dpi_video_mode
94 {
95 kDSI_DpiNonBurstWithSyncPulse = 0U, /*!< Non-Burst mode with Sync Pulses. */
96 kDSI_DpiNonBurstWithSyncEvent = 1U, /*!< Non-Burst mode with Sync Events. */
97 kDSI_DpiBurst = 2U, /*!< Burst mode. */
98 } dsi_dpi_video_mode_t;
99
100 /*! @brief Behavior in BLLP (Blanking or Low-Power Interval). */
101 typedef enum _dsi_dpi_bllp_mode
102 {
103 kDSI_DpiBllpLowPower, /*!< LP mode used in BLLP periods. */
104 kDSI_DpiBllpBlanking, /*!< Blanking packets used in BLLP periods. */
105 kDSI_DpiBllpNull, /*!< Null packets used in BLLP periods. */
106 } dsi_dpi_bllp_mode_t;
107
108 /*! @brief MIPI DSI controller DPI interface configuration. */
109 typedef struct _dsi_dpi_config
110 {
111 uint16_t pixelPayloadSize; /*!< Maximum number of pixels that should be sent
112 as one DSI packet. Recommended that the line size
113 (in pixels) is evenly divisible by this parameter. */
114 dsi_dpi_color_coding_t dpiColorCoding; /*!< DPI color coding. */
115 dsi_dpi_pixel_packet_t pixelPacket; /*!< Pixel packet format. */
116
117 dsi_dpi_video_mode_t videoMode; /*!< Video mode. */
118 dsi_dpi_bllp_mode_t bllpMode; /*!< Behavior in BLLP. */
119
120 uint8_t polarityFlags; /*!< OR'ed value of _dsi_dpi_polarity_flag controls signal polarity. */
121 uint16_t hfp; /*!< Horizontal front porch, in dpi pixel clock. */
122 uint16_t hbp; /*!< Horizontal back porch, in dpi pixel clock. */
123 uint16_t hsw; /*!< Horizontal sync width, in dpi pixel clock. */
124 uint8_t vfp; /*!< Number of lines in vertical front porch. */
125 uint8_t vbp; /*!< Number of lines in vertical back porch. */
126 uint16_t panelHeight; /*!< Line number in vertical active area. */
127
128 uint8_t virtualChannel; /*!< Virtual channel. */
129 } dsi_dpi_config_t;
130
131 /*! @brief MIPI DSI D-PHY configuration. */
132 typedef struct _dsi_dphy_config
133 {
134 uint32_t txHsBitClk_Hz; /*!< The generated HS TX bit clock in Hz. */
135
136 uint8_t tClkPre_ByteClk; /*!< TLPX + TCLK-PREPARE + TCLK-ZERO + TCLK-PRE in byte clock.
137 Set how long the controller
138 will wait after enabling clock lane for HS before
139 enabling data lanes for HS. */
140 uint8_t tClkPost_ByteClk; /*!< TCLK-POST + T_CLK-TRAIL in byte clock. Set how long the controller
141 will wait before putting clock lane into LP mode after
142 data lanes detected in stop state. */
143 uint8_t tHsExit_ByteClk; /*!< THS-EXIT in byte clock. Set how long the controller
144 will wait after the clock lane has been put into LP
145 mode before enabling clock lane for HS again. */
146 uint32_t tWakeup_EscClk; /*!< Number of clk_esc clock periods to keep a clock
147 or data lane in Mark-1 state after exiting ULPS. */
148 uint8_t tHsPrepare_HalfEscClk; /*!< THS-PREPARE in clk_esc/2. Set how long
149 to drive the LP-00 state before HS transmissions,
150 available values are 2, 3, 4, 5. */
151 uint8_t tClkPrepare_HalfEscClk; /*!< TCLK-PREPARE in clk_esc/2. Set how long
152 to drive the LP-00 state before HS transmissions,
153 available values are 2, 3. */
154 uint8_t tHsZero_ByteClk; /*!< THS-ZERO in clk_byte. Set how long that controller
155 drives data lane HS-0 state before transmit
156 the Sync sequence. Available values are 6, 7, ..., 37. */
157 uint8_t tClkZero_ByteClk; /*!< TCLK-ZERO in clk_byte. Set how long that controller
158 drives clock lane HS-0 state before transmit
159 the Sync sequence. Available values are 3, 4, ..., 66. */
160 uint8_t tHsTrail_ByteClk; /*!< THS-TRAIL + 4*UI in clk_byte. Set the time
161 of the flipped differential state after last payload
162 data bit of HS transmission burst. Available values
163 are 0, 1, ..., 15. */
164 uint8_t tClkTrail_ByteClk; /*!< TCLK-TRAIL + 4*UI in clk_byte. Set the time
165 of the flipped differential state after last payload
166 data bit of HS transmission burst. Available values
167 are 0, 1, ..., 15. */
168 } dsi_dphy_config_t;
169
170 /*! @brief _dsi_apb_status Status of APB to packet interface. */
171 enum
172 {
173 kDSI_ApbNotIdle = (1U << 0U), /*!< State machine not idle */
174 kDSI_ApbTxDone = (1U << 1U), /*!< Tx packet done */
175 kDSI_ApbRxControl = (1U << 2U), /*!< DPHY direction 0 - tx had control, 1 - rx has control */
176 kDSI_ApbTxOverflow = (1U << 3U), /*!< TX fifo overflow */
177 kDSI_ApbTxUnderflow = (1U << 4U), /*!< TX fifo underflow */
178 kDSI_ApbRxOverflow = (1U << 5U), /*!< RX fifo overflow */
179 kDSI_ApbRxUnderflow = (1U << 6U), /*!< RX fifo underflow */
180 kDSI_ApbRxHeaderReceived = (1U << 7U), /*!< RX packet header has been received */
181 kDSI_ApbRxPacketReceived = (1U << 8U), /*!< All RX packet payload data has been received */
182 };
183
184 /*! @brief _dsi_rx_error_status Host receive error status. */
185 enum
186 {
187 kDSI_RxErrorEccOneBit = (1U << 0U), /*!< ECC single bit error detected. */
188 kDSI_RxErrorEccMultiBit = (1U << 1U), /*!< ECC multi bit error detected. */
189 kDSI_RxErrorCrc = (1U << 7U), /*!< CRC error detected. */
190 kDSI_RxErrorHtxTo = (1U << 8U), /*!< High Speed forward TX timeout detected. */
191 kDSI_RxErrorLrxTo = (1U << 9U), /*!< Reverse Low power data receive timeout detected. */
192 kDSI_RxErrorBtaTo = (1U << 10U) /*!< BTA timeout detected. */
193 };
194
195 /*! @brief DSI host controller status (status_out) */
196 enum _dsi_host_status
197 {
198 kDSI_HostSoTError = (1U << 0U), /*!< SoT error from peripheral error report. */
199 kDSI_HostSoTSyncError = (1U << 1U), /*!< SoT Sync error from peripheral error report. */
200 kDSI_HostEoTSyncError = (1U << 2U), /*!< EoT Sync error from peripheral error report. */
201 kDSI_HostEscEntryCmdError = (1U << 3U), /*!< Escape Mode Entry Command Error from peripheral error report. */
202 kDSI_HostLpTxSyncError = (1U << 4U), /*!< Low-power transmit Sync Error from peripheral error report. */
203 kDSI_HostPeriphToError = (1U << 5U), /*!< Peripheral timeout error from peripheral error report. */
204 kDSI_HostFalseControlError = (1U << 6U), /*!< False control error from peripheral error report. */
205 kDSI_HostContentionDetected = (1U << 7U), /*!< Contention detected from peripheral error report. */
206 kDSI_HostEccErrorOneBit = (1U << 8U), /*!< Single bit ECC error (corrected) from peripheral error report. */
207 kDSI_HostEccErrorMultiBit = (1U << 9U), /*!< Multi bit ECC error (not corrected) from peripheral error report. */
208 kDSI_HostChecksumError = (1U << 10U), /*!< Checksum error from peripheral error report. */
209 kDSI_HostInvalidDataType = (1U << 11U), /*!< DSI data type not recognized. */
210 kDSI_HostInvalidVcId = (1U << 12U), /*!< DSI VC ID invalid. */
211 kDSI_HostInvalidTxLength = (1U << 13U), /*!< Invalid transmission length. */
212 kDSI_HostProtocalViolation = (1U << 15U), /*!< DSI protocal violation. */
213 kDSI_HostResetTriggerReceived = (1U << 16U), /*!< Reset trigger received. */
214 kDSI_HostTearTriggerReceived = (1U << 17U), /*!< Tear effect trigger receive. */
215 kDSI_HostAckTriggerReceived = (1U << 18U), /*!< Acknowledge trigger message received. */
216 };
217
218 /*! @brief _dsi_interrupt DSI interrupt. */
219 enum
220 {
221 kDSI_InterruptGroup1ApbNotIdle = (1U << 0U), /*!< State machine not idle */
222 kDSI_InterruptGroup1ApbTxDone = (1U << 1U), /*!< Tx packet done */
223 kDSI_InterruptGroup1ApbRxControl = (1U << 2U), /*!< DPHY direction 0 - tx control, 1 - rx control */
224 kDSI_InterruptGroup1ApbTxOverflow = (1U << 3U), /*!< TX fifo overflow */
225 kDSI_InterruptGroup1ApbTxUnderflow = (1U << 4U), /*!< TX fifo underflow */
226 kDSI_InterruptGroup1ApbRxOverflow = (1U << 5U), /*!< RX fifo overflow */
227 kDSI_InterruptGroup1ApbRxUnderflow = (1U << 6U), /*!< RX fifo underflow */
228 kDSI_InterruptGroup1ApbRxHeaderReceived = (1U << 7U), /*!< RX packet header has been received */
229 kDSI_InterruptGroup1ApbRxPacketReceived = (1U << 8U), /*!< All RX packet payload data has been received */
230 kDSI_InterruptGroup1SoTError = (1U << 9U), /*!< SoT error from peripheral error report. */
231 kDSI_InterruptGroup1SoTSyncError = (1U << 10U), /*!< SoT Sync error from peripheral error report. */
232 kDSI_InterruptGroup1EoTSyncError = (1U << 11U), /*!< EoT Sync error from peripheral error report. */
233 kDSI_InterruptGroup1EscEntryCmdError = (1U << 12U), /*!< Escape Mode Entry Command Error
234 from peripheral error report. */
235 kDSI_InterruptGroup1LpTxSyncError = (1U << 13U), /*!< Low-power transmit Sync Error from
236 peripheral error report. */
237 kDSI_InterruptGroup1PeriphToError = (1U << 14U), /*!< Peripheral timeout error from
238 peripheral error report. */
239 kDSI_InterruptGroup1FalseControlError = (1U << 15U), /*!< False control error from peripheral error report. */
240 kDSI_InterruptGroup1ContentionDetected = (1U << 16U), /*!< Contention detected from peripheral error report. */
241 kDSI_InterruptGroup1EccErrorOneBit = (1U << 17U), /*!< Single bit ECC error (corrected) from
242 peripheral error report. */
243 kDSI_InterruptGroup1EccErrorMultiBit = (1U << 18U), /*!< Multi bit ECC error (not corrected) from
244 peripheral error report. */
245 kDSI_InterruptGroup1ChecksumError = (1U << 19U), /*!< Checksum error from peripheral error report. */
246 kDSI_InterruptGroup1InvalidDataType = (1U << 20U), /*!< DSI data type not recognized. */
247 kDSI_InterruptGroup1InvalidVcId = (1U << 21U), /*!< DSI VC ID invalid. */
248 kDSI_InterruptGroup1InvalidTxLength = (1U << 22U), /*!< Invalid transmission length. */
249 kDSI_InterruptGroup1ProtocalViolation = (1U << 24U), /*!< DSI protocal violation. */
250 kDSI_InterruptGroup1ResetTriggerReceived = (1U << 25U), /*!< Reset trigger received. */
251 kDSI_InterruptGroup1TearTriggerReceived = (1U << 26U), /*!< Tear effect trigger receive. */
252 kDSI_InterruptGroup1AckTriggerReceived = (1U << 27U), /*!< Acknowledge trigger message received. */
253 kDSI_InterruptGroup1HtxTo = (1U << 29U), /*!< High speed TX timeout. */
254 kDSI_InterruptGroup1LrxTo = (1U << 30U), /*!< Low power RX timeout. */
255 kDSI_InterruptGroup1BtaTo = (1U << 31U), /*!< Host BTA timeout. */
256 kDSI_InterruptGroup2EccOneBit = (1U << 0U), /*!< Sinle bit ECC error. */
257 kDSI_InterruptGroup2EccMultiBit = (1U << 1U), /*!< Multi bit ECC error. */
258 kDSI_InterruptGroup2CrcError = (1U << 2U), /*!< CRC error. */
259 };
260
261 /*! @brief DSI TX data type. */
262 typedef enum _dsi_tx_data_type
263 {
264 kDSI_TxDataVsyncStart = 0x01U, /*!< V Sync start. */
265 kDSI_TxDataVsyncEnd = 0x11U, /*!< V Sync end. */
266 kDSI_TxDataHsyncStart = 0x21U, /*!< H Sync start. */
267 kDSI_TxDataHsyncEnd = 0x31U, /*!< H Sync end. */
268 kDSI_TxDataEoTp = 0x08U, /*!< End of transmission packet. */
269 kDSI_TxDataCmOff = 0x02U, /*!< Color mode off. */
270 kDSI_TxDataCmOn = 0x12U, /*!< Color mode on. */
271 kDSI_TxDataShutDownPeriph = 0x22U, /*!< Shut down peripheral. */
272 kDSI_TxDataTurnOnPeriph = 0x32U, /*!< Turn on peripheral. */
273 kDSI_TxDataGenShortWrNoParam = 0x03U, /*!< Generic Short WRITE, no parameters. */
274 kDSI_TxDataGenShortWrOneParam = 0x13U, /*!< Generic Short WRITE, one parameter. */
275 kDSI_TxDataGenShortWrTwoParam = 0x23U, /*!< Generic Short WRITE, two parameter. */
276 kDSI_TxDataGenShortRdNoParam = 0x04U, /*!< Generic Short READ, no parameters. */
277 kDSI_TxDataGenShortRdOneParam = 0x14U, /*!< Generic Short READ, one parameter. */
278 kDSI_TxDataGenShortRdTwoParam = 0x24U, /*!< Generic Short READ, two parameter. */
279 kDSI_TxDataDcsShortWrNoParam = 0x05U, /*!< DCS Short WRITE, no parameters. */
280 kDSI_TxDataDcsShortWrOneParam = 0x15U, /*!< DCS Short WRITE, one parameter. */
281 kDSI_TxDataDcsShortRdNoParam = 0x06U, /*!< DCS Short READ, no parameters. */
282 kDSI_TxDataSetMaxReturnPktSize = 0x37U, /*!< Set the Maximum Return Packet Size. */
283
284 kDSI_TxDataNull = 0x09U, /*!< Null Packet, no data. */
285 kDSI_TxDataBlanking = 0x19U, /*!< Blanking Packet, no data. */
286 kDSI_TxDataGenLongWr = 0x29U, /*!< Generic long write. */
287 kDSI_TxDataDcsLongWr = 0x39U, /*!< DCS Long Write/write_LUT Command Packet. */
288 kDSI_TxDataLooselyPackedPixel20BitYCbCr = 0x0CU, /*!< Loosely Packed Pixel Stream, 20-bit YCbCr, 4:2:2 Format. */
289 kDSI_TxDataPackedPixel24BitYCbCr = 0x1CU, /*!< Packed Pixel Stream, 24-bit YCbCr, 4:2:2 Format. */
290 kDSI_TxDataPackedPixel16BitYCbCr = 0x2CU, /*!< Packed Pixel Stream, 16-bit YCbCr, 4:2:2 Format. */
291 kDSI_TxDataPackedPixel30BitRGB = 0x0DU, /*!< Packed Pixel Stream, 30-bit RGB, 10-10-10 Format. */
292 kDSI_TxDataPackedPixel36BitRGB = 0x1DU, /*!< Packed Pixel Stream, 36-bit RGB, 12-12-12 Format. */
293 kDSI_TxDataPackedPixel12BitYCrCb = 0x3DU, /*!< Packed Pixel Stream, 12-bit YCbCr, 4:2:0 Format. */
294 kDSI_TxDataPackedPixel16BitRGB = 0x0EU, /*!< Packed Pixel Stream, 16-bit RGB, 5-6-5 Format. */
295 kDSI_TxDataPackedPixel18BitRGB = 0x1EU, /*!< Packed Pixel Stream, 18-bit RGB, 6-6-6 Format. */
296 kDSI_TxDataLooselyPackedPixel18BitRGB = 0x2EU, /*!< Loosely Packed Pixel Stream, 18-bit RGB, 6-6-6 Format. */
297 kDSI_TxDataPackedPixel24BitRGB = 0x3EU, /*!< Packed Pixel Stream, 24-bit RGB, 8-8-8 Format. */
298 } dsi_tx_data_type_t;
299
300 /*! @brief DSI RX data type. */
301 typedef enum _dsi_rx_data_type
302 {
303 kDSI_RxDataAckAndErrorReport = 0x02U, /*!< Acknowledge and Error Report */
304 kDSI_RxDataEoTp = 0x08U, /*!< End of Transmission packet. */
305 kDSI_RxDataGenShortRdResponseOneByte = 0x11U, /*!< Generic Short READ Response, 1 byte returned. */
306 kDSI_RxDataGenShortRdResponseTwoByte = 0x12U, /*!< Generic Short READ Response, 2 byte returned. */
307 kDSI_RxDataGenLongRdResponse = 0x1AU, /*!< Generic Long READ Response. */
308 kDSI_RxDataDcsLongRdResponse = 0x1CU, /*!< DCS Long READ Response. */
309 kDSI_RxDataDcsShortRdResponseOneByte = 0x21U, /*!< DCS Short READ Response, 1 byte returned. */
310 kDSI_RxDataDcsShortRdResponseTwoByte = 0x22U, /*!< DCS Short READ Response, 2 byte returned. */
311 } dsi_rx_data_type_t;
312
313 /*! @brief _dsi_transfer_flags DSI transfer control flags. */
314 enum
315 {
316 kDSI_TransferUseHighSpeed = (1U << 0U), /*!< Use high speed mode or not. */
317 kDSI_TransferPerformBTA = (1U << 1U), /*!< Perform BTA or not. */
318 };
319
320 /*! @brief Structure for the data transfer. */
321 typedef struct _dsi_transfer
322 {
323 uint8_t virtualChannel; /*!< Virtual channel. */
324 dsi_tx_data_type_t txDataType; /*!< TX data type. */
325 uint8_t flags; /*!< Flags to control the transfer, see _dsi_transfer_flags. */
326 const uint8_t *txData; /*!< The TX data buffer. */
327 uint8_t *rxData; /*!< The TX data buffer. */
328 uint16_t txDataSize; /*!< Size of the TX data. */
329 uint16_t rxDataSize; /*!< Size of the RX data. */
330 bool sendDscCmd; /*!< If set to true, the DSC command is specified by @ref dscCmd, otherwise
331 the DSC command is included in the @ref txData. */
332 uint8_t dscCmd; /*!< The DSC command to send, only valid when @ref sendDscCmd is true. */
333 } dsi_transfer_t;
334
335 /*! @brief MIPI DSI transfer handle. */
336 typedef struct _dsi_handle dsi_handle_t;
337
338 /*!
339 * @brief MIPI DSI callback for finished transfer.
340 *
341 * When transfer finished, one of these status values will be passed to the user:
342 * - @ref kStatus_Success Data transfer finished with no error.
343 * - @ref kStatus_Timeout Transfer failed because of timeout.
344 * - @ref kStatus_DSI_RxDataError RX data error, user could use @ref DSI_GetRxErrorStatus
345 * to check the error details.
346 * - @ref kStatus_DSI_ErrorReportReceived Error Report packet received, user could use
347 * @ref DSI_GetAndClearHostStatus to check the error report status.
348 * - @ref kStatus_Fail Transfer failed for other reasons.
349 */
350 typedef void (*dsi_callback_t)(const MIPI_DSI_Type *base, dsi_handle_t *handle, status_t status, void *userData);
351
352 /*! @brief MIPI DSI transfer handle structure */
353 struct _dsi_handle
354 {
355 volatile bool isBusy; /*!< MIPI DSI is busy with APB data transfer. */
356 dsi_transfer_t xfer; /*!< Transfer information. */
357 dsi_callback_t callback; /*!< DSI callback */
358 void *userData; /*!< Callback parameter */
359 const MIPI_DSI_Type *dsi; /*!< Pointer to MIPI DSI peripheral. */
360 };
361
362 /*******************************************************************************
363 * API
364 ******************************************************************************/
365
366 #if defined(__cplusplus)
367 extern "C" {
368 #endif
369
370 /*!
371 * @name MIPI_DSI host initialization.
372 * @{
373 */
374
375 /*!
376 * @brief Initializes an MIPI DSI host with the user configuration.
377 *
378 * This function initializes the MIPI DSI host with the configuration, it should
379 * be called first before other MIPI DSI driver functions.
380 *
381 * @param base MIPI DSI host peripheral base address.
382 * @param config Pointer to a user-defined configuration structure.
383 */
384 void DSI_Init(const MIPI_DSI_Type *base, const dsi_config_t *config);
385
386 /*!
387 * @brief Deinitializes an MIPI DSI host.
388 *
389 * This function should be called after all bother MIPI DSI driver functions.
390 *
391 * @param base MIPI DSI host peripheral base address.
392 */
393 void DSI_Deinit(const MIPI_DSI_Type *base);
394
395 /*!
396 * @brief Get the default configuration to initialize the MIPI DSI host.
397 *
398 * The default value is:
399 * @code
400 config->numLanes = 4;
401 config->enableNonContinuousHsClk = false;
402 config->enableTxUlps = false;
403 config->autoInsertEoTp = true;
404 config->numExtraEoTp = 0;
405 config->htxTo_ByteClk = 0;
406 config->lrxHostTo_ByteClk = 0;
407 config->btaTo_ByteClk = 0;
408 @endcode
409 *
410 * @param config Pointer to a user-defined configuration structure.
411 */
412 void DSI_GetDefaultConfig(dsi_config_t *config);
413
414 /*! @} */
415
416 /*!
417 * @name DPI interface
418 * @{
419 */
420
421 /*!
422 * @brief Configure the DPI interface core.
423 *
424 * This function sets the DPI interface configuration, it should be used in
425 * video mode.
426 *
427 * @param base MIPI DSI host peripheral base address.
428 * @param config Pointer to the DPI interface configuration.
429 * @param numLanes Lane number, should be same with the setting in @ref dsi_dpi_config_t.
430 * @param dpiPixelClkFreq_Hz The DPI pixel clock frequency in Hz.
431 * @param dsiHsBitClkFreq_Hz The DSI high speed bit clock frequency in Hz. It is
432 * the same with DPHY PLL output.
433 */
434 void DSI_SetDpiConfig(const MIPI_DSI_Type *base,
435 const dsi_dpi_config_t *config,
436 uint8_t numLanes,
437 uint32_t dpiPixelClkFreq_Hz,
438 uint32_t dsiHsBitClkFreq_Hz);
439
440 /*! @} */
441
442 /*!
443 * @name D-PHY configuration.
444 * @{
445 */
446
447 /*!
448 * @brief Initializes the D-PHY
449 *
450 * This function configures the D-PHY timing and setups the D-PHY PLL based on
451 * user configuration. The configuration structure could be got by the function
452 * @ref DSI_GetDphyDefaultConfig.
453 *
454 * For some platforms there is not dedicated D-PHY PLL, indicated by the macro
455 * FSL_FEATURE_MIPI_DSI_NO_DPHY_PLL. For these platforms, the @p refClkFreq_Hz
456 * is useless.
457 *
458 * @param base MIPI DSI host peripheral base address.
459 * @param config Pointer to the D-PHY configuration.
460 * @param refClkFreq_Hz The REFCLK frequency in Hz.
461 * @return The actual D-PHY PLL output frequency. If could not configure the
462 * PLL to the target frequency, the return value is 0.
463 */
464 uint32_t DSI_InitDphy(const MIPI_DSI_Type *base, const dsi_dphy_config_t *config, uint32_t refClkFreq_Hz);
465
466 /*!
467 * @brief Deinitializes the D-PHY
468 *
469 * Power down the D-PHY PLL and shut down D-PHY.
470 *
471 * @param base MIPI DSI host peripheral base address.
472 */
473 void DSI_DeinitDphy(const MIPI_DSI_Type *base);
474
475 /*!
476 * @brief Get the default D-PHY configuration.
477 *
478 * Gets the default D-PHY configuration, the timing parameters are set according
479 * to D-PHY specification. User could use the configuration directly, or change
480 * some parameters according to the special device.
481 *
482 * @param config Pointer to the D-PHY configuration.
483 * @param txHsBitClk_Hz High speed bit clock in Hz.
484 * @param txEscClk_Hz Esc clock in Hz.
485 */
486 void DSI_GetDphyDefaultConfig(dsi_dphy_config_t *config, uint32_t txHsBitClk_Hz, uint32_t txEscClk_Hz);
487
488 /*! @} */
489
490 /*!
491 * @name Interrupts
492 * @{
493 */
494
495 /*!
496 * @brief Enable the interrupts.
497 *
498 * The interrupts to enable are passed in as OR'ed mask value of _dsi_interrupt.
499 *
500 * @param base MIPI DSI host peripheral base address.
501 * @param intGroup1 Interrupts to enable in group 1.
502 * @param intGroup2 Interrupts to enable in group 2.
503 */
DSI_EnableInterrupts(const MIPI_DSI_Type * base,uint32_t intGroup1,uint32_t intGroup2)504 static inline void DSI_EnableInterrupts(const MIPI_DSI_Type *base, uint32_t intGroup1, uint32_t intGroup2)
505 {
506 base->apb->IRQ_MASK &= ~intGroup1;
507 base->apb->IRQ_MASK2 &= ~intGroup2;
508 }
509
510 /*!
511 * @brief Disable the interrupts.
512 *
513 * The interrupts to disable are passed in as OR'ed mask value of _dsi_interrupt.
514 *
515 * @param base MIPI DSI host peripheral base address.
516 * @param intGroup1 Interrupts to disable in group 1.
517 * @param intGroup2 Interrupts to disable in group 2.
518 */
DSI_DisableInterrupts(const MIPI_DSI_Type * base,uint32_t intGroup1,uint32_t intGroup2)519 static inline void DSI_DisableInterrupts(const MIPI_DSI_Type *base, uint32_t intGroup1, uint32_t intGroup2)
520 {
521 base->apb->IRQ_MASK |= intGroup1;
522 base->apb->IRQ_MASK2 |= intGroup2;
523 }
524
525 /*!
526 * @brief Get and clear the interrupt status.
527 *
528 * @param base MIPI DSI host peripheral base address.
529 * @param intGroup1 Group 1 interrupt status.
530 * @param intGroup2 Group 2 interrupt status.
531 */
DSI_GetAndClearInterruptStatus(const MIPI_DSI_Type * base,uint32_t * intGroup1,uint32_t * intGroup2)532 static inline void DSI_GetAndClearInterruptStatus(const MIPI_DSI_Type *base, uint32_t *intGroup1, uint32_t *intGroup2)
533 {
534 *intGroup2 = base->apb->IRQ_STATUS2;
535 *intGroup1 = base->apb->IRQ_STATUS;
536 }
537
538 /*! @} */
539
540 /*!
541 * @name MIPI DSI APB
542 * @{
543 */
544
545 /*!
546 * @brief Configure the APB packet to send.
547 *
548 * This function configures the next APB packet transfer. After configuration,
549 * the packet transfer could be started with function @ref DSI_SendApbPacket.
550 * If the packet is long packet, Use @ref DSI_WriteApbTxPayload to fill the payload
551 * before start transfer.
552 *
553 * @param base MIPI DSI host peripheral base address.
554 * @param wordCount For long packet, this is the byte count of the payload.
555 * For short packet, this is (data1 << 8) | data0.
556 * @param virtualChannel Virtual channel.
557 * @param dataType The packet data type, (DI).
558 * @param flags The transfer control flags, see _dsi_transfer_flags.
559 */
560 void DSI_SetApbPacketControl(
561 const MIPI_DSI_Type *base, uint16_t wordCount, uint8_t virtualChannel, dsi_tx_data_type_t dataType, uint8_t flags);
562
563 /*!
564 * @brief Fill the long APB packet payload.
565 *
566 * Write the long packet payload to TX FIFO.
567 *
568 * @param base MIPI DSI host peripheral base address.
569 * @param payload Pointer to the payload.
570 * @param payloadSize Payload size in byte.
571 */
572 void DSI_WriteApbTxPayload(const MIPI_DSI_Type *base, const uint8_t *payload, uint16_t payloadSize);
573
574 /*!
575 * @brief Extended function to fill the payload to TX FIFO.
576 *
577 * Write the long packet payload to TX FIFO. This function could be used in two ways
578 *
579 * 1. Include the DSC command in parameter @p payload. In this case, the DSC command
580 * is the first byte of @p payload. The parameter @p sendDscCmd is set to false,
581 * the @p dscCmd is not used. This function is the same as @ref DSI_WriteApbTxPayload
582 * when used in this way.
583 *
584 * 2. The DSC command in not in parameter @p payload, but specified by parameter @p dscCmd.
585 * In this case, the parameter @p sendDscCmd is set to true, the @p dscCmd is the DSC
586 * command to send. The @p payload is sent after @p dscCmd.
587 *
588 * @param base MIPI DSI host peripheral base address.
589 * @param payload Pointer to the payload.
590 * @param payloadSize Payload size in byte.
591 * @param sendDscCmd If set to true, the DSC command is specified by @p dscCmd,
592 * otherwise the DSC command is included in the @p payload.
593 * @param dscCmd The DSC command to send, only used when @p sendDscCmd is true.
594 */
595 void DSI_WriteApbTxPayloadExt(
596 const MIPI_DSI_Type *base, const uint8_t *payload, uint16_t payloadSize, bool sendDscCmd, uint8_t dscCmd);
597
598 /*!
599 * @brief Read the long APB packet payload.
600 *
601 * Read the long packet payload from RX FIFO. This function reads directly but
602 * does not check the RX FIFO status. Upper layer should make sure there are
603 * available data.
604 *
605 * @param base MIPI DSI host peripheral base address.
606 * @param payload Pointer to the payload.
607 * @param payloadSize Payload size in byte.
608 */
609 void DSI_ReadApbRxPayload(const MIPI_DSI_Type *base, uint8_t *payload, uint16_t payloadSize);
610
611 /*!
612 * @brief Trigger the controller to send out APB packet.
613 *
614 * Send the packet set by @ref DSI_SetApbPacketControl.
615 *
616 * @param base MIPI DSI host peripheral base address.
617 */
DSI_SendApbPacket(const MIPI_DSI_Type * base)618 static inline void DSI_SendApbPacket(const MIPI_DSI_Type *base)
619 {
620 base->apb->SEND_PACKET = 0x1U;
621 }
622
623 /*!
624 * @brief Get the APB status.
625 *
626 * The return value is OR'ed value of _dsi_apb_status.
627 *
628 * @param base MIPI DSI host peripheral base address.
629 * @return The APB status.
630 */
DSI_GetApbStatus(const MIPI_DSI_Type * base)631 static inline uint32_t DSI_GetApbStatus(const MIPI_DSI_Type *base)
632 {
633 return base->apb->PKT_STATUS;
634 }
635
636 /*!
637 * @brief Get the error status during data transfer.
638 *
639 * The return value is OR'ed value of _dsi_rx_error_status.
640 *
641 * @param base MIPI DSI host peripheral base address.
642 * @return The error status.
643 */
DSI_GetRxErrorStatus(const MIPI_DSI_Type * base)644 static inline uint32_t DSI_GetRxErrorStatus(const MIPI_DSI_Type *base)
645 {
646 return base->host->RX_ERROR_STATUS;
647 }
648
649 /*!
650 * @brief Get the one-bit RX ECC error position.
651 *
652 * When one-bit ECC RX error detected using @ref DSI_GetRxErrorStatus, this
653 * function could be used to get the error bit position.
654 *
655 * @code
656 uint8_t eccErrorPos;
657 uint32_t rxErrorStatus = DSI_GetRxErrorStatus(MIPI_DSI);
658 if (kDSI_RxErrorEccOneBit & rxErrorStatus)
659 {
660 eccErrorPos = DSI_GetEccRxErrorPosition(rxErrorStatus);
661 }
662 @endcode
663 *
664 * @param rxErrorStatus The error status returned by @ref DSI_GetRxErrorStatus.
665 * @return The 1-bit ECC error position.
666 */
DSI_GetEccRxErrorPosition(uint32_t rxErrorStatus)667 static inline uint8_t DSI_GetEccRxErrorPosition(uint32_t rxErrorStatus)
668 {
669 return (uint8_t)((rxErrorStatus >> 2U) & 0x1FU);
670 }
671
672 /*!
673 * @brief Get and clear the DSI host status.
674 *
675 * The host status are returned as mask value of @ref _dsi_host_status.
676 *
677 * @param base MIPI DSI host peripheral base address.
678 * @return The DSI host status.
679 */
DSI_GetAndClearHostStatus(const MIPI_DSI_Type * base)680 static inline uint32_t DSI_GetAndClearHostStatus(const MIPI_DSI_Type *base)
681 {
682 return base->host->CFG_STATUS_OUT;
683 }
684
685 /*!
686 * @brief Get the RX packet header.
687 *
688 * @param base MIPI DSI host peripheral base address.
689 * @return The RX packet header.
690 */
DSI_GetRxPacketHeader(const MIPI_DSI_Type * base)691 static inline uint32_t DSI_GetRxPacketHeader(const MIPI_DSI_Type *base)
692 {
693 return base->apb->PKT_RX_PKT_HEADER;
694 }
695
696 /*!
697 * @brief Extract the RX packet type from the packet header.
698 *
699 * Extract the RX packet type from the packet header get by @ref DSI_GetRxPacketHeader.
700 *
701 * @param rxPktHeader The RX packet header get by @ref DSI_GetRxPacketHeader.
702 * @return The RX packet type.
703 */
DSI_GetRxPacketType(uint32_t rxPktHeader)704 static inline dsi_rx_data_type_t DSI_GetRxPacketType(uint32_t rxPktHeader)
705 {
706 return (dsi_rx_data_type_t)(uint8_t)((rxPktHeader >> 16U) & 0x3FU);
707 }
708
709 /*!
710 * @brief Extract the RX packet word count from the packet header.
711 *
712 * Extract the RX packet word count from the packet header get by @ref DSI_GetRxPacketHeader.
713 *
714 * @param rxPktHeader The RX packet header get by @ref DSI_GetRxPacketHeader.
715 * @return For long packet, return the payload word count (byte). For short packet,
716 * return the (data0 << 8) | data1.
717 */
DSI_GetRxPacketWordCount(uint32_t rxPktHeader)718 static inline uint16_t DSI_GetRxPacketWordCount(uint32_t rxPktHeader)
719 {
720 return (uint16_t)(rxPktHeader & 0xFFFFU);
721 }
722
723 /*!
724 * @brief Extract the RX packet virtual channel from the packet header.
725 *
726 * Extract the RX packet virtual channel from the packet header get by @ref DSI_GetRxPacketHeader.
727 *
728 * @param rxPktHeader The RX packet header get by @ref DSI_GetRxPacketHeader.
729 * @return The virtual channel.
730 */
DSI_GetRxPacketVirtualChannel(uint32_t rxPktHeader)731 static inline uint8_t DSI_GetRxPacketVirtualChannel(uint32_t rxPktHeader)
732 {
733 return (uint8_t)((rxPktHeader >> 22U) & 0x3U);
734 }
735
736 /*!
737 * @brief APB data transfer using blocking method.
738 *
739 * Perform APB data transfer using blocking method. This function waits until all
740 * data send or received, or timeout happens.
741 *
742 * @param base MIPI DSI host peripheral base address.
743 * @param xfer Pointer to the transfer structure.
744 * @retval kStatus_Success Data transfer finished with no error.
745 * @retval kStatus_Timeout Transfer failed because of timeout.
746 * @retval kStatus_DSI_RxDataError RX data error, user could use @ref DSI_GetRxErrorStatus
747 * to check the error details.
748 * @retval kStatus_DSI_ErrorReportReceived Error Report packet received, user could use
749 * @ref DSI_GetAndClearHostStatus to check the error report status.
750 * @retval kStatus_DSI_NotSupported Transfer format not supported.
751 * @retval kStatus_DSI_Fail Transfer failed for other reasons.
752 */
753 status_t DSI_TransferBlocking(const MIPI_DSI_Type *base, dsi_transfer_t *xfer);
754
755 /*! @} */
756
757 /*!
758 * @name Transactional
759 * @{
760 */
761
762 /*!
763 * @brief Create the MIPI DSI handle.
764 *
765 * This function initializes the MIPI DSI handle which can be used for other transactional APIs.
766 *
767 * @param base MIPI DSI host peripheral base address.
768 * @param handle Handle pointer.
769 * @param callback Callback function.
770 * @param userData User data.
771 */
772 status_t DSI_TransferCreateHandle(const MIPI_DSI_Type *base,
773 dsi_handle_t *handle,
774 dsi_callback_t callback,
775 void *userData);
776
777 /*!
778 * @brief APB data transfer using interrupt method.
779 *
780 * Perform APB data transfer using interrupt method, when transfer finished,
781 * upper layer could be informed through callback function.
782 *
783 * @param base MIPI DSI host peripheral base address.
784 * @param handle pointer to dsi_handle_t structure which stores the transfer state.
785 * @param xfer Pointer to the transfer structure.
786 *
787 * @retval kStatus_Success Data transfer started successfully.
788 * @retval kStatus_DSI_Busy Failed to start transfer because DSI is busy with pervious transfer.
789 * @retval kStatus_DSI_NotSupported Transfer format not supported.
790 */
791 status_t DSI_TransferNonBlocking(const MIPI_DSI_Type *base, dsi_handle_t *handle, dsi_transfer_t *xfer);
792
793 /*!
794 * @brief Abort current APB data transfer.
795 *
796 * @param base MIPI DSI host peripheral base address.
797 * @param handle pointer to dsi_handle_t structure which stores the transfer state.
798 */
799 void DSI_TransferAbort(const MIPI_DSI_Type *base, dsi_handle_t *handle);
800
801 /*!
802 * @brief Interrupt handler for the DSI.
803 *
804 * @param base MIPI DSI host peripheral base address.
805 * @param handle pointer to dsi_handle_t structure which stores the transfer state.
806 */
807 void DSI_TransferHandleIRQ(const MIPI_DSI_Type *base, dsi_handle_t *handle);
808
809 /*! @} */
810
811 #if defined(__cplusplus)
812 }
813 #endif
814
815 /*! @} */
816
817 #endif /* _FSL_MIPI_DSI_H_ */
818