diff --git a/storage/blockdevice/COMPONENT_QSPIF/include/QSPIF/QSPIFBlockDevice.h b/storage/blockdevice/COMPONENT_QSPIF/include/QSPIF/QSPIFBlockDevice.h index 8bf4c6c..3ebd0e5 100644 --- a/storage/blockdevice/COMPONENT_QSPIF/include/QSPIF/QSPIFBlockDevice.h +++ b/storage/blockdevice/COMPONENT_QSPIF/include/QSPIF/QSPIFBlockDevice.h @@ -376,6 +376,9 @@ bool _needs_fast_mode; + // S25FS512S needs a quirk + bool _S25FS512S_quirk; + // Clear block protection qspif_clear_protection_method_t _clear_protection_method; diff --git a/storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp b/storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp index 05c9f2b..77d3e8c 100644 --- a/storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp +++ b/storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp @@ -176,6 +176,9 @@ // Set default 4-byte addressing extension register write instruction _attempt_4_byte_addressing = true; _4byte_msb_reg_write_inst = QSPIF_INST_4BYTE_REG_WRITE_DEFAULT; + + // Quirk for Cypress S25FS512S + _S25FS512S_quirk = false; } int QSPIFBlockDevice::init() @@ -1099,6 +1102,16 @@ tr_debug("Applying quirks for ISSI"); _num_status_registers = 1; break; + case 0x01: + if (vendor_device_ids[1] == 0x02 && vendor_device_ids[2] == 0x20) { + tr_debug("Applying quirks for Cypress S25FS512S"); + // On a Cypress S25FS512S flash chip + // * 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. + _S25FS512S_quirk = true; + } + break; } return 0; @@ -1469,6 +1482,16 @@ return status; } + // Handle S25FS512S quirk. + 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(rx_buffer)[0] |= (1 << 1); + } + } + return QSPI_STATUS_OK; }