X-Git-Url: http://git.linex4red.de/pub/USBaspLoader.git/blobdiff_plain/7f2913111392f70a9720574c07e06ee9799a96da..1b7dc6a065378c465ec8ddec57938a25e62b4d35:/firmware/main.c diff --git a/firmware/main.c b/firmware/main.c index bd4eebf..fd5dd48 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -8,6 +8,8 @@ * This Revision: $Id: main.c 786 2010-05-30 20:41:40Z cs $ */ +#include "spminterface.h" /* must be included as first! */ + #include #include #include @@ -18,6 +20,8 @@ #include +#include + #include @@ -44,6 +48,15 @@ static void leaveBootloader() __attribute__((__noreturn__)); #define USBASP_FUNC_WRITEEEPROM 8 #define USBASP_FUNC_SETLONGADDRESS 9 +// additional USBasp Commands +#define USBASP_FUNC_SETISPSCK 10 +#define USBASP_FUNC_TPI_CONNECT 11 +#define USBASP_FUNC_TPI_DISCONNECT 12 +#define USBASP_FUNC_TPI_RAWREAD 13 +#define USBASP_FUNC_TPI_RAWWRITE 14 +#define USBASP_FUNC_TPI_READBLOCK 15 +#define USBASP_FUNC_TPI_WRITEBLOCK 16 +#define USBASP_FUNC_GETCAPABILITIES 127 /* ------------------------------------------------------------------------ */ #ifndef ulong @@ -95,11 +108,10 @@ typedef union longConverter{ }longConverter_t; - #if BOOTLOADER_CAN_EXIT static uchar requestBootLoaderExit; #endif -static volatile unsigned char stayinloader = 1; +static volatile unsigned char stayinloader = 0xfe; static longConverter_t currentAddress; /* in bytes */ static uchar bytesRemaining; @@ -123,6 +135,8 @@ static const uchar signatureBytes[4] = { 0x1e, 0x94, 0x06, 0 #elif defined (__AVR_ATmega328P__) 0x1e, 0x95, 0x0f, 0 +#elif defined (__AVR_ATmega1284P__) + 0x1e, 0x97, 0x05, 0 #else # error "Device signature is not known, please edit main.c!" #endif @@ -142,6 +156,7 @@ static void leaveBootloader() USB_INTR_CFG = 0; /* also reset config bits */ GICR = (1 << IVCE); /* enable change of interrupt vectors */ GICR = (0 << IVSEL); /* move interrupts to application flash section */ + /* We must go through a global function pointer variable instead of writing * ((void (*)(void))0)(); * because the compiler optimizes a constant 0 to "rcall 0" which is not @@ -168,6 +183,7 @@ static uchar replyBuffer[4]; rval = rq->wIndex.bytes[0] & 3; rval = signatureBytes[rval]; #if HAVE_READ_LOCK_FUSE +#if defined (__AVR_ATmega8__) }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 */ @@ -175,6 +191,7 @@ static uchar replyBuffer[4]; }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); #endif +#endif #if HAVE_EEPROM_BYTE_ACCESS }else if(rq->wValue.bytes[0] == 0xa0){ /* read EEPROM byte */ rval = eeprom_read_byte((void *)address.word); @@ -200,7 +217,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){ @@ -220,12 +237,13 @@ static uchar replyBuffer[4]; } }else if(rq->bRequest == USBASP_FUNC_DISCONNECT){ - stayinloader = 0; + stayinloader &= (0xfe); #if BOOTLOADER_CAN_EXIT requestBootLoaderExit = 1; /* allow proper shutdown/close of connection */ #endif }else{ - /* ignore: USBASP_FUNC_CONNECT */ + /* ignore: others, but could be USBASP_FUNC_CONNECT */ + stayinloader |= (0x01); } return len; } @@ -247,43 +265,31 @@ uchar isLast; }else{ uchar i; for(i = 0; i < len;){ -#if !HAVE_CHIP_ERASE - if((currentAddress.w[0] & (SPM_PAGESIZE - 1)) == 0){ /* if page start: erase */ - DBG1(0x33, 0, 0); -# ifndef NO_FLASH_WRITE -# if HAVE_BLB11_SOFTW_LOCKBIT - if (CURRENT_ADDRESS < (addr_t)(BOOTLOADER_ADDRESS)) { -# endif - cli(); - boot_page_erase(CURRENT_ADDRESS); /* erase page */ - sei(); - boot_spm_busy_wait(); /* wait until page is erased */ -# if HAVE_BLB11_SOFTW_LOCKBIT - } -# endif -# endif - } +#if HAVE_BLB11_SOFTW_LOCKBIT + if (CURRENT_ADDRESS >= (addr_t)(BOOTLOADER_ADDRESS)) { + return 1; + } #endif i += 2; DBG1(0x32, 0, 0); -# if HAVE_BLB11_SOFTW_LOCKBIT - if (CURRENT_ADDRESS < (addr_t)(BOOTLOADER_ADDRESS)) { -# endif cli(); boot_page_fill(CURRENT_ADDRESS, *(short *)data); sei(); -# if HAVE_BLB11_SOFTW_LOCKBIT - } -# endif CURRENT_ADDRESS += 2; data += 2; /* write page when we cross page boundary or we have the last partial page */ if((currentAddress.w[0] & (SPM_PAGESIZE - 1)) == 0 || (isLast && i >= len && isLastPage)){ +#if !HAVE_CHIP_ERASE + DBG1(0x33, 0, 0); +# ifndef NO_FLASH_WRITE + cli(); + boot_page_erase(CURRENT_ADDRESS - 2); /* erase page */ + sei(); + boot_spm_busy_wait(); /* wait until page is erased */ +# endif +#endif DBG1(0x34, 0, 0); #ifndef NO_FLASH_WRITE -# if HAVE_BLB11_SOFTW_LOCKBIT - if ((CURRENT_ADDRESS - (addr_t)2) < (addr_t)(BOOTLOADER_ADDRESS)) { -# endif cli(); boot_page_write(CURRENT_ADDRESS - 2); sei(); @@ -291,9 +297,6 @@ uchar isLast; cli(); boot_rww_enable(); sei(); -# if HAVE_BLB11_SOFTW_LOCKBIT - } -# endif #endif } } @@ -331,7 +334,6 @@ uchar i = 0; /* enforce USB re-enumerate: */ usbDeviceDisconnect(); /* do this while interrupts are disabled */ while(--i){ /* fake USB disconnect for > 250 ms */ - wdt_reset(); _delay_ms(1); } usbDeviceConnect(); @@ -341,7 +343,6 @@ uchar i = 0; int __attribute__((noreturn)) main(void) { /* initialize */ - wdt_disable(); /* main app may have enabled watchdog */ bootLoaderInit(); odDebugInit(); DBG1(0x00, 0, 0); @@ -350,6 +351,7 @@ int __attribute__((noreturn)) main(void) GICR = (1 << IVSEL); /* move interrupts to boot flash section */ #endif if(bootLoaderCondition()){ + wdt_disable(); /* main app may have enabled watchdog */ #if BOOTLOADER_CAN_EXIT uchar i = 0, j = 0; #endif @@ -364,7 +366,17 @@ int __attribute__((noreturn)) main(void) } } #endif - }while ((stayinloader) || (!bootLoaderCondition())); /* main event loop */ + if (stayinloader >= 0x10) { + if (!bootLoaderCondition()) { + stayinloader-=0x10; + } + } else { + if (bootLoaderCondition()) { + if (stayinloader > 1) stayinloader-=2; + } + } + + }while (stayinloader); /* main event loop */ } leaveBootloader(); }