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

📄 m128bls.c

📁 ATMEGA128的BOOTLOADER
💻 C
字号:
/****************************************************
Project : Mega128 Bootloader
Version : 1.00
Date    : 2005-12-23
Author  : lq                              
Company : HX GCT
Comments: This program is from M128bls2 based on CVAVR.


Chip type           : ATmega128L
Program type        : Boot Loader - Size:4096words
Clock frequency     : defined in "config.h"
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 1024
*****************************************************/

#include "config.h"

// data buffer
uint8_t gui8_data[DATA_BUFFER_SIZE];
uint8_t pw0[PWLENTH+1]="3452";
uint8_t pw1[PWLENTH+1]="2093";

/*****************************************************************************************
Function:    getpassword
Description: 进入bootload必须检查密码
Calls:       无
Called By:   main
Globel RD:   rx_counter
Globel WR:   无
Input:       无
Output:      无
Return:      0-地址0,1-地址可选
Others:      无
Auther:      Liu.Qian
Time:        2005-7-8
*****************************************************************************************/
uint8_t getpassword(void)
{
    uint8_t i;
    uint8_t pw[PWLENTH];

    while(1)
    {
        putstrf("\r\nInput password:");
        flush();
        while(rx_counter)
        {
            Ugetchar();
        }
        for( i = 0 ; i < PWLENTH ; i++)
        {
            pw[i]=Ugetchar();
            Uputchar('*');
        }
        
        for( i = 0 ; i < PWLENTH ; i++)
        {
            if(pw[i]!=pw0[i])
            {
                break;
            }
        }
        putstrf("\r\n");
        if(i==PWLENTH)
        {
            return(0);
        }
        for( i = 0 ; i < PWLENTH ; i++)
        {
            if(pw[i]!=pw1[i])
            {
                break;
            }
        }
        if(i==PWLENTH)
        {
            return(1);
        }
        DelayMs(2000);
        putstrf("!!!Invalid password!!!\r\n");
    }
}

/*****************************************************************************************
Function:    getpageadd
Description: 数据写入的起始页地址
Calls:       无
Called By:   program
Globel RD:   无
Globel WR:   无
Input:       无
Output:      无
Return:      无
Others:      无
Auther:      Liu.Qian
Time:        2005-12-15
*****************************************************************************************/
uint32_t getpageadd(void)
{
    uint32_t addr=0;
    uint8_t in;
    uint8_t data;
    uint8_t addrhex[5];

    for(;;)
    {
        putstrf("\r\nInput start address(in HEX,default is 0x00000):0x");
        in=0;
        while(in<5)
        {
	    data=Ugetchar();
            if (data==KB_ENT)
            {
                break;
            }
            if ((data>='0')&&(data<='9'))//0-9
            {
                Uputchar(data);
                data = data - '0';
            }
            else
            {
                if ((data>='a')&&(data<='f'))//a-f
                {
                    data = data - 'a' + 10;
                }
                else
                {
                    if ((data>='A')&&(data<='F'))//A-F
                    {
                        data = data - 'A' + 10;
                    }
                    else
                    {
                        continue;
                    }
                }
                Uputchar(data+'A'-10);
            }
            addrhex[in]=data;
            in++;
        } //end of    while(in<5)
        if(in==0)
        {
            putstrf("00000");
	    addr=0;
        }
        else
        {
            data=0;
            for (;in>0;in--)
            {
                addr<<=4;
                addr|=addrhex[data];
                data++;
            }
            if((uint8_t)addr||(addr>=APP_SIZE))
            {
                putstrf("\r\nBad address");
                continue;
            }
        }
        Uputchar('\r');
        Uputchar('\n');
        return(addr);
    } // end of     for(;;)
}

/*****************************************************************************************
Function:    cancel
Description: 发送CAN
Calls:       无
Called By:   无
Globel RD:   无
Globel WR:   无
Input:       无
Output:      无
Return:      无
Others:      无
Auther:      Liu.Qian
Time:        2005-12-15
*****************************************************************************************/
void cancel(void)
{
    uint8_t times;
    for(times=0;times<16;times++)
    {
          Uputchar(XMODEM_CAN);
    }
}

