[sw/silicon_creator] Update spi_device_cmd_get()
This commit updates spi_device_cmd_get() in response to the HW changes
in #12614.
Signed-off-by: Alphan Ulusoy <alphan@google.com>
diff --git a/sw/device/silicon_creator/lib/drivers/spi_device.c b/sw/device/silicon_creator/lib/drivers/spi_device.c
index d3efac7..2a78879 100644
--- a/sw/device/silicon_creator/lib/drivers/spi_device.c
+++ b/sw/device/silicon_creator/lib/drivers/spi_device.c
@@ -622,29 +622,31 @@
rom_error_t spi_device_cmd_get(spi_device_cmd_t *cmd) {
uint32_t reg = 0;
bool cmd_pending = false;
- // TODO(#11871): When should sw read cmd, addr, and payload?
while (!cmd_pending) {
- reg = abs_mmio_read32(kBase + SPI_DEVICE_UPLOAD_STATUS_REG_OFFSET);
- cmd_pending =
- bitfield_bit32_read(reg, SPI_DEVICE_UPLOAD_STATUS_CMDFIFO_NOTEMPTY_BIT);
+ // Note: Using INTR_STATE.UPLOAD_CMDFIFO_NOT_EMPTY because
+ // UPLOAD_STATUS.CMDFIFO_NOTEMPTY is set before the SPI transaction ends.
+ reg = abs_mmio_read32(kBase + SPI_DEVICE_INTR_STATE_REG_OFFSET);
+ cmd_pending = bitfield_bit32_read(
+ reg, SPI_DEVICE_INTR_COMMON_UPLOAD_CMDFIFO_NOT_EMPTY_BIT);
}
- cmd->opcode = abs_mmio_read32(kBase + SPI_DEVICE_UPLOAD_CMDFIFO_REG_OFFSET);
+ abs_mmio_write32(kBase + SPI_DEVICE_INTR_STATE_REG_OFFSET, UINT32_MAX);
+ if (bitfield_bit32_read(reg,
+ SPI_DEVICE_INTR_COMMON_UPLOAD_PAYLOAD_OVERFLOW_BIT)) {
+ return kErrorSpiDevicePayloadOverflow;
+ }
+ cmd->opcode = abs_mmio_read32(kBase + SPI_DEVICE_UPLOAD_CMDFIFO_REG_OFFSET);
cmd->address = kSpiDeviceNoAddress;
+ reg = abs_mmio_read32(kBase + SPI_DEVICE_UPLOAD_STATUS_REG_OFFSET);
if (bitfield_bit32_read(reg,
SPI_DEVICE_UPLOAD_STATUS_ADDRFIFO_NOTEMPTY_BIT)) {
cmd->address =
abs_mmio_read32(kBase + SPI_DEVICE_UPLOAD_ADDRFIFO_REG_OFFSET);
}
- reg = abs_mmio_read32(kBase + SPI_DEVICE_INTR_STATE_REG_OFFSET);
- if (bitfield_bit32_read(reg,
- SPI_DEVICE_INTR_COMMON_UPLOAD_PAYLOAD_OVERFLOW_BIT)) {
- return kErrorSpiDevicePayloadOverflow;
- }
-
+ reg = abs_mmio_read32(kBase + SPI_DEVICE_UPLOAD_STATUS2_REG_OFFSET);
cmd->payload_byte_count =
- abs_mmio_read32(kBase + SPI_DEVICE_UPLOAD_STATUS2_REG_OFFSET);
+ bitfield_field32_read(reg, SPI_DEVICE_UPLOAD_STATUS2_PAYLOAD_DEPTH_FIELD);
uint32_t src =
kBase + SPI_DEVICE_BUFFER_REG_OFFSET + kSpiDevicePayloadAreaOffset;
char *dest = (char *)&cmd->payload;
diff --git a/sw/device/silicon_creator/lib/drivers/spi_device_unittest.cc b/sw/device/silicon_creator/lib/drivers/spi_device_unittest.cc
index 8c985a2..d307589 100644
--- a/sw/device/silicon_creator/lib/drivers/spi_device_unittest.cc
+++ b/sw/device/silicon_creator/lib/drivers/spi_device_unittest.cc
@@ -204,19 +204,14 @@
public testing::WithParamInterface<CmdGetTestCase> {};
TEST_F(CmdGetTest, PayloadOverflow) {
- EXPECT_ABS_READ32(base_ + SPI_DEVICE_UPLOAD_STATUS_REG_OFFSET, 0);
- EXPECT_ABS_READ32(base_ + SPI_DEVICE_UPLOAD_STATUS_REG_OFFSET,
- {
- {SPI_DEVICE_UPLOAD_STATUS_CMDFIFO_NOTEMPTY_BIT, 1},
- {SPI_DEVICE_UPLOAD_STATUS_ADDRFIFO_NOTEMPTY_BIT, 1},
- });
- EXPECT_ABS_READ32(base_ + SPI_DEVICE_UPLOAD_CMDFIFO_REG_OFFSET,
- kSpiDeviceOpcodePageProgram);
-
- EXPECT_ABS_READ32(base_ + SPI_DEVICE_UPLOAD_ADDRFIFO_REG_OFFSET, 0);
-
+ EXPECT_ABS_READ32(base_ + SPI_DEVICE_INTR_STATE_REG_OFFSET, 0);
EXPECT_ABS_READ32(base_ + SPI_DEVICE_INTR_STATE_REG_OFFSET,
- {{SPI_DEVICE_INTR_COMMON_UPLOAD_PAYLOAD_OVERFLOW_BIT, 1}});
+ {
+ {SPI_DEVICE_INTR_STATE_UPLOAD_CMDFIFO_NOT_EMPTY_BIT, 1},
+ {SPI_DEVICE_INTR_STATE_UPLOAD_PAYLOAD_OVERFLOW_BIT, 1},
+ });
+ EXPECT_ABS_WRITE32(base_ + SPI_DEVICE_INTR_STATE_REG_OFFSET,
+ std::numeric_limits<uint32_t>::max());
spi_device_cmd_t cmd;
EXPECT_EQ(spi_device_cmd_get(&cmd), kErrorSpiDevicePayloadOverflow);
@@ -225,29 +220,30 @@
TEST_P(CmdGetTest, CmdGet) {
bool has_address = GetParam().address != kSpiDeviceNoAddress;
- EXPECT_ABS_READ32(base_ + SPI_DEVICE_UPLOAD_STATUS_REG_OFFSET, 0);
- EXPECT_ABS_READ32(
- base_ + SPI_DEVICE_UPLOAD_STATUS_REG_OFFSET,
- {
- {SPI_DEVICE_UPLOAD_STATUS_CMDFIFO_NOTEMPTY_BIT, 1},
- {SPI_DEVICE_UPLOAD_STATUS_ADDRFIFO_NOTEMPTY_BIT, has_address},
- });
+ EXPECT_ABS_READ32(base_ + SPI_DEVICE_INTR_STATE_REG_OFFSET, 0);
+ EXPECT_ABS_READ32(base_ + SPI_DEVICE_INTR_STATE_REG_OFFSET,
+ {{SPI_DEVICE_INTR_STATE_UPLOAD_CMDFIFO_NOT_EMPTY_BIT, 1}});
+ EXPECT_ABS_WRITE32(base_ + SPI_DEVICE_INTR_STATE_REG_OFFSET,
+ std::numeric_limits<uint32_t>::max());
+
EXPECT_ABS_READ32(base_ + SPI_DEVICE_UPLOAD_CMDFIFO_REG_OFFSET,
GetParam().opcode);
+ EXPECT_ABS_READ32(
+ base_ + SPI_DEVICE_UPLOAD_STATUS_REG_OFFSET,
+ {{SPI_DEVICE_UPLOAD_STATUS_ADDRFIFO_NOTEMPTY_BIT, has_address}});
if (has_address) {
EXPECT_ABS_READ32(base_ + SPI_DEVICE_UPLOAD_ADDRFIFO_REG_OFFSET,
GetParam().address);
}
- EXPECT_ABS_READ32(base_ + SPI_DEVICE_INTR_STATE_REG_OFFSET, 0);
-
std::vector<uint32_t> payload_area(kSpiDevicePayloadAreaNumWords,
std::numeric_limits<uint32_t>::max());
std::memcpy(payload_area.data(), GetParam().payload.data(),
GetParam().payload.size());
EXPECT_ABS_READ32(base_ + SPI_DEVICE_UPLOAD_STATUS2_REG_OFFSET,
- GetParam().payload.size());
+ {{SPI_DEVICE_UPLOAD_STATUS2_PAYLOAD_DEPTH_OFFSET,
+ GetParam().payload.size()}});
uint32_t offset =
base_ + SPI_DEVICE_BUFFER_REG_OFFSET + kSpiDevicePayloadAreaOffset;
for (size_t i = 0; i < GetParam().payload.size(); i += sizeof(uint32_t)) {