pkarashchenko commented on code in PR #6422: URL: https://github.com/apache/incubator-nuttx/pull/6422#discussion_r909297778
########## arch/arm/src/stm32wb/hardware/stm32wb_dmamux.h: ########## @@ -0,0 +1,284 @@ +/**************************************************************************** + * arch/arm/src/stm32wb/hardware/stm32wb_dmamux.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32WB_HARDWARE_STM32WB_DMAMUX_H +#define __ARCH_ARM_SRC_STM32WB_HARDWARE_STM32WB_DMAMUX_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include "chip.h" +#include "stm32wb_dma.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DMAMUX1 0 + +/* Register Offsets *********************************************************/ + +#define STM32WB_DMAMUX_CXCR_OFFSET(x) (0x0000 + 0x0004*(x)) /* DMAMUX1 request line multiplexer channel x configuration register */ +#define STM32WB_DMAMUX_C0CR_OFFSET STM32WB_DMAMUX_CXCR_OFFSET(0) +#define STM32WB_DMAMUX_C1CR_OFFSET STM32WB_DMAMUX_CXCR_OFFSET(1) +#define STM32WB_DMAMUX_C2CR_OFFSET STM32WB_DMAMUX_CXCR_OFFSET(2) +#define STM32WB_DMAMUX_C3CR_OFFSET STM32WB_DMAMUX_CXCR_OFFSET(3) +#define STM32WB_DMAMUX_C4CR_OFFSET STM32WB_DMAMUX_CXCR_OFFSET(4) +#define STM32WB_DMAMUX_C5CR_OFFSET STM32WB_DMAMUX_CXCR_OFFSET(5) +#define STM32WB_DMAMUX_C6CR_OFFSET STM32WB_DMAMUX_CXCR_OFFSET(6) +#define STM32WB_DMAMUX_C7CR_OFFSET STM32WB_DMAMUX_CXCR_OFFSET(7) +#define STM32WB_DMAMUX_C8CR_OFFSET STM32WB_DMAMUX_CXCR_OFFSET(8) +#define STM32WB_DMAMUX_C9CR_OFFSET STM32WB_DMAMUX_CXCR_OFFSET(9) +#define STM32WB_DMAMUX_C10CR_OFFSET STM32WB_DMAMUX_CXCR_OFFSET(10) +#define STM32WB_DMAMUX_C11CR_OFFSET STM32WB_DMAMUX_CXCR_OFFSET(11) +#define STM32WB_DMAMUX_C12CR_OFFSET STM32WB_DMAMUX_CXCR_OFFSET(12) +#define STM32WB_DMAMUX_C13CR_OFFSET STM32WB_DMAMUX_CXCR_OFFSET(13) + /* 0x034-0x07C: Reserved */ +#define STM32WB_DMAMUX_CSR_OFFSET 0x0080 /* DMAMUX1 request line multiplexer interrupt channel status register */ +#define STM32WB_DMAMUX_CFR_OFFSET 0x0084 /* DMAMUX1 request line multiplexer interrupt clear flag register */ + /* 0x088-0x0FC: Reserved */ + +#define STM32WB_DMAMUX_RGXCR_OFFSET(x) (0x0100+0x004*(x)) /* DMAMUX1 request generator channel x configuration register */ Review Comment: ```suggestion #define STM32WB_DMAMUX_RGXCR_OFFSET(x) (0x0100 + 0x004 * (x)) /* DMAMUX1 request generator channel x configuration register */ ``` ########## arch/arm/src/stm32wb/stm32wb_dma.h: ########## @@ -0,0 +1,281 @@ +/**************************************************************************** + * arch/arm/src/stm32wb/stm32wb_dma.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32WB_STM32WB_DMA_H +#define __ARCH_ARM_SRC_STM32WB_STM32WB_DMA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include <sys/types.h> + +#include "chip.h" + +#include "hardware/stm32wb_dma.h" +#include "hardware/stm32wb_dmamux.h" + +/* These definitions provide the bit encoding of the 'status' parameter + * passed to the DMA callback function (see dma_callback_t). + */ + +# define DMA_STATUS_TEIF DMA_CHAN_TEIF_BIT /* Channel Transfer Error */ +# define DMA_STATUS_HTIF DMA_CHAN_HTIF_BIT /* Channel Half Transfer */ +# define DMA_STATUS_TCIF DMA_CHAN_TCIF_BIT /* Channel Transfer Complete */ + +#define DMA_STATUS_ERROR (DMA_STATUS_TEIF) +#define DMA_STATUS_SUCCESS (DMA_STATUS_TCIF|DMA_STATUS_HTIF) Review Comment: ```suggestion #define DMA_STATUS_SUCCESS (DMA_STATUS_TCIF | DMA_STATUS_HTIF) ``` ########## arch/arm/src/stm32wb/stm32wb_spi.c: ########## @@ -0,0 +1,1819 @@ +/**************************************************************************** + * arch/arm/src/stm32wb/stm32wb_spi.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * The external functions, stm32wb_spi1/2select and stm32wb_spi1/2status + * 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 + * stm32wb_spibus_initialize()) are provided by common STM32 logic. To use + * this common SPI logic on your board: + * + * 1. Provide logic in stm32wb_board_initialize() to configure SPI chip + * select pins. + * 2. Provide stm32wb_spi1/2select() and stm32wb_spi1/2status() + * 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 stm32wb_spibus_initialize() in your low level + * application initialization logic + * 4. The handle returned by stm32wb_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 STM32WB 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> + +#include <sys/types.h> +#include <inttypes.h> +#include <stdint.h> +#include <stdbool.h> +#include <stddef.h> +#include <assert.h> +#include <errno.h> +#include <debug.h> + +#include <nuttx/irq.h> +#include <nuttx/arch.h> +#include <nuttx/semaphore.h> +#include <nuttx/spi/spi.h> +#include <nuttx/power/pm.h> + +#include "arm_internal.h" +#include "chip.h" +#include "stm32wb.h" +#include "stm32wb_gpio.h" +#include "stm32wb_dma.h" +#include "stm32wb_spi.h" + +#include <arch/board/board.h> + +#if defined(CONFIG_STM32WB_SPI1) || defined(CONFIG_STM32WB_SPI2) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* SPI interrupts */ + +#ifdef CONFIG_STM32WB_SPI_INTERRUPTS +# error "Interrupt driven SPI not yet supported" +#endif + +/* Can't have both interrupt driven SPI and SPI DMA */ + +#if defined(CONFIG_STM32WB_SPI_INTERRUPTS) && defined(CONFIG_STM32WB_SPI_DMA) +# error "Cannot enable both interrupt mode and DMA mode for SPI" +#endif + +/* SPI DMA priority */ + +#ifdef CONFIG_STM32WB_SPI_DMA + +# if defined(CONFIG_SPI_DMAPRIO) +# define SPI_DMA_PRIO CONFIG_SPI_DMAPRIO +# else +# define SPI_DMA_PRIO DMA_CCR_PRIMED +# endif + +# if (SPI_DMA_PRIO & ~DMA_CCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_SPI_DMAPRIO" +# endif + +#endif + +/* DMA channel configuration */ + +#define SPI_RXDMA16_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_16BITS|DMA_CCR_PSIZE_16BITS|DMA_CCR_MINC ) +#define SPI_RXDMA8_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS |DMA_CCR_MINC ) +#define SPI_RXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_16BITS ) +#define SPI_RXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS ) +#define SPI_TXDMA16_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_16BITS|DMA_CCR_PSIZE_16BITS|DMA_CCR_MINC|DMA_CCR_DIR) +#define SPI_TXDMA8_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS |DMA_CCR_MINC|DMA_CCR_DIR) +#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 stm32wb_spidev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + uint32_t spibase; /* SPIn base address */ + uint32_t spiclock; /* Clocking for the SPI module */ +#ifdef CONFIG_STM32WB_SPI_INTERRUPTS + uint8_t spiirq; /* SPI IRQ number */ +#endif +#ifdef CONFIG_STM32WB_SPI_DMA + volatile uint8_t rxresult; /* Result of the RX DMA */ + volatile uint8_t txresult; /* Result of the RX DMA */ +#ifdef CONFIG_SPI_TRIGGER + bool defertrig; /* Flag indicating that trigger should be deferred */ + bool trigarmed; /* Flag indicating that the trigger is armed */ +#endif + uint16_t rxch; /* The RX DMA channel number */ + uint16_t txch; /* The TX DMA channel number */ + DMA_HANDLE rxdma; /* DMA channel handle for RX transfers */ + DMA_HANDLE txdma; /* DMA channel handle for TX transfers */ + sem_t rxsem; /* Wait for RX DMA to complete */ + sem_t txsem; /* Wait for TX DMA to complete */ + uint32_t txccr; /* DMA control register for TX transfers */ + uint32_t rxccr; /* DMA control register for RX transfers */ +#endif + bool initialized; /* Has SPI interface been initialized */ + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + uint8_t nbits; /* Width of word in bits (4 through 16) */ + uint8_t mode; /* Mode 0,1,2,3 */ +#ifdef CONFIG_PM + struct pm_callback_s pm_cb; /* PM callbacks */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Helpers */ + +static inline uint16_t spi_getreg(struct stm32wb_spidev_s *priv, + uint8_t offset); +static inline void spi_putreg(struct stm32wb_spidev_s *priv, + uint8_t offset, uint16_t value); +static inline uint16_t spi_readword(struct stm32wb_spidev_s *priv); +static inline void spi_writeword(struct stm32wb_spidev_s *priv, + uint16_t byte); +static inline bool spi_16bitmode(struct stm32wb_spidev_s *priv); + +/* DMA support */ + +#ifdef CONFIG_STM32WB_SPI_DMA +static int spi_dmarxwait(struct stm32wb_spidev_s *priv); +static int spi_dmatxwait(struct stm32wb_spidev_s *priv); +static inline void spi_dmarxwakeup(struct stm32wb_spidev_s *priv); +static inline void spi_dmatxwakeup(struct stm32wb_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_dmarxsetup(struct stm32wb_spidev_s *priv, + void *rxbuffer, void *rxdummy, + size_t nwords); +static void spi_dmatxsetup(struct stm32wb_spidev_s *priv, + const void *txbuffer, + const void *txdummy, size_t nwords); +static inline void spi_dmarxstart(struct stm32wb_spidev_s *priv); +static inline void spi_dmatxstart(struct stm32wb_spidev_s *priv); +#endif + +/* SPI methods */ + +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); +#ifdef CONFIG_SPI_HWFEATURES +static int spi_hwfeatures(struct spi_dev_s *dev, + spi_hwfeatures_t features); +#endif +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); +#ifdef CONFIG_SPI_TRIGGER +static int spi_trigger(struct spi_dev_s *dev); +#endif +#ifndef CONFIG_SPI_EXCHANGE +static void spi_sndblock(struct spi_dev_s *dev, + const void *txbuffer, size_t nwords); +static void spi_recvblock(struct spi_dev_s *dev, + void *rxbuffer, size_t nwords); +#endif + +/* Initialization */ + +static void spi_bus_initialize(struct stm32wb_spidev_s *priv); + +/* PM interface */ + +#ifdef CONFIG_PM +static int spi_pm_prepare(struct pm_callback_s *cb, int domain, + enum pm_state_e pmstate); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_STM32WB_SPI1 +static const struct spi_ops_s g_spi1ops = +{ + .lock = spi_lock, + .select = stm32wb_spi1select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = spi_hwfeatures, +#endif + .status = stm32wb_spi1status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = stm32wb_spi1cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_TRIGGER + .trigger = spi_trigger, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = stm32wb_spi1register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct stm32wb_spidev_s g_spi1dev = +{ + .spidev = + { + &g_spi1ops + }, + .spibase = STM32WB_SPI1_BASE, + .spiclock = STM32WB_PCLK2_FREQUENCY, +#ifdef CONFIG_STM32WB_SPI_INTERRUPTS + .spiirq = STM32WB_IRQ_SPI1, +#endif +#ifdef CONFIG_STM32WB_SPI_DMA + /* lines must be configured in board.h */ + + .rxch = DMAMAP_SPI1_RX, + .txch = DMAMAP_SPI1_TX, +#endif +#ifdef CONFIG_PM + .pm_cb.prepare = spi_pm_prepare, +#endif +}; +#endif + +#ifdef CONFIG_STM32WB_SPI2 +static const struct spi_ops_s g_spi2ops = +{ + .lock = spi_lock, + .select = stm32wb_spi2select, + .setfrequency = spi_setfrequency, + .setmode = spi_setmode, + .setbits = spi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = spi_hwfeatures, +#endif + .status = stm32wb_spi2status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = stm32wb_spi2cmddata, +#endif + .send = spi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = spi_exchange, +#else + .sndblock = spi_sndblock, + .recvblock = spi_recvblock, +#endif +#ifdef CONFIG_SPI_TRIGGER + .trigger = spi_trigger, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = stm32wb_spi2register, /* provided externally */ +#else + .registercallback = 0, /* not implemented */ +#endif +}; + +static struct stm32wb_spidev_s g_spi2dev = +{ + .spidev = + { + &g_spi2ops + }, + .spibase = STM32WB_SPI2_BASE, + .spiclock = STM32WB_PCLK1_FREQUENCY, +#ifdef CONFIG_STM32WB_SPI_INTERRUPTS + .spiirq = STM32WB_IRQ_SPI2, +#endif +#ifdef CONFIG_STM32WB_SPI_DMA + .rxch = DMACHAN_SPI2_RX, + .txch = DMACHAN_SPI2_TX, +#endif +#ifdef CONFIG_PM + .pm_cb.prepare = spi_pm_prepare, +#endif +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_getreg + * + * Description: + * Get the contents of the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * + * Returned Value: + * The contents of the 16-bit register + * + ****************************************************************************/ + +static inline uint16_t spi_getreg(struct stm32wb_spidev_s *priv, + uint8_t offset) +{ + return getreg16(priv->spibase + offset); +} + +/**************************************************************************** + * Name: spi_putreg + * + * Description: + * Write a 16-bit value to the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * value - the 16-bit value to be written + * + * Returned Value: + * The contents of the 16-bit register + * + ****************************************************************************/ + +static inline void spi_putreg(struct stm32wb_spidev_s *priv, + uint8_t offset, uint16_t value) +{ + putreg16(value, priv->spibase + offset); +} + +/**************************************************************************** + * Name: spi_getreg8 + * + * Description: + * Get the contents of the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * + * Returned Value: + * The contents of the 8-bit register + * + ****************************************************************************/ + +static inline uint8_t spi_getreg8(struct stm32wb_spidev_s *priv, + uint8_t offset) +{ + return getreg8(priv->spibase + offset); +} + +/**************************************************************************** + * Name: spi_putreg8 + * + * Description: + * Write a 8-bit value to the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * value - the 8-bit value to be written + * + ****************************************************************************/ + +static inline void spi_putreg8(struct stm32wb_spidev_s *priv, + uint8_t offset, uint8_t value) +{ + putreg8(value, priv->spibase + offset); +} + +/**************************************************************************** + * Name: spi_readword + * + * Description: + * Read one word (TWO bytes!) from SPI + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * Word as read + * + ****************************************************************************/ + +static inline uint16_t spi_readword(struct stm32wb_spidev_s *priv) +{ + /* Wait until the receive buffer is not empty */ + + while ((spi_getreg(priv, STM32WB_SPI_SR_OFFSET) & SPI_SR_RXNE) == 0); + + /* Then return the received byte */ + + return spi_getreg(priv, STM32WB_SPI_DR_OFFSET); +} + +/**************************************************************************** + * Name: spi_readbyte + * + * Description: + * Read one byte from SPI + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * Byte as read + * + ****************************************************************************/ + +static inline uint8_t spi_readbyte(struct stm32wb_spidev_s *priv) +{ + /* Wait until the receive buffer is not empty */ + + while ((spi_getreg(priv, STM32WB_SPI_SR_OFFSET) & SPI_SR_RXNE) == 0); + + /* Then return the received byte */ + + return spi_getreg8(priv, STM32WB_SPI_DR_OFFSET); +} + +/**************************************************************************** + * Name: spi_writeword + * + * Description: + * Write one 16-bit frame to the SPI FIFO + * + * Input Parameters: + * priv - Device-specific state data + * byte - Word to send + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void spi_writeword(struct stm32wb_spidev_s *priv, + uint16_t word) +{ + /* Wait until the transmit buffer is empty */ + + while ((spi_getreg(priv, STM32WB_SPI_SR_OFFSET) & SPI_SR_TXE) == 0); + + /* Then send the byte */ + + spi_putreg(priv, STM32WB_SPI_DR_OFFSET, word); +} + +/**************************************************************************** + * Name: spi_writebyte + * + * Description: + * Write one 8-bit frame to the SPI FIFO + * + * Input Parameters: + * priv - Device-specific state data + * byte - Byte to send + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void spi_writebyte(struct stm32wb_spidev_s *priv, + uint8_t byte) +{ + /* Wait until the transmit buffer is empty */ + + while ((spi_getreg(priv, STM32WB_SPI_SR_OFFSET) & SPI_SR_TXE) == 0); + + /* Then send the byte */ + + spi_putreg8(priv, STM32WB_SPI_DR_OFFSET, byte); +} + +/**************************************************************************** + * Name: spi_16bitmode + * + * Description: + * Check if the SPI is operating in 16-bit mode + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * true: 16-bit mode, false: 8-bit mode + * + ****************************************************************************/ + +static inline bool spi_16bitmode(struct stm32wb_spidev_s *priv) +{ + return (priv->nbits > 8); +} + +/**************************************************************************** + * Name: spi_dmarxwaitw + * + * Description: + * Wait for DMA to complete. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32WB_SPI_DMA +static int spi_dmarxwait(struct stm32wb_spidev_s *priv) +{ + int ret; + + /* Take the semaphore (perhaps waiting). If the result is zero, then the + * DMA must not really have completed??? + */ + + do + { + ret = nxsem_wait_uninterruptible(&priv->rxsem); + + /* The only expected error is ECANCELED which would occur if the + * calling thread were canceled. + */ + + DEBUGASSERT(ret == OK || ret == -ECANCELED); + } + while (priv->rxresult == 0 && ret == OK); Review Comment: I reviewed again this part and I think you are right. My main concern was that semaphore could be signalled after waiter exists with `ECANCELED` and the next call will take semaphore with no wait because of the previous call as there is not reset of a semaphore before DMA transaction starts. But logic is a bit more tricky here. The "previous" calls are consumed by `priv->rxresult == 0` condition, so even semaphore wait returns OK we will try to take semaphore again due to other condition, so the only exit criteria from the wait loop is either `ECANCELED` or `priv->rxresult != 0` + `ret == OK`. So the checking of return value makes sense and I we will need to fix part from https://github.com/apache/incubator-nuttx/pull/6492 as well. probably I will do it in the new PR. ########## arch/arm/src/stm32wb/hardware/stm32wb_dmamux.h: ########## @@ -0,0 +1,284 @@ +/**************************************************************************** + * arch/arm/src/stm32wb/hardware/stm32wb_dmamux.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32WB_HARDWARE_STM32WB_DMAMUX_H +#define __ARCH_ARM_SRC_STM32WB_HARDWARE_STM32WB_DMAMUX_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include "chip.h" +#include "stm32wb_dma.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DMAMUX1 0 + +/* Register Offsets *********************************************************/ + +#define STM32WB_DMAMUX_CXCR_OFFSET(x) (0x0000 + 0x0004*(x)) /* DMAMUX1 request line multiplexer channel x configuration register */ Review Comment: ```suggestion #define STM32WB_DMAMUX_CXCR_OFFSET(x) (0x0000 + 0x0004 * (x)) /* DMAMUX1 request line multiplexer channel x configuration register */ ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
