288 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			288 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
 | 
						||
 | 
						||
#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);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 |