You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by je...@apache.org on 2023/02/23 07:09:58 UTC

[mynewt-core] 02/03: bus/spi_stm32: Add implementation of duplex write/read

This is an automated email from the ASF dual-hosted git repository.

jerzy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit a7ddedcbf9bf96dee2ed2336062e3cb8345b2f6f
Author: Jerzy Kasenberg <je...@codecoup.pl>
AuthorDate: Fri Feb 17 15:23:02 2023 +0100

    bus/spi_stm32: Add implementation of duplex write/read
    
    This implements duplex_write_read for STM devices
---
 hw/bus/drivers/spi_stm32/src/spi_stm32.c | 53 ++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/hw/bus/drivers/spi_stm32/src/spi_stm32.c b/hw/bus/drivers/spi_stm32/src/spi_stm32.c
index a6b0cf5bf..931243064 100644
--- a/hw/bus/drivers/spi_stm32/src/spi_stm32.c
+++ b/hw/bus/drivers/spi_stm32/src/spi_stm32.c
@@ -651,6 +651,14 @@ HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
     os_sem_release(&dd->sem);
 }
 
+void
+HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
+{
+    struct spi_stm32_driver_data *dd = (struct spi_stm32_driver_data *)hspi;
+
+    os_sem_release(&dd->sem);
+}
+
 static int
 spi_stm32_read(struct bus_dev *bdev, struct bus_node *bnode,
                uint8_t *buf, uint16_t length, os_time_t timeout,
@@ -736,6 +744,50 @@ spi_stm32_write(struct bus_dev *bdev, struct bus_node *bnode,
     return rc;
 }
 
+static int
+spi_stm32_duplex_write_read(struct bus_dev *bdev, struct bus_node *bnode,
+                            const uint8_t *wbuf, uint8_t *rbuf, uint16_t length,
+                            os_time_t timeout, uint16_t flags)
+{
+    struct bus_spi_dev *dev = (struct bus_spi_dev *)bdev;
+    struct bus_spi_node *node = (struct bus_spi_node *)bnode;
+    struct spi_stm32_driver_data *dd;
+    int rc;
+
+    BUS_DEBUG_VERIFY_DEV(dev);
+    BUS_DEBUG_VERIFY_NODE(node);
+
+    dd = driver_data(dev);
+
+    assert(os_sem_get_count(&dd->sem) == 0);
+
+    /* Activate CS */
+    if (node->pin_cs >= 0) {
+        hal_gpio_write(node->pin_cs, 0);
+    }
+
+    if (MIN_DMA_TX_SIZE >= 0 && length >= MIN_DMA_TX_SIZE) {
+        HAL_SPI_TransmitReceive_DMA(&dd->hspi, (uint8_t *)wbuf, rbuf, length);
+    } else {
+        HAL_SPI_TransmitReceive_IT(&dd->hspi, (uint8_t *)wbuf, rbuf, length);
+    }
+
+    rc = os_sem_pend(&dd->sem, timeout);
+
+    if (rc) {
+        HAL_SPI_Abort(&dd->hspi);
+    }
+
+    rc = os_error_to_sys(rc);
+
+    /* Deactivate CS if needed */
+    if ((rc != 0 || !(flags & BUS_F_NOSTOP)) && node->pin_cs >= 0) {
+        hal_gpio_write(node->pin_cs, 1);
+    }
+
+    return rc;
+}
+
 static int
 spi_stm32_enable(struct bus_dev *bdev)
 {
@@ -772,6 +824,7 @@ static const struct bus_dev_ops bus_spi_stm32_ops = {
     .read = spi_stm32_read,
     .write = spi_stm32_write,
     .disable = spi_stm32_disable,
+    .duplex_write_read = spi_stm32_duplex_write_read,
 };
 
 /* Helper function to setup interrupt handler for SPI and DMA */