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