Skip to content

SPIF: Add config for non-SFDP flash devices #10177

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 39 additions & 13 deletions components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,10 @@ enum spif_default_instructions {
// e.g. (1)Set Write Enable, (2)Program, (3)Wait Memory Ready
SingletonPtr<PlatformMutex> SPIFBlockDevice::_mutex;

#ifdef MBED_CONF_SPIF_SFDP_ENABLE
// Local Function
static unsigned int local_math_power(int base, int exp);
#endif

//***********************
// SPIF Block Device APIs
Expand Down Expand Up @@ -128,11 +130,14 @@ int SPIFBlockDevice::init()
uint8_t vendor_device_ids[4];
size_t data_length = 3;
int status = SPIF_BD_ERROR_OK;
#ifdef MBED_CONF_SPIF_SFDP_ENABLE
uint32_t basic_table_addr = 0;
size_t basic_table_size = 0;
uint32_t sector_map_table_addr = 0;
size_t sector_map_table_size = 0;
#endif
spif_bd_error spi_status = SPIF_BD_ERROR_OK;
uint32_t density_bits = 0;

_mutex->lock();

Expand All @@ -155,7 +160,6 @@ int SPIFBlockDevice::init()
tr_info("INFO: Initialize flash memory OK\n");
}


/* Read Manufacturer ID (1byte), and Device ID (2bytes)*/
spi_status = _spi_send_general_command(SPIF_RDID, SPI_NO_ADDRESS_COMMAND, NULL, 0, (char *)vendor_device_ids,
data_length);
Expand All @@ -180,7 +184,7 @@ int SPIFBlockDevice::init()
status = SPIF_BD_ERROR_READY_FAILED;
goto exit_point;
}

#ifdef MBED_CONF_SPIF_SFDP_ENABLE
/**************************** Parse SFDP Header ***********************************/
if (0 != _sfdp_parse_sfdp_headers(basic_table_addr, basic_table_size, sector_map_table_addr, sector_map_table_size)) {
tr_error("ERROR: init - Parse SFDP Headers Failed");
Expand Down Expand Up @@ -210,11 +214,22 @@ int SPIFBlockDevice::init()
goto exit_point;
}
}

#else
density_bits = MBED_CONF_SPIF_DRIVER_DENSITY_BITS;
_device_size_bytes = (density_bits + 1) / 8;
_read_instruction = SPIF_READ;
_prog_instruction = SPIF_PP;
_erase_instruction = MBED_CONF_SPIF_DRIVER_SECTOR_ERASE_INST;
// Set Page Size (SPI write must be done on Page limits)
_page_size_bytes = MBED_CONF_SPIF_DRIVER_PAGE_SIZE_BYTES;
//_sector_size_pages = MBED_CONF_SPIF_DRIVER_SECTOR_SIZE_PAGES;
_min_common_erase_size = MBED_CONF_SPIF_DRIVER_SECTOR_SIZE_PAGES * MBED_CONF_SPIF_DRIVER_PAGE_SIZE_BYTES;
// Configure BUS Mode to 1_1_1 for all commands other than Read
// Dummy And Mode Cycles Back default 0
_dummy_and_mode_cycles = _write_dummy_and_mode_cycles;
_read_dummy_and_mode_cycles = MBED_CONF_SPIF_DRIVER_READ_DUMMY_CYCLES;
_write_dummy_and_mode_cycles = MBED_CONF_SPIF_DRIVER_MODE_WRITE_DUMMY_CYCLES;
_is_initialized = true;
#endif

exit_point:
_mutex->unlock();
Expand Down Expand Up @@ -333,17 +348,19 @@ int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
return BD_ERROR_DEVICE_ERROR;
}

