SPIFBlockDevice: Refactor vendor specific workarounds

To follow the same convention as with QSPIFBlockDevice there was need to
create a separate function for handling vendor specific workarounds.
pull/12524/head
Veijo Pesonen 2020-02-19 15:43:26 +02:00
parent 98dbebb3ed
commit 7c692f5196
4 changed files with 38 additions and 21 deletions

View File

@ -226,7 +226,7 @@ int QSPIFBlockDevice::init()
goto exit_point; goto exit_point;
} }
if (0 != _handle_vendor_quirks()) { if (_handle_vendor_quirks() < 0) {
tr_error("Init - Could not read vendor id"); tr_error("Init - Could not read vendor id");
status = QSPIF_BD_ERROR_DEVICE_ERROR; status = QSPIF_BD_ERROR_DEVICE_ERROR;
goto exit_point; goto exit_point;

View File

@ -306,6 +306,9 @@ private:
// Enable Fast Mode - for flash chips with low power default // Enable Fast Mode - for flash chips with low power default
int _enable_fast_mode(); int _enable_fast_mode();
// Query vendor ID and handle special behavior that isn't covered by SFDP data
int _handle_vendor_quirks();
/****************************************/ /****************************************/
/* SFDP Detection and Parsing Functions */ /* SFDP Detection and Parsing Functions */
/****************************************/ /****************************************/
@ -329,9 +332,6 @@ private:
// Detect 4-byte addressing mode and enable it if supported // Detect 4-byte addressing mode and enable it if supported
int _sfdp_detect_and_enable_4byte_addressing(uint8_t *basic_param_table_ptr, int basic_param_table_size); int _sfdp_detect_and_enable_4byte_addressing(uint8_t *basic_param_table_ptr, int basic_param_table_size);
// Query vendor ID and handle special behavior that isn't covered by SFDP data
int _handle_vendor_quirks();
/***********************/ /***********************/
/* Utilities Functions */ /* Utilities Functions */
/***********************/ /***********************/

View File

@ -115,10 +115,7 @@ SPIFBlockDevice::SPIFBlockDevice(PinName mosi, PinName miso, PinName sclk, PinNa
int SPIFBlockDevice::init() int SPIFBlockDevice::init()
{ {
uint8_t vendor_device_ids[4];
size_t data_length = 3;
int status = SPIF_BD_ERROR_OK; int status = SPIF_BD_ERROR_OK;
spif_bd_error spi_status = SPIF_BD_ERROR_OK;
_mutex->lock(); _mutex->lock();
@ -141,24 +138,12 @@ int SPIFBlockDevice::init()
tr_debug("Initialize flash memory OK"); tr_debug("Initialize flash memory OK");
} }
/* Read Manufacturer ID (1byte), and Device ID (2bytes)*/ if (_handle_vendor_quirks() < 0) {
spi_status = _spi_send_general_command(SPIF_RDID, SPI_NO_ADDRESS_COMMAND, NULL, 0, (char *)vendor_device_ids, tr_error("Init - Could not read vendor id");
data_length);
if (spi_status != SPIF_BD_ERROR_OK) {
tr_error("init - Read Vendor ID Failed");
status = SPIF_BD_ERROR_DEVICE_ERROR; status = SPIF_BD_ERROR_DEVICE_ERROR;
goto exit_point; goto exit_point;
} }
switch (vendor_device_ids[0]) {
case 0xbf:
// SST devices come preset with block protection
// enabled for some regions, issue global protection unlock to clear
_set_write_enable();
_spi_send_general_command(SPIF_ULBPR, SPI_NO_ADDRESS_COMMAND, NULL, 0, NULL, 0);
break;
}
//Synchronize Device //Synchronize Device
if (false == _is_mem_ready()) { if (false == _is_mem_ready()) {
tr_error("init - _is_mem_ready Failed"); tr_error("init - _is_mem_ready Failed");
@ -764,3 +749,32 @@ int SPIFBlockDevice::_set_write_enable()
} while (false); } while (false);
return status; return status;
} }
int SPIFBlockDevice::_handle_vendor_quirks()
{
uint8_t vendor_device_ids[4];
size_t data_length = 3;
/* Read Manufacturer ID (1byte), and Device ID (2bytes)*/
spif_bd_error spi_status = _spi_send_general_command(SPIF_RDID, SPI_NO_ADDRESS_COMMAND, NULL, 0,
(char *)vendor_device_ids,
data_length);
if (spi_status != SPIF_BD_ERROR_OK) {
tr_error("Read Vendor ID Failed");
return -1;
}
tr_debug("Vendor device ID = 0x%x 0x%x 0x%x", vendor_device_ids[0], vendor_device_ids[1], vendor_device_ids[2]);
switch (vendor_device_ids[0]) {
case 0xbf:
// SST devices come preset with block protection
// enabled for some regions, issue global protection unlock to clear
_set_write_enable();
_spi_send_general_command(SPIF_ULBPR, SPI_NO_ADDRESS_COMMAND, NULL, 0, NULL, 0);
break;
}
return 0;
}

View File

@ -260,6 +260,9 @@ private:
// Wait on status register until write not-in-progress // Wait on status register until write not-in-progress
bool _is_mem_ready(); bool _is_mem_ready();
// Query vendor ID and handle special behavior that isn't covered by SFDP data
int _handle_vendor_quirks();
private: private:
// Master side hardware // Master side hardware
mbed::SPI _spi; mbed::SPI _spi;