@@ -83,11 +83,6 @@ using namespace mbed;
8383#define SOFT_RESET_RESET_INST_BITMASK 0b001000
8484#define SOFT_RESET_ENABLE_AND_RESET_INST_BITMASK 0b010000
8585
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
9186
9287// 4-Byte Addressing Support Bitmasks
9388#define FOURBYTE_ADDR_B7_BITMASK 0b00000001
@@ -157,9 +152,9 @@ QSPIFBlockDevice::QSPIFBlockDevice(PinName io0, PinName io1, PinName io2, PinNam
157152 }
158153
159154 // 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 ;
163158
164159 // Until proven otherwise, assume no quad enable
165160 _quad_enable_register_idx = QSPIF_NO_QUAD_ENABLE;
@@ -203,8 +198,10 @@ int QSPIFBlockDevice::init()
203198 }
204199
205200 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 ;
208205
209206 _mutex.lock ();
210207
@@ -248,29 +245,29 @@ int QSPIFBlockDevice::init()
248245 }
249246
250247 /* *************************** 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 ) {
252249 tr_error (" Init - Parse SFDP Headers Failed" );
253250 status = QSPIF_BD_ERROR_PARSING_FAILED;
254251 goto exit_point;
255252 }
256253
257254 /* *************************** 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 )) {
259256 tr_error (" Init - Parse Basic Param Table Failed" );
260257 status = QSPIF_BD_ERROR_PARSING_FAILED;
261258 goto exit_point;
262259 }
263260
264261 /* *************************** Parse Sector Map Table ***********************************/
265- _region_size_bytes[0 ] =
262+ _sfdp_info. smtbl . _region_size_bytes [0 ] =
266263 _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 ;
268265
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 );
272269 if (_sfdp_parse_sector_map_table (callback (this , &QSPIFBlockDevice::_qspi_send_read_sfdp_command),
273- hdr_info .smtbl ) < 0 ) {
270+ _sfdp_info .smtbl ) < 0 ) {
274271 tr_error (" Init - Parse Sector Map Table Failed" );
275272 status = QSPIF_BD_ERROR_PARSING_FAILED;
276273 goto exit_point;
@@ -412,9 +409,9 @@ int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
412409 bool erase_failed = false ;
413410 int status = QSPIF_BD_ERROR_OK;
414411 // Find region of erased address
415- int region = _utils_find_addr_region (addr);
412+ int region = _utils_find_addr_region (addr, _sfdp_info. smtbl );
416413 // 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];
418415
419416 tr_debug (" Erase - addr: %llu, in_size: %llu" , addr, in_size);
420417
@@ -434,9 +431,11 @@ int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
434431 if (_legacy_erase_instruction == QSPI_NO_INST) {
435432 // Iterate to find next largest erase type that is a) supported by region, and b) smaller than size.
436433 // 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];
440439 } else {
441440 // Must use legacy 4k erase instruction
442441 cur_erase_inst = _legacy_erase_instruction;
@@ -469,10 +468,10 @@ int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
469468 addr += chunk;
470469 size -= chunk;
471470
472- if ((size > 0 ) && (addr > _region_high_boundary[region])) {
471+ if ((size > 0 ) && (addr > _sfdp_info. smtbl . _region_high_boundary [region])) {
473472 // erase crossed to next region
474473 region++;
475- bitfield = _region_erase_types_bitfield[region];
474+ bitfield = _sfdp_info. smtbl . _region_erase_types_bitfield [region];
476475 }
477476
478477 if (false == _is_mem_ready ()) {
@@ -508,7 +507,7 @@ bd_size_t QSPIFBlockDevice::get_program_size() const
508507bd_size_t QSPIFBlockDevice::get_erase_size () const
509508{
510509 // 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 ;
512511}
513512
514513const char *QSPIFBlockDevice::get_type () const
@@ -525,20 +524,20 @@ bd_size_t QSPIFBlockDevice::get_erase_size(bd_addr_t addr)
525524 }
526525
527526 // Find region of current address
528- int region = _utils_find_addr_region (addr);
527+ int region = _utils_find_addr_region (addr, _sfdp_info. smtbl );
529528
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 ;
532531 int i_ind = 0 ;
533532
534533 if (region != -1 ) {
535534 type_mask = 0x01 ;
536535
537536 for (i_ind = 0 ; i_ind < 4 ; i_ind++) {
538537 // 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) {
540539
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];
542541 break ;
543542 }
544543 type_mask = type_mask << 1 ;
@@ -662,7 +661,7 @@ int QSPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, s
662661 bool shouldSetQuadEnable = false ;
663662 bool is_qpi_mode = false ;
664663
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 ) {
666665 tr_error (" Init - Detecting erase types instructions/sizes failed" );
667666 return -1 ;
668667 }
@@ -846,31 +845,36 @@ int QSPIFBlockDevice::_sfdp_detect_page_size(uint8_t *basic_param_table_ptr, int
846845 return page_size;
847846}
848847
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)
850851{
851852 uint8_t bitfield = 0x01 ;
852853
853854 // Erase 4K Inst is taken either from param table legacy 4K erase or superseded by erase Instruction for type of size 4K
854855 if (basic_param_table_size > QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE) {
855856 // Loop Erase Types 1-4
856857 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 ) {
862864 // 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];
864867
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 )) {
866870 // 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];
868872 }
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
870874 }
871875
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]);
874878 bitfield = bitfield << 1 ;
875879 }
876880 } else {
@@ -1106,16 +1110,16 @@ int QSPIFBlockDevice::_sfdp_detect_reset_protocol_and_reset(uint8_t *basic_param
11061110int QSPIFBlockDevice::_sfdp_parse_sector_map_table (Callback<int (bd_addr_t , void *, bd_size_t )> sfdp_reader,
11071111 sfdp_smtbl_info &smtbl)
11081112{
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 */
11101114 uint32_t tmp_region_size = 0 ;
11111115 int i_ind = 0 ;
11121116 int prev_boundary = 0 ;
11131117 // 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 ;
11151119
11161120 int status = sfdp_reader (smtbl.addr , sector_map_table, smtbl.size );
11171121 if (status < 0 ) {
1118- tr_error (" Init - Read SFDP First Table Failed " );
1122+ tr_error (" table retrieval failed " );
11191123 return -1 ;
11201124 }
11211125
@@ -1125,37 +1129,38 @@ int QSPIFBlockDevice::_sfdp_parse_sector_map_table(Callback<int(bd_addr_t, void*
11251129 return -1 ;
11261130 }
11271131
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 ) {
11301134 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 );
11321137 return -1 ;
11331138 }
11341139
11351140 // Loop through Regions and set for each one: size, supported erase types, high boundary offset
11361141 // 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++) {
11381143 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 ;
11441149 }
11451150
11461151 // 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 ;
11481153 for (i_ind = 0 ; i_ind < 4 ; i_ind++) {
11491154 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];
11511156 break ;
11521157 }
11531158 type_mask = type_mask << 1 ;
11541159 }
11551160
11561161 if (i_ind == 4 ) {
11571162 // No common erase type was found between regions
1158- _min_common_erase_size = 0 ;
1163+ smtbl. _min_common_erase_size = 0 ;
11591164 }
11601165
11611166 return 0 ;
@@ -1374,39 +1379,44 @@ bool QSPIFBlockDevice::_is_mem_ready()
13741379/* ********************************************/
13751380/* ************ Utility Functions *************/
13761381/* ********************************************/
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 )
13781383{
13791384 // 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 )) {
13811386 return -1 ;
13821387 }
13831388
1384- if (_regions_count == 1 ) {
1389+ if (smtbl. _regions_count == 1 ) {
13851390 return 0 ;
13861391 }
13871392
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--) {
13891394
1390- if (offset > _region_high_boundary[i_ind]) {
1395+ if (offset > smtbl. _region_high_boundary [i_ind]) {
13911396 return (i_ind + 1 );
13921397 }
13931398 }
13941399 return -1 ;
13951400
13961401}
13971402
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)
13991408{
14001409 // Iterate on all supported Erase Types of the Region to which the offset belong to.
14011410 // Iterates from highest type to lowest
1402- uint8_t type_mask = ERASE_BITMASK_TYPE4 ;
1411+ uint8_t type_mask = SFDP_ERASE_BITMASK_TYPE4 ;
14031412 int i_ind = 0 ;
14041413 int largest_erase_type = 0 ;
14051414 for (i_ind = 3 ; i_ind >= 0 ; i_ind--) {
14061415 if (bitfield & type_mask) {
14071416 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]))) {
14101420 break ;
14111421 } else {
14121422 bitfield &= ~type_mask;
0 commit comments