machine/stm32: refactor to use new volatile package for all register access

Signed-off-by: Ron Evans <ron@hybridgroup.com>
Этот коммит содержится в:
Ron Evans 2019-05-19 23:22:23 +02:00 коммит произвёл Ayke
родитель 98a3047b58
коммит e4d53daa02
5 изменённых файлов: 196 добавлений и 195 удалений

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

@ -54,7 +54,7 @@ gen-device-sam:
go fmt ./src/device/sam
gen-device-stm32:
./tools/gen-device-svd.py lib/cmsis-svd/data/STMicro/ src/device/stm32/ --source=https://github.com/posborne/cmsis-svd/tree/master/data/STMicro
./tools/gen-device-svd-vol.py lib/cmsis-svd/data/STMicro/ src/device/stm32/ --source=https://github.com/posborne/cmsis-svd/tree/master/data/STMicro
go fmt ./src/device/stm32

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

@ -55,19 +55,19 @@ func (p GPIO) getPort() *stm32.GPIO_Type {
func (p GPIO) enableClock() {
switch p.Pin / 16 {
case 0:
stm32.RCC.APB2ENR |= stm32.RCC_APB2ENR_IOPAEN
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_IOPAEN)
case 1:
stm32.RCC.APB2ENR |= stm32.RCC_APB2ENR_IOPBEN
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_IOPBEN)
case 2:
stm32.RCC.APB2ENR |= stm32.RCC_APB2ENR_IOPCEN
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_IOPCEN)
case 3:
stm32.RCC.APB2ENR |= stm32.RCC_APB2ENR_IOPDEN
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_IOPDEN)
case 4:
stm32.RCC.APB2ENR |= stm32.RCC_APB2ENR_IOPEEN
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_IOPEEN)
case 5:
stm32.RCC.APB2ENR |= stm32.RCC_APB2ENR_IOPFEN
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_IOPFEN)
case 6:
stm32.RCC.APB2ENR |= stm32.RCC_APB2ENR_IOPGEN
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_IOPGEN)
default:
panic("machine: unknown port")
}
@ -81,9 +81,9 @@ func (p GPIO) Configure(config GPIOConfig) {
pin := p.Pin % 16
pos := p.Pin % 8 * 4
if pin < 8 {
port.CRL = stm32.RegValue((uint32(port.CRL) &^ (0xf << pos)) | (uint32(config.Mode) << pos))
port.CRL.Set((uint32(port.CRL.Get()) &^ (0xf << pos)) | (uint32(config.Mode) << pos))
} else {
port.CRH = stm32.RegValue((uint32(port.CRH) &^ (0xf << pos)) | (uint32(config.Mode) << pos))
port.CRH.Set((uint32(port.CRH.Get()) &^ (0xf << pos)) | (uint32(config.Mode) << pos))
}
}
@ -93,9 +93,9 @@ func (p GPIO) Set(high bool) {
port := p.getPort()
pin := p.Pin % 16
if high {
port.BSRR = 1 << pin
port.BSRR.Set(1 << pin)
} else {
port.BSRR = 1 << (pin + 16)
port.BSRR.Set(1 << (pin + 16))
}
}
@ -122,8 +122,8 @@ func (uart UART) Configure(config UARTConfig) {
switch config.TX {
case PB6:
// use alternate TX/RX pins PB6/PB7 via AFIO mapping
stm32.RCC.APB2ENR |= stm32.RCC_APB2ENR_AFIOEN
stm32.AFIO.MAPR |= stm32.AFIO_MAPR_USART1_REMAP
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_AFIOEN)
stm32.AFIO.MAPR.SetBits(stm32.AFIO_MAPR_USART1_REMAP)
GPIO{PB6}.Configure(GPIOConfig{Mode: GPIO_OUTPUT_50MHz + GPIO_OUTPUT_MODE_ALT_PUSH_PULL})
GPIO{PB7}.Configure(GPIOConfig{Mode: GPIO_INPUT_MODE_FLOATING})
default:
@ -133,13 +133,13 @@ func (uart UART) Configure(config UARTConfig) {
}
// Enable USART1 clock
stm32.RCC.APB2ENR |= stm32.RCC_APB2ENR_USART1EN
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_USART1EN)
// Set baud rate
uart.SetBaudRate(config.BaudRate)
// Enable USART1 port.
stm32.USART1.CR1 = stm32.USART_CR1_TE | stm32.USART_CR1_RE | stm32.USART_CR1_RXNEIE | stm32.USART_CR1_UE
stm32.USART1.CR1.Set(stm32.USART_CR1_TE | stm32.USART_CR1_RE | stm32.USART_CR1_RXNEIE | stm32.USART_CR1_UE)
// Enable RX IRQ.
arm.SetPriority(stm32.IRQ_USART1, 0xc0)
@ -150,21 +150,21 @@ func (uart UART) Configure(config UARTConfig) {
func (uart UART) SetBaudRate(br uint32) {
// first divide by PCLK2 prescaler (div 1) and then desired baudrate
divider := CPU_FREQUENCY / br
stm32.USART1.BRR = stm32.RegValue(divider)
stm32.USART1.BRR.Set(divider)
}
// WriteByte writes a byte of data to the UART.
func (uart UART) WriteByte(c byte) error {
stm32.USART1.DR = stm32.RegValue(c)
stm32.USART1.DR.Set(uint32(c))
for (stm32.USART1.SR & stm32.USART_SR_TXE) == 0 {
for (stm32.USART1.SR.Get() & stm32.USART_SR_TXE) == 0 {
}
return nil
}
//go:export USART1_IRQHandler
func handleUART1() {
UART1.Receive(byte((stm32.USART1.DR & 0xFF)))
UART1.Receive(byte((stm32.USART1.DR.Get() & 0xFF)))
}
// SPI on the STM32.
@ -198,9 +198,9 @@ type SPIConfig struct {
// - hardware SS pin?
func (spi SPI) Configure(config SPIConfig) {
// enable clock for SPI
stm32.RCC.APB2ENR |= stm32.RCC_APB2ENR_SPI1EN
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SPI1EN)
var conf uint16
var conf uint32
// set frequency
switch config.Frequency {
@ -250,34 +250,34 @@ func (spi SPI) Configure(config SPIConfig) {
conf |= stm32.SPI_Mode_Master
// now set the configuration
spi.Bus.CR1 = stm32.RegValue(conf)
spi.Bus.CR1.Set(conf)
// init pins
spi.setPins(config.SCK, config.MOSI, config.MISO)
// enable SPI interface
spi.Bus.CR1 |= stm32.SPI_CR1_SPE
spi.Bus.CR1.SetBits(stm32.SPI_CR1_SPE)
}
// Transfer writes/reads a single byte using the SPI interface.
func (spi SPI) Transfer(w byte) (byte, error) {
// Write data to be transmitted to the SPI data register
spi.Bus.DR = stm32.RegValue(w)
spi.Bus.DR.Set(uint32(w))
// Wait until transmit complete
for (spi.Bus.SR & stm32.SPI_SR_TXE) == 0 {
for (spi.Bus.SR.Get() & stm32.SPI_SR_TXE) == 0 {
}
// Wait until receive complete
for (spi.Bus.SR & stm32.SPI_SR_RXNE) == 0 {
for (spi.Bus.SR.Get() & stm32.SPI_SR_RXNE) == 0 {
}
// Wait until SPI is not busy
for (spi.Bus.SR & stm32.SPI_SR_BSY) > 0 {
for (spi.Bus.SR.Get() & stm32.SPI_SR_BSY) > 0 {
}
// Return received data from SPI data register
return byte(spi.Bus.DR), nil
return byte(spi.Bus.DR.Get()), nil
}
func (spi SPI) setPins(sck, mosi, miso uint8) {
@ -324,15 +324,15 @@ func (i2c I2C) Configure(config I2CConfig) {
}
// enable clock for I2C
stm32.RCC.APB1ENR |= stm32.RCC_APB1ENR_I2C1EN
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_I2C1EN)
// I2C1 pins
switch config.SDA {
case PB9:
config.SCL = PB8
// use alternate I2C1 pins PB8/PB9 via AFIO mapping
stm32.RCC.APB2ENR |= stm32.RCC_APB2ENR_AFIOEN
stm32.AFIO.MAPR |= stm32.AFIO_MAPR_I2C1_REMAP
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_AFIOEN)
stm32.AFIO.MAPR.SetBits(stm32.AFIO_MAPR_I2C1_REMAP)
default:
// use default I2C1 pins PB6/PB7
config.SDA = SDA_PIN
@ -343,7 +343,7 @@ func (i2c I2C) Configure(config I2CConfig) {
GPIO{config.SCL}.Configure(GPIOConfig{Mode: GPIO_OUTPUT_50MHz + GPIO_OUTPUT_MODE_ALT_OPEN_DRAIN})
// Disable the selected I2C peripheral to configure
i2c.Bus.CR1 &^= stm32.I2C_CR1_PE
i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_PE)
// pclk1 clock speed is main frequency divided by PCK1 prescaler (div 2)
pclk1 := uint32(CPU_FREQUENCY / 2)
@ -351,40 +351,40 @@ func (i2c I2C) Configure(config I2CConfig) {
// set freqency range to pclk1 clock speed in Mhz.
// aka setting the value 36 means to use 36MhZ clock.
pclk1Mhz := pclk1 / 1000000
i2c.Bus.CR2 |= stm32.RegValue(pclk1Mhz)
i2c.Bus.CR2.SetBits(pclk1Mhz)
switch config.Frequency {
case TWI_FREQ_100KHZ:
// Normal mode speed calculation
ccr := pclk1 / (config.Frequency * 2)
i2c.Bus.CCR = stm32.RegValue(ccr)
i2c.Bus.CCR.Set(ccr)
// duty cycle 2
i2c.Bus.CCR &^= stm32.I2C_CCR_DUTY
i2c.Bus.CCR.ClearBits(stm32.I2C_CCR_DUTY)
// frequency standard mode
i2c.Bus.CCR &^= stm32.I2C_CCR_F_S
i2c.Bus.CCR.ClearBits(stm32.I2C_CCR_F_S)
// Set Maximum Rise Time for standard mode
i2c.Bus.TRISE = stm32.RegValue(pclk1Mhz)
i2c.Bus.TRISE.Set(pclk1Mhz)
case TWI_FREQ_400KHZ:
// Fast mode speed calculation
ccr := pclk1 / (config.Frequency * 3)
i2c.Bus.CCR = stm32.RegValue(ccr)
i2c.Bus.CCR.Set(ccr)
// duty cycle 2
i2c.Bus.CCR &^= stm32.I2C_CCR_DUTY
i2c.Bus.CCR.ClearBits(stm32.I2C_CCR_DUTY)
// frequency fast mode
i2c.Bus.CCR |= stm32.I2C_CCR_F_S
i2c.Bus.CCR.SetBits(stm32.I2C_CCR_F_S)
// Set Maximum Rise Time for fast mode
i2c.Bus.TRISE = stm32.RegValue(((pclk1Mhz * 300) / 1000))
i2c.Bus.TRISE.Set(((pclk1Mhz * 300) / 1000))
}
// re-enable the selected I2C peripheral
i2c.Bus.CR1 |= stm32.I2C_CR1_PE
i2c.Bus.CR1.SetBits(stm32.I2C_CR1_PE)
}
// Tx does a single I2C transaction at the specified address.
@ -435,11 +435,11 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
}
// Disable ACK of received data
i2c.Bus.CR1 &^= stm32.I2C_CR1_ACK
i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_ACK)
// clear timeout here
timeout := i2cTimeout
for i2c.Bus.SR2&(stm32.I2C_SR2_MSL|stm32.I2C_SR2_BUSY) == 0 {
for i2c.Bus.SR2.Get()&(stm32.I2C_SR2_MSL|stm32.I2C_SR2_BUSY) == 0 {
timeout--
if timeout == 0 {
return errors.New("I2C timeout on read clear address")
@ -447,10 +447,10 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
}
// Generate stop condition
i2c.Bus.CR1 |= stm32.I2C_CR1_STOP
i2c.Bus.CR1.SetBits(stm32.I2C_CR1_STOP)
timeout = i2cTimeout
for (i2c.Bus.SR1 & stm32.I2C_SR1_RxNE) == 0 {
for (i2c.Bus.SR1.Get() & stm32.I2C_SR1_RxNE) == 0 {
timeout--
if timeout == 0 {
return errors.New("I2C timeout on read 1 byte")
@ -458,17 +458,17 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
}
// Read and return data byte from I2C data register
r[0] = byte(i2c.Bus.DR)
r[0] = byte(i2c.Bus.DR.Get())
// wait for stop
return i2c.waitForStop()
case 2:
// enable pos
i2c.Bus.CR1 |= stm32.I2C_CR1_POS
i2c.Bus.CR1.SetBits(stm32.I2C_CR1_POS)
// Enable ACK of received data
i2c.Bus.CR1 |= stm32.I2C_CR1_ACK
i2c.Bus.CR1.SetBits(stm32.I2C_CR1_ACK)
// send address
err = i2c.sendAddress(uint8(addr), false)
@ -478,7 +478,7 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
// clear address here
timeout := i2cTimeout
for i2c.Bus.SR2&(stm32.I2C_SR2_MSL|stm32.I2C_SR2_BUSY) == 0 {
for i2c.Bus.SR2.Get()&(stm32.I2C_SR2_MSL|stm32.I2C_SR2_BUSY) == 0 {
timeout--
if timeout == 0 {
return errors.New("I2C timeout on read clear address")
@ -486,11 +486,11 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
}
// Disable ACK of received data
i2c.Bus.CR1 &^= stm32.I2C_CR1_ACK
i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_ACK)
// wait for btf. we need a longer timeout here than normal.
timeout = 1000
for (i2c.Bus.SR1 & stm32.I2C_SR1_BTF) == 0 {
for (i2c.Bus.SR1.Get() & stm32.I2C_SR1_BTF) == 0 {
timeout--
if timeout == 0 {
return errors.New("I2C timeout on read 2 bytes")
@ -498,18 +498,18 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
}
// Generate stop condition
i2c.Bus.CR1 |= stm32.I2C_CR1_STOP
i2c.Bus.CR1.SetBits(stm32.I2C_CR1_STOP)
// read the 2 bytes by reading twice.
r[0] = byte(i2c.Bus.DR)
r[1] = byte(i2c.Bus.DR)
r[0] = byte(i2c.Bus.DR.Get())
r[1] = byte(i2c.Bus.DR.Get())
// wait for stop
return i2c.waitForStop()
case 3:
// Enable ACK of received data
i2c.Bus.CR1 |= stm32.I2C_CR1_ACK
i2c.Bus.CR1.SetBits(stm32.I2C_CR1_ACK)
// send address
err = i2c.sendAddress(uint8(addr), false)
@ -519,7 +519,7 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
// clear address here
timeout := i2cTimeout
for i2c.Bus.SR2&(stm32.I2C_SR2_MSL|stm32.I2C_SR2_BUSY) == 0 {
for i2c.Bus.SR2.Get()&(stm32.I2C_SR2_MSL|stm32.I2C_SR2_BUSY) == 0 {
timeout--
if timeout == 0 {
return errors.New("I2C timeout on read clear address")
@ -527,11 +527,11 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
}
// Enable ACK of received data
i2c.Bus.CR1 |= stm32.I2C_CR1_ACK
i2c.Bus.CR1.SetBits(stm32.I2C_CR1_ACK)
// wait for btf. we need a longer timeout here than normal.
timeout = 1000
for (i2c.Bus.SR1 & stm32.I2C_SR1_BTF) == 0 {
for (i2c.Bus.SR1.Get() & stm32.I2C_SR1_BTF) == 0 {
timeout--
if timeout == 0 {
println("I2C timeout on read 3 bytes")
@ -540,13 +540,13 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
}
// Disable ACK of received data
i2c.Bus.CR1 &^= stm32.I2C_CR1_ACK
i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_ACK)
// read the first byte
r[0] = byte(i2c.Bus.DR)
r[0] = byte(i2c.Bus.DR.Get())
timeout = 1000
for (i2c.Bus.SR1 & stm32.I2C_SR1_BTF) == 0 {
for (i2c.Bus.SR1.Get() & stm32.I2C_SR1_BTF) == 0 {
timeout--
if timeout == 0 {
return errors.New("I2C timeout on read 3 bytes")
@ -554,11 +554,11 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
}
// Generate stop condition
i2c.Bus.CR1 |= stm32.I2C_CR1_STOP
i2c.Bus.CR1.SetBits(stm32.I2C_CR1_STOP)
// read the last 2 bytes by reading twice.
r[1] = byte(i2c.Bus.DR)
r[2] = byte(i2c.Bus.DR)
r[1] = byte(i2c.Bus.DR.Get())
r[2] = byte(i2c.Bus.DR.Get())
// wait for stop
return i2c.waitForStop()
@ -574,7 +574,7 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
// clear address here
timeout := i2cTimeout
for i2c.Bus.SR2&(stm32.I2C_SR2_MSL|stm32.I2C_SR2_BUSY) == 0 {
for i2c.Bus.SR2.Get()&(stm32.I2C_SR2_MSL|stm32.I2C_SR2_BUSY) == 0 {
timeout--
if timeout == 0 {
return errors.New("I2C timeout on read clear address")
@ -583,11 +583,11 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
for i := 0; i < len(r)-3; i++ {
// Enable ACK of received data
i2c.Bus.CR1 |= stm32.I2C_CR1_ACK
i2c.Bus.CR1.SetBits(stm32.I2C_CR1_ACK)
// wait for btf. we need a longer timeout here than normal.
timeout = 1000
for (i2c.Bus.SR1 & stm32.I2C_SR1_BTF) == 0 {
for (i2c.Bus.SR1.Get() & stm32.I2C_SR1_BTF) == 0 {
timeout--
if timeout == 0 {
println("I2C timeout on read 3 bytes")
@ -596,12 +596,12 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
}
// read the next byte
r[i] = byte(i2c.Bus.DR)
r[i] = byte(i2c.Bus.DR.Get())
}
// wait for btf. we need a longer timeout here than normal.
timeout = 1000
for (i2c.Bus.SR1 & stm32.I2C_SR1_BTF) == 0 {
for (i2c.Bus.SR1.Get() & stm32.I2C_SR1_BTF) == 0 {
timeout--
if timeout == 0 {
return errors.New("I2C timeout on read more than 3 bytes")
@ -609,19 +609,19 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
}
// Disable ACK of received data
i2c.Bus.CR1 &^= stm32.I2C_CR1_ACK
i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_ACK)
// get third from last byte
r[len(r)-3] = byte(i2c.Bus.DR)
r[len(r)-3] = byte(i2c.Bus.DR.Get())
// Generate stop condition
i2c.Bus.CR1 |= stm32.I2C_CR1_STOP
i2c.Bus.CR1.SetBits(stm32.I2C_CR1_STOP)
// get second from last byte
r[len(r)-2] = byte(i2c.Bus.DR)
r[len(r)-2] = byte(i2c.Bus.DR.Get())
timeout = i2cTimeout
for (i2c.Bus.SR1 & stm32.I2C_SR1_RxNE) == 0 {
for (i2c.Bus.SR1.Get() & stm32.I2C_SR1_RxNE) == 0 {
timeout--
if timeout == 0 {
return errors.New("I2C timeout on read last byte of more than 3")
@ -629,7 +629,7 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
}
// get last byte
r[len(r)-1] = byte(i2c.Bus.DR)
r[len(r)-1] = byte(i2c.Bus.DR.Get())
// wait for stop
return i2c.waitForStop()
@ -645,7 +645,7 @@ const i2cTimeout = 500
func (i2c I2C) signalStart() error {
// Wait until I2C is not busy
timeout := i2cTimeout
for (i2c.Bus.SR2 & stm32.I2C_SR2_BUSY) > 0 {
for (i2c.Bus.SR2.Get() & stm32.I2C_SR2_BUSY) > 0 {
timeout--
if timeout == 0 {
return errors.New("I2C busy on start")
@ -653,14 +653,14 @@ func (i2c I2C) signalStart() error {
}
// clear stop
i2c.Bus.CR1 &^= stm32.I2C_CR1_STOP
i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_STOP)
// Generate start condition
i2c.Bus.CR1 |= stm32.I2C_CR1_START
i2c.Bus.CR1.SetBits(stm32.I2C_CR1_START)
// Wait for I2C EV5 aka SB flag.
timeout = i2cTimeout
for (i2c.Bus.SR1 & stm32.I2C_SR1_SB) == 0 {
for (i2c.Bus.SR1.Get() & stm32.I2C_SR1_SB) == 0 {
timeout--
if timeout == 0 {
return errors.New("I2C timeout on start")
@ -673,7 +673,7 @@ func (i2c I2C) signalStart() error {
// signalStop sends a stop signal and waits for it to succeed.
func (i2c I2C) signalStop() error {
// Generate stop condition
i2c.Bus.CR1 |= stm32.I2C_CR1_STOP
i2c.Bus.CR1.SetBits(stm32.I2C_CR1_STOP)
// wait for stop
return i2c.waitForStop()
@ -683,7 +683,7 @@ func (i2c I2C) signalStop() error {
func (i2c I2C) waitForStop() error {
// Wait until I2C is stopped
timeout := i2cTimeout
for (i2c.Bus.SR1 & stm32.I2C_SR1_STOPF) > 0 {
for (i2c.Bus.SR1.Get() & stm32.I2C_SR1_STOPF) > 0 {
timeout--
if timeout == 0 {
println("I2C timeout on wait for stop signal")
@ -701,14 +701,14 @@ func (i2c I2C) sendAddress(address uint8, write bool) error {
data |= 1 // set read flag
}
i2c.Bus.DR = stm32.RegValue(data)
i2c.Bus.DR.Set(uint32(data))
// Wait for I2C EV6 event.
// Destination device acknowledges address
timeout := i2cTimeout
if write {
// EV6 which is ADDR flag.
for i2c.Bus.SR1&stm32.I2C_SR1_ADDR == 0 {
for i2c.Bus.SR1.Get()&stm32.I2C_SR1_ADDR == 0 {
timeout--
if timeout == 0 {
return errors.New("I2C timeout on send write address")
@ -716,7 +716,7 @@ func (i2c I2C) sendAddress(address uint8, write bool) error {
}
timeout = i2cTimeout
for i2c.Bus.SR2&(stm32.I2C_SR2_MSL|stm32.I2C_SR2_BUSY|stm32.I2C_SR2_TRA) == 0 {
for i2c.Bus.SR2.Get()&(stm32.I2C_SR2_MSL|stm32.I2C_SR2_BUSY|stm32.I2C_SR2_TRA) == 0 {
timeout--
if timeout == 0 {
return errors.New("I2C timeout on send write address")
@ -724,7 +724,7 @@ func (i2c I2C) sendAddress(address uint8, write bool) error {
}
} else {
// I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED which is ADDR flag.
for (i2c.Bus.SR1 & stm32.I2C_SR1_ADDR) == 0 {
for (i2c.Bus.SR1.Get() & stm32.I2C_SR1_ADDR) == 0 {
timeout--
if timeout == 0 {
return errors.New("I2C timeout on send read address")
@ -738,13 +738,13 @@ func (i2c I2C) sendAddress(address uint8, write bool) error {
// WriteByte writes a single byte to the I2C bus.
func (i2c I2C) WriteByte(data byte) error {
// Send data byte
i2c.Bus.DR = stm32.RegValue(data)
i2c.Bus.DR.Set(uint32(data))
// Wait for I2C EV8_2 when data has been physically shifted out and
// output on the bus.
// I2C_EVENT_MASTER_BYTE_TRANSMITTED is TXE flag.
timeout := i2cTimeout
for i2c.Bus.SR1&stm32.I2C_SR1_TxE == 0 {
for i2c.Bus.SR1.Get()&stm32.I2C_SR1_TxE == 0 {
timeout--
if timeout == 0 {
return errors.New("I2C timeout on write")

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

@ -74,23 +74,23 @@ func (p GPIO) getPort() *stm32.GPIO_Type {
func (p GPIO) enableClock() {
switch p.Pin / 16 {
case 0:
stm32.RCC.AHB1ENR |= stm32.RCC_AHB1ENR_GPIOAEN
stm32.RCC.AHB1ENR.SetBits(stm32.RCC_AHB1ENR_GPIOAEN)
case 1:
stm32.RCC.AHB1ENR |= stm32.RCC_AHB1ENR_GPIOBEN
stm32.RCC.AHB1ENR.SetBits(stm32.RCC_AHB1ENR_GPIOBEN)
case 2:
stm32.RCC.AHB1ENR |= stm32.RCC_AHB1ENR_GPIOCEN
stm32.RCC.AHB1ENR.SetBits(stm32.RCC_AHB1ENR_GPIOCEN)
case 3:
stm32.RCC.AHB1ENR |= stm32.RCC_AHB1ENR_GPIODEN
stm32.RCC.AHB1ENR.SetBits(stm32.RCC_AHB1ENR_GPIODEN)
case 4:
stm32.RCC.AHB1ENR |= stm32.RCC_AHB1ENR_GPIOEEN
stm32.RCC.AHB1ENR.SetBits(stm32.RCC_AHB1ENR_GPIOEEN)
case 5:
stm32.RCC.AHB1ENR |= stm32.RCC_AHB1ENR_GPIOFEN
stm32.RCC.AHB1ENR.SetBits(stm32.RCC_AHB1ENR_GPIOFEN)
case 6:
stm32.RCC.AHB1ENR |= stm32.RCC_AHB1ENR_GPIOGEN
stm32.RCC.AHB1ENR.SetBits(stm32.RCC_AHB1ENR_GPIOGEN)
case 7:
stm32.RCC.AHB1ENR |= stm32.RCC_AHB1ENR_GPIOHEN
stm32.RCC.AHB1ENR.SetBits(stm32.RCC_AHB1ENR_GPIOHEN)
case 8:
stm32.RCC.AHB1ENR |= stm32.RCC_AHB1ENR_GPIOIEN
stm32.RCC.AHB1ENR.SetBits(stm32.RCC_AHB1ENR_GPIOIEN)
default:
panic("machine: unknown port")
}
@ -105,25 +105,25 @@ func (p GPIO) Configure(config GPIOConfig) {
pos := pin * 2
if config.Mode == GPIO_INPUT_FLOATING {
port.MODER = stm32.RegValue((uint32(port.MODER)&^(0x3<<pos) | (uint32(GPIO_MODE_INPUT) << pos)))
port.PUPDR = stm32.RegValue((uint32(port.PUPDR)&^(0x3<<pos) | (uint32(GPIO_FLOATING) << pos)))
port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_INPUT) << pos)))
port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_FLOATING) << pos)))
} else if config.Mode == GPIO_INPUT_PULLDOWN {
port.MODER = stm32.RegValue((uint32(port.MODER)&^(0x3<<pos) | (uint32(GPIO_MODE_INPUT) << pos)))
port.PUPDR = stm32.RegValue((uint32(port.PUPDR)&^(0x3<<pos) | (uint32(GPIO_PULL_DOWN) << pos)))
port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_INPUT) << pos)))
port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_PULL_DOWN) << pos)))
} else if config.Mode == GPIO_INPUT_PULLUP {
port.MODER = stm32.RegValue((uint32(port.MODER)&^(0x3<<pos) | (uint32(GPIO_MODE_INPUT) << pos)))
port.PUPDR = stm32.RegValue((uint32(port.PUPDR)&^(0x3<<pos) | (uint32(GPIO_PULL_UP) << pos)))
port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_INPUT) << pos)))
port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_PULL_UP) << pos)))
} else if config.Mode == GPIO_OUTPUT {
port.MODER = stm32.RegValue((uint32(port.MODER)&^(0x3<<pos) | (uint32(GPIO_MODE_GENERAL_OUTPUT) << pos)))
port.OSPEEDR = stm32.RegValue((uint32(port.OSPEEDR)&^(0x3<<pos) | (uint32(GPIO_SPEED_HI) << pos)))
port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_GENERAL_OUTPUT) << pos)))
port.OSPEEDR.Set((uint32(port.OSPEEDR.Get())&^(0x3<<pos) | (uint32(GPIO_SPEED_HI) << pos)))
} else if config.Mode == GPIO_UART_TX {
port.MODER = stm32.RegValue((uint32(port.MODER)&^(0x3<<pos) | (uint32(GPIO_MODE_ALTERNABTIVE) << pos)))
port.OSPEEDR = stm32.RegValue((uint32(port.OSPEEDR)&^(0x3<<pos) | (uint32(GPIO_SPEED_HI) << pos)))
port.PUPDR = stm32.RegValue((uint32(port.PUPDR)&^(0x3<<pos) | (uint32(GPIO_PULL_UP) << pos)))
port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_ALTERNABTIVE) << pos)))
port.OSPEEDR.Set((uint32(port.OSPEEDR.Get())&^(0x3<<pos) | (uint32(GPIO_SPEED_HI) << pos)))
port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_PULL_UP) << pos)))
p.setAltFunc(0x7)
} else if config.Mode == GPIO_UART_RX {
port.MODER = stm32.RegValue((uint32(port.MODER)&^(0x3<<pos) | (uint32(GPIO_MODE_ALTERNABTIVE) << pos)))
port.PUPDR = stm32.RegValue((uint32(port.PUPDR)&^(0x3<<pos) | (uint32(GPIO_FLOATING) << pos)))
port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_ALTERNABTIVE) << pos)))
port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_FLOATING) << pos)))
p.setAltFunc(0x7)
}
}
@ -133,9 +133,9 @@ func (p GPIO) setAltFunc(af uint32) {
pin := p.Pin % 16
pos := pin * 4
if pin >= 8 {
port.AFRH = stm32.RegValue(uint32(port.AFRH)&^(0xF<<pos) | ((af & 0xF) << pos))
port.AFRH.Set(uint32(port.AFRH.Get())&^(0xF<<pos) | ((af & 0xF) << pos))
} else {
port.AFRL = stm32.RegValue(uint32(port.AFRL)&^(0xF<<pos) | ((af & 0xF) << pos))
port.AFRL.Set(uint32(port.AFRL.Get())&^(0xF<<pos) | ((af & 0xF) << pos))
}
}
@ -145,9 +145,9 @@ func (p GPIO) Set(high bool) {
port := p.getPort()
pin := p.Pin % 16
if high {
port.BSRR = 1 << pin
port.BSRR.Set(1 << pin)
} else {
port.BSRR = 1 << (pin + 16)
port.BSRR.Set(1 << (pin + 16))
}
}
@ -178,7 +178,7 @@ func (uart UART) Configure(config UARTConfig) {
}
// Enable USART2 clock
stm32.RCC.APB1ENR |= stm32.RCC_APB1ENR_USART2EN
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART2EN)
/*
Set baud rate(115200)
@ -195,10 +195,10 @@ func (uart UART) Configure(config UARTConfig) {
| 115200 | 0x16D |
+----------+--------+
*/
stm32.USART2.BRR = 0x16c
stm32.USART2.BRR.Set(0x16c)
// Enable USART2 port.
stm32.USART2.CR1 = stm32.USART_CR1_TE | stm32.USART_CR1_RE | stm32.USART_CR1_RXNEIE | stm32.USART_CR1_UE
stm32.USART2.CR1.Set(stm32.USART_CR1_TE | stm32.USART_CR1_RE | stm32.USART_CR1_RXNEIE | stm32.USART_CR1_UE)
// Enable RX IRQ.
arm.SetPriority(stm32.IRQ_USART2, 0xc0)
@ -207,14 +207,14 @@ func (uart UART) Configure(config UARTConfig) {
// WriteByte writes a byte of data to the UART.
func (uart UART) WriteByte(c byte) error {
stm32.USART2.DR = stm32.RegValue(c)
stm32.USART2.DR.Set(uint32(c))
for (stm32.USART2.SR & stm32.USART_SR_TXE) == 0 {
for (stm32.USART2.SR.Get() & stm32.USART_SR_TXE) == 0 {
}
return nil
}
//go:export USART2_IRQHandler
func handleUSART2() {
UART1.Receive(byte((stm32.USART2.DR & 0xFF)))
UART1.Receive(byte((stm32.USART2.DR.Get() & 0xFF)))
}

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

@ -21,33 +21,33 @@ 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 |= stm32.FLASH_ACR_LATENCY_2 // Two wait states, per datasheet
stm32.RCC.CFGR |= stm32.RCC_CFGR_PPRE1_DIV_2 // prescale PCLK1 = HCLK/2
stm32.RCC.CFGR |= stm32.RCC_CFGR_PPRE2_DIV_NONE // prescale PCLK2 = HCLK/1
stm32.RCC.CR |= stm32.RCC_CR_HSEON // enable HSE clock
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
// wait for the HSEREADY flag
for (stm32.RCC.CR & stm32.RCC_CR_HSERDY) == 0 {
for (stm32.RCC.CR.Get() & stm32.RCC_CR_HSERDY) == 0 {
}
stm32.RCC.CR |= stm32.RCC_CR_HSION // enable HSI clock
stm32.RCC.CR.SetBits(stm32.RCC_CR_HSION) // enable HSI clock
// wait for the HSIREADY flag
for (stm32.RCC.CR & stm32.RCC_CR_HSIRDY) == 0 {
for (stm32.RCC.CR.Get() & stm32.RCC_CR_HSIRDY) == 0 {
}
stm32.RCC.CFGR |= stm32.RCC_CFGR_PLLSRC // set PLL source to HSE
stm32.RCC.CFGR |= stm32.RCC_CFGR_PLLMUL_9 // multiply by 9
stm32.RCC.CR |= 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_9) // multiply by 9
stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON) // enable the PLL
// wait for the PLLRDY flag
for (stm32.RCC.CR & stm32.RCC_CR_PLLRDY) == 0 {
for (stm32.RCC.CR.Get() & stm32.RCC_CR_PLLRDY) == 0 {
}
stm32.RCC.CFGR |= 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
for (stm32.RCC.CFGR & stm32.RCC_CFGR_SWS_PLL) == 0 {
for (stm32.RCC.CFGR.Get() & stm32.RCC_CFGR_SWS_PLL) == 0 {
}
}
@ -65,43 +65,43 @@ var timerWakeup isrFlag
func initRTC() {
// Enable the PWR and BKP.
stm32.RCC.APB1ENR |= stm32.RCC_APB1ENR_PWREN | stm32.RCC_APB1ENR_BKPEN
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_PWREN | stm32.RCC_APB1ENR_BKPEN)
// access to backup register
stm32.PWR.CR |= stm32.PWR_CR_DBP
stm32.PWR.CR.SetBits(stm32.PWR_CR_DBP)
// Enable LSE
stm32.RCC.BDCR |= stm32.RCC_BDCR_LSEON
stm32.RCC.BDCR.SetBits(stm32.RCC_BDCR_LSEON)
// wait until LSE is ready
for stm32.RCC.BDCR&stm32.RCC_BDCR_LSERDY == 0 {
for stm32.RCC.BDCR.Get()&stm32.RCC_BDCR_LSERDY == 0 {
}
// Select LSE
stm32.RCC.BDCR |= stm32.RCC_RTCCLKSource_LSE
stm32.RCC.BDCR.SetBits(stm32.RCC_RTCCLKSource_LSE)
// set prescaler to "max" per datasheet
stm32.RTC.PRLH = stm32.RTC_PRLH_PRLH_Msk
stm32.RTC.PRLL = stm32.RTC_PRLL_PRLL_Msk
stm32.RTC.PRLH.Set(stm32.RTC_PRLH_PRLH_Msk)
stm32.RTC.PRLL.Set(stm32.RTC_PRLL_PRLL_Msk)
// set count to zero
stm32.RTC.CNTH = 0x0
stm32.RTC.CNTL = 0x0
stm32.RTC.CNTH.Set(0x0)
stm32.RTC.CNTL.Set(0x0)
// Enable RTC
stm32.RCC.BDCR |= stm32.RCC_BDCR_RTCEN
stm32.RCC.BDCR.SetBits(stm32.RCC_BDCR_RTCEN)
// Clear RSF
stm32.RTC.CRL &^= stm32.RTC_CRL_RSF
stm32.RTC.CRL.ClearBits(stm32.RTC_CRL_RSF)
// Wait till flag is set
for stm32.RTC.CRL&stm32.RTC_CRL_RSF == 0 {
for stm32.RTC.CRL.Get()&stm32.RTC_CRL_RSF == 0 {
}
}
// Enable the TIM3 clock.
func initTIM() {
stm32.RCC.APB1ENR |= stm32.RCC_APB1ENR_TIM3EN
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM3EN)
arm.SetPriority(stm32.IRQ_TIM3, 0xc3)
arm.EnableIRQ(stm32.IRQ_TIM3)
@ -122,10 +122,10 @@ func sleepTicks(d timeUnit) {
// number of ticks (microseconds) since start.
func ticks() timeUnit {
// convert RTC counter from seconds to microseconds
timerCounter := uint64(stm32.RTC.CNTH<<16|stm32.RTC.CNTL) * 1000 * 1000
timerCounter := uint64(stm32.RTC.CNTH.Get()<<16|stm32.RTC.CNTL.Get()) * 1000 * 1000
// add the fractional part of current time using DIV register
timerCounter += uint64(0x8000-stm32.RTC.DIVL) * 31
timerCounter += uint64(0x8000-stm32.RTC.DIVL.Get()) * 31
// change since last measurement
offset := (timerCounter - timerLastCounter)
@ -165,16 +165,16 @@ func timerSleep(ticks uint32) {
// The current scaling only supports a range of 100 usec to 6553 msec.
// prescale counter down from 72mhz to 10khz aka 0.1 ms frequency.
stm32.TIM3.PSC = machine.CPU_FREQUENCY/10000 - 1 // 7199
stm32.TIM3.PSC.Set(machine.CPU_FREQUENCY/10000 - 1) // 7199
// set duty aka duration
stm32.TIM3.ARR = stm32.RegValue(ticks/100) - 1 // convert from microseconds to 0.1 ms
stm32.TIM3.ARR.Set(ticks/100 - 1) // convert from microseconds to 0.1 ms
// Enable the hardware interrupt.
stm32.TIM3.DIER |= stm32.TIM_DIER_UIE
stm32.TIM3.DIER.SetBits(stm32.TIM_DIER_UIE)
// Enable the timer.
stm32.TIM3.CR1 |= stm32.TIM_CR1_CEN
stm32.TIM3.CR1.SetBits(stm32.TIM_CR1_CEN)
// wait till timer wakes up
for !timerWakeup {
@ -184,12 +184,12 @@ func timerSleep(ticks uint32) {
//go:export TIM3_IRQHandler
func handleTIM3() {
if (stm32.TIM3.SR & stm32.TIM_SR_UIF) > 0 {
if (stm32.TIM3.SR.Get() & stm32.TIM_SR_UIF) > 0 {
// Disable the timer.
stm32.TIM3.CR1 &^= stm32.TIM_CR1_CEN
stm32.TIM3.CR1.ClearBits(stm32.TIM_CR1_CEN)
// clear the update flag
stm32.TIM3.SR &^= stm32.TIM_SR_UIF
stm32.TIM3.SR.ClearBits(stm32.TIM_SR_UIF)
// timer was triggered
timerWakeup = true

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

@ -42,58 +42,59 @@ func initCLK() {
// Reset clock registers
// Set HSION
stm32.RCC.CR |= stm32.RCC_CR_HSION
for (stm32.RCC.CR & stm32.RCC_CR_HSIRDY) == 0 {
stm32.RCC.CR.SetBits(stm32.RCC_CR_HSION)
for (stm32.RCC.CR.Get() & stm32.RCC_CR_HSIRDY) == 0 {
}
// Reset CFGR
stm32.RCC.CFGR = 0x00000000
stm32.RCC.CFGR.Set(0x00000000)
// Reset HSEON, CSSON and PLLON
stm32.RCC.CR &= 0xFEF6FFFF
stm32.RCC.CR.ClearBits(stm32.RCC_CR_HSEON | stm32.RCC_CR_CSSON | stm32.RCC_CR_PLLON)
// Reset PLLCFGR
stm32.RCC.PLLCFGR = 0x24003010
stm32.RCC.PLLCFGR.Set(0x24003010)
// Reset HSEBYP
stm32.RCC.CR &= 0xFFFBFFFF
stm32.RCC.CR.ClearBits(stm32.RCC_CR_HSEBYP)
// Disable all interrupts
stm32.RCC.CIR = 0x00000000
stm32.RCC.CIR.Set(0x00000000)
// Set up the clock
var startupCounter uint32 = 0
// Enable HSE
stm32.RCC.CR = stm32.RCC_CR_HSEON
stm32.RCC.CR.Set(stm32.RCC_CR_HSEON)
// Wait till HSE is ready and if timeout is reached exit
for {
startupCounter++
if (stm32.RCC.CR&stm32.RCC_CR_HSERDY != 0) || (startupCounter == HSE_STARTUP_TIMEOUT) {
if (stm32.RCC.CR.Get()&stm32.RCC_CR_HSERDY != 0) || (startupCounter == HSE_STARTUP_TIMEOUT) {
break
}
}
if (stm32.RCC.CR & stm32.RCC_CR_HSERDY) != 0 {
if (stm32.RCC.CR.Get() & stm32.RCC_CR_HSERDY) != 0 {
// Enable high performance mode, System frequency up to 168MHz
stm32.RCC.APB1ENR |= stm32.RCC_APB1ENR_PWREN
stm32.PWR.CR |= 0x4000 // PWR_CR_VOS
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_PWREN)
stm32.PWR.CR.SetBits(0x4000) // PWR_CR_VOS
// HCLK = SYSCLK / 1
stm32.RCC.CFGR |= (0x0 << stm32.RCC_CFGR_HPRE_Pos)
stm32.RCC.CFGR.SetBits(0x0 << stm32.RCC_CFGR_HPRE_Pos)
// PCLK2 = HCLK / 2
stm32.RCC.CFGR |= (0x4 << stm32.RCC_CFGR_PPRE2_Pos)
stm32.RCC.CFGR.SetBits(0x4 << stm32.RCC_CFGR_PPRE2_Pos)
// PCLK1 = HCLK / 4
stm32.RCC.CFGR |= (0x5 << stm32.RCC_CFGR_PPRE1_Pos)
stm32.RCC.CFGR.SetBits(0x5 << stm32.RCC_CFGR_PPRE1_Pos)
// Configure the main PLL
// PLL Options - See RM0090 Reference Manual pg. 95
stm32.RCC.PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) - 1) << 16) |
(1 << stm32.RCC_PLLCFGR_PLLSRC_Pos) | (PLL_Q << 24)
stm32.RCC.PLLCFGR.Set(PLL_M | (PLL_N << 6) | (((PLL_P >> 1) - 1) << 16) |
(1 << stm32.RCC_PLLCFGR_PLLSRC_Pos) | (PLL_Q << 24))
// Enable main PLL
stm32.RCC.CR |= stm32.RCC_CR_PLLON
stm32.RCC.CR.SetBits(stm32.RCC_CR_PLLON)
// Wait till the main PLL is ready
for (stm32.RCC.CR & stm32.RCC_CR_PLLRDY) == 0 {
for (stm32.RCC.CR.Get() & stm32.RCC_CR_PLLRDY) == 0 {
}
// Configure Flash prefetch, Instruction cache, Data cache and wait state
stm32.FLASH.ACR = 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
stm32.RCC.CFGR &^= stm32.RCC_CFGR_SW0 | stm32.RCC_CFGR_SW1
stm32.RCC.CFGR |= (0x2 << stm32.RCC_CFGR_SW0_Pos)
for (stm32.RCC.CFGR & (0x3 << stm32.RCC_CFGR_SWS0_Pos)) != (0x2 << stm32.RCC_CFGR_SWS0_Pos) {
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) {
}
} else {
@ -102,7 +103,7 @@ func initCLK() {
}
}
// Enable the CCM RAM clock
stm32.RCC.AHB1ENR |= (1 << 20)
stm32.RCC.AHB1ENR.SetBits(1 << 20)
}
@ -120,7 +121,7 @@ var timerWakeup isrFlag
// Enable the TIM3 clock.(sleep count)
func initTIM3() {
stm32.RCC.APB1ENR |= stm32.RCC_APB1ENR_TIM3EN
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM3EN)
arm.SetPriority(stm32.IRQ_TIM3, 0xc3)
arm.EnableIRQ(stm32.IRQ_TIM3)
@ -128,17 +129,17 @@ func initTIM3() {
// Enable the TIM7 clock.(tick count)
func initTIM7() {
stm32.RCC.APB1ENR |= stm32.RCC_APB1ENR_TIM7EN
stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM7EN)
// CK_INT = APB1 x2 = 84mhz
stm32.TIM7.PSC = 84000000/10000 - 1 // 84mhz to 10khz(0.1ms)
stm32.TIM7.ARR = stm32.RegValue(10) - 1 // interrupt per 1ms
stm32.TIM7.PSC.Set(84000000/10000 - 1) // 84mhz to 10khz(0.1ms)
stm32.TIM7.ARR.Set(10 - 1) // interrupt per 1ms
// Enable the hardware interrupt.
stm32.TIM7.DIER |= stm32.TIM_DIER_UIE
stm32.TIM7.DIER.SetBits(stm32.TIM_DIER_UIE)
// Enable the timer.
stm32.TIM7.CR1 |= stm32.TIM_CR1_CEN
stm32.TIM7.CR1.SetBits(stm32.TIM_CR1_CEN)
arm.SetPriority(stm32.IRQ_TIM7, 0xc1)
arm.EnableIRQ(stm32.IRQ_TIM7)
@ -163,20 +164,20 @@ func timerSleep(ticks uint32) {
// CK_INT = APB1 x2 = 84mhz
// prescale counter down from 84mhz to 10khz aka 0.1 ms frequency.
stm32.TIM3.PSC = 84000000/10000 - 1 // 8399
stm32.TIM3.PSC.Set(84000000/10000 - 1) // 8399
// set duty aka duration
arr := (ticks / 100) - 1 // convert from microseconds to 0.1 ms
if arr == 0 {
arr = 1 // avoid blocking
}
stm32.TIM3.ARR = stm32.RegValue(arr)
stm32.TIM3.ARR.Set(arr)
// Enable the hardware interrupt.
stm32.TIM3.DIER |= stm32.TIM_DIER_UIE
stm32.TIM3.DIER.SetBits(stm32.TIM_DIER_UIE)
// Enable the timer.
stm32.TIM3.CR1 |= stm32.TIM_CR1_CEN
stm32.TIM3.CR1.SetBits(stm32.TIM_CR1_CEN)
// wait till timer wakes up
for !timerWakeup {
@ -186,12 +187,12 @@ func timerSleep(ticks uint32) {
//go:export TIM3_IRQHandler
func handleTIM3() {
if (stm32.TIM3.SR & stm32.TIM_SR_UIF) > 0 {
if (stm32.TIM3.SR.Get() & stm32.TIM_SR_UIF) > 0 {
// Disable the timer.
stm32.TIM3.CR1 &^= stm32.TIM_CR1_CEN
stm32.TIM3.CR1.ClearBits(stm32.TIM_CR1_CEN)
// clear the update flag
stm32.TIM3.SR &^= stm32.TIM_SR_UIF
stm32.TIM3.SR.ClearBits(stm32.TIM_SR_UIF)
// timer was triggered
timerWakeup = true
@ -200,9 +201,9 @@ func handleTIM3() {
//go:export TIM7_IRQHandler
func handleTIM7() {
if (stm32.TIM7.SR & stm32.TIM_SR_UIF) > 0 {
if (stm32.TIM7.SR.Get() & stm32.TIM_SR_UIF) > 0 {
// clear the update flag
stm32.TIM7.SR &^= stm32.TIM_SR_UIF
stm32.TIM7.SR.ClearBits(stm32.TIM_SR_UIF)
tickCount++
}
}