diff --git a/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.cpp b/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.cpp index 8dd0c0f08c..4e776f7e4f 100644 --- a/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.cpp +++ b/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.cpp @@ -64,16 +64,6 @@ using namespace mbed; // Quad Enable Params #define QSPIF_BASIC_PARAM_TABLE_QER_BYTE 58 #define QSPIF_BASIC_PARAM_TABLE_444_MODE_EN_SEQ_BYTE 56 -// Erase Types Params -#define QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE 29 -#define QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_2_BYTE 31 -#define QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_3_BYTE 33 -#define QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_4_BYTE 35 -#define QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE 28 -#define QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_2_SIZE_BYTE 30 -#define QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_3_SIZE_BYTE 32 -#define QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_4_SIZE_BYTE 34 -#define QSPIF_BASIC_PARAM_4K_ERASE_TYPE_BYTE 1 #define QSPIF_BASIC_PARAM_TABLE_SOFT_RESET_BYTE 61 #define QSPIF_BASIC_PARAM_TABLE_4BYTE_ADDR_BYTE 63 @@ -109,7 +99,7 @@ using namespace mbed; // Default read/legacy erase instructions #define QSPIF_INST_READ_DEFAULT 0x03 -#define QSPIF_INST_LEGACY_ERASE_DEFAULT QSPI_NO_INST +#define QSPIF_INST_LEGACY_ERASE_DEFAULT (-1) // Default status register 2 read/write instructions #define QSPIF_INST_WSR2_DEFAULT QSPI_NO_INST @@ -837,17 +827,17 @@ int QSPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size(uint8_t *basic_para uint8_t bitfield = 0x01; // Erase 4K Inst is taken either from param table legacy 4K erase or superseded by erase Instruction for type of size 4K - if (basic_param_table_size > QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE) { + if (basic_param_table_size > SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE) { // Loop Erase Types 1-4 for (int i_ind = 0; i_ind < 4; i_ind++) { smptbl.erase_type_inst_arr[i_ind] = QSPI_NO_INST; // Default for unsupported type smptbl.erase_type_size_arr[i_ind] = 1 - << basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE + 2 * i_ind]; // Size is 2^N where N is the table value + << basic_param_table_ptr[SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE + 2 * i_ind]; // Size is 2^N where N is the table value tr_debug("Erase Type(A) %d - Inst: 0x%xh, Size: %d", (i_ind + 1), smptbl.erase_type_inst_arr[i_ind], smptbl.erase_type_size_arr[i_ind]); if (smptbl.erase_type_size_arr[i_ind] > 1) { // if size==1 type is not supported - smptbl.erase_type_inst_arr[i_ind] = basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE + smptbl.erase_type_inst_arr[i_ind] = basic_param_table_ptr[SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE + 2 * i_ind]; if ((smptbl.erase_type_size_arr[i_ind] < smptbl.regions_min_common_erase_size) @@ -866,7 +856,7 @@ int QSPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size(uint8_t *basic_para tr_debug("SFDP erase types are not available - falling back to legacy 4k erase instruction"); // 0xFF indicates that the legacy 4k erase instruction is not supported - _legacy_erase_instruction = basic_param_table_ptr[QSPIF_BASIC_PARAM_4K_ERASE_TYPE_BYTE]; + _legacy_erase_instruction = basic_param_table_ptr[SFDP_BASIC_PARAM_TABLE_4K_ERASE_TYPE_BYTE]; if (_legacy_erase_instruction == 0xFF) { tr_error("_detectEraseTypesInstAndSize - Legacy 4k erase instruction not supported"); return -1; diff --git a/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.h b/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.h index ba4249901c..8c20b40eef 100644 --- a/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.h +++ b/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.h @@ -386,7 +386,7 @@ private: // Command Instructions mbed::qspi_inst_t _read_instruction; - mbed::qspi_inst_t _legacy_erase_instruction; + int _legacy_erase_instruction; // Status register write/read instructions unsigned int _num_status_registers; diff --git a/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp b/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp index 699ecbf1b1..1e4110e646 100644 --- a/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp +++ b/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp @@ -51,16 +51,11 @@ using namespace mbed; // Address Length #define SPIF_ADDR_SIZE_3_BYTES 3 #define SPIF_ADDR_SIZE_4_BYTES 4 -// Erase Types Params -#define SPIF_BASIC_PARAM_ERASE_TYPE_1_BYTE 29 -#define SPIF_BASIC_PARAM_ERASE_TYPE_2_BYTE 31 -#define SPIF_BASIC_PARAM_ERASE_TYPE_3_BYTE 33 -#define SPIF_BASIC_PARAM_ERASE_TYPE_4_BYTE 35 -#define SPIF_BASIC_PARAM_ERASE_TYPE_1_SIZE_BYTE 28 -#define SPIF_BASIC_PARAM_ERASE_TYPE_2_SIZE_BYTE 30 -#define SPIF_BASIC_PARAM_ERASE_TYPE_3_SIZE_BYTE 32 -#define SPIF_BASIC_PARAM_ERASE_TYPE_4_SIZE_BYTE 34 -#define SPIF_BASIC_PARAM_4K_ERASE_TYPE_BYTE 1 + +// Default read/legacy erase instructions +#define SPIF_INST_READ_DEFAULT 0x03 +#define SPIF_INST_LEGACY_ERASE_DEFAULT (-1) + #define IS_MEM_READY_MAX_RETRIES 10000 @@ -86,16 +81,15 @@ enum spif_default_instructions { // e.g. (1)Set Write Enable, (2)Program, (3)Wait Memory Ready SingletonPtr SPIFBlockDevice::_mutex; -// Local Function -static unsigned int local_math_power(int base, int exp); - //*********************** // SPIF Block Device APIs //*********************** SPIFBlockDevice::SPIFBlockDevice( PinName mosi, PinName miso, PinName sclk, PinName csel, int freq) - : _spi(mosi, miso, sclk), _cs(csel), _read_instruction(0), _prog_instruction(0), _erase_instruction(0), - _erase4k_inst(0), _page_size_bytes(0), _device_size_bytes(0), _init_ref_count(0), _is_initialized(false) + : + _spi(mosi, miso, sclk), _cs(csel), _prog_instruction(0), _erase_instruction(0), + _page_size_bytes(0), + _device_size_bytes(0), _init_ref_count(0), _is_initialized(false) { _address_size = SPIF_ADDR_SIZE_3_BYTES; // Initial SFDP read tables are read with 8 dummy cycles @@ -108,6 +102,11 @@ SPIFBlockDevice::SPIFBlockDevice( _sfdp_info.smptbl.region_cnt = 1; _sfdp_info.smptbl.region_erase_types_bitfld[0] = SFDP_ERASE_BITMASK_NONE; + // Set default read/erase instructions + _read_instruction = SPIF_INST_READ_DEFAULT; + _legacy_erase_instruction = SPIF_INST_LEGACY_ERASE_DEFAULT; + + if (SPIF_BD_ERROR_OK != _spi_set_frequency(freq)) { tr_error("SPI Set Frequency Failed"); } @@ -654,8 +653,8 @@ int SPIFBlockDevice::_sfdp_parse_basic_param_table(Callback SPIF_BASIC_PARAM_ERASE_TYPE_1_SIZE_BYTE) { + if (basic_param_table_size > SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE) { // Loop Erase Types 1-4 for (int i_ind = 0; i_ind < 4; i_ind++) { smptbl.erase_type_inst_arr[i_ind] = 0xff; //0xFF default for unsupported type - smptbl.erase_type_size_arr[i_ind] = local_math_power( - 2, basic_param_table_ptr[SPIF_BASIC_PARAM_ERASE_TYPE_1_SIZE_BYTE + 2 * i_ind]); // Size given as 2^N + smptbl.erase_type_size_arr[i_ind] = 1 + << basic_param_table_ptr[SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE + 2 * i_ind]; // Size given as 2^N tr_debug("Erase Type(A) %d - Inst: 0x%xh, Size: %d", (i_ind + 1), smptbl.erase_type_inst_arr[i_ind], smptbl.erase_type_size_arr[i_ind]); if (smptbl.erase_type_size_arr[i_ind] > 1) { // if size==1 type is not supported smptbl.erase_type_inst_arr[i_ind] = - basic_param_table_ptr[SPIF_BASIC_PARAM_ERASE_TYPE_1_BYTE + 2 * i_ind]; + basic_param_table_ptr[SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE + 2 * i_ind]; if ((smptbl.erase_type_size_arr[i_ind] < smptbl.regions_min_common_erase_size) || (smptbl.regions_min_common_erase_size == 0)) { //Set default minimal common erase for singal region smptbl.regions_min_common_erase_size = smptbl.erase_type_size_arr[i_ind]; } - - // SFDP standard requires 4K Erase type to exist and its instruction to be identical to legacy field erase instruction - if (smptbl.erase_type_size_arr[i_ind] == 4096) { - found_4Kerase_type = true; - if (erase4k_inst != smptbl.erase_type_inst_arr[i_ind]) { - //Verify 4KErase Type is identical to Legacy 4K erase type specified in Byte 1 of Param Table - erase4k_inst = smptbl.erase_type_inst_arr[i_ind]; - tr_warning("_detectEraseTypesInstAndSize - Default 4K erase Inst is different than erase type Inst for 4K"); - - } - } smptbl.region_erase_types_bitfld[0] |= bitfield; // no region map, set region "0" types bitfield as default } tr_info("Erase Type %d - Inst: 0x%xh, Size: %d", (i_ind + 1), smptbl.erase_type_inst_arr[i_ind], smptbl.erase_type_size_arr[i_ind]); bitfield = bitfield << 1; } - } + } else { + tr_debug("SFDP erase types are not available - falling back to legacy 4k erase instruction"); - if (false == found_4Kerase_type) { - tr_warning("Couldn't find Erase Type for 4KB size"); + // 0xFF indicates that the legacy 4k erase instruction is not supported + _legacy_erase_instruction = basic_param_table_ptr[SFDP_BASIC_PARAM_TABLE_4K_ERASE_TYPE_BYTE]; + if (_legacy_erase_instruction == 0xFF) { + tr_error("sfdp_detect_erase_types_inst_and_size - Legacy 4k erase instruction not supported"); + return -1; + } } return 0; } @@ -886,18 +875,3 @@ int SPIFBlockDevice::_utils_iterate_next_largest_erase_type(uint8_t &bitfield, return largest_erase_type; } -/*********************************************/ -/************** Local Functions **************/ -/*********************************************/ -static unsigned int local_math_power(int base, int exp) -{ - // Integer X^Y function, used to calculate size fields given in 2^N format - int result = 1; - while (exp) { - result *= base; - exp--; - } - return result; -} - - diff --git a/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.h b/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.h index 247b052054..20b3389c25 100644 --- a/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.h +++ b/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.h @@ -241,7 +241,6 @@ private: // Detect all supported erase types int _sfdp_detect_erase_types_inst_and_size(uint8_t *basic_param_table_ptr, int basic_param_table_size, - int &erase4k_inst, mbed::sfdp_smptbl_info &smptbl); /***********************/ @@ -302,7 +301,7 @@ private: int _read_instruction; int _prog_instruction; int _erase_instruction; - int _erase4k_inst; // Legacy 4K erase instruction (default 0x20h) + int _legacy_erase_instruction; // Legacy 4K erase instruction (default 0x20h) // Data extracted from the devices SFDP structure mbed::sfdp_hdr_info _sfdp_info; diff --git a/drivers/internal/SFDP.h b/drivers/internal/SFDP.h index c97909d88c..d09512875a 100644 --- a/drivers/internal/SFDP.h +++ b/drivers/internal/SFDP.h @@ -45,6 +45,17 @@ static const int SFDP_ERASE_BITMASK_TYPE1 = 0x01; ///< Erase type 1 (erase granu static const int SFDP_ERASE_BITMASK_NONE = 0x00; ///< Erase type None static const int SFDP_ERASE_BITMASK_ALL = 0x0F; ///< Erase type All +// Erase Types Params +#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE 29 +#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_2_BYTE 31 +#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_3_BYTE 33 +#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_4_BYTE 35 +#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE 28 +#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_2_SIZE_BYTE 30 +#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_3_SIZE_BYTE 32 +#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_4_SIZE_BYTE 34 +#define SFDP_BASIC_PARAM_TABLE_4K_ERASE_TYPE_BYTE 1 + static const int SFDP_MAX_NUM_OF_ERASE_TYPES = 4; ///< Maximum number of different erase types (erase granularity) /** SFDP Basic Parameter Table info */