X-Git-Url: http://git.linex4red.de/pub/USBaspLoader.git/blobdiff_plain/e9f700feb2061244f3c9bfd81e8b0c94011afe10..a93ee833f02abfd9cbd22cc14be1cbe630f9103e:/firmware/main.c diff --git a/firmware/main.c b/firmware/main.c index c4b0b95..c80ab7d 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -1,7 +1,9 @@ /* Name: main.c * Project: USBaspLoader * Author: Christian Starkjohann + * Author: Stephan Baerwolf * Creation Date: 2007-12-08 + * Modification Date: 2012-11-10 * Tabsize: 4 * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH * License: GNU GPL v2 (see License.txt) @@ -18,7 +20,21 @@ #include #include + +#if 0 +/* + * 29.09.2012 / 30.09.2012 + * + * Since cpufunc.h is not needed in this context and + * since it is not available in all toolchains, this include + * becomes deactivated by github issue-report. + * (In case of trouble it remains in sourcecode for reactivation.) + * + * The autor would like to thank Lena-M for reporting this + * issue (https://github.com/baerwolf/USBaspLoader/issues/1). + */ #include +#endif #include @@ -66,16 +82,6 @@ static void leaveBootloader() __attribute__((__noreturn__)); # define uint unsigned int #endif -/* defaults if not in config file: */ -#ifndef HAVE_EEPROM_PAGED_ACCESS -# define HAVE_EEPROM_PAGED_ACCESS 0 -#endif -#ifndef HAVE_EEPROM_BYTE_ACCESS -# define HAVE_EEPROM_BYTE_ACCESS 0 -#endif -#ifndef BOOTLOADER_CAN_EXIT -# define BOOTLOADER_CAN_EXIT 0 -#endif /* allow compatibility with avrusbboot's bootloaderconfig.h: */ #ifdef BOOTLOADER_INIT @@ -109,9 +115,8 @@ typedef union longConverter{ #if BOOTLOADER_CAN_EXIT -static uchar requestBootLoaderExit; -#endif static volatile unsigned char stayinloader = 0xfe; +#endif static longConverter_t currentAddress; /* in bytes */ static uchar bytesRemaining; @@ -125,16 +130,44 @@ static const uchar currentRequest = 0; static const uchar signatureBytes[4] = { #ifdef SIGNATURE_BYTES SIGNATURE_BYTES -#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega8HVA__) +#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega8A__) || defined (__AVR_ATmega8HVA__) 0x1e, 0x93, 0x07, 0 -#elif defined (__AVR_ATmega48__) || defined (__AVR_ATmega48P__) +#elif defined (__AVR_ATmega32__) + 0x1e, 0x95, 0x02, 0 +#elif defined (__AVR_ATmega48__) || defined (__AVR_ATmega48A__) || defined (__AVR_ATmega48P__) + #error ATmega48 does not support bootloaders! 0x1e, 0x92, 0x05, 0 -#elif defined (__AVR_ATmega88__) || defined (__AVR_ATmega88P__) +#elif defined (__AVR_ATmega48PA__) + #error ATmega48 does not support bootloaders! + 0x1e, 0x92, 0x0A, 0 +#elif defined (__AVR_ATmega88__) || defined (__AVR_ATmega88A__) || defined (__AVR_ATmega88P__) 0x1e, 0x93, 0x0a, 0 -#elif defined (__AVR_ATmega168__) || defined (__AVR_ATmega168P__) +#elif defined (__AVR_ATmega88PA__) + 0x1e, 0x93, 0x0F, 0 +#elif defined (__AVR_ATmega164A__) + 0x1e, 0x94, 0x0f, 0 +#elif defined (__AVR_ATmega164P__) + 0x1e, 0x94, 0x0a, 0 +#elif defined (__AVR_ATmega168__) || defined (__AVR_ATmega168A__) || defined (__AVR_ATmega168P__) 0x1e, 0x94, 0x06, 0 +#elif defined (__AVR_ATmega168PA__) + 0x1e, 0x94, 0x0B, 0 +#elif defined (__AVR_ATmega324A__) + 0x1e, 0x95, 0x15, 0 +#elif defined (__AVR_ATmega324P__) + 0x1e, 0x95, 0x08, 0 +#elif defined (__AVR_ATmega328__) + 0x1e, 0x95, 0x14, 0 #elif defined (__AVR_ATmega328P__) 0x1e, 0x95, 0x0f, 0 +#elif defined (__AVR_ATmega644__) || defined (__AVR_ATmega644A__) + 0x1e, 0x96, 0x09, 0 +#elif defined (__AVR_ATmega644P__) || defined (__AVR_ATmega644PA__) + 0x1e, 0x96, 0x0a, 0 +#elif defined (__AVR_ATmega128__) + 0x1e, 0x97, 0x02, 0 +#elif defined (__AVR_ATmega1284__) + 0x1e, 0x97, 0x06, 0 #elif defined (__AVR_ATmega1284P__) 0x1e, 0x97, 0x05, 0 #else @@ -183,13 +216,33 @@ static uchar replyBuffer[4]; rval = rq->wIndex.bytes[0] & 3; rval = signatureBytes[rval]; #if HAVE_READ_LOCK_FUSE -#if defined (__AVR_ATmega8__) +#if defined (__AVR_ATmega8__) || defined (__AVR_ATmega8A__) || defined (__AVR_ATmega32__) + }else if(rq->wValue.bytes[0] == 0x58 && rq->wValue.bytes[1] == 0x00){ /* read lock bits */ + rval = boot_lock_fuse_bits_get(GET_LOCK_BITS); + }else if(rq->wValue.bytes[0] == 0x50 && rq->wValue.bytes[1] == 0x00){ /* read lfuse bits */ + rval = boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS); + }else if(rq->wValue.bytes[0] == 0x58 && rq->wValue.bytes[1] == 0x08){ /* read hfuse bits */ + rval = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); + +#elif defined (__AVR_ATmega48__) || defined (__AVR_ATmega48A__) || defined (__AVR_ATmega48P__) || defined (__AVR_ATmega48PA__) || \ + defined (__AVR_ATmega88__) || defined (__AVR_ATmega88A__) || defined (__AVR_ATmega88P__) || defined (__AVR_ATmega88PA__) || \ + defined (__AVR_ATmega164A__) || defined (__AVR_ATmega164P__) || \ + defined (__AVR_ATmega168__) || defined (__AVR_ATmega168A__) || defined (__AVR_ATmega168P__) || defined (__AVR_ATmega168PA__) || \ + defined (__AVR_ATmega324A__) || defined (__AVR_ATmega324P__) || \ + defined (__AVR_ATmega328__) || defined (__AVR_ATmega328P__) || \ + defined (__AVR_ATmega644__) || defined (__AVR_ATmega644A__) || defined (__AVR_ATmega644P__) || defined (__AVR_ATmega644PA__) || \ + defined (__AVR_ATmega128__) || \ + defined (__AVR_ATmega1284__) || defined (__AVR_ATmega1284P__) }else if(rq->wValue.bytes[0] == 0x58 && rq->wValue.bytes[1] == 0x00){ /* read lock bits */ rval = boot_lock_fuse_bits_get(GET_LOCK_BITS); }else if(rq->wValue.bytes[0] == 0x50 && rq->wValue.bytes[1] == 0x00){ /* read lfuse bits */ rval = boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS); }else if(rq->wValue.bytes[0] == 0x58 && rq->wValue.bytes[1] == 0x08){ /* read hfuse bits */ rval = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); + }else if(rq->wValue.bytes[0] == 0x50 && rq->wValue.bytes[1] == 0x08){ /* read efuse bits */ + rval = boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS ); +#else + #warning "HAVE_READ_LOCK_FUSE is activated but MCU unknown -> will not support this feature" #endif #endif #if HAVE_EEPROM_BYTE_ACCESS @@ -217,7 +270,7 @@ static uchar replyBuffer[4]; } replyBuffer[3] = rval; len = 4; - }else if(rq->bRequest == USBASP_FUNC_ENABLEPROG){ + }else if((rq->bRequest == USBASP_FUNC_ENABLEPROG) || (rq->bRequest == USBASP_FUNC_SETISPSCK)){ /* replyBuffer[0] = 0; is never touched and thus always 0 which means success */ len = 1; }else if(rq->bRequest >= USBASP_FUNC_READFLASH && rq->bRequest <= USBASP_FUNC_SETLONGADDRESS){ @@ -237,13 +290,15 @@ static uchar replyBuffer[4]; } }else if(rq->bRequest == USBASP_FUNC_DISCONNECT){ - stayinloader &= (0xfe); + #if BOOTLOADER_CAN_EXIT - requestBootLoaderExit = 1; /* allow proper shutdown/close of connection */ + stayinloader &= (0xfe); #endif }else{ /* ignore: others, but could be USBASP_FUNC_CONNECT */ +#if BOOTLOADER_CAN_EXIT stayinloader |= (0x01); +#endif } return len; } @@ -351,21 +406,13 @@ int __attribute__((noreturn)) main(void) GICR = (1 << IVSEL); /* move interrupts to boot flash section */ #endif if(bootLoaderCondition()){ +#if NEED_WATCHDOG wdt_disable(); /* main app may have enabled watchdog */ -#if BOOTLOADER_CAN_EXIT - uchar i = 0, j = 0; #endif initForUsbConnectivity(); do{ usbPoll(); #if BOOTLOADER_CAN_EXIT - if(requestBootLoaderExit){ - if(--i == 0){ - if(--j == 0) - break; - } - } -#endif if (stayinloader >= 0x10) { if (!bootLoaderCondition()) { stayinloader-=0x10; @@ -375,8 +422,13 @@ int __attribute__((noreturn)) main(void) if (stayinloader > 1) stayinloader-=2; } } +#endif - }while (stayinloader); /* main event loop */ +#if BOOTLOADER_CAN_EXIT + }while (stayinloader); /* main event loop, if BOOTLOADER_CAN_EXIT*/ +#else + }while (1); /* main event loop */ +#endif } leaveBootloader(); }