5 #include "sw/device/lib/testing/spi_flash_emulator.h"
13 #include "sw/device/lib/testing/spi_device_testutils.h"
14 #include "sw/device/lib/testing/spi_flash_testutils.h"
16 #define MODULE_ID MAKE_MODULE_ID('s', 'f', 'e')
20 kJedecContCode = 0x7f,
22 kJedecManufacturer = 0xEF,
24 kJedecContCodeCount = 12,
46 static status_t read_and_prepare_sfdp(dif_spi_host_t *spih,
48 alignas(uint32_t) uint8_t data[256];
49 TRY(spi_flash_testutils_read_sfdp(spih, 0, data,
sizeof(data)));
55 .header = {.signature = kSfdpSignature,
65 .length =
sizeof(
bfpt_t) /
sizeof(uint32_t),
66 .table_pointer = {(uint8_t)offsetof(
sfdp_t,
bfpt)},
73 read_32(data + offsetof(
sfdp_t, param.table_pointer)) & 0x00FFFFFF;
74 if (offset >=
sizeof(data)) {
75 return INVALID_ARGUMENT();
77 uint8_t length = data[offsetof(
sfdp_t, param.length)];
84 sfdp.bfpt.data[0] &= 0x0047FFFF;
86 sfdp.bfpt.data[1] =
read_32(data + offset + 1 *
sizeof(uint32_t));
88 sfdp.bfpt.data[2] =
read_32(data + offset + 2 *
sizeof(uint32_t));
89 sfdp.bfpt.data[2] &= 0xFFFF0000;
91 sfdp.bfpt.data[7] =
read_32(data + offset + 7 *
sizeof(uint32_t));
92 sfdp.bfpt.data[8] =
read_32(data + offset + 8 *
sizeof(uint32_t));
97 uint32_t quad_enable = 0;
101 quad_enable =
read_32(data + offset + 14 *
sizeof(uint32_t));
104 return OK_STATUS((int32_t)quad_enable);
111 .manufacturer_id = kJedecManufacturer,
112 .continuation_code = kJedecContCode,
113 .num_continuation_code = kJedecContCodeCount,
119 status_t spi_flash_emulator(dif_spi_host_t *spih,
122 LOG_INFO(
"Configuring spi_flash_emulator.");
124 TRY(prepare_jedec_id(spid));
125 uint8_t quad_enable = (uint8_t)TRY(read_and_prepare_sfdp(spih, spid));
126 LOG_INFO(
"Setting the EEPROM's QE bit via mechanism %d", quad_enable);
127 TRY(spi_flash_testutils_quad_enable(spih, quad_enable,
true));
129 LOG_INFO(
"Starting spi_flash_emulator.");
133 upload_info_t info = {0};
134 TRY(spi_device_testutils_wait_for_upload(spid, &info));
137 switch (info.opcode) {
138 case kSpiDeviceFlashOpChipErase:
139 TRY(spi_flash_testutils_erase_chip(spih));
141 case kSpiDeviceFlashOpSectorErase:
142 TRY(spi_flash_testutils_erase_sector(spih, info.address, info.addr_4b));
144 case kSpiDeviceFlashOpBlockErase32k:
145 TRY(spi_flash_testutils_erase_op(spih, kSpiDeviceFlashOpBlockErase32k,
146 info.address, info.addr_4b));
148 case kSpiDeviceFlashOpBlockErase64k:
149 TRY(spi_flash_testutils_erase_op(spih, kSpiDeviceFlashOpBlockErase64k,
150 info.address, info.addr_4b));
152 case kSpiDeviceFlashOpPageProgram:
153 TRY(spi_flash_testutils_program_page(spih, info.data, info.data_len,
154 info.address, info.addr_4b));
156 case kSpiDeviceFlashOpSectorErase4b:
157 TRY(spi_flash_testutils_erase_op(spih, kSpiDeviceFlashOpSectorErase4b,
158 info.address,
true));
160 case kSpiDeviceFlashOpBlockErase32k4b:
161 TRY(spi_flash_testutils_erase_op(spih, kSpiDeviceFlashOpBlockErase32k4b,
162 info.address,
true));
164 case kSpiDeviceFlashOpBlockErase64k4b:
165 TRY(spi_flash_testutils_erase_op(spih, kSpiDeviceFlashOpBlockErase64k4b,
166 info.address,
true));
168 case kSpiDeviceFlashOpPageProgram4b:
169 TRY(spi_flash_testutils_program_op(
170 spih, kSpiDeviceFlashOpPageProgram4b, info.data, info.data_len,
172 true, kTransactionWidthMode111));
174 case kSpiDeviceFlashOpReset:
178 LOG_ERROR(
"Unknown SPI op: %02x", info.opcode);
183 LOG_INFO(
"Exiting spi_flash_emulator.");