mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 10:58:49 +08:00
spi: change spi_send() interface to support of 32-bit word transfer
Signed-off-by: Petro Karashchenko <petro.karashchenko@gmail.com>
This commit is contained in:
parent
29be471f58
commit
3fa6baec98
47 changed files with 2154 additions and 1673 deletions
|
@ -1751,7 +1751,7 @@ The specific environmental definitions are unique for each board but should incl
|
|||
The definitions in that header file provide the common interface between NuttX and the architecture-specific implementation in <code>arch/</code>.
|
||||
</p>
|
||||
<blockquote><small>
|
||||
<code>up_</code> is supposed to stand for microprocessor; the <code>u</code> is like the Greek letter micron: <i>µ</i>. So it would be <code>µP</code> which is a common shortening of the word microprocessor. I don't like that name very much. I wish I would have used a more obvious prefix like <code>arch_</code> instead -- then I would not have to answer this question so often.
|
||||
<code>up_</code> is supposed to stand for microprocessor; the <code>u</code> is like the Greek letter micron: <i>ľ</i>. So it would be <code>ľP</code> which is a common shortening of the word microprocessor. I don't like that name very much. I wish I would have used a more obvious prefix like <code>arch_</code> instead -- then I would not have to answer this question so often.
|
||||
</small></blockquote>
|
||||
</li>
|
||||
<li>
|
||||
|
@ -5865,7 +5865,7 @@ int kbd_decode(FAR struct lib_instream_s *stream, FAR struct kbd_getstate_s *sta
|
|||
<code>void setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode);</code><br>
|
||||
<code>void setbits(FAR struct spi_dev_s *dev, int nbits);</code><br>
|
||||
<code>uint8_t status(FAR struct spi_dev_s *dev, uint32_t devid);</code><br>
|
||||
<code>uint16_t send(FAR struct spi_dev_s *dev, uint16_t wd);</code><br>
|
||||
<code>uint32_t send(FAR struct spi_dev_s *dev, uint32_t wd);</code><br>
|
||||
<code>void exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, FAR void *rxbuffer, size_t nwords);</code><br>
|
||||
<p><code>int registercallback(FAR struct spi_dev_s *dev, mediachange_t callback, void *arg);</code></p>
|
||||
</ul>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arm/arm/src/armv7-m/up_ramvec_initialize.c
|
||||
* arch/arm/src/armv7-m/up_ramvec_initialize.c
|
||||
*
|
||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
|
@ -81,14 +81,15 @@
|
|||
#endif
|
||||
|
||||
/* Alignment ****************************************************************/
|
||||
|
||||
/* Per the ARMv7M Architecture reference manual, the NVIC vector table
|
||||
* requires 7-bit address alignment (i.e, bits 0-6 of the address of the
|
||||
* vector table must be zero). In this case alignment to a 128 byte address
|
||||
* boundary is sufficient.
|
||||
*
|
||||
* Some parts, such as the LPC17xx/LPC40xx family, require alignment to a 256 byte
|
||||
* address boundary. Any other unusual alignment requirements for the vector
|
||||
* can be specified for a given architecture be redefining
|
||||
* Some parts, such as the LPC17xx/LPC40xx family, require alignment to a 256
|
||||
* byte address boundary. Any other unusual alignment requirements for the
|
||||
* vector can be specified for a given architecture be redefining
|
||||
* NVIC_VECTAB_TBLOFF_MASK in the chip-specific chip.h header file for the
|
||||
* appropriate mask.
|
||||
*/
|
||||
|
|
|
@ -117,8 +117,8 @@ struct cxd56_spidev_s
|
|||
|
||||
static inline uint32_t spi_getreg(FAR struct cxd56_spidev_s *priv,
|
||||
uint8_t offset);
|
||||
static inline void spi_putreg(FAR struct cxd56_spidev_s *priv, uint8_t offset,
|
||||
uint32_t value);
|
||||
static inline void spi_putreg(FAR struct cxd56_spidev_s *priv,
|
||||
uint8_t offset, uint32_t value);
|
||||
|
||||
/* DMA support */
|
||||
|
||||
|
@ -136,8 +136,8 @@ static void spi_dmatxsetup(FAR struct cxd56_spidev_s *priv,
|
|||
static void spi_dmarxsetup(FAR struct cxd56_spidev_s *priv,
|
||||
FAR const void *rxbuffer, size_t nwords);
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_dmasndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
|
||||
size_t nwords);
|
||||
static void spi_dmasndblock(FAR struct spi_dev_s *dev,
|
||||
FAR const void *buffer, size_t nwords);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -148,7 +148,7 @@ 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 uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
static void __unused spi_exchange(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer,
|
||||
FAR void *rxbuffer,
|
||||
|
@ -389,8 +389,8 @@ static inline uint32_t spi_getreg(FAR struct cxd56_spidev_s *priv,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_putreg(FAR struct cxd56_spidev_s *priv, uint8_t offset,
|
||||
uint32_t value)
|
||||
static inline void spi_putreg(FAR struct cxd56_spidev_s *priv,
|
||||
uint8_t offset, uint32_t value)
|
||||
{
|
||||
putreg32(value, priv->spibase + (uint32_t)offset);
|
||||
}
|
||||
|
@ -654,7 +654,7 @@ 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 wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
FAR struct cxd56_spidev_s *priv = (FAR struct cxd56_spidev_s *)dev;
|
||||
register uint32_t regval;
|
||||
|
@ -678,7 +678,7 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
|
||||
/* Write the byte to the TX FIFO */
|
||||
|
||||
spi_putreg(priv, CXD56_SPI_DR_OFFSET, (uint32_t)wd);
|
||||
spi_putreg(priv, CXD56_SPI_DR_OFFSET, wd);
|
||||
|
||||
/* Wait for the RX FIFO not empty */
|
||||
|
||||
|
@ -700,7 +700,7 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
|
||||
cxd56_spi_clock_gate_enable(priv->port);
|
||||
|
||||
return (uint16_t)regval;
|
||||
return regval;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -724,8 +724,9 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_do_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords)
|
||||
static void spi_do_exchange(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
size_t nwords)
|
||||
{
|
||||
FAR struct cxd56_spidev_s *priv = (FAR struct cxd56_spidev_s *)dev;
|
||||
uint32_t regval = 0;
|
||||
|
@ -793,7 +794,8 @@ static void spi_do_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
rxpending++;
|
||||
}
|
||||
|
||||
/* Now, read the RX data from the RX FIFO while the RX FIFO is not empty
|
||||
/* Now, read the RX data from the RX FIFO
|
||||
* while the RX FIFO is not empty
|
||||
*/
|
||||
|
||||
spiinfo("RX: rxpending: %d\n", rxpending);
|
||||
|
@ -1495,8 +1497,8 @@ static void spi_dmaexchange(FAR struct spi_dev_s *dev,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_dmasndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
|
||||
size_t nwords)
|
||||
static void spi_dmasndblock(FAR struct spi_dev_s *dev,
|
||||
FAR const void *buffer, size_t nwords)
|
||||
{
|
||||
spi_dmaexchange(dev, buffer, NULL, nwords);
|
||||
}
|
||||
|
@ -1510,8 +1512,7 @@ static void spi_dmasndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
|
|||
****************************************************************************/
|
||||
|
||||
static void spi_dmarecvblock(FAR struct spi_dev_s *dev,
|
||||
FAR const void *buffer,
|
||||
size_t nwords)
|
||||
FAR const void *buffer, size_t nwords)
|
||||
{
|
||||
spi_dmaexchange(dev, NULL, buffer, nwords);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arm/arm/src/efm32/efm32_spi.c
|
||||
* arch/arm/src/efm32/efm32_spi.c
|
||||
*
|
||||
* Copyright (C) 2014, 2016-2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2014 Bouteville Pierre-Noel. All rights reserved.
|
||||
|
@ -73,7 +73,9 @@
|
|||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* SPI DMA */
|
||||
|
||||
#ifndef CONFIG_EFM32_SPI_DMA_TIMEO_NSEC
|
||||
|
@ -145,6 +147,7 @@ struct efm32_spidev_s
|
|||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Low level SPI access */
|
||||
|
||||
static uint32_t spi_getreg(const struct efm32_spiconfig_s *config,
|
||||
|
@ -194,7 +197,7 @@ static uint8_t spi_status(struct spi_dev_s *dev, uint32_t devid);
|
|||
static int spi_cmddata(struct spi_dev_s *dev, uint32_t devid,
|
||||
bool cmd);
|
||||
#endif
|
||||
static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd);
|
||||
static uint32_t spi_send(struct spi_dev_s *dev, uint32_t wd);
|
||||
static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
||||
void *rxbuffer, size_t nwords);
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
|
@ -372,7 +375,8 @@ static void spi_rxflush(const struct efm32_spiconfig_s *config)
|
|||
{
|
||||
/* Loop while data is available */
|
||||
|
||||
while ((spi_getreg(config, EFM32_USART_STATUS_OFFSET) & USART_STATUS_RXDATAV) != 0)
|
||||
while ((spi_getreg(config, EFM32_USART_STATUS_OFFSET) &
|
||||
USART_STATUS_RXDATAV) != 0)
|
||||
{
|
||||
/* Read and discard the data */
|
||||
|
||||
|
@ -409,7 +413,8 @@ static void spi_dma_timeout(int argc, uint32_t arg1, ...)
|
|||
|
||||
/* Mark DMA timeout error and wakeup form RX and TX waiters */
|
||||
|
||||
DEBUGASSERT(priv->rxresult == EINPROGRESS || priv->txresult == EINPROGRESS);
|
||||
DEBUGASSERT(priv->rxresult == EINPROGRESS ||
|
||||
priv->txresult == EINPROGRESS);
|
||||
if (priv->rxresult == EINPROGRESS)
|
||||
{
|
||||
priv->rxresult = ETIMEDOUT;
|
||||
|
@ -815,7 +820,9 @@ static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency)
|
|||
*
|
||||
* CLKDIV = 256 * (fHFPERCLK/(2 * br) - 1)
|
||||
* or
|
||||
* CLKDIV = (256 * fHFPERCLK)/(2 * br) - 256 = (128 * fHFPERCLK)/br - 256
|
||||
* CLKDIV = (256 * fHFPERCLK)/(2 * br) - 256
|
||||
* or
|
||||
* CLKDIV = (128 * fHFPERCLK)/br - 256
|
||||
*
|
||||
* The basic problem with integer division in the above formula is that
|
||||
* the dividend (128 * fHFPERCLK) may become higher than max 32 bit
|
||||
|
@ -907,19 +914,23 @@ static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode)
|
|||
switch (mode)
|
||||
{
|
||||
case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */
|
||||
setting = USART_CTRL_CLKPOL_IDLELOW | USART_CTRL_CLKPHA_SAMPLELEADING;
|
||||
setting = USART_CTRL_CLKPOL_IDLELOW |
|
||||
USART_CTRL_CLKPHA_SAMPLELEADING;
|
||||
break;
|
||||
|
||||
case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */
|
||||
setting = USART_CTRL_CLKPOL_IDLELOW | USART_CTRL_CLKPHA_SAMPLETRAILING;
|
||||
setting = USART_CTRL_CLKPOL_IDLELOW |
|
||||
USART_CTRL_CLKPHA_SAMPLETRAILING;
|
||||
break;
|
||||
|
||||
case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */
|
||||
setting = USART_CTRL_CLKPOL_IDLEHIGH | USART_CTRL_CLKPHA_SAMPLELEADING;
|
||||
setting = USART_CTRL_CLKPOL_IDLEHIGH |
|
||||
USART_CTRL_CLKPHA_SAMPLELEADING;
|
||||
break;
|
||||
|
||||
case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */
|
||||
setting = USART_CTRL_CLKPOL_IDLEHIGH | USART_CTRL_CLKPHA_SAMPLETRAILING;
|
||||
setting = USART_CTRL_CLKPOL_IDLEHIGH |
|
||||
USART_CTRL_CLKPHA_SAMPLETRAILING;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1058,7 +1069,8 @@ static void spi_setbits(struct spi_dev_s *dev, int nbits)
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev, spi_hwfeatures_t features)
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev,
|
||||
spi_hwfeatures_t features)
|
||||
{
|
||||
#ifdef CONFIG_SPI_BITORDER
|
||||
struct efm32_spidev_s *priv = (struct efm32_spidev_s *)dev;
|
||||
|
@ -1194,11 +1206,11 @@ static int spi_cmddata(struct spi_dev_s *dev, uint32_t devid,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t spi_send(struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
struct efm32_spidev_s *priv = (struct efm32_spidev_s *)dev;
|
||||
const struct efm32_spiconfig_s *config;
|
||||
uint16_t ret;
|
||||
uint32_t ret;
|
||||
|
||||
DEBUGASSERT(priv && priv->config);
|
||||
config = priv->config;
|
||||
|
@ -1213,12 +1225,12 @@ static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd)
|
|||
|
||||
/* Write the data */
|
||||
|
||||
spi_putreg(config, EFM32_USART_TXDATA_OFFSET, (uint32_t)wd);
|
||||
spi_putreg(config, EFM32_USART_TXDATA_OFFSET, wd);
|
||||
|
||||
/* Wait for receive data to be available */
|
||||
|
||||
spi_wait_status(config, _USART_STATUS_RXDATAV_MASK, USART_STATUS_RXDATAV);
|
||||
ret = (uint16_t)spi_getreg(config, EFM32_USART_RXDATA_OFFSET);
|
||||
ret = spi_getreg(config, EFM32_USART_RXDATA_OFFSET);
|
||||
|
||||
spiinfo("Sent: %04x Return: %04x \n", wd, ret);
|
||||
return ret;
|
||||
|
@ -1282,10 +1294,11 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
|||
while (unrecvd > 0)
|
||||
{
|
||||
/* REVISIT: Could this cause RX data overruns??? */
|
||||
|
||||
/* Send data if there is space in the TX buffer. */
|
||||
|
||||
if ((spi_getreg(config, EFM32_USART_STATUS_OFFSET) & USART_STATUS_TXBL) != 0 &&
|
||||
unsent > 0)
|
||||
if ((spi_getreg(config, EFM32_USART_STATUS_OFFSET) &
|
||||
USART_STATUS_TXBL) != 0 && unsent > 0)
|
||||
{
|
||||
/* Get the next word to write. Is there a source buffer? */
|
||||
|
||||
|
@ -1306,8 +1319,8 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
|||
|
||||
/* Receive data if there is data available */
|
||||
|
||||
if ((spi_getreg(config, EFM32_USART_STATUS_OFFSET) & USART_STATUS_RXDATAV) != 0 &&
|
||||
unrecvd > 0)
|
||||
if ((spi_getreg(config, EFM32_USART_STATUS_OFFSET) &
|
||||
USART_STATUS_RXDATAV) != 0 && unrecvd > 0)
|
||||
{
|
||||
/* Receive the data */
|
||||
|
||||
|
@ -1336,10 +1349,11 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
|||
while (unrecvd > 0)
|
||||
{
|
||||
/* REVISIT: Could this cause RX data overruns??? */
|
||||
|
||||
/* Send data if there is space in the TX buffer. */
|
||||
|
||||
if ((spi_getreg(config, EFM32_USART_STATUS_OFFSET) & USART_STATUS_TXBL) != 0 &&
|
||||
unsent > 0)
|
||||
if ((spi_getreg(config, EFM32_USART_STATUS_OFFSET) &
|
||||
USART_STATUS_TXBL) != 0 && unsent > 0)
|
||||
{
|
||||
/* Get the next word to write. Is there a source buffer? */
|
||||
|
||||
|
@ -1360,8 +1374,8 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
|||
|
||||
/* Receive data if there is data available */
|
||||
|
||||
if ((spi_getreg(config, EFM32_USART_STATUS_OFFSET) & USART_STATUS_RXDATAV) != 0 &&
|
||||
unrecvd > 0)
|
||||
if ((spi_getreg(config, EFM32_USART_STATUS_OFFSET) &
|
||||
USART_STATUS_RXDATAV) != 0 && unrecvd > 0)
|
||||
{
|
||||
/* Receive the data */
|
||||
|
||||
|
@ -1451,7 +1465,8 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
|||
* when both RX and TX transfers complete.
|
||||
*/
|
||||
|
||||
ret = wd_start(priv->wdog, (int)ticks, spi_dma_timeout, 1, (uint32_t)priv);
|
||||
ret = wd_start(priv->wdog, (int)ticks, spi_dma_timeout, 1,
|
||||
(uint32_t)priv);
|
||||
if (ret < 0)
|
||||
{
|
||||
spierr("ERROR: Failed to start timeout: %d\n", ret);
|
||||
|
@ -1558,8 +1573,8 @@ static int spi_portinitialize(struct efm32_spidev_s *priv)
|
|||
|
||||
/* Set bits for synchronous mode */
|
||||
|
||||
regval = _USART_CTRL_RESETVALUE | USART_CTRL_SYNC | USART_CTRL_CLKPOL_IDLELOW |
|
||||
USART_CTRL_CLKPHA_SAMPLELEADING;
|
||||
regval = _USART_CTRL_RESETVALUE | USART_CTRL_SYNC |
|
||||
USART_CTRL_CLKPOL_IDLELOW | USART_CTRL_CLKPHA_SAMPLELEADING;
|
||||
|
||||
/* MSB First, 8 bits */
|
||||
|
||||
|
@ -1592,7 +1607,7 @@ static int spi_portinitialize(struct efm32_spidev_s *priv)
|
|||
priv->rxdmach = efm32_dmachannel();
|
||||
if (!priv->rxdmach)
|
||||
{
|
||||
spierr("ERROR: Failed to allocate the RX DMA channel for SPI port: %d\n",
|
||||
spierr("ERROR: Failed to allocate RX DMA channel for SPI port: %d\n",
|
||||
port);
|
||||
goto errout;
|
||||
}
|
||||
|
@ -1600,7 +1615,7 @@ static int spi_portinitialize(struct efm32_spidev_s *priv)
|
|||
priv->txdmach = efm32_dmachannel();
|
||||
if (!priv->txdmach)
|
||||
{
|
||||
spierr("ERROR: Failed to allocate the TX DMA channel for SPI port: %d\n",
|
||||
spierr("ERROR: Failed to allocate TX DMA channel for SPI port: %d\n",
|
||||
port);
|
||||
goto errout_with_rxdmach;
|
||||
}
|
||||
|
@ -1623,13 +1638,14 @@ static int spi_portinitialize(struct efm32_spidev_s *priv)
|
|||
* priority inheritance enabled.
|
||||
*/
|
||||
|
||||
nxsem_setprotocol(&priv->rxdmasem, SEM_PRIO_NONE);
|
||||
nxsem_setprotocol(&priv->txdmasem, SEM_PRIO_NONE);
|
||||
nxsem_setprotocol(&priv->rxdmasem, SEM_PRIO_NONE);
|
||||
nxsem_setprotocol(&priv->txdmasem, SEM_PRIO_NONE);
|
||||
#endif
|
||||
|
||||
/* Enable SPI */
|
||||
|
||||
spi_putreg(config, EFM32_USART_CMD_OFFSET, USART_CMD_RXEN | USART_CMD_TXEN);
|
||||
spi_putreg(config, EFM32_USART_CMD_OFFSET,
|
||||
USART_CMD_RXEN | USART_CMD_TXEN);
|
||||
return OK;
|
||||
|
||||
#ifdef CONFIG_EFM32_SPI_DMA
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arm/arm/src/efm32/efm32_spi.h
|
||||
* arch/arm/src/efm32/efm32_spi.h
|
||||
*
|
||||
* Copyright (C) 2009-2013 Bouteville Pierre-Noel. All rights reserved.
|
||||
* Author: Bouteville Pierre-Noel <pnb990@gmail.com>
|
||||
|
@ -77,8 +77,8 @@ struct spi_dev_s *efm32_spibus_initialize(int port);
|
|||
* efm32_spi[n]_cmddata must be provided by board-specific logic. These
|
||||
* are implementations of the select, status, and cmddata methods of the
|
||||
* SPI interface defined by struct spi_ops_s (see include/nuttx/spi/spi.h).
|
||||
* All other methods (including efm32_spibus_initialize()) are provided by common
|
||||
* EFM32 logic. To use this common SPI logic on your board:
|
||||
* All other methods (including efm32_spibus_initialize()) are provided by
|
||||
* common EFM32 logic. To use this common SPI logic on your board:
|
||||
*
|
||||
* 1. Provide logic in efm32_boardinitialize() to configure SPI chip select
|
||||
* pins.
|
||||
|
@ -90,10 +90,10 @@ struct spi_dev_s *efm32_spibus_initialize(int port);
|
|||
* then provide efm32_spi[n]_cmddata() functions in your board-specific
|
||||
* logic. These functions will perform cmd/data selection operations
|
||||
* using GPIOs in the way your board is configured.
|
||||
* 4. Add a calls to efm32_spibus_initialize() in your low level application
|
||||
* initialization logic
|
||||
* 5. The handle returned by efm32_spibus_initialize() may then be used to bind
|
||||
* the SPI driver to higher level logic (e.g., calling
|
||||
* 4. Add a calls to efm32_spibus_initialize() in your low level
|
||||
* application initialization logic
|
||||
* 5. The handle returned by efm32_spibus_initialize() may then be used to
|
||||
* bind the SPI driver to higher level logic (e.g., calling
|
||||
* mmcsd_spislotinitialize(), for example, will bind the SPI driver to
|
||||
* the SPI MMC/SD driver).
|
||||
*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/imx1/imx_spi.c
|
||||
*
|
||||
* Copyright (C) 2009-2010, 2013, 2016-2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2009-2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -144,8 +144,10 @@ struct imx_spidev_s
|
|||
|
||||
/* SPI register access */
|
||||
|
||||
static inline uint32_t spi_getreg(struct imx_spidev_s *priv, unsigned int offset);
|
||||
static inline void spi_putreg(struct imx_spidev_s *priv, unsigned int offset, uint32_t value);
|
||||
static inline uint32_t spi_getreg(struct imx_spidev_s *priv,
|
||||
unsigned int offset);
|
||||
static inline void spi_putreg(struct imx_spidev_s *priv,
|
||||
unsigned int offset, uint32_t value);
|
||||
|
||||
/* SPI data transfer */
|
||||
|
||||
|
@ -164,22 +166,26 @@ static int spi_transfer(struct imx_spidev_s *priv, const void *txbuffer,
|
|||
|
||||
#ifndef CONFIG_SPI_POLLWAIT
|
||||
static inline struct imx_spidev_s *spi_mapirq(int irq);
|
||||
static int spi_interrupt(int irq, void *context, FAR void *arg, FAR void *arg);
|
||||
static int spi_interrupt(int irq, void *context,
|
||||
FAR void *arg, FAR void *arg);
|
||||
#endif
|
||||
|
||||
/* SPI methods */
|
||||
|
||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency);
|
||||
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 wd);
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
#ifdef CONFIG_SPI_EXCHANGE
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
#else
|
||||
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_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
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -258,7 +264,8 @@ static struct imx_spidev_s g_spidev[] =
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t spi_getreg(struct imx_spidev_s *priv, unsigned int offset)
|
||||
static inline uint32_t spi_getreg(struct imx_spidev_s *priv,
|
||||
unsigned int offset)
|
||||
{
|
||||
return getreg32(priv->base + offset);
|
||||
}
|
||||
|
@ -279,7 +286,8 @@ static inline uint32_t spi_getreg(struct imx_spidev_s *priv, unsigned int offset
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_putreg(struct imx_spidev_s *priv, unsigned int offset, uint32_t value)
|
||||
static inline void spi_putreg(struct imx_spidev_s *priv,
|
||||
unsigned int offset, uint32_t value)
|
||||
{
|
||||
putreg32(value, priv->base + offset);
|
||||
}
|
||||
|
@ -288,10 +296,10 @@ static inline void spi_putreg(struct imx_spidev_s *priv, unsigned int offset, ui
|
|||
* Name: spi_txnull, spi_txuint16, and spi_txuint8
|
||||
*
|
||||
* Description:
|
||||
* Transfer all ones, a uint8_t, or uint16_t to Tx FIFO and update the txbuffer
|
||||
* pointer appropriately. The selected function dependes on (1) if there
|
||||
* is a source txbuffer provided, and (2) if the number of bits per
|
||||
* word is <=8 or >8.
|
||||
* Transfer all ones, a uint8_t, or uint16_t to Tx FIFO and update
|
||||
* the txbuffer pointer appropriately. The selected function depends
|
||||
* on (1) if there is a source txbuffer provided, and (2) if the
|
||||
* number of bits per word is <=8 or >8.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - Device-specific state data
|
||||
|
@ -407,6 +415,7 @@ static int spi_performtx(struct imx_spidev_s *priv)
|
|||
spi_putreg(priv, CSPI_INTCS_OFFSET, regval);
|
||||
}
|
||||
}
|
||||
|
||||
return ntxd;
|
||||
}
|
||||
|
||||
|
@ -488,9 +497,9 @@ static void spi_startxfr(struct imx_spidev_s *priv, int ntxd)
|
|||
* txbuffer - The buffer of data to send to the device (may be NULL).
|
||||
* rxbuffer - The buffer to receive data from the device (may be NULL).
|
||||
* nwords - The total number of words to be exchanged. If the interface
|
||||
* uses <= 8 bits per word, then this is the number of uint8_t's;
|
||||
* if the interface uses >8 bits per word, then this is the
|
||||
* number of uint16_t's
|
||||
* uses <= 8 bits per word, then this is the number of
|
||||
* uint8_t's; if the interface uses >8 bits per word, then this
|
||||
* is the number of uint16_t's
|
||||
*
|
||||
* Returned Value:
|
||||
* 0: success, <0:Negated error number on failure
|
||||
|
@ -637,9 +646,9 @@ static inline struct imx_spidev_s *spi_mapirq(int irq)
|
|||
* txbuffer - The buffer of data to send to the device (may be NULL).
|
||||
* rxbuffer - The buffer to receive data from the device (may be NULL).
|
||||
* nwords - The total number of words to be exchanged. If the interface
|
||||
* uses <= 8 bits per word, then this is the number of uint8_t's;
|
||||
* if the interface uses >8 bits per word, then this is the
|
||||
* number of uint16_t's
|
||||
* uses <= 8 bits per word, then this is the number of
|
||||
* uint8_t's; if the interface uses >8 bits per word, then this
|
||||
* is the number of uint16_t's
|
||||
*
|
||||
* Returned Value:
|
||||
* 0: success, <0:Negated error number on failure
|
||||
|
@ -647,7 +656,8 @@ static inline struct imx_spidev_s *spi_mapirq(int irq)
|
|||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SPI_POLLWAIT
|
||||
static int spi_interrupt(int irq, void *context, FAR void *arg, FAR void *arg)
|
||||
static int spi_interrupt(int irq, void *context,
|
||||
FAR void *arg, FAR void *arg)
|
||||
{
|
||||
struct imx_spidev_s *priv = spi_mapirq(irq);
|
||||
int ntxd;
|
||||
|
@ -732,7 +742,8 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency)
|
||||
{
|
||||
struct imx_spidev_s *priv = (struct imx_spidev_s *)dev;
|
||||
uint32_t actual;
|
||||
|
@ -900,10 +911,10 @@ 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 wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
struct imx_spidev_s *priv = (struct imx_spidev_s *)dev;
|
||||
uint16_t response = 0;
|
||||
uint32_t response = 0;
|
||||
|
||||
spi_transfer(priv, &wd, &response, 1);
|
||||
return response;
|
||||
|
@ -922,7 +933,8 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
* 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
|
||||
* packed into uint8_t's; if nbits >8, the data is packed into
|
||||
* uint16_t's
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
|
@ -950,7 +962,8 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
* 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
|
||||
|
@ -958,7 +971,8 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords)
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
|
||||
size_t nwords)
|
||||
{
|
||||
struct imx_spidev_s *priv = (struct imx_spidev_s *)dev;
|
||||
spi_transfer(priv, buffer, NULL, nwords);
|
||||
|
@ -975,9 +989,10 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
|
|||
* dev - Device-specific state data
|
||||
* buffer - 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
|
||||
* 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
|
||||
|
@ -985,7 +1000,8 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
|
|||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords)
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
|
||||
size_t nwords)
|
||||
{
|
||||
struct imx_spidev_s *priv = (struct imx_spidev_s *)dev;
|
||||
spi_transfer(priv, NULL, buffer, nwords);
|
||||
|
@ -1005,10 +1021,10 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nw
|
|||
* prior to calling this function. Specifically: GPIOs should have
|
||||
* been configured for output, and all chip selects disabled.
|
||||
*
|
||||
* One GPIO, SS (PB2 on the eZ8F091) is reserved as a chip select. However,
|
||||
* If multiple devices on on the bus, then multiple chip selects will be
|
||||
* required. Therefore, all GPIO chip management is deferred to board-
|
||||
* specific logic.
|
||||
* One GPIO, SS (PB2 on the eZ8F091) is reserved as a chip select.
|
||||
* However, If multiple devices on on the bus, then multiple chip selects
|
||||
* will be required. Therefore, all GPIO chip management is deferred
|
||||
* to board-specific logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* Port number (for hardware that has multiple SPI interfaces)
|
||||
|
@ -1029,6 +1045,7 @@ FAR struct spi_dev_s *imx_spibus_initialize(int port)
|
|||
{
|
||||
#ifdef CONFIG_IMX1_SPI1
|
||||
case 1:
|
||||
|
||||
/* Select SPI1 */
|
||||
|
||||
priv = &g_spidev[SPI1_NDX];
|
||||
|
@ -1046,11 +1063,13 @@ FAR struct spi_dev_s *imx_spibus_initialize(int port)
|
|||
|
||||
#ifdef CONFIG_IMX1_SPI2
|
||||
case 2:
|
||||
|
||||
/* Select SPI2 */
|
||||
|
||||
priv = &g_spidev[SPI2_NDX];
|
||||
|
||||
/* Configure SPI2 GPIOs */
|
||||
|
||||
/* SCLK: AIN of Port A, pin 0 -OR- AIN of Port D, pin 7 */
|
||||
|
||||
#if 1
|
||||
|
@ -1108,10 +1127,10 @@ FAR struct spi_dev_s *imx_spibus_initialize(int port)
|
|||
* signaling and, hence, should not have priority inheritance enabled.
|
||||
*/
|
||||
|
||||
nxsem_init(&priv->waitsem, 0, 0);
|
||||
nxsem_setprotocol(&priv->waitsem, SEM_PRIO_NONE);
|
||||
nxsem_init(&priv->waitsem, 0, 0);
|
||||
nxsem_setprotocol(&priv->waitsem, SEM_PRIO_NONE);
|
||||
#endif
|
||||
nxsem_init(&priv->exclsem, 0, 1);
|
||||
nxsem_init(&priv->exclsem, 0, 1);
|
||||
|
||||
/* Initialize control register: min frequency, ignore ready, master mode, mode=0, 8-bit */
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@
|
|||
* Private Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Per SPI callouts to board-specific logic */
|
||||
/* Per SPI callouts to board-specific logic */
|
||||
|
||||
typedef CODE void (*imx_select_t)(FAR struct spi_dev_s *dev,
|
||||
uint32_t devid, bool selected);
|
||||
|
@ -202,8 +202,10 @@ struct imx_spidev_s
|
|||
|
||||
/* SPI register access */
|
||||
|
||||
static inline uint32_t spi_getreg(struct imx_spidev_s *priv, unsigned int offset);
|
||||
static inline void spi_putreg(struct imx_spidev_s *priv, unsigned int offset, uint32_t value);
|
||||
static inline uint32_t spi_getreg(struct imx_spidev_s *priv,
|
||||
unsigned int offset);
|
||||
static inline void spi_putreg(struct imx_spidev_s *priv,
|
||||
unsigned int offset, uint32_t value);
|
||||
|
||||
/* SPI data transfer */
|
||||
|
||||
|
@ -233,7 +235,7 @@ 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 wd);
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
static uint8_t spi_status(FAR struct spi_dev_s *dev, uint32_t devid);
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
static int spi_cmddata(FAR struct spi_dev_s *dev, uint32_t devid,
|
||||
|
@ -296,11 +298,11 @@ static struct imx_spidev_s g_spidev[] =
|
|||
#ifdef CONFIG_SPI_CMDDATA
|
||||
.cmddata = imx_spi1cmddata,
|
||||
#endif
|
||||
}
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX6_ECSPI2
|
||||
, {
|
||||
{
|
||||
.ops = &g_spiops,
|
||||
.base = IMX_ECSPI2_VBASE,
|
||||
.spindx = SPI2_NDX,
|
||||
|
@ -312,11 +314,11 @@ static struct imx_spidev_s g_spidev[] =
|
|||
#ifdef CONFIG_SPI_CMDDATA
|
||||
.cmddata = imx_spi2cmddata,
|
||||
#endif
|
||||
}
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX6_ECSPI3
|
||||
, {
|
||||
{
|
||||
.ops = &g_spiops,
|
||||
.base = IMX_ECSPI3_VBASE,
|
||||
.spindx = SPI3_NDX,
|
||||
|
@ -328,11 +330,11 @@ static struct imx_spidev_s g_spidev[] =
|
|||
#ifdef CONFIG_SPI_CMDDATA
|
||||
.cmddata = imx_spi3cmddata,
|
||||
#endif
|
||||
}
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX6_ECSPI4
|
||||
, {
|
||||
{
|
||||
.ops = &g_spiops,
|
||||
.base = IMX_ECSPI4_VBASE,
|
||||
.spindx = SPI4_NDX,
|
||||
|
@ -344,11 +346,11 @@ static struct imx_spidev_s g_spidev[] =
|
|||
#ifdef CONFIG_SPI_CMDDATA
|
||||
.cmddata = imx_spi4cmddata,
|
||||
#endif
|
||||
}
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX6_ECSPI5
|
||||
, {
|
||||
{
|
||||
.ops = &g_spiops,
|
||||
.base = IMX_ECSPI5_VBASE,
|
||||
.spindx = SPI5_NDX,
|
||||
|
@ -383,7 +385,8 @@ static struct imx_spidev_s g_spidev[] =
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t spi_getreg(struct imx_spidev_s *priv, unsigned int offset)
|
||||
static inline uint32_t spi_getreg(struct imx_spidev_s *priv,
|
||||
unsigned int offset)
|
||||
{
|
||||
return getreg32(priv->base + offset);
|
||||
}
|
||||
|
@ -404,7 +407,8 @@ static inline uint32_t spi_getreg(struct imx_spidev_s *priv, unsigned int offset
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_putreg(struct imx_spidev_s *priv, unsigned int offset, uint32_t value)
|
||||
static inline void spi_putreg(struct imx_spidev_s *priv, unsigned int offset,
|
||||
uint32_t value)
|
||||
{
|
||||
putreg32(value, priv->base + offset);
|
||||
}
|
||||
|
@ -413,10 +417,10 @@ static inline void spi_putreg(struct imx_spidev_s *priv, unsigned int offset, ui
|
|||
* Name: spi_txnull, spi_txuint16, and spi_txuint8
|
||||
*
|
||||
* Description:
|
||||
* Transfer all ones, a uint8_t, or uint16_t to Tx FIFO and update the txbuffer
|
||||
* pointer appropriately. The selected function dependes on (1) if there
|
||||
* is a source txbuffer provided, and (2) if the number of bits per
|
||||
* word is <=8 or >8.
|
||||
* Transfer all ones, a uint8_t, or uint16_t to Tx FIFO and update the
|
||||
* txbuffer pointer appropriately. The selected function dependes on
|
||||
* (1) if there is a source txbuffer provided, and (2) if the number of
|
||||
* bits per word is <=8 or >8.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - Device-specific state data
|
||||
|
@ -532,6 +536,7 @@ static int spi_performtx(struct imx_spidev_s *priv)
|
|||
spi_putreg(priv, ECSPI_INTREG_OFFSET, regval);
|
||||
}
|
||||
}
|
||||
|
||||
return ntxd;
|
||||
}
|
||||
|
||||
|
@ -613,9 +618,9 @@ static void spi_startxfr(struct imx_spidev_s *priv, int ntxd)
|
|||
* txbuffer - The buffer of data to send to the device (may be NULL).
|
||||
* rxbuffer - The buffer to receive data from the device (may be NULL).
|
||||
* nwords - The total number of words to be exchanged. If the interface
|
||||
* uses <= 8 bits per word, then this is the number of uint8_t's;
|
||||
* if the interface uses >8 bits per word, then this is the
|
||||
* number of uint16_t's
|
||||
* uses <= 8 bits per word, then this is the number of
|
||||
* uint8_t's; if the interface uses >8 bits per word, then this
|
||||
* is the number of uint16_t's
|
||||
*
|
||||
* Returned Value:
|
||||
* 0: success, <0:Negated error number on failure
|
||||
|
@ -845,7 +850,8 @@ static void spi_select(FAR struct spi_dev_s *dev, uint32_t devid,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency)
|
||||
{
|
||||
struct imx_spidev_s *priv = (struct imx_spidev_s *)dev;
|
||||
uint32_t actual;
|
||||
|
@ -1013,10 +1019,10 @@ 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 wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
struct imx_spidev_s *priv = (struct imx_spidev_s *)dev;
|
||||
uint16_t response = 0;
|
||||
uint32_t response = 0;
|
||||
|
||||
spi_transfer(priv, &wd, &response, 1);
|
||||
return response;
|
||||
|
@ -1107,7 +1113,8 @@ static int spi_cmddata(FAR struct spi_dev_s *dev, uint32_t devid,
|
|||
* 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
|
||||
* packed into uint8_t's; if nbits >8, the data is packed into
|
||||
* uint16_t's
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
|
@ -1135,7 +1142,8 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
* 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
|
||||
|
@ -1143,7 +1151,8 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords)
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
|
||||
size_t nwords)
|
||||
{
|
||||
struct imx_spidev_s *priv = (struct imx_spidev_s *)dev;
|
||||
spi_transfer(priv, buffer, NULL, nwords);
|
||||
|
@ -1160,9 +1169,10 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
|
|||
* dev - Device-specific state data
|
||||
* buffer - 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
|
||||
* 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
|
||||
|
@ -1170,7 +1180,8 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
|
|||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords)
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
|
||||
size_t nwords)
|
||||
{
|
||||
struct imx_spidev_s *priv = (struct imx_spidev_s *)dev;
|
||||
spi_transfer(priv, NULL, buffer, nwords);
|
||||
|
@ -1190,10 +1201,10 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nw
|
|||
* prior to calling this function. Specifically: GPIOs should have
|
||||
* been configured for output, and all chip selects disabled.
|
||||
*
|
||||
* One GPIO, SS (PB2 on the eZ8F091) is reserved as a chip select. However,
|
||||
* If multiple devices on on the bus, then multiple chip selects will be
|
||||
* required. Theregore, all GPIO chip management is deferred to board-
|
||||
* specific logic.
|
||||
* One GPIO, SS (PB2 on the eZ8F091) is reserved as a chip select.
|
||||
* However, If multiple devices on on the bus, then multiple chip selects
|
||||
* will be required. Therefore, all GPIO chip management is deferred to
|
||||
* board-specific logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* Port number (for hardware that has multiple SPI interfaces)
|
||||
|
@ -1214,6 +1225,7 @@ FAR struct spi_dev_s *imx_spibus_initialize(int port)
|
|||
{
|
||||
#ifdef CONFIG_IMX6_ECSPI1
|
||||
case 1:
|
||||
|
||||
/* Select SPI1 */
|
||||
|
||||
priv = &g_spidev[SPI1_NDX];
|
||||
|
@ -1231,11 +1243,13 @@ FAR struct spi_dev_s *imx_spibus_initialize(int port)
|
|||
|
||||
#ifdef CONFIG_IMX6_ECSPI2
|
||||
case 2:
|
||||
|
||||
/* Select SPI2 */
|
||||
|
||||
priv = &g_spidev[SPI2_NDX];
|
||||
|
||||
/* Configure SPI2 GPIOs */
|
||||
|
||||
/* SCLK: AIN of Port A, pin 0 -OR- AIN of Port D, pin 7 */
|
||||
|
||||
#if 1
|
||||
|
@ -1286,6 +1300,7 @@ FAR struct spi_dev_s *imx_spibus_initialize(int port)
|
|||
}
|
||||
|
||||
/* Initialize the state structure */
|
||||
|
||||
/* Initialize Semaphores */
|
||||
|
||||
#ifndef CONFIG_SPI_POLLWAIT
|
||||
|
@ -1294,10 +1309,10 @@ FAR struct spi_dev_s *imx_spibus_initialize(int port)
|
|||
* signaling and, hence, should not have priority inheritance enabled.
|
||||
*/
|
||||
|
||||
nxsem_init(&priv->waitsem, 0, 0);
|
||||
nxsem_setprotocol(&priv->waitsem, SEM_PRIO_NONE);
|
||||
nxsem_init(&priv->waitsem, 0, 0);
|
||||
nxsem_setprotocol(&priv->waitsem, SEM_PRIO_NONE);
|
||||
#endif
|
||||
nxsem_init(&priv->exclsem, 0, 1);
|
||||
nxsem_init(&priv->exclsem, 0, 1);
|
||||
|
||||
/* Initialize control register: min frequency, ignore ready, master mode, mode=0, 8-bit */
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*****************************************************************************
|
||||
* arm/arm/src/imxrt/imxrt_lpspi.c
|
||||
* arch/arm/src/imxrt/imxrt_lpspi.c
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Authors: Teodora Kireva
|
||||
|
@ -151,7 +151,7 @@ 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(
|
||||
static inline uint32_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);
|
||||
|
@ -177,7 +177,7 @@ static void imxrt_lpspi_setbits(FAR struct spi_dev_s *dev, int nbits);
|
|||
static int imxrt_lpspi_hwfeatures(FAR struct spi_dev_s *dev,
|
||||
imxrt_lpspi_hwfeatures_t features);
|
||||
#endif
|
||||
static uint16_t imxrt_lpspi_send(FAR struct spi_dev_s *dev, uint16_t wd);
|
||||
static uint32_t imxrt_lpspi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
static void imxrt_lpspi_exchange(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
size_t nwords);
|
||||
|
@ -482,7 +482,7 @@ static inline void imxrt_lpspi_putreg32(FAR struct imxrt_lpspidev_s *priv,
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static inline uint16_t imxrt_lpspi_readword(FAR struct imxrt_lpspidev_s *priv)
|
||||
static inline uint32_t imxrt_lpspi_readword(FAR struct imxrt_lpspidev_s *priv)
|
||||
{
|
||||
/* Wait until the receive buffer is not empty */
|
||||
|
||||
|
@ -491,7 +491,7 @@ static inline uint16_t imxrt_lpspi_readword(FAR struct imxrt_lpspidev_s *priv)
|
|||
|
||||
/* Then return the received byte */
|
||||
|
||||
return (uint16_t) imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_RDR_OFFSET);
|
||||
return imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_RDR_OFFSET);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -1233,15 +1233,15 @@ static int imxrt_lpspi_hwfeatures(FAR struct spi_dev_s *dev,
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static uint16_t imxrt_lpspi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t imxrt_lpspi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
FAR struct imxrt_lpspidev_s *priv = (FAR struct imxrt_lpspidev_s *)dev;
|
||||
uint32_t regval;
|
||||
uint16_t ret;
|
||||
uint32_t ret;
|
||||
|
||||
DEBUGASSERT(priv && priv->spibase);
|
||||
|
||||
imxrt_lpspi_writeword(priv, (uint32_t) wd);
|
||||
imxrt_lpspi_writeword(priv, wd);
|
||||
|
||||
while ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_SR_OFFSET) & LPSPI_SR_RDF) !=
|
||||
LPSPI_SR_RDF);
|
||||
|
@ -1322,7 +1322,7 @@ static void imxrt_lpspi_exchange_nodma(FAR struct spi_dev_s *dev,
|
|||
|
||||
/* Exchange one word */
|
||||
|
||||
word = imxrt_lpspi_send(dev, word);
|
||||
word = (uint16_t) imxrt_lpspi_send(dev, (uint32_t) word);
|
||||
|
||||
/* Is there a buffer to receive the return value? */
|
||||
|
||||
|
@ -1355,7 +1355,7 @@ static void imxrt_lpspi_exchange_nodma(FAR struct spi_dev_s *dev,
|
|||
|
||||
/* Exchange one word */
|
||||
|
||||
word = (uint8_t) imxrt_lpspi_send(dev, (uint16_t) word);
|
||||
word = (uint8_t) imxrt_lpspi_send(dev, (uint32_t) word);
|
||||
|
||||
/* Is there a buffer to receive the return value? */
|
||||
|
||||
|
@ -1408,9 +1408,9 @@ static void imxrt_lpspi_sndblock(FAR struct spi_dev_s *dev,
|
|||
* 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
|
||||
* 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
|
||||
|
|
|
@ -157,7 +157,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits);
|
|||
static int spi_hwfeatures(FAR struct spi_dev_s *dev,
|
||||
spi_hwfeatures_t features);
|
||||
#endif
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd);
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
|
@ -937,11 +937,11 @@ static uint16_t spi_send_data(FAR struct kinetis_spidev_s *priv, uint16_t wd,
|
|||
*
|
||||
************************************************************************************/
|
||||
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
FAR struct kinetis_spidev_s *priv = (FAR struct kinetis_spidev_s *)dev;
|
||||
|
||||
return spi_send_data(priv, wd, true);
|
||||
return (uint32_t)spi_send_data(priv, (uint16_t)wd, true);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/kl/kl_spi.c
|
||||
*
|
||||
* Copyright (C) 2013, 2016-2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2013-2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -75,35 +75,38 @@ struct kl_spidev_s
|
|||
uint8_t mode; /* Mode 0,1,2,3 */
|
||||
};
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/* Helpers */
|
||||
|
||||
static inline uint8_t spi_getreg(FAR struct kl_spidev_s *priv, uint8_t offset);
|
||||
static inline uint8_t spi_getreg(FAR struct kl_spidev_s *priv,
|
||||
uint8_t offset);
|
||||
static inline void spi_putreg(FAR struct kl_spidev_s *priv, uint8_t offset,
|
||||
uint8_t value);
|
||||
|
||||
/* SPI methods */
|
||||
|
||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
|
||||
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 wd);
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
|
||||
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 uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
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 *txbuffer,
|
||||
size_t nwords);
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer,
|
||||
size_t nwords);
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, size_t nwords);
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer,
|
||||
size_t nwords);
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_KL_SPI0
|
||||
static const struct spi_ops_s g_spi0ops =
|
||||
|
@ -132,7 +135,10 @@ static const struct spi_ops_s g_spi0ops =
|
|||
|
||||
static struct kl_spidev_s g_spi0dev =
|
||||
{
|
||||
.spidev = { &g_spi0ops },
|
||||
.spidev =
|
||||
{
|
||||
&g_spi0ops
|
||||
},
|
||||
.spibase = KL_SPI0_BASE,
|
||||
};
|
||||
#endif
|
||||
|
@ -161,7 +167,10 @@ static const struct spi_ops_s g_spi1ops =
|
|||
|
||||
static struct kl_spidev_s g_spi1dev =
|
||||
{
|
||||
.spidev = { &g_spi1ops },
|
||||
.spidev =
|
||||
{
|
||||
&g_spi1ops
|
||||
},
|
||||
.spibase = KL_SPI1_BASE,
|
||||
};
|
||||
#endif
|
||||
|
@ -170,7 +179,7 @@ static struct kl_spidev_s g_spi1dev =
|
|||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_getreg
|
||||
*
|
||||
* Description:
|
||||
|
@ -183,14 +192,15 @@ static struct kl_spidev_s g_spi1dev =
|
|||
* Returned Value:
|
||||
* The contents of the 16-bit register
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint8_t spi_getreg(FAR struct kl_spidev_s *priv, uint8_t offset)
|
||||
static inline uint8_t spi_getreg(FAR struct kl_spidev_s *priv,
|
||||
uint8_t offset)
|
||||
{
|
||||
return getreg8(priv->spibase + offset);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_putreg
|
||||
*
|
||||
* Description:
|
||||
|
@ -204,7 +214,7 @@ static inline uint8_t spi_getreg(FAR struct kl_spidev_s *priv, uint8_t offset)
|
|||
* Returned Value:
|
||||
* The contents of the 16-bit register
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_putreg(FAR struct kl_spidev_s *priv, uint8_t offset,
|
||||
uint8_t value)
|
||||
|
@ -212,7 +222,7 @@ static inline void spi_putreg(FAR struct kl_spidev_s *priv, uint8_t offset,
|
|||
putreg8(value, priv->spibase + offset);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_lock
|
||||
*
|
||||
* Description:
|
||||
|
@ -231,7 +241,7 @@ static inline void spi_putreg(FAR struct kl_spidev_s *priv, uint8_t offset,
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
||||
{
|
||||
|
@ -250,7 +260,7 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_setfrequency
|
||||
*
|
||||
* Description:
|
||||
|
@ -263,9 +273,10 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
|||
* Returned Value:
|
||||
* Returns the actual frequency selected
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency)
|
||||
{
|
||||
FAR struct kl_spidev_s *priv = (FAR struct kl_spidev_s *)dev;
|
||||
uint32_t divisor;
|
||||
|
@ -287,19 +298,23 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
|||
* divisor in the range {2, 4, 8, 16, 32, 64, 128, 256, or 512).
|
||||
*
|
||||
*
|
||||
* BaudRateDivisor = (SPPR + 1) × 2^(SPR + 1)
|
||||
* BaudRateDivisor = (SPPR + 1) × 2^(SPR + 1)
|
||||
* BaudRate = BusClock / BaudRateDivisor
|
||||
*
|
||||
* The strategy is to pick the smallest divisor that yields an in-range
|
||||
* solution. I am not sure if this *always* results in an optimal solution.
|
||||
* But consider, for example, with a 24Mhz bus clock and a target of 400KHz
|
||||
* solution. I am not sure if this *always* results in an optimal
|
||||
* solution. But consider, for example, with a 24Mhz bus clock and a
|
||||
* target of 400KHz
|
||||
*
|
||||
* target divisor is 24,000,000 / 400,000 = 60
|
||||
* spr = 1 -> sppr = 60 / (1 << 1) = 30 -> out of range
|
||||
* spr = 2 -> sppr = 60 / (1 << 2) = 15 -> out of range
|
||||
* spr = 3 -> sppr = 60 / (1 << 3) = 7 -> actual = 24000000 / 7 * 8 = 428571
|
||||
* spr = 4 -> sppr = 60 / (1 << 4) = 3 -> actual = 24000000 / 3 * 16 = 500000
|
||||
* spr = 5 -> sppr = 60 / (1 << 5) = 1 -> actual = 24000000 / 1 * 32 = 750000
|
||||
* spr = 3 -> sppr = 60 / (1 << 3) = 7 -> actual = 24000000 / 7 * 8
|
||||
* = 428571
|
||||
* spr = 4 -> sppr = 60 / (1 << 4) = 3 -> actual = 24000000 / 3 * 16
|
||||
* = 500000
|
||||
* spr = 5 -> sppr = 60 / (1 << 5) = 1 -> actual = 24000000 / 1 * 32
|
||||
* = 750000
|
||||
*/
|
||||
|
||||
divisor = BOARD_BUSCLK_FREQ / frequency;
|
||||
|
@ -323,7 +338,8 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
|||
|
||||
/* Write the new dividers to the BR register */
|
||||
|
||||
spi_putreg(priv, KL_SPI_BR_OFFSET, SPI_BR_SPR_DIV(spr) | SPI_BR_SPPR(sppr));
|
||||
spi_putreg(priv, KL_SPI_BR_OFFSET, SPI_BR_SPR_DIV(spr) |
|
||||
SPI_BR_SPPR(sppr));
|
||||
|
||||
/* Calculate the actual divisor and frequency */
|
||||
|
||||
|
@ -339,7 +355,7 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
|||
return actual;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_setmode
|
||||
*
|
||||
* Description:
|
||||
|
@ -352,7 +368,7 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
|||
* Returned Value:
|
||||
* Returns the actual frequency selected
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
||||
{
|
||||
|
@ -400,7 +416,7 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
|||
}
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_setbits
|
||||
*
|
||||
* Description:
|
||||
|
@ -413,7 +429,7 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
||||
{
|
||||
|
@ -422,7 +438,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
|||
DEBUGASSERT(nbits == 8);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_send
|
||||
*
|
||||
* Description:
|
||||
|
@ -436,9 +452,9 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
|||
* Returned Value:
|
||||
* response
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
FAR struct kl_spidev_s *priv = (FAR struct kl_spidev_s *)dev;
|
||||
|
||||
|
@ -450,19 +466,19 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
|
||||
spi_putreg(priv, KL_SPI_D_OFFSET, (uint8_t)wd);
|
||||
|
||||
/* Wait for the SPRF bit in the SPI Status Register to be set to 1. SPRF is set
|
||||
* at the completion of an SPI transfer to indicate that received data may be read
|
||||
* from the SPI data registr
|
||||
/* Wait for the SPRF bit in the SPI Status Register to be set to 1. SPRF
|
||||
* is set at the completion of an SPI transfer to indicate that received
|
||||
* data may be read from the SPI data register
|
||||
*/
|
||||
|
||||
while ((spi_getreg(priv, KL_SPI_S_OFFSET) & SPI_S_SPRF) == 0);
|
||||
|
||||
/* Return the data */
|
||||
|
||||
return (uint16_t)spi_getreg(priv, KL_SPI_D_OFFSET);
|
||||
return (uint32_t)spi_getreg(priv, KL_SPI_D_OFFSET);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_exchange
|
||||
*
|
||||
* Description:
|
||||
|
@ -475,12 +491,13 @@ static uint16_t spi_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
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords)
|
||||
|
@ -542,15 +559,16 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
* Input Parameters:
|
||||
* dev - Device-specific state data
|
||||
* txbuffer - 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
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
|
@ -561,7 +579,7 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_recvblock
|
||||
*
|
||||
* Description:
|
||||
|
@ -570,18 +588,20 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
* 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 spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, size_t nwords)
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer,
|
||||
size_t nwords)
|
||||
{
|
||||
spiinfo("rxbuffer=%p nwords=%d\n", rxbuffer, nwords);
|
||||
return spi_exchange(dev, NULL, rxbuffer, nwords);
|
||||
|
|
|
@ -101,13 +101,16 @@ struct lc823450_spidev_s
|
|||
#ifndef CONFIG_SPI_OWNBUS
|
||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
|
||||
#endif
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency);
|
||||
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 uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
#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);
|
||||
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
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -138,7 +141,10 @@ static const struct spi_ops_s g_spiops =
|
|||
|
||||
static struct lc823450_spidev_s g_spidev =
|
||||
{
|
||||
.spidev = { &g_spiops },
|
||||
.spidev =
|
||||
{
|
||||
&g_spiops
|
||||
},
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -179,7 +185,8 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency)
|
||||
{
|
||||
FAR struct lc823450_spidev_s *priv = (FAR struct lc823450_spidev_s *)dev;
|
||||
unsigned long sysclk = lc823450_get_systemfreq();
|
||||
|
@ -193,7 +200,7 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
|||
}
|
||||
#endif
|
||||
|
||||
for (div = 0xFE; div >= 0; div--)
|
||||
for (div = 0xfe; div >= 0; div--)
|
||||
{
|
||||
if (frequency >= sysclk / (4 * (256 - div)))
|
||||
{
|
||||
|
@ -333,15 +340,15 @@ static void spi_dma_callback(DMA_HANDLE hdma, void *arg, int result)
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LC823450_SPI_DMA
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
spi_sndblock(dev, &wd, 1);
|
||||
return 0;
|
||||
}
|
||||
#else /* CONFIG_LC823450_SPI_DMA */
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
putreg16(wd, LC823450_SPI_STR);
|
||||
putreg16((uint16_t)wd, LC823450_SPI_STR);
|
||||
|
||||
modifyreg32(LC823450_SPI_ISR, 0, SPI_ISR_SPIF);
|
||||
|
||||
|
@ -352,11 +359,11 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
while ((getreg32(LC823450_SPI_ISR) & SPI_ISR_SPIF) == 0)
|
||||
;
|
||||
|
||||
return getreg16(LC823450_SPI_SRR);
|
||||
return (uint32_t)getreg16(LC823450_SPI_SRR);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_sndblock
|
||||
*
|
||||
* Description:
|
||||
|
@ -395,7 +402,7 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
|
|||
LC823450_DMA_DSTWIDTH_BYTE |
|
||||
LC823450_DMA_SRCINC,
|
||||
(uint32_t)buffer, /* LC823450_SPI_STR */
|
||||
LC823450_SPI_TxFF, len);
|
||||
LC823450_SPI_TXFF, len);
|
||||
|
||||
lc823450_dmastart(priv->hdma, spi_dma_callback, &priv->dma_wait);
|
||||
|
||||
|
@ -408,8 +415,8 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
|
|||
|
||||
/* Wait for FIFO empty */
|
||||
|
||||
putreg32(SPI_ISR_TxEMP, LC823450_SPI_ISR);
|
||||
while ((getreg32(LC823450_SPI_ISR) & SPI_ISR_TxEMP) != 0)
|
||||
putreg32(SPI_ISR_TXEMP, LC823450_SPI_ISR);
|
||||
while ((getreg32(LC823450_SPI_ISR) & SPI_ISR_TXEMP) != 0)
|
||||
;
|
||||
|
||||
/* Wait for Tx reg empty */
|
||||
|
@ -431,14 +438,14 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
|
|||
{
|
||||
for (i = 0; i < nwords; i++)
|
||||
{
|
||||
spi_send(dev, *buf16++);
|
||||
spi_send(dev, (uint32_t)*buf16++);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < nwords; i++)
|
||||
{
|
||||
spi_send(dev, *buf++);
|
||||
spi_send(dev, (uint32_t)*buf++);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_LC823450_SPI_DMA */
|
||||
|
@ -455,9 +462,10 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
|
|||
* dev - Device-specific state data
|
||||
* buffer - 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
|
||||
* 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
|
||||
|
@ -465,7 +473,8 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
|
|||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords)
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
|
||||
size_t nwords)
|
||||
{
|
||||
FAR struct lc823450_spidev_s *priv = (FAR struct lc823450_spidev_s *)dev;
|
||||
int i;
|
||||
|
@ -476,14 +485,14 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nw
|
|||
{
|
||||
for (i = 0; i < nwords; i++)
|
||||
{
|
||||
*buf16++ = spi_send(dev, 0xffff);
|
||||
*buf16++ = (uint16_t)spi_send(dev, 0xffff);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < nwords; i++)
|
||||
{
|
||||
*buf++ = spi_send(dev, 0xffff);
|
||||
*buf++ = (uint8_t)spi_send(dev, 0xffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -558,7 +567,7 @@ FAR struct spi_dev_s *lc823450_spibus_initialize(int port)
|
|||
|
||||
/* use FIFO */
|
||||
|
||||
putreg32(SPI_TxFF_EN | SPI_TxFF_WL8, LC823450_SPI_FFCTL);
|
||||
putreg32(SPI_TXFF_EN | SPI_TXFF_WL8, LC823450_SPI_FFCTL);
|
||||
#endif /* CONFIG_LC823450_SPI_DMA */
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
#define LC823450_SPI_BRG (LC823450_SPI_REGBASE + 0x10) /* Baudrate Generator */
|
||||
#define LC823450_SPI_ISR (LC823450_SPI_REGBASE + 0x14) /* Interrupt Factor */
|
||||
#define LC823450_SPI_DREQ (LC823450_SPI_REGBASE + 0x18) /* DMA Request */
|
||||
#define LC823450_SPI_TxFF (LC823450_SPI_REGBASE + 0x1C) /* Transfer FIFO */
|
||||
#define LC823450_SPI_TXFF (LC823450_SPI_REGBASE + 0x1C) /* Transfer FIFO */
|
||||
#define LC823450_SPI_RxFF (LC823450_SPI_REGBASE + 0x20) /* Receive FIFO */
|
||||
#define LC823450_SPI_FFCTL (LC823450_SPI_REGBASE + 0x24) /* FIFO Control */
|
||||
#define LC823450_SPI_MSK (LC823450_SPI_REGBASE + 0x28) /* Interrupt Mask */
|
||||
|
@ -93,28 +93,28 @@
|
|||
|
||||
#define SPI_ISR_CS_END (1 << 14) /* Bit 14: CS completion (not supported) */
|
||||
#define SPI_ISR_BURST_END (1 << 13) /* Bit 13: Burst transfer completion */
|
||||
#define SPI_ISR_RxORE (1 << 12) /* Bit 12: Rx FIFO overread */
|
||||
#define SPI_ISR_TxORE (1 << 11) /* Bit 11: Tx FIFO overread */
|
||||
#define SPI_ISR_RxOWE (1 << 10) /* Bit 10: Rx FIFO overwrite */
|
||||
#define SPI_ISR_TxOWE (1 << 9) /* Bit 9: Tx FIFO overwrite */
|
||||
#define SPI_ISR_RxFULL (1 << 8) /* Bit 8: Rx FIFO full */
|
||||
#define SPI_ISR_TxFULL (1 << 7) /* Bit 7: Tx FIFO full */
|
||||
#define SPI_ISR_RxEMP (1 << 6) /* Bit 6: Rx FIFO empty */
|
||||
#define SPI_ISR_TxEMP (1 << 5) /* Bit 5: Tx FIFO empty */
|
||||
#define SPI_ISR_RxWLM (1 << 4) /* Bit 4: Rx FIFO water level match */
|
||||
#define SPI_ISR_TxWLM (1 << 3) /* Bit 3: Tx FIFO water level match */
|
||||
#define SPI_ISR_RXORE (1 << 12) /* Bit 12: Rx FIFO overread */
|
||||
#define SPI_ISR_TXORE (1 << 11) /* Bit 11: Tx FIFO overread */
|
||||
#define SPI_ISR_RXOWE (1 << 10) /* Bit 10: Rx FIFO overwrite */
|
||||
#define SPI_ISR_TXOWE (1 << 9) /* Bit 9: Tx FIFO overwrite */
|
||||
#define SPI_ISR_RXFULL (1 << 8) /* Bit 8: Rx FIFO full */
|
||||
#define SPI_ISR_TXFULL (1 << 7) /* Bit 7: Tx FIFO full */
|
||||
#define SPI_ISR_RXEMP (1 << 6) /* Bit 6: Rx FIFO empty */
|
||||
#define SPI_ISR_TXEMP (1 << 5) /* Bit 5: Tx FIFO empty */
|
||||
#define SPI_ISR_RXWLM (1 << 4) /* Bit 4: Rx FIFO water level match */
|
||||
#define SPI_ISR_TXWLM (1 << 3) /* Bit 3: Tx FIFO water level match */
|
||||
#define SPI_ISR_ROWE (1 << 2) /* Bit 2: SRR register overwrite */
|
||||
#define SPI_ISR_OVE (1 << 1) /* Bit 1: overrun */
|
||||
#define SPI_ISR_SPIF (1 << 0) /* Bit 0: Frame transfer completion */
|
||||
|
||||
/* SPI FIFO contorl Register */
|
||||
|
||||
#define SPI_TxFF_EN (1 << 0)
|
||||
#define SPI_TxFF_WL2 (0 << 4)
|
||||
#define SPI_TxFF_WL4 (1 << 4)
|
||||
#define SPI_TxFF_WL8 (2 << 4)
|
||||
#define SPI_TxFF_WL12 (3 << 4)
|
||||
#define SPI_TxFF_WL14 (4 << 4)
|
||||
#define SPI_TXFF_EN (1 << 0)
|
||||
#define SPI_TXFF_WL2 (0 << 4)
|
||||
#define SPI_TXFF_WL4 (1 << 4)
|
||||
#define SPI_TXFF_WL8 (2 << 4)
|
||||
#define SPI_TXFF_WL12 (3 << 4)
|
||||
#define SPI_TXFF_WL14 (4 << 4)
|
||||
|
||||
/* SPI Interrupt Mask Register */
|
||||
|
||||
|
@ -166,13 +166,10 @@ extern "C"
|
|||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct spi_dev_s *lc823450_spibus_initialize(int bus);
|
||||
void lc823450_spiinitialize(void);
|
||||
void lc823450_spiselect(FAR struct spi_dev_s *dev, uint32_t devid, bool selected);
|
||||
void lc823450_spiselect(FAR struct spi_dev_s *dev, uint32_t devid,
|
||||
bool selected);
|
||||
uint8_t lc823450_spistatus(FAR struct spi_dev_s *dev, uint32_t devid);
|
||||
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
|
|
|
@ -65,7 +65,9 @@
|
|||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* This driver does not support the SPI exchange method. */
|
||||
|
||||
#ifdef CONFIG_SPI_EXCHANGE
|
||||
|
@ -73,12 +75,13 @@
|
|||
#endif
|
||||
|
||||
/* SSP Clocking *************************************************************/
|
||||
/* The CPU clock by 1, 2, 4, or 8 to get the SPI peripheral clock (SPI_CLOCK).
|
||||
* SPI_CLOCK may be further divided by 8-254 to get the SPI clock. If we
|
||||
* want a usable range of 4KHz to 25MHz for the SPI, then:
|
||||
|
||||
/* The CPU clock by 1, 2, 4, or 8 to get the SPI peripheral clock
|
||||
* (SPI_CLOCK). SPI_CLOCK may be further divided by 8-254 to get the SPI
|
||||
* clock. If we want a usable range of 4KHz to 25MHz for the SPI, then:
|
||||
*
|
||||
* 1. SPICLK must be greater than (8*25MHz) = 200MHz (so we can't reach 25MHz),
|
||||
* and
|
||||
* 1. SPICLK must be greater than (8*25MHz) = 200MHz (so we can't reach
|
||||
* 25MHz), and
|
||||
* 2. SPICLK must be less than (254*40Khz) = 101.6MHz.
|
||||
*
|
||||
* If we assume that CCLK less than or equal to 100MHz, we can just
|
||||
|
@ -111,12 +114,15 @@ struct lpc17_40_spidev_s
|
|||
/* SPI methods */
|
||||
|
||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency);
|
||||
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 uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
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);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
|
@ -148,7 +154,10 @@ static const struct spi_ops_s g_spiops =
|
|||
|
||||
static struct lpc17_40_spidev_s g_spidev =
|
||||
{
|
||||
.spidev = { &g_spiops },
|
||||
.spidev =
|
||||
{
|
||||
&g_spiops
|
||||
},
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -212,7 +221,8 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency)
|
||||
{
|
||||
FAR struct lpc17_40_spidev_s *priv = (FAR struct lpc17_40_spidev_s *)dev;
|
||||
uint32_t divisor;
|
||||
|
@ -380,11 +390,11 @@ 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 wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
/* Write the data to transmitted to the SPI Data Register */
|
||||
|
||||
putreg32((uint32_t)wd, LPC17_40_SPI_DR);
|
||||
putreg32(wd, LPC17_40_SPI_DR);
|
||||
|
||||
/* Wait for the SPIF bit in the SPI Status Register to be set to 1. The
|
||||
* SPIF bit will be set after the last sampling clock edge of the SPI
|
||||
|
@ -396,7 +406,7 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
/* Read the SPI Status Register again to clear the status bit */
|
||||
|
||||
getreg32(LPC17_40_SPI_SR);
|
||||
return (uint16_t)getreg32(LPC17_40_SPI_DR);
|
||||
return getreg32(LPC17_40_SPI_DR);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -411,14 +421,16 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
* 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
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords)
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev,
|
||||
FAR const void *buffer, size_t nwords)
|
||||
{
|
||||
FAR uint8_t *ptr = (FAR uint8_t *)buffer;
|
||||
uint8_t data;
|
||||
|
@ -455,16 +467,18 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
|
|||
* dev - Device-specific state data
|
||||
* buffer - 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
|
||||
* 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)
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
|
||||
size_t nwords)
|
||||
{
|
||||
FAR uint8_t *ptr = (FAR uint8_t *)buffer;
|
||||
|
||||
|
|
|
@ -65,7 +65,9 @@
|
|||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* This driver does not support the SPI exchange method. */
|
||||
|
||||
#ifdef CONFIG_SPI_EXCHANGE
|
||||
|
@ -75,9 +77,9 @@
|
|||
/* SSP Clocking *************************************************************/
|
||||
|
||||
#if defined(LPC176x)
|
||||
/* The CPU clock by 1, 2, 4, or 8 to get the SSP peripheral clock (SSP_CLOCK).
|
||||
* SSP_CLOCK may be further divided by 2-254 to get the SSP clock. If we
|
||||
* want a usable range of 4KHz to 25MHz for the SSP, then:
|
||||
/* The CPU clock by 1, 2, 4, or 8 to get the SSP peripheral clock
|
||||
* (SSP_CLOCK). SSP_CLOCK may be further divided by 2-254 to get the SSP
|
||||
* clock. If we want a usable range of 4KHz to 25MHz for the SSP, then:
|
||||
*
|
||||
* 1. SSPCLK must be greater than (2*25MHz) = 50MHz, and
|
||||
* 2. SSPCLK must be less than (254*40Khz) = 101.6MHz.
|
||||
|
@ -94,8 +96,8 @@
|
|||
# define SSP_CLOCK LPC17_40_CCLK
|
||||
|
||||
#elif defined(LPC178x_40xx)
|
||||
/* All peripherals are clocked by the same peripheral clock in the LPC178x/40xx
|
||||
* family.
|
||||
/* All peripherals are clocked by the same peripheral clock in the
|
||||
* LPC178x/40xx family.
|
||||
*/
|
||||
|
||||
# define SSP_CLOCK BOARD_PCLK_FREQUENCY
|
||||
|
@ -128,19 +130,23 @@ struct lpc17_40_sspdev_s
|
|||
|
||||
/* Helpers */
|
||||
|
||||
static inline uint32_t ssp_getreg(FAR struct lpc17_40_sspdev_s *priv, uint8_t offset);
|
||||
static inline void ssp_putreg(FAR struct lpc17_40_sspdev_s *priv, uint8_t offset,
|
||||
uint32_t value);
|
||||
static inline uint32_t ssp_getreg(FAR struct lpc17_40_sspdev_s *priv,
|
||||
uint8_t offset);
|
||||
static inline void ssp_putreg(FAR struct lpc17_40_sspdev_s *priv,
|
||||
uint8_t offset, uint32_t value);
|
||||
|
||||
/* SPI methods */
|
||||
|
||||
static int ssp_lock(FAR struct spi_dev_s *dev, bool lock);
|
||||
static uint32_t ssp_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency);
|
||||
static uint32_t ssp_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency);
|
||||
static void ssp_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
|
||||
static void ssp_setbits(FAR struct spi_dev_s *dev, int nbits);
|
||||
static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t ch);
|
||||
static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords);
|
||||
static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords);
|
||||
static uint32_t ssp_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
static void ssp_sndblock(FAR struct spi_dev_s *dev,
|
||||
FAR const void *buffer, size_t nwords);
|
||||
static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
|
||||
size_t nwords);
|
||||
|
||||
/* Initialization */
|
||||
|
||||
|
@ -185,7 +191,10 @@ static const struct spi_ops_s g_spi0ops =
|
|||
|
||||
static struct lpc17_40_sspdev_s g_ssp0dev =
|
||||
{
|
||||
.spidev = { &g_spi0ops },
|
||||
.spidev =
|
||||
{
|
||||
&g_spi0ops
|
||||
},
|
||||
.sspbase = LPC17_40_SSP0_BASE,
|
||||
#ifdef CONFIG_LPC17_40_SSP_INTERRUPTS
|
||||
.sspirq = LPC17_40_IRQ_SSP0,
|
||||
|
@ -217,7 +226,10 @@ static const struct spi_ops_s g_spi1ops =
|
|||
|
||||
static struct lpc17_40_sspdev_s g_ssp1dev =
|
||||
{
|
||||
.spidev = { &g_spi1ops },
|
||||
.spidev =
|
||||
{
|
||||
&g_spi1ops
|
||||
},
|
||||
.sspbase = LPC17_40_SSP1_BASE,
|
||||
#ifdef CONFIG_LPC17_40_SSP_INTERRUPTS
|
||||
.sspirq = LPC17_40_IRQ_SSP1,
|
||||
|
@ -249,7 +261,10 @@ static const struct spi_ops_s g_spi2ops =
|
|||
|
||||
static struct lpc17_40_sspdev_s g_ssp2dev =
|
||||
{
|
||||
.spidev = { &g_spi2ops },
|
||||
.spidev =
|
||||
{
|
||||
&g_spi2ops
|
||||
},
|
||||
.sspbase = LPC17_40_SSP2_BASE,
|
||||
#ifdef CONFIG_LPC17_40_SSP_INTERRUPTS
|
||||
.sspirq = LPC17_40_IRQ_SSP2,
|
||||
|
@ -280,7 +295,8 @@ static struct lpc17_40_sspdev_s g_ssp2dev =
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t ssp_getreg(FAR struct lpc17_40_sspdev_s *priv, uint8_t offset)
|
||||
static inline uint32_t ssp_getreg(FAR struct lpc17_40_sspdev_s *priv,
|
||||
uint8_t offset)
|
||||
{
|
||||
return getreg32(priv->sspbase + (uint32_t)offset);
|
||||
}
|
||||
|
@ -301,7 +317,8 @@ static inline uint32_t ssp_getreg(FAR struct lpc17_40_sspdev_s *priv, uint8_t of
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void ssp_putreg(FAR struct lpc17_40_sspdev_s *priv, uint8_t offset, uint32_t value)
|
||||
static inline void ssp_putreg(FAR struct lpc17_40_sspdev_s *priv,
|
||||
uint8_t offset, uint32_t value)
|
||||
{
|
||||
putreg32(value, priv->sspbase + (uint32_t)offset);
|
||||
}
|
||||
|
@ -359,7 +376,8 @@ static int ssp_lock(FAR struct spi_dev_s *dev, bool lock)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t ssp_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
||||
static uint32_t ssp_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency)
|
||||
{
|
||||
FAR struct lpc17_40_sspdev_s *priv = (FAR struct lpc17_40_sspdev_s *)dev;
|
||||
uint32_t cpsdvsr;
|
||||
|
@ -562,7 +580,7 @@ static void ssp_setbits(FAR struct spi_dev_s *dev, int nbits)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t ssp_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
FAR struct lpc17_40_sspdev_s *priv = (FAR struct lpc17_40_sspdev_s *)dev;
|
||||
register uint32_t regval;
|
||||
|
@ -573,7 +591,7 @@ static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
|
||||
/* Write the byte to the TX FIFO */
|
||||
|
||||
ssp_putreg(priv, LPC17_40_SSP_DR_OFFSET, (uint32_t)wd);
|
||||
ssp_putreg(priv, LPC17_40_SSP_DR_OFFSET, wd);
|
||||
|
||||
/* Wait for the RX FIFO not empty */
|
||||
|
||||
|
@ -583,7 +601,7 @@ static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
|
||||
regval = ssp_getreg(priv, LPC17_40_SSP_DR_OFFSET);
|
||||
spiinfo("%04x->%04x\n", wd, regval);
|
||||
return (uint16_t)regval;
|
||||
return regval;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -598,14 +616,16 @@ static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
* 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
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords)
|
||||
static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
|
||||
size_t nwords)
|
||||
{
|
||||
FAR struct lpc17_40_sspdev_s *priv = (FAR struct lpc17_40_sspdev_s *)dev;
|
||||
union
|
||||
|
@ -614,6 +634,7 @@ static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
|
|||
FAR const uint16_t *p16;
|
||||
FAR const void *pv;
|
||||
} u;
|
||||
|
||||
uint32_t data;
|
||||
uint32_t sr;
|
||||
|
||||
|
@ -625,7 +646,8 @@ static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
|
|||
{
|
||||
/* While the TX FIFO is not full and there are bytes left to send */
|
||||
|
||||
while ((ssp_getreg(priv, LPC17_40_SSP_SR_OFFSET) & SSP_SR_TNF) && nwords)
|
||||
while ((ssp_getreg(priv, LPC17_40_SSP_SR_OFFSET) & SSP_SR_TNF) &&
|
||||
nwords)
|
||||
{
|
||||
/* Fetch the data to send */
|
||||
|
||||
|
@ -661,9 +683,9 @@ static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
|
|||
}
|
||||
|
||||
/* There is a race condition where TFE may go true just before
|
||||
* RNE goes true and this loop terminates prematurely. The nasty little
|
||||
* delay in the following solves that (it could probably be tuned
|
||||
* to improve performance).
|
||||
* RNE goes true and this loop terminates prematurely. The nasty
|
||||
* little delay in the following solves that (it could probably be
|
||||
* tuned to improve performance).
|
||||
*/
|
||||
|
||||
else if ((sr & SSP_SR_TFE) != 0)
|
||||
|
@ -685,16 +707,18 @@ static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
|
|||
* dev - Device-specific state data
|
||||
* buffer - 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
|
||||
* 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 ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords)
|
||||
static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
|
||||
size_t nwords)
|
||||
{
|
||||
FAR struct lpc17_40_sspdev_s *priv = (FAR struct lpc17_40_sspdev_s *)dev;
|
||||
union
|
||||
|
@ -703,6 +727,7 @@ static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nw
|
|||
FAR uint16_t *p16;
|
||||
FAR void *pv;
|
||||
} u;
|
||||
|
||||
uint32_t data;
|
||||
uint32_t rxpending = 0;
|
||||
|
||||
|
@ -741,6 +766,7 @@ static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nw
|
|||
{
|
||||
*u.p8++ = (uint8_t)data;
|
||||
}
|
||||
|
||||
rxpending--;
|
||||
}
|
||||
}
|
||||
|
@ -956,7 +982,8 @@ FAR struct spi_dev_s *lpc17_40_sspbus_initialize(int port)
|
|||
|
||||
/* Configure 8-bit SPI mode */
|
||||
|
||||
ssp_putreg(priv, LPC17_40_SSP_CR0_OFFSET, SSP_CR0_DSS_8BIT | SSP_CR0_FRF_SPI);
|
||||
ssp_putreg(priv, LPC17_40_SSP_CR0_OFFSET,
|
||||
SSP_CR0_DSS_8BIT | SSP_CR0_FRF_SPI);
|
||||
|
||||
/* Disable the SSP and all interrupts (we'll poll for all data) */
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*
|
||||
* Derived from arch/arm/src/lpc17xx_40xx/lpc17_40_spi.c
|
||||
*
|
||||
* Copyright (C) 2010, 2012, 2014, 2016-2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2010-2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -69,6 +69,7 @@
|
|||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
#ifdef CONFIG_SPI_EXCHANGE
|
||||
|
@ -81,8 +82,8 @@
|
|||
* clock (SPI_CLOCK). SPI_CLOCK may be further divided by 8-254 to get the
|
||||
* SPI clock. If we want a usable range of 4KHz to 25MHz for the SPI, then:
|
||||
*
|
||||
* 1. SPICLK must be greater than (8*25MHz) = 200MHz (so we can't reach 25MHz),
|
||||
* and
|
||||
* 1. SPICLK must be greater than (8*25MHz) = 200MHz (so we can't reach
|
||||
* 25MHz), and
|
||||
* 2. SPICLK must be less than (254*40Khz) = 101.6MHz.
|
||||
*
|
||||
* If we assume that CCLK less than or equal to 100MHz, we can just
|
||||
|
@ -117,12 +118,15 @@ struct lpc23xx_spidev_s
|
|||
/* SPI methods */
|
||||
|
||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency);
|
||||
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 uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
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);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
|
@ -154,7 +158,10 @@ static const struct spi_ops_s g_spiops =
|
|||
|
||||
static struct lpc23xx_spidev_s g_spidev =
|
||||
{
|
||||
.spidev = { &g_spiops },
|
||||
.spidev =
|
||||
{
|
||||
&g_spiops
|
||||
},
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -218,7 +225,8 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency)
|
||||
{
|
||||
FAR struct lpc23xx_spidev_s *priv = (FAR struct lpc23xx_spidev_s *)dev;
|
||||
uint32_t divisor;
|
||||
|
@ -292,7 +300,7 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
|||
|
||||
/* Has the mode changed? */
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
DEBUGASSERT(priv != NULL);
|
||||
if (mode != priv->mode)
|
||||
{
|
||||
/* Yes... Set CR appropriately */
|
||||
|
@ -387,11 +395,11 @@ 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 wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
/* Write the data to transmitted to the SPI Data Register */
|
||||
|
||||
putreg32((uint32_t)wd, SPI_DR);
|
||||
putreg32(wd, SPI_DR);
|
||||
|
||||
/* Wait for the SPIF bit in the SPI Status Register to be set to 1. The
|
||||
* SPIF bit will be set after the last sampling clock edge of the SPI
|
||||
|
@ -403,7 +411,7 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
/* Read the SPI Status Register again to clear the status bit */
|
||||
|
||||
getreg32(SPI_SR);
|
||||
return (uint16_t)getreg32(SPI_DR);
|
||||
return getreg32(SPI_DR);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -418,14 +426,16 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
* 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
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords)
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev,
|
||||
FAR const void *buffer, size_t nwords)
|
||||
{
|
||||
FAR uint8_t *ptr = (FAR uint8_t *)buffer;
|
||||
uint8_t data;
|
||||
|
@ -462,16 +472,18 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
|
|||
* dev - Device-specific state data
|
||||
* buffer - 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
|
||||
* 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)
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
|
||||
size_t nwords)
|
||||
{
|
||||
FAR uint8_t *ptr = (FAR uint8_t *)buffer;
|
||||
|
||||
|
@ -537,14 +549,14 @@ FAR struct spi_dev_s *lpc23_spibus_initialize(int port)
|
|||
|
||||
flags = enter_critical_section();
|
||||
|
||||
regval = getreg32(LPC23XX_SCB_BASE+SCB_PCONP_OFFSET);
|
||||
regval = getreg32(LPC23XX_SCB_BASE + SCB_PCONP_OFFSET);
|
||||
regval |= PCSPI;
|
||||
putreg32(regval, LPC23XX_SCB_BASE+SCB_PCONP_OFFSET);
|
||||
putreg32(regval, LPC23XX_SCB_BASE + SCB_PCONP_OFFSET);
|
||||
|
||||
regval = getreg32(LPC23XX_SCB_BASE+SCB_PCLKSEL0_OFFSET);
|
||||
regval = getreg32(LPC23XX_SCB_BASE + SCB_PCLKSEL0_OFFSET);
|
||||
regval &= ~SPI_PCLKSEL_MASK;
|
||||
regval |= SPI_PCLKSEL;
|
||||
putreg32(regval, LPC23XX_SCB_BASE+SCB_PCLKSEL0_OFFSET);
|
||||
putreg32(regval, LPC23XX_SCB_BASE + SCB_PCLKSEL0_OFFSET);
|
||||
|
||||
regval = getreg32(LPC23XX_PINSEL0);
|
||||
regval &= ~SPI_PINSEL0_MASK ;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/************************************************************************************
|
||||
* arm/arm/src/lpc31xx/lpc31_spi.c
|
||||
/****************************************************************************
|
||||
* arch/arm/src/lpc31xx/lpc31_spi.c
|
||||
*
|
||||
* Copyright (C) 2009-2010, 2012, 2016-2017 Gregory Nutt. All rights reserved.
|
||||
* Author: David Hewson, deriving in part from other SPI drivers originally by
|
||||
* Gregory Nutt <gnutt@nuttx.org>
|
||||
* Copyright (C) 2009-2017 Gregory Nutt. All rights reserved.
|
||||
* Author: David Hewson, deriving in part from other SPI drivers
|
||||
* originally by Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -32,11 +32,11 @@
|
|||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
|
@ -55,13 +55,14 @@
|
|||
#include "lpc31_spi.h"
|
||||
#include "lpc31_ioconfig.h"
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ********************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* Debug ********************************************************************/
|
||||
|
||||
/* Debug ****************************************************************************/
|
||||
/* CONFIG_LPC31_SPI_REGDEBUG enabled very low, register-level debug output.
|
||||
* CONFIG_DEBUG_FEATURES must also be defined
|
||||
*/
|
||||
|
@ -70,18 +71,18 @@
|
|||
# undef CONFIG_LPC31_SPI_REGDEBUG
|
||||
#endif
|
||||
|
||||
/* FIFOs ****************************************************************************/
|
||||
/* 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_MIN_DIVIDER 2
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
struct lpc31_spidev_s
|
||||
{
|
||||
|
@ -96,9 +97,9 @@ struct lpc31_spidev_s
|
|||
uint32_t slv2;
|
||||
};
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LPC31_SPI_REGDEBUG
|
||||
static bool spi_checkreg(bool wr, uint32_t value, uint32_t address);
|
||||
|
@ -109,31 +110,37 @@ static uint32_t spi_getreg(uint32_t address);
|
|||
# define spi_getreg(a) getreg32(a)
|
||||
#endif
|
||||
|
||||
static inline void spi_drive_cs(FAR struct lpc31_spidev_s *priv, uint8_t slave, uint8_t val);
|
||||
static inline void spi_select_slave(FAR struct lpc31_spidev_s *priv, uint8_t slave);
|
||||
static inline uint16_t spi_readword(FAR struct lpc31_spidev_s *priv);
|
||||
static inline void spi_writeword(FAR struct lpc31_spidev_s *priv, uint16_t word);
|
||||
static inline void spi_drive_cs(FAR struct lpc31_spidev_s *priv,
|
||||
uint8_t slave, uint8_t val);
|
||||
static inline void spi_select_slave(FAR struct lpc31_spidev_s *priv,
|
||||
uint8_t slave);
|
||||
static inline uint32_t spi_readword(FAR struct lpc31_spidev_s *priv);
|
||||
static inline void spi_writeword(FAR struct lpc31_spidev_s *priv,
|
||||
uint32_t word);
|
||||
|
||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
|
||||
static void spi_select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected);
|
||||
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_select(FAR struct spi_dev_s *dev, uint32_t devid,
|
||||
bool selected);
|
||||
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 uint8_t spi_status(FAR struct spi_dev_s *dev, uint32_t devid);
|
||||
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,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t word);
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
size_t nwords);
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer,
|
||||
size_t nwords);
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, size_t nwords);
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
#endif
|
||||
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static const struct spi_ops_s g_spiops =
|
||||
{
|
||||
|
@ -161,7 +168,10 @@ static const struct spi_ops_s g_spiops =
|
|||
|
||||
static struct lpc31_spidev_s g_spidev =
|
||||
{
|
||||
.spidev = { &g_spiops },
|
||||
.spidev =
|
||||
{
|
||||
&g_spiops
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef CONFIG_LPC31_SPI_REGDEBUG
|
||||
|
@ -171,13 +181,13 @@ static uint32_t g_valuelast;
|
|||
static int g_ntimes;
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_checkreg
|
||||
|
@ -215,6 +225,7 @@ static bool spi_checkreg(bool wr, uint32_t value, uint32_t address)
|
|||
g_addresslast = address;
|
||||
g_ntimes = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
@ -241,6 +252,7 @@ static void spi_putreg(uint32_t value, uint32_t address)
|
|||
{
|
||||
spiinfo("%08x<-%08x\n", address, value);
|
||||
}
|
||||
|
||||
putreg32(value, address);
|
||||
}
|
||||
#endif
|
||||
|
@ -267,6 +279,7 @@ static uint32_t spi_getreg(uint32_t address)
|
|||
{
|
||||
spiinfo("%08x->%08x\n", address, value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
#endif
|
||||
|
@ -287,7 +300,8 @@ static uint32_t spi_getreg(uint32_t address)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_drive_cs(FAR struct lpc31_spidev_s *priv, uint8_t slave, uint8_t val)
|
||||
static inline void spi_drive_cs(FAR struct lpc31_spidev_s *priv,
|
||||
uint8_t slave, uint8_t val)
|
||||
{
|
||||
switch (slave)
|
||||
{
|
||||
|
@ -300,31 +314,40 @@ static inline void spi_drive_cs(FAR struct lpc31_spidev_s *priv, uint8_t slave,
|
|||
{
|
||||
spi_putreg(IOCONFIG_SPI_CSOUT0, LPC31_IOCONFIG_SPI_MODE0SET);
|
||||
}
|
||||
|
||||
spi_putreg(IOCONFIG_SPI_CSOUT0, LPC31_IOCONFIG_SPI_MODE1SET);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (val == 0)
|
||||
{
|
||||
spi_putreg(IOCONFIG_EBII2STX0_MUARTCTSN, LPC31_IOCONFIG_EBII2STX0_MODE0RESET);
|
||||
spi_putreg(IOCONFIG_EBII2STX0_MUARTCTSN,
|
||||
LPC31_IOCONFIG_EBII2STX0_MODE0RESET);
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_putreg(IOCONFIG_EBII2STX0_MUARTCTSN, LPC31_IOCONFIG_EBII2STX0_MODE0SET);
|
||||
spi_putreg(IOCONFIG_EBII2STX0_MUARTCTSN,
|
||||
LPC31_IOCONFIG_EBII2STX0_MODE0SET);
|
||||
}
|
||||
spi_putreg(IOCONFIG_EBII2STX0_MUARTCTSN, LPC31_IOCONFIG_EBII2STX0_MODE1SET);
|
||||
|
||||
spi_putreg(IOCONFIG_EBII2STX0_MUARTCTSN,
|
||||
LPC31_IOCONFIG_EBII2STX0_MODE1SET);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (val == 0)
|
||||
{
|
||||
spi_putreg(IOCONFIG_EBII2STX0_MUARTRTSN, LPC31_IOCONFIG_EBII2STX0_MODE0RESET);
|
||||
spi_putreg(IOCONFIG_EBII2STX0_MUARTRTSN,
|
||||
LPC31_IOCONFIG_EBII2STX0_MODE0RESET);
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_putreg(IOCONFIG_EBII2STX0_MUARTRTSN, LPC31_IOCONFIG_EBII2STX0_MODE0SET);
|
||||
spi_putreg(IOCONFIG_EBII2STX0_MUARTRTSN,
|
||||
LPC31_IOCONFIG_EBII2STX0_MODE0SET);
|
||||
}
|
||||
spi_putreg(IOCONFIG_EBII2STX0_MUARTRTSN, LPC31_IOCONFIG_EBII2STX0_MODE1SET);
|
||||
|
||||
spi_putreg(IOCONFIG_EBII2STX0_MUARTRTSN,
|
||||
LPC31_IOCONFIG_EBII2STX0_MODE1SET);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -344,7 +367,8 @@ static inline void spi_drive_cs(FAR struct lpc31_spidev_s *priv, uint8_t slave,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_select_slave(FAR struct lpc31_spidev_s *priv, uint8_t slave)
|
||||
static inline void spi_select_slave(FAR struct lpc31_spidev_s *priv,
|
||||
uint8_t slave)
|
||||
{
|
||||
switch (slave)
|
||||
{
|
||||
|
@ -368,7 +392,7 @@ static inline void spi_select_slave(FAR struct lpc31_spidev_s *priv, uint8_t sla
|
|||
}
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_readword
|
||||
*
|
||||
* Description:
|
||||
|
@ -380,9 +404,9 @@ static inline void spi_select_slave(FAR struct lpc31_spidev_s *priv, uint8_t sla
|
|||
* Returned Value:
|
||||
* Byte as read
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint16_t spi_readword(FAR struct lpc31_spidev_s *priv)
|
||||
static inline uint32_t spi_readword(FAR struct lpc31_spidev_s *priv)
|
||||
{
|
||||
/* Wait until the RX FIFO is not empty */
|
||||
|
||||
|
@ -390,10 +414,10 @@ static inline uint16_t spi_readword(FAR struct lpc31_spidev_s *priv)
|
|||
|
||||
/* Then return the received word */
|
||||
|
||||
return (uint16_t)spi_getreg(LPC31_SPI_FIFODATA);
|
||||
return spi_getreg(LPC31_SPI_FIFODATA);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_writeword
|
||||
*
|
||||
* Description:
|
||||
|
@ -406,9 +430,10 @@ static inline uint16_t spi_readword(FAR struct lpc31_spidev_s *priv)
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_writeword(FAR struct lpc31_spidev_s *priv, uint16_t word)
|
||||
static inline void spi_writeword(FAR struct lpc31_spidev_s *priv,
|
||||
uint32_t word)
|
||||
{
|
||||
/* Wait until the TX FIFO is not full */
|
||||
|
||||
|
@ -475,13 +500,16 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected)
|
||||
static void spi_select(FAR struct spi_dev_s *dev, uint32_t devid,
|
||||
bool selected)
|
||||
{
|
||||
struct lpc31_spidev_s *priv = (struct lpc31_spidev_s *) dev;
|
||||
uint8_t slave = 0;
|
||||
|
||||
/* FIXME: map the devid to the SPI slave - this should really
|
||||
* be in board specific code..... */
|
||||
* be in board specific code.....
|
||||
*/
|
||||
|
||||
switch (devid)
|
||||
{
|
||||
case SPIDEV_FLASH(0):
|
||||
|
@ -513,7 +541,9 @@ static void spi_select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected)
|
|||
|
||||
/* Enable SPI as master and notify of slave enables change */
|
||||
|
||||
spi_putreg((1 << SPI_CONFIG_INTERSLVDELAY_SHIFT) | SPI_CONFIG_UPDENABLE | SPI_CONFIG_SPIENABLE, LPC31_SPI_CONFIG);
|
||||
spi_putreg((1 << SPI_CONFIG_INTERSLVDELAY_SHIFT) |
|
||||
SPI_CONFIG_UPDENABLE | SPI_CONFIG_SPIENABLE,
|
||||
LPC31_SPI_CONFIG);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -529,7 +559,7 @@ static void spi_select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected)
|
|||
}
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_setfrequency
|
||||
*
|
||||
* Description:
|
||||
|
@ -542,17 +572,22 @@ static void spi_select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected)
|
|||
* Returned Value:
|
||||
* Returns the actual frequency selected
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency)
|
||||
{
|
||||
FAR struct lpc31_spidev_s *priv = (FAR struct lpc31_spidev_s *)dev;
|
||||
uint32_t spi_clk, div, div1, div2;
|
||||
uint32_t spi_clk;
|
||||
uint32_t div;
|
||||
uint32_t div1;
|
||||
uint32_t div2;
|
||||
|
||||
if (priv->frequency != frequency)
|
||||
{
|
||||
/* The SPI clock is derived from the (main system oscillator / 2),
|
||||
* so compute the best divider from that clock */
|
||||
* so compute the best divider from that clock
|
||||
*/
|
||||
|
||||
spi_clk = lpc31_clkfreq(CLKID_SPICLK, DOMAINID_SPI);
|
||||
|
||||
|
@ -569,10 +604,13 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
|||
div = SPI_MIN_DIVIDER;
|
||||
}
|
||||
|
||||
div2 = (((div-1) / 512) + 2) * 2;
|
||||
div2 = (((div - 1) / 512) + 2) * 2;
|
||||
div1 = ((((div + div2 / 2) / div2) - 1));
|
||||
|
||||
priv->slv1 = (priv->slv1 & ~(SPI_SLV_1_CLKDIV2_MASK | SPI_SLV_1_CLKDIV1_MASK)) | (div2 << SPI_SLV_1_CLKDIV2_SHIFT) | (div1 << SPI_SLV_1_CLKDIV1_SHIFT);
|
||||
priv->slv1 = (priv->slv1 & ~(SPI_SLV_1_CLKDIV2_MASK |
|
||||
SPI_SLV_1_CLKDIV1_MASK)) |
|
||||
(div2 << SPI_SLV_1_CLKDIV2_SHIFT) |
|
||||
(div1 << SPI_SLV_1_CLKDIV1_SHIFT);
|
||||
|
||||
priv->frequency = frequency;
|
||||
priv->actual = frequency; /* FIXME */
|
||||
|
@ -581,7 +619,7 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
|||
return priv->actual;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_setmode
|
||||
*
|
||||
* Description:
|
||||
|
@ -594,7 +632,7 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
|||
* Returned Value:
|
||||
* Returns the actual frequency selected
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
||||
{
|
||||
|
@ -639,7 +677,7 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
|||
}
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_setbits
|
||||
*
|
||||
* Description:
|
||||
|
@ -652,7 +690,7 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
||||
{
|
||||
|
@ -662,7 +700,8 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
|||
|
||||
if (nbits != priv->nbits)
|
||||
{
|
||||
priv->slv2 = (priv->slv2 & ~SPI_SLV_2_WDSIZE_MASK) | ((nbits-1) << SPI_SLV_2_WDSIZE_SHIFT);
|
||||
priv->slv2 = (priv->slv2 & ~SPI_SLV_2_WDSIZE_MASK) |
|
||||
((nbits - 1) << SPI_SLV_2_WDSIZE_SHIFT);
|
||||
priv->nbits = nbits;
|
||||
}
|
||||
}
|
||||
|
@ -685,12 +724,13 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
|||
static uint8_t spi_status(FAR struct spi_dev_s *dev, uint32_t devid)
|
||||
{
|
||||
/* FIXME: is there anyway to determine this
|
||||
* it should probably be board dependent anyway */
|
||||
* it should probably be board dependent anyway
|
||||
*/
|
||||
|
||||
return SPI_STATUS_PRESENT;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_send
|
||||
*
|
||||
* Description:
|
||||
|
@ -704,9 +744,9 @@ static uint8_t spi_status(FAR struct spi_dev_s *dev, uint32_t devid)
|
|||
* Returned Value:
|
||||
* response
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t word)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t word)
|
||||
{
|
||||
FAR struct lpc31_spidev_s *priv = (FAR struct lpc31_spidev_s *)dev;
|
||||
DEBUGASSERT(priv);
|
||||
|
@ -728,12 +768,13 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t word)
|
|||
* 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
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords)
|
||||
|
@ -767,8 +808,9 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
|
||||
/* Then send the word */
|
||||
|
||||
spi_writeword(priv, word);
|
||||
spi_writeword(priv, (uint32_t)word);
|
||||
}
|
||||
|
||||
nwords -= maxtx;
|
||||
|
||||
/* Then empty the RX FIFO */
|
||||
|
@ -807,8 +849,9 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
|
||||
/* Then send the word */
|
||||
|
||||
spi_writeword(priv, (uint16_t)word);
|
||||
spi_writeword(priv, (uint32_t)word);
|
||||
}
|
||||
|
||||
nwords -= maxtx;
|
||||
|
||||
/* Then empty the RX FIFO */
|
||||
|
@ -837,24 +880,26 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
* Input Parameters:
|
||||
* dev - Device-specific state data
|
||||
* txbuffer - 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
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, size_t nwords)
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, size_t nwords)
|
||||
{
|
||||
return spi_exchange(dev, txbuffer, NULL, nwords);
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_recvblock
|
||||
*
|
||||
* Description:
|
||||
|
@ -863,28 +908,30 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, si
|
|||
* 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 spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, size_t nwords)
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer,
|
||||
size_t nwords)
|
||||
{
|
||||
return spi_exchange(dev, NULL, rxbuffer, nwords);
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: lpc31_spibus_initialize
|
||||
*
|
||||
* Description:
|
||||
|
@ -896,7 +943,7 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, size_t
|
|||
* Returned Value:
|
||||
* Valid SPI device structure reference on success; a NULL on failure
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct spi_dev_s *lpc31_spibus_initialize(int port)
|
||||
{
|
||||
|
|
|
@ -66,12 +66,12 @@
|
|||
|
||||
/* SPI Clocking.
|
||||
*
|
||||
* The CPU clock by 1, 2, 4, or 8 to get the SPI peripheral clock (SPI_CLOCK).
|
||||
* SPI_CLOCK may be further divided by 8-254 to get the SPI clock. If we
|
||||
* want a usable range of 4KHz to 25MHz for the SPI, then:
|
||||
* The CPU clock by 1, 2, 4, or 8 to get the SPI peripheral clock
|
||||
* (SPI_CLOCK). SPI_CLOCK may be further divided by 8-254 to get the SPI
|
||||
* clock. If we want a usable range of 4KHz to 25MHz for the SPI, then:
|
||||
*
|
||||
* 1. SPICLK must be greater than (8*25MHz) = 200MHz (so we can't reach 25MHz),
|
||||
* and
|
||||
* 1. SPICLK must be greater than (8*25MHz) = 200MHz (so we can't reach
|
||||
* 25MHz), and
|
||||
* 2. SPICLK must be less than (254*40Khz) = 101.6MHz.
|
||||
*
|
||||
* If we assume that CCLK less than or equal to 100MHz, we can just
|
||||
|
@ -103,13 +103,17 @@ struct lpc43_spidev_s
|
|||
/* SPI methods */
|
||||
|
||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
|
||||
static void spi_select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected);
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency);
|
||||
static void spi_select(FAR struct spi_dev_s *dev, uint32_t devid,
|
||||
bool selected);
|
||||
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 uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
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);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
|
@ -141,7 +145,10 @@ static const struct spi_ops_s g_spiops =
|
|||
|
||||
static struct lpc43_spidev_s g_spidev =
|
||||
{
|
||||
.spidev = { &g_spiops },
|
||||
.spidev =
|
||||
{
|
||||
&g_spiops
|
||||
},
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -205,7 +212,8 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency)
|
||||
{
|
||||
FAR struct lpc43_spidev_s *priv = (FAR struct lpc43_spidev_s *)dev;
|
||||
uint32_t divisor;
|
||||
|
@ -371,11 +379,11 @@ 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 wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
/* Write the data to transmitted to the SPI Data Register */
|
||||
|
||||
putreg32((uint32_t)wd, LPC43_SPI_DR);
|
||||
putreg32(wd, LPC43_SPI_DR);
|
||||
|
||||
/* Wait for the SPIF bit in the SPI Status Register to be set to 1. The
|
||||
* SPIF bit will be set after the last sampling clock edge of the SPI
|
||||
|
@ -387,7 +395,7 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
/* Read the SPI Status Register again to clear the status bit */
|
||||
|
||||
getreg32(LPC43_SPI_SR);
|
||||
return (uint16_t)getreg32(LPC43_SPI_DR);
|
||||
return getreg32(LPC43_SPI_DR);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -402,14 +410,16 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
* 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
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords)
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
|
||||
size_t nwords)
|
||||
{
|
||||
FAR uint8_t *ptr = (FAR uint8_t *)buffer;
|
||||
uint8_t data;
|
||||
|
@ -446,16 +456,18 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
|
|||
* dev - Device-specific state data
|
||||
* buffer - 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
|
||||
* 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)
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
|
||||
size_t nwords)
|
||||
{
|
||||
FAR uint8_t *ptr = (FAR uint8_t *)buffer;
|
||||
|
||||
|
|
|
@ -91,22 +91,27 @@ struct lpc43_sspdev_s
|
|||
|
||||
/* Helpers */
|
||||
|
||||
static inline uint32_t ssp_getreg(FAR struct lpc43_sspdev_s *priv, uint8_t offset);
|
||||
static inline void ssp_putreg(FAR struct lpc43_sspdev_s *priv, uint8_t offset,
|
||||
uint32_t value);
|
||||
static inline uint32_t ssp_getreg(FAR struct lpc43_sspdev_s *priv,
|
||||
uint8_t offset);
|
||||
static inline void ssp_putreg(FAR struct lpc43_sspdev_s *priv,
|
||||
uint8_t offset, uint32_t value);
|
||||
|
||||
/* SPI methods */
|
||||
|
||||
static int ssp_lock(FAR struct spi_dev_s *dev, bool lock);
|
||||
static uint32_t ssp_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency);
|
||||
static uint32_t ssp_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency);
|
||||
static void ssp_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
|
||||
static void ssp_setbits(FAR struct spi_dev_s *dev, int nbits);
|
||||
static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t ch);
|
||||
static void ssp_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
static uint32_t ssp_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
static void ssp_exchange(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
size_t nwords);
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords);
|
||||
static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords);
|
||||
static void ssp_sndblock(FAR struct spi_dev_s *dev,
|
||||
FAR const void *buffer, size_t nwords);
|
||||
static void ssp_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
|
||||
size_t nwords);
|
||||
#endif
|
||||
|
||||
/* Initialization */
|
||||
|
@ -153,7 +158,10 @@ static const struct spi_ops_s g_spi0ops =
|
|||
|
||||
static struct lpc43_sspdev_s g_ssp0dev =
|
||||
{
|
||||
.spidev = { &g_spi0ops },
|
||||
.spidev =
|
||||
{
|
||||
&g_spi0ops
|
||||
},
|
||||
.sspbase = LPC43_SSP0_BASE,
|
||||
.sspbasefreq = BOARD_SSP0_BASEFREQ
|
||||
#ifdef CONFIG_LPC43_SSP_INTERRUPTS
|
||||
|
@ -190,7 +198,10 @@ static const struct spi_ops_s g_spi1ops =
|
|||
|
||||
static struct lpc43_sspdev_s g_ssp1dev =
|
||||
{
|
||||
.spidev = { &g_spi1ops },
|
||||
.spidev =
|
||||
{
|
||||
&g_spi1ops
|
||||
},
|
||||
.sspbase = LPC43_SSP1_BASE,
|
||||
.sspbasefreq = BOARD_SSP1_BASEFREQ
|
||||
#ifdef CONFIG_LPC43_SSP_INTERRUPTS
|
||||
|
@ -222,7 +233,8 @@ static struct lpc43_sspdev_s g_ssp1dev =
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t ssp_getreg(FAR struct lpc43_sspdev_s *priv, uint8_t offset)
|
||||
static inline uint32_t ssp_getreg(FAR struct lpc43_sspdev_s *priv,
|
||||
uint8_t offset)
|
||||
{
|
||||
return getreg32(priv->sspbase + (uint32_t)offset);
|
||||
}
|
||||
|
@ -243,7 +255,8 @@ static inline uint32_t ssp_getreg(FAR struct lpc43_sspdev_s *priv, uint8_t offse
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void ssp_putreg(FAR struct lpc43_sspdev_s *priv, uint8_t offset, uint32_t value)
|
||||
static inline void ssp_putreg(FAR struct lpc43_sspdev_s *priv,
|
||||
uint8_t offset, uint32_t value)
|
||||
{
|
||||
putreg32(value, priv->sspbase + (uint32_t)offset);
|
||||
}
|
||||
|
@ -301,7 +314,8 @@ static int ssp_lock(FAR struct spi_dev_s *dev, bool lock)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t ssp_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
||||
static uint32_t ssp_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency)
|
||||
{
|
||||
FAR struct lpc43_sspdev_s *priv = (FAR struct lpc43_sspdev_s *)dev;
|
||||
uint32_t divisor;
|
||||
|
@ -444,7 +458,8 @@ static void ssp_setbits(FAR struct spi_dev_s *dev, int nbits)
|
|||
regval &= ~SSP_CR0_DSS_MASK;
|
||||
regval |= ((nbits - 1) << SSP_CR0_DSS_SHIFT);
|
||||
ssp_putreg(priv, LPC43_SSP_CR0_OFFSET, regval);
|
||||
spiinfo("SSP Control Register 0 (CR0) after setting DSS: 0x%08X.\n", regval);
|
||||
spiinfo("SSP Control Register 0 (CR0) after setting"
|
||||
"DSS: 0x%08X.\n", regval);
|
||||
|
||||
/* Save the selection so the subsequence re-configurations will be faster */
|
||||
|
||||
|
@ -468,7 +483,7 @@ static void ssp_setbits(FAR struct spi_dev_s *dev, int nbits)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t ssp_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
FAR struct lpc43_sspdev_s *priv = (FAR struct lpc43_sspdev_s *)dev;
|
||||
register uint32_t regval;
|
||||
|
@ -479,7 +494,7 @@ static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
|
||||
/* Write the byte to the TX FIFO */
|
||||
|
||||
ssp_putreg(priv, LPC43_SSP_DR_OFFSET, (uint32_t)wd);
|
||||
ssp_putreg(priv, LPC43_SSP_DR_OFFSET, wd);
|
||||
|
||||
/* Wait for the RX FIFO not empty */
|
||||
|
||||
|
@ -489,7 +504,7 @@ static uint16_t ssp_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
|
||||
regval = ssp_getreg(priv, LPC43_SSP_DR_OFFSET);
|
||||
spiinfo("%04x->%04x\n", wd, regval);
|
||||
return (uint16_t)regval;
|
||||
return regval;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -523,12 +538,14 @@ static void ssp_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
FAR const uint16_t *p16;
|
||||
FAR const void *pv;
|
||||
} tx;
|
||||
|
||||
union
|
||||
{
|
||||
FAR uint8_t *p8;
|
||||
FAR uint16_t *p16;
|
||||
FAR void *pv;
|
||||
} rx;
|
||||
|
||||
uint32_t data;
|
||||
uint32_t datadummy = (priv->nbits > 8) ? 0xffff : 0xff;
|
||||
uint32_t rxpending = 0;
|
||||
|
@ -628,10 +645,10 @@ static void ssp_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
|
|||
* dev - Device-specific state data
|
||||
* buffer - 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
|
||||
* 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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/lpc54xx/lpc54_spi.c
|
||||
* arch/arm/src/lpc54xx/lpc54_spi_master.c
|
||||
*
|
||||
* Copyright (C) 2017-2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
|
@ -159,7 +159,7 @@ struct lpc54_txdummy_s
|
|||
|
||||
/* Transfer helpers */
|
||||
|
||||
static inline unsigned int lpc54_spi_fifodepth(FAR struct lpc54_spidev_s *priv);
|
||||
static inline size_t lpc54_spi_fifodepth(FAR struct lpc54_spidev_s *priv);
|
||||
static inline bool lpc54_spi_txavailable(FAR struct lpc54_spidev_s *priv);
|
||||
static inline bool lpc54_spi_rxavailable(FAR struct lpc54_spidev_s *priv);
|
||||
|
||||
|
@ -182,7 +182,7 @@ static bool lpc54_spi_txdummy(FAR struct lpc54_spidev_s *priv,
|
|||
static void lpc54_spi_exchange8(FAR struct lpc54_spidev_s *priv,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
size_t nwords);
|
||||
#ifdefCONFIG_LPC54_SPI_WIDEDATA
|
||||
#ifdef CONFIG_LPC54_SPI_WIDEDATA
|
||||
static void lpc54_spi_exchange16(FAR struct lpc54_spidev_s *priv,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
size_t nwords);
|
||||
|
@ -209,7 +209,7 @@ static uint32_t lpc54_spi_setfrequency(FAR struct spi_dev_s *dev,
|
|||
static void lpc54_spi_setmode(FAR struct spi_dev_s *dev,
|
||||
enum spi_mode_e mode);
|
||||
static void lpc54_spi_setbits(FAR struct spi_dev_s *dev, int nbits);
|
||||
static uint16_t lpc54_spi_send(FAR struct spi_dev_s *dev, uint16_t ch);
|
||||
static uint32_t lpc54_spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
#ifdef CONFIG_SPI_EXCHANGE
|
||||
static void lpc54_spi_exchange(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
|
@ -591,7 +591,7 @@ static inline uint32_t lpc54_spi_getreg(struct lpc54_spidev_s *priv,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline unsigned int lpc54_spi_fifodepth(FAR struct lpc54_spidev_s *priv)
|
||||
static inline size_t lpc54_spi_fifodepth(FAR struct lpc54_spidev_s *priv)
|
||||
{
|
||||
uint32_t regval = lpc54_spi_getreg(priv, LPC54_SPI_FIFOCFG_OFFSET);
|
||||
return ((regval & SPI_FIFOCFG_SIZE_MASK) >> SPI_FIFOCFG_SIZE_SHIFT) << 3;
|
||||
|
@ -692,7 +692,7 @@ static void lpc54_spi_resetfifos(FAR struct lpc54_spidev_s *priv)
|
|||
* Name: lpc54_spi_rxtransfer8 and lpc54_spi_rxtransfer16
|
||||
*
|
||||
* Description:
|
||||
* Receive one 8- or 16-bit value from the selected SPI device.
|
||||
* Receive one 8-bit or 16-bit value from the selected SPI device.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - Device-specific state data
|
||||
|
@ -887,7 +887,8 @@ static bool lpc54_spi_txdummy(FAR struct lpc54_spidev_s *priv,
|
|||
* Name: lpc54_spi_exchange8 and lpc54_spi_exchange16
|
||||
*
|
||||
* Description:
|
||||
* Implements the SPI exchange method for the case of 8- and 16-bit transfers.
|
||||
* Implements the SPI exchange method for the case of 8-bit and 16-bit
|
||||
* transfers.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - Device-specific state data
|
||||
|
@ -911,7 +912,7 @@ static void lpc54_spi_exchange8(FAR struct lpc54_spidev_s *priv,
|
|||
{
|
||||
struct lpc54_rxtransfer8_s rxtransfer;
|
||||
struct lpc54_txtransfer8_s txtransfer;
|
||||
unsigned int depth;
|
||||
size_t depth;
|
||||
|
||||
DEBUGASSERT(rxbuffer != NULL && txbuffer != NULL);
|
||||
|
||||
|
@ -921,12 +922,12 @@ static void lpc54_spi_exchange8(FAR struct lpc54_spidev_s *priv,
|
|||
|
||||
/* Set up the transfer data */
|
||||
|
||||
txtransfer.txctrl = SPI_FIFOWR_LEN(priv->nbits) | SPI_FIFOWR_TXSSELN_ALL;
|
||||
txtransfer.txptr = (FAR uint8_t *)txbuffer;
|
||||
txtransfer.txctrl = SPI_FIFOWR_LEN(priv->nbits) | SPI_FIFOWR_TXSSELN_ALL;
|
||||
txtransfer.txptr = (FAR uint8_t *)txbuffer;
|
||||
txtransfer.remaining = nwords;
|
||||
rxtransfer.rxptr = (FAR uint8_t *)rxbuffer;
|
||||
rxtransfer.rxptr = (FAR uint8_t *)rxbuffer;
|
||||
rxtransfer.remaining = nwords;
|
||||
rxtransfer.expected = 0;
|
||||
rxtransfer.expected = 0;
|
||||
|
||||
/* Clear Tx/Rx errors and empty FIFOs */
|
||||
|
||||
|
@ -965,13 +966,14 @@ static void lpc54_spi_exchange8(FAR struct lpc54_spidev_s *priv,
|
|||
|
||||
#if defined(CONFIG_SPI_EXCHANGE) && defined(CONFIG_LPC54_SPI_WIDEDATA)
|
||||
static void lpc54_spi_exchange16(FAR struct lpc54_spidev_s *priv,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
FAR const void *txbuffer,
|
||||
FAR void *rxbuffer,
|
||||
size_t nwords)
|
||||
{
|
||||
struct lpc54_rxtransfer16_s rxtransfer;
|
||||
struct lpc54_txtransfer16_s txtransfer;
|
||||
uint32_t regval;
|
||||
unsigned int depth;
|
||||
size_t depth;
|
||||
|
||||
DEBUGASSERT(rxbuffer != NULL && ((uintptr_t)rxbuffer & 1) == 0);
|
||||
DEBUGASSERT(txbuffer != NULL && ((uintptr_t)txbuffer & 1) == 0);
|
||||
|
@ -982,12 +984,12 @@ static void lpc54_spi_exchange16(FAR struct lpc54_spidev_s *priv,
|
|||
|
||||
/* Set up the transfer data */
|
||||
|
||||
txtransfer.txctrl = SPI_FIFOWR_LEN(priv->nbits) | SPI_FIFOWR_TXSSELN_ALL;
|
||||
txtransfer.txptr = (FAR uint16_t *)txbuffer;
|
||||
txtransfer.txctrl = SPI_FIFOWR_LEN(priv->nbits) | SPI_FIFOWR_TXSSELN_ALL;
|
||||
txtransfer.txptr = (FAR uint16_t *)txbuffer;
|
||||
txtransfer.remaining = nwords;
|
||||
rxtransfer.rxptr = (FAR uint16_t *)rxbuffer;
|
||||
rxtransfer.rxptr = (FAR uint16_t *)rxbuffer;
|
||||
rxtransfer.remaining = nwords;
|
||||
rxtransfer.expected = 0;
|
||||
rxtransfer.expected = 0;
|
||||
|
||||
/* Clear Tx/Rx errors and empty FIFOs */
|
||||
|
||||
|
@ -1105,7 +1107,7 @@ static void lpc54_spi_sndblock16(FAR struct lpc54_spidev_s *priv,
|
|||
lpc54_spi_txtransfer16(priv, &txtransfer);
|
||||
}
|
||||
}
|
||||
#endif /*CONFIG_LPC54_SPI_WIDEDATA */
|
||||
#endif /* CONFIG_LPC54_SPI_WIDEDATA */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_spi_recvblock8 and lpc54_spi_recvblock16
|
||||
|
@ -1133,7 +1135,7 @@ static void lpc54_spi_recvblock8(FAR struct lpc54_spidev_s *priv,
|
|||
{
|
||||
struct lpc54_rxtransfer8_s rxtransfer;
|
||||
struct lpc54_txdummy_s txtransfer;
|
||||
unsigned int depth;
|
||||
size_t depth;
|
||||
|
||||
DEBUGASSERT(buffer != NULL);
|
||||
|
||||
|
@ -1158,7 +1160,7 @@ static void lpc54_spi_recvblock8(FAR struct lpc54_spidev_s *priv,
|
|||
* received.
|
||||
*/
|
||||
|
||||
while (txtransfer.remaining != 0|| rxtransfer.remaining != 0)
|
||||
while (txtransfer.remaining != 0 || rxtransfer.remaining != 0)
|
||||
{
|
||||
/* Transfer one byte from the Rx FIFO to the caller's Rx buffer */
|
||||
|
||||
|
@ -1188,7 +1190,7 @@ static void lpc54_spi_recvblock16(FAR struct lpc54_spidev_s *priv,
|
|||
{
|
||||
struct lpc54_rxtransfer16_s rxtransfer;
|
||||
struct lpc54_txdummy_s txtransfer;
|
||||
unsigned int depth;
|
||||
size_t depth;
|
||||
|
||||
DEBUGASSERT(buffer != NULL);
|
||||
|
||||
|
@ -1419,7 +1421,8 @@ static void lpc54_spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
|||
|
||||
/* The valid range of bit selections is SPI_MINWIDTH through SPI_MAXWIDTH */
|
||||
|
||||
DEBUGASSERT(priv != NULL && nbits >= SPI_MINWIDTH && nbits <= SPI_MAXWIDTH);
|
||||
DEBUGASSERT(priv != NULL && nbits >= SPI_MINWIDTH &&
|
||||
nbits <= SPI_MAXWIDTH);
|
||||
|
||||
if (nbits >= SPI_MINWIDTH && nbits <= SPI_MAXWIDTH)
|
||||
{
|
||||
|
@ -1445,7 +1448,7 @@ static void lpc54_spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t lpc54_spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t lpc54_spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
FAR struct lpc54_spidev_s *priv = (FAR struct lpc54_spidev_s *)dev;
|
||||
uint32_t regval;
|
||||
|
@ -1473,7 +1476,7 @@ static uint16_t lpc54_spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
|
||||
/* Then read and return the value from the Rx FIFO */
|
||||
|
||||
return (uint16_t)lpc54_spi_getreg(priv, LPC54_SPI_FIFORD_OFFSET);
|
||||
return lpc54_spi_getreg(priv, LPC54_SPI_FIFORD_OFFSET);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1669,6 +1672,7 @@ FAR struct spi_dev_s *lpc54_spibus_initialize(int port)
|
|||
flags = enter_critical_section();
|
||||
|
||||
/* Configure the requested SPI peripheral */
|
||||
|
||||
/* NOTE: The basic FLEXCOMM initialization was performed in
|
||||
* lpc54_lowputc.c.
|
||||
*/
|
||||
|
@ -2068,8 +2072,8 @@ FAR struct spi_dev_s *lpc54_spibus_initialize(int port)
|
|||
|
||||
/* Set the delay configuration (not used) */
|
||||
|
||||
regval = (SPI_DLY_PRE_DELAY(0) | SPI_DLY_POST_DELAY(0) | SPI_DLY_FRAME_DELAY(0) |
|
||||
SPI_DLY_TRANSFER_DELAY(0));
|
||||
regval = (SPI_DLY_PRE_DELAY(0) | SPI_DLY_POST_DELAY(0) |
|
||||
SPI_DLY_FRAME_DELAY(0) | SPI_DLY_TRANSFER_DELAY(0));
|
||||
lpc54_spi_putreg(priv, LPC54_SPI_DLY_OFFSET, regval);
|
||||
|
||||
/* Select a default frequency of approx. 400KHz */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/max326/max326_spi.c
|
||||
* arch/arm/src/max326xx/max32660/max32660_spim.c
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
|
@ -193,7 +193,7 @@ static void spi_setbits(struct spi_dev_s *dev, int nbits);
|
|||
static int spi_hwfeatures(struct spi_dev_s *dev,
|
||||
spi_hwfeatures_t features);
|
||||
#endif
|
||||
static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd);
|
||||
static uint32_t spi_send(struct spi_dev_s *dev, uint32_t wd);
|
||||
static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
||||
void *rxbuffer, size_t nwords);
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
|
@ -247,7 +247,10 @@ static const struct spi_ops_s g_sp0iops =
|
|||
|
||||
static struct max326_spidev_s g_spi0dev =
|
||||
{
|
||||
.dev = { &g_sp0iops },
|
||||
.dev =
|
||||
{
|
||||
&g_sp0iops
|
||||
},
|
||||
.base = MAX326_SPI0_BASE,
|
||||
#ifdef CONFIG_MAX326_SPI_INTERRUPTS
|
||||
.irq = MAX326_IRQ_SPI,
|
||||
|
@ -624,7 +627,8 @@ static int spi_poll(struct max326_spidev_s *priv)
|
|||
/* Break out if we've transmitted all the bytes and not receiving */
|
||||
|
||||
if ((priv->rxbuffer == NULL) && priv->txbytes == length &&
|
||||
(spi_getreg(priv, MAX326_SPI_DMA_OFFSET) & SPI_DMA_TXFIFOCNT_MASK) == 0)
|
||||
(spi_getreg(priv, MAX326_SPI_DMA_OFFSET) &
|
||||
SPI_DMA_TXFIFOCNT_MASK) == 0)
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
|
@ -790,8 +794,10 @@ static int spi_interrupt(int irq, void *context, void *arg)
|
|||
/* Check if there is more Rx data to be read */
|
||||
|
||||
regval = spi_getreg(priv, MAX326_SPI_DMA_OFFSET);
|
||||
rxavail = (regval & SPI_DMA_TXFIFOCNT_MASK) >> SPI_DMA_TXFIFOCNT_SHIFT;
|
||||
rxlevel = (regval & SPI_DMA_RXFIFOLVL_MASK) >> SPI_DMA_RXFIFOLVL_SHIFT;
|
||||
rxavail = (regval & SPI_DMA_TXFIFOCNT_MASK) >>
|
||||
SPI_DMA_TXFIFOCNT_SHIFT;
|
||||
rxlevel = (regval & SPI_DMA_RXFIFOLVL_MASK) >>
|
||||
SPI_DMA_RXFIFOLVL_SHIFT;
|
||||
}
|
||||
while (/* RX buffer != NULL && */ rxavail > rxlevel);
|
||||
}
|
||||
|
@ -998,12 +1004,14 @@ static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency)
|
|||
}
|
||||
|
||||
regval = spi_getreg(priv, MAX326_SPI_CLKCFG_OFFSET);
|
||||
regval &= ~(SPI_CLKCFG_LO_MASK | SPI_CLKCFG_HI_MASK | SPI_CLKCFG_SCALE_MASK);
|
||||
regval |= (SPI_CLKCFG_LO(high) | SPI_CLKCFG_HI(high) | SPI_CLKCFG_SCALE(scale));
|
||||
regval &= ~(SPI_CLKCFG_LO_MASK | SPI_CLKCFG_HI_MASK |
|
||||
SPI_CLKCFG_SCALE_MASK);
|
||||
regval |= (SPI_CLKCFG_LO(high) | SPI_CLKCFG_HI(high) |
|
||||
SPI_CLKCFG_SCALE(scale));
|
||||
spi_putreg(priv, MAX326_SPI_CLKCFG_OFFSET, regval);
|
||||
|
||||
/* Save the frequency selection so that subsequent reconfigurations will be
|
||||
* faster.
|
||||
/* Save the frequency selection so that subsequent reconfigurations
|
||||
* will be faster.
|
||||
*/
|
||||
|
||||
spiinfo("Frequency %d->%d\n", frequency, actual);
|
||||
|
@ -1160,9 +1168,9 @@ static int spi_hwfeatures(struct spi_dev_s *dev, spi_hwfeatures_t features)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t spi_send(struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
uint16_t ret;
|
||||
uint32_t ret;
|
||||
|
||||
spiinfo("wd=%04u\n", wd);
|
||||
spi_exchange(dev, &wd, &ret, 1);
|
||||
|
@ -1190,8 +1198,8 @@ static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer, void *rxbuffer,
|
||||
size_t nwords)
|
||||
static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
||||
void *rxbuffer, size_t nwords)
|
||||
{
|
||||
struct max326_spidev_s *priv = (struct max326_spidev_s *)dev;
|
||||
#ifndef CONFIG_MAX326_SPI_INTERRUPTS
|
||||
|
@ -1331,11 +1339,11 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer, void *rxbu
|
|||
* Input Parameters:
|
||||
* dev - Device-specific state data
|
||||
* txbuffer - 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
|
||||
|
@ -1343,7 +1351,8 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer, void *rxbu
|
|||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_sndblock(struct spi_dev_s *dev, const void *txbuffer, size_t nwords)
|
||||
static void spi_sndblock(struct spi_dev_s *dev, const void *txbuffer,
|
||||
size_t nwords)
|
||||
{
|
||||
spiinfo("txbuffer=%p nwords=%d\n", txbuffer, nwords);
|
||||
spi_exchange(dev, txbuffer, NULL, nwords);
|
||||
|
@ -1359,11 +1368,11 @@ static void spi_sndblock(struct spi_dev_s *dev, const void *txbuffer, size_t nwo
|
|||
* 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
|
||||
|
@ -1371,7 +1380,8 @@ static void spi_sndblock(struct spi_dev_s *dev, const void *txbuffer, size_t nwo
|
|||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_recvblock(struct spi_dev_s *dev, void *rxbuffer, size_t nwords)
|
||||
static void spi_recvblock(struct spi_dev_s *dev, void *rxbuffer,
|
||||
size_t nwords)
|
||||
{
|
||||
spiinfo("rxbuffer=%p nwords=%d\n", rxbuffer, nwords);
|
||||
spi_exchange(dev, NULL, rxbuffer, nwords);
|
||||
|
@ -1382,8 +1392,8 @@ static void spi_recvblock(struct spi_dev_s *dev, void *rxbuffer, size_t nwords)
|
|||
* Name: spi_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
|
||||
|
@ -1405,7 +1415,8 @@ static void spi_bus_initialize(struct max326_spidev_s *priv)
|
|||
|
||||
/* Setup slaved select timing (even in Master mode?) */
|
||||
|
||||
regval = (SPI_SSTIME_SSACT1(1) | SPI_SSTIME_SSACT2(1) | SPI_SSTIME_SSINACT(1));
|
||||
regval = (SPI_SSTIME_SSACT1(1) | SPI_SSTIME_SSACT2(1) |
|
||||
SPI_SSTIME_SSINACT(1));
|
||||
spi_putreg(priv, MAX326_SPI_SSTIME_OFFSET, regval);
|
||||
|
||||
/* Configure CTRL0. Default configuration:
|
||||
|
|
|
@ -112,7 +112,7 @@ static void nrf52_spi_setbits(FAR struct spi_dev_s *priv, int nbits);
|
|||
static int nrf52_spi_hwfeatures(FAR struct spi_dev_s *dev,
|
||||
spi_hwfeatures_t features);
|
||||
#endif
|
||||
static uint16_t nrf52_spi_send(FAR struct spi_dev_s *dev, uint16_t wd);
|
||||
static uint32_t nrf52_spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
static void nrf52_spi_exchange(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
|
@ -600,7 +600,8 @@ errout:
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void nrf52_spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
||||
static void nrf52_spi_setmode(FAR struct spi_dev_s *dev,
|
||||
enum spi_mode_e mode)
|
||||
{
|
||||
FAR struct nrf52_spidev_s *priv = (FAR struct nrf52_spidev_s *)dev;
|
||||
uint32_t regval = 0;
|
||||
|
@ -757,9 +758,9 @@ static int nrf52_spi_hwfeatures(FAR struct spi_dev_s *dev,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t nrf52_spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t nrf52_spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
uint32_t ret = 0;
|
||||
|
||||
/* Exchange one word on SPI */
|
||||
|
||||
|
@ -869,9 +870,9 @@ static void nrf52_spi_exchange(FAR struct spi_dev_s *dev,
|
|||
* Input Parameters:
|
||||
* dev - Device-specific state data
|
||||
* txbuffer - 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.
|
||||
* 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.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/************************************************************************************
|
||||
* arm/arm/src/s32k1xx/s32k1xx_lpspi.c
|
||||
* arch/arm/src/s32k1xx/s32k1xx_lpspi.c
|
||||
*
|
||||
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
|
||||
* Authors: Teodora Kireva
|
||||
|
@ -149,14 +149,14 @@ static inline uint32_t s32k1xx_lpspi_getreg32(FAR struct s32k1xx_lpspidev_s *pri
|
|||
uint8_t offset);
|
||||
static inline void s32k1xx_lpspi_putreg32(FAR struct s32k1xx_lpspidev_s *priv,
|
||||
uint8_t offset, uint32_t value);
|
||||
static inline uint16_t s32k1xx_lpspi_readword(FAR struct s32k1xx_lpspidev_s *priv);
|
||||
static inline uint32_t s32k1xx_lpspi_readword(FAR struct s32k1xx_lpspidev_s *priv);
|
||||
static inline void s32k1xx_lpspi_writeword(FAR struct s32k1xx_lpspidev_s *priv,
|
||||
uint16_t byte);
|
||||
static inline bool s32k1xx_lpspi_9to16bitmode(FAR struct s32k1xx_lpspidev_s *priv);
|
||||
static uint32_t s32k1xx_lpspi_pckfreq(uintptr_t base);
|
||||
static inline void s32k1xx_lpspi_master_set_delays(FAR struct s32k1xx_lpspidev_s
|
||||
static inline void s32k1xx_lpspi_set_delays(FAR struct s32k1xx_lpspidev_s
|
||||
*priv, uint32_t delay_ns, enum s32k1xx_delay_e type);
|
||||
static inline void s32k1xx_lpspi_master_set_delay_scaler(FAR struct
|
||||
static inline void s32k1xx_lpspi_set_delay_scaler(FAR struct
|
||||
s32k1xx_lpspidev_s *priv, uint32_t scaler, enum s32k1xx_delay_e type);
|
||||
|
||||
/* SPI methods */
|
||||
|
@ -171,7 +171,7 @@ static void s32k1xx_lpspi_setbits(FAR struct spi_dev_s *dev, int nbits);
|
|||
static int s32k1xx_lpspi_hwfeatures(FAR struct spi_dev_s *dev,
|
||||
s32k1xx_lpspi_hwfeatures_t features);
|
||||
#endif
|
||||
static uint16_t s32k1xx_lpspi_send(FAR struct spi_dev_s *dev, uint16_t wd);
|
||||
static uint32_t s32k1xx_lpspi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
static void s32k1xx_lpspi_exchange(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer, size_t nwords);
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
|
@ -428,7 +428,7 @@ static inline void s32k1xx_lpspi_putreg32(FAR struct s32k1xx_lpspidev_s *priv,
|
|||
*
|
||||
************************************************************************************/
|
||||
|
||||
static inline uint16_t s32k1xx_lpspi_readword(FAR struct s32k1xx_lpspidev_s *priv)
|
||||
static inline uint32_t s32k1xx_lpspi_readword(FAR struct s32k1xx_lpspidev_s *priv)
|
||||
{
|
||||
/* Wait until the receive buffer is not empty */
|
||||
|
||||
|
@ -438,7 +438,7 @@ static inline uint16_t s32k1xx_lpspi_readword(FAR struct s32k1xx_lpspidev_s *pri
|
|||
|
||||
/* Then return the received byte */
|
||||
|
||||
return (uint16_t) s32k1xx_lpspi_getreg32(priv, S32K1XX_LPSPI_RDR_OFFSET);
|
||||
return (uint32_t) s32k1xx_lpspi_getreg32(priv, S32K1XX_LPSPI_RDR_OFFSET);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
|
@ -640,7 +640,7 @@ static uint32_t s32k1xx_lpspi_pckfreq(uintptr_t base)
|
|||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: s32k1xx_lpspi_master_set_delays
|
||||
* Name: s32k1xx_lpspi_set_delays
|
||||
*
|
||||
* Description:
|
||||
* SET LPSPI Delay times
|
||||
|
@ -655,9 +655,10 @@ static uint32_t s32k1xx_lpspi_pckfreq(uintptr_t base)
|
|||
*
|
||||
************************************************************************************/
|
||||
|
||||
static inline void s32k1xx_lpspi_master_set_delay_scaler(FAR struct s32k1xx_lpspidev_s *priv,
|
||||
uint32_t scaler,
|
||||
enum s32k1xx_delay_e type)
|
||||
static inline void s32k1xx_lpspi_set_delay_scaler(FAR struct
|
||||
s32k1xx_lpspidev_s *priv,
|
||||
uint32_t scaler,
|
||||
enum s32k1xx_delay_e type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
@ -685,7 +686,7 @@ static inline void s32k1xx_lpspi_master_set_delay_scaler(FAR struct s32k1xx_lpsp
|
|||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: s32k1xx_lpspi_master_set_delays
|
||||
* Name: s32k1xx_lpspi_set_delays
|
||||
*
|
||||
* Description:
|
||||
* SET LPSPI Delay times
|
||||
|
@ -700,7 +701,7 @@ static inline void s32k1xx_lpspi_master_set_delay_scaler(FAR struct s32k1xx_lpsp
|
|||
*
|
||||
************************************************************************************/
|
||||
|
||||
static inline void s32k1xx_lpspi_master_set_delays(FAR struct s32k1xx_lpspidev_s *priv,
|
||||
static inline void s32k1xx_lpspi_set_delays(FAR struct s32k1xx_lpspidev_s *priv,
|
||||
uint32_t delay_ns,
|
||||
enum s32k1xx_delay_e type)
|
||||
{
|
||||
|
@ -785,7 +786,7 @@ static inline void s32k1xx_lpspi_master_set_delays(FAR struct s32k1xx_lpspidev_s
|
|||
|
||||
if (initial_delay_ns >= delay_ns)
|
||||
{
|
||||
s32k1xx_lpspi_master_set_delay_scaler(priv, 0, type);
|
||||
s32k1xx_lpspi_set_delay_scaler(priv, 0, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -822,7 +823,7 @@ static inline void s32k1xx_lpspi_master_set_delays(FAR struct s32k1xx_lpspidev_s
|
|||
}
|
||||
}
|
||||
|
||||
s32k1xx_lpspi_master_set_delay_scaler(priv, best_scaler, type);
|
||||
s32k1xx_lpspi_set_delay_scaler(priv, best_scaler, type);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -959,11 +960,11 @@ static uint32_t s32k1xx_lpspi_setfrequency(FAR struct spi_dev_s *dev,
|
|||
priv->frequency = frequency;
|
||||
priv->actual = best_frequency;
|
||||
|
||||
s32k1xx_lpspi_master_set_delays(priv, 1000000000 / best_frequency,
|
||||
s32k1xx_lpspi_set_delays(priv, 1000000000 / best_frequency,
|
||||
LPSPI_PCS_TO_SCK);
|
||||
s32k1xx_lpspi_master_set_delays(priv, 1000000000 / best_frequency,
|
||||
s32k1xx_lpspi_set_delays(priv, 1000000000 / best_frequency,
|
||||
LPSPI_LAST_SCK_TO_PCS);
|
||||
s32k1xx_lpspi_master_set_delays(priv, 1000000000 / best_frequency,
|
||||
s32k1xx_lpspi_set_delays(priv, 1000000000 / best_frequency,
|
||||
LPSPI_BETWEEN_TRANSFER);
|
||||
|
||||
/* Re-enable LPSPI if it was enabled previously */
|
||||
|
@ -1192,15 +1193,15 @@ static int s32k1xx_lpspi_hwfeatures(FAR struct spi_dev_s *dev,
|
|||
*
|
||||
************************************************************************************/
|
||||
|
||||
static uint16_t s32k1xx_lpspi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t s32k1xx_lpspi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
FAR struct s32k1xx_lpspidev_s *priv = (FAR struct s32k1xx_lpspidev_s *)dev;
|
||||
uint32_t regval;
|
||||
uint16_t ret;
|
||||
uint32_t ret;
|
||||
|
||||
DEBUGASSERT(priv && priv->spibase);
|
||||
|
||||
s32k1xx_lpspi_writeword(priv, (uint32_t) wd);
|
||||
s32k1xx_lpspi_writeword(priv, wd);
|
||||
|
||||
while ((s32k1xx_lpspi_getreg32(priv, S32K1XX_LPSPI_SR_OFFSET) & LPSPI_SR_RDF) !=
|
||||
LPSPI_SR_RDF);
|
||||
|
@ -1281,7 +1282,7 @@ static void s32k1xx_lpspi_exchange_nodma(FAR struct spi_dev_s *dev,
|
|||
|
||||
/* Exchange one word */
|
||||
|
||||
word = s32k1xx_lpspi_send(dev, word);
|
||||
word = (uint16_t) s32k1xx_lpspi_send(dev, (uint32_t) word);
|
||||
|
||||
/* Is there a buffer to receive the return value? */
|
||||
|
||||
|
@ -1314,7 +1315,7 @@ static void s32k1xx_lpspi_exchange_nodma(FAR struct spi_dev_s *dev,
|
|||
|
||||
/* Exchange one word */
|
||||
|
||||
word = (uint8_t) s32k1xx_lpspi_send(dev, (uint16_t) word);
|
||||
word = (uint8_t) s32k1xx_lpspi_send(dev, (uint32_t) word);
|
||||
|
||||
/* Is there a buffer to receive the return value? */
|
||||
|
||||
|
@ -1488,7 +1489,8 @@ FAR struct spi_dev_s *s32k1xx_lpspibus_initialize(int bus)
|
|||
|
||||
/* Only configure if the bus is not already configured */
|
||||
|
||||
if ((s32k1xx_lpspi_getreg32(priv, S32K1XX_LPSPI_CR_OFFSET) & LPSPI_CR_MEN) == 0)
|
||||
if ((s32k1xx_lpspi_getreg32(priv, S32K1XX_LPSPI_CR_OFFSET) &
|
||||
LPSPI_CR_MEN) == 0)
|
||||
{
|
||||
/* Configure SPI0 pins: SCK, MISO, and MOSI */
|
||||
|
||||
|
@ -1512,7 +1514,8 @@ FAR struct spi_dev_s *s32k1xx_lpspibus_initialize(int bus)
|
|||
|
||||
/* Only configure if the bus is not already configured */
|
||||
|
||||
if ((s32k1xx_lpspi_getreg32(priv, S32K1XX_LPSPI_CR_OFFSET) & LPSPI_CR_MEN) == 0)
|
||||
if ((s32k1xx_lpspi_getreg32(priv, S32K1XX_LPSPI_CR_OFFSET) &
|
||||
LPSPI_CR_MEN) == 0)
|
||||
{
|
||||
/* Configure SPI1 pins: SCK, MISO, and MOSI */
|
||||
|
||||
|
@ -1536,7 +1539,8 @@ FAR struct spi_dev_s *s32k1xx_lpspibus_initialize(int bus)
|
|||
|
||||
/* Only configure if the bus is not already configured */
|
||||
|
||||
if ((s32k1xx_lpspi_getreg32(priv, S32K1XX_LPSPI_CR_OFFSET) & LPSPI_CR_MEN) == 0)
|
||||
if ((s32k1xx_lpspi_getreg32(priv, S32K1XX_LPSPI_CR_OFFSET) &
|
||||
LPSPI_CR_MEN) == 0)
|
||||
{
|
||||
/* Configure SPI2 pins: SCK, MISO, and MOSI */
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* When SPI DMA is enabled, small DMA transfers will still be performed by
|
||||
* polling logic. But we need a threshold value to determine what is small.
|
||||
* That value is provided by CONFIG_SAM34_SPI_DMATHRESHOLD.
|
||||
|
@ -113,6 +114,7 @@
|
|||
#endif
|
||||
|
||||
/* Clocking *****************************************************************/
|
||||
|
||||
/* Select MCU-specific settings
|
||||
*
|
||||
* For the SAM3U, SAM3A, SAM3X, SAM4E and SAM4S SPI is driven by the main
|
||||
|
@ -137,7 +139,8 @@
|
|||
#define DMA_TIMEOUT_MS (800)
|
||||
#define DMA_TIMEOUT_TICKS MSEC2TICK(DMA_TIMEOUT_MS)
|
||||
|
||||
/* Debug *******************************************************************/
|
||||
/* Debug ********************************************************************/
|
||||
|
||||
/* Check if SPI debut is enabled */
|
||||
|
||||
#ifndef CONFIG_DEBUG_DMA_INFO
|
||||
|
@ -211,10 +214,10 @@ struct sam_spidev_s
|
|||
/* Debug stuff */
|
||||
|
||||
#ifdef CONFIG_SAM34_SPI_REGDEBUG
|
||||
bool wrlast; /* Last was a write */
|
||||
uint32_t addresslast; /* Last address */
|
||||
uint32_t valuelast; /* Last value */
|
||||
int ntimes; /* Number of times */
|
||||
bool wrlast; /* Last was a write */
|
||||
uint32_t addresslast; /* Last address */
|
||||
uint32_t valuelast; /* Last value */
|
||||
int ntimes; /* Number of times */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -278,7 +281,7 @@ static void spi_select(struct spi_dev_s *dev, uint32_t devid,
|
|||
static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency);
|
||||
static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode);
|
||||
static void spi_setbits(struct spi_dev_s *dev, int nbits);
|
||||
static uint16_t spi_send(struct spi_dev_s *dev, uint16_t ch);
|
||||
static uint32_t spi_send(struct spi_dev_s *dev, uint32_t wd);
|
||||
#ifdef CONFIG_SAM34_SPI_DMA
|
||||
static void spi_exchange_nodma(struct spi_dev_s *dev,
|
||||
const void *txbuffer, void *rxbuffer, size_t nwords);
|
||||
|
@ -624,8 +627,10 @@ static void spi_dma_sampleinit(struct sam_spics_s *spics)
|
|||
{
|
||||
/* Put contents of register samples into a known state */
|
||||
|
||||
memset(spics->rxdmaregs, 0xff, DMA_NSAMPLES * sizeof(struct sam_dmaregs_s));
|
||||
memset(spics->txdmaregs, 0xff, DMA_NSAMPLES * sizeof(struct sam_dmaregs_s));
|
||||
memset(spics->rxdmaregs, 0xff,
|
||||
DMA_NSAMPLES * sizeof(struct sam_dmaregs_s));
|
||||
memset(spics->txdmaregs, 0xff,
|
||||
DMA_NSAMPLES * sizeof(struct sam_dmaregs_s));
|
||||
|
||||
/* Then get the initial samples */
|
||||
|
||||
|
@ -657,6 +662,7 @@ static void spi_dma_sampledone(struct sam_spics_s *spics)
|
|||
sam_dmasample(spics->txdma, &spics->txdmaregs[DMA_END_TRANSFER]);
|
||||
|
||||
/* Then dump the sampled DMA registers */
|
||||
|
||||
/* Initial register values */
|
||||
|
||||
sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_INITIAL],
|
||||
|
@ -780,8 +786,8 @@ static void spi_rxcallback(DMA_HANDLE handle, void *arg, int result)
|
|||
|
||||
spi_rxdma_sample(spics, DMA_CALLBACK);
|
||||
|
||||
/* Report the result of the transfer only if the TX callback has not already
|
||||
* reported an error.
|
||||
/* Report the result of the transfer only if the TX callback has not
|
||||
* already reported an error.
|
||||
*/
|
||||
|
||||
if (spics->result == -EBUSY)
|
||||
|
@ -923,8 +929,8 @@ static void spi_select(struct spi_dev_s *dev, uint32_t devid,
|
|||
{
|
||||
spiinfo("cs=%d\n", spics->cs);
|
||||
|
||||
/* Before writing the TDR, the PCS field in the SPI_MR register must be set
|
||||
* in order to select a slave.
|
||||
/* Before writing the TDR, the PCS field in the SPI_MR register must
|
||||
* be set in order to select a slave.
|
||||
*/
|
||||
|
||||
regval = spi_getreg(spi, SAM_SPI_MR_OFFSET);
|
||||
|
@ -1013,10 +1019,10 @@ static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency)
|
|||
regval &= ~(SPI_CSR_SCBR_MASK | SPI_CSR_DLYBS_MASK | SPI_CSR_DLYBCT_MASK);
|
||||
regval |= scbr << SPI_CSR_SCBR_SHIFT;
|
||||
|
||||
/* DLYBS: Delay Before SPCK. This field defines the delay from NPCS valid to the
|
||||
* first valid SPCK transition. When DLYBS equals zero, the NPCS valid to SPCK
|
||||
* transition is 1/2 the SPCK clock period. Otherwise, the following equations
|
||||
* determine the delay:
|
||||
/* DLYBS: Delay Before SPCK. This field defines the delay from NPCS valid
|
||||
* to the first valid SPCK transition. When DLYBS equals zero, the NPCS
|
||||
* valid to SPCK transition is 1/2 the SPCK clock period. Otherwise, the
|
||||
* following equations determine the delay:
|
||||
*
|
||||
* Delay Before SPCK = DLYBS / SPI_CLK
|
||||
*
|
||||
|
@ -1028,10 +1034,10 @@ static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency)
|
|||
dlybs = SAM_SPI_CLOCK / 500000;
|
||||
regval |= dlybs << SPI_CSR_DLYBS_SHIFT;
|
||||
|
||||
/* DLYBCT: Delay Between Consecutive Transfers. This field defines the delay
|
||||
* between two consecutive transfers with the same peripheral without removing
|
||||
* the chip select. The delay is always inserted after each transfer and
|
||||
* before removing the chip select if needed.
|
||||
/* DLYBCT: Delay Between Consecutive Transfers. This field defines the
|
||||
* delay between two consecutive transfers with the same peripheral without
|
||||
* removing the chip select. The delay is always inserted after each
|
||||
* transfer and before removing the chip select if needed.
|
||||
*
|
||||
* Delay Between Consecutive Transfers = (32 x DLYBCT) / SPI_CLK
|
||||
*
|
||||
|
@ -1194,7 +1200,7 @@ static void spi_setbits(struct spi_dev_s *dev, int nbits)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t spi_send(struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
uint8_t txbyte;
|
||||
uint8_t rxbyte;
|
||||
|
@ -1209,7 +1215,7 @@ static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd)
|
|||
spi_exchange(dev, &txbyte, &rxbyte, 1);
|
||||
|
||||
spiinfo("Sent %02x received %02x\n", txbyte, rxbyte);
|
||||
return (uint16_t)rxbyte;
|
||||
return (uint32_t)rxbyte;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1670,10 +1676,10 @@ static void spi_sndblock(struct spi_dev_s *dev, const void *buffer,
|
|||
* dev - Device-specific state data
|
||||
* buffer - 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
|
||||
* 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
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/sama5/sam_spi.c
|
||||
*
|
||||
* Copyright (C) 2013-2014, 2016-2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2013-2017 Gregory Nutt. All rights reserved.
|
||||
* Authors: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* This derives from SAM3/4 SPI driver:
|
||||
|
@ -80,7 +80,9 @@
|
|||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* When SPI DMA is enabled, small DMA transfers will still be performed by
|
||||
* polling logic. But we need a threshold value to determine what is small.
|
||||
* That value is provided by CONFIG_SAMA5_SPI_DMATHRESHOLD.
|
||||
|
@ -114,6 +116,7 @@
|
|||
#endif
|
||||
|
||||
/* Clocking *****************************************************************/
|
||||
|
||||
/* Select MCU-specific settings
|
||||
*
|
||||
* SPI is driven by the main clock.
|
||||
|
@ -128,7 +131,8 @@
|
|||
#define DMA_TIMEOUT_MS (800)
|
||||
#define DMA_TIMEOUT_TICKS MSEC2TICK(DMA_TIMEOUT_MS)
|
||||
|
||||
/* Debug *******************************************************************/
|
||||
/* Debug ********************************************************************/
|
||||
|
||||
/* Check if SPI debug is enabled */
|
||||
|
||||
#ifndef CONFIG_DEBUG_DMA
|
||||
|
@ -200,10 +204,10 @@ struct sam_spidev_s
|
|||
/* Debug stuff */
|
||||
|
||||
#ifdef CONFIG_SAMA5_SPI_REGDEBUG
|
||||
bool wrlast; /* Last was a write */
|
||||
uint32_t addresslast; /* Last address */
|
||||
uint32_t valuelast; /* Last value */
|
||||
int ntimes; /* Number of times */
|
||||
bool wrlast; /* Last was a write */
|
||||
uint32_t addresslast; /* Last address */
|
||||
uint32_t valuelast; /* Last value */
|
||||
int ntimes; /* Number of times */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -267,7 +271,7 @@ static void spi_select(struct spi_dev_s *dev, uint32_t devid,
|
|||
static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency);
|
||||
static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode);
|
||||
static void spi_setbits(struct spi_dev_s *dev, int nbits);
|
||||
static uint16_t spi_send(struct spi_dev_s *dev, uint16_t ch);
|
||||
static uint32_t spi_send(struct spi_dev_s *dev, uint32_t wd);
|
||||
#ifdef CONFIG_SAMA5_SPI_DMA
|
||||
static void spi_exchange_nodma(struct spi_dev_s *dev,
|
||||
const void *txbuffer, void *rxbuffer, size_t nwords);
|
||||
|
@ -611,8 +615,10 @@ static void spi_dma_sampleinit(struct sam_spics_s *spics)
|
|||
{
|
||||
/* Put contents of register samples into a known state */
|
||||
|
||||
memset(spics->rxdmaregs, 0xff, DMA_NSAMPLES * sizeof(struct sam_dmaregs_s));
|
||||
memset(spics->txdmaregs, 0xff, DMA_NSAMPLES * sizeof(struct sam_dmaregs_s));
|
||||
memset(spics->rxdmaregs, 0xff,
|
||||
DMA_NSAMPLES * sizeof(struct sam_dmaregs_s));
|
||||
memset(spics->txdmaregs, 0xff,
|
||||
DMA_NSAMPLES * sizeof(struct sam_dmaregs_s));
|
||||
|
||||
/* Then get the initial samples */
|
||||
|
||||
|
@ -644,6 +650,7 @@ static void spi_dma_sampledone(struct sam_spics_s *spics)
|
|||
sam_dmasample(spics->txdma, &spics->txdmaregs[DMA_END_TRANSFER]);
|
||||
|
||||
/* Then dump the sampled DMA registers */
|
||||
|
||||
/* Initial register values */
|
||||
|
||||
sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_INITIAL],
|
||||
|
@ -767,13 +774,13 @@ static void spi_rxcallback(DMA_HANDLE handle, void *arg, int result)
|
|||
|
||||
spi_rxdma_sample(spics, DMA_CALLBACK);
|
||||
|
||||
/* Report the result of the transfer only if the TX callback has not already
|
||||
* reported an error.
|
||||
/* Report the result of the transfer only if the TX callback has not
|
||||
* already reported an error.
|
||||
*/
|
||||
|
||||
if (spics->result == -EBUSY)
|
||||
{
|
||||
/* Save the result of the transfer if no error was previuosly reported */
|
||||
/* Save the result of the transfer if no error was previously reported */
|
||||
|
||||
spics->result = result;
|
||||
}
|
||||
|
@ -910,8 +917,8 @@ static void spi_select(struct spi_dev_s *dev, uint32_t devid,
|
|||
{
|
||||
spiinfo("cs=%d\n", spics->cs);
|
||||
|
||||
/* Before writing the TDR, the PCS field in the SPI_MR register must be set
|
||||
* in order to select a slave.
|
||||
/* Before writing the TDR, the PCS field in the SPI_MR register must be
|
||||
* set in order to select a slave.
|
||||
*/
|
||||
|
||||
regval = spi_getreg(spi, SAM_SPI_MR_OFFSET);
|
||||
|
@ -974,7 +981,8 @@ static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency)
|
|||
return spics->actual;
|
||||
}
|
||||
|
||||
/* Configure SPI to a frequency as close as possible to the requested frequency.
|
||||
/* Configure SPI to a frequency as close as possible to the requested
|
||||
* frequency.
|
||||
*
|
||||
* SPCK frequency = SPI_CLK / SCBR, or SCBR = SPI_CLK / frequency
|
||||
*/
|
||||
|
@ -999,10 +1007,10 @@ static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency)
|
|||
regval &= ~(SPI_CSR_SCBR_MASK | SPI_CSR_DLYBS_MASK | SPI_CSR_DLYBCT_MASK);
|
||||
regval |= scbr << SPI_CSR_SCBR_SHIFT;
|
||||
|
||||
/* DLYBS: Delay Before SPCK. This field defines the delay from NPCS valid to the
|
||||
* first valid SPCK transition. When DLYBS equals zero, the NPCS valid to SPCK
|
||||
* transition is 1/2 the SPCK clock period. Otherwise, the following equations
|
||||
* determine the delay:
|
||||
/* DLYBS: Delay Before SPCK. This field defines the delay from NPCS valid
|
||||
* to the first valid SPCK transition. When DLYBS equals zero, the NPCS
|
||||
* valid to SPCK transition is 1/2 the SPCK clock period. Otherwise, the
|
||||
* following equations determine the delay:
|
||||
*
|
||||
* Delay Before SPCK = DLYBS / SPI_CLK
|
||||
*
|
||||
|
@ -1014,10 +1022,10 @@ static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency)
|
|||
dlybs = SAM_SPI_CLOCK / 500000;
|
||||
regval |= dlybs << SPI_CSR_DLYBS_SHIFT;
|
||||
|
||||
/* DLYBCT: Delay Between Consecutive Transfers. This field defines the delay
|
||||
* between two consecutive transfers with the same peripheral without removing
|
||||
* the chip select. The delay is always inserted after each transfer and
|
||||
* before removing the chip select if needed.
|
||||
/* DLYBCT: Delay Between Consecutive Transfers. This field defines the
|
||||
* delay between two consecutive transfers with the same peripheral without
|
||||
* removing the chip select. The delay is always inserted after each
|
||||
* transfer and before removing the chip select if needed.
|
||||
*
|
||||
* Delay Between Consecutive Transfers = (32 x DLYBCT) / SPI_CLK
|
||||
*
|
||||
|
@ -1185,7 +1193,7 @@ static void spi_setbits(struct spi_dev_s *dev, int nbits)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t spi_send(struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
uint8_t txbyte;
|
||||
uint8_t rxbyte;
|
||||
|
@ -1200,7 +1208,7 @@ static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd)
|
|||
spi_exchange(dev, &txbyte, &rxbyte, 1);
|
||||
|
||||
spiinfo("Sent %02x received %02x\n", txbyte, rxbyte);
|
||||
return (uint16_t)rxbyte;
|
||||
return (uint32_t)rxbyte;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1566,7 +1574,8 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
|||
* 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
|
||||
|
@ -1574,7 +1583,8 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
|||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_sndblock(struct spi_dev_s *dev, const void *buffer, size_t nwords)
|
||||
static void spi_sndblock(struct spi_dev_s *dev, const void *buffer,
|
||||
size_t nwords)
|
||||
{
|
||||
/* spi_exchange can do this. */
|
||||
|
||||
|
@ -1592,9 +1602,10 @@ static void spi_sndblock(struct spi_dev_s *dev, const void *buffer, size_t nword
|
|||
* dev - Device-specific state data
|
||||
* buffer - 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
|
||||
* 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
|
||||
|
@ -1602,7 +1613,8 @@ static void spi_sndblock(struct spi_dev_s *dev, const void *buffer, size_t nword
|
|||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_recvblock(struct spi_dev_s *dev, void *buffer, size_t nwords)
|
||||
static void spi_recvblock(struct spi_dev_s *dev, void *buffer,
|
||||
size_t nwords)
|
||||
{
|
||||
/* spi_exchange can do this. */
|
||||
|
||||
|
|
|
@ -135,10 +135,10 @@ struct sam_spidev_s
|
|||
/* Debug stuff */
|
||||
|
||||
#ifdef CONFIG_SAMD2L2_SPI_REGDEBUG
|
||||
bool wr; /* Last was a write */
|
||||
uint32_t regaddr; /* Last address */
|
||||
uint32_t regval; /* Last value */
|
||||
int ntimes; /* Number of times */
|
||||
bool wr; /* Last was a write */
|
||||
uint32_t regaddr; /* Last address */
|
||||
uint32_t regval; /* Last value */
|
||||
int ntimes; /* Number of times */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -190,7 +190,7 @@ static int spi_lock(struct spi_dev_s *dev, bool lock);
|
|||
static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency);
|
||||
static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode);
|
||||
static void spi_setbits(struct spi_dev_s *dev, int nbits);
|
||||
static uint16_t spi_send(struct spi_dev_s *dev, uint16_t ch);
|
||||
static uint32_t spi_send(struct spi_dev_s *dev, uint32_t wd);
|
||||
static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
||||
void *rxbuffer, size_t nwords);
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
|
@ -1072,7 +1072,7 @@ static void spi_setbits(struct spi_dev_s *dev, int nbits)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t spi_send(struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
uint8_t txbyte;
|
||||
uint8_t rxbyte;
|
||||
|
@ -1087,7 +1087,7 @@ static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd)
|
|||
spi_exchange(dev, &txbyte, &rxbyte, 1);
|
||||
|
||||
spiinfo("Sent %02x received %02x\n", txbyte, rxbyte);
|
||||
return (uint16_t)rxbyte;
|
||||
return (uint32_t)rxbyte;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1322,7 +1322,8 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
|||
* 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
|
||||
|
@ -1330,7 +1331,8 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
|||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_sndblock(struct spi_dev_s *dev, const void *buffer, size_t nwords)
|
||||
static void spi_sndblock(struct spi_dev_s *dev, const void *buffer,
|
||||
size_t nwords)
|
||||
{
|
||||
/* spi_exchange can do this. */
|
||||
|
||||
|
@ -1348,9 +1350,10 @@ static void spi_sndblock(struct spi_dev_s *dev, const void *buffer, size_t nword
|
|||
* dev - Device-specific state data
|
||||
* buffer - 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
|
||||
* 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
|
||||
|
@ -1376,11 +1379,12 @@ static void spi_recvblock(struct spi_dev_s *dev, void *buffer, size_t nwords)
|
|||
|
||||
static void spi_wait_synchronization(struct sam_spidev_s *priv)
|
||||
{
|
||||
|
||||
#if defined(CONFIG_ARCH_FAMILY_SAMD20)
|
||||
while ((spi_getreg16(priv, SAM_SPI_STATUS_OFFSET) & SPI_STATUS_SYNCBUSY) != 0);
|
||||
while ((spi_getreg16(priv, SAM_SPI_STATUS_OFFSET) &
|
||||
SPI_STATUS_SYNCBUSY) != 0);
|
||||
#elif defined(CONFIG_ARCH_FAMILY_SAMD21) || defined(CONFIG_ARCH_FAMILY_SAML21)
|
||||
while ((spi_getreg16(priv, SAM_SPI_SYNCBUSY_OFFSET) & SPI_SYNCBUSY_ALL) != 0);
|
||||
while ((spi_getreg16(priv, SAM_SPI_SYNCBUSY_OFFSET) &
|
||||
SPI_SYNCBUSY_ALL) != 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -130,10 +130,10 @@ struct sam_spidev_s
|
|||
/* Debug stuff */
|
||||
|
||||
#ifdef CONFIG_SAMD5E5SPI_REGDEBUG
|
||||
bool wr; /* Last was a write */
|
||||
uint32_t regaddr; /* Last address */
|
||||
uint32_t regval; /* Last value */
|
||||
int ntimes; /* Number of times */
|
||||
bool wr; /* Last was a write */
|
||||
uint32_t regaddr; /* Last address */
|
||||
uint32_t regval; /* Last value */
|
||||
int ntimes; /* Number of times */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -185,7 +185,7 @@ static int spi_lock(struct spi_dev_s *dev, bool lock);
|
|||
static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency);
|
||||
static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode);
|
||||
static void spi_setbits(struct spi_dev_s *dev, int nbits);
|
||||
static uint16_t spi_send(struct spi_dev_s *dev, uint16_t ch);
|
||||
static uint32_t spi_send(struct spi_dev_s *dev, uint32_t ch);
|
||||
static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
||||
void *rxbuffer, size_t nwords);
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
|
@ -1167,7 +1167,7 @@ static void spi_setbits(struct spi_dev_s *dev, int nbits)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t spi_send(struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
uint8_t txbyte;
|
||||
uint8_t rxbyte;
|
||||
|
@ -1182,7 +1182,7 @@ static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd)
|
|||
spi_exchange(dev, &txbyte, &rxbyte, 1);
|
||||
|
||||
spiinfo("Sent %02x received %02x\n", txbyte, rxbyte);
|
||||
return (uint16_t)rxbyte;
|
||||
return (uint32_t)rxbyte;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1417,7 +1417,8 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
|||
* 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
|
||||
|
@ -1425,7 +1426,8 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
|||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_sndblock(struct spi_dev_s *dev, const void *buffer, size_t nwords)
|
||||
static void spi_sndblock(struct spi_dev_s *dev, const void *buffer,
|
||||
size_t nwords)
|
||||
{
|
||||
/* spi_exchange can do this. */
|
||||
|
||||
|
@ -1443,9 +1445,10 @@ static void spi_sndblock(struct spi_dev_s *dev, const void *buffer, size_t nword
|
|||
* dev - Device-specific state data
|
||||
* buffer - 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
|
||||
* 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
|
||||
|
@ -1471,7 +1474,8 @@ static void spi_recvblock(struct spi_dev_s *dev, void *buffer, size_t nwords)
|
|||
|
||||
static void spi_wait_synchronization(struct sam_spidev_s *priv)
|
||||
{
|
||||
while ((spi_getreg16(priv, SAM_SPI_SYNCBUSY_OFFSET) & SPI_SYNCBUSY_ALL) != 0);
|
||||
while ((spi_getreg16(priv, SAM_SPI_SYNCBUSY_OFFSET) &
|
||||
SPI_SYNCBUSY_ALL) != 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -75,7 +75,9 @@
|
|||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* When SPI DMA is enabled, small DMA transfers will still be performed by
|
||||
* polling logic. But we need a threshold value to determine what is small.
|
||||
* That value is provided by CONFIG_SAMV7_SPI_DMATHRESHOLD.
|
||||
|
@ -113,6 +115,7 @@
|
|||
#endif
|
||||
|
||||
/* Clocking *****************************************************************/
|
||||
|
||||
/* The SPI Baud rate clock is generated by dividing the peripheral clock by
|
||||
* a value between 1 and 255
|
||||
*/
|
||||
|
@ -126,7 +129,8 @@
|
|||
#define DMA_TIMEOUT_MS (800)
|
||||
#define DMA_TIMEOUT_TICKS MSEC2TICK(DMA_TIMEOUT_MS)
|
||||
|
||||
/* Debug *******************************************************************/
|
||||
/* Debug ********************************************************************/
|
||||
|
||||
/* Check if SPI debug is enabled */
|
||||
|
||||
#ifndef CONFIG_DEBUG_DMA
|
||||
|
@ -199,10 +203,10 @@ struct sam_spidev_s
|
|||
/* Debug stuff */
|
||||
|
||||
#ifdef CONFIG_SAMV7_SPI_REGDEBUG
|
||||
bool wrlast; /* Last was a write */
|
||||
uint32_t addresslast; /* Last address */
|
||||
uint32_t valuelast; /* Last value */
|
||||
int ntimes; /* Number of times */
|
||||
bool wrlast; /* Last was a write */
|
||||
uint32_t addresslast; /* Last address */
|
||||
uint32_t valuelast; /* Last value */
|
||||
int ntimes; /* Number of times */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -265,14 +269,15 @@ static void spi_select(struct spi_dev_s *dev, uint32_t devid,
|
|||
bool selected);
|
||||
static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency);
|
||||
#ifdef CONFIG_SPI_CS_DELAY_CONTROL
|
||||
static int spi_setdelay(struct spi_dev_s *dev, uint32_t a, uint32_t b, uint32_t c);
|
||||
static int spi_setdelay(struct spi_dev_s *dev, uint32_t a, uint32_t b,
|
||||
uint32_t c);
|
||||
#endif
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
static int spi_hwfeatures(struct spi_dev_s *dev, uint8_t features);
|
||||
#endif
|
||||
static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode);
|
||||
static void spi_setbits(struct spi_dev_s *dev, int nbits);
|
||||
static uint16_t spi_send(struct spi_dev_s *dev, uint16_t ch);
|
||||
static uint32_t spi_send(struct spi_dev_s *dev, uint32_t wd);
|
||||
#ifdef CONFIG_SAMV7_SPI_DMA
|
||||
static void spi_exchange_nodma(struct spi_dev_s *dev,
|
||||
const void *txbuffer, void *rxbuffer, size_t nwords);
|
||||
|
@ -296,9 +301,10 @@ static void spi_recvblock(struct spi_dev_s *dev, void *buffer,
|
|||
static const uint8_t g_csroffset[16] =
|
||||
{
|
||||
0, /* the CS counts from 1 to 15 */
|
||||
SAM_SPI_CSR0_OFFSET, SAM_SPI_CSR0_OFFSET, SAM_SPI_CSR0_OFFSET, SAM_SPI_CSR0_OFFSET,
|
||||
SAM_SPI_CSR1_OFFSET, SAM_SPI_CSR1_OFFSET, SAM_SPI_CSR1_OFFSET, SAM_SPI_CSR1_OFFSET,
|
||||
SAM_SPI_CSR2_OFFSET, SAM_SPI_CSR2_OFFSET, SAM_SPI_CSR2_OFFSET, SAM_SPI_CSR2_OFFSET,
|
||||
SAM_SPI_CSR0_OFFSET, SAM_SPI_CSR0_OFFSET, SAM_SPI_CSR0_OFFSET,
|
||||
SAM_SPI_CSR0_OFFSET, SAM_SPI_CSR1_OFFSET, SAM_SPI_CSR1_OFFSET,
|
||||
SAM_SPI_CSR1_OFFSET, SAM_SPI_CSR1_OFFSET, SAM_SPI_CSR2_OFFSET,
|
||||
SAM_SPI_CSR2_OFFSET, SAM_SPI_CSR2_OFFSET, SAM_SPI_CSR2_OFFSET,
|
||||
SAM_SPI_CSR3_OFFSET, SAM_SPI_CSR3_OFFSET, SAM_SPI_CSR3_OFFSET
|
||||
};
|
||||
#else
|
||||
|
@ -605,18 +611,18 @@ static inline void spi_flush(struct sam_spidev_s *spi)
|
|||
* 2 0011 x011 1011
|
||||
* 3 0111 0111 0111
|
||||
*
|
||||
* The second mode, activated via CONFIG_SAMV7_SPI_CS_DECODING uses the four
|
||||
* chip select pins in "encoded mode" which means, that up to 15 slaves can
|
||||
* be selected via an additional multiplex electronic to decode the values
|
||||
* represented by the four lines. In that mode this function returns the
|
||||
* Bitmask the chip select number represents itself.
|
||||
* The second mode, activated via CONFIG_SAMV7_SPI_CS_DECODING uses the
|
||||
* four chip select pins in "encoded mode" which means, that up to 15
|
||||
* slaves can be selected via an additional multiplex electronic to decode
|
||||
* the values represented by the four lines. In that mode this function
|
||||
* returns the Bitmask the chip select number represents itself.
|
||||
*
|
||||
* Input Parameters:
|
||||
* spics - Device-specific state data
|
||||
*
|
||||
* Returned Value:
|
||||
* Bitmask the pcs part of the SPI data transfer register should be switched
|
||||
* to for the chip select used.
|
||||
* Bitmask the pcs part of the SPI data transfer register should be
|
||||
* switched to for the chip select used.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
@ -648,8 +654,10 @@ static void spi_dma_sampleinit(struct sam_spics_s *spics)
|
|||
{
|
||||
/* Put contents of register samples into a known state */
|
||||
|
||||
memset(spics->rxdmaregs, 0xff, DMA_NSAMPLES * sizeof(struct sam_dmaregs_s));
|
||||
memset(spics->txdmaregs, 0xff, DMA_NSAMPLES * sizeof(struct sam_dmaregs_s));
|
||||
memset(spics->rxdmaregs, 0xff,
|
||||
DMA_NSAMPLES * sizeof(struct sam_dmaregs_s));
|
||||
memset(spics->txdmaregs, 0xff,
|
||||
DMA_NSAMPLES * sizeof(struct sam_dmaregs_s));
|
||||
|
||||
/* Then get the initial samples */
|
||||
|
||||
|
@ -681,6 +689,7 @@ static void spi_dma_sampledone(struct sam_spics_s *spics)
|
|||
sam_dmasample(spics->txdma, &spics->txdmaregs[DMA_END_TRANSFER]);
|
||||
|
||||
/* Then dump the sampled DMA registers */
|
||||
|
||||
/* Initial register values */
|
||||
|
||||
sam_dmadump(spics->txdma, &spics->txdmaregs[DMA_INITIAL],
|
||||
|
@ -804,8 +813,8 @@ static void spi_rxcallback(DMA_HANDLE handle, void *arg, int result)
|
|||
|
||||
spi_rxdma_sample(spics, DMA_CALLBACK);
|
||||
|
||||
/* Report the result of the transfer only if the TX callback has not already
|
||||
* reported an error.
|
||||
/* Report the result of the transfer only if the TX callback has not
|
||||
* already reported an error.
|
||||
*/
|
||||
|
||||
if (spics->result == -EBUSY)
|
||||
|
@ -947,18 +956,18 @@ static void spi_select(struct spi_dev_s *dev, uint32_t devid,
|
|||
{
|
||||
spiinfo("cs=%d\n", spics->cs);
|
||||
|
||||
/* Before writing the TDR, the PCS field in the SPI_MR register must be set
|
||||
* in order to select a slave.
|
||||
/* Before writing the TDR, the PCS field in the SPI_MR register must be
|
||||
* set in order to select a slave.
|
||||
*/
|
||||
|
||||
regval = spi_getreg(spi, SAM_SPI_MR_OFFSET);
|
||||
regval &= ~SPI_MR_PCS_MASK;
|
||||
|
||||
/* SPI_VARSELECT means, that the ChipSelect for each device is set within
|
||||
* the transferred data (SAM_SPI_TDR) instead inside the mode register
|
||||
* (SAM_SPI_MR).
|
||||
* In addition, the LASTXFER flag is also set within the transferred data
|
||||
* (SAM_SPI_TDR) instead inside the control register (SAM_SPI_CR).
|
||||
/* SPI_VARSELECT means, that the ChipSelect for each device is set
|
||||
* within the transferred data (SAM_SPI_TDR) instead inside the mode
|
||||
* register (SAM_SPI_MR).
|
||||
* In addition, the LASTXFER flag is also set within the transferred
|
||||
* data (SAM_SPI_TDR) instead inside the control register (SAM_SPI_CR).
|
||||
* (see spi_exchange)
|
||||
*/
|
||||
|
||||
|
@ -1022,7 +1031,8 @@ static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency)
|
|||
return spics->actual;
|
||||
}
|
||||
|
||||
/* Configure SPI to a frequency as close as possible to the requested frequency.
|
||||
/* Configure SPI to a frequency as close as possible to the requested
|
||||
* frequency.
|
||||
*
|
||||
* SPCK frequency = SPI_CLK / SCBR, or SCBR = SPI_CLK / frequency
|
||||
*/
|
||||
|
@ -1047,10 +1057,10 @@ static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency)
|
|||
regval &= ~(SPI_CSR_SCBR_MASK | SPI_CSR_DLYBS_MASK | SPI_CSR_DLYBCT_MASK);
|
||||
regval |= scbr << SPI_CSR_SCBR_SHIFT;
|
||||
|
||||
/* DLYBS: Delay Before SPCK. This field defines the delay from NPCS valid to the
|
||||
* first valid SPCK transition. When DLYBS equals zero, the NPCS valid to SPCK
|
||||
* transition is 1/2 the SPCK clock period. Otherwise, the following equations
|
||||
* determine the delay:
|
||||
/* DLYBS: Delay Before SPCK. This field defines the delay from NPCS valid
|
||||
* to the first valid SPCK transition. When DLYBS equals zero, the NPCS
|
||||
* valid to SPCK transition is 1/2 the SPCK clock period. Otherwise, the
|
||||
* following equations determine the delay:
|
||||
*
|
||||
* Delay Before SPCK = DLYBS / SPI_CLK
|
||||
*
|
||||
|
@ -1062,10 +1072,10 @@ static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency)
|
|||
dlybs = SAM_SPI_CLOCK / 500000;
|
||||
regval |= dlybs << SPI_CSR_DLYBS_SHIFT;
|
||||
|
||||
/* DLYBCT: Delay Between Consecutive Transfers. This field defines the delay
|
||||
* between two consecutive transfers with the same peripheral without removing
|
||||
* the chip select. The delay is always inserted after each transfer and
|
||||
* before removing the chip select if needed.
|
||||
/* DLYBCT: Delay Between Consecutive Transfers. This field defines the
|
||||
* delay between two consecutive transfers with the same peripheral without
|
||||
* removing the chip select. The delay is always inserted after each
|
||||
* transfer and before removing the chip select if needed.
|
||||
*
|
||||
* Delay Between Consecutive Transfers = (32 x DLYBCT) / SPI_CLK
|
||||
*
|
||||
|
@ -1183,6 +1193,7 @@ static int spi_setdelay(struct spi_dev_s *dev, uint32_t startdelay,
|
|||
*
|
||||
* DLYBCS = SPI_CLK * Delay
|
||||
*/
|
||||
|
||||
dlybcs = SAM_SPI_CLOCK;
|
||||
dlybcs *= csdelay;
|
||||
dlybcs /= 1000000000;
|
||||
|
@ -1239,8 +1250,8 @@ static int spi_hwfeatures(struct spi_dev_s *dev, uint8_t features)
|
|||
spi_putreg(spi, regval, offset);
|
||||
}
|
||||
|
||||
/* CS does not rise automatically after a transmission, also if the spi runs
|
||||
* out of data (for a long time)
|
||||
/* CS does not rise automatically after a transmission, also if the spi
|
||||
* runs out of data (for a long time)
|
||||
*/
|
||||
|
||||
if ((features & HWFEAT_FORCE_CS_ACTIVE_AFTER_TRANSFER) != 0)
|
||||
|
@ -1416,7 +1427,7 @@ static void spi_setbits(struct spi_dev_s *dev, int nbits)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t spi_send(struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
uint8_t txbyte;
|
||||
uint8_t rxbyte;
|
||||
|
@ -1431,7 +1442,7 @@ static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd)
|
|||
spi_exchange(dev, &txbyte, &rxbyte, 1);
|
||||
|
||||
spiinfo("Sent %02x received %02x\n", txbyte, rxbyte);
|
||||
return (uint16_t)rxbyte;
|
||||
return (uint32_t)rxbyte;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1554,11 +1565,11 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
|||
data = 0xffff;
|
||||
}
|
||||
|
||||
/* SPI_VARSELECT means, that the ChipSelect for each device is set within
|
||||
* the transferred data (SAM_SPI_TDR) instead inside the mode register
|
||||
* (SAM_SPI_MR).
|
||||
* In addition, the LASTXFER flag is also set within the transferred data
|
||||
* (SAM_SPI_TDR) instead inside the control register (SAM_SPI_CR).
|
||||
/* SPI_VARSELECT means, that the ChipSelect for each device is set
|
||||
* within the transferred data (SAM_SPI_TDR) instead inside the mode
|
||||
* register (SAM_SPI_MR).
|
||||
* In addition, the LASTXFER flag is also set within the transferred
|
||||
* data (SAM_SPI_TDR) instead inside the control register (SAM_SPI_CR).
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SAMV7_SPI_VARSELECT
|
||||
|
@ -1743,7 +1754,8 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
|||
* the DMA completes
|
||||
*/
|
||||
|
||||
up_invalidate_dcache((uintptr_t)rxbuffer, (uintptr_t)rxbuffer + nbytes);
|
||||
up_invalidate_dcache((uintptr_t)rxbuffer,
|
||||
(uintptr_t)rxbuffer + nbytes);
|
||||
|
||||
/* Use normal RX memory incrementing. */
|
||||
|
||||
|
@ -1937,10 +1949,10 @@ static void spi_sndblock(struct spi_dev_s *dev, const void *buffer,
|
|||
* dev - Device-specific state data
|
||||
* buffer - 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
|
||||
* 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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arm/arm/src/stm32/stm32_i2s.c
|
||||
* arch/arm/src/stm32/stm32_i2s.c
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Taras Drozdovskiy <t.drozdovskiy@gmail.com>
|
||||
|
@ -41,11 +41,12 @@
|
|||
* up_spiinitialize()) are provided by common STM32 logic. To use this
|
||||
* common SPI logic on your board:
|
||||
*
|
||||
* 1. Provide logic in stm32_boardinitialize() to configure I2S chip select
|
||||
* pins.
|
||||
* 2. Provide stm32_i2s2/3select() and stm32_i2s2/3status() functions in your
|
||||
* board-specific logic. These functions will perform chip selection and
|
||||
* status operations using GPIOs in the way your board is configured.
|
||||
* 1. Provide logic in stm32_boardinitialize() to configure I2S chip
|
||||
* select pins.
|
||||
* 2. Provide stm32_i2s2/3select() and stm32_i2s2/3status() 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 up_spiinitialize() in your low level application
|
||||
* initialization logic
|
||||
* 4. The handle returned by stm32_i2sdev_initialize() may then be used to
|
||||
|
@ -136,7 +137,8 @@
|
|||
|
||||
# endif
|
||||
|
||||
/* Configuration ********************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* I2S interrupts */
|
||||
|
||||
#ifdef CONFIG_STM32_SPI_INTERRUPTS
|
||||
|
@ -202,7 +204,8 @@
|
|||
# error "Unknown STM32 DMA"
|
||||
#endif
|
||||
|
||||
/* Debug *******************************************************************/
|
||||
/* Debug ********************************************************************/
|
||||
|
||||
/* Check if SSC debug is enabled (non-standard.. no support in
|
||||
* include/debug.h
|
||||
*/
|
||||
|
@ -316,10 +319,10 @@ struct stm32_i2s_s
|
|||
/* Debug stuff */
|
||||
|
||||
#ifdef CONFIG_STM32_I2S_REGDEBUG
|
||||
bool wr; /* Last was a write */
|
||||
uint32_t regaddr; /* Last address */
|
||||
uint16_t regval; /* Last value */
|
||||
int count; /* Number of times */
|
||||
bool wr; /* Last was a write */
|
||||
uint32_t regaddr; /* Last address */
|
||||
uint16_t regval; /* Last value */
|
||||
int count; /* Number of times */
|
||||
#endif /* CONFIG_STM32_I2S_REGDEBUG */
|
||||
};
|
||||
|
||||
|
@ -330,8 +333,8 @@ struct stm32_i2s_s
|
|||
/* Register helpers */
|
||||
|
||||
#ifdef CONFIG_STM32_I2S_REGDEBUG
|
||||
static bool i2s_checkreg(struct stm32_i2s_s *priv, bool wr, uint16_t regval,
|
||||
uint32_t regaddr);
|
||||
static bool i2s_checkreg(struct stm32_i2s_s *priv, bool wr,
|
||||
uint16_t regval, uint32_t regaddr);
|
||||
#else
|
||||
# define i2s_checkreg(priv,wr,regval,regaddr) (false)
|
||||
#endif
|
||||
|
@ -406,14 +409,16 @@ static void i2s_rxdma_timeout(int argc, uint32_t arg);
|
|||
static int i2s_rxdma_setup(struct stm32_i2s_s *priv);
|
||||
static void i2s_rx_worker(void *arg);
|
||||
static void i2s_rx_schedule(struct stm32_i2s_s *priv, int result);
|
||||
static void i2s_rxdma_callback(DMA_HANDLE handle, uint8_t result, void *arg);
|
||||
static void i2s_rxdma_callback(DMA_HANDLE handle, uint8_t result,
|
||||
void *arg);
|
||||
#endif
|
||||
#ifdef I2S_HAVE_TX
|
||||
static void i2s_txdma_timeout(int argc, uint32_t arg);
|
||||
static int i2s_txdma_setup(struct stm32_i2s_s *priv);
|
||||
static void i2s_tx_worker(void *arg);
|
||||
static void i2s_tx_schedule(struct stm32_i2s_s *priv, int result);
|
||||
static void i2s_txdma_callback(DMA_HANDLE handle, uint8_t result, void *arg);
|
||||
static void i2s_txdma_callback(DMA_HANDLE handle, uint8_t result,
|
||||
void *arg);
|
||||
#endif
|
||||
|
||||
/* I2S methods (and close friends) */
|
||||
|
@ -422,13 +427,16 @@ static int i2s_checkwidth(struct stm32_i2s_s *priv, int bits);
|
|||
|
||||
static uint32_t stm32_i2s_rxsamplerate(struct i2s_dev_s *dev, uint32_t rate);
|
||||
static uint32_t stm32_i2s_rxdatawidth(struct i2s_dev_s *dev, int bits);
|
||||
static int stm32_i2s_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
|
||||
i2s_callback_t callback, void *arg, uint32_t timeout);
|
||||
static int stm32_i2s_receive(struct i2s_dev_s *dev,
|
||||
struct ap_buffer_s *apb,
|
||||
i2s_callback_t callback,
|
||||
void *arg, uint32_t timeout);
|
||||
static uint32_t stm32_i2s_txsamplerate(struct i2s_dev_s *dev, uint32_t rate);
|
||||
static uint32_t stm32_i2s_txdatawidth(struct i2s_dev_s *dev, int bits);
|
||||
static int stm32_i2s_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
|
||||
i2s_callback_t callback, void *arg,
|
||||
uint32_t timeout);
|
||||
static int stm32_i2s_send(struct i2s_dev_s *dev,
|
||||
struct ap_buffer_s *apb,
|
||||
i2s_callback_t callback, void *arg,
|
||||
uint32_t timeout);
|
||||
|
||||
/* Initialization */
|
||||
|
||||
|
@ -714,7 +722,8 @@ static struct stm32_buffer_s *i2s_buf_allocate(struct stm32_i2s_s *priv)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void i2s_buf_free(struct stm32_i2s_s *priv, struct stm32_buffer_s *bfcontainer)
|
||||
static void i2s_buf_free(struct stm32_i2s_s *priv,
|
||||
struct stm32_buffer_s *bfcontainer)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
|
@ -814,6 +823,7 @@ static void i2s_rxdma_sampledone(struct stm32_i2s_s *priv, int result)
|
|||
stm32_dmasample(priv->rx.dma, &priv->rx.dmaregs[DMA_END_TRANSFER]);
|
||||
|
||||
/* Then dump the sampled DMA registers */
|
||||
|
||||
/* Initial register values */
|
||||
|
||||
stm32_dmadump(priv->rx.dma, &priv->rx.dmaregs[DMA_INITIAL],
|
||||
|
@ -879,6 +889,7 @@ static void i2s_txdma_sampledone(struct stm32_i2s_s *priv, int result)
|
|||
stm32_dmasample(priv->tx.dma, &priv->tx.dmaregs[DMA_END_TRANSFER]);
|
||||
|
||||
/* Then dump the sampled DMA registers */
|
||||
|
||||
/* Initial register values */
|
||||
|
||||
stm32_dmadump(priv->tx.dma, &priv->tx.dmaregs[DMA_INITIAL],
|
||||
|
@ -1115,9 +1126,9 @@ static void i2s_rx_worker(void *arg)
|
|||
DEBUGASSERT(priv);
|
||||
|
||||
/* When the transfer was started, the active buffer containers were removed
|
||||
* from the rx.pend queue and saved in the rx.act queue. We get here when the
|
||||
* DMA is finished... either successfully, with a DMA error, or with a DMA
|
||||
* timeout.
|
||||
* from the rx.pend queue and saved in the rx.act queue. We get here when
|
||||
* the DMA is finished... either successfully, with a DMA error, or with a
|
||||
* DMA timeout.
|
||||
*
|
||||
* In any case, the buffer containers in rx.act will be moved to the end
|
||||
* of the rx.done queue and rx.act queue will be emptied before this worker
|
||||
|
@ -1302,7 +1313,8 @@ static void i2s_rxdma_callback(DMA_HANDLE handle, uint8_t result, void *arg)
|
|||
|
||||
/* REVISIT: We would like to the next DMA started here so that we do not
|
||||
* get audio glitches at the boundaries between DMA transfers.
|
||||
* Unfortunately, we cannot call stm32_dmasetup() from an interrupt handler!
|
||||
* Unfortunately, we cannot call stm32_dmasetup() from an interrupt
|
||||
* handler!
|
||||
*/
|
||||
|
||||
/* Then schedule completion of the transfer to occur on the worker thread */
|
||||
|
@ -1424,9 +1436,10 @@ static int i2s_txdma_setup(struct stm32_i2s_s *priv)
|
|||
/* Configure DMA stream */
|
||||
|
||||
stm32_dmasetup(priv->tx.dma, priv->base + STM32_SPI_DR_OFFSET,
|
||||
(uint32_t)samp, nbytes/2, priv->txccr);
|
||||
(uint32_t)samp, nbytes / 2, priv->txccr);
|
||||
|
||||
/* Increment the DMA timeout */
|
||||
|
||||
if (bfcontainer->timeout > 0)
|
||||
{
|
||||
timeout += bfcontainer->timeout;
|
||||
|
@ -1458,7 +1471,8 @@ static int i2s_txdma_setup(struct stm32_i2s_s *priv)
|
|||
|
||||
/* Enable the transmitter */
|
||||
|
||||
i2s_putreg(priv, STM32_SPI_CR2_OFFSET, i2s_getreg(priv, STM32_SPI_CR2_OFFSET) | SPI_CR2_TXDMAEN);
|
||||
i2s_putreg(priv, STM32_SPI_CR2_OFFSET,
|
||||
i2s_getreg(priv, STM32_SPI_CR2_OFFSET) | SPI_CR2_TXDMAEN);
|
||||
|
||||
/* Start a watchdog to catch DMA timeouts */
|
||||
|
||||
|
@ -1507,9 +1521,9 @@ static void i2s_tx_worker(void *arg)
|
|||
DEBUGASSERT(priv);
|
||||
|
||||
/* When the transfer was started, the active buffer containers were removed
|
||||
* from the tx.pend queue and saved in the tx.act queue. We get here when the
|
||||
* DMA is finished... either successfully, with a DMA error, or with a DMA
|
||||
* timeout.
|
||||
* from the tx.pend queue and saved in the tx.act queue. We get here when
|
||||
* the DMA is finished... either successfully, with a DMA error, or with a
|
||||
* DMA timeout.
|
||||
*
|
||||
* In any case, the buffer containers in tx.act will be moved to the end
|
||||
* of the tx.done queue and tx.act will be emptied before this worker is
|
||||
|
@ -1682,7 +1696,8 @@ static void i2s_txdma_callback(DMA_HANDLE handle, uint8_t result, void *arg)
|
|||
|
||||
/* REVISIT: We would like to the next DMA started here so that we do not
|
||||
* get audio glitches at the boundaries between DMA transfers.
|
||||
* Unfortunately, we cannot call stm32_dmasetup() from an interrupt handler!
|
||||
* Unfortunately, we cannot call stm32_dmasetup() from an interrupt
|
||||
* handler!
|
||||
*/
|
||||
|
||||
/* Then schedule completion of the transfer to occur on the worker thread */
|
||||
|
@ -1906,8 +1921,8 @@ static int stm32_i2s_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
|
|||
flags = enter_critical_section();
|
||||
sq_addlast((sq_entry_t *)bfcontainer, &priv->rx.pend);
|
||||
|
||||
/* Then start the next transfer. If there is already a transfer in progress,
|
||||
* then this will do nothing.
|
||||
/* Then start the next transfer. If there is already a transfer in
|
||||
* progress, then this will do nothing.
|
||||
*/
|
||||
|
||||
ret = i2s_rxdma_setup(priv);
|
||||
|
@ -1930,12 +1945,12 @@ errout_with_exclsem:
|
|||
|
||||
static int roundf(float num)
|
||||
{
|
||||
if (((int)(num + 0.5f)) > num)
|
||||
{
|
||||
return num + 1;
|
||||
}
|
||||
if (((int)(num + 0.5f)) > num)
|
||||
{
|
||||
return num + 1;
|
||||
}
|
||||
|
||||
return num;
|
||||
return num;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1999,7 +2014,7 @@ static uint32_t stm32_i2s_txdatawidth(struct i2s_dev_s *dev, int bits)
|
|||
struct stm32_i2s_s *priv = (struct stm32_i2s_s *)dev;
|
||||
int ret;
|
||||
|
||||
i2sinfo("Data width bits of tx = %d\n",bits);
|
||||
i2sinfo("Data width bits of tx = %d\n", bits);
|
||||
DEBUGASSERT(priv && bits > 1);
|
||||
|
||||
/* Check if this is a bit width that we are configured to handle */
|
||||
|
@ -2112,8 +2127,8 @@ static int stm32_i2s_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
|
|||
flags = enter_critical_section();
|
||||
sq_addlast((sq_entry_t *)bfcontainer, &priv->tx.pend);
|
||||
|
||||
/* Then start the next transfer. If there is already a transfer in progress,
|
||||
* then this will do nothing.
|
||||
/* Then start the next transfer. If there is already a transfer in
|
||||
* progress, then this will do nothing.
|
||||
*/
|
||||
|
||||
ret = i2s_txdma_setup(priv);
|
||||
|
@ -2156,7 +2171,10 @@ static uint32_t i2s_mckdivider(struct stm32_i2s_s *priv)
|
|||
uint32_t bitrate;
|
||||
uint32_t regval;
|
||||
|
||||
uint16_t pllr = 5, plln = 256, div = 12, odd = 1;
|
||||
uint16_t pllr = 5;
|
||||
uint16_t plln = 256;
|
||||
uint16_t div = 12;
|
||||
uint16_t odd = 1;
|
||||
|
||||
DEBUGASSERT(priv && priv->samplerate >= 0 && priv->datalen > 0);
|
||||
|
||||
|
@ -2169,39 +2187,43 @@ static uint32_t i2s_mckdivider(struct stm32_i2s_s *priv)
|
|||
}
|
||||
else
|
||||
{
|
||||
int R, n, Od;
|
||||
int Napprox;
|
||||
int R;
|
||||
int n;
|
||||
int od;
|
||||
int napprox;
|
||||
int diff;
|
||||
int diff_min = 500000000;
|
||||
|
||||
for (Od = 0; Od <= 1; ++Od)
|
||||
for (od = 0; od <= 1; ++od)
|
||||
{
|
||||
for (R = 2; R <= 7; ++R)
|
||||
{
|
||||
for (n = 2; n <= 256; ++n)
|
||||
{
|
||||
Napprox = roundf(priv->samplerate / 1000000.0f * (8 * 32 * R * (2 * n + Od)));
|
||||
if ((Napprox > 432) || (Napprox < 50))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
napprox = roundf(priv->samplerate / 1000000.0f *
|
||||
(8 * 32 * R * (2 * n + od)));
|
||||
if ((napprox > 432) || (napprox < 50))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
diff = abs(priv->samplerate - 1000000 * Napprox / (8 * 32 * R * (2 * n + Od)));
|
||||
if (diff_min > diff)
|
||||
{
|
||||
diff_min = diff;
|
||||
plln = Napprox;
|
||||
pllr = R;
|
||||
div = n;
|
||||
odd = Od;
|
||||
}
|
||||
diff = abs(priv->samplerate - 1000000 * napprox /
|
||||
(8 * 32 * R * (2 * n + od)));
|
||||
if (diff_min > diff)
|
||||
{
|
||||
diff_min = diff;
|
||||
plln = napprox;
|
||||
pllr = R;
|
||||
div = n;
|
||||
odd = od;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate the new bitrate in Hz */
|
||||
/* Calculate the new bitrate in Hz */
|
||||
|
||||
bitrate = priv->samplerate * priv->datalen;
|
||||
bitrate = priv->samplerate * priv->datalen;
|
||||
}
|
||||
|
||||
/* Configure MCK divider */
|
||||
|
@ -2216,7 +2238,8 @@ static uint32_t i2s_mckdivider(struct stm32_i2s_s *priv)
|
|||
|
||||
/* PLLI2S clock used as I2S clock source */
|
||||
|
||||
putreg32(((getreg32(STM32_RCC_CFGR)) & (~RCC_CFGR_I2SSRC)), STM32_RCC_CFGR);
|
||||
putreg32(((getreg32(STM32_RCC_CFGR)) & (~RCC_CFGR_I2SSRC)),
|
||||
STM32_RCC_CFGR);
|
||||
regval = (pllr << 28) | (plln << 6);
|
||||
putreg32(regval, STM32_RCC_PLLI2SCFGR);
|
||||
|
||||
|
@ -2230,8 +2253,9 @@ static uint32_t i2s_mckdivider(struct stm32_i2s_s *priv)
|
|||
i2s_putreg(priv, STM32_SPI_I2SCFGR_OFFSET,
|
||||
SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SCFG_MTX | SPI_I2SCFGR_I2SE);
|
||||
|
||||
putreg32(((getreg32(STM32_DMA1_HIFCR)) | 0x80000000 /* DMA_HIFCR_CTCIF7 */),
|
||||
STM32_DMA1_HIFCR);
|
||||
/* putreg32((getreg32(STM32_DMA1_HIFCR) | DMA_HIFCR_CTCIF7), STM32_DMA1_HIFCR); */
|
||||
|
||||
putreg32((getreg32(STM32_DMA1_HIFCR) | 0x80000000), STM32_DMA1_HIFCR);
|
||||
|
||||
return bitrate;
|
||||
#else
|
||||
|
@ -2258,7 +2282,9 @@ static int i2s_dma_flags(struct stm32_i2s_s *priv)
|
|||
switch (priv->datalen)
|
||||
{
|
||||
case 8:
|
||||
|
||||
/* Reconfigure the RX DMA (and TX DMA if applicable) */
|
||||
|
||||
priv->rxccr = SPI_RXDMA8_CONFIG;
|
||||
priv->txccr = SPI_TXDMA8_CONFIG;
|
||||
break;
|
||||
|
@ -2429,7 +2455,7 @@ static void i2s2_configure(struct stm32_i2s_s *priv)
|
|||
* select pins must be selected by board-specific logic.
|
||||
*/
|
||||
|
||||
priv->base = STM32_I2S2_BASE;
|
||||
priv->base = STM32_I2S2_BASE;
|
||||
|
||||
#ifdef CONFIG_STM32_I2S2_RX
|
||||
priv->rxenab = true;
|
||||
|
@ -2541,7 +2567,7 @@ static void i2s3_configure(struct stm32_i2s_s *priv)
|
|||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: stm32_i2sdev_initialize
|
||||
*
|
||||
* Description:
|
||||
|
@ -2553,7 +2579,7 @@ static void i2s3_configure(struct stm32_i2s_s *priv)
|
|||
* Returned Value:
|
||||
* Valid I2S device structure reference on success; a NULL on failure
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct i2s_dev_s *stm32_i2sdev_initialize(int port)
|
||||
{
|
||||
|
|
|
@ -232,7 +232,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits);
|
|||
static int spi_hwfeatures(FAR struct spi_dev_s *dev,
|
||||
spi_hwfeatures_t features);
|
||||
#endif
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd);
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
#ifdef CONFIG_SPI_TRIGGER
|
||||
|
@ -1508,16 +1508,16 @@ static int spi_hwfeatures(FAR struct spi_dev_s *dev, spi_hwfeatures_t features)
|
|||
*
|
||||
************************************************************************************/
|
||||
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
||||
uint32_t regval;
|
||||
uint16_t ret;
|
||||
uint32_t ret;
|
||||
|
||||
DEBUGASSERT(priv && priv->spibase);
|
||||
|
||||
spi_writeword(priv, wd);
|
||||
ret = spi_readword(priv);
|
||||
spi_writeword(priv, (uint32_t)(wd & 0xffff));
|
||||
ret = (uint32_t)spi_readword(priv);
|
||||
|
||||
/* Check and clear any error flags (Reading from the SR clears the error flags) */
|
||||
|
||||
|
@ -1545,7 +1545,8 @@ static uint16_t spi_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
|
||||
|
@ -1592,7 +1593,7 @@ static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuff
|
|||
|
||||
/* Exchange one word */
|
||||
|
||||
word = spi_send(dev, word);
|
||||
word = (uint16_t)spi_send(dev, (uint32_t)word);
|
||||
|
||||
/* Is there a buffer to receive the return value? */
|
||||
|
||||
|
@ -1625,7 +1626,7 @@ static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuff
|
|||
|
||||
/* Exchange one word */
|
||||
|
||||
word = (uint8_t)spi_send(dev, (uint16_t)word);
|
||||
word = (uint8_t)spi_send(dev, (uint32_t)word);
|
||||
|
||||
/* Is there a buffer to receive the return value? */
|
||||
|
||||
|
@ -1651,7 +1652,8 @@ static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuff
|
|||
* nwords - the length of data 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
|
||||
* packed into uint8_t's; if nbits >8, the data is packed into
|
||||
* uint16_t's
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
|
@ -1797,7 +1799,8 @@ static int spi_trigger(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
|
||||
|
@ -1826,7 +1829,8 @@ static void spi_sndblock(FAR struct spi_dev_s *dev,
|
|||
* 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
|
||||
* packed into uint8_t's; if nbits >8, the data is packed into
|
||||
* uint16_t's
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
/************************************************************************************
|
||||
* arm/arm/src/stm32f7/stm32_spi.c
|
||||
/****************************************************************************
|
||||
* arch/arm/src/stm32f7/stm32_spi.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
|
@ -16,34 +16,34 @@
|
|||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* The external functions, stm32_spi1/2/3/4/5/6select and stm32_spi1/2/3/4/5/6status
|
||||
* must be provided by board-specific logic. They are implementations of the select
|
||||
* and status methods of the SPI interface defined by struct spi_ops_s (see
|
||||
* include/nuttx/spi/spi.h). All other methods (including stm32_spibus_initialize())
|
||||
* are provided by common STM32 logic. To use this common SPI logic on your
|
||||
* board:
|
||||
/****************************************************************************
|
||||
* The external functions, stm32_spi1/2/3/4/5/6select and
|
||||
* stm32_spi1/2/3/4/5/6status must be provided by board-specific logic. They
|
||||
* are implementations of the select and status methods of the SPI interface
|
||||
* defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other
|
||||
* methods (including stm32_spibus_initialize()) are provided by common STM32
|
||||
* logic. To use this common SPI logic on your board:
|
||||
*
|
||||
* 1. Provide logic in stm32_boardinitialize() to configure SPI chip select
|
||||
* pins.
|
||||
* 2. Provide stm32_spi1/2/3/4/5/6select() and stm32_spi1/2/3/4/5/6status()
|
||||
* 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 stm32_spibus_initialize() in your low level application
|
||||
* initialization logic
|
||||
* 4. The handle returned by stm32_spibus_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 stm32_spibus_initialize() in your low level
|
||||
* application initialization logic
|
||||
* 4. The handle returned by stm32_spibus_initialize() may then be used to
|
||||
* bind the SPI driver to higher level logic (e.g., calling
|
||||
* mmcsd_spislotinitialize(), for example, will bind the SPI driver to
|
||||
* the SPI MMC/SD driver).
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
|
@ -74,11 +74,11 @@
|
|||
defined(CONFIG_STM32F7_SPI3) || defined(CONFIG_STM32F7_SPI4) || \
|
||||
defined(CONFIG_STM32F7_SPI5) || defined(CONFIG_STM32F7_SPI6)
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ********************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* SPI interrupts */
|
||||
|
||||
|
@ -120,9 +120,9 @@
|
|||
# define SPI_TXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_8BITS |DMA_SCR_DIR_M2P)
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
struct stm32_spidev_s
|
||||
{
|
||||
|
@ -159,17 +159,19 @@ struct stm32_spidev_s
|
|||
#endif
|
||||
};
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/* Helpers */
|
||||
|
||||
static inline uint16_t spi_getreg(FAR struct stm32_spidev_s *priv, uint8_t offset);
|
||||
static inline void spi_putreg(FAR struct stm32_spidev_s *priv, uint8_t offset,
|
||||
uint16_t value);
|
||||
static inline uint16_t spi_getreg(FAR struct stm32_spidev_s *priv,
|
||||
uint8_t offset);
|
||||
static inline void spi_putreg(FAR struct stm32_spidev_s *priv,
|
||||
uint8_t offset, uint16_t value);
|
||||
static inline uint16_t spi_readword(FAR struct stm32_spidev_s *priv);
|
||||
static inline void spi_writeword(FAR struct stm32_spidev_s *priv, uint16_t byte);
|
||||
static inline void spi_writeword(FAR struct stm32_spidev_s *priv,
|
||||
uint16_t byte);
|
||||
static inline bool spi_9to16bitmode(FAR struct stm32_spidev_s *priv);
|
||||
|
||||
/* DMA support */
|
||||
|
@ -179,12 +181,16 @@ static void spi_dmarxwait(FAR struct stm32_spidev_s *priv);
|
|||
static void spi_dmatxwait(FAR struct stm32_spidev_s *priv);
|
||||
static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv);
|
||||
static inline void spi_dmatxwakeup(FAR struct stm32_spidev_s *priv);
|
||||
static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg);
|
||||
static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg);
|
||||
static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr,
|
||||
void *arg);
|
||||
static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr,
|
||||
void *arg);
|
||||
static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv,
|
||||
FAR void *rxbuffer, FAR void *rxdummy, size_t nwords);
|
||||
FAR void *rxbuffer, FAR void *rxdummy,
|
||||
size_t nwords);
|
||||
static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv,
|
||||
FAR const void *txbuffer, FAR const void *txdummy, size_t nwords);
|
||||
FAR const void *txbuffer,
|
||||
FAR const void *txdummy, size_t nwords);
|
||||
static inline void spi_dmarxstart(FAR struct stm32_spidev_s *priv);
|
||||
static inline void spi_dmatxstart(FAR struct stm32_spidev_s *priv);
|
||||
#endif
|
||||
|
@ -192,24 +198,27 @@ static inline void spi_dmatxstart(FAR struct stm32_spidev_s *priv);
|
|||
/* SPI methods */
|
||||
|
||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
|
||||
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 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);
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev,
|
||||
spi_hwfeatures_t features);
|
||||
#endif
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd);
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
size_t nwords);
|
||||
#ifdef CONFIG_SPI_TRIGGER
|
||||
static int spi_trigger(FAR struct spi_dev_s *dev);
|
||||
#endif
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
size_t nwords);
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer,
|
||||
size_t nwords);
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, size_t nwords);
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
#endif
|
||||
|
||||
/* Initialization */
|
||||
|
@ -223,9 +232,9 @@ static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain,
|
|||
enum pm_state_e pmstate);
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32F7_SPI1
|
||||
static const struct spi_ops_s g_sp1iops =
|
||||
|
@ -575,11 +584,11 @@ static struct stm32_spidev_s g_spi6dev =
|
|||
};
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_getreg8
|
||||
*
|
||||
* Description:
|
||||
|
@ -592,14 +601,15 @@ static struct stm32_spidev_s g_spi6dev =
|
|||
* Returned Value:
|
||||
* The contents of the 8-bit register
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint8_t spi_getreg8(FAR struct stm32_spidev_s *priv, uint8_t offset)
|
||||
static inline uint8_t spi_getreg8(FAR struct stm32_spidev_s *priv,
|
||||
uint8_t offset)
|
||||
{
|
||||
return getreg8(priv->spibase + offset);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_putreg8
|
||||
*
|
||||
* Description:
|
||||
|
@ -610,15 +620,15 @@ static inline uint8_t spi_getreg8(FAR struct stm32_spidev_s *priv, uint8_t offse
|
|||
* offset - offset to the register of interest
|
||||
* value - the 8-bit value to be written
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_putreg8(FAR struct stm32_spidev_s *priv, uint8_t offset,
|
||||
uint8_t value)
|
||||
static inline void spi_putreg8(FAR struct stm32_spidev_s *priv,
|
||||
uint8_t offset, uint8_t value)
|
||||
{
|
||||
putreg8(value, priv->spibase + offset);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_getreg
|
||||
*
|
||||
* Description:
|
||||
|
@ -631,14 +641,15 @@ static inline void spi_putreg8(FAR struct stm32_spidev_s *priv, uint8_t offset,
|
|||
* Returned Value:
|
||||
* The contents of the 16-bit register
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint16_t spi_getreg(FAR struct stm32_spidev_s *priv, uint8_t offset)
|
||||
static inline uint16_t spi_getreg(FAR struct stm32_spidev_s *priv,
|
||||
uint8_t offset)
|
||||
{
|
||||
return getreg16(priv->spibase + offset);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_putreg
|
||||
*
|
||||
* Description:
|
||||
|
@ -652,15 +663,15 @@ static inline uint16_t spi_getreg(FAR struct stm32_spidev_s *priv, uint8_t offse
|
|||
* Returned Value:
|
||||
* The contents of the 16-bit register
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_putreg(FAR struct stm32_spidev_s *priv, uint8_t offset,
|
||||
uint16_t value)
|
||||
static inline void spi_putreg(FAR struct stm32_spidev_s *priv,
|
||||
uint8_t offset, uint16_t value)
|
||||
{
|
||||
putreg16(value, priv->spibase + offset);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_readword
|
||||
*
|
||||
* Description:
|
||||
|
@ -672,7 +683,7 @@ static inline void spi_putreg(FAR struct stm32_spidev_s *priv, uint8_t offset,
|
|||
* Returned Value:
|
||||
* Byte as read
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint16_t spi_readword(FAR struct stm32_spidev_s *priv)
|
||||
{
|
||||
|
@ -685,7 +696,7 @@ static inline uint16_t spi_readword(FAR struct stm32_spidev_s *priv)
|
|||
return spi_getreg(priv, STM32_SPI_DR_OFFSET);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_writeword
|
||||
*
|
||||
* Description:
|
||||
|
@ -698,9 +709,10 @@ static inline uint16_t spi_readword(FAR struct stm32_spidev_s *priv)
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_writeword(FAR struct stm32_spidev_s *priv, uint16_t word)
|
||||
static inline void spi_writeword(FAR struct stm32_spidev_s *priv,
|
||||
uint16_t word)
|
||||
{
|
||||
/* Wait until the transmit buffer is empty */
|
||||
|
||||
|
@ -711,7 +723,7 @@ static inline void spi_writeword(FAR struct stm32_spidev_s *priv, uint16_t word)
|
|||
spi_putreg(priv, STM32_SPI_DR_OFFSET, word);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_readbyte
|
||||
*
|
||||
* Description:
|
||||
|
@ -723,7 +735,7 @@ static inline void spi_writeword(FAR struct stm32_spidev_s *priv, uint16_t word)
|
|||
* Returned Value:
|
||||
* Byte as read
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint8_t spi_readbyte(FAR struct stm32_spidev_s *priv)
|
||||
{
|
||||
|
@ -736,7 +748,7 @@ static inline uint8_t spi_readbyte(FAR struct stm32_spidev_s *priv)
|
|||
return spi_getreg8(priv, STM32_SPI_DR_OFFSET);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_writebyte
|
||||
*
|
||||
* Description:
|
||||
|
@ -749,9 +761,10 @@ static inline uint8_t spi_readbyte(FAR struct stm32_spidev_s *priv)
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_writebyte(FAR struct stm32_spidev_s *priv, uint8_t byte)
|
||||
static inline void spi_writebyte(FAR struct stm32_spidev_s *priv,
|
||||
uint8_t byte)
|
||||
{
|
||||
/* Wait until the transmit buffer is empty */
|
||||
|
||||
|
@ -762,7 +775,7 @@ static inline void spi_writebyte(FAR struct stm32_spidev_s *priv, uint8_t byte)
|
|||
spi_putreg8(priv, STM32_SPI_DR_OFFSET, byte);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_9to16bitmode
|
||||
*
|
||||
* Description:
|
||||
|
@ -774,26 +787,27 @@ static inline void spi_writebyte(FAR struct stm32_spidev_s *priv, uint8_t byte)
|
|||
* Returned Value:
|
||||
* true: >8 bit mode-bit mode, false: <= 8-bit mode
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline bool spi_9to16bitmode(FAR struct stm32_spidev_s *priv)
|
||||
{
|
||||
return ((spi_getreg(priv, STM32_SPI_CR2_OFFSET) & SPI_CR2_DS_9BIT) == SPI_CR2_DS_9BIT);
|
||||
return ((spi_getreg(priv, STM32_SPI_CR2_OFFSET) & SPI_CR2_DS_9BIT) ==
|
||||
SPI_CR2_DS_9BIT);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmarxwait
|
||||
*
|
||||
* Description:
|
||||
* Wait for DMA to complete.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32F7_SPI_DMA
|
||||
static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
|
||||
{
|
||||
/* Take the semaphore (perhaps waiting). If the result is zero, then the DMA
|
||||
* must not really have completed???
|
||||
/* Take the semaphore (perhaps waiting). If the result is zero, then the
|
||||
* DMA must not really have completed???
|
||||
*/
|
||||
|
||||
do
|
||||
|
@ -804,19 +818,19 @@ static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmatxwait
|
||||
*
|
||||
* Description:
|
||||
* Wait for DMA to complete.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32F7_SPI_DMA
|
||||
static void spi_dmatxwait(FAR struct stm32_spidev_s *priv)
|
||||
{
|
||||
/* Take the semaphore (perhaps waiting). If the result is zero, then the DMA
|
||||
* must not really have completed???
|
||||
/* Take the semaphore (perhaps waiting). If the result is zero, then the
|
||||
* DMA must not really have completed???
|
||||
*/
|
||||
|
||||
do
|
||||
|
@ -827,13 +841,13 @@ static void spi_dmatxwait(FAR struct stm32_spidev_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmarxwakeup
|
||||
*
|
||||
* Description:
|
||||
* Signal that DMA is complete
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32F7_SPI_DMA
|
||||
static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv)
|
||||
|
@ -842,13 +856,13 @@ static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmatxwakeup
|
||||
*
|
||||
* Description:
|
||||
* Signal that DMA is complete
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32F7_SPI_DMA
|
||||
static inline void spi_dmatxwakeup(FAR struct stm32_spidev_s *priv)
|
||||
|
@ -857,13 +871,13 @@ static inline void spi_dmatxwakeup(FAR struct stm32_spidev_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmarxcallback
|
||||
*
|
||||
* Description:
|
||||
* Called when the RX DMA completes
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32F7_SPI_DMA
|
||||
static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg)
|
||||
|
@ -877,13 +891,13 @@ static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmatxcallback
|
||||
*
|
||||
* Description:
|
||||
* Called when the RX DMA completes
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32F7_SPI_DMA
|
||||
static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg)
|
||||
|
@ -897,17 +911,18 @@ static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmarxsetup
|
||||
*
|
||||
* Description:
|
||||
* Setup to perform RX DMA
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32F7_SPI_DMA
|
||||
static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv, FAR void *rxbuffer,
|
||||
FAR void *rxdummy, size_t nwords)
|
||||
static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv,
|
||||
FAR void *rxbuffer, FAR void *rxdummy,
|
||||
size_t nwords)
|
||||
{
|
||||
/* 8- or 16-bit mode? */
|
||||
|
||||
|
@ -947,17 +962,18 @@ static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv, FAR void *rxbuffer,
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmatxsetup
|
||||
*
|
||||
* Description:
|
||||
* Setup to perform TX DMA
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32F7_SPI_DMA
|
||||
static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv, FAR const void *txbuffer,
|
||||
FAR const void *txdummy, size_t nwords)
|
||||
static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv,
|
||||
FAR const void *txbuffer, FAR const void *txdummy,
|
||||
size_t nwords)
|
||||
{
|
||||
/* 8- or 16-bit mode? */
|
||||
|
||||
|
@ -997,13 +1013,13 @@ static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv, FAR const void *txbu
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmarxstart
|
||||
*
|
||||
* Description:
|
||||
* Start RX DMA
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32F7_SPI_DMA
|
||||
static void spi_dmarxstart(FAR struct stm32_spidev_s *priv)
|
||||
|
@ -1013,13 +1029,13 @@ static void spi_dmarxstart(FAR struct stm32_spidev_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmatxstart
|
||||
*
|
||||
* Description:
|
||||
* Start TX DMA
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32F7_SPI_DMA
|
||||
static void spi_dmatxstart(FAR struct stm32_spidev_s *priv)
|
||||
|
@ -1029,7 +1045,7 @@ static void spi_dmatxstart(FAR struct stm32_spidev_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_modifycr1
|
||||
*
|
||||
* Description:
|
||||
|
@ -1043,7 +1059,7 @@ static void spi_dmatxstart(FAR struct stm32_spidev_s *priv)
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_modifycr1(FAR struct stm32_spidev_s *priv, uint16_t setbits,
|
||||
uint16_t clrbits)
|
||||
|
@ -1055,7 +1071,7 @@ static void spi_modifycr1(FAR struct stm32_spidev_s *priv, uint16_t setbits,
|
|||
spi_putreg(priv, STM32_SPI_CR1_OFFSET, cr1);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_modifycr2
|
||||
*
|
||||
* Description:
|
||||
|
@ -1069,7 +1085,7 @@ static void spi_modifycr1(FAR struct stm32_spidev_s *priv, uint16_t setbits,
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_modifycr2(FAR struct stm32_spidev_s *priv, uint16_t setbits,
|
||||
uint16_t clrbits)
|
||||
|
@ -1081,7 +1097,7 @@ static void spi_modifycr2(FAR struct stm32_spidev_s *priv, uint16_t setbits,
|
|||
spi_putreg(priv, STM32_SPI_CR2_OFFSET, cr2);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_lock
|
||||
*
|
||||
* Description:
|
||||
|
@ -1100,7 +1116,7 @@ static void spi_modifycr2(FAR struct stm32_spidev_s *priv, uint16_t setbits,
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
||||
{
|
||||
|
@ -1119,7 +1135,7 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_setfrequency
|
||||
*
|
||||
* Description:
|
||||
|
@ -1132,9 +1148,10 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
|||
* Returned Value:
|
||||
* Returns the actual frequency selected
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency)
|
||||
{
|
||||
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
||||
uint16_t setbits;
|
||||
|
@ -1214,8 +1231,8 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
|||
spi_modifycr1(priv, setbits, SPI_CR1_BR_MASK);
|
||||
spi_modifycr1(priv, SPI_CR1_SPE, 0);
|
||||
|
||||
/* Save the frequency selection so that subsequent reconfigurations will be
|
||||
* faster.
|
||||
/* Save the frequency selection so that subsequent reconfigurations
|
||||
* will be faster.
|
||||
*/
|
||||
|
||||
spiinfo("Frequency %d->%d\n", frequency, actual);
|
||||
|
@ -1227,7 +1244,7 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
|||
return priv->actual;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_setmode
|
||||
*
|
||||
* Description:
|
||||
|
@ -1240,7 +1257,7 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
|||
* Returned Value:
|
||||
* Returns the actual frequency selected
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
||||
{
|
||||
|
@ -1303,7 +1320,8 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
|||
/* Re-enable SPI */
|
||||
|
||||
spi_modifycr1(priv, SPI_CR1_SPE, 0);
|
||||
while ((spi_getreg(priv, STM32_SPI_SR_OFFSET) & SPI_SR_FRLVL_MASK) != 0)
|
||||
while ((spi_getreg(priv, STM32_SPI_SR_OFFSET) &
|
||||
SPI_SR_FRLVL_MASK) != 0)
|
||||
{
|
||||
/* Flush SPI read FIFO */
|
||||
|
||||
|
@ -1325,7 +1343,7 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
|||
}
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_setbits
|
||||
*
|
||||
* Description:
|
||||
|
@ -1338,7 +1356,7 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
||||
{
|
||||
|
@ -1388,7 +1406,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
|||
}
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_hwfeatures
|
||||
*
|
||||
* Description:
|
||||
|
@ -1402,10 +1420,11 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
|||
* Zero (OK) if the selected H/W features are enabled; A negated errno
|
||||
* value if any H/W feature is not supportable.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev, spi_hwfeatures_t features)
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev,
|
||||
spi_hwfeatures_t features)
|
||||
{
|
||||
#if defined(CONFIG_SPI_BITORDER) || defined(CONFIG_SPI_TRIGGER)
|
||||
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
||||
|
@ -1457,7 +1476,7 @@ static int spi_hwfeatures(FAR struct spi_dev_s *dev, spi_hwfeatures_t features)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_send
|
||||
*
|
||||
* Description:
|
||||
|
@ -1471,25 +1490,25 @@ static int spi_hwfeatures(FAR struct spi_dev_s *dev, spi_hwfeatures_t features)
|
|||
* Returned Value:
|
||||
* response
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
||||
uint32_t regval;
|
||||
uint16_t ret;
|
||||
uint32_t ret;
|
||||
|
||||
DEBUGASSERT(priv && priv->spibase);
|
||||
|
||||
/* According to the number of bits, access data register as word or byte
|
||||
* This is absolutely required because of packing. With nbits <=8 bit frames,
|
||||
* two bytes are received by a 16-bit read of the data register!
|
||||
* This is absolutely required because of packing. With nbits <=8 bit
|
||||
* frames, two bytes are received by a 16-bit read of the data register!
|
||||
*/
|
||||
|
||||
if (spi_9to16bitmode(priv))
|
||||
{
|
||||
spi_writeword(priv, wd);
|
||||
ret = spi_readword(priv);
|
||||
spi_writeword(priv, (uint16_t)(wd & 0xffff));
|
||||
ret = (uint32_t)spi_readword(priv);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1516,7 +1535,7 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_exchange (no DMA). aka spi_exchange_nodma
|
||||
*
|
||||
* Description:
|
||||
|
@ -1529,12 +1548,13 @@ static uint16_t spi_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_STM32F7_SPI_DMA) || defined(CONFIG_STM32F7_DMACAPABLE) || \
|
||||
defined(CONFIG_STM32F7_SPI_DMATHRESHOLD)
|
||||
|
@ -1542,8 +1562,9 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords)
|
||||
#else
|
||||
static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords)
|
||||
static void spi_exchange_nodma(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
size_t nwords)
|
||||
#endif
|
||||
{
|
||||
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
||||
|
@ -1576,7 +1597,7 @@ static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuff
|
|||
|
||||
/* Exchange one word */
|
||||
|
||||
word = spi_send(dev, word);
|
||||
word = (uint16_t)spi_send(dev, (uint32_t)word);
|
||||
|
||||
/* Is there a buffer to receive the return value? */
|
||||
|
||||
|
@ -1609,7 +1630,7 @@ static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuff
|
|||
|
||||
/* Exchange one word */
|
||||
|
||||
word = (uint8_t)spi_send(dev, (uint16_t)word);
|
||||
word = (uint8_t)spi_send(dev, (uint32_t)word);
|
||||
|
||||
/* Is there a buffer to receive the return value? */
|
||||
|
||||
|
@ -1620,11 +1641,12 @@ static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuff
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_STM32F7_SPI_DMA || CONFIG_STM32F7_DMACAPABLE ||
|
||||
* CONFIG_STM32F7_SPI_DMATHRESHOLD
|
||||
*/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_exchange (with DMA capability)
|
||||
*
|
||||
* Description:
|
||||
|
@ -1637,12 +1659,13 @@ static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuff
|
|||
* nwords - the length of data 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
|
||||
* packed into uint8_t's; if nbits >8, the data is packed into
|
||||
* uint16_t's
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32F7_SPI_DMA
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
|
@ -1678,8 +1701,10 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_STM32F7_DMACAPABLE
|
||||
if ((txbuffer && !stm32_dmacapable((uint32_t)txbuffer, nwords, priv->txccr)) ||
|
||||
(rxbuffer && !stm32_dmacapable((uint32_t)rxbuffer, nwords, priv->rxccr)))
|
||||
if ((txbuffer &&
|
||||
!stm32_dmacapable((uint32_t)txbuffer, nwords, priv->txccr)) ||
|
||||
(rxbuffer &&
|
||||
!stm32_dmacapable((uint32_t)rxbuffer, nwords, priv->rxccr)))
|
||||
{
|
||||
/* Unsupported memory region fall back to non-DMA method. */
|
||||
|
||||
|
@ -1698,7 +1723,8 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
buflen = nwords * sizeof(uint16_t);
|
||||
}
|
||||
|
||||
spiinfo("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords);
|
||||
spiinfo("txbuffer=%p rxbuffer=%p nwords=%d\n",
|
||||
txbuffer, rxbuffer, nwords);
|
||||
DEBUGASSERT(priv->spibase != 0);
|
||||
|
||||
/* Setup DMAs */
|
||||
|
@ -1761,7 +1787,7 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
}
|
||||
#endif /* CONFIG_STM32F7_SPI_DMA */
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_trigger
|
||||
*
|
||||
* Description:
|
||||
|
@ -1775,7 +1801,7 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
* ENOTSUP - Trigger not fired due to lack of DMA support
|
||||
* EIO - Trigger not fired because not previously primed
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SPI_TRIGGER
|
||||
static int spi_trigger(FAR struct spi_dev_s *dev)
|
||||
|
@ -1798,7 +1824,7 @@ static int spi_trigger(FAR struct spi_dev_s *dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_sndblock
|
||||
*
|
||||
* Description:
|
||||
|
@ -1807,25 +1833,27 @@ static int spi_trigger(FAR struct spi_dev_s *dev)
|
|||
* Input Parameters:
|
||||
* dev - Device-specific state data
|
||||
* txbuffer - 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
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, size_t nwords)
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
size_t nwords)
|
||||
{
|
||||
spiinfo("txbuffer=%p nwords=%d\n", txbuffer, nwords);
|
||||
return spi_exchange(dev, txbuffer, NULL, nwords);
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_recvblock
|
||||
*
|
||||
* Description:
|
||||
|
@ -1834,25 +1862,27 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, si
|
|||
* 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 spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, size_t nwords)
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer,
|
||||
size_t nwords)
|
||||
{
|
||||
spiinfo("rxbuffer=%p nwords=%d\n", rxbuffer, nwords);
|
||||
return spi_exchange(dev, NULL, rxbuffer, nwords);
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_pm_prepare
|
||||
*
|
||||
* Description:
|
||||
|
@ -1879,7 +1909,7 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, size_t
|
|||
* power state change). Drivers are not permitted to return non-zero
|
||||
* values when reverting back to higher power consumption modes!
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain,
|
||||
|
@ -1929,11 +1959,12 @@ static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain,
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_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
|
||||
|
@ -1941,7 +1972,7 @@ static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain,
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_bus_initialize(struct stm32_spidev_s *priv)
|
||||
{
|
||||
|
@ -1955,13 +1986,16 @@ static void spi_bus_initialize(struct stm32_spidev_s *priv)
|
|||
* Mode 0: CR1.CPHA=0 and CR1.CPOL=0
|
||||
* Master: CR1.MSTR=1
|
||||
* 8-bit: CR2.DS=7
|
||||
* MSB transmitted first: CR1.LSBFIRST=0
|
||||
* Replace NSS with SSI & SSI=1: CR1.SSI=1 CR1.SSM=1 (prevents MODF error)
|
||||
* Two lines full duplex: CR1.BIDIMODE=0 CR1.BIDIOIE=(Don't care) and CR1.RXONLY=0
|
||||
* MSB transmitted first: CR1.LSBFIRST=0
|
||||
* Replace NSS with SSI & SSI=1: CR1.SSI=1 CR1.SSM=1 (prevents MODF
|
||||
* error)
|
||||
* Two lines full duplex: CR1.BIDIMODE=0 CR1.BIDIOIE=(Don't care)
|
||||
* and CR1.RXONLY=0
|
||||
*/
|
||||
|
||||
clrbits = SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_BR_MASK | SPI_CR1_LSBFIRST |
|
||||
SPI_CR1_RXONLY | SPI_CR1_BIDIOE | SPI_CR1_BIDIMODE;
|
||||
clrbits = SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_BR_MASK |
|
||||
SPI_CR1_LSBFIRST | SPI_CR1_RXONLY | SPI_CR1_BIDIOE |
|
||||
SPI_CR1_BIDIMODE;
|
||||
setbits = SPI_CR1_MSTR | SPI_CR1_SSI | SPI_CR1_SSM;
|
||||
spi_modifycr1(priv, setbits, clrbits);
|
||||
|
||||
|
@ -1999,12 +2033,13 @@ static void spi_bus_initialize(struct stm32_spidev_s *priv)
|
|||
nxsem_setprotocol(&priv->rxsem, SEM_PRIO_NONE);
|
||||
nxsem_setprotocol(&priv->txsem, SEM_PRIO_NONE);
|
||||
|
||||
/* Get DMA channels. NOTE: stm32_dmachannel() will always assign the DMA
|
||||
* channel. If the channel is not available, then stm32_dmachannel() will
|
||||
* block and wait until the channel becomes available. WARNING: If you have
|
||||
* another device sharing a DMA channel with SPI and the code never releases
|
||||
* that channel, then the call to stm32_dmachannel() will hang forever in
|
||||
* this function! Don't let your design do that!
|
||||
/* Get DMA channels. NOTE: stm32_dmachannel() will always assign the
|
||||
* DMA channel. If the channel is not available, then
|
||||
* stm32_dmachannel() will block and wait until the channel becomes
|
||||
* available. WARNING: If you have another device sharing a DMA
|
||||
* channel with SPI and the code never releases that channel, then the
|
||||
* call to stm32_dmachannel() will hang forever in this function!
|
||||
* Don't let your design do that!
|
||||
*/
|
||||
|
||||
priv->rxdma = stm32_dmachannel(priv->rxch);
|
||||
|
@ -2033,11 +2068,11 @@ static void spi_bus_initialize(struct stm32_spidev_s *priv)
|
|||
#endif
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: stm32_spibus_initialize
|
||||
*
|
||||
* Description:
|
||||
|
@ -2049,7 +2084,7 @@ static void spi_bus_initialize(struct stm32_spidev_s *priv)
|
|||
* Returned Value:
|
||||
* Valid SPI device structure reference on success; a NULL on failure
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct spi_dev_s *stm32_spibus_initialize(int bus)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/************************************************************************************
|
||||
* arm/arm/src/stm32f7/stm32_tim.c
|
||||
* arch/arm/src/stm32f7/stm32_tim.c
|
||||
*
|
||||
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
||||
* Author: Uros Platise <uros.platise@isotel.eu>
|
||||
|
@ -712,6 +712,7 @@ static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t m
|
|||
break;
|
||||
|
||||
case STM32_TIM_MODE_UPDOWN:
|
||||
|
||||
/* Our default: Interrupts are generated on compare, when counting down */
|
||||
|
||||
val |= ATIM_CR1_CENTER1;
|
||||
|
@ -1165,6 +1166,7 @@ static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, uint8_t channel
|
|||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -1190,6 +1192,7 @@ static int stm32_tim_setcompare(FAR struct stm32_tim_dev_s *dev, uint8_t channel
|
|||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -1248,6 +1251,7 @@ struct stm32_tim_priv_s stm32_tim1_priv =
|
|||
.base = STM32_TIM1_BASE,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STM32F7_TIM2
|
||||
struct stm32_tim_priv_s stm32_tim2_priv =
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* arch/arm/src/stm32h7/stm32_spi.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
|
@ -16,34 +16,34 @@
|
|||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* The external functions, stm32_spi1/2/3/4/5/6select and stm32_spi1/2/3/4/5/6status
|
||||
* must be provided by board-specific logic. They are implementations of the select
|
||||
* and status methods of the SPI interface defined by struct spi_ops_s (see
|
||||
* include/nuttx/spi/spi.h). All other methods (including stm32_spibus_initialize())
|
||||
* are provided by common STM32 logic. To use this common SPI logic on your
|
||||
* board:
|
||||
/****************************************************************************
|
||||
* The external functions, stm32_spi1/2/3/4/5/6select and
|
||||
* stm32_spi1/2/3/4/5/6status must be provided by board-specific logic. They
|
||||
* are implementations of the select and status methods of the SPI interface
|
||||
* defined by struct spi_ops_s (see include/nuttx/spi/spi.h). All other
|
||||
* methods (including stm32_spibus_initialize()) are provided by common STM32
|
||||
* logic. To use this common SPI logic on your board:
|
||||
*
|
||||
* 1. Provide logic in stm32_boardinitialize() to configure SPI chip select
|
||||
* pins.
|
||||
* 2. Provide stm32_spi1/2/3/4/5/6select() and stm32_spi1/2/3/4/5/6status()
|
||||
* 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 stm32_spibus_initialize() in your low level application
|
||||
* initialization logic
|
||||
* 4. The handle returned by stm32_spibus_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 stm32_spibus_initialize() in your low level
|
||||
* application initialization logic
|
||||
* 4. The handle returned by stm32_spibus_initialize() may then be used to
|
||||
* bind the SPI driver to higher level logic (e.g., calling
|
||||
* mmcsd_spislotinitialize(), for example, will bind the SPI driver to
|
||||
* the SPI MMC/SD driver).
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
|
@ -75,11 +75,11 @@
|
|||
defined(CONFIG_STM32H7_SPI3) || defined(CONFIG_STM32H7_SPI4) || \
|
||||
defined(CONFIG_STM32H7_SPI5) || defined(CONFIG_STM32H7_SPI6)
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ********************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* SPI interrupts */
|
||||
|
||||
|
@ -166,9 +166,9 @@
|
|||
# endif
|
||||
#endif /* SPI6 */
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
struct stm32_spidev_s
|
||||
{
|
||||
|
@ -205,17 +205,19 @@ struct stm32_spidev_s
|
|||
#endif
|
||||
};
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/* Helpers */
|
||||
|
||||
static inline uint32_t spi_getreg(FAR struct stm32_spidev_s *priv, uint32_t offset);
|
||||
static inline void spi_putreg(FAR struct stm32_spidev_s *priv, uint32_t offset,
|
||||
uint32_t value);
|
||||
static inline uint32_t spi_getreg(FAR struct stm32_spidev_s *priv,
|
||||
uint32_t offset);
|
||||
static inline void spi_putreg(FAR struct stm32_spidev_s *priv,
|
||||
uint32_t offset, uint32_t value);
|
||||
static inline uint32_t spi_readword(FAR struct stm32_spidev_s *priv);
|
||||
static inline void spi_writeword(FAR struct stm32_spidev_s *priv, uint32_t byte);
|
||||
static inline void spi_writeword(FAR struct stm32_spidev_s *priv,
|
||||
uint32_t byte);
|
||||
static inline bool spi_9to16bitmode(FAR struct stm32_spidev_s *priv);
|
||||
#ifdef CONFIG_DEBUG_SPI_INFO
|
||||
static inline void spi_dumpregs(FAR struct stm32_spidev_s *priv);
|
||||
|
@ -228,8 +230,10 @@ static void spi_dmarxwait(FAR struct stm32_spidev_s *priv);
|
|||
static void spi_dmatxwait(FAR struct stm32_spidev_s *priv);
|
||||
static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv);
|
||||
static inline void spi_dmatxwakeup(FAR struct stm32_spidev_s *priv);
|
||||
static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg);
|
||||
static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg);
|
||||
static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr,
|
||||
void *arg);
|
||||
static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr,
|
||||
void *arg);
|
||||
static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv,
|
||||
FAR void *rxbuffer,
|
||||
FAR void *rxdummy,
|
||||
|
@ -245,24 +249,27 @@ static inline void spi_dmatxstart(FAR struct stm32_spidev_s *priv);
|
|||
/* SPI methods */
|
||||
|
||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
|
||||
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 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);
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev,
|
||||
spi_hwfeatures_t features);
|
||||
#endif
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd);
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
size_t nwords);
|
||||
#ifdef CONFIG_SPI_TRIGGER
|
||||
static int spi_trigger(FAR struct spi_dev_s *dev);
|
||||
#endif
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
size_t nwords);
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer,
|
||||
size_t nwords);
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, size_t nwords);
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
#endif
|
||||
|
||||
/* Initialization */
|
||||
|
@ -276,9 +283,9 @@ static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain,
|
|||
enum pm_state_e pmstate);
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32H7_SPI1
|
||||
static const struct spi_ops_s g_sp1iops =
|
||||
|
@ -598,11 +605,11 @@ static struct stm32_spidev_s g_spi6dev =
|
|||
};
|
||||
#endif /* CONFIG_STM32H7_SPI6 */
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_getreg8
|
||||
*
|
||||
* Description:
|
||||
|
@ -615,14 +622,15 @@ static struct stm32_spidev_s g_spi6dev =
|
|||
* Returned Value:
|
||||
* The contents of the 8-bit register
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint8_t spi_getreg8(FAR struct stm32_spidev_s *priv, uint32_t offset)
|
||||
static inline uint8_t spi_getreg8(FAR struct stm32_spidev_s *priv,
|
||||
uint32_t offset)
|
||||
{
|
||||
return getreg8(priv->spibase + offset);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_putreg8
|
||||
*
|
||||
* Description:
|
||||
|
@ -633,15 +641,15 @@ static inline uint8_t spi_getreg8(FAR struct stm32_spidev_s *priv, uint32_t offs
|
|||
* offset - offset to the register of interest
|
||||
* value - the 8-bit value to be written
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_putreg8(FAR struct stm32_spidev_s *priv, uint32_t offset,
|
||||
uint8_t value)
|
||||
static inline void spi_putreg8(FAR struct stm32_spidev_s *priv,
|
||||
uint32_t offset, uint8_t value)
|
||||
{
|
||||
putreg8(value, priv->spibase + offset);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_getreg
|
||||
*
|
||||
* Description:
|
||||
|
@ -654,14 +662,15 @@ static inline void spi_putreg8(FAR struct stm32_spidev_s *priv, uint32_t offset,
|
|||
* Returned Value:
|
||||
* The contents of the 16-bit register
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t spi_getreg(FAR struct stm32_spidev_s *priv, uint32_t offset)
|
||||
static inline uint32_t spi_getreg(FAR struct stm32_spidev_s *priv,
|
||||
uint32_t offset)
|
||||
{
|
||||
return getreg32(priv->spibase + offset);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_putreg
|
||||
*
|
||||
* Description:
|
||||
|
@ -675,15 +684,15 @@ static inline uint32_t spi_getreg(FAR struct stm32_spidev_s *priv, uint32_t offs
|
|||
* Returned Value:
|
||||
* The contents of the 16-bit register
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_putreg(FAR struct stm32_spidev_s *priv, uint32_t offset,
|
||||
uint32_t value)
|
||||
static inline void spi_putreg(FAR struct stm32_spidev_s *priv,
|
||||
uint32_t offset, uint32_t value)
|
||||
{
|
||||
putreg32(value, priv->spibase + offset);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_readword
|
||||
*
|
||||
* Description:
|
||||
|
@ -695,7 +704,7 @@ static inline void spi_putreg(FAR struct stm32_spidev_s *priv, uint32_t offset,
|
|||
* Returned Value:
|
||||
* Byte as read
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t spi_readword(FAR struct stm32_spidev_s *priv)
|
||||
{
|
||||
|
@ -708,7 +717,7 @@ static inline uint32_t spi_readword(FAR struct stm32_spidev_s *priv)
|
|||
return spi_getreg(priv, STM32_SPI_RXDR_OFFSET);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_writeword
|
||||
*
|
||||
* Description:
|
||||
|
@ -721,9 +730,10 @@ static inline uint32_t spi_readword(FAR struct stm32_spidev_s *priv)
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_writeword(FAR struct stm32_spidev_s *priv, uint32_t word)
|
||||
static inline void spi_writeword(FAR struct stm32_spidev_s *priv,
|
||||
uint32_t word)
|
||||
{
|
||||
/* Wait until the transmit buffer is empty */
|
||||
|
||||
|
@ -734,7 +744,7 @@ static inline void spi_writeword(FAR struct stm32_spidev_s *priv, uint32_t word)
|
|||
spi_putreg(priv, STM32_SPI_TXDR_OFFSET, word);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_readbyte
|
||||
*
|
||||
* Description:
|
||||
|
@ -746,7 +756,7 @@ static inline void spi_writeword(FAR struct stm32_spidev_s *priv, uint32_t word)
|
|||
* Returned Value:
|
||||
* Byte as read
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint8_t spi_readbyte(FAR struct stm32_spidev_s *priv)
|
||||
{
|
||||
|
@ -759,7 +769,7 @@ static inline uint8_t spi_readbyte(FAR struct stm32_spidev_s *priv)
|
|||
return spi_getreg8(priv, STM32_SPI_RXDR_OFFSET);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_writebyte
|
||||
*
|
||||
* Description:
|
||||
|
@ -772,9 +782,10 @@ static inline uint8_t spi_readbyte(FAR struct stm32_spidev_s *priv)
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_writebyte(FAR struct stm32_spidev_s *priv, uint8_t byte)
|
||||
static inline void spi_writebyte(FAR struct stm32_spidev_s *priv,
|
||||
uint8_t byte)
|
||||
{
|
||||
/* Wait until the transmit buffer is empty */
|
||||
|
||||
|
@ -785,9 +796,9 @@ static inline void spi_writebyte(FAR struct stm32_spidev_s *priv, uint8_t byte)
|
|||
spi_putreg8(priv, STM32_SPI_TXDR_OFFSET, byte);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dumpregs
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_SPI_INFO
|
||||
static void spi_dumpregs(FAR struct stm32_spidev_s *priv)
|
||||
|
@ -803,7 +814,7 @@ static void spi_dumpregs(FAR struct stm32_spidev_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_9to16bitmode
|
||||
*
|
||||
* Description:
|
||||
|
@ -815,7 +826,7 @@ static void spi_dumpregs(FAR struct stm32_spidev_s *priv)
|
|||
* Returned Value:
|
||||
* true: >8 bit mode-bit mode, false: <= 8-bit mode
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline bool spi_9to16bitmode(FAR struct stm32_spidev_s *priv)
|
||||
{
|
||||
|
@ -824,19 +835,19 @@ static inline bool spi_9to16bitmode(FAR struct stm32_spidev_s *priv)
|
|||
return ((regval & SPI_CFG1_CRCSIZE_9BIT) == SPI_CFG1_CRCSIZE_9BIT);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmarxwait
|
||||
*
|
||||
* Description:
|
||||
* Wait for DMA to complete.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32H7_SPI_DMA
|
||||
static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
|
||||
{
|
||||
/* Take the semaphore (perhaps waiting). If the result is zero, then the DMA
|
||||
* must not really have completed???
|
||||
/* Take the semaphore (perhaps waiting). If the result is zero, then the
|
||||
* DMA must not really have completed???
|
||||
*/
|
||||
|
||||
do
|
||||
|
@ -847,19 +858,19 @@ static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmatxwait
|
||||
*
|
||||
* Description:
|
||||
* Wait for DMA to complete.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32H7_SPI_DMA
|
||||
static void spi_dmatxwait(FAR struct stm32_spidev_s *priv)
|
||||
{
|
||||
/* Take the semaphore (perhaps waiting). If the result is zero, then the DMA
|
||||
* must not really have completed???
|
||||
/* Take the semaphore (perhaps waiting). If the result is zero, then the
|
||||
* DMA must not really have completed???
|
||||
*/
|
||||
|
||||
do
|
||||
|
@ -870,13 +881,13 @@ static void spi_dmatxwait(FAR struct stm32_spidev_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmarxwakeup
|
||||
*
|
||||
* Description:
|
||||
* Signal that DMA is complete
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32H7_SPI_DMA
|
||||
static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv)
|
||||
|
@ -885,13 +896,13 @@ static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmatxwakeup
|
||||
*
|
||||
* Description:
|
||||
* Signal that DMA is complete
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32H7_SPI_DMA
|
||||
static inline void spi_dmatxwakeup(FAR struct stm32_spidev_s *priv)
|
||||
|
@ -900,13 +911,13 @@ static inline void spi_dmatxwakeup(FAR struct stm32_spidev_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmarxcallback
|
||||
*
|
||||
* Description:
|
||||
* Called when the RX DMA completes
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32H7_SPI_DMA
|
||||
static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg)
|
||||
|
@ -920,13 +931,13 @@ static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmatxcallback
|
||||
*
|
||||
* Description:
|
||||
* Called when the RX DMA completes
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32H7_SPI_DMA
|
||||
static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg)
|
||||
|
@ -940,17 +951,18 @@ static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmarxsetup
|
||||
*
|
||||
* Description:
|
||||
* Setup to perform RX DMA
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32H7_SPI_DMA
|
||||
static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv, FAR void *rxbuffer,
|
||||
FAR void *rxdummy, size_t nwords)
|
||||
static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv,
|
||||
FAR void *rxbuffer, FAR void *rxdummy,
|
||||
size_t nwords)
|
||||
{
|
||||
stm32_dmacfg_t dmacfg;
|
||||
|
||||
|
@ -997,17 +1009,18 @@ static void spi_dmarxsetup(FAR struct stm32_spidev_s *priv, FAR void *rxbuffer,
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmatxsetup
|
||||
*
|
||||
* Description:
|
||||
* Setup to perform TX DMA
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32H7_SPI_DMA
|
||||
static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv, FAR const void *txbuffer,
|
||||
FAR const void *txdummy, size_t nwords)
|
||||
static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv,
|
||||
FAR const void *txbuffer, FAR const void *txdummy,
|
||||
size_t nwords)
|
||||
{
|
||||
stm32_dmacfg_t dmacfg;
|
||||
|
||||
|
@ -1054,13 +1067,13 @@ static void spi_dmatxsetup(FAR struct stm32_spidev_s *priv, FAR const void *txbu
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmarxstart
|
||||
*
|
||||
* Description:
|
||||
* Start RX DMA
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32H7_SPI_DMA
|
||||
static void spi_dmarxstart(FAR struct stm32_spidev_s *priv)
|
||||
|
@ -1070,13 +1083,13 @@ static void spi_dmarxstart(FAR struct stm32_spidev_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmatxstart
|
||||
*
|
||||
* Description:
|
||||
* Start TX DMA
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32H7_SPI_DMA
|
||||
static void spi_dmatxstart(FAR struct stm32_spidev_s *priv)
|
||||
|
@ -1094,7 +1107,7 @@ static void spi_modifyreg(FAR struct stm32_spidev_s *priv, uint32_t offset,
|
|||
modifyreg32(priv->spibase + offset, clrbits, setbits);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_lock
|
||||
*
|
||||
* Description:
|
||||
|
@ -1113,7 +1126,7 @@ static void spi_modifyreg(FAR struct stm32_spidev_s *priv, uint32_t offset,
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
||||
{
|
||||
|
@ -1132,9 +1145,9 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_enable
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline int spi_enable(FAR struct stm32_spidev_s *priv, bool state)
|
||||
{
|
||||
|
@ -1156,7 +1169,7 @@ static inline int spi_enable(FAR struct stm32_spidev_s *priv, bool state)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_setfrequency
|
||||
*
|
||||
* Description:
|
||||
|
@ -1169,9 +1182,10 @@ static inline int spi_enable(FAR struct stm32_spidev_s *priv, bool state)
|
|||
* Returned Value:
|
||||
* Returns the actual frequency selected
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency)
|
||||
{
|
||||
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
||||
uint32_t setbits = 0;
|
||||
|
@ -1251,8 +1265,8 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
|||
spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, SPI_CFG1_MBR_MASK, setbits);
|
||||
spi_enable(priv, true);
|
||||
|
||||
/* Save the frequency selection so that subsequent reconfigurations will be
|
||||
* faster.
|
||||
/* Save the frequency selection so that subsequent reconfigurations
|
||||
* will be faster.
|
||||
*/
|
||||
|
||||
spiinfo("Frequency %d->%d\n", frequency, actual);
|
||||
|
@ -1264,7 +1278,7 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
|||
return priv->actual;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_setmode
|
||||
*
|
||||
* Description:
|
||||
|
@ -1277,7 +1291,7 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
|||
* Returned Value:
|
||||
* Returns the actual frequency selected
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
||||
{
|
||||
|
@ -1338,7 +1352,8 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
|||
/* Re-enable SPI */
|
||||
|
||||
spi_enable(priv, true);
|
||||
while ((spi_getreg(priv, STM32_SPI_SR_OFFSET) & SPI_SR_RXPLVL_MASK) != 0)
|
||||
while ((spi_getreg(priv, STM32_SPI_SR_OFFSET) &
|
||||
SPI_SR_RXPLVL_MASK) != 0)
|
||||
{
|
||||
/* Flush SPI read FIFO */
|
||||
|
||||
|
@ -1361,7 +1376,7 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
|||
}
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_setbits
|
||||
*
|
||||
* Description:
|
||||
|
@ -1374,7 +1389,7 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
||||
{
|
||||
|
@ -1426,7 +1441,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
|||
}
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_hwfeatures
|
||||
*
|
||||
* Description:
|
||||
|
@ -1440,10 +1455,11 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
|||
* Zero (OK) if the selected H/W features are enabled; A negated errno
|
||||
* value if any H/W feature is not supportable.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev, spi_hwfeatures_t features)
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev,
|
||||
spi_hwfeatures_t features)
|
||||
{
|
||||
#if defined(CONFIG_SPI_BITORDER) || defined(CONFIG_SPI_TRIGGER)
|
||||
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
||||
|
@ -1492,7 +1508,7 @@ static int spi_hwfeatures(FAR struct spi_dev_s *dev, spi_hwfeatures_t features)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_send
|
||||
*
|
||||
* Description:
|
||||
|
@ -1506,9 +1522,9 @@ static int spi_hwfeatures(FAR struct spi_dev_s *dev, spi_hwfeatures_t features)
|
|||
* Returned Value:
|
||||
* response
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
||||
uint32_t regval = 0;
|
||||
|
@ -1525,13 +1541,13 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
spi_modifyreg(priv, STM32_SPI_CR1_OFFSET, 0, SPI_CR1_CSTART);
|
||||
|
||||
/* According to the number of bits, access data register as word or byte
|
||||
* This is absolutely required because of packing. With nbits <=8 bit frames,
|
||||
* two bytes are received by a 16-bit read of the data register!
|
||||
* This is absolutely required because of packing. With nbits <=8 bit
|
||||
* frames, two bytes are received by a 16-bit read of the data register!
|
||||
*/
|
||||
|
||||
if (spi_9to16bitmode(priv))
|
||||
{
|
||||
spi_writeword(priv, wd);
|
||||
spi_writeword(priv, (uint16_t)(wd & 0xffff));
|
||||
ret = spi_readword(priv);
|
||||
}
|
||||
else
|
||||
|
@ -1566,7 +1582,7 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_exchange (no DMA). aka spi_exchange_nodma
|
||||
*
|
||||
* Description:
|
||||
|
@ -1579,12 +1595,13 @@ static uint16_t spi_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_STM32H7_SPI_DMA) || defined(CONFIG_STM32H7_DMACAPABLE) || \
|
||||
defined(CONFIG_STM32H7_SPI_DMATHRESHOLD)
|
||||
|
@ -1592,8 +1609,9 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords)
|
||||
#else
|
||||
static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords)
|
||||
static void spi_exchange_nodma(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
size_t nwords)
|
||||
#endif
|
||||
{
|
||||
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
||||
|
@ -1626,7 +1644,7 @@ static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuff
|
|||
|
||||
/* Exchange one word */
|
||||
|
||||
word = spi_send(dev, word);
|
||||
word = (uint16_t)spi_send(dev, (uint32_t)word);
|
||||
|
||||
/* Is there a buffer to receive the return value? */
|
||||
|
||||
|
@ -1659,7 +1677,7 @@ static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuff
|
|||
|
||||
/* Exchange one word */
|
||||
|
||||
word = (uint8_t)spi_send(dev, (uint16_t)word);
|
||||
word = (uint8_t)spi_send(dev, (uint32_t)word);
|
||||
|
||||
/* Is there a buffer to receive the return value? */
|
||||
|
||||
|
@ -1670,11 +1688,12 @@ static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuff
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_STM32H7_SPI_DMA || CONFIG_STM32H7_DMACAPABLE ||
|
||||
* CONFIG_STM32H7_SPI_DMATHRESHOLD
|
||||
*/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_exchange (with DMA capability)
|
||||
*
|
||||
* Description:
|
||||
|
@ -1687,12 +1706,13 @@ static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuff
|
|||
* nwords - the length of data 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
|
||||
* packed into uint8_t's; if nbits >8, the data is packed into
|
||||
* uint16_t's
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32H7_SPI_DMA
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
|
@ -1763,7 +1783,8 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
buflen = nwords * sizeof(uint16_t);
|
||||
}
|
||||
|
||||
spiinfo("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords);
|
||||
spiinfo("txbuffer=%p rxbuffer=%p nwords=%d\n",
|
||||
txbuffer, rxbuffer, nwords);
|
||||
DEBUGASSERT(priv->spibase != 0);
|
||||
|
||||
/* Setup DMAs */
|
||||
|
@ -1830,7 +1851,7 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
}
|
||||
#endif /* CONFIG_STM32H7_SPI_DMA */
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_trigger
|
||||
*
|
||||
* Description:
|
||||
|
@ -1844,7 +1865,7 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
* ENOTSUP - Trigger not fired due to lack of DMA support
|
||||
* EIO - Trigger not fired because not previously primed
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SPI_TRIGGER
|
||||
static int spi_trigger(FAR struct spi_dev_s *dev)
|
||||
|
@ -1867,7 +1888,7 @@ static int spi_trigger(FAR struct spi_dev_s *dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_sndblock
|
||||
*
|
||||
* Description:
|
||||
|
@ -1876,15 +1897,16 @@ static int spi_trigger(FAR struct spi_dev_s *dev)
|
|||
* Input Parameters:
|
||||
* dev - Device-specific state data
|
||||
* txbuffer - 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
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev,
|
||||
|
@ -1896,7 +1918,7 @@ static void spi_sndblock(FAR struct spi_dev_s *dev,
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_recvblock
|
||||
*
|
||||
* Description:
|
||||
|
@ -1905,15 +1927,16 @@ static void spi_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 spi_recvblock(FAR struct spi_dev_s *dev,
|
||||
|
@ -1925,7 +1948,7 @@ static void spi_recvblock(FAR struct spi_dev_s *dev,
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_pm_prepare
|
||||
*
|
||||
* Description:
|
||||
|
@ -1952,7 +1975,7 @@ static void spi_recvblock(FAR struct spi_dev_s *dev,
|
|||
* power state change). Drivers are not permitted to return non-zero
|
||||
* values when reverting back to higher power consumption modes!
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain,
|
||||
|
@ -2002,7 +2025,7 @@ static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain,
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_bus_initialize
|
||||
*
|
||||
* Description:
|
||||
|
@ -2015,7 +2038,7 @@ static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain,
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_bus_initialize(struct stm32_spidev_s *priv)
|
||||
{
|
||||
|
@ -2029,8 +2052,9 @@ static void spi_bus_initialize(struct stm32_spidev_s *priv)
|
|||
* Mode 0: CFG2.CPHA=0 and CFG2.CPOL=0
|
||||
* Master: CFG2.MSTR=1
|
||||
* 8-bit: CFG1.DSIZE=7
|
||||
* MSB transmitted first: CFG2.LSBFRST=0
|
||||
* Replace NSS with SSI & SSI=1: CR1.SSI=1 CFG2.SSM=1 (prevents MODF error)
|
||||
* MSB transmitted first: CFG2.LSBFRST=0
|
||||
* Replace NSS with SSI & SSI=1: CR1.SSI=1 CFG2.SSM=1 (prevents MODF
|
||||
* error)
|
||||
* Two lines full duplex: CFG2.COMM=0
|
||||
*/
|
||||
|
||||
|
@ -2048,7 +2072,8 @@ static void spi_bus_initialize(struct stm32_spidev_s *priv)
|
|||
|
||||
/* CFG2 */
|
||||
|
||||
clrbits = SPI_CFG2_CPHA | SPI_CFG2_CPOL | SPI_CFG2_LSBFRST | SPI_CFG2_COMM_MASK;
|
||||
clrbits = SPI_CFG2_CPHA | SPI_CFG2_CPOL | SPI_CFG2_LSBFRST |
|
||||
SPI_CFG2_COMM_MASK;
|
||||
setbits = SPI_CFG2_MASTER | SPI_CFG2_SSM;
|
||||
spi_modifyreg(priv, STM32_SPI_CFG2_OFFSET, clrbits, setbits);
|
||||
|
||||
|
@ -2080,19 +2105,20 @@ static void spi_bus_initialize(struct stm32_spidev_s *priv)
|
|||
nxsem_setprotocol(&priv->rxsem, SEM_PRIO_NONE);
|
||||
nxsem_setprotocol(&priv->txsem, SEM_PRIO_NONE);
|
||||
|
||||
/* Get DMA channels. NOTE: stm32_dmachannel() will always assign the DMA channel.
|
||||
* if the channel is not available, then stm32_dmachannel() will block and wait
|
||||
* until the channel becomes available. WARNING: If you have another device sharing
|
||||
* a DMA channel with SPI and the code never releases that channel, then the call
|
||||
* to stm32_dmachannel() will hang forever in this function! Don't let your
|
||||
* design do that!
|
||||
/* Get DMA channels. NOTE: stm32_dmachannel() will always assign the DMA
|
||||
* channel. If the channel is not available, then stm32_dmachannel() will
|
||||
* block and wait until the channel becomes available. WARNING: If you
|
||||
* have another device sharing a DMA channel with SPI and the code never
|
||||
* releases that channel, then the call to stm32_dmachannel() will hang
|
||||
* forever in this function! Don't let your design do that!
|
||||
*/
|
||||
|
||||
priv->rxdma = stm32_dmachannel(priv->rxch);
|
||||
priv->txdma = stm32_dmachannel(priv->txch);
|
||||
DEBUGASSERT(priv->rxdma && priv->txdma);
|
||||
|
||||
spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, 0, SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN);
|
||||
spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, 0,
|
||||
SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN);
|
||||
#endif
|
||||
|
||||
/* Enable SPI */
|
||||
|
@ -2114,11 +2140,11 @@ static void spi_bus_initialize(struct stm32_spidev_s *priv)
|
|||
#endif
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: stm32_spibus_initialize
|
||||
*
|
||||
* Description:
|
||||
|
@ -2130,7 +2156,7 @@ static void spi_bus_initialize(struct stm32_spidev_s *priv)
|
|||
* Returned Value:
|
||||
* Valid SPI device structure reference on success; a NULL on failure
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct spi_dev_s *stm32_spibus_initialize(int bus)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/***************************************************************************
|
||||
* arm/arm/src/stm32h7/stm32_tim.c
|
||||
/****************************************************************************
|
||||
* arch/arm/src/stm32h7/stm32_tim.c
|
||||
*
|
||||
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
||||
* Author: Uros Platise <uros.platise@isotel.eu>
|
||||
|
@ -64,9 +64,9 @@
|
|||
#include "stm32_gpio.h"
|
||||
#include "stm32_tim.h"
|
||||
|
||||
/***************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
***************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
|
@ -274,19 +274,23 @@ struct stm32_tim_priv_s
|
|||
|
||||
/* Timer methods */
|
||||
|
||||
static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t mode);
|
||||
static int stm32_tim_setclock(FAR struct stm32_tim_dev_s *dev, uint32_t freq);
|
||||
static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev,
|
||||
stm32_tim_mode_t mode);
|
||||
static int stm32_tim_setclock(FAR struct stm32_tim_dev_s *dev,
|
||||
uint32_t freq);
|
||||
static void stm32_tim_setperiod(FAR struct stm32_tim_dev_s *dev,
|
||||
uint32_t period);
|
||||
static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
|
||||
stm32_tim_channel_t mode);
|
||||
static int stm32_tim_setcompare(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
|
||||
uint32_t compare);
|
||||
static int stm32_tim_getcapture(FAR struct stm32_tim_dev_s *dev, uint8_t channel);
|
||||
static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev,
|
||||
uint8_t channel, stm32_tim_channel_t mode);
|
||||
static int stm32_tim_setcompare(FAR struct stm32_tim_dev_s *dev,
|
||||
uint8_t channel, uint32_t compare);
|
||||
static int stm32_tim_getcapture(FAR struct stm32_tim_dev_s *dev,
|
||||
uint8_t channel);
|
||||
static int stm32_tim_setisr(FAR struct stm32_tim_dev_s *dev, xcpt_t handler,
|
||||
void *arg, int source);
|
||||
static void stm32_tim_enableint(FAR struct stm32_tim_dev_s *dev, int source);
|
||||
static void stm32_tim_disableint(FAR struct stm32_tim_dev_s *dev, int source);
|
||||
static void stm32_tim_disableint(FAR struct stm32_tim_dev_s *dev,
|
||||
int source);
|
||||
static void stm32_tim_ackint(FAR struct stm32_tim_dev_s *dev, int source);
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1219,6 +1223,7 @@ static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev,
|
|||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/************************************************************************************
|
||||
* arm/arm/src/stm3l42/stm32l4_lptim.c
|
||||
* arch/arm/src/stm3l42/stm32l4_lptim.c
|
||||
*
|
||||
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
||||
* Author: Uros Platise <uros.platise@isotel.eu>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/************************************************************************************
|
||||
* arm/arm/src/stm32l4/stm32l4_spi.c
|
||||
/****************************************************************************
|
||||
* arch/arm/src/stm32l4/stm32l4_spi.c
|
||||
*
|
||||
* Copyright (C) 2009-2013, 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
|
@ -31,40 +31,41 @@
|
|||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* The external functions, stm32l4_spi1/2/3select and stm32l4_spi1/2/3status must be
|
||||
* provided by board-specific logic. They are implementations of the select
|
||||
* and status methods of the SPI interface defined by struct spi_ops_s (see
|
||||
* include/nuttx/spi/spi.h). All other methods (including stm32l4_spibus_initialize())
|
||||
* are provided by common STM32 logic. To use this common SPI logic on your
|
||||
* board:
|
||||
/****************************************************************************
|
||||
* The external functions, stm32l4_spi1/2/3select and stm32l4_spi1/2/3status
|
||||
* must be provided by board-specific logic. They are implementations of the
|
||||
* select and status methods of the SPI interface defined by struct spi_ops_s
|
||||
* (see include/nuttx/spi/spi.h). All other methods (including
|
||||
* stm32l4_spibus_initialize()) are provided by common STM32 logic. To use
|
||||
* this common SPI logic on your board:
|
||||
*
|
||||
* 1. Provide logic in stm32l4_board_initialize() to configure SPI chip select
|
||||
* pins.
|
||||
* 2. Provide stm32l4_spi1/2/3select() and stm32l4_spi1/2/3status() 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 stm32l4_spibus_initialize() in your low level application
|
||||
* initialization logic
|
||||
* 4. The handle returned by stm32l4_spibus_initialize() may then be used to bind
|
||||
* the SPI driver to higher level logic (e.g., calling
|
||||
* 1. Provide logic in stm32l4_board_initialize() to configure SPI chip
|
||||
* select pins.
|
||||
* 2. Provide stm32l4_spi1/2/3select() and stm32l4_spi1/2/3status()
|
||||
* 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 stm32l4_spibus_initialize() in your low level
|
||||
* application initialization logic
|
||||
* 4. The handle returned by stm32l4_spibus_initialize() may then be used
|
||||
* to bind the SPI driver to higher level logic (e.g., calling
|
||||
* mmcsd_spislotinitialize(), for example, will bind the SPI driver to
|
||||
* the SPI MMC/SD driver).
|
||||
*
|
||||
*************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/* This driver is ported from the stm32 one, which only supports 8 and 16 bits
|
||||
* transfers. The STM32L4 family supports frame size from 4 to 16 bits, but we do not
|
||||
* support that yet. For the moment, we replace uses of the CR1_DFF bit with a check
|
||||
* of the CR2_DS[0..3] bits. If the value is SPI_CR2_DS_16BIT it means 16 bits,
|
||||
* else 8 bits.
|
||||
/* This driver is ported from the stm32 one, which only supports 8 and 16
|
||||
* bits transfers. The STM32L4 family supports frame size from 4 to 16 bits,
|
||||
* but we do not support that yet. For the moment, we replace uses of the
|
||||
* CR1_DFF bit with a check of the CR2_DS[0..3] bits. If the value is
|
||||
* SPI_CR2_DS_16BIT it means 16 bits, else 8 bits.
|
||||
*/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
|
@ -95,11 +96,11 @@
|
|||
#if defined(CONFIG_STM32L4_SPI1) || defined(CONFIG_STM32L4_SPI2) || \
|
||||
defined(CONFIG_STM32L4_SPI3)
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ********************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* SPI interrupts */
|
||||
|
||||
|
@ -140,9 +141,9 @@
|
|||
#define SPI_TXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_16BITS |DMA_CCR_DIR)
|
||||
#define SPI_TXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS |DMA_CCR_DIR)
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
struct stm32l4_spidev_s
|
||||
{
|
||||
|
@ -179,17 +180,20 @@ struct stm32l4_spidev_s
|
|||
#endif
|
||||
};
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/* Helpers */
|
||||
|
||||
static inline uint16_t spi_getreg(FAR struct stm32l4_spidev_s *priv, uint8_t offset);
|
||||
static inline void spi_putreg(FAR struct stm32l4_spidev_s *priv, uint8_t offset,
|
||||
static inline uint16_t spi_getreg(FAR struct stm32l4_spidev_s *priv,
|
||||
uint8_t offset);
|
||||
static inline void spi_putreg(FAR struct stm32l4_spidev_s *priv,
|
||||
uint8_t offset,
|
||||
uint16_t value);
|
||||
static inline uint16_t spi_readword(FAR struct stm32l4_spidev_s *priv);
|
||||
static inline void spi_writeword(FAR struct stm32l4_spidev_s *priv, uint16_t byte);
|
||||
static inline void spi_writeword(FAR struct stm32l4_spidev_s *priv,
|
||||
uint16_t byte);
|
||||
static inline bool spi_16bitmode(FAR struct stm32l4_spidev_s *priv);
|
||||
|
||||
/* DMA support */
|
||||
|
@ -199,8 +203,10 @@ static void spi_dmarxwait(FAR struct stm32l4_spidev_s *priv);
|
|||
static void spi_dmatxwait(FAR struct stm32l4_spidev_s *priv);
|
||||
static inline void spi_dmarxwakeup(FAR struct stm32l4_spidev_s *priv);
|
||||
static inline void spi_dmatxwakeup(FAR struct stm32l4_spidev_s *priv);
|
||||
static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg);
|
||||
static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg);
|
||||
static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr,
|
||||
void *arg);
|
||||
static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr,
|
||||
void *arg);
|
||||
static void spi_dmarxsetup(FAR struct stm32l4_spidev_s *priv,
|
||||
FAR void *rxbuffer,
|
||||
FAR void *rxdummy,
|
||||
|
@ -216,24 +222,27 @@ static inline void spi_dmatxstart(FAR struct stm32l4_spidev_s *priv);
|
|||
/* SPI methods */
|
||||
|
||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
|
||||
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 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);
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev,
|
||||
spi_hwfeatures_t features);
|
||||
#endif
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd);
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
size_t nwords);
|
||||
#ifdef CONFIG_SPI_TRIGGER
|
||||
static int spi_trigger(FAR struct spi_dev_s *dev);
|
||||
#endif
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
size_t nwords);
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer,
|
||||
size_t nwords);
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, size_t nwords);
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
#endif
|
||||
|
||||
/* Initialization */
|
||||
|
@ -247,9 +256,9 @@ static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain,
|
|||
enum pm_state_e pmstate);
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32L4_SPI1
|
||||
static const struct spi_ops_s g_spi1ops =
|
||||
|
@ -412,11 +421,11 @@ static struct stm32l4_spidev_s g_spi3dev =
|
|||
};
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_getreg
|
||||
*
|
||||
* Description:
|
||||
|
@ -429,14 +438,15 @@ static struct stm32l4_spidev_s g_spi3dev =
|
|||
* Returned Value:
|
||||
* The contents of the 16-bit register
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint16_t spi_getreg(FAR struct stm32l4_spidev_s *priv, uint8_t offset)
|
||||
static inline uint16_t spi_getreg(FAR struct stm32l4_spidev_s *priv,
|
||||
uint8_t offset)
|
||||
{
|
||||
return getreg16(priv->spibase + offset);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_putreg
|
||||
*
|
||||
* Description:
|
||||
|
@ -450,15 +460,15 @@ static inline uint16_t spi_getreg(FAR struct stm32l4_spidev_s *priv, uint8_t off
|
|||
* Returned Value:
|
||||
* The contents of the 16-bit register
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_putreg(FAR struct stm32l4_spidev_s *priv, uint8_t offset,
|
||||
uint16_t value)
|
||||
static inline void spi_putreg(FAR struct stm32l4_spidev_s *priv,
|
||||
uint8_t offset, uint16_t value)
|
||||
{
|
||||
putreg16(value, priv->spibase + offset);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_getreg8
|
||||
*
|
||||
* Description:
|
||||
|
@ -471,14 +481,15 @@ static inline void spi_putreg(FAR struct stm32l4_spidev_s *priv, uint8_t offset,
|
|||
* Returned Value:
|
||||
* The contents of the 8-bit register
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint8_t spi_getreg8(FAR struct stm32l4_spidev_s *priv, uint8_t offset)
|
||||
static inline uint8_t spi_getreg8(FAR struct stm32l4_spidev_s *priv,
|
||||
uint8_t offset)
|
||||
{
|
||||
return getreg8(priv->spibase + offset);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_putreg8
|
||||
*
|
||||
* Description:
|
||||
|
@ -489,15 +500,15 @@ static inline uint8_t spi_getreg8(FAR struct stm32l4_spidev_s *priv, uint8_t off
|
|||
* offset - offset to the register of interest
|
||||
* value - the 8-bit value to be written
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_putreg8(FAR struct stm32l4_spidev_s *priv, uint8_t offset,
|
||||
uint8_t value)
|
||||
static inline void spi_putreg8(FAR struct stm32l4_spidev_s *priv,
|
||||
uint8_t offset, uint8_t value)
|
||||
{
|
||||
putreg8(value, priv->spibase + offset);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_readword
|
||||
*
|
||||
* Description:
|
||||
|
@ -509,7 +520,7 @@ static inline void spi_putreg8(FAR struct stm32l4_spidev_s *priv, uint8_t offset
|
|||
* Returned Value:
|
||||
* Word as read
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint16_t spi_readword(FAR struct stm32l4_spidev_s *priv)
|
||||
{
|
||||
|
@ -522,7 +533,7 @@ static inline uint16_t spi_readword(FAR struct stm32l4_spidev_s *priv)
|
|||
return spi_getreg(priv, STM32L4_SPI_DR_OFFSET);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_readbyte
|
||||
*
|
||||
* Description:
|
||||
|
@ -534,7 +545,7 @@ static inline uint16_t spi_readword(FAR struct stm32l4_spidev_s *priv)
|
|||
* Returned Value:
|
||||
* Byte as read
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint8_t spi_readbyte(FAR struct stm32l4_spidev_s *priv)
|
||||
{
|
||||
|
@ -547,7 +558,7 @@ static inline uint8_t spi_readbyte(FAR struct stm32l4_spidev_s *priv)
|
|||
return spi_getreg8(priv, STM32L4_SPI_DR_OFFSET);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_writeword
|
||||
*
|
||||
* Description:
|
||||
|
@ -560,9 +571,10 @@ static inline uint8_t spi_readbyte(FAR struct stm32l4_spidev_s *priv)
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_writeword(FAR struct stm32l4_spidev_s *priv, uint16_t word)
|
||||
static inline void spi_writeword(FAR struct stm32l4_spidev_s *priv,
|
||||
uint16_t word)
|
||||
{
|
||||
/* Wait until the transmit buffer is empty */
|
||||
|
||||
|
@ -573,7 +585,7 @@ static inline void spi_writeword(FAR struct stm32l4_spidev_s *priv, uint16_t wor
|
|||
spi_putreg(priv, STM32L4_SPI_DR_OFFSET, word);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_writebyte
|
||||
*
|
||||
* Description:
|
||||
|
@ -586,9 +598,10 @@ static inline void spi_writeword(FAR struct stm32l4_spidev_s *priv, uint16_t wor
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline void spi_writebyte(FAR struct stm32l4_spidev_s *priv, uint8_t byte)
|
||||
static inline void spi_writebyte(FAR struct stm32l4_spidev_s *priv,
|
||||
uint8_t byte)
|
||||
{
|
||||
/* Wait until the transmit buffer is empty */
|
||||
|
||||
|
@ -599,7 +612,7 @@ static inline void spi_writebyte(FAR struct stm32l4_spidev_s *priv, uint8_t byte
|
|||
spi_putreg8(priv, STM32L4_SPI_DR_OFFSET, byte);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_16bitmode
|
||||
*
|
||||
* Description:
|
||||
|
@ -611,26 +624,26 @@ static inline void spi_writebyte(FAR struct stm32l4_spidev_s *priv, uint8_t byte
|
|||
* Returned Value:
|
||||
* true: 16-bit mode, false: 8-bit mode
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static inline bool spi_16bitmode(FAR struct stm32l4_spidev_s *priv)
|
||||
{
|
||||
return (priv->nbits > 8);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmarxwaitw
|
||||
*
|
||||
* Description:
|
||||
* Wait for DMA to complete.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32L4_SPI_DMA
|
||||
static void spi_dmarxwait(FAR struct stm32l4_spidev_s *priv)
|
||||
{
|
||||
/* Take the semaphore (perhaps waiting). If the result is zero, then the DMA
|
||||
* must not really have completed???
|
||||
/* Take the semaphore (perhaps waiting). If the result is zero, then the
|
||||
* DMA must not really have completed???
|
||||
*/
|
||||
|
||||
do
|
||||
|
@ -641,19 +654,19 @@ static void spi_dmarxwait(FAR struct stm32l4_spidev_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmatxwait
|
||||
*
|
||||
* Description:
|
||||
* Wait for DMA to complete.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32L4_SPI_DMA
|
||||
static void spi_dmatxwait(FAR struct stm32l4_spidev_s *priv)
|
||||
{
|
||||
/* Take the semaphore (perhaps waiting). If the result is zero, then the DMA
|
||||
* must not really have completed???
|
||||
/* Take the semaphore (perhaps waiting). If the result is zero, then the
|
||||
* DMA must not really have completed???
|
||||
*/
|
||||
|
||||
do
|
||||
|
@ -664,13 +677,13 @@ static void spi_dmatxwait(FAR struct stm32l4_spidev_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmarxwakeup
|
||||
*
|
||||
* Description:
|
||||
* Signal that DMA is complete
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32L4_SPI_DMA
|
||||
static inline void spi_dmarxwakeup(FAR struct stm32l4_spidev_s *priv)
|
||||
|
@ -679,13 +692,13 @@ static inline void spi_dmarxwakeup(FAR struct stm32l4_spidev_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmatxwakeup
|
||||
*
|
||||
* Description:
|
||||
* Signal that DMA is complete
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32L4_SPI_DMA
|
||||
static inline void spi_dmatxwakeup(FAR struct stm32l4_spidev_s *priv)
|
||||
|
@ -694,13 +707,13 @@ static inline void spi_dmatxwakeup(FAR struct stm32l4_spidev_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmarxcallback
|
||||
*
|
||||
* Description:
|
||||
* Called when the RX DMA completes
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32L4_SPI_DMA
|
||||
static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg)
|
||||
|
@ -714,13 +727,13 @@ static void spi_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmatxcallback
|
||||
*
|
||||
* Description:
|
||||
* Called when the RX DMA completes
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32L4_SPI_DMA
|
||||
static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg)
|
||||
|
@ -734,17 +747,18 @@ static void spi_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmarxsetup
|
||||
*
|
||||
* Description:
|
||||
* Setup to perform RX DMA
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32L4_SPI_DMA
|
||||
static void spi_dmarxsetup(FAR struct stm32l4_spidev_s *priv, FAR void *rxbuffer,
|
||||
FAR void *rxdummy, size_t nwords)
|
||||
static void spi_dmarxsetup(FAR struct stm32l4_spidev_s *priv,
|
||||
FAR void *rxbuffer, FAR void *rxdummy,
|
||||
size_t nwords)
|
||||
{
|
||||
/* 8- or 16-bit mode? */
|
||||
|
||||
|
@ -784,13 +798,13 @@ static void spi_dmarxsetup(FAR struct stm32l4_spidev_s *priv, FAR void *rxbuffer
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmatxsetup
|
||||
*
|
||||
* Description:
|
||||
* Setup to perform TX DMA
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32L4_SPI_DMA
|
||||
static void spi_dmatxsetup(FAR struct stm32l4_spidev_s *priv,
|
||||
|
@ -836,13 +850,13 @@ static void spi_dmatxsetup(FAR struct stm32l4_spidev_s *priv,
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmarxstart
|
||||
*
|
||||
* Description:
|
||||
* Start RX DMA
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32L4_SPI_DMA
|
||||
static inline void spi_dmarxstart(FAR struct stm32l4_spidev_s *priv)
|
||||
|
@ -852,13 +866,13 @@ static inline void spi_dmarxstart(FAR struct stm32l4_spidev_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_dmatxstart
|
||||
*
|
||||
* Description:
|
||||
* Start TX DMA
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32L4_SPI_DMA
|
||||
static inline void spi_dmatxstart(FAR struct stm32l4_spidev_s *priv)
|
||||
|
@ -868,7 +882,7 @@ static inline void spi_dmatxstart(FAR struct stm32l4_spidev_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_modifycr
|
||||
*
|
||||
* Description:
|
||||
|
@ -882,7 +896,7 @@ static inline void spi_dmatxstart(FAR struct stm32l4_spidev_s *priv)
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_modifycr(uint32_t addr, FAR struct stm32l4_spidev_s *priv,
|
||||
uint16_t setbits, uint16_t clrbits)
|
||||
|
@ -895,7 +909,7 @@ static void spi_modifycr(uint32_t addr, FAR struct stm32l4_spidev_s *priv,
|
|||
spi_putreg(priv, addr, cr);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_lock
|
||||
*
|
||||
* Description:
|
||||
|
@ -914,7 +928,7 @@ static void spi_modifycr(uint32_t addr, FAR struct stm32l4_spidev_s *priv,
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
||||
{
|
||||
|
@ -933,7 +947,7 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_setfrequency
|
||||
*
|
||||
* Description:
|
||||
|
@ -946,9 +960,10 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
|||
* Returned Value:
|
||||
* Returns the actual frequency selected
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency)
|
||||
{
|
||||
FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev;
|
||||
uint16_t setbits;
|
||||
|
@ -1028,8 +1043,8 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
|||
spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, setbits, SPI_CR1_BR_MASK);
|
||||
spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, SPI_CR1_SPE, 0);
|
||||
|
||||
/* Save the frequency selection so that subsequent reconfigurations will be
|
||||
* faster.
|
||||
/* Save the frequency selection so that subsequent reconfigurations
|
||||
* will be faster.
|
||||
*/
|
||||
|
||||
spiinfo("Frequency %d->%d\n", frequency, actual);
|
||||
|
@ -1041,7 +1056,7 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
|||
return priv->actual;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_setmode
|
||||
*
|
||||
* Description:
|
||||
|
@ -1054,7 +1069,7 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
|||
* Returned Value:
|
||||
* Returns the actual frequency selected
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
||||
{
|
||||
|
@ -1106,12 +1121,12 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
|||
}
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_setbits
|
||||
*
|
||||
* Description:
|
||||
* Set the number of bits per word. With STM32L4, this is not restricted to 8 or 16,
|
||||
* but can be any value between 4 and 16.
|
||||
* Set the number of bits per word. With STM32L4, this is not restricted to
|
||||
* 8 or 16, but can be any value between 4 and 16.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Device-specific state data
|
||||
|
@ -1120,7 +1135,7 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
||||
{
|
||||
|
@ -1188,7 +1203,8 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev, spi_hwfeatures_t features)
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev,
|
||||
spi_hwfeatures_t features)
|
||||
{
|
||||
#if defined(CONFIG_SPI_BITORDER) || defined(CONFIG_SPI_TRIGGER)
|
||||
FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev;
|
||||
|
@ -1237,7 +1253,7 @@ static int spi_hwfeatures(FAR struct spi_dev_s *dev, spi_hwfeatures_t features)
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_send
|
||||
*
|
||||
* Description:
|
||||
|
@ -1251,13 +1267,13 @@ static int spi_hwfeatures(FAR struct spi_dev_s *dev, spi_hwfeatures_t features)
|
|||
* Returned Value:
|
||||
* response
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev;
|
||||
uint32_t regval;
|
||||
uint16_t ret;
|
||||
uint32_t ret;
|
||||
|
||||
DEBUGASSERT(priv && priv->spibase);
|
||||
|
||||
|
@ -1268,13 +1284,13 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
|
||||
if (spi_16bitmode(priv))
|
||||
{
|
||||
spi_writeword(priv, wd);
|
||||
ret = spi_readword(priv);
|
||||
spi_writeword(priv, (uint16_t)(wd & 0xffff));
|
||||
ret = (uint32_t)spi_readword(priv);
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_writebyte(priv, (uint8_t)(wd & 0xff));
|
||||
ret = (uint16_t)spi_readbyte(priv);
|
||||
ret = (uint32_t)spi_readbyte(priv);
|
||||
}
|
||||
|
||||
/* Check and clear any error flags (Reading from the SR clears the error
|
||||
|
@ -1296,7 +1312,7 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_exchange (no DMA). aka spi_exchange_nodma
|
||||
*
|
||||
* Description:
|
||||
|
@ -1309,20 +1325,22 @@ static uint16_t spi_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_STM32L4_SPI_DMA) || defined(CONFIG_STM32L4_DMACAPABLE)
|
||||
#if !defined(CONFIG_STM32L4_SPI_DMA)
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords)
|
||||
#else
|
||||
static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords)
|
||||
static void spi_exchange_nodma(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
size_t nwords)
|
||||
#endif
|
||||
{
|
||||
FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev;
|
||||
|
@ -1355,7 +1373,7 @@ static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuff
|
|||
|
||||
/* Exchange one word */
|
||||
|
||||
word = spi_send(dev, word);
|
||||
word = (uint16_t)spi_send(dev, (uint32_t)word);
|
||||
|
||||
/* Is there a buffer to receive the return value? */
|
||||
|
||||
|
@ -1388,7 +1406,7 @@ static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuff
|
|||
|
||||
/* Exchange one word */
|
||||
|
||||
word = (uint8_t)spi_send(dev, (uint16_t)word);
|
||||
word = (uint8_t)spi_send(dev, (uint32_t)word);
|
||||
|
||||
/* Is there a buffer to receive the return value? */
|
||||
|
||||
|
@ -1414,12 +1432,13 @@ static void spi_exchange_nodma(FAR struct spi_dev_s *dev, FAR const void *txbuff
|
|||
* nwords - the length of data 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
|
||||
* packed into uint8_t's; if nbits >8, the data is packed into
|
||||
* uint16_t's
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32L4_SPI_DMA
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
|
@ -1428,8 +1447,10 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev;
|
||||
|
||||
#ifdef CONFIG_STM32L4_DMACAPABLE
|
||||
if ((txbuffer && !stm32l4_dmacapable((uint32_t)txbuffer, nwords, priv->txccr)) ||
|
||||
(rxbuffer && !stm32l4_dmacapable((uint32_t)rxbuffer, nwords, priv->rxccr)))
|
||||
if ((txbuffer &&
|
||||
!stm32l4_dmacapable((uint32_t)txbuffer, nwords, priv->txccr)) ||
|
||||
(rxbuffer &&
|
||||
!stm32l4_dmacapable((uint32_t)rxbuffer, nwords, priv->rxccr)))
|
||||
{
|
||||
/* Unsupported memory region, fall back to non-DMA method. */
|
||||
|
||||
|
@ -1441,7 +1462,8 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
static uint16_t rxdummy = 0xffff;
|
||||
static const uint16_t txdummy = 0xffff;
|
||||
|
||||
spiinfo("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords);
|
||||
spiinfo("txbuffer=%p rxbuffer=%p nwords=%d\n",
|
||||
txbuffer, rxbuffer, nwords);
|
||||
DEBUGASSERT(priv && priv->spibase);
|
||||
|
||||
/* Setup DMAs */
|
||||
|
@ -1530,15 +1552,16 @@ static int spi_trigger(FAR struct spi_dev_s *dev)
|
|||
* Input Parameters:
|
||||
* dev - Device-specific state data
|
||||
* txbuffer - 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
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev,
|
||||
|
@ -1550,7 +1573,7 @@ static void spi_sndblock(FAR struct spi_dev_s *dev,
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_recvblock
|
||||
*
|
||||
* Description:
|
||||
|
@ -1559,15 +1582,16 @@ static void spi_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 spi_recvblock(FAR struct spi_dev_s *dev,
|
||||
|
@ -1579,7 +1603,7 @@ static void spi_recvblock(FAR struct spi_dev_s *dev,
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_pm_prepare
|
||||
*
|
||||
* Description:
|
||||
|
@ -1606,15 +1630,14 @@ static void spi_recvblock(FAR struct spi_dev_s *dev,
|
|||
* power state change). Drivers are not permitted to return non-zero
|
||||
* values when reverting back to higher power consumption modes!
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain,
|
||||
enum pm_state_e pmstate)
|
||||
{
|
||||
struct stm32l4_spidev_s *priv =
|
||||
(struct stm32l4_spidev_s *)((char *)cb -
|
||||
offsetof(struct stm32l4_spidev_s, pm_cb));
|
||||
struct stm32l4_spidev_s *priv = (struct stm32l4_spidev_s *)((char *)cb -
|
||||
offsetof(struct stm32l4_spidev_s, pm_cb));
|
||||
int sval;
|
||||
|
||||
/* Logic to prepare for a reduced power state goes here. */
|
||||
|
@ -1656,7 +1679,7 @@ static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain,
|
|||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: spi_bus_initialize
|
||||
*
|
||||
* Description:
|
||||
|
@ -1669,7 +1692,7 @@ static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain,
|
|||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_bus_initialize(FAR struct stm32l4_spidev_s *priv)
|
||||
{
|
||||
|
@ -1683,14 +1706,16 @@ static void spi_bus_initialize(FAR struct stm32l4_spidev_s *priv)
|
|||
* Mode 0: CR1.CPHA=0 and CR1.CPOL=0
|
||||
* Master: CR1.MSTR=1
|
||||
* 8-bit: CR2.DS=7
|
||||
* MSB transmitted first: CR1.LSBFIRST=0
|
||||
* Replace NSS with SSI & SSI=1: CR1.SSI=1 CR1.SSM=1 (prevents MODF error)
|
||||
* Two lines full duplex: CR1.BIDIMODE=0 CR1.BIDIOIE=(Don't care) and
|
||||
* CR1.RXONLY=0
|
||||
* MSB transmitted first: CR1.LSBFIRST=0
|
||||
* Replace NSS with SSI & SSI=1: CR1.SSI=1 CR1.SSM=1 (prevents MODF
|
||||
* error)
|
||||
* Two lines full duplex: CR1.BIDIMODE=0 CR1.BIDIOIE=(Don't care)
|
||||
* and CR1.RXONLY=0
|
||||
*/
|
||||
|
||||
clrbits = SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_BR_MASK | SPI_CR1_LSBFIRST |
|
||||
SPI_CR1_RXONLY | SPI_CR1_BIDIOE | SPI_CR1_BIDIMODE;
|
||||
clrbits = SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_BR_MASK |
|
||||
SPI_CR1_LSBFIRST | SPI_CR1_RXONLY | SPI_CR1_BIDIOE |
|
||||
SPI_CR1_BIDIMODE;
|
||||
setbits = SPI_CR1_MSTR | SPI_CR1_SSI | SPI_CR1_SSM;
|
||||
spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, setbits, clrbits);
|
||||
|
||||
|
@ -1727,19 +1752,20 @@ static void spi_bus_initialize(FAR struct stm32l4_spidev_s *priv)
|
|||
nxsem_setprotocol(&priv->rxsem, SEM_PRIO_NONE);
|
||||
nxsem_setprotocol(&priv->txsem, SEM_PRIO_NONE);
|
||||
|
||||
/* Get DMA channels. NOTE: stm32l4_dmachannel() will always assign the DMA channel.
|
||||
* if the channel is not available, then stm32l4_dmachannel() will block and wait
|
||||
* until the channel becomes available. WARNING: If you have another device sharing
|
||||
* a DMA channel with SPI and the code never releases that channel, then the call
|
||||
* to stm32l4_dmachannel() will hang forever in this function! Don't let your
|
||||
* design do that!
|
||||
/* Get DMA channels. NOTE: stm32l4_dmachannel() will always assign the DMA
|
||||
* channel. If the channel is not available, then stm32l4_dmachannel()
|
||||
* will block and wait until the channel becomes available. WARNING: If
|
||||
* you have another device sharing a DMA channel with SPI and the code
|
||||
* never releases that channel, then the call to stm32l4_dmachannel() will
|
||||
* hang forever in this function! Don't let your design do that!
|
||||
*/
|
||||
|
||||
priv->rxdma = stm32l4_dmachannel(priv->rxch);
|
||||
priv->txdma = stm32l4_dmachannel(priv->txch);
|
||||
DEBUGASSERT(priv->rxdma && priv->txdma);
|
||||
|
||||
spi_modifycr(STM32L4_SPI_CR2_OFFSET, priv, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN, 0);
|
||||
spi_modifycr(STM32L4_SPI_CR2_OFFSET, priv,
|
||||
SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN, 0);
|
||||
#endif
|
||||
|
||||
/* Enable spi */
|
||||
|
@ -1755,11 +1781,11 @@ static void spi_bus_initialize(FAR struct stm32l4_spidev_s *priv)
|
|||
#endif
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: stm32l4_spibus_initialize
|
||||
*
|
||||
* Description:
|
||||
|
@ -1771,7 +1797,7 @@ static void spi_bus_initialize(FAR struct stm32l4_spidev_s *priv)
|
|||
* Returned Value:
|
||||
* Valid SPI device structure reference on success; a NULL on failure
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct spi_dev_s *stm32l4_spibus_initialize(int bus)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/************************************************************************************
|
||||
* arm/arm/src/stm32l4/stm32l4_tim.c
|
||||
* arch/arm/src/stm32l4/stm32l4_tim.c
|
||||
*
|
||||
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
||||
* Author: Uros Platise <uros.platise@isotel.eu>
|
||||
|
@ -68,6 +68,7 @@
|
|||
************************************************************************************/
|
||||
|
||||
/* Configuration ********************************************************************/
|
||||
|
||||
/* Timer devices may be used for different purposes. Such special purposes include:
|
||||
*
|
||||
* - To generate modulated outputs for such things as motor control. If
|
||||
|
@ -208,8 +209,8 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/* This module then only compiles if there are enabled timers that are not intended for
|
||||
* some other purpose.
|
||||
/* This module then only compiles if there are enabled timers that are not
|
||||
* intended for some other purpose.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_STM32L4_TIM1) || defined(CONFIG_STM32L4_TIM2) || \
|
||||
|
@ -604,7 +605,9 @@ static int stm32l4_tim_setmode(FAR struct stm32l4_tim_dev_s *dev,
|
|||
|
||||
case STM32L4_TIM_MODE_UPDOWN:
|
||||
val |= ATIM_CR1_CENTER1;
|
||||
// Our default: Interrupts are generated on compare, when counting down
|
||||
|
||||
/* Our default: Interrupts are generated on compare, when counting down */
|
||||
|
||||
break;
|
||||
|
||||
case STM32L4_TIM_MODE_PULSE:
|
||||
|
@ -892,10 +895,10 @@ static uint32_t stm32l4_tim_getcounter(FAR struct stm32l4_tim_dev_s *dev)
|
|||
return counter;
|
||||
|
||||
default:
|
||||
return counter & 0x0000FFFF;
|
||||
return counter & 0x0000ffff;
|
||||
}
|
||||
#else
|
||||
return counter & 0x0000FFFF;
|
||||
return counter & 0x0000ffff;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -951,7 +954,8 @@ static int stm32l4_tim_setchannel(FAR struct stm32l4_tim_dev_s *dev,
|
|||
break;
|
||||
|
||||
case STM32L4_TIM_CH_OUTPWM:
|
||||
ccmr_val = (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC1M_SHIFT) + ATIM_CCMR1_OC1PE;
|
||||
ccmr_val = (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC1M_SHIFT) +
|
||||
ATIM_CCMR1_OC1PE;
|
||||
ccer_val |= ATIM_CCER_CC1E << (channel << 2);
|
||||
break;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/tiva/common/tiva_ssi.c
|
||||
*
|
||||
* Copyright (C) 2009-2010, 2014, 2016-2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2009-2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -75,8 +75,8 @@
|
|||
#endif
|
||||
|
||||
/* How many SSI modules does this chip support? The LM3S6918 supports 2 SSI
|
||||
* modules, the LM3S6965 and LM3S8962 support 1 module (others may support more than 2-- in
|
||||
* such case, the following must be expanded).
|
||||
* modules, the LM3S6965 and LM3S8962 support 1 module (others may support
|
||||
* more than 2-- in such case, the following must be expanded).
|
||||
*/
|
||||
|
||||
#if TIVA_NSSI < 1
|
||||
|
@ -229,9 +229,9 @@ struct tiva_ssidev_s
|
|||
/* SSI register access */
|
||||
|
||||
static inline uint32_t ssi_getreg(struct tiva_ssidev_s *priv,
|
||||
unsigned int offset);
|
||||
static inline void ssi_putreg(struct tiva_ssidev_s *priv, unsigned int offset,
|
||||
uint32_t value);
|
||||
unsigned int offset);
|
||||
static inline void ssi_putreg(struct tiva_ssidev_s *priv,
|
||||
unsigned int offset, uint32_t value);
|
||||
|
||||
/* Misc helpers */
|
||||
|
||||
|
@ -281,7 +281,7 @@ static void ssi_setmodeinternal(struct tiva_ssidev_s *priv,
|
|||
static void ssi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
|
||||
static void ssi_setbitsinternal(struct tiva_ssidev_s *priv, int nbits);
|
||||
static void ssi_setbits(FAR struct spi_dev_s *dev, int nbits);
|
||||
static uint16_t ssi_send(FAR struct spi_dev_s *dev, uint16_t wd);
|
||||
static uint32_t ssi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
#ifdef CONFIG_SPI_EXCHANGE
|
||||
static void ssi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
|
@ -434,8 +434,8 @@ static inline void ssi_putreg(struct tiva_ssidev_s *priv,
|
|||
* Name: ssi_disable
|
||||
*
|
||||
* Description:
|
||||
* Disable SSI operation. NOTE: The SSI must be disabled before any control
|
||||
* registers can be re-programmed.
|
||||
* Disable SSI operation. NOTE: The SSI must be disabled before any
|
||||
* control registers can be re-programmed.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - Device-specific state data
|
||||
|
@ -511,10 +511,10 @@ static void ssi_semtake(sem_t *sem)
|
|||
* Name: ssi_txnull, ssi_txuint16, and ssi_txuint8
|
||||
*
|
||||
* Description:
|
||||
* Transfer all ones, a uint8_t, or uint16_t to Tx FIFO and update the txbuffer
|
||||
* pointer appropriately. The selected function dependes on (1) if there
|
||||
* is a source txbuffer provided, and (2) if the number of bits per
|
||||
* word is <=8 or >8.
|
||||
* Transfer all ones, a uint8_t, or uint16_t to Tx FIFO and update the
|
||||
* txbuffer pointer appropriately. The selected function dependes on (1)
|
||||
* if there is a source txbuffer provided, and (2) if the number of bits
|
||||
* per word is <=8 or >8.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - Device-specific state data
|
||||
|
@ -656,6 +656,7 @@ static inline int ssi_performtx(struct tiva_ssidev_s *priv)
|
|||
priv->ntxwords--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -684,7 +685,9 @@ static int ssi_performtx(struct tiva_ssidev_s *priv)
|
|||
* FIFO to CONFIG_SSI_TXLIMIT. Otherwise, we could
|
||||
* overrun the Rx FIFO on a very fast SSI bus.
|
||||
*/
|
||||
for (; ntxd < priv->ntxwords && ntxd < CONFIG_SSI_TXLIMIT && !ssi_txfifofull(priv); ntxd++)
|
||||
|
||||
for (; ntxd < priv->ntxwords && ntxd < CONFIG_SSI_TXLIMIT &&
|
||||
!ssi_txfifofull(priv); ntxd++)
|
||||
#else
|
||||
for (; ntxd < priv->ntxwords && !ssi_txfifofull(priv); ntxd++)
|
||||
#endif
|
||||
|
@ -721,9 +724,11 @@ static int ssi_performtx(struct tiva_ssidev_s *priv)
|
|||
|
||||
regval &= ~(SSI_IM_TX | SSI_RIS_ROR);
|
||||
}
|
||||
|
||||
ssi_putreg(priv, TIVA_SSI_IM_OFFSET, regval);
|
||||
#endif /* CONFIG_SSI_POLLWAIT */
|
||||
}
|
||||
|
||||
return ntxd;
|
||||
}
|
||||
|
||||
|
@ -794,6 +799,7 @@ static inline void ssi_performrx(struct tiva_ssidev_s *priv)
|
|||
|
||||
regval &= ~(SSI_IM_RX | SSI_IM_RT);
|
||||
}
|
||||
|
||||
ssi_putreg(priv, TIVA_SSI_IM_OFFSET, regval);
|
||||
#endif /* CONFIG_SSI_POLLWAIT */
|
||||
}
|
||||
|
@ -809,9 +815,9 @@ static inline void ssi_performrx(struct tiva_ssidev_s *priv)
|
|||
* txbuffer - The buffer of data to send to the device (may be NULL).
|
||||
* rxbuffer - The buffer to receive data from the device (may be NULL).
|
||||
* nwords - The total number of words to be exchanged. If the interface
|
||||
* uses <= 8 bits per word, then this is the number of uint8_t's;
|
||||
* if the interface uses >8 bits per word, then this is the
|
||||
* number of uint16_t's
|
||||
* uses <= 8 bits per word, then this is the number of
|
||||
* uint8_t's; if the interface uses >8 bits per word, then this
|
||||
* is the number of uint16_t's
|
||||
*
|
||||
* Returned Value:
|
||||
* 0: success, <0:Negated error number on failure
|
||||
|
@ -987,9 +993,9 @@ static inline struct tiva_ssidev_s *ssi_mapirq(int irq)
|
|||
* txbuffer - The buffer of data to send to the device (may be NULL).
|
||||
* rxbuffer - The buffer to receive data from the device (may be NULL).
|
||||
* nwords - The total number of words to be exchanged. If the interface
|
||||
* uses <= 8 bits per word, then this is the number of uint8_t's;
|
||||
* if the interface uses >8 bits per word, then this is the
|
||||
* number of uint16_t's
|
||||
* uses <= 8 bits per word, then this is the number of
|
||||
* uint8_t's; if the interface uses >8 bits per word, then this
|
||||
* is the number of uint16_t's
|
||||
*
|
||||
* Returned Value:
|
||||
* 0: success, <0:Negated error number on failure
|
||||
|
@ -1127,25 +1133,25 @@ static uint32_t ssi_setfrequencyinternal(struct tiva_ssidev_s *priv,
|
|||
{
|
||||
/* "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
|
||||
* (SSI_CPSR) register ... The clock is further divided by a value
|
||||
* from 1 to 256, which is 1 + SCR, where SCR is the value programmed
|
||||
* i n the SSI Control0 (SSICR0) register ...
|
||||
* CPSDVSR from 2 to 254, which is programmed in the SSI Clock
|
||||
* Prescale (SSI_CPSR) register ... The clock is further divided by
|
||||
* a value from 1 to 256, which is 1 + SCR, where SCR is the value
|
||||
* programmed in the SSI Control0 (SSICR0) register ...
|
||||
*
|
||||
* "The frequency of the output clock SSIClk is defined by:
|
||||
*
|
||||
* "SSIClk = FSysClk / (CPSDVSR * (1 + SCR))
|
||||
*
|
||||
* "Note: Although the SSIClk transmit clock can theoretically be 25 MHz,
|
||||
* the module may not be able to operate at that speed. For master mode,
|
||||
* the system clock must be at least two times faster than the SSIClk.
|
||||
* For slave mode, the system clock must be at least 12 times faster
|
||||
* than the SSIClk."
|
||||
* "Note: Although the SSIClk transmit clock can theoretically be
|
||||
* 25 MHz, the module may not be able to operate at that speed. For
|
||||
* master mode, the system clock must be at least two times faster
|
||||
* than the SSIClk. For slave mode, the system clock must be at
|
||||
* least 12 times faster than the SSIClk."
|
||||
*/
|
||||
|
||||
if (frequency > SYSCLK_FREQUENCY/2)
|
||||
if (frequency > SYSCLK_FREQUENCY / 2)
|
||||
{
|
||||
frequency = SYSCLK_FREQUENCY/2;
|
||||
frequency = SYSCLK_FREQUENCY / 2;
|
||||
}
|
||||
|
||||
/* Find optimal values for CPSDVSR and SCR. This loop is inefficient,
|
||||
|
@ -1194,8 +1200,8 @@ static uint32_t ssi_setfrequencyinternal(struct tiva_ssidev_s *priv,
|
|||
|
||||
actual = SYSCLK_FREQUENCY / (cpsdvsr * (scr + 1));
|
||||
|
||||
/* Save the frequency selection so that subsequent reconfigurations will be
|
||||
* faster.
|
||||
/* Save the frequency selection so that subsequent reconfigurations
|
||||
* will be faster.
|
||||
*/
|
||||
|
||||
priv->frequency = frequency;
|
||||
|
@ -1205,7 +1211,8 @@ static uint32_t ssi_setfrequencyinternal(struct tiva_ssidev_s *priv,
|
|||
return priv->actual;
|
||||
}
|
||||
|
||||
static uint32_t ssi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
||||
static uint32_t ssi_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency)
|
||||
{
|
||||
struct tiva_ssidev_s *priv = (struct tiva_ssidev_s *)dev;
|
||||
uint32_t enable;
|
||||
|
@ -1237,7 +1244,8 @@ static uint32_t ssi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ssi_setmodeinternal(struct tiva_ssidev_s *priv, enum spi_mode_e mode)
|
||||
static void ssi_setmodeinternal(struct tiva_ssidev_s *priv,
|
||||
enum spi_mode_e mode)
|
||||
{
|
||||
uint32_t modebits;
|
||||
uint32_t regval;
|
||||
|
@ -1363,10 +1371,10 @@ static void ssi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t ssi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t ssi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
struct tiva_ssidev_s *priv = (struct tiva_ssidev_s *)dev;
|
||||
uint16_t response = 0;
|
||||
uint32_t response = 0;
|
||||
|
||||
ssi_transfer(priv, &wd, &response, 1);
|
||||
return response;
|
||||
|
@ -1385,7 +1393,8 @@ static uint16_t ssi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
* 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
|
||||
* packed into uint8_t's; if nbits >8, the data is packed into
|
||||
* uint16_t's
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
|
@ -1413,7 +1422,8 @@ static void ssi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
* 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
|
||||
|
@ -1439,9 +1449,10 @@ static void ssi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
|
|||
* dev - Device-specific state data
|
||||
* buffer - 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
|
||||
* 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
|
||||
|
@ -1470,10 +1481,10 @@ static void ssi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
|
|||
* prior to calling this function. Specifically: GPIOs should have
|
||||
* been configured for output, and all chip selects disabled.
|
||||
*
|
||||
* One GPIO, SS (PB2 on the eZ8F091) is reserved as a chip select. However,
|
||||
* If multiple devices on on the bus, then multiple chip selects will be
|
||||
* required. Therefore, all GPIO chip management is deferred to board-
|
||||
* specific logic.
|
||||
* One GPIO, SS (PB2 on the eZ8F091) is reserved as a chip select.
|
||||
* However, if multiple devices on on the bus, then multiple chip selects
|
||||
* will be required. Therefore, all GPIO chip management is deferred to
|
||||
* board-specific logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* Port number (for hardware that has multiple SSI interfaces)
|
||||
|
@ -1497,6 +1508,7 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port)
|
|||
{
|
||||
#ifdef CONFIG_TIVA_SSI0
|
||||
case 0:
|
||||
|
||||
/* Select SSI0 */
|
||||
|
||||
priv = &g_ssidev[SSI0_NDX];
|
||||
|
@ -1520,7 +1532,7 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port)
|
|||
*/
|
||||
|
||||
tiva_configgpio(GPIO_SSI0_CLK); /* PA2: SSI0 clock (SSI0Clk) */
|
||||
/* tiva_configgpio(GPIO_SSI0_FSS); PA3: SSI0 frame (SSI0Fss) */
|
||||
/* tiva_configgpio(GPIO_SSI0_FSS); PA3: SSI0 frame (SSI0Fss) */
|
||||
tiva_configgpio(GPIO_SSI0_RX); /* PA4: SSI0 receive (SSI0Rx) */
|
||||
tiva_configgpio(GPIO_SSI0_TX); /* PA5: SSI0 transmit (SSI0Tx) */
|
||||
break;
|
||||
|
@ -1528,6 +1540,7 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port)
|
|||
|
||||
#ifdef CONFIG_TIVA_SSI1
|
||||
case 1:
|
||||
|
||||
/* Select SSI1 */
|
||||
|
||||
priv = &g_ssidev[SSI1_NDX];
|
||||
|
@ -1549,7 +1562,7 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port)
|
|||
/* Configure SSI1 GPIOs */
|
||||
|
||||
tiva_configgpio(GPIO_SSI1_CLK); /* PE0: SSI1 clock (SSI1Clk) */
|
||||
/* tiva_configgpio(GPIO_SSI1_FSS); PE1: SSI1 frame (SSI1Fss) */
|
||||
/* tiva_configgpio(GPIO_SSI1_FSS); PE1: SSI1 frame (SSI1Fss) */
|
||||
tiva_configgpio(GPIO_SSI1_RX); /* PE2: SSI1 receive (SSI1Rx) */
|
||||
tiva_configgpio(GPIO_SSI1_TX); /* PE3: SSI1 transmit (SSI1Tx) */
|
||||
break;
|
||||
|
@ -1557,6 +1570,7 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port)
|
|||
|
||||
#ifdef CONFIG_TIVA_SSI2
|
||||
case 2:
|
||||
|
||||
/* Select SSI2 */
|
||||
|
||||
priv = &g_ssidev[SSI2_NDX];
|
||||
|
@ -1578,7 +1592,7 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port)
|
|||
/* Configure SSI2 GPIOs */
|
||||
|
||||
tiva_configgpio(GPIO_SSI2_CLK); /* PE0: SSI2 clock (SSI2Clk) */
|
||||
/* tiva_configgpio(GPIO_SSI2_FSS); PE1: SSI2 frame (SSI2Fss) */
|
||||
/* tiva_configgpio(GPIO_SSI2_FSS); PE1: SSI2 frame (SSI2Fss) */
|
||||
tiva_configgpio(GPIO_SSI2_RX); /* PE2: SSI2 receive (SSI2Rx) */
|
||||
tiva_configgpio(GPIO_SSI2_TX); /* PE3: SSI2 transmit (SSI2Tx) */
|
||||
break;
|
||||
|
@ -1586,6 +1600,7 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port)
|
|||
|
||||
#ifdef CONFIG_TIVA_SSI3
|
||||
case 3:
|
||||
|
||||
/* Select SSI3 */
|
||||
|
||||
priv = &g_ssidev[SSI3_NDX];
|
||||
|
@ -1607,7 +1622,7 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port)
|
|||
/* Configure SSI3 GPIOs */
|
||||
|
||||
tiva_configgpio(GPIO_SSI3_CLK); /* PE0: SSI3 clock (SSI3Clk) */
|
||||
/* tiva_configgpio(GPIO_SSI3_FSS); PE1: SSI3 frame (SSI3Fss) */
|
||||
/* tiva_configgpio(GPIO_SSI3_FSS); PE1: SSI3 frame (SSI3Fss) */
|
||||
tiva_configgpio(GPIO_SSI3_RX); /* PE2: SSI3 receive (SSI3Rx) */
|
||||
tiva_configgpio(GPIO_SSI3_TX); /* PE3: SSI3 transmit (SSI3Tx) */
|
||||
break;
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* When SPI DMA is enabled, small DMA transfers will still be performed by
|
||||
* polling logic. But we need a threshold value to determine what is small.
|
||||
* That value is provided by CONFIG_XMC4_SPI_DMATHRESHOLD.
|
||||
|
@ -129,6 +130,7 @@
|
|||
#endif
|
||||
|
||||
/* Clocking *****************************************************************/
|
||||
|
||||
/* Select MCU-specific settings */
|
||||
|
||||
#if defined(CONFIG_ARCH_CHIP_XMC4)
|
||||
|
@ -287,7 +289,7 @@ static void spi_select(struct spi_dev_s *dev, uint32_t devid,
|
|||
static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency);
|
||||
static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode);
|
||||
static void spi_setbits(struct spi_dev_s *dev, int nbits);
|
||||
static uint16_t spi_send(struct spi_dev_s *dev, uint16_t ch);
|
||||
static uint32_t spi_send(struct spi_dev_s *dev, uint32_t wd);
|
||||
|
||||
#ifdef CONFIG_XMC4_SPI_DMA
|
||||
static void spi_exchange_nodma(struct spi_dev_s *dev,
|
||||
|
@ -1300,7 +1302,7 @@ static void spi_setbits(struct spi_dev_s *dev, int nbits)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t spi_send(struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
uint8_t txbyte;
|
||||
uint8_t rxbyte;
|
||||
|
@ -1315,7 +1317,7 @@ static uint16_t spi_send(struct spi_dev_s *dev, uint16_t wd)
|
|||
spi_exchange(dev, &txbyte, &rxbyte, 1);
|
||||
|
||||
spiinfo("Sent %02x received %02x\n", txbyte, rxbyte);
|
||||
return (uint16_t)rxbyte;
|
||||
return (uint32_t)rxbyte;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1395,7 +1397,8 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
|||
|
||||
/* Loop, sending each word in the user-provided data buffer.
|
||||
*
|
||||
* Note: Good SPI performance would require that we implement DMA transfers!
|
||||
* Note: Good SPI performance would require that we implement
|
||||
* DMA transfers!
|
||||
*/
|
||||
|
||||
for (; nwords > 0; nwords--)
|
||||
|
@ -1435,7 +1438,8 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
|||
{
|
||||
}
|
||||
|
||||
spi_putreg(spi, (USIC_PSCR_CRIF | USIC_PSCR_CAIF), XMC4_USIC_PSCR_OFFSET);
|
||||
spi_putreg(spi, (USIC_PSCR_CRIF | USIC_PSCR_CAIF),
|
||||
XMC4_USIC_PSCR_OFFSET);
|
||||
|
||||
/* Read the received data from the SPI Data Register. */
|
||||
|
||||
|
@ -1551,7 +1555,8 @@ static void spi_exchange(struct spi_dev_s *dev, const void *txbuffer,
|
|||
* the DMA completes
|
||||
*/
|
||||
|
||||
xmc4_cmcc_invalidate((uintptr_t)rxbuffer, (uintptr_t)rxbuffer + nbytes);
|
||||
xmc4_cmcc_invalidate((uintptr_t)rxbuffer,
|
||||
(uintptr_t)rxbuffer + nbytes);
|
||||
|
||||
/* Use normal RX memory incrementing. */
|
||||
|
||||
|
@ -1747,10 +1752,10 @@ static void spi_sndblock(struct spi_dev_s *dev, const void *buffer,
|
|||
* dev - Device-specific state data
|
||||
* buffer - 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
|
||||
* 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
|
||||
|
@ -1890,13 +1895,14 @@ struct spi_dev_s *xmc4_spibus_initialize(int channel)
|
|||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
{
|
||||
spierr("ERROR: spino invalid: %d\n", spino);
|
||||
}
|
||||
}
|
||||
|
||||
/* Save the chip select and SPI controller numbers */
|
||||
|
||||
/*spics->cs = csno; */
|
||||
/* spics->cs = csno; */
|
||||
|
||||
spics->cs = 0;
|
||||
spics->spino = spino;
|
||||
|
||||
|
@ -2005,9 +2011,9 @@ struct spi_dev_s *xmc4_spibus_initialize(int channel)
|
|||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
{
|
||||
spierr("ERROR: spino invalid: %d\n", spino);
|
||||
}
|
||||
}
|
||||
|
||||
/* Leave critical section */
|
||||
|
||||
|
@ -2063,7 +2069,7 @@ struct spi_dev_s *xmc4_spibus_initialize(int channel)
|
|||
|
||||
/* Clear protocol status */
|
||||
|
||||
spi_putreg(spi, 0xffffffffUL, XMC4_USIC_PSCR_OFFSET);
|
||||
spi_putreg(spi, 0xfffffffful, XMC4_USIC_PSCR_OFFSET);
|
||||
|
||||
/* Disable the parity */
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/avr/up_spi.c
|
||||
* arch/avr/src/avr/up_spi.c
|
||||
*
|
||||
* Copyright (C) 2011, 2016-2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
|
@ -82,12 +82,16 @@ struct avr_spidev_s
|
|||
/* SPI methods */
|
||||
|
||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
|
||||
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 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 uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
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);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
|
@ -115,7 +119,10 @@ static const struct spi_ops_s g_spiops =
|
|||
|
||||
static struct avr_spidev_s g_spidev =
|
||||
{
|
||||
.spidev = { &g_spiops },
|
||||
.spidev =
|
||||
{
|
||||
&g_spiops
|
||||
},
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -175,7 +182,8 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency)
|
||||
{
|
||||
FAR struct avr_spidev_s *priv = (FAR struct avr_spidev_s *)dev;
|
||||
uint32_t actual;
|
||||
|
@ -340,7 +348,7 @@ 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 wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
/* Write the data to transmitted to the SPI Data Register */
|
||||
|
||||
|
@ -352,7 +360,7 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
|
||||
/* Then return the received value */
|
||||
|
||||
return (uint16_t)SPDR;
|
||||
return (uint32_t)SPDR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -375,7 +383,8 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size_t nwords)
|
||||
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
|
||||
size_t nwords)
|
||||
{
|
||||
FAR uint8_t *ptr = (FAR uint8_t *)buffer;
|
||||
|
||||
|
@ -406,7 +415,8 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords)
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
|
||||
size_t nwords)
|
||||
{
|
||||
FAR uint8_t *ptr = (FAR uint8_t *)buffer;
|
||||
|
||||
|
@ -465,6 +475,7 @@ FAR struct spi_dev_s *avr_spibus_initialize(int port)
|
|||
SPCR = (1 << SPE) | (1 << MSTR);
|
||||
|
||||
/* Set clock rate to f(osc)/8 */
|
||||
|
||||
/* SPSR |= (1 << 0); */
|
||||
|
||||
/* Clear status flags by reading them */
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration */
|
||||
|
||||
#ifdef CONFIG_SPI_EXCHANGE
|
||||
|
@ -98,6 +99,7 @@ struct pic32mx_dev_s
|
|||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Low-level register access */
|
||||
|
||||
static uint32_t spi_getreg(FAR struct pic32mx_dev_s *priv,
|
||||
|
@ -112,7 +114,7 @@ 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 uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
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,
|
||||
|
@ -565,10 +567,10 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
|||
*
|
||||
* CPOL=0: The inactive value of the clock is zero
|
||||
* CPOL=1: The inactive value of the clock is one
|
||||
* CPHA=0: Data is captured on the clock's inactive-to-active edge and
|
||||
* data is propagated on a active-to-inactive edge.
|
||||
* CPHA=1: Data is captured on the clock's active-to-inactive edge and
|
||||
* data is propagated on a active-to-inactive edge.
|
||||
* CPHA=0: Data is captured on the clock's inactive-to-active edge
|
||||
* and data is propagated on a active-to-inactive edge.
|
||||
* CPHA=1: Data is captured on the clock's active-to-inactive edge
|
||||
* and data is propagated on a active-to-inactive edge.
|
||||
*
|
||||
* CON Register mapping:
|
||||
* CPOL=0 corresponds to CON:CKP=0; CPOL=1 corresponds to CON:CKP=1
|
||||
|
@ -694,7 +696,7 @@ 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 wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
FAR struct pic32mx_dev_s *priv = (FAR struct pic32mx_dev_s *)dev;
|
||||
|
||||
|
@ -702,7 +704,7 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
|
||||
/* Write the data to transmitted to the SPI Data Register */
|
||||
|
||||
spi_putreg(priv, PIC32MX_SPI_BUF_OFFSET, (uint32_t)wd);
|
||||
spi_putreg(priv, PIC32MX_SPI_BUF_OFFSET, wd);
|
||||
|
||||
#ifdef CONFIG_PIC32MX_SPI_ENHBUF
|
||||
/* Wait for the SPIRBE bit in the SPI Status Register to be set to 0. In
|
||||
|
@ -722,7 +724,7 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
|
||||
/* Return the SPI data */
|
||||
|
||||
return (uint16_t)spi_getreg(priv, PIC32MX_SPI_BUF_OFFSET);
|
||||
return spi_getreg(priv, PIC32MX_SPI_BUF_OFFSET);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -762,9 +764,9 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
|
|||
spi_putreg(priv, PIC32MX_SPI_BUF_OFFSET, (uint32_t)data);
|
||||
|
||||
#ifdef CONFIG_PIC32MX_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.
|
||||
/* 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, PIC32MX_SPI_STAT_OFFSET) &
|
||||
|
@ -823,9 +825,9 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
|
|||
spi_putreg(priv, PIC32MX_SPI_BUF_OFFSET, 0xff);
|
||||
|
||||
#ifdef CONFIG_PIC32MX_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.
|
||||
/* 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, PIC32MX_SPI_STAT_OFFSET) &
|
||||
|
|
|
@ -228,7 +228,7 @@ 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 wd);
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
size_t nwords);
|
||||
|
@ -1058,8 +1058,8 @@ static void spi_exchange8(FAR struct pic32mz_dev_s *priv,
|
|||
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
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
|
@ -1132,8 +1132,8 @@ static void spi_exchange16(FAR struct pic32mz_dev_s *priv,
|
|||
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
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
|
@ -1308,10 +1308,10 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
|||
*
|
||||
* CPOL=0: The inactive value of the clock is zero
|
||||
* CPOL=1: The inactive value of the clock is one
|
||||
* CPHA=0: Data is captured on the clock's inactive-to-active edge and
|
||||
* data is propagated on a active-to-inactive edge.
|
||||
* CPHA=1: Data is captured on the clock's active-to-inactive edge and
|
||||
* data is propagated on a active-to-inactive edge.
|
||||
* CPHA=0: Data is captured on the clock's inactive-to-active edge
|
||||
* and data is propagated on a active-to-inactive edge.
|
||||
* CPHA=1: Data is captured on the clock's active-to-inactive edge
|
||||
* and data is propagated on a active-to-inactive edge.
|
||||
*
|
||||
* CON Register mapping:
|
||||
* CPOL=0 corresponds to CON:CKP=0; CPOL=1 corresponds to CON:CKP=1
|
||||
|
@ -1434,7 +1434,7 @@ 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 wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
FAR struct pic32mz_dev_s *priv = (FAR struct pic32mz_dev_s *)dev;
|
||||
|
||||
|
@ -1456,7 +1456,7 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
spi_exchange16(priv, &txword, &rxword, 1);
|
||||
|
||||
spiinfo("Sent %04x received %04x\n", txword, rxword);
|
||||
return rxword;
|
||||
return (uint32_t)rxword;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1470,7 +1470,7 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
spi_exchange8(priv, &txbyte, &rxbyte, 1);
|
||||
|
||||
spiinfo("Sent %02x received %02x\n", txbyte, rxbyte);
|
||||
return (uint16_t)rxbyte;
|
||||
return (uint32_t)rxbyte;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1837,8 +1837,8 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
}
|
||||
else
|
||||
{
|
||||
up_invalidate_dcache((uintptr_t)dummy,
|
||||
(uintptr_t)dummy + CONFIG_PIC32MZ_SPI_DMABUFFSIZE);
|
||||
up_invalidate_dcache((uintptr_t)dummy, (uintptr_t)dummy +
|
||||
CONFIG_PIC32MZ_SPI_DMABUFFSIZE);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_PIC32MZ_SPI_DMA */
|
||||
|
|
|
@ -178,7 +178,7 @@ struct sim_spiflashdev_s
|
|||
FAR char * name; /* Name of the flash type (m25p, w25, etc.) */
|
||||
int wren;
|
||||
int state;
|
||||
uint16_t read_data;
|
||||
uint32_t read_data;
|
||||
uint8_t last_cmd;
|
||||
uint8_t capacity;
|
||||
uint8_t manuf;
|
||||
|
@ -194,27 +194,30 @@ struct sim_spiflashdev_s
|
|||
/* SPI methods */
|
||||
|
||||
static int spiflash_lock(FAR struct spi_dev_s *dev, bool lock);
|
||||
static uint32_t spiflash_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency);
|
||||
static uint32_t spiflash_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency);
|
||||
static void spiflash_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
|
||||
static void spiflash_setbits(FAR struct spi_dev_s *dev, int nbits);
|
||||
static uint16_t spiflash_send(FAR struct spi_dev_s *dev, uint16_t wd);
|
||||
static void spiflash_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
static uint32_t spiflash_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
static void spiflash_exchange(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
size_t nwords);
|
||||
static void spiflash_select(FAR struct spi_dev_s *dev, uint32_t devid,
|
||||
bool selected);
|
||||
bool selected);
|
||||
static uint8_t spiflash_status(FAR struct spi_dev_s *dev, uint32_t devid);
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
static int spiflash_cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd);
|
||||
static int spiflash_cmddata(FAR struct spi_dev_s *dev, uint32_t devid,
|
||||
bool cmd);
|
||||
#endif
|
||||
#ifndef CONFIG_SPI_EXCHANGE
|
||||
static void spiflash_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
size_t nwords);
|
||||
static void spiflash_sndblock(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, size_t nwords);
|
||||
static void spiflash_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer,
|
||||
size_t nwords);
|
||||
size_t nwords);
|
||||
#endif
|
||||
|
||||
static void spiflash_writeword(FAR struct sim_spiflashdev_s *priv, uint16_t data);
|
||||
static uint16_t spiflash_readword(FAR struct sim_spiflashdev_s *priv);
|
||||
static uint32_t spiflash_readword(FAR struct sim_spiflashdev_s *priv);
|
||||
|
||||
/************************************************************************************
|
||||
* Private Data
|
||||
|
@ -500,10 +503,10 @@ static uint8_t spiflash_status(FAR struct spi_dev_s *dev, uint32_t devid)
|
|||
*
|
||||
************************************************************************************/
|
||||
|
||||
static uint16_t spiflash_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t spiflash_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
FAR struct sim_spiflashdev_s *priv = (FAR struct sim_spiflashdev_s *)dev;
|
||||
uint16_t ret;
|
||||
uint32_t ret;
|
||||
|
||||
if (priv->selected)
|
||||
{
|
||||
|
@ -897,7 +900,7 @@ static void spiflash_writeword(FAR struct sim_spiflashdev_s *priv, uint16_t data
|
|||
*
|
||||
************************************************************************************/
|
||||
|
||||
static uint16_t spiflash_readword(FAR struct sim_spiflashdev_s *priv)
|
||||
static uint32_t spiflash_readword(FAR struct sim_spiflashdev_s *priv)
|
||||
{
|
||||
return priv->read_data;
|
||||
}
|
||||
|
|
|
@ -74,10 +74,10 @@ struct z16f_spi_s
|
|||
/* Debug stuff */
|
||||
|
||||
#ifdef CONFIG_Z16F_ESPI_REGDEBUG
|
||||
bool wr; /* Last was a write */
|
||||
uint16_t regval; /* Last value */
|
||||
int ntimes; /* Number of times */
|
||||
uintptr_t regaddr; /* Last address */
|
||||
bool wr; /* Last was a write */
|
||||
uint16_t regval; /* Last value */
|
||||
int ntimes; /* Number of times */
|
||||
uintptr_t regaddr; /* Last address */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -112,17 +112,19 @@ static void spi_flush(FAR struct z16f_spi_s *priv);
|
|||
/* SPI methods */
|
||||
|
||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency);
|
||||
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_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
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);
|
||||
FAR const void *buffer, size_t nwords);
|
||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
|
||||
size_t nwords);
|
||||
size_t nwords);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -185,8 +187,8 @@ static struct z16f_spi_s g_espi;
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_Z16F_ESPI_REGDEBUG
|
||||
static bool spi_checkreg(FAR struct z16f_spi_s *priv, bool wr, uint16_t regval,
|
||||
uintptr_t regaddr)
|
||||
static bool spi_checkreg(FAR struct z16f_spi_s *priv, bool wr,
|
||||
uint16_t regval, uintptr_t regaddr)
|
||||
{
|
||||
if (wr == priv->wr && /* Same kind of access? */
|
||||
regval == priv->regval && /* Same value? */
|
||||
|
@ -398,7 +400,8 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
|
||||
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency)
|
||||
{
|
||||
FAR struct z16f_spi_s *priv = (FAR struct z16f_spi_s *)dev;
|
||||
uint32_t actual;
|
||||
|
@ -580,7 +583,7 @@ 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 wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
uint8_t txbyte;
|
||||
uint8_t rxbyte;
|
||||
|
@ -595,7 +598,7 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
spi_exchange(dev, &txbyte, &rxbyte, 1);
|
||||
|
||||
spiinfo("Sent %02x received %02x\n", txbyte, rxbyte);
|
||||
return (uint16_t)rxbyte;
|
||||
return (uint32_t)rxbyte;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -663,7 +666,7 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
|||
* Save the final byte.
|
||||
*/
|
||||
|
||||
for ( ; nwords > 0; nwords--)
|
||||
for (; nwords > 0; nwords--)
|
||||
{
|
||||
/* Get the data to send (0xff if there is no data source). */
|
||||
|
||||
|
@ -745,10 +748,10 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
|
|||
* dev - Device-specific state data
|
||||
* buffer - 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
|
||||
* 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
|
||||
|
@ -803,8 +806,8 @@ FAR struct spi_dev_s *z16_spibus_initialize(int port)
|
|||
priv->spi.ops = &g_epsiops;
|
||||
nxsem_init(&priv->exclsem, 0, 1);
|
||||
|
||||
/* Set up the SPI pin configuration (board-specific logic is required to
|
||||
* configure and manage all chip selects).
|
||||
/* Set up the SPI pin configuration (board-specific logic is required
|
||||
* to configure and manage all chip selects).
|
||||
*
|
||||
* SCK - PC3, Alternate function 1
|
||||
* MOSI - PC4, Alternate function 1
|
||||
|
@ -824,14 +827,16 @@ FAR struct spi_dev_s *z16_spibus_initialize(int port)
|
|||
spi_putreg8(priv, 0x00, Z16F_ESPI_CTL); /* Disabled the ESPI */
|
||||
spi_putreg8(priv, 0x00, Z16F_ESPI_DCR); /* Disabled slave select; clear TEOF */
|
||||
|
||||
regval = Z16F_ESPI_MODE_SSIO | Z16F_ESPI_MODE_NUMBITS_8BITS | Z16F_ESPI_MODE_SSMD_SPI;
|
||||
regval = Z16F_ESPI_MODE_SSIO | Z16F_ESPI_MODE_NUMBITS_8BITS |
|
||||
Z16F_ESPI_MODE_SSMD_SPI;
|
||||
spi_putreg8(priv, regval, Z16F_ESPI_MODE); /* SPI mode, 8-bit */
|
||||
|
||||
regval = Z16F_ESPI_CTL_ESPIEN0 | Z16F_ESPI_CTL_MMEN | Z16F_ESPI_CTL_ESPIEN1;
|
||||
regval = Z16F_ESPI_CTL_ESPIEN0 | Z16F_ESPI_CTL_MMEN |
|
||||
Z16F_ESPI_CTL_ESPIEN1;
|
||||
spi_putreg8(priv, 0x00, Z16F_ESPI_CTL); /* TX/RX mode, Master mode */
|
||||
|
||||
/* Make sure that we are all in agreement about the configuration and set
|
||||
* the BRG for 400KHz operation.
|
||||
/* Make sure that we are all in agreement about the configuration and
|
||||
* set the BRG for 400KHz operation.
|
||||
*/
|
||||
|
||||
spi_setfrequency(&priv->spi, 400000);
|
||||
|
|
|
@ -74,7 +74,7 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
|
|||
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 uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd);
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
#ifdef CONFIG_SPI_EXCHANGE
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
|
@ -405,7 +405,7 @@ static int spi_transfer(uint8_t chout, FAR uint8_t *chin)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
uint8_t response;
|
||||
int ret;
|
||||
|
@ -414,11 +414,11 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
|
|||
if (ret < 0)
|
||||
{
|
||||
spierr("ERROR: spi_transfer returned %d\n", ret);
|
||||
return (uint16_t)0xff;
|
||||
return (uint32_t)0xff;
|
||||
}
|
||||
|
||||
spiinfo("cmd: %04x resp: %02x\n", wd, response);
|
||||
return (uint16_t)response;
|
||||
return (uint32_t)response;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -96,7 +96,7 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
|
|||
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 uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
size_t nwords);
|
||||
|
@ -308,12 +308,12 @@ 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 wd)
|
||||
static uint32_t spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
FAR struct spi_bitbang_s *priv = (FAR struct spi_bitbang_s *)dev;
|
||||
DEBUGASSERT(priv && priv->low && priv->low->exchange);
|
||||
|
||||
return priv->low->exchange(priv, wd);
|
||||
return priv->low->exchange(priv, (uint16_t)wd);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -528,7 +528,8 @@ static int spi_cmddata(FAR struct spi_dev_s *dev, uint32_t devid,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct spi_dev_s *spi_create_bitbang(FAR const struct spi_bitbang_ops_s *low)
|
||||
FAR struct spi_dev_s *spi_create_bitbang(FAR const struct
|
||||
spi_bitbang_ops_s *low)
|
||||
{
|
||||
FAR struct spi_bitbang_s *priv;
|
||||
|
||||
|
|
|
@ -557,10 +557,11 @@ struct spi_ops_s
|
|||
CODE int (*lock)(FAR struct spi_dev_s *dev, bool lock);
|
||||
CODE void (*select)(FAR struct spi_dev_s *dev, uint32_t devid,
|
||||
bool selected);
|
||||
CODE uint32_t (*setfrequency)(FAR struct spi_dev_s *dev, uint32_t frequency);
|
||||
CODE uint32_t (*setfrequency)(FAR struct spi_dev_s *dev,
|
||||
uint32_t frequency);
|
||||
#ifdef CONFIG_SPI_CS_DELAY_CONTROL
|
||||
CODE int (*setdelay)(FAR struct spi_dev_s *dev, uint32_t a, uint32_t b,
|
||||
uint32_t c);
|
||||
CODE int (*setdelay)(FAR struct spi_dev_s *dev, uint32_t a,
|
||||
uint32_t b, uint32_t c);
|
||||
#endif
|
||||
CODE void (*setmode)(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
|
||||
CODE void (*setbits)(FAR struct spi_dev_s *dev, int nbits);
|
||||
|
@ -573,7 +574,7 @@ struct spi_ops_s
|
|||
CODE int (*cmddata)(FAR struct spi_dev_s *dev, uint32_t devid,
|
||||
bool cmd);
|
||||
#endif
|
||||
CODE uint16_t (*send)(FAR struct spi_dev_s *dev, uint16_t wd);
|
||||
CODE uint32_t (*send)(FAR struct spi_dev_s *dev, uint32_t wd);
|
||||
#ifdef CONFIG_SPI_EXCHANGE
|
||||
CODE void (*exchange)(FAR struct spi_dev_s *dev,
|
||||
FAR const void *txbuffer, FAR void *rxbuffer,
|
||||
|
@ -601,10 +602,6 @@ struct spi_dev_s
|
|||
FAR const struct spi_ops_s *ops;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
|
|
Loading…
Reference in a new issue