I have been working on porting an atmega32 project to atmega1284p, and only have the bootloader left now.
I have changed, or rather defined the names for registers that have changed, and changed the bootloader address in project settings (avr studio 4) and fuses.
When the board boots, it enter bootloader correct, and I can start a upload, however several times during the load, it seems to reboot, without the MCUSR giving an idea of why.
The boot loading completes "successfully", but the program never stats, and a hex dump confirms the flash was not actually updated.
Anybody see anything wrong with this (just main file included)
//******************************************************************************************** // // AVRnetLoader firmware Version 1.0 // // MCU : ATMEGA32 @ 16MHz // Ethernet controller : ENC28J60 // IDE & Compiler : AVR Studio version 4.13.528 & WINAVR version 20070525 // Author : Jirawat Kongkaen // Website : http://www.avrportal.com/ // // *** important *** // Please set .text section to 0x3800 before build all source code // by select menu // Project -> Configuration Options // then select Memory settings and click add button // Memory type is Flash // Name is .text // Address is 0x3800 // //******************************************************************************************** // // File : main.c main program for AVRnet development board. // //******************************************************************************************** // // Copyright (C) 2007 // // This program is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) any later // version. // This program is distributed in the hope that it will be useful, but // // WITHOUT ANY WARRANTY; // // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along with // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin St, Fifth Floor, Boston, MA 02110, USA // // http://www.gnu.de/gpl-ger.html // //******************************************************************************************** #include "define.h" #include#include #include #include // Global variables MAC_ADDR avr_mac; IP_ADDR avr_ip; MAC_ADDR host_mac; IP_ADDR host_ip; BYTE rxtx_buffer[MAX_RXTX_BUFFER]; WORD dlength; WORD boot_delay=0; WORD_BYTES address, temp; BYTE i, led_delay=0; //BYTE ee_avr_ip[4] EEMEM = { 10, 1, 1, 1 }; void block_read(BYTE *rxtx_buffer, WORD size, BYTE mem, WORD *address); BYTE block_load(BYTE *rxtx_buffer, WORD size, BYTE mem, WORD *address); // software reset void software_reset(void) __attribute__ ((naked)); void software_reset(void) { wdt_enable(WDTO_15MS); for(;;); } // application vector void (*jump_to_application)(void) = (void *)0x0000; #define LED_DDR DDRC #define LED_PORT PORTC #define LED_PIN PINC #define LED_STATUS PC7 #define UCSRA UCSR0A #define UBRRL UBRR0L #define UCSRB UCSR0B #define UDR UDR0 #define UDRE UDRE0 #define TXEN TXEN0 #define RXEN RXEN0 #define EEMWE EEMPE #define EEWE EEPE int uart_putchar0(char c, FILE *stream) { while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it UDR = c; return 0; } //Fylder mindre end printf void putString(char* str) { char* ptr = str; while (*ptr != '\0') { putchar(*ptr); ptr++; } } FILE uart0_str = FDEV_SETUP_STREAM(uart_putchar0, NULL, _FDEV_SETUP_WRITE); ISR(WDT_vect) { printf("Watchdog timeout, saving eeprom\r\n"); while(true); //Next WDT timeout will reset chip } int main(void) __attribute__ ((naked)); int main(void) { uint8_t resetSource = MCUSR; wdt_reset(); wdt_disable(); wdt_reset(); // wdt_enable(WDTO_4S); // WDTCSR |= (1 << WDIE); //enable watchdog interrupt UBRRL = 0; //1,000,000@16mhz UCSRB = _BV(TXEN) | _BV(RXEN); /* tx/rx enable */ stdout = &uart0_str; if(resetSource & (1<<WDRF)) { printf("Mega was reset by watchdog...\r\n"); } if(resetSource & (1<<BORF)) { printf("Mega was reset by brownout...\r\n"); } if(resetSource & (1<<EXTRF)) { printf("Mega was reset by external...\r\n"); } if(resetSource & (1<<PORF)) { printf("Mega was reset by power on...\r\n"); } printf("Bootloader ready\r\n"); //BYTE i; //BYTE rxtx_buffer[MAX_RXTX_BUFFER]; //WORD dlength; //WORD boot_delay=0; //WORD_BYTES address, temp; //BYTE i, led_delay=0; // Change MAC Address here eeprom_read_block ( &avr_mac, (void*)23, 6 ); if (avr_mac.byte[0]==0xff || avr_mac.byte[1]==0xff || avr_mac.byte[2]==0xff || avr_mac.byte[3]==0xff || avr_mac.byte[4]==0xff || avr_mac.byte[5]==0xff) { avr_mac.byte[0] = 0; avr_mac.byte[1] = 32; avr_mac.byte[2] = 24; avr_mac.byte[3] = 177; avr_mac.byte[4] = 21; avr_mac.byte[5] = 111; } // read AVR IP from eeprom, if IP=0xff,0xff,0xff,0xff change it to default IP eeprom_read_block ( &avr_ip, (void*)11, 4 ); if(avr_ip.byte[0]==0xff || avr_ip.byte[1]==0xff || avr_ip.byte[2]==0xff || avr_ip.byte[3]==0xff) { // default IP avr_ip.byte[0]=192; avr_ip.byte[1]=168; avr_ip.byte[2]=1; avr_ip.byte[3]=47; } // initial ENC28J60 enc28j60_init((BYTE*)&avr_mac); // set LED_STATUS as output LED_DDR |= _BV(LED_STATUS); for(;;) { // wait 5'S for enter to bootloader command if(flag1.bits.prog_mode==0) { if(++boot_delay==10000) { flag1.bits.prog_mode = 1; temp.word = 0; // check blank (first block only) block_read((BYTE*)&rxtx_buffer, BLOCKSIZE, 'F', &temp.word); // Block read for(i=0; i >8) & 0xFF); // MSB first. rxtx_buffer[UDP_DATA_P+2] = (BLOCKSIZE&0xFF); // Report BLOCKSIZE (bytes). udp_send_packet((BYTE*)&rxtx_buffer, 3); // send 3-bytes continue; } // Start block load. else if(rxtx_buffer[UDP_DATA_P]=='B') { temp.byte.high = rxtx_buffer[UDP_DATA_P+1];// Get block size. temp.byte.low = rxtx_buffer[UDP_DATA_P+2]; rxtx_buffer[UDP_DATA_P] = block_load((BYTE*)&rxtx_buffer, temp.word, rxtx_buffer[UDP_DATA_P+3], &address.word); // Block load. udp_send_packet((BYTE*)&rxtx_buffer, 1); // send ok to host continue; } // Start block read. else if(rxtx_buffer[UDP_DATA_P]=='g') { temp.byte.high = rxtx_buffer[UDP_DATA_P+1];// Get block size. temp.byte.low = rxtx_buffer[UDP_DATA_P+2]; block_read((BYTE*)&rxtx_buffer[UDP_DATA_P], temp.word, rxtx_buffer[UDP_DATA_P+3], &address.word); // Block read udp_send_packet((BYTE*)&rxtx_buffer, temp.word); // send flash data to host continue; } } // end for(;;) return 0; }// end main unsigned char block_load(BYTE *rxtx_buffer, WORD size, BYTE mem, WORD *address) { //unsigned char buffer[BLOCKSIZE]; WORD_BYTES data; WORD tempaddress; WORD temp; // EEPROM memory type. if(mem=='E') { /* Fill buffer first, as EEPROM is too slow to copy with UART speed */ //for(tempaddress=0;tempaddress > 8); EEDR = rxtx_buffer[UDP_DATA_P+4+tempaddress]; // Get byte. EECR |= (1<<EEMWE); // Write byte. EECR |= (1<<EEWE); while (EECR & (1<<EEWE)); // Wait for write operation to finish. (*address)++; // Select next EEPROM byte } return '\r'; // Report programming OK } // Flash memory type. else if(mem=='F') { // NOTE: For flash programming, 'address' is given in words. (*address) <<= 1; // Convert address to bytes temporarily. tempaddress = (*address); // Store address in page. putchar('#'); for(temp=0; temp >= 1; // Convert address back to Flash words again. return '\r'; // Report programming OK } // Invalid memory type? else { return '?'; } } void block_read(BYTE *rxtx_buffer, WORD size, BYTE mem, WORD *address) { //BYTE temp; //temp = size; // EEPROM memory type. if (mem=='E') // Read EEPROM { do { EEARL = *address; // Setup EEPROM address EEARH = ((*address) >> 8); (*address)++; // Select next EEPROM byte EECR |= (1<<EERE); // Read EEPROM *rxtx_buffer++ = EEDR; // Transmit EEPROM dat ato PC size--; // Decrease number of bytes to read } while (size); // Repeat until all block has been read } // Flash memory type. else if(mem=='F') { (*address) <<= 1; // Convert address to bytes temporarily. do { *rxtx_buffer++ = _LOAD_PROGRAM_MEMORY(*address); *rxtx_buffer++ = _LOAD_PROGRAM_MEMORY((*address)+1); (*address) += 2; // Select next word in memory. size -= 2; // Subtract two bytes from number of bytes to read } while (size); // Repeat until all block has been read (*address) >>= 1; // Convert address back to Flash words again. } }
USART debug
Mega was reset by watchdog... Mega was reset by brownout... Mega was reset by external... Mega was reset by power on... Bootloader ready Programming mode enabled Chip erase mode ##################################Mega was reset by watchdog... Mega was reset by brownout... Mega was reset by external... Mega was reset by power on... Bootloader ready ########################################################################Mega was reset by watchdog... Mega was reset by brownout... Mega was reset by external... Mega was reset by power on... Bootloader ready ########################################################################Mega was reset by watchdog... Mega was reset by brownout... Mega was reset by external... Mega was reset by power on... Bootloader ready ##########################################EMega was reset by watchdog...
The program I am trying to load is less than 32kbyte, but the bootloader is located in the >64kbyte flash space, does this need special care ?