@@ -51,16 +51,11 @@ using namespace mbed;
5151// Address Length
5252#define SPIF_ADDR_SIZE_3_BYTES 3
5353#define SPIF_ADDR_SIZE_4_BYTES 4
54- // Erase Types Params
55- #define SPIF_BASIC_PARAM_ERASE_TYPE_1_BYTE 29
56- #define SPIF_BASIC_PARAM_ERASE_TYPE_2_BYTE 31
57- #define SPIF_BASIC_PARAM_ERASE_TYPE_3_BYTE 33
58- #define SPIF_BASIC_PARAM_ERASE_TYPE_4_BYTE 35
59- #define SPIF_BASIC_PARAM_ERASE_TYPE_1_SIZE_BYTE 28
60- #define SPIF_BASIC_PARAM_ERASE_TYPE_2_SIZE_BYTE 30
61- #define SPIF_BASIC_PARAM_ERASE_TYPE_3_SIZE_BYTE 32
62- #define SPIF_BASIC_PARAM_ERASE_TYPE_4_SIZE_BYTE 34
63- #define SPIF_BASIC_PARAM_4K_ERASE_TYPE_BYTE 1
54+
55+ // Default read/legacy erase instructions
56+ #define SPIF_INST_READ_DEFAULT 0x03
57+ #define SPIF_INST_LEGACY_ERASE_DEFAULT (-1 )
58+
6459
6560#define IS_MEM_READY_MAX_RETRIES 10000
6661
@@ -86,16 +81,15 @@ enum spif_default_instructions {
8681// e.g. (1)Set Write Enable, (2)Program, (3)Wait Memory Ready
8782SingletonPtr<PlatformMutex> SPIFBlockDevice::_mutex;
8883
89- // Local Function
90- static unsigned int local_math_power (int base, int exp);
91-
9284// ***********************
9385// SPIF Block Device APIs
9486// ***********************
9587SPIFBlockDevice::SPIFBlockDevice (
9688 PinName mosi, PinName miso, PinName sclk, PinName csel, int freq)
97- : _spi(mosi, miso, sclk), _cs(csel), _read_instruction(0 ), _prog_instruction(0 ), _erase_instruction(0 ),
98- _erase4k_inst(0 ), _page_size_bytes(0 ), _device_size_bytes(0 ), _init_ref_count(0 ), _is_initialized(false )
89+ :
90+ _spi(mosi, miso, sclk), _cs(csel), _prog_instruction(0 ), _erase_instruction(0 ),
91+ _page_size_bytes(0 ),
92+ _device_size_bytes(0 ), _init_ref_count(0 ), _is_initialized(false )
9993{
10094 _address_size = SPIF_ADDR_SIZE_3_BYTES;
10195 // Initial SFDP read tables are read with 8 dummy cycles
@@ -108,6 +102,11 @@ SPIFBlockDevice::SPIFBlockDevice(
108102 _sfdp_info.smptbl .region_cnt = 1 ;
109103 _sfdp_info.smptbl .region_erase_types_bitfld [0 ] = SFDP_ERASE_BITMASK_NONE;
110104
105+ // Set default read/erase instructions
106+ _read_instruction = SPIF_INST_READ_DEFAULT;
107+ _legacy_erase_instruction = SPIF_INST_LEGACY_ERASE_DEFAULT;
108+
109+
111110 if (SPIF_BD_ERROR_OK != _spi_set_frequency (freq)) {
112111 tr_error (" SPI Set Frequency Failed" );
113112 }
@@ -654,65 +653,55 @@ int SPIFBlockDevice::_sfdp_parse_basic_param_table(Callback<int(bd_addr_t, void
654653 _page_size_bytes = sfdp_detect_page_size (param_table, sfdp_info.bptbl .size );
655654
656655 // Detect and Set Erase Types
657- _sfdp_detect_erase_types_inst_and_size (param_table, sfdp_info.bptbl .size , _erase4k_inst, sfdp_info.smptbl );
658- _erase_instruction = _erase4k_inst ;
656+ _sfdp_detect_erase_types_inst_and_size (param_table, sfdp_info.bptbl .size , sfdp_info.smptbl );
657+ _erase_instruction = _legacy_erase_instruction ;
659658
660659 // Detect and Set fastest Bus mode (default 1-1-1)
661660 _sfdp_detect_best_bus_read_mode (param_table, sfdp_info.bptbl .size , _read_instruction);
662661
663662 return 0 ;
664663}
665664
666- int SPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size (uint8_t *basic_param_table_ptr, int basic_param_table_size,
667- int &erase4k_inst ,
665+ int SPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size (uint8_t *basic_param_table_ptr,
666+ int basic_param_table_size ,
668667 sfdp_smptbl_info &smptbl)
669668{
670- erase4k_inst = 0xff ;
671- bool found_4Kerase_type = false ;
672669 uint8_t bitfield = 0x01 ;
673670
674671 // Erase 4K Inst is taken either from param table legacy 4K erase or superseded by erase Instruction for type of size 4K
675- erase4k_inst = basic_param_table_ptr[SPIF_BASIC_PARAM_4K_ERASE_TYPE_BYTE];
676-
677- if (basic_param_table_size > SPIF_BASIC_PARAM_ERASE_TYPE_1_SIZE_BYTE) {
672+ if (basic_param_table_size > SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE) {
678673 // Loop Erase Types 1-4
679674 for (int i_ind = 0 ; i_ind < 4 ; i_ind++) {
680675 smptbl.erase_type_inst_arr [i_ind] = 0xff ; // 0xFF default for unsupported type
681- smptbl.erase_type_size_arr [i_ind] = local_math_power (
682- 2 , basic_param_table_ptr[SPIF_BASIC_PARAM_ERASE_TYPE_1_SIZE_BYTE + 2 * i_ind]) ; // Size given as 2^N
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
683678 tr_debug (" Erase Type(A) %d - Inst: 0x%xh, Size: %d" , (i_ind + 1 ), smptbl.erase_type_inst_arr [i_ind],
684679 smptbl.erase_type_size_arr [i_ind]);
685680 if (smptbl.erase_type_size_arr [i_ind] > 1 ) {
686681 // if size==1 type is not supported
687682 smptbl.erase_type_inst_arr [i_ind] =
688- basic_param_table_ptr[SPIF_BASIC_PARAM_ERASE_TYPE_1_BYTE + 2 * i_ind];
683+ basic_param_table_ptr[SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE + 2 * i_ind];
689684
690685 if ((smptbl.erase_type_size_arr [i_ind] < smptbl.regions_min_common_erase_size )
691686 || (smptbl.regions_min_common_erase_size == 0 )) {
692687 // Set default minimal common erase for singal region
693688 smptbl.regions_min_common_erase_size = smptbl.erase_type_size_arr [i_ind];
694689 }
695-
696- // SFDP standard requires 4K Erase type to exist and its instruction to be identical to legacy field erase instruction
697- if (smptbl.erase_type_size_arr [i_ind] == 4096 ) {
698- found_4Kerase_type = true ;
699- if (erase4k_inst != smptbl.erase_type_inst_arr [i_ind]) {
700- // Verify 4KErase Type is identical to Legacy 4K erase type specified in Byte 1 of Param Table
701- erase4k_inst = smptbl.erase_type_inst_arr [i_ind];
702- tr_warning (" _detectEraseTypesInstAndSize - Default 4K erase Inst is different than erase type Inst for 4K" );
703-
704- }
705- }
706690 smptbl.region_erase_types_bitfld [0 ] |= bitfield; // no region map, set region "0" types bitfield as default
707691 }
708692 tr_info (" Erase Type %d - Inst: 0x%xh, Size: %d" , (i_ind + 1 ),
709693 smptbl.erase_type_inst_arr [i_ind], smptbl.erase_type_size_arr [i_ind]);
710694 bitfield = bitfield << 1 ;
711695 }
712- }
696+ } else {
697+ tr_debug (" SFDP erase types are not available - falling back to legacy 4k erase instruction" );
713698
714- if (false == found_4Kerase_type) {
715- tr_warning (" Couldn't find Erase Type for 4KB size" );
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+ }
716705 }
717706 return 0 ;
718707}
@@ -886,18 +875,3 @@ int SPIFBlockDevice::_utils_iterate_next_largest_erase_type(uint8_t &bitfield,
886875 return largest_erase_type;
887876}
888877
889- /* ********************************************/
890- /* ************* Local Functions **************/
891- /* ********************************************/
892- static unsigned int local_math_power (int base, int exp)
893- {
894- // Integer X^Y function, used to calculate size fields given in 2^N format
895- int result = 1 ;
896- while (exp) {
897- result *= base;
898- exp--;
899- }
900- return result;
901- }
902-
903-
0 commit comments