mirror of https://github.com/ARMmbed/mbed-os.git
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.pull/12270/head
parent
aa599412e6
commit
6bd3933652
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "drivers/internal/SFDP.h"
|
||||
#include "platform/Callback.h"
|
||||
#include "QSPIFBlockDevice.h"
|
||||
#include <string.h>
|
||||
#include "rtos/ThisThread.h"
|
||||
|
@ -628,59 +629,14 @@ int QSPIFBlockDevice::remove_csel_instance(PinName csel)
|
|||
/*********************************************************/
|
||||
int QSPIFBlockDevice::_sfdp_parse_sfdp_headers(mbed::sfdp_hdr_info &hdr_info)
|
||||
{
|
||||
bd_addr_t addr = 0x0;
|
||||
int number_of_param_headers = 0;
|
||||
size_t data_length;
|
||||
|
||||
{
|
||||
data_length = SFDP_HEADER_SIZE;
|
||||
uint8_t sfdp_header[SFDP_HEADER_SIZE];
|
||||
|
||||
qspi_status_t status = _qspi_send_read_sfdp_command(addr, (char *)sfdp_header, data_length);
|
||||
if (status != QSPI_STATUS_OK) {
|
||||
tr_error("init - Retrieving SFDP Header failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
number_of_param_headers = sfdp_parse_sfdp_header((sfdp_hdr *)sfdp_header);
|
||||
if (number_of_param_headers < 0) {
|
||||
return number_of_param_headers;
|
||||
}
|
||||
}
|
||||
|
||||
addr += SFDP_HEADER_SIZE;
|
||||
|
||||
{
|
||||
data_length = SFDP_HEADER_SIZE;
|
||||
uint8_t param_header[SFDP_HEADER_SIZE];
|
||||
qspi_status_t status;
|
||||
int hdr_status;
|
||||
|
||||
// Loop over Param Headers and parse them (currently supports Basic Param Table and Sector Region Map Table)
|
||||
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);
|
||||
if (status != QSPI_STATUS_OK) {
|
||||
tr_error("init - Retrieving Parameter Header %d failed", i_ind + 1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
hdr_status = sfdp_parse_single_param_header((sfdp_prm_hdr *)param_header, hdr_info);
|
||||
if (hdr_status < 0) {
|
||||
return hdr_status;
|
||||
}
|
||||
|
||||
addr += SFDP_HEADER_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return sfdp_parse_headers(callback(this, &QSPIFBlockDevice::_qspi_send_read_sfdp_command), hdr_info);
|
||||
}
|
||||
|
||||
int QSPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, size_t basic_table_size)
|
||||
{
|
||||
uint8_t param_table[SFDP_DEFAULT_BASIC_PARAMS_TABLE_SIZE_BYTES]; /* Up To 16 DWORDS = 64 Bytes */
|
||||
|
||||
qspi_status_t status = _qspi_send_read_sfdp_command(basic_table_addr, (char *) param_table, basic_table_size);
|
||||
int status = _qspi_send_read_sfdp_command(basic_table_addr, (char *)param_table, basic_table_size);
|
||||
if (status != QSPI_STATUS_OK) {
|
||||
tr_error("Init - Read SFDP First Table Failed");
|
||||
return -1;
|
||||
|
@ -1161,7 +1117,7 @@ int QSPIFBlockDevice::_sfdp_parse_sector_map_table(uint32_t sector_map_table_add
|
|||
// Default set to all type bits 1-4 are common
|
||||
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);
|
||||
int status = _qspi_send_read_sfdp_command(sector_map_table_addr, (char *)sector_map_table, sector_map_table_size);
|
||||
if (status != QSPI_STATUS_OK) {
|
||||
tr_error("Init - Read SFDP First Table Failed");
|
||||
return -1;
|
||||
|
@ -1604,7 +1560,7 @@ qspi_status_t QSPIFBlockDevice::_qspi_send_general_command(qspi_inst_t instructi
|
|||
return QSPI_STATUS_OK;
|
||||
}
|
||||
|
||||
qspi_status_t QSPIFBlockDevice::_qspi_send_read_sfdp_command(bd_addr_t addr, void *rx_buffer, bd_size_t rx_length)
|
||||
int QSPIFBlockDevice::_qspi_send_read_sfdp_command(bd_addr_t addr, void *rx_buffer, bd_size_t rx_length)
|
||||
{
|
||||
size_t rx_len = rx_length;
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "drivers/QSPI.h"
|
||||
#include "drivers/internal/SFDP.h"
|
||||
#include "features/storage/blockdevice/BlockDevice.h"
|
||||
#include "platform/Callback.h"
|
||||
|
||||
#ifndef MBED_CONF_QSPIF_QSPI_IO0
|
||||
#define MBED_CONF_QSPIF_QSPI_IO0 NC
|
||||
|
@ -249,6 +250,11 @@ public:
|
|||
virtual const char *get_type() const;
|
||||
|
||||
private:
|
||||
|
||||
// SFDP helpers
|
||||
friend int mbed::sfdp_parse_headers(mbed::Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader,
|
||||
mbed::sfdp_hdr_info &hdr_info);
|
||||
|
||||
// Internal functions
|
||||
|
||||
|
||||
|
@ -280,7 +286,7 @@ private:
|
|||
mbed::bd_size_t tx_length, const char *rx_buffer, mbed::bd_size_t rx_length);
|
||||
|
||||
// Send command to read from the SFDP table
|
||||
qspi_status_t _qspi_send_read_sfdp_command(mbed::bd_addr_t addr, void *rx_buffer, mbed::bd_size_t rx_length);
|
||||
int _qspi_send_read_sfdp_command(mbed::bd_addr_t addr, 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)
|
||||
qspi_status_t _qspi_read_status_registers(uint8_t *reg_buffer);
|
||||
|
|
|
@ -528,6 +528,21 @@ spif_bd_error SPIFBlockDevice::_spi_send_read_command(int read_inst, uint8_t *bu
|
|||
return SPIF_BD_ERROR_OK;
|
||||
}
|
||||
|
||||
int SPIFBlockDevice::_spi_send_read_sfdp_command(bd_addr_t addr, void *rx_buffer, bd_size_t rx_length)
|
||||
{
|
||||
// Set 1-1-1 bus mode for SFDP header parsing
|
||||
// Initial SFDP read tables are read with 8 dummy cycles
|
||||
_read_dummy_and_mode_cycles = 8;
|
||||
_dummy_and_mode_cycles = 8;
|
||||
|
||||
int status = _spi_send_read_command(SPIF_SFDP, (uint8_t *)rx_buffer, addr, rx_length);
|
||||
if (status < 0) {
|
||||
tr_error("_spi_send_read_sfdp_command failed");
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
spif_bd_error SPIFBlockDevice::_spi_send_program_command(int prog_inst, const void *buffer, bd_addr_t addr,
|
||||
bd_size_t size)
|
||||
{
|
||||
|
@ -716,57 +731,7 @@ int SPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, si
|
|||
|
||||
int SPIFBlockDevice::_sfdp_parse_sfdp_headers(sfdp_hdr_info &hdr_info)
|
||||
{
|
||||
bd_addr_t addr = 0x0;
|
||||
int number_of_param_headers = 0;
|
||||
size_t data_length;
|
||||
|
||||
{
|
||||
data_length = SFDP_HEADER_SIZE;
|
||||
uint8_t sfdp_header[SFDP_HEADER_SIZE];
|
||||
|
||||
// Set 1-1-1 bus mode for SFDP header parsing
|
||||
// Initial SFDP read tables are read with 8 dummy cycles
|
||||
_read_dummy_and_mode_cycles = 8;
|
||||
_dummy_and_mode_cycles = 8;
|
||||
|
||||
spif_bd_error status = _spi_send_read_command(SPIF_SFDP, sfdp_header, addr /*address*/, data_length);
|
||||
if (status != SPIF_BD_ERROR_OK) {
|
||||
tr_error("init - Read SFDP Failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
number_of_param_headers = sfdp_parse_sfdp_header((sfdp_hdr *)sfdp_header);
|
||||
if (number_of_param_headers < 0) {
|
||||
return number_of_param_headers;
|
||||
}
|
||||
}
|
||||
|
||||
addr += SFDP_HEADER_SIZE;
|
||||
|
||||
{
|
||||
data_length = SFDP_HEADER_SIZE;
|
||||
uint8_t param_header[SFDP_HEADER_SIZE];
|
||||
spif_bd_error status;
|
||||
int hdr_status;
|
||||
|
||||
// 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++) {
|
||||
|
||||
status = _spi_send_read_command(SPIF_SFDP, param_header, addr, data_length);
|
||||
if (status != SPIF_BD_ERROR_OK) {
|
||||
tr_error("init - Read Param Table %d Failed", i_ind + 1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
hdr_status = sfdp_parse_single_param_header((sfdp_prm_hdr *)param_header, hdr_info);
|
||||
if (hdr_status < 0) {
|
||||
return hdr_status;
|
||||
}
|
||||
|
||||
addr += SFDP_HEADER_SIZE;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return sfdp_parse_headers(callback(this, &SPIFBlockDevice::_spi_send_read_sfdp_command), hdr_info);
|
||||
}
|
||||
|
||||
unsigned int SPIFBlockDevice::_sfdp_detect_page_size(uint8_t *basic_param_table_ptr, int basic_param_table_size)
|
||||
|
|
|
@ -225,6 +225,9 @@ private:
|
|||
/****************************************/
|
||||
/* SFDP Detection and Parsing Functions */
|
||||
/****************************************/
|
||||
// Send SFDP Read command to Driver
|
||||
int _spi_send_read_sfdp_command(mbed::bd_addr_t addr, void *rx_buffer, mbed::bd_size_t rx_length);
|
||||
|
||||
// Parse SFDP Headers and retrieve Basic Param and Sector Map Tables (if exist)
|
||||
int _sfdp_parse_sfdp_headers(mbed::sfdp_hdr_info &hdr_info);
|
||||
|
||||
|
@ -301,6 +304,11 @@ private:
|
|||
int _erase_instruction;
|
||||
int _erase4k_inst; // Legacy 4K erase instruction (default 0x20h)
|
||||
|
||||
// SFDP helpers
|
||||
friend int mbed::sfdp_parse_headers(mbed::Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader,
|
||||
mbed::sfdp_hdr_info &hdr_info);
|
||||
|
||||
|
||||
// Up To 4 Erase Types are supported by SFDP (each with its own command Instruction and Size)
|
||||
int _erase_type_inst_arr[MAX_NUM_OF_ERASE_TYPES];
|
||||
unsigned int _erase_type_size_arr[MAX_NUM_OF_ERASE_TYPES];
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include "features/storage/blockdevice/BlockDevice.h"
|
||||
#include "platform/Callback.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
|
@ -61,12 +63,22 @@ struct sfdp_prm_hdr {
|
|||
*/
|
||||
int sfdp_parse_sfdp_header(sfdp_hdr *sfdp_hdr_ptr);
|
||||
|
||||
/** Parse Parameter Headers
|
||||
/** Parse Parameter Header
|
||||
* @param parameter_header Pointer to memory holding a single SFDP Parameter header
|
||||
* @param hdr_info Reference to a Parameter Table structure where info about the table is written
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int sfdp_parse_single_param_header(sfdp_prm_hdr *parameter_header, sfdp_hdr_info &hdr_info);
|
||||
|
||||
/** Parse SFDP Headers
|
||||
* Retrieves SFDP headers from a device and parses the information contained by the headers
|
||||
*
|
||||
* @param sfdp_reader Callback function used to read headers from a device
|
||||
* @param hdr_info All information parsed from the headers gets passed back on this structure
|
||||
*
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
int sfdp_parse_headers(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader, sfdp_hdr_info &hdr_info);
|
||||
|
||||
} /* namespace mbed */
|
||||
#endif
|
||||
|
|
|
@ -83,5 +83,56 @@ int sfdp_parse_single_param_header(sfdp_prm_hdr *phdr, sfdp_hdr_info &hdr_info)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sfdp_parse_headers(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader, sfdp_hdr_info &hdr_info)
|
||||
{
|
||||
bd_addr_t addr = 0x0;
|
||||
int number_of_param_headers = 0;
|
||||
size_t data_length;
|
||||
|
||||
{
|
||||
data_length = SFDP_HEADER_SIZE;
|
||||
uint8_t sfdp_header[SFDP_HEADER_SIZE];
|
||||
|
||||
int status = sfdp_reader(addr, sfdp_header, data_length);
|
||||
if (status < 0) {
|
||||
tr_error("retrieving SFDP Header failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
number_of_param_headers = sfdp_parse_sfdp_header((sfdp_hdr *)sfdp_header);
|
||||
if (number_of_param_headers < 0) {
|
||||
return number_of_param_headers;
|
||||
}
|
||||
}
|
||||
|
||||
addr += SFDP_HEADER_SIZE;
|
||||
|
||||
{
|
||||
data_length = SFDP_HEADER_SIZE;
|
||||
uint8_t param_header[SFDP_HEADER_SIZE];
|
||||
int status;
|
||||
int hdr_status;
|
||||
|
||||
// Loop over Param Headers and parse them (currently supports Basic Param Table and Sector Region Map Table)
|
||||
for (int i_ind = 0; i_ind < number_of_param_headers; i_ind++) {
|
||||
status = sfdp_reader(addr, param_header, data_length);
|
||||
if (status < 0) {
|
||||
tr_error("retrieving Parameter Header %d failed", i_ind + 1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
hdr_status = sfdp_parse_single_param_header((sfdp_prm_hdr *)param_header, hdr_info);
|
||||
if (hdr_status < 0) {
|
||||
return hdr_status;
|
||||
}
|
||||
|
||||
addr += SFDP_HEADER_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} /* namespace mbed */
|
||||
#endif /* (DEVICE_SPI || DEVICE_QSPI) */
|
||||
|
|
Loading…
Reference in New Issue