Этот коммит содержится в:
GeoffThomas 2020-03-15 23:36:33 -05:00 коммит произвёл Ron Evans
родитель 046efdd93a
коммит c61c5e5799
5 изменённых файлов: 107 добавлений и 104 удалений

Просмотреть файл

@ -2,6 +2,11 @@
package machine
import (
"device/stm32"
"runtime/interrupt"
)
const (
PA0 = portA + 0
PA1 = portA + 1
@ -110,3 +115,17 @@ const (
UART_TX_PIN = PA2
UART_RX_PIN = PA3
)
var (
UART0 = UART{
Buffer: NewRingBuffer(),
Bus: stm32.USART2,
AltFuncSelector: stm32.AF7_USART1_2_3,
}
UART1 = &UART0
)
// set up RX IRQ handler. Follow similar pattern for other UARTx instances
func init() {
UART0.Interrupt = interrupt.New(stm32.IRQ_USART2, UART0.handleInterrupt)
}

Просмотреть файл

@ -82,7 +82,7 @@ func (p Pin) ConfigureAltFunc(config PinConfig, altFunc stm32.AltFunc) {
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos)
p.SetAltFunc(altFunc)
// I2C)
// I2C
case PinModeI2CSCL:
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos)
port.OTYPER.ReplaceBits(stm32.GPIOOutputTypeOpenDrain, 0x1, pos)

62
src/machine/machine_stm32_uart.go Обычный файл
Просмотреть файл

@ -0,0 +1,62 @@
// +build stm32
package machine
// Peripheral abstraction layer for UARTs on the stm32 family.
import (
"device/stm32"
"runtime/interrupt"
"unsafe"
)
// Configure the UART.
func (uart UART) Configure(config UARTConfig) {
// Default baud rate to 115200.
if config.BaudRate == 0 {
config.BaudRate = 115200
}
// Set the GPIO pins to defaults if they're not set
if config.TX == 0 && config.RX == 0 {
config.TX = UART_TX_PIN
config.RX = UART_RX_PIN
}
// Enable USART clock
enableAltFuncClock(unsafe.Pointer(uart.Bus))
uart.configurePins(config)
// Set baud rate
uart.SetBaudRate(config.BaudRate)
// Enable USART port, tx, rx and rx interrupts
uart.Bus.CR1.Set(stm32.USART_CR1_TE | stm32.USART_CR1_RE | stm32.USART_CR1_RXNEIE | stm32.USART_CR1_UE)
// Enable RX IRQ
uart.Interrupt.SetPriority(0xc0)
uart.Interrupt.Enable()
}
// handleInterrupt should be called from the appropriate interrupt handler for
// this UART instance.
func (uart *UART) handleInterrupt(interrupt.Interrupt) {
uart.Receive(byte((uart.Bus.DR.Get() & 0xFF)))
}
// SetBaudRate sets the communication speed for the UART. Defer to chip-specific
// routines for calculation
func (uart UART) SetBaudRate(br uint32) {
divider := uart.getBaudRateDivisor(br)
uart.Bus.BRR.Set(divider)
}
// WriteByte writes a byte of data to the UART.
func (uart UART) WriteByte(c byte) error {
uart.Bus.DR.Set(uint32(c))
for !uart.Bus.SR.HasBits(stm32.USART_SR_TXE) {
}
return nil
}

Просмотреть файл

