mirror of https://github.com/ARMmbed/mbed-os.git
Move configuration of QSPI format to within commands where it is necessary
parent
08a0b3daeb
commit
ba412734e1
|
@ -43,6 +43,7 @@ using namespace mbed;
|
||||||
|
|
||||||
/* SFDP Header Parsing */
|
/* SFDP Header Parsing */
|
||||||
/***********************/
|
/***********************/
|
||||||
|
#define QSPIF_RSFDP_DUMMY_CYCLES 8
|
||||||
#define QSPIF_SFDP_HEADER_SIZE 8
|
#define QSPIF_SFDP_HEADER_SIZE 8
|
||||||
#define QSPIF_PARAM_HEADER_SIZE 8
|
#define QSPIF_PARAM_HEADER_SIZE 8
|
||||||
|
|
||||||
|
@ -190,6 +191,14 @@ int QSPIFBlockDevice::init()
|
||||||
|
|
||||||
_mutex.lock();
|
_mutex.lock();
|
||||||
|
|
||||||
|
// All commands other than Read and RSFDP use default 1-1-1 bus mode (Program/Erase are constrained by flash memory performance more than bus performance)
|
||||||
|
if (QSPI_STATUS_OK != _qspi.configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, _address_size, QSPI_CFG_BUS_SINGLE,
|
||||||
|
0, QSPI_CFG_BUS_SINGLE, 0)) {
|
||||||
|
tr_error("_qspi_configure_format failed");
|
||||||
|
status = QSPIF_BD_ERROR_DEVICE_ERROR;
|
||||||
|
goto exit_point;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_is_initialized) {
|
if (!_is_initialized) {
|
||||||
_init_ref_count = 0;
|
_init_ref_count = 0;
|
||||||
}
|
}
|
||||||
|
@ -254,14 +263,6 @@ int QSPIFBlockDevice::init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure BUS Mode to 1_1_1 for all commands other than Read
|
|
||||||
if (QSPI_STATUS_OK != _qspi_configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE,
|
|
||||||
0, QSPI_CFG_BUS_SINGLE, 0)) {
|
|
||||||
tr_error("_qspi_configure_format failed");
|
|
||||||
status = QSPIF_BD_ERROR_DEVICE_ERROR;
|
|
||||||
goto exit_point;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != _clear_block_protection()) {
|
if (0 != _clear_block_protection()) {
|
||||||
tr_error("Init - clearing block protection failed");
|
tr_error("Init - clearing block protection failed");
|
||||||
status = QSPIF_BD_ERROR_PARSING_FAILED;
|
status = QSPIF_BD_ERROR_PARSING_FAILED;
|
||||||
|
@ -320,28 +321,11 @@ int QSPIFBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
|
||||||
|
|
||||||
_mutex.lock();
|
_mutex.lock();
|
||||||
|
|
||||||
// Configure Bus for Reading
|
|
||||||
if (QSPI_STATUS_OK != _qspi_configure_format(_inst_width, _address_width, _address_size, _address_width, // Alt width == address width
|
|
||||||
_alt_size, _data_width, _dummy_cycles)) {
|
|
||||||
tr_error("_qspi_configure_format failed");
|
|
||||||
status = QSPIF_BD_ERROR_DEVICE_ERROR;
|
|
||||||
goto exit_point;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (QSPI_STATUS_OK != _qspi_send_read_command(_read_instruction, buffer, addr, size)) {
|
if (QSPI_STATUS_OK != _qspi_send_read_command(_read_instruction, buffer, addr, size)) {
|
||||||
tr_error("Read Command failed");
|
tr_error("Read Command failed");
|
||||||
status = QSPIF_BD_ERROR_DEVICE_ERROR;
|
status = QSPIF_BD_ERROR_DEVICE_ERROR;
|
||||||
goto exit_point;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// All commands other than Read use default 1-1-1 Bus mode (Program/Erase are constrained by flash memory performance more than bus performance)
|
|
||||||
if (QSPI_STATUS_OK != _qspi_configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE, 0, QSPI_CFG_BUS_SINGLE, 0)) {
|
|
||||||
tr_error("_qspi_configure_format failed");
|
|
||||||
status = QSPIF_BD_ERROR_DEVICE_ERROR;
|
|
||||||
goto exit_point;
|
|
||||||
}
|
|
||||||
|
|
||||||
exit_point:
|
|
||||||
_mutex.unlock();
|
_mutex.unlock();
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
@ -625,14 +609,7 @@ int QSPIFBlockDevice::_sfdp_parse_sfdp_headers(uint32_t &basic_table_addr, size_
|
||||||
size_t data_length = QSPIF_SFDP_HEADER_SIZE;
|
size_t data_length = QSPIF_SFDP_HEADER_SIZE;
|
||||||
bd_addr_t addr = 0x0;
|
bd_addr_t addr = 0x0;
|
||||||
|
|
||||||
// Set 1-1-1 bus mode for SFDP header parsing
|
qspi_status_t status = _qspi_send_read_sfdp_command(addr, (char*) sfdp_header, data_length);
|
||||||
if (QSPI_STATUS_OK != _qspi_configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE,
|
|
||||||
0, QSPI_CFG_BUS_SINGLE, 8)) {
|
|
||||||
tr_error("_qspi_configure_format failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
qspi_status_t status = _qspi_send_read_command(QSPIF_SFDP, (char *)sfdp_header, addr /*address*/, data_length);
|
|
||||||
if (status != QSPI_STATUS_OK) {
|
if (status != QSPI_STATUS_OK) {
|
||||||
tr_error("Init - Read SFDP Failed");
|
tr_error("Init - Read SFDP Failed");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -657,8 +634,7 @@ int QSPIFBlockDevice::_sfdp_parse_sfdp_headers(uint32_t &basic_table_addr, size_
|
||||||
|
|
||||||
// Loop over Param Headers and parse them (currently supported Basic Param Table and Sector Region Map Table)
|
// Loop over Param Headers and parse them (currently supported Basic Param Table and Sector Region Map Table)
|
||||||
for (int i_ind = 0; i_ind < number_of_param_headers; i_ind++) {
|
for (int i_ind = 0; i_ind < number_of_param_headers; i_ind++) {
|
||||||
|
status = _qspi_send_read_sfdp_command(addr, (char *) param_header, data_length);
|
||||||
status = _qspi_send_read_command(QSPIF_SFDP, (char *)param_header, addr, data_length);
|
|
||||||
if (status != QSPI_STATUS_OK) {
|
if (status != QSPI_STATUS_OK) {
|
||||||
tr_error("Init - Read Param Table %d Failed", i_ind + 1);
|
tr_error("Init - Read Param Table %d Failed", i_ind + 1);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -696,8 +672,7 @@ int QSPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, s
|
||||||
{
|
{
|
||||||
uint8_t param_table[SFDP_DEFAULT_BASIC_PARAMS_TABLE_SIZE_BYTES]; /* Up To 16 DWORDS = 64 Bytes */
|
uint8_t param_table[SFDP_DEFAULT_BASIC_PARAMS_TABLE_SIZE_BYTES]; /* Up To 16 DWORDS = 64 Bytes */
|
||||||
|
|
||||||
qspi_status_t status = _qspi_send_read_command(QSPIF_SFDP, (char *)param_table, basic_table_addr /*address*/,
|
qspi_status_t status = _qspi_send_read_sfdp_command(basic_table_addr, (char*) param_table, basic_table_size);
|
||||||
basic_table_size);
|
|
||||||
if (status != QSPI_STATUS_OK) {
|
if (status != QSPI_STATUS_OK) {
|
||||||
tr_error("Init - Read SFDP First Table Failed");
|
tr_error("Init - Read SFDP First Table Failed");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -804,13 +779,6 @@ int QSPIFBlockDevice::_sfdp_set_quad_enabled(uint8_t *basic_param_table_ptr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure BUS Mode to 1_1_1 for all commands other than Read
|
|
||||||
if (QSPI_STATUS_OK != _qspi_configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE,
|
|
||||||
0, QSPI_CFG_BUS_SINGLE, 0)) {
|
|
||||||
tr_error("_qspi_configure_format failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read existing status register values
|
// Read existing status register values
|
||||||
_qspi_read_status_registers(status_regs);
|
_qspi_read_status_registers(status_regs);
|
||||||
|
|
||||||
|
@ -1176,9 +1144,7 @@ int QSPIFBlockDevice::_sfdp_parse_sector_map_table(uint32_t sector_map_table_add
|
||||||
// Default set to all type bits 1-4 are common
|
// Default set to all type bits 1-4 are common
|
||||||
int min_common_erase_type_bits = ERASE_BITMASK_ALL;
|
int min_common_erase_type_bits = ERASE_BITMASK_ALL;
|
||||||
|
|
||||||
|
qspi_status_t status = _qspi_send_read_sfdp_command(sector_map_table_addr, (char *) sector_map_table, sector_map_table_size);
|
||||||
qspi_status_t status = _qspi_send_read_command(QSPIF_SFDP, (char *)sector_map_table, sector_map_table_addr /*address*/,
|
|
||||||
sector_map_table_size);
|
|
||||||
if (status != QSPI_STATUS_OK) {
|
if (status != QSPI_STATUS_OK) {
|
||||||
tr_error("Init - Read SFDP First Table Failed");
|
tr_error("Init - Read SFDP First Table Failed");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1435,7 +1401,25 @@ qspi_status_t QSPIFBlockDevice::_qspi_send_read_command(qspi_inst_t read_inst, v
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send read command to device driver
|
// Send read command to device driver
|
||||||
status = _qspi.read(read_inst, -1, (unsigned int)addr, (char *)buffer, &buf_len);
|
// Read commands use the best bus mode supported by the part
|
||||||
|
status = _qspi.configure_format(_inst_width, _address_width, _address_size, _address_width, // Alt width should be the same as address width
|
||||||
|
_alt_size, _data_width, _dummy_cycles);
|
||||||
|
if (QSPI_STATUS_OK != status) {
|
||||||
|
tr_error("_qspi_configure_format failed");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't check the read status until after we've configured the format back to 1-1-1, to avoid leaving the interface in an
|
||||||
|
// incorrect state if the read fails.
|
||||||
|
status = _qspi.read(read_inst, (_alt_size == 0) ? -1 : QSPI_ALT_DEFAULT_VALUE, (unsigned int)addr, (char *)buffer, &buf_len);
|
||||||
|
|
||||||
|
// All commands other than Read and RSFDP use default 1-1-1 bus mode (Program/Erase are constrained by flash memory performance more than bus performance)
|
||||||
|
qspi_status_t format_status = _qspi.configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, _address_size, QSPI_CFG_BUS_SINGLE, 0, QSPI_CFG_BUS_SINGLE, 0);
|
||||||
|
if (QSPI_STATUS_OK != format_status) {
|
||||||
|
tr_error("_qspi_configure_format failed");
|
||||||
|
return format_status;
|
||||||
|
}
|
||||||
|
|
||||||
if (QSPI_STATUS_OK != status) {
|
if (QSPI_STATUS_OK != status) {
|
||||||
tr_error("QSPI Read failed");
|
tr_error("QSPI Read failed");
|
||||||
return status;
|
return status;
|
||||||
|
@ -1507,15 +1491,34 @@ qspi_status_t QSPIFBlockDevice::_qspi_send_general_command(qspi_inst_t instructi
|
||||||
return QSPI_STATUS_OK;
|
return QSPI_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
qspi_status_t QSPIFBlockDevice::_qspi_configure_format(qspi_bus_width_t inst_width, qspi_bus_width_t address_width,
|
qspi_status_t QSPIFBlockDevice::_qspi_send_read_sfdp_command(bd_addr_t addr, void *rx_buffer, bd_size_t rx_length)
|
||||||
qspi_address_size_t address_size, qspi_bus_width_t alt_width, qspi_alt_size_t alt_size, qspi_bus_width_t data_width,
|
|
||||||
int dummy_cycles)
|
|
||||||
{
|
{
|
||||||
// Configure QSPI driver Bus format
|
size_t rx_len = rx_length;
|
||||||
qspi_status_t status = _qspi.configure_format(inst_width, address_width, address_size, alt_width, alt_size, data_width,
|
|
||||||
dummy_cycles);
|
|
||||||
|
|
||||||
return status;
|
// SFDP read instruction requires 1-1-1 bus mode with 8 dummy cycles and a 3-byte address
|
||||||
|
qspi_status_t status = _qspi.configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE, 0, QSPI_CFG_BUS_SINGLE, QSPIF_RSFDP_DUMMY_CYCLES);
|
||||||
|
if (QSPI_STATUS_OK != status) {
|
||||||
|
tr_error("_qspi_configure_format failed");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't check the read status until after we've configured the format back to 1-1-1, to avoid leaving the interface in an
|
||||||
|
// incorrect state if the read fails.
|
||||||
|
status = _qspi.read(QSPIF_INST_RSFDP, -1, (unsigned int) addr, (char *) rx_buffer, &rx_len);
|
||||||
|
|
||||||
|
qspi_status_t format_status = _qspi.configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, _address_size, QSPI_CFG_BUS_SINGLE, 0, QSPI_CFG_BUS_SINGLE, 0);
|
||||||
|
// All commands other than Read and RSFDP use default 1-1-1 bus mode (Program/Erase are constrained by flash memory performance more than bus performance)
|
||||||
|
if (QSPI_STATUS_OK != format_status) {
|
||||||
|
tr_error("_qspi_configure_format failed");
|
||||||
|
return format_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QSPI_STATUS_OK != status) {
|
||||||
|
tr_error("Sending SFDP read instruction");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QSPI_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
qspi_status_t QSPIFBlockDevice::_qspi_read_status_registers(uint8_t *reg_buffer)
|
qspi_status_t QSPIFBlockDevice::_qspi_read_status_registers(uint8_t *reg_buffer)
|
||||||
|
|
|
@ -248,10 +248,8 @@ private:
|
||||||
qspi_status_t _qspi_send_general_command(mbed::qspi_inst_t instruction_int, mbed::bd_addr_t addr, const char *tx_buffer,
|
qspi_status_t _qspi_send_general_command(mbed::qspi_inst_t instruction_int, mbed::bd_addr_t addr, const char *tx_buffer,
|
||||||
mbed::bd_size_t tx_length, const char *rx_buffer, mbed::bd_size_t rx_length);
|
mbed::bd_size_t tx_length, const char *rx_buffer, mbed::bd_size_t rx_length);
|
||||||
|
|
||||||
// Send Bus configure_format command to Driver
|
// Send command to read from the SFDP table
|
||||||
qspi_status_t _qspi_configure_format(qspi_bus_width_t inst_width, qspi_bus_width_t address_width,
|
qspi_status_t _qspi_send_read_sfdp_command(mbed::bd_addr_t addr, void *rx_buffer, mbed::bd_size_t rx_length);
|
||||||
qspi_address_size_t address_size, qspi_bus_width_t alt_width, qspi_alt_size_t alt_size, qspi_bus_width_t data_width,
|
|
||||||
int dummy_cycles);
|
|
||||||
|
|
||||||
// Read the contents of status registers 1 and 2 into a buffer (buffer must have a length of 2)
|
// Read the contents of status registers 1 and 2 into a buffer (buffer must have a length of 2)
|
||||||
qspi_status_t _qspi_read_status_registers(uint8_t *reg_buffer);
|
qspi_status_t _qspi_read_status_registers(uint8_t *reg_buffer);
|
||||||
|
|
Loading…
Reference in New Issue