@@ -32,7 +32,6 @@ using namespace mbed;
32
32
33
33
/* Default QSPIF Parameters */
34
34
/* ***************************/
35
- #define QSPIF_DEFAULT_PAGE_SIZE 256
36
35
#define QSPIF_DEFAULT_SE_SIZE 4096
37
36
// The SFDP spec only defines two status registers. But some devices,
38
37
// have three "status-like" registers (one status, two config)
@@ -63,20 +62,9 @@ using namespace mbed;
63
62
#define QSPIF_BASIC_PARAM_TABLE_222_READ_INST_BYTE 23
64
63
#define QSPIF_BASIC_PARAM_TABLE_122_READ_INST_BYTE 15
65
64
#define QSPIF_BASIC_PARAM_TABLE_112_READ_INST_BYTE 13
66
- #define QSPIF_BASIC_PARAM_TABLE_PAGE_SIZE_BYTE 40
67
65
// Quad Enable Params
68
66
#define QSPIF_BASIC_PARAM_TABLE_QER_BYTE 58
69
67
#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
80
68
81
69
#define QSPIF_BASIC_PARAM_TABLE_SOFT_RESET_BYTE 61
82
70
#define QSPIF_BASIC_PARAM_TABLE_4BYTE_ADDR_BYTE 63
@@ -112,7 +100,7 @@ using namespace mbed;
112
100
113
101
// Default read/legacy erase instructions
114
102
#define QSPIF_INST_READ_DEFAULT 0x03
115
- #define QSPIF_INST_LEGACY_ERASE_DEFAULT QSPI_NO_INST
103
+ #define QSPIF_INST_LEGACY_ERASE_DEFAULT (- 1 )
116
104
117
105
// Default status register 2 read/write instructions
118
106
#define QSPIF_INST_WSR2_DEFAULT QSPI_NO_INST
@@ -153,6 +141,7 @@ QSPIFBlockDevice::QSPIFBlockDevice(PinName io0, PinName io1, PinName io2, PinNam
153
141
}
154
142
155
143
// Initialize parameters
144
+ _sfdp_info.bptbl .legacy_erase_instruction = QSPIF_INST_LEGACY_ERASE_DEFAULT;
156
145
_sfdp_info.smptbl .regions_min_common_erase_size = 0 ;
157
146
_sfdp_info.smptbl .region_cnt = 1 ;
158
147
_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
172
161
173
162
// Set default read/erase instructions
174
163
_read_instruction = QSPIF_INST_READ_DEFAULT;
175
- _legacy_erase_instruction = QSPIF_INST_LEGACY_ERASE_DEFAULT;
176
164
177
165
_num_status_registers = QSPI_DEFAULT_STATUS_REGISTERS;
178
166
// Set default status register 2 write/read instructions
@@ -253,7 +241,8 @@ int QSPIFBlockDevice::init()
253
241
}
254
242
255
243
/* *************************** 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 ) {
257
246
tr_error (" Init - Parse Basic Param Table Failed" );
258
247
status = QSPIF_BD_ERROR_PARSING_FAILED;
259
248
goto exit_point;
@@ -429,7 +418,7 @@ int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
429
418
// For each iteration erase the largest section supported by current region
430
419
while (size > 0 ) {
431
420
unsigned int eu_size;
432
- if (_legacy_erase_instruction == QSPI_NO_INST) {
421
+ if (_sfdp_info. bptbl . legacy_erase_instruction == QSPI_NO_INST) {
433
422
// Iterate to find next largest erase type that is a) supported by region, and b) smaller than size.
434
423
// Find the matching instruction and erase size chunk for that type.
435
424
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)
439
428
eu_size = _sfdp_info.smptbl .erase_type_size_arr [type];
440
429
} else {
441
430
// Must use legacy 4k erase instruction
442
- cur_erase_inst = _legacy_erase_instruction ;
431
+ cur_erase_inst = _sfdp_info. bptbl . legacy_erase_instruction ;
443
432
eu_size = QSPIF_DEFAULT_SE_SIZE;
444
433
}
445
434
offset = addr % eu_size;
@@ -520,7 +509,7 @@ const char *QSPIFBlockDevice::get_type() const
520
509
bd_size_t QSPIFBlockDevice::get_erase_size (bd_addr_t addr)
521
510
{
522
511
// 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) {
524
513
return QSPIF_DEFAULT_SE_SIZE;
525
514
}
526
515
@@ -627,11 +616,12 @@ int QSPIFBlockDevice::remove_csel_instance(PinName csel)
627
616
/* ********************************************************/
628
617
/* ********* SFDP Parsing and Detection Functions *********/
629
618
/* ********************************************************/
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)
631
621
{
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 */
633
623
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 );
635
625
if (status != QSPI_STATUS_OK) {
636
626
tr_error (" Init - Read SFDP First Table Failed" );
637
627
return -1 ;
@@ -651,7 +641,7 @@ int QSPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, s
651
641
_device_size_bytes = (density_bits + 1 ) / 8 ;
652
642
653
643
// 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 );
655
645
656
646
if (_sfdp_detect_reset_protocol_and_reset (param_table) != QSPIF_BD_ERROR_OK) {
657
647
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
662
652
bool shouldSetQuadEnable = false ;
663
653
bool is_qpi_mode = false ;
664
654
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 ) {
666
656
tr_error (" Init - Detecting erase types instructions/sizes failed" );
667
657
return -1 ;
668
658
}
669
659
670
660
// 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);
672
662
if (true == shouldSetQuadEnable) {
673
663
if (_needs_fast_mode) {
674
664
_enable_fast_mode ();
@@ -688,7 +678,7 @@ int QSPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, s
688
678
#ifndef TARGET_NORDIC
689
679
// 4 byte addressing is not currently supported with the Nordic QSPI controller
690
680
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) {
692
682
tr_error (" Init - Detecting/enabling 4-byte addressing failed" );
693
683
return -1 ;
694
684
}
@@ -831,67 +821,6 @@ int QSPIFBlockDevice::_sfdp_set_qpi_enabled(uint8_t *basic_param_table_ptr)
831
821
return 0 ;
832
822
}
833
823
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
-
895
824
int QSPIFBlockDevice::_sfdp_detect_best_bus_read_mode (uint8_t *basic_param_table_ptr, int basic_param_table_size,
896
825
bool &set_quad_enable, bool &is_qpi_mode)
897
826
{
0 commit comments