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
|
||||
|
||||
import (
|
||||
"device/avr"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
// Return the current CPU frequency in hertz.
|
||||
func CPUFrequency() uint32 {
|
||||
return 16000000
|
||||
|
@ -62,12 +67,12 @@ const (
|
|||
D11 Pin = PB5
|
||||
D12 Pin = PB6
|
||||
D13 Pin = PB7
|
||||
D14 Pin = PJ1
|
||||
D15 Pin = PJ0
|
||||
D16 Pin = PH1
|
||||
D17 Pin = PH0
|
||||
D18 Pin = PD3
|
||||
D19 Pin = PD2
|
||||
D14 Pin = PJ1 // TX3
|
||||
D15 Pin = PJ0 // RX3
|
||||
D16 Pin = PH1 // TX2
|
||||
D17 Pin = PH0 // RX2
|
||||
D18 Pin = PD3 // TX1
|
||||
D19 Pin = PD2 // RX1
|
||||
D20 Pin = PD1
|
||||
D21 Pin = PD0
|
||||
D22 Pin = PA0
|
||||
|
@ -103,3 +108,59 @@ const (
|
|||
D52 Pin = PB1
|
||||
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 (
|
||||
// UART0 is the hardware serial port on the AVR.
|
||||
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.
|
||||
type UART struct {
|
||||
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.
|
||||
|
@ -143,38 +165,37 @@ func (uart *UART) Configure(config UARTConfig) {
|
|||
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
|
||||
// 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)
|
||||
avr.UBRR0H.Set(uint8(ps >> 8))
|
||||
avr.UBRR0L.Set(uint8(ps & 0xff))
|
||||
uart.baudRegH.Set(uint8(ps >> 8))
|
||||
uart.baudRegL.Set(uint8(ps & 0xff))
|
||||
|
||||
// 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
|
||||
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.
|
||||
func (uart *UART) WriteByte(c byte) error {
|
||||
// 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
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,9 @@ import (
|
|||
)
|
||||
|
||||
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 (
|
||||
portA Pin = iota * 8
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче