1#![no_std]
10#![cfg_attr(not(doc), no_main)]
13#![deny(missing_docs)]
14
15use core::ptr::addr_of_mut;
16
17use capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm;
18use components::gpio::GpioComponent;
19use components::led::LedsComponent;
20use enum_primitive::cast::FromPrimitive;
21use kernel::component::Component;
22use kernel::hil::led::LedHigh;
23use kernel::platform::{KernelResources, SyscallDriverLookup};
24use kernel::process::ProcessArray;
25use kernel::scheduler::round_robin::RoundRobinSched;
26use kernel::syscall::SyscallDriver;
27use kernel::{capabilities, create_capability, static_init, Kernel};
28
29use rp2350::chip::{Rp2350, Rp2350DefaultPeripherals};
30use rp2350::clocks::{
31 AdcAuxiliaryClockSource, HstxAuxiliaryClockSource, PeripheralAuxiliaryClockSource, PllClock,
32 ReferenceAuxiliaryClockSource, ReferenceClockSource, SystemAuxiliaryClockSource,
33 SystemClockSource, UsbAuxiliaryClockSource,
34};
35use rp2350::gpio::{GpioFunction, RPGpio, RPGpioPin};
36use rp2350::resets::Peripheral;
37use rp2350::timer::RPTimer;
38#[allow(unused)]
39use rp2350::{xosc, BASE_VECTORS};
40
41mod io;
42
43mod flash_bootloader;
44
45#[cfg_attr(not(target_os = "macos"), link_section = ".stack_buffer")]
51#[no_mangle]
52static mut STACK_MEMORY: [u8; 0x3000] = [0; 0x3000];
53
54#[cfg_attr(not(target_os = "macos"), link_section = ".flash_bootloader")]
60#[used]
61static FLASH_BOOTLOADER: [u8; 256] = flash_bootloader::FLASH_BOOTLOADER;
62
63#[cfg_attr(not(target_os = "macos"), link_section = ".metadata_block")]
67#[used]
68static METADATA_BLOCK: [u8; 28] = flash_bootloader::METADATA_BLOCK;
69
70const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
73 capsules_system::process_policies::PanicFaultPolicy {};
74
75const NUM_PROCS: usize = 4;
77
78type ChipHw = Rp2350<'static, Rp2350DefaultPeripherals<'static>>;
79
80static mut PROCESSES: Option<&'static ProcessArray<NUM_PROCS>> = None;
82
83static mut CHIP: Option<&'static Rp2350<Rp2350DefaultPeripherals<'static>>> = None;
84static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::ProcessPrinterText> =
85 None;
86
87pub struct RaspberryPiPico2 {
89 ipc: kernel::ipc::IPC<{ NUM_PROCS as u8 }>,
90 console: &'static capsules_core::console::Console<'static>,
91 scheduler: &'static RoundRobinSched<'static>,
92 systick: cortexm33::systick::SysTick,
93 alarm: &'static capsules_core::alarm::AlarmDriver<
94 'static,
95 VirtualMuxAlarm<'static, rp2350::timer::RPTimer<'static>>,
96 >,
97 gpio: &'static capsules_core::gpio::GPIO<'static, RPGpioPin<'static>>,
98 led: &'static capsules_core::led::LedDriver<'static, LedHigh<'static, RPGpioPin<'static>>, 1>,
99}
100
101impl SyscallDriverLookup for RaspberryPiPico2 {
102 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
103 where
104 F: FnOnce(Option<&dyn SyscallDriver>) -> R,
105 {
106 match driver_num {
107 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
108 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
109 capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
110 capsules_core::led::DRIVER_NUM => f(Some(self.led)),
111 kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
112 _ => f(None),
113 }
114 }
115}
116
117impl KernelResources<Rp2350<'static, Rp2350DefaultPeripherals<'static>>> for RaspberryPiPico2 {
118 type SyscallDriverLookup = Self;
119 type SyscallFilter = ();
120 type ProcessFault = ();
121 type Scheduler = RoundRobinSched<'static>;
122 type SchedulerTimer = cortexm33::systick::SysTick;
123 type WatchDog = ();
124 type ContextSwitchCallback = ();
125
126 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
127 self
128 }
129 fn syscall_filter(&self) -> &Self::SyscallFilter {
130 &()
131 }
132 fn process_fault(&self) -> &Self::ProcessFault {
133 &()
134 }
135 fn scheduler(&self) -> &Self::Scheduler {
136 self.scheduler
137 }
138 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
139 &self.systick
140 }
141 fn watchdog(&self) -> &Self::WatchDog {
142 &()
143 }
144 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
145 &()
146 }
147}
148
149#[allow(dead_code)]
150extern "C" {
151 fn jump_to_bootloader();
162}
163
164#[cfg(any(doc, all(target_arch = "arm", target_os = "none")))]
165core::arch::global_asm!(
166 "
167 .section .jump_to_bootloader, \"ax\"
168 .global jump_to_bootloader
169 .thumb_func
170 jump_to_bootloader:
171 movs r0, #0
172 ldr r1, =(0xe0000000 + 0x0000ed08)
173 str r0, [r1]
174 ldmia r0!, {{r1, r2}}
175 msr msp, r1
176 bx r2
177 "
178);
179
180fn init_clocks(peripherals: &Rp2350DefaultPeripherals) {
181 peripherals.clocks.disable_resus();
186
187 peripherals.xosc.init();
189
190 peripherals.clocks.disable_sys_aux();
192 peripherals.clocks.disable_ref_aux();
193
194 peripherals
195 .resets
196 .reset(&[Peripheral::PllSys, Peripheral::PllUsb]);
197 peripherals
198 .resets
199 .unreset(&[Peripheral::PllSys, Peripheral::PllUsb], true);
200
201 peripherals
209 .clocks
210 .pll_init(PllClock::Sys, 12, 1, 1500 * 1000000, 6, 2);
211 peripherals
212 .clocks
213 .pll_init(PllClock::Usb, 12, 1, 480 * 1000000, 5, 2);
214
215 peripherals.clocks.configure_reference(
217 ReferenceClockSource::Xosc,
218 ReferenceAuxiliaryClockSource::PllUsb,
219 12000000,
220 12000000,
221 );
222 peripherals.clocks.configure_system(
224 SystemClockSource::Auxiliary,
225 SystemAuxiliaryClockSource::PllSys,
226 125000000,
227 125000000,
228 );
229
230 peripherals
232 .clocks
233 .configure_usb(UsbAuxiliaryClockSource::PllSys, 48000000, 48000000);
234 peripherals
236 .clocks
237 .configure_adc(AdcAuxiliaryClockSource::PllUsb, 48000000, 48000000);
238 peripherals
240 .clocks
241 .configure_hstx(HstxAuxiliaryClockSource::PllSys, 48000000, 46875);
242 peripherals
246 .clocks
247 .configure_peripheral(PeripheralAuxiliaryClockSource::System, 125000000);
248}
249
250unsafe fn get_peripherals() -> &'static mut Rp2350DefaultPeripherals<'static> {
251 static_init!(Rp2350DefaultPeripherals, Rp2350DefaultPeripherals::new())
252}
253
254#[no_mangle]
256pub unsafe fn main() {
257 rp2350::init();
258
259 kernel::deferred_call::initialize_deferred_call_state::<
261 <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
262 >();
263
264 let peripherals = get_peripherals();
265 peripherals.resolve_dependencies();
266
267 peripherals.resets.reset_all_except(&[
268 Peripheral::IOQSpi,
269 Peripheral::PadsQSpi,
270 Peripheral::PllUsb,
271 Peripheral::PllSys,
272 ]);
273
274 init_clocks(peripherals);
275
276 peripherals.resets.unreset_all_except(&[], true);
277
278 (*addr_of_mut!(io::WRITER)).set_uart(&peripherals.uart0);
280
281 let gpio_tx = peripherals.pins.get_pin(RPGpio::GPIO0);
282 let gpio_rx = peripherals.pins.get_pin(RPGpio::GPIO1);
283 gpio_rx.set_function(GpioFunction::UART);
284 gpio_tx.set_function(GpioFunction::UART);
285
286 for pin in 26..30 {
288 peripherals
289 .pins
290 .get_pin(RPGpio::from_usize(pin).unwrap())
291 .deactivate_pads();
292 }
293
294 let chip = static_init!(
295 Rp2350<Rp2350DefaultPeripherals>,
296 Rp2350::new(peripherals, &peripherals.sio)
297 );
298
299 CHIP = Some(chip);
300
301 let processes = components::process_array::ProcessArrayComponent::new()
303 .finalize(components::process_array_component_static!(NUM_PROCS));
304 PROCESSES = Some(processes);
305
306 let board_kernel = static_init!(Kernel, Kernel::new(processes.as_slice()));
307
308 let process_management_capability =
309 create_capability!(capabilities::ProcessManagementCapability);
310 let memory_allocation_capability = create_capability!(capabilities::MemoryAllocationCapability);
311
312 let mux_alarm = components::alarm::AlarmMuxComponent::new(&peripherals.timer0)
313 .finalize(components::alarm_mux_component_static!(RPTimer));
314
315 let alarm = components::alarm::AlarmDriverComponent::new(
316 board_kernel,
317 capsules_core::alarm::DRIVER_NUM,
318 mux_alarm,
319 )
320 .finalize(components::alarm_component_static!(RPTimer));
321
322 let uart_mux = components::console::UartMuxComponent::new(&peripherals.uart0, 115200)
323 .finalize(components::uart_mux_component_static!());
324
325 let console = components::console::ConsoleComponent::new(
327 board_kernel,
328 capsules_core::console::DRIVER_NUM,
329 uart_mux,
330 )
331 .finalize(components::console_component_static!());
332
333 let gpio = GpioComponent::new(
334 board_kernel,
335 capsules_core::gpio::DRIVER_NUM,
336 components::gpio_component_helper!(
337 RPGpioPin,
338 2 => peripherals.pins.get_pin(RPGpio::GPIO2),
342 3 => peripherals.pins.get_pin(RPGpio::GPIO3),
343 4 => peripherals.pins.get_pin(RPGpio::GPIO4),
344 5 => peripherals.pins.get_pin(RPGpio::GPIO5),
345 6 => peripherals.pins.get_pin(RPGpio::GPIO6),
346 7 => peripherals.pins.get_pin(RPGpio::GPIO7),
347 8 => peripherals.pins.get_pin(RPGpio::GPIO8),
348 9 => peripherals.pins.get_pin(RPGpio::GPIO9),
349 10 => peripherals.pins.get_pin(RPGpio::GPIO10),
350 11 => peripherals.pins.get_pin(RPGpio::GPIO11),
351 12 => peripherals.pins.get_pin(RPGpio::GPIO12),
352 13 => peripherals.pins.get_pin(RPGpio::GPIO13),
353 14 => peripherals.pins.get_pin(RPGpio::GPIO14),
354 15 => peripherals.pins.get_pin(RPGpio::GPIO15),
355 16 => peripherals.pins.get_pin(RPGpio::GPIO16),
356 17 => peripherals.pins.get_pin(RPGpio::GPIO17),
357 18 => peripherals.pins.get_pin(RPGpio::GPIO18),
358 19 => peripherals.pins.get_pin(RPGpio::GPIO19),
359 20 => peripherals.pins.get_pin(RPGpio::GPIO20),
360 21 => peripherals.pins.get_pin(RPGpio::GPIO21),
361 22 => peripherals.pins.get_pin(RPGpio::GPIO22),
362 23 => peripherals.pins.get_pin(RPGpio::GPIO23),
363 24 => peripherals.pins.get_pin(RPGpio::GPIO24),
364 26 => peripherals.pins.get_pin(RPGpio::GPIO26),
367 27 => peripherals.pins.get_pin(RPGpio::GPIO27),
368 28 => peripherals.pins.get_pin(RPGpio::GPIO28),
369 29 => peripherals.pins.get_pin(RPGpio::GPIO29)
370 ),
371 )
372 .finalize(components::gpio_component_static!(RPGpioPin<'static>));
373
374 let led = LedsComponent::new().finalize(components::led_component_static!(
375 LedHigh<'static, RPGpioPin<'static>>,
376 LedHigh::new(peripherals.pins.get_pin(RPGpio::GPIO25))
377 ));
378
379 components::debug_writer::DebugWriterComponent::new::<
381 <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
382 >(
383 uart_mux,
384 create_capability!(capabilities::SetDebugWriterCapability),
385 )
386 .finalize(components::debug_writer_component_static!());
387
388 let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
390 .finalize(components::process_printer_text_component_static!());
391 PROCESS_PRINTER = Some(process_printer);
392
393 let process_console = components::process_console::ProcessConsoleComponent::new(
394 board_kernel,
395 uart_mux,
396 mux_alarm,
397 process_printer,
398 Some(cortexm33::support::reset),
399 )
400 .finalize(components::process_console_component_static!(RPTimer));
401 let _ = process_console.start();
402
403 let scheduler = components::sched::round_robin::RoundRobinComponent::new(processes)
404 .finalize(components::round_robin_component_static!(NUM_PROCS));
405
406 let raspberry_pi_pico = RaspberryPiPico2 {
407 ipc: kernel::ipc::IPC::new(
408 board_kernel,
409 kernel::ipc::DRIVER_NUM,
410 &memory_allocation_capability,
411 ),
412 console,
413 alarm,
414 gpio,
415 led,
416 scheduler,
417 systick: cortexm33::systick::SysTick::new_with_calibration(125_000_000),
418 };
419
420 kernel::debug!("Initialization complete. Enter main loop");
421
422 extern "C" {
424 static _sapps: u8;
426 static _eapps: u8;
428 static mut _sappmem: u8;
430 static _eappmem: u8;
432 }
433
434 kernel::process::load_processes(
435 board_kernel,
436 chip,
437 core::slice::from_raw_parts(
438 core::ptr::addr_of!(_sapps),
439 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
440 ),
441 core::slice::from_raw_parts_mut(
442 core::ptr::addr_of_mut!(_sappmem),
443 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
444 ),
445 &FAULT_RESPONSE,
446 &process_management_capability,
447 )
448 .unwrap_or_else(|err| {
449 kernel::debug!("Error loading processes!");
450 kernel::debug!("{:?}", err);
451 });
452
453 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
454
455 board_kernel.kernel_loop(
456 &raspberry_pi_pico,
457 chip,
458 Some(&raspberry_pi_pico.ipc),
459 &main_loop_capability,
460 );
461}