flash_internal: add function to probe actual flash size
This commit is contained in:
parent
2b3b4431e2
commit
1ac92ec4ac
|
@ -12,7 +12,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
/** library to read/write internal flash (code)
|
||||
/** library to read/write internal flash
|
||||
* @file
|
||||
* @author King Kévin <kingkevin@cuvoodoo.info>
|
||||
* @date 2016-2020
|
||||
|
@ -319,3 +319,91 @@ int32_t flash_internal_eeprom_write(const uint8_t *eeprom, uint16_t size)
|
|||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
uint16_t flash_internal_probe_size(void)
|
||||
{
|
||||
if (0 == DESIG_FLASH_SIZE) { // no flash size advertised
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get max flash size based on device identifier (DEV_ID)
|
||||
uint32_t flash_size_max = 0; // max flash size (in bytes)
|
||||
switch (DBGMCU_IDCODE & DBGMCU_IDCODE_DEV_ID_MASK) { // get page size based on family code
|
||||
case 0x412: // low-density, 16-32 kB flash
|
||||
flash_size_max = 32;
|
||||
break;
|
||||
case 0x410: // medium-density, 64-128 kB flash
|
||||
flash_size_max = 128;
|
||||
break;
|
||||
case 0x414: // high-density, 256-512 kB flash
|
||||
flash_size_max = 512;
|
||||
break;
|
||||
case 0x430: // XL-density, 768-1024 kB flash
|
||||
flash_size_max = 1024;
|
||||
break;
|
||||
case 0x418: // connectivity, 64-256 kB flash
|
||||
flash_size_max = 256;
|
||||
break;
|
||||
case 0: // DBGMCU_IDCODE is only accessible in debug mode (this is a known issue documented in STM32F10xxC/D/E Errata sheet, without workaround)
|
||||
default: // unknown
|
||||
if ((*(uint32_t*)0x1FFFF000 & 0xFFFE0000) == 0x20000000) { // non-connectivity system memory start detected (MSP address pointing to SRAM
|
||||
switch (DESIG_FLASH_SIZE) {
|
||||
case 16:
|
||||
case 32:
|
||||
flash_size_max = 32; // low-density, 16-32 kB flash
|
||||
break;
|
||||
case 64:
|
||||
case 128:
|
||||
flash_size_max = 128; // medium-density, 64-128 kB flash
|
||||
break;
|
||||
case 256:
|
||||
case 512:
|
||||
flash_size_max = 512; // high-density, 256-512 kB flash
|
||||
break;
|
||||
case 768:
|
||||
case 1024:
|
||||
flash_size_max = 1024; // XL-density, 768-1024 kB flash
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else { // connectivity system memory start is at 0x1FFFB000
|
||||
flash_size_max = 256; // connectivity, 64-256 kB flash
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (0 == flash_size_max) { // could not determine max flash size
|
||||
return 0;
|
||||
}
|
||||
flash_size_max *= 1024; // get in bytes
|
||||
|
||||
// test if page is writable, starting with last one
|
||||
uint32_t flash_size; // tested flash size (in bytes)
|
||||
const uint16_t test_data = 0x2342; // the data we will write and read to test page
|
||||
flash_unlock(); // unlock flash to be able to write it
|
||||
for (flash_size = DESIG_FLASH_SIZE * 1024 - flash_internal_page_size(); flash_size < flash_size_max; flash_size += flash_internal_page_size()) { // don't exceed max size else it will erase the first page (weird behaviour)
|
||||
uint32_t address = FLASH_BASE + flash_size;
|
||||
flash_erase_page(address); // erase current page
|
||||
if (flash_get_status_flags() != FLASH_SR_EOP) { // operation went wrong
|
||||
break;
|
||||
}
|
||||
flash_program_half_word(address, test_data); // writes test data
|
||||
if (flash_get_status_flags() != FLASH_SR_EOP) { // operation went wrong
|
||||
break;
|
||||
}
|
||||
if (test_data != *((uint16_t*)address)) { // verify data is written correctly
|
||||
break;
|
||||
}
|
||||
flash_erase_page(address); // erase test data
|
||||
if (flash_get_status_flags() != FLASH_SR_EOP) { // operation went wrong
|
||||
break;
|
||||
}
|
||||
}
|
||||
flash_lock();
|
||||
|
||||
if (flash_size < DESIG_FLASH_SIZE * 1024) { // less than advertised size
|
||||
return 0;
|
||||
} else {
|
||||
return flash_size / 1024;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
/** library to read/write internal flash (API)
|
||||
/** library to read/write internal flash
|
||||
* @file
|
||||
* @author King Kévin <kingkevin@cuvoodoo.info>
|
||||
* @date 2016-2020
|
||||
|
@ -57,3 +57,8 @@ bool flash_internal_eeprom_read(uint8_t *eeprom, uint16_t size);
|
|||
* @return number of bytes written (including preserved data), or negative in case of error
|
||||
*/
|
||||
int32_t flash_internal_eeprom_write(const uint8_t *eeprom, uint16_t size);
|
||||
/** probe the real size of the internal flash
|
||||
* @return tested size (in KiB), or 0 if less than advertised
|
||||
* @warning it will write the last page of the advertised size
|
||||
*/
|
||||
uint16_t flash_internal_probe_size(void);
|
||||
|
|
Loading…
Reference in New Issue