Hi all, I'm currently porting a bootloader from the Atmega644 to the AVR128DA using the 'AN3341: Basic Bootloader for the AVR DA MCU Family' as a guide. I get two amazingly descript errors: "confused by earlier errors, bailing out" & "local fram unavailable (naked function?), both of which point to an I2C read function in the main bootloader code. I'm starting the boot code in the ".ctor" section as described in the app note and I think I just don't know how to code this properly. The little I've seen on what these errors mean it could be the c code in the 'naked' function, which the Atmel bootloader code gets away with, or functions not being inlined properly (although I'm not sure that applies here without inline functions). Here's what I've got so far:
__attribute__((naked)) __attribute__((section(".ctors"))) void boot(void) { // Initialize system for AVR GCC support, expects r1 = 0 asm volatile("clr r1"); fram_init(); // Initializes FRAM // Read AVR EEPROM for start condition bootStatus = fram_readByte(&FRAMBoot.bootStatus); // Check start normal or finalizing if (bootStatus == START_NORMAL) { // Enable Boot Section Lock NVMCTRL.CTRLB = NVMCTRL_BOOTRP_bm; // Jump to OS pgm_jmp_far (APPCODE_START / sizeof(uint16_t)); } // Execute bootloader bootloader(); }
This code above just checks FRAM for a byte that says to start the bootloader or normally. The boot loader itself is:
void bootloader (void) { //#define BOOT_READY 10 uint8_t handshakeStatus = USB_HS_NONE; uint8_t command; uint8_t statusCmd = CMD_SEND_FW_PACKET; cli(); // Disable Interrupts bootInit(); // Initialize bootloader (Pins) i2c_initMaster(); // Initializes the i2c bus setOutPinHigh(); // Tells PC we are ready after restart for(;;) { // Listen for USB handshake if((~USB_PIN_PORT.IN & USB_IN_PIN_MSK) && (handshakeStatus == USB_HS_RESET)) { handshakeStatus = usb_HandshakeRespond(); } // Get Task if(handshakeStatus == USB_HS_HANDSHAKE) { handshakeStatus = USB_HS_TASK; USBReadMessage(FTDI_7BIT_ADDR, &command, SIZE_GET_USB_CMD); <- Problem is here switch(command) { case CMD_GET_FW_VER: usb_GetFirmwareVersionCommand(); break; case CMD_GET_DATE_UPDATED: usb_GetDateLastUpdated(); break; ...
The problem occurs at the USBReadMessage function and if I comment that out it compiles. The USBReadMessage is just an I2C read assembled from the Fleury driver that I ported to the DA series TWI.
Any clue what is going on? And, do I even have to start the bootloader this way or can it be done normally with main and not omitting the function prologue and epilogue as shown? Seems like that would be a bit simpler.