Skip to content
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

SFDP: Add support for multiple configurations and sector maps #14989

Merged
merged 12 commits into from
Sep 13, 2021
Merged
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
1 change: 1 addition & 0 deletions drivers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ target_sources(mbed-core
source/I2CSlave.cpp
source/InterruptIn.cpp
source/MbedCRC.cpp
source/OSPI.cpp
source/PortIn.cpp
source/PortInOut.cpp
source/PortOut.cpp
Expand Down
7 changes: 1 addition & 6 deletions drivers/include/drivers/QSPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,7 @@ class QSPI : private NonCopyable<QSPI> {
QSPI(const qspi_pinmap_t &pinmap, int mode = 0);
QSPI(const qspi_pinmap_t &&, int = 0) = delete; // prevent passing of temporary objects

virtual ~QSPI()
{
lock();
qspi_free(&_qspi);
unlock();
}
virtual ~QSPI();

/** Configure the data transmission format
*
Expand Down
7 changes: 7 additions & 0 deletions drivers/source/QSPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ QSPI::QSPI(const qspi_pinmap_t &pinmap, int mode) : _qspi()
MBED_ASSERT(success);
}

QSPI::~QSPI()
{
lock();
qspi_free(&_qspi);
unlock();
}

qspi_status_t QSPI::configure_format(qspi_bus_width_t inst_width, qspi_bus_width_t address_width, 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)
{
// Check that alt_size/alt_width are a valid combination
Expand Down
1 change: 1 addition & 0 deletions storage/blockdevice/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING)
if(BUILD_GREENTEA_TESTS)
# add greentea test
else()
add_subdirectory(COMPONENT_QSPIF)
add_subdirectory(tests/UNITTESTS)
endif()
endif()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,9 @@ class OSPIFBlockDevice : public mbed::BlockDevice {
mbed::bd_size_t tx_length, const char *rx_buffer, mbed::bd_size_t rx_length);

// Send command to read from the SFDP table
int _ospi_send_read_sfdp_command(mbed::bd_addr_t addr, void *rx_buffer, mbed::bd_size_t rx_length);
int _ospi_send_read_sfdp_command(mbed::bd_addr_t addr, mbed::sfdp_cmd_addr_size_t addr_size,
Patater marked this conversation as resolved.
Show resolved Hide resolved
uint8_t inst, uint8_t dummy_cycles,
void *rx_buffer, mbed::bd_size_t rx_length);

// Read the contents of status registers 1 and 2 into a buffer (buffer must have a length of 2)
ospi_status_t _ospi_read_status_registers(uint8_t *reg_buffer);
Expand Down Expand Up @@ -366,11 +368,11 @@ class OSPIFBlockDevice : public mbed::BlockDevice {
/* SFDP Detection and Parsing Functions */
/****************************************/
// Parse and Detect required Basic Parameters from Table
int _sfdp_parse_basic_param_table(mbed::Callback<int(mbed::bd_addr_t, void *, mbed::bd_size_t)> sfdp_reader,
int _sfdp_parse_basic_param_table(mbed::Callback<int(mbed::bd_addr_t, mbed::sfdp_cmd_addr_size_t, uint8_t, uint8_t, void *, mbed::bd_size_t)> sfdp_reader,
mbed::sfdp_hdr_info &sfdp_info);

// Parse and Detect 4-Byte Address Instruction Parameters from Table
int _sfdp_parse_4_byte_inst_table(mbed::Callback<int(mbed::bd_addr_t, void *, mbed::bd_size_t)> sfdp_reader,
int _sfdp_parse_4_byte_inst_table(mbed::Callback<int(mbed::bd_addr_t, mbed::sfdp_cmd_addr_size_t, uint8_t, uint8_t, void *, mbed::bd_size_t)> sfdp_reader,
mbed::sfdp_hdr_info &sfdp_info);

// Detect the soft reset protocol and reset - returns error if soft reset is not supported
Expand Down
57 changes: 49 additions & 8 deletions storage/blockdevice/COMPONENT_OSPIF/source/OSPIFBlockDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -921,12 +921,19 @@ int OSPIFBlockDevice::remove_csel_instance(PinName csel)
/*********************************************************/
/********** SFDP Parsing and Detection Functions *********/
/*********************************************************/
int OSPIFBlockDevice::_sfdp_parse_basic_param_table(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader,
int OSPIFBlockDevice::_sfdp_parse_basic_param_table(Callback<int(bd_addr_t, mbed::sfdp_cmd_addr_size_t, uint8_t, uint8_t, void *, bd_size_t)> sfdp_reader,
sfdp_hdr_info &sfdp_info)
{
uint8_t param_table[SFDP_BASIC_PARAMS_TBL_SIZE]; /* Up To 20 DWORDS = 80 Bytes */

int status = sfdp_reader(sfdp_info.bptbl.addr, param_table, sfdp_info.bptbl.size);
int status = sfdp_reader(
sfdp_info.bptbl.addr,
SFDP_READ_CMD_ADDR_TYPE,
SFDP_READ_CMD_INST,
SFDP_READ_CMD_DUMMY_CYCLES,
param_table,
sfdp_info.bptbl.size
);
if (status != OSPI_STATUS_OK) {
tr_error("Init - Read SFDP First Table Failed");
return -1;
Expand Down Expand Up @@ -1383,12 +1390,19 @@ int OSPIFBlockDevice::_sfdp_detect_reset_protocol_and_reset(uint8_t *basic_param
return status;
}

int OSPIFBlockDevice::_sfdp_parse_4_byte_inst_table(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader,
int OSPIFBlockDevice::_sfdp_parse_4_byte_inst_table(Callback<int(mbed::bd_addr_t, mbed::sfdp_cmd_addr_size_t, uint8_t, uint8_t, void *, mbed::bd_size_t)> sfdp_reader,
sfdp_hdr_info &sfdp_info)
{
uint8_t four_byte_inst_table[SFDP_DEFAULT_4_BYTE_INST_TABLE_SIZE_BYTES]; /* Up To 2 DWORDS = 8 Bytes */

int status = sfdp_reader(sfdp_info.fbatbl.addr, four_byte_inst_table, sfdp_info.fbatbl.size);
int status = sfdp_reader(
sfdp_info.fbatbl.addr,
SFDP_READ_CMD_ADDR_TYPE,
SFDP_READ_CMD_INST,
SFDP_READ_CMD_DUMMY_CYCLES,
four_byte_inst_table,
sfdp_info.fbatbl.size
);
if (status != OSPI_STATUS_OK) {
tr_error("Init - Read SFDP Four Byte Inst Table Failed");
return -1;
Expand Down Expand Up @@ -1823,21 +1837,48 @@ ospi_status_t OSPIFBlockDevice::_ospi_send_general_command(ospi_inst_t instructi
return OSPI_STATUS_OK;
}

int OSPIFBlockDevice::_ospi_send_read_sfdp_command(bd_addr_t addr, void *rx_buffer, bd_size_t rx_length)
int OSPIFBlockDevice::_ospi_send_read_sfdp_command(mbed::bd_addr_t addr, mbed::sfdp_cmd_addr_size_t addr_size,
uint8_t inst, uint8_t dummy_cycles,
void *rx_buffer, mbed::bd_size_t rx_length)
{
size_t rx_len = rx_length;
uint8_t *rx_buffer_tmp = (uint8_t *)rx_buffer;

// Set default here to avoid uninitialized variable warning
ospi_address_size_t address_size = _address_size;
int address = addr;
switch (addr_size) {
case SFDP_CMD_ADDR_3_BYTE:
address_size = OSPI_CFG_ADDR_SIZE_24;
break;
case SFDP_CMD_ADDR_4_BYTE:
address_size = OSPI_CFG_ADDR_SIZE_32;
break;
case SFDP_CMD_ADDR_SIZE_VARIABLE: // use current setting
break;
case SFDP_CMD_ADDR_NONE: // no address in command
address = static_cast<int>(OSPI_NO_ADDRESS_COMMAND);
break;
default:
tr_error("Invalid SFDP command address size: 0x%02X", addr_size);
return -1;
}

if (dummy_cycles == SFDP_CMD_DUMMY_CYCLES_VARIABLE) {
// use current setting
dummy_cycles = _dummy_cycles;
}

// SFDP read instruction requires 1-1-1 bus mode with 8 dummy cycles and a 3-byte address
ospi_status_t status = _ospi.configure_format(OSPI_CFG_BUS_SINGLE, OSPI_CFG_INST_SIZE_8, OSPI_CFG_BUS_SINGLE, OSPI_CFG_ADDR_SIZE_24, OSPI_CFG_BUS_SINGLE, 0, OSPI_CFG_BUS_SINGLE, OSPIF_RSFDP_DUMMY_CYCLES);
ospi_status_t status = _ospi.configure_format(OSPI_CFG_BUS_SINGLE, OSPI_CFG_INST_SIZE_8, OSPI_CFG_BUS_SINGLE, address_size, OSPI_CFG_BUS_SINGLE, 0, OSPI_CFG_BUS_SINGLE, dummy_cycles);
if (OSPI_STATUS_OK != status) {
tr_error("_ospi_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 = _ospi.read(OSPIF_INST_RSFDP, -1, (unsigned int) addr, (char *) rx_buffer, &rx_len);
size_t rx_len = rx_length;
status = _ospi.read(inst, -1, address, static_cast<char *>(rx_buffer), &rx_len);

ospi_status_t format_status = _ospi.configure_format(OSPI_CFG_BUS_SINGLE, OSPI_CFG_INST_SIZE_8, OSPI_CFG_BUS_SINGLE, _address_size, OSPI_CFG_BUS_SINGLE, 0, OSPI_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)
Expand Down
4 changes: 4 additions & 0 deletions storage/blockdevice/COMPONENT_QSPIF/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ target_sources(mbed-storage-qspif
INTERFACE
source/QSPIFBlockDevice.cpp
)

if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING)
add_subdirectory(UNITTESTS)
endif()
1 change: 1 addition & 0 deletions storage/blockdevice/COMPONENT_QSPIF/UNITTESTS/.mbedignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*
39 changes: 39 additions & 0 deletions storage/blockdevice/COMPONENT_QSPIF/UNITTESTS/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright (c) 2021 Arm Limited. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

include(GoogleTest)

add_executable(qspif-unittest)

target_compile_definitions(qspif-unittest
PRIVATE
DEVICE_QSPI=1
MBED_CONF_QSPIF_QSPI_MIN_READ_SIZE=1
MBED_CONF_QSPIF_QSPI_MIN_PROG_SIZE=1
)

target_include_directories(qspif-unittest
PRIVATE
${mbed-os_SOURCE_DIR}/storage/blockdevice/COMPONENT_QSPIF/include
)

target_sources(qspif-unittest
PRIVATE
${mbed-os_SOURCE_DIR}/storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp
test_QSPIFBlockDevice.cpp
)

target_link_libraries(qspif-unittest
PRIVATE
mbed-headers-blockdevice
mbed-headers-drivers
mbed-headers-platform
mbed-headers-rtos
mbed-stubs-blockdevice
mbed-stubs-platform
mbed-stubs-drivers
mbed-stubs-rtos
gmock_main
)

gtest_discover_tests(qspif-unittest PROPERTIES LABELS "storage")
Loading