From: Stephan Baerwolf Date: Mon, 30 Jul 2012 21:12:38 +0000 (+0000) Subject: update new features X-Git-Tag: 2010-07-27-stephan-201207302330~2 X-Git-Url: http://git.linex4red.de/pub/USBaspLoader.git/commitdiff_plain/7f2913111392f70a9720574c07e06ee9799a96da update new features * Software overwrite protection (so no urgend need for BLB11 lockbit * make USBAspLoader able to read lock-, lfuse- and hfusebit * change JUMPER-logik to button-logik Signed-off-by: Stephan Baerwolf --- diff --git a/firmware/bootloaderconfig.h b/firmware/bootloaderconfig.h index aa234a1..1b2bf24 100644 --- a/firmware/bootloaderconfig.h +++ b/firmware/bootloaderconfig.h @@ -42,7 +42,11 @@ these macros are defined, the boot loader usees them. /* This is the port where the USB bus is connected. When you configure it to * "B", the registers PORTB, PINB and DDRB will be used. */ -#define USB_CFG_DMINUS_BIT 4 +#define JUMPER_BIT 7 /* old value was 0 */ +/* + * jumper is connected to this bit in port D, active low + */ +#define USB_CFG_DMINUS_BIT 6 /* old value was 4 */ /* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected. * This may be any bit in the port. */ @@ -77,6 +81,18 @@ these macros are defined, the boot loader usees them. /* ---------------------- feature / code size options ---------------------- */ /* ------------------------------------------------------------------------- */ +#define HAVE_READ_LOCK_FUSE 1 +/* + * enable the loaders capability to load its lfuse, hfuse and lockbits + * ...However, programming of these is prohibited... + */ + +#define HAVE_BLB11_SOFTW_LOCKBIT 1 +/* + * The IC itself do not need to prgra BLB11, but the bootloader will avaoid + * to erase itself from the bootregion + */ + #define HAVE_EEPROM_PAGED_ACCESS 1 /* If HAVE_EEPROM_PAGED_ACCESS is defined to 1, page mode access to EEPROM is * compiled in. Whether page mode or byte mode access is used by AVRDUDE @@ -90,7 +106,7 @@ these macros are defined, the boot loader usees them. * signature) does not support page mode for EEPROM. It is required for * accessing the EEPROM on the ATMega8. Costs ~54 bytes. */ -#define BOOTLOADER_CAN_EXIT 1 +#define BOOTLOADER_CAN_EXIT 0 /* If this macro is defined to 1, the boot loader will exit shortly after the * programmer closes the connection to the device. Costs ~36 bytes. */ @@ -132,8 +148,6 @@ these macros are defined, the boot loader usees them. #ifndef __ASSEMBLER__ /* assembler cannot parse function definitions */ -#define JUMPER_BIT 7 /* jumper is connected to this bit in port D, active low */ - #ifndef MCUCSR /* compatibility between ATMega8 and ATMega88 */ # define MCUCSR MCUSR #endif @@ -141,8 +155,9 @@ these macros are defined, the boot loader usees them. static inline void bootLoaderInit(void) { PORTD |= (1 << JUMPER_BIT); /* activate pull-up */ - if(!(MCUCSR & (1 << EXTRF))) /* If this was not an external reset, ignore */ - leaveBootloader(); +// deactivated by Stephan - reset after each avrdude op is annoing! +// if(!(MCUCSR & (1 << EXTRF))) /* If this was not an external reset, ignore */ +// leaveBootloader(); MCUCSR = 0; /* clear all reset flags for next time */ } @@ -151,7 +166,7 @@ static inline void bootLoaderExit(void) PORTD = 0; /* undo bootLoaderInit() changes */ } -#define bootLoaderCondition() ((PIND & (1 << JUMPER_BIT)) == 0) +#define bootLoaderCondition() ((PIND & (1 << JUMPER_BIT)) == 0) #endif /* __ASSEMBLER__ */ diff --git a/firmware/main.c b/firmware/main.c index 968cf61..bd4eebf 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -15,13 +15,22 @@ #include #include #include + +#include + #include + + static void leaveBootloader() __attribute__((__noreturn__)); #include "bootloaderconfig.h" #include "usbdrv/usbdrv.c" +#ifndef BOOTLOADER_ADDRESS + #error need to know the bootloaders flash address! +#endif + /* ------------------------------------------------------------------------ */ /* Request constants used by USBasp */ @@ -85,14 +94,20 @@ typedef union longConverter{ uchar b[sizeof(addr_t)]; }longConverter_t; -static uchar requestBootLoaderExit; -static longConverter_t currentAddress; /* in bytes */ -static uchar bytesRemaining; -static uchar isLastPage; + + +#if BOOTLOADER_CAN_EXIT +static uchar requestBootLoaderExit; +#endif +static volatile unsigned char stayinloader = 1; + +static longConverter_t currentAddress; /* in bytes */ +static uchar bytesRemaining; +static uchar isLastPage; #if HAVE_EEPROM_PAGED_ACCESS -static uchar currentRequest; +static uchar currentRequest; #else -static const uchar currentRequest = 0; +static const uchar currentRequest = 0; #endif static const uchar signatureBytes[4] = { @@ -120,8 +135,9 @@ static void (*nullVector)(void) __attribute__((__noreturn__)); static void leaveBootloader() { DBG1(0x01, 0, 0); - bootLoaderExit(); cli(); + usbDeviceDisconnect(); + bootLoaderExit(); USB_INTR_ENABLE = 0; USB_INTR_CFG = 0; /* also reset config bits */ GICR = (1 << IVCE); /* enable change of interrupt vectors */ @@ -151,6 +167,14 @@ static uchar replyBuffer[4]; if(rq->wValue.bytes[0] == 0x30){ /* read signature */ rval = rq->wIndex.bytes[0] & 3; rval = signatureBytes[rval]; +#if HAVE_READ_LOCK_FUSE + }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); +#endif #if HAVE_EEPROM_BYTE_ACCESS }else if(rq->wValue.bytes[0] == 0xa0){ /* read EEPROM byte */ rval = eeprom_read_byte((void *)address.word); @@ -194,9 +218,11 @@ static uchar replyBuffer[4]; #endif len = 0xff; /* hand over to usbFunctionRead() / usbFunctionWrite() */ } -#if BOOTLOADER_CAN_EXIT + }else if(rq->bRequest == USBASP_FUNC_DISCONNECT){ - requestBootLoaderExit = 1; /* allow proper shutdown/close of connection */ + stayinloader = 0; +#if BOOTLOADER_CAN_EXIT + requestBootLoaderExit = 1; /* allow proper shutdown/close of connection */ #endif }else{ /* ignore: USBASP_FUNC_CONNECT */ @@ -225,24 +251,39 @@ uchar isLast; 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 } #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)){ 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(); @@ -250,6 +291,9 @@ uchar isLast; cli(); boot_rww_enable(); sei(); +# if HAVE_BLB11_SOFTW_LOCKBIT + } +# endif #endif } } @@ -306,7 +350,9 @@ int __attribute__((noreturn)) main(void) GICR = (1 << IVSEL); /* move interrupts to boot flash section */ #endif if(bootLoaderCondition()){ +#if BOOTLOADER_CAN_EXIT uchar i = 0, j = 0; +#endif initForUsbConnectivity(); do{ usbPoll(); @@ -318,7 +364,7 @@ int __attribute__((noreturn)) main(void) } } #endif - }while(bootLoaderCondition()); /* main event loop */ + }while ((stayinloader) || (!bootLoaderCondition())); /* main event loop */ } leaveBootloader(); } diff --git a/firmware/usbconfig.h b/firmware/usbconfig.h index 8d56d4d..94e3d99 100644 --- a/firmware/usbconfig.h +++ b/firmware/usbconfig.h @@ -203,8 +203,8 @@ * the macros. See the file USB-IDs-for-free.txt before you assign a name if * you use a shared VID/PID. */ -/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */ -/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */ +// #define USB_CFG_SERIAL_NUMBER '2', '0', '1', '2', '0', '7', '2', '1', '0', '1', '0', '0' +// #define USB_CFG_SERIAL_NUMBER_LEN 12 /* Same as above for the serial number. If you don't want a serial number, * undefine the macros. * It may be useful to provide the serial number through other means than at