X-Git-Url: http://git.linex4red.de/pub/USBaspLoader.git/blobdiff_plain/a3d7386c66be4c2479a15ebfa60eb733c0005dbc..refs/heads/testing:/firmware/main.c diff --git a/firmware/main.c b/firmware/main.c index 98703f9..fccec56 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -11,7 +11,8 @@ #include "spminterface.h" /* must be included as first! */ -#include +#include "../misc/iofixes.h" + #include #include #include @@ -124,12 +125,13 @@ static volatile uint8_t timeout_remaining; static volatile uint16_t timeout_remaining; # endif # endif + +# define stayinloader_initialValue 0xfe # if ((HAVE_UNPRECISEWAIT)) /* here we have to assume we need to optimize for every byte */ -#define __REGISTER_stayinloader_initialValue 0xfe volatile register uint8_t stayinloader __asm__("r17"); # else -static volatile uint8_t stayinloader = 0xfe; +static volatile uint8_t stayinloader; # endif #endif @@ -163,6 +165,8 @@ static const uchar signatureBytes[4] = { 0x1e, 0x93, 0x0a, 0 #elif defined (__AVR_ATmega88PA__) 0x1e, 0x93, 0x0F, 0 +#elif defined (__AVR_ATmega162__) + 0x1e, 0x94, 0x04, 0 #elif defined (__AVR_ATmega164A__) 0x1e, 0x94, 0x0f, 0 #elif defined (__AVR_ATmega164P__) || defined (__AVR_ATmega164PA__) @@ -213,18 +217,6 @@ static const uchar signatureBytes[4] = { /* ------------------------------------------------------------------------ */ -#if (__REGISTER_stayinloader_initialValue) -/* need to put it after libc init - otherwise it fucks up the register */ -void __attribute__ ((section(".init8"),naked,used,no_instrument_function)) __REGISTER_stayinloader_initialValue_INITIALIZATION(void); -void __REGISTER_stayinloader_initialValue_INITIALIZATION(void) { - asm volatile ( - "ldi %[silreg] , %[silval]\n\t" - : [silreg] "=a" (stayinloader) - : [silval] "M" (__REGISTER_stayinloader_initialValue) - ); -} -#endif - #if (HAVE_BOOTLOADERENTRY_FROMSOFTWARE) void __attribute__ ((section(".init3"),naked,used,no_instrument_function)) __BOOTLOADERENTRY_FROMSOFTWARE__bootup_investigate_RAMEND(void); void __BOOTLOADERENTRY_FROMSOFTWARE__bootup_investigate_RAMEND(void) { @@ -374,6 +366,7 @@ uchar usbFunctionSetup_USBASP_FUNC_TRANSMIT(usbRequest_t *rq) { #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_ATmega162__) || \ defined (__AVR_ATmega164A__) || defined (__AVR_ATmega164P__) || \ defined (__AVR_ATmega168__) || defined (__AVR_ATmega168A__) || defined (__AVR_ATmega168P__) || defined (__AVR_ATmega168PA__) || \ defined (__AVR_ATmega324A__) || defined (__AVR_ATmega324P__) || \ @@ -493,9 +486,9 @@ static uchar replyBuffer[4]; }else if(rq->bRequest == USBASP_FUNC_DISCONNECT){ #if BOOTLOADER_CAN_EXIT -# if (BOOTLOADER_LOOPCYCLES_TIMEOUT) - timeout_remaining = BOOTLOADER_LOOPCYCLES_TIMEOUT; - stayinloader = (0xfe); +# ifdef CONFIG_HAVE__BOOTLOADER_ABORTTIMEOUTONACT + /* let the main loop know for ever that here was activity */ + stayinloader &= (0xfc); # else stayinloader &= (0xfe); # endif @@ -702,32 +695,35 @@ uchar i; /* ------------------------------------------------------------------------ */ -static void initForUsbConnectivity(void) -{ -#if HAVE_UNPRECISEWAIT - /* (0.25s*F_CPU)/(4 cycles per loop) ~ (65536*waitloopcnt) - * F_CPU/(16*65536) ~ waitloopcnt - * F_CPU / 1048576 ~ waitloopcnt - */ - uint8_t waitloopcnt = 1 + (F_CPU/1048576); -#endif - usbInit(); - /* enforce USB re-enumerate: */ - usbDeviceDisconnect(); /* do this while interrupts are disabled */ #if HAVE_UNPRECISEWAIT +static void _mywait(uint8_t waitloopcnt) { asm volatile ( /*we really don't care what value Z has... * ...if we loop 65536/F_CPU more or less... * ...unimportant - just save some opcodes */ -"initForUsbConnectivity_sleeploop: \n\t" +"_mywait_sleeploop%=: \n\t" "sbiw r30, 1 \n\t" "sbci %0, 0 \n\t" - "brne initForUsbConnectivity_sleeploop \n\t" + "brne _mywait_sleeploop%= \n\t" : "+d" (waitloopcnt) : : "r30","r31" ); +} +#endif + +static void initForUsbConnectivity(void) +{ + usbInit(); + /* enforce USB re-enumerate: */ + usbDeviceDisconnect(); /* do this while interrupts are disabled */ +#if HAVE_UNPRECISEWAIT + /* (0.25s*F_CPU)/(4 cycles per loop) ~ (65536*waitloopcnt) + * F_CPU/(16*65536) ~ waitloopcnt + * F_CPU / 1048576 ~ waitloopcnt + */ + _mywait(1 + (F_CPU/1048576)); #else _delay_ms(260); /* fake USB disconnect for > 250 ms */ #endif @@ -749,7 +745,39 @@ int __attribute__((__noreturn__)) main(void) GICR = (1 << IVCE); /* enable change of interrupt vectors */ GICR = (1 << IVSEL); /* move interrupts to boot flash section */ #endif +#if (HAVE_BOOTLOADER_ADDITIONALMSDEVICEWAIT>0) +# if HAVE_UNPRECISEWAIT + _mywait(1+((HAVE_BOOTLOADER_ADDITIONALMSDEVICEWAIT*F_CPU)/262144000)); +# else + _delay_ms(HAVE_BOOTLOADER_ADDITIONALMSDEVICEWAIT); +# endif +#endif if(bootLoaderCondition()){ +#if (BOOTLOADER_CAN_EXIT) +# if (USE_EXCESSIVE_ASSEMBLER) +asm volatile ( + "ldi %[sil], %[normval]\n\t" +# if ((defined(CONFIG_HAVE__BOOTLOADER_ABORTTIMEOUTONACT)) && (!(BOOTLOADER_IGNOREPROGBUTTON)) && (BOOTLOADER_LOOPCYCLES_TIMEOUT)) + "sbis %[pin], %[bit]\n\t" + "subi %[sil], 0x02\n\t" +# endif + : [sil] "=d" (stayinloader) + : [normval] "M" (stayinloader_initialValue) +# if (!(BOOTLOADER_IGNOREPROGBUTTON)) + , + [pin] "I" (_SFR_IO_ADDR(PIN_PIN(JUMPER_PORT))), + [bit] "I" (PIN(JUMPER_PORT, JUMPER_BIT)) +# endif +); +# else +# if ((defined(CONFIG_HAVE__BOOTLOADER_ABORTTIMEOUTONACT)) && (!(BOOTLOADER_IGNOREPROGBUTTON)) && (BOOTLOADER_LOOPCYCLES_TIMEOUT)) + if (bootLoaderConditionSimple()) { + stayinloader = stayinloader_initialValue - 0x02; + } else +# endif + stayinloader = stayinloader_initialValue; +# endif +#endif #if NEED_WATCHDOG # if (defined(MCUSR) && defined(WDRF)) /* @@ -766,14 +794,38 @@ int __attribute__((__noreturn__)) main(void) initForUsbConnectivity(); do{ #if ((BOOTLOADER_LOOPCYCLES_TIMEOUT) && (BOOTLOADER_CAN_EXIT)) - __loopscycles++; - if (!(__loopscycles)) { - if(timeout_remaining) timeout_remaining--; - else stayinloader&=0xf1; +# ifdef CONFIG_HAVE__BOOTLOADER_ABORTTIMEOUTONACT + if (stayinloader != 0x0e) { + /* can be reached, since high-nibble is decreased every cycle... */ +#else + if (stayinloader & 0x01) { +#endif + timeout_remaining = BOOTLOADER_LOOPCYCLES_TIMEOUT; + } else { + __loopscycles++; + if (!(__loopscycles)) { + if(timeout_remaining) timeout_remaining--; + else stayinloader&=0xf1; + } } #endif usbPoll(); #if BOOTLOADER_CAN_EXIT +#if BOOTLOADER_IGNOREPROGBUTTON + /* + * remove the high nibble as it would be subtracted due to: + * "(!bootLoaderConditionSimple())" + */ +#if USE_EXCESSIVE_ASSEMBLER +asm volatile ( + "andi %[sil], 0x0f\n\t" + : [sil] "+d" (stayinloader) + : +); +#else + stayinloader &= 0x0f; +#endif +#else #if USE_EXCESSIVE_ASSEMBLER asm volatile ( "cpi %[sil], 0x10\n\t" @@ -805,6 +857,7 @@ asm volatile ( } #endif #endif +#endif #if BOOTLOADER_CAN_EXIT }while (stayinloader); /* main event loop, if BOOTLOADER_CAN_EXIT*/