@@ -32,7 +32,6 @@ using namespace mbed;
3232
3333/* Default QSPIF Parameters */
3434/* ***************************/
35- #define QSPIF_DEFAULT_PAGE_SIZE 256
3635#define QSPIF_DEFAULT_SE_SIZE 4096
3736// The SFDP spec only defines two status registers. But some devices,
3837// have three "status-like" registers (one status, two config)
@@ -63,20 +62,9 @@ using namespace mbed;
6362#define QSPIF_BASIC_PARAM_TABLE_222_READ_INST_BYTE 23
6463#define QSPIF_BASIC_PARAM_TABLE_122_READ_INST_BYTE 15
6564#define QSPIF_BASIC_PARAM_TABLE_112_READ_INST_BYTE 13
66- #define QSPIF_BASIC_PARAM_TABLE_PAGE_SIZE_BYTE 40
6765// Quad Enable Params
6866#define QSPIF_BASIC_PARAM_TABLE_QER_BYTE 58
6967#define QSPIF_BASIC_PARAM_TABLE_444_MODE_EN_SEQ_BYTE 56
70- // Erase Types Params
71- #define QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE 29
72- #define QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_2_BYTE 31
73- #define QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_3_BYTE 33
74- #define QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_4_BYTE 35
75- #define QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE 28
76- #define QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_2_SIZE_BYTE 30
77- #define QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_3_SIZE_BYTE 32
78- #define QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_4_SIZE_BYTE 34
79- #define QSPIF_BASIC_PARAM_4K_ERASE_TYPE_BYTE 1
8068
8169#define QSPIF_BASIC_PARAM_TABLE_SOFT_RESET_BYTE 61
8270#define QSPIF_BASIC_PARAM_TABLE_4BYTE_ADDR_BYTE 63
@@ -112,7 +100,7 @@ using namespace mbed;
112100
113101// Default read/legacy erase instructions
114102#define QSPIF_INST_READ_DEFAULT 0x03
115- #define QSPIF_INST_LEGACY_ERASE_DEFAULT QSPI_NO_INST
103+ #define QSPIF_INST_LEGACY_ERASE_DEFAULT (- 1 )
116104
117105// Default status register 2 read/write instructions
118106#define QSPIF_INST_WSR2_DEFAULT QSPI_NO_INST
@@ -153,6 +141,7 @@ QSPIFBlockDevice::QSPIFBlockDevice(PinName io0, PinName io1, PinName io2, PinNam
153141 }
154142
155143 // Initialize parameters
144+ _sfdp_info.bptbl .legacy_erase_instruction = QSPIF_INST_LEGACY_ERASE_DEFAULT;
156145 _sfdp_info.smptbl .regions_min_common_erase_size = 0 ;
157146 _sfdp_info.smptbl .region_cnt = 1 ;
158147 _sfdp_info.smptbl .region_erase_types_bitfld [0 ] = SFDP_ERASE_BITMASK_NONE;
@@ -172,7 +161,6 @@ QSPIFBlockDevice::QSPIFBlockDevice(PinName io0, PinName io1, PinName io2, PinNam
172161
173162 // Set default read/erase instructions
174163 _read_instruction = QSPIF_INST_READ_DEFAULT;
175- _legacy_erase_instruction = QSPIF_INST_LEGACY_ERASE_DEFAULT;
176164
177165 _num_status_registers = QSPI_DEFAULT_STATUS_REGISTERS;
178166 // Set default status register 2 write/read instructions
@@ -253,7 +241,8 @@ int QSPIFBlockDevice::init()
253241 }
254242
255243 /* *************************** Parse Basic Parameters Table ***********************************/
256- if (0 != _sfdp_parse_basic_param_table (_sfdp_info.bptbl .addr , _sfdp_info.bptbl .size )) {
244+ if (_sfdp_parse_basic_param_table (callback (this , &QSPIFBlockDevice::_qspi_send_read_sfdp_command),
245+ _sfdp_info) < 0 ) {
257246 tr_error (" Init - Parse Basic Param Table Failed" );
258247 status = QSPIF_BD_ERROR_PARSING_FAILED;
259248 goto exit_point;
@@ -429,7 +418,7 @@ int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
429418 // For each iteration erase the largest section supported by current region
430419 while (size > 0 ) {
431420 unsigned int eu_size;
432- if (_legacy_erase_instruction == QSPI_NO_INST) {
421+ if (_sfdp_info. bptbl . legacy_erase_instruction == QSPI_NO_INST) {
433422 // Iterate to find next largest erase type that is a) supported by region, and b) smaller than size.
434423 // Find the matching instruction and erase size chunk for that type.
435424 type = _utils_iterate_next_largest_erase_type (bitfield, size, (int )addr,
@@ -439,7 +428,7 @@ int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
439428 eu_size = _sfdp_info.smptbl .erase_type_size_arr [type];
440429 } else {
441430 // Must use legacy 4k erase instruction
442- cur_erase_inst = _legacy_erase_instruction ;
431+ cur_erase_inst = _sfdp_info. bptbl . legacy_erase_instruction ;
443432 eu_size = QSPIF_DEFAULT_SE_SIZE;
444433 }
445434 offset = addr % eu_size;
@@ -520,7 +509,7 @@ const char *QSPIFBlockDevice::get_type() const
520509bd_size_t QSPIFBlockDevice::get_erase_size (bd_addr_t addr)
521510{
522511 // If the legacy erase instruction is in use, the erase size is uniformly 4k
523- if (_legacy_erase_instruction != QSPI_NO_INST) {
512+ if (_sfdp_info. bptbl . legacy_erase_instruction != QSPI_NO_INST) {
524513 return QSPIF_DEFAULT_SE_SIZE;
525514 }
526515
@@ -627,11 +616,12 @@ int QSPIFBlockDevice::remove_csel_instance(PinName csel)
627616/* ********************************************************/
628617/* ********* SFDP Parsing and Detection Functions *********/
629618/* ********************************************************/
630- int QSPIFBlockDevice::_sfdp_parse_basic_param_table (uint32_t basic_table_addr, size_t basic_table_size)
619+ int QSPIFBlockDevice::_sfdp_parse_basic_param_table (Callback<int (bd_addr_t , void *, bd_size_t )> sfdp_reader,
620+ sfdp_hdr_info &sfdp_info)
631621{
632- uint8_t param_table[SFDP_BASIC_PARAMS_TBL_SIZE]; /* Up To 16 DWORDS = 64 Bytes */
622+ uint8_t param_table[SFDP_BASIC_PARAMS_TBL_SIZE]; /* Up To 20 DWORDS = 80 Bytes */
633623
634- int status = _qspi_send_read_sfdp_command (basic_table_addr, ( char *) param_table, basic_table_size );
624+ int status = sfdp_reader (sfdp_info. bptbl . addr , param_table, sfdp_info. bptbl . size );
635625 if (status != QSPI_STATUS_OK) {
636626 tr_error (" Init - Read SFDP First Table Failed" );
637627 return -1 ;
@@ -651,7 +641,7 @@ int QSPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, s
651641 _device_size_bytes = (density_bits + 1 ) / 8 ;
652642
653643 // Set Page Size (QSPI write must be done on Page limits)
654- _page_size_bytes = _sfdp_detect_page_size (param_table, basic_table_size );
644+ _page_size_bytes = sfdp_detect_page_size (param_table, sfdp_info. bptbl . size );
655645
656646 if (_sfdp_detect_reset_protocol_and_reset (param_table) != QSPIF_BD_ERROR_OK) {
657647 tr_error (" Init - Detecting reset protocol/resetting failed" );
@@ -662,13 +652,13 @@ int QSPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, s
662652 bool shouldSetQuadEnable = false ;
663653 bool is_qpi_mode = false ;
664654
665- if (_sfdp_detect_erase_types_inst_and_size (param_table, basic_table_size, _sfdp_info. smptbl ) != 0 ) {
655+ if (sfdp_detect_erase_types_inst_and_size (param_table, _sfdp_info) < 0 ) {
666656 tr_error (" Init - Detecting erase types instructions/sizes failed" );
667657 return -1 ;
668658 }
669659
670660 // Detect and Set fastest Bus mode (default 1-1-1)
671- _sfdp_detect_best_bus_read_mode (param_table, basic_table_size , shouldSetQuadEnable, is_qpi_mode);
661+ _sfdp_detect_best_bus_read_mode (param_table, sfdp_info. bptbl . size , shouldSetQuadEnable, is_qpi_mode);
672662 if (true == shouldSetQuadEnable) {
673663 if (_needs_fast_mode) {
674664 _enable_fast_mode ();
@@ -688,7 +678,7 @@ int QSPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, s
688678#ifndef TARGET_NORDIC
689679 // 4 byte addressing is not currently supported with the Nordic QSPI controller
690680 if (_attempt_4_byte_addressing) {
691- if (_sfdp_detect_and_enable_4byte_addressing (param_table, basic_table_size ) != QSPIF_BD_ERROR_OK) {
681+ if (_sfdp_detect_and_enable_4byte_addressing (param_table, sfdp_info. bptbl . size ) != QSPIF_BD_ERROR_OK) {
692682 tr_error (" Init - Detecting/enabling 4-byte addressing failed" );
693683 return -1 ;
694684 }
@@ -831,67 +821,6 @@ int QSPIFBlockDevice::_sfdp_set_qpi_enabled(uint8_t *basic_param_table_ptr)
831821 return 0 ;
832822}
833823
834- int QSPIFBlockDevice::_sfdp_detect_page_size (uint8_t *basic_param_table_ptr, int basic_param_table_size)
835- {
836- unsigned int page_size = QSPIF_DEFAULT_PAGE_SIZE;
837-
838- if (basic_param_table_size > QSPIF_BASIC_PARAM_TABLE_PAGE_SIZE_BYTE) {
839- // Page Size is specified by 4 Bits (N), calculated by 2^N
840- int page_to_power_size = ((int )basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_PAGE_SIZE_BYTE]) >> 4 ;
841- page_size = 1 << page_to_power_size;
842- tr_debug (" Detected Page Size: %d" , page_size);
843- } else {
844- tr_debug (" Using Default Page Size: %d" , page_size);
845- }
846- return page_size;
847- }
848-
849- int QSPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size (uint8_t *basic_param_table_ptr,
850- int basic_param_table_size,
851- sfdp_smptbl_info &smptbl)
852- {
853- uint8_t bitfield = 0x01 ;
854-
855- // Erase 4K Inst is taken either from param table legacy 4K erase or superseded by erase Instruction for type of size 4K
856- if (basic_param_table_size > QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE) {
857- // Loop Erase Types 1-4
858- for (int i_ind = 0 ; i_ind < 4 ; i_ind++) {
859- smptbl.erase_type_inst_arr [i_ind] = QSPI_NO_INST; // Default for unsupported type
860- smptbl.erase_type_size_arr [i_ind] = 1
861- << basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE + 2 * i_ind]; // Size is 2^N where N is the table value
862- tr_debug (" Erase Type(A) %d - Inst: 0x%xh, Size: %d" , (i_ind + 1 ), smptbl.erase_type_inst_arr [i_ind],
863- smptbl.erase_type_size_arr [i_ind]);
864- if (smptbl.erase_type_size_arr [i_ind] > 1 ) {
865- // if size==1 type is not supported
866- smptbl.erase_type_inst_arr [i_ind] = basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE
867- + 2 * i_ind];
868-
869- if ((smptbl.erase_type_size_arr [i_ind] < smptbl.regions_min_common_erase_size )
870- || (smptbl.regions_min_common_erase_size == 0 )) {
871- // Set default minimal common erase for signal region
872- smptbl.regions_min_common_erase_size = smptbl.erase_type_size_arr [i_ind];
873- }
874- smptbl.region_erase_types_bitfld [0 ] |= bitfield; // If there's no region map, set region "0" types bitfield as default
875- }
876-
877- tr_debug (" Erase Type %d - Inst: 0x%xh, Size: %d" , (i_ind + 1 ), smptbl.erase_type_inst_arr [i_ind],
878- smptbl.erase_type_size_arr [i_ind]);
879- bitfield = bitfield << 1 ;
880- }
881- } else {
882- tr_debug (" SFDP erase types are not available - falling back to legacy 4k erase instruction" );
883-
884- // 0xFF indicates that the legacy 4k erase instruction is not supported
885- _legacy_erase_instruction = basic_param_table_ptr[QSPIF_BASIC_PARAM_4K_ERASE_TYPE_BYTE];
886- if (_legacy_erase_instruction == 0xFF ) {
887- tr_error (" _detectEraseTypesInstAndSize - Legacy 4k erase instruction not supported" );
888- return -1 ;
889- }
890- }
891-
892- return 0 ;
893- }
894-
895824int QSPIFBlockDevice::_sfdp_detect_best_bus_read_mode (uint8_t *basic_param_table_ptr, int basic_param_table_size,
896825 bool &set_quad_enable, bool &is_qpi_mode)
897826{
0 commit comments