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

📄 main.c

📁 lpc213x的IAP程序
💻 C
字号:
#define IN_MAIN
#include "config.h"
#include "UART.h"
#include "IAP.h"


#pragma import(__use_no_semihosting_swi)        //don't delete this line

#define	UART0_n			0		//UART0
#define	UART0_baud		9600	//波特率57800
#define	UART0_datab		8		//8位数据位
#define	UART0_stopb		1		//1位停止位
#define	UART0_parity	2		//偶校验位
#define	UART0_IntEn		1		//中断禁止

#define	UART1_n			1		//UART0
#define	UART1_baud		1200	//波特率1200
#define	UART1_datab		8		//8位数据位
#define	UART1_stopb		1		//1位停止位
#define	UART1_parity	2		//偶校验位
#define	UART1_IntEn		1		//中断禁止

static uint16 DA;
static uint16 DT;
static uint16 SEQ;
static uint8  CS;
static uint16 DataLength; 
static CMode CM;
static SEQMode SM;
uint8  UARTn;


unsigned char U0Buffer[1024+5];


//返回类型定义
#define OPT_OK              0x01        //操作正常结束
#define WR_FLASH_ERR        0x02        //写Flash错误
#define CHECKSUM_ERR        0x02        //数据校验错误
#define PARMR_ERR           0x02        //参数错误
#define RUN_ERR             0x02        //运行新程序出错

void SendStatus(uint8 status)
{
 uint8  i;
 uint8  sum = 0;
 U0Buffer[0]=0x68;
 U0Buffer[5]=0x68;
 CM.Reg8=U0Buffer[6];
 CM.Bits.DIR=1;
 CM.Bits.PRM=0;
 CM.Bits.FCB=0;
 CM.Bits.FN =8;	                                                                                                     
 U0Buffer[6]=CM.Reg8;
 U0Buffer[1]=((12<<2)&0xfc)|0x1;
 U0Buffer[2]=(12>>6)&0xff;
 U0Buffer[3]=U0Buffer[1];
 U0Buffer[4]=U0Buffer[2];
 U0Buffer[12]=0;
 SM.Reg8=U0Buffer[13];
 SM.Bits.FIR=1;
 SM.Bits.FIN=1;
 SM.Bits.CON=0;
 U0Buffer[13]=SM.Reg8;
 U0Buffer[14]=0;
 U0Buffer[15]=0;
 U0Buffer[16]=status;
 U0Buffer[17]=0;
 for(i =  0; i < 12; i++)
 {
   sum +=U0Buffer[6+i];
 }

 U0Buffer[18]=sum;
 U0Buffer[19]=0x16;
 UARTn_SendData(UARTn,&U0Buffer[0],20);
}


void delay(uint32 dly)
{
    for(; dly > 0; dly--);
}

//串口数据接收
uint16 RcvData()
{
    uint8 tmp = 0;
    uint16 i;
    uint16 len;
    uint8  sum = 0;
    uint32 rcvsum = 0;
    
    uint8 tt[3];
    
    							    
    while(1)	    //等待帧头
    {
      UARTn_RcvData(0, &U0Buffer[0], 1);
	  if(U0Buffer[0] == 0x68)
	  break;
    } 
    
    UARTn_RcvData(UARTn,&U0Buffer[1],5);   //接收数据长度值

    len=64*U0Buffer[2]+((U0Buffer[1]&0xfc)>>2);
    
        
    if((len > 1024)||(U0Buffer[0]!=0x68)||(U0Buffer[5]!=0x68))
    {
        delay(10000);
		return 1;			//返回参数错误      
    }
    for(i =  0; i < len+2; i++)
    {
	 UARTn_RcvData(UARTn, &U0Buffer[i+6],1);  //接收数据 
	
	} 									 
    for(i =  0; i < len; i++)
    {
        
        sum +=U0Buffer[6+i];
    }
       
    delay(1000);
    
    if((U0Buffer[len+6]==sum)&&(U0Buffer[len+7]==0x16))
    {
     SM.Reg8=U0Buffer[13];

     return 0;
	}
	else
	 return 1;   
}



