mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			SFDP: consolidates sfdp_detect_erase_types_inst_and_size
							parent
							
								
									2da963b8de
								
							
						
					
					
						commit
						6a60574cf5
					
				| 
						 | 
				
			
			@ -140,6 +140,7 @@ QSPIFBlockDevice::QSPIFBlockDevice(PinName io0, PinName io1, PinName io2, PinNam
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    // Initialize parameters
 | 
			
		||||
    _sfdp_info.bptbl.legacy_erase_instruction = QSPIF_INST_LEGACY_ERASE_DEFAULT;
 | 
			
		||||
    _sfdp_info.smptbl.regions_min_common_erase_size = 0;
 | 
			
		||||
    _sfdp_info.smptbl.region_cnt = 1;
 | 
			
		||||
    _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
 | 
			
		|||
 | 
			
		||||
    // Set default read/erase instructions
 | 
			
		||||
    _read_instruction = QSPIF_INST_READ_DEFAULT;
 | 
			
		||||
    _legacy_erase_instruction = QSPIF_INST_LEGACY_ERASE_DEFAULT;
 | 
			
		||||
 | 
			
		||||
    _num_status_registers = QSPI_DEFAULT_STATUS_REGISTERS;
 | 
			
		||||
    // Set default status register 2 write/read instructions
 | 
			
		||||
| 
						 | 
				
			
			@ -417,7 +417,7 @@ int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
 | 
			
		|||
    // For each iteration erase the largest section supported by current region
 | 
			
		||||
    while (size > 0) {
 | 
			
		||||
        unsigned int eu_size;
 | 
			
		||||
        if (_legacy_erase_instruction == QSPI_NO_INST) {
 | 
			
		||||
        if (_sfdp_info.bptbl.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,
 | 
			
		||||
| 
						 | 
				
			
			@ -427,7 +427,7 @@ int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
 | 
			
		|||
            eu_size = _sfdp_info.smptbl.erase_type_size_arr[type];
 | 
			
		||||
        } else {
 | 
			
		||||
            // Must use legacy 4k erase instruction
 | 
			
		||||
            cur_erase_inst = _legacy_erase_instruction;
 | 
			
		||||
            cur_erase_inst = _sfdp_info.bptbl.legacy_erase_instruction;
 | 
			
		||||
            eu_size = QSPIF_DEFAULT_SE_SIZE;
 | 
			
		||||
        }
 | 
			
		||||
        offset = addr % eu_size;
 | 
			
		||||
| 
						 | 
				
			
			@ -508,7 +508,7 @@ const char *QSPIFBlockDevice::get_type() const
 | 
			
		|||
bd_size_t QSPIFBlockDevice::get_erase_size(bd_addr_t addr)
 | 
			
		||||
{
 | 
			
		||||
    // If the legacy erase instruction is in use, the erase size is uniformly 4k
 | 
			
		||||
    if (_legacy_erase_instruction != QSPI_NO_INST) {
 | 
			
		||||
    if (_sfdp_info.bptbl.legacy_erase_instruction != QSPI_NO_INST) {
 | 
			
		||||
        return QSPIF_DEFAULT_SE_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -651,7 +651,7 @@ int QSPIFBlockDevice::_sfdp_parse_basic_param_table(Callback<int(bd_addr_t, void
 | 
			
		|||
    bool shouldSetQuadEnable = false;
 | 
			
		||||
    bool is_qpi_mode = false;
 | 
			
		||||
 | 
			
		||||
    if (_sfdp_detect_erase_types_inst_and_size(param_table, basic_table_size, _sfdp_info.smptbl) != 0) {
 | 
			
		||||
    if (sfdp_detect_erase_types_inst_and_size(param_table, _sfdp_info) < 0) {
 | 
			
		||||
        tr_error("Init - Detecting erase types instructions/sizes failed");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -820,52 +820,6 @@ int QSPIFBlockDevice::_sfdp_set_qpi_enabled(uint8_t *basic_param_table_ptr)
 | 
			
		|||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int QSPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size(uint8_t *basic_param_table_ptr,
 | 
			
		||||
                                                             int basic_param_table_size,
 | 
			
		||||
                                                             sfdp_smptbl_info &smptbl)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t bitfield = 0x01;
 | 
			
		||||
 | 
			
		||||
    // Erase 4K Inst is taken either from param table legacy 4K erase or superseded by erase Instruction for type of size 4K
 | 
			
		||||
    if (basic_param_table_size > SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE) {
 | 
			
		||||
        // Loop Erase Types 1-4
 | 
			
		||||
        for (int i_ind = 0; i_ind < 4; i_ind++) {
 | 
			
		||||
            smptbl.erase_type_inst_arr[i_ind] = QSPI_NO_INST; // Default for unsupported type
 | 
			
		||||
            smptbl.erase_type_size_arr[i_ind] = 1
 | 
			
		||||
                                                << 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
 | 
			
		||||
            tr_debug("Erase Type(A) %d - Inst: 0x%xh, Size: %d", (i_ind + 1), smptbl.erase_type_inst_arr[i_ind],
 | 
			
		||||
                     smptbl.erase_type_size_arr[i_ind]);
 | 
			
		||||
            if (smptbl.erase_type_size_arr[i_ind] > 1) {
 | 
			
		||||
                // if size==1 type is not supported
 | 
			
		||||
                smptbl.erase_type_inst_arr[i_ind] = basic_param_table_ptr[SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE
 | 
			
		||||
                                                                          + 2 * i_ind];
 | 
			
		||||
 | 
			
		||||
                if ((smptbl.erase_type_size_arr[i_ind] < smptbl.regions_min_common_erase_size)
 | 
			
		||||
                        || (smptbl.regions_min_common_erase_size == 0)) {
 | 
			
		||||
                    //Set default minimal common erase for signal region
 | 
			
		||||
                    smptbl.regions_min_common_erase_size = smptbl.erase_type_size_arr[i_ind];
 | 
			
		||||
                }
 | 
			
		||||
                smptbl.region_erase_types_bitfld[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), smptbl.erase_type_inst_arr[i_ind],
 | 
			
		||||
                     smptbl.erase_type_size_arr[i_ind]);
 | 
			
		||||
            bitfield = bitfield << 1;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        tr_debug("SFDP erase types are not available - falling back to legacy 4k erase instruction");
 | 
			
		||||
 | 
			
		||||
        // 0xFF indicates that the legacy 4k erase instruction is not supported
 | 
			
		||||
        _legacy_erase_instruction = basic_param_table_ptr[SFDP_BASIC_PARAM_TABLE_4K_ERASE_TYPE_BYTE];
 | 
			
		||||
        if (_legacy_erase_instruction == 0xFF) {
 | 
			
		||||
            tr_error("_detectEraseTypesInstAndSize - Legacy 4k erase instruction not supported");
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int QSPIFBlockDevice::_sfdp_detect_best_bus_read_mode(uint8_t *basic_param_table_ptr, int basic_param_table_size,
 | 
			
		||||
                                                      bool &set_quad_enable, bool &is_qpi_mode)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -336,11 +336,6 @@ private:
 | 
			
		|||
    // Set Page size for program
 | 
			
		||||
    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,
 | 
			
		||||
                                               mbed::sfdp_smptbl_info &smptbl);
 | 
			
		||||
 | 
			
		||||
    // 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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -386,7 +381,6 @@ private:
 | 
			
		|||
 | 
			
		||||
    // Command Instructions
 | 
			
		||||
    mbed::qspi_inst_t _read_instruction;
 | 
			
		||||
    int _legacy_erase_instruction;
 | 
			
		||||
 | 
			
		||||
    // Status register write/read instructions
 | 
			
		||||
    unsigned int _num_status_registers;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -98,14 +98,13 @@ SPIFBlockDevice::SPIFBlockDevice(
 | 
			
		|||
    _write_dummy_and_mode_cycles = 0;
 | 
			
		||||
    _dummy_and_mode_cycles = _read_dummy_and_mode_cycles;
 | 
			
		||||
 | 
			
		||||
    _sfdp_info.bptbl.legacy_erase_instruction = SPIF_INST_LEGACY_ERASE_DEFAULT;
 | 
			
		||||
    _sfdp_info.smptbl.regions_min_common_erase_size = 0;
 | 
			
		||||
    _sfdp_info.smptbl.region_cnt = 1;
 | 
			
		||||
    _sfdp_info.smptbl.region_erase_types_bitfld[0] = SFDP_ERASE_BITMASK_NONE;
 | 
			
		||||
 | 
			
		||||
    // Set default read/erase instructions
 | 
			
		||||
    _read_instruction = SPIF_INST_READ_DEFAULT;
 | 
			
		||||
    _legacy_erase_instruction = SPIF_INST_LEGACY_ERASE_DEFAULT;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if (SPIF_BD_ERROR_OK != _spi_set_frequency(freq)) {
 | 
			
		||||
        tr_error("SPI Set Frequency Failed");
 | 
			
		||||
| 
						 | 
				
			
			@ -653,8 +652,12 @@ int SPIFBlockDevice::_sfdp_parse_basic_param_table(Callback<int(bd_addr_t, void
 | 
			
		|||
    _page_size_bytes = sfdp_detect_page_size(param_table, sfdp_info.bptbl.size);
 | 
			
		||||
 | 
			
		||||
    // Detect and Set Erase Types
 | 
			
		||||
    _sfdp_detect_erase_types_inst_and_size(param_table, sfdp_info.bptbl.size, sfdp_info.smptbl);
 | 
			
		||||
    _erase_instruction = _legacy_erase_instruction;
 | 
			
		||||
    if (sfdp_detect_erase_types_inst_and_size(param_table, sfdp_info) < 0) {
 | 
			
		||||
        tr_error("Init - Detecting erase types instructions/sizes failed");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _erase_instruction = sfdp_info.bptbl.legacy_erase_instruction;
 | 
			
		||||
 | 
			
		||||
    // Detect and Set fastest Bus mode (default 1-1-1)
 | 
			
		||||
    _sfdp_detect_best_bus_read_mode(param_table, sfdp_info.bptbl.size, _read_instruction);
 | 
			
		||||
| 
						 | 
				
			
			@ -662,50 +665,6 @@ int SPIFBlockDevice::_sfdp_parse_basic_param_table(Callback<int(bd_addr_t, void
 | 
			
		|||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int SPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size(uint8_t *basic_param_table_ptr,
 | 
			
		||||
                                                            int basic_param_table_size,
 | 
			
		||||
                                                            sfdp_smptbl_info &smptbl)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t bitfield = 0x01;
 | 
			
		||||
 | 
			
		||||
    // Erase 4K Inst is taken either from param table legacy 4K erase or superseded by erase Instruction for type of size 4K
 | 
			
		||||
    if (basic_param_table_size > SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE) {
 | 
			
		||||
        // Loop Erase Types 1-4
 | 
			
		||||
        for (int i_ind = 0; i_ind < 4; i_ind++) {
 | 
			
		||||
            smptbl.erase_type_inst_arr[i_ind] = 0xff; //0xFF default for unsupported type
 | 
			
		||||
            smptbl.erase_type_size_arr[i_ind] = 1
 | 
			
		||||
                                                << basic_param_table_ptr[SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE + 2 * i_ind]; // Size given as 2^N
 | 
			
		||||
            tr_debug("Erase Type(A) %d - Inst: 0x%xh, Size: %d", (i_ind + 1), smptbl.erase_type_inst_arr[i_ind],
 | 
			
		||||
                     smptbl.erase_type_size_arr[i_ind]);
 | 
			
		||||
            if (smptbl.erase_type_size_arr[i_ind] > 1) {
 | 
			
		||||
                // if size==1 type is not supported
 | 
			
		||||
                smptbl.erase_type_inst_arr[i_ind] =
 | 
			
		||||
                    basic_param_table_ptr[SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE + 2 * i_ind];
 | 
			
		||||
 | 
			
		||||
                if ((smptbl.erase_type_size_arr[i_ind] < smptbl.regions_min_common_erase_size)
 | 
			
		||||
                        || (smptbl.regions_min_common_erase_size == 0)) {
 | 
			
		||||
                    //Set default minimal common erase for singal region
 | 
			
		||||
                    smptbl.regions_min_common_erase_size = smptbl.erase_type_size_arr[i_ind];
 | 
			
		||||
                }
 | 
			
		||||
                smptbl.region_erase_types_bitfld[0] |= bitfield; // no region map, set region "0" types bitfield as default
 | 
			
		||||
            }
 | 
			
		||||
            tr_info("Erase Type %d - Inst: 0x%xh, Size: %d", (i_ind + 1),
 | 
			
		||||
                    smptbl.erase_type_inst_arr[i_ind], smptbl.erase_type_size_arr[i_ind]);
 | 
			
		||||
            bitfield = bitfield << 1;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        tr_debug("SFDP erase types are not available - falling back to legacy 4k erase instruction");
 | 
			
		||||
 | 
			
		||||
        // 0xFF indicates that the legacy 4k erase instruction is not supported
 | 
			
		||||
        _legacy_erase_instruction = basic_param_table_ptr[SFDP_BASIC_PARAM_TABLE_4K_ERASE_TYPE_BYTE];
 | 
			
		||||
        if (_legacy_erase_instruction == 0xFF) {
 | 
			
		||||
            tr_error("sfdp_detect_erase_types_inst_and_size - Legacy 4k erase instruction not supported");
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int SPIFBlockDevice::_sfdp_detect_best_bus_read_mode(uint8_t *basic_param_table_ptr, int basic_param_table_size,
 | 
			
		||||
                                                     int &read_inst)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -239,10 +239,6 @@ private:
 | 
			
		|||
    // Set Page size for program
 | 
			
		||||
    unsigned 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,
 | 
			
		||||
                                               mbed::sfdp_smptbl_info &smptbl);
 | 
			
		||||
 | 
			
		||||
    /***********************/
 | 
			
		||||
    /* Utilities Functions */
 | 
			
		||||
    /***********************/
 | 
			
		||||
| 
						 | 
				
			
			@ -301,7 +297,6 @@ private:
 | 
			
		|||
    int _read_instruction;
 | 
			
		||||
    int _prog_instruction;
 | 
			
		||||
    int _erase_instruction;
 | 
			
		||||
    int _legacy_erase_instruction;  // Legacy 4K erase instruction (default 0x20h)
 | 
			
		||||
 | 
			
		||||
    // Data extracted from the devices SFDP structure
 | 
			
		||||
    mbed::sfdp_hdr_info _sfdp_info;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,30 +38,20 @@ static const int SFDP_BASIC_PARAMS_TBL_SIZE = 80; ///< Basic Parameter Table siz
 | 
			
		|||
static const int SFDP_SECTOR_MAP_MAX_REGIONS = 10; ///< Maximum number of regions with different erase granularity
 | 
			
		||||
 | 
			
		||||
// Erase Types Per Region BitMask
 | 
			
		||||
static const int SFDP_ERASE_BITMASK_TYPE4 = 0x08; ///< Erase type 4 (erase granularity) identifier
 | 
			
		||||
static const int SFDP_ERASE_BITMASK_TYPE3 = 0x04; ///< Erase type 3 (erase granularity) identifier
 | 
			
		||||
static const int SFDP_ERASE_BITMASK_TYPE2 = 0x02; ///< Erase type 2 (erase granularity) identifier
 | 
			
		||||
static const int SFDP_ERASE_BITMASK_TYPE1 = 0x01; ///< Erase type 1 (erase granularity) identifier
 | 
			
		||||
static const int SFDP_ERASE_BITMASK_NONE = 0x00;  ///< Erase type None
 | 
			
		||||
static const int SFDP_ERASE_BITMASK_ALL = 0x0F;   ///< Erase type All
 | 
			
		||||
constexpr int SFDP_ERASE_BITMASK_TYPE4 = 0x08; ///< Erase type 4 (erase granularity) identifier
 | 
			
		||||
constexpr int SFDP_ERASE_BITMASK_TYPE3 = 0x04; ///< Erase type 3 (erase granularity) identifier
 | 
			
		||||
constexpr int SFDP_ERASE_BITMASK_TYPE2 = 0x02; ///< Erase type 2 (erase granularity) identifier
 | 
			
		||||
constexpr int SFDP_ERASE_BITMASK_TYPE1 = 0x01; ///< Erase type 1 (erase granularity) identifier
 | 
			
		||||
constexpr int SFDP_ERASE_BITMASK_NONE = 0x00;  ///< Erase type None
 | 
			
		||||
constexpr int SFDP_ERASE_BITMASK_ALL = 0x0F;   ///< Erase type All
 | 
			
		||||
 | 
			
		||||
// Erase Types Params
 | 
			
		||||
#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE 29
 | 
			
		||||
#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_2_BYTE 31
 | 
			
		||||
#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_3_BYTE 33
 | 
			
		||||
#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_4_BYTE 35
 | 
			
		||||
#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE 28
 | 
			
		||||
#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_2_SIZE_BYTE 30
 | 
			
		||||
#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_3_SIZE_BYTE 32
 | 
			
		||||
#define SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_4_SIZE_BYTE 34
 | 
			
		||||
#define SFDP_BASIC_PARAM_TABLE_4K_ERASE_TYPE_BYTE 1
 | 
			
		||||
 | 
			
		||||
static const int SFDP_MAX_NUM_OF_ERASE_TYPES = 4;  ///< Maximum number of different erase types (erase granularity)
 | 
			
		||||
constexpr int SFDP_MAX_NUM_OF_ERASE_TYPES = 4;  ///< Maximum number of different erase types (erase granularity)
 | 
			
		||||
 | 
			
		||||
/** SFDP Basic Parameter Table info */
 | 
			
		||||
struct sfdp_bptbl_info {
 | 
			
		||||
    uint32_t addr; ///< Address
 | 
			
		||||
    size_t size; ///< Size
 | 
			
		||||
    int legacy_erase_instruction; ///< Legacy 4K erase instruction
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** 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
 | 
			
		|||
 */
 | 
			
		||||
size_t sfdp_detect_page_size(uint8_t *bptbl_ptr, size_t bptbl_size);
 | 
			
		||||
 | 
			
		||||
/** Detect all supported erase types
 | 
			
		||||
 *
 | 
			
		||||
 * @param bptbl_ptr Pointer to memory holding a Basic Parameter Table structure
 | 
			
		||||
 * @param smtbl     All information parsed from the table gets passed back on this structure
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success, negative error code on failure
 | 
			
		||||
 */
 | 
			
		||||
int sfdp_detect_erase_types_inst_and_size(uint8_t *bptbl_ptr, sfdp_hdr_info &sfdp_info);
 | 
			
		||||
 | 
			
		||||
/** @}*/
 | 
			
		||||
} /* namespace mbed */
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,6 +42,17 @@ inline uint32_t sfdp_get_param_tbl_ptr(uint32_t dword2)
 | 
			
		|||
 | 
			
		||||
namespace mbed {
 | 
			
		||||
 | 
			
		||||
// Erase Types Params
 | 
			
		||||
constexpr int SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE = 29; ///< Erase Type 1 Instruction
 | 
			
		||||
constexpr int SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_2_BYTE = 31; ///< Erase Type 2 Instruction
 | 
			
		||||
constexpr int SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_3_BYTE = 33; ///< Erase Type 3 Instruction
 | 
			
		||||
constexpr int SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_4_BYTE = 35; ///< Erase Type 4 Instruction
 | 
			
		||||
constexpr int SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE = 28; ///< Erase Type 1 Size
 | 
			
		||||
constexpr int SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_2_SIZE_BYTE = 30; ///< Erase Type 2 Size
 | 
			
		||||
constexpr int SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_3_SIZE_BYTE = 32; ///< Erase Type 3 Size
 | 
			
		||||
constexpr int SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_4_SIZE_BYTE = 34; ///< Erase Type 4 Size
 | 
			
		||||
constexpr int SFDP_BASIC_PARAM_TABLE_4K_ERASE_TYPE_BYTE = 1; ///< 4 Kilobyte Erase Instruction
 | 
			
		||||
 | 
			
		||||
/* Verifies SFDP Header and return number of parameter headers */
 | 
			
		||||
int sfdp_parse_sfdp_header(sfdp_hdr *sfdp_hdr_ptr)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -210,6 +221,51 @@ size_t sfdp_detect_page_size(uint8_t *basic_param_table_ptr, size_t basic_param_
 | 
			
		|||
    return page_size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sfdp_detect_erase_types_inst_and_size(uint8_t *bptbl_ptr, sfdp_hdr_info &sfdp_info)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t bitfield = 0x01;
 | 
			
		||||
 | 
			
		||||
    // Erase 4K Inst is taken either from param table legacy 4K erase or superseded by erase Instruction for type of size 4K
 | 
			
		||||
    if (sfdp_info.bptbl.size > SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE) {
 | 
			
		||||
        // Loop Erase Types 1-4
 | 
			
		||||
        for (int i_ind = 0; i_ind < 4; i_ind++) {
 | 
			
		||||
            sfdp_info.smptbl.erase_type_inst_arr[i_ind] = -1; // Default for unsupported type
 | 
			
		||||
            sfdp_info.smptbl.erase_type_size_arr[i_ind] = 1
 | 
			
		||||
                                                          << bptbl_ptr[SFDP_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), sfdp_info.smptbl.erase_type_inst_arr[i_ind],
 | 
			
		||||
                     sfdp_info.smptbl.erase_type_size_arr[i_ind]);
 | 
			
		||||
            if (sfdp_info.smptbl.erase_type_size_arr[i_ind] > 1) {
 | 
			
		||||
                // if size==1 type is not supported
 | 
			
		||||
                sfdp_info.smptbl.erase_type_inst_arr[i_ind] = bptbl_ptr[SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE
 | 
			
		||||
                                                                        + 2 * i_ind];
 | 
			
		||||
 | 
			
		||||
                if ((sfdp_info.smptbl.erase_type_size_arr[i_ind] < sfdp_info.smptbl.regions_min_common_erase_size)
 | 
			
		||||
                        || (sfdp_info.smptbl.regions_min_common_erase_size == 0)) {
 | 
			
		||||
                    //Set default minimal common erase for signal region
 | 
			
		||||
                    sfdp_info.smptbl.regions_min_common_erase_size = sfdp_info.smptbl.erase_type_size_arr[i_ind];
 | 
			
		||||
                }
 | 
			
		||||
                sfdp_info.smptbl.region_erase_types_bitfld[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), sfdp_info.smptbl.erase_type_inst_arr[i_ind],
 | 
			
		||||
                     sfdp_info.smptbl.erase_type_size_arr[i_ind]);
 | 
			
		||||
            bitfield = bitfield << 1;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        tr_debug("SFDP erase types are not available - falling back to legacy 4k erase instruction");
 | 
			
		||||
 | 
			
		||||
        // 0xFF indicates that the legacy 4k erase instruction is not supported
 | 
			
		||||
        sfdp_info.bptbl.legacy_erase_instruction = bptbl_ptr[SFDP_BASIC_PARAM_TABLE_4K_ERASE_TYPE_BYTE];
 | 
			
		||||
        if (sfdp_info.bptbl.legacy_erase_instruction == 0xFF) {
 | 
			
		||||
            tr_error("_detectEraseTypesInstAndSize - Legacy 4k erase instruction not supported");
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} /* namespace mbed */
 | 
			
		||||
#endif /* (DEVICE_SPI || DEVICE_QSPI) */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue