arch/stm32 ensure all spi dma handler check the result

Author: Alan Carvalho de Assis <acassis@gmail.com>

    Run nxstyle on .c files and fix the issues

Author: Xiang Xiao <xiaoxiang@xiaomi.com>

    arch/stm32 ensure all spi dma handler check the result

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2020-01-11 09:56:52 -03:00 committed by Alan Carvalho de Assis
parent 97bead5496
commit b96d0bfb70
3 changed files with 176 additions and 51 deletions

View File

@ -53,7 +53,7 @@
* mmcsd_spislotinitialize(), for example, will bind the SPI driver to * mmcsd_spislotinitialize(), for example, will bind the SPI driver to
* the SPI MMC/SD driver). * the SPI MMC/SD driver).
* *
****************************************************c********************************/ ************************************************************************************/
/************************************************************************************ /************************************************************************************
* Included Files * Included Files
@ -90,7 +90,9 @@
/************************************************************************************ /************************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
************************************************************************************/ ************************************************************************************/
/* Configuration ********************************************************************/ /* Configuration ********************************************************************/
/* SPI interrupts */ /* SPI interrupts */
#ifdef CONFIG_STM32_SPI_INTERRUPTS #ifdef CONFIG_STM32_SPI_INTERRUPTS
@ -224,9 +226,13 @@ 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_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg);
static void spi_dmatxcallback(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, 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, 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_dmarxstart(FAR struct stm32_spidev_s *priv);
static inline void spi_dmatxstart(FAR struct stm32_spidev_s *priv); static inline void spi_dmatxstart(FAR struct stm32_spidev_s *priv);
#endif #endif
@ -296,7 +302,10 @@ static const struct spi_ops_s g_sp1iops =
static struct stm32_spidev_s g_spi1dev = static struct stm32_spidev_s g_spi1dev =
{ {
.spidev = { &g_sp1iops }, .spidev =
{
&g_sp1iops
},
.spibase = STM32_SPI1_BASE, .spibase = STM32_SPI1_BASE,
.spiclock = STM32_PCLK2_FREQUENCY, .spiclock = STM32_PCLK2_FREQUENCY,
#ifdef CONFIG_STM32_SPI_INTERRUPTS #ifdef CONFIG_STM32_SPI_INTERRUPTS
@ -348,7 +357,10 @@ static const struct spi_ops_s g_sp2iops =
static struct stm32_spidev_s g_spi2dev = static struct stm32_spidev_s g_spi2dev =
{ {
.spidev = { &g_sp2iops }, .spidev =
{
&g_sp2iops
},
.spibase = STM32_SPI2_BASE, .spibase = STM32_SPI2_BASE,
.spiclock = STM32_PCLK1_FREQUENCY, .spiclock = STM32_PCLK1_FREQUENCY,
#ifdef CONFIG_STM32_SPI_INTERRUPTS #ifdef CONFIG_STM32_SPI_INTERRUPTS
@ -400,7 +412,10 @@ static const struct spi_ops_s g_sp3iops =
static struct stm32_spidev_s g_spi3dev = static struct stm32_spidev_s g_spi3dev =
{ {
.spidev = { &g_sp3iops }, .spidev =
{
&g_sp3iops
},
.spibase = STM32_SPI3_BASE, .spibase = STM32_SPI3_BASE,
.spiclock = STM32_PCLK1_FREQUENCY, .spiclock = STM32_PCLK1_FREQUENCY,
#ifdef CONFIG_STM32_SPI_INTERRUPTS #ifdef CONFIG_STM32_SPI_INTERRUPTS
@ -452,7 +467,10 @@ static const struct spi_ops_s g_sp4iops =
static struct stm32_spidev_s g_spi4dev = static struct stm32_spidev_s g_spi4dev =
{ {
.spidev = { &g_sp4iops }, .spidev =
{
&g_sp4iops
},
.spibase = STM32_SPI4_BASE, .spibase = STM32_SPI4_BASE,
.spiclock = STM32_PCLK2_FREQUENCY, .spiclock = STM32_PCLK2_FREQUENCY,
#ifdef CONFIG_STM32_SPI_INTERRUPTS #ifdef CONFIG_STM32_SPI_INTERRUPTS
@ -504,7 +522,10 @@ static const struct spi_ops_s g_sp5iops =
static struct stm32_spidev_s g_spi5dev = static struct stm32_spidev_s g_spi5dev =
{ {
.spidev = { &g_sp5iops }, .spidev =
{
&g_sp5iops
},
.spibase = STM32_SPI5_BASE, .spibase = STM32_SPI5_BASE,
.spiclock = STM32_PCLK2_FREQUENCY, .spiclock = STM32_PCLK2_FREQUENCY,
#ifdef CONFIG_STM32_SPI_INTERRUPTS #ifdef CONFIG_STM32_SPI_INTERRUPTS
@ -556,7 +577,10 @@ static const struct spi_ops_s g_sp6iops =
static struct stm32_spidev_s g_spi6dev = static struct stm32_spidev_s g_spi6dev =
{ {
.spidev = { &g_sp6iops }, .spidev =
{
&g_sp6iops
},
.spibase = STM32_SPI6_BASE, .spibase = STM32_SPI6_BASE,
.spiclock = STM32_PCLK2_FREQUENCY, .spiclock = STM32_PCLK2_FREQUENCY,
#ifdef CONFIG_STM32_SPI_INTERRUPTS #ifdef CONFIG_STM32_SPI_INTERRUPTS
@ -636,7 +660,9 @@ static inline uint8_t spi_getreg8(FAR struct stm32_spidev_s *priv, uint8_t offse
* *
************************************************************************************/ ************************************************************************************/
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); putreg16(value, priv->spibase + offset);
} }
@ -800,7 +826,15 @@ static inline bool spi_16bitmode(FAR struct stm32_spidev_s *priv)
#ifdef CONFIG_STM32_SPI_DMA #ifdef CONFIG_STM32_SPI_DMA
static void spi_dmarxwait(FAR struct stm32_spidev_s *priv) static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
{ {
nxsem_wait_uninterruptible(&priv->rxsem); /* Take the semaphore (perhaps waiting). If the result is zero, then the DMA
* must not really have completed???
*/
do
{
nxsem_wait_uninterruptible(&priv->rxsem);
}
while (priv->rxresult == 0);
} }
#endif #endif
@ -815,7 +849,15 @@ static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
#ifdef CONFIG_STM32_SPI_DMA #ifdef CONFIG_STM32_SPI_DMA
static void spi_dmatxwait(FAR struct stm32_spidev_s *priv) static void spi_dmatxwait(FAR struct stm32_spidev_s *priv)
{ {
nxsem_wait_uninterruptible(&priv->txsem); /* Take the semaphore (perhaps waiting). If the result is zero, then the DMA
* must not really have completed???
*/
do
{
nxsem_wait_uninterruptible(&priv->txsem);
}
while (priv->txresult == 0);
} }
#endif #endif
@ -1342,6 +1384,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
{ {
#if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) #if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX)
/* Yes... Set CR2 appropriately */ /* Yes... Set CR2 appropriately */
/* Set the number of bits (valid range 4-16) */ /* Set the number of bits (valid range 4-16) */
if (nbits < 4 || nbits > 16) if (nbits < 4 || nbits > 16)
@ -1753,7 +1796,9 @@ static int spi_trigger(FAR struct spi_dev_s *dev)
************************************************************************************/ ************************************************************************************/
#ifndef CONFIG_SPI_EXCHANGE #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); spiinfo("txbuffer=%p nwords=%d\n", txbuffer, nwords);
return spi_exchange(dev, txbuffer, NULL, nwords); return spi_exchange(dev, txbuffer, NULL, nwords);
@ -1780,7 +1825,9 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, si
************************************************************************************/ ************************************************************************************/
#ifndef CONFIG_SPI_EXCHANGE #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); spiinfo("rxbuffer=%p nwords=%d\n", rxbuffer, nwords);
return spi_exchange(dev, NULL, rxbuffer, nwords); return spi_exchange(dev, NULL, rxbuffer, nwords);
@ -1791,7 +1838,8 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *rxbuffer, size_t
* Name: spi_bus_initialize * Name: spi_bus_initialize
* *
* Description: * 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: * Input Parameters:
* priv - private SPI device structure * priv - private SPI device structure
@ -1813,7 +1861,8 @@ static void spi_bus_initialize(FAR struct stm32_spidev_s *priv)
* 8-bit: CR2.DS=7 * 8-bit: CR2.DS=7
* MSB transmitted first: CR1.LSBFIRST=0 * MSB transmitted first: CR1.LSBFIRST=0
* Replace NSS with SSI & SSI=1: CR1.SSI=1 CR1.SSM=1 (prevents MODF error) * 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 * 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 | clrbits = SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_BR_MASK | SPI_CR1_LSBFIRST |

View File

@ -98,6 +98,7 @@
************************************************************************************/ ************************************************************************************/
/* Configuration ********************************************************************/ /* Configuration ********************************************************************/
/* SPI interrupts */ /* SPI interrupts */
#ifdef CONFIG_STM32H7_SPI_INTERRUPTS #ifdef CONFIG_STM32H7_SPI_INTERRUPTS
@ -248,9 +249,13 @@ 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_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg);
static void spi_dmatxcallback(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, 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, 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_dmarxstart(FAR struct stm32_spidev_s *priv);
static inline void spi_dmatxstart(FAR struct stm32_spidev_s *priv); static inline void spi_dmatxstart(FAR struct stm32_spidev_s *priv);
#endif #endif
@ -327,7 +332,10 @@ static const struct spi_ops_s g_sp1iops =
static struct stm32_spidev_s g_spi1dev = static struct stm32_spidev_s g_spi1dev =
{ {
.spidev = { &g_sp1iops }, .spidev =
{
&g_sp1iops
},
.spibase = STM32_SPI1_BASE, .spibase = STM32_SPI1_BASE,
.spiclock = SPI123_KERNEL_CLOCK_FREQ, .spiclock = SPI123_KERNEL_CLOCK_FREQ,
#ifdef CONFIG_STM32H7_SPI_INTERRUPTS #ifdef CONFIG_STM32H7_SPI_INTERRUPTS
@ -377,7 +385,10 @@ static const struct spi_ops_s g_sp2iops =
static struct stm32_spidev_s g_spi2dev = static struct stm32_spidev_s g_spi2dev =
{ {
.spidev = { &g_sp2iops }, .spidev =
{
&g_sp2iops
},
.spibase = STM32_SPI2_BASE, .spibase = STM32_SPI2_BASE,
.spiclock = SPI123_KERNEL_CLOCK_FREQ, .spiclock = SPI123_KERNEL_CLOCK_FREQ,
#ifdef CONFIG_STM32H7_SPI_INTERRUPTS #ifdef CONFIG_STM32H7_SPI_INTERRUPTS
@ -427,7 +438,10 @@ static const struct spi_ops_s g_sp3iops =
static struct stm32_spidev_s g_spi3dev = static struct stm32_spidev_s g_spi3dev =
{ {
.spidev = { &g_sp3iops }, .spidev =
{
&g_sp3iops
},
.spibase = STM32_SPI3_BASE, .spibase = STM32_SPI3_BASE,
.spiclock = SPI123_KERNEL_CLOCK_FREQ, .spiclock = SPI123_KERNEL_CLOCK_FREQ,
#ifdef CONFIG_STM32H7_SPI_INTERRUPTS #ifdef CONFIG_STM32H7_SPI_INTERRUPTS
@ -477,7 +491,10 @@ static const struct spi_ops_s g_sp4iops =
static struct stm32_spidev_s g_spi4dev = static struct stm32_spidev_s g_spi4dev =
{ {
.spidev = { &g_sp4iops }, .spidev =
{
&g_sp4iops
},
.spibase = STM32_SPI4_BASE, .spibase = STM32_SPI4_BASE,
.spiclock = SPI45_KERNEL_CLOCK_FREQ, .spiclock = SPI45_KERNEL_CLOCK_FREQ,
#ifdef CONFIG_STM32H7_SPI_INTERRUPTS #ifdef CONFIG_STM32H7_SPI_INTERRUPTS
@ -527,7 +544,10 @@ static const struct spi_ops_s g_sp5iops =
static struct stm32_spidev_s g_spi5dev = static struct stm32_spidev_s g_spi5dev =
{ {
.spidev = { &g_sp5iops }, .spidev =
{
&g_sp5iops
},
.spibase = STM32_SPI5_BASE, .spibase = STM32_SPI5_BASE,
.spiclock = SPI45_KERNEL_CLOCK_FREQ, .spiclock = SPI45_KERNEL_CLOCK_FREQ,
#ifdef CONFIG_STM32H7_SPI_INTERRUPTS #ifdef CONFIG_STM32H7_SPI_INTERRUPTS
@ -577,7 +597,10 @@ static const struct spi_ops_s g_sp6iops =
static struct stm32_spidev_s g_spi6dev = static struct stm32_spidev_s g_spi6dev =
{ {
.spidev = { &g_sp6iops }, .spidev =
{
&g_sp6iops
},
.spibase = STM32_SPI6_BASE, .spibase = STM32_SPI6_BASE,
.spiclock = SPI6_KERNEL_CLOCK_FREQ, .spiclock = SPI6_KERNEL_CLOCK_FREQ,
#ifdef CONFIG_STM32H7_SPI_INTERRUPTS #ifdef CONFIG_STM32H7_SPI_INTERRUPTS
@ -853,7 +876,15 @@ static void spi_dmarxwait(FAR struct stm32_spidev_s *priv)
#ifdef CONFIG_STM32H7_SPI_DMA #ifdef CONFIG_STM32H7_SPI_DMA
static void spi_dmatxwait(FAR struct stm32_spidev_s *priv) static void spi_dmatxwait(FAR struct stm32_spidev_s *priv)
{ {
nxsem_wait_uninterruptible(&priv->txsem); /* Take the semaphore (perhaps waiting). If the result is zero, then the DMA
* must not really have completed???
*/
do
{
nxsem_wait_uninterruptible(&priv->txsem);
}
while (priv->txresult == 0);
} }
#endif #endif
@ -1318,7 +1349,8 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
* enabling; and flush the SPI RX FIFO before re-enabling DMA. * enabling; and flush the SPI RX FIFO before re-enabling DMA.
*/ */
spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN, 0); spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, SPI_CFG1_RXDMAEN |
SPI_CFG1_TXDMAEN, 0);
#endif #endif
/* Re-enable SPI */ /* Re-enable SPI */
@ -1336,7 +1368,8 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
/* Re-enable DMA (with SPI disabled) */ /* Re-enable DMA (with SPI disabled) */
spi_enable(priv, false); spi_enable(priv, false);
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);
spi_enable(priv, true); spi_enable(priv, true);
#endif #endif
@ -1375,6 +1408,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
if (nbits != priv->nbits) if (nbits != priv->nbits)
{ {
/* Yes... Set CFG1 appropriately */ /* Yes... Set CFG1 appropriately */
/* Set the number of bits (valid range 4-32) */ /* Set the number of bits (valid range 4-32) */
if (nbits < 4 || nbits > 32) if (nbits < 4 || nbits > 32)
@ -1520,7 +1554,7 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
} }
else else
{ {
spi_writebyte(priv, (uint8_t)(wd & 0xFF)); spi_writebyte(priv, (uint8_t)(wd & 0xff));
ret = (uint32_t)spi_readbyte(priv); ret = (uint32_t)spi_readbyte(priv);
} }
@ -1843,7 +1877,9 @@ static int spi_trigger(FAR struct spi_dev_s *dev)
************************************************************************************/ ************************************************************************************/
#ifndef CONFIG_SPI_EXCHANGE #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); spiinfo("txbuffer=%p nwords=%d\n", txbuffer, nwords);
return spi_exchange(dev, txbuffer, NULL, nwords); return spi_exchange(dev, txbuffer, NULL, nwords);
@ -1870,7 +1906,9 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, si
************************************************************************************/ ************************************************************************************/
#ifndef CONFIG_SPI_EXCHANGE #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); spiinfo("rxbuffer=%p nwords=%d\n", rxbuffer, nwords);
return spi_exchange(dev, NULL, rxbuffer, nwords); return spi_exchange(dev, NULL, rxbuffer, nwords);
@ -1925,6 +1963,7 @@ static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain,
case PM_STANDBY: case PM_STANDBY:
case PM_SLEEP: case PM_SLEEP:
/* Check if exclusive lock for SPI bus is held. */ /* Check if exclusive lock for SPI bus is held. */
if (nxsem_getvalue(&priv->exclsem, &sval) < 0) if (nxsem_getvalue(&priv->exclsem, &sval) < 0)
@ -1943,6 +1982,7 @@ static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain,
break; break;
default: default:
/* Should not get here */ /* Should not get here */
break; break;
@ -1956,7 +1996,8 @@ static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain,
* Name: spi_bus_initialize * Name: spi_bus_initialize
* *
* Description: * 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: * Input Parameters:
* priv - private SPI device structure * priv - private SPI device structure

View File

@ -43,22 +43,23 @@
* *
* 1. Provide logic in stm32l4_board_initialize() to configure SPI chip select * 1. Provide logic in stm32l4_board_initialize() to configure SPI chip select
* pins. * pins.
* 2. Provide stm32l4_spi1/2/3select() and stm32l4_spi1/2/3status() functions in your * 2. Provide stm32l4_spi1/2/3select() and stm32l4_spi1/2/3status() functions in
* board-specific logic. These functions will perform chip selection and * your board-specific logic. These functions will perform chip selection and
* status operations using GPIOs in the way your board is configured. * status operations using GPIOs in the way your board is configured.
* 3. Add a calls to stm32l4_spibus_initialize() in your low level application * 3. Add a calls to stm32l4_spibus_initialize() in your low level application
* initialization logic * initialization logic
* 4. The handle returned by stm32l4_spibus_initialize() may then be used to bind the * 4. The handle returned by stm32l4_spibus_initialize() may then be used to bind
* SPI driver to higher level logic (e.g., calling * the SPI driver to higher level logic (e.g., calling
* mmcsd_spislotinitialize(), for example, will bind the SPI driver to * mmcsd_spislotinitialize(), for example, will bind the SPI driver to
* the SPI MMC/SD driver). * the SPI MMC/SD driver).
* *
****************************************************c********************************/ *************************************************************************************/
/* This driver is ported from the stm32 one, which only supports 8 and 16 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 * 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 * 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. * of the CR2_DS[0..3] bits. If the value is SPI_CR2_DS_16BIT it means 16 bits,
* else 8 bits.
*/ */
/************************************************************************************ /************************************************************************************
@ -100,6 +101,7 @@
************************************************************************************/ ************************************************************************************/
/* Configuration ********************************************************************/ /* Configuration ********************************************************************/
/* SPI interrupts */ /* SPI interrupts */
#ifdef CONFIG_STM32L4_SPI_INTERRUPTS #ifdef CONFIG_STM32L4_SPI_INTERRUPTS
@ -201,9 +203,13 @@ 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_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg);
static void spi_dmatxcallback(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, static void spi_dmarxsetup(FAR struct stm32l4_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 stm32l4_spidev_s *priv, static void spi_dmatxsetup(FAR struct stm32l4_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 stm32l4_spidev_s *priv); static inline void spi_dmarxstart(FAR struct stm32l4_spidev_s *priv);
static inline void spi_dmatxstart(FAR struct stm32l4_spidev_s *priv); static inline void spi_dmatxstart(FAR struct stm32l4_spidev_s *priv);
#endif #endif
@ -280,7 +286,10 @@ static const struct spi_ops_s g_spi1ops =
static struct stm32l4_spidev_s g_spi1dev = static struct stm32l4_spidev_s g_spi1dev =
{ {
.spidev = { &g_spi1ops }, .spidev =
{
&g_spi1ops
},
.spibase = STM32L4_SPI1_BASE, .spibase = STM32L4_SPI1_BASE,
.spiclock = STM32L4_PCLK2_FREQUENCY, .spiclock = STM32L4_PCLK2_FREQUENCY,
#ifdef CONFIG_STM32L4_SPI_INTERRUPTS #ifdef CONFIG_STM32L4_SPI_INTERRUPTS
@ -288,6 +297,7 @@ static struct stm32l4_spidev_s g_spi1dev =
#endif #endif
#ifdef CONFIG_STM32L4_SPI_DMA #ifdef CONFIG_STM32L4_SPI_DMA
/* lines must be configured in board.h */ /* lines must be configured in board.h */
.rxch = DMACHAN_SPI1_RX, .rxch = DMACHAN_SPI1_RX,
.txch = DMACHAN_SPI1_TX, .txch = DMACHAN_SPI1_TX,
#endif #endif
@ -331,7 +341,10 @@ static const struct spi_ops_s g_spi2ops =
static struct stm32l4_spidev_s g_spi2dev = static struct stm32l4_spidev_s g_spi2dev =
{ {
.spidev = { &g_spi2ops }, .spidev =
{
&g_spi2ops
},
.spibase = STM32L4_SPI2_BASE, .spibase = STM32L4_SPI2_BASE,
.spiclock = STM32L4_PCLK1_FREQUENCY, .spiclock = STM32L4_PCLK1_FREQUENCY,
#ifdef CONFIG_STM32L4_SPI_INTERRUPTS #ifdef CONFIG_STM32L4_SPI_INTERRUPTS
@ -381,7 +394,10 @@ static const struct spi_ops_s g_spi3ops =
static struct stm32l4_spidev_s g_spi3dev = static struct stm32l4_spidev_s g_spi3dev =
{ {
.spidev = { &g_spi3ops }, .spidev =
{
&g_spi3ops
},
.spibase = STM32L4_SPI3_BASE, .spibase = STM32L4_SPI3_BASE,
.spiclock = STM32L4_PCLK1_FREQUENCY, .spiclock = STM32L4_PCLK1_FREQUENCY,
#ifdef CONFIG_STM32L4_SPI_INTERRUPTS #ifdef CONFIG_STM32L4_SPI_INTERRUPTS
@ -637,7 +653,15 @@ static void spi_dmarxwait(FAR struct stm32l4_spidev_s *priv)
#ifdef CONFIG_STM32L4_SPI_DMA #ifdef CONFIG_STM32L4_SPI_DMA
static void spi_dmatxwait(FAR struct stm32l4_spidev_s *priv) static void spi_dmatxwait(FAR struct stm32l4_spidev_s *priv)
{ {
nxsem_wait_uninterruptible(&priv->txsem); /* Take the semaphore (perhaps waiting). If the result is zero, then the DMA
* must not really have completed???
*/
do
{
nxsem_wait_uninterruptible(&priv->txsem);
}
while (priv->txresult == 0);
} }
#endif #endif
@ -770,8 +794,10 @@ static void spi_dmarxsetup(FAR struct stm32l4_spidev_s *priv, FAR void *rxbuffer
************************************************************************************/ ************************************************************************************/
#ifdef CONFIG_STM32L4_SPI_DMA #ifdef CONFIG_STM32L4_SPI_DMA
static void spi_dmatxsetup(FAR struct stm32l4_spidev_s *priv, FAR const void *txbuffer, static void spi_dmatxsetup(FAR struct stm32l4_spidev_s *priv,
FAR const void *txdummy, size_t nwords) FAR const void *txbuffer,
FAR const void *txdummy,
size_t nwords)
{ {
/* 8- or 16-bit mode? */ /* 8- or 16-bit mode? */
@ -1111,6 +1137,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
if (nbits != priv->nbits) if (nbits != priv->nbits)
{ {
/* Yes... Set CR2 appropriately */ /* Yes... Set CR2 appropriately */
/* Set the number of bits (valid range 4-16) */ /* Set the number of bits (valid range 4-16) */
if (nbits < 4 || nbits > 16) if (nbits < 4 || nbits > 16)
@ -1141,7 +1168,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
/* Save the selection so the subsequence re-configurations will be faster */ /* Save the selection so the subsequence re-configurations will be faster */
priv->nbits = savbits; // nbits has been clobbered... save the signed value. priv->nbits = savbits; /* nbits has been clobbered... save the signed value. */
} }
} }
@ -1247,7 +1274,7 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
} }
else else
{ {
spi_writebyte(priv, (uint8_t)(wd & 0xFF)); spi_writebyte(priv, (uint8_t)(wd & 0xff));
ret = (uint16_t)spi_readbyte(priv); ret = (uint16_t)spi_readbyte(priv);
} }
@ -1515,7 +1542,9 @@ static int spi_trigger(FAR struct spi_dev_s *dev)
************************************************************************************/ ************************************************************************************/
#ifndef CONFIG_SPI_EXCHANGE #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); spiinfo("txbuffer=%p nwords=%d\n", txbuffer, nwords);
return spi_exchange(dev, txbuffer, NULL, nwords); return spi_exchange(dev, txbuffer, NULL, nwords);
@ -1542,7 +1571,9 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *txbuffer, si
************************************************************************************/ ************************************************************************************/
#ifndef CONFIG_SPI_EXCHANGE #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); spiinfo("rxbuffer=%p nwords=%d\n", rxbuffer, nwords);
return spi_exchange(dev, NULL, rxbuffer, nwords); return spi_exchange(dev, NULL, rxbuffer, nwords);
@ -1597,6 +1628,7 @@ static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain,
case PM_STANDBY: case PM_STANDBY:
case PM_SLEEP: case PM_SLEEP:
/* Check if exclusive lock for SPI bus is held. */ /* Check if exclusive lock for SPI bus is held. */
if (nxsem_getvalue(&priv->exclsem, &sval) < 0) if (nxsem_getvalue(&priv->exclsem, &sval) < 0)
@ -1615,6 +1647,7 @@ static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain,
break; break;
default: default:
/* Should not get here */ /* Should not get here */
break; break;
@ -1628,7 +1661,8 @@ static int spi_pm_prepare(FAR struct pm_callback_s *cb, int domain,
* Name: spi_bus_initialize * Name: spi_bus_initialize
* *
* Description: * 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: * Input Parameters:
* priv - private SPI device structure * priv - private SPI device structure
@ -1652,7 +1686,8 @@ static void spi_bus_initialize(FAR struct stm32l4_spidev_s *priv)
* 8-bit: CR2.DS=7 * 8-bit: CR2.DS=7
* MSB tranmitted first: CR1.LSBFIRST=0 * MSB tranmitted first: CR1.LSBFIRST=0
* Replace NSS with SSI & SSI=1: CR1.SSI=1 CR1.SSM=1 (prevents MODF error) * 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 * 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 | clrbits = SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_BR_MASK | SPI_CR1_LSBFIRST |