diff --git a/arch/arm/src/imxrt/imxrt_lpspi.c b/arch/arm/src/imxrt/imxrt_lpspi.c index b33cee894f6..8c8838662a4 100644 --- a/arch/arm/src/imxrt/imxrt_lpspi.c +++ b/arch/arm/src/imxrt/imxrt_lpspi.c @@ -1,4 +1,4 @@ -/************************************************************************************ +/***************************************************************************** * arm/arm/src/imxrt/imxrt_lpspi.c * * Copyright (C) 2018 Gregory Nutt. All rights reserved. @@ -32,34 +32,35 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************************/ + *****************************************************************************/ -/************************************************************************************ - * The external functions, imxrt_lpspi1/2/3/4select and imxrt_lpspi1/2/3/4status - * must be provided by board-specific logic. They are implementations of the select - * and status methods of the SPI interface defined by struct imxrt_lpspi_ops_s (see - * include/nuttx/spi/spi.h). All other methods (including imxrt_lpspibus_initialize()) - * are provided by common IMXRT logic. To use this common SPI logic on your - * board: +/***************************************************************************** + * The external functions, imxrt_lpspi1/2/3/4select and + * imxrt_lpspi1/2/3/4status must be provided by board-specific logic. + * They are implementations of the select and status methods of the SPI + * interface defined by struct imxrt_lpspi_ops_s (see + * include/nuttx/spi/spi.h). All other methods (including + * imxrt_lpspibus_initialize()) are provided by common IMXRT logic. + * To use this common SPI logic on your board: * * 1. Provide logic in imxrt_boardinitialize() to configure SPI chip select * pins. * 2. Provide imxrt_lpspi1/2/3/4select() and imxrt_lpspi1/2/3/4status() - * functions in your board-specific logic. These functions will perform chip - * selection and status operations using GPIOs in the way your board is - * configured. - * 3. Add a calls to imxrt_lpspibus_initialize() in your low level application - * initialization logic - * 4. The handle returned by imxrt_lpspibus_initialize() may then be used to bind the - * SPI driver to higher level logic (e.g., calling + * functions in your board-specific logic. These functions will perform + * chip selection and status operations using GPIOs in the way your board + * is configured. + * 3. Add a calls to imxrt_lpspibus_initialize() in your low level + * application initialization logic + * 4. The handle returned by imxrt_lpspibus_initialize() may then be used to + * bind the SPI driver to higher level logic (e.g., calling * mmcsd_lpspislotinitialize(), for example, will bind the SPI driver to * the SPI MMC/SD driver). * - ************************************************************************************/ + *****************************************************************************/ -/************************************************************************************ +/***************************************************************************** * Included Files - ************************************************************************************/ + *****************************************************************************/ #include @@ -94,11 +95,11 @@ #if defined(CONFIG_IMXRT_LPSPI1) || defined(CONFIG_IMXRT_LPSPI2) || \ defined(CONFIG_IMXRT_LPSPI3) || defined(CONFIG_IMXRT_LPSPI4) -/************************************************************************************ +/***************************************************************************** * Pre-processor Definitions - ************************************************************************************/ + ****************************************************************************/ -/* Configuration ********************************************************************/ +/* Configuration ************************************************************/ /* SPI interrupts */ @@ -116,9 +117,9 @@ # error "Cannot enable both interrupt mode and DMA mode for SPI" #endif -/************************************************************************************ +/***************************************************************************** * Private Types - ************************************************************************************/ + ****************************************************************************/ struct imxrt_lpspidev_s { @@ -141,9 +142,9 @@ enum imxrt_delay_e LPSPI_BETWEEN_TRANSFER /* Delay between transfers. */ }; -/************************************************************************************ +/***************************************************************************** * Private Function Prototypes - ************************************************************************************/ + ****************************************************************************/ /* Helpers */ @@ -151,17 +152,19 @@ static inline uint32_t imxrt_lpspi_getreg32(FAR struct imxrt_lpspidev_s *priv, uint8_t offset); static inline void imxrt_lpspi_putreg32(FAR struct imxrt_lpspidev_s *priv, uint8_t offset, uint32_t value); -static inline uint16_t imxrt_lpspi_readword(FAR struct imxrt_lpspidev_s *priv); +static inline uint16_t imxrt_lpspi_readword( + FAR struct imxrt_lpspidev_s *priv); static inline void imxrt_lpspi_writeword(FAR struct imxrt_lpspidev_s *priv, uint16_t byte); -static inline bool imxrt_lpspi_9to16bitmode(FAR struct imxrt_lpspidev_s *priv); +static inline bool imxrt_lpspi_9to16bitmode( + FAR struct imxrt_lpspidev_s *priv); static inline void imxrt_lpspi_master_set_delays(FAR struct imxrt_lpspidev_s *priv, uint32_t delay_ns, enum imxrt_delay_e type); -static inline void imxrt_lpspi_master_set_delay_scaler(FAR struct - imxrt_lpspidev_s *priv, - uint32_t scaler, - enum imxrt_delay_e type); +static inline void imxrt_lpspi_master_set_delay_scaler( + FAR struct imxrt_lpspidev_s *priv, + uint32_t scaler, + enum imxrt_delay_e type); /* SPI methods */ @@ -182,7 +185,8 @@ static void imxrt_lpspi_exchange(FAR struct spi_dev_s *dev, #ifndef CONFIG_SPI_EXCHANGE static void imxrt_lpspi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, size_t nwords); -static void imxrt_lpspi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, +static void imxrt_lpspi_recvblock(FAR struct spi_dev_s *dev, + FAR void *rxbuffer, size_t nwords); #endif @@ -190,9 +194,9 @@ static void imxrt_lpspi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, static void imxrt_lpspi_bus_initialize(FAR struct imxrt_lpspidev_s *priv); -/************************************************************************************ +/***************************************************************************** * Private Data - ************************************************************************************/ + *****************************************************************************/ #ifdef CONFIG_IMXRT_LPSPI1 static const struct spi_ops_s g_spi1ops = @@ -378,11 +382,11 @@ static struct imxrt_lpspidev_s g_lpspi4dev = }; #endif -/************************************************************************************ +/***************************************************************************** * Private Functions - ************************************************************************************/ + *****************************************************************************/ -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_getreg8 * * Description: @@ -395,7 +399,7 @@ static struct imxrt_lpspidev_s g_lpspi4dev = * Returned Value: * The contents of the 8-bit register * - ************************************************************************************/ + *****************************************************************************/ static inline uint8_t imxrt_lpspi_getreg8(FAR struct imxrt_lpspidev_s *priv, uint8_t offset) @@ -403,7 +407,7 @@ static inline uint8_t imxrt_lpspi_getreg8(FAR struct imxrt_lpspidev_s *priv, return getreg8(priv->spibase + offset); } -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_putreg8 * * Description: @@ -414,7 +418,7 @@ static inline uint8_t imxrt_lpspi_getreg8(FAR struct imxrt_lpspidev_s *priv, * offset - offset to the register of interest * value - the 8-bit value to be written * - ************************************************************************************/ + *****************************************************************************/ static inline void imxrt_lpspi_putreg8(FAR struct imxrt_lpspidev_s *priv, uint8_t offset, uint8_t value) @@ -422,7 +426,7 @@ static inline void imxrt_lpspi_putreg8(FAR struct imxrt_lpspidev_s *priv, putreg8(value, priv->spibase + offset); } -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_getreg * * Description: @@ -435,7 +439,7 @@ static inline void imxrt_lpspi_putreg8(FAR struct imxrt_lpspidev_s *priv, * Returned Value: * The contents of the 32-bit register * - ************************************************************************************/ + *****************************************************************************/ static inline uint32_t imxrt_lpspi_getreg32(FAR struct imxrt_lpspidev_s *priv, uint8_t offset) @@ -443,7 +447,7 @@ static inline uint32_t imxrt_lpspi_getreg32(FAR struct imxrt_lpspidev_s *priv, return getreg32(priv->spibase + offset); } -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_putreg * * Description: @@ -457,7 +461,7 @@ static inline uint32_t imxrt_lpspi_getreg32(FAR struct imxrt_lpspidev_s *priv, * Returned Value: * The contents of the 32-bit register * - ************************************************************************************/ + *****************************************************************************/ static inline void imxrt_lpspi_putreg32(FAR struct imxrt_lpspidev_s *priv, uint8_t offset, uint32_t value) @@ -465,7 +469,7 @@ static inline void imxrt_lpspi_putreg32(FAR struct imxrt_lpspidev_s *priv, putreg32(value, priv->spibase + offset); } -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_readword * * Description: @@ -477,20 +481,21 @@ static inline void imxrt_lpspi_putreg32(FAR struct imxrt_lpspidev_s *priv, * Returned Value: * word as read * - ************************************************************************************/ + *****************************************************************************/ static inline uint16_t imxrt_lpspi_readword(FAR struct imxrt_lpspidev_s *priv) { /* Wait until the receive buffer is not empty */ - while ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_SR_OFFSET) & LPSPI_SR_RDF) == 0); + while ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_SR_OFFSET) + & LPSPI_SR_RDF) == 0); /* Then return the received byte */ return (uint16_t) imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_RDR_OFFSET); } -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_writeword * * Description: @@ -503,21 +508,22 @@ static inline uint16_t imxrt_lpspi_readword(FAR struct imxrt_lpspidev_s *priv) * Returned Value: * None * - ************************************************************************************/ + *****************************************************************************/ static inline void imxrt_lpspi_writeword(FAR struct imxrt_lpspidev_s *priv, uint16_t word) { /* Wait until the transmit buffer is empty */ - while ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_SR_OFFSET) & LPSPI_SR_TDF) == 0); + while ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_SR_OFFSET) + & LPSPI_SR_TDF) == 0); /* Then send the word */ imxrt_lpspi_putreg32(priv, IMXRT_LPSPI_TDR_OFFSET, word); } -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_readbyte * * Description: @@ -529,20 +535,21 @@ static inline void imxrt_lpspi_writeword(FAR struct imxrt_lpspidev_s *priv, * Returned Value: * Byte as read * - ************************************************************************************/ + *****************************************************************************/ static inline uint8_t imxrt_lpspi_readbyte(FAR struct imxrt_lpspidev_s *priv) { /* Wait until the receive buffer is not empty */ - while ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_SR_OFFSET) & LPSPI_SR_RDF) == 0); + while ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_SR_OFFSET) + & LPSPI_SR_RDF) == 0); /* Then return the received byte */ return imxrt_lpspi_getreg8(priv, IMXRT_LPSPI_RDR_OFFSET); } -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_writebyte * * Description: @@ -555,21 +562,22 @@ static inline uint8_t imxrt_lpspi_readbyte(FAR struct imxrt_lpspidev_s *priv) * Returned Value: * None * - ************************************************************************************/ + *****************************************************************************/ static inline void imxrt_lpspi_writebyte(FAR struct imxrt_lpspidev_s *priv, uint8_t byte) { /* Wait until the transmit buffer is empty */ - while ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_SR_OFFSET) & LPSPI_SR_TDF) == 0); + while ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_SR_OFFSET) + & LPSPI_SR_TDF) == 0); /* Then send the byte */ imxrt_lpspi_putreg8(priv, IMXRT_LPSPI_TDR_OFFSET, byte); } -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_9to16bitmode * * Description: @@ -581,7 +589,7 @@ static inline void imxrt_lpspi_writebyte(FAR struct imxrt_lpspidev_s *priv, * Returned Value: * true: >8 bit mode-bit mode, false: <= 8-bit mode * - ************************************************************************************/ + *****************************************************************************/ static inline bool imxrt_lpspi_9to16bitmode(FAR struct imxrt_lpspidev_s *priv) { @@ -600,7 +608,7 @@ static inline bool imxrt_lpspi_9to16bitmode(FAR struct imxrt_lpspidev_s *priv) return ret; } -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_modifyreg * * Description: @@ -615,7 +623,7 @@ static inline bool imxrt_lpspi_9to16bitmode(FAR struct imxrt_lpspidev_s *priv) * Returned Value: * None * - ************************************************************************************/ + *****************************************************************************/ static void imxrt_lpspi_modifyreg32(FAR struct imxrt_lpspidev_s *priv, uint8_t offset, uint32_t clrbits, @@ -624,7 +632,7 @@ static void imxrt_lpspi_modifyreg32(FAR struct imxrt_lpspidev_s *priv, modifyreg32(priv->spibase + offset, clrbits, setbits); } -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_master_set_delays * * Description: @@ -638,11 +646,12 @@ static void imxrt_lpspi_modifyreg32(FAR struct imxrt_lpspidev_s *priv, * Returned Value: * None * - ************************************************************************************/ + *****************************************************************************/ -static inline void imxrt_lpspi_master_set_delay_scaler(FAR struct imxrt_lpspidev_s *priv, - uint32_t scaler, - enum imxrt_delay_e type) +static inline void imxrt_lpspi_master_set_delay_scaler( + FAR struct imxrt_lpspidev_s *priv, + uint32_t scaler, + enum imxrt_delay_e type) { switch (type) { @@ -661,15 +670,15 @@ static inline void imxrt_lpspi_master_set_delay_scaler(FAR struct imxrt_lpspidev break; case LPSPI_BETWEEN_TRANSFER: - imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CCR_OFFSET, LPSPI_CCR_DBT_MASK, - 0); + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CCR_OFFSET, + LPSPI_CCR_DBT_MASK, 0); imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CCR_OFFSET, 0, LPSPI_CCR_DBT(scaler)); break; } } -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_master_set_delays * * Description: @@ -683,10 +692,12 @@ static inline void imxrt_lpspi_master_set_delay_scaler(FAR struct imxrt_lpspidev * Returned Value: * None * - ************************************************************************************/ -static inline void imxrt_lpspi_master_set_delays(FAR struct imxrt_lpspidev_s *priv, - uint32_t delay_ns, - enum imxrt_delay_e type) + *****************************************************************************/ + +static inline void imxrt_lpspi_master_set_delays( + FAR struct imxrt_lpspidev_s *priv, + uint32_t delay_ns, + enum imxrt_delay_e type) { uint32_t pll3_div; uint32_t pll_freq; @@ -719,8 +730,9 @@ static inline void imxrt_lpspi_master_set_delays(FAR struct imxrt_lpspidev_s *pr */ src_freq = pll_freq / - ((getreg32(IMXRT_CCM_ANALOG_PFD_480) & CCM_ANALOG_PFD_480_PFD0_FRAC_MASK) >> - CCM_ANALOG_PFD_480_PFD0_FRAC_SHIFT); + ((getreg32(IMXRT_CCM_ANALOG_PFD_480) + & CCM_ANALOG_PFD_480_PFD0_FRAC_MASK) >> + CCM_ANALOG_PFD_480_PFD0_FRAC_SHIFT); src_freq *= 18; src_freq /= ((getreg32(IMXRT_CCM_CBCMR) & CCM_CBCMR_LPSPI_PODF_MASK) >> CCM_CBCMR_LPSPI_PODF_SHIFT) + 1; @@ -797,9 +809,9 @@ static inline void imxrt_lpspi_master_set_delays(FAR struct imxrt_lpspidev_s *pr for (scaler = 0; (scaler < 256) && min_diff; scaler++) { /* Calculate the real delay value as we cycle through the scaler - * values. Due to large size of calculated values (uint64_t), we need - * to break up the calculation into several steps to ensure accurate - * calculated results + * values. Due to large size of calculated values (uint64_t), + * we need to break up the calculation into several steps to + * ensure accurate calculated results */ real_delay = 1000000000U; @@ -829,7 +841,7 @@ static inline void imxrt_lpspi_master_set_delays(FAR struct imxrt_lpspidev_s *pr } } -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_lock * * Description: @@ -848,7 +860,7 @@ static inline void imxrt_lpspi_master_set_delays(FAR struct imxrt_lpspidev_s *pr * Returned Value: * None * - ************************************************************************************/ + *****************************************************************************/ static int imxrt_lpspi_lock(FAR struct spi_dev_s *dev, bool lock) { @@ -867,7 +879,7 @@ static int imxrt_lpspi_lock(FAR struct spi_dev_s *dev, bool lock) return ret; } -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_setfrequency * * Description: @@ -880,7 +892,7 @@ static int imxrt_lpspi_lock(FAR struct spi_dev_s *dev, bool lock) * Returned Value: * Returns the actual frequency selected * - ************************************************************************************/ + *****************************************************************************/ static uint32_t imxrt_lpspi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) @@ -909,7 +921,8 @@ static uint32_t imxrt_lpspi_setfrequency(FAR struct spi_dev_s *dev, men = imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CR_OFFSET) & LPSPI_CR_MEN; if (men) { - imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, LPSPI_CR_MEN, 0); + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, + LPSPI_CR_MEN, 0); } if ((getreg32(IMXRT_CCM_ANALOG_PLL_USB1) & @@ -930,8 +943,9 @@ static uint32_t imxrt_lpspi_setfrequency(FAR struct spi_dev_s *dev, */ src_freq = pll_freq / - ((getreg32(IMXRT_CCM_ANALOG_PFD_480) & CCM_ANALOG_PFD_480_PFD0_FRAC_MASK) >> - CCM_ANALOG_PFD_480_PFD0_FRAC_SHIFT); + ((getreg32(IMXRT_CCM_ANALOG_PFD_480) + & CCM_ANALOG_PFD_480_PFD0_FRAC_MASK) >> + CCM_ANALOG_PFD_480_PFD0_FRAC_SHIFT); src_freq *= 18; src_freq /= ((getreg32(IMXRT_CCM_CBCMR) & CCM_CBCMR_LPSPI_PODF_MASK) >> CCM_CBCMR_LPSPI_PODF_SHIFT) + 1; @@ -994,14 +1008,15 @@ static uint32_t imxrt_lpspi_setfrequency(FAR struct spi_dev_s *dev, if (men) { - imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, 0, LPSPI_CR_MEN); + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, 0, + LPSPI_CR_MEN); } } return priv->actual; } -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_setmode * * Description: @@ -1014,9 +1029,10 @@ static uint32_t imxrt_lpspi_setfrequency(FAR struct spi_dev_s *dev, * Returned Value: * Returns the actual frequency selected * - ************************************************************************************/ + *****************************************************************************/ -static void imxrt_lpspi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) +static void imxrt_lpspi_setmode(FAR struct spi_dev_s *dev, + enum spi_mode_e mode) { FAR struct imxrt_lpspidev_s *priv = (FAR struct imxrt_lpspidev_s *)dev; uint32_t setbits; @@ -1034,7 +1050,8 @@ static void imxrt_lpspi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) men = imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CR_OFFSET) & LPSPI_CR_MEN; if (men) { - imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, LPSPI_CR_MEN, 0); + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, + LPSPI_CR_MEN, 0); } switch (mode) @@ -1081,12 +1098,13 @@ static void imxrt_lpspi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) if (men) { - imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, 0, LPSPI_CR_MEN); + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, 0, + LPSPI_CR_MEN); } } } -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_setbits * * Description: @@ -1099,7 +1117,7 @@ static void imxrt_lpspi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) * Returned Value: * None * - ************************************************************************************/ + *****************************************************************************/ static void imxrt_lpspi_setbits(FAR struct spi_dev_s *dev, int nbits) { @@ -1113,7 +1131,6 @@ static void imxrt_lpspi_setbits(FAR struct spi_dev_s *dev, int nbits) if (nbits != priv->nbits) { - if (nbits < 2 || nbits > 4096) { return; @@ -1124,14 +1141,17 @@ static void imxrt_lpspi_setbits(FAR struct spi_dev_s *dev, int nbits) men = imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CR_OFFSET) & LPSPI_CR_MEN; if (men) { - imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, LPSPI_CR_MEN, 0); + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, + LPSPI_CR_MEN, 0); } imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_TCR_OFFSET, LPSPI_TCR_FRAMESZ_MASK, LPSPI_TCR_FRAMESZ(nbits - 1)); - /* Save the selection so the subsequence re-configurations will be faster */ + /* Save the selection so the subsequence re-configurations + * will be faster + */ priv->nbits = savbits; /* nbits has been clobbered... save the signed * value. */ @@ -1140,12 +1160,13 @@ static void imxrt_lpspi_setbits(FAR struct spi_dev_s *dev, int nbits) if (men) { - imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, 0, LPSPI_CR_MEN); + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, 0, + LPSPI_CR_MEN); } } } -/**************************************************************************** +/***************************************************************************** * Name: imxrt_lpspi_hwfeatures * * Description: @@ -1197,7 +1218,7 @@ static int imxrt_lpspi_hwfeatures(FAR struct spi_dev_s *dev, } #endif -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_send * * Description: @@ -1211,7 +1232,7 @@ static int imxrt_lpspi_hwfeatures(FAR struct spi_dev_s *dev, * Returned Value: * response * - ************************************************************************************/ + *****************************************************************************/ static uint16_t imxrt_lpspi_send(FAR struct spi_dev_s *dev, uint16_t wd) { @@ -1240,7 +1261,7 @@ static uint16_t imxrt_lpspi_send(FAR struct spi_dev_s *dev, uint16_t wd) return ret; } -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_exchange (no DMA). aka imxrt_lpspi_exchange_nodma * * Description: @@ -1253,12 +1274,13 @@ static uint16_t imxrt_lpspi_send(FAR struct spi_dev_s *dev, uint16_t wd) * nwords - the length of data to be exchaned in units of words. * The wordsize is determined by the number of bits-per-word * selected for the SPI interface. If nbits <= 8, the data is - * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * packed into uint8_t's; if nbits >8, the data is packed + * into uint16_t's * * Returned Value: * None * - ************************************************************************************/ + *****************************************************************************/ #if !defined(CONFIG_IMXRT_LPSPI_DMA) || defined(CONFIG_IMXRT_DMACAPABLE) #if !defined(CONFIG_IMXRT_LPSPI_DMA) @@ -1359,12 +1381,13 @@ static void imxrt_lpspi_exchange_nodma(FAR struct spi_dev_s *dev, * nwords - the length of data to send from the buffer in number of words. * The wordsize is determined by the number of bits-per-word * selected for the SPI interface. If nbits <= 8, the data is - * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * packed into uint8_t's; if nbits >8, the data is packed into + * uint16_t's * * Returned Value: * None * - ************************************************************************************/ + *****************************************************************************/ #ifndef CONFIG_SPI_EXCHANGE static void imxrt_lpspi_sndblock(FAR struct spi_dev_s *dev, @@ -1375,7 +1398,7 @@ static void imxrt_lpspi_sndblock(FAR struct spi_dev_s *dev, } #endif -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_recvblock * * Description: @@ -1384,32 +1407,33 @@ static void imxrt_lpspi_sndblock(FAR struct spi_dev_s *dev, * Input Parameters: * dev - Device-specific state data * rxbuffer - A pointer to the buffer in which to receive data - * nwords - the length of data that can be received in the buffer in number - * of words. The wordsize is determined by the number of bits-per-word - * selected for the SPI interface. If nbits <= 8, the data is - * packed into uint8_t's; if nbits >8, the data is packed into uint16_t's + * nwords - the length of data that can be received in the buffer in + * number of words. The wordsize is determined by the number of + * bits-per-word selected for the SPI interface. If + * nbits <= 8, the data is packed into uint8_t's; + * if nbits >8, the data is packed into uint16_t's * * Returned Value: * None * - ************************************************************************************/ + *****************************************************************************/ #ifndef CONFIG_SPI_EXCHANGE -static void imxrt_lpspi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, - size_t nwords) +static void imxrt_lpspi_recvblock(FAR struct spi_dev_s *dev, + FAR void *rxbuffer, size_t nwords) { spiinfo("rxbuffer=%p nwords=%d\n", rxbuffer, nwords); return imxrt_lpspi_exchange(dev, NULL, rxbuffer, nwords); } #endif -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_clock_enable * * Description: * Ungate LPSPI clock * - ************************************************************************************/ + *****************************************************************************/ void imxrt_lpspi_clock_enable(uint32_t base) { @@ -1431,13 +1455,13 @@ void imxrt_lpspi_clock_enable(uint32_t base) } } -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_clock_disable * * Description: * Gate LPSPI clock * - ************************************************************************************/ + *****************************************************************************/ void imxrt_lpspi_clock_disable(uint32_t base) { @@ -1459,11 +1483,12 @@ void imxrt_lpspi_clock_disable(uint32_t base) } } -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspi_bus_initialize * * Description: - * Initialize the selected SPI bus in its default state (Master, 8-bit, mode 0, etc.) + * Initialize the selected SPI bus in its default state + * (Master, 8-bit, mode 0, etc.) * * Input Parameters: * priv - private SPI device structure @@ -1471,7 +1496,7 @@ void imxrt_lpspi_clock_disable(uint32_t base) * Returned Value: * None * - ************************************************************************************/ + *****************************************************************************/ static void imxrt_lpspi_bus_initialize(struct imxrt_lpspidev_s *priv) { @@ -1493,13 +1518,15 @@ static void imxrt_lpspi_bus_initialize(struct imxrt_lpspidev_s *priv) imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CFGR1_OFFSET, 0, LPSPI_CFGR1_MASTER); - /* Set specific PCS to active high or low */ - /* TODO: Not needed for now */ + /* Set specific PCS to active high or low + * TODO: Not needed for now + */ /* Set Configuration Register 1 related setting. */ reg = imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CFGR1_OFFSET); - reg &= ~(LPSPI_CFGR1_OUTCFG | LPSPI_CFGR1_PINCFG_MASK | LPSPI_CFGR1_NOSTALL); + reg &= ~(LPSPI_CFGR1_OUTCFG | LPSPI_CFGR1_PINCFG_MASK + | LPSPI_CFGR1_NOSTALL); reg |= LPSPI_CFGR1_OUTCFG_RETAIN | LPSPI_CFGR1_PINCFG_SIN_SOUT; imxrt_lpspi_putreg32(priv, IMXRT_LPSPI_CFGR1_OFFSET, reg); @@ -1527,11 +1554,11 @@ static void imxrt_lpspi_bus_initialize(struct imxrt_lpspidev_s *priv) imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, 0, LPSPI_CR_MEN); } -/************************************************************************************ +/***************************************************************************** * Public Functions - ************************************************************************************/ + *****************************************************************************/ -/************************************************************************************ +/***************************************************************************** * Name: imxrt_lpspibus_initialize * * Description: @@ -1543,7 +1570,7 @@ static void imxrt_lpspi_bus_initialize(struct imxrt_lpspidev_s *priv) * Returned Value: * Valid SPI device structure reference on success; a NULL on failure * - ************************************************************************************/ + ****************************************************************************/ FAR struct spi_dev_s *imxrt_lpspibus_initialize(int bus) { @@ -1560,13 +1587,20 @@ FAR struct spi_dev_s *imxrt_lpspibus_initialize(int bus) /* Only configure if the bus is not already configured */ - if ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CR_OFFSET) & LPSPI_CR_MEN) == 0) + if ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CR_OFFSET) + & LPSPI_CR_MEN) == 0) { /* Configure SPI1 pins: SCK, MISO, and MOSI */ imxrt_config_gpio(GPIO_LPSPI1_SCK); imxrt_config_gpio(GPIO_LPSPI1_MISO); imxrt_config_gpio(GPIO_LPSPI1_MOSI); +#ifdef GPIO_LPSPI1_CS + imxrt_config_gpio(GPIO_LPSPI1_CS); +#endif +#if defined(GPIO_LPSPI1_DC) && defined(CONFIG_SPI_CMDDATA) + imxrt_config_gpio(GPIO_LPSPI1_DC); +#endif /* Set up default configuration: Master, 8-bit, etc. */ @@ -1584,13 +1618,20 @@ FAR struct spi_dev_s *imxrt_lpspibus_initialize(int bus) /* Only configure if the bus is not already configured */ - if ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CR_OFFSET) & LPSPI_CR_MEN) == 0) + if ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CR_OFFSET) + & LPSPI_CR_MEN) == 0) { /* Configure SPI2 pins: SCK, MISO, and MOSI */ imxrt_config_gpio(GPIO_LPSPI2_SCK); imxrt_config_gpio(GPIO_LPSPI2_MISO); imxrt_config_gpio(GPIO_LPSPI2_MOSI); +#ifdef GPIO_LPSPI2_CS + imxrt_config_gpio(GPIO_LPSPI2_CS); +#endif +#if defined(GPIO_LPSPI2_DC) && defined(CONFIG_SPI_CMDDATA) + imxrt_config_gpio(GPIO_LPSPI2_DC); +#endif /* Set up default configuration: Master, 8-bit, etc. */ @@ -1608,13 +1649,20 @@ FAR struct spi_dev_s *imxrt_lpspibus_initialize(int bus) /* Only configure if the bus is not already configured */ - if ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CR_OFFSET) & LPSPI_CR_MEN) == 0) + if ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CR_OFFSET) + & LPSPI_CR_MEN) == 0) { /* Configure SPI3 pins: SCK, MISO, and MOSI */ imxrt_config_gpio(GPIO_LPSPI3_SCK); imxrt_config_gpio(GPIO_LPSPI3_MISO); imxrt_config_gpio(GPIO_LPSPI3_MOSI); +#ifdef GPIO_LPSPI3_CS + imxrt_config_gpio(GPIO_LPSPI3_CS); +#endif +#if defined(GPIO_LPSPI3_DC) && defined(CONFIG_SPI_CMDDATA) + imxrt_config_gpio(GPIO_LPSPI3_DC); +#endif /* Set up default configuration: Master, 8-bit, etc. */ @@ -1632,13 +1680,20 @@ FAR struct spi_dev_s *imxrt_lpspibus_initialize(int bus) /* Only configure if the bus is not already configured */ - if ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CR_OFFSET) & LPSPI_CR_MEN) == 0) + if ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CR_OFFSET) + & LPSPI_CR_MEN) == 0) { /* Configure SPI4 pins: SCK, MISO, and MOSI */ imxrt_config_gpio(GPIO_LPSPI4_SCK); imxrt_config_gpio(GPIO_LPSPI4_MISO); imxrt_config_gpio(GPIO_LPSPI4_MOSI); +#ifdef GPIO_LPSPI4_CS + imxrt_config_gpio(GPIO_LPSPI4_CS); +#endif +#if defined(GPIO_LPSPI4_DC) && defined(CONFIG_SPI_CMDDATA) + imxrt_config_gpio(GPIO_LPSPI4_DC); +#endif /* Set up default configuration: Master, 8-bit, etc. */ diff --git a/drivers/lcd/Kconfig b/drivers/lcd/Kconfig index 9bc3ac284bb..88a9f5a4d50 100644 --- a/drivers/lcd/Kconfig +++ b/drivers/lcd/Kconfig @@ -1134,6 +1134,23 @@ config LCD_ILI9341_IFACE1_RGB565 endchoice endif +config LCD_LCDDRV_SPIIF + bool "Generic SPI Interface Driver (for ILI9341 or others)" + default n + depends on LCD_ILI9341 + ---help--- + SPI Interface shim to allow LCD and ePaper to be bound to + a normal SPI port. + +config LCD_LCDDRV_SPEED + int "Generic SPI Interface speed" + default 10000000 + depends on LCD_LCDDRV_SPIIF + ---help--- + SPI Interface speed. According to the specification this is generally + quite limited, but people have had success with much faster + speeds than the spec sheets say. YMMV. + config LCD_RA8875 bool "RA8875 LCD Display Controller" default n diff --git a/drivers/lcd/Make.defs b/drivers/lcd/Make.defs index bfc50baed8e..b40aca2b339 100644 --- a/drivers/lcd/Make.defs +++ b/drivers/lcd/Make.defs @@ -124,6 +124,10 @@ ifeq ($(CONFIG_LCD_ILI9341),y) CSRCS += ili9341.c endif +ifeq ($(CONFIG_LCD_LCDDRV_SPIIF),y) + CSRCS += lcddrv_spiif.c +endif + ifeq ($(CONFIG_LCD_RA8875),y) CSRCS += ra8875.c endif diff --git a/drivers/lcd/lcddrv_spiif.c b/drivers/lcd/lcddrv_spiif.c new file mode 100644 index 00000000000..d1dbb3e2eaa --- /dev/null +++ b/drivers/lcd/lcddrv_spiif.c @@ -0,0 +1,347 @@ +/**************************************************************************** + * drivers/lcd/lcddrv_spiif.c + * + * Generic Driver interface for the Single Chip LCD driver connected + * via spi driver + * + * Copyright (C) 2019 Greg Nutt. All rights reserved. + * Author: Dave Marples + * Based on work from Marco Krahl + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior writen permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Definition + ****************************************************************************/ + +struct lcddrv_spiif_lcd_s +{ + /* Publically visible device structure */ + + struct lcddrv_lcd_s dev; + + /* Reference to spi device structure */ + + struct spi_dev_s *spi; +}; + +/**************************************************************************** + * Private Function Protototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lcddrv_spiif_backlight + * + * Description: + * Set the backlight level of the connected display. + * + * Input Parameters: + * spi - Reference to the public driver structure + * level - backlight level + * + * Returned Value: + * OK - On Success + * + ****************************************************************************/ + +static int lcddrv_spiif_backlight(struct lcddrv_lcd_s *lcd, int level) +{ + return spiif_backlight(lcd, level); +} + +/**************************************************************************** + * Name: lcddrv_spiif_select + * + * Description: + * Select the SPI, locking and re-configuring if necessary + * + * Input Parameters: + * spi - Reference to the public driver structure + * isCommand - Flag indicating is command mode + * + * Returned Value: + * + ****************************************************************************/ + +static void lcddrv_spiif_select(FAR struct lcddrv_lcd_s *lcd) +{ + FAR struct lcddrv_spiif_lcd_s *priv = (FAR struct lcddrv_spiif_lcd_s *)lcd; + + SPI_LOCK(priv->spi, true); + SPI_SELECT(priv->spi, SPIDEV_DISPLAY(0), true); +} + +/**************************************************************************** + * Name: lcddrv_spiif_deselect + * + * Description: + * De-select the SPI + * + * Input Parameters: + * spi - Reference to the public driver structure + * + * Returned Value: + * + ****************************************************************************/ + +static void lcddrv_spiif_deselect(FAR struct lcddrv_lcd_s *lcd) +{ + FAR struct lcddrv_spiif_lcd_s *priv = (FAR struct lcddrv_spiif_lcd_s *)lcd; + + SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY(0), false); + SPI_SELECT(priv->spi, SPIDEV_DISPLAY(0), false); + SPI_LOCK(priv->spi, false); +} + +/**************************************************************************** + * Name: lcddrv_spiif_sendmulti + * + * Description: + * Send a number of pixel words to the lcd driver gram. + * + * Input Parameters: + * lcd - Reference to the lcddrv_lcd_s driver structure + * wd - Reference to the words to send + * nwords - number of words to send + * + * Returned Value: + * OK - On Success + * + ****************************************************************************/ + +static int lcddrv_spiif_sendmulti(FAR struct lcddrv_lcd_s *lcd, + FAR const uint16_t *wd, uint32_t nwords) +{ + FAR struct lcddrv_spiif_lcd_s *priv = (FAR struct lcddrv_spiif_lcd_s *)lcd; + + SPI_SETBITS(priv->spi, 16); + for (uint32_t t = 0; t < nwords; t++) + { + SPI_SEND(priv->spi, *wd++); + } + + SPI_SETBITS(priv->spi, 8); + + return OK; +}; + +/**************************************************************************** + * Name: lcddrv_spiif_recv + * + * Description: + * Receive a parameter from the lcd driver. + * + * Input Parameters: + * lcd - Reference to the lcddrv_lcd_s driver structure + * param - Reference to where parameter receive + * + * Returned Value: + * OK - On Success + * + ****************************************************************************/ + +static int lcddrv_spiif_recv(FAR struct lcddrv_lcd_s *lcd, + uint8_t *param) +{ + FAR struct lcddrv_spiif_lcd_s *priv = (FAR struct lcddrv_spiif_lcd_s *)lcd; + + lcdinfo("param=%04x\n", param); + SPI_RECVBLOCK(priv->spi, param, 1); + return OK; +} + +/**************************************************************************** + * Name: lcddrv_spiif_send + * + * Description: + * Send to the lcd + * + * Input Parameters: + * lcd - Reference to the lcddrv_lcd_s driver structure + * param - Reference to where parameter to send is located + * + * Returned Value: + * OK - On Success + * + ****************************************************************************/ + +static int lcddrv_spiif_send(FAR struct lcddrv_lcd_s *lcd, + const uint8_t param) +{ + uint8_t r; + FAR struct lcddrv_spiif_lcd_s *priv = (FAR struct lcddrv_spiif_lcd_s *)lcd; + + r = SPI_SEND(priv->spi, param); + return r; +} + +/**************************************************************************** + * Name: lcddrv_spiif_sendcmd + * + * Description: + * Send command to the lcd + * + * Input Parameters: + * lcd - Reference to the lcddrv_lcd_s driver structure + * param - Reference to where parameter to send is located + * + * Returned Value: + * OK - On Success + * + ****************************************************************************/ + +static int lcddrv_spiif_sendcmd(FAR struct lcddrv_lcd_s *lcd, + const uint8_t param) +{ + uint8_t r; + FAR struct lcddrv_spiif_lcd_s *priv = (FAR struct lcddrv_spiif_lcd_s *)lcd; + + lcdinfo("param=%04x\n", param); + SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY(0), true); + r = SPI_SEND(priv->spi, param); + SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY(0), false); + return r; +} + +/**************************************************************************** + * Name: lcddrv_spiif_recvmulti + * + * Description: + * Receive pixel words from the lcd driver gram. + * + * Input Parameters: + * lcd - Reference to the public driver structure + * wd - Reference to where the pixel words receive + * nwords - number of pixel words to receive + * + * Returned Value: + * OK - On Success + * + ****************************************************************************/ + +static int lcddrv_spiif_recvmulti(FAR struct lcddrv_lcd_s *lcd, + FAR uint16_t *wd, uint32_t nwords) +{ + FAR struct lcddrv_spiif_lcd_s *priv = (FAR struct lcddrv_spiif_lcd_s *)lcd; + + lcdinfo("wd=%p, nwords=%d\n", wd, nwords); + SPI_SETBITS(priv->spi, 16); + SPI_RECVBLOCK(priv->spi, wd, nwords); + SPI_SETBITS(priv->spi, 8); + return OK; +} + +/**************************************************************************** + * Name: FAR struct lcddrv_lcd_s *lcddrv_spiif_initialize + * + * Description: + * Initialize the device structure to control the LCD Single chip driver. + * + * Input Parameters: + * spi : handle to the spi to use + * + * Returned Value: + * On success, this function returns a reference to the LCD control object + * for the specified LCDDRV LCD Single chip driver. + * NULL is returned on failure. + * + ****************************************************************************/ + +FAR struct lcddrv_lcd_s *lcddrv_spiif_initialize(struct spi_dev_s *spi) +{ + FAR struct lcddrv_spiif_lcd_s *priv = + (struct lcddrv_spiif_lcd_s *)kmm_zalloc(sizeof(struct lcddrv_spiif_lcd_s)); + + if (!priv) + { + return NULL; + } + + lcdinfo("initialize lcddrv spi subdriver\n"); + + priv->spi = spi; + + if (!priv->spi) + { + kmm_free(priv); + return 0; + } + + SPI_SETFREQUENCY(spi, CONFIG_LCD_LCDDRV_SPEED); + SPI_SETBITS(spi, 8); + + /* Hook in our driver routines */ + + priv->dev.select = lcddrv_spiif_select; + priv->dev.deselect = lcddrv_spiif_deselect; + priv->dev.sendparam = lcddrv_spiif_send; + priv->dev.sendcmd = lcddrv_spiif_sendcmd; + priv->dev.recvparam = lcddrv_spiif_recv; + priv->dev.sendgram = lcddrv_spiif_sendmulti; + priv->dev.recvgram = lcddrv_spiif_recvmulti; + priv->dev.backlight = lcddrv_spiif_backlight; + + return &priv->dev; +} diff --git a/include/nuttx/lcd/lcddrv_spiif.h b/include/nuttx/lcd/lcddrv_spiif.h new file mode 100644 index 00000000000..aefa5e3be14 --- /dev/null +++ b/include/nuttx/lcd/lcddrv_spiif.h @@ -0,0 +1,144 @@ +/***************************************************************************** + * include/nuttx/lcd/lcddrv_spiif.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Dave Marples + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_LCD_LCDDRV_SPIIF_H +#define __INCLUDE_NUTTX_LCD_LCDDRV_SPIIF_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct lcddrv_lcd_s +{ + /* Interface to control the ILI9341 lcd driver + * + * - select Select the device (as neccessary) before performing + * any operations. + * - deselect Deselect the device (as necessary). + * - send Send specific parameter to the LCD driver. + * - recv Receive specific parameter from the LCD driver. + * - sendmulti Send pixel data to the LCD drivers gram. + * - recvmulti Receive pixel data from the LCD drivers gram. + * - backlight Change the backlight level of the connected display. + * In the context of the ili9341 that means change the + * backlight level of the connected LED driver. + * The implementation in detail is part of the platform + * specific sub driver. + */ + + CODE void (*select)(FAR struct lcddrv_lcd_s *lcd); + CODE void (*deselect)(FAR struct lcddrv_lcd_s *lcd); + CODE int (*sendcmd)(FAR struct lcddrv_lcd_s *lcd, const uint8_t cmd); + CODE int (*sendparam)(FAR struct lcddrv_lcd_s *lcd, const uint8_t param); + CODE int (*recvparam)(FAR struct lcddrv_lcd_s *lcd, uint8_t *param); + CODE int (*recvgram)(FAR struct lcddrv_lcd_s *lcd, + uint16_t *wd, uint32_t nwords); + CODE int (*sendgram)(FAR struct lcddrv_lcd_s *lcd, + const uint16_t *wd, uint32_t nwords); + CODE int (*backlight)(FAR struct lcddrv_lcd_s *lcd, int level); + + /* mcu interface specific data following */ +}; + +/***************************************************************************** + * Public Data + *****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/***************************************************************************** + * Public Function Prototypes + *****************************************************************************/ + +/***************************************************************************** + * Name: spiif_backlight + * (Provided by integrating platform) + * + * Description: + * Set the backlight level of the connected display. + * + * Input Parameters: + * spi - Reference to the public driver structure + * level - backlight level + * + * Returned Value: + * OK - On Success + * + ****************************************************************************/ + +extern int spiif_backlight(struct lcddrv_lcd_s *lcd, int level); + +/**************************************************************************** + * Name: FAR struct lcddrv_lcd_s *lcddrv_spiif_initialize + * + * Description: + * Initialize the device structure to control the LCD Single chip driver. + * + * Input Parameters: + * path : path to spi device to use + * + * Returned Value: + * On success, this function returns a reference to the LCD control object + * for the specified LCDDRV LCD Single chip driver. + * NULL is returned on failure. + * + ****************************************************************************/ + +FAR struct lcddrv_lcd_s *lcddrv_spiif_initialize(struct spi_dev_s *spi); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTTX_LCD_LCDDRV_SPIIF_H */