aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorYurii Soldak <[email protected]>2023-12-04 01:30:31 +0100
committerRon Evans <[email protected]>2023-12-05 16:29:51 +0100
commit338590cc7505bc529e98b122b39460d5fb3a13be (patch)
tree678c738238c009a1a06df43b5c4dd7ef0419bdb1 /src
parent22d70604d841aa01319a9b9ff0231763f77fabb4 (diff)
downloadtinygo-338590cc7505bc529e98b122b39460d5fb3a13be.tar.gz
tinygo-338590cc7505bc529e98b122b39460d5fb3a13be.zip
machine/atmega: uart double speed mode
Less errors and higher throughput. Example: default / slow mode is problematic for 115200 on 16Mhz CPU.
Diffstat (limited to 'src')
-rw-r--r--src/machine/machine_atmega.go16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/machine/machine_atmega.go b/src/machine/machine_atmega.go
index f1838a08a..46dee5ef1 100644
--- a/src/machine/machine_atmega.go
+++ b/src/machine/machine_atmega.go
@@ -179,10 +179,18 @@ func (uart *UART) Configure(config UARTConfig) {
config.BaudRate = 9600
}
- // Set baud rate based on prescale formula from
- // https://www.microchip.com/webdoc/AVRLibcReferenceManual/FAQ_1faq_wrong_baud_rate.html
- // ((F_CPU + UART_BAUD_RATE * 8L) / (UART_BAUD_RATE * 16L) - 1)
- ps := ((CPUFrequency()+config.BaudRate*8)/(config.BaudRate*16) - 1)
+ // Prescale formula for u2x mode from AVR MiniCore source code.
+ // Same as formula from specification but taking into account rounding error.
+ ps := (CPUFrequency()/4/config.BaudRate - 1) / 2
+ uart.statusRegA.SetBits(avr.UCSR0A_U2X0)
+
+ // Hardcoded exception for 57600 for compatibility with older bootloaders.
+ // Also, prescale cannot be > 4095, so switch back to non-u2x mode if the baud rate is too low.
+ if (CPUFrequency() == 16000000 && config.BaudRate == 57600) || ps > 0xfff {
+ ps = (CPUFrequency()/8/config.BaudRate - 1) / 2
+ uart.statusRegA.ClearBits(avr.UCSR0A_U2X0)
+ }
+
uart.baudRegH.Set(uint8(ps >> 8))
uart.baudRegL.Set(uint8(ps & 0xff))