SpenceKonde / megaTinyCore

Arduino core for the tinyAVR 0/1/2-series - Ones's digit 2,4,5,7 (pincount, 8,14,20,24), tens digit 0, 1, or 2 (featureset), preceded by flash in kb. Library maintainers: porting help available!
Other
561 stars 146 forks source link

External CLK and Serial UART serial errors at 115200 #451

Closed EclipseBoom closed 3 years ago

EclipseBoom commented 3 years ago

When using the ATTiny1626 with 8MHz >>external clock<< 115200 baud has lots of errors in transmission. 57600 works perfectly.

20MHz internal has errors. 16MHz internal with 3V baud compensation seems to work perfectly at 115200

Test case: 8Mhz External selected from menu.
Running at 2.85V
Voltage Baud correction "closer to 3V" makes things slightly better but not fixed

Several different units tested.

Using an 8.000Mhz CMOS clock osc

This may be uncommon but if one wants accurate timing with these chips an external clock is needed.

`void setup() { Serial.begin(115200); // 57600 works - 115200 doesn't seem to work well

digitalWrite(IGNITION_PIN, LOW); pinMode(IGNITION_PIN, OUTPUT);

digitalWrite(DUMP_PIN, LOW); pinMode(DUMP_PIN, OUTPUT);

delay(10);

}

void loop() { // put your main code here, to run repeatedly: Serial.println(millis()); delay(50);

}`

EclipseBoom commented 3 years ago

8MHz internal with 3V compensation has fewer errors but still far too many

SpenceKonde commented 3 years ago

I have never seen any modern AVR device, ever, whose oscillator was not close enough for UART to work even without the UART voltage compensation. I can grab any of the several dozen tinyAVRs 0/1/2-series devices that I have in the bins around my desk, and upload something to them, and serial will work off internal. Something isn't adding up here. The tinyAVR 2-series parts are calibrated twice as tightly at the factory as the 0/1-series ones, too (twice the granularity in the calibration values). That's bizarre

And the UART baud voltage compensation is not used when external clock source is selected since it applies to the internal oscillator, so it shouldn't be making any difference there anyway.

I don't know if the last released version even used the compensation values for 2-series (they're tiny on the 2-series, like -2 to +2, parts out of 1024, and they're missing from some of the io headers so I had a test in there to see if it was defined, though I then realized that they were always there and put in #ifndef to catch if the headers didn't and make sure that SIGROW_OSCxxERRyV were defined to look in the right places in the signature row.

Something here is not adding up. What are you trying to talk to that you're seeing this problem on? It is most definitely not broken in the general case - I was using the USART on a tinyAVR (off it's internal oscillator, no oscillator correction) at 921600 baud recently, no problem. So I think there is something else in your system that is not behaving as expected

Do you have access to an oscilloscope? I'd suggest this sanity check:

void setup() {
  // We will be outputting PWM on PB0
  pinMode(PIN_PB0, OUTPUT); //PB0 - TCA0 WO0
  TCA0.SPLIT.CTRLA = 0; //disable TCA0 and set divider to 1
  TCA0.SPLIT.CTRLESET = TCA_SPLIT_CMD_RESET_gc | 0x03; //set CMD to RESET, and enable on both pins.
  TCA0.SPLIT.CTRLD = 0; //Split mode now off, CMPn = 0, CNT = 0, PER = 255
  TCA0.SINGLE.CTRLB = (TCA_SINGLE_CMP0EN_bm | TCA_SINGLE_WGMODE_SINGLESLOPE_gc); // output single slope PWM on WO0.
  TCA0.SINGLE.PER = (F_CPU/1000 - 1);
  TCA0.SINGLE.CMP0 = (F_CPU/2000 - 1);
  TCA0.SINGLE.CTRLA = TCA_SINGLE_ENABLE_bm; //enable the timer with no prescaler
  Serial.begin(115200); // and we want to see what it's actually generating for 115200 baud... 
}

void loop() { // Not even going to do anything in here
  Serial.write(0xF0); // 0b1111000,  but because it's serial, sent down wire from LSB first. The start bit is LOW and the stop bit HIGH, hence this results in a squarewave of frequency 1/10th what it's generating for the baud rate. 
}

