Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions src/machine/board_nucleoh723zg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//go:build nucleoh723zg

package machine

import (
"device/stm32"
"runtime/interrupt"
)

const xtalHz = 8_000_000
const hseBypass = true

const (
// Arduino Pins
A0 = PA3 // ADC12_INP15
A1 = PC0 // ADC123_INP10
A2 = PC3 // ADC12_INP13
A3 = PB1 // ADC12_INP5
A4 = PC2 // ADC123_INP12 || I2C1_SDA
A5 = PF10 // ADC3_INP6 || I2C1_SCL
A6 = PF4 // ADC3_INP9
A7 = PF5 // ADC3_INP4
A8 = PF6 // ADC3_INP8

D0 = PB7 // LPUART1
D1 = PB6 // LPUART1
D2 = PG14
D3 = PE13 // TIM3_CH3
D4 = PE14
D5 = PE11 // TIM1_CH2 / I2C1_SCL
D6 = PE9 // TIM1_CH2
D7 = PG12
D8 = PF3
D9 = PD15 // TIM4_CH4
D10 = PD14 // SPI1_CS || TIM4_CH3
D11 = PB5 // SPI1_MOSI || TIM3_CH2
D12 = PA6 // SPI1_MISO
D13 = PA5 // SPI1_SCK
D14 = PB9
D15 = PB8
)

const (
LED = LED_BUILTIN
LED_BUILTIN = LED_GREEN
LED_GREEN = PB0
LED_YELLOW = PE1
LED_RED = PB14
)

const (
BUTTON = PC13
)

const (
// UART pins
// PA2 and PA3 are connected to the ST-Link Virtual Com Port (VCP)
UART_TX_PIN = PD8
UART_RX_PIN = PD9

// SPI
SPI1_SCK_PIN = PA5
SPI1_SDI_PIN = PB5
SPI1_SDO_PIN = PA6
SPI0_SCK_PIN = SPI1_SCK_PIN
SPI0_SDI_PIN = SPI1_SDI_PIN
SPI0_SDO_PIN = SPI1_SDO_PIN

// I2C pins
I2C0_SCL_PIN = PF1 // I2C2
I2C0_SDA_PIN = PF0 // I2C2
)

var (
// USART3 is the hardware serial port connected to the
// onboard ST-LINK debugger to be exposed as virtual COM
// port over USB on Nucleo boards.
UART1 = &_UART1
_UART1 = UART{
Buffer: NewRingBuffer(),
Bus: stm32.USART3,
TxAltFuncSelector: 7,
RxAltFuncSelector: 7,
}
DefaultUART = UART1

// I2C2 is documented, alias to I2C0 as well
I2C2 = &I2C{
Bus: stm32.I2C2,
AltFuncSelector: 4,
}
I2C0 = I2C2
)

func init() {
UART1.Interrupt = interrupt.New(stm32.IRQ_USART3, _UART1.handleInterrupt)
}
9 changes: 9 additions & 0 deletions src/machine/machine_stm32_moder_gpio.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ const (

// for USB (DP/DM lines)
PinModeUSB PinMode = 13

// for Ethernet
PinModeETH PinMode = 14
)

// Define several bitfields that have different names across chip families but
Expand Down Expand Up @@ -158,6 +161,12 @@ func (p Pin) ConfigureAltFunc(config PinConfig, altFunc uint8) {
case PinInputAnalog:
port.MODER.ReplaceBits(gpioModeAnalog, gpioModeMask, pos)
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)