int type = 0;
uint32_t offset = 0;
uint32_t chunk = 4096;
int cur_erase_inst = _erase_instruction;
int size = (int)in_size;
bool erase_failed = false;
int status = SPIF_BD_ERROR_OK;
#ifdef MBED_CONF_SPIF_SFDP_ENABLE
int type = 0;
uint32_t offset = 0;
uint32_t chunk = 4096;
// Find region of erased address
int region = _utils_find_addr_region(addr);
// Erase Types of selected region
uint8_t bitfield = _region_erase_types_bitfield[region];
#endif

tr_info("DEBUG: erase - addr: %llu, in_size: %llu", addr, in_size);

Expand All @@ -359,7 +376,7 @@ int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)

// For each iteration erase the largest section supported by current region
while (size > 0) {

#ifdef MBED_CONF_SPIF_SFDP_ENABLE
// iterate to find next Largest erase type ( a. supported by region, b. smaller than size)
// find the matching instruction and erase size chunk for that type.
type = _utils_iterate_next_largest_erase_type(bitfield, size, (unsigned int)addr, _region_high_boundary[region]);
Expand All @@ -371,7 +388,7 @@ int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
addr, size, cur_erase_inst, chunk);
tr_debug("DEBUG: erase - Region: %d, Type:%d",
region, type);

#endif
_mutex->lock();

if (_set_write_enable() != 0) {
Expand All @@ -382,7 +399,7 @@ int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
}

_spi_send_erase_command(cur_erase_inst, addr, size);

#ifdef MBED_CONF_SPIF_SFDP_ENABLE
addr += chunk;
size -= chunk;

Expand All @@ -391,7 +408,10 @@ int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
region++;
bitfield = _region_erase_types_bitfield[region];
}

#else
addr += _min_common_erase_size;
size -= _min_common_erase_size;
#endif
if (false == _is_mem_ready()) {
tr_error("ERROR: SPI After Erase Device not ready - failed\n");
erase_failed = true;
Expand Down Expand Up @@ -431,6 +451,7 @@ bd_size_t SPIFBlockDevice::get_erase_size() const
// Find minimal erase size supported by the region to which the address belongs to
bd_size_t SPIFBlockDevice::get_erase_size(bd_addr_t addr)
{
#ifdef MBED_CONF_SPIF_SFDP_ENABLE
// Find region of current address
int region = _utils_find_addr_region(addr);

Expand All @@ -457,6 +478,9 @@ bd_size_t SPIFBlockDevice::get_erase_size(bd_addr_t addr)
}

return (bd_size_t)min_region_erase_size;
#else
return _min_common_erase_size;
#endif
}

bd_size_t SPIFBlockDevice::size() const
Expand Down Expand Up @@ -596,6 +620,7 @@ spif_bd_error SPIFBlockDevice::_spi_send_general_command(int instruction, bd_add
return SPIF_BD_ERROR_OK;
}

#ifdef MBED_CONF_SPIF_SFDP_ENABLE
/*********************************************************/
/********** SFDP Parsing and Detection Functions *********/
/*********************************************************/
Expand Down Expand Up @@ -887,6 +912,7 @@ int SPIFBlockDevice::_sfdp_detect_best_bus_read_mode(uint8_t *basic_param_table_

return 0;
}
#endif

