X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/603a7d86e9596be2af91aff985611481bcdcbc74..f2740a66bafa876dfcf2cdfa4c6f3e17395e8bf8:/Bootloaders/CDC/BootloaderCDC.c diff --git a/Bootloaders/CDC/BootloaderCDC.c b/Bootloaders/CDC/BootloaderCDC.c index bb5c1e673..00755a54c 100644 --- a/Bootloaders/CDC/BootloaderCDC.c +++ b/Bootloaders/CDC/BootloaderCDC.c @@ -1,13 +1,13 @@ /* LUFA Library - Copyright (C) Dean Camera, 2012. + Copyright (C) Dean Camera, 2018. dean [at] fourwalledcubicle [dot] com www.lufa-lib.org */ /* - Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2018 Dean Camera (dean [at] fourwalledcubicle [dot] com) Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted @@ -18,7 +18,7 @@ advertising or publicity pertaining to distribution of the software without specific, written prior permission. - The author disclaim all warranties with regard to this + The author disclaims all warranties with regard to this software, including all implied warranties of merchantability and fitness. In no event shall the author be liable for any special, indirect or consequential damages or any damages @@ -72,7 +72,17 @@ void Application_Jump_Check(void) { bool JumpToApplication = false; - #if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1)) + #if (BOARD == BOARD_LEONARDO) + /* Enable pull-up on the IO13 pin so we can use it to select the mode */ + PORTC |= (1 << 7); + Delay_MS(10); + + /* If IO13 is not jumpered to ground, start the user application instead */ + JumpToApplication = ((PINC & (1 << 7)) != 0); + + /* Disable pull-up after the check has completed */ + PORTC &= ~(1 << 7); + #elif ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1)) /* Disable JTAG debugging */ JTAG_DISABLE(); @@ -81,22 +91,42 @@ void Application_Jump_Check(void) Delay_MS(10); /* If the TCK pin is not jumpered to ground, start the user application instead */ - JumpToApplication |= ((PINF & (1 << 4)) != 0); + JumpToApplication = ((PINF & (1 << 4)) != 0); /* Re-enable JTAG debugging */ JTAG_ENABLE(); + #else + /* Check if the device's BOOTRST fuse is set */ + if (!(BootloaderAPI_ReadFuse(GET_HIGH_FUSE_BITS) & ~FUSE_BOOTRST)) + { + /* If the reset source was not an external reset or the key is correct, clear it and jump to the application */ + if (!(MCUSR & (1 << EXTRF)) || (MagicBootKey == MAGIC_BOOT_KEY)) + JumpToApplication = true; + + /* Clear reset source */ + MCUSR &= ~(1 << EXTRF); + } + else + { + /* If the reset source was the bootloader and the key is correct, clear it and jump to the application; + * this can happen in the HWBE fuse is set, and the HBE pin is low during the watchdog reset */ + if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY)) + JumpToApplication = true; + + /* Clear reset source */ + MCUSR &= ~(1 << WDRF); + } #endif - /* If the reset source was the bootloader and the key is correct, clear it and jump to the application */ - if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY)) - JumpToApplication |= true; + /* Don't run the user application if the reset vector is blank (no app loaded) */ + bool ApplicationValid = (pgm_read_word_near(0) != 0xFFFF); /* If a request has been made to jump to the user application, honor it */ - if (JumpToApplication) + if (JumpToApplication && ApplicationValid) { /* Turn off the watchdog */ - MCUSR &= ~(1<> 1)), FetchNextCommandByte()); + eeprom_update_byte((uint8_t*)((intptr_t)(CurrAddress >> 1)), FetchNextCommandByte()); /* Increment the address counter after use */ CurrAddress += 2; @@ -330,10 +365,7 @@ static void ReadWriteMemoryBlock(const uint8_t Command) if (MemoryType == MEMORY_TYPE_FLASH) { /* Commit the flash page to memory */ - boot_page_write(PageStartAddress); - - /* Wait until write operation has completed */ - boot_spm_busy_wait(); + BootloaderAPI_WritePage(PageStartAddress); } /* Send response byte back to the host */ @@ -394,7 +426,7 @@ static void WriteNextResponseByte(const uint8_t Response) Endpoint_Write_8(Response); } -/** Task to read in AVR910 commands from the CDC data OUT endpoint, process them, perform the required actions +/** Task to read in AVR109 commands from the CDC data OUT endpoint, process them, perform the required actions * and send the appropriate response back to the host. */ static void CDC_Task(void) @@ -442,7 +474,7 @@ static void CDC_Task(void) } else if (Command == AVR109_COMMAND_SetCurrentAddress) { - /* Set the current address to that given by the host */ + /* Set the current address to that given by the host (translate 16-bit word address to byte address) */ CurrAddress = (FetchNextCommandByte() << 9); CurrAddress |= (FetchNextCommandByte() << 1); @@ -460,7 +492,7 @@ static void CDC_Task(void) for (uint8_t CurrByte = 0; CurrByte < 7; CurrByte++) WriteNextResponseByte(SOFTWARE_IDENTIFIER[CurrByte]); } - else if (Command == AVR109_COMMAND_ReadBootloaderVersion) + else if (Command == AVR109_COMMAND_ReadBootloaderSWVersion) { WriteNextResponseByte('0' + BOOTLOADER_VERSION_MAJOR); WriteNextResponseByte('0' + BOOTLOADER_VERSION_MINOR); @@ -475,12 +507,7 @@ static void CDC_Task(void) { /* Clear the application section of flash */ for (uint32_t CurrFlashAddress = 0; CurrFlashAddress < (uint32_t)BOOT_START_ADDR; CurrFlashAddress += SPM_PAGESIZE) - { - boot_page_erase(CurrFlashAddress); - boot_spm_busy_wait(); - boot_page_write(CurrFlashAddress); - boot_spm_busy_wait(); - } + BootloaderAPI_ErasePage(CurrFlashAddress); /* Send confirmation byte back to the host */ WriteNextResponseByte('\r'); @@ -489,7 +516,7 @@ static void CDC_Task(void) else if (Command == AVR109_COMMAND_WriteLockbits) { /* Set the lock bits to those given by the host */ - boot_lock_bits_set(FetchNextCommandByte()); + BootloaderAPI_WriteLock(FetchNextCommandByte()); /* Send confirmation byte back to the host */ WriteNextResponseByte('\r'); @@ -497,19 +524,19 @@ static void CDC_Task(void) #endif else if (Command == AVR109_COMMAND_ReadLockbits) { - WriteNextResponseByte(boot_lock_fuse_bits_get(GET_LOCK_BITS)); + WriteNextResponseByte(BootloaderAPI_ReadLock()); } else if (Command == AVR109_COMMAND_ReadLowFuses) { - WriteNextResponseByte(boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS)); + WriteNextResponseByte(BootloaderAPI_ReadFuse(GET_LOW_FUSE_BITS)); } else if (Command == AVR109_COMMAND_ReadHighFuses) { - WriteNextResponseByte(boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS)); + WriteNextResponseByte(BootloaderAPI_ReadFuse(GET_HIGH_FUSE_BITS)); } else if (Command == AVR109_COMMAND_ReadExtendedFuses) { - WriteNextResponseByte(boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS)); + WriteNextResponseByte(BootloaderAPI_ReadFuse(GET_EXTENDED_FUSE_BITS)); } #if !defined(NO_BLOCK_SUPPORT) else if (Command == AVR109_COMMAND_GetBlockWriteSupport) @@ -530,7 +557,7 @@ static void CDC_Task(void) else if (Command == AVR109_COMMAND_FillFlashPageWordHigh) { /* Write the high byte to the current flash page */ - boot_page_fill(CurrAddress, FetchNextCommandByte()); + BootloaderAPI_FillWord(CurrAddress, FetchNextCommandByte()); /* Send confirmation byte back to the host */ WriteNextResponseByte('\r'); @@ -538,7 +565,7 @@ static void CDC_Task(void) else if (Command == AVR109_COMMAND_FillFlashPageWordLow) { /* Write the low byte to the current flash page */ - boot_page_fill(CurrAddress | 0x01, FetchNextCommandByte()); + BootloaderAPI_FillWord(CurrAddress | 0x01, FetchNextCommandByte()); /* Increment the address */ CurrAddress += 2; @@ -549,10 +576,7 @@ static void CDC_Task(void) else if (Command == AVR109_COMMAND_WriteFlashPage) { /* Commit the flash page to memory */ - boot_page_write(CurrAddress); - - /* Wait until write operation has completed */ - boot_spm_busy_wait(); + BootloaderAPI_WritePage(CurrAddress); /* Send confirmation byte back to the host */ WriteNextResponseByte('\r'); @@ -573,7 +597,7 @@ static void CDC_Task(void) else if (Command == AVR109_COMMAND_WriteEEPROM) { /* Read the byte from the endpoint and write it to the EEPROM */ - eeprom_write_byte((uint8_t*)((intptr_t)(CurrAddress >> 1)), FetchNextCommandByte()); + eeprom_update_byte((uint8_t*)((intptr_t)(CurrAddress >> 1)), FetchNextCommandByte()); /* Increment the address after use */ CurrAddress += 2; @@ -630,4 +654,3 @@ static void CDC_Task(void) /* Acknowledge the command from the host */ Endpoint_ClearOUT(); } -