📄 main.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 + -