Looks like the patch which I tried to attach was lost on the way. Trying again with .txt suffix...
From 292153fc368976c8abbd65fdd1b48b3bbc93e998 Mon Sep 17 00:00:00 2001 From: Jukka Laitinen <jukka.laiti...@intel.com> Date: Fri, 20 Sep 2019 09:17:10 +0300 Subject: [PATCH] Update to SPI slave intefaces Make it possible to enqueue and receive full buffers of data with single call, to avoid call overhead when sending / receiving large amounts of data. Also make it possible for the slave device to leave received data in the controller receive buffers and retrieve it from there by polling Signed-off-by: Jukka Laitinen <jukka.laiti...@intel.com> --- arch/arm/src/samv7/sam_spi_slave.c | 6 ++-- include/nuttx/spi/slave.h | 56 ++++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/arch/arm/src/samv7/sam_spi_slave.c b/arch/arm/src/samv7/sam_spi_slave.c index 9845ce83f5..6095d465b2 100644 --- a/arch/arm/src/samv7/sam_spi_slave.c +++ b/arch/arm/src/samv7/sam_spi_slave.c @@ -485,7 +485,7 @@ static int spi_interrupt(int irq, void *context, FAR void *arg) /* Report the receipt of data to the SPI device driver */ - SPI_SDEV_RECEIVE(priv->sdev, data); + SPI_SDEV_RECEIVE(priv->sdev, (const uint16_t*)&data, sizeof(data)); } /* When a transfer starts, the data shifted out is the data present @@ -763,6 +763,7 @@ static void spi_bind(struct spi_sctrlr_s *sctrlr, struct sam_spidev_s *priv = (struct sam_spidev_s *)sctrlr; uint32_t regval; int ret; + const uint16_t* data; spiinfo("sdev=%p mode=%d nbits=%d\n", sdv, mode, nbits); @@ -812,7 +813,8 @@ static void spi_bind(struct spi_sctrlr_s *sctrlr, * be shifted out the SPI clock is detected. */ - priv->outval = SPI_SDEV_GETDATA(sdev); + SPI_SDEV_GETDATA(sdev, &data); + priv->outval = *data; spi_putreg(priv, priv->outval, SAM_SPI_TDR_OFFSET); /* Setup to begin normal SPI operation */ diff --git a/include/nuttx/spi/slave.h b/include/nuttx/spi/slave.h index a979d22c42..b7f7682ee1 100644 --- a/include/nuttx/spi/slave.h +++ b/include/nuttx/spi/slave.h @@ -109,18 +109,20 @@ * * Input Parameters: * sctrlr - SPI slave controller interface instance - * data - Command/data mode data value to be shifted out. The width of - * the data must be the same as the nbits parameter previously - * provided to the bind() methods. + * data - Pointer to the command/data mode data to be shifted out. + * The alignment of the data must be the same as the nbits parameter + * previously provided to the bind() methods. + * len - Number of bytes to enqueue * * Returned Value: - * Zero if the word was successfully queue; A negated errno valid is - * returned on any failure to enqueue the word (such as if the queue is - * full). + * Number of data items successfully queued, or a negated errno: + * - "len" if all the data was successfully queued + * - "0..len-1" if queue is full + * - "-errno" in any other error * ****************************************************************************/ -#define SPI_SCTRLR_ENQUEUE(c,v) ((c)->ops->enqueue(c,v)) +#define SPI_SCTRLR_ENQUEUE(c,v,l) ((c)->ops->enqueue(c,v,l)) /**************************************************************************** * Name: SPI_SCTRLR_QFULL @@ -157,6 +159,23 @@ #define SPI_SCTRLR_QFLUSH(c) ((c)->ops->qflush(c)) +/**************************************************************************** + * Name: SPI_SCTRLR_RXQPOLL + * + * Description: + * Tell the controller to output all the receive queue data. + * + * Input Parameters: + * sctrlr - SPI slave controller interface instance + * + * Returned Value: + * Number of bytes left in the rx queue. If the device accepted all the + * data, the return value will be 0 + * + ****************************************************************************/ + +#define SPI_SCTRLR_RXQPOLL(c) ((c)->ops->rxqpoll(c)) + /**************************************************************************** * Name: SPI_SDEV_SELECT * @@ -222,9 +241,11 @@ * * Input Parameters: * sdev - SPI device interface instance + * data - Pointer to the data buffer pointer to be shifed out. + * The device will set the data buffer pointer to the actual data * * Returned Value: - * The next data value to be shifted out + * The number of data bytes to be shifted out from the data buffer * * Assumptions: * May be called from an interrupt handler and the response is usually @@ -232,7 +253,7 @@ * ****************************************************************************/ -#define SPI_SDEV_GETDATA(d) ((d)->ops->getdata(d)) +#define SPI_SDEV_GETDATA(d,v) ((d)->ops->getdata(d,v)) /**************************************************************************** * Name: SPI_SDEV_RECEIVE @@ -245,10 +266,12 @@ * * Input Parameters: * sdev - SPI device interface instance - * data - The last command/data value that was shifted in + * data - Pointer to the new data that has been shifted in + * len - Length of the new data in bytes * * Returned Value: - * None + * Number of bytes accepted by the device. In other words, + * number of bytes to be removed from controller's receive queue. * * Assumptions: * May be called from an interrupt handler and in time-critical @@ -258,7 +281,7 @@ * ****************************************************************************/ -#define SPI_SDEV_RECEIVE(d,v) ((d)->ops->receive(d,v)) +#define SPI_SDEV_RECEIVE(d,v,l) ((d)->ops->receive(d,v,l)) /**************************************************************************** * Public Types @@ -451,9 +474,11 @@ struct spi_sctrlrops_s FAR struct spi_sdev_s *sdev, enum spi_smode_e mode, int nbits); CODE void (*unbind)(FAR struct spi_sctrlr_s *sctrlr); - CODE int (*enqueue)(FAR struct spi_sctrlr_s *sctrlr, uint16_t data); + CODE int (*enqueue)(FAR struct spi_sctrlr_s *sctrlr, + const uint16_t *data, uint16_t len); CODE bool (*qfull)(FAR struct spi_sctrlr_s *sctrlr); CODE void (*qflush)(FAR struct spi_sctrlr_s *sctrlr); + CODE uint16_t (*rxqpoll)(FAR struct spi_sctrlr_s *sctrlr); }; /* SPI slave controller private data. This structure only defines the @@ -475,8 +500,9 @@ struct spi_sdevops_s { CODE void (*select)(FAR struct spi_sdev_s *sdev, bool selected); CODE void (*cmddata)(FAR struct spi_sdev_s *sdev, bool data); - CODE uint16_t (*getdata)(FAR struct spi_sdev_s *sdev); - CODE void (*receive)(FAR struct spi_sdev_s *sdev, uint16_t cmd); + CODE uint16_t (*getdata)(FAR struct spi_sdev_s *sdev, const uint16_t** data); + CODE uint16_t (*receive)(FAR struct spi_sdev_s *sdev, const uint16_t* cmddata, + uint16_t len); }; /* SPI slave device private data. This structure only defines the initial -- 2.25.1