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);
|
static uint32_t GetSectorSize(uint32_t Sector);
|
||||||
|
|
||||||
int32_t flash_init(flash_t *obj)
|
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 */
|
/* Allow Access to Flash control registers and user Falsh */
|
||||||
if (HAL_FLASH_Unlock()) {
|
if (HAL_FLASH_Unlock()) {
|
||||||
|
@ -48,7 +58,8 @@ int32_t flash_init(flash_t *obj)
|
||||||
return 0;
|
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) */
|
the option Bytes against possible unwanted operations) */
|
||||||
|
@ -58,15 +69,20 @@ int32_t flash_free(flash_t *obj)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
||||||
{
|
{
|
||||||
/*Variable used for Erase procedure*/
|
/*Variable used for Erase procedure*/
|
||||||
static FLASH_EraseInitTypeDef EraseInitStruct;
|
static FLASH_EraseInitTypeDef EraseInitStruct;
|
||||||
uint32_t FirstSector;
|
uint32_t FirstSector;
|
||||||
uint32_t SectorError = 0;
|
uint32_t SectorError = 0;
|
||||||
|
int32_t status = 0;
|
||||||
|
|
||||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flash_unlock() != HAL_OK) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,19 +95,26 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
||||||
EraseInitStruct.Sector = FirstSector;
|
EraseInitStruct.Sector = FirstSector;
|
||||||
EraseInitStruct.NbSectors = 1;
|
EraseInitStruct.NbSectors = 1;
|
||||||
if(HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK){
|
if(HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK){
|
||||||
return -1;
|
status = -1;
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flash_lock();
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size)
|
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)) {
|
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||||
return -1;
|
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,
|
/* 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
|
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
|
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_INSTRUCTION_CACHE_ENABLE();
|
||||||
__HAL_FLASH_DATA_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) {
|
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, address, (uint64_t)*data) != HAL_OK) {
|
||||||
return -1;
|
status = -1;
|
||||||
} else {
|
} else {
|
||||||
size--;
|
size--;
|
||||||
address++;
|
address++;
|
||||||
data++;
|
data++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
flash_lock();
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
|
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)
|
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()) {
|
if (HAL_FLASH_Unlock()) {
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
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) */
|
the option Bytes against possible unwanted operations) */
|
||||||
|
@ -55,6 +65,7 @@ int32_t flash_free(flash_t *obj)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
||||||
{
|
{
|
||||||
/* Variable used for Erase procedure */
|
/* Variable used for Erase procedure */
|
||||||
|
@ -62,11 +73,16 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
||||||
FLASH_OBProgramInitTypeDef OBInit;
|
FLASH_OBProgramInitTypeDef OBInit;
|
||||||
uint32_t SectorId;
|
uint32_t SectorId;
|
||||||
uint32_t SectorError = 0;
|
uint32_t SectorError = 0;
|
||||||
|
int32_t status = 0;
|
||||||
|
|
||||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||||
return -1;
|
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,
|
/* 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
|
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
|
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;
|
EraseInitStruct.NbSectors = 1;
|
||||||
|
|
||||||
if(HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK){
|
if(HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK){
|
||||||
return -1;
|
status = -1;
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flash_lock();
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data,
|
int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data,
|
||||||
uint32_t size)
|
uint32_t size)
|
||||||
{
|
{
|
||||||
|
int32_t status = 0;
|
||||||
|
|
||||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||||
return -1;
|
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,
|
/* 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
|
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
|
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_RESET();
|
||||||
__HAL_FLASH_ART_ENABLE();
|
__HAL_FLASH_ART_ENABLE();
|
||||||
|
|
||||||
while (size > 0) {
|
while ((size > 0) && (status == 0)) {
|
||||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE,
|
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE,
|
||||||
address, (uint64_t)*data) != HAL_OK) {
|
address, (uint64_t)*data) != HAL_OK) {
|
||||||
return -1;
|
status = -1;
|
||||||
} else {
|
} else {
|
||||||
size--;
|
size--;
|
||||||
address++;
|
address++;
|
||||||
data++;
|
data++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
flash_lock();
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
|
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
|
||||||
|
|
|
@ -26,30 +26,51 @@
|
||||||
|
|
||||||
int32_t flash_init(flash_t *obj)
|
int32_t flash_init(flash_t *obj)
|
||||||
{
|
{
|
||||||
/* Unlock the Flash to enable the flash control register access *************/
|
|
||||||
HAL_FLASH_Unlock();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t flash_free(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;
|
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)
|
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
||||||
{
|
{
|
||||||
uint32_t FirstPage = 0;
|
uint32_t FirstPage = 0;
|
||||||
uint32_t PAGEError = 0;
|
uint32_t PAGEError = 0;
|
||||||
FLASH_EraseInitTypeDef EraseInitStruct;
|
FLASH_EraseInitTypeDef EraseInitStruct;
|
||||||
|
int32_t status = 0;
|
||||||
|
|
||||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flash_unlock() != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Clear OPTVERR bit set on virgin samples */
|
/* Clear OPTVERR bit set on virgin samples */
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
|
__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. */
|
DCRST and ICRST bits in the FLASH_CR register. */
|
||||||
|
|
||||||
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
|
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
|
||||||
return -1;
|
status = -1;
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flash_lock();
|
||||||
|
|
||||||
|
return status;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t flash_program_page(flash_t *obj, uint32_t address,
|
int32_t flash_program_page(flash_t *obj, uint32_t address,
|
||||||
const uint8_t *data, uint32_t size)
|
const uint8_t *data, uint32_t size)
|
||||||
{
|
{
|
||||||
uint32_t StartAddress = 0;
|
uint32_t StartAddress = 0;
|
||||||
|
int32_t status = 0;
|
||||||
|
|
||||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -85,6 +110,10 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flash_unlock() != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Program the user Flash area word by word */
|
/* Program the user Flash area word by word */
|
||||||
StartAddress = address;
|
StartAddress = address;
|
||||||
|
|
||||||
|
@ -92,7 +121,7 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
|
||||||
* parameters doesn't ensure */
|
* parameters doesn't ensure */
|
||||||
if ((uint32_t) data % 4 != 0) {
|
if ((uint32_t) data % 4 != 0) {
|
||||||
volatile uint32_t data32;
|
volatile uint32_t data32;
|
||||||
while (address < (StartAddress + size)) {
|
while ((address < (StartAddress + size)) && (status == 0)) {
|
||||||
for (uint8_t i =0; i < 4; i++) {
|
for (uint8_t i =0; i < 4; i++) {
|
||||||
*(((uint8_t *) &data32) + i) = *(data + 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;
|
address = address + 4;
|
||||||
data = data + 4;
|
data = data + 4;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
status = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { /* case where data is aligned, so let's avoid any copy */
|
} 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) {
|
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *((uint32_t*) data)) == HAL_OK) {
|
||||||
address = address + 4;
|
address = address + 4;
|
||||||
data = data + 4;
|
data = data + 4;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
status = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
flash_lock();
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) {
|
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) {
|
||||||
|
|
|
@ -26,30 +26,51 @@
|
||||||
|
|
||||||
int32_t flash_init(flash_t *obj)
|
int32_t flash_init(flash_t *obj)
|
||||||
{
|
{
|
||||||
/* Unlock the Flash to enable the flash control register access *************/
|
|
||||||
HAL_FLASH_Unlock();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t flash_free(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;
|
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)
|
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
||||||
{
|
{
|
||||||
uint32_t FirstPage = 0;
|
uint32_t FirstPage = 0;
|
||||||
uint32_t PAGEError = 0;
|
uint32_t PAGEError = 0;
|
||||||
FLASH_EraseInitTypeDef EraseInitStruct;
|
FLASH_EraseInitTypeDef EraseInitStruct;
|
||||||
|
int32_t status = 0;
|
||||||
|
|
||||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||||
|
|
||||||
return -1;
|
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);
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR | FLASH_FLAG_EOP | FLASH_FLAG_PGAERR | FLASH_FLAG_WRPERR);
|
||||||
/* MBED HAL erases 1 sector at a time */
|
/* MBED HAL erases 1 sector at a time */
|
||||||
/* Fill EraseInit structure*/
|
/* 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. */
|
DCRST and ICRST bits in the FLASH_CR register. */
|
||||||
|
|
||||||
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
|
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
|
||||||
return -1;
|
status = -1;
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flash_lock();
|
||||||
|
|
||||||
|
return status;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t flash_program_page(flash_t *obj, uint32_t address,
|
int32_t flash_program_page(flash_t *obj, uint32_t address,
|
||||||
const uint8_t *data, uint32_t size)
|
const uint8_t *data, uint32_t size)
|
||||||
{
|
{
|
||||||
uint32_t StartAddress = 0;
|
uint32_t StartAddress = 0;
|
||||||
|
int32_t status = 0;
|
||||||
|
|
||||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -83,6 +108,10 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flash_unlock() != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Program the user Flash area word by word */
|
/* Program the user Flash area word by word */
|
||||||
StartAddress = address;
|
StartAddress = address;
|
||||||
|
|
||||||
|
@ -90,7 +119,7 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
|
||||||
* parameters doesn't ensure */
|
* parameters doesn't ensure */
|
||||||
if ((uint32_t) data % 4 != 0) {
|
if ((uint32_t) data % 4 != 0) {
|
||||||
volatile uint32_t data32;
|
volatile uint32_t data32;
|
||||||
while (address < (StartAddress + size)) {
|
while (address < (StartAddress + size) && (status == 0)) {
|
||||||
for (uint8_t i =0; i < 4; i++) {
|
for (uint8_t i =0; i < 4; i++) {
|
||||||
*(((uint8_t *) &data32) + i) = *(data + 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;
|
address = address + 4;
|
||||||
data = data + 4;
|
data = data + 4;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
status = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { /* case where data is aligned, so let's avoid any copy */
|
} 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) {
|
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *((uint32_t*) data)) == HAL_OK) {
|
||||||
address = address + 4;
|
address = address + 4;
|
||||||
data = data + 4;
|
data = data + 4;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
status = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
flash_lock();
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
|
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)
|
int32_t flash_init(flash_t *obj)
|
||||||
{
|
{
|
||||||
/* Unlock the Flash to enable the flash control register access *************/
|
|
||||||
HAL_FLASH_Unlock();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,12 +90,30 @@ int32_t flash_init(flash_t *obj)
|
||||||
*/
|
*/
|
||||||
int32_t flash_free(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;
|
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
|
/** Erase one sector starting at defined address
|
||||||
*
|
*
|
||||||
* The address should be at sector boundary. This function does not do any check for address alignments
|
* 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 FirstPage = 0, BankNumber = 0;
|
||||||
uint32_t PAGEError = 0;
|
uint32_t PAGEError = 0;
|
||||||
FLASH_EraseInitTypeDef EraseInitStruct;
|
FLASH_EraseInitTypeDef EraseInitStruct;
|
||||||
|
int32_t status = 0;
|
||||||
|
|
||||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flash_unlock() != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Clear OPTVERR bit set on virgin samples */
|
/* Clear OPTVERR bit set on virgin samples */
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
|
||||||
/* Get the 1st page to erase */
|
/* 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. */
|
DCRST and ICRST bits in the FLASH_CR register. */
|
||||||
|
|
||||||
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
|
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
|
||||||
return -1;
|
status = -1;
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flash_lock();
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Program one page starting at defined address
|
/** 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)
|
const uint8_t *data, uint32_t size)
|
||||||
{
|
{
|
||||||
uint32_t StartAddress = 0;
|
uint32_t StartAddress = 0;
|
||||||
|
int32_t status = 0;
|
||||||
|
|
||||||
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -166,6 +190,10 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flash_unlock() != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Program the user Flash area word by word */
|
/* Program the user Flash area word by word */
|
||||||
StartAddress = address;
|
StartAddress = address;
|
||||||
|
|
||||||
|
@ -173,30 +201,35 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
|
||||||
* parameters doesn't ensure */
|
* parameters doesn't ensure */
|
||||||
if ((uint32_t) data % 4 != 0) {
|
if ((uint32_t) data % 4 != 0) {
|
||||||
volatile uint64_t data64;
|
volatile uint64_t data64;
|
||||||
while (address < (StartAddress + size)) {
|
while ((address < (StartAddress + size)) && (status == 0)) {
|
||||||
for (uint8_t i =0; i < 8; i++) {
|
for (uint8_t i =0; i < 8; i++) {
|
||||||
*(((uint8_t *) &data64) + i) = *(data + 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;
|
address = address + 8;
|
||||||
data = data + 8;
|
data = data + 8;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
status = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { /* case where data is aligned, so let's avoid any copy */
|
} 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_DOUBLEWORD, address, *((uint64_t*) data)) == HAL_OK) {
|
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address,
|
||||||
|
*((uint64_t*) data))
|
||||||
|
== HAL_OK) {
|
||||||
address = address + 8;
|
address = address + 8;
|
||||||
data = data + 8;
|
data = data + 8;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
status = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
flash_lock();
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get sector size
|
/** Get sector size
|
||||||
|
|
Loading…
Reference in New Issue