machine/stm32: refactor to use new volatile package for all register access
Signed-off-by: Ron Evans <ron@hybridgroup.com>
Этот коммит содержится в:
родитель
98a3047b58
коммит
e4d53daa02
5 изменённых файлов: 196 добавлений и 195 удалений
2
Makefile
2
Makefile
|
@ -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++
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче