+ example for uart
Этот коммит содержится в:
Yurii Soldak 2022-06-15 15:55:11 +02:00 коммит произвёл Ron Evans
родитель 9294141d70
коммит c119721e3b
4 изменённых файлов: 135 добавлений и 25 удалений

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