From 8eb18dba4aed3431ecfe2a65ab63b25d7ed5e863 Mon Sep 17 00:00:00 2001 From: Alvaro Gomes Sobral Barcellos Date: Wed, 20 Jul 2022 15:31:15 -0300 Subject: [PATCH] include bare bone spm routine --- optiboot/bootloaders/optiboot/Makefile | 12 ++++--- optiboot/bootloaders/optiboot/optiboot.c | 44 ++++++++++++++++++++---- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/optiboot/bootloaders/optiboot/Makefile b/optiboot/bootloaders/optiboot/Makefile index b1819468f..0f0de371c 100644 --- a/optiboot/bootloaders/optiboot/Makefile +++ b/optiboot/bootloaders/optiboot/Makefile @@ -259,6 +259,13 @@ APPSPM_CMD = -DAPP_NOSPM=1 endif endif +HELPTEXT += "Option APP_BBSPM=1 - allow call of bare bone spm\n" +ifdef APP_BBSPM +ifneq ($(APP_BBSPM),0) +BBSPM_CMD = -DAPP_BBSPM=1 +endif +endif + HELPTEXT += "Option OSCCAL_VALUE=nnn - set set OSCCAL_VALUE in bootloader\n" ifdef OSCCAL_VALUE OSCCAL_VALUE_CMD = -DOSCCAL_VALUE=$(OSCCAL_VALUE) @@ -297,7 +304,7 @@ endif COMMON_OPTIONS = $(BAUD_RATE_CMD) $(LED_START_FLASHES_CMD) $(BIGBOOT_CMD) COMMON_OPTIONS += $(SOFT_UART_CMD) $(LED_DATA_FLASH_CMD) $(LED_CMD) $(SS_CMD) -COMMON_OPTIONS += $(SUPPORT_EEPROM_CMD) $(LED_START_ON_CMD) $(APPSPM_CMD) +COMMON_OPTIONS += $(SUPPORT_EEPROM_CMD) $(LED_START_ON_CMD) $(APPSPM_CMD) $(BBSPM_CMD) COMMON_OPTIONS += $(OSCCAL_VALUE_CMD) $(VERSION_CMD) $(TIMEOUT_CMD) COMMON_OPTIONS += $(POR_CMD) $(EXTR_CMD) $(RS485_CMD) @@ -718,6 +725,3 @@ clean_asm: help: @echo -e $(HELPTEXT) - -.DEFAULT: - @echo No target named \"$<\": Maybe you need \"-f Makefile.mega0\"? diff --git a/optiboot/bootloaders/optiboot/optiboot.c b/optiboot/bootloaders/optiboot/optiboot.c index 6d9e0cc6f..30c304e4e 100644 --- a/optiboot/bootloaders/optiboot/optiboot.c +++ b/optiboot/bootloaders/optiboot/optiboot.c @@ -181,6 +181,9 @@ # define NO_START_APP_ON_POR 0 #endif +#if !defined(APP_BBSPM) +#define APP_BBSPM 0 +#endif /* UART options */ #if !defined(SOFT_UART) @@ -699,6 +702,11 @@ void pre_main(void) { " ret\n" // if do_spm isn't include, return without doing anything #else " rjmp do_spm\n" +#endif +#if APP_BBSPM + " rjmp bb_spm\n" +#else + " ret\n" // if do_spm isn't include, return without doing anything #endif "1:\n" ); @@ -1267,12 +1275,7 @@ static void inline toggle_led(void) { defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) LED_PORT ^= _BV(LED); #else - // Newer AVRs can toggle by writing PINx. - if (&LED_PIN <= &_SFR_IO8(0x31)) { // "if" code optimizes away. - LED_PIN |= _BV(LED); // becomes SBI on low ports (in theory: incorrectly) - } else { - LED_PIN = _BV(LED); // high ports can't be sbi'ed (Issue #346) - } + LED_PIN |= _BV(LED); // Newer AVRs can toggle by writing PINx #endif } @@ -1605,7 +1608,35 @@ static void do_spm(uint16_t address, uint8_t command, uint16_t data) { } #endif +#if APP_BBSPM + +/* + bare bone do_spm: + + r24 command and scratch, r25 SREG hold + r0:r1 defined by caller + r30:r31 defined by caller + SPMCR == 0x37 + SPMEN == 0x00 + + only does spm and wait until ends. only. + */ + +void bb_spm (void) { + asm volatile ( + " in r25, __SREG__\n" + " cli\n" + " sts 0x37, r24\n" + " spm\n" + "10:\n" + " lds r24, 0x37\n" + " sbrc r24, 0x00\n" + " rjmp 10b\n" + " out __SREG__, r25\n" + ); +} +#endif #if BIGBOOT /* @@ -1679,3 +1710,4 @@ OPT2FLASH(OPTIBOOT_CUSTOMVER); OPTFLASHSECT const char f_version[] = "Version=" xstr(OPTIBOOT_MAJVER) "." xstr(OPTIBOOT_MINVER); #endif +