mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-07-26 06:38:42 +00:00
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>
This commit is contained in:
@@ -49,15 +49,10 @@ func machineInit() {
|
||||
bits := ^uint32(initDontReset)
|
||||
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()
|
||||
|
||||
// Peripheral clocks should now all be running
|
||||
unresetBlockWait(RESETS_RESET_Msk)
|
||||
unresetBlockWait(initUnreset)
|
||||
|
||||
// DBGPAUSE pauses the timer when a debugger is connected. This prevents
|
||||
// sleep functions from ever returning, so disable it.
|
||||
|
||||
@@ -15,13 +15,8 @@ const (
|
||||
_NUMIRQ = 32
|
||||
rp2350ExtraReg = 0
|
||||
RESETS_RESET_Msk = 0x01ffffff
|
||||
initUnreset = rp.RESETS_RESET_ADC |
|
||||
rp.RESETS_RESET_RTC |
|
||||
rp.RESETS_RESET_SPI0 |
|
||||
rp.RESETS_RESET_SPI1 |
|
||||
rp.RESETS_RESET_UART0 |
|
||||
rp.RESETS_RESET_UART1 |
|
||||
rp.RESETS_RESET_USBCTRL
|
||||
initUnreset = rp.RESETS_RESET_IO_BANK0 |
|
||||
rp.RESETS_RESET_TIMER
|
||||
initDontReset = rp.RESETS_RESET_IO_QSPI |
|
||||
rp.RESETS_RESET_PADS_QSPI |
|
||||
rp.RESETS_RESET_PLL_USB |
|
||||
|
||||
@@ -16,12 +16,8 @@ const (
|
||||
_NUMIRQ = 51
|
||||
notimpl = "rp2350: not implemented"
|
||||
RESETS_RESET_Msk = 0x1fffffff
|
||||
initUnreset = rp.RESETS_RESET_ADC |
|
||||
rp.RESETS_RESET_SPI0 |
|
||||
rp.RESETS_RESET_SPI1 |
|
||||
rp.RESETS_RESET_UART0 |
|
||||
rp.RESETS_RESET_UART1 |
|
||||
rp.RESETS_RESET_USBCTRL
|
||||
initUnreset = rp.RESETS_RESET_IO_BANK0 |
|
||||
rp.RESETS_RESET_TIMER0
|
||||
initDontReset = rp.RESETS_RESET_USBCTRL |
|
||||
rp.RESETS_RESET_SYSCFG |
|
||||
rp.RESETS_RESET_PLL_USB |
|
||||
|
||||
@@ -19,10 +19,10 @@ var adcAref uint32
|
||||
|
||||
// InitADC resets the ADC peripheral.
|
||||
func InitADC() {
|
||||
rp.RESETS.RESET.SetBits(rp.RESETS_RESET_ADC)
|
||||
rp.RESETS.RESET.ClearBits(rp.RESETS_RESET_ADC)
|
||||
for !rp.RESETS.RESET_DONE.HasBits(rp.RESETS_RESET_ADC) {
|
||||
}
|
||||
// reset ADC controller
|
||||
resetBlock(rp.RESETS_RESET_ADC)
|
||||
unresetBlockWait(rp.RESETS_RESET_ADC)
|
||||
|
||||
// enable ADC
|
||||
rp.ADC.CS.Set(rp.ADC_CS_EN)
|
||||
adcAref = 3300
|
||||
|
||||
@@ -259,10 +259,7 @@ func (i2c *I2C) init(config I2CConfig) error {
|
||||
//go:inline
|
||||
func (i2c *I2C) reset() {
|
||||
resetVal := i2c.deinit()
|
||||
rp.RESETS.RESET.ClearBits(resetVal)
|
||||
// Wait until reset is done.
|
||||
for !rp.RESETS.RESET_DONE.HasBits(resetVal) {
|
||||
}
|
||||
unresetBlockWait(resetVal)
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
// Perform I2C reset.
|
||||
rp.RESETS.RESET.SetBits(resetVal)
|
||||
resetBlock(resetVal)
|
||||
|
||||
return resetVal
|
||||
}
|
||||
|
||||
@@ -212,10 +212,7 @@ func (spi *SPI) setFormat(mode uint8) {
|
||||
//go:inline
|
||||
func (spi *SPI) reset() {
|
||||
resetVal := spi.deinit()
|
||||
rp.RESETS.RESET.ClearBits(resetVal)
|
||||
// Wait until reset is done.
|
||||
for !rp.RESETS.RESET_DONE.HasBits(resetVal) {
|
||||
}
|
||||
unresetBlockWait(resetVal)
|
||||
}
|
||||
|
||||
//go:inline
|
||||
@@ -227,7 +224,7 @@ func (spi *SPI) deinit() (resetVal uint32) {
|
||||
resetVal = rp.RESETS_RESET_SPI1
|
||||
}
|
||||
// Perform SPI reset.
|
||||
rp.RESETS.RESET.SetBits(resetVal)
|
||||
resetBlock(resetVal)
|
||||
return resetVal
|
||||
}
|
||||
|
||||
|
||||
@@ -148,10 +148,8 @@ func initUART(uart *UART) {
|
||||
}
|
||||
|
||||
// reset UART
|
||||
rp.RESETS.RESET.SetBits(resetVal)
|
||||
rp.RESETS.RESET.ClearBits(resetVal)
|
||||
for !rp.RESETS.RESET_DONE.HasBits(resetVal) {
|
||||
}
|
||||
resetBlock(resetVal)
|
||||
unresetBlockWait(resetVal)
|
||||
}
|
||||
|
||||
// handleInterrupt should be called from the appropriate interrupt handler for
|
||||
|
||||
Reference in New Issue
Block a user