Skip to content

Commit 23a79ef

Browse files
committed
QSPIFBlockDevice: Add quirk to ignore overlaying sectors on S25FS512S
The entire flash chip S25FS512S consists of uniform 256KB sectors. Additionally, it has three configurations: * 0x01: Eight 4KB sectors (32KB in total) overlaying the start of the first 256KB sector * 0x03: Eight 4KB sectors (32KB in total) overlaying the end of the last 256KB sector * 0x05: No overlaying sectors The active configuration is determined from bit fields of two registers, CR1NV and CR3NV. Mbed OS does not currently support partially overlaying sectors, meaning that with eight 4KB sectors overlay a 256KB sectors, the remaining 224KB (== 256KB - 8 * 4KB) of the big sector can't be correctly handled. Supporting such scenario would involve a large amount of rewriting in Mbed OS's BlockDevice, SFDP and their tests, and may increase the code size. So, this commit applies a quirk to always report configuration 0x05 (no overlaying sectors). Even if 0x01 or 0x03 is the real configuration, they are compatible with the 0x05 configuration because 256KB sectors exist in all cases. Note: This quirk does *not* change actual configurations on hardware, because registers CR1NV and CR3NV are one-time configurable (OTP) - each bit field has a factory value of 0 and can be changed to 1 by the user but not back to 0. So QSPIFBlockDevice avoids changing them.
1 parent 6032671 commit 23a79ef

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,13 @@ int QSPIFBlockDevice::_handle_vendor_quirks()
11091109
// * The SFDP table expects the register bitfield CR3NV[1] to be 1
11101110
// but its actual value on the hardware is 0. In order for SFDP parsing
11111111
// to work, the quirk reports CR3NV[1] as 1.
1112+
// * All three possible configurations support 256KB sectors across
1113+
// the entire chip. But when CR3NV[3] is 0, eight 4KB sectors overlay
1114+
// either the first 32KB or the last 32KB of the chip, whereas when
1115+
// CR3NV[3] is 1 there are no overlaying 4KB sectors. Mbed OS can't
1116+
// handle this type of overlay, so the quirk reports CR3NV[3] as 1 to
1117+
// let the code treat the chip as if it has no overlay. (Also CR1NV[2]
1118+
// is required to be 0 when CR3NV[3] is 1.)
11121119
_S25FS512S_quirk = true;
11131120
}
11141121
break;
@@ -1483,12 +1490,16 @@ int QSPIFBlockDevice::_qspi_send_read_sfdp_command(mbed::bd_addr_t addr, mbed::s
14831490
}
14841491

14851492
// Handle S25FS512S quirk.
1493+
const mbed::bd_addr_t S25FS512S_CR1NV = 0x2;
14861494
const mbed::bd_addr_t S25FS512S_CR3NV = 0x4;
14871495
if (_S25FS512S_quirk) {
14881496
if (addr == S25FS512S_CR3NV) {
14891497
// If we reach here, rx_buffer is guaranteed to be non-null
14901498
// because it's been checked by _qspi.read() above.
14911499
static_cast<uint8_t *>(rx_buffer)[0] |= (1 << 1);
1500+
static_cast<uint8_t *>(rx_buffer)[0] |= (1 << 3);
1501+
} else if (addr == S25FS512S_CR1NV) {
1502+
static_cast<uint8_t *>(rx_buffer)[0] &= ~(1 << 2);
14921503
}
14931504
}
14941505

0 commit comments

Comments
 (0)