-
Notifications
You must be signed in to change notification settings - Fork 43
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
Changes to compile with ATtiny84 #22
base: master
Are you sure you want to change the base?
Conversation
@@ -109,14 +122,14 @@ static volatile uint8_t *txPort; // port register | |||
|
|||
#endif | |||
|
|||
static uint16_t mul8x8to16(uint8_t x, uint8_t y) | |||
static uint16_t mul8x8to16(uint16_t x, uint16_t y) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function was carefully crafted (and named) to force the compiler to generate one inline instruction for MCUs that have a MUL instruction (the 84 does not). There is no MUL instruction for 16x16, so this will always call a library routine. This may be too expensive for some baud rates, CPU freqs or MCUs.
Did you look at the generated assembly?
Did you try all baud rates on other boards?
Normally, I would adjust the fixed-point arithmetic for the different scale imposed by the clock and prescaler, and keep the fast 8x8 multiply (2 cycles or a library call). Is that something you can evaluate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK now I see why you used a function with that name.
I don't have much experience with assembly, sorry, but I can test with tiny84, 85 and mega328p (arduino UNO), the only boards I have. Only the mega has MUL instruction.
The problem for me is that BITS_PER_TICK_31250_Q10 and BITS_PER_TICK_38400_Q10 will overflow the 8 bit of the unit8_t type with my calculation for the frequency I need for the 84.
So do you mean that I should use the prescaler at 8 instead of 64, to keep the fixed point arithmetic?? If this is going to work I'be happy to do it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What baud rates did you try, and on which boards?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had the time to test only tiny84 at 9600b.
Now I tried with prescaler at 8 on the 84 at 9600b, but RX is not working now with clock at 1Mhz. Maybe the interrupt doesn't gets called...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had the time to test only tiny84 at 9600b.
Ah, I was a little skeptical of the other baud rates.
So do you mean that I should use the prescaler at 8 instead of 64
No, I meant the other calculations would shift the ticks into the required 8-bit range. For example, it could divide the dt
by 2 (a const
that is 1 for most platforms) before calling mul8x8to16
.
With 10 bit times to worry about, the math has to be careful to avoid overflows when ticks/bit > 2.55 25.5. When you tried the prescaler of 8, the ticks/bit @ 9600 becomes 104 (I think). This is too big for 8 bit math (more than 2 bit times), kind of the reverse of too few ticks/bit @ higher baud rates (leads to rounding errors and general garbage).
OTOH you could simply say that 9600 is the only supported baud rate for 8MHz ATtinyx4s... :P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes 104 was the value of tick/bits.
I have no time now to test, so for now... 9600 baud is the only supported rate.. for me.. 👍
But I will test, so.. where does the value 2.55 comes from??
And why 10 bit times?
Sorry for the nooooob question... :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where does the value 2.55 comes from??
Oops, 25.5 (fixed above). Then 10 bits will take 255 ticks (or more) and 8-bit math doesn't work any more.
why 10 bit times?
Because receiving a character with all 1's will not have any intermediate bit changes. The elapsed time will be 1 start bit, 8 x 1 bits and 1 stop bit. When the stop bit finishes, there is (finally) a rising edge to cause an interrupt. That's when the elapsed time is calculated from the previous edge counter value (the start bit) and the current edge counter value (the stop bit). If the 8-bit counter has rolled over during those 10 bit times, the calculation is wrong (too small by 256).
Timer register and BITS timings definition to compile and run on a tiny84 (at 8Mhz), where the 32 prescaler is not available.
Fixes #21.
Please consider only the changes to NeoSWSerial.cpp.