Generic SPI interface for controlling an LCD display
This commit is contained in:
parent
6ad906488e
commit
e99a8d192d
@ -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. */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
347
drivers/lcd/lcddrv_spiif.c
Normal 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;
|
||||
}
|
144
include/nuttx/lcd/lcddrv_spiif.h
Normal file
144
include/nuttx/lcd/lcddrv_spiif.h
Normal 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 */
|
Loading…
x
Reference in New Issue
Block a user