//IAR 7.1
#include <string.h>
#include "stm32_flash.h"
FLASH_Status FLASHStatus = FLASH_COMPLETE;
//TestStatus MemoryProgramStatus = PASSED;
uint8_t backups[FLASH_PAGE_SIZE];
void stm32_flash_unlock(void)
{
FLASH_Unlock();
}
void stm32_flash_lock(void)
{
FLASH_Lock();
}
FLASH_Status stm32_flash_init(void)
{
uint16_t pages, count;
/*Unlock the Flash to enable the flash control register access*/
FLASH_Unlock();
/*Clear pending flags*/
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
/*Erase the user Flash area*/
pages = (FLASH_USER_END_ADDR - FLASH_SUPER_PASSWORD_ADDR +1) / FLASH_PAGE_SIZE;
for(count = 0; (count < pages) && (FLASHStatus == FLASH_COMPLETE); count++)
{
if (FLASH_ErasePage(FLASH_SUPER_PASSWORD_ADDR + (FLASH_PAGE_SIZE * count))!= FLASH_COMPLETE)
return FLASH_ERROR_PG;
}
/*Lock the Flash to disable the flash control register access*/
FLASH_Lock();
return FLASH_COMPLETE;
}
FLASH_Status stm32_flash_write(uint32_t addr, const uint8_t* buf, uint16_t len)
{
uint32_t offs = addr % FLASH_PAGE_SIZE;
uint32_t flash_ptr = addr - offs;
uint32_t* buf_ptr = (uint32_t*)backups;
uint16_t count;
/*Unlock the flash to enable the flash control register access*/
FLASH_Unlock();
/* Clear pending flags (if any) */
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
/*Backup the data from falsh memory*/
memset(backups, 0, FLASH_PAGE_SIZE);
memcpy(backups, (uint8_t*)flash_ptr, FLASH_PAGE_SIZE);
/*Copy my data to backup buffer*/
memcpy(backups + offs, buf, len);
/*Erase the whole page*/
FLASH_ErasePage(flash_ptr);
/*Write the data into flash memory again*/
for(count = 0; count < (FLASH_PAGE_SIZE / 4); count++)
{
if(FLASH_ProgramWord(flash_ptr, *buf_ptr++) == FLASH_COMPLETE)
{
flash_ptr += 4;
}
else
{
FLASH_Lock();
return FLASH_ERROR_PG;
}
}
FLASH_Lock();
return FLASH_COMPLETE;
}
void stm32_flash_read(uint32_t addr, uint8_t* buf, uint16_t len)
{
uint8_t* flash_ptr;
flash_ptr = (uint8_t*) addr;
memcpy(buf,flash_ptr,len);
}
/**
* @brief Erase the FLASH pages
* @param addr_start : the address to start
page_cnt : how many pages to be erased
* @retval None
*/
FLASH_Status flash_erase_pages(uint32_t addr_start,uint16_t page_cnt)
{
uint16_t erase_count;
uint32_t addr = addr_start;
for(erase_count = 0; (erase_count < page_cnt) && (FLASHStatus == FLASH_COMPLETE); erase_count++)
{
// TODO:implement it
//we do not ensure the FLASH_USER_STAART_ADDR
if (FLASH_ErasePage(addr)!= FLASH_COMPLETE)
{
/* Error occurred while sector erase.
User can add here some code to deal with this error */
return FLASH_ERROR_PG;
}
addr += FLASH_PAGE_SIZE;
}
return FLASH_COMPLETE;
}
FLASH_Status flash_program_words(uint32_t addr,uint32_t *data,uint32_t count)
{
uint32_t i=0;
// TODO:implement it
//we do not ensure the FLASH_SUER_END_ADDR
while (i<count)
{
if (FLASH_ProgramWord(addr, *(__IO uint32_t *)data) == FLASH_COMPLETE)
{
addr = addr + 4;
data++;
i++;
}
else
{
/* Error occurred while writing data in Flash memory.
User can add here some code to deal with this error */
return FLASH_ERROR_PG;
}
}
return FLASH_COMPLETE;
}
FLASH_Status flash_program_page(uint32_t dst, uint32_t *data)
{
size_t words = FLASH_PAGE_SIZE / sizeof(uint32_t);
FLASH_Unlock();
flash_erase_pages(dst, 1);
flash_program_words(dst, data, words);
FLASH_Lock();
return FLASH_COMPLETE;
}