Make better use of these deep FIFOs
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2958 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
11440645f9
commit
63d189c52a
@ -72,6 +72,10 @@
|
|||||||
# undef CONFIG_DEBUG_SPIREGS
|
# undef CONFIG_DEBUG_SPIREGS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* FIFOs ****************************************************************************/
|
||||||
|
|
||||||
|
#define SPI_FIFO_DEPTH 64 /* 64 words deep (8- or 16-bit words) */
|
||||||
|
|
||||||
/* Timing ***************************************************************************/
|
/* Timing ***************************************************************************/
|
||||||
|
|
||||||
#define SPI_MAX_DIVIDER 65024 /* = 254 * (255 + 1) */
|
#define SPI_MAX_DIVIDER 65024 /* = 254 * (255 + 1) */
|
||||||
@ -118,7 +122,7 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequenc
|
|||||||
static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
|
static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
|
||||||
static void spi_setbits(FAR struct spi_dev_s *dev, int nbits);
|
static void spi_setbits(FAR struct spi_dev_s *dev, int nbits);
|
||||||
static uint8_t spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
|
static uint8_t spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
|
||||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd);
|
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t word);
|
||||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||||
FAR void *rxbuffer, size_t nwords);
|
FAR void *rxbuffer, size_t nwords);
|
||||||
#ifndef CONFIG_SPI_EXCHANGE
|
#ifndef CONFIG_SPI_EXCHANGE
|
||||||
@ -376,16 +380,13 @@ static inline void spi_select_slave(FAR struct lpc313x_spidev_s *priv, uint8_t s
|
|||||||
|
|
||||||
static inline uint16_t spi_readword(FAR struct lpc313x_spidev_s *priv)
|
static inline uint16_t spi_readword(FAR struct lpc313x_spidev_s *priv)
|
||||||
{
|
{
|
||||||
/* Wait until the receive buffer is not empty */
|
/* Wait until the RX FIFO is not empty */
|
||||||
|
|
||||||
while ((spi_getreg(LPC313X_SPI_STATUS) & SPI_STATUS_RXFIFOEMPTY) != 0)
|
while ((spi_getreg(LPC313X_SPI_STATUS) & SPI_STATUS_RXFIFOEMPTY) != 0);
|
||||||
;
|
|
||||||
|
|
||||||
/* Then return the received word */
|
/* Then return the received word */
|
||||||
|
|
||||||
uint32_t val = spi_getreg(LPC313X_SPI_FIFODATA);
|
return (uint16_t)spi_getreg(LPC313X_SPI_FIFODATA);
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
@ -405,10 +406,9 @@ static inline uint16_t spi_readword(FAR struct lpc313x_spidev_s *priv)
|
|||||||
|
|
||||||
static inline void spi_writeword(FAR struct lpc313x_spidev_s *priv, uint16_t word)
|
static inline void spi_writeword(FAR struct lpc313x_spidev_s *priv, uint16_t word)
|
||||||
{
|
{
|
||||||
/* Wait until the transmit buffer is not full */
|
/* Wait until the TX FIFO is not full */
|
||||||
|
|
||||||
while ((spi_getreg(LPC313X_SPI_STATUS) & SPI_STATUS_TXFIFOFULL) != 0)
|
while ((spi_getreg(LPC313X_SPI_STATUS) & SPI_STATUS_TXFIFOFULL) != 0);
|
||||||
;
|
|
||||||
|
|
||||||
/* Then send the word */
|
/* Then send the word */
|
||||||
|
|
||||||
@ -701,21 +701,21 @@ static uint8_t spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid)
|
|||||||
* Exchange one word on SPI
|
* Exchange one word on SPI
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* dev - Device-specific state data
|
* dev - Device-specific state data
|
||||||
* wd - The word to send. the size of the data is determined by the
|
* word - The word to send. the size of the data is determined by the
|
||||||
* number of bits selected for the SPI interface.
|
* number of bits selected for the SPI interface.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* response
|
* response
|
||||||
*
|
*
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t word)
|
||||||
{
|
{
|
||||||
FAR struct lpc313x_spidev_s *priv = (FAR struct lpc313x_spidev_s *)dev;
|
FAR struct lpc313x_spidev_s *priv = (FAR struct lpc313x_spidev_s *)dev;
|
||||||
DEBUGASSERT(priv);
|
DEBUGASSERT(priv);
|
||||||
|
|
||||||
spi_writeword(priv, wd);
|
spi_writeword(priv, word);
|
||||||
return spi_readword(priv);
|
return spi_readword(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -743,6 +743,9 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||||||
FAR void *rxbuffer, size_t nwords)
|
FAR void *rxbuffer, size_t nwords)
|
||||||
{
|
{
|
||||||
FAR struct lpc313x_spidev_s *priv = (FAR struct lpc313x_spidev_s *)dev;
|
FAR struct lpc313x_spidev_s *priv = (FAR struct lpc313x_spidev_s *)dev;
|
||||||
|
unsigned int maxtx;
|
||||||
|
unsigned int ntx;
|
||||||
|
|
||||||
DEBUGASSERT(priv);
|
DEBUGASSERT(priv);
|
||||||
|
|
||||||
/* 8- or 16-bit mode? */
|
/* 8- or 16-bit mode? */
|
||||||
@ -755,21 +758,35 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||||||
uint16_t *dest = (uint16_t*)rxbuffer;
|
uint16_t *dest = (uint16_t*)rxbuffer;
|
||||||
uint16_t word;
|
uint16_t word;
|
||||||
|
|
||||||
while (nwords-- > 0)
|
while (nwords > 0)
|
||||||
{
|
{
|
||||||
/* Get the next word to write. Is there a source buffer? */
|
/* Fill up the TX FIFO */
|
||||||
|
|
||||||
word = src ? *src++ : 0xffff;
|
maxtx = nwords > SPI_FIFO_DEPTH ? SPI_FIFO_DEPTH : nwords;
|
||||||
|
for (ntx = 0; ntx < maxtx; ntx++)
|
||||||
/* Exchange one word */
|
|
||||||
|
|
||||||
word = spi_send(dev, word);
|
|
||||||
|
|
||||||
/* Is there a buffer to receive the return value? */
|
|
||||||
|
|
||||||
if (dest)
|
|
||||||
{
|
{
|
||||||
*dest++ = word;
|
/* Get the next word to write. Is there a source buffer? */
|
||||||
|
|
||||||
|
word = src ? *src++ : 0xffff;
|
||||||
|
|
||||||
|
/* Then send the word */
|
||||||
|
|
||||||
|
spi_writeword(priv, word);
|
||||||
|
}
|
||||||
|
nwords -= maxtx;
|
||||||
|
|
||||||
|
/* Then empty the RX FIFO */
|
||||||
|
|
||||||
|
while (ntx-- > 0)
|
||||||
|
{
|
||||||
|
word = spi_readword(priv);
|
||||||
|
|
||||||
|
/* Is there a buffer to receive the return value? */
|
||||||
|
|
||||||
|
if (dest)
|
||||||
|
{
|
||||||
|
*dest++ = word;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -781,21 +798,35 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||||||
uint8_t *dest = (uint8_t*)rxbuffer;
|
uint8_t *dest = (uint8_t*)rxbuffer;
|
||||||
uint8_t word;
|
uint8_t word;
|
||||||
|
|
||||||
while (nwords-- > 0)
|
while (nwords > 0)
|
||||||
{
|
{
|
||||||
/* Get the next word to write. Is there a source buffer? */
|
/* Fill up the TX FIFO */
|
||||||
|
|
||||||
word = src ? *src++ : 0xff;
|
maxtx = nwords > SPI_FIFO_DEPTH ? SPI_FIFO_DEPTH : nwords;
|
||||||
|
for (ntx = 0; ntx < maxtx; ntx++)
|
||||||
/* Exchange one word */
|
|
||||||
|
|
||||||
word = (uint8_t)spi_send(dev, (uint16_t)word);
|
|
||||||
|
|
||||||
/* Is there a buffer to receive the return value? */
|
|
||||||
|
|
||||||
if (dest)
|
|
||||||
{
|
{
|
||||||
*dest++ = word;
|
/* Get the next word to write. Is there a source buffer? */
|
||||||
|
|
||||||
|
word = src ? *src++ : 0xff;
|
||||||
|
|
||||||
|
/* Then send the word */
|
||||||
|
|
||||||
|
spi_writeword(priv, (uint16_t)word);
|
||||||
|
}
|
||||||
|
nwords -= maxtx;
|
||||||
|
|
||||||
|
/* Then empty the RX FIFO */
|
||||||
|
|
||||||
|
while (ntx-- > 0)
|
||||||
|
{
|
||||||
|
word = (uint8_t)spi_readword(priv);
|
||||||
|
|
||||||
|
/* Is there a buffer to receive the return value? */
|
||||||
|
|
||||||
|
if (dest)
|
||||||
|
{
|
||||||
|
*dest++ = word;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user