Skip to content

Commit 6a60574

Browse files
author
Veijo Pesonen
committed
SFDP: consolidates sfdp_detect_erase_types_inst_and_size
1 parent 2da963b commit 6a60574

File tree

6 files changed

+86
-129
lines changed

6 files changed

+86
-129
lines changed

components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.cpp

Lines changed: 5 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ QSPIFBlockDevice::QSPIFBlockDevice(PinName io0, PinName io1, PinName io2, PinNam
140140
}
141141

142142
// Initialize parameters
143+
_sfdp_info.bptbl.legacy_erase_instruction = QSPIF_INST_LEGACY_ERASE_DEFAULT;
143144
_sfdp_info.smptbl.regions_min_common_erase_size = 0;
144145
_sfdp_info.smptbl.region_cnt = 1;
145146
_sfdp_info.smptbl.region_erase_types_bitfld[0] = SFDP_ERASE_BITMASK_NONE;
@@ -159,7 +160,6 @@ QSPIFBlockDevice::QSPIFBlockDevice(PinName io0, PinName io1, PinName io2, PinNam
159160

160161
// Set default read/erase instructions
161162
_read_instruction = QSPIF_INST_READ_DEFAULT;
162-
_legacy_erase_instruction = QSPIF_INST_LEGACY_ERASE_DEFAULT;
163163

164164
_num_status_registers = QSPI_DEFAULT_STATUS_REGISTERS;
165165
// Set default status register 2 write/read instructions
@@ -417,7 +417,7 @@ int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
417417
// For each iteration erase the largest section supported by current region
418418
while (size > 0) {
419419
unsigned int eu_size;
420-
if (_legacy_erase_instruction == QSPI_NO_INST) {
420+
if (_sfdp_info.bptbl.legacy_erase_instruction == QSPI_NO_INST) {
421421
// Iterate to find next largest erase type that is a) supported by region, and b) smaller than size.
422422
// Find the matching instruction and erase size chunk for that type.
423423
type = _utils_iterate_next_largest_erase_type(bitfield, size, (int)addr,
@@ -427,7 +427,7 @@ int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
427427
eu_size = _sfdp_info.smptbl.erase_type_size_arr[type];
428428
} else {
429429
// Must use legacy 4k erase instruction
430-
cur_erase_inst = _legacy_erase_instruction;
430+
cur_erase_inst = _sfdp_info.bptbl.legacy_erase_instruction;
431431
eu_size = QSPIF_DEFAULT_SE_SIZE;
432432
}
433433
offset = addr % eu_size;
@@ -508,7 +508,7 @@ const char *QSPIFBlockDevice::get_type() const
508508
bd_size_t QSPIFBlockDevice::get_erase_size(bd_addr_t addr)
509509
{
510510
// If the legacy erase instruction is in use, the erase size is uniformly 4k
511-
if (_legacy_erase_instruction != QSPI_NO_INST) {
511+
if (_sfdp_info.bptbl.legacy_erase_instruction != QSPI_NO_INST) {
512512
return QSPIF_DEFAULT_SE_SIZE;
513513
}
514514

@@ -651,7 +651,7 @@ int QSPIFBlockDevice::_sfdp_parse_basic_param_table(Callback<int(bd_addr_t, void
651651
bool shouldSetQuadEnable = false;
652652
bool is_qpi_mode = false;
653653

654-
if (_sfdp_detect_erase_types_inst_and_size(param_table, basic_table_size, _sfdp_info.smptbl) != 0) {
654+
if (sfdp_detect_erase_types_inst_and_size(param_table, _sfdp_info) < 0) {
655655
tr_error("Init - Detecting erase types instructions/sizes failed");
656656
return -1;
657657
}
@@ -820,52 +820,6 @@ int QSPIFBlockDevice::_sfdp_set_qpi_enabled(uint8_t *basic_param_table_ptr)
820820
return 0;
821821
}
822822

823-
int QSPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size(uint8_t *basic_param_table_ptr,
824-
int basic_param_table_size,
825-
sfdp_smptbl_info &smptbl)
826-
{
827-
uint8_t bitfield = 0x01;
828-
829-
// Erase 4K Inst is taken either from param table legacy 4K erase or superseded by erase Instruction for type of size 4K
830-
if (basic_param_table_size > SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE) {
831-
// Loop Erase Types 1-4
832-
for (int i_ind = 0; i_ind < 4; i_ind++) {
833-
smptbl.erase_type_inst_arr[i_ind] = QSPI_NO_INST; // Default for unsupported type
834-
smptbl.erase_type_size_arr[i_ind] = 1
835-
<< 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
836-
tr_debug("Erase Type(A) %d - Inst: 0x%xh, Size: %d", (i_ind + 1), smptbl.erase_type_inst_arr[i_ind],
837-
smptbl.erase_type_size_arr[i_ind]);
838-
if (smptbl.erase_type_size_arr[i_ind] > 1) {
839-
// if size==1 type is not supported
840-
smptbl.erase_type_inst_arr[i_ind] = basic_param_table_ptr[SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE
841-
+ 2 * i_ind];
842-
843-
if ((smptbl.erase_type_size_arr[i_ind] < smptbl.regions_min_common_erase_size)
844-
|| (smptbl.regions_min_common_erase_size == 0)) {
845-
//Set default minimal common erase for signal region
846-
smptbl.regions_min_common_erase_size = smptbl.erase_type_size_arr[i_ind];
847-
}
848-
smptbl.region_erase_types_bitfld[0] |= bitfield; // If there's no region map, set region "0" types bitfield as default
849-
}
850-
851-
tr_debug("Erase Type %d - Inst: 0x%xh, Size: %d", (i_ind + 1), smptbl.erase_type_inst_arr[i_ind],
852-
smptbl.erase_type_size_arr[i_ind]);
853-
bitfield = bitfield << 1;
854-
}
855-
} else {
856-
tr_debug("SFDP erase types are not available - falling back to legacy 4k erase instruction");
857-
858-
// 0xFF indicates that the legacy 4k erase instruction is not supported
859-
_legacy_erase_instruction = basic_param_table_ptr[SFDP_BASIC_PARAM_TABLE_4K_ERASE_TYPE_BYTE];
860-
if (_legacy_erase_instruction == 0xFF) {
861-
tr_error("_detectEraseTypesInstAndSize - Legacy 4k erase instruction not supported");
862-
return -1;
863-
}
864-
}
865-
866-
return 0;
867-
}
868-
869823
int QSPIFBlockDevice::_sfdp_detect_best_bus_read_mode(uint8_t *basic_param_table_ptr, int basic_param_table_size,
870824
bool &set_quad_enable, bool &is_qpi_mode)
871825
{

components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -336,11 +336,6 @@ class QSPIFBlockDevice : public mbed::BlockDevice {
336336
// Set Page size for program
337337
int _sfdp_detect_page_size(uint8_t *basic_param_table_ptr, int basic_param_table_size);
338338

339-
// Detect all supported erase types
340-
int _sfdp_detect_erase_types_inst_and_size(uint8_t *basic_param_table_ptr,
341-
int basic_param_table_size,
342-
mbed::sfdp_smptbl_info &smptbl);
343-
344339
// Detect 4-byte addressing mode and enable it if supported
345340
int _sfdp_detect_and_enable_4byte_addressing(uint8_t *basic_param_table_ptr, int basic_param_table_size);
346341

@@ -386,7 +381,6 @@ class QSPIFBlockDevice : public mbed::BlockDevice {
386381

387382
// Command Instructions
388383
mbed::qspi_inst_t _read_instruction;
389-
int _legacy_erase_instruction;
390384

391385
// Status register write/read instructions
392386
unsigned int _num_status_registers;

components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp

Lines changed: 7 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,13 @@ SPIFBlockDevice::SPIFBlockDevice(
9898
_write_dummy_and_mode_cycles = 0;
9999
_dummy_and_mode_cycles = _read_dummy_and_mode_cycles;
100100

101+
_sfdp_info.bptbl.legacy_erase_instruction = SPIF_INST_LEGACY_ERASE_DEFAULT;
101102
_sfdp_info.smptbl.regions_min_common_erase_size = 0;
102103
_sfdp_info.smptbl.region_cnt = 1;
103104
_sfdp_info.smptbl.region_erase_types_bitfld[0] = SFDP_ERASE_BITMASK_NONE;
104105

105106
// Set default read/erase instructions
106107
_read_instruction = SPIF_INST_READ_DEFAULT;
107-
_legacy_erase_instruction = SPIF_INST_LEGACY_ERASE_DEFAULT;
108-
109108

110109
if (SPIF_BD_ERROR_OK != _spi_set_frequency(freq)) {
111110
tr_error("SPI Set Frequency Failed");
@@ -653,59 +652,19 @@ int SPIFBlockDevice::_sfdp_parse_basic_param_table(Callback<int(bd_addr_t, void
653652
_page_size_bytes = sfdp_detect_page_size(param_table, sfdp_info.bptbl.size);
654653

655654
// Detect and Set Erase Types
656-
_sfdp_detect_erase_types_inst_and_size(param_table, sfdp_info.bptbl.size, sfdp_info.smptbl);
657-
_erase_instruction = _legacy_erase_instruction;
655+
if (sfdp_detect_erase_types_inst_and_size(param_table, sfdp_info) < 0) {
656+
tr_error("Init - Detecting erase types instructions/sizes failed");
657+
return -1;
658+
}
659+
660+
_erase_instruction = sfdp_info.bptbl.legacy_erase_instruction;
658661

659662
// Detect and Set fastest Bus mode (default 1-1-1)
660663
_sfdp_detect_best_bus_read_mode(param_table, sfdp_info.bptbl.size, _read_instruction);
661664

662665
return 0;
663666
}
664667

665-
int SPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size(uint8_t *basic_param_table_ptr,
666-
int basic_param_table_size,
667-
sfdp_smptbl_info &smptbl)
668-
{
669-
uint8_t bitfield = 0x01;
670-
671-
// Erase 4K Inst is taken either from param table legacy 4K erase or superseded by erase Instruction for type of size 4K
672-
if (basic_param_table_size > SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE) {
673-
// Loop Erase Types 1-4
674-
for (int i_ind = 0; i_ind < 4; i_ind++) {
675-
smptbl.erase_type_inst_arr[i_ind] = 0xff; //0xFF default for unsupported type
676-
smptbl.erase_type_size_arr[i_ind] = 1
677-
<< basic_param_table_ptr[SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE + 2 * i_ind]; // Size given as 2^N
678-
tr_debug("Erase Type(A) %d - Inst: 0x%xh, Size: %d", (i_ind + 1), smptbl.erase_type_inst_arr[i_ind],
679-
smptbl.erase_type_size_arr[i_ind]);
680-
if (smptbl.erase_type_size_arr[i_ind] > 1) {
681-
// if size==1 type is not supported
682-
smptbl.erase_type_inst_arr[i_ind] =
683-
basic_param_table_ptr[SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE + 2 * i_ind];
684-
685-
if ((smptbl.erase_type_size_arr[i_ind] < smptbl.regions_min_common_erase_size)
686-
|| (smptbl.regions_min_common_erase_size == 0)) {
687-
//Set default minimal common erase for singal region
688-
smptbl.regions_min_common_erase_size = smptbl.erase_type_size_arr[i_ind];
689-
}
690-
smptbl.region_erase_types_bitfld[0] |= bitfield; // no region map, set region "0" types bitfield as default
691-
}
692-
tr_info("Erase Type %d - Inst: 0x%xh, Size: %d", (i_ind + 1),
693-
smptbl.erase_type_inst_arr[i_ind], smptbl.erase_type_size_arr[i_ind]);
694-
bitfield = bitfield << 1;
695-
}
696-
} else {
697-
tr_debug("SFDP erase types are not available - falling back to legacy 4k erase instruction");
698-
699-
// 0xFF indicates that the legacy 4k erase instruction is not supported
700-
_legacy_erase_instruction = basic_param_table_ptr[SFDP_BASIC_PARAM_TABLE_4K_ERASE_TYPE_BYTE];
701-
if (_legacy_erase_instruction == 0xFF) {
702-
tr_error("sfdp_detect_erase_types_inst_and_size - Legacy 4k erase instruction not supported");
703-
return -1;
704-
}
705-
}
706-
return 0;
707-
}
708-
709668
int SPIFBlockDevice::_sfdp_detect_best_bus_read_mode(uint8_t *basic_param_table_ptr, int basic_param_table_size,
710669
int &read_inst)
711670
{

components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,6 @@ class SPIFBlockDevice : public mbed::BlockDevice {
239239
// Set Page size for program
240240
unsigned int _sfdp_detect_page_size(uint8_t *basic_param_table_ptr, int basic_param_table_size);
241241

242-
// Detect all supported erase types
243-
int _sfdp_detect_erase_types_inst_and_size(uint8_t *basic_param_table_ptr, int basic_param_table_size,
244-
mbed::sfdp_smptbl_info &smptbl);
245-
246242
/***********************/
247243
/* Utilities Functions */
248244
/***********************/
@@ -301,7 +297,6 @@ class SPIFBlockDevice : public mbed::BlockDevice {
301297
int _read_instruction;
302298
int _prog_instruction;
303299
int _erase_instruction;
304-
int _legacy_erase_instruction; // Legacy 4K erase instruction (default 0x20h)
305300

306301
// Data extracted from the devices SFDP structure
307302
mbed::sfdp_hdr_info _sfdp_info;

drivers/internal/SFDP.h

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -38,30 +38,20 @@ static const int SFDP_BASIC_PARAMS_TBL_SIZE = 80; ///< Basic Parameter Table siz
3838
static const int SFDP_SECTOR_MAP_MAX_REGIONS = 10; ///< Maximum number of regions with different erase granularity
3939

4040
// Erase Types Per Region BitMask
41-
static const int SFDP_ERASE_BITMASK_TYPE4 = 0x08; ///< Erase type 4 (erase granularity) identifier
42-
static const int SFDP_ERASE_BITMASK_TYPE3 = 0x04; ///< Erase type 3 (erase granularity) identifier
43-
static const int SFDP_ERASE_BITMASK_TYPE2 = 0x02; ///< Erase type 2 (erase granularity) identifier
44-
static const int SFDP_ERASE_BITMASK_TYPE1 = 0x01; ///< Erase type 1 (erase granularity) identifier
45-
static const int SFDP_ERASE_BITMASK_NONE = 0x00; ///< Erase type None
46-
static const int SFDP_ERASE_BITMASK_ALL = 0x0F; ///< Erase type All
47-
48-
// Erase Types Params
49-
#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE 29
50-
#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_2_BYTE 31
51-
#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_3_BYTE 33
52-
#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_4_BYTE 35
53-
#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE 28
54-
#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_2_SIZE_BYTE 30
55-
#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_3_SIZE_BYTE 32
56-
#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_4_SIZE_BYTE 34
57-
#define SFDP_BASIC_PARAM_TABLE_4K_ERASE_TYPE_BYTE 1
58-
59-
static const int SFDP_MAX_NUM_OF_ERASE_TYPES = 4; ///< Maximum number of different erase types (erase granularity)
41+
constexpr int SFDP_ERASE_BITMASK_TYPE4 = 0x08; ///< Erase type 4 (erase granularity) identifier
42+
constexpr int SFDP_ERASE_BITMASK_TYPE3 = 0x04; ///< Erase type 3 (erase granularity) identifier
43+
constexpr int SFDP_ERASE_BITMASK_TYPE2 = 0x02; ///< Erase type 2 (erase granularity) identifier
44+
constexpr int SFDP_ERASE_BITMASK_TYPE1 = 0x01; ///< Erase type 1 (erase granularity) identifier
45+
constexpr int SFDP_ERASE_BITMASK_NONE = 0x00; ///< Erase type None
46+
constexpr int SFDP_ERASE_BITMASK_ALL = 0x0F; ///< Erase type All
47+
48+
constexpr int SFDP_MAX_NUM_OF_ERASE_TYPES = 4; ///< Maximum number of different erase types (erase granularity)
6049

6150
/** SFDP Basic Parameter Table info */
6251
struct sfdp_bptbl_info {
6352
uint32_t addr; ///< Address
6453
size_t size; ///< Size
54+
int legacy_erase_instruction; ///< Legacy 4K erase instruction
6555
};
6656

6757
/** SFDP Sector Map Table info */
@@ -146,6 +136,15 @@ int sfdp_parse_sector_map_table(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp
146136
*/
147137
size_t sfdp_detect_page_size(uint8_t *bptbl_ptr, size_t bptbl_size);
148138

139+
/** Detect all supported erase types
140+
*
141+
* @param bptbl_ptr Pointer to memory holding a Basic Parameter Table structure
142+
* @param smtbl All information parsed from the table gets passed back on this structure
143+
*
144+
* @return 0 on success, negative error code on failure
145+
*/
146+
int sfdp_detect_erase_types_inst_and_size(uint8_t *bptbl_ptr, sfdp_hdr_info &sfdp_info);
147+
149148
/** @}*/
150149
} /* namespace mbed */
151150
#endif

drivers/source/SFDP.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@ inline uint32_t sfdp_get_param_tbl_ptr(uint32_t dword2)
4242

4343
namespace mbed {
4444

45+
// Erase Types Params
46+
constexpr int SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE = 29; ///< Erase Type 1 Instruction
47+
constexpr int SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_2_BYTE = 31; ///< Erase Type 2 Instruction
48+
constexpr int SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_3_BYTE = 33; ///< Erase Type 3 Instruction
49+
constexpr int SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_4_BYTE = 35; ///< Erase Type 4 Instruction
50+
constexpr int SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE = 28; ///< Erase Type 1 Size
51+
constexpr int SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_2_SIZE_BYTE = 30; ///< Erase Type 2 Size
52+
constexpr int SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_3_SIZE_BYTE = 32; ///< Erase Type 3 Size
53+
constexpr int SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_4_SIZE_BYTE = 34; ///< Erase Type 4 Size
54+
constexpr int SFDP_BASIC_PARAM_TABLE_4K_ERASE_TYPE_BYTE = 1; ///< 4 Kilobyte Erase Instruction
55+
4556
/* Verifies SFDP Header and return number of parameter headers */
4657
int sfdp_parse_sfdp_header(sfdp_hdr *sfdp_hdr_ptr)
4758
{
@@ -210,6 +221,51 @@ size_t sfdp_detect_page_size(uint8_t *basic_param_table_ptr, size_t basic_param_
210221
return page_size;
211222
}
212223

224+
int sfdp_detect_erase_types_inst_and_size(uint8_t *bptbl_ptr, sfdp_hdr_info &sfdp_info)
225+
{
226+
uint8_t bitfield = 0x01;
227+
228+
// Erase 4K Inst is taken either from param table legacy 4K erase or superseded by erase Instruction for type of size 4K
229+
if (sfdp_info.bptbl.size > SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE) {
230+
// Loop Erase Types 1-4
231+
for (int i_ind = 0; i_ind < 4; i_ind++) {
232+
sfdp_info.smptbl.erase_type_inst_arr[i_ind] = -1; // Default for unsupported type
233+
sfdp_info.smptbl.erase_type_size_arr[i_ind] = 1
234+
<< bptbl_ptr[SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE + 2 * i_ind]; // Size is 2^N where N is the table value
235+
tr_debug("Erase Type(A) %d - Inst: 0x%xh, Size: %d", (i_ind + 1), sfdp_info.smptbl.erase_type_inst_arr[i_ind],
236+
sfdp_info.smptbl.erase_type_size_arr[i_ind]);
237+
if (sfdp_info.smptbl.erase_type_size_arr[i_ind] > 1) {
238+
// if size==1 type is not supported
239+
sfdp_info.smptbl.erase_type_inst_arr[i_ind] = bptbl_ptr[SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE
240+
+ 2 * i_ind];
241+
242+
if ((sfdp_info.smptbl.erase_type_size_arr[i_ind] < sfdp_info.smptbl.regions_min_common_erase_size)
243+
|| (sfdp_info.smptbl.regions_min_common_erase_size == 0)) {
244+
//Set default minimal common erase for signal region
245+
sfdp_info.smptbl.regions_min_common_erase_size = sfdp_info.smptbl.erase_type_size_arr[i_ind];
246+
}
247+
sfdp_info.smptbl.region_erase_types_bitfld[0] |= bitfield; // If there's no region map, set region "0" types bitfield as default
248+
}
249+
250+
tr_debug("Erase Type %d - Inst: 0x%xh, Size: %d", (i_ind + 1), sfdp_info.smptbl.erase_type_inst_arr[i_ind],
251+
sfdp_info.smptbl.erase_type_size_arr[i_ind]);
252+
bitfield = bitfield << 1;
253+
}
254+
} else {
255+
tr_debug("SFDP erase types are not available - falling back to legacy 4k erase instruction");
256+
257+
// 0xFF indicates that the legacy 4k erase instruction is not supported
258+
sfdp_info.bptbl.legacy_erase_instruction = bptbl_ptr[SFDP_BASIC_PARAM_TABLE_4K_ERASE_TYPE_BYTE];
259+
if (sfdp_info.bptbl.legacy_erase_instruction == 0xFF) {
260+
tr_error("_detectEraseTypesInstAndSize - Legacy 4k erase instruction not supported");
261+
return -1;
262+
}
263+
}
264+
265+
return 0;
266+
}
267+
268+
213269

214270
} /* namespace mbed */
215271
#endif /* (DEVICE_SPI || DEVICE_QSPI) */

0 commit comments

Comments
 (0)