@@ -83,11 +83,6 @@ using namespace mbed;
83
83
#define SOFT_RESET_RESET_INST_BITMASK 0b001000
84
84
#define SOFT_RESET_ENABLE_AND_RESET_INST_BITMASK 0b010000
85
85
86
- // Erase Types Per Region BitMask
87
- #define ERASE_BITMASK_TYPE4 0x08
88
- #define ERASE_BITMASK_TYPE1 0x01
89
- #define ERASE_BITMASK_NONE 0x00
90
- #define ERASE_BITMASK_ALL 0x0F
91
86
92
87
// 4-Byte Addressing Support Bitmasks
93
88
#define FOURBYTE_ADDR_B7_BITMASK 0b00000001
@@ -157,9 +152,9 @@ QSPIFBlockDevice::QSPIFBlockDevice(PinName io0, PinName io1, PinName io2, PinNam
157
152
}
158
153
159
154
// Initialize parameters
160
- _min_common_erase_size = 0 ;
161
- _regions_count = 1 ;
162
- _region_erase_types_bitfield[0 ] = ERASE_BITMASK_NONE ;
155
+ _sfdp_info. smtbl . _min_common_erase_size = 0 ;
156
+ _sfdp_info. smtbl . _regions_count = 1 ;
157
+ _sfdp_info. smtbl . _region_erase_types_bitfield [0 ] = SFDP_ERASE_BITMASK_NONE ;
163
158
164
159
// Until proven otherwise, assume no quad enable
165
160
_quad_enable_register_idx = QSPIF_NO_QUAD_ENABLE;
@@ -203,8 +198,10 @@ int QSPIFBlockDevice::init()
203
198
}
204
199
205
200
int status = QSPIF_BD_ERROR_OK;
206
- sfdp_hdr_info hdr_info;
207
- memset (&hdr_info, 0 , sizeof hdr_info);
201
+ _sfdp_info.bptbl .addr = 0x0 ;
202
+ _sfdp_info.bptbl .size = 0 ;
203
+ _sfdp_info.smtbl .addr = 0x0 ;
204
+ _sfdp_info.smtbl .size = 0 ;
208
205
209
206
_mutex.lock ();
210
207
@@ -248,29 +245,29 @@ int QSPIFBlockDevice::init()
248
245
}
249
246
250
247
/* *************************** Parse SFDP Header ***********************************/
251
- if (sfdp_parse_headers (callback (this , &QSPIFBlockDevice::_qspi_send_read_sfdp_command), hdr_info ) < 0 ) {
248
+ if (sfdp_parse_headers (callback (this , &QSPIFBlockDevice::_qspi_send_read_sfdp_command), _sfdp_info ) < 0 ) {
252
249
tr_error (" Init - Parse SFDP Headers Failed" );
253
250
status = QSPIF_BD_ERROR_PARSING_FAILED;
254
251
goto exit_point;
255
252
}
256
253
257
254
/* *************************** Parse Basic Parameters Table ***********************************/
258
- if (0 != _sfdp_parse_basic_param_table (hdr_info .bptbl .addr , hdr_info .bptbl .size )) {
255
+ if (0 != _sfdp_parse_basic_param_table (_sfdp_info .bptbl .addr , _sfdp_info .bptbl .size )) {
259
256
tr_error (" Init - Parse Basic Param Table Failed" );
260
257
status = QSPIF_BD_ERROR_PARSING_FAILED;
261
258
goto exit_point;
262
259
}
263
260
264
261
/* *************************** Parse Sector Map Table ***********************************/
265
- _region_size_bytes[0 ] =
262
+ _sfdp_info. smtbl . _region_size_bytes [0 ] =
266
263
_device_size_bytes; // If there's no region map, we have a single region sized the entire device size
267
- _region_high_boundary[0 ] = _device_size_bytes - 1 ;
264
+ _sfdp_info. smtbl . _region_high_boundary [0 ] = _device_size_bytes - 1 ;
268
265
269
- if ((hdr_info .smtbl .addr != 0 ) && (0 != hdr_info .smtbl .size )) {
270
- tr_debug (" Init - Parsing Sector Map Table - addr: 0x%lxh, Size: %d" , hdr_info .smtbl .addr ,
271
- hdr_info .smtbl .size );
266
+ if ((_sfdp_info .smtbl .addr != 0 ) && (0 != _sfdp_info .smtbl .size )) {
267
+ tr_debug (" Init - Parsing Sector Map Table - addr: 0x%lxh, Size: %d" , _sfdp_info .smtbl .addr ,
268
+ _sfdp_info .smtbl .size );
272
269
if (_sfdp_parse_sector_map_table (callback (this , &QSPIFBlockDevice::_qspi_send_read_sfdp_command),
273
- hdr_info .smtbl ) < 0 ) {
270
+ _sfdp_info .smtbl ) < 0 ) {
274
271
tr_error (" Init - Parse Sector Map Table Failed" );
275
272
status = QSPIF_BD_ERROR_PARSING_FAILED;
276
273
goto exit_point;
@@ -412,9 +409,9 @@ int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
412
409
bool erase_failed = false ;
413
410
int status = QSPIF_BD_ERROR_OK;
414
411
// Find region of erased address
415
- int region = _utils_find_addr_region (addr);
412
+ int region = _utils_find_addr_region (addr, _sfdp_info. smtbl );
416
413
// Erase Types of selected region
417
- uint8_t bitfield = _region_erase_types_bitfield[region];
414
+ uint8_t bitfield = _sfdp_info. smtbl . _region_erase_types_bitfield [region];
418
415
419
416
tr_debug (" Erase - addr: %llu, in_size: %llu" , addr, in_size);
420
417
@@ -434,9 +431,11 @@ int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
434
431
if (_legacy_erase_instruction == QSPI_NO_INST) {
435
432
// Iterate to find next largest erase type that is a) supported by region, and b) smaller than size.
436
433
// Find the matching instruction and erase size chunk for that type.
437
- type = _utils_iterate_next_largest_erase_type (bitfield, size, (int )addr, _region_high_boundary[region]);
438
- cur_erase_inst = _erase_type_inst_arr[type];
439
- eu_size = _erase_type_size_arr[type];
434
+ type = _utils_iterate_next_largest_erase_type (bitfield, size, (int )addr,
435
+ region,
436
+ _sfdp_info.smtbl );
437
+ cur_erase_inst = _sfdp_info.smtbl ._erase_type_inst_arr [type];
438
+ eu_size = _sfdp_info.smtbl ._erase_type_size_arr [type];
440
439
} else {
441
440
// Must use legacy 4k erase instruction
442
441
cur_erase_inst = _legacy_erase_instruction;
@@ -469,10 +468,10 @@ int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
469
468
addr += chunk;
470
469
size -= chunk;
471
470
472
- if ((size > 0 ) && (addr > _region_high_boundary[region])) {
471
+ if ((size > 0 ) && (addr > _sfdp_info. smtbl . _region_high_boundary [region])) {
473
472
// erase crossed to next region
474
473
region++;
475
- bitfield = _region_erase_types_bitfield[region];
474
+ bitfield = _sfdp_info. smtbl . _region_erase_types_bitfield [region];
476
475
}
477
476
478
477
if (false == _is_mem_ready ()) {
@@ -508,7 +507,7 @@ bd_size_t QSPIFBlockDevice::get_program_size() const
508
507
bd_size_t QSPIFBlockDevice::get_erase_size () const
509
508
{
510
509
// return minimal erase size supported by all regions (0 if none exists)
511
- return _min_common_erase_size;
510
+ return _sfdp_info. smtbl . _min_common_erase_size ;
512
511
}
513
512
514
513
const char *QSPIFBlockDevice::get_type () const
@@ -525,20 +524,20 @@ bd_size_t QSPIFBlockDevice::get_erase_size(bd_addr_t addr)
525
524
}
526
525
527
526
// Find region of current address
528
- int region = _utils_find_addr_region (addr);
527
+ int region = _utils_find_addr_region (addr, _sfdp_info. smtbl );
529
528
530
- int min_region_erase_size = _min_common_erase_size;
531
- int8_t type_mask = ERASE_BITMASK_TYPE1 ;
529
+ int min_region_erase_size = _sfdp_info. smtbl . _min_common_erase_size ;
530
+ int8_t type_mask = SFDP_ERASE_BITMASK_TYPE1 ;
532
531
int i_ind = 0 ;
533
532
534
533
if (region != -1 ) {
535
534
type_mask = 0x01 ;
536
535
537
536
for (i_ind = 0 ; i_ind < 4 ; i_ind++) {
538
537
// loop through erase types bitfield supported by region
539
- if (_region_erase_types_bitfield[region] & type_mask) {
538
+ if (_sfdp_info. smtbl . _region_erase_types_bitfield [region] & type_mask) {
540
539
541
- min_region_erase_size = _erase_type_size_arr[i_ind];
540
+ min_region_erase_size = _sfdp_info. smtbl . _erase_type_size_arr [i_ind];
542
541
break ;
543
542
}
544
543
type_mask = type_mask << 1 ;
@@ -662,7 +661,7 @@ int QSPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, s
662
661
bool shouldSetQuadEnable = false ;
663
662
bool is_qpi_mode = false ;
664
663
665
- if (_sfdp_detect_erase_types_inst_and_size (param_table, basic_table_size) != 0 ) {
664
+ if (_sfdp_detect_erase_types_inst_and_size (param_table, basic_table_size, _sfdp_info. smtbl ) != 0 ) {
666
665
tr_error (" Init - Detecting erase types instructions/sizes failed" );
667
666
return -1 ;
668
667
}
@@ -846,31 +845,36 @@ int QSPIFBlockDevice::_sfdp_detect_page_size(uint8_t *basic_param_table_ptr, int
846
845
return page_size;
847
846
}
848
847
849
- int QSPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size (uint8_t *basic_param_table_ptr, int basic_param_table_size)
848
+ int QSPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size (uint8_t *basic_param_table_ptr,
849
+ int basic_param_table_size,
850
+ sfdp_smtbl_info &smtbl)
850
851
{
851
852
uint8_t bitfield = 0x01 ;
852
853
853
854
// Erase 4K Inst is taken either from param table legacy 4K erase or superseded by erase Instruction for type of size 4K
854
855
if (basic_param_table_size > QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE) {
855
856
// Loop Erase Types 1-4
856
857
for (int i_ind = 0 ; i_ind < 4 ; i_ind++) {
857
- _erase_type_inst_arr[i_ind] = QSPI_NO_INST; // Default for unsupported type
858
- _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
859
- tr_debug (" Erase Type(A) %d - Inst: 0x%xh, Size: %d" , (i_ind + 1 ), _erase_type_inst_arr[i_ind],
860
- _erase_type_size_arr[i_ind]);
861
- if (_erase_type_size_arr[i_ind] > 1 ) {
858
+ smtbl._erase_type_inst_arr [i_ind] = QSPI_NO_INST; // Default for unsupported type
859
+ smtbl._erase_type_size_arr [i_ind] = 1
860
+ << 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
861
+ tr_debug (" Erase Type(A) %d - Inst: 0x%xh, Size: %d" , (i_ind + 1 ), smtbl._erase_type_inst_arr [i_ind],
862
+ smtbl._erase_type_size_arr [i_ind]);
863
+ if (smtbl._erase_type_size_arr [i_ind] > 1 ) {
862
864
// if size==1 type is not supported
863
- _erase_type_inst_arr[i_ind] = basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE + 2 * i_ind];
865
+ smtbl._erase_type_inst_arr [i_ind] = basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE
866
+ + 2 * i_ind];
864
867
865
- if ((_erase_type_size_arr[i_ind] < _min_common_erase_size) || (_min_common_erase_size == 0 )) {
868
+ if ((smtbl._erase_type_size_arr [i_ind] < smtbl._min_common_erase_size )
869
+ || (smtbl._min_common_erase_size == 0 )) {
866
870
// Set default minimal common erase for signal region
867
- _min_common_erase_size = _erase_type_size_arr[i_ind];
871
+ smtbl. _min_common_erase_size = smtbl. _erase_type_size_arr [i_ind];
868
872
}
869
- _region_erase_types_bitfield[0 ] |= bitfield; // If there's no region map, set region "0" types bitfield as default
873
+ smtbl. _region_erase_types_bitfield [0 ] |= bitfield; // If there's no region map, set region "0" types bitfield as default
870
874
}
871
875
872
- tr_debug (" Erase Type %d - Inst: 0x%xh, Size: %d" , (i_ind + 1 ), _erase_type_inst_arr[i_ind],
873
- _erase_type_size_arr[i_ind]);
876
+ tr_debug (" Erase Type %d - Inst: 0x%xh, Size: %d" , (i_ind + 1 ), smtbl. _erase_type_inst_arr [i_ind],
877
+ smtbl. _erase_type_size_arr [i_ind]);
874
878
bitfield = bitfield << 1 ;
875
879
}
876
880
} else {
@@ -1106,16 +1110,16 @@ int QSPIFBlockDevice::_sfdp_detect_reset_protocol_and_reset(uint8_t *basic_param
1106
1110
int QSPIFBlockDevice::_sfdp_parse_sector_map_table (Callback<int (bd_addr_t , void *, bd_size_t )> sfdp_reader,
1107
1111
sfdp_smtbl_info &smtbl)
1108
1112
{
1109
- uint8_t sector_map_table[SFDP_BASIC_PARAMS_TBL_SIZE]; /* Up To 16 DWORDS = 64 Bytes */
1113
+ uint8_t sector_map_table[SFDP_BASIC_PARAMS_TBL_SIZE]; /* Up To 20 DWORDS = 80 Bytes */
1110
1114
uint32_t tmp_region_size = 0 ;
1111
1115
int i_ind = 0 ;
1112
1116
int prev_boundary = 0 ;
1113
1117
// Default set to all type bits 1-4 are common
1114
- int min_common_erase_type_bits = ERASE_BITMASK_ALL ;
1118
+ int min_common_erase_type_bits = SFDP_ERASE_BITMASK_ALL ;
1115
1119
1116
1120
int status = sfdp_reader (smtbl.addr , sector_map_table, smtbl.size );
1117
1121
if (status < 0 ) {
1118
- tr_error (" Init - Read SFDP First Table Failed " );
1122
+ tr_error (" table retrieval failed " );
1119
1123
return -1 ;
1120
1124
}
1121
1125
@@ -1125,37 +1129,38 @@ int QSPIFBlockDevice::_sfdp_parse_sector_map_table(Callback<int(bd_addr_t, void*
1125
1129
return -1 ;
1126
1130
}
1127
1131
1128
- _regions_count = sector_map_table[2 ] + 1 ;
1129
- if (_regions_count > QSPIF_MAX_REGIONS ) {
1132
+ smtbl. _regions_count = sector_map_table[2 ] + 1 ;
1133
+ if (smtbl. _regions_count > SFDP_SECTOR_MAP_MAX_REGIONS ) {
1130
1134
tr_error (" Supporting up to %d regions, current setup to %d regions - fail" ,
1131
- QSPIF_MAX_REGIONS, _regions_count);
1135
+ SFDP_SECTOR_MAP_MAX_REGIONS,
1136
+ smtbl.regions_count );
1132
1137
return -1 ;
1133
1138
}
1134
1139
1135
1140
// Loop through Regions and set for each one: size, supported erase types, high boundary offset
1136
1141
// Calculate minimum Common Erase Type for all Regions
1137
- for (i_ind = 0 ; i_ind < _regions_count; i_ind++) {
1142
+ for (i_ind = 0 ; i_ind < smtbl. _regions_count ; i_ind++) {
1138
1143
tmp_region_size = ((*((uint32_t *)§or_map_table[(i_ind + 1 ) * 4 ])) >> 8 ) & 0x00FFFFFF ; // bits 9-32
1139
- _region_size_bytes[i_ind] = (tmp_region_size + 1 ) * 256 ; // Region size is 0 based multiple of 256 bytes;
1140
- _region_erase_types_bitfield[i_ind] = sector_map_table[(i_ind + 1 ) * 4 ] & 0x0F ; // bits 1-4
1141
- min_common_erase_type_bits &= _region_erase_types_bitfield[i_ind];
1142
- _region_high_boundary[i_ind] = (_region_size_bytes[i_ind] - 1 ) + prev_boundary;
1143
- prev_boundary = _region_high_boundary[i_ind] + 1 ;
1144
+ smtbl. _region_size_bytes [i_ind] = (tmp_region_size + 1 ) * 256 ; // Region size is 0 based multiple of 256 bytes;
1145
+ smtbl. _region_erase_types_bitfield [i_ind] = sector_map_table[(i_ind + 1 ) * 4 ] & 0x0F ; // bits 1-4
1146
+ min_common_erase_type_bits &= smtbl. _region_erase_types_bitfield [i_ind];
1147
+ smtbl. _region_high_boundary [i_ind] = (smtbl. _region_size_bytes [i_ind] - 1 ) + prev_boundary;
1148
+ prev_boundary = smtbl. _region_high_boundary [i_ind] + 1 ;
1144
1149
}
1145
1150
1146
1151
// Calc minimum Common Erase Size from min_common_erase_type_bits
1147
- uint8_t type_mask = ERASE_BITMASK_TYPE1 ;
1152
+ uint8_t type_mask = SFDP_ERASE_BITMASK_TYPE1 ;
1148
1153
for (i_ind = 0 ; i_ind < 4 ; i_ind++) {
1149
1154
if (min_common_erase_type_bits & type_mask) {
1150
- _min_common_erase_size = _erase_type_size_arr[i_ind];
1155
+ smtbl. _min_common_erase_size = smtbl. _erase_type_size_arr [i_ind];
1151
1156
break ;
1152
1157
}
1153
1158
type_mask = type_mask << 1 ;
1154
1159
}
1155
1160
1156
1161
if (i_ind == 4 ) {
1157
1162
// No common erase type was found between regions
1158
- _min_common_erase_size = 0 ;
1163
+ smtbl. _min_common_erase_size = 0 ;
1159
1164
}
1160
1165
1161
1166
return 0 ;
@@ -1374,39 +1379,44 @@ bool QSPIFBlockDevice::_is_mem_ready()
1374
1379
/* ********************************************/
1375
1380
/* ************ Utility Functions *************/
1376
1381
/* ********************************************/
1377
- int QSPIFBlockDevice::_utils_find_addr_region (bd_size_t offset)
1382
+ int QSPIFBlockDevice::_utils_find_addr_region (bd_size_t offset, sfdp_smtbl_info &smtbl )
1378
1383
{
1379
1384
// Find the region to which the given offset belong to
1380
- if ((offset > _device_size_bytes) || (_regions_count == 0 )) {
1385
+ if ((offset > _device_size_bytes) || (smtbl. _regions_count == 0 )) {
1381
1386
return -1 ;
1382
1387
}
1383
1388
1384
- if (_regions_count == 1 ) {
1389
+ if (smtbl. _regions_count == 1 ) {
1385
1390
return 0 ;
1386
1391
}
1387
1392
1388
- for (int i_ind = _regions_count - 2 ; i_ind >= 0 ; i_ind--) {
1393
+ for (int i_ind = smtbl. _regions_count - 2 ; i_ind >= 0 ; i_ind--) {
1389
1394
1390
- if (offset > _region_high_boundary[i_ind]) {
1395
+ if (offset > smtbl. _region_high_boundary [i_ind]) {
1391
1396
return (i_ind + 1 );
1392
1397
}
1393
1398
}
1394
1399
return -1 ;
1395
1400
1396
1401
}
1397
1402
1398
- int QSPIFBlockDevice::_utils_iterate_next_largest_erase_type (uint8_t &bitfield, int size, int offset, int boundry)
1403
+ int QSPIFBlockDevice::_utils_iterate_next_largest_erase_type (uint8_t &bitfield,
1404
+ int size,
1405
+ int offset,
1406
+ int region,
1407
+ sfdp_smtbl_info &smtbl)
1399
1408
{
1400
1409
// Iterate on all supported Erase Types of the Region to which the offset belong to.
1401
1410
// Iterates from highest type to lowest
1402
- uint8_t type_mask = ERASE_BITMASK_TYPE4 ;
1411
+ uint8_t type_mask = SFDP_ERASE_BITMASK_TYPE4 ;
1403
1412
int i_ind = 0 ;
1404
1413
int largest_erase_type = 0 ;
1405
1414
for (i_ind = 3 ; i_ind >= 0 ; i_ind--) {
1406
1415
if (bitfield & type_mask) {
1407
1416
largest_erase_type = i_ind;
1408
- if ((size > (int )(_erase_type_size_arr[largest_erase_type])) &&
1409
- ((boundry - offset) > (int )(_erase_type_size_arr[largest_erase_type]))) {
1417
+ if ((size > (int )(smtbl._erase_type_size_arr [largest_erase_type])) &&
1418
+ ((_sfdp_info.smtbl ._region_high_boundary [region] - offset)
1419
+ > (int )(smtbl._erase_type_size_arr [largest_erase_type]))) {
1410
1420
break ;
1411
1421
} else {
1412
1422
bitfield &= ~type_mask;
0 commit comments