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