1#![no_std]
10#![no_main]
11#![deny(missing_docs)]
12
13use core::ptr::{addr_of, addr_of_mut};
14
15use components::gpio::GpioComponent;
16use kernel::capabilities;
17use kernel::component::Component;
18use kernel::hil::gpio::Configure;
19use kernel::platform::{KernelResources, SyscallDriverLookup};
20use kernel::scheduler::round_robin::RoundRobinSched;
21use kernel::{create_capability, debug, static_init};
22
23pub mod io;
25
26const NUM_PROCS: usize = 4;
28
29static mut PROCESSES: [Option<&'static dyn kernel::process::Process>; NUM_PROCS] =
31 [None; NUM_PROCS];
32
33static mut CHIP: Option<&'static msp432::chip::Msp432<msp432::chip::Msp432DefaultPeripherals>> =
35 None;
36static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::ProcessPrinterText> =
38 None;
39
40const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
42 capsules_system::process_policies::PanicFaultPolicy {};
43
44#[no_mangle]
46#[link_section = ".stack_buffer"]
47pub static mut STACK_MEMORY: [u8; 0x1000] = [0; 0x1000];
48
49struct MspExp432P401R {
52 led: &'static capsules_core::led::LedDriver<
53 'static,
54 kernel::hil::led::LedHigh<'static, msp432::gpio::IntPin<'static>>,
55 3,
56 >,
57 console: &'static capsules_core::console::Console<'static>,
58 button: &'static capsules_core::button::Button<'static, msp432::gpio::IntPin<'static>>,
59 gpio: &'static capsules_core::gpio::GPIO<'static, msp432::gpio::IntPin<'static>>,
60 alarm: &'static capsules_core::alarm::AlarmDriver<
61 'static,
62 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
63 'static,
64 msp432::timer::TimerA<'static>,
65 >,
66 >,
67 ipc: kernel::ipc::IPC<{ NUM_PROCS as u8 }>,
68 adc: &'static capsules_core::adc::AdcDedicated<'static, msp432::adc::Adc<'static>>,
69 wdt: &'static msp432::wdt::Wdt,
70 scheduler: &'static RoundRobinSched<'static>,
71 systick: cortexm4::systick::SysTick,
72}
73
74impl KernelResources<msp432::chip::Msp432<'static, msp432::chip::Msp432DefaultPeripherals<'static>>>
75 for MspExp432P401R
76{
77 type SyscallDriverLookup = Self;
78 type SyscallFilter = ();
79 type ProcessFault = ();
80 type Scheduler = RoundRobinSched<'static>;
81 type SchedulerTimer = cortexm4::systick::SysTick;
82 type WatchDog = msp432::wdt::Wdt;
83 type ContextSwitchCallback = ();
84
85 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
86 self
87 }
88 fn syscall_filter(&self) -> &Self::SyscallFilter {
89 &()
90 }
91 fn process_fault(&self) -> &Self::ProcessFault {
92 &()
93 }
94 fn scheduler(&self) -> &Self::Scheduler {
95 self.scheduler
96 }
97 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
98 &self.systick
99 }
100 fn watchdog(&self) -> &Self::WatchDog {
101 self.wdt
102 }
103 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
104 &()
105 }
106}
107
108impl SyscallDriverLookup for MspExp432P401R {
110 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
111 where
112 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
113 {
114 match driver_num {
115 capsules_core::led::DRIVER_NUM => f(Some(self.led)),
116 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
117 capsules_core::button::DRIVER_NUM => f(Some(self.button)),
118 capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
119 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
120 kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
121 capsules_core::adc::DRIVER_NUM => f(Some(self.adc)),
122 _ => f(None),
123 }
124 }
125}
126
127unsafe fn startup_intilialisation() {
134 msp432::init();
135
136 let wdt = msp432::wdt::Wdt::new();
141 let sysctl = msp432::sysctl::SysCtl::new();
142 let flctl = msp432::flctl::FlCtl::new();
143 let pcm = msp432::pcm::Pcm::new();
144
145 wdt.disable();
150 sysctl.enable_all_sram_banks();
151 pcm.set_high_power();
152 flctl.set_waitstates(msp432::flctl::WaitStates::_1);
153 flctl.set_buffering(true);
154}
155
156unsafe fn setup_adc_pins(gpio: &msp432::gpio::GpioManager) {
159 use msp432::gpio::{IntPinNr, PinNr};
160 gpio.int_pins[IntPinNr::P05_5 as usize].enable_tertiary_function(); gpio.int_pins[IntPinNr::P05_4 as usize].enable_tertiary_function(); gpio.int_pins[IntPinNr::P05_3 as usize].enable_tertiary_function(); gpio.int_pins[IntPinNr::P05_2 as usize].enable_tertiary_function(); gpio.int_pins[IntPinNr::P05_1 as usize].enable_tertiary_function(); gpio.int_pins[IntPinNr::P05_0 as usize].enable_tertiary_function(); gpio.int_pins[IntPinNr::P04_7 as usize].enable_tertiary_function(); gpio.int_pins[IntPinNr::P04_6 as usize].enable_tertiary_function(); gpio.int_pins[IntPinNr::P04_5 as usize].enable_tertiary_function(); gpio.int_pins[IntPinNr::P04_4 as usize].enable_tertiary_function(); gpio.int_pins[IntPinNr::P04_3 as usize].enable_tertiary_function(); gpio.int_pins[IntPinNr::P04_2 as usize].enable_tertiary_function(); gpio.int_pins[IntPinNr::P04_1 as usize].enable_tertiary_function(); gpio.int_pins[IntPinNr::P04_0 as usize].enable_tertiary_function(); gpio.int_pins[IntPinNr::P06_1 as usize].enable_tertiary_function(); gpio.int_pins[IntPinNr::P06_0 as usize].enable_tertiary_function(); gpio.pins[PinNr::P09_1 as usize].enable_tertiary_function(); gpio.pins[PinNr::P09_0 as usize].enable_tertiary_function(); gpio.pins[PinNr::P08_7 as usize].enable_tertiary_function(); gpio.pins[PinNr::P08_6 as usize].enable_tertiary_function(); gpio.pins[PinNr::P08_5 as usize].enable_tertiary_function(); gpio.pins[PinNr::P08_4 as usize].enable_tertiary_function(); }
188
189#[inline(never)]
193unsafe fn start() -> (
194 &'static kernel::Kernel,
195 MspExp432P401R,
196 &'static msp432::chip::Msp432<'static, msp432::chip::Msp432DefaultPeripherals<'static>>,
197) {
198 startup_intilialisation();
199
200 let peripherals = static_init!(
201 msp432::chip::Msp432DefaultPeripherals,
202 msp432::chip::Msp432DefaultPeripherals::new()
203 );
204 peripherals.init();
205
206 peripherals.gpio.pins[msp432::gpio::PinNr::PJ_2 as usize].enable_primary_function();
208 peripherals.gpio.pins[msp432::gpio::PinNr::PJ_3 as usize].enable_primary_function();
209
210 peripherals.gpio.pins[msp432::gpio::PinNr::PJ_0 as usize].enable_primary_function();
212 peripherals.gpio.pins[msp432::gpio::PinNr::PJ_1 as usize].enable_primary_function();
213
214 peripherals.cs.setup_clocks();
216
217 let dbg_gpio0 = &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_0 as usize];
219 let dbg_gpio1 = &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_5 as usize];
220 let dbg_gpio2 = &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_7 as usize];
221 dbg_gpio0.make_output();
222 dbg_gpio1.make_output();
223 dbg_gpio2.make_output();
224 debug::assign_gpios(
225 Some(dbg_gpio0), Some(dbg_gpio1),
227 Some(dbg_gpio2),
228 );
229
230 peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_2 as usize].enable_primary_function();
232 peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_3 as usize].enable_primary_function();
233
234 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&*addr_of!(PROCESSES)));
235 let chip = static_init!(
236 msp432::chip::Msp432<msp432::chip::Msp432DefaultPeripherals>,
237 msp432::chip::Msp432::new(peripherals)
238 );
239 CHIP = Some(chip);
240
241 let button = components::button::ButtonComponent::new(
243 board_kernel,
244 capsules_core::button::DRIVER_NUM,
245 components::button_component_helper!(
246 msp432::gpio::IntPin,
247 (
248 &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_1 as usize],
249 kernel::hil::gpio::ActivationMode::ActiveLow,
250 kernel::hil::gpio::FloatingState::PullUp
251 ),
252 (
253 &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_4 as usize],
254 kernel::hil::gpio::ActivationMode::ActiveLow,
255 kernel::hil::gpio::FloatingState::PullUp
256 )
257 ),
258 )
259 .finalize(components::button_component_static!(msp432::gpio::IntPin));
260
261 let leds = components::led::LedsComponent::new().finalize(components::led_component_static!(
263 kernel::hil::led::LedHigh<'static, msp432::gpio::IntPin>,
264 kernel::hil::led::LedHigh::new(
265 &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_0 as usize]
266 ),
267 kernel::hil::led::LedHigh::new(
268 &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_1 as usize]
269 ),
270 kernel::hil::led::LedHigh::new(
271 &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_2 as usize]
272 ),
273 ));
274
275 let gpio = GpioComponent::new(
277 board_kernel,
278 capsules_core::gpio::DRIVER_NUM,
279 components::gpio_component_helper!(
280 msp432::gpio::IntPin<'static>,
281 1 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_2 as usize],
284 2 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_3 as usize],
285 5 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_5 as usize],
288 7 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P06_5 as usize],
290 8 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P06_4 as usize],
291 17 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_7 as usize],
302 18 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_6 as usize],
303 19 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_4 as usize],
304 20 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P05_6 as usize],
305 21 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P06_6 as usize],
306 22 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P06_7 as usize],
307 23 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_3 as usize],
308 27 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_5 as usize],
313 28 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_0 as usize],
314 29 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P05_7 as usize],
315 30 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_6 as usize],
316 31 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_7 as usize],
317 34 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_6 as usize]
320 ),
321 )
322 .finalize(components::gpio_component_static!(
323 msp432::gpio::IntPin<'static>
324 ));
325
326 let memory_allocation_capability = create_capability!(capabilities::MemoryAllocationCapability);
327 let process_management_capability =
328 create_capability!(capabilities::ProcessManagementCapability);
329
330 let uart_mux = components::console::UartMuxComponent::new(&peripherals.uart0, 115200)
332 .finalize(components::uart_mux_component_static!());
333
334 let console = components::console::ConsoleComponent::new(
336 board_kernel,
337 capsules_core::console::DRIVER_NUM,
338 uart_mux,
339 )
340 .finalize(components::console_component_static!());
341 components::debug_writer::DebugWriterComponent::new(
343 uart_mux,
344 create_capability!(capabilities::SetDebugWriterCapability),
345 )
346 .finalize(components::debug_writer_component_static!());
347
348 let timer0 = &peripherals.timer_a0;
350 let mux_alarm = components::alarm::AlarmMuxComponent::new(timer0).finalize(
351 components::alarm_mux_component_static!(msp432::timer::TimerA),
352 );
353 let alarm = components::alarm::AlarmDriverComponent::new(
354 board_kernel,
355 capsules_core::alarm::DRIVER_NUM,
356 mux_alarm,
357 )
358 .finalize(components::alarm_component_static!(msp432::timer::TimerA));
359
360 setup_adc_pins(&peripherals.gpio);
362
363 let adc_channels = static_init!(
364 [msp432::adc::Channel; 24],
365 [
366 msp432::adc::Channel::Channel0, msp432::adc::Channel::Channel1, msp432::adc::Channel::Channel2, msp432::adc::Channel::Channel3, msp432::adc::Channel::Channel4, msp432::adc::Channel::Channel5, msp432::adc::Channel::Channel6, msp432::adc::Channel::Channel7, msp432::adc::Channel::Channel8, msp432::adc::Channel::Channel9, msp432::adc::Channel::Channel10, msp432::adc::Channel::Channel11, msp432::adc::Channel::Channel12, msp432::adc::Channel::Channel13, msp432::adc::Channel::Channel14, msp432::adc::Channel::Channel15, msp432::adc::Channel::Channel16, msp432::adc::Channel::Channel17, msp432::adc::Channel::Channel18, msp432::adc::Channel::Channel19, msp432::adc::Channel::Channel20, msp432::adc::Channel::Channel21, msp432::adc::Channel::Channel22, msp432::adc::Channel::Channel23, ]
391 );
392 let adc = components::adc::AdcDedicatedComponent::new(
393 &peripherals.adc,
394 adc_channels,
395 board_kernel,
396 capsules_core::adc::DRIVER_NUM,
397 )
398 .finalize(components::adc_dedicated_component_static!(
399 msp432::adc::Adc
400 ));
401
402 peripherals
404 .adc_ref
405 .select_ref_voltage(msp432::ref_module::ReferenceVoltage::Volt2_5);
406 peripherals.adc_ref.enable_temp_sensor(true);
408
409 let scheduler = components::sched::round_robin::RoundRobinComponent::new(&*addr_of!(PROCESSES))
410 .finalize(components::round_robin_component_static!(NUM_PROCS));
411
412 let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
413 .finalize(components::process_printer_text_component_static!());
414 PROCESS_PRINTER = Some(process_printer);
415
416 let msp_exp432p4014 = MspExp432P401R {
417 led: leds,
418 console,
419 button,
420 gpio,
421 alarm,
422 ipc: kernel::ipc::IPC::new(
423 board_kernel,
424 kernel::ipc::DRIVER_NUM,
425 &memory_allocation_capability,
426 ),
427 adc,
428 scheduler,
429 systick: cortexm4::systick::SysTick::new_with_calibration(48_000_000),
430 wdt: &peripherals.wdt,
431 };
432
433 debug!("Initialization complete. Entering main loop");
434
435 extern "C" {
437 static _sapps: u8;
439 static _eapps: u8;
441 static mut _sappmem: u8;
443 static _eappmem: u8;
445 }
446
447 kernel::process::load_processes(
448 board_kernel,
449 chip,
450 core::slice::from_raw_parts(
451 core::ptr::addr_of!(_sapps),
452 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
453 ),
454 core::slice::from_raw_parts_mut(
455 core::ptr::addr_of_mut!(_sappmem),
456 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
457 ),
458 &mut *addr_of_mut!(PROCESSES),
459 &FAULT_RESPONSE,
460 &process_management_capability,
461 )
462 .unwrap();
463
464 (board_kernel, msp_exp432p4014, chip)
470}
471
472#[no_mangle]
474pub unsafe fn main() {
475 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
476
477 let (board_kernel, board, chip) = start();
478 board_kernel.kernel_loop(&board, chip, Some(&board.ipc), &main_loop_capability);
479}