📄 main.c
字号:
/*****************************************************************************
*
* Copyright (C) 1996-1998 Atmel Corporation
*
* File : main.c
* Created : 16-jun-99
* Last Modified : 3-dec-1999 (mt: ??)
* Author(s) : BBrandal, PKastnes, ARodland, LHM
*
* Description : This Program allows an AVR with bootloader capabilities to
* Read/write its own Flash/EEprom.
*
*
****************************************************************************
*
* 1/2004 port to avr-gcc/avr-libc by Martin Thomas, Kaiserslautern, Germany
*
* Many functions used by "AVRPROG" (fuses) have been disabled by ATMEL in
* the original source code not by me. Please 'diff' against the original
* source to see everything that has been changed for the gcc port.
* As in the BF-application source most of my changes are marked with "mt"
* or enclosed with "//mtA" "//mtE".
*
* The boot interrupt vector is included (this bootloader is completly in
* ".text" section). If you need this space for further functions you have to
* add a separate section for the bootloader functions and add an attribute
* for this section to _all_ function prototypes of functions in the loader.
* With this the interrupt vector will be placed at .0000 and the bootloader
* code (without interrupt vector) at the adress you define in the linker
* options for the newly created section. Take care since the pin-change
* interrupt is used in the Butterflys bootloader for power-saving reasons.
* See the avr-libc FAQ and the avr-libc boot.h documentation for further
* details.
*
* 5/2005 - added receive-buffer in function BufferLoad()
* - made register-definitions compatible with avr-libc V1.2.3
* 5/2007 - avoid delay loop removal
* SIGNAL->ISR
*
****************************************************************************/
// mt redundant: #define ENABLE_BIT_DEFINITIONS
//mtA
// #include <inavr.h>
// #include "iom169.h"
// #include "assembly.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include <lowlevel.h>
// Enable functions originaly disabled
// #define ENABLEREADFUSELOCK // keep this disabled until AVRPROG supports ATmega169
//mtE
// ATmega169 is not suppored by AVRPROG V1.37, so "mimic" an ATmega16 instead
// AVRProg 1.40 supports an ATmega169 device-type
// #define _ATMEGA16
#define _ATMEGA169
//* Select Boot Size (select one, comment out the others) */
// #define _B128
//#define _B256
//#define _B512
#define _B1024
#include "main.h"
unsigned char gBuffer[UART_RX_BUFFER_SIZE];
void sendchar(char ) ;
char recchar(void) ;
// cbA void USART_Init(unsigned int );
unsigned char BufferLoad(unsigned int , unsigned char ) ;
void BlockRead(unsigned int , unsigned char ) ;
void OSCCAL_calibration(void) ;
void Delay(unsigned int) ;
unsigned int address;
unsigned char device;
// mt__C_task void main(void)
int main(void)
{
void (*funcptr)( void ) = 0x0000; // Set up function pointer
unsigned int tempi;
char val;
char OK = 1;
OSCCAL_calibration(); // Calibrate the OSCCAL byte
ACSR = (1<<ACD);
// Disable Digital input on PF0-2 (power save)
// mt DIDR1 = (7<<ADC0D);
DIDR0 = (7<<ADC0D);
PORTB = 0xFF; // Enable pullups on Ports B and E
PORTE = 0xFF;
// boost IntRC to 2Mhz to achieve 19200 baudrate
CLKPR = (1<<CLKPCE); // set Clock Prescaler Change Enable
// set prescaler = 4, Inter RC 8Mhz / 4 = 2Mhz
CLKPR = (1<<CLKPS1);
UBRRH = 0;//(unsigned char)(baudrate>>8);
UBRRL = 12;//(unsigned char)baudrate;
// Enable 2x speed
UCSRA = (1<<U2X);
// Enable receiver and transmitter
UCSRB = (1<<RXEN)|(1<<TXEN)|(0<<RXCIE)|(0<<UDRIE);
// Async. mode, 8N1
UCSRC = (0<<UMSEL)|(0<<UPM0)|(0<<USBS)|(3<<UCSZ0)|(0<<UCPOL);
MCUCR = (1<<IVCE);
MCUCR = (1<<IVSEL); //move interruptvectors to the Boot sector
sei(); // mt __enable_interrupt();
// mt PCMSK1 = (1<<PORTB6) | (1<<PORTB4);
PCMSK1 = (1<<PINB6) | (1<<PINB4); // set pin-change interrupt mask
EIFR = (1<<PCIF1); // clear external intterupt flag 1
EIMSK = (1<<PCIE1); // enable external interrupt 1
for(;OK;)
{
if(!(PINB & (1<<PINB6))) // mt if(!(PINB & (1<<PORTB6)))
{ // joystick "up" detected
MCUCR = (1<<IVCE);
MCUCR = (0<<IVSEL); //move interruptvectors to the Application sector
funcptr(); // Jump to application sector
}
//else if(PINB & (1<<PORTB4)) // If joystick not in the ENTER-position
else if(PINB & (1<<PINB4)) // If joystick not in the ENTER-position
{
UCSRA = 0x02;
SMCR = (3<<SM0) | (1<<SE); // Enable Power-save mode
// mt __sleep(); // Go to sleep
asm volatile ("sleep"::); // Go to sleep
SMCR = 0; // Just woke, disable sleep
}
else
{
val = recchar();
if( val == 0x1B)
{ // AVRPROG connection
while (val != 'S') // Wait for signon
{
val = recchar();
}
sendchar('A'); // Report signon
sendchar('V');
sendchar('R');
sendchar('B');
sendchar('O');
sendchar('O');
sendchar('T');
cli(); // mt __disable_interrupt();
OK = 0;
}
else
sendchar('?');
}
}
for(;;) // If PINDX is pulled low: programmingmode. (mt: here PINB4)
{
val=recchar();
if(val=='a') //Autoincrement?
{
sendchar('Y'); //Autoincrement is quicker
}
else if(val=='A') //write address
{
address=recchar(); //read address 8 MSB
address=(address<<8)|recchar();
address=address<<1; //convert from word address to byte address
sendchar('\r');
}
else if(val=='b')
{ // Buffer load support
sendchar('Y'); // Report buffer load supported
sendchar((UART_RX_BUFFER_SIZE >> 8) & 0xFF);
// Report buffer size in bytes
sendchar(UART_RX_BUFFER_SIZE & 0xFF);
}
else if(val=='B') // Start buffer load
{
tempi = recchar() << 8; // Load high byte of buffersize
tempi |= recchar(); // Load low byte of buffersize
val = recchar(); // Load memory type ('E' or 'F')
sendchar (BufferLoad(tempi,val));
// Start downloading of buffer
}
else if(val == 'g') // Block read
{
tempi = (recchar() << 8) | recchar();
val = recchar(); // Get memtype
BlockRead(tempi,val); // Perform the block read
}
/*
else if(val=='c') //Write program memory, low byte
{
ldata=recchar();
sendchar('\r');
}
else if(val== 'C') //Write program memory, high byte
{
data=ldata|(recchar()<<8);
if (device == devtype)
{
fill_temp_buffer(data,(address)); //call asm routine.
}
address=address+2;
sendchar('\r');
}
*/
else if(val=='e') //Chip erase
{
if (device == devtype)
{
for(address=0;address < APP_END;address += PAGESIZE) //Application section = 60 pages
{
write_page(address,(1<<PGERS) + (1<<SPMEN)); //Perform page erase
write_page(address,(1<<RWWSRE) + (1<<SPMEN)); //Re-enable the RWW section
}
}
write_page(address,(1<<RWWSRE) + (1<<SPMEN)); //Re-enable the RWW section
sendchar('\r');
}
else if(val=='E') //Exit upgrade
{
WDTCR = (1<<WDCE) | (1<<WDE); //Enable Watchdog Timer to give reset
sendchar('\r');
}
/*
else if(val=='l') // write lockbits
{
if (device == devtype)
{
write_lock_bits(recchar());
}
sendchar('\r');
}
else if(val== 'm') // write page
{
if (device == devtype)
{
write_page(address,(1<<PGERS) + (1<<SPMEN)); //Perform page erase
write_page((address),0x05);
write_page(address,(1<<RWWSRE) + (1<<SPMEN)); //Re-enable the RWW section
}
sendchar('\r');
}
*/
else if(val=='P') // Enter programming mode
{
sendchar('\r');
}
else if(val=='L') // Leave programming mode
{
sendchar('\r');
}
else if (val=='p') // mt: return programmer type
{
sendchar('S'); // serial programmer
}
/*
else if(val=='R') //Read program memory
{
write_page(0,(1<<RWWSRE) + (1<<SPMEN)); //Re-enable the RWW section
// SPMCSR = (1<<RWWSRE) | (1<<SPMEN);
// __store_program_memory();
// while((SPMCSR & 0x01));
intval=read_program_memory(address,0x00);
sendchar((char)(intval>>8)); //send MSB
sendchar((char)intval); //send LSB
address=address+2;
}
else if (val == 'D') // write EEPROM
{
if (device == devtype)
{
EEARL = address;
EEARH = (address >> 8);
address++;
EEDR = recchar();
EECR |= (1<<EEMWE);
EECR |= (1<<EEWE);
while (EECR & (1<<EEWE))
;
}
sendchar('\r');
}
else if (val == 'd') // read eeprom
{
EEARL = address;
EEARH = (address >> 8);
address++;
EECR |= (1<<EERE);
sendchar(EEDR);
}
*/
#ifdef ENABLEREADFUSELOCK
#warning "Extension 'ReadFuseLock' enabled"
// mt TODO: Read fuse bit seems to work for clock speed, other settings are not
// interpreted correctly. Locks and high fuse do not work at all (in AVRPROG 1.37)
// Reason for this should be the difference between ATmega16 and ATmega169.
// AVRPROG interprets the results as from an ATmega16 while they are from an ATmega169
else if(val=='F') // read fuse bits
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -