Skip to content
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

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open

Conversation

gion86
Copy link

@gion86 gion86 commented Oct 14, 2017

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.

@@ -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)
Copy link
Owner

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?

Copy link
Author

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.

Copy link
Owner

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?

Copy link
Author

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...

Copy link
Owner

@SlashDevin SlashDevin Oct 17, 2017

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

Copy link
Author

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... :)

Copy link
Owner

@SlashDevin SlashDevin Oct 22, 2017

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants