5 #include "sw/device/lib/testing/json/spi_passthru.h"
11 #include "sw/device/lib/base/status.h"
16 #include "sw/device/lib/testing/json/command.h"
17 #include "sw/device/lib/testing/spi_device_testutils.h"
18 #include "sw/device/lib/testing/spi_flash_emulator.h"
19 #include "sw/device/lib/testing/spi_flash_testutils.h"
20 #include "sw/device/lib/testing/test_framework/check.h"
22 #include "sw/device/lib/testing/test_framework/ujson_ottf.h"
23 #include "sw/device/lib/testing/test_framework/ujson_ottf_commands.h"
24 #include "sw/device/lib/ujson/ujson.h"
28 OTTF_DEFINE_TEST_CONFIG(.enable_uart_flow_control =
true);
30 volatile uint32_t kReadPipelineMode = 0;
32 static uint32_t current_read_pipeline_mode;
34 static dif_spi_host_t spih;
37 config_jedec_id_t config;
38 TRY(UJSON_WITH_CRC(ujson_deserialize_config_jedec_id_t, uj, &config));
41 .manufacturer_id = config.manufacturer_id,
42 .continuation_code = config.continuation_code,
43 .num_continuation_code = config.continuation_len,
46 return RESP_OK_STATUS(uj);
52 TRY(UJSON_WITH_CRC(ujson_deserialize_status_register_t, uj, &sr));
54 return RESP_OK_STATUS(uj);
64 RESP_OK(ujson_serialize_status_register_t, uj, &sr);
70 TRY(UJSON_WITH_CRC(ujson_deserialize_sfdp_data_t, uj, &
sfdp));
73 return RESP_OK_STATUS(uj);
77 upload_info_t info = {0};
78 TRY(spi_device_testutils_wait_for_upload(spid, &info));
82 RESP_OK(ujson_serialize_upload_info_t, uj, &info);
90 TRY(spi_flash_testutils_read_id(spih, &jedec_id));
93 spi_flash_read_id_t uj_id = {
94 .device_id = jedec_id.device_id,
95 .manufacturer_id = jedec_id.manufacturer_id,
96 .continuation_len = jedec_id.continuation_len,
98 return RESP_OK(ujson_serialize_spi_flash_read_id_t, uj, &uj_id);
104 spi_flash_read_sfdp_t op;
105 TRY(UJSON_WITH_CRC(ujson_deserialize_spi_flash_read_sfdp_t, uj, &op));
108 CHECK(op.length <=
sizeof(
sfdp.data));
109 TRY(spi_flash_testutils_read_sfdp(spih, op.address,
sfdp.data, op.length));
112 return RESP_OK(ujson_serialize_sfdp_data_t, uj, &
sfdp);
117 spi_flash_erase_sector_t op;
119 TRY(UJSON_WITH_CRC(ujson_deserialize_spi_flash_erase_sector_t, uj, &op));
120 TRY(spi_flash_testutils_erase_sector(spih, op.address, op.addr4b));
122 return RESP_OK_STATUS(uj);
127 spi_flash_write_t op;
129 TRY(UJSON_WITH_CRC(ujson_deserialize_spi_flash_write_t, uj, &op));
130 if (op.length >
sizeof(op.data)) {
131 LOG_ERROR(
"Flash write length larger than buffer: %u", op.length);
132 return INVALID_ARGUMENT();
135 TRY(spi_flash_testutils_program_page(spih, op.data, op.length, op.address,
138 return RESP_OK_STATUS(uj);
142 spi_mailbox_map_t map;
143 TRY(UJSON_WITH_CRC(ujson_deserialize_spi_mailbox_map_t, uj, &map));
145 return RESP_OK_STATUS(uj);
150 return RESP_OK_STATUS(uj);
154 spi_mailbox_write_t op;
155 TRY(UJSON_WITH_CRC(ujson_deserialize_spi_mailbox_write_t, uj, &op));
156 if (op.length >
sizeof(op.data)) {
157 LOG_ERROR(
"Mailbox write length larger than buffer: %u", op.length);
158 return INVALID_ARGUMENT();
162 op.offset, op.length, op.data));
163 return RESP_OK_STATUS(uj);
168 spi_passthru_swap_map_t swap;
169 TRY(UJSON_WITH_CRC(ujson_deserialize_spi_passthru_swap_map_t, uj, &swap));
171 return RESP_OK_STATUS(uj);
176 test_command_t command;
177 TRY(UJSON_WITH_CRC(ujson_deserialize_test_command_t, uj, &command));
178 status_t result = ujson_ottf_dispatch(uj, command);
179 if (status_ok(result)) {
181 if (current_read_pipeline_mode != kReadPipelineMode) {
182 current_read_pipeline_mode = kReadPipelineMode;
183 CHECK_STATUS_OK(spi_device_testutils_configure_read_pipeline(
184 &spid, current_read_pipeline_mode, current_read_pipeline_mode));
187 }
else if (status_err(result) != kUnimplemented) {
191 case kTestCommandSpiConfigureJedecId:
192 RESP_ERR(uj, configure_jedec_id(uj, &spid));
194 case kTestCommandSpiReadStatus:
195 RESP_ERR(uj, read_status_register(uj, &spid));
197 case kTestCommandSpiWriteStatus:
198 RESP_ERR(uj, write_status_register(uj, &spid));
200 case kTestCommandSpiWriteSfdp:
201 RESP_ERR(uj, write_sfdp_data(uj, &spid));
203 case kTestCommandSpiWaitForUpload:
204 RESP_ERR(uj, wait_for_upload(uj, &spid));
206 case kTestCommandSpiFlashReadId:
207 RESP_ERR(uj, spi_flash_read_id(uj, &spih, &spid));
209 case kTestCommandSpiFlashReadSfdp:
210 RESP_ERR(uj, spi_flash_read_sfdp(uj, &spih, &spid));
212 case kTestCommandSpiFlashEraseSector:
213 RESP_ERR(uj, spi_flash_erase_sector(uj, &spih, &spid));
215 case kTestCommandSpiFlashWrite:
216 RESP_ERR(uj, spi_flash_write(uj, &spih, &spid));
218 case kTestCommandSpiFlashEmulator:
219 RESP_ERR(uj, spi_flash_emulator(&spih, &spid));
221 case kTestCommandSpiMailboxMap:
222 RESP_ERR(uj, spi_mailbox_map(uj, &spid));
224 case kTestCommandSpiMailboxUnmap:
225 RESP_ERR(uj, spi_mailbox_unmap(uj, &spid));
227 case kTestCommandSpiMailboxWrite:
228 RESP_ERR(uj, spi_mailbox_write(uj, &spid));
230 case kTestCommandSpiPassthruSetAddressMap:
231 RESP_ERR(uj, spi_passthru_set_address_map(uj, &spid));
235 LOG_ERROR(
"Unrecognized command: %d", command);
236 RESP_ERR(uj, INVALID_ARGUMENT());
250 CHECK_DIF_OK(dif_pinmux_init(base_addr, &pinmux));
256 .flags = kDifPinmuxPadAttrPullResistorEnable |
257 kDifPinmuxPadAttrPullResistorUp};
278 const uint32_t spi_host_clock_freq_hz =
280 CHECK_DIF_OK(dif_spi_host_init(
284 .peripheral_clock_freq_hz = spi_host_clock_freq_hz,
301 CHECK_STATUS_OK(spi_device_testutils_configure_passthrough(
315 current_read_pipeline_mode = kReadPipelineMode;
316 CHECK_STATUS_OK(spi_device_testutils_configure_read_pipeline(
317 &spid, current_read_pipeline_mode, current_read_pipeline_mode));
319 ujson_t uj = ujson_ottf_console();
320 status_t s = command_processor(&uj);