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

📄 bootloader.c

📁 ECOG bootloader, used to initialized ecog microcontroller
💻 C
📖 第 1 页 / 共 2 页
字号:
/*============================================================================Cyan Technology LimitedFILE - bootloader.cDESCRIPTION    Accepts an entire eCOG ROM file on UART A in binary and copies it to     flash memory. This program is intended to run from RAM. The code then    executes when the eCOG is restarted with GPIO4 low (DIP SW1 closed).        Version 2.0 supports binary format only, and tramsission is via UART A    and the XModem-1k protocol with CRC checking.    CHANGE LOG    27/11/04 - Version 1.0 - Tony Ward    20/06/05 - Version 2.0 - Tony Ward            Updated receive function to transmit start character ('C'),             previously transmitted using init function    08/05/05 - V2.1 ADC            Updated code sytle    08/25/05 - V2.2 TW            Fixed errors at start of file download            Added support for partial image files    02/11/05 - V2.3 EJH            Added retransmission of initial C to start download            Added new CRC16 calculation code to remove the need for the            256 word lookup table.=============================================================================*/// Defines the location of the following code in memory - see cstartup.asm#pragma code_segment BOOTLOADER#include <ecog.h>#include <ecog1.h>#include "driver_lib.h"#define PROGRAM_FLASH 1#define ENABLE_TIMEOUT 1#define FALSE   0#define TRUE    !FALSE#define NULL ((void *)0)typedef unsigned int bool;// XModem timeouts#define TIMEOUT 5120    // 5 second timeout#define MAX_RETRY 5// ASCII control codes#define SOH 1#define STX 2#define ETX 3#define EOT 4#define ACK 6#define NAK 21#define CAN 24    // cancel#define CRC 'C'     // use format with CRC// Error valuestypedef enum{    E_NONE = 0,    E_ABORT,    // 1    E_RETRY,    // 2    E_TIMEOUT,  // 3    E_OVF,      // 4    E_EOT,      // 5    E_PKT1,     // 6    E_PKT2,     // 7    E_CRC       // 8} Error_State_e;// Status valuestypedef enum{    S_OK = 1,       // 1 - General OK status for higher level    S_PKT128,       // 2 - 128 byte packet received    S_PKT1024,      // 3 - 1024 byte packet received    S_RETRY,        // 4 - Retry    S_EOT,          // 5 - End of transmission (EOT)    S_PKTERR,       // 6 - Packet number error    S_CRCERR,       // 7 - CRC error    S_MAXRETRY      // 8 - Maximum retries exceeded (fatal)} XModem_State_e;/******************************************************************************Declaration of static functions.******************************************************************************/void msec_delay(unsigned int delay);void usec_delay(unsigned int delay);int readchar(void);/******************************************************************************Declaration of public functions.******************************************************************************/int txchar(int c);// The following are used for XModem transferXModem_State_e get_word (unsigned int *ptr);unsigned int get_eot(void);void XM_init(unsigned int max_retries);XModem_State_e XM_rxp(unsigned int *pbuf);// CRC32 calculation routinesunsigned long CalcCrc(unsigned short *ptr, unsigned long count);unsigned long CalcPoly(unsigned long arg);// CRC16 calculation routinesunsigned int Update_crc(unsigned int CrntCRC, unsigned char Data);// Flash memory routinesvoid flash_erase(int first_page, int last_page);void flash_program(unsigned int program_address, unsigned int *ptr, unsigned int count);static int retry_max;    /******************************************************************************NAME    bootloaderSYNOPSIS    void bootloader(void)FUNCTION    Main code function.  Responsible for receiving the ROM file, performing     validation and writing it to the flash memoryRETURNS    after programming of flash memory is complete******************************************************************************/void bootloader(void){    // Application specific parameters    unsigned int app_size = 0;          // Size of application (KB)    unsigned long app_crc = 0;          // CRC of entire application (CRC32)        // Binary file parameters for reading and programming    unsigned int *buffer = (unsigned int *)0x8c00;  // Page buffer in cache    unsigned int *ptr = buffer;                     // Pointer to buffer    XModem_State_e status = S_OK;                   // Return status from get_word        int page;                           // Page (programming address)    int data_size = 256;                // Flash buffer size    int program_address = 0;    unsigned int alpha;                 // Temporary variable    int i;                              // Loop counter    // Map cache bank 1 as ram for flash programming buffer area    rg.mmu.cache1_data_log = (unsigned int)buffer >> 8;    fd.mmu.translate_en.cache1_data = 1;    fd.tim.int_dis1.cnt1_exp = 1;       // Disable the timer expiry interrupt    XM_init(MAX_RETRY);                 // Initialise XModem crc table    // Erase any user program in flash memory (pages from 0x0100 to 0x6f00)    flash_erase(1, 0x6f);        // Prepare flash data using a 1k buffer, page by page    for (page = 0x0; (page < 0x71) && (S_OK == status); page++)    {        ptr = buffer;        for (i = 0; i <= 255; i++)      // Clear buffer        {            *ptr++ = 0xffff;        }                ptr = buffer;        if (0 == page)          // First page, read interrupt vectors and change them to branch instructions        {            for (i = 0; (i < 4) && (S_OK == status); i++)   // Copy first four words (reset branch)            {                status = get_word(ptr++);            }            for (; (i <= 0x38) && (S_OK == status); i++)    // Interrupt vectors            {                /* Each vector address is converted into a two word branch instruction                 * with a relative address, programmed in the 2nd page of flash (0x0100 to 0x01ff).                 * The interrupt vectors are static and defined in irq.asm.                 */                status = get_word(&alpha);                if (S_OK == status)                {                    alpha = alpha - (i << 1) - 0x101 + 4;                    if (alpha & 0x0080)                    {                        alpha += 0x100;                    }                    *ptr++ = (alpha & 0xff00);                    *ptr++ = ((alpha & 0x00ff) << 8) | 0x00e0;                }            }            // Discard the rest of the downloaded first page (should be blank)            for (; (i <= 255) && (S_OK == status); i++)            {                status = get_word(&alpha);            }            data_size = (S_OK != status) ? 0 : i;            program_address = 0x100;        }        /* It is possible that the image file does not contain an entire flash memory         * dump.  If this occurs outside of the following loop then this is an error         */        else if ((page > 0) && (page < 0x70) && (S_OK == status))   // Data page, read and program        {            // Get the data            for (i = 0; (i <= 255) && (S_OK == status); i++)            {                status = get_word(ptr++);            }            // Set the parameters            data_size = ((1 == page) || (S_OK != status)) ? 0 : i;  // Skip programming page 1            program_address = page << 8;            app_size += data_size;        }        else if (0x70 == page)                  // End of flash memory, discard rest of file        {                while (status != S_EOT)            {                status = get_word(&alpha);      // Keep checking for the EOT packet            }        }                if (S_EOT == status)        {            // End of file, program size and checksum            // Map flash to data space and calculate the crc            rg.mmu.flash_data_log  = 0x0000;    // Logical data address            rg.mmu.flash_data_phy  = 0x0000;    // Physical flash address            rg.mmu.flash_data_size = 0x7f;      // 32k words of flash            rg.mmu.translate_en |= 0x0010;      // Enable flash data translation            // Calculate checksum over downloaded application file            app_crc = CalcCrc((unsigned short *)0x0200, app_size);            rg.mmu.translate_en &= ~0x0010;     // Disable flash data translation            // Store application size and checksum to flash            ptr = buffer;            *ptr++ = app_size;            *ptr++ = (unsigned int)(app_crc >> 16);     //MSW            *ptr++ = (unsigned int)(app_crc & 0xffff);  //LSW                        data_size = 3;            program_address = 0x01fd;           // Save these at end of page 1            // NB These are not included in checksum calculation        }                    // Program the buffer to the flash memory        flash_program(program_address, buffer, data_size);    }    // Tidy up and exit    txchar('D');    txchar('o');    txchar('n');    txchar('e');    brk();    return;         // Stop for now, work out what to do later}        /******************************************************************************NAME    get_wordSYNOPSIS    int get_word(void)FUNCTION    Gets a single word from the XModem buffer, refills buffer if necessary    Initialisation is also automaticRETURNS    The next byte in the buffer and S_OK******************************************************************************/XModem_State_e get_word(unsigned int *ptr){    static XModem_State_e status = S_OK;    static unsigned int index = 0;    static unsigned int size = 0;        // NB word address 0x8800 is equivalent to byte address 0x11000    static unsigned int *bufptr = (unsigned int *)0x8800;   // Cache buffer        if (index >= size)        index = 0;        if (index == 0)             // Read new packet into buffer memory    {        status = XM_rxp(bufptr);        // Get packet size in words        if (status == S_PKT1024)        {            size = 512;            status = S_OK;        }        else if (status == S_PKT128)        {            size = 64;            status = S_OK;        }    }        if ((S_OK == status) && (ptr != NULL))    {        *ptr = (bufptr[index++]);    }        return (status);}/******************************************************************************NAME    XM_initSYNOPSIS    void XM_init(unsigned int max_retries)FUNCTION    Performs all the initalisation for the XModem transfer.RETURNS    Nothing******************************************************************************/void XM_init(unsigned int max_retries){    unsigned int timeout = TIMEOUT;        retry_max = max_retries;            // Set global variable        rg.cache.ctrl = 0;                  // Enable cache data access    rg.mmu.cache0_data_log = 0x0088;    // Map in the cache as data buffer            rg.mmu.translate_en = rg.mmu.translate_en | 0x0180;        // Timer initialisation    fd.ssm.rst_clr.low_ref_div_chn = 1; // Bring Low reference clock up    fd.ssm.div_sel.low_clk_timer = 1;   // Use the low freq clock    fd.ssm.div_sel.cnt1 = 0;            // Use the reference    fd.ssm.tap_sel2.cnt1 = 3;           // Divide by 32 = 1 m second intervals    fd.ssm.clk_en.cnt1 = 1;             // Enable the timer    fd.ssm.rst_clr.cnt1 = 1;            // Take the timer out of reset    rg.tim.cnt1_ld = timeout;           // Set the timer load value            fd.tim.ctrl_en.cnt1_cnt = 1;        // Start counting}/******************************************************************************NAME    XM_rxpSYNOPSIS    XModem_State_e XM_rxp(unsigned int *pbuf)FUNCTION    Receives the next XModem packet from the serial port.    Handles all the CRC checking and retying.RETURNS        S_PKT128   128 byte packet received        S_PKT1024  1024 byte packet received        S_RETRY    requested resend        S_EOT      end of transmission (EOT)        S_CRCERR   CRC error        S_MAXRETRY maximum retries exceeded (fatal) ******************************************************************************/XModem_State_e XM_rxp(unsigned int *pbuf){    static bool ack_flag = FALSE;    static int packet_num = 0;	static bool start_flag = TRUE;        int retries = 0;    int c;                          // Input character    unsigned int i;                 // Loop counter    XModem_State_e result;          // Return value    unsigned int packet_len = 0;    unsigned int crc = 0;    Error_State_e error;    unsigned char *ptr = (unsigned char *)pbuf;    int done = FALSE;    // Read one XModem packet into buffer, retry if any errors    do    {        error = E_NONE;             // Reset these for each retry                    do        {            if (start_flag)         // Start of transmission ?            {                txchar(CRC);        // ..yes, send C to start CRC transfer            }            else if (ack_flag)      // Acknowledge last packet ?            {                txchar(ACK);        // ..yes, send ACK to request next packet                ack_flag = FALSE;   // Reset flag            }                // Look for the start of the next packet            c = readchar();            if (c < 0)            {                result = S_RETRY;                error = E_TIMEOUT;                break;            }            if (++packet_num > 255) // Increment packet number, restart at 0 if > 255            {                packet_num = 0;			}            switch (c)            {                case SOH:                start_flag = FALSE; // Clear the start condition                packet_len = 128;   // 128 byte packet                result = S_PKT128;                break;                        case STX:                start_flag = FALSE; // Clear the start condition                packet_len = 1024;  // 1024 byte packet                result = S_PKT1024;                break;                case CAN:           // Cancel received                case EOT:           // EOT received - stop                txchar(ACK);        // Send ACK                result = S_EOT;                error = E_EOT;                done = TRUE;                break;                default:    // Unexpected character, could be mid packet, check for duart overflow                while (fd.duart.a_sts.rx_ofl)                {                    // We have an overflow, wait for end of packet                    unsigned int save = rg.tim.cnt1_ld; // back up timer load value                                   rg.tim.cnt1_ld = 10;                // set for 10 ms delays                    fd.tim.cmd.cnt1_ld = 1;             // Load the timer                    while (rg.tim.cnt1_cnt)                    {                        if (fd.duart.a_sts.rx_1b_rdy)                        {                            fd.tim.cmd.cnt1_ld = 1; // Reset timer                            c = rg.duart.a_rx;      // Empty buffer                        }                    }                    fd.duart.a_int_clr.rx_ofl = 1;  // Clear overflow

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -