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.
Этот коммит содержится в:
родитель
65caf777dd
коммит
154c7c691b
24 изменённых файлов: 259 добавлений и 333 удалений
3
.gitmodules
предоставленный
3
.gitmodules
предоставленный
|
@ -20,3 +20,6 @@
|
|||
[submodule "lib/picolibc"]
|
||||
path = lib/picolibc
|
||||
url = https://github.com/keith-packard/picolibc.git
|
||||
[submodule "lib/stm32-svd"]
|
||||
path = lib/stm32-svd
|
||||
url = https://github.com/tinygo-org/stm32-svd
|
||||
|
|
2
Makefile
2
Makefile
|
@ -130,7 +130,7 @@ gen-device-kendryte: build/gen-device-svd
|
|||
GO111MODULE=off $(GO) fmt ./src/device/kendryte
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
|
1
lib/stm32-svd
Подмодуль
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{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: stm32.USART3,
|
||||
AltFuncSelector: stm32.AF7_USART1_2_3,
|
||||
AltFuncSelector: AF7_USART1_2_3,
|
||||
}
|
||||
UART2 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: stm32.USART6,
|
||||
AltFuncSelector: stm32.AF8_USART4_5_6,
|
||||
AltFuncSelector: AF8_USART4_5_6,
|
||||
}
|
||||
UART3 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: stm32.USART1,
|
||||
AltFuncSelector: stm32.AF7_USART1_2_3,
|
||||
AltFuncSelector: AF7_USART1_2_3,
|
||||
}
|
||||
UART0 = UART1
|
||||
)
|
||||
|
@ -181,15 +181,15 @@ const (
|
|||
var (
|
||||
SPI1 = SPI{
|
||||
Bus: stm32.SPI2,
|
||||
AltFuncSelector: stm32.AF5_SPI1_SPI2,
|
||||
AltFuncSelector: AF5_SPI1_SPI2,
|
||||
}
|
||||
SPI2 = SPI{
|
||||
Bus: stm32.SPI3,
|
||||
AltFuncSelector: stm32.AF6_SPI3,
|
||||
AltFuncSelector: AF6_SPI3,
|
||||
}
|
||||
SPI3 = SPI{
|
||||
Bus: stm32.SPI1,
|
||||
AltFuncSelector: stm32.AF5_SPI1_SPI2,
|
||||
AltFuncSelector: AF5_SPI1_SPI2,
|
||||
}
|
||||
SPI0 = SPI1
|
||||
)
|
||||
|
@ -229,15 +229,15 @@ const (
|
|||
var (
|
||||
I2C1 = I2C{
|
||||
Bus: stm32.I2C1,
|
||||
AltFuncSelector: stm32.AF4_I2C1_2_3,
|
||||
AltFuncSelector: AF4_I2C1_2_3,
|
||||
}
|
||||
I2C2 = I2C{
|
||||
Bus: stm32.I2C2,
|
||||
AltFuncSelector: stm32.AF4_I2C1_2_3,
|
||||
AltFuncSelector: AF4_I2C1_2_3,
|
||||
}
|
||||
I2C3 = I2C{
|
||||
Bus: stm32.I2C1,
|
||||
AltFuncSelector: stm32.AF4_I2C1_2_3,
|
||||
AltFuncSelector: AF4_I2C1_2_3,
|
||||
}
|
||||
I2C0 = I2C1
|
||||
)
|
||||
|
|
|
@ -55,7 +55,7 @@ var (
|
|||
// Console UART (LPUSART1)
|
||||
UART0 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: stm32.LPUSART1,
|
||||
Bus: stm32.LPUART1,
|
||||
AltFuncSelector: 6,
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ var (
|
|||
UART0 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: stm32.USART2,
|
||||
AltFuncSelector: stm32.AF7_USART1_2_3,
|
||||
AltFuncSelector: AF7_USART1_2_3,
|
||||
}
|
||||
UART1 = &UART0
|
||||
)
|
||||
|
@ -62,7 +62,7 @@ const (
|
|||
var (
|
||||
SPI0 = SPI{
|
||||
Bus: stm32.SPI1,
|
||||
AltFuncSelector: stm32.AF5_SPI1_SPI2,
|
||||
AltFuncSelector: AF5_SPI1_SPI2,
|
||||
}
|
||||
SPI1 = &SPI0
|
||||
)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build stm32,!stm32f103xx,!stm32f407,!stm32f7x2,!stm32l0
|
||||
// +build stm32,!stm32f103,!stm32f407,!stm32f7x2,!stm32l0
|
||||
|
||||
package machine
|
||||
|
||||
|
@ -110,10 +110,10 @@ type (
|
|||
)
|
||||
|
||||
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 {
|
||||
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
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build stm32,!stm32f103xx
|
||||
// +build stm32,!stm32f103
|
||||
|
||||
package machine
|
||||
|
||||
|
@ -38,85 +38,106 @@ const (
|
|||
// 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
|
||||
func (p Pin) Configure(config PinConfig) {
|
||||
// Use the default system alternate function; this
|
||||
// will only be used if you try to call this with
|
||||
// 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
|
||||
// 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.
|
||||
p.enableClock()
|
||||
port := p.getPort()
|
||||
pin := uint8(p) % 16
|
||||
pos := pin * 2
|
||||
pos := (uint8(p) % 16) * 2 // assume each field is two bits in size (with mask 0x3)
|
||||
|
||||
switch config.Mode {
|
||||
|
||||
// GPIO
|
||||
case PinInputFloating:
|
||||
port.MODER.ReplaceBits(stm32.GPIOModeInput, 0x3, pos)
|
||||
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos)
|
||||
port.MODER.ReplaceBits(gpioModeInput, gpioModeMask, pos)
|
||||
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
||||
case PinInputPulldown:
|
||||
port.MODER.ReplaceBits(stm32.GPIOModeInput, 0x3, pos)
|
||||
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRPullDown, 0x3, pos)
|
||||
port.MODER.ReplaceBits(gpioModeInput, gpioModeMask, pos)
|
||||
port.PUPDR.ReplaceBits(gpioPullDown, gpioPullMask, pos)
|
||||
case PinInputPullup:
|
||||
port.MODER.ReplaceBits(stm32.GPIOModeInput, 0x3, pos)
|
||||
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRPullUp, 0x3, pos)
|
||||
port.MODER.ReplaceBits(gpioModeInput, gpioModeMask, pos)
|
||||
port.PUPDR.ReplaceBits(gpioPullUp, gpioPullMask, pos)
|
||||
case PinOutput:
|
||||
port.MODER.ReplaceBits(stm32.GPIOModeOutputGeneral, 0x3, pos)
|
||||
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedHigh, 0x3, pos)
|
||||
port.MODER.ReplaceBits(gpioModeOutput, gpioModeMask, pos)
|
||||
port.OSPEEDR.ReplaceBits(gpioOutputSpeedHigh, gpioOutputSpeedMask, pos)
|
||||
|
||||
// UART
|
||||
case PinModeUARTTX:
|
||||
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos)
|
||||
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedHigh, 0x3, pos)
|
||||
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRPullUp, 0x3, pos)
|
||||
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
||||
port.OSPEEDR.ReplaceBits(gpioOutputSpeedHigh, gpioOutputSpeedMask, pos)
|
||||
port.PUPDR.ReplaceBits(gpioPullUp, gpioPullMask, pos)
|
||||
p.SetAltFunc(altFunc)
|
||||
case PinModeUARTRX:
|
||||
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos)
|
||||
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos)
|
||||
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
||||
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
||||
p.SetAltFunc(altFunc)
|
||||
|
||||
// I2C
|
||||
case PinModeI2CSCL:
|
||||
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos)
|
||||
port.OTYPER.ReplaceBits(stm32.GPIOOutputTypeOpenDrain, 0x1, pos)
|
||||
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedLow, 0x3, pos)
|
||||
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos)
|
||||
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
||||
port.OTYPER.ReplaceBits(stm32.GPIO_OTYPER_OT0_OpenDrain, stm32.GPIO_OTYPER_OT0_Msk, pos/2)
|
||||
port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos)
|
||||
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
||||
p.SetAltFunc(altFunc)
|
||||
case PinModeI2CSDA:
|
||||
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos)
|
||||
port.OTYPER.ReplaceBits(stm32.GPIOOutputTypeOpenDrain, 0x1, pos)
|
||||
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedLow, 0x3, pos)
|
||||
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos)
|
||||
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
||||
port.OTYPER.ReplaceBits(stm32.GPIO_OTYPER_OT0_OpenDrain, stm32.GPIO_OTYPER_OT0_Msk, pos/2)
|
||||
port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos)
|
||||
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
||||
p.SetAltFunc(altFunc)
|
||||
|
||||
// SPI
|
||||
case PinModeSPICLK:
|
||||
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos)
|
||||
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedLow, 0x3, pos)
|
||||
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos)
|
||||
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
||||
port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos)
|
||||
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
||||
p.SetAltFunc(altFunc)
|
||||
case PinModeSPISDO:
|
||||
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos)
|
||||
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedLow, 0x3, pos)
|
||||
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos)
|
||||
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
||||
port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos)
|
||||
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
||||
p.SetAltFunc(altFunc)
|
||||
case PinModeSPISDI:
|
||||
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos)
|
||||
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedLow, 0x3, pos)
|
||||
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos)
|
||||
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
||||
port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos)
|
||||
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
||||
p.SetAltFunc(altFunc)
|
||||
}
|
||||
}
|
||||
|
||||
// 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()
|
||||
pin := uint8(p) % 16
|
||||
pos := (pin % 8) * 4
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build stm32,stm32f103xx
|
||||
// +build stm32,stm32f103
|
||||
|
||||
package machine
|
||||
|
||||
|
@ -169,21 +169,21 @@ func (spi SPI) getBaudRate(config SPIConfig) uint32 {
|
|||
switch config.Frequency {
|
||||
case 125000:
|
||||
// Note: impossible to achieve lower frequency with current PCLK2!
|
||||
conf |= stm32.SPI_BaudRatePrescaler_256
|
||||
conf |= stm32.SPI_CR1_BR_Div256
|
||||
case 250000:
|
||||
conf |= stm32.SPI_BaudRatePrescaler_256
|
||||
conf |= stm32.SPI_CR1_BR_Div256
|
||||
case 500000:
|
||||
conf |= stm32.SPI_BaudRatePrescaler_128
|
||||
conf |= stm32.SPI_CR1_BR_Div128
|
||||
case 1000000:
|
||||
conf |= stm32.SPI_BaudRatePrescaler_64
|
||||
conf |= stm32.SPI_CR1_BR_Div64
|
||||
case 2000000:
|
||||
conf |= stm32.SPI_BaudRatePrescaler_32
|
||||
conf |= stm32.SPI_CR1_BR_Div32
|
||||
case 4000000:
|
||||
conf |= stm32.SPI_BaudRatePrescaler_16
|
||||
conf |= stm32.SPI_CR1_BR_Div16
|
||||
case 8000000:
|
||||
conf |= stm32.SPI_BaudRatePrescaler_8
|
||||
conf |= stm32.SPI_CR1_BR_Div8
|
||||
default:
|
||||
conf |= stm32.SPI_BaudRatePrescaler_256
|
||||
conf |= stm32.SPI_CR1_BR_Div256
|
||||
}
|
||||
return conf
|
||||
}
|
||||
|
@ -542,7 +542,7 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
const i2cTimeout = 500
|
||||
const i2cTimeout = 1000
|
||||
|
||||
// signalStart sends a start signal.
|
||||
func (i2c I2C) signalStart() error {
|
|
@ -14,13 +14,33 @@ func CPUFrequency() uint32 {
|
|||
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 ---------------------------------------------------------------------
|
||||
|
||||
type UART struct {
|
||||
Buffer *RingBuffer
|
||||
Bus *stm32.USART_Type
|
||||
Interrupt interrupt.Interrupt
|
||||
AltFuncSelector stm32.AltFunc
|
||||
AltFuncSelector uint8
|
||||
}
|
||||
|
||||
func (uart UART) configurePins(config UARTConfig) {
|
||||
|
@ -44,7 +64,7 @@ func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 {
|
|||
|
||||
type SPI struct {
|
||||
Bus *stm32.SPI_Type
|
||||
AltFuncSelector stm32.AltFunc
|
||||
AltFuncSelector uint8
|
||||
}
|
||||
|
||||
func (spi SPI) configurePins(config SPIConfig) {
|
||||
|
@ -93,7 +113,7 @@ func (spi SPI) getBaudRate(config SPIConfig) uint32 {
|
|||
|
||||
type I2C struct {
|
||||
Bus *stm32.I2C_Type
|
||||
AltFuncSelector stm32.AltFunc
|
||||
AltFuncSelector uint8
|
||||
}
|
||||
|
||||
func (i2c I2C) configurePins(config I2CConfig) {
|
||||
|
|
|
@ -13,6 +13,26 @@ func CPUFrequency() uint32 {
|
|||
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 representation
|
||||
|
@ -20,7 +40,7 @@ type UART struct {
|
|||
Buffer *RingBuffer
|
||||
Bus *stm32.USART_Type
|
||||
Interrupt interrupt.Interrupt
|
||||
AltFuncSelector stm32.AltFunc
|
||||
AltFuncSelector uint8
|
||||
}
|
||||
|
||||
// Configure the UART.
|
||||
|
@ -48,7 +68,7 @@ func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 {
|
|||
// SPI on the STM32Fxxx using MODER / alternate function pins
|
||||
type SPI struct {
|
||||
Bus *stm32.SPI_Type
|
||||
AltFuncSelector stm32.AltFunc
|
||||
AltFuncSelector uint8
|
||||
}
|
||||
|
||||
// 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
|
||||
switch true {
|
||||
case localFrequency < 328125:
|
||||
conf = stm32.SPI_PCLK_256
|
||||
conf = stm32.SPI_CR1_BR_Div256
|
||||
case localFrequency < 656250:
|
||||
conf = stm32.SPI_PCLK_128
|
||||
conf = stm32.SPI_CR1_BR_Div128
|
||||
case localFrequency < 1312500:
|
||||
conf = stm32.SPI_PCLK_64
|
||||
conf = stm32.SPI_CR1_BR_Div64
|
||||
case localFrequency < 2625000:
|
||||
conf = stm32.SPI_PCLK_32
|
||||
conf = stm32.SPI_CR1_BR_Div32
|
||||
case localFrequency < 5250000:
|
||||
conf = stm32.SPI_PCLK_16
|
||||
conf = stm32.SPI_CR1_BR_Div16
|
||||
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
|
||||
// Check the datasheet of the part
|
||||
case localFrequency < 21000000:
|
||||
conf = stm32.SPI_PCLK_4
|
||||
conf = stm32.SPI_CR1_BR_Div4
|
||||
case localFrequency < 42000000:
|
||||
conf = stm32.SPI_PCLK_2
|
||||
conf = stm32.SPI_CR1_BR_Div2
|
||||
default:
|
||||
// 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
|
||||
|
|
|
@ -20,7 +20,7 @@ type UART struct {
|
|||
Buffer *RingBuffer
|
||||
Bus *stm32.USART_Type
|
||||
Interrupt interrupt.Interrupt
|
||||
AltFuncSelector stm32.AltFunc
|
||||
AltFuncSelector uint8
|
||||
}
|
||||
|
||||
// Configure the UART.
|
||||
|
|
|
@ -164,7 +164,7 @@ func enableAltFuncClock(bus unsafe.Pointer) {
|
|||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART2EN)
|
||||
case unsafe.Pointer(stm32.SPI2): // SPI2 clock enable
|
||||
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)
|
||||
case unsafe.Pointer(stm32.WWDG): // Window watchdog clock enable
|
||||
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)
|
||||
case unsafe.Pointer(stm32.TIM2): // TIM2 clock enable
|
||||
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)
|
||||
case unsafe.Pointer(stm32.SPI1): // SPI1 clock enable
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SPI1EN)
|
||||
|
@ -194,7 +194,7 @@ type UART struct {
|
|||
Buffer *RingBuffer
|
||||
Bus *stm32.USART_Type
|
||||
Interrupt interrupt.Interrupt
|
||||
AltFuncSelector stm32.AltFunc
|
||||
AltFuncSelector uint8
|
||||
}
|
||||
|
||||
// Configure the UART.
|
||||
|
@ -208,7 +208,7 @@ func (uart UART) configurePins(config UARTConfig) {
|
|||
func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 {
|
||||
var clock, rate uint32
|
||||
switch uart.Bus {
|
||||
case stm32.LPUSART1:
|
||||
case stm32.LPUART1:
|
||||
clock = CPUFrequency() / 2 // APB1 Frequency
|
||||
rate = uint32((256 * clock) / baudRate)
|
||||
case stm32.USART1:
|
||||
|
@ -227,7 +227,7 @@ func (uart UART) getBaudRateDivisor(baudRate uint32) uint32 {
|
|||
// SPI on the STM32Fxxx using MODER / alternate function pins
|
||||
type SPI struct {
|
||||
Bus *stm32.SPI_Type
|
||||
AltFuncSelector stm32.AltFunc
|
||||
AltFuncSelector uint8
|
||||
}
|
||||
|
||||
// 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
|
||||
switch {
|
||||
case localFrequency < 328125:
|
||||
conf = stm32.SPI_PCLK_256
|
||||
conf = stm32.SPI_CR1_BR_Div256
|
||||
case localFrequency < 656250:
|
||||
conf = stm32.SPI_PCLK_128
|
||||
conf = stm32.SPI_CR1_BR_Div128
|
||||
case localFrequency < 1312500:
|
||||
conf = stm32.SPI_PCLK_64
|
||||
conf = stm32.SPI_CR1_BR_Div64
|
||||
case localFrequency < 2625000:
|
||||
conf = stm32.SPI_PCLK_32
|
||||
conf = stm32.SPI_CR1_BR_Div32
|
||||
case localFrequency < 5250000:
|
||||
conf = stm32.SPI_PCLK_16
|
||||
conf = stm32.SPI_CR1_BR_Div16
|
||||
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
|
||||
// Check the datasheet of the part
|
||||
case localFrequency < 21000000:
|
||||
conf = stm32.SPI_PCLK_4
|
||||
conf = stm32.SPI_CR1_BR_Div4
|
||||
case localFrequency < 42000000:
|
||||
conf = stm32.SPI_PCLK_2
|
||||
conf = stm32.SPI_CR1_BR_Div2
|
||||
default:
|
||||
// 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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build stm32,stm32f103xx
|
||||
// +build stm32,stm32f103
|
||||
|
||||
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).
|
||||
func initCLK() {
|
||||
stm32.FLASH.ACR.SetBits(stm32.FLASH_ACR_LATENCY_2) // 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_PPRE2_DIV_NONE) // prescale PCLK2 = HCLK/1
|
||||
stm32.RCC.CR.SetBits(stm32.RCC_CR_HSEON) // enable HSE clock
|
||||
stm32.FLASH.ACR.SetBits(stm32.FLASH_ACR_LATENCY_WS2) // Two wait states, per datasheet
|
||||
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_Div1 << stm32.RCC_CFGR_PPRE2_Pos) // prescale PCLK2 = HCLK/1
|
||||
stm32.RCC.CR.SetBits(stm32.RCC_CR_HSEON) // enable HSE clock
|
||||
|
||||
// wait for the HSEREADY flag
|
||||
for !stm32.RCC.CR.HasBits(stm32.RCC_CR_HSERDY) {
|
||||
|
@ -38,9 +38,9 @@ func initCLK() {
|
|||
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_PLLMUL_9) // multiply by 9
|
||||
stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON) // enable the PLL
|
||||
stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PLLSRC) // set PLL source to HSE
|
||||
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
|
||||
|
||||
// wait for the PLLRDY flag
|
||||
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
|
||||
|
||||
// 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
|
||||
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
|
||||
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_HSI = 0 // use HSI for PLL and PLLI2S
|
||||
|
||||
PLL_DIV_M = 6 << stm32.RCC_PLLCFGR_PLLM0_Pos
|
||||
PLL_MLT_N = 168 << stm32.RCC_PLLCFGR_PLLN0_Pos
|
||||
PLL_DIV_P = ((2 >> 1) - 1) << stm32.RCC_PLLCFGR_PLLP0_Pos
|
||||
PLL_DIV_Q = 7 << stm32.RCC_PLLCFGR_PLLQ0_Pos
|
||||
PLL_DIV_M = 6 << stm32.RCC_PLLCFGR_PLLM_Pos
|
||||
PLL_MLT_N = 168 << stm32.RCC_PLLCFGR_PLLN_Pos
|
||||
PLL_DIV_P = ((2 >> 1) - 1) << stm32.RCC_PLLCFGR_PLLP_Pos
|
||||
PLL_DIV_Q = 7 << stm32.RCC_PLLCFGR_PLLQ_Pos
|
||||
|
||||
SYSCLK_SRC_PLL = 2 << stm32.RCC_CFGR_SW0_Pos
|
||||
SYSCLK_STAT_PLL = 2 << stm32.RCC_CFGR_SWS0_Pos
|
||||
SYSCLK_SRC_PLL = stm32.RCC_CFGR_SW_PLL << stm32.RCC_CFGR_SW_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_PCLK2 = 4 << stm32.RCC_CFGR_PPRE2_Pos // HCLK / 2
|
||||
RCC_DIV_HCLK = 0 << stm32.RCC_CFGR_HPRE_Pos // SYSCLK / 1
|
||||
RCC_DIV_PCLK1 = stm32.RCC_CFGR_PPRE1_Div4 << stm32.RCC_CFGR_PPRE1_Pos // HCLK / 4
|
||||
RCC_DIV_PCLK2 = stm32.RCC_CFGR_PPRE2_Div2 << stm32.RCC_CFGR_PPRE2_Pos // HCLK / 2
|
||||
RCC_DIV_HCLK = stm32.RCC_CFGR_HPRE_Div1 << stm32.RCC_CFGR_HPRE_Pos // SYSCLK / 1
|
||||
|
||||
CLK_CCM_RAM = 1 << 20
|
||||
)
|
||||
|
|
|
@ -77,11 +77,11 @@ func initCLK() {
|
|||
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_PWREN)
|
||||
stm32.PWR.CR.SetBits(0x4000) // PWR_CR_VOS
|
||||
// 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
|
||||
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
|
||||
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
|
||||
// PLL Options - See RM0090 Reference Manual pg. 95
|
||||
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
|
||||
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
|
||||
stm32.RCC.CFGR.ClearBits(stm32.RCC_CFGR_SW0 | stm32.RCC_CFGR_SW1)
|
||||
stm32.RCC.CFGR.SetBits(0x2 << stm32.RCC_CFGR_SW0_Pos)
|
||||
for (stm32.RCC.CFGR.Get() & (0x3 << stm32.RCC_CFGR_SWS0_Pos)) != (0x2 << stm32.RCC_CFGR_SWS0_Pos) {
|
||||
stm32.RCC.CFGR.ClearBits(stm32.RCC_CFGR_SW_Msk)
|
||||
stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_SW_PLL << stm32.RCC_CFGR_SW_Pos)
|
||||
for (stm32.RCC.CFGR.Get() & stm32.RCC_CFGR_SWS_Msk) != (stm32.RCC_CFGR_SWS_PLL << stm32.RCC_CFGR_SWS_Pos) {
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
|
@ -93,9 +93,9 @@ func initOsc() {
|
|||
stm32.RCC.PLLCFGR.Set(0x20000000 |
|
||||
(1 << stm32.RCC_PLLCFGR_PLLSRC_Pos) | // 1 = HSE
|
||||
PLL_M |
|
||||
(PLL_N << stm32.RCC_PLLCFGR_PLLN0_Pos) |
|
||||
(((PLL_P >> 1) - 1) << stm32.RCC_PLLCFGR_PLLP0_Pos) |
|
||||
(PLL_Q << stm32.RCC_PLLCFGR_PLLQ0_Pos))
|
||||
(PLL_N << stm32.RCC_PLLCFGR_PLLN_Pos) |
|
||||
(((PLL_P >> 1) - 1) << stm32.RCC_PLLCFGR_PLLP_Pos) |
|
||||
(PLL_Q << stm32.RCC_PLLCFGR_PLLQ_Pos))
|
||||
|
||||
// Enable the PLL, wait until ready
|
||||
stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON)
|
||||
|
|
|
@ -10,22 +10,6 @@ import (
|
|||
"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() {
|
||||
initCLK()
|
||||
initRTC()
|
||||
|
@ -44,11 +28,11 @@ func initCLK() {
|
|||
|
||||
// Set the Flash ACR to use 1 wait-state
|
||||
// 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)
|
||||
stm32.RCC.CFGR.SetBits(RCC_CFGR_PPRE1_DIV_2)
|
||||
stm32.RCC.CFGR.SetBits(RCC_CFGR_PPRE2_DIV_2)
|
||||
stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PPRE1_Div2 << stm32.RCC_CFGR_PPRE1_Pos)
|
||||
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.
|
||||
stm32.RCC.CR.SetBits(stm32.RCC_CR_HSI16ON)
|
||||
|
@ -202,7 +186,7 @@ func timerSleep(ticks uint32) {
|
|||
if 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.
|
||||
stm32.TIM3.DIER.SetBits(stm32.TIM_DIER_UIE)
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
{
|
||||
"inherits": ["cortex-m"],
|
||||
"llvm-target": "armv7m-none-eabi",
|
||||
"build-tags": ["bluepill", "stm32f103xx", "stm32"],
|
||||
"build-tags": ["bluepill", "stm32f103", "stm32"],
|
||||
"cflags": [
|
||||
"--target=armv7m-none-eabi",
|
||||
"-Qunused-arguments"
|
||||
],
|
||||
"linkerscript": "targets/stm32.ld",
|
||||
"extra-files": [
|
||||
"src/device/stm32/stm32f103xx.s"
|
||||
"src/device/stm32/stm32f103.s"
|
||||
],
|
||||
"flash-method": "openocd",
|
||||
"openocd-interface": "stlink-v2",
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
{
|
||||
"inherits": ["cortex-m"],
|
||||
"llvm-target": "armv7m-none-eabi",
|
||||
"build-tags": ["nucleof103rb", "stm32f103xx", "stm32"],
|
||||
"build-tags": ["nucleof103rb", "stm32f103", "stm32"],
|
||||
"cflags": [
|
||||
"--target=armv7m-none-eabi",
|
||||
"-Qunused-arguments"
|
||||
],
|
||||
"linkerscript": "targets/stm32f103rb.ld",
|
||||
"extra-files": [
|
||||
"src/device/stm32/stm32f103xx.s"
|
||||
"src/device/stm32/stm32f103.s"
|
||||
],
|
||||
"flash-method": "openocd",
|
||||
"openocd-interface": "stlink-v2-1",
|
||||
|
|
|
@ -60,11 +60,15 @@ type SVDField struct {
|
|||
BitOffset *uint32 `xml:"bitOffset"`
|
||||
BitWidth *uint32 `xml:"bitWidth"`
|
||||
BitRange *string `xml:"bitRange"`
|
||||
EnumeratedValues []struct {
|
||||
Name string `xml:"name"`
|
||||
Description string `xml:"description"`
|
||||
Value string `xml:"value"`
|
||||
} `xml:"enumeratedValues>enumeratedValue"`
|
||||
EnumeratedValues struct {
|
||||
DerivedFrom string `xml:"derivedFrom,attr"`
|
||||
Name string `xml:"name"`
|
||||
EnumeratedValue []struct {
|
||||
Name string `xml:"name"`
|
||||
Description string `xml:"description"`
|
||||
Value string `xml:"value"`
|
||||
} `xml:"enumeratedValue"`
|
||||
} `xml:"enumeratedValues"`
|
||||
}
|
||||
|
||||
type SVDCluster struct {
|
||||
|
@ -444,7 +448,7 @@ func addInterrupt(interrupts map[string]*interrupt, name, interruptName string,
|
|||
if interrupts[name].Value != index {
|
||||
// Note: some SVD files like the one for STM32H7x7 contain mistakes.
|
||||
// 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)
|
||||
}
|
||||
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 {
|
||||
var fields []Bitfield
|
||||
enumSeen := map[string]bool{}
|
||||
enumSeen := map[string]int64{}
|
||||
for _, fieldEl := range fieldEls {
|
||||
// Some bitfields (like the STM32H7x7) contain invalid bitfield
|
||||
// names like "CNT[31]". Replace invalid characters with "_" when
|
||||
|
@ -511,6 +515,32 @@ func parseBitfields(groupName, regName string, fieldEls []*SVDField, bitfieldPre
|
|||
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{
|
||||
name: fmt.Sprintf("%s_%s%s_%s_Pos", groupName, bitfieldPrefix, regName, fieldName),
|
||||
description: fmt.Sprintf("Position of %s field.", fieldName),
|
||||
|
@ -528,7 +558,7 @@ func parseBitfields(groupName, regName string, fieldEls []*SVDField, bitfieldPre
|
|||
value: 1 << lsb,
|
||||
})
|
||||
}
|
||||
for _, enumEl := range fieldEl.EnumeratedValues {
|
||||
for _, enumEl := range enumeratedValues.EnumeratedValue {
|
||||
enumName := enumEl.Name
|
||||
if strings.EqualFold(enumName, "reserved") || !validName.MatchString(enumName) {
|
||||
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)
|
||||
_, 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{
|
||||
name: enumName,
|
||||
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
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче