stm32: use stm32-rs SVDs which are of much higher quality

This commit changes the number of wait states for the stm32f103 chip to
2 instead of 4. This gets it back in line with the datasheet, but it
also has the side effect of breaking I2C. Therefore, another (seemingly
unrelated) change is needed: the i2cTimeout constant must be increased
to a higher value to adjust to the lower flash wait states - presumably
because the lower number of wait states allows the chip to run code
faster.
Этот коммит содержится в:
Ayke van Laethem 2020-12-29 13:14:00 +01:00 коммит произвёл Ron Evans
родитель 65caf777dd
коммит 154c7c691b
24 изменённых файлов: 259 добавлений и 333 удалений

3
.gitmodules предоставленный
Просмотреть файл

@ -20,3 +20,6 @@
[submodule "lib/picolibc"] [submodule "lib/picolibc"]
path = lib/picolibc path = lib/picolibc
url = https://github.com/keith-packard/picolibc.git url = https://github.com/keith-packard/picolibc.git
[submodule "lib/stm32-svd"]
path = lib/stm32-svd
url = https://github.com/tinygo-org/stm32-svd

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

@ -130,7 +130,7 @@ gen-device-kendryte: build/gen-device-svd
GO111MODULE=off $(GO) fmt ./src/device/kendryte GO111MODULE=off $(GO) fmt ./src/device/kendryte
gen-device-stm32: build/gen-device-svd gen-device-stm32: build/gen-device-svd
./build/gen-device-svd -source=https://github.com/posborne/cmsis-svd/tree/master/data/STMicro lib/cmsis-svd/data/STMicro/ src/device/stm32/ ./build/gen-device-svd -source=https://github.com/tinygo-org/stm32-svd lib/stm32-svd/svd src/device/stm32/
GO111MODULE=off $(GO) fmt ./src/device/stm32 GO111MODULE=off $(GO) fmt ./src/device/stm32

1
lib/stm32-svd Подмодуль

@ -0,0 +1 @@
Subproject commit 9ec99824859540e61076a81149019222dc19b780

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

@ -1,57 +0,0 @@
// Hand created file. DO NOT DELETE.
// STM32FXXX (except stm32f1xx) bitfield definitions that are not
// auto-generated by gen-device-svd.go
// These apply to the stm32 families that use the MODER, OTYPE amd PUPDR
// registers for managing GPIO functionality.
// Add in other families that use the same settings, e.g. stm32f0xx, etc
// +build stm32,!stm32f103xx
package stm32
// AltFunc represents the alternate function peripherals that can be mapped to
// the GPIO ports. Since these differ by what is supported on the stm32 family
// they are defined in the more specific files
type AltFunc uint8
// Family-wide common post-reset AltFunc. This represents
// normal GPIO operation of the pins
const AF0_SYSTEM AltFunc = 0
const (
// Register values for the chip
// GPIOx_MODER
GPIOModeInput = 0
GPIOModeOutputGeneral = 1
GPIOModeOutputAltFunc = 2
GPIOModeAnalog = 3
// GPIOx_OTYPER
GPIOOutputTypePushPull = 0
GPIOOutputTypeOpenDrain = 1
// GPIOx_OSPEEDR
GPIOSpeedLow = 0
GPIOSpeedMid = 1
GPIOSpeedHigh = 2 // Note: this is also low speed on stm32f0, see RM0091
GPIOSpeedVeryHigh = 3
// GPIOx_PUPDR
GPIOPUPDRFloating = 0
GPIOPUPDRPullUp = 1
GPIOPUPDRPullDown = 2
)
// SPI prescaler values fPCLK / X
const (
SPI_PCLK_2 = 0
SPI_PCLK_4 = 1
SPI_PCLK_8 = 2
SPI_PCLK_16 = 3
SPI_PCLK_32 = 4
SPI_PCLK_64 = 5
SPI_PCLK_128 = 6
SPI_PCLK_256 = 7
)

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

@ -1,88 +0,0 @@
// Hand created file. DO NOT DELETE.
// STM32F103XX bitfield definitions that are not auto-generated by gen-device-svd.go
// +build stm32,stm32f103xx
package stm32
const (
// Flash Access Control Register flag values.
FLASH_ACR_LATENCY_0 = 0x00000001
FLASH_ACR_LATENCY_1 = 0x00000002
FLASH_ACR_LATENCY_2 = 0x00000004
// Reset and Clock Control Control Register flag values.
// System Clock source
RCC_CFGR_SW_HSI = 0
RCC_CFGR_SW_HSE = 1
RCC_CFGR_SW_PLL = 2
// Flags for when System Clock source is set.
RCC_CFGR_SWS_HSI = 0x00000000
RCC_CFGR_SWS_HSE = 0x00000004
RCC_CFGR_SWS_PLL = 0x00000008
// Sets PCLK1
RCC_CFGR_PPRE1_DIV_NONE = 0x00000000
RCC_CFGR_PPRE1_DIV_2 = 0x00000400
RCC_CFGR_PPRE1_DIV_4 = 0x00000500
RCC_CFGR_PPRE1_DIV_8 = 0x00000600
RCC_CFGR_PPRE1_DIV_16 = 0x00000700
// Sets PCLK2
RCC_CFGR_PPRE2_DIV_NONE = 0x00000000
RCC_CFGR_PPRE2_DIV_2 = 0x00002000
RCC_CFGR_PPRE2_DIV_4 = 0x00002800
RCC_CFGR_PPRE2_DIV_8 = 0x00003000
RCC_CFGR_PPRE2_DIV_16 = 0x00003800
// Sets PLL multiplier
RCC_CFGR_PLLMUL_2 = 0x00000000
RCC_CFGR_PLLMUL_3 = 0x00040000
RCC_CFGR_PLLMUL_4 = 0x00080000
RCC_CFGR_PLLMUL_5 = 0x000C0000
RCC_CFGR_PLLMUL_6 = 0x00100000
RCC_CFGR_PLLMUL_7 = 0x00140000
RCC_CFGR_PLLMUL_8 = 0x00180000
RCC_CFGR_PLLMUL_9 = 0x001C0000
RCC_CFGR_PLLMUL_10 = 0x00200000
RCC_CFGR_PLLMUL_11 = 0x00240000
RCC_CFGR_PLLMUL_12 = 0x00280000
RCC_CFGR_PLLMUL_13 = 0x002C0000
RCC_CFGR_PLLMUL_14 = 0x00300000
RCC_CFGR_PLLMUL_15 = 0x00340000
RCC_CFGR_PLLMUL_16 = 0x00380000
// RTC clock source
RCC_RTCCLKSource_LSE = 0x00000100
RCC_RTCCLKSource_LSI = 0x00000200
RCC_RTCCLKSource_HSE_Div128 = 0x00000300
// SPI settings
SPI_FirstBit_MSB = 0x0000
SPI_FirstBit_LSB = 0x0080
SPI_BaudRatePrescaler_2 = 0x0000
SPI_BaudRatePrescaler_4 = 0x0008
SPI_BaudRatePrescaler_8 = 0x0010
SPI_BaudRatePrescaler_16 = 0x0018
SPI_BaudRatePrescaler_32 = 0x0020
SPI_BaudRatePrescaler_64 = 0x0028
SPI_BaudRatePrescaler_128 = 0x0030
SPI_BaudRatePrescaler_256 = 0x0038
SPI_Direction_2Lines_FullDuplex = 0x0000
SPI_Direction_2Lines_RxOnly = 0x0400
SPI_Direction_1Line_Rx = 0x8000
SPI_Direction_1Line_Tx = 0xC000
SPI_Mode_Master = 0x0104
SPI_Mode_Slave = 0x0000
SPI_NSS_Soft = 0x0200
SPI_NSS_Hard = 0x0000
SPI_NSSInternalSoft_Set = 0x0100
SPI_NSSInternalSoft_Reset = 0xFEFF
)

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

@ -1,28 +0,0 @@
// Hand created file. DO NOT DELETE.
// STM32FXXX (except stm32f1xx) bitfield definitions that are not
// auto-generated by gen-device-svd.go
// +build stm32f4
// Alternate function settings on the stm32f4 series
package stm32
const (
// Alternative peripheral pin functions
// AF0_SYSTEM is defined im the common bitfields package
AF1_TIM1_2 AltFunc = 1
AF2_TIM3_4_5 = 2
AF3_TIM8_9_10_11 = 3
AF4_I2C1_2_3 = 4
AF5_SPI1_SPI2 = 5
AF6_SPI3 = 6
AF7_USART1_2_3 = 7
AF8_USART4_5_6 = 8
AF9_CAN1_CAN2_TIM12_13_14 = 9
AF10_OTG_FS_OTG_HS = 10
AF11_ETH = 11
AF12_FSMC_SDIO_OTG_HS_1 = 12
AF13_DCMI = 13
AF14 = 14
AF15_EVENTOUT = 15
)

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

@ -122,17 +122,17 @@ var (
UART1 = UART{ UART1 = UART{
Buffer: NewRingBuffer(), Buffer: NewRingBuffer(),
Bus: stm32.USART3, Bus: stm32.USART3,
AltFuncSelector: stm32.AF7_USART1_2_3, AltFuncSelector: AF7_USART1_2_3,
} }
UART2 = UART{ UART2 = UART{
Buffer: NewRingBuffer(), Buffer: NewRingBuffer(),
Bus: stm32.USART6, Bus: stm32.USART6,
AltFuncSelector: stm32.AF8_USART4_5_6, AltFuncSelector: AF8_USART4_5_6,
} }
UART3 = UART{ UART3 = UART{
Buffer: NewRingBuffer(), Buffer: NewRingBuffer(),
Bus: stm32.USART1, Bus: stm32.USART1,
AltFuncSelector: stm32.AF7_USART1_2_3, AltFuncSelector: AF7_USART1_2_3,
} }
UART0 = UART1 UART0 = UART1
) )
@ -181,15 +181,15 @@ const (
var ( var (
SPI1 = SPI{ SPI1 = SPI{
Bus: stm32.SPI2, Bus: stm32.SPI2,
AltFuncSelector: stm32.AF5_SPI1_SPI2, AltFuncSelector: AF5_SPI1_SPI2,
} }
SPI2 = SPI{ SPI2 = SPI{
Bus: stm32.SPI3, Bus: stm32.SPI3,
AltFuncSelector: stm32.AF6_SPI3, AltFuncSelector: AF6_SPI3,
} }
SPI3 = SPI{ SPI3 = SPI{
Bus: stm32.SPI1, Bus: stm32.SPI1,
AltFuncSelector: stm32.AF5_SPI1_SPI2, AltFuncSelector: AF5_SPI1_SPI2,
} }
SPI0 = SPI1 SPI0 = SPI1
) )
@ -229,15 +229,15 @@ const (
var ( var (
I2C1 = I2C{ I2C1 = I2C{
Bus: stm32.I2C1, Bus: stm32.I2C1,
AltFuncSelector: stm32.AF4_I2C1_2_3, AltFuncSelector: AF4_I2C1_2_3,
} }
I2C2 = I2C{ I2C2 = I2C{
Bus: stm32.I2C2, Bus: stm32.I2C2,
AltFuncSelector: stm32.AF4_I2C1_2_3, AltFuncSelector: AF4_I2C1_2_3,
} }
I2C3 = I2C{ I2C3 = I2C{
Bus: stm32.I2C1, Bus: stm32.I2C1,
AltFuncSelector: stm32.AF4_I2C1_2_3, AltFuncSelector: AF4_I2C1_2_3,
} }
I2C0 = I2C1 I2C0 = I2C1
) )

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

@ -55,7 +55,7 @@ var (
// Console UART (LPUSART1) // Console UART (LPUSART1)
UART0 = UART{ UART0 = UART{
Buffer: NewRingBuffer(), Buffer: NewRingBuffer(),
Bus: stm32.LPUSART1, Bus: stm32.LPUART1,
AltFuncSelector: 6, AltFuncSelector: 6,
} }

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

@ -30,7 +30,7 @@ var (
UART0 = UART{ UART0 = UART{
Buffer: NewRingBuffer(), Buffer: NewRingBuffer(),
Bus: stm32.USART2, Bus: stm32.USART2,
AltFuncSelector: stm32.AF7_USART1_2_3, AltFuncSelector: AF7_USART1_2_3,
} }
UART1 = &UART0 UART1 = &UART0
) )
@ -62,7 +62,7 @@ const (
var ( var (
SPI0 = SPI{ SPI0 = SPI{
Bus: stm32.SPI1, Bus: stm32.SPI1,
AltFuncSelector: stm32.AF5_SPI1_SPI2, AltFuncSelector: AF5_SPI1_SPI2,
} }
SPI1 = &SPI0 SPI1 = &SPI0
) )

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

@ -1,4 +1,4 @@
// +build stm32,!stm32f103xx,!stm32f407,!stm32f7x2,!stm32l0 // +build stm32,!stm32f103,!stm32f407,!stm32f7x2,!stm32l0
package machine package machine
@ -110,10 +110,10 @@ type (
) )
func (sa address7Bit) toRead() uint32 { func (sa address7Bit) toRead() uint32 {
return uint32(((uint8(sa) << 1) | uint8(stm32.I2C_OAR1_ADD0)) & 0xFF) return uint32(((uint8(sa) << 1) | 1) & 0xFF)
} }
func (sa address7Bit) toWrite() uint32 { func (sa address7Bit) toWrite() uint32 {
return uint32(((uint8(sa) << 1) & ^(uint8(stm32.I2C_OAR1_ADD0))) & 0xFF) return uint32((uint8(sa) << 1) & 0xFF)
} }
func (sa address7Bit) bitSize() uint8 { return 7 } // 7-bit addresses func (sa address7Bit) bitSize() uint8 { return 7 } // 7-bit addresses

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

@ -1,4 +1,4 @@
// +build stm32,!stm32f103xx // +build stm32,!stm32f103
package machine package machine
@ -38,85 +38,106 @@ const (
// TBD // TBD
) )
// Define several bitfields that have different names across chip families but
// essentially have the same meaning.
const (
// MODER bitfields.
gpioModeInput = 0
gpioModeOutput = 1
gpioModeAlternate = 2
gpioModeAnalog = 3
gpioModeMask = 0x3
// PUPDR bitfields.
gpioPullFloating = 0
gpioPullUp = 1
gpioPullDown = 2
gpioPullMask = 0x3
// OSPEED bitfields.
gpioOutputSpeedHigh = 2
gpioOutputSpeedLow = 0
gpioOutputSpeedMask = 0x3
)
// Configure this pin with the given configuration // Configure this pin with the given configuration
func (p Pin) Configure(config PinConfig) { func (p Pin) Configure(config PinConfig) {
// Use the default system alternate function; this // Use the default system alternate function; this
// will only be used if you try to call this with // will only be used if you try to call this with
// one of the peripheral modes instead of vanilla GPIO. // one of the peripheral modes instead of vanilla GPIO.
p.ConfigureAltFunc(config, stm32.AF0_SYSTEM) p.ConfigureAltFunc(config, 0)
} }
// Configure this pin with the given configuration including alternate // Configure this pin with the given configuration including alternate
// function mapping if necessary. // function mapping if necessary.
func (p Pin) ConfigureAltFunc(config PinConfig, altFunc stm32.AltFunc) { func (p Pin) ConfigureAltFunc(config PinConfig, altFunc uint8) {
// Configure the GPIO pin. // Configure the GPIO pin.
p.enableClock() p.enableClock()
port := p.getPort() port := p.getPort()
pin := uint8(p) % 16 pos := (uint8(p) % 16) * 2 // assume each field is two bits in size (with mask 0x3)
pos := pin * 2
switch config.Mode { switch config.Mode {
// GPIO // GPIO
case PinInputFloating: case PinInputFloating:
port.MODER.ReplaceBits(stm32.GPIOModeInput, 0x3, pos) port.MODER.ReplaceBits(gpioModeInput, gpioModeMask, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos) port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
case PinInputPulldown: case PinInputPulldown:
port.MODER.ReplaceBits(stm32.GPIOModeInput, 0x3, pos) port.MODER.ReplaceBits(gpioModeInput, gpioModeMask, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRPullDown, 0x3, pos) port.PUPDR.ReplaceBits(gpioPullDown, gpioPullMask, pos)
case PinInputPullup: case PinInputPullup:
port.MODER.ReplaceBits(stm32.GPIOModeInput, 0x3, pos) port.MODER.ReplaceBits(gpioModeInput, gpioModeMask, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRPullUp, 0x3, pos) port.PUPDR.ReplaceBits(gpioPullUp, gpioPullMask, pos)
case PinOutput: case PinOutput:
port.MODER.ReplaceBits(stm32.GPIOModeOutputGeneral, 0x3, pos) port.MODER.ReplaceBits(gpioModeOutput, gpioModeMask, pos)
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedHigh, 0x3, pos) port.OSPEEDR.ReplaceBits(gpioOutputSpeedHigh, gpioOutputSpeedMask, pos)
// UART // UART
case PinModeUARTTX: case PinModeUARTTX:
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos) port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedHigh, 0x3, pos) port.OSPEEDR.ReplaceBits(gpioOutputSpeedHigh, gpioOutputSpeedMask, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRPullUp, 0x3, pos) port.PUPDR.ReplaceBits(gpioPullUp, gpioPullMask, pos)
p.SetAltFunc(altFunc) p.SetAltFunc(altFunc)
case PinModeUARTRX: case PinModeUARTRX:
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos) port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos) port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
p.SetAltFunc(altFunc) p.SetAltFunc(altFunc)
// I2C // I2C
case PinModeI2CSCL: case PinModeI2CSCL:
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos) port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
port.OTYPER.ReplaceBits(stm32.GPIOOutputTypeOpenDrain, 0x1, pos) port.OTYPER.ReplaceBits(stm32.GPIO_OTYPER_OT0_OpenDrain, stm32.GPIO_OTYPER_OT0_Msk, pos/2)
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedLow, 0x3, pos) port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos) port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
p.SetAltFunc(altFunc) p.SetAltFunc(altFunc)
case PinModeI2CSDA: case PinModeI2CSDA:
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos) port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
port.OTYPER.ReplaceBits(stm32.GPIOOutputTypeOpenDrain, 0x1, pos) port.OTYPER.ReplaceBits(stm32.GPIO_OTYPER_OT0_OpenDrain, stm32.GPIO_OTYPER_OT0_Msk, pos/2)
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedLow, 0x3, pos) port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos) port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
p.SetAltFunc(altFunc) p.SetAltFunc(altFunc)
// SPI // SPI
case PinModeSPICLK: case PinModeSPICLK:
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos) port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedLow, 0x3, pos) port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos) port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
p.SetAltFunc(altFunc) p.SetAltFunc(altFunc)
case PinModeSPISDO: case PinModeSPISDO:
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos) port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedLow, 0x3, pos) port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos) port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
p.SetAltFunc(altFunc) p.SetAltFunc(altFunc)
case PinModeSPISDI: case PinModeSPISDI:
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos) port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedLow, 0x3, pos) port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos) port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
p.SetAltFunc(altFunc) p.SetAltFunc(altFunc)
} }
} }
// SetAltFunc maps the given alternative function to the I/O pin // SetAltFunc maps the given alternative function to the I/O pin
func (p Pin) SetAltFunc(af stm32.AltFunc) { func (p Pin) SetAltFunc(af uint8) {
port := p.getPort() port := p.getPort()
pin := uint8(p) % 16 pin := uint8(p) % 16
pos := (pin % 8) * 4 pos := (pin % 8) * 4

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

@ -1,4 +1,4 @@
// +build stm32,stm32f103xx // +build stm32,stm32f103
package machine package machine
@ -169,21 +169,21 @@ func (spi SPI) getBaudRate(config SPIConfig) uint32 {
switch config.Frequency { switch config.Frequency {
case 125000: case 125000:
// Note: impossible to achieve lower frequency with current PCLK2! // Note: impossible to achieve lower frequency with current PCLK2!
conf |= stm32.SPI_BaudRatePrescaler_256 conf |= stm32.SPI_CR1_BR_Div256
case 250000: case 250000:
conf |= stm32.SPI_BaudRatePrescaler_256 conf |= stm32.SPI_CR1_BR_Div256
case 500000: case 500000:
conf |= stm32.SPI_BaudRatePrescaler_128 conf |= stm32.SPI_CR1_BR_Div128
case 1000000: case 1000000:
conf |= stm32.SPI_BaudRatePrescaler_64 conf |= stm32.SPI_CR1_BR_Div64
case 2000000: case 2000000:
conf |= stm32.SPI_BaudRatePrescaler_32 conf |= stm32.SPI_CR1_BR_Div32
case 4000000: case 4000000:
conf |= stm32.SPI_BaudRatePrescaler_16 conf |= stm32.SPI_CR1_BR_Div16
case 8000000: case 8000000:
conf |= stm32.SPI_BaudRatePrescaler_8 conf |= stm32.SPI_CR1_BR_Div8
default: default:
conf |= stm32.SPI_BaudRatePrescaler_256 conf |= stm32.SPI_CR1_BR_Div256
} }
return conf return conf
} }
@ -542,7 +542,7 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
return nil return nil
} }
const i2cTimeout = 500 const i2cTimeout = 1000
// signalStart sends a start signal. // signalStart sends a start signal.
func (i2c I2C) signalStart() error { func (i2c I2C) signalStart() error {

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

@ -14,13 +14,33 @@ func CPUFrequency() uint32 {
return 168000000 return 168000000
} }
// Alternative peripheral pin functions
const (
AF0_SYSTEM = 0
AF1_TIM1_2 = 1
AF2_TIM3_4_5 = 2
AF3_TIM8_9_10_11 = 3
AF4_I2C1_2_3 = 4
AF5_SPI1_SPI2 = 5
AF6_SPI3 = 6
AF7_USART1_2_3 = 7
AF8_USART4_5_6 = 8
AF9_CAN1_CAN2_TIM12_13_14 = 9
AF10_OTG_FS_OTG_HS = 10
AF11_ETH = 11
AF12_FSMC_SDIO_OTG_HS_1 = 12
AF13_DCMI = 13
AF14 = 14
AF15_EVENTOUT = 15
)
// -- UART --------------------------------------------------------------------- // -- UART ---------------------------------------------------------------------
type UART struct { type UART struct {
Buffer *RingBuffer Buffer *RingBuffer
Bus *stm32.USART_Type Bus *stm32.USART_Type
Interrupt interrupt.Interrupt Interrupt interrupt.Interrupt
AltFuncSelector stm32.AltFunc AltFuncSelector uint8
} }
func (uart UART) configurePins(config UARTConfig) { func (uart UART) configurePins(config UARTConfig) {
@ -44,7 +64,7 @@ func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 {
type SPI struct { type SPI struct {
Bus *stm32.SPI_Type Bus *stm32.SPI_Type
AltFuncSelector stm32.AltFunc AltFuncSelector uint8
} }
func (spi SPI) configurePins(config SPIConfig) { func (spi SPI) configurePins(config SPIConfig) {
@ -93,7 +113,7 @@ func (spi SPI) getBaudRate(config SPIConfig) uint32 {
type I2C struct { type I2C struct {
Bus *stm32.I2C_Type Bus *stm32.I2C_Type
AltFuncSelector stm32.AltFunc AltFuncSelector uint8
} }
func (i2c I2C) configurePins(config I2CConfig) { func (i2c I2C) configurePins(config I2CConfig) {

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

@ -13,6 +13,26 @@ func CPUFrequency() uint32 {
return 168000000 return 168000000
} }
// Alternative peripheral pin functions
const (
AF0_SYSTEM = 0
AF1_TIM1_2 = 1
AF2_TIM3_4_5 = 2
AF3_TIM8_9_10_11 = 3
AF4_I2C1_2_3 = 4
AF5_SPI1_SPI2 = 5
AF6_SPI3 = 6
AF7_USART1_2_3 = 7
AF8_USART4_5_6 = 8
AF9_CAN1_CAN2_TIM12_13_14 = 9
AF10_OTG_FS_OTG_HS = 10
AF11_ETH = 11
AF12_FSMC_SDIO_OTG_HS_1 = 12
AF13_DCMI = 13
AF14 = 14
AF15_EVENTOUT = 15
)
//---------- UART related types and code //---------- UART related types and code
// UART representation // UART representation
@ -20,7 +40,7 @@ type UART struct {
Buffer *RingBuffer Buffer *RingBuffer
Bus *stm32.USART_Type Bus *stm32.USART_Type
Interrupt interrupt.Interrupt Interrupt interrupt.Interrupt
AltFuncSelector stm32.AltFunc AltFuncSelector uint8
} }
// Configure the UART. // Configure the UART.
@ -48,7 +68,7 @@ func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 {
// SPI on the STM32Fxxx using MODER / alternate function pins // SPI on the STM32Fxxx using MODER / alternate function pins
type SPI struct { type SPI struct {
Bus *stm32.SPI_Type Bus *stm32.SPI_Type
AltFuncSelector stm32.AltFunc AltFuncSelector uint8
} }
// Set baud rate for SPI // Set baud rate for SPI
@ -70,26 +90,26 @@ func (spi SPI) getBaudRate(config SPIConfig) uint32 {
// TODO: also include the MCU/APB clock setting in the equation // TODO: also include the MCU/APB clock setting in the equation
switch true { switch true {
case localFrequency < 328125: case localFrequency < 328125:
conf = stm32.SPI_PCLK_256 conf = stm32.SPI_CR1_BR_Div256
case localFrequency < 656250: case localFrequency < 656250:
conf = stm32.SPI_PCLK_128 conf = stm32.SPI_CR1_BR_Div128
case localFrequency < 1312500: case localFrequency < 1312500:
conf = stm32.SPI_PCLK_64 conf = stm32.SPI_CR1_BR_Div64
case localFrequency < 2625000: case localFrequency < 2625000:
conf = stm32.SPI_PCLK_32 conf = stm32.SPI_CR1_BR_Div32
case localFrequency < 5250000: case localFrequency < 5250000:
conf = stm32.SPI_PCLK_16 conf = stm32.SPI_CR1_BR_Div16
case localFrequency < 10500000: case localFrequency < 10500000:
conf = stm32.SPI_PCLK_8 conf = stm32.SPI_CR1_BR_Div8
// NOTE: many SPI components won't operate reliably (or at all) above 10MHz // NOTE: many SPI components won't operate reliably (or at all) above 10MHz
// Check the datasheet of the part // Check the datasheet of the part
case localFrequency < 21000000: case localFrequency < 21000000:
conf = stm32.SPI_PCLK_4 conf = stm32.SPI_CR1_BR_Div4
case localFrequency < 42000000: case localFrequency < 42000000:
conf = stm32.SPI_PCLK_2 conf = stm32.SPI_CR1_BR_Div2
default: default:
// None of the specific baudrates were selected; choose the lowest speed // None of the specific baudrates were selected; choose the lowest speed
conf = stm32.SPI_PCLK_256 conf = stm32.SPI_CR1_BR_Div256
} }
return conf << stm32.SPI_CR1_BR_Pos return conf << stm32.SPI_CR1_BR_Pos

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

@ -20,7 +20,7 @@ type UART struct {
Buffer *RingBuffer Buffer *RingBuffer
Bus *stm32.USART_Type Bus *stm32.USART_Type
Interrupt interrupt.Interrupt Interrupt interrupt.Interrupt
AltFuncSelector stm32.AltFunc AltFuncSelector uint8
} }
// Configure the UART. // Configure the UART.

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

@ -164,7 +164,7 @@ func enableAltFuncClock(bus unsafe.Pointer) {
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART2EN) stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART2EN)
case unsafe.Pointer(stm32.SPI2): // SPI2 clock enable case unsafe.Pointer(stm32.SPI2): // SPI2 clock enable
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_SPI2EN) stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_SPI2EN)
case unsafe.Pointer(stm32.LPUSART1): // LPUSART1 clock enable case unsafe.Pointer(stm32.LPUART1): // LPUART1 clock enable
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_LPUART1EN) stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_LPUART1EN)
case unsafe.Pointer(stm32.WWDG): // Window watchdog clock enable case unsafe.Pointer(stm32.WWDG): // Window watchdog clock enable
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_WWDGEN) stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_WWDGEN)
@ -176,7 +176,7 @@ func enableAltFuncClock(bus unsafe.Pointer) {
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM3EN) stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM3EN)
case unsafe.Pointer(stm32.TIM2): // TIM2 clock enable case unsafe.Pointer(stm32.TIM2): // TIM2 clock enable
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM2EN) stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM2EN)
case unsafe.Pointer(stm32.SYSCFG_COMP): // System configuration controller clock enable case unsafe.Pointer(stm32.SYSCFG): // System configuration controller clock enable
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SYSCFGEN) stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SYSCFGEN)
case unsafe.Pointer(stm32.SPI1): // SPI1 clock enable case unsafe.Pointer(stm32.SPI1): // SPI1 clock enable
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SPI1EN) stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SPI1EN)
@ -194,7 +194,7 @@ type UART struct {
Buffer *RingBuffer Buffer *RingBuffer
Bus *stm32.USART_Type Bus *stm32.USART_Type
Interrupt interrupt.Interrupt Interrupt interrupt.Interrupt
AltFuncSelector stm32.AltFunc AltFuncSelector uint8
} }
// Configure the UART. // Configure the UART.
@ -208,7 +208,7 @@ func (uart UART) configurePins(config UARTConfig) {
func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 { func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 {
var clock, rate uint32 var clock, rate uint32
switch uart.Bus { switch uart.Bus {
case stm32.LPUSART1: case stm32.LPUART1:
clock = CPUFrequency() / 2 // APB1 Frequency clock = CPUFrequency() / 2 // APB1 Frequency
rate = uint32((256 * clock) / baudRate) rate = uint32((256 * clock) / baudRate)
case stm32.USART1: case stm32.USART1:
@ -227,7 +227,7 @@ func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 {
// SPI on the STM32Fxxx using MODER / alternate function pins // SPI on the STM32Fxxx using MODER / alternate function pins
type SPI struct { type SPI struct {
Bus *stm32.SPI_Type Bus *stm32.SPI_Type
AltFuncSelector stm32.AltFunc AltFuncSelector uint8
} }
// Set baud rate for SPI // Set baud rate for SPI
@ -255,26 +255,26 @@ func (spi SPI) getBaudRate(config SPIConfig) uint32 {
// TODO: also include the MCU/APB clock setting in the equation // TODO: also include the MCU/APB clock setting in the equation
switch { switch {
case localFrequency < 328125: case localFrequency < 328125:
conf = stm32.SPI_PCLK_256 conf = stm32.SPI_CR1_BR_Div256
case localFrequency < 656250: case localFrequency < 656250:
conf = stm32.SPI_PCLK_128 conf = stm32.SPI_CR1_BR_Div128
case localFrequency < 1312500: case localFrequency < 1312500:
conf = stm32.SPI_PCLK_64 conf = stm32.SPI_CR1_BR_Div64
case localFrequency < 2625000: case localFrequency < 2625000:
conf = stm32.SPI_PCLK_32 conf = stm32.SPI_CR1_BR_Div32
case localFrequency < 5250000: case localFrequency < 5250000:
conf = stm32.SPI_PCLK_16 conf = stm32.SPI_CR1_BR_Div16
case localFrequency < 10500000: case localFrequency < 10500000:
conf = stm32.SPI_PCLK_8 conf = stm32.SPI_CR1_BR_Div8
// NOTE: many SPI components won't operate reliably (or at all) above 10MHz // NOTE: many SPI components won't operate reliably (or at all) above 10MHz
// Check the datasheet of the part // Check the datasheet of the part
case localFrequency < 21000000: case localFrequency < 21000000:
conf = stm32.SPI_PCLK_4 conf = stm32.SPI_CR1_BR_Div4
case localFrequency < 42000000: case localFrequency < 42000000:
conf = stm32.SPI_PCLK_2 conf = stm32.SPI_CR1_BR_Div2
default: default:
// None of the specific baudrates were selected; choose the lowest speed // None of the specific baudrates were selected; choose the lowest speed
conf = stm32.SPI_PCLK_256 conf = stm32.SPI_CR1_BR_Div256
} }
return conf << stm32.SPI_CR1_BR_Pos return conf << stm32.SPI_CR1_BR_Pos

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

@ -1,4 +1,4 @@
// +build stm32,stm32f103xx // +build stm32,stm32f103
package runtime package runtime
@ -23,10 +23,10 @@ func putchar(c byte) {
// initCLK sets clock to 72MHz using HSE 8MHz crystal w/ PLL X 9 (8MHz x 9 = 72MHz). // initCLK sets clock to 72MHz using HSE 8MHz crystal w/ PLL X 9 (8MHz x 9 = 72MHz).
func initCLK() { func initCLK() {
stm32.FLASH.ACR.SetBits(stm32.FLASH_ACR_LATENCY_2) // Two wait states, per datasheet stm32.FLASH.ACR.SetBits(stm32.FLASH_ACR_LATENCY_WS2) // Two wait states, per datasheet
stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE1_DIV_2) // prescale PCLK1 = HCLK/2 stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE1_Div2 << stm32.RCC_CFGR_PPRE1_Pos) // prescale PCLK1 = HCLK/2
stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE2_DIV_NONE) // prescale PCLK2 = HCLK/1 stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE2_Div1 << stm32.RCC_CFGR_PPRE2_Pos) // prescale PCLK2 = HCLK/1
stm32.RCC.CR.SetBits(stm32.RCC_CR_HSEON) // enable HSE clock stm32.RCC.CR.SetBits(stm32.RCC_CR_HSEON) // enable HSE clock
// wait for the HSEREADY flag // wait for the HSEREADY flag
for !stm32.RCC.CR.HasBits(stm32.RCC_CR_HSERDY) { for !stm32.RCC.CR.HasBits(stm32.RCC_CR_HSERDY) {
@ -38,9 +38,9 @@ func initCLK() {
for !stm32.RCC.CR.HasBits(stm32.RCC_CR_HSIRDY) { for !stm32.RCC.CR.HasBits(stm32.RCC_CR_HSIRDY) {
} }
stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PLLSRC) // set PLL source to HSE stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PLLSRC) // set PLL source to HSE
stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PLLMUL_9) // multiply by 9 stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PLLMUL_Mul9 << stm32.RCC_CFGR_PLLMUL_Pos) // multiply by 9
stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON) // enable the PLL stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON) // enable the PLL
// wait for the PLLRDY flag // wait for the PLLRDY flag
for !stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) { for !stm32.RCC.CR.HasBits(stm32.RCC_CR_PLLRDY) {
@ -49,7 +49,7 @@ func initCLK() {
stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_SW_PLL) // set clock source to pll stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_SW_PLL) // set clock source to pll
// wait for PLL to be CLK // wait for PLL to be CLK
for !stm32.RCC.CFGR.HasBits(stm32.RCC_CFGR_SWS_PLL) { for !stm32.RCC.CFGR.HasBits(stm32.RCC_CFGR_SWS_PLL << stm32.RCC_CFGR_SWS_Pos) {
} }
} }
@ -75,7 +75,7 @@ func initRTC() {
} }
// Select LSE // Select LSE
stm32.RCC.BDCR.SetBits(stm32.RCC_RTCCLKSource_LSE) stm32.RCC.BDCR.SetBits(stm32.RCC_BDCR_RTCSEL_LSE << stm32.RCC_BDCR_RTCSEL_Pos)
// set prescaler to "max" per datasheet // set prescaler to "max" per datasheet
stm32.RTC.PRLH.Set(stm32.RTC_PRLH_PRLH_Msk) stm32.RTC.PRLH.Set(stm32.RTC_PRLH_PRLH_Msk)

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

@ -39,17 +39,17 @@ const (
PLL_SRC_HSE = 1 << stm32.RCC_PLLCFGR_PLLSRC_Pos // use HSE for PLL and PLLI2S PLL_SRC_HSE = 1 << stm32.RCC_PLLCFGR_PLLSRC_Pos // use HSE for PLL and PLLI2S
PLL_SRC_HSI = 0 // use HSI for PLL and PLLI2S PLL_SRC_HSI = 0 // use HSI for PLL and PLLI2S
PLL_DIV_M = 6 << stm32.RCC_PLLCFGR_PLLM0_Pos PLL_DIV_M = 6 << stm32.RCC_PLLCFGR_PLLM_Pos
PLL_MLT_N = 168 << stm32.RCC_PLLCFGR_PLLN0_Pos PLL_MLT_N = 168 << stm32.RCC_PLLCFGR_PLLN_Pos
PLL_DIV_P = ((2 >> 1) - 1) << stm32.RCC_PLLCFGR_PLLP0_Pos PLL_DIV_P = ((2 >> 1) - 1) << stm32.RCC_PLLCFGR_PLLP_Pos
PLL_DIV_Q = 7 << stm32.RCC_PLLCFGR_PLLQ0_Pos PLL_DIV_Q = 7 << stm32.RCC_PLLCFGR_PLLQ_Pos
SYSCLK_SRC_PLL = 2 << stm32.RCC_CFGR_SW0_Pos SYSCLK_SRC_PLL = stm32.RCC_CFGR_SW_PLL << stm32.RCC_CFGR_SW_Pos
SYSCLK_STAT_PLL = 2 << stm32.RCC_CFGR_SWS0_Pos SYSCLK_STAT_PLL = stm32.RCC_CFGR_SWS_PLL << stm32.RCC_CFGR_SWS_Pos
RCC_DIV_PCLK1 = 5 << stm32.RCC_CFGR_PPRE1_Pos // HCLK / 4 RCC_DIV_PCLK1 = stm32.RCC_CFGR_PPRE1_Div4 << stm32.RCC_CFGR_PPRE1_Pos // HCLK / 4
RCC_DIV_PCLK2 = 4 << stm32.RCC_CFGR_PPRE2_Pos // HCLK / 2 RCC_DIV_PCLK2 = stm32.RCC_CFGR_PPRE2_Div2 << stm32.RCC_CFGR_PPRE2_Pos // HCLK / 2
RCC_DIV_HCLK = 0 << stm32.RCC_CFGR_HPRE_Pos // SYSCLK / 1 RCC_DIV_HCLK = stm32.RCC_CFGR_HPRE_Div1 << stm32.RCC_CFGR_HPRE_Pos // SYSCLK / 1
CLK_CCM_RAM = 1 << 20 CLK_CCM_RAM = 1 << 20
) )

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

@ -77,11 +77,11 @@ func initCLK() {
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_PWREN) stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_PWREN)
stm32.PWR.CR.SetBits(0x4000) // PWR_CR_VOS stm32.PWR.CR.SetBits(0x4000) // PWR_CR_VOS
// HCLK = SYSCLK / 1 // HCLK = SYSCLK / 1
stm32.RCC.CFGR.SetBits(0x0 << stm32.RCC_CFGR_HPRE_Pos) stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_HPRE_Div1 << stm32.RCC_CFGR_HPRE_Pos)
// PCLK2 = HCLK / 2 // PCLK2 = HCLK / 2
stm32.RCC.CFGR.SetBits(0x4 << stm32.RCC_CFGR_PPRE2_Pos) stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE2_Div2 << stm32.RCC_CFGR_PPRE2_Pos)
// PCLK1 = HCLK / 4 // PCLK1 = HCLK / 4
stm32.RCC.CFGR.SetBits(0x5 << stm32.RCC_CFGR_PPRE1_Pos) stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE1_Div4 << stm32.RCC_CFGR_PPRE1_Pos)
// Configure the main PLL // Configure the main PLL
// PLL Options - See RM0090 Reference Manual pg. 95 // PLL Options - See RM0090 Reference Manual pg. 95
stm32.RCC.PLLCFGR.Set(PLL_M | (PLL_N << 6) | (((PLL_P >> 1) - 1) << 16) | stm32.RCC.PLLCFGR.Set(PLL_M | (PLL_N << 6) | (((PLL_P >> 1) - 1) << 16) |
@ -94,9 +94,9 @@ func initCLK() {
// Configure Flash prefetch, Instruction cache, Data cache and wait state // Configure Flash prefetch, Instruction cache, Data cache and wait state
stm32.FLASH.ACR.Set(stm32.FLASH_ACR_ICEN | stm32.FLASH_ACR_DCEN | (5 << stm32.FLASH_ACR_LATENCY_Pos)) stm32.FLASH.ACR.Set(stm32.FLASH_ACR_ICEN | stm32.FLASH_ACR_DCEN | (5 << stm32.FLASH_ACR_LATENCY_Pos))
// Select the main PLL as system clock source // Select the main PLL as system clock source
stm32.RCC.CFGR.ClearBits(stm32.RCC_CFGR_SW0 | stm32.RCC_CFGR_SW1) stm32.RCC.CFGR.ClearBits(stm32.RCC_CFGR_SW_Msk)
stm32.RCC.CFGR.SetBits(0x2 << stm32.RCC_CFGR_SW0_Pos) stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_SW_PLL << stm32.RCC_CFGR_SW_Pos)
for (stm32.RCC.CFGR.Get() & (0x3 << stm32.RCC_CFGR_SWS0_Pos)) != (0x2 << stm32.RCC_CFGR_SWS0_Pos) { for (stm32.RCC.CFGR.Get() & stm32.RCC_CFGR_SWS_Msk) != (stm32.RCC_CFGR_SWS_PLL << stm32.RCC_CFGR_SWS_Pos) {
} }
} else { } else {

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

@ -93,9 +93,9 @@ func initOsc() {
stm32.RCC.PLLCFGR.Set(0x20000000 | stm32.RCC.PLLCFGR.Set(0x20000000 |
(1 << stm32.RCC_PLLCFGR_PLLSRC_Pos) | // 1 = HSE (1 << stm32.RCC_PLLCFGR_PLLSRC_Pos) | // 1 = HSE
PLL_M | PLL_M |
(PLL_N << stm32.RCC_PLLCFGR_PLLN0_Pos) | (PLL_N << stm32.RCC_PLLCFGR_PLLN_Pos) |
(((PLL_P >> 1) - 1) << stm32.RCC_PLLCFGR_PLLP0_Pos) | (((PLL_P >> 1) - 1) << stm32.RCC_PLLCFGR_PLLP_Pos) |
(PLL_Q << stm32.RCC_PLLCFGR_PLLQ0_Pos)) (PLL_Q << stm32.RCC_PLLCFGR_PLLQ_Pos))
// Enable the PLL, wait until ready // Enable the PLL, wait until ready
stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON) stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON)

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

@ -10,22 +10,6 @@ import (
"runtime/volatile" "runtime/volatile"
) )
const (
// Sets PCLK1
RCC_CFGR_PPRE1_DIV_NONE = 0x00000000
RCC_CFGR_PPRE1_DIV_2 = 0x00000400
RCC_CFGR_PPRE1_DIV_4 = 0x00000500
RCC_CFGR_PPRE1_DIV_8 = 0x00000600
RCC_CFGR_PPRE1_DIV_16 = 0x00000700
// Sets PCLK2
RCC_CFGR_PPRE2_DIV_NONE = 0x00000000
RCC_CFGR_PPRE2_DIV_2 = 0x00002000
RCC_CFGR_PPRE2_DIV_4 = 0x00002800
RCC_CFGR_PPRE2_DIV_8 = 0x00003000
RCC_CFGR_PPRE2_DIV_16 = 0x00003800
)
func init() { func init() {
initCLK() initCLK()
initRTC() initRTC()
@ -44,11 +28,11 @@ func initCLK() {
// Set the Flash ACR to use 1 wait-state // Set the Flash ACR to use 1 wait-state
// enable the prefetch buffer and pre-read for performance // enable the prefetch buffer and pre-read for performance
stm32.Flash.ACR.SetBits(stm32.Flash_ACR_LATENCY | stm32.Flash_ACR_PRFTEN | stm32.Flash_ACR_PRE_READ) stm32.FLASH.ACR.SetBits(stm32.Flash_ACR_LATENCY | stm32.Flash_ACR_PRFTEN | stm32.Flash_ACR_PRE_READ)
// Set presaclers so half system clock (PCLKx = HCLK/2) // Set presaclers so half system clock (PCLKx = HCLK/2)
stm32.RCC.CFGR.SetBits(RCC_CFGR_PPRE1_DIV_2) stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE1_Div2 << stm32.RCC_CFGR_PPRE1_Pos)
stm32.RCC.CFGR.SetBits(RCC_CFGR_PPRE2_DIV_2) stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE2_Div2 << stm32.RCC_CFGR_PPRE2_Pos)
// Enable the HSI16 oscillator, since the L0 series boots to the MSI one. // Enable the HSI16 oscillator, since the L0 series boots to the MSI one.
stm32.RCC.CR.SetBits(stm32.RCC_CR_HSI16ON) stm32.RCC.CR.SetBits(stm32.RCC_CR_HSI16ON)
@ -202,7 +186,7 @@ func timerSleep(ticks uint32) {
if ticks < 200 { if ticks < 200 {
ticks = 200 ticks = 200
} }
stm32.TIM3.ARR.Set(ticks/100 - 1) // convert from microseconds to 0.1 ms stm32.TIM3.ARR.Set(uint16(ticks/100 - 1)) // convert from microseconds to 0.1 ms
// Enable the hardware interrupt. // Enable the hardware interrupt.
stm32.TIM3.DIER.SetBits(stm32.TIM_DIER_UIE) stm32.TIM3.DIER.SetBits(stm32.TIM_DIER_UIE)

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

@ -1,14 +1,14 @@
{ {
"inherits": ["cortex-m"], "inherits": ["cortex-m"],
"llvm-target": "armv7m-none-eabi", "llvm-target": "armv7m-none-eabi",
"build-tags": ["bluepill", "stm32f103xx", "stm32"], "build-tags": ["bluepill", "stm32f103", "stm32"],
"cflags": [ "cflags": [
"--target=armv7m-none-eabi", "--target=armv7m-none-eabi",
"-Qunused-arguments" "-Qunused-arguments"
], ],
"linkerscript": "targets/stm32.ld", "linkerscript": "targets/stm32.ld",
"extra-files": [ "extra-files": [
"src/device/stm32/stm32f103xx.s" "src/device/stm32/stm32f103.s"
], ],
"flash-method": "openocd", "flash-method": "openocd",
"openocd-interface": "stlink-v2", "openocd-interface": "stlink-v2",

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

@ -1,14 +1,14 @@
{ {
"inherits": ["cortex-m"], "inherits": ["cortex-m"],
"llvm-target": "armv7m-none-eabi", "llvm-target": "armv7m-none-eabi",
"build-tags": ["nucleof103rb", "stm32f103xx", "stm32"], "build-tags": ["nucleof103rb", "stm32f103", "stm32"],
"cflags": [ "cflags": [
"--target=armv7m-none-eabi", "--target=armv7m-none-eabi",
"-Qunused-arguments" "-Qunused-arguments"
], ],
"linkerscript": "targets/stm32f103rb.ld", "linkerscript": "targets/stm32f103rb.ld",
"extra-files": [ "extra-files": [
"src/device/stm32/stm32f103xx.s" "src/device/stm32/stm32f103.s"
], ],
"flash-method": "openocd", "flash-method": "openocd",
"openocd-interface": "stlink-v2-1", "openocd-interface": "stlink-v2-1",

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

@ -60,11 +60,15 @@ type SVDField struct {
BitOffset *uint32 `xml:"bitOffset"` BitOffset *uint32 `xml:"bitOffset"`
BitWidth *uint32 `xml:"bitWidth"` BitWidth *uint32 `xml:"bitWidth"`
BitRange *string `xml:"bitRange"` BitRange *string `xml:"bitRange"`
EnumeratedValues []struct { EnumeratedValues struct {
Name string `xml:"name"` DerivedFrom string `xml:"derivedFrom,attr"`
Description string `xml:"description"` Name string `xml:"name"`
Value string `xml:"value"` EnumeratedValue []struct {
} `xml:"enumeratedValues>enumeratedValue"` Name string `xml:"name"`
Description string `xml:"description"`
Value string `xml:"value"`
} `xml:"enumeratedValue"`
} `xml:"enumeratedValues"`
} }
type SVDCluster struct { type SVDCluster struct {
@ -444,7 +448,7 @@ func addInterrupt(interrupts map[string]*interrupt, name, interruptName string,
if interrupts[name].Value != index { if interrupts[name].Value != index {
// Note: some SVD files like the one for STM32H7x7 contain mistakes. // Note: some SVD files like the one for STM32H7x7 contain mistakes.
// Instead of throwing an error, simply log it. // Instead of throwing an error, simply log it.
fmt.Fprintf(os.Stderr, "interrupt with the same name has different indexes: %s (%d vs %d)", fmt.Fprintf(os.Stderr, "interrupt with the same name has different indexes: %s (%d vs %d)\n",
name, interrupts[name].Value, index) name, interrupts[name].Value, index)
} }
parts := strings.Split(interrupts[name].Description, " // ") parts := strings.Split(interrupts[name].Description, " // ")
@ -470,7 +474,7 @@ func addInterrupt(interrupts map[string]*interrupt, name, interruptName string,
func parseBitfields(groupName, regName string, fieldEls []*SVDField, bitfieldPrefix string) []Bitfield { func parseBitfields(groupName, regName string, fieldEls []*SVDField, bitfieldPrefix string) []Bitfield {
var fields []Bitfield var fields []Bitfield
enumSeen := map[string]bool{} enumSeen := map[string]int64{}
for _, fieldEl := range fieldEls { for _, fieldEl := range fieldEls {
// Some bitfields (like the STM32H7x7) contain invalid bitfield // Some bitfields (like the STM32H7x7) contain invalid bitfield
// names like "CNT[31]". Replace invalid characters with "_" when // names like "CNT[31]". Replace invalid characters with "_" when
@ -511,6 +515,32 @@ func parseBitfields(groupName, regName string, fieldEls []*SVDField, bitfieldPre
continue continue
} }
// The enumerated values can be the same as another field, so to avoid
// duplication SVD files can simply refer to another set of enumerated
// values in the same register.
// See: https://www.keil.com/pack/doc/CMSIS/SVD/html/elem_registers.html#elem_enumeratedValues
enumeratedValues := fieldEl.EnumeratedValues
if enumeratedValues.DerivedFrom != "" {
parts := strings.Split(enumeratedValues.DerivedFrom, ".")
if len(parts) == 1 {
found := false
for _, otherFieldEl := range fieldEls {
if otherFieldEl.EnumeratedValues.Name == parts[0] {
found = true
enumeratedValues = otherFieldEl.EnumeratedValues
}
}
if !found {
fmt.Fprintf(os.Stderr, "Warning: could not find enumeratedValue.derivedFrom of %s for register field %s\n", enumeratedValues.DerivedFrom, fieldName)
}
} else {
// The derivedFrom attribute may also point to enumerated values
// in other registers and even peripherals, but this feature
// isn't often used in SVD files.
fmt.Fprintf(os.Stderr, "TODO: enumeratedValue.derivedFrom to a different register: %s\n", enumeratedValues.DerivedFrom)
}
}
fields = append(fields, Bitfield{ fields = append(fields, Bitfield{
name: fmt.Sprintf("%s_%s%s_%s_Pos", groupName, bitfieldPrefix, regName, fieldName), name: fmt.Sprintf("%s_%s%s_%s_Pos", groupName, bitfieldPrefix, regName, fieldName),
description: fmt.Sprintf("Position of %s field.", fieldName), description: fmt.Sprintf("Position of %s field.", fieldName),
@ -528,7 +558,7 @@ func parseBitfields(groupName, regName string, fieldEls []*SVDField, bitfieldPre
value: 1 << lsb, value: 1 << lsb,
}) })
} }
for _, enumEl := range fieldEl.EnumeratedValues { for _, enumEl := range enumeratedValues.EnumeratedValue {
enumName := enumEl.Name enumName := enumEl.Name
if strings.EqualFold(enumName, "reserved") || !validName.MatchString(enumName) { if strings.EqualFold(enumName, "reserved") || !validName.MatchString(enumName) {
continue continue
@ -557,8 +587,35 @@ func parseBitfields(groupName, regName string, fieldEls []*SVDField, bitfieldPre
} }
} }
enumName = fmt.Sprintf("%s_%s%s_%s_%s", groupName, bitfieldPrefix, regName, fieldName, enumName) enumName = fmt.Sprintf("%s_%s%s_%s_%s", groupName, bitfieldPrefix, regName, fieldName, enumName)
_, seen := enumSeen[enumName]
enumSeen[enumName] = seen // Avoid duplicate values. Duplicate names with the same value are
// allowed, but the same name with a different value is not. Instead
// of trying to work around those cases, remove the value entirely
// as there is probably not one correct answer in such a case.
// For example, SVD files from NXP have enums limited to 20
// characters, leading to lots of duplicates when these enum names
// are long. Nothing here can really fix those cases.
previousEnumValue, seenBefore := enumSeen[enumName]
if seenBefore {
if previousEnumValue < 0 {
// There was a mismatch before, ignore all equally named fields.
continue
}
if int64(enumValue) != previousEnumValue {
// There is a mismatch. Mark it as such, and remove the
// existing enum bitfield value.
enumSeen[enumName] = -1
for i, field := range fields {
if field.name == enumName {
fields = append(fields[:i], fields[i+1:]...)
break
}
}
}
continue
}
enumSeen[enumName] = int64(enumValue)
fields = append(fields, Bitfield{ fields = append(fields, Bitfield{
name: enumName, name: enumName,
description: enumDescription, description: enumDescription,
@ -566,13 +623,6 @@ func parseBitfields(groupName, regName string, fieldEls []*SVDField, bitfieldPre
}) })
} }
} }
// check if any of the field names appeared more than once. if so, append
// its value onto its name to ensure each name is unique.
for i, field := range fields {
if dup, seen := enumSeen[field.name]; dup && seen {
fields[i].name = fmt.Sprintf("%s_%d", field.name, field.value)
}
}
return fields return fields
} }