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


The following commit(s) were added to refs/heads/master by this push:
     new 3bb49f717 bus: Allow configuration change for a node
3bb49f717 is described below

commit 3bb49f717bff9ef300c5060ce8dba8ef53d48734
Author: Jerzy Kasenberg <[email protected]>
AuthorDate: Sat May 10 14:04:51 2025 +0200

    bus: Allow configuration change for a node
    
    It was impossible to change basic configuration
    for SPI/I2C device once it was used.
    If only one devices is connected to SPI lines
    and device requires for example different frequency
    during work (like for SD card) it was impossible
    to change it.
    Now node can have change settings and drivers
    will check actual parameters and not only whether
    same device is being used.
    
    Signed-off-by: Jerzy Kasenberg <[email protected]>
---
 hw/bus/drivers/i2c_common/include/bus/drivers/i2c_common.h |  4 ++++
 hw/bus/drivers/i2c_da1469x/src/i2c_da1469x.c               |  3 +++
 hw/bus/drivers/i2c_hal/src/i2c_hal.c                       |  5 +++--
 hw/bus/drivers/i2c_nrf52_twim/src/i2c_nrf52_twim.c         |  8 +++++++-
 hw/bus/drivers/i2c_nrf5340/src/i2c_nrf5340.c               |  8 +++++++-
 hw/bus/drivers/i2c_nrf91_twim/src/i2c_nrf91_twim.c         | 13 ++++++++-----
 hw/bus/drivers/spi_apollo3/src/spi_apollo3.c               | 10 ++++++----
 hw/bus/drivers/spi_common/include/bus/drivers/spi_common.h |  6 ++++++
 hw/bus/drivers/spi_da1469x/src/spi_da1469x.c               | 12 ++++++++----
 hw/bus/drivers/spi_hal/src/spi_hal.c                       | 10 ++++++----
 hw/bus/drivers/spi_stm32/src/spi_stm32.c                   | 10 +++++-----
 hw/bus/src/bus.c                                           |  5 -----
 12 files changed, 63 insertions(+), 31 deletions(-)

