@@ -115,15 +115,7 @@ SPIFBlockDevice::SPIFBlockDevice(PinName mosi, PinName miso, PinName sclk, PinNa
115115
116116int SPIFBlockDevice::init ()
117117{
118- uint8_t vendor_device_ids[4 ];
119- size_t data_length = 3 ;
120118 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 ;
127119
128120 _mutex->lock ();
129121
@@ -146,56 +138,39 @@ int SPIFBlockDevice::init()
146138 tr_debug (" Initialize flash memory OK" );
147139 }
148140
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" );
154143 status = SPIF_BD_ERROR_DEVICE_ERROR;
155144 goto exit_point;
156145 }
157146
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-
167147 // Synchronize Device
168148 if (false == _is_mem_ready ()) {
169149 tr_error (" init - _is_mem_ready Failed" );
170150 status = SPIF_BD_ERROR_READY_FAILED;
171151 goto exit_point;
172152 }
173153
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 ;
181160
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+ }
188166
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+ }
193172
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 ) {
199174 tr_error (" init - Parse Sector Map Table Failed" );
200175 status = SPIF_BD_ERROR_PARSING_FAILED;
201176 goto exit_point;
@@ -629,19 +604,15 @@ int SPIFBlockDevice::_sfdp_parse_basic_param_table(Callback<int(bd_addr_t, void
629604 }
630605
631606 // 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 " );
634609 return -1 ;
635610 }
636611
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+ }
645616
646617 // Set Default read/program/erase Instructions
647618 _read_instruction = SPIF_READ;
@@ -778,3 +749,32 @@ int SPIFBlockDevice::_set_write_enable()
778749 } while (false );
779750 return status;
780751}
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