Skip to content

Commit 756830e

Browse files
authored
Merge pull request #14989 from LDong-Arm/sfdp_sector_maps_multi
SFDP: Add support for multiple configurations and sector maps
2 parents f96b930 + 9ade440 commit 756830e

File tree

18 files changed

+1142
-101
lines changed

18 files changed

+1142
-101
lines changed

drivers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ target_sources(mbed-core
3434
source/I2CSlave.cpp
3535
source/InterruptIn.cpp
3636
source/MbedCRC.cpp
37+
source/OSPI.cpp
3738
source/PortIn.cpp
3839
source/PortInOut.cpp
3940
source/PortOut.cpp

drivers/include/drivers/QSPI.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,7 @@ class QSPI : private NonCopyable<QSPI> {
115115
QSPI(const qspi_pinmap_t &pinmap, int mode = 0);
116116
QSPI(const qspi_pinmap_t &&, int = 0) = delete; // prevent passing of temporary objects
117117

118-
virtual ~QSPI()
119-
{
120-
lock();
121-
qspi_free(&_qspi);
122-
unlock();
123-
}
118+
virtual ~QSPI();
124119

125120
/** Configure the data transmission format
126121
*

drivers/source/QSPI.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ QSPI::QSPI(const qspi_pinmap_t &pinmap, int mode) : _qspi()
9292
MBED_ASSERT(success);
9393
}
9494

95+
QSPI::~QSPI()
96+
{
97+
lock();
98+
qspi_free(&_qspi);
99+
unlock();
100+
}
101+
95102
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)
96103
{
97104
// Check that alt_size/alt_width are a valid combination

storage/blockdevice/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING)
55
if(BUILD_GREENTEA_TESTS)
66
# add greentea test
77
else()
8+
add_subdirectory(COMPONENT_QSPIF)
89
add_subdirectory(tests/UNITTESTS)
910
endif()
1011
endif()

storage/blockdevice/COMPONENT_OSPIF/include/OSPIF/OSPIFBlockDevice.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,9 @@ class OSPIFBlockDevice : public mbed::BlockDevice {
327327
mbed::bd_size_t tx_length, const char *rx_buffer, mbed::bd_size_t rx_length);
328328

329329
// Send command to read from the SFDP table
330-
int _ospi_send_read_sfdp_command(mbed::bd_addr_t addr, void *rx_buffer, mbed::bd_size_t rx_length);
330+
int _ospi_send_read_sfdp_command(mbed::bd_addr_t addr, mbed::sfdp_cmd_addr_size_t addr_size,
331+
uint8_t inst, uint8_t dummy_cycles,
332+
void *rx_buffer, mbed::bd_size_t rx_length);
331333

332334
// Read the contents of status registers 1 and 2 into a buffer (buffer must have a length of 2)
333335
ospi_status_t _ospi_read_status_registers(uint8_t *reg_buffer);
@@ -366,11 +368,11 @@ class OSPIFBlockDevice : public mbed::BlockDevice {
366368
/* SFDP Detection and Parsing Functions */
367369
/****************************************/
368370
// Parse and Detect required Basic Parameters from Table
369-
int _sfdp_parse_basic_param_table(mbed::Callback<int(mbed::bd_addr_t, void *, mbed::bd_size_t)> sfdp_reader,
371+
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,
370372
mbed::sfdp_hdr_info &sfdp_info);
371373

372374
// Parse and Detect 4-Byte Address Instruction Parameters from Table
373-
int _sfdp_parse_4_byte_inst_table(mbed::Callback<int(mbed::bd_addr_t, void *, mbed::bd_size_t)> sfdp_reader,
375+
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,
374376
mbed::sfdp_hdr_info &sfdp_info);
375377

376378
// Detect the soft reset protocol and reset - returns error if soft reset is not supported

storage/blockdevice/COMPONENT_OSPIF/source/OSPIFBlockDevice.cpp

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -921,12 +921,19 @@ int OSPIFBlockDevice::remove_csel_instance(PinName csel)
921921
/*********************************************************/
922922
/********** SFDP Parsing and Detection Functions *********/
923923
/*********************************************************/
924-
int OSPIFBlockDevice::_sfdp_parse_basic_param_table(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader,
924+
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,
925925
sfdp_hdr_info &sfdp_info)
926926
{
927927
uint8_t param_table[SFDP_BASIC_PARAMS_TBL_SIZE]; /* Up To 20 DWORDS = 80 Bytes */
928928

929-
int status = sfdp_reader(sfdp_info.bptbl.addr, param_table, sfdp_info.bptbl.size);
929+
int status = sfdp_reader(
930+
sfdp_info.bptbl.addr,
931+
SFDP_READ_CMD_ADDR_TYPE,
932+
SFDP_READ_CMD_INST,
933+
SFDP_READ_CMD_DUMMY_CYCLES,
934+
param_table,
935+
sfdp_info.bptbl.size
936+
);
930937
if (status != OSPI_STATUS_OK) {
931938
tr_error("Init - Read SFDP First Table Failed");
932939
return -1;
@@ -1383,12 +1390,19 @@ int OSPIFBlockDevice::_sfdp_detect_reset_protocol_and_reset(uint8_t *basic_param
13831390
return status;
13841391
}
13851392

1386-
int OSPIFBlockDevice::_sfdp_parse_4_byte_inst_table(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader,
1393+
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,
13871394
sfdp_hdr_info &sfdp_info)
13881395
{
13891396
uint8_t four_byte_inst_table[SFDP_DEFAULT_4_BYTE_INST_TABLE_SIZE_BYTES]; /* Up To 2 DWORDS = 8 Bytes */
13901397

1391-
int status = sfdp_reader(sfdp_info.fbatbl.addr, four_byte_inst_table, sfdp_info.fbatbl.size);
1398+
int status = sfdp_reader(
1399+
sfdp_info.fbatbl.addr,
1400+
SFDP_READ_CMD_ADDR_TYPE,
1401+
SFDP_READ_CMD_INST,
1402+
SFDP_READ_CMD_DUMMY_CYCLES,
1403+
four_byte_inst_table,
1404+
sfdp_info.fbatbl.size
1405+
);
13921406
if (status != OSPI_STATUS_OK) {
13931407
tr_error("Init - Read SFDP Four Byte Inst Table Failed");
13941408
return -1;
@@ -1823,21 +1837,48 @@ ospi_status_t OSPIFBlockDevice::_ospi_send_general_command(ospi_inst_t instructi
18231837
return OSPI_STATUS_OK;
18241838
}
18251839

1826-
int OSPIFBlockDevice::_ospi_send_read_sfdp_command(bd_addr_t addr, void *rx_buffer, bd_size_t rx_length)
1840+
int OSPIFBlockDevice::_ospi_send_read_sfdp_command(mbed::bd_addr_t addr, mbed::sfdp_cmd_addr_size_t addr_size,
1841+
uint8_t inst, uint8_t dummy_cycles,
1842+
void *rx_buffer, mbed::bd_size_t rx_length)
18271843
{
1828-
size_t rx_len = rx_length;
18291844
uint8_t *rx_buffer_tmp = (uint8_t *)rx_buffer;
18301845

1846+
// Set default here to avoid uninitialized variable warning
1847+
ospi_address_size_t address_size = _address_size;
1848+
int address = addr;
1849+
switch (addr_size) {
1850+
case SFDP_CMD_ADDR_3_BYTE:
1851+
address_size = OSPI_CFG_ADDR_SIZE_24;
1852+
break;
1853+
case SFDP_CMD_ADDR_4_BYTE:
1854+
address_size = OSPI_CFG_ADDR_SIZE_32;
1855+
break;
1856+
case SFDP_CMD_ADDR_SIZE_VARIABLE: // use current setting
1857+
break;
1858+
case SFDP_CMD_ADDR_NONE: // no address in command
1859+
address = static_cast<int>(OSPI_NO_ADDRESS_COMMAND);
1860+
break;
1861+
default:
1862+
tr_error("Invalid SFDP command address size: 0x%02X", addr_size);
1863+
return -1;
1864+
}
1865+
1866+
if (dummy_cycles == SFDP_CMD_DUMMY_CYCLES_VARIABLE) {
1867+
// use current setting
1868+
dummy_cycles = _dummy_cycles;
1869+
}
1870+
18311871
// SFDP read instruction requires 1-1-1 bus mode with 8 dummy cycles and a 3-byte address
1832-
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);
1872+
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);
18331873
if (OSPI_STATUS_OK != status) {
18341874
tr_error("_ospi_configure_format failed");
18351875
return status;
18361876
}
18371877

18381878
// 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
18391879
// incorrect state if the read fails.
1840-
status = _ospi.read(OSPIF_INST_RSFDP, -1, (unsigned int) addr, (char *) rx_buffer, &rx_len);
1880+
size_t rx_len = rx_length;
1881+
status = _ospi.read(inst, -1, address, static_cast<char *>(rx_buffer), &rx_len);
18411882

18421883
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);
18431884
// 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)

storage/blockdevice/COMPONENT_QSPIF/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ target_sources(mbed-storage-qspif
1111
INTERFACE
1212
source/QSPIFBlockDevice.cpp
1313
)
14+
15+
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING)
16+
add_subdirectory(UNITTESTS)
17+
endif()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Copyright (c) 2021 Arm Limited. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
include(GoogleTest)
5+
6+
add_executable(qspif-unittest)
7+
8+
target_compile_definitions(qspif-unittest
9+
PRIVATE
10+
DEVICE_QSPI=1
11+
MBED_CONF_QSPIF_QSPI_MIN_READ_SIZE=1
12+
MBED_CONF_QSPIF_QSPI_MIN_PROG_SIZE=1
13+
)
14+
15+
target_include_directories(qspif-unittest
16+
PRIVATE
17+
${mbed-os_SOURCE_DIR}/storage/blockdevice/COMPONENT_QSPIF/include
18+
)
19+
20+
target_sources(qspif-unittest
21+
PRIVATE
22+
${mbed-os_SOURCE_DIR}/storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp
23+
test_QSPIFBlockDevice.cpp
24+
)
25+
26+
target_link_libraries(qspif-unittest
27+
PRIVATE
28+
mbed-headers-blockdevice
29+
mbed-headers-drivers
30+
mbed-headers-platform
31+
mbed-headers-rtos
32+
mbed-stubs-blockdevice
33+
mbed-stubs-platform
34+
mbed-stubs-drivers
35+
mbed-stubs-rtos
36+
gmock_main
37+
)
38+
39+
gtest_discover_tests(qspif-unittest PROPERTIES LABELS "storage")

0 commit comments

Comments
 (0)