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

📄 flashtest.c

📁 DSP5000中的FLASH烧写程序
💻 C
字号:
#include <csl.h>
#include <csl_emif.h>
#include <csl_chiphal.h>
#include <csl_gpio.h>
#include <csl_pll.h> 
#include <stdio.h>
#include  "EmifConfig.h"
#include   "date.h"

void ChipErase(void);  //FLASH擦除函数
void EraseCheck(void);
void BurnBlock(Uint16* pdata,Uint16 FlashDstAddr,Uint16 nWords); //FLASH连续烧写函数
void BurnWord (Uint16 Addr, Uint16 Val); //对FLASH写入一个字
void WriteCommand(Uint16 Addr, Uint16 Value);
Uint16 ReadFlash(Uint16 Addr);
void BurnInfoPrtf(void);
void WriteOrEraseIsOver(void);     //判断D6位,确定FLASH写或者擦写操作是否结束
void EntryID(void);  //进入读FLASH ID模式
void ExitID(void);   //退出读ID 模式( EntryID 与 ExitID 应成对使用)
void Lockout(void);  //对BOOT区上锁
void SetGpio01HiAddr(Uint16 Addr);  //FLASH 高两位操作(A14  A15)
void Delayus(Uint16 nusSum);//延时2us程序
void Delays(Uint16 nsSum);

#define	FLASH_BASE_ADDR		0x200000	//linear base word address
#define FLASH_SIZE          0xFFFF
#define PROG_SIZE           0xffff
#define	FCP5			    (FLASH_BASE_ADDR+0x5555)		//flash command port 5
#define	FCPA			    (FLASH_BASE_ADDR+0x2aaa)		//flash command port A

PLL_Config MyConfig = {
1,   /* iai      */
1,   /* iab      */           /*   F=[晶振频率/(div+1)]*pllmult     */
31,  /* pllmult  */           /*   通过调节pllmult值来调节工作频率   */
3    /* div      */           /*   F=[24/(3+1)]*31=186MHz    约5.3ns */
};

Uint16 ErrorBurnAddrTab[1000];
Uint16 AddrTabCnt=0;

#pragma DATA_SECTION(ErrorBurnAddrTab,".my_sect");



void main()
{
     Uint16 *DataSource;
     DataSource=(Uint16*)0x800e;    //数据区起始地址(0x8000b)+2字

     IRQ_globalDisable();           //禁止所有可屏蔽的中断源

     CSL_init();                    //初始化

     PLL_config(&MyConfig);

     CHIP_RSET(XBSR,0x0281);        //EMIF为全EMIF接口

     EMIF_config(&Config_emif);     //配置EMIF

     GPIO_pinDirection(GPIO_PIN0,GPIO_OUTPUT); //将IO0和IO1设成输出口
     GPIO_pinDirection(GPIO_PIN1,GPIO_OUTPUT);

//延时时间测试
/*
	while(1)
	{
	GPIO_pinWrite(GPIO_PIN0,0);
	Delayus(30);
	GPIO_pinWrite(GPIO_PIN0,1);
	Delayus(40);
	}
*/
     Delayus(100);		
     EntryID();      // 读ID
     Delayus(100);
     ExitID();       // 退出读ID模式
     Delayus(100);
     ChipErase();	 // Flash 擦除
     Delayus(100);
     EraseCheck();   // Flash 擦除校验
     Delayus(100); 
     BurnBlock(DataSource,FLASH_BASE_ADDR,PROG_SIZE);  //  Flash块烧写
     Delayus(100);     
     BurnInfoPrtf();  // 打印烧写信息
           
     while(1){}

}



/*************************************
                子程序
**************************************/

/*********** FLASH 擦除 **************/
void ChipErase(void)   
{
    WriteCommand(0x5555,0xaa);
    WriteCommand(0x2aaa,0x55);
    WriteCommand(0x5555,0x80);
    WriteCommand(0x5555,0xaa);
    WriteCommand(0x2aaa,0x55);
    WriteCommand(0x5555,0x10);
	WriteOrEraseIsOver();	
}
   
   
/*********** 擦除校验 ****************/
void EraseCheck(void)
{
     Uint16 i;
     Uint16 ErrorFlag=0;
     Uint16 EraseTemp;
     for(i=0;i<FLASH_SIZE;i++)
       {
        EraseTemp=ReadFlash(i); 
          if(EraseTemp!=0xFFFF)
  	         ErrorFlag++;
       }
       
     if(ErrorFlag==0)
         printf("\nChipErase is successful! \n");
     else
         printf("ChipErase failed %d times!\n",ErrorFlag);
}

/********** FLASH 烧写************/
void BurnBlock(Uint16 * pdata,Uint16 FlashDstAddr,Uint16 nWords)
{
     Uint16 i,j;
	 Uint16 ReadTemp;
	 for(i=0;i<nWords;i++)
	 {
	    BurnWord(i,*(pdata+i)); //flash_date[i]) ;
        ReadTemp=ReadFlash(i);
	    if(ReadTemp!=*(pdata+i))  //判断是否烧写成功
	    {
	       for(j=0;j<10;j++)       //烧写失败,重复对该单元烧写 10 次
	       {
	          BurnWord(i,*(pdata+i));	       
 	       }
 	       ReadTemp=ReadFlash(i);	 //重复烧写5次后,判断是否烧写成功    
	       if(ReadTemp!=*(pdata+i))  
	       {
	          ErrorBurnAddrTab[AddrTabCnt]=i; //失败!纪录烧写失败单元的地址
	          AddrTabCnt++;
	       }
	    }
     }
}
 
 
/******************************************
         FLASH 单个字的读写操作
在对FLASH的读写操作中,传递参数中的地址
是FLASH的空间地址而不是EMIF空间地址
*******************************************/

/********* 向 FLASH 烧一个字  ********/	
void BurnWord (Uint16 Addr, Uint16 Val)
{
		WriteCommand(0x5555,0xaa);
		WriteCommand(0x2aaa,0x55);
		WriteCommand(0x5555,0xa0);
		WriteCommand(Addr,Val);
		WriteOrEraseIsOver();
		Delayus(20);
}

/********** 写控制或数据命令 ***********/
void WriteCommand(Uint16 Addr, Uint16 Value)
{
		SetGpio01HiAddr(Addr);
		*(volatile Uint16 *)(FLASH_BASE_ADDR+Addr)=Value;
}

/********* 读 FLASH ********/
Uint16 ReadFlash(Uint16 Addr)
{
        Uint16 Value;
        SetGpio01HiAddr(Addr);
        Value=*(volatile Uint16 *)(FLASH_BASE_ADDR+Addr);
        return(Value);
}


/*********打印烧写信息*******/
void BurnInfoPrtf(void)
{
    Uint16 i;
    if(AddrTabCnt==0)
       {
         printf("\nFlash burn succeful! \n");
       }
    else
       { 
        printf("\nFlash burn failed %d times!\n",AddrTabCnt);   
        for(i=0;i<AddrTabCnt;i++)
         {
           printf("Flash Burn Error Adderss is : %x! \n",ErrorBurnAddrTab[i]);
         }

       }
}
  

/********* 操作结束标志判断 *************/
void WriteOrEraseIsOver(void)
{
	 volatile Uint16 LastToggleBit,CurrentToggleBit;	
	 LastToggleBit= (*(volatile Uint16 *)(FLASH_BASE_ADDR))&0x40;
	 CurrentToggleBit=(*(volatile Uint16 *)(FLASH_BASE_ADDR))&0x40;
	 while(1)
	 {
		if(LastToggleBit==CurrentToggleBit)
	 	break;
		LastToggleBit=CurrentToggleBit;
		CurrentToggleBit=(*(volatile Uint16*)(FLASH_BASE_ADDR))&0x40;
	 }
}

/***********进入读 FLASH ID模式****************/  
void EntryID(void)
{
    int Manufacturer_code;
    int Device_Code;

	WriteCommand(0x5555,0xaa);
	WriteCommand(0x2aaa,0x55);
	WriteCommand(0x5555,0x90);
	
    Manufacturer_code = ReadFlash(0x0);  
    Device_Code = ReadFlash(0x1);
       
    if(Manufacturer_code==0x001f)
      {
        printf("Manufacturer code: 001f\n");
      }
    else 
      {
        printf("Manufacturer code error!\n");
      }
    
    if(Device_Code==0x0087)
      {
        printf("Device code: 0087\n");
      }
    else 
      {
        printf("Device code error!\n");
      }
}


/*************退出读 FLASH ID模式*************/
void ExitID(void)
{
 	WriteCommand(0x5555,0xaa);
 	WriteCommand(0x2aaa,0x55);
 	WriteCommand(0x5555,0xf0);
}

/*********** 对 FLASH 前 8K 字上锁 ***********/
void Lockout(void)
{
    WriteCommand(0x5555,0xaa);
    WriteCommand(0x2aaa,0x55);
    WriteCommand(0x5555,0x80);
    WriteCommand(0x5555,0xaa);
    WriteCommand(0x2aaa,0x55);
    WriteCommand(0x5555,0x40);
}
		
/********** 高两位地址设置 ***********/
void SetGpio01HiAddr(Uint16 Addr)
{
      Uint16 A14,A15,Temp;
      Temp=Addr>>14;
      A14=Temp&0x01;
      A15=Temp>>1;
      GPIO_pinWrite(GPIO_PIN0,A14);   //14
      GPIO_pinWrite(GPIO_PIN1,A15);   //15
      Delayus(2);   
}


/**********延时函数***************/
void Delayus(Uint16 nusSum)  //186 MHz工作频率下,延时 N个us;
{
   int i,j,k;
   for(i=0;i<nusSum;i++)
   {
      k=0;                  //使程序不进行编译优化处理;
     for(j=0;j<13;j++)
     {
      k=0;
     }
   }
}


void Delays(Uint16 nsSum) //延时 N个s;
{
  int i,j,k;
  for(i=0;i<nsSum;i++)
  {
      k=0;
    for(j=0;j<100000;j++)
    {
      k=0;
    }
  }
}




   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -