You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

237 lines
4.5 KiB

#include "board_config.h"
#include "cammsys_flash.h"
#define FLASH_PAGE_ADDR 0x00000000
#define FLASH_PAGE_MAX 32
#define FLASH_PAGE_SIZE 8192
void Flash_Initialization(void)
{
const sys_cfg_t sys_flash_cfg = NULL;
FLC_Init(&sys_flash_cfg);
}
/*
APIs
*/
int flash_verify(uint32_t address, uint32_t length, uint8_t *data)
{
volatile uint8_t *ptr;
for (ptr = (uint8_t *)address; ptr < (uint8_t *)(address + length); ptr++, data++) {
if (*ptr != *data) {
// printf("Verify failed at 0x%x (0x%x != 0x%x)\n", (unsigned int)ptr, (unsigned int)*ptr, (unsigned int)*data);
return E_UNKNOWN;
}
}
return E_NO_ERROR;
}
/******************************************************************************/
int flash_uninit(void)
{
FLC_ClearFlags(MXC_F_FLC_INTR_DONE | MXC_F_FLC_INTR_AF);
return 0; // Finished without Errors
}
/******************************************************************************/
/*
* Erase complete Flash Memory
* Return Value: 0 - OK, 1 - Failed
*/
int flash_erase_chip(void)
{
return FLC_MassErase();
}
/******************************************************************************/
/*
* Erase given page address in Flash Memory
* Parameter: address: Sector Address
* Return Value: 0 - OK, 1 - Failed
*/
int flash_erase_page(unsigned long address)
{
return FLC_PageErase(address);
}
int flash_program_page(unsigned long address, unsigned long size, unsigned char *buffer8)
{
uint32_t dest_addr;
int i = 0;
uint32_t *buffer32 = (uint32_t *)buffer8;
for (dest_addr = address; dest_addr < (address + size); dest_addr += 4) {
// Write a word
if (FLC_Write32(dest_addr, buffer32[i]) != E_NO_ERROR) {
// printf("Failure in writing a word.\n");
break;
}
i++;
}
// Verify if page is written properly
if (flash_verify(address, size, (uint8_t*)buffer8) != E_NO_ERROR) {
//printf("%ld bytes are not written properly.\n", size);
return -1;
}
// printf("* %d data succefully written to address %X, and verified.\n", size, address);
return 0;
}
int Flash_Check_Mem(uint32_t startaddr, uint32_t length, uint32_t data)
{
uint32_t *ptr;
for (ptr = (uint32_t *)startaddr; ptr < (uint32_t *)(startaddr + length); ptr++)
{
if (*ptr != data)
{
return false;
}
}
return true;
}
bool Flash_Erase(uint32_t Address, uint32_t length)
{
bool ret = false;
uint32_t i;
int16_t start_page_num = -1;
volatile uint32_t page_count = 0;
uint8_t retrycount;
for (i=0; i<FLASH_PAGE_MAX; i++)
{
if (flashInPage(i, Address, length) == true)
{
if (start_page_num < 0)
{
start_page_num = i;
}
page_count++;
}
}
if (page_count > 0)
{
int i;
int delayCount;
for (i = 0 ; i < page_count ; i++)
{
if(flash_erase_page(((start_page_num + i) * FLASH_PAGE_SIZE)) != E_NO_ERROR)
{
flash_uninit();
return false;
}
if(Flash_Check_Mem(((start_page_num + i) * FLASH_PAGE_SIZE), FLASH_PAGE_SIZE, 0xFFFFFFFF) == false)
{
flash_uninit();
return false;
}
}
ret = true;
}
return ret;
}
bool flashInPage(uint16_t sector_num, uint32_t addr, uint32_t length)
{
bool ret = false;
uint32_t sector_start;
uint32_t sector_end;
uint32_t flash_start;
uint32_t flash_end;
sector_start = FLASH_PAGE_ADDR + (sector_num * FLASH_PAGE_SIZE);
sector_end = sector_start + FLASH_PAGE_SIZE - 1;
flash_start = addr;
flash_end = addr + length - 1;
if (sector_start >= flash_start && sector_start <= flash_end)
{
ret = true;
}
if (sector_end >= flash_start && sector_end <= flash_end)
{
ret = true;
}
if (flash_start >= sector_start && flash_start <= sector_end)
{
ret = true;
}
if (flash_end >= sector_start && flash_end <= sector_end)
{
ret = true;
}
return ret;
}
bool Flash_Write(uint32_t addr, uint8_t *p_data, uint32_t length)
{
bool ret = true;
if (addr%4 != 0)
{
return false;
}
if(flash_program_page(addr, length, p_data) != E_NO_ERROR)
{
return false;
}
return ret;
}