Generic SPI interface for controlling an LCD display

This commit is contained in:
Dave Marples 2020-01-28 11:30:34 -03:00 committed by Alan Carvalho de Assis
parent 6ad906488e
commit e99a8d192d
5 changed files with 698 additions and 131 deletions

View File

@ -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 <nuttx/config.h>
@ -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. */

View File

@ -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

View File

@ -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

347
drivers/lcd/lcddrv_spiif.c Normal file
View File

@ -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 <dave@marples.net>
* Based on work from Marco Krahl <ocram.lhark@gmail.com>
*
* 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 <nuttx/config.h>
#include <sys/types.h>
#include <stdbool.h>
#include <errno.h>
#include <debug.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <nuttx/kmalloc.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <nuttx/spi/spi.h>
#include <nuttx/lcd/lcddrv_spiif.h>
/****************************************************************************
* 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;
}

View File

@ -0,0 +1,144 @@
/*****************************************************************************
* include/nuttx/lcd/lcddrv_spiif.h
*
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Authors: Gregory Nutt <gnutt@nuttx.org>
* Dave Marples <dave@marples.net>
*
* 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 <nuttx/config.h>
#include <nuttx/spi/spi.h>
/****************************************************************************
* 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 */