int SPIFBlockDevice::_reset_flash_mem()
{
Expand Down Expand Up @@ -1040,6 +1066,7 @@ int SPIFBlockDevice::_utils_iterate_next_largest_erase_type(uint8_t &bitfield, i
/*********************************************/
/************** Local Functions **************/
/*********************************************/
#ifdef MBED_CONF_SPIF_SFDP_ENABLE
static unsigned int local_math_power(int base, int exp)
{
// Integer X^Y function, used to calculate size fields given in 2^N format
Expand All @@ -1050,5 +1077,4 @@ static unsigned int local_math_power(int base, int exp)
}
return result;
}


#endif
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ class SPIFBlockDevice : public mbed::BlockDevice {
private:

// Internal functions

#ifdef MBED_CONF_SPIF_SFDP_ENABLE
/****************************************/
/* SFDP Detection and Parsing Functions */
/****************************************/
Expand All @@ -222,7 +222,7 @@ class SPIFBlockDevice : public mbed::BlockDevice {
int _sfdp_detect_erase_types_inst_and_size(uint8_t *basic_param_table_ptr, int basic_param_table_size,
int &erase4k_inst,
int *erase_type_inst_arr, unsigned int *erase_type_size_arr);

#endif
/***********************/
/* Utilities Functions */
/***********************/
Expand Down Expand Up @@ -299,8 +299,8 @@ class SPIFBlockDevice : public mbed::BlockDevice {
unsigned int _read_dummy_and_mode_cycles; // Number of Dummy and Mode Bits required by Read Bus Mode
unsigned int _write_dummy_and_mode_cycles; // Number of Dummy and Mode Bits required by Write Bus Mode
unsigned int _dummy_and_mode_cycles; // Number of Dummy and Mode Bits required by Current Bus Mode
uint32_t _init_ref_count;
bool _is_initialized;
uint32_t _init_ref_count;
};

#endif /* MBED_SPIF_BLOCK_DEVICE_H */
50 changes: 46 additions & 4 deletions components/storage/blockdevice/COMPONENT_SPIF/mbed_lib.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,35 @@
"SPI_MISO": "SPI_MISO",
"SPI_CLK": "SPI_SCK",
"SPI_CS": "SPI_CS",
"SPI_FREQ": "40000000"
"SPI_FREQ": "40000000",
"SFDP_ENABLE": {
"help": "Enables Serial Flash Discovery Protocal for automatically determining flash parameters from the SFDP register",
"value": true
},
"density_bits": {
"help": "Flash density in bits. 16Mb = 16000000",
"value": null
},
"page_size_bytes": {
"help": "Flash page size in bytes",
"value": null
},
"read_dummy_cycles": {
"help": "Number of dummy cycles required between read cmd/addr and data output",
"value": null
},
"mode_write_dummy_cycles": {
"help": "Number of dummy cycles required between write or mode commands and data",
"value": null
},
"sector_erase_inst": {
"help": "Sector erase instruction.",
"value": null
},
"sector_size_pages": {
"help": "Sector size in pages for sector erase",
"value": null
}
},
"target_overrides": {
"LPC54114": {
Expand Down Expand Up @@ -36,25 +64,39 @@
"SPI_MOSI": "PC_3",
"SPI_MISO": "PC_2",
"SPI_CLK": "PB_13",
"SPI_CS": "PC_12"
"SPI_CS": "PC_12"
},
"MTB_MXCHIP_EMW3166": {
"SPI_MOSI": "PB_15",
"SPI_MISO": "PB_14",
"SPI_CLK": "PB_13",
"SPI_CS": "PA_10"
"SPI_CS": "PA_10"
},
"MTB_USI_WM_BN_BM_22": {
"SPI_MOSI": "PC_3",
"SPI_MISO": "PC_2",
"SPI_CLK": "PB_13",
"SPI_CS": "PA_6"
"SPI_CS": "PA_6"
},
"MTB_ADV_WISE_1570": {
"SPI_MOSI": "PA_7",
"SPI_MISO": "PA_6",
"SPI_CLK": "PA_5",
"SPI_CS": "PB_12"
},
"MTS_DRAGONFLY_F411RE": {
"SPI_MOSI": "SPI3_MOSI",
"SPI_MISO": "SPI3_MISO",
"SPI_CLK": "SPI3_SCK",
"SPI_CS": "SPI_CS1",
"SPI_FREQ": "40000000",
"SFDP_ENABLE": null,
"density_bits": 16000000,
"page_size_bytes": 256,
"read_dummy_cycles": 0,
"mode_write_dummy_cycles": 0,
"sector_erase_inst": "0xD8",
"sector_size_pages": 256
}
}
}