1 /*
2 * Copyright 2021-2024 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #ifndef FSL_LCDIC_H_
9 #define FSL_LCDIC_H_
10
11 #include "fsl_common.h"
12
13 /*!
14 * @addtogroup lcdic
15 * @{
16 */
17
18 /*******************************************************************************
19 * Definitions
20 ******************************************************************************/
21
22 /*! @name Driver version */
23 /*! @{ */
24 #define FSL_LCDIC_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
25 /*! @} */
26
27 /*! @brief Delay used in LCDIC_ResetState
28 *
29 * This should be larger than 5 * core clock / LCDIC function clock.
30 */
31 #ifndef LCDIC_RESET_STATE_DELAY
32 #define LCDIC_RESET_STATE_DELAY 130u
33 #endif
34
35 /* Max data send or receive in one TRX. */
36 #define LCDIC_MAX_BYTE_PER_TRX (1UL << 18U)
37
38 /*! @brief LCDIC mode. */
39 typedef enum _lcdic_mode
40 {
41 kLCDIC_3WireSPI = 0U, /*!< 3-wire SPI mode. */
42 kLCDIC_4WireSPI = LCDIC_CTRL_SPI_MD_MASK, /*!< 4-wire SPI mode. */
43 kLCDIC_I8080 = LCDIC_CTRL_LCDIC_MD_MASK, /*!< I8080 mode. */
44 } lcdic_mode_t;
45
46 /*! @brief LCDIC byte order data endian. */
47 typedef enum _lcdic_endian
48 {
49 kLCDIC_BigEndian = 0U, /*!< Big endian. */
50 kLCDIC_LittleEndian, /*!< Little endian.*/
51 } lcdic_endian_t;
52
53 /*! @brief LCDIC RX FIFO threshold.
54 *
55 * RX threshold interrupt happens if the occupied word number in RX FIFO is
56 * bigger than the threshold value.
57 */
58 typedef enum _lcdic_rx_threshold
59 {
60 kLCDIC_RxThreshold0Word = 0U, /*!< 0 word. */
61 kLCDIC_RxThreshold1Word, /*!< 1 word. */
62 } lcdic_rx_threshold_t;
63
64 /*! @brief LCDIC TX FIFO threshold.
65 *
66 * TX threshold interrupt happens if the empty word number in TX FIFO is
67 * bigger than the threshold value.
68 */
69 typedef enum _lcdic_tx_threshold
70 {
71 kLCDIC_TxThreshold0Word = 0U, /*!< 0 word. */
72 kLCDIC_TxThreshold1Word, /*!< 1 word. */
73 kLCDIC_TxThreshold2Word, /*!< 2 word. */
74 kLCDIC_TxThreshold3Word, /*!< 3 word. */
75 kLCDIC_TxThreshold4Word, /*!< 4 word. */
76 kLCDIC_TxThreshold5Word, /*!< 5 word. */
77 kLCDIC_TxThreshold6Word, /*!< 6 word. */
78 kLCDIC_TxThreshold7Word, /*!< 7 word. */
79 } lcdic_tx_threshold_t;
80
81 /*! @brief LCDIC reset signal polarity. */
82 typedef enum _lcdic_reset_polarity
83 {
84 kLCDIC_ResetActiveLow = 0U, /*!< Active low. */
85 kLCDIC_ResetActiveHigh, /*!< Active high. */
86 } lcdic_reset_polarity_t;
87
88 /*! @brief LCDIC I8080 control flags.
89 * @anchor _lcdic_i8080_ctrl_flags
90 */
91 enum
92 {
93 kLCDIC_I8080_CsActiveLow = 0U, /*!< CS active low. */
94 kLCDIC_I8080_CsActiveHigh = LCDIC_I8080_CTRL0_CS_POL_MASK, /*!< CS active high. */
95 kLCDIC_I8080_DcCmdLow = 0U, /*!< DC 0 means command, while 1 means data. */
96 kLCDIC_I8080_DcCmdHigh = LCDIC_I8080_CTRL0_DC_POL_MASK, /*!< DC 1 means command, while 0 means data. */
97 kLCDIC_I8080_RdActiveLow = 0U, /*!< RD active low. */
98 kLCDIC_I8080_RdActiveHigh = LCDIC_I8080_CTRL0_RD_POL_MASK, /*!< RD active high. */
99 kLCDIC_I8080_WrActiveLow = 0U, /*!< WR active low. */
100 kLCDIC_I8080_WrActiveHigh = LCDIC_I8080_CTRL0_WR_POL_MASK, /*!< WR active high. */
101 kLCDIC_I8080_CsEnableIdleOff = LCDIC_I8080_CTRL0_EN_IDLE_OFF_MASK, /*!< CS off while no transmission. */
102 kLCDIC_I8080_CsEnableDcSwitchOff = LCDIC_I8080_CTRL0_EN_DC_OFF_MASK, /*!< CS off while DC switches. */
103 };
104
105 /*! @brief LCDIC SPI mode control flags.
106 * @anchor _lcdic_spi_ctrl_flags
107 */
108 enum
109 {
110 kLCDIC_SPI_MsbFirst = 0U, /*!< MSB(bit 7) sent and received first. */
111 kLCDIC_SPI_LsbFirst = LCDIC_SPI_CTRL_SDAT_ENDIAN_MASK, /*!< LSB(bit 0) sent and received first. */
112 kLCDIC_SPI_ClkActiveHigh = 0U, /*!< CPOL=0. Clock active-high (idle low) */
113 kLCDIC_SPI_ClkActiveLow = LCDIC_SPI_CTRL_CPOL_MASK, /*!< CPOL=1. Clock active-low (idle high) */
114 kLCDIC_SPI_ClkPhaseFirstEdge = 0U, /*!< CPHA=0. Data sample at first clock edge. */
115 kLCDIC_SPI_ClkPhaseSecondEdge = LCDIC_SPI_CTRL_CPHA_MASK, /*!< CPHA=1. Data sample at second clock edge. */
116 kLCDIC_SPI_DcCmdLow = 0U, /*!< DC 0 means command, while 1 means data. */
117 kLCDIC_SPI_DcCmdHigh = LCDIC_SPI_CTRL_DC_POL_MASK, /*!< DC 1 means command, while 0 means data. */
118 };
119
120 /*! @brief LCDIC configuration. */
121 typedef struct _lcdic_config
122 {
123 lcdic_mode_t mode; /*!< LCDIC work mode. */
124 lcdic_endian_t endian; /*!< Data endian. */
125 lcdic_rx_threshold_t rxThreshold; /*!< RX FIFO threshold. */
126 lcdic_tx_threshold_t txThreshold; /*!< TX FIFO threshold. */
127
128 uint8_t timerRatio0; /*!< Valid range: 0~15. freq(timer0) = freq(lcdic_clk) / (2 ^ timerRatio0). */
129 uint8_t timerRatio1; /*!< Valid range: 0~15. freq(timer1) = freq(timer0) / (2 ^ timerRatio1). */
130
131 /* Reset signal. */
132 uint8_t resetPulseWidth_Timer0; /*!< Reset pulse width, in the unit of timer0 period. Valid range 1 ~ 64. */
133 uint8_t resetSequence; /*!< Reset sequence, it is a 8-bit value sent to reset pin from LSB. */
134 uint8_t resetSequencePulseNum; /*!< Reset sequence pulse number, valid range is 1 ~ 8. */
135 lcdic_reset_polarity_t resetPolarity; /*!< Reset signal polarity. */
136
137 /* I8080 */
138 uint8_t i8080CtrlFlags; /*!< I8080 control flags, it is OR'ed value of @ref _lcdic_i8080_ctrl_flags. */
139 uint8_t csWaitTime; /*!< Minimum CS inactive pulse width. T(csw)=T(lcdic_clk)*csWaitTime, valid range 0-7. */
140 uint8_t csSetupTime; /*!< Minimum CS setup time before WR/RD. T(css)=T(lcdic_clk)*csSetupTime, valid range 0-255. */
141 uint8_t csHoldTime; /*!< Minimum CS hold time after WR/RD. T(csh)=T(lcdic_clk)*csHoldTime, valid range 0-7. */
142 uint8_t
143 dcSetupTime; /*!< Minimum DC setup time before WR/RD/CS. T(dcs)=T(lcdic_clk)*dsSetupTime, valid range 0-7. */
144 uint8_t dcHoldTime; /*!< Minimum DC hold time after WR/RD/CS. T(dch)=T(lcdic_clk)*dsHoldTime, valid range 0-7. */
145 uint8_t writeDataSetupTime; /*!< Minimum write data setup time after WR active.
146 T(wdh)=T(lcdic_clk)*writeDataSetupTime, valid range 0-7. */
147 uint8_t writeDataHoldTime; /*!< Minimum write data setup time before WR active.
148 T(wds)=T(lcdic_clk)*writeDataHoldTime, valid range 0-7. */
149 uint8_t writeEnableActiveWidth; /*!< Minmum write enable active pulse width.
150 T(waw)=T(lcdic_clk)*writeEnableActiveWidth, valid range 0-63. */
151 uint8_t writeEnableInactiveWidth; /*!< Minmum write enable inactive pulse width.
152 T(wiw)=T(lcdic_clk)*writeEnableInactiveWidth, valid range 0-63. */
153 uint8_t readEnableActiveWidth; /*!< Minmum read enable active pulse width.
154 T(raw)=T(lcdic_clk)*readEnableActiveWidth, valid range 0-255. */
155 uint8_t readEnableInactiveWidth; /*!< Minmum read enable inactive pulse width.
156 T(riw)=T(lcdic_clk)*readEnableInactiveWidth, valid range 0-255. */
157
158 /* SPI */
159 uint8_t spiCtrlFlags; /*!< SPI control flags, it is OR'ed value of @ref _lcdic_spi_ctrl_flags. */
160
161 /* TE. */
162 uint8_t teTimeoutTime_Timer1; /*!< Tearing effect timeout time. T(te_to)=T(timer1)*teTimeoutTime_Timer1. */
163 uint8_t teSyncWaitTime_Timer1; /*!< Tearing effect signal synchronization wait time.
164 T(tew)=T(timer1)*teSyncWaitTime_Timer1. */
165
166 /* Command. */
167 uint8_t cmdShortTimeout_Timer0; /*!< Command short timeout. T(cmd_short_to)=T(timer0)*cmdShortTimeout_Timer0. */
168 uint8_t cmdLongTimeout_Timer1; /*!< Command long timeout. T(cmd_long_to)=T(timer1)*cmdLongTimeout_Timer1. */
169 } lcdic_config_t;
170
171 /*! @brief LCDIC interrupts. */
172 enum _lcdic_interrupt
173 {
174 kLCDIC_ResetDoneInterrupt = LCDIC_ISR_RST_DONE_INTR_MASK, /*< Reset done interrupt. */
175 kLCDIC_CmdDoneInterrupt = LCDIC_ISR_CMD_DONE_INTR_MASK, /*< TRX command done interrupt. */
176 kLCDIC_CmdTimeoutInterrupt = LCDIC_ISR_CMD_TO_INTR_MASK, /*< TRX command timeout interrupt. */
177 kLCDIC_TeTimeoutInterrupt = LCDIC_ISR_TE_TO_INTR_MASK, /*< TE timeout interrupt. */
178 kLCDIC_TxOverflowInterrupt = LCDIC_ISR_TFIFO_OVERFLOW_INTR_MASK, /*< TX FIFO overflow interrupt. */
179 kLCDIC_TxThresholdInterrupt = LCDIC_ISR_TFIFO_THRES_INTR_MASK, /*< TX FIFO threshold interrupt. */
180 kLCDIC_RxUnderflowInterrupt = LCDIC_ISR_RFIFO_UNDERFLOW_INTR_MASK, /*< RX FIFO underflow interrupt. */
181 kLCDIC_RxThresholdInterrupt = LCDIC_ISR_RFIFO_THRES_INTR_MASK, /*< RX FIFO threshold interrupt. */
182 kLCDIC_AllInterrupt = kLCDIC_ResetDoneInterrupt | kLCDIC_CmdDoneInterrupt | kLCDIC_CmdTimeoutInterrupt |
183 kLCDIC_TeTimeoutInterrupt | kLCDIC_TxOverflowInterrupt | kLCDIC_TxThresholdInterrupt |
184 kLCDIC_RxUnderflowInterrupt | kLCDIC_RxThresholdInterrupt, /*!< All interrupts. */
185 };
186
187 /*! @brief LCDIC status flags.
188 * @anchor _lcdic_flags
189 */
190 enum
191 {
192 kLCDIC_IdleFlag = LCDIC_STATUS0_LCDIC_IDLE_MASK, /*< LCDIC is idle. */
193 kLCDIC_TxThresholdFlag = LCDIC_STATUS0_TFIFO_THRES_MASK, /*< TX FIFO threshold reach. */
194 kLCDIC_TxFullFlag = LCDIC_STATUS0_TFIFO_FULL_MASK, /*< TX FIFO full. */
195 kLCDIC_RxThresholdFlag = LCDIC_STATUS0_RFIFO_THRES_MASK, /*< RX FIFO threshold reach. */
196 kLCDIC_RxEmptyFlag = LCDIC_STATUS0_RFIFO_EMPTY_MASK, /*< RX FIFO empty. */
197 kLCDIC_AllFlag = kLCDIC_IdleFlag | kLCDIC_TxThresholdFlag | kLCDIC_TxFullFlag | kLCDIC_RxThresholdFlag |
198 kLCDIC_RxEmptyFlag, /*!< All flags. */
199 };
200
201 /*! @brief LCDIC TE sync mode
202 * @anchor _lcdic_te_sync_mode
203 */
204 enum
205 {
206 kLCDIC_TeNoSync = 0, /*!< Don't need to sync. */
207 kLCDIC_TeRisingEdgeSync, /*!< Sync to TE rising edge. */
208 kLCDIC_TeFallingEdgeSync, /*!< Sync to TE falling edge. */
209 };
210
211 /*! @brief LCDIC TRX command timeout mode
212 * @anchor _lcdic_trx_timeout_mode
213 */
214 enum
215 {
216 kLCDIC_ShortTimeout = 0, /*!< Using short timeout. */
217 kLCDIC_LongTimeout, /*!< Using long timeout. */
218 };
219
220 /*! @brief LCDIC data format
221 * @anchor _lcdic_data_format
222 */
223 enum
224 {
225 kLCDIC_DataFormatByte = 0, /*!< Byte. */
226 kLCDIC_DataFormatHalfWord, /*!< Half word (2-byte). */
227 kLCDIC_DataFormatWord, /*!< Word (4-byte). */
228 };
229
230 /*! @brief LCDIC data or command
231 * @anchor _lcdic_dc
232 */
233 enum
234 {
235 kLCDIC_Command = 0, /*!< Command. */
236 kLCDIC_Data, /*!< Data. */
237 };
238
239 /*! @brief LCDIC TX or RX
240 * @anchor _lcdic_trx
241 */
242 enum
243 {
244 kLCDIC_RX = 0, /*!< RX */
245 kLCDIC_TX, /*!< TX. */
246 };
247
248 /*! @brief LCDIC TRX command */
249 typedef union _lcdic_trx_cmd
250 {
251 struct
252 {
253 uint32_t dataLen : 18; /*!< Data length in bytes, transfered byte is dataLen + 1. */
254 uint32_t dummyCount : 3; /*!< Dummy cycle count between TX and RX (for SPI only). */
255 uint32_t : 2;
256 uint32_t useAutoRepeat : 1; /*!< Use auto repeat mode or not. */
257 uint32_t teSyncMode : 2; /*!< TE sync mode, see @ref _lcdic_te_sync_mode. */
258 uint32_t trxTimeoutMode : 1; /*!< TRX command timeout mode, see @ref _lcdic_trx_timeout_mode. */
259 uint32_t dataFormat : 2; /*!< Data format, see @ref _lcdic_data_format. */
260 uint32_t enableCmdDoneInt : 1; /*!< Enable command done interrupt or not. */
261 uint32_t cmdOrData : 1; /*!< Command or data, see @ref _lcdic_dc. */
262 uint32_t trx : 1; /*!< TX or TX, see @ref _lcdic_trx. */
263 } bits;
264 uint32_t u32;
265 } lcdic_trx_cmd_t;
266
267 /*! @brief LCDIC repeat data TX transfer structure. */
268 typedef struct _lcdic_repeat_tx_xfer
269 {
270 uint8_t cmd; /*!< Command. */
271 uint8_t teSyncMode; /*!< TE sync mode, see @ref _lcdic_te_sync_mode. */
272 uint8_t trxTimeoutMode; /*!< TRX command timeout mode, see @ref _lcdic_trx_timeout_mode. */
273 uint8_t dataFormat; /*!< Data format, see @ref _lcdic_data_format. */
274 uint32_t dataLen; /*!< Data length. */
275 uint32_t txRepeatData; /*!< The repeat data. */
276 } lcdic_repeat_tx_xfer_t;
277
278 /*! @brief LCDIC data array TX transfer structure. */
279 typedef struct _lcdic_tx_xfer
280 {
281 uint8_t cmd; /*!< Command. */
282 uint8_t teSyncMode; /*!< TE sync mode, see @ref _lcdic_te_sync_mode. */
283 uint8_t trxTimeoutMode; /*!< TRX command timeout mode, see @ref _lcdic_trx_timeout_mode. */
284 uint8_t dataFormat; /*!< Data format, see @ref _lcdic_data_format. */
285 uint32_t dataLen; /*!< Data length. */
286 const uint8_t *txData; /*!< The data to send. */
287 } lcdic_tx_xfer_t;
288
289 /*! @brief LCDIC data array RX transfer structure. */
290 typedef struct _lcdic_rx_xfer
291 {
292 uint8_t cmd; /*!< Command. */
293 uint8_t dummyCount; /*!< Dummy cycle between TX and RX, only used for SPI mode. */
294 uint8_t trxTimeoutMode; /*!< TRX command timeout mode, see @ref _lcdic_trx_timeout_mode. */
295 uint8_t dataFormat; /*!< Data format, see @ref _lcdic_data_format. */
296 uint32_t dataLen; /*!< Data length. */
297 uint8_t *rxData; /*!< Pointer to the data receive array. */
298 } lcdic_rx_xfer_t;
299
300 /*! @brief LCDIC transfer mode. */
301 typedef enum
302 {
303 kLCDIC_XferCmdOnly = 0, /*!< Only send command. */
304 kLCDIC_XferSendRepeatData, /*!< Send repeat data. */
305 kLCDIC_XferSendDataArray, /*!< Send data array. */
306 kLCDIC_XferReceiveDataArray, /*!< Receive data array. */
307 } lcdic_xfer_mode_t;
308
309 /*! @brief LCDIC transfer structure. */
310 typedef struct _lcdic_xfer
311 {
312 lcdic_xfer_mode_t mode; /*!< Transfer mode. */
313
314 union
315 {
316 uint8_t cmdToSendOnly; /*!< Command to send in mode @ref kLCDIC_XferCmdOnly. */
317 lcdic_repeat_tx_xfer_t repeatTxXfer; /*!< For mode @ref kLCDIC_XferSendRepeatData. */
318 lcdic_tx_xfer_t txXfer; /*!< For mode @ref kLCDIC_XferSendDataArray. */
319 lcdic_rx_xfer_t rxXfer; /*!< For mode @ref kLCDIC_XferReceiveDataArray. */
320 };
321 } lcdic_xfer_t;
322
323 /* Forward declaration of the handle typedef. */
324 typedef struct _lcdic_handle lcdic_handle_t;
325
326 /*!
327 * @brief LCDIC transfer callback function.
328 *
329 * The status is @ref kStatus_Success when transfer finished successfully, it is
330 * @ref kStatus_Timeout when timeout happened.
331 */
332 typedef void (*lcdic_transfer_callback_t)(LCDIC_Type *base, lcdic_handle_t *handle, status_t status, void *userData);
333
334 /*! @brief LCDIC handle structure. */
335 struct _lcdic_handle
336 {
337 volatile bool xferInProgress; /*!< Transfer in progress. */
338 lcdic_xfer_mode_t xferMode; /*!< On-going transfer mode. */
339 lcdic_transfer_callback_t callback; /*!< Callback function. */
340 void *userData; /*!< LCDIC callback function parameter.*/
341 union
342 {
343 const uint8_t *txData; /*!< Data array to send. */
344 uint8_t *rxData; /*!< RX data array. */
345 };
346 uint32_t xferSizeWordAligned; /*!< 4-byte aligned part of the transfer size. */
347 uint8_t xferSizeWordUnaligned; /*!< 4-byte unaligned part of the transfer size. */
348 uint32_t tmpData; /*!< Temp data for driver internal use. */
349 };
350
351 /*! @brief Typedef for transactional APIs IRQ handler. */
352 typedef void (*lcdic_transfer_irq_handler_t)(LCDIC_Type *base, void *handle);
353
354 /*! @brief Typedef for reset sequence sent done callback. */
355 typedef void (*lcdic_reset_done_callback_t)(LCDIC_Type *base);
356
357 /*******************************************************************************
358 * API
359 ******************************************************************************/
360
361 #if defined(__cplusplus)
362 extern "C" {
363 #endif
364
365 /*!
366 * @name Initialization and deinitialization
367 * @{
368 */
369
370 /*!
371 * @brief Initialize the LCDIC.
372 *
373 * This function initializes the LCDIC to work, it configues the LCDIC
374 * according to the configue structure and enables the module. After
375 * calling this function, the peripheral is ready to work.
376 *
377 * @param base LCDIC peripheral base address.
378 * @retval kStatus_Success Initialize successfully.
379 */
380 status_t LCDIC_Init(LCDIC_Type *base, const lcdic_config_t *config);
381
382 /*!
383 * @brief De-initialize the LCDIC.
384 *
385 * This function disables the LCDIC, and disables peripheral clock if necessary.
386 *
387 * @param base LCDIC peripheral base address.
388 */
389 void LCDIC_Deinit(LCDIC_Type *base);
390
391 /*!
392 * @brief Get the default configuration for to initialize the LCDIC.
393 *
394 * The default configuration value is:
395 *
396 * @code
397 config->mode = kLCDIC_3WireSPI;
398 config->endian = kLCDIC_BigEndian;
399 config->rxThreshold = kLCDIC_RxThreshold0Word;
400 config->txThreshold = kLCDIC_TxThreshold3Word;
401
402 config->timerRatio0 = 8;
403 config->timerRatio1 = 9;
404
405 config->resetPulseWidth_Timer0 = 20;
406 config->resetSequence = 0;
407 config->resetSequencePulseNum = 1;
408 config->resetPolarity = kLCDIC_ResetActiveLow;
409
410 config->i8080CtrlFlags = kLCDIC_I8080_CsActiveLow | kLCDIC_I8080_DcCmdLow | kLCDIC_I8080_RdActiveLow |
411 kLCDIC_I8080_WrActiveLow | kLCDIC_I8080_CsEnableIdleOff;
412
413 config->csWaitTime = 2;
414 config->csSetupTime = 2;
415 config->csHoldTime = 2;
416 config->dcSetupTime = 2;
417 config->dcHoldTime = 2;
418 config->writeDataSetupTime = 2;
419 config->writeDataHoldTime = 2;
420 config->writeEnableActiveWidth = 6;
421 config->writeEnableInactiveWidth = 6;
422 config->readEnableActiveWidth = 15;
423 config->readEnableInactiveWidth = 15;
424
425 config->spiCtrlFlags =
426 kLCDIC_SPI_MsbFirst | kLCDIC_SPI_ClkActiveHigh | kLCDIC_SPI_ClkPhaseFirstEdge | kLCDIC_SPI_DcCmdLow;
427
428 config->teTimeoutTime_Timer1 = 16;
429 config->teSyncWaitTime_Timer1 = 0;
430
431 config->cmdShortTimeout_Timer0 = 1;
432 config->cmdLongTimeout_Timer1 = 16;
433
434 @endcode
435 *
436 * @param config Pointer to the LCDIC configuration.
437 */
438 void LCDIC_GetDefaultConfig(lcdic_config_t *config);
439
440 /*!
441 * @brief Reset the LCDIC.
442 *
443 * This function resets the LCDIC state. After calling this function,
444 * all data in TX_FIFO and RX_FIFO will be cleared and all transactions
445 * on LCD interface will restart despite of formal status.
446 *
447 * The configurations will not be reset.
448 *
449 * @param base LCDIC peripheral base address.
450 */
451 void LCDIC_ResetState(LCDIC_Type *base);
452
453 /*! @} */
454
455 /*!
456 * @name Interrupts
457 * @{
458 */
459
460 /*!
461 * @brief Enables LCDIC interrupts.
462 *
463 * @param base LCDIC peripheral base address.
464 * @param interrupts The interrupts to enable, pass in as OR'ed value of @ref _lcdic_interrupt.
465 */
LCDIC_EnableInterrupts(LCDIC_Type * base,uint32_t interrupts)466 static inline void LCDIC_EnableInterrupts(LCDIC_Type *base, uint32_t interrupts)
467 {
468 base->IMR &= ~interrupts;
469 }
470
471 /*!
472 * @brief Disable LCDIC interrupts.
473 *
474 * @param base LCDIC peripheral base address.
475 * @param interrupts The interrupts to disable, pass in as OR'ed value of @ref _lcdic_interrupt.
476 */
LCDIC_DisableInterrupts(LCDIC_Type * base,uint32_t interrupts)477 static inline void LCDIC_DisableInterrupts(LCDIC_Type *base, uint32_t interrupts)
478 {
479 base->IMR |= interrupts;
480 }
481
482 /*!
483 * @brief Get LCDIC interrupt pending status.
484 *
485 * @param base LCDIC peripheral base address.
486 * @return The interrupt pending status.
487 *
488 * @note The interrupt must be enabled, otherwise the interrupt flags will not assert.
489 */
LCDIC_GetInterruptStatus(LCDIC_Type * base)490 static inline uint32_t LCDIC_GetInterruptStatus(LCDIC_Type *base)
491 {
492 return base->ISR;
493 }
494
495 /*!
496 * @brief Get LCDIC raw interrupt status.
497 *
498 * This function gets the raw interrupt pending flags, it is not affected by
499 * interrupt enabled status.
500 *
501 * @param base LCDIC peripheral base address.
502 * @return The raw interrupt status.
503 */
LCDIC_GetInterruptRawStatus(LCDIC_Type * base)504 static inline uint32_t LCDIC_GetInterruptRawStatus(LCDIC_Type *base)
505 {
506 return base->IRSR;
507 }
508
509 /*!
510 * @brief Clear LCDIC interrupt status.
511 *
512 * @param base LCDIC peripheral base address.
513 * @param interrupts The interrupt status to clear , pass in as OR'ed value of @ref _lcdic_interrupt.
514 */
LCDIC_ClearInterruptStatus(LCDIC_Type * base,uint32_t interrupts)515 static inline void LCDIC_ClearInterruptStatus(LCDIC_Type *base, uint32_t interrupts)
516 {
517 base->ICR = interrupts;
518 }
519
520 /*!
521 * @brief Get LCDIC status flags.
522 *
523 * @note The interval between two times calling this function shall be larger
524 * than one LCDIC function clock.
525 *
526 * @param base LCDIC peripheral base address.
527 * @return The status flags, it is OR'ed value of _lcdic_flags.
528 */
LCDIC_GetStatusFlags(LCDIC_Type * base)529 static inline uint32_t LCDIC_GetStatusFlags(LCDIC_Type *base)
530 {
531 return base->STATUS0 & (uint32_t)kLCDIC_AllFlag;
532 }
533
534 /*!
535 * @brief Get current on-going LCDIC TRX-CMD.
536 *
537 * @note The interval between two times calling this function shall be larger
538 * than one LCDIC function clock.
539 *
540 * @param base LCDIC peripheral base address.
541 * @return The TRX-CMD on-going.
542 */
LCDIC_GetProcessingTrxCmd(LCDIC_Type * base)543 static inline uint32_t LCDIC_GetProcessingTrxCmd(LCDIC_Type *base)
544 {
545 return base->STATUS1;
546 }
547 /*! @} */
548
549 /*!
550 * @name FIFO
551 * @{
552 */
553
554 /*!
555 * @brief Set TX FIFO threshold.
556 *
557 * @param base LCDIC peripheral base address.
558 * @param threshold TX threshold.
559 */
LCDIC_SetTxThreshold(LCDIC_Type * base,lcdic_tx_threshold_t threshold)560 static inline void LCDIC_SetTxThreshold(LCDIC_Type *base, lcdic_tx_threshold_t threshold)
561 {
562 base->FIFO_CTRL = (base->FIFO_CTRL & ~LCDIC_FIFO_CTRL_TFIFO_THRES_MASK) | LCDIC_FIFO_CTRL_TFIFO_THRES(threshold);
563 }
564
565 /*!
566 * @brief Set RX FIFO threshold.
567 *
568 * @param base LCDIC peripheral base address.
569 * @param threshold RX threshold.
570 */
LCDIC_SetRxThreshold(LCDIC_Type * base,lcdic_rx_threshold_t threshold)571 static inline void LCDIC_SetRxThreshold(LCDIC_Type *base, lcdic_rx_threshold_t threshold)
572 {
573 base->FIFO_CTRL = (base->FIFO_CTRL & ~LCDIC_FIFO_CTRL_RFIFO_THRES_MASK) | LCDIC_FIFO_CTRL_RFIFO_THRES(threshold);
574 }
575
576 /*!
577 * @brief Write the TX FIFO using blocking way.
578 *
579 * This function waits for empty slot in TX FIFO and fill the data to TX FIFO.
580 *
581 * @param base LCDIC peripheral base address.
582 * @param data Data to send, the data length must be dividable by 4.
583 * @param dataLen_Word Data length in word.
584 * @retval kStatus_Success Write successfully.
585 * @retval kStatus_Timeout Timeout happened.
586 */
587 status_t LCDIC_WriteTxFifoBlocking(LCDIC_Type *base, const uint32_t *data, uint32_t dataLen_Word);
588
589 /*!
590 * @brief Read the RX FIFO using blocking way.
591 *
592 * This function waits for valid data in RX FIFO and read them.
593 *
594 * @param base LCDIC peripheral base address.
595 * @param data Array for received data, the data length must be dividable by 4.
596 * @param dataLen_Word Data length in word.
597 * @retval kStatus_Success Read successfully.
598 * @retval kStatus_Timeout Timeout happened.
599 */
600 status_t LCDIC_ReadRxFifoBlocking(LCDIC_Type *base, uint32_t *data, uint32_t dataLen_Word);
601
602 /*! @} */
603
604 /*!
605 * @name Misc Operations
606 * @{
607 */
608
609 /*!
610 * @brief Send reset sequence to the reset pin.
611 *
612 * The function sends reset to reset pin, to reset the external panel.
613 * The reset sequence parameters are configued by @ref lcdic_config_t.
614 *
615 * @param base LCDIC peripheral base address.
616 */
LCDIC_SendResetSequence(LCDIC_Type * base)617 static inline void LCDIC_SendResetSequence(LCDIC_Type *base)
618 {
619 base->RST_CTRL |= LCDIC_RST_CTRL_RST_START_MASK;
620 }
621
622 /*!
623 * @brief Set the callback called when reset sequence sent done.
624 *
625 * @param callback The callback to set.
626 */
627 void LCDIC_SetResetSequenceDoneCallback(lcdic_reset_done_callback_t callback);
628
629 /*!
630 * @brief Enable or disable to trigger DMA.
631 *
632 * @param base LCDIC peripheral base address.
633 * @param enable Use true to enable, false to disable.
634 */
LCDIC_EnableDMA(LCDIC_Type * base,bool enable)635 static inline void LCDIC_EnableDMA(LCDIC_Type *base, bool enable)
636 {
637 if (enable)
638 {
639 base->CTRL |= LCDIC_CTRL_DMA_EN_MASK;
640 }
641 else
642 {
643 base->CTRL &= ~LCDIC_CTRL_DMA_EN_MASK;
644 }
645 }
646
647 /*! @} */
648
649 /*!
650 * @name Blocking transfer
651 * @{
652 */
653
654 /*!
655 * @brief Send command using blocking way.
656 *
657 * This function sends out command and waits until send finished.
658 *
659 * @param base LCDIC peripheral base address.
660 * @param cmd Command to send.
661 * @retval kStatus_Success Command sent successfully.
662 */
663 status_t LCDIC_SendCommandBlocking(LCDIC_Type *base, uint8_t cmd);
664
665 /*!
666 * @brief Send repeat data using blocking way.
667 *
668 * This function sends out command and the repeat data, then waits until
669 * send finished or timeout happened.
670 *
671 * @param base LCDIC peripheral base address.
672 * @param xfer Pointer to the transfer configuration.
673 * @retval kStatus_Success Sent successfully.
674 * @retval kStatus_Timeout Timeout happened.
675 * @retval kStatus_InvalidArgument Invalid argument.
676 */
677 status_t LCDIC_SendRepeatDataBlocking(LCDIC_Type *base, const lcdic_repeat_tx_xfer_t *xfer);
678
679 /*!
680 * @brief Send data array using blocking way.
681 *
682 * This function sends out command and the data array, then waits until
683 * send finished or timeout happened.
684 *
685 * @param base LCDIC peripheral base address.
686 * @param xfer Pointer to the transfer configuration.
687 * @retval kStatus_Success Sent successfully.
688 * @retval kStatus_Timeout Timeout happened.
689 * @retval kStatus_InvalidArgument Invalid argument.
690 */
691 status_t LCDIC_SendDataArrayBlocking(LCDIC_Type *base, const lcdic_tx_xfer_t *xfer);
692
693 /*!
694 * @brief Read data array using blocking way.
695 *
696 * This function sends out command and read the data array, then waits until
697 * send finished or timeout happened.
698 *
699 * @param base LCDIC peripheral base address.
700 * @param xfer Pointer to the transfer configuration.
701 * @retval kStatus_Success Sent successfully.
702 * @retval kStatus_Timeout Timeout happened.
703 * @retval kStatus_InvalidArgument Invalid argument.
704 */
705 status_t LCDIC_ReadDataArrayBlocking(LCDIC_Type *base, const lcdic_rx_xfer_t *xfer);
706
707 /*!
708 * @brief LCDIC data transfer using blocking way.
709 *
710 * This function sends command only, or sends repeat data, or sends data array,
711 * or reads data array based on the transfer structure. It uses blocking way,
712 * only returns when transfer successed or failed.
713 *
714 * @param base LCDIC peripheral base address.
715 * @param xfer Pointer to the transfer configuration.
716 * @retval kStatus_Success Sent successfully.
717 * @retval kStatus_Timeout Timeout happened.
718 * @retval kStatus_InvalidArgument Invalid argument.
719 */
720 status_t LCDC_TransferBlocking(LCDIC_Type *base, const lcdic_xfer_t *xfer);
721
722 /*! @} */
723
724 /*!
725 * @name Transactional APIs
726 * @{
727 */
728
729 /*!
730 * @brief Initializes the LCDIC driver handle, which is used in transactional
731 * functions.
732 *
733 * @param base LCDIC peripheral base address.
734 * @param handle Pointer to the lcdic_handle_t structure to store the transfer state.
735 * @param callback The callback function.
736 * @param userData The parameter of the callback function.
737 * @retval kStatus_Success Successfully created the handle.
738 */
739 status_t LCDIC_TransferCreateHandle(LCDIC_Type *base,
740 lcdic_handle_t *handle,
741 lcdic_transfer_callback_t callback,
742 void *userData);
743
744 /*!
745 * @brief Transfer data using IRQ.
746 *
747 * This function transfer data using IRQ. This is a non-blocking function, which
748 * returns right away. When all data is sent out/received, or timeout happened,
749 * the callback function is called.
750 *
751 * @param base LCDIC peripheral base address.
752 * @param handle Pointer to the lcdic_handle_t structure to store the transfer state.
753 * @param xfer LCDIC transfer structure.
754 * @retval kStatus_Success Successfully start a transfer.
755 * @retval kStatus_InvalidArgument Input argument is invalid.
756 * @retval kStatus_Busy LCDIC driver is busy with another transfer.
757 */
758 status_t LCDIC_TransferNonBlocking(LCDIC_Type *base, lcdic_handle_t *handle, lcdic_xfer_t *xfer);
759
760 /*!
761 * @brief Send command using interrupt-driven way.
762 *
763 * @param base LCDIC peripheral base address.
764 * @param handle Pointer to the lcdic_handle_t structure to store the transfer state.
765 * @param cmd Command to send.
766 * @retval kStatus_Success Command sent successfully.
767 * @retval kStatus_Busy LCDIC driver is busy with another transfer.
768 */
769 status_t LCDIC_SendCommandNonBlocking(LCDIC_Type *base, lcdic_handle_t *handle, uint8_t cmd);
770
771 /*!
772 * @brief Send repeat data using interrupt-driven way.
773 *
774 * @param base LCDIC peripheral base address.
775 * @param handle Pointer to the lcdic_handle_t structure to store the transfer state.
776 * @param xfer LCDIC transfer structure.
777 * @retval kStatus_Success Successfully start a transfer.
778 * @retval kStatus_InvalidArgument Input argument is invalid.
779 * @retval kStatus_Busy LCDIC driver is busy with another transfer.
780 */
781 status_t LCDIC_SendRepeatDataNonBlocking(LCDIC_Type *base, lcdic_handle_t *handle, const lcdic_repeat_tx_xfer_t *xfer);
782
783 /*!
784 * @brief Send data array using interrupt-driven way.
785 *
786 * @param base LCDIC peripheral base address.
787 * @param handle Pointer to the lcdic_handle_t structure to store the transfer state.
788 * @param xfer LCDIC transfer structure.
789 * @retval kStatus_Success Successfully start a transfer.
790 * @retval kStatus_InvalidArgument Input argument is invalid.
791 * @retval kStatus_Busy LCDIC driver is busy with another transfer.
792 */
793 status_t LCDIC_SendDataArrayNonBlocking(LCDIC_Type *base, lcdic_handle_t *handle, const lcdic_tx_xfer_t *xfer);
794
795 /*!
796 * @brief Read data array using interrupt-driven way.
797 *
798 * @param base LCDIC peripheral base address.
799 * @param handle Pointer to the lcdic_handle_t structure to store the transfer state.
800 * @param xfer LCDIC transfer structure.
801 * @retval kStatus_Success Successfully start a transfer.
802 * @retval kStatus_InvalidArgument Input argument is invalid.
803 * @retval kStatus_Busy LCDIC driver is busy with another transfer.
804 */
805 status_t LCDIC_ReadDataArrayNonBlocking(LCDIC_Type *base, lcdic_handle_t *handle, const lcdic_rx_xfer_t *xfer);
806
807 /*!
808 * @brief LCDIC IRQ handler function.
809 *
810 * IRQ handler to work with @ref LCDIC_TransferNonBlocking.
811 *
812 * @param base LCDIC peripheral base address.
813 * @param handle Pointer to the lcdic_handle_t structure to store the transfer state.
814 */
815 void LCDIC_TransferHandleIRQ(LCDIC_Type *base, void *handle);
816
817 /*!
818 * @brief Install the IRQ handler.
819 *
820 * Install IRQ handler for specific instance.
821 *
822 * @param instance LCDIC instance.
823 * @param handle Driver handle, it will be used as IRQ handler parameter.
824 * @param handler IRQ handler to instance.
825 */
826 void LCDIC_TransferInstallIRQHandler(uint32_t instance, void *handle, lcdic_transfer_irq_handler_t handler);
827
828 /*! @} */
829
830 /*!
831 * @name Helper functions
832 * @{
833 */
834
835 /*!
836 * @brief Get the instance from the base address
837 *
838 * @param base LCDIC peripheral base address
839 * @return The LCDIC module instance
840 */
841 uint32_t LCDIC_GetInstance(LCDIC_Type *base);
842
843 /*!
844 * @brief Get IRQn for specific instance.
845 *
846 * @param instance LCDIC instance.
847 * @return The LCDIC IRQn.
848 */
849 IRQn_Type LCDIC_GetIRQn(uint32_t instance);
850
851 /*!
852 * @brief Get data from byte array, and fill to 4-byte word.
853 *
854 * LCDIC data registers only accept 4-byte data, but the user passed data might
855 * be not 4-byte size aligned. This function is used to construct the unaligned
856 * part to a word, to write to LCDIC register.
857 *
858 * @param bytes The byte array.
859 * @param len Length of the byte array.
860 * @return The construct word.
861 */
862 uint32_t LCDIC_FillByteToWord(const uint8_t *bytes, uint8_t len);
863
864 /*!
865 * @brief Get data from 4-byte, and fill to byte array.
866 *
867 * LCDIC data registers only accept 4-byte data, but the user passed data might
868 * be not 4-byte size aligned. This function is used to get desired bytes from
869 * the word read from LCDIC register, and save to the user data array.
870 *
871 * @param word Word data read from LCDIC register.
872 * @param bytes The byte array.
873 * @param len Length of the byte array.
874 */
875 void LCDIC_ExtractByteFromWord(uint32_t word, uint8_t *bytes, uint8_t len);
876
877 /*!
878 * @brief Prepare the command sending.
879 *
880 * Fill the TRX command and command to TX FIFO, after calling this function, user
881 * should wait for transfer done by checking status or IRQ.
882 *
883 * @param base LCDIC peripheral base address.
884 * @param cmd Command to send.
885 * @retval kStatus_Success Operation successed.
886 */
887 status_t LCDIC_PrepareSendCommand(LCDIC_Type *base, uint8_t cmd);
888
889 /*!
890 * @brief Prepare the repeat data sending.
891 *
892 * Fill the required data to TX FIFO, after calling this function, user
893 * should wait for transfer done by checking status or IRQ.
894 *
895 * @param base LCDIC peripheral base address.
896 * @param xfer Transfer structure.
897 * @retval kStatus_Success Operation successed.
898 * @retval kStatus_InvalidArgument Invalid argument.
899 */
900 status_t LCDIC_PrepareSendRepeatData(LCDIC_Type *base, const lcdic_repeat_tx_xfer_t *xfer);
901
902 /*!
903 * @brief Prepare sending data array.
904 *
905 * Fill the required command data to TX FIFO, after calling this function, user
906 * should fill the xfer->txData to TX FIFO based on FIFO status.
907 *
908 * @param base LCDIC peripheral base address.
909 * @param xfer Transfer structure.
910 * @param xferSizeWordAligned The word size aligned part of the transfer data.
911 * @param xferSizeWordUnaligned The word size unaligned part of the transfer data.
912 * @param wordUnalignedData Word to save the word size unaligned data, it should
913 * be sent after all word size aligned data write finished.
914 * @retval kStatus_Success Operation successed.
915 * @retval kStatus_InvalidArgument Invalid argument.
916 */
917 status_t LCDIC_PrepareSendDataArray(LCDIC_Type *base,
918 const lcdic_tx_xfer_t *xfer,
919 uint32_t *xferSizeWordAligned,
920 uint8_t *xferSizeWordUnaligned,
921 uint32_t *wordUnalignedData);
922
923 /*!
924 * @brief Prepare reading data array.
925 *
926 * Fill the required command data to TX FIFO, after calling this function, user
927 * should read RX FIFO to xfer->rxData based on FIFO status.
928 *
929 * @param base LCDIC peripheral base address.
930 * @param xfer Transfer structure.
931 * @param xferSizeWordAligned The word size aligned part of the transfer data.
932 * @param xferSizeWordUnaligned The word size unaligned part of the transfer data.
933 * @retval kStatus_Success Operation successed.
934 * @retval kStatus_InvalidArgument Invalid argument.
935 */
936 status_t LCDIC_PrepareReadDataArray(LCDIC_Type *base,
937 const lcdic_rx_xfer_t *xfer,
938 uint32_t *xferSizeWordAligned,
939 uint8_t *xferSizeWordUnaligned);
940
941 /*! @} */
942
943 #if defined(__cplusplus)
944 }
945 #endif
946
947 /*! @}*/
948
949 #endif /* FSL_LCDIC_H_ */
950