atmega2560: support UART1-3
+ example for uart
Этот коммит содержится в:
родитель
9294141d70
коммит
c119721e3b
4 изменённых файлов: 135 добавлений и 25 удалений
25
src/examples/uart/uart.go
Обычный файл
25
src/examples/uart/uart.go
Обычный файл
|
@ -0,0 +1,25 @@
|
||||||
|
// This reads from UART1 and outputs to default serial, usually UART0 or USB.
|
||||||
|
// Example of how to work with UARTs other than the default.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
uart = machine.UART1
|
||||||
|
tx = machine.UART1_TX_PIN
|
||||||
|
rx = machine.UART1_RX_PIN
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
uart.Configure(machine.UARTConfig{TX: tx, RX: rx})
|
||||||
|
for {
|
||||||
|
if uart.Buffered() > 0 {
|
||||||
|
data, _ := uart.ReadByte()
|
||||||
|
print(string(data))
|
||||||
|
}
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,11 @@
|
||||||
|
|
||||||
package machine
|
package machine
|
||||||
|
|
||||||
|
import (
|
||||||
|
"device/avr"
|
||||||
|
"runtime/interrupt"
|
||||||
|
)
|
||||||
|
|
||||||
// Return the current CPU frequency in hertz.
|
// Return the current CPU frequency in hertz.
|
||||||
func CPUFrequency() uint32 {
|
func CPUFrequency() uint32 {
|
||||||
return 16000000
|
return 16000000
|
||||||
|
@ -62,12 +67,12 @@ const (
|
||||||
D11 Pin = PB5
|
D11 Pin = PB5
|
||||||
D12 Pin = PB6
|
D12 Pin = PB6
|
||||||
D13 Pin = PB7
|
D13 Pin = PB7
|
||||||
D14 Pin = PJ1
|
D14 Pin = PJ1 // TX3
|
||||||
D15 Pin = PJ0
|
D15 Pin = PJ0 // RX3
|
||||||
D16 Pin = PH1
|
D16 Pin = PH1 // TX2
|
||||||
D17 Pin = PH0
|
D17 Pin = PH0 // RX2
|
||||||
D18 Pin = PD3
|
D18 Pin = PD3 // TX1
|
||||||
D19 Pin = PD2
|
D19 Pin = PD2 // RX1
|
||||||
D20 Pin = PD1
|
D20 Pin = PD1
|
||||||
D21 Pin = PD0
|
D21 Pin = PD0
|
||||||
D22 Pin = PA0
|
D22 Pin = PA0
|
||||||
|
@ -103,3 +108,59 @@ const (
|
||||||
D52 Pin = PB1
|
D52 Pin = PB1
|
||||||
D53 Pin = PB0
|
D53 Pin = PB0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// UART pins
|
||||||
|
const (
|
||||||
|
UART_TX_PIN Pin = UART0_TX_PIN
|
||||||
|
UART_RX_PIN Pin = UART0_RX_PIN
|
||||||
|
UART0_TX_PIN Pin = D1
|
||||||
|
UART0_RX_PIN Pin = D0
|
||||||
|
UART1_TX_PIN Pin = D18
|
||||||
|
UART1_RX_PIN Pin = D19
|
||||||
|
UART2_TX_PIN Pin = D16
|
||||||
|
UART2_RX_PIN Pin = D17
|
||||||
|
UART3_TX_PIN Pin = D14
|
||||||
|
UART3_RX_PIN Pin = D15
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
UART1 = &_UART1
|
||||||
|
_UART1 = UART{
|
||||||
|
Buffer: NewRingBuffer(),
|
||||||
|
|
||||||
|
dataReg: avr.UDR1,
|
||||||
|
baudRegH: avr.UBRR1H,
|
||||||
|
baudRegL: avr.UBRR1L,
|
||||||
|
statusRegA: avr.UCSR1A,
|
||||||
|
statusRegB: avr.UCSR1B,
|
||||||
|
statusRegC: avr.UCSR1C,
|
||||||
|
}
|
||||||
|
UART2 = &_UART2
|
||||||
|
_UART2 = UART{
|
||||||
|
Buffer: NewRingBuffer(),
|
||||||
|
|
||||||
|
dataReg: avr.UDR2,
|
||||||
|
baudRegH: avr.UBRR2H,
|
||||||
|
baudRegL: avr.UBRR2L,
|
||||||
|
statusRegA: avr.UCSR2A,
|
||||||
|
statusRegB: avr.UCSR2B,
|
||||||
|
statusRegC: avr.UCSR2C,
|
||||||
|
}
|
||||||
|
UART3 = &_UART3
|
||||||
|
_UART3 = UART{
|
||||||
|
Buffer: NewRingBuffer(),
|
||||||
|
|
||||||
|
dataReg: avr.UDR3,
|
||||||
|
baudRegH: avr.UBRR3H,
|
||||||
|
baudRegL: avr.UBRR3L,
|
||||||
|
statusRegA: avr.UCSR3A,
|
||||||
|
statusRegB: avr.UCSR3B,
|
||||||
|
statusRegC: avr.UCSR3C,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
interrupt.New(irq_USART1_RX, _UART1.handleInterrupt)
|
||||||
|
interrupt.New(irq_USART2_RX, _UART2.handleInterrupt)
|
||||||
|
interrupt.New(irq_USART3_RX, _UART3.handleInterrupt)
|
||||||
|
}
|
||||||
|
|
|
@ -129,12 +129,34 @@ var DefaultUART = UART0
|
||||||
var (
|
var (
|
||||||
// UART0 is the hardware serial port on the AVR.
|
// UART0 is the hardware serial port on the AVR.
|
||||||
UART0 = &_UART0
|
UART0 = &_UART0
|
||||||
_UART0 = UART{Buffer: NewRingBuffer()}
|
_UART0 = UART{
|
||||||
|
Buffer: NewRingBuffer(),
|
||||||
|
|
||||||
|
dataReg: avr.UDR0,
|
||||||
|
baudRegH: avr.UBRR0H,
|
||||||
|
baudRegL: avr.UBRR0L,
|
||||||
|
statusRegA: avr.UCSR0A,
|
||||||
|
statusRegB: avr.UCSR0B,
|
||||||
|
statusRegC: avr.UCSR0C,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// Register the UART interrupt.
|
||||||
|
interrupt.New(irq_USART0_RX, _UART0.handleInterrupt)
|
||||||
|
}
|
||||||
|
|
||||||
// UART on the AVR.
|
// UART on the AVR.
|
||||||
type UART struct {
|
type UART struct {
|
||||||
Buffer *RingBuffer
|
Buffer *RingBuffer
|
||||||
|
|
||||||
|
dataReg *volatile.Register8
|
||||||
|
baudRegH *volatile.Register8
|
||||||
|
baudRegL *volatile.Register8
|
||||||
|
|
||||||
|
statusRegA *volatile.Register8
|
||||||
|
statusRegB *volatile.Register8
|
||||||
|
statusRegC *volatile.Register8
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure the UART on the AVR. Defaults to 9600 baud on Arduino.
|
// Configure the UART on the AVR. Defaults to 9600 baud on Arduino.
|
||||||
|
@ -143,38 +165,37 @@ func (uart *UART) Configure(config UARTConfig) {
|
||||||
config.BaudRate = 9600
|
config.BaudRate = 9600
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register the UART interrupt.
|
|
||||||
interrupt.New(irq_USART0_RX, func(intr interrupt.Interrupt) {
|
|
||||||
// Read register to clear it.
|
|
||||||
data := avr.UDR0.Get()
|
|
||||||
|
|
||||||
// Ensure no error.
|
|
||||||
if !avr.UCSR0A.HasBits(avr.UCSR0A_FE0 | avr.UCSR0A_DOR0 | avr.UCSR0A_UPE0) {
|
|
||||||
// Put data from UDR register into buffer.
|
|
||||||
UART0.Receive(byte(data))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Set baud rate based on prescale formula from
|
// Set baud rate based on prescale formula from
|
||||||
// https://www.microchip.com/webdoc/AVRLibcReferenceManual/FAQ_1faq_wrong_baud_rate.html
|
// https://www.microchip.com/webdoc/AVRLibcReferenceManual/FAQ_1faq_wrong_baud_rate.html
|
||||||
// ((F_CPU + UART_BAUD_RATE * 8L) / (UART_BAUD_RATE * 16L) - 1)
|
// ((F_CPU + UART_BAUD_RATE * 8L) / (UART_BAUD_RATE * 16L) - 1)
|
||||||
ps := ((CPUFrequency()+config.BaudRate*8)/(config.BaudRate*16) - 1)
|
ps := ((CPUFrequency()+config.BaudRate*8)/(config.BaudRate*16) - 1)
|
||||||
avr.UBRR0H.Set(uint8(ps >> 8))
|
uart.baudRegH.Set(uint8(ps >> 8))
|
||||||
avr.UBRR0L.Set(uint8(ps & 0xff))
|
uart.baudRegL.Set(uint8(ps & 0xff))
|
||||||
|
|
||||||
// enable RX, TX and RX interrupt
|
// enable RX, TX and RX interrupt
|
||||||
avr.UCSR0B.Set(avr.UCSR0B_RXEN0 | avr.UCSR0B_TXEN0 | avr.UCSR0B_RXCIE0)
|
uart.statusRegB.Set(avr.UCSR0B_RXEN0 | avr.UCSR0B_TXEN0 | avr.UCSR0B_RXCIE0)
|
||||||
|
|
||||||
// 8-bits data
|
// 8-bits data
|
||||||
avr.UCSR0C.Set(avr.UCSR0C_UCSZ01 | avr.UCSR0C_UCSZ00)
|
uart.statusRegC.Set(avr.UCSR0C_UCSZ01 | avr.UCSR0C_UCSZ00)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (uart *UART) handleInterrupt(intr interrupt.Interrupt) {
|
||||||
|
// Read register to clear it.
|
||||||
|
data := uart.dataReg.Get()
|
||||||
|
|
||||||
|
// Ensure no error.
|
||||||
|
if !uart.statusRegA.HasBits(avr.UCSR0A_FE0 | avr.UCSR0A_DOR0 | avr.UCSR0A_UPE0) {
|
||||||
|
// Put data from UDR register into buffer.
|
||||||
|
uart.Receive(byte(data))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteByte writes a byte of data to the UART.
|
// WriteByte writes a byte of data to the UART.
|
||||||
func (uart *UART) WriteByte(c byte) error {
|
func (uart *UART) WriteByte(c byte) error {
|
||||||
// Wait until UART buffer is not busy.
|
// Wait until UART buffer is not busy.
|
||||||
for !avr.UCSR0A.HasBits(avr.UCSR0A_UDRE0) {
|
for !uart.statusRegA.HasBits(avr.UCSR0A_UDRE0) {
|
||||||
}
|
}
|
||||||
avr.UDR0.Set(c) // send char
|
uart.dataReg.Set(c) // send char
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const irq_USART0_RX = avr.IRQ_USART0_RX
|
const irq_USART0_RX = avr.IRQ_USART0_RX
|
||||||
|
const irq_USART1_RX = avr.IRQ_USART1_RX
|
||||||
|
const irq_USART2_RX = avr.IRQ_USART2_RX
|
||||||
|
const irq_USART3_RX = avr.IRQ_USART3_RX
|
||||||
|
|
||||||
const (
|
const (
|
||||||
portA Pin = iota * 8
|
portA Pin = iota * 8
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче