Files
checker_gen1/source/dev/dev_flash.c
2023-06-10 11:52:00 +08:00

288 lines
5.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "rtthread.h"
#include "stm32f4xx.h"
#include "board.h"
#include "dev_flash.h"
#include "debug.h"
#include "stdlib.h"
#include "string.h"
#ifndef RT_THREAD
#define rt_interrupt_enter()
#define rt_interrupt_leave()
#define rt_mutex_create(...) 0
#define rt_mutex_delete(...)
#define rt_mutex_take(...)
#define rt_mutex_release(...)
#endif
typedef struct{
void *mutex;
}self_def;
static self_def g_self;
typedef struct{
uint32_t *addr;
uint32_t sector;
}flash_item;
const static flash_item g_flash_addr_table[]={
{(uint32_t *)0x08000000,FLASH_Sector_0},
{(uint32_t *)0x08004000,FLASH_Sector_1},
{(uint32_t *)0x08008000,FLASH_Sector_2},
{(uint32_t *)0x0800c000,FLASH_Sector_3},
{(uint32_t *)0x08010000,FLASH_Sector_4},
{(uint32_t *)0x08020000,FLASH_Sector_5},
{(uint32_t *)0x08040000,FLASH_Sector_6},
{(uint32_t *)0x08060000,FLASH_Sector_7},
{(uint32_t *)0x08080000,FLASH_Sector_8},
{(uint32_t *)0x080a0000,FLASH_Sector_9},
{(uint32_t *)0x080c0000,FLASH_Sector_10},
{(uint32_t *)0x080e0000,FLASH_Sector_11},
};
#define FLASH_CLEAR_FLAG() \
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR|\
FLASH_FLAG_PGAERR|FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR|FLASH_FLAG_RDERR);
// 擦除指定扇区返回0成功-1失败
static int flash_erase(uint32_t FLASH_Sector)
{
self_def *s=&g_self;
FLASH_Status ret;
if(s->mutex==0){
s->mutex=rt_mutex_create("flash_mutex",RT_IPC_FLAG_FIFO);
}
rt_mutex_take(s->mutex,RT_WAITING_FOREVER);
FLASH_Unlock();
FLASH_CLEAR_FLAG();
FLASH_DataCacheCmd(DISABLE);
ret=FLASH_EraseSector(FLASH_Sector,VoltageRange_3);
rt_mutex_release(s->mutex);
if(ret!=FLASH_COMPLETE)
{
DBG_WARN("flash earse failed.ret=%d",ret);
return -1;
}else{
DBG_LOG("flash earse success.ret=%d",ret);
return 0;
}
}
// 操作结束
int flash_operate_end(void)
{
FLASH_Status state;
int ret=0;
self_def *s=&g_self;
#ifdef RT_THREAD
param_check(s->mutex);
#endif
rt_mutex_take(s->mutex,RT_WAITING_FOREVER);
FLASH_DataCacheCmd(ENABLE);
FLASH_Lock();
rt_mutex_release(s->mutex);
return 0;
}
// 参数区16K
int flash_erase_param(void)
{
int ret;
ret=flash_erase(FLASH_Sector_1);
if(ret!=0) return -1;
return 0;
}
//程序区1 256K
int flash_erase_app1(void)
{
int ret;
ret=flash_erase(FLASH_Sector_5);
if(ret!=0) return -1;
ret=flash_erase(FLASH_Sector_6);
if(ret!=0) return -1;
return 0;
}
//程序区2 256K
int flash_erase_app2(void)
{
int ret;
ret=flash_erase(FLASH_Sector_7);
if(ret!=0) return -1;
ret=flash_erase(FLASH_Sector_8);
if(ret!=0) return -1;
return 0;
}
//小板程序区 128K
int flash_erase_slave(void)
{
int ret;
ret=flash_erase(FLASH_Sector_9);
if(ret!=0) return -1;
return 0;
}
//方案区 16K
int flash_erase_scheme(void)
{
int ret;
ret=flash_erase(FLASH_Sector_2);
if(ret!=0) return -1;
return 0;
}
//脚本区 128K
int flash_erase_lua(void)
{
int ret;
ret=flash_erase(FLASH_Sector_11);
if(ret!=0) return -1;
return 0;
}
uint32_t *flash_get_param(void)
{
return (void *)0x08004000;
}
//uint32_t *flash_get_app1(void)
//{
// return (void *)0x08020000;
//}
uint32_t *flash_get_app2(void)
{
return (void *)0x08060000;
}
uint32_t *flash_get_slave(void)
{
return (void *)0x080a0000;
}
uint32_t *flash_get_scheme(void)
{
return (void *)0x08008000;
}
uint32_t *flash_get_lua(void)
{
return (void *)0x080e0000;
}
int flash_write(uint8_t *addr,const uint8_t *data,int len)
{
FLASH_Status state;
int ret=0;
self_def *s=&g_self;
if((uint32_t)data%4)
{
DBG_WARN("write addr err.");
return -1;
}
uint32_t *t=(uint32_t *)data;
uint32_t flash_addr=(uint32_t)addr;
#ifdef RT_THREAD
param_check(s->mutex);
#endif
rt_mutex_take(s->mutex,RT_WAITING_FOREVER);
//DBG_LOG("write flash addr=%08x",flash_addr);
len+=3;// len不是4字节对齐时强行增加到4字节
for(int i=0;i<len/4;i++)
{
//FLASH_CLEAR_FLAG();
//state=FLASH_ProgramByte((uint32_t)addr,data[i]);
state=FLASH_ProgramWord(flash_addr,t[i]);
flash_addr+=4;
if(state!=FLASH_COMPLETE)
{
DBG_WARN("flash write failed.ret=%d",state);
DBG_WARN("FLASH->SR=%08X",FLASH->SR);
ret=-1;
break;
}
}
if(memcmp(addr,data,(len/4)*4)!=0)
{
DBG_WARN("addr=%08x write/read data not equate.",addr);
ret=-2;
}
rt_mutex_release(s->mutex);
return ret;
}
uint8_t *flash_get_rom(rom_head **head)
{
uint8_t *src=(uint8_t *)flash_get_app2();
flash_file *file=(flash_file *)flash_get_app2();
rom_head *h=(rom_head *)(src+FLASH_FILE_HEAD_SIZE);
uint8_t *rom=src+ROM_HEAD_SIZE+FLASH_FILE_HEAD_SIZE;
if(file->file_size==0xffffffff){
return 0;
}
if(head) *head=h;
return rom;
}
int flash_updata_app(uint8_t *rom,uint32_t size)
{
uint8_t *dst=(uint8_t *)0x08020000;
flash_erase_app1();
return flash_write(dst,rom,size);
}
// 保存参数
int flash_save_param(sys_param_def *par)
{
uint8_t *dst=(uint8_t *)flash_get_param();
uint8_t *src=(uint8_t *)par;
int size=sizeof(sys_param_def);
flash_erase_param();
return flash_write(dst,src,size);
}
const sys_param_def *sys_param(void)
{
return (sys_param_def *)flash_get_param();
}
const scheme_def *check_scheme(void)
{
uint8_t *d=(uint8_t *)flash_get_scheme();
return (scheme_def *)(d+FLASH_FILE_HEAD_SIZE);
}