mirror of https://github.com/ARMmbed/mbed-os.git
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.pull/14989/head
parent
6032671b41
commit
23a79ef459
|
@ -1109,6 +1109,13 @@ int QSPIFBlockDevice::_handle_vendor_quirks()
|
|||
// * The SFDP table expects the register bitfield CR3NV[1] to be 1
|
||||
// but its actual value on the hardware is 0. In order for SFDP parsing
|
||||
// to work, the quirk reports CR3NV[1] as 1.
|
||||
// * All three possible configurations support 256KB sectors across
|
||||
// the entire chip. But when CR3NV[3] is 0, eight 4KB sectors overlay
|
||||
// either the first 32KB or the last 32KB of the chip, whereas when
|
||||
// CR3NV[3] is 1 there are no overlaying 4KB sectors. Mbed OS can't
|
||||
// handle this type of overlay, so the quirk reports CR3NV[3] as 1 to
|
||||
// let the code treat the chip as if it has no overlay. (Also CR1NV[2]
|
||||
// is required to be 0 when CR3NV[3] is 1.)
|
||||
_S25FS512S_quirk = true;
|
||||
}
|
||||
break;
|
||||
|
@ -1483,12 +1490,16 @@ int QSPIFBlockDevice::_qspi_send_read_sfdp_command(mbed::bd_addr_t addr, mbed::s
|
|||
}
|
||||
|
||||
// Handle S25FS512S quirk.
|
||||
const mbed::bd_addr_t S25FS512S_CR1NV = 0x2;
|
||||
const mbed::bd_addr_t S25FS512S_CR3NV = 0x4;
|
||||
if (_S25FS512S_quirk) {
|
||||
if (addr == S25FS512S_CR3NV) {
|
||||
// If we reach here, rx_buffer is guaranteed to be non-null
|
||||
// because it's been checked by _qspi.read() above.
|
||||
static_cast<uint8_t *>(rx_buffer)[0] |= (1 << 1);
|
||||
static_cast<uint8_t *>(rx_buffer)[0] |= (1 << 3);
|
||||
} else if (addr == S25FS512S_CR1NV) {
|
||||
static_cast<uint8_t *>(rx_buffer)[0] &= ~(1 << 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue