📄 bootloader_atmega2560.c
字号:
#if defined(__AVR_ATmega128__) || defined(__AVR_AT90CAN128__)
if(bootuart0) {
UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
UCSR0A = 0x00;
UCSR0C = 0x06;
UCSR0B = _BV(TXEN0)|_BV(RXEN0);
}
if(bootuart1) {
UBRR1L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
UBRR1H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
UCSR1A = 0x00;
UCSR1C = 0x06;
UCSR1B = _BV(TXEN1)|_BV(RXEN1);
}
#elif defined __AVR_ATmega163__
UBRR = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
UBRRHI = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
UCSRA = 0x00;
UCSRB = _BV(TXEN)|_BV(RXEN);
#elif defined __AVR_ATmega2560__
UBRR1L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
UBRR1H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
UCSR1A = 0x00;
UCSR1C = 0x06;
UCSR1B = _BV(TXEN1)|_BV(RXEN1);
#else
/* m8,m16,m32,m169,m8515,m8535 */
UBRRL = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
UBRRH = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
UCSRA = 0x00;
UCSRC = 0x86;
UCSRB = _BV(TXEN)|_BV(RXEN);
#endif
} // end of initUart
/*----------------------------------------------------------------------------*/
/* check if flash is programmed already, if not start bootloader anyway */
/*----------------------------------------------------------------------------*/
void bootCheck(void) {
if(pgm_read_byte_near(0x0000) != 0xFF) {
#ifdef __AVR_ATmega128__
/* check which UART should be used for booting */
if(bit_is_clear(BL_PIN,BL0)) {
bootuart0 = 1;
}
else if(bit_is_clear(BL_PIN,BL1)) {
bootuart1 = 1;
} else {
/* if no UART is being selected, start application */
app_start();
}
#elif defined __AVR_AT90CAN128__
/* check which UART should be used for booting */
if(bit_is_clear(BL_PIN,BL0)) {
bootuart1 = 1;
}
else if(bit_is_clear(BL_PIN,BL1)) {
bootuart0 = 1;
} else {
/* if no UART is being selected, start application */
app_start();
}
#else
/* check if bootloader pin is set low */
if(bit_is_set(BL_PIN,BL)) app_start();
#endif
}
#ifdef __AVR_ATmega128__
/* if no UART is being selected, default is RS232 */
if((bootuart0 == 0) && (bootuart1 == 0)) {
bootuart0 = 1;
}
#elif defined __AVR_AT90CAN128__
/* if no UART is being selected, default is USB */
if((bootuart0 == 0) && (bootuart1 == 0)) {
bootuart1 = 1;
}
#endif
} // end of bootCheck
void putch(char ch)
{
#if defined(__AVR_ATmega128__) || defined(__AVR_AT90CAN128__)
if(bootuart0) {
while (!(UCSR0A & _BV(UDRE0)));
UDR0 = ch;
}
else if (bootuart1) {
while (!(UCSR1A & _BV(UDRE1)));
UDR1 = ch;
}
#elif defined(__AVR_ATmega2560__)
while (!(UCSR1A & _BV(UDRE1)));
UDR1 = ch;
#else
/* m8,16,32,169,8515,8535,163 */
while (!(UCSRA & _BV(UDRE)));
UDR = ch;
#endif
} // end of putch
char getch(void)
{
char tmp;
#if defined(__AVR_ATmega128__) || defined(__AVR_AT90CAN128__)
if(bootuart0) {
while(!(UCSR0A & _BV(RXC0)));
tmp = UDR0;
}
else if(bootuart1) {
while(!(UCSR1A & _BV(RXC1)));
tmp = UDR1;
}
#elif defined(__AVR_ATmega2560__)
while(!(UCSR1A & _BV(RXC1)));
tmp = UDR1;
#else
/* m8,16,32,169,8515,8535,163 */
while(!(UCSRA & _BV(RXC)));
tmp = UDR ;
#endif
if( echo ) {
putch( tmp );
}
return( tmp );
} // end of getch
void eeprom_wb(unsigned int uiAddress, unsigned char ucData)
{
/* Wait for completion of previous write */
while(EECR & (1<<EEWE))
;
/* Set up address and data registers */
EEAR = uiAddress;
EEDR = ucData;
/* Write logical one to EEMWE */
EECR |= (1<<EEMWE);
/* Start eeprom write by setting EEWE */
EECR |= (1<<EEWE);
}
unsigned char eeprom_rb(unsigned int uiAddress)
{
/* Wait for completion of previous write */
while(EECR & (1<<EEWE))
;
/* Set up address register */
EEAR = uiAddress;
/* Start eeprom read by writing EERE */
EECR |= (1<<EERE);
/* Return data from data register */
return EEDR;
}
#ifdef MONITOR
void monitorMain( void ) {
uint8_t *buf ;
uint8_t convBuf[20];
uint8_t quit = 0;
uint32_t address ;
uint8_t value;
uint8_t cmd;
uint8_t lastCmd = 0;
struct time t;
struct date d;
monitorInit();
print_P( (uint32_t)monitorWelcome );
echo = 1;
while( ! quit ) {
putch( MONITOR_PROMPT );
buf = monitorReadLine();
while( isblank( *buf ) ) {
buf ++ ;
}
cmd = toupper(*(buf++));
switch( cmd ) {
case MONITOR_CMD_QUIT:
echo = 0;
quit = 1;
monitor_cnt = 0;
print_P( (uint32_t)monitorQuit );
break;
case MONITOR_CMD_TIME:
buf = getValue( buf, &(t.hour10), 1 );
if( buf ) {
buf = getValue( buf, &(t.hour), 1 );
buf = getValue( buf, &(t.min10), 1 );
buf = getValue( buf, &(t.min), 1 );
buf = getValue( buf, &(t.sec10), 1 );
buf = getValue( buf, &(t.sec), 1 );
set_clock( 0, &t );
}
print( time2str(get_time(&t),convBuf) );
putch('\n');
lastCmd = cmd;
break;
case MONITOR_CMD_DATE:
buf = getValue( buf, &(d.year10), 1 );
if( buf ) {
buf = getValue( buf, &(d.year), 1 );
buf = getValue( buf, &(d.month10), 1 );
buf = getValue( buf, &(d.month), 1 );
buf = getValue( buf, &(d.day10), 1 );
buf = getValue( buf, &(d.day), 1 );
set_clock( &d, 0 );
}
print( date2str(get_date(&d),convBuf) );
putch('\n');
lastCmd = cmd;
break;
case MONITOR_CMD_FLASH:
buf = getValue( buf, &address, 5 );
if( buf ) {
address = monitorDump( address,MONITOR_DISPLAY_LINES, MONITOR_MEM_FLASH );
}
lastCmd = cmd;
break;
case MONITOR_CMD_RAM:
buf = getValue( buf, &address, 4 );
if( buf ) {
buf = getValue( buf, &value, 2 );
if( buf ) {
monitorChange( address, value, MONITOR_MEM_RAM );
address = monitorDump( address,1, MONITOR_MEM_RAM );
}
else {
address = monitorDump( address,MONITOR_DISPLAY_LINES, MONITOR_MEM_RAM );
}
}
lastCmd = cmd;
break;
case MONITOR_CMD_EEPROM:
buf = getValue( buf, &address, 3 );
if( buf ) {
buf = getValue( buf, &value, 2 );
if( buf ) {
monitorChange( address, value, MONITOR_MEM_EEPROM );
address = monitorDump( address,1, MONITOR_MEM_EEPROM );
}
else {
address = monitorDump( address,MONITOR_DISPLAY_LINES, MONITOR_MEM_EEPROM );
}
}
lastCmd = cmd;
break;
case MONITOR_CMD_HELP:
print_P( (uint32_t) PSTR("\nF AAAA - dump flash\n") );
print_P( (uint32_t) PSTR("X AAAA XX - dump/modify ram\n") );
print_P( (uint32_t) PSTR("E AAAA XX - dump/modify eeprom\n") );
print_P( (uint32_t) PSTR("T HHMMSS - display/set time\n") );
print_P( (uint32_t) PSTR("D YYMMDD - display/set date\n") );
print_P( (uint32_t) PSTR("Q - quit monitor\n") );
break;
case '\0':
case '\n':
case '\r':
switch( lastCmd ) {
case MONITOR_CMD_TIME:
print( time2str(get_time(&t),convBuf) );
putch('\n');
break;
case MONITOR_CMD_DATE:
print( date2str(get_date(&d),convBuf) );
putch('\n');
break;
case MONITOR_CMD_FLASH:
address = monitorDump( address,MONITOR_DISPLAY_LINES, MONITOR_MEM_FLASH );
break;
case MONITOR_CMD_RAM:
address = monitorDump( address,MONITOR_DISPLAY_LINES, MONITOR_MEM_RAM );
break;
case MONITOR_CMD_EEPROM:
address = monitorDump( address,MONITOR_DISPLAY_LINES, MONITOR_MEM_EEPROM );
break;
}
break;
default:
print_P( (uint32_t) monitorError );
break;
}
}
}
void monitorInit( void ) {
XMCRB = 0x00 ; // 60kb RAM available
#if defined(__AVR_ATmega128__)
XDIV = 0x00; //xtal divider disabled
XMCRA = 0x00; //ext ram one sector 1100-FFFF
MCUCR = ( 1 << SRE ); // ext ram enable
#elif defined(__AVR_AT90CAN128__)
CLKPR = 0x00; // clock divider disabled
XMCRA = ( 1 << SRE ) ; // ext ram enable, one segment
#endif
}
uint32_t monitorDump( uint32_t address, uint8_t lineNum, uint8_t memType ) {
uint8_t charCnt ;
uint8_t lineCnt ;
uint8_t memByte ;
uint8_t bufHex[10];
uint8_t bufAsc[20];
putch('\n');
for( lineCnt = 0; lineCnt < lineNum; lineCnt++ ) {
print( ultoa(address,bufHex,16) );
putch( ' ');
for( charCnt = 0; charCnt < 16; charCnt++ ) {
switch( memType ) {
case MONITOR_MEM_FLASH:
memByte = pgm_read_byte_far( address++ );
break;
case MONITOR_MEM_RAM:
memByte = *((uint8_t *)address++);
break;
case MONITOR_MEM_EEPROM:
memByte = eeprom_rb( address++ );
}
if( memByte < 0x10 ) {
putch('0');
}
print( ultoa(memByte,bufHex,16) );
putch(' ');
bufAsc[charCnt] = isprint(memByte) ? memByte : '.';
}
bufAsc[16] = '\0';
print( bufAsc );
putch('\n');
}
return address ;
}
void monitorChange( uint32_t address, uint8_t value, uint8_t memType ) {
switch( memType ) {
case MONITOR_MEM_RAM:
*((uint8_t *)address) = value;
break;
case MONITOR_MEM_EEPROM:
eeprom_wb( address, value );
break;
}
}
char *monitorReadLine( void ) {
unsigned int cnt;
char key;
cnt = 0;
while( ((key = getch()) != '\n') && cnt < ( MONITOR_BUFFER_SIZE - 1) ) {
monitorBuf[ cnt++ ] = key ;
}
monitorBuf[ cnt ] = '\0';
return monitorBuf ;
}
void print( char *s ) {
while( *s ) {
putch( *s );
s++ ;
}
}
void print_P( uint32_t address ) {
uint8_t c;
while ((c = pgm_read_byte_far(address++))) {
putch(c);
}
}
char *getValue( char *src, uint32_t *value, uint8_t len ) {
char buf[10];
*buf = '\0';
*value = 0;
while( isblank( *src ) && ( *src != '\0' ) ) {
src ++ ;
}
if ( *src == '\0' || !isxdigit(*src) ) {
return 0;
}
else {
while( isxdigit( *src ) && len ) {
*value = (*value << 4) | htoi( *src );
len-- ;
src++ ;
}
return src ;
}
}
uint8_t htoi( uint8_t val ) {
if( val >= '0' && val <= '9' ) {
return (val - '0');
}
else {
return ( toupper( val ) - 'A' + 10 );
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -