📄 hal.c
字号:
#include<instructions.h>
#include <types.h>
#include <bsp.h>
#define NOK 0
#define OK 1
#define EEPROM_CNTRL 0x98011240
#define EEPROM_BASE 0x88000000
#define EEPROM_SIZE 0x8000
#define FCU_MAIN_ADDR 0x80000000
#define FCU_MAIN_SIZE (32 * 1024 * 4)
#define FCU_INFO_ADDR 0x98010000
#define FCU_INFO_SIZE (256 * 4)
#define FCU_MAIN_PAGES 128
#define FCU_FCC_ADDR (FCU_INFO_ADDR + FCU_INFO_SIZE)
#define FCU_FWC_ADDR (FCU_INFO_ADDR + FCU_INFO_SIZE + 64)
#define BOOT_ROM_FLAG 0x1c00
#define FLASH_MAIN_BASE 0x80000000
#define FLASH_SIZE 0x20000
#define FLASH_PAGE_SIZE 1024
//写EEPROM函数
unsigned char WriteEeprom(char *Buf,int Add,int NbByte )
{
int i,j;
unsigned long addr=EEPROM_BASE,pos,mydata,tempdata,myaddr,count,lastaddr;
char *ptr,tempdata8,lastflag=0;
int totallen=0;
Add &=0x7fff;
pos=Add &3;
addr+=Add;
ptr=Buf;
if(addr+NbByte>EEPROM_BASE+EEPROM_SIZE)
return NOK;
// enable single-word erase + program
REG32(EEPROM_CNTRL)=3;
while(REG32(EEPROM_CNTRL)&0x80000000);
count = 0;
if(pos>0)
{
myaddr = addr&0xfffffffc;
mydata = REG32(myaddr);
if((pos+NbByte)>4)
{
memcpy((char *)(&mydata) +pos,Buf,4-pos);
count += 4-pos;
}
else
{
memcpy((char *)(&mydata) +pos,Buf,NbByte);
count = NbByte;
}
REG32(myaddr) = mydata;
ptr += (4-pos);
addr = myaddr +4;
}
while(REG32(EEPROM_CNTRL)&0x80000000);
totallen=NbByte-count;
while(totallen>0)
{
if(totallen >=4)
{
memcpy(&tempdata,ptr,4);
ptr+=4;
REG32(addr)=tempdata;
}
else
{
tempdata = REG32(addr);
memcpy(&tempdata,ptr,totallen);
ptr+=totallen;
REG32(addr)=tempdata;
lastaddr=addr;
lastflag=1;
}
totallen -=4;
// wait if eeprom busy
while(REG32(EEPROM_CNTRL)&0x80000000);
addr+=4;
if(totallen <=0)
break;
}
REG32(EEPROM_CNTRL)=0;
addr=EEPROM_BASE + Add;
for(j=0;j<10;j++)
{
i_dcache_invalidate();
if(pos>0)
{
if(REG32(myaddr)!= mydata)
return NOK;
}
if(lastflag==1)
{if(REG32(lastaddr)!= tempdata)
return NOK;
}
for(i=0;i<NbByte;i++)
{
tempdata8=REG8(addr+i);
if(tempdata8!=Buf[i])
return NOK;
}
}
return OK;
}
//功能描述:从EEPROM指定的地址Add开始填充Data指定的值,长度为NbByte。Add是EEPROM的虚拟地址
BYTE FillEeprom(BYTE Data, DWORD NbByte , DWORD Add)
{
int i,len,addr,writelen;
BYTE tempbuf[130];
memset(tempbuf,Data,128);
i=0;
len=NbByte;
addr=Add;
while(len)
{
if(len>128)
writelen=128;
else
writelen=len;
if(WriteEeprom(tempbuf,addr,writelen)==NOK)
return NOK;
len-=128;
addr+=128;
if(len<=0)
break;
}
return OK;
}
//功能描述:读指定长度的EEPROM数据到buf。
BYTE ReadEeprom(BYTE *Buf, DWORD Add, DWORD Length)
{
SHORT i;
DWORD addr=EEPROM_BASE;
Add &= 0x7fff;
addr+=Add;
if(addr+Length>EEPROM_BASE+EEPROM_SIZE)
return NOK;
i_dcache_invalidate();
for(i=0;i<Length;i++)
*Buf++=REG8(addr++);
return OK;
}
//功能描述:从FLASH指定的地址读数据到Buf,Add是FLASH的虚拟地址。数据长度不大于一个PAGE,允许跨页读取。
BYTE ReadFlash(BYTE *Buf, DWORD Add, DWORD Length)
{
WORD i;
DWORD addr=Add;
if(addr < FLASH_MAIN_BASE)
return NOK;
if(addr+Length>FLASH_MAIN_BASE+FLASH_SIZE)
return NOK;
for(i=0;i<Length;i++)
*Buf++=REG8(addr++);
return OK;
}
RAM_SYS_DATA DWORD __write_flash(DWORD newaddr ,DWORD *buf, DWORD length)
{
DWORD i=0;
DWORD *from;
DWORD addr=newaddr;
from = buf;
/*count position of flashrom*/
addr&=0x1ffff;
if(addr<0x2000)
return NOK;
/* enable page erase */
REG32(FCU_FWC_ADDR)=5;
if(addr<0x2000||length >0x1ffff)
{ REG32(FCU_FWC_ADDR)=0;
return NOK;
}
/* write a data to erase the page*/
REG32(FCU_MAIN_ADDR+addr)=0;
REG32(FCU_FWC_ADDR)=0;
/*enable single-word program */
REG32(FCU_FWC_ADDR)=1;
/*write data to dstaddr*/
for (i=0; i< length; i+=4)
REG32(FCU_MAIN_ADDR+addr+i)=*from++;
/*protect the flashrom*/
REG32(FCU_FWC_ADDR)=0;
return OK;
}
//功能描述:使能bootrom标记
int en_bootflag=0;
RAM_SYS_DATA void _enable_bootloader(int *flag)
{
/* enable page erase */
REG32(FCU_FWC_ADDR)=5;
if(*flag!=0x32346578)
{
REG32(FCU_FWC_ADDR)=0;
return;
}
/* write a data to erase the page*/
REG32(FCU_MAIN_ADDR+BOOT_ROM_FLAG)=0;
REG32(FCU_FWC_ADDR)=0;
*flag=0;
}
void ClearBootRomFlag(void)
{
en_bootflag=0x32346578;
_enable_bootloader(&en_bootflag);
}
//功能描述:写数据到指定的FLASH地址, 数据长度任意(不会大于一个PAGE),
//Add是FLASH的虚拟地址,允许跨页操作,不影响页内其它数据
BYTE WriteFlash(BYTE *Buf, DWORD Add,DWORD Length)
{
BYTE tempbuf[1024];
DWORD len,copylen;
DWORD pagestart_addr=0,pos=0;
BYTE *ptr;
DWORD i;
len=Length;
if(Add < FLASH_MAIN_BASE +0x2000)
return NOK;
if(Add+Length>FLASH_MAIN_BASE+FLASH_SIZE)
return NOK;
pagestart_addr = Add & 0xfffffc00;
pos = Add & 0x3ff;
copylen= FLASH_PAGE_SIZE -pos ;
ptr=Buf;
if(copylen > len)
copylen =len;
do
{
if(copylen < FLASH_PAGE_SIZE)
ReadFlash(tempbuf,pagestart_addr,FLASH_PAGE_SIZE);
memcpy(tempbuf+pos,ptr,copylen);
__write_flash((DWORD)pagestart_addr ,(DWORD *)tempbuf,FLASH_PAGE_SIZE);
pagestart_addr +=FLASH_PAGE_SIZE;
pos =0;
len -= copylen;
ptr+=copylen;
if(len > FLASH_PAGE_SIZE)
copylen = FLASH_PAGE_SIZE;
else
copylen = len;
}while(len>0);
return OK;
}
//功能描述:写一页(1K)数据到指定的FLASH。Add是FLASH的虚拟地址,且是该页的起始地址。
BYTE WriteFlashPage(BYTE *Buf, DWORD Add)
{
return __write_flash(Add,(DWORD *)Buf,FLASH_PAGE_SIZE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -