Skip to content

Commit a9a6d0e

Browse files
ardnewdeadprogram
authored andcommitted
add basic UART handler
1 parent 19d5e05 commit a9a6d0e

File tree

3 files changed

+79
-25
lines changed

3 files changed

+79
-25
lines changed

src/machine/board_feather-stm32f405.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
package machine
44

5+
import (
6+
"device/stm32"
7+
"runtime/interrupt"
8+
)
9+
510
const (
611
NUM_DIGITAL_IO_PINS = 39
712
NUM_ANALOG_IO_PINS = 7
@@ -113,7 +118,30 @@ const (
113118
UART_TX_PIN = UART0_TX_PIN //
114119
)
115120

116-
func initUART() {}
121+
var (
122+
UART1 = UART{
123+
Buffer: NewRingBuffer(),
124+
Bus: stm32.USART3,
125+
AltFuncSelector: stm32.AF7_USART1_2_3,
126+
}
127+
UART2 = UART{
128+
Buffer: NewRingBuffer(),
129+
Bus: stm32.USART6,
130+
AltFuncSelector: stm32.AF8_USART4_5_6,
131+
}
132+
UART3 = UART{
133+
Buffer: NewRingBuffer(),
134+
Bus: stm32.USART1,
135+
AltFuncSelector: stm32.AF7_USART1_2_3,
136+
}
137+
UART0 = UART1
138+
)
139+
140+
func initUART() {
141+
UART1.Interrupt = interrupt.New(stm32.IRQ_USART3, UART1.handleInterrupt)
142+
UART2.Interrupt = interrupt.New(stm32.IRQ_USART6, UART2.handleInterrupt)
143+
UART3.Interrupt = interrupt.New(stm32.IRQ_USART1, UART3.handleInterrupt)
144+
}
117145

118146
// -- SPI ----------------------------------------------------------------------
119147

src/machine/machine_stm32f405.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,22 @@ type UART struct {
2222
AltFuncSelector stm32.AltFunc
2323
}
2424

25-
func (uart UART) configurePins(config UARTConfig) {}
26-
func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 { return 0 }
25+
func (uart UART) configurePins(config UARTConfig) {
26+
// enable the alternate functions on the TX and RX pins
27+
config.TX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTTX}, uart.AltFuncSelector)
28+
config.RX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTRX}, uart.AltFuncSelector)
29+
}
30+
31+
func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 {
32+
var clock uint32
33+
switch uart.Bus {
34+
case stm32.USART1, stm32.USART6:
35+
clock = CPUFrequency() / 2 // APB2 Frequency
36+
case stm32.USART2, stm32.USART3, stm32.UART4, stm32.UART5:
37+
clock = CPUFrequency() / 4 // APB1 Frequency
38+
}
39+
return clock / baudRate
40+
}
2741

2842
// -- SPI ----------------------------------------------------------------------
2943

src/runtime/runtime_stm32f405.go

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
// +build stm32,stm32f4,stm32f405
1+
// +build stm32f405
22

33
package runtime
44

55
import (
66
"device/arm"
77
"device/stm32"
8+
"machine"
89
"runtime/interrupt"
910
"runtime/volatile"
1011
)
@@ -13,6 +14,7 @@ func init() {
1314
initOSC() // configure oscillators
1415
initCLK() // configure CPU, AHB, and APB bus clocks
1516
initTIM() // configure timers
17+
initCOM() // configure serial comm interfaces
1618
}
1719

