Move configuration of QSPI format to within commands where it is necessary

pull/11531/head
Matthew Macovsky 2019-08-30 03:00:52 -07:00 committed by Kyle Kearney
parent 08a0b3daeb
commit ba412734e1
2 changed files with 60 additions and 59 deletions

View File

@ -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)

View File

@ -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);