Compare commits

...

1 Commits

Author SHA1 Message Date
deadprogram cde28db20e rp2: perform lazy block init to save power
This changes the machine init process for the rp2040/rp2350
to only unreset aka make available the minimum needed peripherals
in order to try to save power use.

I2C, SPI, and other devices unreset themselves as needed as used.

Signed-off-by: deadprogram <ron@hybridgroup.com>
2026-01-12 01:33:04 +01:00
7 changed files with 15 additions and 37 deletions
+1 -6
View File
@@ -49,15 +49,10 @@ func machineInit() {
bits := ^uint32(initDontReset) bits := ^uint32(initDontReset)
resetBlock(bits) resetBlock(bits)
// Remove reset from peripherals which are clocked only by clkSys and
// clkRef. Other peripherals stay in reset until we've configured clocks.
bits = ^uint32(initUnreset)
unresetBlockWait(bits)
clocks.init() clocks.init()
// Peripheral clocks should now all be running // Peripheral clocks should now all be running
unresetBlockWait(RESETS_RESET_Msk) unresetBlockWait(initUnreset)
// DBGPAUSE pauses the timer when a debugger is connected. This prevents // DBGPAUSE pauses the timer when a debugger is connected. This prevents
// sleep functions from ever returning, so disable it. // sleep functions from ever returning, so disable it.
+2 -7
View File
@@ -15,13 +15,8 @@ const (
_NUMIRQ = 32 _NUMIRQ = 32
rp2350ExtraReg = 0 rp2350ExtraReg = 0
RESETS_RESET_Msk = 0x01ffffff RESETS_RESET_Msk = 0x01ffffff
initUnreset = rp.RESETS_RESET_ADC | initUnreset = rp.RESETS_RESET_IO_BANK0 |
rp.RESETS_RESET_RTC | rp.RESETS_RESET_TIMER
rp.RESETS_RESET_SPI0 |
rp.RESETS_RESET_SPI1 |
rp.RESETS_RESET_UART0 |
rp.RESETS_RESET_UART1 |
rp.RESETS_RESET_USBCTRL
initDontReset = rp.RESETS_RESET_IO_QSPI | initDontReset = rp.RESETS_RESET_IO_QSPI |
rp.RESETS_RESET_PADS_QSPI | rp.RESETS_RESET_PADS_QSPI |
rp.RESETS_RESET_PLL_USB | rp.RESETS_RESET_PLL_USB |
+2 -6
View File
@@ -16,12 +16,8 @@ const (
_NUMIRQ = 51 _NUMIRQ = 51
notimpl = "rp2350: not implemented" notimpl = "rp2350: not implemented"
RESETS_RESET_Msk = 0x1fffffff RESETS_RESET_Msk = 0x1fffffff
initUnreset = rp.RESETS_RESET_ADC | initUnreset = rp.RESETS_RESET_IO_BANK0 |
rp.RESETS_RESET_SPI0 | rp.RESETS_RESET_TIMER0
rp.RESETS_RESET_SPI1 |
rp.RESETS_RESET_UART0 |
rp.RESETS_RESET_UART1 |
rp.RESETS_RESET_USBCTRL
initDontReset = rp.RESETS_RESET_USBCTRL | initDontReset = rp.RESETS_RESET_USBCTRL |
rp.RESETS_RESET_SYSCFG | rp.RESETS_RESET_SYSCFG |
rp.RESETS_RESET_PLL_USB | rp.RESETS_RESET_PLL_USB |
+4 -4
View File
@@ -19,10 +19,10 @@ var adcAref uint32
// InitADC resets the ADC peripheral. // InitADC resets the ADC peripheral.
func InitADC() { func InitADC() {
rp.RESETS.RESET.SetBits(rp.RESETS_RESET_ADC) // reset ADC controller
rp.RESETS.RESET.ClearBits(rp.RESETS_RESET_ADC) resetBlock(rp.RESETS_RESET_ADC)
for !rp.RESETS.RESET_DONE.HasBits(rp.RESETS_RESET_ADC) { unresetBlockWait(rp.RESETS_RESET_ADC)
}
// enable ADC // enable ADC
rp.ADC.CS.Set(rp.ADC_CS_EN) rp.ADC.CS.Set(rp.ADC_CS_EN)
adcAref = 3300 adcAref = 3300
+2 -5
View File
@@ -259,10 +259,7 @@ func (i2c *I2C) init(config I2CConfig) error {
//go:inline //go:inline
func (i2c *I2C) reset() { func (i2c *I2C) reset() {
resetVal := i2c.deinit() resetVal := i2c.deinit()
rp.RESETS.RESET.ClearBits(resetVal) unresetBlockWait(resetVal)
// Wait until reset is done.
for !rp.RESETS.RESET_DONE.HasBits(resetVal) {
}
} }
// deinit sets reset bit for I2C. Must call reset to reenable I2C after deinit. // deinit sets reset bit for I2C. Must call reset to reenable I2C after deinit.
@@ -276,7 +273,7 @@ func (i2c *I2C) deinit() (resetVal uint32) {
resetVal = rp.RESETS_RESET_I2C1 resetVal = rp.RESETS_RESET_I2C1
} }
// Perform I2C reset. // Perform I2C reset.
rp.RESETS.RESET.SetBits(resetVal) resetBlock(resetVal)
return resetVal return resetVal
} }
+2 -5
View File
@@ -212,10 +212,7 @@ func (spi *SPI) setFormat(mode uint8) {
//go:inline //go:inline
func (spi *SPI) reset() { func (spi *SPI) reset() {
resetVal := spi.deinit() resetVal := spi.deinit()
rp.RESETS.RESET.ClearBits(resetVal) unresetBlockWait(resetVal)
// Wait until reset is done.
for !rp.RESETS.RESET_DONE.HasBits(resetVal) {
}
} }
//go:inline //go:inline
@@ -227,7 +224,7 @@ func (spi *SPI) deinit() (resetVal uint32) {
resetVal = rp.RESETS_RESET_SPI1 resetVal = rp.RESETS_RESET_SPI1
} }
// Perform SPI reset. // Perform SPI reset.
rp.RESETS.RESET.SetBits(resetVal) resetBlock(resetVal)
return resetVal return resetVal
} }
+2 -4
View File
@@ -148,10 +148,8 @@ func initUART(uart *UART) {
} }
// reset UART // reset UART
rp.RESETS.RESET.SetBits(resetVal) resetBlock(resetVal)
rp.RESETS.RESET.ClearBits(resetVal) unresetBlockWait(resetVal)
for !rp.RESETS.RESET_DONE.HasBits(resetVal) {
}
} }
// handleInterrupt should be called from the appropriate interrupt handler for // handleInterrupt should be called from the appropriate interrupt handler for