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

Signed-off-by: Ron Evans <ron@hybridgroup.com>
This commit is contained in:
Ron Evans
2019-05-19 23:22:23 +02:00
committed by Ayke
parent 98a3047b58
commit e4d53daa02
5 changed files with 196 additions and 195 deletions
+88 -88
View File
@@ -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")
+32 -32
View File
@@ -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)))
}