1use core::fmt::Write;
8use kernel::platform::chip::Chip;
9use kernel::platform::chip::InterruptService;
10
11use crate::adc;
12use crate::clocks::Clocks;
13use crate::gpio::{RPGpio, RPPins, SIO};
14use crate::i2c;
15use crate::interrupts;
16use crate::pio::Pio;
17use crate::pwm;
18use crate::resets::Resets;
19use crate::rtc;
20use crate::spi;
21use crate::sysinfo;
22use crate::timer::RPTimer;
23use crate::uart::Uart;
24use crate::usb;
25use crate::watchdog::Watchdog;
26use crate::xosc::Xosc;
27use cortexm0p::{interrupt_mask, CortexM0P, CortexMVariant};
28
29#[repr(u8)]
30pub enum Processor {
31 Processor0 = 0,
32 Processor1 = 1,
33}
34
35pub struct Rp2040<'a, I: InterruptService + 'a> {
36 mpu: cortexm0p::mpu::MPU,
37 userspace_kernel_boundary: cortexm0p::syscall::SysCall,
38 interrupt_service: &'a I,
39 sio: &'a SIO,
40 processor0_interrupt_mask: (u128, u128),
41 processor1_interrupt_mask: (u128, u128),
42}
43
44impl<'a, I: InterruptService> Rp2040<'a, I> {
45 pub unsafe fn new(interrupt_service: &'a I, sio: &'a SIO) -> Self {
46 Self {
47 mpu: cortexm0p::mpu::new(),
48 userspace_kernel_boundary: cortexm0p::syscall::SysCall::new(),
49 interrupt_service,
50 sio,
51 processor0_interrupt_mask: interrupt_mask!(interrupts::SIO_IRQ_PROC1),
52 processor1_interrupt_mask: interrupt_mask!(interrupts::SIO_IRQ_PROC0),
53 }
54 }
55}
56
57impl<I: InterruptService> Chip for Rp2040<'_, I> {
58 type MPU = cortexm0p::mpu::MPU;
59 type UserspaceKernelBoundary = cortexm0p::syscall::SysCall;
60 type ThreadIdProvider = cortexm0p::thread_id::CortexMThreadIdProvider;
61
62 fn service_pending_interrupts(&self) {
63 unsafe {
64 let mask = match self.sio.get_processor() {
65 Processor::Processor0 => self.processor0_interrupt_mask,
66 Processor::Processor1 => self.processor1_interrupt_mask,
67 };
68 while let Some(interrupt) = cortexm0p::nvic::next_pending_with_mask(mask) {
69 if !self.interrupt_service.service_interrupt(interrupt) {
73 panic!("unhandled interrupt {}", interrupt);
74 }
75 let n = cortexm0p::nvic::Nvic::new(interrupt);
76 n.clear_pending();
77 n.enable();
78 }
79 }
80 }
81
82 fn has_pending_interrupts(&self) -> bool {
83 let mask = match self.sio.get_processor() {
87 Processor::Processor0 => self.processor0_interrupt_mask,
88 Processor::Processor1 => self.processor1_interrupt_mask,
89 };
90 unsafe { cortexm0p::nvic::has_pending_with_mask(mask) }
91 }
92
93 fn mpu(&self) -> &Self::MPU {
94 &self.mpu
95 }
96
97 fn userspace_kernel_boundary(&self) -> &Self::UserspaceKernelBoundary {
98 &self.userspace_kernel_boundary
99 }
100
101 fn sleep(&self) {
102 unsafe {
103 cortexm0p::support::wfi();
104 }
105 }
106
107 unsafe fn with_interrupts_disabled<F, R>(&self, f: F) -> R
108 where
109 F: FnOnce() -> R,
110 {
111 cortexm0p::support::with_interrupts_disabled(f)
112 }
113
114 unsafe fn print_state(&self, writer: &mut dyn Write) {
115 CortexM0P::print_cortexm_state(writer);
116 }
117}
118
119pub struct Rp2040DefaultPeripherals<'a> {
120 pub adc: adc::Adc<'a>,
121 pub clocks: Clocks,
122 pub i2c0: i2c::I2c<'a, 'a>,
123 pub pins: RPPins<'a>,
124 pub pio0: Pio,
125 pub pio1: Pio,
126 pub pwm: pwm::Pwm<'a>,
127 pub resets: Resets,
128 pub sio: SIO,
129 pub spi0: spi::Spi<'a>,
130 pub sysinfo: sysinfo::SysInfo,
131 pub timer: RPTimer<'a>,
132 pub uart0: Uart<'a>,
133 pub uart1: Uart<'a>,
134 pub usb: usb::UsbCtrl<'a>,
135 pub watchdog: Watchdog<'a>,
136 pub xosc: Xosc,
137 pub rtc: rtc::Rtc<'a>,
138}
139
140impl Rp2040DefaultPeripherals<'_> {
141 pub fn new() -> Self {
142 Self {
143 adc: adc::Adc::new(),
144 clocks: Clocks::new(),
145 i2c0: i2c::I2c::new_i2c0(),
146 pins: RPPins::new(),
147 pio0: Pio::new_pio0(),
148 pio1: Pio::new_pio1(),
149 pwm: pwm::Pwm::new(),
150 resets: Resets::new(),
151 sio: SIO::new(),
152 spi0: spi::Spi::new_spi0(),
153 sysinfo: sysinfo::SysInfo::new(),
154 timer: RPTimer::new(),
155 uart0: Uart::new_uart0(),
156 uart1: Uart::new_uart1(),
157 usb: usb::UsbCtrl::new(),
158 watchdog: Watchdog::new(),
159 xosc: Xosc::new(),
160 rtc: rtc::Rtc::new(),
161 }
162 }
163
164 pub fn resolve_dependencies(&'static self) {
165 self.pwm.set_clocks(&self.clocks);
166 self.watchdog.resolve_dependencies(&self.resets);
167 self.spi0.set_clocks(&self.clocks);
168 self.uart0.set_clocks(&self.clocks);
169 kernel::deferred_call::DeferredCallClient::register(&self.uart0);
170 kernel::deferred_call::DeferredCallClient::register(&self.uart1);
171 kernel::deferred_call::DeferredCallClient::register(&self.rtc);
172 self.i2c0.resolve_dependencies(&self.clocks, &self.resets);
173 self.usb.set_gpio(self.pins.get_pin(RPGpio::GPIO15));
174 self.rtc.set_clocks(&self.clocks);
175 }
176}
177
178impl InterruptService for Rp2040DefaultPeripherals<'_> {
179 unsafe fn service_interrupt(&self, interrupt: u32) -> bool {
180 match interrupt {
181 interrupts::PIO0_IRQ_0 => {
182 self.pio0.handle_interrupt();
183 true
184 }
185 interrupts::TIMER_IRQ_0 => {
186 self.timer.handle_interrupt();
187 true
188 }
189 interrupts::SIO_IRQ_PROC0 => {
190 self.sio.handle_proc_interrupt(Processor::Processor0);
191 true
192 }
193 interrupts::SIO_IRQ_PROC1 => {
194 self.sio.handle_proc_interrupt(Processor::Processor1);
195 true
196 }
197 interrupts::SPI0_IRQ => {
198 self.spi0.handle_interrupt();
199 true
200 }
201 interrupts::UART0_IRQ => {
202 self.uart0.handle_interrupt();
203 true
204 }
205 interrupts::ADC_IRQ_FIFO => {
206 self.adc.handle_interrupt();
207 true
208 }
209 interrupts::USBCTRL_IRQ => {
210 self.usb.handle_interrupt();
211 true
212 }
213 interrupts::IO_IRQ_BANK0 => {
214 self.pins.handle_interrupt();
215 true
216 }
217
218 interrupts::I2C0_IRQ => {
219 self.i2c0.handle_interrupt();
220 true
221 }
222 interrupts::PWM_IRQ_WRAP => {
223 true
228 }
229 _ => false,
230 }
231 }
232}