Skip to content

Commit 6bd3933

Browse files
author
Veijo Pesonen
committed
Q/SPIFBlockDevice: Separates SFDP Header retrieval
Separates SFDP header retrieval and moves it as a part of the earlier introduced SFDP file. Purpose is to abstract away differences between SPIF and QSPIF devices when it comes to fetching the SFDP headers from a device.
1 parent aa59941 commit 6bd3933

File tree

6 files changed

+100
-102
lines changed

6 files changed

+100
-102
lines changed

components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.cpp

+5-49
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
#include "drivers/internal/SFDP.h"
18+
#include "platform/Callback.h"
1819
#include "QSPIFBlockDevice.h"
1920
#include <string.h>
2021
#include "rtos/ThisThread.h"
@@ -628,59 +629,14 @@ int QSPIFBlockDevice::remove_csel_instance(PinName csel)
628629
/*********************************************************/
629630
int QSPIFBlockDevice::_sfdp_parse_sfdp_headers(mbed::sfdp_hdr_info &hdr_info)
630631
{
631-
bd_addr_t addr = 0x0;
632-
int number_of_param_headers = 0;
633-
size_t data_length;
634-
635-
{
636-
data_length = SFDP_HEADER_SIZE;
637-
uint8_t sfdp_header[SFDP_HEADER_SIZE];
638-
639-
qspi_status_t status = _qspi_send_read_sfdp_command(addr, (char *)sfdp_header, data_length);
640-
if (status != QSPI_STATUS_OK) {
641-
tr_error("init - Retrieving SFDP Header failed");
642-
return -1;
643-
}
644-
645-
number_of_param_headers = sfdp_parse_sfdp_header((sfdp_hdr *)sfdp_header);
646-
if (number_of_param_headers < 0) {
647-
return number_of_param_headers;
648-
}
649-
}
650-
651-
addr += SFDP_HEADER_SIZE;
652-
653-
{
654-
data_length = SFDP_HEADER_SIZE;
655-
uint8_t param_header[SFDP_HEADER_SIZE];
656-
qspi_status_t status;
657-
int hdr_status;
658-
659-
// Loop over Param Headers and parse them (currently supports Basic Param Table and Sector Region Map Table)
660-
for (int i_ind = 0; i_ind < number_of_param_headers; i_ind++) {
661-
status = _qspi_send_read_sfdp_command(addr, (char *)param_header, data_length);
662-
if (status != QSPI_STATUS_OK) {
663-
tr_error("init - Retrieving Parameter Header %d failed", i_ind + 1);
664-
return -1;
665-
}
666-
667-
hdr_status = sfdp_parse_single_param_header((sfdp_prm_hdr *)param_header, hdr_info);
668-
if (hdr_status < 0) {
669-
return hdr_status;
670-
}
671-
672-
addr += SFDP_HEADER_SIZE;
673-
}
674-
}
675-
676-
return 0;
632+
return sfdp_parse_headers(callback(this, &QSPIFBlockDevice::_qspi_send_read_sfdp_command), hdr_info);
677633
}
678634

679635
int QSPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, size_t basic_table_size)
680636
{
681637
uint8_t param_table[SFDP_DEFAULT_BASIC_PARAMS_TABLE_SIZE_BYTES]; /* Up To 16 DWORDS = 64 Bytes */
682638

683-
qspi_status_t status = _qspi_send_read_sfdp_command(basic_table_addr, (char *) param_table, basic_table_size);
639+
int status = _qspi_send_read_sfdp_command(basic_table_addr, (char *)param_table, basic_table_size);
684640
if (status != QSPI_STATUS_OK) {
685641
tr_error("Init - Read SFDP First Table Failed");
686642
return -1;
@@ -1161,7 +1117,7 @@ int QSPIFBlockDevice::_sfdp_parse_sector_map_table(uint32_t sector_map_table_add
11611117
// Default set to all type bits 1-4 are common
11621118
int min_common_erase_type_bits = ERASE_BITMASK_ALL;
11631119

1164-
qspi_status_t status = _qspi_send_read_sfdp_command(sector_map_table_addr, (char *) sector_map_table, sector_map_table_size);
1120+
int status = _qspi_send_read_sfdp_command(sector_map_table_addr, (char *)sector_map_table, sector_map_table_size);
11651121
if (status != QSPI_STATUS_OK) {
11661122
tr_error("Init - Read SFDP First Table Failed");
11671123
return -1;
@@ -1604,7 +1560,7 @@ qspi_status_t QSPIFBlockDevice::_qspi_send_general_command(qspi_inst_t instructi
16041560
return QSPI_STATUS_OK;
16051561
}
16061562

1607-
qspi_status_t QSPIFBlockDevice::_qspi_send_read_sfdp_command(bd_addr_t addr, void *rx_buffer, bd_size_t rx_length)
1563+
int QSPIFBlockDevice::_qspi_send_read_sfdp_command(bd_addr_t addr, void *rx_buffer, bd_size_t rx_length)
16081564
{
16091565
size_t rx_len = rx_length;
16101566

components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "drivers/QSPI.h"
2020
#include "drivers/internal/SFDP.h"
2121
#include "features/storage/blockdevice/BlockDevice.h"
22+
#include "platform/Callback.h"
2223

2324
#ifndef MBED_CONF_QSPIF_QSPI_IO0
2425
#define MBED_CONF_QSPIF_QSPI_IO0 NC
@@ -249,6 +250,11 @@ class QSPIFBlockDevice : public mbed::BlockDevice {
249250
virtual const char *get_type() const;
250251

251252
private:
253+
254+
// SFDP helpers
255+
friend int mbed::sfdp_parse_headers(mbed::Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader,
256+
mbed::sfdp_hdr_info &hdr_info);
257+
252258
// Internal functions
253259

254260

@@ -280,7 +286,7 @@ class QSPIFBlockDevice : public mbed::BlockDevice {
280286
mbed::bd_size_t tx_length, const char *rx_buffer, mbed::bd_size_t rx_length);
281287

282288
// Send command to read from the SFDP table
283-
qspi_status_t _qspi_send_read_sfdp_command(mbed::bd_addr_t addr, void *rx_buffer, mbed::bd_size_t rx_length);
289+
int _qspi_send_read_sfdp_command(mbed::bd_addr_t addr, void *rx_buffer, mbed::bd_size_t rx_length);
284290

285291
// Read the contents of status registers 1 and 2 into a buffer (buffer must have a length of 2)
286292
qspi_status_t _qspi_read_status_registers(uint8_t *reg_buffer);

components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp

+16-51
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,21 @@ spif_bd_error SPIFBlockDevice::_spi_send_read_command(int read_inst, uint8_t *bu
528528
return SPIF_BD_ERROR_OK;
529529
}
530530

531+
int SPIFBlockDevice::_spi_send_read_sfdp_command(bd_addr_t addr, void *rx_buffer, bd_size_t rx_length)
532+
{
533+
// Set 1-1-1 bus mode for SFDP header parsing
534+
// Initial SFDP read tables are read with 8 dummy cycles
535+
_read_dummy_and_mode_cycles = 8;
536+
_dummy_and_mode_cycles = 8;
537+
538+
int status = _spi_send_read_command(SPIF_SFDP, (uint8_t *)rx_buffer, addr, rx_length);
539+
if (status < 0) {
540+
tr_error("_spi_send_read_sfdp_command failed");
541+
}
542+
543+
return status;
544+
}
545+
531546
spif_bd_error SPIFBlockDevice::_spi_send_program_command(int prog_inst, const void *buffer, bd_addr_t addr,
532547
bd_size_t size)
533548
{
@@ -716,57 +731,7 @@ int SPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, si
716731

717732
int SPIFBlockDevice::_sfdp_parse_sfdp_headers(sfdp_hdr_info &hdr_info)
718733
{
719-
bd_addr_t addr = 0x0;
720-
int number_of_param_headers = 0;
721-
size_t data_length;
722-
723-
{
724-
data_length = SFDP_HEADER_SIZE;
725-
uint8_t sfdp_header[SFDP_HEADER_SIZE];
726-
727-
// Set 1-1-1 bus mode for SFDP header parsing
728-
// Initial SFDP read tables are read with 8 dummy cycles
729-
_read_dummy_and_mode_cycles = 8;
730-
_dummy_and_mode_cycles = 8;
731-
732-
spif_bd_error status = _spi_send_read_command(SPIF_SFDP, sfdp_header, addr /*address*/, data_length);
733-
if (status != SPIF_BD_ERROR_OK) {
734-
tr_error("init - Read SFDP Failed");
735-
return -1;
736-
}
737-
738-
number_of_param_headers = sfdp_parse_sfdp_header((sfdp_hdr *)sfdp_header);
739-
if (number_of_param_headers < 0) {
740-
return number_of_param_headers;
741-
}
742-
}
743-
744-
addr += SFDP_HEADER_SIZE;
745-
746-
{
747-
data_length = SFDP_HEADER_SIZE;
748-
uint8_t param_header[SFDP_HEADER_SIZE];
749-
spif_bd_error status;
750-
int hdr_status;
751-
752-
// Loop over Param Headers and parse them (currently supported Basic Param Table and Sector Region Map Table)
753-
for (int i_ind = 0; i_ind < number_of_param_headers; i_ind++) {
754-
755-
status = _spi_send_read_command(SPIF_SFDP, param_header, addr, data_length);
756-
if (status != SPIF_BD_ERROR_OK) {
757-
tr_error("init - Read Param Table %d Failed", i_ind + 1);
758-
return -1;
759-
}
760-
761-
hdr_status = sfdp_parse_single_param_header((sfdp_prm_hdr *)param_header, hdr_info);
762-
if (hdr_status < 0) {
763-
return hdr_status;
764-
}
765-
766-
addr += SFDP_HEADER_SIZE;
767-
}
768-
}
769-
return 0;
734+
return sfdp_parse_headers(callback(this, &SPIFBlockDevice::_spi_send_read_sfdp_command), hdr_info);
770735
}
771736

772737
unsigned int SPIFBlockDevice::_sfdp_detect_page_size(uint8_t *basic_param_table_ptr, int basic_param_table_size)

components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.h

+8
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,9 @@ class SPIFBlockDevice : public mbed::BlockDevice {
225225
/****************************************/
226226
/* SFDP Detection and Parsing Functions */
227227
/****************************************/
228+
// Send SFDP Read command to Driver
229+
int _spi_send_read_sfdp_command(mbed::bd_addr_t addr, void *rx_buffer, mbed::bd_size_t rx_length);
230+
228231
// Parse SFDP Headers and retrieve Basic Param and Sector Map Tables (if exist)
229232
int _sfdp_parse_sfdp_headers(mbed::sfdp_hdr_info &hdr_info);
230233

@@ -301,6 +304,11 @@ class SPIFBlockDevice : public mbed::BlockDevice {
301304
int _erase_instruction;
302305
int _erase4k_inst; // Legacy 4K erase instruction (default 0x20h)
303306

307+
// SFDP helpers
308+
friend int mbed::sfdp_parse_headers(mbed::Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader,
309+
mbed::sfdp_hdr_info &hdr_info);
310+
311+
304312
// Up To 4 Erase Types are supported by SFDP (each with its own command Instruction and Size)
305313
int _erase_type_inst_arr[MAX_NUM_OF_ERASE_TYPES];
306314
unsigned int _erase_type_size_arr[MAX_NUM_OF_ERASE_TYPES];

drivers/internal/SFDP.h

+13-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
#include <cstddef>
2222
#include <cstdint>
23+
#include "features/storage/blockdevice/BlockDevice.h"
24+
#include "platform/Callback.h"
2325

2426
namespace mbed {
2527

@@ -61,12 +63,22 @@ struct sfdp_prm_hdr {
6163
*/
6264
int sfdp_parse_sfdp_header(sfdp_hdr *sfdp_hdr_ptr);
6365

64-
/** Parse Parameter Headers
66+
/** Parse Parameter Header
6567
* @param parameter_header Pointer to memory holding a single SFDP Parameter header
6668
* @param hdr_info Reference to a Parameter Table structure where info about the table is written
6769
* @return 0 on success, -1 on failure
6870
*/
6971
int sfdp_parse_single_param_header(sfdp_prm_hdr *parameter_header, sfdp_hdr_info &hdr_info);
7072

73+
/** Parse SFDP Headers
74+
* Retrieves SFDP headers from a device and parses the information contained by the headers
75+
*
76+
* @param sfdp_reader Callback function used to read headers from a device
77+
* @param hdr_info All information parsed from the headers gets passed back on this structure
78+
*
79+
* @return 0 on success, negative error code on failure
80+
*/
81+
int sfdp_parse_headers(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader, sfdp_hdr_info &hdr_info);
82+
7183
} /* namespace mbed */
7284
#endif

drivers/source/SFDP.cpp

+51
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,56 @@ int sfdp_parse_single_param_header(sfdp_prm_hdr *phdr, sfdp_hdr_info &hdr_info)
8383

8484
return 0;
8585
}
86+
87+
int sfdp_parse_headers(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader, sfdp_hdr_info &hdr_info)
88+
{
89+
bd_addr_t addr = 0x0;
90+
int number_of_param_headers = 0;
91+
size_t data_length;
92+
93+
{
94+
data_length = SFDP_HEADER_SIZE;
95+
uint8_t sfdp_header[SFDP_HEADER_SIZE];
96+
97+
int status = sfdp_reader(addr, sfdp_header, data_length);
98+
if (status < 0) {
99+
tr_error("retrieving SFDP Header failed");
100+
return -1;
101+
}
102+
103+
number_of_param_headers = sfdp_parse_sfdp_header((sfdp_hdr *)sfdp_header);
104+
if (number_of_param_headers < 0) {
105+
return number_of_param_headers;
106+
}
107+
}
108+
109+
addr += SFDP_HEADER_SIZE;
110+
111+
{
112+
data_length = SFDP_HEADER_SIZE;
113+
uint8_t param_header[SFDP_HEADER_SIZE];
114+
int status;
115+
int hdr_status;
116+
117+
// Loop over Param Headers and parse them (currently supports Basic Param Table and Sector Region Map Table)
118+
for (int i_ind = 0; i_ind < number_of_param_headers; i_ind++) {
119+
status = sfdp_reader(addr, param_header, data_length);
120+
if (status < 0) {
121+
tr_error("retrieving Parameter Header %d failed", i_ind + 1);
122+
return -1;
123+
}
124+
125+
hdr_status = sfdp_parse_single_param_header((sfdp_prm_hdr *)param_header, hdr_info);
126+
if (hdr_status < 0) {
127+
return hdr_status;
128+
}
129+
130+
addr += SFDP_HEADER_SIZE;
131+
}
132+
}
133+
134+
return 0;
135+
}
136+
86137
} /* namespace mbed */
87138
#endif /* (DEVICE_SPI || DEVICE_QSPI) */

0 commit comments

Comments
 (0)