msp_exp432p401r/
main.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 Tock Contributors 2022.
4
5//! Board file for the MSP-EXP432P401R evaluation board from TI.
6//!
7//! - <https://www.ti.com/tool/MSP-EXP432P401R>
8
9#![no_std]
10#![no_main]
11#![deny(missing_docs)]
12
13use components::gpio::GpioComponent;
14use kernel::capabilities;
15use kernel::component::Component;
16use kernel::debug::PanicResources;
17use kernel::hil::gpio::Configure;
18use kernel::platform::{KernelResources, SyscallDriverLookup};
19use kernel::scheduler::round_robin::RoundRobinSched;
20use kernel::utilities::single_thread_value::SingleThreadValue;
21use kernel::{create_capability, debug, static_init};
22
23/// Support routines for debugging I/O.
24pub mod io;
25
26/// Number of concurrent processes this platform supports.
27const NUM_PROCS: usize = 4;
28
29type ChipHw = msp432::chip::Msp432<'static, msp432::chip::Msp432DefaultPeripherals<'static>>;
30type ProcessPrinterInUse = capsules_system::process_printer::ProcessPrinterText;
31
32/// Resources for when a board panics used by io.rs.
33static PANIC_RESOURCES: SingleThreadValue<PanicResources<ChipHw, ProcessPrinterInUse>> =
34    SingleThreadValue::new(PanicResources::new());
35
36/// How should the kernel respond when a process faults.
37const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
38    capsules_system::process_policies::PanicFaultPolicy {};
39
40kernel::stack_size! {0x1000}
41
42/// A structure representing this platform that holds references to all
43/// capsules for this platform.
44struct MspExp432P401R {
45    led: &'static capsules_core::led::LedDriver<
46        'static,
47        kernel::hil::led::LedHigh<'static, msp432::gpio::IntPin<'static>>,
48        3,
49    >,
50    console: &'static capsules_core::console::Console<'static>,
51    button: &'static capsules_core::button::Button<'static, msp432::gpio::IntPin<'static>>,
52    gpio: &'static capsules_core::gpio::GPIO<'static, msp432::gpio::IntPin<'static>>,
53    alarm: &'static capsules_core::alarm::AlarmDriver<
54        'static,
55        capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
56            'static,
57            msp432::timer::TimerA<'static>,
58        >,
59    >,
60    ipc: kernel::ipc::IPC<{ NUM_PROCS as u8 }>,
61    adc: &'static capsules_core::adc::AdcDedicated<'static, msp432::adc::Adc<'static>>,
62    wdt: &'static msp432::wdt::Wdt,
63    scheduler: &'static RoundRobinSched<'static>,
64    systick: cortexm4::systick::SysTick,
65}
66
67impl KernelResources<msp432::chip::Msp432<'static, msp432::chip::Msp432DefaultPeripherals<'static>>>
68    for MspExp432P401R
69{
70    type SyscallDriverLookup = Self;
71    type SyscallFilter = ();
72    type ProcessFault = ();
73    type Scheduler = RoundRobinSched<'static>;
74    type SchedulerTimer = cortexm4::systick::SysTick;
75    type WatchDog = msp432::wdt::Wdt;
76    type ContextSwitchCallback = ();
77
78    fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
79        self
80    }
81    fn syscall_filter(&self) -> &Self::SyscallFilter {
82        &()
83    }
84    fn process_fault(&self) -> &Self::ProcessFault {
85        &()
86    }
87    fn scheduler(&self) -> &Self::Scheduler {
88        self.scheduler
89    }
90    fn scheduler_timer(&self) -> &Self::SchedulerTimer {
91        &self.systick
92    }
93    fn watchdog(&self) -> &Self::WatchDog {
94        self.wdt
95    }
96    fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
97        &()
98    }
99}
100
101/// Mapping of integer syscalls to objects that implement syscalls.
102impl SyscallDriverLookup for MspExp432P401R {
103    fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
104    where
105        F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
106    {
107        match driver_num {
108            capsules_core::led::DRIVER_NUM => f(Some(self.led)),
109            capsules_core::console::DRIVER_NUM => f(Some(self.console)),
110            capsules_core::button::DRIVER_NUM => f(Some(self.button)),
111            capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
112            capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
113            kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
114            capsules_core::adc::DRIVER_NUM => f(Some(self.adc)),
115            _ => f(None),
116        }
117    }
118}
119
120/// Startup initialisation
121///
122/// This code was more or less copied from the code examples of Texas instruments.
123/// It disables the watchdog, enables all RAM banks, configures the chip to the high-power mode
124/// (which is necessary for 48MHz operation) and enables waitstates and buffering in a way that
125/// the flash returns valid data with 48MHz CPU frequency.
126unsafe fn startup_intilialisation() {
127    msp432::init();
128
129    // For now, these peripherals are only used at startup, so we do not
130    // allocate them for the life of the program. If these are later used by the
131    // chip crate (such as for handling interrupts), they will need to be
132    // added to Msp432DefaultPeripherals
133    let wdt = msp432::wdt::Wdt::new();
134    let sysctl = msp432::sysctl::SysCtl::new();
135    let flctl = msp432::flctl::FlCtl::new();
136    let pcm = msp432::pcm::Pcm::new();
137
138    // The watchdog must be disabled, because it is enabled by default on reset and has a
139    // interval of approximately 10ms. See datasheet p. 759, section 17.2.2.
140    // Do this in a separate function which is executed before the kernel is started in order to
141    // make sure that not more than 1 watchdog instances exist at the same time.
142    wdt.disable();
143    sysctl.enable_all_sram_banks();
144    pcm.set_high_power();
145    flctl.set_waitstates(msp432::flctl::WaitStates::_1);
146    flctl.set_buffering(true);
147}
148
149/// Function to setup all ADC-capaable pins
150/// Since the chips has 100 pins, we really setup all capable pins to work as ADC-pins.
151unsafe fn setup_adc_pins(gpio: &msp432::gpio::GpioManager) {
152    use msp432::gpio::{IntPinNr, PinNr};
153    gpio.int_pins[IntPinNr::P05_5 as usize].enable_tertiary_function(); // A0
154    gpio.int_pins[IntPinNr::P05_4 as usize].enable_tertiary_function(); // A1
155    gpio.int_pins[IntPinNr::P05_3 as usize].enable_tertiary_function(); // A2
156    gpio.int_pins[IntPinNr::P05_2 as usize].enable_tertiary_function(); // A3
157    gpio.int_pins[IntPinNr::P05_1 as usize].enable_tertiary_function(); // A4
158    gpio.int_pins[IntPinNr::P05_0 as usize].enable_tertiary_function(); // A5
159    gpio.int_pins[IntPinNr::P04_7 as usize].enable_tertiary_function(); // A6
160    gpio.int_pins[IntPinNr::P04_6 as usize].enable_tertiary_function(); // A7
161    gpio.int_pins[IntPinNr::P04_5 as usize].enable_tertiary_function(); // A8
162    gpio.int_pins[IntPinNr::P04_4 as usize].enable_tertiary_function(); // A9
163    gpio.int_pins[IntPinNr::P04_3 as usize].enable_tertiary_function(); // A10
164    gpio.int_pins[IntPinNr::P04_2 as usize].enable_tertiary_function(); // A11
165    gpio.int_pins[IntPinNr::P04_1 as usize].enable_tertiary_function(); // A12
166    gpio.int_pins[IntPinNr::P04_0 as usize].enable_tertiary_function(); // A13
167    gpio.int_pins[IntPinNr::P06_1 as usize].enable_tertiary_function(); // A14
168    gpio.int_pins[IntPinNr::P06_0 as usize].enable_tertiary_function(); // A15
169    gpio.pins[PinNr::P09_1 as usize].enable_tertiary_function(); // A16
170    gpio.pins[PinNr::P09_0 as usize].enable_tertiary_function(); // A17
171    gpio.pins[PinNr::P08_7 as usize].enable_tertiary_function(); // A18
172    gpio.pins[PinNr::P08_6 as usize].enable_tertiary_function(); // A19
173    gpio.pins[PinNr::P08_5 as usize].enable_tertiary_function(); // A20
174    gpio.pins[PinNr::P08_4 as usize].enable_tertiary_function(); // A21
175
176    // Don't configure these pins since their channels are used for the internal
177    // temperature sensor (Channel 22) and the Battery Monitor (A23)
178    // gpio.pins[PinNr::P08_3 as usize].enable_tertiary_function(); // A22
179    // gpio.pins[PinNr::P08_2 as usize].enable_tertiary_function(); // A23
180}
181
182/// This is in a separate, inline(never) function so that its stack frame is
183/// removed when this function returns. Otherwise, the stack space used for
184/// these static_inits is wasted.
185#[inline(never)]
186unsafe fn start() -> (
187    &'static kernel::Kernel,
188    MspExp432P401R,
189    &'static msp432::chip::Msp432<'static, msp432::chip::Msp432DefaultPeripherals<'static>>,
190) {
191    startup_intilialisation();
192
193    // Initialize deferred calls very early.
194    kernel::deferred_call::initialize_deferred_call_state::<
195        <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
196    >();
197
198    // Bind global variables to this thread.
199    PANIC_RESOURCES.bind_to_thread::<<ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider>();
200
201    let peripherals = static_init!(
202        msp432::chip::Msp432DefaultPeripherals,
203        msp432::chip::Msp432DefaultPeripherals::new()
204    );
205    peripherals.init();
206
207    // Setup the GPIO pins to use the HFXT (high frequency external) oscillator (48MHz)
208    peripherals.gpio.pins[msp432::gpio::PinNr::PJ_2 as usize].enable_primary_function();
209    peripherals.gpio.pins[msp432::gpio::PinNr::PJ_3 as usize].enable_primary_function();
210
211    // Setup the GPIO pins to use the LFXT (low frequency external) oscillator (32.768kHz)
212    peripherals.gpio.pins[msp432::gpio::PinNr::PJ_0 as usize].enable_primary_function();
213    peripherals.gpio.pins[msp432::gpio::PinNr::PJ_1 as usize].enable_primary_function();
214
215    // Setup the clocks: MCLK: 48MHz, HSMCLK: 12MHz, SMCLK: 1.5MHz, ACLK: 32.768kHz
216    peripherals.cs.setup_clocks();
217
218    // Setup the debug GPIOs
219    let dbg_gpio0 = &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_0 as usize];
220    let dbg_gpio1 = &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_5 as usize];
221    let dbg_gpio2 = &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_7 as usize];
222    dbg_gpio0.make_output();
223    dbg_gpio1.make_output();
224    dbg_gpio2.make_output();
225    let debug_gpios = static_init!(
226        [&'static dyn kernel::hil::gpio::Pin; 3],
227        [
228            // Red LED
229            dbg_gpio0, dbg_gpio1, dbg_gpio2
230        ]
231    );
232    kernel::debug::initialize_debug_gpio::<
233        <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
234    >();
235    kernel::debug::assign_gpios(debug_gpios);
236
237    // Setup pins for UART0
238    peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_2 as usize].enable_primary_function();
239    peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_3 as usize].enable_primary_function();
240
241    // Create an array to hold process references.
242    let processes = components::process_array::ProcessArrayComponent::new()
243        .finalize(components::process_array_component_static!(NUM_PROCS));
244    PANIC_RESOURCES.get().map(|resources| {
245        resources.processes.put(processes.as_slice());
246    });
247
248    // Setup space to store the core kernel data structure.
249    let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes.as_slice()));
250
251    let chip = static_init!(
252        msp432::chip::Msp432<msp432::chip::Msp432DefaultPeripherals>,
253        msp432::chip::Msp432::new(peripherals)
254    );
255    PANIC_RESOURCES.get().map(|resources| {
256        resources.chip.put(chip);
257    });
258
259    // Setup buttons
260    let button = components::button::ButtonComponent::new(
261        board_kernel,
262        capsules_core::button::DRIVER_NUM,
263        components::button_component_helper!(
264            msp432::gpio::IntPin,
265            (
266                &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_1 as usize],
267                kernel::hil::gpio::ActivationMode::ActiveLow,
268                kernel::hil::gpio::FloatingState::PullUp
269            ),
270            (
271                &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_4 as usize],
272                kernel::hil::gpio::ActivationMode::ActiveLow,
273                kernel::hil::gpio::FloatingState::PullUp
274            )
275        ),
276    )
277    .finalize(components::button_component_static!(msp432::gpio::IntPin));
278
279    // Setup LEDs
280    let leds = components::led::LedsComponent::new().finalize(components::led_component_static!(
281        kernel::hil::led::LedHigh<'static, msp432::gpio::IntPin>,
282        kernel::hil::led::LedHigh::new(
283            &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_0 as usize]
284        ),
285        kernel::hil::led::LedHigh::new(
286            &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_1 as usize]
287        ),
288        kernel::hil::led::LedHigh::new(
289            &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_2 as usize]
290        ),
291    ));
292
293    // Setup user-GPIOs
294    let gpio = GpioComponent::new(
295        board_kernel,
296        capsules_core::gpio::DRIVER_NUM,
297        components::gpio_component_helper!(
298            msp432::gpio::IntPin<'static>,
299            // Left outer connector, top to bottom
300            // 0 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P06_0 as usize], // A15
301            1 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_2 as usize],
302            2 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_3 as usize],
303            // 3 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P04_1 as usize], // A12
304            // 4 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P04_3 as usize], // A10
305            5 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_5 as usize],
306            // 6 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P04_6 as usize], // A7
307            7 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P06_5 as usize],
308            8 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P06_4 as usize],
309            // Left inner connector, top to bottom
310            // 9 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P06_1 as usize], // A14
311            // 10 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P04_0 as usize], // A13
312            // 11 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P04_2 as usize], // A11
313            // 12 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P04_4 as usize], // A9
314            // 13 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P04_5 as usize], // A8
315            // 14 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P04_7 as usize], // A6
316            // 15 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P05_4 as usize], // A1
317            // 16 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P05_5 as usize], // A0
318            // Right inner connector, top to bottom
319            17 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_7 as usize],
320            18 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_6 as usize],
321            19 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_4 as usize],
322            20 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P05_6 as usize],
323            21 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P06_6 as usize],
324            22 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P06_7 as usize],
325            23 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_3 as usize],
326            // 24 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P05_1 as usize], // A4
327            // 25 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_5 as usize], // debug-gpio
328            // 26 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_7 as usize], // debug-gpio
329            // Right outer connector, top to bottom
330            27 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P02_5 as usize],
331            28 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_0 as usize],
332            29 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P05_7 as usize],
333            30 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_6 as usize],
334            31 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P01_7 as usize],
335            // 32 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P05_0 as usize], // A5
336            // 33 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P05_2 as usize], // A3
337            34 => &peripherals.gpio.int_pins[msp432::gpio::IntPinNr::P03_6 as usize]
338        ),
339    )
340    .finalize(components::gpio_component_static!(
341        msp432::gpio::IntPin<'static>
342    ));
343
344    let memory_allocation_capability = create_capability!(capabilities::MemoryAllocationCapability);
345    let process_management_capability =
346        create_capability!(capabilities::ProcessManagementCapability);
347
348    // Setup UART0
349    let uart_mux = components::console::UartMuxComponent::new(&peripherals.uart0, 115200)
350        .finalize(components::uart_mux_component_static!());
351
352    // Setup the console.
353    let console = components::console::ConsoleComponent::new(
354        board_kernel,
355        capsules_core::console::DRIVER_NUM,
356        uart_mux,
357    )
358    .finalize(components::console_component_static!());
359    // Create the debugger object that handles calls to `debug!()`.
360    components::debug_writer::DebugWriterComponent::new::<
361        <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
362    >(
363        uart_mux,
364        create_capability!(capabilities::SetDebugWriterCapability),
365    )
366    .finalize(components::debug_writer_component_static!());
367
368    // Setup alarm
369    let timer0 = &peripherals.timer_a0;
370    let mux_alarm = components::alarm::AlarmMuxComponent::new(timer0).finalize(
371        components::alarm_mux_component_static!(msp432::timer::TimerA),
372    );
373    let alarm = components::alarm::AlarmDriverComponent::new(
374        board_kernel,
375        capsules_core::alarm::DRIVER_NUM,
376        mux_alarm,
377    )
378    .finalize(components::alarm_component_static!(msp432::timer::TimerA));
379
380    // Setup ADC
381    setup_adc_pins(&peripherals.gpio);
382
383    let adc_channels = static_init!(
384        [msp432::adc::Channel; 24],
385        [
386            msp432::adc::Channel::Channel0,  // A0
387            msp432::adc::Channel::Channel1,  // A1
388            msp432::adc::Channel::Channel2,  // A2
389            msp432::adc::Channel::Channel3,  // A3
390            msp432::adc::Channel::Channel4,  // A4
391            msp432::adc::Channel::Channel5,  // A5
392            msp432::adc::Channel::Channel6,  // A6
393            msp432::adc::Channel::Channel7,  // A7
394            msp432::adc::Channel::Channel8,  // A8
395            msp432::adc::Channel::Channel9,  // A9
396            msp432::adc::Channel::Channel10, // A10
397            msp432::adc::Channel::Channel11, // A11
398            msp432::adc::Channel::Channel12, // A12
399            msp432::adc::Channel::Channel13, // A13
400            msp432::adc::Channel::Channel14, // A14
401            msp432::adc::Channel::Channel15, // A15
402            msp432::adc::Channel::Channel16, // A16
403            msp432::adc::Channel::Channel17, // A17
404            msp432::adc::Channel::Channel18, // A18
405            msp432::adc::Channel::Channel19, // A19
406            msp432::adc::Channel::Channel20, // A20
407            msp432::adc::Channel::Channel21, // A21
408            msp432::adc::Channel::Channel22, // A22
409            msp432::adc::Channel::Channel23, // A23
410        ]
411    );
412    let adc = components::adc::AdcDedicatedComponent::new(
413        &peripherals.adc,
414        adc_channels,
415        board_kernel,
416        capsules_core::adc::DRIVER_NUM,
417    )
418    .finalize(components::adc_dedicated_component_static!(
419        msp432::adc::Adc
420    ));
421
422    // Set the reference voltage for the ADC to 2.5V
423    peripherals
424        .adc_ref
425        .select_ref_voltage(msp432::ref_module::ReferenceVoltage::Volt2_5);
426    // Enable the internal temperature sensor on ADC Channel 22
427    peripherals.adc_ref.enable_temp_sensor(true);
428
429    let scheduler = components::sched::round_robin::RoundRobinComponent::new(processes)
430        .finalize(components::round_robin_component_static!(NUM_PROCS));
431
432    let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
433        .finalize(components::process_printer_text_component_static!());
434    PANIC_RESOURCES.get().map(|resources| {
435        resources.printer.put(process_printer);
436    });
437
438    let msp_exp432p4014 = MspExp432P401R {
439        led: leds,
440        console,
441        button,
442        gpio,
443        alarm,
444        ipc: kernel::ipc::IPC::new(
445            board_kernel,
446            kernel::ipc::DRIVER_NUM,
447            &memory_allocation_capability,
448        ),
449        adc,
450        scheduler,
451        systick: cortexm4::systick::SysTick::new_with_calibration(48_000_000),
452        wdt: &peripherals.wdt,
453    };
454
455    debug!("Initialization complete. Entering main loop");
456
457    // These symbols are defined in the linker script.
458    extern "C" {
459        /// Beginning of the ROM region containing app images.
460        static _sapps: u8;
461        /// End of the ROM region containing app images.
462        static _eapps: u8;
463        /// Beginning of the RAM region for app memory.
464        static mut _sappmem: u8;
465        /// End of the RAM region for app memory.
466        static _eappmem: u8;
467    }
468
469    kernel::process::load_processes(
470        board_kernel,
471        chip,
472        core::slice::from_raw_parts(
473            core::ptr::addr_of!(_sapps),
474            core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
475        ),
476        core::slice::from_raw_parts_mut(
477            core::ptr::addr_of_mut!(_sappmem),
478            core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
479        ),
480        &FAULT_RESPONSE,
481        &process_management_capability,
482    )
483    .unwrap();
484
485    //Uncomment to run multi alarm test
486    /*components::test::multi_alarm_test::MultiAlarmTestComponent::new(mux_alarm)
487    .finalize(components::multi_alarm_test_component_buf!(msp432::timer::TimerA))
488    .run();*/
489
490    (board_kernel, msp_exp432p4014, chip)
491}
492
493/// Main function called after RAM initialized.
494#[no_mangle]
495pub unsafe fn main() {
496    let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
497
498    let (board_kernel, board, chip) = start();
499    board_kernel.kernel_loop(&board, chip, Some(&board.ipc), &main_loop_capability);
500}