-
Notifications
You must be signed in to change notification settings - Fork 88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reduce flash size #243
Comments
1I found that the 2On the other hand, four bytes could be saved in all such cases lgt8fx/lgt8f/cores/lgt8f/main.cpp Lines 79 to 82 in 960b49a
if code replaced to this: uint8_t xyz_temp = PMCR & 0x9f;
PMCR = 0x80;
PMCR = xyz_temp; 3And one more. When main clock switched to external I think no need to wait after core switched. lgt8fx/lgt8f/cores/lgt8f/main.cpp Lines 56 to 70 in 960b49a
There is also an opportunity to save here some bytes: uint8_t c = 1;
do { for(GPIOR0 = 0xff; GPIOR0 > 0; --GPIOR0); } while (c--); |
Why does not using GPIOR0 save space? Being a IO register, I think guarantees the compiler doesn't remove the code (b/c it is volatile). |
I compiled an original and a recommended code. After it done, I turned the code to assembler source. Initial code snippet: } else if(mode == INT_OSC) {
// prescaler settings - CLKPR addr 0x61
CLKPR = 0x80; // 80 e8 ldi r24, 0x80
// 80 93 61 00 sts 0x0061, r24
CLKPR = 0x01; // 91 e0 ldi r25, 0x01
// 90 93 61 00 sts 0x0061, r25
// switch to int. crystal - PMCR addr 0xF2
GPIOR0 = PMCR & 0x9f; // 90 91 f2 00 lds r25, 0x00F2
// 9f 79 andi r25, 0x9F
// 9e bb out 0x1e, r25
PMCR = 0x80; // 80 93 f2 00 sts 0x00F2, r24 - 0x80 is already in r24
PMCR = GPIOR0; // 9e b3 in r25, 0x1e
// 90 93 f2 00 sts 0x00F2, r25
- GPIOR0 addr 0x1e
// disable ext. crystal
GPIOR0 = PMCR & 0xfb; // 90 91 f2 00 lds r25, 0x00F2
// 9b 7f andi r25, 0xFB
// 9e bb out 0x1e, r25
PMCR = 0x80; // 80 93 f2 00 sts 0x00F2, r24
PMCR = GPIOR0; // 9e b3 in r25, 0x1e
// 90 93 f2 00 sts 0x00F2, r25
} Recommended code snippet: } else if(mode == INT_OSC) {
// prescaler settings - CLKPR addr 0x61
CLKPR = 0x80; // 80 e8 ldi r24, 0x80
// 80 93 61 00 sts 0x0061, r24
CLKPR = 0x01; // 91 e0 ldi r25, 0x01
// 90 93 61 00 sts 0x0061, r25
// switch to int. crystal - PMCR addr 0xF2
unint8_t temp_ = PMCR & 0x9f; // 90 91 f2 00 lds r25, 0x00F2
// 9f 79 andi r25, 0x9F
PMCR = 0x80; // 80 93 f2 00 sts 0x00F2, r24 - 0x80 is already in r24
PMCR = temp_; // 90 93 f2 00 sts 0x00F2, r25
// disable ext. crystal
temp_ = PMCR & 0xfb; // 90 91 f2 00 lds r25, 0x00F2
// 9b 7f andi r25, 0xFB
PMCR = 0x80; // 80 93 f2 00 sts 0x00F2, r24
PMCR = temp_; // 90 93 f2 00 sts 0x00F2, r25
} |
Oh, that makes sense now. If it's put in a variable, the compiler just keeps that at hand in a CPU register. GPIO0R is not a cpu register so extra operations are needed to move the value in and out. Regarding the waits, I think I see what you are up to: using |
Yes! This is the solution. This code takes about 3566 cycles. (16 instructions, 32 bytes) for(GPIOR0 = 0xff; GPIOR0 > 0; --GPIOR0);
for(GPIOR0 = 0xff; GPIOR0 > 0; --GPIOR0); Tis replacement code takes the same amount of cycles. (4 instructions, 8 bytes)
_lgt8fx_delay_cycles() is part of the delayMicroseconds() and is based on __builtin_avr_delay_cycles() |
Nice! another 24 bytes down! |
Yes, save a bunch of space. That was a good suggestion. |
The menu side is not that bad, I made that for the clock originally (that was originally the main reason for this repo to exist). |
If you give me a constant name and values for each EEPROM size I can add the menu side. |
Ok, I'm assuming that ot os enough to add variants to the boards.txt that change:
Is there anything else that needs to be done? |
Few more byte savings when initializing Timer1. before
after
|
Great! |
We get rid of almost all of them, but we supporting 328d too, isn't it? |
I'll be away from the computer for a few days, so I'm not sure I'll be able to answer during that time. |
Add menu options to disable PWM functions to save FLASH space. In lot of cases PWM functions not used. If someone doesn't want to use PWM capability with this menu will frees up additional FLASH space by not initializing the timers in In the same way, perhaps the ADC initialization could also be omitted. |
I did the experiment @LaZsolt and @nerdralph propose
Just replacing Timer3 initialisation frees up 16 bytes
before
after
Modifying the other timers and the ADC prescaler code frees up a total of 78 bytes.
I assume we could also port the newer Wire & co libraries from the latest uno core, they seem to have become more efficient. I think @jg1uaa was trying that.
And of course making the EEPROM space configurable via menu would add another 2k
Originally posted by @dbuezas in #33 (comment)
Will take PRs if anybody wants to give it a shot :)
The text was updated successfully, but these errors were encountered: