rp2350/
resets.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright OxidOS Automotive 2025.
4
5use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
6use kernel::utilities::registers::{register_bitfields, register_structs, FieldValue, ReadWrite};
7use kernel::utilities::StaticRef;
8
9register_structs! {
10
11    ResetsRegisters {
12
13        (0x000 => reset: ReadWrite<u32, RESET::Register>),
14
15        (0x004 => wdsel: ReadWrite<u32, WDSEL::Register>),
16
17        (0x008 => reset_done: ReadWrite<u32, RESET_DONE::Register>),
18        (0x00C => @END),
19    }
20}
21register_bitfields![u32,
22RESET [
23
24    USBCTRL OFFSET(28) NUMBITS(1) [],
25
26    UART1 OFFSET(27) NUMBITS(1) [],
27
28    UART0 OFFSET(26) NUMBITS(1) [],
29
30    TRNG OFFSET(25) NUMBITS(1) [],
31
32    TIMER1 OFFSET(24) NUMBITS(1) [],
33
34    TIMER0 OFFSET(23) NUMBITS(1) [],
35
36    TBMAN OFFSET(22) NUMBITS(1) [],
37
38    SYSINFO OFFSET(21) NUMBITS(1) [],
39
40    SYSCFG OFFSET(20) NUMBITS(1) [],
41
42    SPI1 OFFSET(19) NUMBITS(1) [],
43
44    SPI0 OFFSET(18) NUMBITS(1) [],
45
46    SHA256 OFFSET(17) NUMBITS(1) [],
47
48    PWM OFFSET(16) NUMBITS(1) [],
49
50    PLL_USB OFFSET(15) NUMBITS(1) [],
51
52    PLL_SYS OFFSET(14) NUMBITS(1) [],
53
54    PIO2 OFFSET(13) NUMBITS(1) [],
55
56    PIO1 OFFSET(12) NUMBITS(1) [],
57
58    PIO0 OFFSET(11) NUMBITS(1) [],
59
60    PADS_QSPI OFFSET(10) NUMBITS(1) [],
61
62    PADS_BANK0 OFFSET(9) NUMBITS(1) [],
63
64    JTAG OFFSET(8) NUMBITS(1) [],
65
66    IO_QSPI OFFSET(7) NUMBITS(1) [],
67
68    IO_BANK0 OFFSET(6) NUMBITS(1) [],
69
70    I2C1 OFFSET(5) NUMBITS(1) [],
71
72    I2C0 OFFSET(4) NUMBITS(1) [],
73
74    HSTX OFFSET(3) NUMBITS(1) [],
75
76    DMA OFFSET(2) NUMBITS(1) [],
77
78    BUSCTRL OFFSET(1) NUMBITS(1) [],
79
80    ADC OFFSET(0) NUMBITS(1) []
81],
82WDSEL [
83
84    USBCTRL OFFSET(28) NUMBITS(1) [],
85
86    UART1 OFFSET(27) NUMBITS(1) [],
87
88    UART0 OFFSET(26) NUMBITS(1) [],
89
90    TRNG OFFSET(25) NUMBITS(1) [],
91
92    TIMER1 OFFSET(24) NUMBITS(1) [],
93
94    TIMER0 OFFSET(23) NUMBITS(1) [],
95
96    TBMAN OFFSET(22) NUMBITS(1) [],
97
98    SYSINFO OFFSET(21) NUMBITS(1) [],
99
100    SYSCFG OFFSET(20) NUMBITS(1) [],
101
102    SPI1 OFFSET(19) NUMBITS(1) [],
103
104    SPI0 OFFSET(18) NUMBITS(1) [],
105
106    SHA256 OFFSET(17) NUMBITS(1) [],
107
108    PWM OFFSET(16) NUMBITS(1) [],
109
110    PLL_USB OFFSET(15) NUMBITS(1) [],
111
112    PLL_SYS OFFSET(14) NUMBITS(1) [],
113
114    PIO2 OFFSET(13) NUMBITS(1) [],
115
116    PIO1 OFFSET(12) NUMBITS(1) [],
117
118    PIO0 OFFSET(11) NUMBITS(1) [],
119
120    PADS_QSPI OFFSET(10) NUMBITS(1) [],
121
122    PADS_BANK0 OFFSET(9) NUMBITS(1) [],
123
124    JTAG OFFSET(8) NUMBITS(1) [],
125
126    IO_QSPI OFFSET(7) NUMBITS(1) [],
127
128    IO_BANK0 OFFSET(6) NUMBITS(1) [],
129
130    I2C1 OFFSET(5) NUMBITS(1) [],
131
132    I2C0 OFFSET(4) NUMBITS(1) [],
133
134    HSTX OFFSET(3) NUMBITS(1) [],
135
136    DMA OFFSET(2) NUMBITS(1) [],
137
138    BUSCTRL OFFSET(1) NUMBITS(1) [],
139
140    ADC OFFSET(0) NUMBITS(1) []
141],
142RESET_DONE [
143
144    USBCTRL OFFSET(28) NUMBITS(1) [],
145
146    UART1 OFFSET(27) NUMBITS(1) [],
147
148    UART0 OFFSET(26) NUMBITS(1) [],
149
150    TRNG OFFSET(25) NUMBITS(1) [],
151
152    TIMER1 OFFSET(24) NUMBITS(1) [],
153
154    TIMER0 OFFSET(23) NUMBITS(1) [],
155
156    TBMAN OFFSET(22) NUMBITS(1) [],
157
158    SYSINFO OFFSET(21) NUMBITS(1) [],
159
160    SYSCFG OFFSET(20) NUMBITS(1) [],
161
162    SPI1 OFFSET(19) NUMBITS(1) [],
163
164    SPI0 OFFSET(18) NUMBITS(1) [],
165
166    SHA256 OFFSET(17) NUMBITS(1) [],
167
168    PWM OFFSET(16) NUMBITS(1) [],
169
170    PLL_USB OFFSET(15) NUMBITS(1) [],
171
172    PLL_SYS OFFSET(14) NUMBITS(1) [],
173
174    PIO2 OFFSET(13) NUMBITS(1) [],
175
176    PIO1 OFFSET(12) NUMBITS(1) [],
177
178    PIO0 OFFSET(11) NUMBITS(1) [],
179
180    PADS_QSPI OFFSET(10) NUMBITS(1) [],
181
182    PADS_BANK0 OFFSET(9) NUMBITS(1) [],
183
184    JTAG OFFSET(8) NUMBITS(1) [],
185
186    IO_QSPI OFFSET(7) NUMBITS(1) [],
187
188    IO_BANK0 OFFSET(6) NUMBITS(1) [],
189
190    I2C1 OFFSET(5) NUMBITS(1) [],
191
192    I2C0 OFFSET(4) NUMBITS(1) [],
193
194    HSTX OFFSET(3) NUMBITS(1) [],
195
196    DMA OFFSET(2) NUMBITS(1) [],
197
198    BUSCTRL OFFSET(1) NUMBITS(1) [],
199
200    ADC OFFSET(0) NUMBITS(1) []
201]
202];
203const RESETS_BASE: StaticRef<ResetsRegisters> =
204    unsafe { StaticRef::new(0x40020000 as *const ResetsRegisters) };
205
206pub enum Peripheral {
207    Adc,
208    BusController,
209    Dma,
210    Hstx,
211    I2c0,
212    I2c1,
213    IOBank0,
214    IOQSpi,
215    Jtag,
216    PadsBank0,
217    PadsQSpi,
218    Pio0,
219    Pio1,
220    PllSys,
221    PllUsb,
222    Pwm,
223    Spi0,
224    Spi1,
225    Syscfg,
226    SysInfo,
227    TBMan,
228    Timer0,
229    Timer1,
230    Uart0,
231    Uart1,
232    UsbCtrl,
233}
234
235impl Peripheral {
236    fn get_reset_field_set(&self) -> FieldValue<u32, RESET::Register> {
237        match self {
238            Peripheral::Adc => RESET::ADC::SET,
239            Peripheral::BusController => RESET::BUSCTRL::SET,
240            Peripheral::Dma => RESET::DMA::SET,
241            Peripheral::Hstx => RESET::HSTX::SET,
242            Peripheral::I2c0 => RESET::I2C0::SET,
243            Peripheral::I2c1 => RESET::I2C1::SET,
244            Peripheral::IOBank0 => RESET::IO_BANK0::SET,
245            Peripheral::IOQSpi => RESET::IO_QSPI::SET,
246            Peripheral::Jtag => RESET::JTAG::SET,
247            Peripheral::PadsBank0 => RESET::PADS_BANK0::SET,
248            Peripheral::PadsQSpi => RESET::PADS_QSPI::SET,
249            Peripheral::Pio0 => RESET::PIO0::SET,
250            Peripheral::Pio1 => RESET::PIO1::SET,
251            Peripheral::PllSys => RESET::PLL_SYS::SET,
252            Peripheral::PllUsb => RESET::PLL_USB::SET,
253            Peripheral::Pwm => RESET::PWM::SET,
254            Peripheral::Spi0 => RESET::SPI0::SET,
255            Peripheral::Spi1 => RESET::SPI1::SET,
256            Peripheral::Syscfg => RESET::SYSCFG::SET,
257            Peripheral::SysInfo => RESET::SYSINFO::SET,
258            Peripheral::TBMan => RESET::TBMAN::SET,
259            Peripheral::Timer0 => RESET::TIMER0::SET,
260            Peripheral::Timer1 => RESET::TIMER1::SET,
261            Peripheral::Uart0 => RESET::UART0::SET,
262            Peripheral::Uart1 => RESET::UART1::SET,
263            Peripheral::UsbCtrl => RESET::USBCTRL::SET,
264        }
265    }
266
267    fn get_reset_field_clear(&self) -> FieldValue<u32, RESET::Register> {
268        match self {
269            Peripheral::Adc => RESET::ADC::CLEAR,
270            Peripheral::BusController => RESET::BUSCTRL::CLEAR,
271            Peripheral::Dma => RESET::DMA::CLEAR,
272            Peripheral::Hstx => RESET::HSTX::CLEAR,
273            Peripheral::I2c0 => RESET::I2C0::CLEAR,
274            Peripheral::I2c1 => RESET::I2C1::CLEAR,
275            Peripheral::IOBank0 => RESET::IO_BANK0::CLEAR,
276            Peripheral::IOQSpi => RESET::IO_QSPI::CLEAR,
277            Peripheral::Jtag => RESET::JTAG::CLEAR,
278            Peripheral::PadsBank0 => RESET::PADS_BANK0::CLEAR,
279            Peripheral::PadsQSpi => RESET::PADS_QSPI::CLEAR,
280            Peripheral::Pio0 => RESET::PIO0::CLEAR,
281            Peripheral::Pio1 => RESET::PIO1::CLEAR,
282            Peripheral::PllSys => RESET::PLL_SYS::CLEAR,
283            Peripheral::PllUsb => RESET::PLL_USB::CLEAR,
284            Peripheral::Pwm => RESET::PWM::CLEAR,
285            Peripheral::Spi0 => RESET::SPI0::CLEAR,
286            Peripheral::Spi1 => RESET::SPI1::CLEAR,
287            Peripheral::Syscfg => RESET::SYSCFG::CLEAR,
288            Peripheral::SysInfo => RESET::SYSINFO::CLEAR,
289            Peripheral::TBMan => RESET::TBMAN::CLEAR,
290            Peripheral::Timer0 => RESET::TIMER0::CLEAR,
291            Peripheral::Timer1 => RESET::TIMER1::CLEAR,
292            Peripheral::Uart0 => RESET::UART0::CLEAR,
293            Peripheral::Uart1 => RESET::UART1::CLEAR,
294            Peripheral::UsbCtrl => RESET::USBCTRL::CLEAR,
295        }
296    }
297
298    fn get_reset_done_field_set(&self) -> FieldValue<u32, RESET_DONE::Register> {
299        match self {
300            Peripheral::Adc => RESET_DONE::ADC::SET,
301            Peripheral::BusController => RESET_DONE::BUSCTRL::SET,
302            Peripheral::Dma => RESET_DONE::DMA::SET,
303            Peripheral::Hstx => RESET_DONE::HSTX::SET,
304            Peripheral::I2c0 => RESET_DONE::I2C0::SET,
305            Peripheral::I2c1 => RESET_DONE::I2C1::SET,
306            Peripheral::IOBank0 => RESET_DONE::IO_BANK0::SET,
307            Peripheral::IOQSpi => RESET_DONE::IO_QSPI::SET,
308            Peripheral::Jtag => RESET_DONE::JTAG::SET,
309            Peripheral::PadsBank0 => RESET_DONE::PADS_BANK0::SET,
310            Peripheral::PadsQSpi => RESET_DONE::PADS_QSPI::SET,
311            Peripheral::Pio0 => RESET_DONE::PIO0::SET,
312            Peripheral::Pio1 => RESET_DONE::PIO1::SET,
313            Peripheral::PllSys => RESET_DONE::PLL_SYS::SET,
314            Peripheral::PllUsb => RESET_DONE::PLL_USB::SET,
315            Peripheral::Pwm => RESET_DONE::PWM::SET,
316            Peripheral::Spi0 => RESET_DONE::SPI0::SET,
317            Peripheral::Spi1 => RESET_DONE::SPI1::SET,
318            Peripheral::Syscfg => RESET_DONE::SYSCFG::SET,
319            Peripheral::SysInfo => RESET_DONE::SYSINFO::SET,
320            Peripheral::TBMan => RESET_DONE::TBMAN::SET,
321            Peripheral::Timer0 => RESET_DONE::TIMER0::SET,
322            Peripheral::Timer1 => RESET_DONE::TIMER1::SET,
323            Peripheral::Uart0 => RESET_DONE::UART0::SET,
324            Peripheral::Uart1 => RESET_DONE::UART1::SET,
325            Peripheral::UsbCtrl => RESET_DONE::USBCTRL::SET,
326        }
327    }
328}
329
330pub struct Resets {
331    registers: StaticRef<ResetsRegisters>,
332}
333
334impl Resets {
335    pub const fn new() -> Resets {
336        Resets {
337            registers: RESETS_BASE,
338        }
339    }
340
341    pub fn reset(&self, peripherals: &'static [Peripheral]) {
342        if peripherals.len() > 0 {
343            let mut value: FieldValue<u32, RESET::Register> = peripherals[0].get_reset_field_set();
344            for peripheral in peripherals {
345                value += peripheral.get_reset_field_set();
346            }
347            self.registers.reset.modify(value);
348        }
349    }
350
351    pub fn unreset(&self, peripherals: &'static [Peripheral], wait_for: bool) {
352        if peripherals.len() > 0 {
353            let mut value: FieldValue<u32, RESET::Register> =
354                peripherals[0].get_reset_field_clear();
355            for peripheral in peripherals {
356                value += peripheral.get_reset_field_clear();
357            }
358            self.registers.reset.modify(value);
359
360            if wait_for {
361                let mut value_done: FieldValue<u32, RESET_DONE::Register> =
362                    peripherals[0].get_reset_done_field_set();
363                for peripheral in peripherals {
364                    value_done += peripheral.get_reset_done_field_set();
365                }
366                while !self.registers.reset_done.matches_all(value_done) {}
367            }
368        }
369    }
370
371    pub fn reset_all_except(&self, peripherals: &'static [Peripheral]) {
372        let mut value = 0x1FFFFFFF;
373        for peripheral in peripherals {
374            value ^= peripheral.get_reset_field_set().value;
375        }
376        self.registers.reset.set(value);
377    }
378
379    pub fn unreset_all_except(&self, peripherals: &'static [Peripheral], wait_for: bool) {
380        let mut value = 0;
381        for peripheral in peripherals {
382            value |= peripheral.get_reset_field_set().value;
383        }
384
385        self.registers.reset.set(value);
386
387        if wait_for {
388            value = !value & 0x1FFFFFFF;
389            while (self.registers.reset_done.get() & value) != value {}
390        }
391    }
392
393    pub fn watchdog_reset_all_except(&self, peripherals: &'static [Peripheral]) {
394        let mut value = 0xFFFFFF;
395        for peripheral in peripherals {
396            value ^= peripheral.get_reset_field_set().value;
397        }
398        self.registers.wdsel.set(value);
399    }
400}