diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | firmware/Makefile | 22 | ||||
-rw-r--r-- | firmware/main.c | 110 | ||||
-rw-r--r-- | firmware/osccalASM.S | 22 | ||||
-rw-r--r-- | firmware/usbconfig.h | 8 | ||||
-rw-r--r-- | firmware/usbdrv/asmcommon.inc | 5 | ||||
-rw-r--r-- | firmware/usbdrv/usbdrvasm165.inc | 4 |
7 files changed, 125 insertions, 48 deletions
@@ -1,3 +1,5 @@ +*.o +*.tmp firmware/*.bin commandline/littleWire_util.o commandline/micronucleus diff --git a/firmware/Makefile b/firmware/Makefile index 941310c..5db6aa9 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -24,7 +24,7 @@ LOCKOPT = -U lock:w:0x2f:m # - for the size of your device (8kb = 1024 * 8 = 8192) subtract above value 2124... = 6068 # - How many pages in is that? 6068 / 64 (tiny85 page size in bytes) = 94.8125 # - round that down to 94 - our new bootloader address is 94 * 64 = 6016, in hex = 1780 -BOOTLOADER_ADDRESS = 18C0 +BOOTLOADER_ADDRESS = 17C0 PROGRAMMER = -c USBasp # PROGRAMMER contains AVRDUDE options to address your programmer @@ -159,17 +159,17 @@ OBJECTS += osccalASM.o all: main.hex .c.o: - $(CC) $(CFLAGS) -c $< -o $@ -Wa,-ahls=$<.lst + @$(CC) $(CFLAGS) -c $< -o $@ -Wa,-ahls=$<.lst .S.o: - $(CC) $(CFLAGS) -x assembler-with-cpp -c $< -o $@ + @$(CC) $(CFLAGS) -x assembler-with-cpp -c $< -o $@ # "-x assembler-with-cpp" should not be necessary since this is the default # file type for the .S (with capital S) extension. However, upper case # characters are not always preserved on Windows. To ensure WinAVR # compatibility define the file type manually. .c.s: - $(CC) $(CFLAGS) -S $< -o $@ + @$(CC) $(CFLAGS) -S $< -o $@ flash: all $(AVRDUDE) -U flash:w:main.hex:i -B 10 @@ -190,22 +190,22 @@ read_fuses: $(UISP) --rd_fuses clean: - rm -f main.hex main.bin main.c.lst main.map *.o usbdrv/*.o main.s usbdrv/oddebug.s usbdrv/usbdrv.s *.lss + @rm -f main.hex main.bin main.c.lst main.map *.o usbdrv/*.o main.s usbdrv/oddebug.s usbdrv/usbdrv.s main.lss # file targets: main.bin: $(OBJECTS) - $(CC) $(CFLAGS) -o main.bin $(OBJECTS) $(LDFLAGS) + @$(CC) $(CFLAGS) -o main.bin $(OBJECTS) $(LDFLAGS) 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-size main.hex + @rm -f main.hex main.eep.hex + @avr-objcopy -j .text -j .zerotable -j .data -O ihex main.bin main.hex + @avr-size main.bin disasm: main.bin - avr-objdump -d -S main.bin >main.lss + @avr-objdump -d -S main.bin >main.lss cpp: - $(CC) $(CFLAGS) -E main.c + @$(CC) $(CFLAGS) -E main.c # Special rules for generating hex files for various devices and clock speeds ALLHEXFILES = hexfiles/mega8_12mhz.hex hexfiles/mega8_15mhz.hex hexfiles/mega8_16mhz.hex \ diff --git a/firmware/main.c b/firmware/main.c index 16cca65..1fdda03 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -27,9 +27,6 @@ #include <util/delay.h> #include "bootloaderconfig.h" - - - #include "usbdrv/usbdrv.c" // verify the bootloader address aligns with page size @@ -100,9 +97,9 @@ static inline void eraseApplication(void) { // simply write currently stored page in to already erased flash memory static void writeFlashPage(void) { - cli(); + // cli(); boot_page_write(currentAddress.w - 2); // will halt CPU, no waiting required - sei(); + // sei(); } // clear memory which stores data to be written by next writeFlashPage call @@ -147,14 +144,14 @@ static void writeWordToPageBuffer(uint16_t data) { #endif } - previous_sreg=SREG; - cli(); // ensure interrupts are disabled + // previous_sreg=SREG; + // cli(); // ensure interrupts are disabled boot_page_fill(currentAddress.w, data); // increment progmem address by one word currentAddress.w += 2; - SREG=previous_sreg; + // SREG=previous_sreg; } // This function is never called, it is just here to suppress a compiler warning. @@ -231,11 +228,14 @@ static void initHardware (void) #endif usbDeviceDisconnect(); /* do this while interrupts are disabled */ - _delay_ms(500); + _delay_ms(300); usbDeviceConnect(); + + // Todo: timeout if no reset is found + calibrateOscillatorASM(); usbInit(); // Initialize INT settings after reconnect - - sei(); + + // sei(); } /* ------------------------------------------------------------------------ */ @@ -244,7 +244,7 @@ static void leaveBootloader(void) __attribute__((__noreturn__)); static inline void leaveBootloader(void) { bootLoaderExit(); - cli(); + //cli(); usbDeviceDisconnect(); /* Disconnect micronucleus */ USB_INTR_ENABLE = 0; @@ -271,6 +271,33 @@ static inline void leaveBootloader(void) { for (;;); // Make sure function does not return to help compiler optimize } + +static void wait_usb_interrupt( void ) +{ + // Clear any stale pending interrupt, then wait for interrupt flag + USB_INTR_PENDING = 1<<USB_INTR_PENDING_BIT; + while ( !(USB_INTR_PENDING & (1<<USB_INTR_PENDING_BIT)) ) + wdt_reset(); + + for ( ;; ) + { + // Vector interrupt manually + USB_INTR_PENDING = 1<<USB_INTR_PENDING_BIT; + USB_INTR_VECTOR(); + + // Wait a little while longer in case another one comes + uchar n = 250; // about 90us timeout + do { + if ( !--n ) + goto handled; + } + while ( !(USB_INTR_PENDING & (1<<USB_INTR_PENDING_BIT)) ); + } +handled: + command=cmd_local_nop; + usbPoll(); +} + int main(void) { bootLoaderInit(); @@ -287,23 +314,68 @@ int main(void) { } do { - _delay_us(100); - wdt_reset(); // Only necessary if WDT is fused on + + uint8_t n=200; + 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=100; + } + } + command=cmd_local_nop; + usbPoll(); + + 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; + } + } + } + +// _delay_us(100); + // wdt_reset(); // Only necessary if WDT is fused on - command=cmd_local_nop; - usbPoll(); +// command=cmd_local_nop; + // usbPoll(); idlePolls.w++; // Try to execute program if bootloader exit condition is met - if (AUTO_EXIT_MS&&(idlePolls.w==AUTO_EXIT_MS*10L)) command=cmd_exit; + // if (AUTO_EXIT_MS&&(idlePolls.w==AUTO_EXIT_MS*10L)) command=cmd_exit; LED_MACRO( idlePolls.b[1] ); // Wait for USB traffic to finish before a blocking event is executed // All events will render the MCU unresponsive to USB traffic for a while. - if (command!=cmd_local_nop) _delay_ms(2); - + /* + 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; + } + } + } + */ if (command==cmd_erase_application) eraseApplication(); else if (command==cmd_write_page) diff --git a/firmware/osccalASM.S b/firmware/osccalASM.S index 9a317f1..c0c8803 100644 --- a/firmware/osccalASM.S +++ b/firmware/osccalASM.S @@ -90,7 +90,7 @@ .global calibrateOscillatorASM calibrateOscillatorASM: - cli +; cli ldi opD, 255 ldi try, 128 ; calibration start value @@ -105,13 +105,19 @@ usbCOloop: ; Delay values = F_CPU * 999e-6 / 5 + 0.5 #if (F_CPU == 16500000) - ldi cnt16L, lo8(3297) - ldi cnt16H, hi8(3297) + ldi cnt16L, lo8(3297) + ldi cnt16H, hi8(3297) #elif (F_CPU == 12800000) - ldi cnt16L, lo8(2557) - ldi cnt16H, hi8(2557) + ldi cnt16L, lo8(2557) + ldi cnt16H, hi8(2557) +#elif (F_CPU == 12000000) + ldi cnt16L, lo8(2398) + ldi cnt16H, hi8(2398) +#elif (F_CPU == 16000000) + ldi cnt16L, lo8(3197) + ldi cnt16H, hi8(3197) #else - #error "calibrateOscillatorASM: no delayvalues defined for this F_CPU setting" + #error "calibrateOscillatorASM: no delayvalues defined for this F_CPU setting" #endif usbCOWaitStrobe: ; first wait for D- == 0 (idle strobe) @@ -147,8 +153,8 @@ usbCOnoneighborhoodsearch: out OSCCAL, opV nop - sei - ret +; sei + ret #undef i #undef opV diff --git a/firmware/usbconfig.h b/firmware/usbconfig.h index dc5cafc..6de0611 100644 --- a/firmware/usbconfig.h +++ b/firmware/usbconfig.h @@ -163,20 +163,18 @@ return;\ * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable * for each control- and out-endpoint to check for duplicate packets. */ -//#if USB_CFG_CLOCK_KHZ==16500 - -//#include "osccal.h" + #ifndef __ASSEMBLER__ void calibrateOscillatorASM(void); - +/* #if AUTO_EXIT_NO_USB_MS>0 extern uint16_union_t idlePolls; #define USB_RESET_HOOK(resetStarts) if(!resetStarts){ idlePolls.b[1]=0; calibrateOscillatorASM();} #else #define USB_RESET_HOOK(resetStarts) if(!resetStarts){ calibrateOscillatorASM();} #endif - +*/ #define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0 #endif diff --git a/firmware/usbdrv/asmcommon.inc b/firmware/usbdrv/asmcommon.inc index d2a4f7c..5e525f5 100644 --- a/firmware/usbdrv/asmcommon.inc +++ b/firmware/usbdrv/asmcommon.inc @@ -99,8 +99,9 @@ doReturn: rjmp waitForJ ;[51] save the pops and pushes -- a new interrupt is already pending sofError: POP_RETI ;macro call - reti - +; reti + ret + handleData: #if USB_CFG_CHECK_CRC CRC_CLEANUP_AND_CHECK ; jumps to ignorePacket if CRC error diff --git a/firmware/usbdrv/usbdrvasm165.inc b/firmware/usbdrv/usbdrvasm165.inc index 450d2fd..20457f4 100644 --- a/firmware/usbdrv/usbdrvasm165.inc +++ b/firmware/usbdrv/usbdrvasm165.inc @@ -49,9 +49,7 @@ USB_INTR_VECTOR: in YL, SREG ; push YL ; -#ifdef TINY85MODE -; look for magic word "B007" at the bottom of the stack - lds YL, RAMEND +#if 0 cpi YL, 0xB0 brne cleanupAndJumpToApp |