Serial buffer issue Attiny806 at 20MHz #920
-
There seems to be a problem with Serial specifically with Attiny806 at 20 MHz. The test code is simple, below. with the exception of Attiny806 at 20MHz; //CODE void setup() { Serial.begin(9600); } void loop() { char inchar = Serial.read(); if(inchar > -1) delay(1000); } |
Beta Was this translation helpful? Give feedback.
Replies: 8 comments 2 replies
-
I can't reproduce your issue. I tested on a 806 with IDE 1.8.13 with Github version of MegaTinycore and IDE 1.8.19 with latest boards manager version of MegaTinycore Both can receive 16 characters on 20, 10 or 8 MHz (the ones I tested) |
Beta Was this translation helpful? Give feedback.
-
Hm. I'm pretty sure I don't have an 806 within reach. The problem as described makes just about zero sense - there is no difference between the code running on an 806 vs any other part, and that it's only seen to fail at 20 MHz on impacted parts. Can you please post what you're sending it and what the data output looks like? Since it seems that all the likely sort of problems have been ruled out, we're down to trying to squint at the console output like a fortune teller peering into a cup of tea looking for prophecies.... This modification should give more insight - with an LED and it's series resistor (connected correctly (you're holding the wire 0.3" away from the vcc pin, so you can touch the end of the wire to that and the light had better come on, Once you have an LED on it, something you can do that would be useful is something like
This corrects the test (as I discuss below) and makes it flash an LED on PA7, though you could use any pin. As written, your code would be guaranteed to break for half of the characters you could send it..... if(inchar > -1) means don't retain any characters with the high bit set. Even if you eventually plan to use a filter like that, you don't want it in the way now, because it could be covering up big clues. Most characters with the high bit set are not meaningful characters and usually don't display a proper glyph, but they give you one of those boxes, which is enough to tell you that you got a bad character. But in any event for debugging, gibberish characters are frequently valuable - if you're seeing them, that says "baud rate mismatch". Other things I'd suggest include: And you were using latest released version? |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
AAHA! So, it's not specific to the 806, it's specific to THAT 806 in combination with THAT serial adapter, when running at that voltage I think the tiny is running a hair slow, and the serial adapter a hair fast. Either nudge the oscillator cal up a notch or two, or set the thing talking to it to use 2 stop bits, (this is precisely why >1 stopbit options exist :-P ). The extra stop bit adds enough time between the bytes that the receiver will for sure have finished receiving (the stopbit setting only effects TX behavior, not RX behavior - you likely don't need to set this on the tinyAVR) Also, the Arduino IDE serial console is unfit for purpose. It is, without exaggeration, the worst serial console I've ever used. They have carefully avoided checking any boxes on my feature wishlist, from basic to advanced. hTerm is the one you want. The person who did it comes from embedded software background, so it's got all those wacky features that we need. |
Beta Was this translation helpful? Give feedback.
-
Thanks for this, I will suspect that the Oscillator is a bit inaccurate at 20MHz, and avoid using it, unless I tune it.. But, just to haunt my sleep Only Serial exhibits the issue, ( at all baud rates) I have put the simple test code below for reference, it has the two versions, one uses SoftwareSerial, one uses Serial. Possibly Serial, using the native UART, is more susceptible to clock inaccuracies , or less robust for whatever reason, Summary: Baud rates tested: 300, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200. //CODE // 16-Mar-2023 #include <SoftwareSerial.h> #define RXPIN (6) SoftwareSerial soft = SoftwareSerial(RXPIN, TXPIN); void setup() { soft.begin(9600); /* //-------------------------------------------------------------------------------------------- void setup() { Serial.begin(9600); } */ |
Beta Was this translation helpful? Give feedback.
-
Did you see the page about self tuning? |
Beta Was this translation helpful? Give feedback.
-
He can't self tune, he's zero-series. Their event system was gutted, they can't get the required RTC output onto an event channel - PIT events are one one of the channels that the 0-series parts didn't get. Though the tuning was largely meant for people who want to run their parts at funky speeds, if just trying to get the part to work at 20 MHz you could use a much more brute force approach (I'm assuming you don't have a scope - if you do, just output 1kHz PWM, view it on the scope (where you'll find it's not 1 kHz, and keep increasing the value passed to something like this; otherwise you can guess any check with this function and your application bool tweakCal(int8_t tweakval) {
volatile uint8_t* calptr=(volatile uint8_t*) (uint16_t)&SIGROW; /*points to start of sigrow */
calptr +=26; /* now points to the location of the value loaded to to the oscillator at 20 MHz derived speeds (address determined experimentally) */
uint8_t tweakedval = *calptr + tweakval;
uint8_t oldsreg = SREG;
cli();
if (tweakedval < 64) {
__PROTECTED_WRITE(OSC20MCALIBA, tweakedval);
_NOP(); //don't have anything other than nop in the pipeline during and immediately after the change.
_NOP();
SREG = oldsreg;
return true;
}
SREG = oldsreg;
return false;
} This function takes a signed 8-bit integer, which should have a small absolute value (1 notch is 1.5% - so 1-2 notches is all you should need to adjust it by). This way you can keep running at a speed where timekeeping will work correctly and keep F_CPU at 20mhz. Edit: updated it to be a bit safer. (with the nops (which probably aren't necessary with such a small nudge to the clock) and disabling interrupts so we can't have an interrupt fire as soon as the protected write sequence is done, and hence our nops getting displaced. |
Beta Was this translation helpful? Give feedback.
-
Then 2-3 notches added to the calbyte should get it to where it should be. I'd expect it to work if you bumped the cal up like that. More likely 3 than 2. As for why it works with software serial even though software serial sucks - many software serial implementations exit as soon as they see the stop bit. -so they can use that time preparing So while the UART looks at all 10 bits (including framing) the software serial doesnt pay much attention t o the last |
Beta Was this translation helpful? Give feedback.
AAHA!
That serial output was exactly the thing I had a sneaking suspicion would be seen. There's a clock mismatch, so when you send multiple characters in a row with only one stop bit, it gets confused because the sender is sending the next character, the receiver thinks it's on the tail end of the stop bit, and within a few bytes, it's gotten far enough off that it's more than half a bitperiod off and seeing the wrong characters.
So, it's not specific to the 806, it's specific to THAT 806 in combination with THAT serial adapter, when running at that voltage I think the tiny is running a hair slow, and the serial adapter a hair fast. Either nudge the oscillator cal up a notch or two, or s…