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:57 UTC

[mynewt-core] 01/03: hw/bus: Add duplex_write_read function to bus_dev_ops

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 420bce6ddcbd37031cf489cc0a11b9131fe29746
Author: Jerzy Kasenberg <je...@codecoup.pl>
AuthorDate: Fri Feb 17 15:21:24 2023 +0100

    hw/bus: Add duplex_write_read function to bus_dev_ops
    
    Duplex of SPI was not covered in bus drivers.
    This adds bus_node_duplex_write_read() function that
    can be used with SPI drivers that support duplex
    mode.
    For simplicity both buffers provided to function
    have same length.
---
 hw/bus/include/bus/bus.h        | 21 +++++++++++++++++++++
 hw/bus/include/bus/bus_driver.h |  4 ++++
 hw/bus/src/bus.c                | 39 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 64 insertions(+)

diff --git a/hw/bus/include/bus/bus.h b/hw/bus/include/bus/bus.h
index 4d357f376..e43c091a1 100644
--- a/hw/bus/include/bus/bus.h
+++ b/hw/bus/include/bus/bus.h
@@ -128,6 +128,27 @@ bus_node_write_read_transact(struct os_dev *node, const void  *wbuf,
                              uint16_t wlength, void *rbuf, uint16_t rlength,
                              os_time_t timeout, uint16_t flags);
 
+/**
+ * Perform write and read in duplex mode (SPI)
+ *
+ * Writes data to node and automatically reads response at the same time.
+ *
+ * The timeout parameter applies to complete transaction time.
+ *
+ * @param node     Node device object
+ * @param wbuf     Buffer with data to be written
+ * @param rbuf     Buffer to read data into
+ * @param length   Length of data to be written and read
+ * @param timeout  Operation timeout
+ * @param flags    Flags
+ *
+ * @return 0 on success, SYS_xxx on error
+ */
+int
+bus_node_duplex_write_read(struct os_dev *node, const void *wbuf,
+                           void *rbuf, uint16_t length,
+                           os_time_t timeout, uint16_t flags);
+
 /**
  * Read data from node
  *
diff --git a/hw/bus/include/bus/bus_driver.h b/hw/bus/include/bus/bus_driver.h
index 8429ab6a2..207aeb23f 100644
--- a/hw/bus/include/bus/bus_driver.h
+++ b/hw/bus/include/bus/bus_driver.h
@@ -68,6 +68,10 @@ struct bus_dev_ops {
                        const uint8_t *wbuf, uint16_t wlength,
                        uint8_t *rbuf, uint16_t rlength,
                        os_time_t timeout,  uint16_t flags);
+    /* Duplex write and read */
+    int (* 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);
 };
 
 /**
diff --git a/hw/bus/src/bus.c b/hw/bus/src/bus.c
index 29987542a..f481be6dd 100644
--- a/hw/bus/src/bus.c
+++ b/hw/bus/src/bus.c
@@ -456,6 +456,45 @@ done:
     return rc;
 }
 
+int
+bus_node_duplex_write_read(struct os_dev *node, const void *wbuf,
+                           void *rbuf, uint16_t length,
+                           os_time_t timeout, uint16_t flags)
+{
+    struct bus_node *bnode = (struct bus_node *)node;
+    struct bus_dev *bdev = bnode->parent_bus;
+    int rc;
+
+    BUS_DEBUG_VERIFY_DEV(bdev);
+    BUS_DEBUG_VERIFY_NODE(bnode);
+
+    if (!bdev->dops->duplex_write_read) {
+        return SYS_ENOTSUP;
+    }
+
+    rc = bus_node_lock(node, bus_node_get_lock_timeout(node));
+    if (rc) {
+        return rc;
+    }
+
+    if (!bdev->enabled) {
+        rc = SYS_EIO;
+        goto done;
+    }
+
+    BUS_STATS_INC(bdev, bnode, write_ops);
+    BUS_STATS_INC(bdev, bnode, read_ops);
+    rc = bdev->dops->duplex_write_read(bdev, bnode, wbuf, rbuf, length, timeout, flags);
+    if (rc) {
+        BUS_STATS_INC(bdev, bnode, write_errors);
+        BUS_STATS_INC(bdev, bnode, read_errors);
+    }
+
+done:
+    (void)bus_node_unlock(node);
+
+    return rc;
+}
 
 int
 bus_node_lock(struct os_dev *node, os_time_t timeout)