diff --git a/sw/device/lib/testing/spi_device_testutils.c b/sw/device/lib/testing/spi_device_testutils.c index b081542c4d6822..58b865164fbec2 100644 --- a/sw/device/lib/testing/spi_device_testutils.c +++ b/sw/device/lib/testing/spi_device_testutils.c @@ -11,7 +11,8 @@ status_t spi_device_testutils_configure_passthrough( dif_spi_device_handle_t *spi_device, uint32_t filters, - bool upload_write_commands) { + bool upload_write_commands, dif_spi_device_flash_command_t *write_cmds, + size_t write_cmds_size, dif_spi_device_flash_command_t *read_cmds) { dif_spi_device_config_t spi_device_config = { .tx_order = kDifSpiDeviceBitOrderMsbToLsb, .rx_order = kDifSpiDeviceBitOrderMsbToLsb, @@ -32,106 +33,7 @@ status_t spi_device_testutils_configure_passthrough( TRY(dif_spi_device_set_all_passthrough_command_filters(spi_device, kDifToggleDisabled)); - dif_spi_device_flash_command_t read_commands[] = { - { - // Slot 0: ReadStatus1 - .opcode = kSpiDeviceFlashOpReadStatus1, - .address_type = kDifSpiDeviceFlashAddrDisabled, - .dummy_cycles = 0, - .payload_io_type = kDifSpiDevicePayloadIoSingle, - .payload_dir_to_host = true, - }, - { - // Slot 1: ReadStatus2 - .opcode = kSpiDeviceFlashOpReadStatus2, - .address_type = kDifSpiDeviceFlashAddrDisabled, - .dummy_cycles = 0, - .payload_io_type = kDifSpiDevicePayloadIoSingle, - .payload_dir_to_host = true, - }, - { - // Slot 2: ReadStatus3 - .opcode = kSpiDeviceFlashOpReadStatus3, - .address_type = kDifSpiDeviceFlashAddrDisabled, - .dummy_cycles = 0, - .payload_io_type = kDifSpiDevicePayloadIoSingle, - .payload_dir_to_host = true, - }, - { - // Slot 3: ReadJedecID - .opcode = kSpiDeviceFlashOpReadJedec, - .address_type = kDifSpiDeviceFlashAddrDisabled, - .dummy_cycles = 0, - .payload_io_type = kDifSpiDevicePayloadIoSingle, - .payload_dir_to_host = true, - }, - { - // Slot 4: ReadSfdp - .opcode = kSpiDeviceFlashOpReadSfdp, - .address_type = kDifSpiDeviceFlashAddr3Byte, - .dummy_cycles = 8, - .payload_io_type = kDifSpiDevicePayloadIoSingle, - .payload_dir_to_host = true, - }, - { - // Slot 5: ReadNormal - .opcode = kSpiDeviceFlashOpReadNormal, - .address_type = kDifSpiDeviceFlashAddrCfg, - .passthrough_swap_address = true, - .dummy_cycles = 0, - .payload_io_type = kDifSpiDevicePayloadIoSingle, - .payload_dir_to_host = true, - }, - { - // Slot 6: ReadFast - .opcode = kSpiDeviceFlashOpReadFast, - .address_type = kDifSpiDeviceFlashAddrCfg, - .passthrough_swap_address = true, - .dummy_cycles = 8, - .payload_io_type = kDifSpiDevicePayloadIoSingle, - .payload_dir_to_host = true, - }, - { - // Slot 7: ReadDual - .opcode = kSpiDeviceFlashOpReadDual, - .address_type = kDifSpiDeviceFlashAddrCfg, - .passthrough_swap_address = true, - .dummy_cycles = 8, - .payload_io_type = kDifSpiDevicePayloadIoDual, - .payload_dir_to_host = true, - }, - { - // Slot 8: ReadQuad - .opcode = kSpiDeviceFlashOpReadQuad, - .address_type = kDifSpiDeviceFlashAddrCfg, - .passthrough_swap_address = true, - .dummy_cycles = 8, - .payload_io_type = kDifSpiDevicePayloadIoQuad, - .payload_dir_to_host = true, - }, - { - // Slot 9: Read4b - .opcode = kSpiDeviceFlashOpRead4b, - .address_type = kDifSpiDeviceFlashAddr4Byte, - .passthrough_swap_address = true, - .dummy_cycles = 0, - .payload_io_type = kDifSpiDevicePayloadIoSingle, - .payload_dir_to_host = true, - }, - { - // Slot 10: ReadFast4b - .opcode = kSpiDeviceFlashOpReadFast4b, - .address_type = kDifSpiDeviceFlashAddr4Byte, - .passthrough_swap_address = true, - .dummy_cycles = 8, - .payload_io_type = kDifSpiDevicePayloadIoSingle, - .payload_dir_to_host = true, - }, - }; - static_assert(ARRAYSIZE(read_commands) <= UINT8_MAX, - "Length of read_commands must fit in uint8_t or we must change " - "the type of i."); - for (uint8_t i = 0; i < ARRAYSIZE(read_commands); ++i) { + for (uint8_t i = 0; i < read_commands_size; ++i) { uint8_t slot = i + kSpiDeviceReadCommandSlotBase; if (bitfield_bit32_read(filters, slot)) { TRY(dif_spi_device_set_passthrough_command_filter( @@ -140,128 +42,16 @@ status_t spi_device_testutils_configure_passthrough( TRY(dif_spi_device_set_flash_command_slot( spi_device, slot, kDifToggleEnabled, read_commands[i])); } - dif_spi_device_flash_command_t write_commands[] = { - { - // Slot 11: WriteStatus1 - .opcode = kSpiDeviceFlashOpWriteStatus1, - .address_type = kDifSpiDeviceFlashAddrDisabled, - .payload_io_type = kDifSpiDevicePayloadIoSingle, - .payload_dir_to_host = false, - .upload = upload_write_commands, - .set_busy_status = upload_write_commands, - }, - { - // Slot 12: WriteStatus2 - .opcode = kSpiDeviceFlashOpWriteStatus2, - .address_type = kDifSpiDeviceFlashAddrDisabled, - .payload_io_type = kDifSpiDevicePayloadIoSingle, - .payload_dir_to_host = false, - .upload = upload_write_commands, - .set_busy_status = upload_write_commands, - }, - { - // Slot 13: WriteStatus3 - .opcode = kSpiDeviceFlashOpWriteStatus3, - .address_type = kDifSpiDeviceFlashAddrDisabled, - .payload_io_type = kDifSpiDevicePayloadIoSingle, - .payload_dir_to_host = false, - .upload = upload_write_commands, - .set_busy_status = upload_write_commands, - }, - { - // Slot 14: ChipErase - .opcode = kSpiDeviceFlashOpChipErase, - .address_type = kDifSpiDeviceFlashAddrDisabled, - .payload_io_type = kDifSpiDevicePayloadIoNone, - .upload = upload_write_commands, - .set_busy_status = upload_write_commands, - }, - { - // Slot 15: SectorErase - .opcode = kSpiDeviceFlashOpSectorErase, - .address_type = kDifSpiDeviceFlashAddrCfg, - .payload_io_type = kDifSpiDevicePayloadIoNone, - .upload = upload_write_commands, - .set_busy_status = upload_write_commands, - }, - { - // Slot 16: BlockErase32k - .opcode = kSpiDeviceFlashOpBlockErase32k, - .address_type = kDifSpiDeviceFlashAddrCfg, - .payload_io_type = kDifSpiDevicePayloadIoNone, - .upload = upload_write_commands, - .set_busy_status = upload_write_commands, - }, - { - // Slot 17: BlockErase64k - .opcode = kSpiDeviceFlashOpBlockErase64k, - .address_type = kDifSpiDeviceFlashAddrCfg, - .payload_io_type = kDifSpiDevicePayloadIoNone, - .upload = upload_write_commands, - .set_busy_status = upload_write_commands, - }, - { - // Slot 18: PageProgram - .opcode = kSpiDeviceFlashOpPageProgram, - .address_type = kDifSpiDeviceFlashAddrCfg, - .payload_io_type = kDifSpiDevicePayloadIoSingle, - .payload_dir_to_host = false, - .upload = upload_write_commands, - .set_busy_status = upload_write_commands, - }, - { - // Slot 19: SectorErase4b - .opcode = kSpiDeviceFlashOpSectorErase4b, - .address_type = kDifSpiDeviceFlashAddr4Byte, - .payload_io_type = kDifSpiDevicePayloadIoNone, - .upload = upload_write_commands, - .set_busy_status = upload_write_commands, - }, - { - // Slot 20: BlockErase32k4b - .opcode = kSpiDeviceFlashOpBlockErase32k4b, - .address_type = kDifSpiDeviceFlashAddr4Byte, - .payload_io_type = kDifSpiDevicePayloadIoNone, - .upload = upload_write_commands, - .set_busy_status = upload_write_commands, - }, - { - // Slot 21: BlockErase64k4b - .opcode = kSpiDeviceFlashOpBlockErase64k4b, - .address_type = kDifSpiDeviceFlashAddr4Byte, - .payload_io_type = kDifSpiDevicePayloadIoNone, - .upload = upload_write_commands, - .set_busy_status = upload_write_commands, - }, - { - // Slot 22: PageProgram4b - .opcode = kSpiDeviceFlashOpPageProgram4b, - .address_type = kDifSpiDeviceFlashAddr4Byte, - .payload_io_type = kDifSpiDevicePayloadIoSingle, - .payload_dir_to_host = false, - .upload = upload_write_commands, - .set_busy_status = upload_write_commands, - }, - { - // Slot 23: Reset - .opcode = kSpiDeviceFlashOpReset, - .address_type = kDifSpiDeviceFlashAddrDisabled, - .payload_io_type = kDifSpiDevicePayloadIoNone, - .upload = upload_write_commands, - .set_busy_status = upload_write_commands, - }, - - }; - static_assert(ARRAYSIZE(write_commands) <= UINT8_MAX, - "Length of write_commands must fit into uint8_t"); - for (uint8_t i = 0; i < ARRAYSIZE(write_commands); ++i) { + for (uint8_t i = 0; i < write_commands_size; ++i) { uint8_t slot = i + (uint8_t)kSpiDeviceWriteCommandSlotBase; if (bitfield_bit32_read(filters, slot) || upload_write_commands) { TRY(dif_spi_device_set_passthrough_command_filter( spi_device, write_commands[i].opcode, kDifToggleEnabled)); } - TRY(dif_spi_device_set_flash_command_slot( - spi_device, slot, kDifToggleEnabled, write_commands[i])); + dif_spi_device_flash_command_t cmd = write_commands[i]; + cmd.upload = cmd.set_busy_status = upload_write_commands; + TRY(dif_spi_device_set_flash_command_slot(spi_device, slot, + kDifToggleEnabled, cmd)); } // This configuration for these commands does not guard against misbehaved // hosts. The timing of any of these commands relative to an uploaded command diff --git a/sw/device/lib/testing/spi_device_testutils.h b/sw/device/lib/testing/spi_device_testutils.h index 2abd812ddae038..6b1d9f2fe80103 100644 --- a/sw/device/lib/testing/spi_device_testutils.h +++ b/sw/device/lib/testing/spi_device_testutils.h @@ -69,46 +69,238 @@ static const top_earlgrey_direct_pads_t spi_device_direct_pads[4] = { kTopEarlgreyDirectPadsSpiDeviceSd0 // sio[0] }; +static const dif_spi_device_flash_command_t kReadCommands[] = { + { + // Slot 0: ReadStatus1 + .opcode = kSpiDeviceFlashOpReadStatus1, + .address_type = kDifSpiDeviceFlashAddrDisabled, + .dummy_cycles = 0, + .payload_io_type = kDifSpiDevicePayloadIoSingle, + .payload_dir_to_host = true, + }, + { + // Slot 1: ReadStatus2 + .opcode = kSpiDeviceFlashOpReadStatus2, + .address_type = kDifSpiDeviceFlashAddrDisabled, + .dummy_cycles = 0, + .payload_io_type = kDifSpiDevicePayloadIoSingle, + .payload_dir_to_host = true, + }, + { + // Slot 2: ReadStatus3 + .opcode = kSpiDeviceFlashOpReadStatus3, + .address_type = kDifSpiDeviceFlashAddrDisabled, + .dummy_cycles = 0, + .payload_io_type = kDifSpiDevicePayloadIoSingle, + .payload_dir_to_host = true, + }, + { + // Slot 3: ReadJedecID + .opcode = kSpiDeviceFlashOpReadJedec, + .address_type = kDifSpiDeviceFlashAddrDisabled, + .dummy_cycles = 0, + .payload_io_type = kDifSpiDevicePayloadIoSingle, + .payload_dir_to_host = true, + }, + { + // Slot 4: ReadSfdp + .opcode = kSpiDeviceFlashOpReadSfdp, + .address_type = kDifSpiDeviceFlashAddr3Byte, + .dummy_cycles = 8, + .payload_io_type = kDifSpiDevicePayloadIoSingle, + .payload_dir_to_host = true, + }, + { + // Slot 5: ReadNormal + .opcode = kSpiDeviceFlashOpReadNormal, + .address_type = kDifSpiDeviceFlashAddrCfg, + .passthrough_swap_address = true, + .dummy_cycles = 0, + .payload_io_type = kDifSpiDevicePayloadIoSingle, + .payload_dir_to_host = true, + }, + { + // Slot 6: ReadFast + .opcode = kSpiDeviceFlashOpReadFast, + .address_type = kDifSpiDeviceFlashAddrCfg, + .passthrough_swap_address = true, + .dummy_cycles = 8, + .payload_io_type = kDifSpiDevicePayloadIoSingle, + .payload_dir_to_host = true, + }, + { + // Slot 7: ReadDual + .opcode = kSpiDeviceFlashOpReadDual, + .address_type = kDifSpiDeviceFlashAddrCfg, + .passthrough_swap_address = true, + .dummy_cycles = 8, + .payload_io_type = kDifSpiDevicePayloadIoDual, + .payload_dir_to_host = true, + }, + { + // Slot 8: ReadQuad + .opcode = kSpiDeviceFlashOpReadQuad, + .address_type = kDifSpiDeviceFlashAddrCfg, + .passthrough_swap_address = true, + .dummy_cycles = 8, + .payload_io_type = kDifSpiDevicePayloadIoQuad, + .payload_dir_to_host = true, + }, + { + // Slot 9: Read4b + .opcode = kSpiDeviceFlashOpRead4b, + .address_type = kDifSpiDeviceFlashAddr4Byte, + .passthrough_swap_address = true, + .dummy_cycles = 0, + .payload_io_type = kDifSpiDevicePayloadIoSingle, + .payload_dir_to_host = true, + }, + { + // Slot 10: ReadFast4b + .opcode = kSpiDeviceFlashOpReadFast4b, + .address_type = kDifSpiDeviceFlashAddr4Byte, + .passthrough_swap_address = true, + .dummy_cycles = 8, + .payload_io_type = kDifSpiDevicePayloadIoSingle, + .payload_dir_to_host = true, + }, +}; +static_assert(ARRAYSIZE(kReadCommands) <= UINT8_MAX, + "Length of read_commands must fit in uint8_t or we must change " + "the type of i."); + +static const dif_spi_device_flash_command_t kWriteCommands[] = { + { + // Slot 11: WriteStatus1 + .opcode = kSpiDeviceFlashOpWriteStatus1, + .address_type = kDifSpiDeviceFlashAddrDisabled, + .payload_io_type = kDifSpiDevicePayloadIoSingle, + .payload_dir_to_host = false, + .upload = true, + .set_busy_status = true, + }, + { + // Slot 12: WriteStatus2 + .opcode = kSpiDeviceFlashOpWriteStatus2, + .address_type = kDifSpiDeviceFlashAddrDisabled, + .payload_io_type = kDifSpiDevicePayloadIoSingle, + .payload_dir_to_host = false, + .upload = true, + .set_busy_status = true, + }, + { + // Slot 13: WriteStatus3 + .opcode = kSpiDeviceFlashOpWriteStatus3, + .address_type = kDifSpiDeviceFlashAddrDisabled, + .payload_io_type = kDifSpiDevicePayloadIoSingle, + .payload_dir_to_host = false, + .upload = true, + .set_busy_status = true, + }, + { + // Slot 14: ChipErase + .opcode = kSpiDeviceFlashOpChipErase, + .address_type = kDifSpiDeviceFlashAddrDisabled, + .payload_io_type = kDifSpiDevicePayloadIoNone, + .upload = true, + .set_busy_status = true, + }, + { + // Slot 15: SectorErase + .opcode = kSpiDeviceFlashOpSectorErase, + .address_type = kDifSpiDeviceFlashAddrCfg, + .payload_io_type = kDifSpiDevicePayloadIoNone, + .upload = true, + .set_busy_status = true, + }, + { + // Slot 16: BlockErase32k + .opcode = kSpiDeviceFlashOpBlockErase32k, + .address_type = kDifSpiDeviceFlashAddrCfg, + .payload_io_type = kDifSpiDevicePayloadIoNone, + .upload = true, + .set_busy_status = true, + }, + { + // Slot 17: BlockErase64k + .opcode = kSpiDeviceFlashOpBlockErase64k, + .address_type = kDifSpiDeviceFlashAddrCfg, + .payload_io_type = kDifSpiDevicePayloadIoNone, + .upload = true, + .set_busy_status = true, + }, + { + // Slot 18: PageProgram + .opcode = kSpiDeviceFlashOpPageProgram, + .address_type = kDifSpiDeviceFlashAddrCfg, + .payload_io_type = kDifSpiDevicePayloadIoSingle, + .payload_dir_to_host = false, + .upload = true, + .set_busy_status = true, + }, + { + // Slot 19: SectorErase4b + .opcode = kSpiDeviceFlashOpSectorErase4b, + .address_type = kDifSpiDeviceFlashAddr4Byte, + .payload_io_type = kDifSpiDevicePayloadIoNone, + .upload = true, + .set_busy_status = true, + }, + { + // Slot 20: BlockErase32k4b + .opcode = kSpiDeviceFlashOpBlockErase32k4b, + .address_type = kDifSpiDeviceFlashAddr4Byte, + .payload_io_type = kDifSpiDevicePayloadIoNone, + .upload = true, + .set_busy_status = true, + }, + { + // Slot 21: BlockErase64k4b + .opcode = kSpiDeviceFlashOpBlockErase64k4b, + .address_type = kDifSpiDeviceFlashAddr4Byte, + .payload_io_type = kDifSpiDevicePayloadIoNone, + .upload = true, + .set_busy_status = true, + }, + { + // Slot 22: PageProgram4b + .opcode = kSpiDeviceFlashOpPageProgram4b, + .address_type = kDifSpiDeviceFlashAddr4Byte, + .payload_io_type = kDifSpiDevicePayloadIoSingle, + .payload_dir_to_host = false, + .upload = true, + .set_busy_status = true, + }, + { + // Slot 23: Reset + .opcode = kSpiDeviceFlashOpReset, + .address_type = kDifSpiDeviceFlashAddrDisabled, + .payload_io_type = kDifSpiDevicePayloadIoNone, + .upload = true, + .set_busy_status = true, + }, + +}; +static_assert(ARRAYSIZE(kWriteCommands) <= UINT8_MAX, + "Length of write_commands must fit into uint8_t"); + /** - * Configure the SPI device in passthrough mode, allowing the following - * commands to pass through: - * - ReadJedec - * - ReadSfdp - * - ReadNormal - * - Read4b - * - ReadFast - * - ReadFast4b - * - ReadDual - * - ReadQuad - * - WriteEnable - * - WriteDisable - * - ReadStatus1 - * - ReadStatus2 - * - ReadStatus3 - * - WriteStatus1 - * - WriteStatus2 - * - WriteStatus3 - * - ChipErase - * - SectorErase - * - BlockErase32k - * - BlockErase64k - * - PageProgram - * - SectorErase4b - * - BlockErase32k4b - * - BlockErase64k4b - * - PageProgram4b - * - Reset - * - Enter4bAddr - * - Exit4bAddr + * Configure the SPI device in passthrough mode, allowing the commands in the + * provideded tables to pass through: * * @param spi_device A spi_device DIF handle. * @param filters A bitmap of command slots to enable passthrough filters for. - * @param upload_write_commands Whether to upload write commands. + * @param upload Whether to upload write commands. + * @param write_cmds A table with the write commands to be configured. + * @param write_cmds_size Num of elements in the write cmds table. + * @param read_cmds A table with the read commands to be configured. + * @param read_cmds_size Num of elements in the read cmds table. */ OT_WARN_UNUSED_RESULT status_t spi_device_testutils_configure_passthrough( - dif_spi_device_handle_t *spi_device, uint32_t filters, - bool upload_write_commands); + dif_spi_device_handle_t *spi_device, uint32_t filters, bool upload, + dif_spi_device_flash_command_t *write_cmds, size_t write_cmds_size, + dif_spi_device_flash_command_t *read_cmds); /** * Configure the read pipeline setting of the read command slots. diff --git a/sw/device/tests/power_virus_systemtest.c b/sw/device/tests/power_virus_systemtest.c index 363a4a68f5dbd5..1f7fcd57d58044 100644 --- a/sw/device/tests/power_virus_systemtest.c +++ b/sw/device/tests/power_virus_systemtest.c @@ -1480,7 +1480,9 @@ bool test_main(void) { configure_spi_host(&spi_host_1, /*enable=*/false); CHECK_STATUS_OK(spi_device_testutils_configure_passthrough( &spi_device, /*filters=*/0, - /*upload_write_commands=*/false)); + /*upload_write_commands=*/false, kWriteCommands, ARRAYSIZE(kWriteCommands), + kReadCommands, ARRAYSIZE(kReadCommands))); + configure_pattgen(); configure_pwm(); LOG_INFO("All IPs configured."); diff --git a/sw/device/tests/sim_dv/spi_passthrough_test.c b/sw/device/tests/sim_dv/spi_passthrough_test.c index 3232b9e406947c..a9e407dae80033 100644 --- a/sw/device/tests/sim_dv/spi_passthrough_test.c +++ b/sw/device/tests/sim_dv/spi_passthrough_test.c @@ -403,10 +403,11 @@ bool test_main(void) { CHECK_DIF_OK(dif_spi_device_init_handle(spi_device_base_addr, &spi_device)); bool upload_write_commands = (kUploadWriteCommands != 0); CHECK_STATUS_OK(spi_device_testutils_configure_passthrough( - &spi_device, kFilteredCommands, upload_write_commands)); + &spi_device, kFilteredCommands, upload_write_commands, kWriteComands, + ARRAYSIZE(kWriteCommands), kReadCommands, ARRAYSIZE(kReadCommands))); - // Enable all spi_device and spi_host interrupts, and check that they do not - // trigger unless command upload is enabled. + // Enable all spi_device and spi_host interrupts, and check that they do + // not trigger unless command upload is enabled. dif_spi_device_irq_t all_spi_device_irqs[] = { kDifSpiDeviceIrqUploadCmdfifoNotEmpty, kDifSpiDeviceIrqReadbufWatermark, diff --git a/sw/device/tests/spi_passthru_test.c b/sw/device/tests/spi_passthru_test.c index 41dc25d8fa0247..e5fd7d852ec98f 100644 --- a/sw/device/tests/spi_passthru_test.c +++ b/sw/device/tests/spi_passthru_test.c @@ -301,7 +301,8 @@ bool test_main(void) { CHECK_STATUS_OK(spi_device_testutils_configure_passthrough( &spid, /*filters=*/0x1F, - /*upload_write_commands=*/true)); + /*upload_write_commands=*/true, kWriteCommands, ARRAYSIZE(kWriteCommands), + kReadCommands, ARRAYSIZE(kReadCommands))); dif_spi_device_passthrough_intercept_config_t passthru_cfg = { .status = true,