📄 bootloader.c
字号:
/*******************************************************************************
; Page Erase
; re-enable the RWW section
; transfer data to Flash page buffer
; execute Page Write
; re-enable the RWW section
; read back and check, optional
; return to RWW section
; verify that RWW section is safe to read
Return:
in temp1, SPMCSR
sbrs temp1, RWWSB ; If RWWSB is set, the RWW section is not ready yet
ret
; re-enable the RWW section
*******************************************************************************/
#include "bootloader.h"
#define SET_CD_STR (PORTB |= 1 << PB0)
#define CLR_CD_STR (PORTB &= ~ (1 << PB0))
#define SET_SPI_DATA (PORTB |= 1 << PB2)
#define CLR_SPI_DATA (PORTB &= ~ (1 << PB2))
#define SET_SPI_CLK (PORTB |= 1 << PB1)
#define CLR_SPI_CLK (PORTB &= ~ (1 << PB1))
//==============================================================================
void Led(BYTE cmd)
{
BYTE i;
DDRB = B0000_0111;
CLR_CD_STR;
SET_CD_STR;
for(i=0;i<8;i++){
if(cmd& 0x80) SET_SPI_DATA;
else CLR_SPI_DATA;
_NOP();_NOP();
CLR_SPI_CLK;
cmd <<= 1;
SET_SPI_CLK ;
}
CLR_CD_STR;
}
//==============================================================================
void Pause_1mS(BYTE delay)
{
while(delay--){
for(BYTE j = 10;j;j--)
for(BYTE i = 100;i>0;i--){
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
}
}
}
//==============================================================================
void Spm_wait(void)
{
WAIT_EEPROM;
while(SPMCSR & (1<<RWWSB)) {
while(SPMCSR & (1<<SPMEN));
SPMCSR = 0x11;
asm("spm ");
}
}
//-------------------------------------------------------------------------
void Spm_page_cmd(unsigned int p_address,char code)
{
asm("movw r30, r16");
SPMCSR = code;
asm("spm");
Spm_wait();
}
//-------------------------------------------------------------------------
void Spm_page_fill(unsigned int address,int data)
{
asm("movw r30,r16");
asm("movw r0,r18");
SPMCSR = 0x01;
asm("spm");
}
//-------------------------------------------------------------------------
/* The Boot Lock bits can be set in software andin Serial or Parallel Programming
mode, but they can be cleared by a Chip Erase commandonly.
*/
void Spm_fuse_write(unsigned int address,int data)
{
asm("movw r30,r16");
asm("movw r0, r18");
SPMCSR = 0x09;
asm("spm");
}
//-------------------------------------------------------------------------
// Fuse Low byte, 0x0000 FLB7 FLB6 FLB5 FLB4 FLB3 FLB2 FLB1 FLB0
// Lock bits, 0x0001 – – BLB12 BLB11 BLB02 BLB01 LB2 LB1
// Fuse byte, 0x0002 – – – – EFB3 EFB2 EFB1 EFB0
// Fuse High byte, 0x0003 FHB7 FHB6 FHB5 FHB4 FHB3 FHB2 FHB1 FHB0
// cmd == 0, read falsh
// cmd == 0x09 read fuse and lock
// e2,ff,fa,9f(9E)
char Read_flash_fuse (unsigned int addr ,char cmd)
{
asm("movw r30, r16 "); // move adress to z pointer
asm("sbrc R18, 0 ");
SPMCSR = cmd;
#ifdef EN_PAMPZ
asm("elpm r16, z ");
#else
asm("lpm r16, z ");
#endif
asm("clr r17 "); // may make warning here,no problem
}
//==============================================================================
void EEPPUT(unsigned int ADR,char val)
{
Spm_wait();
EEAR = ADR;
EEDR = val;
EECR |= (1<<EEMWE);
EECR |= (1<<EEWE);
}
//==============================================================================
char EEPGET(unsigned int ADR)
{
Spm_wait();
EEAR = ADR;
EECR |= (1<<EERE);
return EEDR;
}
//==============================================================================
void main(void)
{
_CLI();
DDRC = B1111_1111; // port switch
PORTC = B1000_0000;
DDRG = B1111_1111;
PORTG = B1111_1111;
//-----------------------------------------------------------------------------
//RXCn TXCn UDREn FEn DORn UPEn U2Xn MPCMn (UCSRnA)
UCSR0A = B0000_0010;
//RXCIEn TXCIEn UDRIEn RXENn TXENn UCSZn2 RXB8n TXB8n (UCSRnB)
UCSR0B = B0001_1000;
//UMSELn1 UMSELn0 UPMn1 UPMn0 USBSn UCSZn1 UCSZn0 UCPOLn (UCSRnC)
UCSR0C = B0000_1110;
#ifdef USE_UBRR0H
UBRR0H = HIGH(BAUD_SET9600);
#endif
UBRR0L = LOW(BAUD_SET9600);
//-----------------------------------------------------------------------------
/*
//TCNT0
OCR0A = TIMER_OCR0A; //10ms-77,15ms-166,20ms-155
//OCR0B
//COM0A1 COM0A0 COM0B1 COM0B0 – – WGM01 WGM00 [TCCR0A]
TCCR0A = B0000_0010;
//FOC0A FOC0B – – WGM02 CS02 CS01 CS00 [TCCR0B]
TCCR0B = B0000_0101;
//– – – – – OCIE0B OCIE0A TOIE0 [TIMSK0]
//TIMSK0 = B0000_0000;
//– – – – – OCF0B OCF0A TOV0 [TIFR0]
//TIFR0 = 0;
*/
//TCNT0
//OCR0 = TIMER_OCR0A;
//FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00 [TCCR0]
//TCCR0 = B0000_1111;
//OCF2 TOV2 ICF1 OCF1A OCF1B TOV1 OCF0 TOV0 [TIFR]
//TIFR = B0000_0000;
TIMER_INIT();
//-----------------------------------------------------------------------------
Wait = BOOT_WAIT;
LedT = 0x00;
#if 0 // debug UART & timer
/*
char c;
char i;
const char Str_rampz[] = {"\r\nRAMPZ = "};
while(1){
Slip_package(SLIP_ACK|SLIP_ERROR, 2+1);
Pause_1mS(200);
Led(i++);
}
for(i = 0;Str_rampz[i];i++) UART_putc(Str_rampz[i]);
if(RAMPZ == 0) UART_putc('0');
else UART_putc('1');
while(1){
Pause_1mS(250);
Pause_1mS(250);
Pause_1mS(250);
Pause_1mS(250);
Led(i++);
}
Wait = 0;
while(1){
if(UART_getc()){
c = UDR0;
UART_putc(c);
}
if(TIMER_OVERFLOW){
TIMER_CLEAR;
UART_putc('T');
}
}*/
char buf[256];
char bufr[256];
for(int i =0; i<256; i++) buf[i] = i;
Flash_Read_String(0, bufr, 256);
Flash_Erase_Sector(0);
Flash_Read_String(0, bufr, 256);
Flash_Write_String(0, buf, 256);
Flash_Read_String(0, bufr, 256);
Flash_Erase_Sector(0);
Flash_Read_String(0, bufr, 256);
if(bufr[127] != 127) Led(0xff);
#endif
Led(0xff);
while(Wait){
#ifdef ALWAYS_CHECK_LINK
Slip_unpackage();
#else
if(Slip_unpackage()){
Wait = 0;
while(1) Slip_unpackage();
}
#endif
}
Led(0x00);
Goto_app();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -