57 .cmd = JEDEC_CMD_READ,
60 .cfg = WSPI_CFG_ADDR_SIZE_24 |
61#if JEDEC_BUS_MODE == JEDEC_BUS_MODE_WSPI1L
62 WSPI_CFG_CMD_MODE_ONE_LINE |
63 WSPI_CFG_ADDR_MODE_ONE_LINE |
64 WSPI_CFG_DATA_MODE_ONE_LINE |
65#elif JEDEC_BUS_MODE == JEDEC_BUS_MODE_WSPI2L
66 WSPI_CFG_CMD_MODE_TWO_LINES |
67 WSPI_CFG_ADDR_MODE_TWO_LINES |
68 WSPI_CFG_DATA_MODE_TWO_LINES |
70 WSPI_CFG_CMD_MODE_FOUR_LINES |
71 WSPI_CFG_ADDR_MODE_FOUR_LINES |
72 WSPI_CFG_DATA_MODE_FOUR_LINES |
74 WSPI_CFG_ALT_MODE_NONE
124 static const wspi_command_t cmd_reset_enable_1 = {
125 .cmd = JEDEC_CMD_RESET_ENABLE,
126 .cfg = WSPI_CFG_CMD_MODE_ONE_LINE,
133 static const wspi_command_t cmd_reset_memory_1 = {
134 .cmd = JEDEC_CMD_RESET_MEMORY,
135 .cfg = WSPI_CFG_CMD_MODE_ONE_LINE,
145#if JEDEC_BUS_MODE == JEDEC_BUS_MODE_WSPI4L
147 static const wspi_command_t cmd_reset_enable_4 = {
148 .cmd = JEDEC_CMD_RESET_ENABLE,
149 .cfg = WSPI_CFG_CMD_MODE_FOUR_LINES,
156 static const wspi_command_t cmd_reset_memory_4 = {
157 .cmd = JEDEC_CMD_RESET_MEMORY,
158 .cfg = WSPI_CFG_CMD_MODE_FOUR_LINES,
164 wspiCommand(devp->config->busp, &cmd_reset_enable_4);
165 wspiCommand(devp->config->busp, &cmd_reset_memory_4);
166#elif JEDEC_BUS_MODE == JEDEC_BUS_MODE_WSPI4L
168 static const wspi_command_t cmd_reset_enable_2 = {
169 .cmd = JEDEC_CMD_RESET_ENABLE,
170 .cfg = WSPI_CFG_CMD_MODE_TWO_LINES,
177 static const wspi_command_t cmd_reset_memory_2 = {
178 .cmd = JEDEC_CMD_RESET_MEMORY,
179 .cfg = WSPI_CFG_CMD_MODE_TWO_LINES,
185 wspiCommand(devp->config->busp, &cmd_reset_enable_2);
186 wspiCommand(devp->config->busp, &cmd_reset_memory_2);
191 wspiCommand(devp->config->busp, &cmd_reset_enable_1);
192 wspiCommand(devp->config->busp, &cmd_reset_memory_1);
217 uint32_t cfg, uint8_t opcode,
218 uint8_t mode_clocks, uint8_t dummy_clocks)
226 uint8_t mode_bytes = 0;
229 if ((cmd->cfg & WSPI_CFG_ADDR_MODE_MASK) == WSPI_CFG_ADDR_MODE_ONE_LINE) {
230 cmd->cfg |= WSPI_CFG_ALT_MODE_ONE_LINE;
231 mode_bytes = mode_clocks / 8;
232 }
else if ((cmd->cfg & WSPI_CFG_ADDR_MODE_MASK) == WSPI_CFG_ADDR_MODE_TWO_LINES) {
233 cmd->cfg |= WSPI_CFG_ALT_MODE_TWO_LINES;
234 mode_bytes = mode_clocks / 4;
235 }
else if ((cmd->cfg & WSPI_CFG_ADDR_MODE_MASK) == WSPI_CFG_ADDR_MODE_FOUR_LINES) {
236 cmd->cfg |= WSPI_CFG_ALT_MODE_FOUR_LINES;
237 mode_bytes = mode_clocks / 2;
244 cmd->cfg |= WSPI_CFG_ALT_SIZE_8;
245 else if (mode_bytes == 2)
246 cmd->cfg |= WSPI_CFG_ALT_SIZE_16;
247 else if (mode_bytes == 3)
248 cmd->cfg |= WSPI_CFG_ALT_SIZE_24;
249 else if (mode_bytes == 4)
250 cmd->cfg |= WSPI_CFG_ALT_SIZE_32;
252 osalDbgAssert(0,
"Failed to calculate alternative bytes size");
254 cmd->cfg |= WSPI_CFG_ALT_MODE_NONE;
257 cmd->dummy = dummy_clocks;
267 uint8_t parameter_headers_n;
269 uint8_t *buf = (uint8_t *)
sfdpbuf;
272 flash_offset_t
offset = 0;
273 const uint8_t sfdp_sign[4] = {0x53, 0x46, 0x44, 0x50};
275#if SNOR_BUS_DRIVER == SNOR_BUS_DRIVER_WSPI
295 bus_cmd(devp, JEDEC_CMD_GLOBAL_BLOCK_PROTECTION_UNLOCK);
301 osalDbgAssert(memcmp(sfdp_sign, buf, 4) == 0,
302 "chip does not support SFDP");
305 parameter_headers_n = buf[6];
306 for (i = 0; i < parameter_headers_n; i++) {
312 if (buf[0] != 0x00) {
318 offset = buf[4] | (buf[5] << 8) | (buf[6] << 16);
330 osalDbgAssert(i != parameter_headers_n,
331 "JEDEC SFDP parameters block not found");
335 if (sfdp[1] & 0x80000000)
347 if (sfdp[0] & (1 << 21)) {
350 WSPI_CFG_CMD_MODE_ONE_LINE | WSPI_CFG_CMD_SIZE_8 |
351 WSPI_CFG_ADDR_MODE_FOUR_LINES |
352 WSPI_CFG_DATA_MODE_FOUR_LINES,
353 (sfdp[2] >> 8) & 0xff, (sfdp[2] >> 5) & 0x07, (sfdp[2] >> 0) & 0x1f);
354 }
else if (sfdp[0] & (1 << 22)) {
357 WSPI_CFG_CMD_MODE_ONE_LINE | WSPI_CFG_CMD_SIZE_8 |
358 WSPI_CFG_ADDR_MODE_ONE_LINE |
359 WSPI_CFG_DATA_MODE_FOUR_LINES,
360 (sfdp[2] >> 24) & 0xff, (sfdp[2] >> 21) & 0x07, (sfdp[2] >> 16) & 0x1f);
361 }
else if (sfdp[0] & (1 << 20)) {
364 WSPI_CFG_CMD_MODE_ONE_LINE | WSPI_CFG_CMD_SIZE_8 |
365 WSPI_CFG_ADDR_MODE_TWO_LINES |
366 WSPI_CFG_DATA_MODE_TWO_LINES,
367 (sfdp[3] >> 24) & 0xff, (sfdp[3] >> 21) & 0x07, (sfdp[3] >> 16) & 0x1f);
368 }
else if (sfdp[0] & (1 << 16)) {
371 WSPI_CFG_CMD_MODE_ONE_LINE | WSPI_CFG_CMD_SIZE_8 |
372 WSPI_CFG_ADDR_MODE_ONE_LINE |
373 WSPI_CFG_DATA_MODE_TWO_LINES,
374 (sfdp[3] >> 8) & 0xff, (sfdp[3] >> 5) & 0x07, (sfdp[3] >> 0) & 0x1f);
379 WSPI_CFG_CMD_MODE_ONE_LINE | WSPI_CFG_CMD_SIZE_8 |
380 WSPI_CFG_ADDR_MODE_ONE_LINE |
381 WSPI_CFG_DATA_MODE_ONE_LINE,
382 JEDEC_CMD_FAST_READ, 0, 8);
387 WSPI_CFG_CMD_MODE_ONE_LINE | WSPI_CFG_CMD_SIZE_8 |
388 WSPI_CFG_ADDR_MODE_ONE_LINE,
389 JEDEC_CMD_SUBSECTOR_ERASE, 0, 0);
392 WSPI_CFG_CMD_MODE_ONE_LINE | WSPI_CFG_CMD_SIZE_8 |
393 WSPI_CFG_ADDR_MODE_ONE_LINE |
394 WSPI_CFG_DATA_MODE_ONE_LINE,
395 JEDEC_CMD_PAGE_PROGRAM, 0, 0);
547 size_t n, uint8_t *rp) {
549 wspi_command_t jedec_cmd_read_sfdp = {
550 .cmd = JEDEC_CMD_READ_DISCOVERY_PARAMETER,
551 .cfg = WSPI_CFG_CMD_MODE_ONE_LINE |
552 WSPI_CFG_CMD_SIZE_8 |
553 WSPI_CFG_ADDR_MODE_ONE_LINE |
554 WSPI_CFG_ADDR_SIZE_24 |
555 WSPI_CFG_ALT_MODE_NONE |
556 WSPI_CFG_DATA_MODE_ONE_LINE,
563 size_t chunk = n <
sizeof(tmpbuf) ? n :
sizeof(tmpbuf);
565 jedec_cmd_read_sfdp.addr =
offset;
567 if (wspiReceive(devp->config->busp, &jedec_cmd_read_sfdp, chunk, tmpbuf))
568 return FLASH_ERROR_HW_FAILURE;
570 memcpy(rp, tmpbuf, chunk);
577 return FLASH_NO_ERROR;
598 static const uint8_t flash_conf[1] = {
599 (JEDEC_READ_DUMMY_CYCLES << 4U) | 0x0FU
608 cmd.dummy = JEDEC_READ_DUMMY_CYCLES - 2U;
609 cmd.cfg = WSPI_CFG_CMD_MODE_NONE |
610 WSPI_CFG_ADDR_SIZE_24 |
611#if JEDEC_BUS_MODE == JEDEC_BUS_MODE_WSPI1L
612 WSPI_CFG_ADDR_MODE_ONE_LINE |
613 WSPI_CFG_DATA_MODE_ONE_LINE |
614#elif JEDEC_BUS_MODE == JEDEC_BUS_MODE_WSPI2L
615 WSPI_CFG_ADDR_MODE_TWO_LINES |
616 WSPI_CFG_DATA_MODE_TWO_LINES |
617#elif JEDEC_BUS_MODE == JEDEC_BUS_MODE_WSPI4L
618 WSPI_CFG_ADDR_MODE_FOUR_LINES |
619 WSPI_CFG_DATA_MODE_FOUR_LINES |
621 WSPI_CFG_ADDR_MODE_EIGHT_LINES |
622 WSPI_CFG_DATA_MODE_EIGHT_LINES |
624 WSPI_CFG_ALT_MODE_FOUR_LINES |
626 wspiReceive(devp->config->busp, &cmd, 1, buf);
631 bus_cmd_send(devp, JEDEC_CMD_WRITE_V_CONF_REGISTER,