diff --git a/hw/bus/drivers/i2c_common/include/bus/drivers/i2c_common.h 
b/hw/bus/drivers/i2c_common/include/bus/drivers/i2c_common.h
index e7fa161d4..8c7460a43 100644
--- a/hw/bus/drivers/i2c_common/include/bus/drivers/i2c_common.h
+++ b/hw/bus/drivers/i2c_common/include/bus/drivers/i2c_common.h
@@ -53,6 +53,10 @@ struct bus_i2c_dev_cfg {
 struct bus_i2c_dev {
     struct bus_dev bdev;
     struct bus_i2c_dev_cfg cfg;
+    /** I2C address */
+    uint16_t addr;
+    /** I2C frequency in kHz */
+    uint16_t freq;
 
 #if MYNEWT_VAL(BUS_DEBUG_OS_DEV)
     uint32_t devmagic;
diff --git a/hw/bus/drivers/i2c_da1469x/src/i2c_da1469x.c 
b/hw/bus/drivers/i2c_da1469x/src/i2c_da1469x.c
index a47363654..f40dc6a10 100644
--- a/hw/bus/drivers/i2c_da1469x/src/i2c_da1469x.c
+++ b/hw/bus/drivers/i2c_da1469x/src/i2c_da1469x.c
@@ -421,6 +421,9 @@ i2c_da1469x_configure_controller(struct bus_i2c_dev *dev, 
uint8_t address, uint1
 
     BUS_DEBUG_VERIFY_DEV(dev);
 
+    if (dev->addr == address && dev->freq == freq) {
+        goto end;
+    }
     i2c_regs = da1469x_i2c[dev->cfg.i2c_num].regs;
 
     if (i2c_regs->I2C_ENABLE_REG & I2C_I2C_ENABLE_REG_I2C_EN_Msk) {
diff --git a/hw/bus/drivers/i2c_hal/src/i2c_hal.c 
b/hw/bus/drivers/i2c_hal/src/i2c_hal.c
index 2c6ed684c..8e9fb1689 100644
--- a/hw/bus/drivers/i2c_hal/src/i2c_hal.c
+++ b/hw/bus/drivers/i2c_hal/src/i2c_hal.c
@@ -82,14 +82,13 @@ bus_i2c_configure(struct bus_dev *bdev, struct bus_node 
*bnode)
 {
     struct bus_i2c_dev *dev = (struct bus_i2c_dev *)bdev;
     struct bus_i2c_node *node = (struct bus_i2c_node *)bnode;
-    struct bus_i2c_node *current_node = (struct bus_i2c_node 
*)bdev->configured_for;
     struct hal_i2c_settings i2c_cfg;
     int rc;
 
     BUS_DEBUG_VERIFY_DEV(dev);
     BUS_DEBUG_VERIFY_NODE(node);
 
-    if (current_node && (current_node->freq == node->freq)) {
+    if (dev->freq == node->freq) {
         return 0;
     }
 
@@ -104,6 +103,8 @@ bus_i2c_configure(struct bus_dev *bdev, struct bus_node 
*bnode)
     if (rc) {
         goto done;
     }
+    dev->freq = node->freq;
+    dev->addr = node->addr;
 
     rc = hal_i2c_enable(dev->cfg.i2c_num);
 
diff --git a/hw/bus/drivers/i2c_nrf52_twim/src/i2c_nrf52_twim.c 
b/hw/bus/drivers/i2c_nrf52_twim/src/i2c_nrf52_twim.c
index ad43f6167..18ba7e1a6 100644
--- a/hw/bus/drivers/i2c_nrf52_twim/src/i2c_nrf52_twim.c
+++ b/hw/bus/drivers/i2c_nrf52_twim/src/i2c_nrf52_twim.c
@@ -406,6 +406,10 @@ bus_i2c_nrf52_twim_configure_controller(struct bus_i2c_dev 
*dev, uint8_t address
 
     BUS_DEBUG_VERIFY_DEV(dev);
 
+    if (dev->freq == freq && dev->addr == address) {
+        goto end;
+    }
+
     nrf_twim = twims[dev->cfg.i2c_num].nrf_twim;
 
     switch (freq) {
@@ -427,8 +431,10 @@ bus_i2c_nrf52_twim_configure_controller(struct bus_i2c_dev 
*dev, uint8_t address
 
     if (rc == 0) {
         nrf_twim->ADDRESS = address;
+        dev->addr = address;
+        dev->freq = freq;
     }
-
+end:
     return rc;
 }
 
diff --git a/hw/bus/drivers/i2c_nrf5340/src/i2c_nrf5340.c 
b/hw/bus/drivers/i2c_nrf5340/src/i2c_nrf5340.c
index b35431044..c3329e675 100644
--- a/hw/bus/drivers/i2c_nrf5340/src/i2c_nrf5340.c
+++ b/hw/bus/drivers/i2c_nrf5340/src/i2c_nrf5340.c
@@ -207,6 +207,10 @@ bus_i2c_nrf5340_configure_controller(struct bus_i2c_dev 
*dev, uint8_t address, u
     NRF_TWIM_Type *nrf_twim;
     int rc = 0;
 
+    if (dev->freq == freq && dev->addr == address) {
+        goto end;
+    }
+
     nrf_twim = twims[dev->cfg.i2c_num].nrf_twim;
 
     switch (freq) {
@@ -228,8 +232,10 @@ bus_i2c_nrf5340_configure_controller(struct bus_i2c_dev 
*dev, uint8_t address, u
 
     if (rc == 0) {
         nrf_twim->ADDRESS = address;
+        dev->addr = address;
+        dev->freq = freq;
     }
-
+end:
     return rc;
 }
 
diff --git a/hw/bus/drivers/i2c_nrf91_twim/src/i2c_nrf91_twim.c 
b/hw/bus/drivers/i2c_nrf91_twim/src/i2c_nrf91_twim.c
index 302777b06..cb3508321 100644
--- a/hw/bus/drivers/i2c_nrf91_twim/src/i2c_nrf91_twim.c
+++ b/hw/bus/drivers/i2c_nrf91_twim/src/i2c_nrf91_twim.c
@@ -395,21 +395,19 @@ bus_i2c_nrf91_twim_configure(struct bus_dev *bdev, struct 
bus_node *bnode)
 {
     struct bus_i2c_dev *dev = (struct bus_i2c_dev *)bdev;
     struct bus_i2c_node *node = (struct bus_i2c_node *)bnode;
-    struct bus_i2c_node *current_node = (struct bus_i2c_node 
*)bdev->configured_for;
     NRF_TWIM_Type *nrf_twim;
     int rc;
 
     BUS_DEBUG_VERIFY_DEV(dev);
     BUS_DEBUG_VERIFY_NODE(node);
 
+    if (dev->addr == node->addr && dev->freq == node->freq) {
+        return 0;
+    }
     nrf_twim = twims[dev->cfg.i2c_num].nrf_twim;
 
     nrf_twim->ADDRESS = node->addr;
 
-    if (current_node && (current_node->freq == node->freq)) {
-        return 0;
-    }
-
     rc = 0;
 
     switch (node->freq) {
@@ -429,6 +427,11 @@ bus_i2c_nrf91_twim_configure(struct bus_dev *bdev, struct 
bus_node *bnode)
         rc = SYS_EIO;
     }
 
+    if (rc == 0) {
+        dev->freq = node->freq;
+        dev->addr = node->addr;
+    }
+
     return rc;
 }
 
diff --git a/hw/bus/drivers/spi_apollo3/src/spi_apollo3.c 
b/hw/bus/drivers/spi_apollo3/src/spi_apollo3.c
index 0a95aaa82..f5b82c88d 100644
--- a/hw/bus/drivers/spi_apollo3/src/spi_apollo3.c
+++ b/hw/bus/drivers/spi_apollo3/src/spi_apollo3.c
@@ -86,7 +86,6 @@ bus_spi_configure(struct bus_dev *bdev, struct bus_node 
*bnode)
 {
     struct bus_spi_dev *spi_dev = (struct bus_spi_dev *)bdev;
     struct bus_spi_node *node = (struct bus_spi_node *)bnode;
-    struct bus_spi_node *current_node = (struct bus_spi_node 
*)bdev->configured_for;
     struct hal_spi_settings spi_cfg;
     int rc;
 
@@ -94,9 +93,8 @@ bus_spi_configure(struct bus_dev *bdev, struct bus_node 
*bnode)
     BUS_DEBUG_VERIFY_NODE(node);
 
     /* No need to reconfigure if already configured with the same settings */
-    if (current_node && (current_node->mode == node->mode) &&
-                        (current_node->data_order == node->data_order) &&
-                        (current_node->freq == node->freq)) {
+    if ((spi_dev->mode == node->mode) && (spi_dev->data_order == 
node->data_order) &&
+        (spi_dev->freq == node->freq)) {
         return 0;
     }
 
@@ -105,6 +103,10 @@ bus_spi_configure(struct bus_dev *bdev, struct bus_node 
*bnode)
         goto done;
     }
 
+    spi_dev->freq = node->freq;
+    spi_dev->data_order = node->data_order;
+    spi_dev->mode = node->mode;
+
     spi_cfg.data_mode = node->mode;
     spi_cfg.data_order = node->data_order;
     spi_cfg.baudrate = node->freq * 1000;
diff --git a/hw/bus/drivers/spi_common/include/bus/drivers/spi_common.h 
b/hw/bus/drivers/spi_common/include/bus/drivers/spi_common.h
index 7aaf3f027..f4f8e68a0 100644
--- a/hw/bus/drivers/spi_common/include/bus/drivers/spi_common.h
+++ b/hw/bus/drivers/spi_common/include/bus/drivers/spi_common.h
@@ -41,6 +41,12 @@ struct bus_spi_dev_cfg {
 struct bus_spi_dev {
     struct bus_dev bdev;
     struct bus_spi_dev_cfg cfg;
+    /** Data mode, one of the BUS_SPI_MODE_x */
+    int mode;
+    /** Data order, one of the BUS_SPI_DATA_ORDER_LSB/MSB */
+    int data_order;
+    /** Current SPI frequency in kHz */
+    uint32_t freq;
 
 #if MYNEWT_VAL(BUS_DEBUG_OS_DEV)
     uint32_t devmagic;
diff --git a/hw/bus/drivers/spi_da1469x/src/spi_da1469x.c 
b/hw/bus/drivers/spi_da1469x/src/spi_da1469x.c
index cf8fa95b6..12e90e0f0 100644
--- a/hw/bus/drivers/spi_da1469x/src/spi_da1469x.c
+++ b/hw/bus/drivers/spi_da1469x/src/spi_da1469x.c
@@ -393,7 +393,7 @@ spi_da1469x_disable(struct bus_dev *bdev)
      * Domain COM can be powered off, register content can be lost prepare
      * to set it from scratch.
      */
-    bdev->configured_for = NULL;
+    dev->freq = 0;
 
     da1469x_pd_release(MCU_PD_DOMAIN_COM);
 
@@ -437,7 +437,6 @@ spi_da1469x_configure(struct bus_dev *bdev, struct bus_node 
*bnode)
 {
     struct bus_spi_dev *dev = (struct bus_spi_dev *)bdev;
     struct bus_spi_node *node = (struct bus_spi_node *)bnode;
-    struct bus_spi_node *current_node = (struct bus_spi_node 
*)bdev->configured_for;
     struct spi_da1469x_driver_data *dd;
     SPI_Type *regs;
     uint32_t ctrl_reg;
@@ -453,11 +452,16 @@ spi_da1469x_configure(struct bus_dev *bdev, struct 
bus_node *bnode)
         regs->SPI_CTRL_REG = ctrl_reg ^ (SPI_SPI_CTRL_REG_SPI_ON_Msk);
     }
 
-    if (current_node && (current_node->freq == node->freq) && 
current_node->mode == node->mode) {
-        /* Same device, no changes required. */
+    if ((spi_dev->mode == node->mode) && (spi_dev->data_order == 
node->data_order) &&
+        (spi_dev->freq == node->freq)) {
+        /* Same configuration, no changes required. */
         goto end;
     }
 
+    spi_dev->freq = node->freq;
+    spi_dev->data_order = node->data_order;
+    spi_dev->mode = node->mode;
+
     ctrl_reg &= ~(SPI_SPI_CTRL_REG_SPI_TX_FIFO_NOTFULL_MASK_Msk |
                   SPI_SPI_CTRL_REG_SPI_DMA_TXREQ_MODE_Msk |
                   SPI_SPI_CTRL_REG_SPI_9BIT_VAL_Msk |
diff --git a/hw/bus/drivers/spi_hal/src/spi_hal.c 
b/hw/bus/drivers/spi_hal/src/spi_hal.c
index 5384f3766..394a12995 100644
--- a/hw/bus/drivers/spi_hal/src/spi_hal.c
+++ b/hw/bus/drivers/spi_hal/src/spi_hal.c
@@ -95,7 +95,6 @@ bus_spi_configure(struct bus_dev *bdev, struct bus_node 
*bnode)
 {
     struct bus_spi_dev *spi_dev = (struct bus_spi_dev *)bdev;
     struct bus_spi_node *node = (struct bus_spi_node *)bnode;
-    struct bus_spi_node *current_node = (struct bus_spi_node 
*)bdev->configured_for;
     struct hal_spi_settings spi_cfg;
     int rc;
 
@@ -103,9 +102,8 @@ bus_spi_configure(struct bus_dev *bdev, struct bus_node 
*bnode)
     BUS_DEBUG_VERIFY_NODE(node);
 
     /* No need to reconfigure if already configured with the same settings */
-    if (current_node && (current_node->mode == node->mode) &&
-                        (current_node->data_order == node->data_order) &&
-                        (current_node->freq == node->freq)) {
+    if ((spi_dev->mode == node->mode) && (spi_dev->data_order == 
node->data_order) &&
+        (spi_dev->freq == node->freq)) {
         return 0;
     }
 
@@ -114,6 +112,10 @@ bus_spi_configure(struct bus_dev *bdev, struct bus_node 
*bnode)
         goto done;
     }
 
+    spi_dev->freq = node->freq;
+    spi_dev->data_order = node->data_order;
+    spi_dev->mode = node->mode;
+
     spi_cfg.data_mode = node->mode;
     spi_cfg.data_order = node->data_order;
     spi_cfg.baudrate = node->freq;
diff --git a/hw/bus/drivers/spi_stm32/src/spi_stm32.c 
b/hw/bus/drivers/spi_stm32/src/spi_stm32.c
index ff0357eb8..c9bd2128b 100644
--- a/hw/bus/drivers/spi_stm32/src/spi_stm32.c
+++ b/hw/bus/drivers/spi_stm32/src/spi_stm32.c
@@ -607,7 +607,6 @@ spi_stm32_configure(struct bus_dev *bdev, struct bus_node 
*bnode)
 {
     struct bus_spi_dev *dev = (struct bus_spi_dev *)bdev;
     struct bus_spi_node *node = (struct bus_spi_node *)bnode;
-    struct bus_spi_node *current_node = (struct bus_spi_node 
*)bdev->configured_for;
     struct spi_stm32_driver_data *dd;
     const struct stm32_spi_hw *hw;
     uint32_t pclk;
@@ -620,10 +619,8 @@ spi_stm32_configure(struct bus_dev *bdev, struct bus_node 
*bnode)
 
     dd = driver_data(dev);
 
-    if (current_node &&
-        current_node->freq == node->freq &&
-        current_node->data_order == node->data_order &&
-        current_node->mode == node->mode) {
+    if (dev->freq == node->freq && dev->data_order == node->data_order &&
+        dev->mode == node->mode) {
         goto end;
     }
 
@@ -639,6 +636,9 @@ spi_stm32_configure(struct bus_dev *bdev, struct bus_node 
*bnode)
     if (prescaler > 7) {
         rc = SYS_EINVAL;
     } else {
+        dev->freq = node->freq;
+        dev->data_order = node->data_order;
+        dev->mode = node->mode;
 #if MYNEWT_VAL(MCU_STM32H7) || MYNEWT_VAL(MCU_STM32U5)
         dd->hspi.Init.BaudRatePrescaler = prescaler << SPI_CFG1_MBR_Pos;
 #else
diff --git a/hw/bus/src/bus.c b/hw/bus/src/bus.c
index a3b4e07c8..e764bfcb9 100644
--- a/hw/bus/src/bus.c
+++ b/hw/bus/src/bus.c
@@ -530,11 +530,6 @@ bus_node_lock(struct os_dev *node, os_time_t timeout)
     }
 #endif
 
-    /* No need to configure if already configured for the same node */
-    if (bdev->configured_for == bnode) {
-        return 0;
-    }
-
     /*
      * Configuration is done on 1st lock so in case we need to configure device
      * on nested lock it means that most likely bus device was locked for one

Reply via email to