diff options
-rwxr-xr-x | nuttx/arch/arm/src/lm3s/lm3s_ssi.c | 120 | ||||
-rwxr-xr-x | nuttx/arch/arm/src/stm32/stm32_spi.c | 41 | ||||
-rwxr-xr-x | nuttx/configs/lm3s6965-ek/src/lm3s6965ek_internal.h | 2 | ||||
-rwxr-xr-x | nuttx/configs/lm3s6965-ek/src/up_boot.c | 5 | ||||
-rwxr-xr-x | nuttx/drivers/lcd/p14201.c | 1 |
5 files changed, 132 insertions, 37 deletions
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_ssi.c b/nuttx/arch/arm/src/lm3s/lm3s_ssi.c index 73b995671..18418b886 100755 --- a/nuttx/arch/arm/src/lm3s/lm3s_ssi.c +++ b/nuttx/arch/arm/src/lm3s/lm3s_ssi.c @@ -148,12 +148,11 @@ struct lm3s_ssidev_s #ifndef CONFIG_SSI_POLLWAIT sem_t xfrsem; /* Wait for transfer to complete */ #endif - sem_t exclsem; /* For exclusive access to the SSI bus */ /* These following are the source and destination buffers of the transfer. * they are retained in this structure so that they will be accessible - * from an interrupt handler. The actual type of the buffer is uint8_t is - * nbits <=8 and uint16_t is nbits >8. + * from an interrupt handler. The actual type of the buffer is uint8_t if + * nbits <=8 and uint16_t if nbits >8. */ void *txbuffer; /* Source buffer */ @@ -172,18 +171,27 @@ struct lm3s_ssidev_s #if NSSI_ENABLED > 1 uint32_t base; /* SSI register base address */ #endif - uint32_t frequency; /* Current desired SCLK frequency */ - uint32_t actual; /* Current actual SCLK frequency */ int ntxwords; /* Number of words left to transfer on the Tx FIFO */ int nrxwords; /* Number of words received on the Rx FIFO */ int nwords; /* Number of words to be exchanged */ - - uint8_t mode; /* Current mode */ uint8_t nbits; /* Current number of bits per word */ + #if !defined(CONFIG_SSI_POLLWAIT) && NSSI_ENABLED > 1 uint8_t irq; /* SSI IRQ number */ #endif + + /* If there is more than one device on the SPI bus, then we have to enforce + * mutual exclusion and remember some configuration settings to reduce the + * overhead of constant SPI re-configuration. + */ + +#ifndef CONFIG_SPI_OWNBUS + sem_t exclsem; /* For exclusive access to the SSI bus */ + uint32_t frequency; /* Current desired SCLK frequency */ + uint32_t actual; /* Current actual SCLK frequency */ + uint8_t mode; /* Current mode 0,1,2,3 */ +#endif }; /**************************************************************************** @@ -235,7 +243,7 @@ static int ssi_interrupt(int irq, void *context); #ifndef CONFIG_SPI_OWNBUS static int ssi_lock(FAR struct spi_dev_s *dev, bool lock); #endif -static void ssi_setfrequencyinternal(struct lm3s_ssidev_s *priv, +static uint32_t ssi_setfrequencyinternal(struct lm3s_ssidev_s *priv, uint32_t frequency); static uint32_t ssi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); @@ -378,6 +386,9 @@ static inline void ssi_putreg(struct lm3s_ssidev_s *priv, unsigned int offset, u * Returned Value: * State of the SSI before the SSE was disabled * + * Assumption: + * Caller holds a lock on the SPI bus (if CONFIG_SPI_OWNBUS not defined) + * ****************************************************************************/ static uint32_t ssi_disable(struct lm3s_ssidev_s *priv) @@ -404,6 +415,9 @@ static uint32_t ssi_disable(struct lm3s_ssidev_s *priv) * * Returned Value: * + * Assumption: + * Caller holds a lock on the SPI bus (if CONFIG_SPI_OWNBUS not defined) + * ****************************************************************************/ static void ssi_enable(struct lm3s_ssidev_s *priv, uint32_t enable) @@ -749,6 +763,9 @@ static inline void ssi_performrx(struct lm3s_ssidev_s *priv) * Returned Value: * 0: success, <0:Negated error number on failure * + * Assumption: + * Caller holds a lock on the SPI bus (if CONFIG_SPI_OWNBUS not defined) + * ****************************************************************************/ static int ssi_transfer(struct lm3s_ssidev_s *priv, const void *txbuffer, @@ -760,7 +777,6 @@ static int ssi_transfer(struct lm3s_ssidev_s *priv, const void *txbuffer, int ntxd; ssidbg("txbuffer: %p rxbuffer: %p nwords: %d\n", txbuffer, rxbuffer, nwords); - ssi_semtake(&priv->exclsem); /* Set up to perform the transfer */ @@ -858,7 +874,6 @@ static int ssi_transfer(struct lm3s_ssidev_s *priv, const void *txbuffer, } while (priv->nrxwords < priv->nwords); #endif - ssi_semgive(&priv->exclsem); return OK; } @@ -997,9 +1012,26 @@ static int ssi_interrupt(int irq, void *context) #ifndef CONFIG_SPI_OWNBUS static int ssi_lock(FAR struct spi_dev_s *dev, bool lock) { - /* Not implemented */ + FAR struct lm3s_ssidev_s *priv = (FAR struct lm3s_ssidev_s *)dev; + + if (lock) + { + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->exclsem) != 0) + { + /* The only case that an error should occur here is if the wait was awakened + * by a signal. + */ - return -ENOSYS; + ASSERT(errno == EINTR); + } + } + else + { + (void)sem_post(&priv->exclsem); + } + return OK; } #endif @@ -1016,18 +1048,28 @@ static int ssi_lock(FAR struct spi_dev_s *dev, bool lock) * Returned Value: * Returns the actual frequency selected * + * Assumption: + * Caller holds a lock on the SPI bus (if CONFIG_SPI_OWNBUS not defined) + * ****************************************************************************/ -static void ssi_setfrequencyinternal(struct lm3s_ssidev_s *priv, uint32_t frequency) +static uint32_t ssi_setfrequencyinternal(struct lm3s_ssidev_s *priv, uint32_t frequency) { uint32_t maxdvsr; uint32_t cpsdvsr; uint32_t regval; uint32_t scr; + uint32_t actual; ssidbg("frequency: %d\n", frequency); - if (priv && frequency != priv->frequency) + DEBUGASSERT(frequency); + + /* Has the frequency changed? */ + +#ifndef CONFIG_SPI_OWNBUS + if (frequency != priv->frequency) { +#endif /* "The serial bit rate is derived by dividing down the input clock * (FSysClk). The clock is first divided by an even prescale value * CPSDVSR from 2 to 254, which is programmed in the SSI Clock Prescale @@ -1095,23 +1137,34 @@ static void ssi_setfrequencyinternal(struct lm3s_ssidev_s *priv, uint32_t freque /* Calcluate the actual frequency */ - priv->actual = SYSCLK_FREQUENCY / (cpsdvsr * (scr + 1)); + actual = SYSCLK_FREQUENCY / (cpsdvsr * (scr + 1)); + + /* Save the frequency selection so that subsequent reconfigurations will be + * faster. + */ + +#ifndef CONFIG_SPI_OWNBUS + priv->frequency = frequency; + priv->actual = actual; } + return priv->actual; +#else + return actual; +#endif } static uint32_t ssi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) { struct lm3s_ssidev_s *priv = (struct lm3s_ssidev_s *)dev; uint32_t enable; + uint32_t actual; /* NOTE that the SSI must be disabled when setting any configuration registers. */ - ssi_semtake(&priv->exclsem); enable = ssi_disable(priv); - ssi_setfrequencyinternal(priv, frequency); + actual = ssi_setfrequencyinternal(priv, frequency); ssi_enable(priv, enable); - ssi_semgive(&priv->exclsem); - return priv->actual; + return actual; } /**************************************************************************** @@ -1127,6 +1180,9 @@ static uint32_t ssi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) * Returned Value: * none * + * Assumption: + * Caller holds a lock on the SPI bus (if CONFIG_SPI_OWNBUS not defined) + * ****************************************************************************/ static void ssi_setmodeinternal(struct lm3s_ssidev_s *priv, enum spi_mode_e mode) @@ -1135,8 +1191,14 @@ static void ssi_setmodeinternal(struct lm3s_ssidev_s *priv, enum spi_mode_e mode uint32_t regval; ssidbg("mode: %d\n", mode); - if (priv && mode != priv->mode) + DEBUGASSERT(priv); + + /* Has the number of bits per word changed? */ + +#ifndef CONFIG_SPI_OWNBUS + if (mode != priv->mode) { +#endif /* Select the CTL register bits based on the selected mode */ switch (mode) @@ -1168,7 +1230,13 @@ static void ssi_setmodeinternal(struct lm3s_ssidev_s *priv, enum spi_mode_e mode regval |= modebits; ssi_putreg(priv, LM3S_SSI_CR0_OFFSET, regval); ssivdbg("CR0: %08x\n", regval); + + /* Save the mode so that subsequent re-configuratins will be faster */ + +#ifndef CONFIG_SPI_OWNBUS + priv->mode = mode; } +#endif } static void ssi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) @@ -1178,11 +1246,9 @@ static void ssi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) /* NOTE that the SSI must be disabled when setting any configuration registers. */ - ssi_semtake(&priv->exclsem); enable = ssi_disable(priv); ssi_setmodeinternal(priv, mode); ssi_enable(priv, enable); - ssi_semgive(&priv->exclsem); } /**************************************************************************** @@ -1198,6 +1264,9 @@ static void ssi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) * Returned Value: * none * + * Assumption: + * Caller holds a lock on the SPI bus (if CONFIG_SPI_OWNBUS not defined) + * ****************************************************************************/ static void ssi_setbitsinternal(struct lm3s_ssidev_s *priv, int nbits) @@ -1205,7 +1274,8 @@ static void ssi_setbitsinternal(struct lm3s_ssidev_s *priv, int nbits) uint32_t regval; ssidbg("nbits: %d\n", nbits); - if (priv && nbits != priv->nbits && nbits >=4 && nbits <= 16) + DEBUGASSERT(priv); + if (nbits != priv->nbits && nbits >=4 && nbits <= 16) { regval = ssi_getreg(priv, LM3S_SSI_CR0_OFFSET); regval &= ~SSI_CR0_DSS_MASK; @@ -1224,11 +1294,9 @@ static void ssi_setbits(FAR struct spi_dev_s *dev, int nbits) /* NOTE that the SSI must be disabled when setting any configuration registers. */ - ssi_semtake(&priv->exclsem); enable = ssi_disable(priv); ssi_setbitsinternal(priv, nbits); ssi_enable(priv, enable); - ssi_semgive(&priv->exclsem); } /**************************************************************************** @@ -1434,7 +1502,9 @@ FAR struct spi_dev_s *up_spiinitialize(int port) #ifndef CONFIG_SSI_POLLWAIT sem_init(&priv->xfrsem, 0, 0); #endif +#ifndef CONFIG_SPI_OWNBUS sem_init(&priv->exclsem, 0, 1); +#endif /* Set all CR1 fields to reset state. This will be master mode. */ diff --git a/nuttx/arch/arm/src/stm32/stm32_spi.c b/nuttx/arch/arm/src/stm32/stm32_spi.c index 4b50380eb..4605f8a30 100755 --- a/nuttx/arch/arm/src/stm32/stm32_spi.c +++ b/nuttx/arch/arm/src/stm32/stm32_spi.c @@ -120,10 +120,6 @@ struct stm32_spidev_s struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ uint32_t spibase; /* SPIn base address */ uint32_t spiclock; /* Clocking for the SPI module */ - uint32_t frequency; /* Requested clock frequency */ - uint32_t actual; /* Actual clock frequency */ - uint8_t nbits; /* Width of work in bits (8 or 16) */ - uint8_t mode; /* Mode 0,1,2,3 */ #ifdef CONFIG_STM32_SPI_INTERRUPTS uint8_t spiirq; /* SPI IRQ number */ #endif @@ -139,6 +135,10 @@ struct stm32_spidev_s #endif #ifndef CONFIG_SPI_OWNBUS sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t nbits; /* Width of word in bits (8 or 16) */ + uint8_t mode; /* Mode 0,1,2,3 */ #endif }; @@ -753,8 +753,10 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) /* Has the frequency changed? */ +#ifndef CONFIG_SPI_OWNBUS if (frequency != priv->frequency) { +#endif /* Choices are limited by PCLK frequency with a set of divisors */ if (frequency >= priv->spiclock >> 1) @@ -815,10 +817,19 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency) } spi_modifycr1(priv, setbits, SPI_CR1_BR_MASK); + + /* Save the frequency selection so that subsequent reconfigurations will be + * faster. + */ + +#ifndef CONFIG_SPI_OWNBUS priv->frequency = frequency; priv->actual = actual; } return priv->actual; +#else + return actual; +#endif } /************************************************************************************ @@ -844,8 +855,10 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) /* Has the mode changed? */ +#ifndef CONFIG_SPI_OWNBUS if (mode != priv->mode) { +#endif /* Yes... Set CR1 appropriately */ switch (mode) @@ -875,8 +888,13 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) } spi_modifycr1(priv, setbits, clrbits); + + /* Save the mode so that subsequent re-configuratins will be faster */ + +#ifndef CONFIG_SPI_OWNBUS priv->mode = mode; } +#endif } /************************************************************************************ @@ -902,8 +920,10 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) /* Has the number of bits changed? */ +#ifndef CONFIG_SPI_OWNBUS if (nbits != priv->nbits) { +#endif /* Yes... Set CR1 appropriately */ switch (nbits) @@ -923,8 +943,13 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits) } spi_modifycr1(priv, setbits, clrbits); + + /* Save the selection so the subsequence re-configurations will be faster */ + +#ifndef CONFIG_SPI_OWNBUS priv->nbits = nbits; } +#endif } /************************************************************************************ @@ -1183,12 +1208,14 @@ static void spi_portinitialize(FAR struct stm32_spidev_s *priv) setbits = SPI_CR1_MSTR|SPI_CR1_SSI|SPI_CR1_SSM; spi_modifycr1(priv, setbits, clrbits); - priv->nbits = 8; - priv->mode = SPIDEV_MODE0; +#ifndef CONFIG_SPI_OWNBUS + priv->frequency = 0; + priv->nbits = 8; + priv->mode = SPIDEV_MODE0; +#endif /* Select a default frequency of approx. 400KHz */ - priv->frequency = 0; spi_setfrequency((FAR struct spi_dev_s *)priv, 400000); /* CRCPOLY configuration */ diff --git a/nuttx/configs/lm3s6965-ek/src/lm3s6965ek_internal.h b/nuttx/configs/lm3s6965-ek/src/lm3s6965ek_internal.h index 07a0aa3fe..17a791ea4 100755 --- a/nuttx/configs/lm3s6965-ek/src/lm3s6965ek_internal.h +++ b/nuttx/configs/lm3s6965-ek/src/lm3s6965ek_internal.h @@ -135,7 +135,7 @@ extern void weak_function lm3s_ssiinitialize(void); ************************************************************************************/
#ifdef CONFIG_NX_LCDDRIVER
-extern void weak_function lm3s_oledinitialize(void);
+extern void lm3s_oledinitialize(void);
#endif
#endif /* __ASSEMBLY__ */
diff --git a/nuttx/configs/lm3s6965-ek/src/up_boot.c b/nuttx/configs/lm3s6965-ek/src/up_boot.c index 3e8f54fbf..d4ab263d5 100755 --- a/nuttx/configs/lm3s6965-ek/src/up_boot.c +++ b/nuttx/configs/lm3s6965-ek/src/up_boot.c @@ -85,10 +85,7 @@ void lm3s_boardinitialize(void) /* Configure the OLED for use */
#ifdef CONFIG_NX_LCDDRIVER
- if (lm3s_oledinitialize)
- {
- lm3s_oledinitialize();
- }
+ lm3s_oledinitialize();
#endif
#endif
diff --git a/nuttx/drivers/lcd/p14201.c b/nuttx/drivers/lcd/p14201.c index 73e303979..abaad4f46 100755 --- a/nuttx/drivers/lcd/p14201.c +++ b/nuttx/drivers/lcd/p14201.c @@ -769,6 +769,7 @@ static int rit_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, rit_sndcmd(priv, g_horzinc, sizeof(g_horzinc)); rit_snddata(priv, buffer, npixels >> 1); } +#endif return OK; } |