mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #5026 from LMESTM/flash_init_issue_4967
STM32: Lock / Unlock flash for each operationpull/5154/merge
commit
6cb0258344
|
@ -40,6 +40,16 @@ static uint32_t GetSector(uint32_t Address);
|
|||
static uint32_t GetSectorSize(uint32_t Sector);
|
||||
|
||||
int32_t flash_init(flash_t *obj)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t flash_free(flash_t *obj)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t flash_unlock(void)
|
||||
{
|
||||
/* Allow Access to Flash control registers and user Falsh */
|
||||
if (HAL_FLASH_Unlock()) {
|
||||
|
@ -48,9 +58,10 @@ int32_t flash_init(flash_t *obj)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
int32_t flash_free(flash_t *obj)
|
||||
|
||||
static int32_t flash_lock(void)
|
||||
{
|
||||
/* Disable the Flash option control register access (recommended to protect
|
||||
/* Disable the Flash option control register access (recommended to protect
|
||||
the option Bytes against possible unwanted operations) */
|
||||
if (HAL_FLASH_Lock()) {
|
||||
return -1;
|
||||
|
@ -58,18 +69,23 @@ int32_t flash_free(flash_t *obj)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
||||
{
|
||||
/*Variable used for Erase procedure*/
|
||||
static FLASH_EraseInitTypeDef EraseInitStruct;
|
||||
uint32_t FirstSector;
|
||||
uint32_t SectorError = 0;
|
||||
|
||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||
int32_t status = 0;
|
||||
|
||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (flash_unlock() != HAL_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get the 1st sector to erase */
|
||||
FirstSector = GetSector(address);
|
||||
|
||||
|
@ -79,19 +95,26 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
|||
EraseInitStruct.Sector = FirstSector;
|
||||
EraseInitStruct.NbSectors = 1;
|
||||
if(HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK){
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
status = -1;
|
||||
}
|
||||
|
||||
flash_lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size)
|
||||
{
|
||||
int32_t status = 0;
|
||||
|
||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flash_unlock() != HAL_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
|
||||
you have to make sure that these data are rewritten before they are accessed during code
|
||||
execution. If this cannot be done safely, it is recommended to flush the caches by setting the
|
||||
|
@ -105,16 +128,19 @@ int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data,
|
|||
__HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
|
||||
__HAL_FLASH_DATA_CACHE_ENABLE();
|
||||
|
||||
while (size > 0) {
|
||||
while ((size > 0) && (status == 0)) {
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, address, (uint64_t)*data) != HAL_OK) {
|
||||
return -1;
|
||||
status = -1;
|
||||
} else {
|
||||
size--;
|
||||
address++;
|
||||
data++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
flash_lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
|
||||
|
|
|
@ -38,14 +38,24 @@ static uint32_t GetSectorSize(uint32_t Sector);
|
|||
|
||||
int32_t flash_init(flash_t *obj)
|
||||
{
|
||||
/* Allow Access to Flash control registers and user Flash */
|
||||
return 0;
|
||||
}
|
||||
int32_t flash_free(flash_t *obj)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t flash_unlock(void)
|
||||
{
|
||||
/* Allow Access to Flash control registers and user Falsh */
|
||||
if (HAL_FLASH_Unlock()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int32_t flash_free(flash_t *obj)
|
||||
|
||||
static int32_t flash_lock(void)
|
||||
{
|
||||
/* Disable the Flash option control register access (recommended to protect
|
||||
the option Bytes against possible unwanted operations) */
|
||||
|
@ -55,6 +65,7 @@ int32_t flash_free(flash_t *obj)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
||||
{
|
||||
/* Variable used for Erase procedure */
|
||||
|
@ -62,11 +73,16 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
|||
FLASH_OBProgramInitTypeDef OBInit;
|
||||
uint32_t SectorId;
|
||||
uint32_t SectorError = 0;
|
||||
int32_t status = 0;
|
||||
|
||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flash_unlock() != HAL_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
|
||||
you have to make sure that these data are rewritten before they are accessed during code
|
||||
execution. If this cannot be done safely, it is recommended to flush the caches by setting the
|
||||
|
@ -102,19 +118,27 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
|||
EraseInitStruct.NbSectors = 1;
|
||||
|
||||
if(HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK){
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
status = -1;
|
||||
}
|
||||
|
||||
flash_lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data,
|
||||
uint32_t size)
|
||||
{
|
||||
int32_t status = 0;
|
||||
|
||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flash_unlock() != HAL_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
|
||||
you have to make sure that these data are rewritten before they are accessed during code
|
||||
execution. If this cannot be done safely, it is recommended to flush the caches by setting the
|
||||
|
@ -123,17 +147,20 @@ int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data,
|
|||
__HAL_FLASH_ART_RESET();
|
||||
__HAL_FLASH_ART_ENABLE();
|
||||
|
||||
while (size > 0) {
|
||||
while ((size > 0) && (status == 0)) {
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE,
|
||||
address, (uint64_t)*data) != HAL_OK) {
|
||||
return -1;
|
||||
status = -1;
|
||||
} else {
|
||||
size--;
|
||||
address++;
|
||||
data++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
flash_lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
|
||||
|
|
|
@ -26,30 +26,51 @@
|
|||
|
||||
int32_t flash_init(flash_t *obj)
|
||||
{
|
||||
/* Unlock the Flash to enable the flash control register access *************/
|
||||
HAL_FLASH_Unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t flash_free(flash_t *obj)
|
||||
{
|
||||
/* Lock the Flash to disable the flash control register access (recommended
|
||||
* to protect the FLASH memory against possible unwanted operation) *********/
|
||||
HAL_FLASH_Lock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t flash_unlock(void)
|
||||
{
|
||||
/* Allow Access to Flash control registers and user Falsh */
|
||||
if (HAL_FLASH_Unlock()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t flash_lock(void)
|
||||
{
|
||||
/* Disable the Flash option control register access (recommended to protect
|
||||
the option Bytes against possible unwanted operations) */
|
||||
if (HAL_FLASH_Lock()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
||||
{
|
||||
uint32_t FirstPage = 0;
|
||||
uint32_t PAGEError = 0;
|
||||
FLASH_EraseInitTypeDef EraseInitStruct;
|
||||
int32_t status = 0;
|
||||
|
||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flash_unlock() != HAL_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Clear OPTVERR bit set on virgin samples */
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
|
||||
|
||||
|
@ -65,16 +86,20 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
|||
DCRST and ICRST bits in the FLASH_CR register. */
|
||||
|
||||
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
status = -1;
|
||||
}
|
||||
|
||||
flash_lock();
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
int32_t flash_program_page(flash_t *obj, uint32_t address,
|
||||
const uint8_t *data, uint32_t size)
|
||||
{
|
||||
uint32_t StartAddress = 0;
|
||||
int32_t status = 0;
|
||||
|
||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||
return -1;
|
||||
|
@ -85,6 +110,10 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (flash_unlock() != HAL_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Program the user Flash area word by word */
|
||||
StartAddress = address;
|
||||
|
||||
|
@ -92,7 +121,7 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
|
|||
* parameters doesn't ensure */
|
||||
if ((uint32_t) data % 4 != 0) {
|
||||
volatile uint32_t data32;
|
||||
while (address < (StartAddress + size)) {
|
||||
while ((address < (StartAddress + size)) && (status == 0)) {
|
||||
for (uint8_t i =0; i < 4; i++) {
|
||||
*(((uint8_t *) &data32) + i) = *(data + i);
|
||||
}
|
||||
|
@ -101,21 +130,23 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
|
|||
address = address + 4;
|
||||
data = data + 4;
|
||||
} else {
|
||||
return -1;
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
} else { /* case where data is aligned, so let's avoid any copy */
|
||||
while (address < (StartAddress + size)) {
|
||||
while ((address < (StartAddress + size)) && (status == 0)) {
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *((uint32_t*) data)) == HAL_OK) {
|
||||
address = address + 4;
|
||||
data = data + 4;
|
||||
} else {
|
||||
return -1;
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
flash_lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) {
|
||||
|
|
|
@ -26,30 +26,51 @@
|
|||
|
||||
int32_t flash_init(flash_t *obj)
|
||||
{
|
||||
/* Unlock the Flash to enable the flash control register access *************/
|
||||
HAL_FLASH_Unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t flash_free(flash_t *obj)
|
||||
{
|
||||
/* Lock the Flash to disable the flash control register access (recommended
|
||||
* to protect the FLASH memory against possible unwanted operation) *********/
|
||||
HAL_FLASH_Lock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t flash_unlock(void)
|
||||
{
|
||||
/* Allow Access to Flash control registers and user Falsh */
|
||||
if (HAL_FLASH_Unlock()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t flash_lock(void)
|
||||
{
|
||||
/* Disable the Flash option control register access (recommended to protect
|
||||
the option Bytes against possible unwanted operations) */
|
||||
if (HAL_FLASH_Lock()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
||||
{
|
||||
uint32_t FirstPage = 0;
|
||||
uint32_t PAGEError = 0;
|
||||
FLASH_EraseInitTypeDef EraseInitStruct;
|
||||
int32_t status = 0;
|
||||
|
||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flash_unlock() != HAL_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR | FLASH_FLAG_EOP | FLASH_FLAG_PGAERR | FLASH_FLAG_WRPERR);
|
||||
/* MBED HAL erases 1 sector at a time */
|
||||
/* Fill EraseInit structure*/
|
||||
|
@ -63,16 +84,20 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
|||
DCRST and ICRST bits in the FLASH_CR register. */
|
||||
|
||||
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
status = -1;
|
||||
}
|
||||
|
||||
flash_lock();
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
int32_t flash_program_page(flash_t *obj, uint32_t address,
|
||||
const uint8_t *data, uint32_t size)
|
||||
{
|
||||
uint32_t StartAddress = 0;
|
||||
int32_t status = 0;
|
||||
|
||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||
return -1;
|
||||
|
@ -83,6 +108,10 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (flash_unlock() != HAL_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Program the user Flash area word by word */
|
||||
StartAddress = address;
|
||||
|
||||
|
@ -90,7 +119,7 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
|
|||
* parameters doesn't ensure */
|
||||
if ((uint32_t) data % 4 != 0) {
|
||||
volatile uint32_t data32;
|
||||
while (address < (StartAddress + size)) {
|
||||
while (address < (StartAddress + size) && (status == 0)) {
|
||||
for (uint8_t i =0; i < 4; i++) {
|
||||
*(((uint8_t *) &data32) + i) = *(data + i);
|
||||
}
|
||||
|
@ -99,21 +128,23 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
|
|||
address = address + 4;
|
||||
data = data + 4;
|
||||
} else {
|
||||
return -1;
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
} else { /* case where data is aligned, so let's avoid any copy */
|
||||
while (address < (StartAddress + size)) {
|
||||
while ((address < (StartAddress + size)) && (status == 0)) {
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *((uint32_t*) data)) == HAL_OK) {
|
||||
address = address + 4;
|
||||
data = data + 4;
|
||||
} else {
|
||||
return -1;
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
flash_lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
|
||||
|
|
|
@ -80,8 +80,6 @@ static uint32_t GetBank(uint32_t Addr)
|
|||
*/
|
||||
int32_t flash_init(flash_t *obj)
|
||||
{
|
||||
/* Unlock the Flash to enable the flash control register access *************/
|
||||
HAL_FLASH_Unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -92,12 +90,30 @@ int32_t flash_init(flash_t *obj)
|
|||
*/
|
||||
int32_t flash_free(flash_t *obj)
|
||||
{
|
||||
/* Lock the Flash to disable the flash control register access (recommended
|
||||
* to protect the FLASH memory against possible unwanted operation) *********/
|
||||
HAL_FLASH_Lock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t flash_unlock(void)
|
||||
{
|
||||
/* Allow Access to Flash control registers and user Falsh */
|
||||
if (HAL_FLASH_Unlock()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t flash_lock(void)
|
||||
{
|
||||
/* Disable the Flash option control register access (recommended to protect
|
||||
the option Bytes against possible unwanted operations) */
|
||||
if (HAL_FLASH_Lock()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** Erase one sector starting at defined address
|
||||
*
|
||||
* The address should be at sector boundary. This function does not do any check for address alignments
|
||||
|
@ -110,12 +126,17 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
|||
uint32_t FirstPage = 0, BankNumber = 0;
|
||||
uint32_t PAGEError = 0;
|
||||
FLASH_EraseInitTypeDef EraseInitStruct;
|
||||
int32_t status = 0;
|
||||
|
||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flash_unlock() != HAL_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Clear OPTVERR bit set on virgin samples */
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
|
||||
/* Get the 1st page to erase */
|
||||
|
@ -135,10 +156,12 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
|||
DCRST and ICRST bits in the FLASH_CR register. */
|
||||
|
||||
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
status = -1;
|
||||
}
|
||||
|
||||
flash_lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/** Program one page starting at defined address
|
||||
|
@ -156,6 +179,7 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
|
|||
const uint8_t *data, uint32_t size)
|
||||
{
|
||||
uint32_t StartAddress = 0;
|
||||
int32_t status = 0;
|
||||
|
||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||
return -1;
|
||||
|
@ -166,6 +190,10 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (flash_unlock() != HAL_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Program the user Flash area word by word */
|
||||
StartAddress = address;
|
||||
|
||||
|
@ -173,34 +201,39 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
|
|||
* parameters doesn't ensure */
|
||||
if ((uint32_t) data % 4 != 0) {
|
||||
volatile uint64_t data64;
|
||||
while (address < (StartAddress + size)) {
|
||||
while ((address < (StartAddress + size)) && (status == 0)) {
|
||||
for (uint8_t i =0; i < 8; i++) {
|
||||
*(((uint8_t *) &data64) + i) = *(data + i);
|
||||
}
|
||||
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data64) == HAL_OK) {
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data64)
|
||||
== HAL_OK) {
|
||||
address = address + 8;
|
||||
data = data + 8;
|
||||
} else {
|
||||
return -1;
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
} else { /* case where data is aligned, so let's avoid any copy */
|
||||
while (address < (StartAddress + size)) {
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, *((uint64_t*) data)) == HAL_OK) {
|
||||
while ((address < (StartAddress + size)) && (status == 0)) {
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address,
|
||||
*((uint64_t*) data))
|
||||
== HAL_OK) {
|
||||
address = address + 8;
|
||||
data = data + 8;
|
||||
} else {
|
||||
return -1;
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
flash_lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/** Get sector size
|
||||
*
|
||||
*
|
||||
* @param obj The flash object
|
||||
* @param address The sector starting address
|
||||
* @return The size of a sector
|
||||
|
|
Loading…
Reference in New Issue