⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bootload.c

📁 牛人张明峰写的bootloader。很有参考价值。和很多freescale的例子不太一样
💻 C
📖 第 1 页 / 共 2 页
字号:
//=============================================================================
// 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 + -