1#![no_std]
10#![cfg_attr(not(doc), no_main)]
13#![deny(missing_docs)]
14
15use core::ptr::{addr_of, addr_of_mut};
16
17use components::gpio::GpioComponent;
18use kernel::capabilities;
19use kernel::component::Component;
20use kernel::hil::gpio::Configure;
21use kernel::platform::{KernelResources, SyscallDriverLookup};
22use kernel::scheduler::round_robin::RoundRobinSched;
23use kernel::{create_capability, debug, static_init};
24
25pub mod io;
27
28const NUM_PROCS: usize = 4;
30
31static mut PROCESSES: [Option<&'static dyn kernel::process::Process>; NUM_PROCS] =
33 [None; NUM_PROCS];
34
35static mut CHIP: Option<&'static msp432::chip::Msp432<msp432::chip::Msp432DefaultPeripherals>> =
37 None;
38static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::ProcessPrinterText> =
40 None;
41
42const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
44 capsules_system::process_policies::PanicFaultPolicy {};
45
46#[no_mangle]
48#[link_section = ".stack_buffer"]
49pub static mut STACK_MEMORY: [u8; 0x1000] = [0; 0x1000];
50
51struct MspExp432P401R {
54 led: &'static capsules_core::led::LedDriver<
55 'static,
56 kernel::hil::led::LedHigh<'static, msp432::gpio::IntPin<'static>>,
57 3,
58 >,
59 console: &'static capsules_core::console::Console<'static>,
60 button: &'static capsules_core::button::Button<'static, msp432::gpio::IntPin<'static>>,
61 gpio: &'static capsules_core::gpio::GPIO<'static, msp432::gpio::IntPin<'static>>,
62 alarm: &'static capsules_core::alarm::AlarmDriver<
63 'static,
64 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
65 'static,
66 msp432::timer::TimerA<'static>,
67 >,
68 >,
69 ipc: kernel::ipc::IPC<{ NUM_PROCS as u8 }>,
70 adc: &'static capsules_core::adc::AdcDedicated<'static, msp432::adc::Adc<'static>>,
71 wdt: &'static msp432::wdt::Wdt,
72 scheduler: &'static RoundRobinSched<'static>,
73 systick: cortexm4::systick::SysTick,
74}
75
76impl KernelResources<msp432::chip::Msp432<'static, msp432::chip::Msp432DefaultPeripherals<'static>>>
77 for MspExp432P401R
78{
79 type SyscallDriverLookup = Self;
80 type SyscallFilter = ();
81 type ProcessFault = ();
82 type Scheduler = RoundRobinSched<'static>;
83 type SchedulerTimer = cortexm4::systick::SysTick;
84 type WatchDog = msp432::wdt::Wdt;
85 type ContextSwitchCallback = ();
86
87 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
88 self
89 }
90 fn syscall_filter(&self) -> &Self::SyscallFilter {
91 &()
92 }
93 fn process_fault(&self) -> &Self::ProcessFault {
94 &()
95 }
96 fn scheduler(&self) -> &Self::Scheduler {
97 self.scheduler
98 }
99 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
100 &self.systick
101 }
102 fn watchdog(&self) -> &Self::WatchDog {
103 self.wdt
104 }
105 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
106 &()
107 }
108}
109
110impl SyscallDriverLookup for MspExp432P401R {
112 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
113 where
114 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
115 {
116 match driver_num {
117 capsules_core::led::DRIVER_NUM => f(Some(self.led)),
118 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
119 capsules_core::button::DRIVER_NUM => f(Some(self.button)),
120 capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
121 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
122 kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
123 capsules_core::adc::DRIVER_NUM => f(Some(self.adc)),
124 _ => f(None),
125 }
126 }
127}
128
129unsafe fn startup_intilialisation() {
136 msp432::init();
137
138 let wdt = msp432::wdt::Wdt::new();
143 let sysctl = msp432::sysctl::SysCtl::new();
144 let flctl = msp432::flctl::FlCtl::new();
145 let pcm = msp432::pcm::Pcm::new();
146
147 wdt.disable();
152 sysctl.enable_all_sram_banks();
153 pcm.set_high_power();
154 flctl.set_waitstates(msp432::flctl::WaitStates::_1);
155 flctl.set_buffering(true);
156}
157
158unsafe fn setup_adc_pins(gpio: &msp432::gpio::GpioManager) {
161 use msp432::gpio::{IntPinNr, PinNr};
162 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(); }
190
191#[inline(never)]
195unsafe fn start() -> (
196 &'static kernel::Kernel,
197 MspExp432P401R,
198 &'static msp432::chip::Msp432<'static, msp432::chip::Msp432DefaultPeripherals<'static>>,
199) {
200 startup_intilialisation();
201
202 let peripherals = static_init!(
203 msp432::chip::Msp432DefaultPeripherals,
204 msp432::chip::Msp432DefaultPeripherals::new()
205 );
206 peripherals.init();
207
208 peripherals.gpio.pins[msp432::gpio::PinNr::PJ_2 as usize].enable_primary_function();
210 peripherals.gpio.pins[msp432::gpio::PinNr::PJ_3 as usize].enable_primary_function();
211
212 peripherals.gpio.pins[msp432::gpio::PinNr::PJ_0 as usize].enable_primary_function();
214 peripherals.gpio.pins[msp432::gpio::PinNr::PJ_1 as usize].enable_primary_function();
215
216 peripherals.cs.setup_clocks();
218
219 let dbg_gpio0 = &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_0 as usize];
221 let dbg_gpio1 = &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_5 as usize];
222 let dbg_gpio2 = &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_7 as usize];
223 dbg_gpio0.make_output();
224 dbg_gpio1.make_output();
225 dbg_gpio2.make_output();
226 debug::assign_gpios(
227 Some(dbg_gpio0), Some(dbg_gpio1),
229 Some(dbg_gpio2),
230 );
231
232 peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_2 as usize].enable_primary_function();
234 peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_3 as usize].enable_primary_function();
235
236 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&*addr_of!(PROCESSES)));
237 let chip = static_init!(
238 msp432::chip::Msp432<msp432::chip::Msp432DefaultPeripherals>,
239 msp432::chip::Msp432::new(peripherals)
240 );
241 CHIP = Some(chip);
242
243 let button = components::button::ButtonComponent::new(
245 board_kernel,
246 capsules_core::button::DRIVER_NUM,
247 components::button_component_helper!(
248 msp432::gpio::IntPin,
249 (
250 &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_1 as usize],
251 kernel::hil::gpio::ActivationMode::ActiveLow,
252 kernel::hil::gpio::FloatingState::PullUp
253 ),
254 (
255 &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_4 as usize],
256 kernel::hil::gpio::ActivationMode::ActiveLow,
257 kernel::hil::gpio::FloatingState::PullUp
258 )
259 ),
260 )
261 .finalize(components::button_component_static!(msp432::gpio::IntPin));
262
263 let leds = components::led::LedsComponent::new().finalize(components::led_component_static!(
265 kernel::hil::led::LedHigh<'static, msp432::gpio::IntPin>,
266 kernel::hil::led::LedHigh::new(
267 &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_0 as usize]
268 ),
269 kernel::hil::led::LedHigh::new(
270 &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_1 as usize]
271 ),
272 kernel::hil::led::LedHigh::new(
273 &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_2 as usize]
274 ),
275 ));
276
277 let gpio = GpioComponent::new(
279 board_kernel,
280 capsules_core::gpio::DRIVER_NUM,
281 components::gpio_component_helper!(
282 msp432::gpio::IntPin<'static>,
283 1 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_2 as usize],
286 2 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_3 as usize],
287 5 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_5 as usize],
290 7 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P06_5 as usize],
292 8 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P06_4 as usize],
293 17 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_7 as usize],
304 18 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_6 as usize],
305 19 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_4 as usize],
306 20 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P05_6 as usize],
307 21 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P06_6 as usize],
308 22 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P06_7 as usize],
309 23 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_3 as usize],
310 27 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_5 as usize],
315 28 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_0 as usize],
316 29 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P05_7 as usize],
317 30 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_6 as usize],
318 31 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_7 as usize],
319 34 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_6 as usize]
322 ),
323 )
324 .finalize(components::gpio_component_static!(
325 msp432::gpio::IntPin<'static>
326 ));
327
328 let memory_allocation_capability = create_capability!(capabilities::MemoryAllocationCapability);
329 let process_management_capability =
330 create_capability!(capabilities::ProcessManagementCapability);
331
332 let uart_mux = components::console::UartMuxComponent::new(&peripherals.uart0, 115200)
334 .finalize(components::uart_mux_component_static!());
335
336 let console = components::console::ConsoleComponent::new(
338 board_kernel,
339 capsules_core::console::DRIVER_NUM,
340 uart_mux,
341 )
342 .finalize(components::console_component_static!());
343 components::debug_writer::DebugWriterComponent::new(uart_mux)
345 .finalize(components::debug_writer_component_static!());
346
347 let timer0 = &peripherals.timer_a0;
349 let mux_alarm = components::alarm::AlarmMuxComponent::new(timer0).finalize(
350 components::alarm_mux_component_static!(msp432::timer::TimerA),
351 );
352 let alarm = components::alarm::AlarmDriverComponent::new(
353 board_kernel,
354 capsules_core::alarm::DRIVER_NUM,
355 mux_alarm,
356 )
357 .finalize(components::alarm_component_static!(msp432::timer::TimerA));
358
359 setup_adc_pins(&peripherals.gpio);
361
362 let adc_channels = static_init!(
363 [msp432::adc::Channel; 24],
364 [
365 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, ]
390 );
391 let adc = components::adc::AdcDedicatedComponent::new(
392 &peripherals.adc,
393 adc_channels,
394 board_kernel,
395 capsules_core::adc::DRIVER_NUM,
396 )
397 .finalize(components::adc_dedicated_component_static!(
398 msp432::adc::Adc
399 ));
400
401 peripherals
403 .adc_ref
404 .select_ref_voltage(msp432::ref_module::ReferenceVoltage::Volt2_5);
405 peripherals.adc_ref.enable_temp_sensor(true);
407
408 let scheduler = components::sched::round_robin::RoundRobinComponent::new(&*addr_of!(PROCESSES))
409 .finalize(components::round_robin_component_static!(NUM_PROCS));
410
411 let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
412 .finalize(components::process_printer_text_component_static!());
413 PROCESS_PRINTER = Some(process_printer);
414
415 let msp_exp432p4014 = MspExp432P401R {
416 led: leds,
417 console,
418 button,
419 gpio,
420 alarm,
421 ipc: kernel::ipc::IPC::new(
422 board_kernel,
423 kernel::ipc::DRIVER_NUM,
424 &memory_allocation_capability,
425 ),
426 adc,
427 scheduler,
428 systick: cortexm4::systick::SysTick::new_with_calibration(48_000_000),
429 wdt: &peripherals.wdt,
430 };
431
432 debug!("Initialization complete. Entering main loop");
433
434 extern "C" {
436 static _sapps: u8;
438 static _eapps: u8;
440 static mut _sappmem: u8;
442 static _eappmem: u8;
444 }
445
446 kernel::process::load_processes(
447 board_kernel,
448 chip,
449 core::slice::from_raw_parts(
450 core::ptr::addr_of!(_sapps),
451 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
452 ),
453 core::slice::from_raw_parts_mut(
454 core::ptr::addr_of_mut!(_sappmem),
455 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
456 ),
457 &mut *addr_of_mut!(PROCESSES),
458 &FAULT_RESPONSE,
459 &process_management_capability,
460 )
461 .unwrap();
462
463 (board_kernel, msp_exp432p4014, chip)
469}
470
471#[no_mangle]
473pub unsafe fn main() {
474 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
475
476 let (board_kernel, board, chip) = start();
477 board_kernel.kernel_loop(&board, chip, Some(&board.ipc), &main_loop_capability);
478}