X-Git-Url: http://git.linex4red.de/pub/USBaspLoader.git/blobdiff_plain/65042b482afd45caf8926e5a116cd72349d6ffd8..4c96f1315e9f6c7560c6aead20b393e4c55c778f:/firmware/bootloaderconfig.h diff --git a/firmware/bootloaderconfig.h b/firmware/bootloaderconfig.h index 531ba97..9eb07c9 100644 --- a/firmware/bootloaderconfig.h +++ b/firmware/bootloaderconfig.h @@ -312,6 +312,82 @@ these macros are defined, the boot loader usees them. * (except registers and IO), since RESET will NOT clear old RAM content. */ +#ifdef CONFIG_NO__BOOTLOADERENTRY_FROMSOFTWARE +# define HAVE_BOOTLOADERENTRY_FROMSOFTWARE 0 +#else +# define HAVE_BOOTLOADERENTRY_FROMSOFTWARE 1 +#endif +/* + * Enable firmware to boot the bootloader without + * user intervention + */ + +#ifdef CONFIG_NO__BOOTLOADER_HIDDENEXITCOMMAND +# define HAVE_BOOTLOADER_HIDDENEXITCOMMAND 0 +#else +# define HAVE_BOOTLOADER_HIDDENEXITCOMMAND 0xff +#endif +/* + * When enabling "BOOTLOADER_HIDDENEXITCOMMAND", then + * sending the RAW-ISP command "0xff 0xXX 0xXX 0xXX" + * will cause the bootloader to start the firmware + * as soon as the programming software disconnects. + */ + +#ifdef CONFIG_BOOTLOADER_LOOPCYCLES_TIMEOUT +# define BOOTLOADER_LOOPCYCLES_TIMEOUT (CONFIG_BOOTLOADER_LOOPCYCLES_TIMEOUT) +#else +# define BOOTLOADER_LOOPCYCLES_TIMEOUT (0) +#endif +/* + * When greater than "0", "BOOTLOADER_LOOPCYCLES_TIMEOUT" + * defines how many 16bit loopcycles can be cycled, + * before bootloader times out and starts user + * firmware. + * Of course "BOOTLOADER_CAN_EXIT" must be enabled. + * If value is even too small, bootloader will not + * exit as long as bootLoaderConditionSimple stays on. + */ + +#ifdef CONFIG_HAVE__BOOTLOADER_ABORTTIMEOUTONACT +#endif +/* + * When defined, the bootloader will abort the timeout when + * it sees some activity (bootLoaderConditionSimple() or + * programming). + * After aborting timeout, the bootloader falls back to + * conventional exitting. + */ + +#ifdef CONFIG_HAVE__BOOTLOADER_ALWAYSENTERPROGRAMMODE +#endif +/* + * Ignore bootLoaderCondition() (BUT NOT bootLoaderConditionSimple()) + * and always enter the program-mode. + * This is helpful to emulate behaviour of Arduino bootloaders + */ + +#ifdef CONFIG_HAVE__BOOTLOADER_IGNOREPROGBUTTON +# if ( (defined(CONFIG_HAVE__BOOTLOADER_ALWAYSENTERPROGRAMMODE)) && (defined(BOOTLOADER_CAN_EXIT)) && (BOOTLOADER_LOOPCYCLES_TIMEOUT >= 8) ) +# define BOOTLOADER_IGNOREPROGBUTTON 1 +# else +# define BOOTLOADER_IGNOREPROGBUTTON 0 +# endif +#endif +/* + * Generates an USBaspLoader without using the PROGBUTTON. + * It can be used to reduce the required PINcount for USBaspLoader + * on the MCU. + * However this feature is very dangerous, so it becomes only + * enabled, if "CONFIG_HAVE__BOOTLOADER_ALWAYSENTERPROGRAMMODE" is + * enabled and "CONFIG_NO__BOOTLOADER_CAN_EXIT" is disabled, too. + * Additionally "BOOTLOADER_LOOPCYCLES_TIMEOUT" must be greater + * or equal than 8 (In order to give user enough time to program). + * + * When active, "JUMPER_PORT" and "JUMPER_BIT" are ignored and + * can be soldered otherwise. + */ + //#define SIGNATURE_BYTES 0x1e, 0x93, 0x07, 0 /* ATMega8 */ /* This macro defines the signature bytes returned by the emulated USBasp to * the programmer software. They should match the actual device at least in @@ -342,22 +418,73 @@ these macros are defined, the boot loader usees them. static inline void bootLoaderInit(void) { +#if (BOOTLOADER_IGNOREPROGBUTTON) +#else PIN_DDR(JUMPER_PORT) = 0; PIN_PORT(JUMPER_PORT) = (1<< PIN(JUMPER_PORT, JUMPER_BIT)); /* activate pull-up */ +#endif // 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 */ } static inline void bootLoaderExit(void) { +#if (BOOTLOADER_IGNOREPROGBUTTON) +#else PIN_PORT(JUMPER_PORT) = 0; /* undo bootLoaderInit() changes */ +#endif } -#define bootLoaderCondition() ((PIN_PIN(JUMPER_PORT) & (1 << PIN(JUMPER_PORT, JUMPER_BIT))) == 0) + +#if (BOOTLOADER_IGNOREPROGBUTTON) +# define bootLoaderConditionSimple() (false) +#else +# define bootLoaderConditionSimple() ((PIN_PIN(JUMPER_PORT) & (1 << PIN(JUMPER_PORT, JUMPER_BIT))) == 0) +#endif + +#if (HAVE_BOOTLOADERENTRY_FROMSOFTWARE) +/* + * How it works: The idea + * + * During normal C initialization, the stackpointer (SP) always is pointed to + * SRAMs end, where it grows towards RAMSTART. + * + * Check if last possible pushed address in stack is bootloaders address. + * Store investigation result into "__BOOTLOADERENTRY_FROMSOFTWARE__bootup_RAMEND_doesmatch" + * Result will be "0xff" in case of mismatch. + */ + +#include +#include + +#define __BOOTLOADERENTRY_FROMSOFTWARE__EXPECTEDADDRESS (BOOTLOADER_ADDRESS>>1) +static volatile uint8_t __BOOTLOADERENTRY_FROMSOFTWARE__bootup_RAMEND_doesmatch __attribute__ ((section(".noinit"))); +static volatile uint8_t __BOOTLOADERENTRY_FROMSOFTWARE__bootup_MCUCSR __attribute__ ((section(".noinit"))); + +# ifdef CONFIG_HAVE__BOOTLOADER_ALWAYSENTERPROGRAMMODE +# define bootLoaderCondition() (true) +# else +static inline bool bootLoaderCondition(void) +{ + if (__BOOTLOADERENTRY_FROMSOFTWARE__bootup_MCUCSR & (~(_BV(WDRF)))) { + } else { + if (__BOOTLOADERENTRY_FROMSOFTWARE__bootup_RAMEND_doesmatch == (__BOOTLOADERENTRY_FROMSOFTWARE__EXPECTEDADDRESS & 0xff)) { + // anything else: match - the firmware is calling the bootloader + return true; + } + } + return bootLoaderConditionSimple(); +} +# endif +#else +# ifdef CONFIG_HAVE__BOOTLOADER_ALWAYSENTERPROGRAMMODE +# define bootLoaderCondition() (true) +# else +# define bootLoaderCondition bootLoaderConditionSimple +# endif +#endif #endif /* __ASSEMBLER__ */