?? 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 + -