Using the internal oscillator at 20 on the one I grabbed, I see 1.0015 kHz on PB0 and 11.527 kHz on TX.... it is within well under a percent at 3.3v, and even closer at 5V. The error term is vanishingly small, so of course changing the oscillator error correction between 5v and 3v does practically nothing. It was already unnecessary for UART to work on the 0/1-series, and the 2-series has done better at both temp calibration and doubled the granularity of the osccilator calibration. Resting a hot soldering iron against the top of the chip made it slowly creep up a tenth of a percent or so. I couldn't come up with any pathway towards getting it further from roomtemperature without setting something on fire, which I wasn't willing to do. My recent dump of SIGROW contents and F vs Calibration value on two dozen 2-series parts supports my supposition that the internal oscillator is generally extremely accurate under realistic conditions.

My current theory is that you're talking to something else that is doing a shitty job of generating the requested baud rate, like a classic-AVR microcontroller with a crystal or clock for 8 Mhz (with U2X, used by default by Arduino) or 16 MHx (without U2X); due to the poor granularity of the baud rate generator on classic AVRs, that device would be outputting serial at 111k baud instead of 115.2k, 4% low even with a perfectly accurate clock source, which would be just at the edge of working, which would explain why small perturbations in the oscillator speed like a 1 or 2 part in1024 oscillator correction factor was enough to make a difference in the observed error rates.

SpenceKonde commented 3 years ago

How did you rule out the possibility that the problem was elsewhere in the system? I just got through doing a lot of work with internal oscillators on the 2-series, and never saw anything like what you claim to be observing.and I am not convinced that sufficient work (or possibly even any work at all) has been directed towards ruling out other explanations.

EclipseBoom commented 3 years ago

It is very possible that the problem lies elsewhere namely in the programmer/comm unit. I initially saw this when using a Tiny1616 later a Tiny1626 connected to the uPDI programmer hack with a Arduino Pro Micro as the core. As you know this setup has UPDI programming and a serial UART port facing the target. I assumed all of these were hardware ports. It is possible the target-side serial is using software serial for comm and the hardware USART for the UPDI connection then passing back through the USB to the PC using the hardware USB port on the M32U4.

Since both the programmer and target units have crystals there should be no clock accuracy issues for low speed UART comms like 115200.

I had assumed the programmer unit was using all hardware serial peripherals doing UPDI with the SPI perhipheral, and since the clock accuracy was not an issue due to the crystals, My conclusion was that it was a likely baud register or clock tree setup issue. Especially since I suspect very few people use the EXTCLK input on this chips.

I'll soon be trying the CH340 adapter for programming so I will have a second CH340 unit for comms so I'll have fully dedicated hardware for the UART to USB conversion back to the PC.

SpenceKonde commented 3 years ago

Since both the programmer and target units have crystals there should be no clock accuracy issues for low speed UART comms like 115200.

This is NOT TRUE.

On classic AVRs the system clock is divided BY AN INTEGER to get a frequency of 8 (U2X=1) or 16 (U2X=0) times the the baud rate. There is no integer by which one can divide 8000000 by to get (8*115200).

Two classic AVRs with the same frequency crystal will generate the same inaccurate baud rates, but that doesn't make them correct. You may not notice, especially if you talk to one via USB serial port (eg, the 32u4) and it's talking to the other through a hardware serial port, and both are classic AVRs with the same system clock.

The modern AVRs have a fractional baud rate generator - there instead of an integer, we specify the divisor in 64ths (still used to generate a clock 8 or 16x the baud rate). This results in far more accurate baud rates.

So if you had a 16 MHz U2x= 0 or 8 MHz U2X=1 configuration at 115200 baud, they're both running at 111.1 kbaud, but you don't notice until you swap one out for a modern AVR and suddenly one is running at 115200 or 115300 baud (modern AVR clocks seem t9 have more tendency to skew fast than slow at factory cal. The baud rate calculation accuracy is within a tenth of a percent at that speed and thereabouts.

Please refer to this table I made (since the old wormfood avr baud rate page is gone). I swore I'd shared this already, but I can't find the shared one on sheets, so I guess not https://docs.google.com/spreadsheets/d/1uzU_HqWEpK-wQUo4Q7FBZGtHOo_eY4P_BAzmVbKCj6Y/edit?usp=sharing

SpenceKonde commented 3 years ago

Any news?

SpenceKonde commented 3 years ago

No response from OP. Please reopen if this is still an issue; I am pretty sure this is a manifestation the crude baud rate generation with non UART-clock speeds. on the classic AVR parts.