1#![no_std]
11#![no_main]
12#![deny(missing_docs)]
13
14mod imix_components;
15
16use capsules_core::alarm::AlarmDriver;
17use capsules_core::console_ordered::ConsoleOrdered;
18use capsules_core::virtualizers::virtual_aes_ccm::MuxAES128CCM;
19use capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm;
20use capsules_core::virtualizers::virtual_i2c::MuxI2C;
21use capsules_core::virtualizers::virtual_spi::VirtualSpiMasterDevice;
22use capsules_extra::net::ieee802154::MacAddress;
23use capsules_extra::net::ipv6::ip_utils::IPAddr;
24use kernel::capabilities;
25use kernel::component::Component;
26use kernel::deferred_call::DeferredCallClient;
27use kernel::hil::i2c::I2CMaster;
28use kernel::hil::radio;
29#[allow(unused_imports)]
30use kernel::hil::radio::{RadioConfig, RadioData};
31use kernel::hil::symmetric_encryption::AES128;
32use kernel::platform::{KernelResources, SyscallDriverLookup};
33use kernel::process::ProcessArray;
34use kernel::scheduler::round_robin::RoundRobinSched;
35
36use kernel::hil::led::LedHigh;
38use kernel::hil::Controller;
39#[allow(unused_imports)]
40use kernel::{create_capability, debug, debug_gpio, static_buf, static_init};
41use sam4l::chip::Sam4lDefaultPeripherals;
42
43use components::alarm::{AlarmDriverComponent, AlarmMuxComponent};
44use components::console::{ConsoleOrderedComponent, UartMuxComponent};
45use components::crc::CrcComponent;
46use components::debug_writer::DebugWriterComponent;
47use components::gpio::GpioComponent;
48use components::isl29035::AmbientLightComponent;
49use components::isl29035::Isl29035Component;
50use components::led::LedsComponent;
51use components::nrf51822::Nrf51822Component;
52use components::process_console::ProcessConsoleComponent;
53use components::rng::RngComponent;
54use components::si7021::SI7021Component;
55use components::spi::{SpiComponent, SpiSyscallComponent};
56
57pub mod io;
61
62#[allow(dead_code)]
64mod test;
65
66mod power;
68
69#[allow(dead_code)]
70mod alarm_test;
71
72#[allow(dead_code)]
73mod multi_timer_test;
74
75const NUM_PROCS: usize = 4;
78
79const RADIO_CHANNEL: radio::RadioChannel = radio::RadioChannel::Channel26;
88const DST_MAC_ADDR: MacAddress = MacAddress::Short(49138);
89const DEFAULT_CTX_PREFIX_LEN: u8 = 8; const DEFAULT_CTX_PREFIX: [u8; 16] = [0x0_u8; 16]; const PAN_ID: u16 = 0xABCD;
92
93const FAULT_RESPONSE: capsules_system::process_policies::StopFaultPolicy =
95    capsules_system::process_policies::StopFaultPolicy {};
96
97type ChipHw = sam4l::chip::Sam4l<Sam4lDefaultPeripherals>;
98
99static mut PROCESSES: Option<&'static ProcessArray<NUM_PROCS>> = None;
101static mut CHIP: Option<&'static sam4l::chip::Sam4l<Sam4lDefaultPeripherals>> = None;
102static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::ProcessPrinterText> =
103    None;
104
105kernel::stack_size! {0x2000}
106
107type SI7021Sensor = components::si7021::SI7021ComponentType<
108    capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, sam4l::ast::Ast<'static>>,
109    capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, sam4l::i2c::I2CHw<'static>>,
110>;
111type TemperatureDriver = components::temperature::TemperatureComponentType<SI7021Sensor>;
112type HumidityDriver = components::humidity::HumidityComponentType<SI7021Sensor>;
113type RngDriver = components::rng::RngComponentType<sam4l::trng::Trng<'static>>;
114
115type Rf233 = capsules_extra::rf233::RF233<
116    'static,
117    VirtualSpiMasterDevice<'static, sam4l::spi::SpiHw<'static>>,
118>;
119type Ieee802154MacDevice =
120    components::ieee802154::Ieee802154ComponentMacDeviceType<Rf233, sam4l::aes::Aes<'static>>;
121
122struct Imix {
123    pconsole: &'static capsules_core::process_console::ProcessConsole<
124        'static,
125        { capsules_core::process_console::DEFAULT_COMMAND_HISTORY_LEN },
126        capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
127            'static,
128            sam4l::ast::Ast<'static>,
129        >,
130        components::process_console::Capability,
131    >,
132    console: &'static capsules_core::console_ordered::ConsoleOrdered<
133        'static,
134        VirtualMuxAlarm<'static, sam4l::ast::Ast<'static>>,
135    >,
136    gpio: &'static capsules_core::gpio::GPIO<'static, sam4l::gpio::GPIOPin<'static>>,
137    alarm: &'static AlarmDriver<'static, VirtualMuxAlarm<'static, sam4l::ast::Ast<'static>>>,
138    temp: &'static TemperatureDriver,
139    humidity: &'static HumidityDriver,
140    ambient_light: &'static capsules_extra::ambient_light::AmbientLight<'static>,
141    adc: &'static capsules_core::adc::AdcDedicated<'static, sam4l::adc::Adc<'static>>,
142    led: &'static capsules_core::led::LedDriver<
143        'static,
144        LedHigh<'static, sam4l::gpio::GPIOPin<'static>>,
145        1,
146    >,
147    button: &'static capsules_core::button::Button<'static, sam4l::gpio::GPIOPin<'static>>,
148    rng: &'static RngDriver,
149    analog_comparator: &'static capsules_extra::analog_comparator::AnalogComparator<
150        'static,
151        sam4l::acifc::Acifc<'static>,
152    >,
153    spi: &'static capsules_core::spi_controller::Spi<
154        'static,
155        VirtualSpiMasterDevice<'static, sam4l::spi::SpiHw<'static>>,
156    >,
157    ipc: kernel::ipc::IPC<{ NUM_PROCS as u8 }>,
158    ninedof: &'static capsules_extra::ninedof::NineDof<'static>,
159    udp_driver: &'static capsules_extra::net::udp::UDPDriver<'static>,
160    crc: &'static capsules_extra::crc::CrcDriver<'static, sam4l::crccu::Crccu<'static>>,
161    usb_driver: &'static capsules_extra::usb::usb_user::UsbSyscallDriver<
162        'static,
163        capsules_extra::usb::usbc_client::Client<'static, sam4l::usbc::Usbc<'static>>,
164    >,
165    nrf51822: &'static capsules_extra::nrf51822_serialization::Nrf51822Serialization<'static>,
166    nonvolatile_storage:
167        &'static capsules_extra::nonvolatile_storage_driver::NonvolatileStorage<'static>,
168    scheduler: &'static RoundRobinSched<'static>,
169    systick: cortexm4::systick::SysTick,
170}
171
172impl SyscallDriverLookup for Imix {
173    fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
174    where
175        F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
176    {
177        match driver_num {
178            capsules_core::console_ordered::DRIVER_NUM => f(Some(self.console)),
179            capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
180            capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
181            capsules_core::spi_controller::DRIVER_NUM => f(Some(self.spi)),
182            capsules_core::adc::DRIVER_NUM => f(Some(self.adc)),
183            capsules_core::led::DRIVER_NUM => f(Some(self.led)),
184            capsules_core::button::DRIVER_NUM => f(Some(self.button)),
185            capsules_extra::analog_comparator::DRIVER_NUM => f(Some(self.analog_comparator)),
186            capsules_extra::ambient_light::DRIVER_NUM => f(Some(self.ambient_light)),
187            capsules_extra::temperature::DRIVER_NUM => f(Some(self.temp)),
188            capsules_extra::humidity::DRIVER_NUM => f(Some(self.humidity)),
189            capsules_extra::ninedof::DRIVER_NUM => f(Some(self.ninedof)),
190            capsules_extra::crc::DRIVER_NUM => f(Some(self.crc)),
191            capsules_extra::usb::usb_user::DRIVER_NUM => f(Some(self.usb_driver)),
192            capsules_extra::net::udp::DRIVER_NUM => f(Some(self.udp_driver)),
193            capsules_extra::nrf51822_serialization::DRIVER_NUM => f(Some(self.nrf51822)),
194            capsules_extra::nonvolatile_storage_driver::DRIVER_NUM => {
195                f(Some(self.nonvolatile_storage))
196            }
197            capsules_core::rng::DRIVER_NUM => f(Some(self.rng)),
198            kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
199            _ => f(None),
200        }
201    }
202}
203
204impl KernelResources<sam4l::chip::Sam4l<Sam4lDefaultPeripherals>> for Imix {
205    type SyscallDriverLookup = Self;
206    type SyscallFilter = ();
207    type ProcessFault = ();
208    type Scheduler = RoundRobinSched<'static>;
209    type SchedulerTimer = cortexm4::systick::SysTick;
210    type WatchDog = ();
211    type ContextSwitchCallback = ();
212
213    fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
214        self
215    }
216    fn syscall_filter(&self) -> &Self::SyscallFilter {
217        &()
218    }
219    fn process_fault(&self) -> &Self::ProcessFault {
220        &()
221    }
222    fn scheduler(&self) -> &Self::Scheduler {
223        self.scheduler
224    }
225    fn scheduler_timer(&self) -> &Self::SchedulerTimer {
226        &self.systick
227    }
228    fn watchdog(&self) -> &Self::WatchDog {
229        &()
230    }
231    fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
232        &()
233    }
234}
235
236unsafe fn set_pin_primary_functions(peripherals: &Sam4lDefaultPeripherals) {
237    use sam4l::gpio::PeripheralFunction::{A, B, C, E};
238
239    peripherals.pa[04].configure(Some(A)); peripherals.pa[05].configure(Some(A)); peripherals.pa[06].configure(Some(C)); peripherals.pa[07].configure(Some(A)); peripherals.pa[08].configure(None); peripherals.pa[09].configure(None); peripherals.pa[10].configure(None); peripherals.pa[13].configure(None); peripherals.pa[14].configure(None); peripherals.pa[17].configure(None); peripherals.pa[18].configure(Some(A)); peripherals.pa[20].configure(None); peripherals.pa[21].configure(Some(E)); peripherals.pa[22].configure(Some(E)); peripherals.pa[25].configure(Some(A)); peripherals.pa[26].configure(Some(A)); peripherals.pb[00].configure(Some(A)); peripherals.pb[01].configure(Some(A)); peripherals.pb[02].configure(Some(A)); peripherals.pb[03].configure(Some(A)); peripherals.pb[04].configure(Some(A)); peripherals.pb[05].configure(Some(A)); peripherals.pb[06].configure(Some(A)); peripherals.pb[07].configure(None); peripherals.pb[09].configure(Some(A)); peripherals.pb[10].configure(Some(A)); peripherals.pb[11].configure(Some(A)); peripherals.pb[12].configure(Some(A)); peripherals.pb[13].configure(Some(A)); peripherals.pb[14].configure(Some(A)); peripherals.pb[15].configure(Some(A)); peripherals.pc[00].configure(Some(A)); peripherals.pc[01].configure(Some(A)); peripherals.pc[02].configure(Some(A)); peripherals.pc[03].configure(Some(A)); peripherals.pc[04].configure(Some(A)); peripherals.pc[05].configure(Some(A)); peripherals.pc[06].configure(Some(A)); peripherals.pc[07].configure(Some(B)); peripherals.pc[08].configure(Some(E)); peripherals.pc[09].configure(Some(E)); peripherals.pc[10].configure(Some(E)); peripherals.pc[11].configure(Some(B)); peripherals.pc[12].configure(Some(B)); peripherals.pc[13].configure(Some(E)); peripherals.pc[14].configure(Some(E)); peripherals.pc[16].configure(None); peripherals.pc[17].configure(None); peripherals.pc[18].configure(None); peripherals.pc[19].configure(None); peripherals.pc[22].configure(None); peripherals.pc[24].configure(None); peripherals.pc[25].configure(Some(B)); peripherals.pc[26].configure(None); peripherals.pc[27].configure(None); peripherals.pc[28].configure(None); peripherals.pc[29].configure(None); peripherals.pc[30].configure(None); peripherals.pc[31].configure(None); }
305
306#[inline(never)]
310unsafe fn start() -> (
311    &'static kernel::Kernel,
312    Imix,
313    &'static sam4l::chip::Sam4l<Sam4lDefaultPeripherals>,
314) {
315    sam4l::init();
316    let pm = static_init!(sam4l::pm::PowerManager, sam4l::pm::PowerManager::new());
317    let peripherals = static_init!(Sam4lDefaultPeripherals, Sam4lDefaultPeripherals::new(pm));
318
319    pm.setup_system_clock(
320        sam4l::pm::SystemClockSource::PllExternalOscillatorAt48MHz {
321            frequency: sam4l::pm::OscillatorFrequency::Frequency16MHz,
322            startup_mode: sam4l::pm::OscillatorStartup::FastStart,
323        },
324        &peripherals.flash_controller,
325    );
326
327    sam4l::bpm::set_ck32source(sam4l::bpm::CK32Source::RC32K);
329
330    set_pin_primary_functions(peripherals);
331
332    peripherals.setup_circular_deps();
333    let chip = static_init!(
334        sam4l::chip::Sam4l<Sam4lDefaultPeripherals>,
335        sam4l::chip::Sam4l::new(pm, peripherals)
336    );
337    CHIP = Some(chip);
338
339    let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
342
343    power::configure_submodules(
344        &peripherals.pa,
345        &peripherals.pb,
346        &peripherals.pc,
347        power::SubmoduleConfig {
348            rf233: true,
349            nrf51422: true,
350            sensors: true,
351            trng: true,
352        },
353    );
354
355    let processes = components::process_array::ProcessArrayComponent::new()
357        .finalize(components::process_array_component_static!(NUM_PROCS));
358    PROCESSES = Some(processes);
359
360    let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes.as_slice()));
362
363    let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
364        .finalize(components::process_printer_text_component_static!());
365    PROCESS_PRINTER = Some(process_printer);
366
367    peripherals.usart3.set_mode(sam4l::usart::UsartMode::Uart);
370    let uart_mux = UartMuxComponent::new(&peripherals.usart3, 115200)
371        .finalize(components::uart_mux_component_static!());
372
373    let mux_alarm = AlarmMuxComponent::new(&peripherals.ast)
375        .finalize(components::alarm_mux_component_static!(sam4l::ast::Ast));
376    peripherals.ast.configure(mux_alarm);
377
378    let alarm =
379        AlarmDriverComponent::new(board_kernel, capsules_core::alarm::DRIVER_NUM, mux_alarm)
380            .finalize(components::alarm_component_static!(sam4l::ast::Ast));
381
382    let pconsole = ProcessConsoleComponent::new(
383        board_kernel,
384        uart_mux,
385        mux_alarm,
386        process_printer,
387        Some(cortexm4::support::reset),
388    )
389    .finalize(components::process_console_component_static!(
390        sam4l::ast::Ast
391    ));
392
393    let console = ConsoleOrderedComponent::new(
394        board_kernel,
395        capsules_core::console_ordered::DRIVER_NUM,
396        uart_mux,
397        mux_alarm,
398        200,
399        5,
400        5,
401    )
402    .finalize(components::console_ordered_component_static!(
403        sam4l::ast::Ast
404    ));
405    DebugWriterComponent::new::<<ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider>(
406        uart_mux,
407        create_capability!(capabilities::SetDebugWriterCapability),
408    )
409    .finalize(components::debug_writer_component_static!());
410
411    peripherals.usart2.set_mode(sam4l::usart::UsartMode::Uart);
413    let nrf_serialization = Nrf51822Component::new(
414        board_kernel,
415        capsules_extra::nrf51822_serialization::DRIVER_NUM,
416        &peripherals.usart2,
417        &peripherals.pb[07],
418    )
419    .finalize(components::nrf51822_component_static!());
420
421    let mux_i2c = static_init!(
423        MuxI2C<'static, sam4l::i2c::I2CHw<'static>>,
424        MuxI2C::new(&peripherals.i2c2, None)
425    );
426    kernel::deferred_call::DeferredCallClient::register(mux_i2c);
427    peripherals.i2c2.set_master_client(mux_i2c);
428
429    let isl29035 = Isl29035Component::new(mux_i2c, mux_alarm).finalize(
430        components::isl29035_component_static!(sam4l::ast::Ast, sam4l::i2c::I2CHw<'static>),
431    );
432    let ambient_light = AmbientLightComponent::new(
433        board_kernel,
434        capsules_extra::ambient_light::DRIVER_NUM,
435        isl29035,
436    )
437    .finalize(components::ambient_light_component_static!());
438
439    let si7021 = SI7021Component::new(mux_i2c, mux_alarm, 0x40).finalize(
440        components::si7021_component_static!(sam4l::ast::Ast, sam4l::i2c::I2CHw<'static>),
441    );
442    let temp = components::temperature::TemperatureComponent::new(
443        board_kernel,
444        capsules_extra::temperature::DRIVER_NUM,
445        si7021,
446    )
447    .finalize(components::temperature_component_static!(SI7021Sensor));
448    let humidity = components::humidity::HumidityComponent::new(
449        board_kernel,
450        capsules_extra::humidity::DRIVER_NUM,
451        si7021,
452    )
453    .finalize(components::humidity_component_static!(SI7021Sensor));
454
455    let fxos8700 = components::fxos8700::Fxos8700Component::new(mux_i2c, 0x1e, &peripherals.pc[13])
456        .finalize(components::fxos8700_component_static!(
457            sam4l::i2c::I2CHw<'static>
458        ));
459
460    let ninedof = components::ninedof::NineDofComponent::new(
461        board_kernel,
462        capsules_extra::ninedof::DRIVER_NUM,
463    )
464    .finalize(components::ninedof_component_static!(fxos8700));
465
466    let mux_spi = components::spi::SpiMuxComponent::new(&peripherals.spi).finalize(
468        components::spi_mux_component_static!(sam4l::spi::SpiHw<'static>),
469    );
470
471    let spi_syscalls = SpiSyscallComponent::new(
472        board_kernel,
473        mux_spi,
474        sam4l::spi::Peripheral::Peripheral2,
475        capsules_core::spi_controller::DRIVER_NUM,
476    )
477    .finalize(components::spi_syscall_component_static!(
478        sam4l::spi::SpiHw<'static>
479    ));
480    let rf233_spi = SpiComponent::new(mux_spi, sam4l::spi::Peripheral::Peripheral3).finalize(
481        components::spi_component_static!(sam4l::spi::SpiHw<'static>),
482    );
483    let rf233 = components::rf233::RF233Component::new(
484        rf233_spi,
485        &peripherals.pa[09], &peripherals.pa[10], &peripherals.pa[08], &peripherals.pa[08],
489        RADIO_CHANNEL,
490    )
491    .finalize(components::rf233_component_static!(
492        sam4l::spi::SpiHw<'static>
493    ));
494
495    let adc_channels = static_init!(
497        [sam4l::adc::AdcChannel; 6],
498        [
499            sam4l::adc::AdcChannel::new(sam4l::adc::Channel::AD1), sam4l::adc::AdcChannel::new(sam4l::adc::Channel::AD2), sam4l::adc::AdcChannel::new(sam4l::adc::Channel::AD3), sam4l::adc::AdcChannel::new(sam4l::adc::Channel::AD4), sam4l::adc::AdcChannel::new(sam4l::adc::Channel::AD5), sam4l::adc::AdcChannel::new(sam4l::adc::Channel::AD6), ]
506    );
507    let adc = components::adc::AdcDedicatedComponent::new(
508        &peripherals.adc,
509        adc_channels,
510        board_kernel,
511        capsules_core::adc::DRIVER_NUM,
512    )
513    .finalize(components::adc_dedicated_component_static!(sam4l::adc::Adc));
514
515    let gpio = GpioComponent::new(
516        board_kernel,
517        capsules_core::gpio::DRIVER_NUM,
518        components::gpio_component_helper!(
519            sam4l::gpio::GPIOPin,
520            0 => &peripherals.pc[31],
521            1 => &peripherals.pc[30],
522            2 => &peripherals.pc[29],
523            3 => &peripherals.pc[28],
524            4 => &peripherals.pc[27],
525            5 => &peripherals.pc[26],
526            6 => &peripherals.pa[20]
527        ),
528    )
529    .finalize(components::gpio_component_static!(sam4l::gpio::GPIOPin));
530
531    let led = LedsComponent::new().finalize(components::led_component_static!(
532        LedHigh<'static, sam4l::gpio::GPIOPin>,
533        LedHigh::new(&peripherals.pc[10]),
534    ));
535
536    let button = components::button::ButtonComponent::new(
537        board_kernel,
538        capsules_core::button::DRIVER_NUM,
539        components::button_component_helper!(
540            sam4l::gpio::GPIOPin,
541            (
542                &peripherals.pc[24],
543                kernel::hil::gpio::ActivationMode::ActiveLow,
544                kernel::hil::gpio::FloatingState::PullNone
545            )
546        ),
547    )
548    .finalize(components::button_component_static!(sam4l::gpio::GPIOPin));
549
550    let crc = CrcComponent::new(
551        board_kernel,
552        capsules_extra::crc::DRIVER_NUM,
553        &peripherals.crccu,
554    )
555    .finalize(components::crc_component_static!(sam4l::crccu::Crccu));
556
557    let ac_0 = static_init!(
558        sam4l::acifc::AcChannel,
559        sam4l::acifc::AcChannel::new(sam4l::acifc::Channel::AC0)
560    );
561    let ac_1 = static_init!(
562        sam4l::acifc::AcChannel,
563        sam4l::acifc::AcChannel::new(sam4l::acifc::Channel::AC0)
564    );
565    let ac_2 = static_init!(
566        sam4l::acifc::AcChannel,
567        sam4l::acifc::AcChannel::new(sam4l::acifc::Channel::AC0)
568    );
569    let ac_3 = static_init!(
570        sam4l::acifc::AcChannel,
571        sam4l::acifc::AcChannel::new(sam4l::acifc::Channel::AC0)
572    );
573    let analog_comparator = components::analog_comparator::AnalogComparatorComponent::new(
574        &peripherals.acifc,
575        components::analog_comparator_component_helper!(
576            <sam4l::acifc::Acifc as kernel::hil::analog_comparator::AnalogComparator>::Channel,
577            ac_0,
578            ac_1,
579            ac_2,
580            ac_3
581        ),
582        board_kernel,
583        capsules_extra::analog_comparator::DRIVER_NUM,
584    )
585    .finalize(components::analog_comparator_component_static!(
586        sam4l::acifc::Acifc
587    ));
588    let rng = RngComponent::new(
589        board_kernel,
590        capsules_core::rng::DRIVER_NUM,
591        &peripherals.trng,
592    )
593    .finalize(components::rng_component_static!(sam4l::trng::Trng));
594
595    let serial_num: sam4l::serial_num::SerialNum = sam4l::serial_num::SerialNum::new();
601    let serial_num_bottom_16 = (serial_num.get_lower_64() & 0x0000_0000_0000_ffff) as u16;
602    let src_mac_from_serial_num: MacAddress = MacAddress::Short(serial_num_bottom_16);
603    const DEFAULT_EXT_SRC_MAC: [u8; 8] = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77];
604
605    let aes_mux = static_init!(
606        MuxAES128CCM<'static, sam4l::aes::Aes>,
607        MuxAES128CCM::new(&peripherals.aes)
608    );
609    aes_mux.register();
610    peripherals.aes.set_client(aes_mux);
611
612    let (_, mux_mac) = components::ieee802154::Ieee802154Component::new(
613        board_kernel,
614        capsules_extra::ieee802154::DRIVER_NUM,
615        rf233,
616        aes_mux,
617        PAN_ID,
618        serial_num_bottom_16,
619        DEFAULT_EXT_SRC_MAC,
620    )
621    .finalize(components::ieee802154_component_static!(
622        capsules_extra::rf233::RF233<
623            'static,
624            VirtualSpiMasterDevice<'static, sam4l::spi::SpiHw<'static>>,
625        >,
626        sam4l::aes::Aes<'static>
627    ));
628
629    let usb_driver = components::usb::UsbComponent::new(
630        board_kernel,
631        capsules_extra::usb::usb_user::DRIVER_NUM,
632        &peripherals.usbc,
633    )
634    .finalize(components::usb_component_static!(sam4l::usbc::Usbc));
635
636    extern "C" {
639        static _sstorage: u8;
641        static _estorage: u8;
642    }
643
644    let nonvolatile_storage = components::nonvolatile_storage::NonvolatileStorageComponent::new(
645        board_kernel,
646        capsules_extra::nonvolatile_storage_driver::DRIVER_NUM,
647        &peripherals.flash_controller,
648        0x60000, 0x20000, core::ptr::addr_of!(_sstorage) as usize, core::ptr::addr_of!(_estorage) as usize - core::ptr::addr_of!(_sstorage) as usize, )
653    .finalize(components::nonvolatile_storage_component_static!(
654        sam4l::flashcalw::FLASHCALW
655    ));
656
657    let local_ip_ifaces = static_init!(
658        [IPAddr; 3],
659        [
660            IPAddr([
661                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
662                0x0e, 0x0f,
663            ]),
664            IPAddr([
665                0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
666                0x1e, 0x1f,
667            ]),
668            IPAddr::generate_from_mac(src_mac_from_serial_num),
669        ]
670    );
671
672    let (udp_send_mux, udp_recv_mux, udp_port_table) = components::udp_mux::UDPMuxComponent::new(
673        mux_mac,
674        DEFAULT_CTX_PREFIX_LEN,
675        DEFAULT_CTX_PREFIX,
676        DST_MAC_ADDR,
677        src_mac_from_serial_num, local_ip_ifaces,
680        mux_alarm,
681    )
682    .finalize(components::udp_mux_component_static!(
683        sam4l::ast::Ast,
684        Ieee802154MacDevice
685    ));
686
687    let udp_driver = components::udp_driver::UDPDriverComponent::new(
689        board_kernel,
690        capsules_extra::net::udp::driver::DRIVER_NUM,
691        udp_send_mux,
692        udp_recv_mux,
693        udp_port_table,
694        local_ip_ifaces,
695    )
696    .finalize(components::udp_driver_component_static!(sam4l::ast::Ast));
697
698    let scheduler = components::sched::round_robin::RoundRobinComponent::new(processes)
699        .finalize(components::round_robin_component_static!(NUM_PROCS));
700
701    let sha = components::sha::ShaSoftware256Component::new()
703        .finalize(components::sha_software_256_component_static!());
704
705    let checking_policy = components::appid::checker_sha::AppCheckerSha256Component::new(sha)
707        .finalize(components::app_checker_sha256_component_static!());
708
709    let assigner = components::appid::assigner_name::AppIdAssignerNamesComponent::new()
711        .finalize(components::appid_assigner_names_component_static!());
712
713    let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
715        .finalize(components::process_checker_machine_component_static!());
716
717    let storage_permissions_policy =
722        components::storage_permissions::individual::StoragePermissionsIndividualComponent::new()
723            .finalize(
724                components::storage_permissions_individual_component_static!(
725                    sam4l::chip::Sam4l<Sam4lDefaultPeripherals>,
726                    kernel::process::ProcessStandardDebugFull,
727                ),
728            );
729
730    extern "C" {
736        static _sapps: u8;
738        static _eapps: u8;
740        static mut _sappmem: u8;
742        static _eappmem: u8;
744    }
745
746    let app_flash = core::slice::from_raw_parts(
747        core::ptr::addr_of!(_sapps),
748        core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
749    );
750    let app_memory = core::slice::from_raw_parts_mut(
751        core::ptr::addr_of_mut!(_sappmem),
752        core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
753    );
754
755    let _loader = components::loader::sequential::ProcessLoaderSequentialComponent::new(
757        checker,
758        board_kernel,
759        chip,
760        &FAULT_RESPONSE,
761        assigner,
762        storage_permissions_policy,
763        app_flash,
764        app_memory,
765    )
766    .finalize(components::process_loader_sequential_component_static!(
767        sam4l::chip::Sam4l<Sam4lDefaultPeripherals>,
768        kernel::process::ProcessStandardDebugFull,
769        NUM_PROCS
770    ));
771
772    let imix = Imix {
773        pconsole,
774        console,
775        alarm,
776        gpio,
777        temp,
778        humidity,
779        ambient_light,
780        adc,
781        led,
782        button,
783        rng,
784        analog_comparator,
785        crc,
786        spi: spi_syscalls,
787        ipc: kernel::ipc::IPC::new(board_kernel, kernel::ipc::DRIVER_NUM, &grant_cap),
788        ninedof,
789        udp_driver,
790        usb_driver,
791        nrf51822: nrf_serialization,
792        nonvolatile_storage,
793        scheduler,
794        systick: cortexm4::systick::SysTick::new(),
795    };
796
797    imix.nrf51822.initialize();
799
800    let _ = rf233.reset();
803    let _ = rf233.start();
804
805    let _ = imix.pconsole.start();
806
807    debug!("Initialization complete. Entering main loop");
857
858    (board_kernel, imix, chip)
859}
860
861#[no_mangle]
863pub unsafe fn main() {
864    let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
865
866    let (board_kernel, platform, chip) = start();
867    board_kernel.kernel_loop(&platform, chip, Some(&platform.ipc), &main_loop_capability);
868}