/*****************************************************************************************
Function:    boot_program_page
Description: 页编程
Calls:       无
Called By:   无
Globel RD:   无
Globel WR:   无
Input:       无
Output:      无
Return:      uint8_t
Others:      无
Auther:      Liu.Qian
Time:        2005-12-15
*****************************************************************************************/
uint8_t boot_program_page (uint32_t page)
{
    uint16_t i;
    uint8_t sreg;
    uint8_t retry;
    uint16_t w;
    uint16_t *buf;

    for(retry=0; retry<3; retry++)
    {
        // Disable interrupts.
        sreg = SREG;
        cli();

        eeprom_busy_wait ();

        boot_page_erase (page);
        boot_spm_busy_wait ();      // Wait until the memory is erased.

        buf = (uint16_t *)gui8_data;
        for(i=0; i<SPM_PAGESIZE; i+=2)
        {
            // Set up little-endian word.
            w = *buf++;
            boot_page_fill (page + i, w);
        }

        boot_page_write (page);     // Store buffer in flash page.
        boot_spm_busy_wait();       // Wait until the memory is written.

        // Reenable RWW-section again. We need this if we want to jump back
        // to the application after bootloading.
        boot_rww_enable ();

        // Re-enable interrupts (if they were ever enabled).
        SREG = sreg;

        // verify
        buf = (uint16_t *)gui8_data;
        for(i=0; i<SPM_PAGESIZE; i+=2)
        {
            if(pgm_read_word_far(page + i)!=*buf++)
            {
	        break;
            }
        }
        if(i==SPM_PAGESIZE)
        {
            return(0);
        }
    }
    return(1);
}

/*****************************************************************************************
Function:    program
Description: program
Calls:       无
Called By:   无
Globel RD:   无
Globel WR:   无
Input:       无
Output:      无
Return:      无
Others:      无
Auther:      Liu.Qian
Time:        2005-12-15
*****************************************************************************************/
void program(void)
{
    uint32_t pageadd;
    uint8_t i;
    uint8_t addf;
    uint8_t pack_no;
    
    if(getpassword())
    {
        pageadd = getpageadd();
    }
    else
    {
        pageadd = 0;
    }

    wait_soh();
    pack_no = 1;
    addf = 0;
    while(1)
    {
        i=get_pack(gui8_data+addf,pack_no);
        if (addf)
        {
            if (pageadd >= APP_SIZE)
            {
		while(1)
                {
                    cancel();
                    putstrf("\r\nApplication Flash Section(0x00000-0x1DFFF) is full!");
                    DelayMs(2000);
                }
            }
            if(boot_program_page(pageadd))
            {
                while(1);
                {
                    cancel();
                    putstrf("\r\nFlash write error!");
                    DelayMs(2000);
                }
            } // end of     if(ProgramPage(pageadd)==0)
            else
            {
                if(i==0)
                {
                    return;
                }
                pageadd += SPM_PAGESIZE;
                addf = 0;
            } // end of     if(ProgramPage(pageadd)==0)else
        } // end of if(addf)
        else
        {
            if (i==0)
            {
		return;
            }
            addf = 128;
        }
        Uputchar(XMODEM_ACK);
        pack_no++;
    } // end of     while(1)
}
 
/*****************************************************************************************
Function:    quit
Description: 退出Bootloader程序,从0x00000处执行应用程序 
Calls:       无
Called By:   无
Globel RD:   无
Globel WR:   无
Input:       无
Output:      无
Return:      无
Others:      无
Auther:      Liu.Qian
Time:        2005-7-8
*****************************************************************************************/
void quit(void) 
{ 
    putstrf("\r\nGo! 0x00000\r\n");
    flush();
    cli();
    MCUCR = 0x01; 
    MCUCR = 0x00;                //将中断向量表迁移到应用程序区头部
    RAMPZ = 0x00;                //RAMPZ清零初始化
    asm volatile ("jmp 0"::);    //跳转到Flash的0x00000处,执行用户的应用程序
} 