void DataCpy(uint8 *dst, uint8 *src, uint32 num)
{
    uint32 i;
    for(i = 0; i < num; i++)
	{
	    dst[i] = src[i];
	} 
}


//将Flash中的数据保存到RAM中。
uint32 FlashToRam(uint32 dst, uint32 src, uint32 no)
{
	uint8 *pSrc;
	uint8 *pdst;
	uint32 i;
	
	pSrc = (uint8 *)src;
	pdst = (uint8 *)dst;
	
	for(i = 0; i < no; i++)
	{
	    pdst[i] = pSrc[i];
	}
	
	return 0;
	 									    
}

//新程序向量表累加和测试。若新程序的累加和为零则说明有新程序可运行。
uint32 TestVectorList(uint32 *pVlst)
{
    uint32 sum = 0; 
    uint8 i;
    
    for(i = 0; i <8; i++)
    {
        sum+= pVlst[i];   
    }
    
    if(sum != 0)
    {
        return 1;  //返回中断向量表和不为零错误
    }
    
    return 0;      //中断向量表和为零 则返回零
}


//运行新程序
uint32 RunPrg(void)  
{

    void (*pfunc)();    //函数指针
    
    if(TestVectorList((uint32 *)0x00002000)!= 0)
    {
        return 1;     // 中断向量表不为零,无更新程序可运行
    }            
    
    //将新程序的中断向量表(起始地址0x00001000)复制到RAM(起始地址0x40000000)中。
    DataCpy((uint8 *)0x40000000, (uint8 *)0x00002000, 64);	
     
    MEMMAP = 0x2;                     //将中断向量remap到RAM中。

    pfunc =( void (*)()) 0x40000000;  //函数指针指向新程序的中断向量表起始地址

    ( *pfunc)();	                  //启动新程序
    
    return 0;                         //返回 

}

//超时等待程序升级同步信息
uint32 WaitForSync(uint8 overtime)
{
    
    if(UARTn_RcvData_SE(&U0Buffer[0],28, overtime) == 1)
    {
        return 1;      //接收超时,说明无升级同步信息,不进行代码升级操作
    }
    
    if((U0Buffer[0]!= 0x68)||(U0Buffer[5]!=0x68)||(U0Buffer[12]!=0x0f))
    {
        return 1;      //接收错误
    }
    
    SendStatus(OPT_OK);	//返回同步成功
    return 0;		    //有同步信息
}


uint32  RamBuf[4096];			     //程序数据临时缓冲区,共1024字(4096字节)

#define FLASH_ADDR  4096             //Secorter1的起始地址  即新程序保存的起始地址





/*********************************************************************************************************
** 函数功能:Main()
** 函数功能:IAP-BootLoader
********************************************************************************************************/
int main(void)
{

	uint32 addr;
	uint16 nlen;
	uint32 rcv_back[8];
	uint8 *pRam;
	
	
//    TargetInit(VPBDIV_DATA, PLLCFG_DATA, MAMTIM_DATA);      // don't delete
//    while((PLLSTAT & (1 << 10)) == 0);                      // can delete
    PINSEL0 = (0x01<< 0)|   //TXD0
	          (0x01<< 2)|   //RXD0
			  (0x01<< 4)|   //SCL0
			  (0x01<< 6)|   //SDA0
			  (0x01<< 8)|   //SCK0
			  (0x01<<10)|   //MISO0
			  (0x01<<12)|   //MOSI0
			  (0x00<<14)|   //P0.7
			  (0x01<<16)|   //TXD1
			  (0x01<<18)|   //RXD1
			  (0x01<<20)|   //CAP1.0
			  (0x03<<22)|   //SCL1
			  (0x03<<24)|   //AD1.3
			  (0x00<<26)|   //P0.13
			  (0x03<<28)|   //SDA1
			  (0x00<<30);   //P0.15
	PINSEL1 = (0x01<< 0)|   //EINT0
	          (0x02<< 2)|   //SCK1
			  (0x02<< 4)|   //MISO1
			  (0x02<< 6)|   //MOSI1
			  (0x02<< 8)|   //SSEL1
			  (0x01<<10)|   //PWM5
			  (0x00<<12)|   //P0.22
			  (0x00<<14)|   //P0.23
			  (0x00<<16)|   //
			  (0x00<<18)|   //P0.25
			  (0x00<<20)|   //P0.26
			  (0x00<<22)|   //P0.27	
			  (0x00<<24)|   //P0.28
			  (0x00<<26)|   //P0.29
			  (0x00<<28)|   //P0.30
			  (0x00<<30);   //P0.31
	PINSEL2 = (PINSEL2 & 0xFFFFFFF3)|(0x01<<2); 
   	IO0DIR = 0xFAFAE9DD; 	   // 设置
	IO1DIR = 0x03EF0000;
    
	IO0SET = ERR; 
	IO0CLR = DE1;
	IO0SET=LRX; 
	IO0SET=QOUT;
	IO0SET=OUT1;
	IO0SET=OUT2;
    IO0SET=OUT3;
	IO1SET=LTX;
	IO1CLR = RUN;
	IO1SET=POUT;
	IO1SET=OUT4; 
	WDTC=0x00fff000;
	WDMOD=0x03;
	WDFEED=0xaa;
	WDFEED=0x55;
    UARTn_Init(UART0_n,UART0_baud,UART0_datab,UART0_stopb,UART0_parity,UART0_IntEn);
    UARTn_Init(UART1_n,UART1_baud,UART1_datab,UART1_stopb,UART1_parity,UART1_IntEn);

	Set_FIFO(0,1);                 //设置FIFO大小为1个字节。
    Set_FIFO(1,1);                 //设置FIFO大小为1个字节。

    pRam = (uint8 *)RamBuf ;	   //指向数据缓冲区
	
	UARTn=0;
	while(1)
	{
    	WDFEED=0xaa;
	    WDFEED=0x55;
	
    }
    
    while(1)
    {
      
	 WDFEED=0xaa;
	 WDFEED=0x55;
	 
		if(RcvData() !=0)            //串口接收
        {
            SendStatus(PARMR_ERR);	 //返回参数错误

            continue;
        }
 		addr = ((U0Buffer[18]<<24)+(U0Buffer[19]<<16)+(U0Buffer[20]<<8)+U0Buffer[21]);
		if(addr>=0x00009100)  //写Flash功能,下载新程序到起始地址为 0x00001000的flash中
		{
		 addr=addr;
		}
        if((addr<0x00080000)&&(addr>=0x00002000))  //写Flash功能,下载新程序到起始地址为 0x00001000的flash中
		{
            
            nlen = ((U0Buffer[23]<<8)+U0Buffer[22]);
            
            FlashToRam((uint32)RamBuf, 4096*(addr / 4096), 4096);  //将Flash中的数据复制到RAM中

            DataCpy(&pRam[0],&U0Buffer[24], nlen);	           //更新RAM中的数据
                	    
            ReadParID(rcv_back);
            BootCodeID(rcv_back);  

            if(0 == WriteFlash(addr, (uint32)pRam, nlen))
            {
                SendStatus(OPT_OK);	          //返回操作成功
            }
            else
            {
                SendStatus(WR_FLASH_ERR);	  //返回写flash错误
            }
		}
        if(addr==0xffffffff)
		{   
         
            SendStatus(OPT_OK);	      //返回命令接收成功
          	RunPrg();                 //若不能运行新程序,则再次进入在线升级状态
          	SendStatus(RUN_ERR);	  //返回新程序运行错误 
        }  	
             
       
             
       
        
    }
     
     
  return(0);     
}
/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

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