📄 bootload.c
字号:
//=============================================================================
// All the code below are provided for demo purpose only.
// It'll be on your own risk if you like to adopt all or parts of the code into
// your own application.
//
// This module implements all the functions needed for boot-loader
//
// All the codes must be put into a specific segment called "text_bootload".
// This segment is defined in linker-config-file (.lcf) for special positioning
// It'll be resided in Flash memory permanently as a basic driver. It can only
// be reprogrammed by hardware programming tools such as BDM
//
// Designed by Paul Zhang (paul.zhang@freescale.com)
// May 10, 2008
//=============================================================================
#include <hidef.h> // for EnableInterrupts macro
#include "derivative.h" // include peripheral declarations
//=============================================================================
// Declare function reference
//=============================================================================
void StartupEntry(void); // First vector entry, declared in "VectorMap.c"
void BootLoader(void); // Bootload routine, defined in this module
//=============================================================================
// External lable referred in this module
// They are all defined in 'project.lcf' file
//=============================================================================
extern unsigned long far _SP_INIT, _SDA_BASE;
//=============================================================================
// Macro definition for ease-of-maintenance and better readability
//=============================================================================
//define the page size of flash memory
//On Coldfire V1 it's 1024 bytes
#define FLASH_PAGE_SIZE 1024
//define the max length for one S19 text line
#define MAX_S19_LINE 256
//define the starting address of reprogramable flash block
//This address is defined in 'project.lcf' file with 'VectorReMap'
#define FLASH_PRG_ADDR 0x00000C00
//define the max length for a code buffer in RAM
#define RAM_CODE_SIZE 128
//define LED pins and on/off control state
#define LED_BOOTLOADER PTCD_PTCD0 //Blinking LED to indicate in Bootloader mode
#define LED_COMM_IN PTED_PTED6 //LED to indicate SCI data receiving
#define LED_PRG_BUSY PTED_PTED7 //LED to indicate busy of flash programming
#define LED_OFF 1 //IO state to turn LED off
#define LED_ON 0 //IO state to turn LED on
//=============================================================================
// Declare data segment specified for boot-loader
//=============================================================================
#pragma DATA_SEG __FAR_SEG DEFAULT
void *datPtr; //memory pointer for various usages
byte s19RecBuff[MAX_S19_LINE], //buffer to receive a complete line of S19 text
s19RecCount, //counter to receive S19 data
s19RecState; //state-machine control in processing S19 text line
word wTmp; //word-size variable for general useage
byte bTmp; //byte-size variable for general useage
byte reBootFlag; //Flag to reflect end-of-download and enable re-boot
byte codeInRam[RAM_CODE_SIZE]; //RAM buffer to contain and execute key portion of flash
//programming command.
//=============================================================================
// Declare a code segment with name "text_bootload"
//=============================================================================
#pragma CODE_SEG __FAR_SEG text_bootload
//=============================================================================
// Initialization for boot-loader function
//=============================================================================
void InitBootLoad(void)
{
if (NVICSTRM != 0xFF)
ICSTRM = NVICSTRM; //load trim value if NV location not blank
else
ICSTRM = 0xAD; //use a default value if NVICSTRM is blank
//setup the bus frequency to 8Mhz with internal reference clock of 31.25KHz
ICSC1 = 0b00000110;
//||||||||------ IREFSTEN = 0, Internal reference clock is disabled in stop
//|||||||------- IRCLKEN = 1, ICSIRCLK active
//||||||-------- IREFS = 1, Internal reference clock selected
//|||++--------- RDIV = 000, Reference Divider. Don't care with internal reference clock
//|+------------ CLKS = 00, Output of FLL is selected
ICSC2 = 0b00000000;
//||||||||------ EREFSTEN = 0, External Reference Stop Enable. Don't care
//|||||||------- ERCLKEN = 0, External Reference Enable. Don't care
//||||||-------- EREFS = 0, External Reference Select. Don't care
//|||||--------- LP = 0, Low Power Select. Don't care
//||||---------- HGO = 0, High Gain Oscillator Select. Don't care
//||------------ RANGE = 0, Frequency Range Select. Don't care
//|+------------ BDIV = 00, Bus Frequency Divider=1.
ICSSC = 0b00000000;
//||||||||------ FTRIM = 0, ICS Fine Trim.
//|||||||------- OSCINIT = x, OSC Initialization. Read-only
//|||||+-------- CLKST = x, Clock Mode Status. Read-only
//||||---------- IREFST = x, Internal Reference Status. Read-only
//|||----------- DMX32 = 0, DCO has default range of 25%.
//|+------------ DRS = 00, DCO low range, FLL=512, DCO=16-20MHz
//setup the SCI1 for boot-loader communication
SCI1C1 = 0b01000000;
//||||||||------ PT = 0, Parity Type. Don't care
//|||||||------- PE = 0, Parity Enable. 0 = No hardware parity generation or checking.
//||||||-------- ILT = 0, Idle Line Type Select.
//|||||--------- WAKE = 0, Idle-line wakeup.
//||||---------- M = 0, Normal- start + 8 data bits (lsb first) + stop.
//|||----------- RSRC = 0, Don't care
//||------------ SCISWAI = 1, SCI Stops in Wait Mode. 1=SCI clocks freeze while CPU is in wait mode.
//|------------- LOOPS = 0, Normal operation. RxD and TxD use separate pins.
SCI1C2 = 0b00001100;
//||||||||------ SBK = 0, Normal transmitter operation. No send break
//|||||||------- RWU = 0, Normal SCI receiver operation.
//||||||-------- RE = 1, Receiver on.
//|||||--------- TE = 1, Transmitter on.
//||||---------- ILIE = 0, Hardware interrupts from IDLE disabled
//|||----------- RIE = 0, Hardware interrupts from RDRF disabled
//||------------ TCIE = 0, Hardware interrupts from TC disabled
//|------------- TIE = 0, Hardware interrupts from TDRE disabled
SCI1C3 = 0b00000000;
//||||||||------ PEIE = 0, PF interrupts disabled
//|||||||------- FEIE = 0, FE interrupts disabled
//||||||-------- NEIE = 0, NF interrupts disabled
//|||||--------- ORIE = 0, OR interrupts disabled
//||||---------- TXINV = 0, Transmit data not inverted
//|||----------- TXDIR = 0, TxD Pin Direction in Single-Wire Mode. Don't care
//||------------ T8 = 0, Ninth Data Bit for Transmitter, don't care
//|------------- R8 = 0, Ninth Data Bit for Receiver. Read-only & don't care
SCI1S2 = 0b00000000;
SCI1BD = 13; //38400bps @ 8MHz Fbus
//setup the IO ports
PTADD = 0b11110011; //set PTA2-3 as input (key)
PTDDD = 0b00110011; //set PTD2-3 as input (key)
PTCDD = 0b00111111; //set PTC0-5 as output (LED)
PTEDD = 0b11000000; //set PTE6-7 as output (LED)
PTCD_PTCD5 = 1;
PTCD = 0b00111111; //set PTCD5 high to turn on power supply for RS232 driver
//set PTCD[4:0] high to turn off LED
PTED = 0b11000000; //set PTED[7:6] high to turn off LED
//setup timer for timing indication
TPM1SC = 0b00001011;
//||||||++------ PS[2:0] = 011, clock divider=8
//||||+--------- CLKS[B:A] = 01, TPM Clock Source = Bus rate clock
//|||----------- CPWMS = 0, Center-aligned PWM select. Don't care
//||------------ TOIE = 0, Timer overflow interrupt disable.
//|------------- TOF = 0, Timer overflow flag.
//setup flash control register for flash programming
FCDIV = 39; //programing clock frequency=200KHz @ 8MHz Fbus
reBootFlag = 0; //reset flag for re-boot control
s19RecCount = 0; //reset S19 data receiving counter
s19RecState = 0; //reset S19 line state
}
//=============================================================================
// - Send out a byte of data via SCI port
//=============================================================================
void __SciSendData(byte dat)
{
SCI1D = dat; //write data to transmit buffer
while (!SCI1S1_TC) {;} //wait for transmisson completion
}
//=============================================================================
// - Read back a byte data received by SCI port
//=============================================================================
byte __SciReadData(void)
{
SCI1S1; //read the status register once to clear RDRF bit
return(SCI1D); //read and return with teh data in SCI buffer
}
//=============================================================================
// - Poll if there's any data ready in SCI buffer
// - Return 0 - no data available
// 1 - data available in receive buffer
//=============================================================================
byte __IsSciDataReady(void)
{
if (SCI1S1_RDRF) return(1);
else return(0);
}
//=============================================================================
// - Re-format one S19 line from ASCII text to binary data
// - Return with the checksum
// - Note original leading 2 text codes 'Sx'(x=0,3,7) have been wiped out already
// - Data sample:
// 21000024004E7551FC4E7551FC2F0E2F0CB1C9671C60102C48204E52882849224C1A
//=============================================================================
byte S19LineFormat(void)
{
byte i, j, sum, *ptr;
//convert all ASCII code to binary data
for (i=0;i<s19RecCount;i++) {
j = s19RecBuff[i];
if (j>='0' && j<='9') j -= '0'; //convert code '0'-'9' to 0-9
else j += 10-'A'; //convert code 'A'-'F' to 10-15
s19RecBuff[i] = j; //write back at same position
}
ptr = s19RecBuff; //set a buffer pointer
s19RecCount >>= 1; //get the actual data length
sum = 0; //reset for checksum calculation
//combine 2 splitted code into one real data
for (i=0;i<s19RecCount;i++) {
j = *ptr++; //fetch 1st splitted code
j <<= 4; //move to high nibble
j += *ptr++; //combine with next splitted code
s19RecBuff[i] = j; //save back the real data into buffer
sum += j; //sum up to get checksum
}
//all done, return with checksum
return(sum);
}
//=============================================================================
// - Receive and process one S19 ASCII text data line from SCI port, end of 0x00
// - Line sample:
// S321000024004E7551FC4E7551FC2F0E2F0CB1C9671C60102C48204E52882849224C1A
//=============================================================================
void ReceiveS19Text(void)
{
byte dat, num, i, prg, *tmpPtr;
if (!__IsSciDataReady()) //check if any data received from SCI
return; //no data, simply return
//SCI port received a new data byte
dat = __SciReadData(); //fetch the data
LED_COMM_IN = LED_ON; //SCI data in-coming active
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -