From 05d60b11e67f4826215cbb40bf08a625bd2483f7 Mon Sep 17 00:00:00 2001 From: Lingkai Dong Date: Tue, 10 Aug 2021 10:01:59 +0100 Subject: [PATCH] QSPIFBlockDevice: Handle CR3NV[1] quirk on S25FS512S Cypress S25FS512S's SFDP table suggests checking bit-1 of the register 25FS512S as part of configuration detection. This bit should equal 1 in order for configuration to be correctly determined, but it is 0 on actual hardware. We add a quirk to work around this. Note: In Mbed OS, vendor-specific quirks are handled in block devices, and the SFDP class is agnostic of any quirks. So when the SFDP class requests the value of CR3NV, we let QSPIFBlockDevice's SFDP reader callback to set bit-1 of the output to 1 to allow the SFDP class to work correctly. --- .../include/QSPIF/QSPIFBlockDevice.h | 1 + .../source/QSPIFBlockDevice.cpp | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/storage/blockdevice/COMPONENT_QSPIF/include/QSPIF/QSPIFBlockDevice.h b/storage/blockdevice/COMPONENT_QSPIF/include/QSPIF/QSPIFBlockDevice.h index 8bf4c6cccf00..fa11bd95cb62 100644 --- a/storage/blockdevice/COMPONENT_QSPIF/include/QSPIF/QSPIFBlockDevice.h +++ b/storage/blockdevice/COMPONENT_QSPIF/include/QSPIF/QSPIFBlockDevice.h @@ -375,6 +375,7 @@ class QSPIFBlockDevice : public mbed::BlockDevice { int _quad_enable_bit; bool _needs_fast_mode; + bool _CR3NV_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 599b61a5592a..1f0275ec051f 100644 --- a/storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp +++ b/storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp @@ -176,6 +176,9 @@ QSPIFBlockDevice::QSPIFBlockDevice(PinName io0, PinName io1, PinName io2, PinNam // 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 CR3NV[1] on Cypress S25FS512S + _CR3NV_quirk = false; } int QSPIFBlockDevice::init() @@ -1099,6 +1102,15 @@ int QSPIFBlockDevice::_handle_vendor_quirks() tr_debug("Applying quirks for ISSI"); _num_status_registers = 1; break; + case 0x01: + if (vendor_device_ids[1] == 0x02 && vendor_device_ids[2] == 0x20) { + // On a Cypress S25FS512S flash chip, bit-1 of the register CR3NV is + // expected to be 1 but its actual value is 0 on manufactured hardware. + // In order for configuration detection to work, this chip needs to be + // specially handled. + _CR3NV_quirk = true; + } + break; } return 0; @@ -1469,6 +1481,14 @@ int QSPIFBlockDevice::_qspi_send_read_sfdp_command(mbed::bd_addr_t addr, mbed::s return status; } + // Handle CR3NV[1] quirk. + const mbed::bd_addr_t register_CR3NV = 0x000004; + if (_CR3NV_quirk && (addr == register_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] |= 0x01; + } + return QSPI_STATUS_OK; }