aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/machine/machine_stm32f407.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/machine/machine_stm32f407.go')
-rw-r--r--src/machine/machine_stm32f407.go143
1 files changed, 38 insertions, 105 deletions
diff --git a/src/machine/machine_stm32f407.go b/src/machine/machine_stm32f407.go
index c75e38771..85d9e2b25 100644
--- a/src/machine/machine_stm32f407.go
+++ b/src/machine/machine_stm32f407.go
@@ -2,51 +2,18 @@
package machine
-// Peripheral abstraction layer for the stm32.
+// Peripheral abstraction layer for the stm32f4(07)
import (
"device/stm32"
"runtime/interrupt"
+ "unsafe"
)
func CPUFrequency() uint32 {
return 168000000
}
-const (
- // Mode Flag
- PinOutput PinMode = 0
- PinInput PinMode = PinInputFloating
- PinInputFloating PinMode = 1
- PinInputPulldown PinMode = 2
- PinInputPullup PinMode = 3
-
- // for UART
- PinModeUartTX PinMode = 4
- PinModeUartRX PinMode = 5
-
- //GPIOx_MODER
- GPIO_MODE_INPUT = 0
- GPIO_MODE_GENERAL_OUTPUT = 1
- GPIO_MODE_ALTERNABTIVE = 2
- GPIO_MODE_ANALOG = 3
-
- //GPIOx_OTYPER
- GPIO_OUTPUT_MODE_PUSH_PULL = 0
- GPIO_OUTPUT_MODE_OPEN_DRAIN = 1
-
- // GPIOx_OSPEEDR
- GPIO_SPEED_LOW = 0
- GPIO_SPEED_MID = 1
- GPIO_SPEED_HI = 2
- GPIO_SPEED_VERY_HI = 3
-
- // GPIOx_PUPDR
- GPIO_FLOATING = 0
- GPIO_PULL_UP = 1
- GPIO_PULL_DOWN = 2
-)
-
func (p Pin) getPort() *stm32.GPIO_Type {
switch p / 16 {
case 0:
@@ -98,69 +65,33 @@ func (p Pin) enableClock() {
}
}
-// Configure this pin with the given configuration.
-func (p Pin) Configure(config PinConfig) {
- // Configure the GPIO pin.
- p.enableClock()
- port := p.getPort()
- pin := uint8(p) % 16
- pos := pin * 2
-
- if config.Mode == PinInputFloating {
- port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_INPUT) << pos)))
- port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_FLOATING) << pos)))
- } else if config.Mode == PinInputPulldown {
- port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_INPUT) << pos)))
- port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_PULL_DOWN) << pos)))
- } else if config.Mode == PinInputPullup {
- port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_INPUT) << pos)))
- port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_PULL_UP) << pos)))
- } else if config.Mode == PinOutput {
- port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_GENERAL_OUTPUT) << pos)))
- port.OSPEEDR.Set((uint32(port.OSPEEDR.Get())&^(0x3<<pos) | (uint32(GPIO_SPEED_HI) << pos)))
- } else if config.Mode == PinModeUartTX {
- port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_ALTERNABTIVE) << pos)))
- port.OSPEEDR.Set((uint32(port.OSPEEDR.Get())&^(0x3<<pos) | (uint32(GPIO_SPEED_HI) << pos)))
- port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_PULL_UP) << pos)))
- p.setAltFunc(0x7)
- } else if config.Mode == PinModeUartRX {
- port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_ALTERNABTIVE) << pos)))
- port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_FLOATING) << pos)))
- p.setAltFunc(0x7)
- }
-}
-
-func (p Pin) setAltFunc(af uint32) {
- port := p.getPort()
- pin := uint8(p) % 16
- pos := pin * 4
- if pin >= 8 {
- port.AFRH.Set(uint32(port.AFRH.Get())&^(0xF<<pos) | ((af & 0xF) << pos))
- } else {
- port.AFRL.Set(uint32(port.AFRL.Get())&^(0xF<<pos) | ((af & 0xF) << pos))
- }
-}
-
-// Set the pin to high or low.
-// Warning: only use this on an output pin!
-func (p Pin) Set(high bool) {
- port := p.getPort()
- pin := p % 16
- if high {
- port.BSRR.Set(1 << uint8(pin))
- } else {
- port.BSRR.Set(1 << uint8(pin+16))
+// Enable peripheral clock
+func enableAltFuncClock(bus unsafe.Pointer) {
+ switch bus {
+ case unsafe.Pointer(stm32.USART1):
+ stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_USART1EN)
+ case unsafe.Pointer(stm32.USART2):
+ stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART2EN)
+ case unsafe.Pointer(stm32.I2C1):
+ stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_I2C1EN)
+ case unsafe.Pointer(stm32.SPI1):
+ stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SPI1EN)
}
}
// UART
type UART struct {
- Buffer *RingBuffer
+ Buffer *RingBuffer
+ Bus *stm32.USART_Type
+ AltFuncSelector stm32.AltFunc
}
var (
- // Both UART0 and UART1 refer to USART2.
- UART0 = UART{Buffer: NewRingBuffer()}
+ UART0 = UART{
+ Buffer: NewRingBuffer(),
+ Bus: stm32.USART2,
+ AltFuncSelector: stm32.AF7_USART1_2_3,
+ }
UART1 = &UART0
)
@@ -171,20 +102,22 @@ func (uart UART) Configure(config UARTConfig) {
config.BaudRate = 115200
}
- // pins
- switch config.TX {
- default:
- // use standard TX/RX pins PA2 and PA3
- UART_TX_PIN.Configure(PinConfig{Mode: PinModeUartTX})
- UART_RX_PIN.Configure(PinConfig{Mode: PinModeUartRX})
+ // 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 USART2 clock
- stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART2EN)
+ // Enable USART clock
+ enableAltFuncClock(unsafe.Pointer(uart.Bus))
+
+ // use standard TX/RX pins PA2 and PA3
+ config.TX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTTX}, uart.AltFuncSelector)
+ config.RX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTRX}, uart.AltFuncSelector)
/*
Set baud rate(115200)
- OVER8 = 0, APB2 = 42mhz
+ OVER8 = 0, APB1 = 42mhz
+----------+--------+
| baudrate | BRR |
+----------+--------+
@@ -197,14 +130,14 @@ func (uart UART) Configure(config UARTConfig) {
| 115200 | 0x16D |
+----------+--------+
*/
- stm32.USART2.BRR.Set(0x16c)
+ uart.Bus.BRR.Set(0x16c)
// Enable USART2 port.
- stm32.USART2.CR1.Set(stm32.USART_CR1_TE | stm32.USART_CR1_RE | stm32.USART_CR1_RXNEIE | stm32.USART_CR1_UE)
+ uart.Bus.CR1.Set(stm32.USART_CR1_TE | stm32.USART_CR1_RE | stm32.USART_CR1_RXNEIE | stm32.USART_CR1_UE)
- // Enable RX IRQ.
+ // 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((stm32.USART2.DR.Get() & 0xFF)))
+ UART1.Receive(byte((UART1.Bus.DR.Get() & 0xFF)))
})
intr.SetPriority(0xc0)
intr.Enable()
@@ -212,9 +145,9 @@ func (uart UART) Configure(config UARTConfig) {
// WriteByte writes a byte of data to the UART.
func (uart UART) WriteByte(c byte) error {
- stm32.USART2.DR.Set(uint32(c))
+ uart.Bus.DR.Set(uint32(c))
- for !stm32.USART2.SR.HasBits(stm32.USART_SR_TXE) {
+ for !uart.Bus.SR.HasBits(stm32.USART_SR_TXE) {
}
return nil
}