diff options
author | cpldcpu <cpldcpu@gmail.com> | 2013-10-07 01:05:23 +0200 |
---|---|---|
committer | cpldcpu <cpldcpu@gmail.com> | 2013-10-07 01:05:23 +0200 |
commit | bfc82adaf601462b5bb27afd20d5f655f5537146 (patch) | |
tree | 17e9712d4bfcdbeba167cd27ca61fc2f08175ccb /firmware/main.c | |
parent | a3fdc6f10b89ef806e2f4744f3f5de667c0df84f (diff) | |
download | micronucleus-bfc82adaf601462b5bb27afd20d5f655f5537146.tar.gz micronucleus-bfc82adaf601462b5bb27afd20d5f655f5537146.tar.bz2 micronucleus-bfc82adaf601462b5bb27afd20d5f655f5537146.zip |
Do modulo only on lower byte - saves 24 bytes
GCC generated some quite weird code from the module operations. Although
highly optimized, most of the instructions are redundant. Is this a bug?
The current solution is a bit hacky, but should also work when the pages
size is changed in future devices.
uchar isLast = (((currentAddress&0xff) % SPM_PAGESIZE) == 0);
1e02: 80 91 69 00 lds r24, 0x0069
1e06: 90 91 6a 00 lds r25, 0x006A
1e0a: 8f 73 andi r24, 0x3F ; 63
1e0c: 99 27 eor r25, r25
// definitely need this if! seems usbFunctionWrite gets called again in
future usbPoll's in the runloop!
if (isLast) fireEvent(EVENT_WRITE_PAGE); // ask runloop to write our
page
1e0e: 89 2b or r24, r25
1e10: 39 f0 breq .+14 ; 0x1e20 <main+0x1ee>
1e12: 0d c0 rjmp .+26 ; 0x1e2e <main+0x1fc>
Diffstat (limited to 'firmware/main.c')
-rw-r--r-- | firmware/main.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/firmware/main.c b/firmware/main.c index 78d72f3..fb03923 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -134,7 +134,7 @@ static inline void eraseApplication(void) { // to minimise the chance of leaving the device in a state where the bootloader wont run, if there's power failure // during upload addr_t ptr = BOOTLOADER_ADDRESS; -// currentAddress = BOOTLOADER_ADDRESS; + cli(); while (ptr) { ptr -= SPM_PAGESIZE; @@ -223,9 +223,18 @@ static void fillFlashWithVectors(void) { //} // TODO: Or more simply: + + +#if SPM_PAGESIZE<256 do { - writeWordToPageBuffer(0xFFFF); + writeWordToPageBuffer(0xFFFF); + } while ((uchar)currentAddress % SPM_PAGESIZE); +#else + do { + writeWordToPageBuffer(0xFFFF); } while (currentAddress % SPM_PAGESIZE); +#endif + writeFlashPage(); } @@ -294,7 +303,14 @@ static uchar usbFunctionWrite(uchar *data, uchar length) { // if we have now reached another page boundary, we're done //uchar isLast = (writeLength == 0); + +#if SPM_PAGESIZE<256 + // Hack to reduce code size + uchar isLast = ((((uchar)currentAddress) % SPM_PAGESIZE) == 0); +#else uchar isLast = ((currentAddress % SPM_PAGESIZE) == 0); +#endif + // definitely need this if! seems usbFunctionWrite gets called again in future usbPoll's in the runloop! if (isLast) fireEvent(EVENT_WRITE_PAGE); // ask runloop to write our page @@ -343,7 +359,15 @@ static inline void tiny85FlashWrites(void) { // write page to flash, interrupts will be disabled for > 4.5ms including erase // TODO: Do we need this? Wouldn't the programmer always send full sized pages? - if (currentAddress % SPM_PAGESIZE) { // when we aren't perfectly aligned to a flash page boundary + +#if SPM_PAGESIZE<256 + // Hack to reduce code size + if ((uchar)currentAddress % SPM_PAGESIZE) +#else + if (currentAddress % SPM_PAGESIZE) +#endif + { + // when we aren't perfectly aligned to a flash page boundary fillFlashWithVectors(); // fill up the rest of the page with 0xFFFF (unprogrammed) bits } else { writeFlashPage(); // otherwise just write it @@ -382,6 +406,7 @@ static inline void leaveBootloader(void) { if (stored_osc_calibration != 0xFF && stored_osc_calibration != 0x00) { //OSCCAL = stored_osc_calibration; // this should really be a gradual change, but maybe it's alright anyway? // do the gradual change - failed to score extra free bytes anyway in 1.06 + while (OSCCAL > stored_osc_calibration) OSCCAL--; while (OSCCAL < stored_osc_calibration) OSCCAL++; } |