📄 binload.c
字号:
/*/ binload.c : BINFile的DownLoad和Flash写入。/*/
//Writemode FLASH Vendor
// 0 AMD, FUJITSU and so on
// 1 SST
// 2 WINBOND
#include "uapdef.h"
#include "binload.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#pragma INTERRUPT OnUARTTxEnd
#pragma INTERRUPT OnUARTRxEnd
#pragma ADDRESS S0TIC 51H
#pragma ADDRESS S0RIC 52H
#pragma ADDRESS U0MR 3A0H
#pragma ADDRESS U0BRG 3A1H
#pragma ADDRESS U0TB 3A2H
#pragma ADDRESS U0C0 3A4H
#pragma ADDRESS U0C1 3A5H
#pragma ADDRESS U0RB 3A6H
#pragma ADDRESS UCON 3B0H
#pragma ADDRESS TA4IC 59H
#pragma ADDRESS TABSR 380H
#pragma ADDRESS ONSF 382H
#pragma ADDRESS TRGSR 383H
#pragma ADDRESS UDF 384H
#pragma ADDRESS TA4 38EH
#pragma ADDRESS TA4MR 39AH
#pragma ADDRESS CPSRF 381H
#pragma ADDRESS PM0 04H
#pragma ADDRESS PRCR 0AH
#pragma ADDRESS PD7 3EFH
#pragma ADDRESS P7 3EDH
#pragma ADDRESS PD9 3F3H
#pragma ADDRESS P9 3F1H
#pragma ADDRESS SYSCLK 40F9H
#pragma ADDRESS BANKEN 4128H
#pragma ADDRESS BANKREG 4129H
#pragma ADDRESS PRCR 000AH
struct _PORT {
BYTE bit0:1;
BYTE bit1:1;
BYTE bit2:1;
BYTE bit3:1;
BYTE bit4:1;
BYTE bit5:1;
BYTE bit6:1;
BYTE bit7:1;
};
WORD U0TB, U0RB, TA4;
BYTE S0TIC, S0RIC, U0MR, U0BRG, U0C0, U0C1, UCON;
BYTE TA4IC, TABSR, ONSF, TRGSR, UDF, TA4MR, CPSRF, PM0, PRCR;
BYTE PD9, P9, PD7, P7;
BYTE SYSCLK;
BYTE BANKEN, BANKREG;
#define MAXUARTTXBUFFER 255 /*/// 送信BufferSize。/*/
#define MAXUARTRXBUFFER 255 /*/// 受信BufferSize。/*/
#define FLASHTYPE_UNDEFINED 0
#define FLASHTYPE_8MTOPBOOT 1
#define FLASHTYPE_COMBOFALSH 2
#define FLASHTYPE_16MTOPBOOT 4
BYTE FlashType = FLASHTYPE_UNDEFINED;
RINGBUFF UARTTx, UARTRx;
BYTE abTxData[MAXUARTTXBUFFER]; /*/// 送信DataBuffer。/*/
BYTE abRxData[MAXUARTRXBUFFER]; /*/ 受信DataBuffer。/*/
BYTE bXModemSequenceBlockNumber; /*/ 受信XModem的Sequence.Block号码/*/
BYTE cbXModemRxCharacter; /*/ XModem的DataBlock受信Byte数/*/
BYTE far * npabXModemFileWrite; /*/ 受信File的写入Pointer/*/
BYTE abXModemFileWrite[512]; /*/ 受信File的写入Buffer,每次256字节,乒乓工作/*/
BYTE abXModemFreeBlock[4]; /*/ File的写入Buffer中,空的Block/*/
BYTE bXModemWritingBlock; /*/ 写入中的Buffer的Block号码/*/
BINFILEHEADER BinFileHeader; /*/ BINFile的Header的保存Buffer/*/
BYTE SectorStartAddressIndex; /*/边界地址的序号/*/
BYTE szDial[10]; /*/ 设为原状的程序中,工作使用的Buffer/*/
BYTE bStatus; /*/ 现在的状态。 /*/
BYTE far * lpabFlashMemory; /*/ 指向将要写入的FlashMemory的Pointer/*/
BYTE far * lpabFlashMemoryEnd; /*/ 将要写入的FlashMemory的终了Address/*/
//BYTE bWriteMode; /*/ 写入模式。 /*/
BYTE ManufacturerCode, DeviceCode; /*/ 生产商代码和器件代码 /*/
DWORD WriteAddress;
/*/波特率为115200的下载程序版本号为3以上。/*/
/*/4.0版增加了对FLASH擦除时超时的处理/*/
//const BYTE szVersionMessage[] = "Welcome to flash downloader V3.0.\r\n";
const BYTE szExit[] = "Exit? (Yes/No/Reset)\r\n";
//const BYTE szDownloadPrompt[] = "Please send the bin file to flash by Xmodem protocol.\r\n";
const BYTE szProgramFailure[] = "Undefined Flash Type. Program failed\r\n";
const BYTE szVersion[] = "EPFLASHV3.0\r\n";
void CS0AddressTransform(DWORD dwPhysicalAddress);
BOOL DetectFlashType(void);
BOOL FlashEraseSector(DWORD sectoraddr);
void FlashReset(void);
void FlashChipErase(void);
/////////////////////////////////////////////////////////////////////////////
// main : binload的MainRoutine。
void main(void)
{
BYTE c; /*/ 为了数据的发送的变量。 /*/
SYSCLK = 0x02; /*/ 采用9.6M的时钟 /*/
P9 &= 0x7f; /*/ 关绿指示灯 /*/
P9 |= 0x40; /*/点亮红指示灯 /*/
PRCR|=0x04; /*/ PRCR 写入允许 /*/
PD9 |= 0xc0; /*/ 关红绿指示灯 /*/
PRCR&=0xfb;//PD9的操作的禁止/
BANKEN = 0x91;//10010001B; /*/CS0\CS2扩展/*/
UARTTx.abData = abTxData; /*/ 送信Buffer的设定。 /*/
UARTTx.cbData = 0; /*/ Data数的清除。 /*/
UARTTx.bWriteIndex = 0; /*/ 写入位置设为先头。 /*/
UARTTx.bReadIndex = 0; /*/ 读入位置设为先头。 /*/
UARTTx.bSize = MAXUARTTXBUFFER; /*/ 送信BufferSize的设定。 /*/
UARTRx.abData = abRxData; /*/ 受信Buffer的设定。 /*/
UARTRx.cbData = 0; /*/ Data数的清除。 /*/
UARTRx.bWriteIndex = 0; /*/ 写入位置设为先头。 /*/
UARTRx.bReadIndex = 0; /*/ 读入位置设为先头。 /*/
UARTRx.bSize = MAXUARTRXBUFFER; /*/ 受信BufferSize的设定。 /*/
U0MR = 0x05; /*/ 流控无效、Parity无、Stop1、内部Clock、8Bit。 /*/
U0C0 = 0x10; /*/ TxD0为CMOS、CTS禁止、CountSource设为f1。LSB FIRST!!!!! /*/
UCON = 0x00; /*/ CTS和RTS设为共通端子。 /*/
U0BRG = 4; /*/ 设为5分频。9.6MHz/16/5 = 120000bps。 /*/
U0C1 = 0x05; /*/ 送受信许可。 /*/
S0TIC = 0x03; /*/ UART0送信中断控制Register的IPL设为3。 /*/
S0RIC = 0x03; /*/ UART0受信中断控制Register的IPL设为3。 /*/
asm("fclr I"); /*/ 中断禁止。 /*/
P9 &= 0xfd; /*/ WP设为Low。 /*/
PRCR |= 0x04; /*/// ProtectRegister的Bit2设为1。 /*/
PD9 |= 0x02; /*/ WP设为输出Port。 /*/ // upd 2000.02.08 sawada 0x03(WR_PRT1、WR_PRT2) -> 0x02(WP)
asm("fset I"); /*/ 中断许可。 /*/
BinFileHeader.Struct.WriteMode = 0; //default JDDEC command set
bStatus = 1; /*/ 现在的状态设为最初的CR等待状态。 /*/
TA4IC = 0; /*/ TimerA4中断要求的清除。 /*/
while (TRUE) { /*/ 无限Loop。 /*/
if (UARTRx.cbData || TA4IC & 0x08) { /*/ 受信Data有的时候、TimerA4为OneShortTimeOut时 /*/
switch (bStatus) {
case 1 : /*/ CR等待状态 /*/
ReadUART(&c, 1); /*/ 1Byte受信。 /*/
if (c == CR) { // CR detect
FlashUART(); /*/ 送受信Buffer的Flash。 /*/
DetectFlashType(); /*/判断FLASH类型,并将结果输出到超级终端/*/
c = NAK; /*/ NAK的装入。 /*/
WriteUART(&c, 1); /*/ NAK的送信。 /*/
TA4MR = 0x82; /*/ TimerA4以4.8/32MHz=150KHz设为OneShortTimer。 /*/
TA4IC = 0; /*/ TimerA4中断要求的清除。 /*/
TA4 = 0xFFFF; /*/ 0.43秒的TimeOut。 /*/
CPSRF = 0x80; /*/ 时钟用的Prescale的Reset。 /*/
TABSR |= 0x10; /*/ TimerA4Count开始Flag的Set /*/
ONSF |= 0x10; /*/ OneShort开始。 /*/
c = 0; /*/ 在NAKTimer的Count中使用。 /*/
bStatus = 2; /*/ XModem的开始等待状态。 /*/
}
break;
case 2 : /*/ XModem的开始等待状态 /*/
if (UARTRx.cbData) { /*/ 受信Data有的时候 /*/
bXModemSequenceBlockNumber = 0xFF; /*/ 受信XModem的Sequence.Block号码进行初始化。 /*/
cbXModemRxCharacter = 0; /*/ XModem的DataBlock受信Byte数进行初始化。 /*/
npabXModemFileWrite = abXModemFileWrite; /*/ 写入受信File的Pointer设置到Buffer的先头。 /*/
abXModemFreeBlock[0] = abXModemFreeBlock[1] = abXModemFreeBlock[2] = abXModemFreeBlock[3] = 0; /*/ 写入File的Buffer的Block设为全Block空。 /*/
bXModemWritingBlock = 0; /*/ 写入中的Block号码设为先头。 /*/
TABSR &= (~0x10); /*/ TimerA4Count开始Flag进行Reset。 /*/
TA4IC = 0; /*/ TimerA4中断要求的清除。 /*/
bStatus = 3; /*/ BINHeader等待状态。 /*/
break; /*/ 跳出Loop,用XModem开始进行受信。 /*/
} else if (TA4IC & 0x08) { /*/ OneShortTimeOut时 /*/
c ++; /*/ TimeOut回数的增加。 /*/
if (c == 5) { /*/ 5回TimeOut时 /*/
c = NAK; /*/ NAK的装入。 /*/
WriteUART(&c, 1); /*/ NAK的送信。 /*/
c = 0; /*/ Counter的清除。 /*/
}
TA4IC = 0; /*/ TimerA4中断要求的清除。 /*/
ONSF |= 0x10; /*/ OneShort开始。 /*/
}
break;
case 3 : /*/ BINHeader等待状态 /*/
c = OnRxXModem(); /*/ File的受信。 /*/
switch (c) {
case 1 : /*/// 2Block受信时 /*/
memcpy(BinFileHeader.abBINHeader, abXModemFileWrite, 256); /*/// BINFileHeader的拷贝。 /*/
abXModemFreeBlock[0] = abXModemFreeBlock[1] = 0; /*/ Block设为空。 /*/
if (StartProgram(BinFileHeader.abBINHeader)) { /*/// Flash写入能够开始时 /*/
c = ACK; /*/// ACK的装入。 /*/
WriteUART(&c, 1); /*/// ACK的送信。 /*/
bStatus = 4; /*/// Flash写入状态。 /*/
} else { /*/ Flash写入不能开始时 /*/
c = CAN; /*/// CAN的装入。 /*/
WriteUART(&c, 1); /*/ CAN的送信。 /*/
WriteUART(szProgramFailure, 16); /*/// 写入失败Message的输出。 /*/
WriteUART(szExit, 22); /*/// 终了提示符的输出。 /*/
bStatus = 5; /*/// 终了确认等待状态。 /*/
}
break;
case 0 :
case 2 :
case 3 : /*/// 受信Block号码时 /*/
c = ACK; /*/// ACK的装入。 /*/
WriteUART(&c, 1); /*/// ACK的送信。 /*/
break;
case 4 : /*/// XModem终了时 /*/
WriteUART("Unexpected EOF\r\n", 16); /*/// 异常File终了Message的输出。 /*/
WriteUART(szProgramFailure, 16); /*/// 中断的Message的输出。 /*/
WriteUART(szExit, 22); /*/// 终了提示符的输出。 /*/
bStatus = 5; /*/// 终了确认等待状态。 /*/
break;
}
break;
case 4 : /*/// Flash写入状态 /*/
c = OnRxXModem(); /*/// File的受信。 /*/
switch (c) { /*/// 返回值。 /*/
case 1 :
if (WritePage(abXModemFileWrite)) { /*/// 0、1Block写入到Flash中 /*/
abXModemFreeBlock[0] = abXModemFreeBlock[1] = 0; /*/// Block设为空。 /*/
c = ACK; /*/// ACK的装入。 /*/
WriteUART(&c, 1); /*/// ACK的送信。 /*/
} else { /*/// 写入失败时 /*/
c = CAN; /*/// CAN的装入。 /*/
WriteUART(&c, 1); /*/// CAN的送信。 /*/
WriteUART(szProgramFailure, 16); /*/// 写入失败Message的输出。 /*/
WriteUART(szExit, 22); /*/// 终了提示符的输出。 /*/
bStatus = 5; /*/// 终了确认等待状态。 /*/
}
break;
case 3 : /*/// 2Block受信时 /*/
if (WritePage(abXModemFileWrite + 256)) { /*/// 2、3Block写入到Flash中 /*/
abXModemFreeBlock[2] = abXModemFreeBlock[3] = 0; /*/// Block设为空。 /*/
c = ACK; /*/// ACK的装入。 /*/
WriteUART(&c, 1); /*/// ACK的送信。 /*/
} else { /*/// 写入失败时 /*/
c = CAN; /*/// CAN的装入。 /*/
WriteUART(&c, 1); /*/// CAN的送信。 /*/
WriteUART(szProgramFailure, 16); /*/// 写入失败Message的输出。 /*/
WriteUART(szExit, 22); /*/// 终了提示符的输出。 /*/
bStatus = 5; /*/// 终了确认等待状态。 /*/
}
break;
case 0 :
case 2 : /*/// 受信Block号码时 /*/
c = ACK; /*/// ACK的装入。 /*/
WriteUART(&c, 1); /*/// ACK的送信。 /*/
break;
case 4 : /*/// XModem终了时 /*/
switch (bXModemWritingBlock) { /*/// 下一个写入Block号码。 /*/
case 1 : /*/// 下一个应该向Block1中写入时 /*/
bzero(abXModemFileWrite + 128, 128); /*/// Block1的清除。 /*/
c = WritePage(abXModemFileWrite); /*/// 0、1Block写入到Flash。 /*/
break;
case 3 : /*/// 下一个应该写入Block3时 /*/
bzero(abXModemFileWrite + 384, 128); /*/// Block3的清除。 /*/
c = WritePage(abXModemFileWrite + 256); /*/// 2、3Block写入到Flash。 /*/
break;
}
if (c) { /*/// 写入成功时 /*/
StopProgram(); /*/// Flash写入的终了。 /*/
WriteUART("Program Complete\r\n", 18); /*/// Program终了Message的输出。 /*/
WriteUART("\r\n", 2); /*/// 1行改行。 /*/
// WriteUART(BinFileHeader.abBINHeader, 200); /*/// Header的输出。 /*/
// while (UARTTx.bSize - UARTTx.cbData < 100) { /*/// 空的UART送信Buffer到为止一直等待。 /*/
// }
// WriteUART(BinFileHeader.abBINHeader + 200, 56); /*/// Header的剩余的输出。 /*/
WriteUART(szExit, 22); /*/// 终了提示符的输出。 /*/
bStatus = 5; /*/// 终了确认等待状态。 /*/
} else { /*/// 写入失败时 /*/
c = CAN; /*/// CAN的装入。 /*/
WriteUART(&c, 1); /*/// CAN的送信。 /*/
WriteUART(szProgramFailure, 16); /*/// 写入失败Message的输出。 /*/
WriteUART(szExit, 22); /*/// 终了提示符的输出。 /*/
bStatus = 5; /*/// 终了确认等待状态。 /*/
}
break;
}
break;
case 5 : /*/ 终了确认等待状态 /*/
ReadUART(&c, 1); /*/// 1Byte受信。 /*/
if (c == 'Y' || c == 'y') { /*/// Yes时 /*/
return; /*/// 终了。 /*/
} else if (c == 'N' || c == 'n') { /*/// No时 /*/
FlashUART(); /*/// 送受信Buffer的Flash。 /*/
// WriteUART(szVersionMessage, 35); /*/// 起动Message的输出。 /*/
// WriteUART(szDownloadPrompt, 43); /*/// BINFile的DownLoadMessage的输出。 /*/
c = NAK; /*/// NAK的装入。 /*/
WriteUART(&c, 1); /*/// NAK的送信。 /*/
TA4MR = 0x82; /*/ TimerA4以4.8/32MHz=150KHz设为OneShortTimer。 /*/
TA4IC = 0; /*/ TimerA4中断要求的清除。 /*/
TA4 = 0xFFFF; /*/ 0.43秒的TimeOut。 /*/
CPSRF = 0x80; /*/ 时钟用Prescale进行Reset。 /*/
TABSR |= 0x10; /*/ TimerA4Count开始Flag的SET。 /*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -