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
237 lines
4.5 KiB
3 months ago
|
#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;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|