/*****************************************************************************************
Function:    cpuinit
Description: cpu初始化
Calls:       main
Called By:   无
Globel RD:   无
Globel WR:   无
Input:       无
Output:      无
Return:      无
Others:      无
Auther:      Liu.Qian
Time:        2005-7-8
*****************************************************************************************/
void cpuinit(void)
{
// Input/Output Ports initialization
PORTA=0x00;
DDRA=0x00;
PORTB=0x00;
DDRB=0x00;
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0x00;
PORTE=0x00;
DDRE=0x00;
PORTF=0x00;
DDRF=0x00;
PORTG=0x00;
DDRG=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
ASSR=0x00;
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 3 initialization
// Clock source: System Clock
// Clock value: Timer 3 Stopped
// Mode: Normal top=FFFFh
// Noise Canceler: Off
// Input Capture on Falling Edge
// OC3A output: Discon.
// OC3B output: Discon.
// OC3C output: Discon.
// Timer 3 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// Timer/Counter 3 initialization
// Clock source: System Clock
// Clock value: Timer 3 Stopped
// Mode: Normal top=FFFFh
// Noise Canceler: Off
// Input Capture on Falling Edge
// OC3A output: Discon.
// OC3B output: Discon.
// OC3C output: Discon.
// Timer 3 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR3A=0x00;
TCCR3B=0x00;
TCNT3H=0x00;
TCNT3L=0x00;
ICR3H=0x00;
ICR3L=0x00;
OCR3AH=0x00;
OCR3AL=0x00;
OCR3BH=0x00;
OCR3BL=0x00;
OCR3CH=0x00;
OCR3CL=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
// INT3: Off
// INT4: Off
// INT5: Off
// INT6: Off
// INT7: Off
EICRA=0x00;
EICRB=0x00;
EIMSK=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
ETIMSK=0x00;

#if defined UART0
    UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
    UBRR0H = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1) >> 8;
    UCSR0A = 0x00;
    UCSR0C = 0x06;
    UCSR0B = _BV(RXCIE)|_BV(TXCIE)|_BV(TXEN)|_BV(RXEN);
    UBRR1L = 0;
    UBRR1H = 0;
    UCSR1A = 0;
    UCSR1C = 0;
    UCSR1B = 0;
#else
    UBRR0L = 0;
    UBRR0H = 0;
    UCSR0A = 0;
    UCSR0C = 0;
    UCSR0B = 0;
    UBRR1L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
    UBRR1H = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1) >> 8;
    UCSR1A = 0x00;
    UCSR1C = 0x06;
    UCSR1B = _BV(RXCIE)|_BV(TXCIE)|_BV(TXEN)|_BV(RXEN);
#endif

// SPI initialization
// SPI Type: Disable
SPCR=0x00;
SPSR=0x00;

// 2 Wire Bus initialization
// TWI disable
TWSR=0x00;
TWBR=0x00;
TWAR=0x00;
TWCR=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC disable
ADMUX=0;
ADCSRA=0;
}

/*****************************************************************************************
Function:    main
Description: main
Auther:      Liu.Qian
Time:        2005-7-8
*****************************************************************************************/
int16_t main(void)
{
    uint8_t temp;
    uint8_t esc_ct;
    cpuinit();
    MCUCR = 0x01;
    MCUCR = 0x02;                    //将中断向量表迁移到Boot区头部
    sei();
    // boot
    putstrf("\r\nMega128 bootloader 1.00. Built at ");
    putstrf(__DATE__);
    putstrf(", by WINAVR 20050214.");
    putstrf("\r\n(c)Copyright 2001-2005 HX GCT Co., Ltd. All Rights Reserved.");
    putstrf("\r\nAutoboot in 2 seconds. Triple <Esc> to abort...");
    flush();
    esc_ct=0;
    for(temp=0;temp<20;temp++)
    {
        if(rx_counter)
        {
            if(Ugetchar()==KB_ESC)
            {
                esc_ct++;
                if (esc_ct==3)
                {
                    program();
                    putstrf("\r\nOver. Go to application after 3 seconds.");
                    DelayMs(3000);
                    break;
		}
	    }
	    else
	    {
		esc_ct=0;
	    }
        }
        DelayMs(100);
    };
    quit();
    return(0);
}
// end of file

⌨️ 快捷键说明

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