@ -104,25 +104,17 @@ func enableAltFuncClock(bus unsafe.Pointer) {
}
}
// UART
//---------- UART related types and code
// UART representation
type UART struct {
Buffer *RingBuffer
Bus *stm32.USART_Type
Interrupt interrupt.Interrupt
}
// Configure the UART.
func (uart UART) Configure(config UARTConfig) {
// Default baud rate to 115200.
if config.BaudRate == 0 {
config.BaudRate = 115200
}
// Set the GPIO pins to defaults if they're not set
if config.TX == 0 && config.RX == 0 {
config.TX = UART_TX_PIN
config.RX = UART_RX_PIN
}
// Configure the TX and RX pins
func (uart UART) configurePins(config UARTConfig) {
// pins
switch config.TX {
@ -139,23 +131,11 @@ func (uart UART) Configure(config UARTConfig) {
}
config.TX.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltPushPull})
config.RX.Configure(PinConfig{Mode: PinInputModeFloating})
// Enable USART clock
enableAltFuncClock(unsafe.Pointer(uart.Bus))
// Set baud rate
uart.SetBaudRate(config.BaudRate)
// Enable USART port
uart.Bus.CR1.Set(stm32.USART_CR1_TE | stm32.USART_CR1_RE | stm32.USART_CR1_RXNEIE | stm32.USART_CR1_UE)
// Enable RX IRQ
uart.Interrupt.SetPriority(0xc0)
uart.Interrupt.Enable()
}
// SetBaudRate sets the communication speed for the UART.
func (uart UART) SetBaudRate(br uint32) {
// Determine the divisor for USARTs to get the given baudrate
func (uart UART) getBaudRateDivisor(br uint32) uint32 {
// Note: PCLK2 (from APB2) used for USART1 and PCLK1 for USART2, 3, 4, 5
var divider uint32
if uart.Bus == stm32.USART1 {
@ -165,22 +145,7 @@ func (uart UART) SetBaudRate(br uint32) {
// first divide by PCLK1 prescaler (div 2) and then desired baudrate
divider = CPUFrequency() / 2 / br
}
uart.Bus.BRR.Set(divider)
}
// WriteByte writes a byte of data to the UART.
func (uart UART) WriteByte(c byte) error {
uart.Bus.DR.Set(uint32(c))
for !uart.Bus.SR.HasBits(stm32.USART_SR_TXE) {
}
return nil
}
// handleInterrupt should be called from the appropriate interrupt handler for
// this UART instance.
func (uart *UART) handleInterrupt(interrupt.Interrupt) {
uart.Receive(byte((uart.Bus.DR.Get() & 0xFF)))
return divider
}
// SPI on the STM32.

Просмотреть файл

@ -79,75 +79,32 @@ func enableAltFuncClock(bus unsafe.Pointer) {
}
}
// UART
//---------- UART related types and code
// UART representation
type UART struct {
Buffer *RingBuffer
Bus *stm32.USART_Type
Interrupt interrupt.Interrupt
AltFuncSelector stm32.AltFunc
}
var (
UART0 = UART{
Buffer: NewRingBuffer(),
Bus: stm32.USART2,
AltFuncSelector: stm32.AF7_USART1_2_3,
}
UART1 = &UART0
)
// Configure the UART.
func (uart UART) Configure(config UARTConfig) {
// Default baud rate to 115200.
if config.BaudRate == 0 {
config.BaudRate = 115200
}
// Set the GPIO pins to defaults if they're not set
if config.TX == 0 && config.RX == 0 {
config.TX = UART_TX_PIN
config.RX = UART_RX_PIN
}
// Enable USART clock
enableAltFuncClock(unsafe.Pointer(uart.Bus))
// use standard TX/RX pins PA2 and PA3
func (uart UART) configurePins(config UARTConfig) {
// enable the alternate functions on the TX and RX pins
config.TX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTTX}, uart.AltFuncSelector)
config.RX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTRX}, uart.AltFuncSelector)
/*
Set baud rate(115200)
OVER8 = 0, APB1 = 42mhz
+----------+--------+
| baudrate | BRR |
+----------+--------+
| 1200 | 0x88B8 |
| 2400 | 0x445C |
| 9600 | 0x1117 |
| 19200 | 0x88C |
| 38400 | 0x446 |
| 57600 | 0x2D9 |
| 115200 | 0x16D |
+----------+--------+
*/
uart.Bus.BRR.Set(0x16c)
// Enable USART2 port.
uart.Bus.CR1.Set(stm32.USART_CR1_TE | stm32.USART_CR1_RE | stm32.USART_CR1_RXNEIE | stm32.USART_CR1_UE)
// Enable RX IRQ. TODO: pick the right IRQ_xxx for the bus and the uart
intr := interrupt.New(stm32.IRQ_USART2, func(interrupt.Interrupt) {
UART1.Receive(byte((UART1.Bus.DR.Get() & 0xFF)))
})
intr.SetPriority(0xc0)
intr.Enable()
}
// WriteByte writes a byte of data to the UART.
func (uart UART) WriteByte(c byte) error {
uart.Bus.DR.Set(uint32(c))
for !uart.Bus.SR.HasBits(stm32.USART_SR_TXE) {
// UART baudrate calc based on the bus and clockspeed
// NOTE: keep this in sync with the runtime/runtime_stm32f407.go clock init code
func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 {
var clock uint32
switch uart.Bus {
case stm32.USART1, stm32.USART6:
clock = CPUFrequency() / 2 // APB2 Frequency
case stm32.USART2, stm32.USART3, stm32.UART4, stm32.UART5:
clock = CPUFrequency() / 4 // APB1 Frequency
}
return nil
return clock / baudRate
}