diff options
author | cpldcpu <cpldcpu@gmail.com> | 2014-01-05 16:30:52 +0100 |
---|---|---|
committer | cpldcpu <cpldcpu@gmail.com> | 2014-01-05 16:30:52 +0100 |
commit | 4614182cbc1fa442bf58be4e8a9e86f3bdf74341 (patch) | |
tree | c99d751d354142ca933c14826a5b4622cd5f4afd /firmware | |
parent | 4f96c4048389d6be8df8143b3a29d877f75b5860 (diff) | |
download | micronucleus-4614182cbc1fa442bf58be4e8a9e86f3bdf74341.tar.gz micronucleus-4614182cbc1fa442bf58be4e8a9e86f3bdf74341.tar.bz2 micronucleus-4614182cbc1fa442bf58be4e8a9e86f3bdf74341.zip |
firmware: Removed trampoline and INT patching
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/Makefile | 4 | ||||
-rw-r--r-- | firmware/bootloaderconfig.h | 6 | ||||
-rw-r--r-- | firmware/crt1.S | 11 | ||||
-rw-r--r-- | firmware/main.c | 114 |
4 files changed, 56 insertions, 79 deletions
diff --git a/firmware/Makefile b/firmware/Makefile index 5db6aa9..996b08c 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -150,7 +150,7 @@ DEFINES = -DBOOTLOADER_ADDRESS=0x$(BOOTLOADER_ADDRESS) #-DDEBUG_LEVEL=2 # Remove the -fno-* options when you use gcc 3, it does not understand them # CFLAGS = -g2 -nostartfiles -ffunction-sections -fdata-sections -fpack-struct -Wall -Os -fno-inline-small-functions -fno-move-loop-invariants -fno-tree-scev-cprop -I. -mmcu=$(DEVICE) -DF_CPU=$(F_CPU) $(DEFINES) -LDFLAGS = -Wl,--relax,--section-start=.text=$(BOOTLOADER_ADDRESS),-Map=main.map,--section-start=.zerotable=0 +LDFLAGS = -Wl,--relax,--section-start=.text=$(BOOTLOADER_ADDRESS),-Map=main.map OBJECTS = crt1.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o @@ -198,7 +198,7 @@ main.bin: $(OBJECTS) main.hex: main.bin @rm -f main.hex main.eep.hex - @avr-objcopy -j .text -j .zerotable -j .data -O ihex main.bin main.hex + @avr-objcopy -j .text -j .data -O ihex main.bin main.hex @avr-size main.bin disasm: main.bin diff --git a/firmware/bootloaderconfig.h b/firmware/bootloaderconfig.h index a93e6ff..b551db7 100644 --- a/firmware/bootloaderconfig.h +++ b/firmware/bootloaderconfig.h @@ -140,16 +140,14 @@ these macros are defined, the boot loader uses them. // Microcontroller vectortable entries in the flash #define RESET_VECTOR_OFFSET 0 -#define USBPLUS_VECTOR_OFFSET 2 // number of bytes before the boot loader vectors to store the tiny application vector table -#define TINYVECTOR_RESET_OFFSET 4 -#define TINYVECTOR_USBPLUS_OFFSET 2 +#define TINYVECTOR_RESET_OFFSET 2 #define TINYVECTOR_OSCCAL_OFFSET 6 /* ------------------------------------------------------------------------ */ // postscript are the few bytes at the end of programmable memory which store tinyVectors -#define POSTSCRIPT_SIZE 6 +#define POSTSCRIPT_SIZE 4 #define PROGMEM_SIZE (BOOTLOADER_ADDRESS - POSTSCRIPT_SIZE) /* max size of user program */ /* ------------------------------------------------------------------------- */ diff --git a/firmware/crt1.S b/firmware/crt1.S index 29693ac..399e68d 100644 --- a/firmware/crt1.S +++ b/firmware/crt1.S @@ -60,8 +60,8 @@ __bad_interrupt: __vectors: XJMP __init vector __vector_1 - vector __vector_2 - vector __vector_3 +; vector __vector_2 +; vector __vector_3 .endfunc /* Handle unexpected interrupts (enabled and no handler), which @@ -98,10 +98,3 @@ __init: XJMP main ; .endfunc - - .section .zerotable,"ax",@progbits -zerovectors: - XJMP __init - XJMP __vector_1 - XJMP __vector_2 - XJMP __vector_3 diff --git a/firmware/main.c b/firmware/main.c index d3b1ce4..19ed37a 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -13,10 +13,10 @@ */ #define MICRONUCLEUS_VERSION_MAJOR 1 -#define MICRONUCLEUS_VERSION_MINOR 11 +#define MICRONUCLEUS_VERSION_MINOR 99 // how many milliseconds should host wait till it sends another erase or write? // needs to be above 4.5 (and a whole integer) as avr freezes for 4.5ms -#define MICRONUCLEUS_WRITE_SLEEP 8 +#define MICRONUCLEUS_WRITE_SLEEP 5 // Use the old delay routines without NOP padding. This saves memory. #define __DELAY_BACKWARD_COMPATIBLE__ @@ -47,7 +47,7 @@ register uint16_union_t idlePolls asm("r6"); // r6/r7 idlecounter register uint8_t osccal_default asm("r2"); #endif -static uint16_t vectorTemp[2]; // remember data to create tinyVector table before BOOTLOADER_ADDRESS +static uint16_t vectorTemp; // remember data to create tinyVector table before BOOTLOADER_ADDRESS enum { cmd_local_nop=0, // also: get device info @@ -55,7 +55,7 @@ enum { cmd_transfer_page=1, cmd_erase_application=2, cmd_exit=4, - cmd_write_page=5, + cmd_write_page=64, // internal commands start at 64 }; // Definition of sei and cli without memory barrier keyword to prevent reloading of memory variables @@ -83,7 +83,6 @@ static inline void eraseApplication(void) { uint8_t i; uint16_t ptr = BOOTLOADER_ADDRESS; - cli(); while (ptr) { ptr -= SPM_PAGESIZE; @@ -92,14 +91,15 @@ static inline void eraseApplication(void) { currentAddress.w = 0; for (i=0; i<8; i++) writeWordToPageBuffer(0xFFFF); // Write first 8 words to fill in vectors. - writeFlashPage(); // enables interrupts -} + writeFlashPage(); + } + // simply write currently stored page in to already erased flash memory -static void writeFlashPage(void) { - // cli(); +static inline void writeFlashPage(void) { + boot_page_write(currentAddress.w - 2); // will halt CPU, no waiting required - // sei(); + } // clear memory which stores data to be written by next writeFlashPage call @@ -117,29 +117,20 @@ static void writeFlashPage(void) { // write a word in to the page buffer, doing interrupt table modifications where they're required static void writeWordToPageBuffer(uint16_t data) { - uint8_t previous_sreg; // first two interrupt vectors get replaced with a jump to the bootloader's vector table // remember vectors or the tinyvector table if (currentAddress.w == RESET_VECTOR_OFFSET * 2) { - vectorTemp[0] = data; - data = 0xC000 + (BOOTLOADER_ADDRESS/2) - 1; - } -/* - if (currentAddress.w == USBPLUS_VECTOR_OFFSET * 2) { - vectorTemp[1] = data; + vectorTemp = data; data = 0xC000 + (BOOTLOADER_ADDRESS/2) - 1; } - */ - // at end of page just before bootloader, write in tinyVector table + + // at end of page just before bootloader, write in tinyVector table // see http://embedded-creations.com/projects/attiny85-usb-bootloader-overview/avr-jtag-programmer/ // for info on how the tiny vector table works if (currentAddress.w == BOOTLOADER_ADDRESS - TINYVECTOR_RESET_OFFSET) { - data = vectorTemp[0] + ((FLASHEND + 1) - BOOTLOADER_ADDRESS)/2 + 2 + RESET_VECTOR_OFFSET; -/* - } else if (currentAddress.w == BOOTLOADER_ADDRESS - TINYVECTOR_USBPLUS_OFFSET) { - data = vectorTemp[1] + ((FLASHEND + 1) - BOOTLOADER_ADDRESS)/2 + 1 + USBPLUS_VECTOR_OFFSET; -*/ + data = vectorTemp + ((FLASHEND + 1) - BOOTLOADER_ADDRESS)/2 + 2 + RESET_VECTOR_OFFSET; + #if (!OSCCAL_RESTORE) && OSCCAL_16_5MHz } else if (currentAddress.w == BOOTLOADER_ADDRESS - TINYVECTOR_OSCCAL_OFFSET) { data = OSCCAL; @@ -206,17 +197,6 @@ static uint8_t usbFunctionWrite(uint8_t *data, uint8_t length) { return isLast; // let V-USB know we're done with this request } -/* ------------------------------------------------------------------------ */ -void PushMagicWord (void) __attribute__ ((naked)) __attribute__ ((section (".init3"))); - -// put the word "B007" at the bottom of the stack (RAMEND - RAMEND-1) -void PushMagicWord (void) { - asm volatile("ldi r16, 0xB0"::); - asm volatile("push r16"::); - asm volatile("ldi r16, 0x07"::); - asm volatile("push r16"::); -} - static void initHardware (void) { // Disable watchdog and set timeout to maximum in case the WDT is fused on @@ -244,20 +224,18 @@ static void initHardware (void) // reset system to a normal state and launch user program static void leaveBootloader(void) __attribute__((__noreturn__)); static inline void leaveBootloader(void) { - + bootLoaderExit(); - //cli(); + + _delay_ms(10); // Bus needs to see a few more SOFs before it can be disconnected usbDeviceDisconnect(); /* Disconnect micronucleus */ USB_INTR_ENABLE = 0; USB_INTR_CFG = 0; /* also reset config bits */ - // clear magic word from bottom of stack before jumping to the app - *(uint8_t*)(RAMEND) = 0x00; // A single write is sufficient to invalidate magic word - #if OSCCAL_RESTORE OSCCAL=osccal_default; - nop(); // NOP to avoid CPU hickup during oscillator stabilization + nop(); // NOP to avoid CPU hickup during oscillator stabilization #elif OSCCAL_16_5MHz // adjust clock to previous calibration value, so user program always starts with same calibration // as when it was uploaded originally @@ -268,13 +246,15 @@ static inline void leaveBootloader(void) { } #endif - asm volatile ("rjmp __vectors - 4"); // jump to application reset vector at end of flash + asm volatile ("rjmp __vectors - 2"); // jump to application reset vector at end of flash for (;;); // Make sure function does not return to help compiler optimize } +void USB_INTR_VECTOR(void); + int main(void) { - + uint8_t ackSent=0; bootLoaderInit(); DDRB|=3; @@ -291,6 +271,8 @@ int main(void) { } do { + + USB_INTR_PENDING = 1<<USB_INTR_PENDING_BIT; while ( !(USB_INTR_PENDING & (1<<USB_INTR_PENDING_BIT)) ); USB_INTR_VECTOR(); @@ -324,38 +306,42 @@ int main(void) { if (USB_INTR_PENDING & (1<<USB_INTR_PENDING_BIT)) // Usbpoll intersected with data packe { PORTB|=_BV(PB0); - uint8_t tx; - uint8_t timeout=(uint8_t)(10.0f*(F_CPU/1.0e6f)/7.0f+0.5); - tx=timeout; + uint8_t ctr; + uint8_t timeout=(uint8_t)(10.0f*(F_CPU/1.0e6f)/5.0f+0.5); + + // loop takes 5 cycles + asm volatile( + " ldi %0,%1 \n\t" + "loop%=: sbic %2,%3 \n\t" + " ldi %0,%1 \n\t" + " subi %0,1 \n\t" + " brne loop%= \n\t" + : "=&d" (ctr) + : "M" ((uint8_t)(10.0f*(F_CPU/1.0e6f)/5.0f+0.5)), "I" (_SFR_IO_ADDR(USBIN)), "M" (USB_CFG_DPLUS_BIT) + ); + // loop takes 9 cycles + /* while (--tx) { uint8_t usbin=USBIN; if (usbin&(1<<USB_CFG_DPLUS_BIT)) {tx=timeout;} } - USB_INTR_PENDING = 1<<USB_INTR_PENDING_BIT; + */ PORTB&=~_BV(PB0); } PORTB&=~_BV(PB1); + + if (command == cmd_local_nop) continue; +/* if (!ackSent) {ackSent=1;continue;} + ackSent=0;*/ - if ( command != cmd_local_nop) - { - // Make sure all USB activity has finished before running any blocking events - uint16_t n=1000; - while (--n) - { - if (USB_INTR_PENDING & (1<<USB_INTR_PENDING_BIT)) - { - // Vector interrupt manually - USB_INTR_PENDING = 1<<USB_INTR_PENDING_BIT; - USB_INTR_VECTOR(); - n=1000; - } - } - } - + USB_INTR_PENDING = 1<<USB_INTR_PENDING_BIT; + while ( !(USB_INTR_PENDING & (1<<USB_INTR_PENDING_BIT)) ); + USB_INTR_VECTOR(); + idlePolls.w++; // Try to execute program if bootloader exit condition is met @@ -373,7 +359,7 @@ int main(void) { LED_EXIT(); } - + leaveBootloader(); } /* ------------------------------------------------------------------------ */ |