⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hal.c

📁 中兴单片机COS系统
💻 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 + -