9
0
Fork 0

PIC32MZ SPI: Implement exchange() method; update SPI_REGDEBUG configuration and clean up implementation

This commit is contained in:
Gregory Nutt 2015-03-03 12:23:27 -06:00
parent 3623faa192
commit 93b35db978
3 changed files with 425 additions and 181 deletions

View File

@ -549,7 +549,7 @@ static void pic32mx_checkreg(uint32_t addr, uint32_t val, bool iswrite)
count = 0;
prevwrite = iswrite;
/* Show the new regisgter access */
/* Show the new register access */
pic32mx_printreg(addr, val, iswrite);
}

View File

@ -317,15 +317,25 @@ config PIC32MZ_GPIOIRQ_PORTK
endif # PIC32MZ_GPIOIRQ
menu "SPI Driver Configuration"
depends on PIC32MZ_SPI && EXPERIMENTAL
depends on PIC32MZ_SPI
config PIC32MZ_SPI_INTERRUPTS
bool "SPI Interrupt Driven"
default n
depends on EXPERIMENTAL
config PIC32MZ_SPI_ENHBUF
bool "SPI Enhanced Buffer Mode"
default n
depends on EXPERIMENTAL
config PIC32MZ_SPI_REGDEBUG
bool "SPI Register level debug"
depends on DEBUG
default n
---help---
Output detailed register-level SPI device debug information.
Requires also DEBUG.
endmenu # SPI Driver Configuration

View File

@ -111,8 +111,15 @@ struct pic32mz_dev_s
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 to 16) */
uint8_t mode; /* Mode 0,1,2,3 */
#endif
uint8_t nbits; /* Width of word in bits (8 to 16) */
#ifdef CONFIG_PIC32MZ_SPI_REGDEBUG
bool wrlast; /* Last was a write */
uint32_t addrlast; /* Last address */
uint32_t vallast; /* Last value */
int ntimes; /* Number of times */
#endif
};
@ -121,10 +128,27 @@ struct pic32mz_dev_s
****************************************************************************/
/* Low-level register access */
#ifdef CONFIG_PIC32MZ_SPI_REGDEBUG
static bool spi_checkreg(FAR struct pic32mz_dev_s *priv,
uintptr_t regaddr, uint32_t regvaql, bool wr);
static uint32_t spi_getreg(FAR struct pic32mz_dev_s *priv,
unsigned int offset);
static void spi_putreg(FAR struct pic32mz_dev_s *priv,
static void spi_putaddr(FAR struct pic32mz_dev_s *priv,
uintptr_t regaddr, uint32_t value);
#else
static inline uint32_t spi_getreg(FAR struct pic32mz_dev_s *priv,
unsigned int offset);
static inline void spi_putaddr(FAR struct pic32mz_dev_s *priv,
uintptr_t regaddr, uint32_t value);
#endif
static inline void spi_putreg(FAR struct pic32mz_dev_s *priv,
unsigned int offset, uint32_t value);
static void spi_exchange16(FAR struct pic32mz_dev_s *priv,
FAR const uint16_t *txbuffer, FAR uint16_t *rxbuffer,
size_t nwords);
static void spi_exchange8(FAR struct pic32mz_dev_s *priv,
FAR const uint8_t *txbuffer, FAR uint8_t *rxbuffer,
size_t nbytes);
/* SPI methods */
@ -135,8 +159,15 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency);
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 uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t ch);
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords);
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords);
static void spi_exchange(FAR struct spi_dev_s *dev,
FAR const void *txbuffer, FAR void *rxbuffer,
size_t nwords);
#ifndef CONFIG_SPI_EXCHANGE
static void spi_sndblock(FAR struct spi_dev_s *dev,
FAR const void *buffer, size_t nwords);
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
size_t nwords);
#endif
/****************************************************************************
* Private Data
@ -158,8 +189,12 @@ static const struct spi_ops_s g_spi1ops =
.cmddata = pic32mz_spi1cmddata,
#endif
.send = spi_send,
#ifdef CONFIG_SPI_EXCHANGE
.exchange = spi_exchange,
#else
.sndblock = spi_sndblock,
.recvblock = spi_recvblock,
#endif
#ifdef CONFIG_SPI_CALLBACK
.registercallback = pic32mz_spi1register, /* Provided externally */
#else
@ -202,8 +237,12 @@ static const struct spi_ops_s g_spi2ops =
.cmddata = pic32mz_spi2cmddata,
#endif
.send = spi_send,
#ifdef CONFIG_SPI_EXCHANGE
.exchange = spi_exchange,
#else
.sndblock = spi_sndblock,
.recvblock = spi_recvblock,
#endif
#ifdef CONFIG_SPI_CALLBACK
.registercallback = pic32mz_spi2register, /* Provided externally */
#else
@ -246,8 +285,12 @@ static const struct spi_ops_s g_spi3ops =
.cmddata = pic32mz_spi3cmddata,
#endif
.send = spi_send,
#ifdef CONFIG_SPI_EXCHANGE
.exchange = spi_exchange,
#else
.sndblock = spi_sndblock,
.recvblock = spi_recvblock,
#endif
#ifdef CONFIG_SPI_CALLBACK
.registercallback = pic32mz_spi3register, /* Provided externally */
#else
@ -290,8 +333,12 @@ static const struct spi_ops_s g_spi4ops =
.cmddata = pic32mz_spi4cmddata,
#endif
.send = spi_send,
#ifdef CONFIG_SPI_EXCHANGE
.exchange = spi_exchange,
#else
.sndblock = spi_sndblock,
.recvblock = spi_recvblock,
#endif
#ifdef CONFIG_SPI_CALLBACK
.registercallback = pic32mz_spi4register, /* Provided externally */
#else
@ -334,8 +381,12 @@ static const struct spi_ops_s g_spi5ops =
.cmddata = pic32mz_spi5cmddata,
#endif
.send = spi_send,
#ifdef CONFIG_SPI_EXCHANGE
.exchange = spi_exchange,
#else
.sndblock = spi_sndblock,
.recvblock = spi_recvblock,
#endif
#ifdef CONFIG_SPI_CALLBACK
.registercallback = pic32mz_spi5register, /* Provided externally */
#else
@ -378,8 +429,12 @@ static const struct spi_ops_s g_spi6ops =
.cmddata = pic32mz_spi6cmddata,
#endif
.send = spi_send,
#ifdef CONFIG_SPI_EXCHANGE
.exchange = spi_exchange,
#else
.sndblock = spi_sndblock,
.recvblock = spi_recvblock,
#endif
#ifdef CONFIG_SPI_CALLBACK
.registercallback = pic32mz_spi6register, /* Provided externally */
#else
@ -415,6 +470,62 @@ static struct pic32mz_dev_s g_spi6dev =
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: spi_checkreg
*
* Description:
* Check if the current register access is a duplicate of the preceding.
*
* Input Parameters:
* priv - SPI driver instance
* regaddr - The address of the register to write to
* regval - The value to be written
* wr - True: write access
*
* Returned Value:
* true: This is the first register access of this type.
* false: This is the same as the preceding register access.
*
****************************************************************************/
#ifdef CONFIG_PIC32MZ_SPI_REGDEBUG
static bool spi_checkreg(struct pic32mz_dev_s *priv, uintptr_t regaddr,
uint32_t regval, bool wr)
{
if (wr == priv->wrlast && /* Same kind of access? */
regval == priv->vallast && /* Same value? */
regaddr == priv->addrlast) /* Same address? */
{
/* Yes, then just keep a count of the number of times we did this. */
priv->ntimes++;
return false;
}
else
{
/* Did we do the previous operation more than once? */
if (priv->ntimes > 0)
{
/* Yes... show how many times we did it */
lldbg("...[Repeats %d times]...\n", priv->ntimes);
}
/* Save information about the new access */
priv->wrlast = wr;
priv->vallast = regval;
priv->addrlast = regaddr;
priv->ntimes = 0;
}
/* Return true if this is the first time that we have done this operation */
return true;
}
#endif
/****************************************************************************
* Name: spi_getreg
*
@ -430,73 +541,84 @@ static struct pic32mz_dev_s g_spi6dev =
*
****************************************************************************/
#ifdef CONFIG_SPI_REGDEBUG
static uint32_t spi_getreg(FAR struct pic32mz_dev_s *priv, unsigned int offset)
#ifdef CONFIG_PIC32MZ_SPI_REGDEBUG
static uint32_t spi_getreg(FAR struct pic32mz_dev_s *priv,
unsigned int offset)
{
/* Last address, value, and count */
uintptr_t regaddr;
uint32_t regval;
static uint32_t prevaddr = 0;
static uint32_t prevalue = 0;
static uint32_t count = 0;
/* Read the register value */
/* New address and value */
regaddr = priv->config->base + offset;
regval = getreg32(regaddr);
uint32_t addr;
uint32_t value;
/* Should we print something? */
/* Read the value from the register */
addr = priv->config->base + offset;
value = getreg32(addr);
/* Is this the same value that we read from the same register last time?
* Are we polling the register? If so, suppress some of the output.
*/
if (addr == prevaddr && value == prevalue)
if (spi_checkreg(priv, regaddr, regval, false))
{
if (count == 0xffffffff || ++count > 3)
{
if (count == 4)
{
lldbg("...\n");
}
return value;
}
/* Yes.. */
lldbg("%08lx->%08lx\n",
(unsigned long)regaddr, (unsigned long)regval);
}
/* No this is a new address or value */
/* Return the value read */
else
{
/* Did we print "..." for the previous value? */
if (count > 3)
{
/* Yes.. then show how many times the value repeated */
lldbg("[repeats %d more times]\n", count-3);
}
/* Save the new address, value, and count */
prevaddr = addr;
prevalue = value;
count = 1;
}
/* Show the register value read */
lldbg("%08x->%08x\n", addr, value);
return value;
return regval;
}
#else
static uint32_t spi_getreg(FAR struct pic32mz_dev_s *priv, unsigned int offset)
static inline uint32_t spi_getreg(FAR struct pic32mz_dev_s *priv,
unsigned int offset)
{
return getreg32(priv->config->base + offset);
}
#endif
/****************************************************************************
* Name: spi_putaddr
*
* Description:
* Write a 32-bit value value an absolute address
*
* Input Parameters:
* priv - A pointer to a PIC32MZ SPI state structure
* regaddr - Address to write to
* regval - The value to write to the SPI register
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_PIC32MZ_SPI_REGDEBUG
static void spi_putaddr(FAR struct pic32mz_dev_s *priv, uintptr_t regaddr,
uint32_t regval)
{
/* Should we print something? */
if (spi_checkreg(priv, regaddr, regval, true))
{
/* Yes.. */
lldbg("%08lx<-%08lx\n",
(unsigned long)regaddr, (unsigned long)regval);
}
/* Write the value to the register */
putreg32(regval, regaddr);
}
#else
static inline void spi_putaddr(FAR struct pic32mz_dev_s *priv,
uintptr_t regaddr, uint32_t regval)
{
/* Write the value to the register */
putreg32(regval, regaddr);
}
#endif
/****************************************************************************
* Name: spi_putreg
*
@ -513,32 +635,154 @@ static uint32_t spi_getreg(FAR struct pic32mz_dev_s *priv, unsigned int offset)
*
****************************************************************************/
#ifdef CONFIG_SPI_REGDEBUG
static void spi_putreg(FAR struct pic32mz_dev_s *priv, unsigned int offset,
uint32_t value)
static inline void spi_putreg(FAR struct pic32mz_dev_s *priv,
unsigned int offset, uint32_t regval)
{
uint32_t addr;
/* Get the address to write to */
addr = priv->config->base + offset;
/* Show the register value being written */
lldbg("%08x<-%08x\n", addr, value);
/* Then do the write */
putreg32(value, addr);
spi_putaddr(priv, priv->config->base + offset, regval);
}
/****************************************************************************
* Name: spi_exchange8
*
* Description:
* Exchange a block of 8-bit data from SPI.
*
* Input Parameters:
* dev - Device-specific state data
* txbuffer - A pointer to the buffer of data to be sent
* rxbuffer - A pointer to the buffer in which to receive data
* nwords - the length of byres that to be exchanged
*
* Returned Value:
* None
*
****************************************************************************/
static void spi_exchange8(FAR struct pic32mz_dev_s *priv,
FAR const uint8_t *txbuffer, FAR uint8_t *rxbuffer,
size_t nbytes)
{
uint32_t regval;
uint8_t data;
spivdbg("nbytes: %d\n", nbytes);
while (nbytes)
{
/* Write the data to transmitted to the SPI Data Register */
if (txbuffer)
{
data = *txbuffer++;
}
else
{
data = 0xff;
}
spi_putreg(priv, PIC32MZ_SPI_BUF_OFFSET, (uint32_t)data);
#ifdef CONFIG_PIC32MZ_SPI_ENHBUF
/* Wait for the SPIRBE bit in the SPI Status Register to be set to 0. In
* enhanced buffer mode, the SPIRBE bit will be cleared in when the
* receive buffer is not empty.
*/
while ((spi_getreg(priv, PIC32MZ_SPI_STAT_OFFSET) & SPI_STAT_SPIRBE) != 0);
#else
static void spi_putreg(FAR struct pic32mz_dev_s *priv, unsigned int offset,
uint32_t value)
{
putreg32(value, priv->config->base + offset);
}
/* Wait for the SPIRBF bit in the SPI Status Register to be set to 1. In
* normal mode, the SPIRBF bit will be set when receive data is available.
*/
while ((spi_getreg(priv, PIC32MZ_SPI_STAT_OFFSET) & SPI_STAT_SPIRBF) == 0);
#endif
/* Read from the buffer register to clear the status bit */
regval = spi_getreg(priv, PIC32MZ_SPI_BUF_OFFSET);
if (rxbuffer)
{
*rxbuffer++ = (uint8_t)regval;
}
else
{
UNUSED(regval);
}
nbytes--;
}
}
/****************************************************************************
* Name: spi_exchange16
*
* Description:
* Exchange a block of 16-bit data from SPI.
*
* Input Parameters:
* dev - Device-specific state data
* txbuffer - A pointer to the buffer of data to be sent
* rxbuffer - A pointer to the buffer in which to recieve data
* nwords - the length of data that to be exchanged in units of words.
*
* Returned Value:
* None
*
****************************************************************************/
static void spi_exchange16(FAR struct pic32mz_dev_s *priv,
FAR const uint16_t *txbuffer,
FAR uint16_t *rxbuffer, size_t nwords)
{
uint32_t regval;
uint16_t data;
spivdbg("nwords: %d\n", nwords);
while (nwords)
{
/* Write the data to transmitted to the SPI Data Register */
if (txbuffer)
{
data = *txbuffer++;
}
else
{
data = 0xffff;
}
spi_putreg(priv, PIC32MZ_SPI_BUF_OFFSET, (uint32_t)data);
#ifdef CONFIG_PIC32MZ_SPI_ENHBUF
/* Wait for the SPIRBE bit in the SPI Status Register to be set to 0. In
* enhanced buffer mode, the SPIRBE bit will be cleared in when the
* receive buffer is not empty.
*/
while ((spi_getreg(priv, PIC32MZ_SPI_STAT_OFFSET) & SPI_STAT_SPIRBE) != 0);
#else
/* Wait for the SPIRBF bit in the SPI Status Register to be set to 1. In
* normal mode, the SPIRBF bit will be set when receive data is available.
*/
while ((spi_getreg(priv, PIC32MZ_SPI_STAT_OFFSET) & SPI_STAT_SPIRBF) == 0);
#endif
/* Read from the buffer register to clear the status bit */
regval = spi_getreg(priv, PIC32MZ_SPI_BUF_OFFSET);
if (rxbuffer)
{
*rxbuffer++ = (uint16_t)regval;
}
else
{
UNUSED(regval);
}
nwords--;
}
}
/****************************************************************************
* Name: spi_lock
*
@ -789,19 +1033,13 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
uint32_t setting;
uint32_t regval;
#ifndef CONFIG_SPI_OWNBUS
spivdbg("Old nbits: %d New nbits: %d\n", priv->nbits, nbits);
#else
spivdbg("New nbits: %d\n", nbits);
#endif
/* Has the number of bits changed? */
DEBUGASSERT(priv && nbits > 7 && nbits < 17);
#ifndef CONFIG_SPI_OWNBUS
if (nbits != priv->nbits)
{
#endif
/* Yes... Set the CON register appropriately */
if (nbits == 8)
@ -828,12 +1066,12 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
regval = spi_getreg(priv, PIC32MZ_SPI_CON_OFFSET);
spivdbg("CON: %08x\n", regval);
/* Save the selection so the subsequence re-configurations will be faster */
/* Save the selection so the subsequence re-configurations will be
* faster
*/
#ifndef CONFIG_SPI_OWNBUS
priv->nbits = nbits;
}
#endif
}
/****************************************************************************
@ -856,30 +1094,78 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
{
FAR struct pic32mz_dev_s *priv = (FAR struct pic32mz_dev_s *)dev;
spivdbg("wd: %04x\n", wd);
DEBUGASSERT(priv);
if (priv->nbits > 8)
{
uint16_t txword;
uint16_t rxword;
/* Write the data to transmitted to the SPI Data Register */
/* spi_exchange16() can do this. */
spi_putreg(priv, PIC32MZ_SPI_BUF_OFFSET, (uint32_t)wd);
txword = wd;
rxword = 0;
spi_exchange16(priv, &txword, &rxword, 1);
#ifdef CONFIG_PIC32MZ_SPI_ENHBUF
/* Wait for the SPIRBE bit in the SPI Status Register to be set to 0. In
* enhanced buffer mode, the SPIRBE bit will be cleared in when the
* receive buffer is not empty.
*/
spivdbg("Sent %04x received %04x\n", txword, rxword);
return rxword;
}
else
{
uint8_t txbyte;
uint8_t rxbyte;
while ((spi_getreg(priv, PIC32MZ_SPI_STAT_OFFSET) & SPI_STAT_SPIRBE) != 0);
#else
/* Wait for the SPIRBF bit in the SPI Status Register to be set to 1. In
* normal mode, the SPIRBF bit will be set when receive data is available.
*/
/* spi_exchange8() can do this. */
while ((spi_getreg(priv, PIC32MZ_SPI_STAT_OFFSET) & SPI_STAT_SPIRBF) == 0);
#endif
txbyte = (uint8_t)wd;
rxbyte = (uint8_t)0;
spi_exchange8(priv, &txbyte, &rxbyte, 1);
/* Return the SPI data */
spivdbg("Sent %02x received %02x\n", txbyte, rxbyte);
return (uint16_t)rxbyte;
}
}
return (uint16_t)spi_getreg(priv, PIC32MZ_SPI_BUF_OFFSET);
/****************************************************************************
* Name: spi_exchange
*
* Description:
* Exchange a block of data from SPI..
*
* Input Parameters:
* dev - Device-specific state data
* txbuffer - A pointer to the buffer of data to be sent
* rxbuffer - A pointer to the buffer in which to recieve data
* nwords - the length of data that to be exchanged 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
*
* Returned Value:
* None
*
****************************************************************************/
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
FAR void *rxbuffer, size_t nwords)
{
FAR struct pic32mz_dev_s *priv = (FAR struct pic32mz_dev_s *)dev;
DEBUGASSERT(priv);
if (priv->nbits > 8)
{
/* spi_exchange16() can do this. */
spi_exchange16(priv, (FAR const uint16_t *)txbuffer,
(FAR uint16_t *)rxbuffer, nwords);
}
else
{
/* spi_exchange8() can do this. */
spi_exchange8(priv, (FAR const uint8_t *)txbuffer,
(FAR uint8_t *)rxbuffer, nwords);
}
}
/*************************************************************************
@ -891,53 +1177,26 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
* Input Parameters:
* dev - Device-specific state data
* buffer - A pointer to the buffer of data to be sent
* 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
* 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
*
* Returned Value:
* None
*
****************************************************************************/
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords)
#ifndef CONFIG_SPI_EXCHANGE
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
size_t nwords)
{
FAR struct pic32mz_dev_s *priv = (FAR struct pic32mz_dev_s *)dev;
FAR uint8_t *ptr = (FAR uint8_t*)buffer;
uint32_t regval;
uint8_t data;
/* spi_exchange() can do this. */
spivdbg("nwords: %d\n", nwords);
while (nwords)
{
/* Write the data to transmitted to the SPI Data Register */
data = *ptr++;
spi_putreg(priv, PIC32MZ_SPI_BUF_OFFSET, (uint32_t)data);
#ifdef CONFIG_PIC32MZ_SPI_ENHBUF
/* Wait for the SPIRBE bit in the SPI Status Register to be set to 0. In
* enhanced buffer mode, the SPIRBE bit will be cleared in when the
* receive buffer is not empty.
*/
while ((spi_getreg(priv, PIC32MZ_SPI_STAT_OFFSET) & SPI_STAT_SPIRBE) != 0);
#else
/* Wait for the SPIRBF bit in the SPI Status Register to be set to 1. In
* normal mode, the SPIRBF bit will be set when receive data is available.
*/
while ((spi_getreg(priv, PIC32MZ_SPI_STAT_OFFSET) & SPI_STAT_SPIRBF) == 0);
#endif
/* Read from the buffer register to clear the status bit */
regval = spi_getreg(priv, PIC32MZ_SPI_BUF_OFFSET);
UNUSED(regval);
nwords--;
}
spi_exchange(dev, buffer, NULL, nwords);
}
#endif
/****************************************************************************
* Name: spi_recvblock
@ -946,53 +1205,28 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
* Revice a block of data from SPI
*
* Input Parameters:
* dev - Device-specific state data
* dev - Device-specific state data
* buffer - A pointer to the buffer in which to recieve 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
*
****************************************************************************/
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords)
#ifndef CONFIG_SPI_EXCHANGE
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
size_t nwords)
{
FAR struct pic32mz_dev_s *priv = (FAR struct pic32mz_dev_s *)dev;
FAR uint8_t *ptr = (FAR uint8_t*)buffer;
/* spi_exchange() can do this. */
spivdbg("nwords: %d\n", nwords);
while (nwords)
{
/* Write some dummy data to the SPI Data Register in order to clock the
* read data.
*/
spi_putreg(priv, PIC32MZ_SPI_BUF_OFFSET, 0xff);
#ifdef CONFIG_PIC32MZ_SPI_ENHBUF
/* Wait for the SPIRBE bit in the SPI Status Register to be set to 0. In
* enhanced buffer mode, the SPIRBE bit will be cleared in when the
* receive buffer is not empty.
*/
while ((spi_getreg(priv, PIC32MZ_SPI_STAT_OFFSET) & SPI_STAT_SPIRBE) != 0);
#else
/* Wait for the SPIRBF bit in the SPI Status Register to be set to 1. In
* normal mode, the SPIRBF bit will be set when receive data is available.
*/
while ((spi_getreg(priv, PIC32MZ_SPI_STAT_OFFSET) & SPI_STAT_SPIRBF) == 0);
#endif
/* Read the received data from the SPI Data Register */
*ptr++ = (uint8_t)spi_getreg(priv, PIC32MZ_SPI_BUF_OFFSET);
nwords--;
}
spi_exchange(dev, NULL, buffer, nwords);
}
#endif
/****************************************************************************
* Public Functions
@ -1097,8 +1331,8 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
* managed as GPIOs; CLK (output) pins are not selectable.
*/
putreg32((uint32_t)priv->config->sdipps, regaddr);
putreg32((uint32_t)priv->config->sdopps, priv->config->sdoreg);
spi_putaddr(priv, regaddr, (uint32_t)priv->config->sdipps);
spi_putaddr(priv, priv->config->sdoreg, (uint32_t)priv->config->sdopps);
#ifdef CONFIG_PIC32MZ_SPI_INTERRUPTS
/* Attach the interrupt handlers. We do this early to make sure that the