diff --git a/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.cpp b/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.cpp index 698c669532..1e04235cc0 100644 --- a/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.cpp +++ b/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.cpp @@ -83,11 +83,6 @@ using namespace mbed; #define SOFT_RESET_RESET_INST_BITMASK 0b001000 #define SOFT_RESET_ENABLE_AND_RESET_INST_BITMASK 0b010000 -// Erase Types Per Region BitMask -#define ERASE_BITMASK_TYPE4 0x08 -#define ERASE_BITMASK_TYPE1 0x01 -#define ERASE_BITMASK_NONE 0x00 -#define ERASE_BITMASK_ALL 0x0F // 4-Byte Addressing Support Bitmasks #define FOURBYTE_ADDR_B7_BITMASK 0b00000001 @@ -157,9 +152,9 @@ QSPIFBlockDevice::QSPIFBlockDevice(PinName io0, PinName io1, PinName io2, PinNam } // Initialize parameters - _min_common_erase_size = 0; - _regions_count = 1; - _region_erase_types_bitfield[0] = ERASE_BITMASK_NONE; + _sfdp_info.smtbl._min_common_erase_size = 0; + _sfdp_info.smtbl._regions_count = 1; + _sfdp_info.smtbl._region_erase_types_bitfield[0] = SFDP_ERASE_BITMASK_NONE; // Until proven otherwise, assume no quad enable _quad_enable_register_idx = QSPIF_NO_QUAD_ENABLE; @@ -203,8 +198,10 @@ int QSPIFBlockDevice::init() } int status = QSPIF_BD_ERROR_OK; - sfdp_hdr_info hdr_info; - memset(&hdr_info, 0, sizeof hdr_info); + _sfdp_info.bptbl.addr = 0x0; + _sfdp_info.bptbl.size = 0; + _sfdp_info.smtbl.addr = 0x0; + _sfdp_info.smtbl.size = 0; _mutex.lock(); @@ -248,29 +245,29 @@ int QSPIFBlockDevice::init() } /**************************** Parse SFDP Header ***********************************/ - if (sfdp_parse_headers(callback(this, &QSPIFBlockDevice::_qspi_send_read_sfdp_command), hdr_info) < 0) { + if (sfdp_parse_headers(callback(this, &QSPIFBlockDevice::_qspi_send_read_sfdp_command), _sfdp_info) < 0) { tr_error("Init - Parse SFDP Headers Failed"); status = QSPIF_BD_ERROR_PARSING_FAILED; goto exit_point; } /**************************** Parse Basic Parameters Table ***********************************/ - if (0 != _sfdp_parse_basic_param_table(hdr_info.bptbl.addr, hdr_info.bptbl.size)) { + if (0 != _sfdp_parse_basic_param_table(_sfdp_info.bptbl.addr, _sfdp_info.bptbl.size)) { tr_error("Init - Parse Basic Param Table Failed"); status = QSPIF_BD_ERROR_PARSING_FAILED; goto exit_point; } /**************************** Parse Sector Map Table ***********************************/ - _region_size_bytes[0] = + _sfdp_info.smtbl._region_size_bytes[0] = _device_size_bytes; // If there's no region map, we have a single region sized the entire device size - _region_high_boundary[0] = _device_size_bytes - 1; + _sfdp_info.smtbl._region_high_boundary[0] = _device_size_bytes - 1; - if ((hdr_info.smtbl.addr != 0) && (0 != hdr_info.smtbl.size)) { - tr_debug("Init - Parsing Sector Map Table - addr: 0x%lxh, Size: %d", hdr_info.smtbl.addr, - hdr_info.smtbl.size); + if ((_sfdp_info.smtbl.addr != 0) && (0 != _sfdp_info.smtbl.size)) { + tr_debug("Init - Parsing Sector Map Table - addr: 0x%lxh, Size: %d", _sfdp_info.smtbl.addr, + _sfdp_info.smtbl.size); if (_sfdp_parse_sector_map_table(callback(this, &QSPIFBlockDevice::_qspi_send_read_sfdp_command), - hdr_info.smtbl) < 0) { + _sfdp_info.smtbl) < 0) { tr_error("Init - Parse Sector Map Table Failed"); status = QSPIF_BD_ERROR_PARSING_FAILED; goto exit_point; @@ -412,9 +409,9 @@ int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size) bool erase_failed = false; int status = QSPIF_BD_ERROR_OK; // Find region of erased address - int region = _utils_find_addr_region(addr); + int region = _utils_find_addr_region(addr, _sfdp_info.smtbl); // Erase Types of selected region - uint8_t bitfield = _region_erase_types_bitfield[region]; + uint8_t bitfield = _sfdp_info.smtbl._region_erase_types_bitfield[region]; tr_debug("Erase - addr: %llu, in_size: %llu", addr, in_size); @@ -434,9 +431,11 @@ int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size) if (_legacy_erase_instruction == QSPI_NO_INST) { // Iterate to find next largest erase type that is a) supported by region, and b) smaller than size. // Find the matching instruction and erase size chunk for that type. - type = _utils_iterate_next_largest_erase_type(bitfield, size, (int)addr, _region_high_boundary[region]); - cur_erase_inst = _erase_type_inst_arr[type]; - eu_size = _erase_type_size_arr[type]; + type = _utils_iterate_next_largest_erase_type(bitfield, size, (int)addr, + region, + _sfdp_info.smtbl); + cur_erase_inst = _sfdp_info.smtbl._erase_type_inst_arr[type]; + eu_size = _sfdp_info.smtbl._erase_type_size_arr[type]; } else { // Must use legacy 4k erase instruction cur_erase_inst = _legacy_erase_instruction; @@ -469,10 +468,10 @@ int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size) addr += chunk; size -= chunk; - if ((size > 0) && (addr > _region_high_boundary[region])) { + if ((size > 0) && (addr > _sfdp_info.smtbl._region_high_boundary[region])) { // erase crossed to next region region++; - bitfield = _region_erase_types_bitfield[region]; + bitfield = _sfdp_info.smtbl._region_erase_types_bitfield[region]; } if (false == _is_mem_ready()) { @@ -508,7 +507,7 @@ bd_size_t QSPIFBlockDevice::get_program_size() const bd_size_t QSPIFBlockDevice::get_erase_size() const { // return minimal erase size supported by all regions (0 if none exists) - return _min_common_erase_size; + return _sfdp_info.smtbl._min_common_erase_size; } const char *QSPIFBlockDevice::get_type() const @@ -525,10 +524,10 @@ bd_size_t QSPIFBlockDevice::get_erase_size(bd_addr_t addr) } // Find region of current address - int region = _utils_find_addr_region(addr); + int region = _utils_find_addr_region(addr, _sfdp_info.smtbl); - int min_region_erase_size = _min_common_erase_size; - int8_t type_mask = ERASE_BITMASK_TYPE1; + int min_region_erase_size = _sfdp_info.smtbl._min_common_erase_size; + int8_t type_mask = SFDP_ERASE_BITMASK_TYPE1; int i_ind = 0; if (region != -1) { @@ -536,9 +535,9 @@ bd_size_t QSPIFBlockDevice::get_erase_size(bd_addr_t addr) for (i_ind = 0; i_ind < 4; i_ind++) { // loop through erase types bitfield supported by region - if (_region_erase_types_bitfield[region] & type_mask) { + if (_sfdp_info.smtbl._region_erase_types_bitfield[region] & type_mask) { - min_region_erase_size = _erase_type_size_arr[i_ind]; + min_region_erase_size = _sfdp_info.smtbl._erase_type_size_arr[i_ind]; break; } type_mask = type_mask << 1; @@ -662,7 +661,7 @@ int QSPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, s bool shouldSetQuadEnable = false; bool is_qpi_mode = false; - if (_sfdp_detect_erase_types_inst_and_size(param_table, basic_table_size) != 0) { + if (_sfdp_detect_erase_types_inst_and_size(param_table, basic_table_size, _sfdp_info.smtbl) != 0) { tr_error("Init - Detecting erase types instructions/sizes failed"); return -1; } @@ -846,7 +845,9 @@ int QSPIFBlockDevice::_sfdp_detect_page_size(uint8_t *basic_param_table_ptr, int return page_size; } -int QSPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size(uint8_t *basic_param_table_ptr, int basic_param_table_size) +int QSPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size(uint8_t *basic_param_table_ptr, + int basic_param_table_size, + sfdp_smtbl_info &smtbl) { uint8_t bitfield = 0x01; @@ -854,23 +855,26 @@ int QSPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size(uint8_t *basic_para if (basic_param_table_size > QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE) { // Loop Erase Types 1-4 for (int i_ind = 0; i_ind < 4; i_ind++) { - _erase_type_inst_arr[i_ind] = QSPI_NO_INST; // Default for unsupported type - _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 - tr_debug("Erase Type(A) %d - Inst: 0x%xh, Size: %d", (i_ind + 1), _erase_type_inst_arr[i_ind], - _erase_type_size_arr[i_ind]); - if (_erase_type_size_arr[i_ind] > 1) { + smtbl._erase_type_inst_arr[i_ind] = QSPI_NO_INST; // Default for unsupported type + smtbl._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 + tr_debug("Erase Type(A) %d - Inst: 0x%xh, Size: %d", (i_ind + 1), smtbl._erase_type_inst_arr[i_ind], + smtbl._erase_type_size_arr[i_ind]); + if (smtbl._erase_type_size_arr[i_ind] > 1) { // if size==1 type is not supported - _erase_type_inst_arr[i_ind] = basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE + 2 * i_ind]; + smtbl._erase_type_inst_arr[i_ind] = basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE + + 2 * i_ind]; - if ((_erase_type_size_arr[i_ind] < _min_common_erase_size) || (_min_common_erase_size == 0)) { + if ((smtbl._erase_type_size_arr[i_ind] < smtbl._min_common_erase_size) + || (smtbl._min_common_erase_size == 0)) { //Set default minimal common erase for signal region - _min_common_erase_size = _erase_type_size_arr[i_ind]; + smtbl._min_common_erase_size = smtbl._erase_type_size_arr[i_ind]; } - _region_erase_types_bitfield[0] |= bitfield; // If there's no region map, set region "0" types bitfield as default + smtbl._region_erase_types_bitfield[0] |= bitfield; // If there's no region map, set region "0" types bitfield as default } - tr_debug("Erase Type %d - Inst: 0x%xh, Size: %d", (i_ind + 1), _erase_type_inst_arr[i_ind], - _erase_type_size_arr[i_ind]); + tr_debug("Erase Type %d - Inst: 0x%xh, Size: %d", (i_ind + 1), smtbl._erase_type_inst_arr[i_ind], + smtbl._erase_type_size_arr[i_ind]); bitfield = bitfield << 1; } } else { @@ -1106,16 +1110,16 @@ int QSPIFBlockDevice::_sfdp_detect_reset_protocol_and_reset(uint8_t *basic_param int QSPIFBlockDevice::_sfdp_parse_sector_map_table(Callback sfdp_reader, sfdp_smtbl_info &smtbl) { - uint8_t sector_map_table[SFDP_BASIC_PARAMS_TBL_SIZE]; /* Up To 16 DWORDS = 64 Bytes */ + uint8_t sector_map_table[SFDP_BASIC_PARAMS_TBL_SIZE]; /* Up To 20 DWORDS = 80 Bytes */ uint32_t tmp_region_size = 0; int i_ind = 0; int prev_boundary = 0; // Default set to all type bits 1-4 are common - int min_common_erase_type_bits = ERASE_BITMASK_ALL; + int min_common_erase_type_bits = SFDP_ERASE_BITMASK_ALL; int status = sfdp_reader(smtbl.addr, sector_map_table, smtbl.size); if (status < 0) { - tr_error("Init - Read SFDP First Table Failed"); + tr_error("table retrieval failed"); return -1; } @@ -1125,29 +1129,30 @@ int QSPIFBlockDevice::_sfdp_parse_sector_map_table(Callback QSPIF_MAX_REGIONS) { + smtbl._regions_count = sector_map_table[2] + 1; + if (smtbl._regions_count > SFDP_SECTOR_MAP_MAX_REGIONS) { tr_error("Supporting up to %d regions, current setup to %d regions - fail", - QSPIF_MAX_REGIONS, _regions_count); + SFDP_SECTOR_MAP_MAX_REGIONS, + smtbl.regions_count); return -1; } // Loop through Regions and set for each one: size, supported erase types, high boundary offset // Calculate minimum Common Erase Type for all Regions - for (i_ind = 0; i_ind < _regions_count; i_ind++) { + for (i_ind = 0; i_ind < smtbl._regions_count; i_ind++) { tmp_region_size = ((*((uint32_t *)§or_map_table[(i_ind + 1) * 4])) >> 8) & 0x00FFFFFF; // bits 9-32 - _region_size_bytes[i_ind] = (tmp_region_size + 1) * 256; // Region size is 0 based multiple of 256 bytes; - _region_erase_types_bitfield[i_ind] = sector_map_table[(i_ind + 1) * 4] & 0x0F; // bits 1-4 - min_common_erase_type_bits &= _region_erase_types_bitfield[i_ind]; - _region_high_boundary[i_ind] = (_region_size_bytes[i_ind] - 1) + prev_boundary; - prev_boundary = _region_high_boundary[i_ind] + 1; + smtbl._region_size_bytes[i_ind] = (tmp_region_size + 1) * 256; // Region size is 0 based multiple of 256 bytes; + smtbl._region_erase_types_bitfield[i_ind] = sector_map_table[(i_ind + 1) * 4] & 0x0F; // bits 1-4 + min_common_erase_type_bits &= smtbl._region_erase_types_bitfield[i_ind]; + smtbl._region_high_boundary[i_ind] = (smtbl._region_size_bytes[i_ind] - 1) + prev_boundary; + prev_boundary = smtbl._region_high_boundary[i_ind] + 1; } // Calc minimum Common Erase Size from min_common_erase_type_bits - uint8_t type_mask = ERASE_BITMASK_TYPE1; + uint8_t type_mask = SFDP_ERASE_BITMASK_TYPE1; for (i_ind = 0; i_ind < 4; i_ind++) { if (min_common_erase_type_bits & type_mask) { - _min_common_erase_size = _erase_type_size_arr[i_ind]; + smtbl._min_common_erase_size = smtbl._erase_type_size_arr[i_ind]; break; } type_mask = type_mask << 1; @@ -1155,7 +1160,7 @@ int QSPIFBlockDevice::_sfdp_parse_sector_map_table(Callback _device_size_bytes) || (_regions_count == 0)) { + if ((offset > _device_size_bytes) || (smtbl._regions_count == 0)) { return -1; } - if (_regions_count == 1) { + if (smtbl._regions_count == 1) { return 0; } - for (int i_ind = _regions_count - 2; i_ind >= 0; i_ind--) { + for (int i_ind = smtbl._regions_count - 2; i_ind >= 0; i_ind--) { - if (offset > _region_high_boundary[i_ind]) { + if (offset > smtbl._region_high_boundary[i_ind]) { return (i_ind + 1); } } @@ -1395,18 +1400,23 @@ int QSPIFBlockDevice::_utils_find_addr_region(bd_size_t offset) } -int QSPIFBlockDevice::_utils_iterate_next_largest_erase_type(uint8_t &bitfield, int size, int offset, int boundry) +int QSPIFBlockDevice::_utils_iterate_next_largest_erase_type(uint8_t &bitfield, + int size, + int offset, + int region, + sfdp_smtbl_info &smtbl) { // Iterate on all supported Erase Types of the Region to which the offset belong to. // Iterates from highest type to lowest - uint8_t type_mask = ERASE_BITMASK_TYPE4; + uint8_t type_mask = SFDP_ERASE_BITMASK_TYPE4; int i_ind = 0; int largest_erase_type = 0; for (i_ind = 3; i_ind >= 0; i_ind--) { if (bitfield & type_mask) { largest_erase_type = i_ind; - if ((size > (int)(_erase_type_size_arr[largest_erase_type])) && - ((boundry - offset) > (int)(_erase_type_size_arr[largest_erase_type]))) { + if ((size > (int)(smtbl._erase_type_size_arr[largest_erase_type])) && + ((_sfdp_info.smtbl._region_high_boundary[region] - offset) + > (int)(smtbl._erase_type_size_arr[largest_erase_type]))) { break; } else { bitfield &= ~type_mask; diff --git a/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.h b/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.h index 2e41b9489b..89316d420d 100644 --- a/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.h +++ b/components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.h @@ -70,8 +70,6 @@ enum qspif_polarity_mode { QSPIF_POLARITY_MODE_1 /* CPOL=1, CPHA=1 */ }; -#define QSPIF_MAX_REGIONS 10 -#define MAX_NUM_OF_ERASE_TYPES 4 #define QSPIF_MAX_ACTIVE_FLASH_DEVICES 10 /** BlockDevice for SFDP based flash devices over QSPI bus @@ -342,7 +340,9 @@ private: int _sfdp_detect_page_size(uint8_t *basic_param_table_ptr, int basic_param_table_size); // 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 _sfdp_detect_erase_types_inst_and_size(uint8_t *basic_param_table_ptr, + int basic_param_table_size, + mbed::sfdp_smtbl_info &smtbl); // Detect 4-byte addressing mode and enable it if supported int _sfdp_detect_and_enable_4byte_addressing(uint8_t *basic_param_table_ptr, int basic_param_table_size); @@ -354,11 +354,15 @@ private: /* Utilities Functions */ /***********************/ // Find the region to which the given offset belong to - int _utils_find_addr_region(mbed::bd_size_t offset); + int _utils_find_addr_region(mbed::bd_size_t offset, mbed::sfdp_smtbl_info &smtbl); // Iterate on all supported Erase Types of the Region to which the offset belong to. // Iterates from highest type to lowest - int _utils_iterate_next_largest_erase_type(uint8_t &bitfield, int size, int offset, int boundry); + int _utils_iterate_next_largest_erase_type(uint8_t &bitfield, + int size, + int offset, + int region, + mbed::sfdp_smtbl_info &smtbl); private: enum qspif_clear_protection_method_t { @@ -397,10 +401,6 @@ private: // 4-byte addressing extension register write instruction mbed::qspi_inst_t _4byte_msb_reg_write_inst; - // Up To 4 Erase Types are supported by SFDP (each with its own command Instruction and Size) - mbed::qspi_inst_t _erase_type_inst_arr[MAX_NUM_OF_ERASE_TYPES]; - unsigned int _erase_type_size_arr[MAX_NUM_OF_ERASE_TYPES]; - // Quad mode enable status register and bit int _quad_enable_register_idx; int _quad_enable_bit; @@ -410,13 +410,8 @@ private: // Clear block protection qspif_clear_protection_method_t _clear_protection_method; - // Sector Regions Map - int _regions_count; //number of regions - int _region_size_bytes[QSPIF_MAX_REGIONS]; //regions size in bytes - bd_size_t _region_high_boundary[QSPIF_MAX_REGIONS]; //region high address offset boundary - //Each Region can support a bit combination of any of the 4 Erase Types - uint8_t _region_erase_types_bitfield[QSPIF_MAX_REGIONS]; - unsigned int _min_common_erase_size; // minimal common erase size for all regions (0 if none exists) + // Data extracted from the devices SFDP structure + mbed::sfdp_hdr_info _sfdp_info; unsigned int _page_size_bytes; // Page size - 256 Bytes default int _freq; diff --git a/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp b/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp index b10574ae5e..d8c98cabc2 100644 --- a/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp +++ b/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp @@ -65,12 +65,6 @@ using namespace mbed; #define SPIF_BASIC_PARAM_ERASE_TYPE_4_SIZE_BYTE 34 #define SPIF_BASIC_PARAM_4K_ERASE_TYPE_BYTE 1 -// Erase Types Per Region BitMask -#define ERASE_BITMASK_TYPE4 0x08 -#define ERASE_BITMASK_TYPE1 0x01 -#define ERASE_BITMASK_NONE 0x00 -#define ERASE_BITMASK_ALL 0x0F - #define IS_MEM_READY_MAX_RETRIES 10000 enum spif_default_instructions { @@ -115,7 +109,7 @@ SPIFBlockDevice::SPIFBlockDevice( _min_common_erase_size = 0; _regions_count = 1; - _region_erase_types_bitfield[0] = ERASE_BITMASK_NONE; + _region_erase_types_bitfield[0] = SFDP_ERASE_BITMASK_NONE; if (SPIF_BD_ERROR_OK != _spi_set_frequency(freq)) { tr_error("SPI Set Frequency Failed"); @@ -445,7 +439,7 @@ bd_size_t SPIFBlockDevice::get_erase_size(bd_addr_t addr) const int region = _utils_find_addr_region(addr); unsigned int min_region_erase_size = _min_common_erase_size; - int8_t type_mask = ERASE_BITMASK_TYPE1; + int8_t type_mask = SFDP_ERASE_BITMASK_TYPE1; int i_ind = 0; if (region != -1) { @@ -631,7 +625,7 @@ int SPIFBlockDevice::_sfdp_parse_sector_map_table(uint32_t sector_map_table_addr int i_ind = 0; int prev_boundary = 0; // Default set to all type bits 1-4 are common - int min_common_erase_type_bits = ERASE_BITMASK_ALL; + int min_common_erase_type_bits = SFDP_ERASE_BITMASK_ALL; spif_bd_error status = _spi_send_read_command(SPIF_SFDP, sector_map_table, sector_map_table_addr /*address*/, @@ -666,7 +660,7 @@ int SPIFBlockDevice::_sfdp_parse_sector_map_table(uint32_t sector_map_table_addr } // Calc minimum Common Erase Size from min_common_erase_type_bits - uint8_t type_mask = ERASE_BITMASK_TYPE1; + uint8_t type_mask = SFDP_ERASE_BITMASK_TYPE1; for (i_ind = 0; i_ind < 4; i_ind++) { if (min_common_erase_type_bits & type_mask) { _min_common_erase_size = _erase_type_size_arr[i_ind]; @@ -943,7 +937,7 @@ int SPIFBlockDevice::_utils_iterate_next_largest_erase_type(uint8_t &bitfield, i { // Iterate on all supported Erase Types of the Region to which the offset belong to. // Iterates from highest type to lowest - uint8_t type_mask = ERASE_BITMASK_TYPE4; + uint8_t type_mask = SFDP_ERASE_BITMASK_TYPE4; int i_ind = 0; int largest_erase_type = 0; for (i_ind = 3; i_ind >= 0; i_ind--) { diff --git a/drivers/internal/SFDP.h b/drivers/internal/SFDP.h index 9951df792f..23bbdcae96 100644 --- a/drivers/internal/SFDP.h +++ b/drivers/internal/SFDP.h @@ -27,6 +27,15 @@ namespace mbed { static const int SFDP_HEADER_SIZE = 8; ///< Size of an SFDP header */ static const int SFDP_BASIC_PARAMS_TBL_SIZE = 80; ///< Basic Parameter Table size in Bytes, 20 DWORDS */ +static const int SFDP_SECTOR_MAP_MAX_REGIONS = 10; + +// Erase Types Per Region BitMask +static const int SFDP_ERASE_BITMASK_TYPE4 = 0x08; +static const int SFDP_ERASE_BITMASK_TYPE1 = 0x01; +static const int SFDP_ERASE_BITMASK_NONE = 0x00; +static const int SFDP_ERASE_BITMASK_ALL = 0x0F; + +static const int SFDP_MAX_NUM_OF_ERASE_TYPES = 4; /** SFDP Basic Parameter Table info */ struct sfdp_bptbl_info { @@ -38,6 +47,15 @@ struct sfdp_bptbl_info { struct sfdp_smtbl_info { uint32_t addr; size_t size; + int _regions_count; + int _region_size_bytes[SFDP_SECTOR_MAP_MAX_REGIONS]; + //Each Region can support a bit combination of any of the 4 Erase Types + uint8_t _region_erase_types_bitfield[SFDP_SECTOR_MAP_MAX_REGIONS]; + unsigned int _min_common_erase_size; // minimal common erase size for all regions (0 if none exists) + bd_size_t _region_high_boundary[SFDP_SECTOR_MAP_MAX_REGIONS]; //region high address offset boundary + // Up To 4 Erase Types are supported by SFDP (each with its own command Instruction and Size) + int _erase_type_inst_arr[SFDP_MAX_NUM_OF_ERASE_TYPES]; + unsigned int _erase_type_size_arr[SFDP_MAX_NUM_OF_ERASE_TYPES]; }; /** SFDP Parameter Table addresses and sizes */ @@ -90,5 +108,7 @@ int sfdp_parse_single_param_header(sfdp_prm_hdr *parameter_header, sfdp_hdr_info */ int sfdp_parse_headers(Callback sfdp_reader, sfdp_hdr_info &hdr_info); +int sfdp_parse_sector_map_table(Callback sfdp_reader, sfdp_smtbl_info &smtbl); + } /* namespace mbed */ #endif diff --git a/drivers/source/SFDP.cpp b/drivers/source/SFDP.cpp index f4f29f738a..af8afa2b91 100644 --- a/drivers/source/SFDP.cpp +++ b/drivers/source/SFDP.cpp @@ -134,5 +134,10 @@ int sfdp_parse_headers(Callback sfdp_reader, return 0; } +int sfdp_parse_sector_map_table(Callback sfdp_reader, sfdp_smtbl_info &smtbl) +{ + return 0; +} + } /* namespace mbed */ #endif /* (DEVICE_SPI || DEVICE_QSPI) */