1820
const (
@@ -42,7 +44,8 @@ const (
4244
PLL_DIV_P = ((2 >> 1) - 1) << stm32.RCC_PLLCFGR_PLLP0_Pos
4345
PLL_DIV_Q = 7 << stm32.RCC_PLLCFGR_PLLQ0_Pos
4446

45-
SYSCLK_SRC_PLL = 2 << stm32.RCC_CFGR_SW0_Pos
47+
SYSCLK_SRC_PLL = 2 << stm32.RCC_CFGR_SW0_Pos
48+
SYSCLK_STAT_PLL = 2 << stm32.RCC_CFGR_SWS0_Pos
4649

4750
RCC_DIV_PCLK1 = 5 << stm32.RCC_CFGR_PPRE1_Pos // HCLK / 4
4851
RCC_DIV_PCLK2 = 4 << stm32.RCC_CFGR_PPRE2_Pos // HCLK / 2
@@ -52,22 +55,19 @@ const (
5255
)
5356

5457
const (
55-
// +---------------------+---------------------------------------------------------------------------+
56-
// | | HCLK (MHz) |
57-
// | +------------------+------------------+------------------+------------------+
58-
// | Wait states (WS) | Voltage range | Voltage range | Voltage range | Voltage range |
59-
// | (LATENCY) | 2.7 V - 3.6 V | 2.4 V - 2.7 V | 2.1 V - 2.4 V | 1.8 V - 2.1 V |
60-
// | | | | | Prefetch OFF |
61-
// +---------------------+------------------+------------------+------------------+------------------+
62-
// | 0 WS (1 CPU cycle) | 0 < HCLK ≤ 30 | 0 < HCLK ≤ 24 | 0 < HCLK ≤ 22 | 0 < HCLK ≤ 20 |
63-
// | 1 WS (2 CPU cycles) | 30 < HCLK ≤ 60 | 24 < HCLK ≤ 48 | 22 < HCLK ≤ 44 | 20 < HCLK ≤ 40 |
64-
// | 2 WS (3 CPU cycles) | 60 < HCLK ≤ 90 | 48 < HCLK ≤ 72 | 44 < HCLK ≤ 66 | 40 < HCLK ≤ 60 |
65-
// | 3 WS (4 CPU cycles) | 90 < HCLK ≤ 120 | 72 < HCLK ≤ 96 | 66 < HCLK ≤ 88 | 60 < HCLK ≤ 80 |
66-
// | 4 WS (5 CPU cycles) | 120 < HCLK ≤ 150 | 96 < HCLK ≤ 120 | 88 < HCLK ≤ 110 | 80 < HCLK ≤ 100 |
67-
// | 5 WS (6 CPU cycles) | 150 < HCLK ≤ 168 | 120 < HCLK ≤ 144 | 110 < HCLK ≤ 132 | 100 < HCLK ≤ 120 |
68-
// | 6 WS (7 CPU cycles) | | 144 < HCLK ≤ 168 | 132 < HCLK ≤ 154 | 120 < HCLK ≤ 140 |
69-
// | 7 WS (8 CPU cycles) | | | 154 < HCLK ≤ 168 | 140 < HCLK ≤ 160 |
70-
// +---------------------+------------------+------------------+------------------+------------------+
58+
// +-----------------------------------+
59+
// | Voltage range = 2.7V - 3.6V |
60+
// +----------------+------------------+
61+
// | Wait states | System Bus |
62+
// | (WS, LATENCY) | HCLK (MHz) |
63+
// +----------------+------------------+
64+
// | 0 WS, 1 cycle | 0 < HCLK ≤ 30 |
65+
// | 1 WS, 2 cycles | 30 < HCLK ≤ 60 |
66+
// | 2 WS, 3 cycles | 60 < HCLK ≤ 90 |
67+
// | 3 WS, 4 cycles | 90 < HCLK ≤ 120 |
68+
// | 4 WS, 5 cycles | 120 < HCLK ≤ 150 |
69+
// | 5 WS, 6 cycles | 150 < HCLK ≤ 168 |
70+
// +----------------+------------------+
7171
FLASH_LATENCY = 5 << stm32.FLASH_ACR_LATENCY_Pos // 5 WS (6 CPU cycles)
7272

7373
// instruction cache, data cache, and prefetch
@@ -126,6 +126,8 @@ func initCLK() {
126126

127127
// configure instruction/data caching, prefetch, and flash access wait states
128128
stm32.FLASH.ACR.Set(FLASH_OPTIONS | FLASH_LATENCY)
129+
for !stm32.FLASH.ACR.HasBits(FLASH_LATENCY) { // verify new wait states
130+
}
129131

130132
// After a system reset, the HSI oscillator is selected as the system clock.
131133
// When a clock source is used directly or through PLL as the system clock, it
@@ -140,12 +142,14 @@ func initCLK() {
140142

141143
// set CPU clock source to PLL
142144
stm32.RCC.CFGR.SetBits(SYSCLK_SRC_PLL)
143-
for !stm32.RCC.CFGR.HasBits(SYSCLK_SRC_PLL) {
144-
}
145145

146146
// update PCKL1/2 and HCLK divisors
147147
stm32.RCC.CFGR.SetBits(RCC_DIV_PCLK1 | RCC_DIV_PCLK2 | RCC_DIV_HCLK)
148148

149+
// verify system clock source is ready
150+
for !stm32.RCC.CFGR.HasBits(SYSCLK_STAT_PLL) {
151+
}
152+
149153
// enable the CCM RAM clock
150154
stm32.RCC.AHB1ENR.SetBits(CLK_CCM_RAM)
151155
}
@@ -172,6 +176,12 @@ func initTIM() {
172176
tim7.Enable()
173177
}
174178

179+
func initCOM() {
180+
if machine.NUM_UART_INTERFACES > 0 {
181+
machine.UART0.Configure(machine.UARTConfig{})
182+
}
183+
}
184+
175185
var (
176186
// tick in milliseconds
177187
tickCount timeUnit
@@ -203,7 +213,7 @@ func timerSleep(ticks uint32) {
203213
timerWakeup.Set(0)
204214

205215
stm32.TIM3.PSC.Set((PCLK1_FREQ_HZ*2)/10000 - 1) // 8399
206-
arr := (ticks / 100) - 1 // convert from microseconds to 0.1 ms
216+
arr := (ticks / 100) - 1 // microseconds to 0.1 ms
207217
if arr == 0 {
208218
arr = 1 // avoid blocking
209219
}
@@ -233,4 +243,6 @@ func handleTIM7(interrupt.Interrupt) {
233243
}
234244
}
235245

236-
func putchar(c byte) {}
246+
func putchar(c byte) {
247+
machine.UART0.WriteByte(c)
248+
}

0 commit comments

Comments
 (0)