summaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorcpldcpu <cpldcpu@gmail.com>2013-10-07 01:05:23 +0200
committercpldcpu <cpldcpu@gmail.com>2013-10-07 01:05:23 +0200
commitbfc82adaf601462b5bb27afd20d5f655f5537146 (patch)
tree17e9712d4bfcdbeba167cd27ca61fc2f08175ccb /firmware
parenta3fdc6f10b89ef806e2f4744f3f5de667c0df84f (diff)
downloadmicronucleus-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')
-rw-r--r--firmware/main.c31
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++;
}