From 3e6c308c850e659243136e48932167b0a38a9345 Mon Sep 17 00:00:00 2001 From: Ray Lau Date: Wed, 20 May 2026 10:23:53 +0100 Subject: [PATCH] [sw] Fix SPI device SyncReqAckDataHoldSrc2Dst assertion failure This fixes the address mode pending mask, and ensures the smoke test does not change the address mode multiple times without waiting for the pending bit to clear. This commit also adds blocking and non-blocking variants of function to set the address mode. The spi_device_init function uses the non-blocking variant to prevent spi_device_init from blocking forever in environments where there is no active SPI clock to clear the pending bit. --- sw/device/lib/hal/spi_device.c | 9 +++++++-- sw/device/lib/hal/spi_device.h | 5 +++-- sw/device/tests/spi_device/smoketest.c | 10 ---------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/sw/device/lib/hal/spi_device.c b/sw/device/lib/hal/spi_device.c index 6f21cc0bb..d24946e4f 100644 --- a/sw/device/lib/hal/spi_device.c +++ b/sw/device/lib/hal/spi_device.c @@ -56,7 +56,12 @@ void spi_device_enable_set(spi_device_t spi_device, bool enable) DEV_WRITE(spi_device + SPI_DEVICE_CTRL_REG, enable << SPI_DEVICE_CTRL_MODE_OFFSET); } -void spi_device_4b_addr_mode_enable_set(spi_device_t spi_device, bool enable) +void spi_device_4b_addr_mode_enable_set_non_blocking(spi_device_t spi_device, bool enable) +{ + DEV_WRITE(spi_device + SPI_DEVICE_ADDR_MODE_REG, (uint32_t)enable); +} + +void spi_device_4b_addr_mode_enable_set_blocking(spi_device_t spi_device, bool enable) { DEV_WRITE(spi_device + SPI_DEVICE_ADDR_MODE_REG, (uint32_t)enable); @@ -574,7 +579,7 @@ void spi_device_sfdp_table_init(spi_device_t spi_device) void spi_device_init(spi_device_t spi_device) { - spi_device_4b_addr_mode_enable_set(spi_device, true); + spi_device_4b_addr_mode_enable_set_non_blocking(spi_device, true); spi_device_jedec_cc_set(spi_device, MOCHA_SPI_DEVICE_JEDEC_CC, MOCHA_SPI_DEVICE_JEDEC_CC_COUNT); spi_device_jedec_id_set(spi_device, MOCHA_SPI_DEVICE_ROM_BOOTSTRAP, MOCHA_SPI_DEVICE_CHIP_REV, MOCHA_SPI_DEVICE_CHIP_GEN, MOCHA_SPI_DEVICE_DENSITY_BYTES_LOG2, diff --git a/sw/device/lib/hal/spi_device.h b/sw/device/lib/hal/spi_device.h index 76e48f975..e7627513f 100644 --- a/sw/device/lib/hal/spi_device.h +++ b/sw/device/lib/hal/spi_device.h @@ -27,7 +27,7 @@ #define SPI_DEVICE_ADDR_MODE_REG (0x20) #define SPI_DEVICE_ADDR_MODE_4B_EN_MASK (0x1) -#define SPI_DEVICE_ADDR_MODE_PENDING_MASK (0x70000000) +#define SPI_DEVICE_ADDR_MODE_PENDING_MASK (0x80000000) #define SPI_DEVICE_FLASH_STATUS_REG (0x28) #define SPI_DEVICE_FLASH_STATUS_BUSY_MASK (0x1) @@ -177,7 +177,8 @@ void spi_device_interrupt_enable(spi_device_t spi_device, uint8_t intr_id); void spi_device_interrupt_disable(spi_device_t spi_device, uint8_t intr_id); void spi_device_interrupt_trigger(spi_device_t spi_device, uint8_t intr_id); void spi_device_enable_set(spi_device_t spi_device, bool enable); -void spi_device_4b_addr_mode_enable_set(spi_device_t spi_device, bool enable); +void spi_device_4b_addr_mode_enable_set_non_blocking(spi_device_t spi_device, bool enable); +void spi_device_4b_addr_mode_enable_set_blocking(spi_device_t spi_device, bool enable); bool spi_device_4b_addr_mode_enable_get(spi_device_t spi_device); void spi_device_flash_status_set(spi_device_t spi_device, uint32_t flash_status); uint32_t spi_device_flash_status_get(spi_device_t spi_device); diff --git a/sw/device/tests/spi_device/smoketest.c b/sw/device/tests/spi_device/smoketest.c index a4b81cf09..2ac1178c3 100644 --- a/sw/device/tests/spi_device/smoketest.c +++ b/sw/device/tests/spi_device/smoketest.c @@ -48,16 +48,6 @@ bool cmd_info_readback_test(spi_device_t spi_device, uint32_t offset) bool reg_test(spi_device_t spi_device) { - spi_device_4b_addr_mode_enable_set(spi_device, true); - if (!spi_device_4b_addr_mode_enable_get(spi_device)) { - return false; - } - - spi_device_4b_addr_mode_enable_set(spi_device, false); - if (spi_device_4b_addr_mode_enable_get(spi_device)) { - return false; - } - spi_device_jedec_cc_set(spi_device, 0xE1, 0x45); if ((spi_device_jedec_cc_get(spi_device) & 0xFFFF) != 0x45E1) { return false;