Skip to content

Commit c119721

Browse files
ysoldakdeadprogram
authored andcommitted
atmega2560: support UART1-3
+ example for uart
1 parent 9294141 commit c119721

File tree

4 files changed

+135
-25
lines changed

4 files changed

+135
-25
lines changed

src/examples/uart/uart.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// This reads from UART1 and outputs to default serial, usually UART0 or USB.
2+
// Example of how to work with UARTs other than the default.
3+
package main
4+
5+
import (
6+
"machine"
7+
"time"
8+
)
9+
10+
var (
11+
uart = machine.UART1
12+
tx = machine.UART1_TX_PIN
13+
rx = machine.UART1_RX_PIN
14+
)
15+
16+
func main() {
17+
uart.Configure(machine.UARTConfig{TX: tx, RX: rx})
18+
for {
19+
if uart.Buffered() > 0 {
20+
data, _ := uart.ReadByte()
21+
print(string(data))
22+
}
23+
time.Sleep(10 * time.Millisecond)
24+
}
25+
}

src/machine/board_arduino_mega2560.go

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33

44
package machine
55

6+
import (
7+
"device/avr"
8+
"runtime/interrupt"
9+
)
10+
611
// Return the current CPU frequency in hertz.
712
func CPUFrequency() uint32 {
813
return 16000000
@@ -62,12 +67,12 @@ const (
6267
D11 Pin = PB5
6368
D12 Pin = PB6
6469
D13 Pin = PB7
65-
D14 Pin = PJ1
66-
D15 Pin = PJ0
67-
D16 Pin = PH1
68-
D17 Pin = PH0
69-
D18 Pin = PD3
70-
D19 Pin = PD2
70+
D14 Pin = PJ1 // TX3
71+
D15 Pin = PJ0 // RX3
72+
D16 Pin = PH1 // TX2
73+
D17 Pin = PH0 // RX2
74+
D18 Pin = PD3 // TX1
75+
D19 Pin = PD2 // RX1
7176
D20 Pin = PD1
7277
D21 Pin = PD0
7378
D22 Pin = PA0
@@ -103,3 +108,59 @@ const (
103108
D52 Pin = PB1
104109
D53 Pin = PB0
105110
)
111+
112+
// UART pins
113+
const (
114+
UART_TX_PIN Pin = UART0_TX_PIN
115+
UART_RX_PIN Pin = UART0_RX_PIN
116+
UART0_TX_PIN Pin = D1
117+
UART0_RX_PIN Pin = D0
118+
UART1_TX_PIN Pin = D18
119+
UART1_RX_PIN Pin = D19
120+
UART2_TX_PIN Pin = D16
121+
UART2_RX_PIN Pin = D17
122+
UART3_TX_PIN Pin = D14
123+
UART3_RX_PIN Pin = D15
124+
)
125+
126+
var (
127+
UART1 = &_UART1
128+
_UART1 = UART{
129+
Buffer: NewRingBuffer(),
130+
131+
dataReg: avr.UDR1,
132+
baudRegH: avr.UBRR1H,
133+
baudRegL: avr.UBRR1L,
134+
statusRegA: avr.UCSR1A,
135+
statusRegB: avr.UCSR1B,
136+
statusRegC: avr.UCSR1C,
137+
}
138+
UART2 = &_UART2
139+
_UART2 = UART{
140+
Buffer: NewRingBuffer(),
141+
142+
dataReg: avr.UDR2,
143+
baudRegH: avr.UBRR2H,
144+
baudRegL: avr.UBRR2L,
145+
statusRegA: avr.UCSR2A,
146+
statusRegB: avr.UCSR2B,
147+
statusRegC: avr.UCSR2C,
148+
}
149+
UART3 = &_UART3
150+
_UART3 = UART{
151+
Buffer: NewRingBuffer(),
152+
153+
dataReg: avr.UDR3,
154+
baudRegH: avr.UBRR3H,
155+
baudRegL: avr.UBRR3L,
156+
statusRegA: avr.UCSR3A,
157+
statusRegB: avr.UCSR3B,
158+
statusRegC: avr.UCSR3C,
159+
}
160+
)
161+
162+
func init() {
163+
interrupt.New(irq_USART1_RX, _UART1.handleInterrupt)
164+
interrupt.New(irq_USART2_RX, _UART2.handleInterrupt)
165+
interrupt.New(irq_USART3_RX, _UART3.handleInterrupt)
166+
}

src/machine/machine_atmega.go

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,34 @@ var DefaultUART = UART0
129129
var (
130130
// UART0 is the hardware serial port on the AVR.
131131
UART0 = &_UART0
132-
_UART0 = UART{Buffer: NewRingBuffer()}
132+
_UART0 = UART{
133+
Buffer: NewRingBuffer(),
134+
135+
dataReg: avr.UDR0,
136+
baudRegH: avr.UBRR0H,
137+
baudRegL: avr.UBRR0L,
138+
statusRegA: avr.UCSR0A,
139+
statusRegB: avr.UCSR0B,
140+
statusRegC: avr.UCSR0C,
141+
}
133142
)
134143

144+
func init() {
145+
// Register the UART interrupt.
146+
interrupt.New(irq_USART0_RX, _UART0.handleInterrupt)
147+
}
148+
135149
// UART on the AVR.
136150
type UART struct {
137151
Buffer *RingBuffer
152+
153+
dataReg *volatile.Register8
154+
baudRegH *volatile.Register8
155+
baudRegL *volatile.Register8
156+
157+
statusRegA *volatile.Register8
158+
statusRegB *volatile.Register8
159+
statusRegC *volatile.Register8
138160
}
139161

140162
// Configure the UART on the AVR. Defaults to 9600 baud on Arduino.
@@ -143,38 +165,37 @@ func (uart *UART) Configure(config UARTConfig) {
143165
config.BaudRate = 9600
144166
}
145167

146-
// Register the UART interrupt.
147-
interrupt.New(irq_USART0_RX, func(intr interrupt.Interrupt) {
148-
// Read register to clear it.
149-
data := avr.UDR0.Get()
150-
151-
// Ensure no error.
152-
if !avr.UCSR0A.HasBits(avr.UCSR0A_FE0 | avr.UCSR0A_DOR0 | avr.UCSR0A_UPE0) {
153-
// Put data from UDR register into buffer.
154-
UART0.Receive(byte(data))
155-
}
156-
})
157-
158168
// Set baud rate based on prescale formula from
159169
// https://www.microchip.com/webdoc/AVRLibcReferenceManual/FAQ_1faq_wrong_baud_rate.html
160170
// ((F_CPU + UART_BAUD_RATE * 8L) / (UART_BAUD_RATE * 16L) - 1)
161171
ps := ((CPUFrequency()+config.BaudRate*8)/(config.BaudRate*16) - 1)
162-
avr.UBRR0H.Set(uint8(ps >> 8))
163-
avr.UBRR0L.Set(uint8(ps & 0xff))
172+
uart.baudRegH.Set(uint8(ps >> 8))
173+
uart.baudRegL.Set(uint8(ps & 0xff))
164174

165175
// enable RX, TX and RX interrupt
166-
avr.UCSR0B.Set(avr.UCSR0B_RXEN0 | avr.UCSR0B_TXEN0 | avr.UCSR0B_RXCIE0)
176+
uart.statusRegB.Set(avr.UCSR0B_RXEN0 | avr.UCSR0B_TXEN0 | avr.UCSR0B_RXCIE0)
167177

168178
// 8-bits data
169-
avr.UCSR0C.Set(avr.UCSR0C_UCSZ01 | avr.UCSR0C_UCSZ00)
179+
uart.statusRegC.Set(avr.UCSR0C_UCSZ01 | avr.UCSR0C_UCSZ00)
180+
}
181+
182+
func (uart *UART) handleInterrupt(intr interrupt.Interrupt) {
183+
// Read register to clear it.
184+
data := uart.dataReg.Get()
185+
186+
// Ensure no error.
187+
if !uart.statusRegA.HasBits(avr.UCSR0A_FE0 | avr.UCSR0A_DOR0 | avr.UCSR0A_UPE0) {
188+
// Put data from UDR register into buffer.
189+
uart.Receive(byte(data))
190+
}
170191
}
171192

172193
// WriteByte writes a byte of data to the UART.
173194
func (uart *UART) WriteByte(c byte) error {
174195
// Wait until UART buffer is not busy.
175-
for !avr.UCSR0A.HasBits(avr.UCSR0A_UDRE0) {
196+
for !uart.statusRegA.HasBits(avr.UCSR0A_UDRE0) {
176197
}
177-
avr.UDR0.Set(c) // send char
198+
uart.dataReg.Set(c) // send char
178199
return nil
179200
}
180201

src/machine/machine_atmega2560.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import (
99
)
1010

1111
const irq_USART0_RX = avr.IRQ_USART0_RX
12+
const irq_USART1_RX = avr.IRQ_USART1_RX
13+
const irq_USART2_RX = avr.IRQ_USART2_RX
14+
const irq_USART3_RX = avr.IRQ_USART3_RX
1215

1316
const (
1417
portA Pin = iota * 8

0 commit comments

Comments
 (0)