spiFlash: moved BP status, unlock step into a dedicatedmethod
This commit is contained in:
parent
a7e4303563
commit
4a593c258c
|
|
@ -86,7 +86,8 @@
|
||||||
|
|
||||||
SPIFlash::SPIFlash(SPIInterface *spi, bool unprotect, int8_t verbose):
|
SPIFlash::SPIFlash(SPIInterface *spi, bool unprotect, int8_t verbose):
|
||||||
_spi(spi), _verbose(verbose), _jedec_id(0),
|
_spi(spi), _verbose(verbose), _jedec_id(0),
|
||||||
_flash_model(NULL), _unprotect(unprotect)
|
_flash_model(NULL), _unprotect(unprotect), _must_relock(false),
|
||||||
|
_status(0)
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
power_up();
|
power_up();
|
||||||
|
|
@ -365,23 +366,23 @@ bool SPIFlash::dump(const std::string &filename, const int &base_addr,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SPIFlash::erase_and_prog(int base_addr, const uint8_t *data, int len)
|
bool SPIFlash::prepare_flash(const int base_addr, const int len)
|
||||||
{
|
{
|
||||||
|
/* If flash not already detected: do that here */
|
||||||
if (_jedec_id == 0) {
|
if (_jedec_id == 0) {
|
||||||
try {
|
try {
|
||||||
read_id();
|
read_id();
|
||||||
} catch(std::exception &e) {
|
} catch(std::exception &e) {
|
||||||
printError(e.what());
|
printError(e.what());
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool must_relock = false; // used to relock after write;
|
|
||||||
|
|
||||||
/* check Block Protect Bits (hide WIP/WEN bits) */
|
/* check Block Protect Bits (hide WIP/WEN bits) */
|
||||||
uint8_t status = read_status_reg() & ~0x03;
|
_status = read_status_reg() & ~0x03;
|
||||||
if (_verbose > 0)
|
if (_verbose > 0)
|
||||||
display_status_reg(status);
|
display_status_reg(_status);
|
||||||
|
|
||||||
/* if known chip */
|
/* if known chip */
|
||||||
if (_flash_model) {
|
if (_flash_model) {
|
||||||
/* microchip SST26VF032B/64B have global lock set
|
/* microchip SST26VF032B/64B have global lock set
|
||||||
|
|
@ -390,23 +391,23 @@ int SPIFlash::erase_and_prog(int base_addr, const uint8_t *data, int len)
|
||||||
*/
|
*/
|
||||||
if (_flash_model->global_lock) {
|
if (_flash_model->global_lock) {
|
||||||
if (!global_unlock())
|
if (!global_unlock())
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if offset + len fit in flash */
|
/* check if offset + len fit in flash */
|
||||||
if ((unsigned int)(base_addr + len) > (_flash_model->nr_sector * 0x10000)) {
|
if ((unsigned int)(base_addr + len) > (_flash_model->nr_sector * 0x10000)) {
|
||||||
printError("flash overflow");
|
printError("flash overflow");
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
// if device has block protect
|
// if device has block protect
|
||||||
if (_flash_model->bp_len != 0) {
|
if (_flash_model->bp_len != 0) {
|
||||||
/* compute protected area */
|
/* compute protected area */
|
||||||
int8_t tb = get_tb();
|
int8_t tb = get_tb();
|
||||||
if (tb == -1)
|
if (tb == -1)
|
||||||
return -1;
|
return false;
|
||||||
std::map<std::string, uint32_t> lock_len = bp_to_len(status, tb);
|
std::map<std::string, uint32_t> lock_len = bp_to_len(_status, tb);
|
||||||
printf("%08x %08x %08x %02x\n", base_addr,
|
printf("%08x %08x %08x %02x\n", base_addr,
|
||||||
lock_len["start"], lock_len["end"], status);
|
lock_len["start"], lock_len["end"], _status);
|
||||||
|
|
||||||
/* if some blocks are locked */
|
/* if some blocks are locked */
|
||||||
if (lock_len["start"] != 0 || lock_len["end"] != 0) {
|
if (lock_len["start"] != 0 || lock_len["end"] != 0) {
|
||||||
|
|
@ -414,10 +415,10 @@ int SPIFlash::erase_and_prog(int base_addr, const uint8_t *data, int len)
|
||||||
if (tb == 1) { // bottom blocks are protected
|
if (tb == 1) { // bottom blocks are protected
|
||||||
// check if start is in protected blocks
|
// check if start is in protected blocks
|
||||||
if ((uint32_t)base_addr <= lock_len["end"])
|
if ((uint32_t)base_addr <= lock_len["end"])
|
||||||
must_relock = true;
|
_must_relock = true;
|
||||||
} else { // top blocks
|
} else { // top blocks
|
||||||
if ((uint32_t)(base_addr + len) >= lock_len["start"])
|
if ((uint32_t)(base_addr + len) >= lock_len["start"])
|
||||||
must_relock = true;
|
_must_relock = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* ISSI IS25LP032 seems have a bug:
|
/* ISSI IS25LP032 seems have a bug:
|
||||||
|
|
@ -426,7 +427,7 @@ int SPIFlash::erase_and_prog(int base_addr, const uint8_t *data, int len)
|
||||||
*/
|
*/
|
||||||
if ((_jedec_id >> 8) == 0x9d6016 && tb == 1 && base_addr != 0) {
|
if ((_jedec_id >> 8) == 0x9d6016 && tb == 1 && base_addr != 0) {
|
||||||
_unprotect = true;
|
_unprotect = true;
|
||||||
must_relock = true;
|
_must_relock = true;
|
||||||
}
|
}
|
||||||
/* ST M25P16 has not TB bit:
|
/* ST M25P16 has not TB bit:
|
||||||
* block protection is always in top mode:
|
* block protection is always in top mode:
|
||||||
|
|
@ -434,28 +435,38 @@ int SPIFlash::erase_and_prog(int base_addr, const uint8_t *data, int len)
|
||||||
*/
|
*/
|
||||||
if ((_jedec_id >> 8) == 0x202015 && tb == 1 && base_addr != 0) {
|
if ((_jedec_id >> 8) == 0x202015 && tb == 1 && base_addr != 0) {
|
||||||
_unprotect = true;
|
_unprotect = true;
|
||||||
must_relock = true;
|
_must_relock = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // unknown chip: basic test
|
} else { // unknown chip: basic test
|
||||||
printWarn("flash chip unknown: use basic protection detection");
|
printWarn("flash chip unknown: use basic protection detection");
|
||||||
if (get_bp() != 0)
|
if (get_bp() != 0)
|
||||||
must_relock = true;
|
_must_relock = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if it's needs to unlock */
|
/* if it's needs to unlock... */
|
||||||
if (must_relock) {
|
/* Checks if unlock is asked/allowed by the user */
|
||||||
|
if (_must_relock) {
|
||||||
printf("unlock blocks\n");
|
printf("unlock blocks\n");
|
||||||
if (!_unprotect) {
|
if (!_unprotect) {
|
||||||
printError("Error: block protection is set");
|
printError("Error: block protection is set");
|
||||||
printError(" can't unlock without --unprotect-flash");
|
printError(" can't unlock without --unprotect-flash");
|
||||||
return -1;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if (disable_protection() != 0)
|
if (disable_protection() != 0)
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int SPIFlash::erase_and_prog(int base_addr, const uint8_t *data, int len)
|
||||||
|
{
|
||||||
|
if (!prepare_flash(base_addr, len))
|
||||||
|
return -1;
|
||||||
|
|
||||||
/* Now we can erase sector and write new data */
|
/* Now we can erase sector and write new data */
|
||||||
ProgressBar progress("Writing", len, 50, _verbose < 0);
|
ProgressBar progress("Writing", len, 50, _verbose < 0);
|
||||||
if (sectors_erase(base_addr, len) == -1)
|
if (sectors_erase(base_addr, len) == -1)
|
||||||
|
|
@ -475,8 +486,8 @@ int SPIFlash::erase_and_prog(int base_addr, const uint8_t *data, int len)
|
||||||
progress.done();
|
progress.done();
|
||||||
|
|
||||||
/* and if required: relock blocks */
|
/* and if required: relock blocks */
|
||||||
if (must_relock) {
|
if (_must_relock) {
|
||||||
enable_protection(status);
|
enable_protection(_status);
|
||||||
if (_verbose > 0)
|
if (_verbose > 0)
|
||||||
display_status_reg(read_status_reg());
|
display_status_reg(read_status_reg());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,9 @@ class SPIFlash {
|
||||||
*/
|
*/
|
||||||
uint8_t get_bp_mask();
|
uint8_t get_bp_mask();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool prepare_flash(const int base_addr, const int len);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
* \brief convert block protect to len in byte
|
* \brief convert block protect to len in byte
|
||||||
|
|
@ -174,6 +177,8 @@ class SPIFlash {
|
||||||
uint32_t _jedec_id; /**< CHIP ID */
|
uint32_t _jedec_id; /**< CHIP ID */
|
||||||
flash_t *_flash_model; /**< detect flash model */
|
flash_t *_flash_model; /**< detect flash model */
|
||||||
bool _unprotect; /**< allows to unprotect memory before write */
|
bool _unprotect; /**< allows to unprotect memory before write */
|
||||||
|
bool _must_relock;
|
||||||
|
uint8_t _status;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SRC_SPIFLASH_HPP_
|
#endif // SRC_SPIFLASH_HPP_
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue