@@ -115,15 +115,7 @@ SPIFBlockDevice::SPIFBlockDevice(PinName mosi, PinName miso, PinName sclk, PinNa
115
115
116
116
int SPIFBlockDevice::init ()
117
117
{
118
- uint8_t vendor_device_ids[4 ];
119
- size_t data_length = 3 ;
120
118
int status = SPIF_BD_ERROR_OK;
121
- spif_bd_error spi_status = SPIF_BD_ERROR_OK;
122
-
123
- _sfdp_info.bptbl .addr = 0x0 ;
124
- _sfdp_info.bptbl .size = 0 ;
125
- _sfdp_info.smptbl .addr = 0x0 ;
126
- _sfdp_info.smptbl .size = 0 ;
127
119
128
120
_mutex->lock ();
129
121
@@ -146,56 +138,39 @@ int SPIFBlockDevice::init()
146
138
tr_debug (" Initialize flash memory OK" );
147
139
}
148
140
149
- /* Read Manufacturer ID (1byte), and Device ID (2bytes)*/
150
- spi_status = _spi_send_general_command (SPIF_RDID, SPI_NO_ADDRESS_COMMAND, NULL , 0 , (char *)vendor_device_ids,
151
- data_length);
152
- if (spi_status != SPIF_BD_ERROR_OK) {
153
- tr_error (" init - Read Vendor ID Failed" );
141
+ if (_handle_vendor_quirks () < 0 ) {
142
+ tr_error (" Init - Could not read vendor id" );
154
143
status = SPIF_BD_ERROR_DEVICE_ERROR;
155
144
goto exit_point;
156
145
}
157
146
158
- switch (vendor_device_ids[0 ]) {
159
- case 0xbf :
160
- // SST devices come preset with block protection
161
- // enabled for some regions, issue global protection unlock to clear
162
- _set_write_enable ();
163
- _spi_send_general_command (SPIF_ULBPR, SPI_NO_ADDRESS_COMMAND, NULL , 0 , NULL , 0 );
164
- break ;
165
- }
166
-
167
147
// Synchronize Device
168
148
if (false == _is_mem_ready ()) {
169
149
tr_error (" init - _is_mem_ready Failed" );
170
150
status = SPIF_BD_ERROR_READY_FAILED;
171
151
goto exit_point;
172
152
}
173
153
174
- /* *************************** Parse SFDP Header ***********************************/
175
- if (sfdp_parse_headers (callback (this , &SPIFBlockDevice::_spi_send_read_sfdp_command), _sfdp_info) < 0 ) {
176
- tr_error (" init - Parse SFDP Headers Failed" );
177
- status = SPIF_BD_ERROR_PARSING_FAILED;
178
- goto exit_point;
179
- }
180
-
154
+ /* *************************** Parse SFDP headers and tables ***********************************/
155
+ {
156
+ _sfdp_info.bptbl .addr = 0x0 ;
157
+ _sfdp_info.bptbl .size = 0 ;
158
+ _sfdp_info.smptbl .addr = 0x0 ;
159
+ _sfdp_info.smptbl .size = 0 ;
181
160
182
- /* *************************** Parse Basic Parameters Table ***********************************/
183
- if (_sfdp_parse_basic_param_table (callback (this , &SPIFBlockDevice::_spi_send_read_sfdp_command), _sfdp_info) < 0 ) {
184
- tr_error (" init - Parse Basic Param Table Failed" );
185
- status = SPIF_BD_ERROR_PARSING_FAILED;
186
- goto exit_point;
187
- }
161
+ if (sfdp_parse_headers (callback (this , &SPIFBlockDevice::_spi_send_read_sfdp_command), _sfdp_info) < 0 ) {
162
+ tr_error (" init - Parse SFDP Headers Failed" );
163
+ status = SPIF_BD_ERROR_PARSING_FAILED;
164
+ goto exit_point;
165
+ }
188
166
189
- /* *************************** Parse Sector Map Table ***********************************/
190
- _sfdp_info.smptbl .region_size [0 ] = _sfdp_info.bptbl .device_size_bytes ;
191
- // If there's no region map, we have a single region sized the entire device size
192
- _sfdp_info.smptbl .region_high_boundary [0 ] = _sfdp_info.bptbl .device_size_bytes - 1 ;
167
+ if (_sfdp_parse_basic_param_table (callback (this , &SPIFBlockDevice::_spi_send_read_sfdp_command), _sfdp_info) < 0 ) {
168
+ tr_error (" init - Parse Basic Param Table Failed" );
169
+ status = SPIF_BD_ERROR_PARSING_FAILED;
170
+ goto exit_point;
171
+ }
193
172
194
- if ((_sfdp_info.smptbl .addr != 0 ) && (0 != _sfdp_info.smptbl .size )) {
195
- tr_debug (" init - Parsing Sector Map Table - addr: 0x%" PRIx32 " h, Size: %d" , _sfdp_info.smptbl .addr ,
196
- _sfdp_info.smptbl .size );
197
- if (sfdp_parse_sector_map_table (callback (this , &SPIFBlockDevice::_spi_send_read_sfdp_command),
198
- _sfdp_info.smptbl ) < 0 ) {
173
+ if (sfdp_parse_sector_map_table (callback (this , &SPIFBlockDevice::_spi_send_read_sfdp_command), _sfdp_info) < 0 ) {
199
174
tr_error (" init - Parse Sector Map Table Failed" );
200
175
status = SPIF_BD_ERROR_PARSING_FAILED;
201
176
goto exit_point;
@@ -629,19 +604,15 @@ int SPIFBlockDevice::_sfdp_parse_basic_param_table(Callback<int(bd_addr_t, void
629
604
}
630
605
631
606
// Check address size, currently only supports 3byte addresses
632
- if ((param_table[ 2 ] & 0x4 ) != 0 || (param_table[ 7 ] & 0x80 ) != 0 ) {
633
- tr_error (" init - verify 3byte addressing Failed " );
607
+ if (sfdp_detect_addressability (param_table, _sfdp_info. bptbl ) < 0 ) {
608
+ tr_error (" Verify 3byte addressing failed " );
634
609
return -1 ;
635
610
}
636
611
637
- // Get device density (stored in bits - 1)
638
- uint32_t density_bits = (
639
- (param_table[7 ] << 24 ) |
640
- (param_table[6 ] << 16 ) |
641
- (param_table[5 ] << 8 ) |
642
- param_table[4 ]);
643
- sfdp_info.bptbl .device_size_bytes = (density_bits + 1 ) / 8 ;
644
- tr_debug (" Density bits: %" PRIu32 " , device size: %llu bytes" , density_bits, sfdp_info.bptbl .device_size_bytes );
612
+ if (sfdp_detect_device_density (param_table, _sfdp_info.bptbl ) < 0 ) {
613
+ tr_error (" Detecting device density failed" );
614
+ return -1 ;
615
+ }
645
616
646
617
// Set Default read/program/erase Instructions
647
618
_read_instruction = SPIF_READ;
@@ -778,3 +749,32 @@ int SPIFBlockDevice::_set_write_enable()
778
749
} while (false );
779
750
return status;
780
751
}
752
+
753
+ int SPIFBlockDevice::_handle_vendor_quirks ()
754
+ {
755
+ uint8_t vendor_device_ids[4 ];
756
+ size_t data_length = 3 ;
757
+
758
+ /* Read Manufacturer ID (1byte), and Device ID (2bytes)*/
759
+ spif_bd_error spi_status = _spi_send_general_command (SPIF_RDID, SPI_NO_ADDRESS_COMMAND, NULL , 0 ,
760
+ (char *)vendor_device_ids,
761
+ data_length);
762
+
763
+ if (spi_status != SPIF_BD_ERROR_OK) {
764
+ tr_error (" Read Vendor ID Failed" );
765
+ return -1 ;
766
+ }
767
+
768
+ tr_debug (" Vendor device ID = 0x%x 0x%x 0x%x" , vendor_device_ids[0 ], vendor_device_ids[1 ], vendor_device_ids[2 ]);
769
+
770
+ switch (vendor_device_ids[0 ]) {
771
+ case 0xbf :
772
+ // SST devices come preset with block protection
773
+ // enabled for some regions, issue global protection unlock to clear
774
+ _set_write_enable ();
775
+ _spi_send_general_command (SPIF_ULBPR, SPI_NO_ADDRESS_COMMAND, NULL , 0 , NULL , 0 );
776
+ break ;
777
+ }
778
+
779
+ return 0 ;
780
+ }
0 commit comments