case PinModeETH:
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
port.OSPEEDR.ReplaceBits(gpioOutputSpeedVeryHigh, gpioOutputSpeedMask, pos)
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
p.SetAltFunc(altFunc)
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/machine/machine_stm32h7.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ func (p Pin) getPort() *stm32.GPIO_Type {
case 7:
return stm32.GPIOH
case 8:
return stm32.GPIOI
return pinGetPortI()
case 9:
return stm32.GPIOJ
case 10:
Expand Down Expand Up @@ -345,12 +345,12 @@ func (p Pin) enableClock() {
stm32.RCC.AHB4ENR.SetBits(stm32.RCC_AHB4ENR_GPIOGEN)
case stm32.GPIOH:
stm32.RCC.AHB4ENR.SetBits(stm32.RCC_AHB4ENR_GPIOHEN)
case stm32.GPIOI:
stm32.RCC.AHB4ENR.SetBits(stm32.RCC_AHB4ENR_GPIOIEN)
case stm32.GPIOJ:
stm32.RCC.AHB4ENR.SetBits(stm32.RCC_AHB4ENR_GPIOJEN)
case stm32.GPIOK:
stm32.RCC.AHB4ENR.SetBits(stm32.RCC_AHB4ENR_GPIOKEN)
default:
p.enableClockOther()
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/machine/machine_stm32h7_gpio.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (p Pin) SetInterrupt(change PinChange, callback func(Pin)) error {
enableEXTIConfigRegisters()

if callback == nil {
stm32.EXTI.CPUIMR1.ClearBits(1 << pin)
intrMaskReg().ClearBits(1 << pin)
pinCallbacks[pin] = nil
return nil
}
Expand All @@ -46,7 +46,7 @@ func (p Pin) SetInterrupt(change PinChange, callback func(Pin)) error {
if (change & PinFalling) != 0 {
stm32.EXTI.FTSR1.SetBits(1 << pin)
}
stm32.EXTI.CPUIMR1.SetBits(1 << pin)
intrMaskReg().SetBits(1 << pin)

intr := p.registerInterrupt()
intr.SetPriority(0)
Expand Down Expand Up @@ -98,10 +98,10 @@ func handlePinInterrupt15_10(interrupt.Interrupt) {
}

func handlePinInterrupt(pin uint8) {
if stm32.EXTI.CPUPR1.HasBits(1 << pin) {
if intrPendReg().HasBits(1 << pin) {
// Writing 1 to the pending register clears the
// pending flag for that bit
stm32.EXTI.CPUPR1.Set(1 << pin)
intrPendReg().Set(1 << pin)

callback := pinCallbacks[pin]
if callback != nil {
Expand Down
16 changes: 16 additions & 0 deletions src/machine/machine_stm32h7_gpio_mp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//go:build stm32 && stm32h7 && stm32h757_cm7

package machine

import (
"device/stm32"
"runtime/volatile"
)

func intrMaskReg() *volatile.Register32 {
return &stm32.EXTI.C1IMR1
}

func intrPendReg() *volatile.Register32 {
return &stm32.EXTI.C1PR1
}
16 changes: 16 additions & 0 deletions src/machine/machine_stm32h7_gpio_sp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//go:build stm32 && stm32h7 && !stm32h757_cm7

package machine

import (
"device/stm32"
"runtime/volatile"
)

func intrMaskReg() *volatile.Register32 {
return &stm32.EXTI.CPUIMR1
}

func intrPendReg() *volatile.Register32 {
return &stm32.EXTI.CPUPR1
}
13 changes: 13 additions & 0 deletions src/machine/machine_stm32h7_no_port_i.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//go:build stm32 && stm32h7 && stm32h723

package machine

import (
"device/stm32"
)

func pinGetPortI() *stm32.GPIO_Type {
panic("machine: unknown port")
}

func (p Pin) enableClockOther() {}
18 changes: 18 additions & 0 deletions src/machine/machine_stm32h7_port_i.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//go:build stm32 && stm32h7 && !stm32h723

package machine

import (
"device/stm32"
)

func pinGetPortI() *stm32.GPIO_Type {
return stm32.GPIOI
}

func (p Pin) enableClockOther() {
switch p.getPort() {
case stm32.GPIOI:
stm32.RCC.AHB4ENR.SetBits(stm32.RCC_AHB4ENR_GPIOIEN)
}
}
2 changes: 1 addition & 1 deletion src/machine/machine_stm32h7_usb.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build stm32 && stm32h7
//go:build stm32 && stm32h7 && !stm32h723 && !stm32h757_cm7

package machine

Expand Down
2 changes: 1 addition & 1 deletion src/machine/usb.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build sam || nrf52840 || rp2040 || rp2350 || stm32f4 || stm32f7 || stm32h7
//go:build sam || nrf52840 || rp2040 || rp2350 || stm32f4 || stm32f7 || (stm32h7 && !stm32h723 && !stm32h757_cm7)

package machine

Expand Down
1 change: 0 additions & 1 deletion src/runtime/runtime_stm32h7.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package runtime
import (
"device/stm32"
"machine"
_ "machine/usb/cdc"
)

func init() {
Expand Down
7 changes: 7 additions & 0 deletions src/runtime/runtime_stm32h7_usbcdc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//go:build stm32 && stm32h7 && !stm32h723 && !stm32h757_cm7

package runtime

import (
_ "machine/usb/cdc"
)
13 changes: 13 additions & 0 deletions targets/nucleo-h723zg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"inherits": ["cortex-m7"],
"build-tags": ["nucleoh723zg", "stm32h723", "stm32h7", "stm32"],
"serial": "uart",
"linkerscript": "targets/stm32h723xg.ld",
"extra-files": [
"src/device/stm32/stm32h723.s"
],
"flash-method": "openocd",
"openocd-interface": "stlink",
"openocd-target": "stm32h7x",
"openocd-commands": ["reset_config srst_only srst_nogate connect_assert_srst"]
}
19 changes: 19 additions & 0 deletions targets/stm32h723xg.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

MEMORY
{
FLASH_TEXT (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 128K
}

/*
* D2 SRAM (0x30000000, 32K on H723) and D3 SRAM (0x38000000, 16K) are not
* mapped here and unused by the runtime. If a future driver places DMA
* buffers there, add MPU regions for them in initMPU()
* (src/runtime/runtime_stm32h7_mpu.go) — they currently fall through to the
* default privileged WBWA map, so cache maintenance via DCacheClean/
* DCacheInvalidate/DCacheFlush would silently miss those addresses.
*/

_stack_size = 8K;

INCLUDE "targets/arm.ld"
4 changes: 4 additions & 0 deletions tools/gen-device-svd/gen-device-svd.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ type Metadata struct {

type Interrupt struct {
Name string
Alias string
HandlerName string
PeripheralIndex int
Value int // interrupt number
Expand Down Expand Up @@ -1278,6 +1279,9 @@ const (
{{- end}}
{{- end}}
IRQ_{{.Name}} = {{.Value}}
{{- if .Alias}}
IRQ_{{.Alias}} = IRQ_{{.Name}}
{{- end}}
{{- "\n"}}
{{- end}}
// Highest interrupt number on this device.
Expand Down
24 changes: 22 additions & 2 deletions tools/gen-device-svd/tweak.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ func tweakDevice(d *Device, pkgName string) {
// a register IWDG. On some devices, though, like the h723,
// there are two registers, IWDG1 and IWDG2. In this case we
// define an alias IWDG for IWDG1.
addUnnumberedAlias(d, "IWDG", "IWDG1")
addUnnumberedPeriphAlias(d, "IWDG", "IWDG1")

addUnnumberedPeriphAlias(d, "WWDG", "WWDG1")
addUnnumberedIRQAlias(d, "TIM_CC", "TIM1_CC")

for _, p := range d.Peripherals {
switch p.GroupName {
Expand Down Expand Up @@ -55,14 +58,31 @@ func tweakDevice(d *Device, pkgName string) {
}
}

func addUnnumberedAlias(d *Device, dest, src string) {
func addUnnumberedPeriphAlias(d *Device, dest, src string) {
if _, ok := d.PeripheralDict[dest]; !ok {
if p := d.PeripheralDict[src]; p != nil {
p.Alias = dest
}
}
}

func addUnnumberedIRQAlias(d *Device, dest, src string) {
var iSrc *Interrupt

for _, i := range d.Interrupts {
if i.Name == dest {
return
}
if i.Name == src {
iSrc = i
}
}
if iSrc == nil {
return
}
iSrc.Alias = dest
}

func stm32EnsureCCMROrder(registers []*PeripheralField) {
for i, r := range registers {
if i > 0 {
Expand Down
Loading