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 go fmt ./src/device/sam
gen-device-stm32: 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 go fmt ./src/device/stm32

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

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

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

@ -74,23 +74,23 @@ func (p GPIO) getPort() *stm32.GPIO_Type {
func (p GPIO) enableClock() { func (p GPIO) enableClock() {
switch p.Pin / 16 { switch p.Pin / 16 {
case 0: case 0:
stm32.RCC.AHB1ENR |= stm32.RCC_AHB1ENR_GPIOAEN stm32.RCC.AHB1ENR.SetBits(stm32.RCC_AHB1ENR_GPIOAEN)
case 1: case 1:
stm32.RCC.AHB1ENR |= stm32.RCC_AHB1ENR_GPIOBEN stm32.RCC.AHB1ENR.SetBits(stm32.RCC_AHB1ENR_GPIOBEN)
case 2: case 2:
stm32.RCC.AHB1ENR |= stm32.RCC_AHB1ENR_GPIOCEN stm32.RCC.AHB1ENR.SetBits(stm32.RCC_AHB1ENR_GPIOCEN)
case 3: case 3:
stm32.RCC.AHB1ENR |= stm32.RCC_AHB1ENR_GPIODEN stm32.RCC.AHB1ENR.SetBits(stm32.RCC_AHB1ENR_GPIODEN)
case 4: case 4:
stm32.RCC.AHB1ENR |= stm32.RCC_AHB1ENR_GPIOEEN stm32.RCC.AHB1ENR.SetBits(stm32.RCC_AHB1ENR_GPIOEEN)
case 5: case 5:
stm32.RCC.AHB1ENR |= stm32.RCC_AHB1ENR_GPIOFEN stm32.RCC.AHB1ENR.SetBits(stm32.RCC_AHB1ENR_GPIOFEN)
case 6: case 6:
stm32.RCC.AHB1ENR |= stm32.RCC_AHB1ENR_GPIOGEN stm32.RCC.AHB1ENR.SetBits(stm32.RCC_AHB1ENR_GPIOGEN)
case 7: case 7:
stm32.RCC.AHB1ENR |= stm32.RCC_AHB1ENR_GPIOHEN stm32.RCC.AHB1ENR.SetBits(stm32.RCC_AHB1ENR_GPIOHEN)
case 8: case 8:
stm32.RCC.AHB1ENR |= stm32.RCC_AHB1ENR_GPIOIEN stm32.RCC.AHB1ENR.SetBits(stm32.RCC_AHB1ENR_GPIOIEN)
default: default:
panic("machine: unknown port") panic("machine: unknown port")
} }
@ -105,25 +105,25 @@ func (p GPIO) Configure(config GPIOConfig) {
pos := pin * 2 pos := pin * 2
if config.Mode == GPIO_INPUT_FLOATING { if config.Mode == GPIO_INPUT_FLOATING {
port.MODER = stm32.RegValue((uint32(port.MODER)&^(0x3<<pos) | (uint32(GPIO_MODE_INPUT) << pos))) port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_INPUT) << pos)))
port.PUPDR = stm32.RegValue((uint32(port.PUPDR)&^(0x3<<pos) | (uint32(GPIO_FLOATING) << pos))) port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_FLOATING) << pos)))
} else if config.Mode == GPIO_INPUT_PULLDOWN { } else if config.Mode == GPIO_INPUT_PULLDOWN {
port.MODER = stm32.RegValue((uint32(port.MODER)&^(0x3<<pos) | (uint32(GPIO_MODE_INPUT) << pos))) port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_INPUT) << pos)))
port.PUPDR = stm32.RegValue((uint32(port.PUPDR)&^(0x3<<pos) | (uint32(GPIO_PULL_DOWN) << pos))) port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_PULL_DOWN) << pos)))
} else if config.Mode == GPIO_INPUT_PULLUP { } else if config.Mode == GPIO_INPUT_PULLUP {
port.MODER = stm32.RegValue((uint32(port.MODER)&^(0x3<<pos) | (uint32(GPIO_MODE_INPUT) << pos))) port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_INPUT) << pos)))
port.PUPDR = stm32.RegValue((uint32(port.PUPDR)&^(0x3<<pos) | (uint32(GPIO_PULL_UP) << pos))) port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_PULL_UP) << pos)))
} else if config.Mode == GPIO_OUTPUT { } else if config.Mode == GPIO_OUTPUT {
port.MODER = stm32.RegValue((uint32(port.MODER)&^(0x3<<pos) | (uint32(GPIO_MODE_GENERAL_OUTPUT) << pos))) port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_GENERAL_OUTPUT) << pos)))
port.OSPEEDR = stm32.RegValue((uint32(port.OSPEEDR)&^(0x3<<pos) | (uint32(GPIO_SPEED_HI) << pos))) port.OSPEEDR.Set((uint32(port.OSPEEDR.Get())&^(0x3<<pos) | (uint32(GPIO_SPEED_HI) << pos)))
} else if config.Mode == GPIO_UART_TX { } else if config.Mode == GPIO_UART_TX {
port.MODER = stm32.RegValue((uint32(port.MODER)&^(0x3<<pos) | (uint32(GPIO_MODE_ALTERNABTIVE) << pos))) port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_ALTERNABTIVE) << pos)))
port.OSPEEDR = stm32.RegValue((uint32(port.OSPEEDR)&^(0x3<<pos) | (uint32(GPIO_SPEED_HI) << pos))) port.OSPEEDR.Set((uint32(port.OSPEEDR.Get())&^(0x3<<pos) | (uint32(GPIO_SPEED_HI) << pos)))
port.PUPDR = stm32.RegValue((uint32(port.PUPDR)&^(0x3<<pos) | (uint32(GPIO_PULL_UP) << pos))) port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_PULL_UP) << pos)))
p.setAltFunc(0x7) p.setAltFunc(0x7)
} else if config.Mode == GPIO_UART_RX { } else if config.Mode == GPIO_UART_RX {
port.MODER = stm32.RegValue((uint32(port.MODER)&^(0x3<<pos) | (uint32(GPIO_MODE_ALTERNABTIVE) << pos))) port.MODER.Set((uint32(port.MODER.Get())&^(0x3<<pos) | (uint32(GPIO_MODE_ALTERNABTIVE) << pos)))
port.PUPDR = stm32.RegValue((uint32(port.PUPDR)&^(0x3<<pos) | (uint32(GPIO_FLOATING) << pos))) port.PUPDR.Set((uint32(port.PUPDR.Get())&^(0x3<<pos) | (uint32(GPIO_FLOATING) << pos)))
p.setAltFunc(0x7) p.setAltFunc(0x7)
} }
} }
@ -133,9 +133,9 @@ func (p GPIO) setAltFunc(af uint32) {
pin := p.Pin % 16 pin := p.Pin % 16
pos := pin * 4 pos := pin * 4
if pin >= 8 { 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 { } 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() port := p.getPort()
pin := p.Pin % 16 pin := p.Pin % 16
if high { if high {
port.BSRR = 1 << pin port.BSRR.Set(1 << pin)
} else { } 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 // Enable USART2 clock
stm32.RCC.APB1ENR |= stm32.RCC_APB1ENR_USART2EN stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_USART2EN)
/* /*
Set baud rate(115200) Set baud rate(115200)
@ -195,10 +195,10 @@ func (uart UART) Configure(config UARTConfig) {
| 115200 | 0x16D | | 115200 | 0x16D |
+----------+--------+ +----------+--------+
*/ */
stm32.USART2.BRR = 0x16c stm32.USART2.BRR.Set(0x16c)
// Enable USART2 port. // 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. // Enable RX IRQ.
arm.SetPriority(stm32.IRQ_USART2, 0xc0) 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. // WriteByte writes a byte of data to the UART.
func (uart UART) WriteByte(c byte) error { 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 return nil
} }
//go:export USART2_IRQHandler //go:export USART2_IRQHandler
func handleUSART2() { 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). // initCLK sets clock to 72MHz using HSE 8MHz crystal w/ PLL X 9 (8MHz x 9 = 72MHz).
func initCLK() { func initCLK() {
stm32.FLASH.ACR |= stm32.FLASH_ACR_LATENCY_2 // Two wait states, per datasheet stm32.FLASH.ACR.SetBits(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.SetBits(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.CFGR.SetBits(stm32.RCC_CFGR_PPRE2_DIV_NONE) // prescale PCLK2 = HCLK/1
stm32.RCC.CR |= 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 & 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 // 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.SetBits(stm32.RCC_CFGR_PLLSRC) // set PLL source to HSE
stm32.RCC.CFGR |= stm32.RCC_CFGR_PLLMUL_9 // multiply by 9 stm32.RCC.CFGR.SetBits(stm32.RCC_CFGR_PLLMUL_9) // multiply by 9
stm32.RCC.CR |= 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 & 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 // 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() { func initRTC() {
// Enable the PWR and BKP. // 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 // access to backup register
stm32.PWR.CR |= stm32.PWR_CR_DBP stm32.PWR.CR.SetBits(stm32.PWR_CR_DBP)
// Enable LSE // Enable LSE
stm32.RCC.BDCR |= stm32.RCC_BDCR_LSEON stm32.RCC.BDCR.SetBits(stm32.RCC_BDCR_LSEON)
// wait until LSE is ready // 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 // Select LSE
stm32.RCC.BDCR |= stm32.RCC_RTCCLKSource_LSE stm32.RCC.BDCR.SetBits(stm32.RCC_RTCCLKSource_LSE)
// set prescaler to "max" per datasheet // set prescaler to "max" per datasheet
stm32.RTC.PRLH = stm32.RTC_PRLH_PRLH_Msk stm32.RTC.PRLH.Set(stm32.RTC_PRLH_PRLH_Msk)
stm32.RTC.PRLL = stm32.RTC_PRLL_PRLL_Msk stm32.RTC.PRLL.Set(stm32.RTC_PRLL_PRLL_Msk)
// set count to zero // set count to zero
stm32.RTC.CNTH = 0x0 stm32.RTC.CNTH.Set(0x0)
stm32.RTC.CNTL = 0x0 stm32.RTC.CNTL.Set(0x0)
// Enable RTC // Enable RTC
stm32.RCC.BDCR |= stm32.RCC_BDCR_RTCEN stm32.RCC.BDCR.SetBits(stm32.RCC_BDCR_RTCEN)
// Clear RSF // Clear RSF
stm32.RTC.CRL &^= stm32.RTC_CRL_RSF stm32.RTC.CRL.ClearBits(stm32.RTC_CRL_RSF)
// Wait till flag is set // 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. // Enable the TIM3 clock.
func initTIM() { func initTIM() {
stm32.RCC.APB1ENR |= stm32.RCC_APB1ENR_TIM3EN stm32.RCC.APB1ENR.SetBits(stm32.RCC_APB1ENR_TIM3EN)
arm.SetPriority(stm32.IRQ_TIM3, 0xc3) arm.SetPriority(stm32.IRQ_TIM3, 0xc3)
arm.EnableIRQ(stm32.IRQ_TIM3) arm.EnableIRQ(stm32.IRQ_TIM3)
@ -122,10 +122,10 @@ func sleepTicks(d timeUnit) {
// number of ticks (microseconds) since start. // number of ticks (microseconds) since start.
func ticks() timeUnit { func ticks() timeUnit {
// convert RTC counter from seconds to microseconds // 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 // 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 // change since last measurement
offset := (timerCounter - timerLastCounter) offset := (timerCounter - timerLastCounter)
@ -165,16 +165,16 @@ func timerSleep(ticks uint32) {
// The current scaling only supports a range of 100 usec to 6553 msec. // 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. // 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 // 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. // Enable the hardware interrupt.
stm32.TIM3.DIER |= stm32.TIM_DIER_UIE stm32.TIM3.DIER.SetBits(stm32.TIM_DIER_UIE)
// Enable the timer. // Enable the timer.
stm32.TIM3.CR1 |= stm32.TIM_CR1_CEN stm32.TIM3.CR1.SetBits(stm32.TIM_CR1_CEN)
// wait till timer wakes up // wait till timer wakes up
for !timerWakeup { for !timerWakeup {
@ -184,12 +184,12 @@ func timerSleep(ticks uint32) {
//go:export TIM3_IRQHandler //go:export TIM3_IRQHandler
func handleTIM3() { func handleTIM3() {
if (stm32.TIM3.SR & stm32.TIM_SR_UIF) > 0 { if (stm32.TIM3.SR.Get() & stm32.TIM_SR_UIF) > 0 {
// Disable the timer. // Disable the timer.
stm32.TIM3.CR1 &^= stm32.TIM_CR1_CEN stm32.TIM3.CR1.ClearBits(stm32.TIM_CR1_CEN)
// clear the update flag // clear the update flag
stm32.TIM3.SR &^= stm32.TIM_SR_UIF stm32.TIM3.SR.ClearBits(stm32.TIM_SR_UIF)
// timer was triggered // timer was triggered
timerWakeup = true timerWakeup = true

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

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