QSPIFBlockDevice: Consolidates SFDP info data

This far all SFDP Sector Map Table related data has been found in small
pieces inside QSPIFBlockDevice. Purpose was to consolidate the data
under one SFDP structure where all the information gathered from
SFDP tables is stored.

Parsing a Sector Map Table was made more generic so that later it can be
moved under SFDP module. Once that is done it can be shared with
SPIFBlockDevice to avoid code duplication.
pull/12318/head
Veijo Pesonen 2020-01-22 09:41:58 +02:00
parent cba5bfc790
commit 6108f384fb
5 changed files with 119 additions and 95 deletions

View File

@ -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<int(bd_addr_t, void*, bd_size_t)> 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<int(bd_addr_t, void*
return -1;
}
_regions_count = sector_map_table[2] + 1;
if (_regions_count > 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 *)&sector_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<int(bd_addr_t, void*
if (i_ind == 4) {
// No common erase type was found between regions
_min_common_erase_size = 0;
smtbl._min_common_erase_size = 0;
}
return 0;
@ -1374,20 +1379,20 @@ bool QSPIFBlockDevice::_is_mem_ready()
/*********************************************/
/************* Utility Functions *************/
/*********************************************/
int QSPIFBlockDevice::_utils_find_addr_region(bd_size_t offset)
int QSPIFBlockDevice::_utils_find_addr_region(bd_size_t offset, sfdp_smtbl_info &smtbl)
{
//Find the region to which the given offset belong to
if ((offset > _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;

View File

@ -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;

View File

@ -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--) {

View File

@ -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<int(bd_addr_t, void *, bd_size_t)> sfdp_reader, sfdp_hdr_info &hdr_info);
int sfdp_parse_sector_map_table(Callback<int(bd_addr_t, void*, bd_size_t)> sfdp_reader, sfdp_smtbl_info &smtbl);
} /* namespace mbed */
#endif

View File

@ -134,5 +134,10 @@ int sfdp_parse_headers(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader,
return 0;
}
int sfdp_parse_sector_map_table(Callback<int(bd_addr_t, void*, bd_size_t)> sfdp_reader, sfdp_smtbl_info &smtbl)
{
return 0;
}
} /* namespace mbed */
#endif /* (DEVICE_SPI || DEVICE_QSPI) */