- // 定义EEPROM的起始地址和大小
- #define EEPROM_START_ADDRESS 0x5000
- #define EEPROM_SIZE 0x5000
-
- // 定义接收和发送数据的缓冲区
- #define BUFFER_SIZE 256
- uint8_t recv_buf[BUFFER_SIZE];
- uint8_t send_buf[BUFFER_SIZE];
-
- typedef void (*FunctionPointer)(void);
- FunctionPointer entry_app = (FunctionPointer)0x5000;
-
- void IapProgram(int addr, int dat)
- {
- IAP_CONTR = 0x80; //使能IAP
- IAP_TPS = 12; //设置等待参数12MHz
- IAP_CMD = 2; //设置IAP写命令
- IAP_ADDRL = addr; //设置IAP低地址
- IAP_ADDRH = addr >> 8; //设置IAP高地址
- IAP_DATA = dat; //写IAP数据
- IAP_TRIG = 0x5a; //写触发命令(0x5a)
- IAP_TRIG = 0xa5; //写触发命令(0xa5)
- _nop_();
- IapIdle(); //关闭IAP功能
- }
-
- // 接收一个字节的数据
- uint8_t receive_byte() {
- SPDAT = 0xff;
- while((SPSTAT & SPIF) == 0) ;
- SPSTAT = SPIF + WCOL; //清0 SPIF和WCOL标志
- return (SPDAT);
- }
-
-
- // 定义一个函数从外置SPI Flash中读取数据
- void read_flash(uint32_t address, uint8_t *dat, uint32_t sz)
- {
- if(sz == 0) return;
-
- while(CheckFlashBusy() > 0); //Flash忙检测
-
- SPI_CS = 0; //enable device
- send_byte(0x03); //read command
-
- send_byte(((u8 *)&address)[1]); //设置起始地址
- send_byte(((u8 *)&address)[2]);
- send_byte(((u8 *)&address)[3]);
-
- do{
- *dat = receive_byte(); //receive byte and store at buffer
- dat++;
- }while(--sz); //read until no_bytes is reached
- SPI_CS = 1; //disable device
- }
-
- // 定义一个函数将应用程序从外置SPI Flash中拷贝到EEPROM中
- void copy_app_to_eeprom() {
- uint32_t app_size;
- uint16_t addr;
- uint16_t rev;
- uint32_t k;
-
- uint32_t offset;
- uint32_t sz;
- uint8_t TEST = 0x55;
-
- Get_App_Size((unsigned int*)&app_size);
-
- // 擦除EEPROM
- for (addr = EEPROM_SIZE; addr < EEPROM_SIZE+ EEPROM_SIZE; )
- {
- IapErase(addr);
- addr = addr+512;
- }
-
- app_size = 0x4800;//暂时手动设置读取的大小
- sz = BUFFER_SIZE;
- for (k = 0; k < app_size; ) {
- offset = 0 + k;
- read_flash(offset, recv_buf, sz);
- for (rev = 0; rev < sz; rev++) {
- IapProgram(EEPROM_START_ADDRESS + k + rev, recv_buf[rev]);
- }
- k += BUFFER_SIZE;
- }
- }
-
- void SPI_init(void)
- {
- P2M0 &= ~0x3e;
- P2M1 &= ~0x3e;
- SPCTL |= (1 << 7); //忽略 SS 引脚功能,使用 MSTR 确定器件是主机还是从机
- SPCTL |= (1 << 6); //使能 SPI 功能
- SPCTL &= ~(1 << 5); //先发送/接收数据的高位( MSB)
- SPCTL |= (1 << 4); //设置主机模式
- SPCTL &= ~(1 << 3); //SCLK 空闲时为低电平,SCLK 的前时钟沿为上升沿,后时钟沿为下降沿
- SPCTL &= ~(1 << 2); //数据 SS 管脚为低电平驱动第一位数据并在 SCLK 的后时钟沿改变数据
- SPCTL = (SPCTL & ~3) | 3; //SPI 时钟频率选择, 0: 4T, 1: 8T, 2: 16T, 3: 32T
- P_SW1 = (P_SW1 & ~(3<<2)) | (1<<2); //IO口切换. 0: P1.2/P5.4 P1.3 P1.4 P1.5, 1: P2.2 P2.3 P2.4 P2.5, 2: P5.4 P4.0 P4.1 P4.3, 3: P3.5 P3.4 P3.3 P3.2
-
- SPI_CLK = 0; // set clock to low initial state
- SPI_SI = 1;
- SPSTAT = SPIF + WCOL; //清0 SPIF和WCOL标志
- }
-
- void main() {
- // 初始化SPI
- SPI_init();
- // FlashCheckID();
- // FlashCheckID();
-
- should_copy_app_to_eeprom = 1; // 判断是否需要将应用程序拷贝到EEPROM中
- if (should_copy_app_to_eeprom) {
- copy_app_to_eeprom();
- }
-
- // 跳转到应用程序的地址
- EA = 0;
- entry_app();
- }
复制代码
|