1#![no_std]
10#![no_main]
11#![deny(missing_docs)]
12
13use core::ptr::addr_of;
14
15use kernel::capabilities;
16use kernel::component::Component;
17use kernel::hil::time::Counter;
18use kernel::platform::{KernelResources, SyscallDriverLookup};
19use kernel::process::ProcessArray;
20use kernel::scheduler::round_robin::RoundRobinSched;
21
22#[allow(unused_imports)]
23use kernel::{create_capability, debug, debug_gpio, debug_verbose, static_init};
24
25use nrf52833::gpio::Pin;
26use nrf52833::interrupt_service::Nrf52833DefaultPeripherals;
27
28const LED_KERNEL_PIN: Pin = Pin::P0_20;
30const LED_MICROPHONE_PIN: Pin = Pin::P0_20;
31
32const BUTTON_A: Pin = Pin::P0_14;
34const BUTTON_B: Pin = Pin::P0_23;
35const TOUCH_LOGO: Pin = Pin::P1_04;
36
37const _GPIO_P0: Pin = Pin::P0_02;
41const _GPIO_P1: Pin = Pin::P0_03;
42const _GPIO_P2: Pin = Pin::P0_04;
43const GPIO_P8: Pin = Pin::P0_10;
44const GPIO_P9: Pin = Pin::P0_09;
45const GPIO_P16: Pin = Pin::P1_02;
46
47const UART_TX_PIN: Pin = Pin::P0_06;
48const UART_RX_PIN: Pin = Pin::P1_08;
49
50const LED_MATRIX_COLS: [Pin; 5] = [Pin::P0_28, Pin::P0_11, Pin::P0_31, Pin::P1_05, Pin::P0_30];
52const LED_MATRIX_ROWS: [Pin; 5] = [Pin::P0_21, Pin::P0_22, Pin::P0_15, Pin::P0_24, Pin::P0_19];
53
54const SPEAKER_PIN: Pin = Pin::P0_00;
57
58const I2C_SDA_PIN: Pin = Pin::P0_16;
60const I2C_SCL_PIN: Pin = Pin::P0_08;
61
62pub mod io;
64
65const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
68    capsules_system::process_policies::PanicFaultPolicy {};
69
70const NUM_PROCS: usize = 4;
72
73type ChipHw = nrf52833::chip::NRF52<'static, Nrf52833DefaultPeripherals<'static>>;
74
75static mut PROCESSES: Option<&'static ProcessArray<NUM_PROCS>> = None;
77static mut CHIP: Option<&'static nrf52833::chip::NRF52<Nrf52833DefaultPeripherals>> = None;
78static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::ProcessPrinterText> =
79    None;
80
81kernel::stack_size! {0x2000}
82
83type TemperatureDriver =
84    components::temperature::TemperatureComponentType<nrf52::temperature::Temp<'static>>;
85type RngDriver = components::rng::RngComponentType<nrf52833::trng::Trng<'static>>;
86type Ieee802154RawDriver =
87    components::ieee802154::Ieee802154RawComponentType<nrf52833::ieee802154_radio::Radio<'static>>;
88type NonVolatilePages = components::dynamic_binary_storage::NVPages<nrf52833::nvmc::Nvmc>;
89type DynamicBinaryStorage<'a> = kernel::dynamic_binary_storage::SequentialDynamicBinaryStorage<
90    'static,
91    'static,
92    nrf52833::chip::NRF52<'a, Nrf52833DefaultPeripherals<'a>>,
93    kernel::process::ProcessStandardDebugFull,
94    NonVolatilePages,
95>;
96pub struct MicroBit {
98    ble_radio: &'static capsules_extra::ble_advertising_driver::BLE<
99        'static,
100        nrf52::ble_radio::Radio<'static>,
101        capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
102            'static,
103            nrf52::rtc::Rtc<'static>,
104        >,
105    >,
106    eui64: &'static capsules_extra::eui64::Eui64,
107    ieee802154: &'static Ieee802154RawDriver,
108    console: &'static capsules_core::console::Console<'static>,
109    gpio: &'static capsules_core::gpio::GPIO<'static, nrf52::gpio::GPIOPin<'static>>,
110    led: &'static capsules_core::led::LedDriver<
111        'static,
112        capsules_extra::led_matrix::LedMatrixLed<
113            'static,
114            nrf52::gpio::GPIOPin<'static>,
115            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
116                'static,
117                nrf52::rtc::Rtc<'static>,
118            >,
119        >,
120        25,
121    >,
122    button: &'static capsules_core::button::Button<'static, nrf52::gpio::GPIOPin<'static>>,
123    rng: &'static RngDriver,
124    ninedof: &'static capsules_extra::ninedof::NineDof<'static>,
125    lsm303agr: &'static capsules_extra::lsm303agr::Lsm303agrI2C<
126        'static,
127        capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, nrf52833::i2c::TWI<'static>>,
128    >,
129    temperature: &'static TemperatureDriver,
130    ipc: kernel::ipc::IPC<{ NUM_PROCS as u8 }>,
131    adc: &'static capsules_core::adc::AdcVirtualized<'static>,
132    alarm: &'static capsules_core::alarm::AlarmDriver<
133        'static,
134        capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
135            'static,
136            nrf52::rtc::Rtc<'static>,
137        >,
138    >,
139    buzzer_driver: &'static capsules_extra::buzzer_driver::Buzzer<
140        'static,
141        capsules_extra::buzzer_pwm::PwmBuzzer<
142            'static,
143            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
144                'static,
145                nrf52833::rtc::Rtc<'static>,
146            >,
147            capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52833::pwm::Pwm>,
148        >,
149    >,
150    pwm: &'static capsules_extra::pwm::Pwm<'static, 1>,
151    app_flash: &'static capsules_extra::app_flash_driver::AppFlash<'static>,
152    sound_pressure: &'static capsules_extra::sound_pressure::SoundPressureSensor<'static>,
153    dynamic_app_loader: &'static capsules_extra::app_loader::AppLoader<
154        DynamicBinaryStorage<'static>,
155        DynamicBinaryStorage<'static>,
156    >,
157
158    scheduler: &'static RoundRobinSched<'static>,
159    systick: cortexm4::systick::SysTick,
160}
161
162impl SyscallDriverLookup for MicroBit {
163    fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
164    where
165        F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
166    {
167        match driver_num {
168            capsules_core::console::DRIVER_NUM => f(Some(self.console)),
169            capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
170            capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
171            capsules_core::button::DRIVER_NUM => f(Some(self.button)),
172            capsules_core::led::DRIVER_NUM => f(Some(self.led)),
173            capsules_extra::ninedof::DRIVER_NUM => f(Some(self.ninedof)),
174            capsules_core::adc::DRIVER_NUM => f(Some(self.adc)),
175            capsules_extra::temperature::DRIVER_NUM => f(Some(self.temperature)),
176            capsules_extra::lsm303agr::DRIVER_NUM => f(Some(self.lsm303agr)),
177            capsules_core::rng::DRIVER_NUM => f(Some(self.rng)),
178            capsules_extra::ble_advertising_driver::DRIVER_NUM => f(Some(self.ble_radio)),
179            capsules_extra::buzzer_driver::DRIVER_NUM => f(Some(self.buzzer_driver)),
180            capsules_extra::pwm::DRIVER_NUM => f(Some(self.pwm)),
181            capsules_extra::app_flash_driver::DRIVER_NUM => f(Some(self.app_flash)),
182            capsules_extra::sound_pressure::DRIVER_NUM => f(Some(self.sound_pressure)),
183            capsules_extra::eui64::DRIVER_NUM => f(Some(self.eui64)),
184            capsules_extra::ieee802154::DRIVER_NUM => f(Some(self.ieee802154)),
185            kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
186            capsules_extra::app_loader::DRIVER_NUM => f(Some(self.dynamic_app_loader)),
187            _ => f(None),
188        }
189    }
190}
191
192impl KernelResources<nrf52833::chip::NRF52<'static, Nrf52833DefaultPeripherals<'static>>>
193    for MicroBit
194{
195    type SyscallDriverLookup = Self;
196    type SyscallFilter = ();
197    type ProcessFault = ();
198    type Scheduler = RoundRobinSched<'static>;
199    type SchedulerTimer = cortexm4::systick::SysTick;
200    type WatchDog = ();
201    type ContextSwitchCallback = ();
202
203    fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
204        self
205    }
206    fn syscall_filter(&self) -> &Self::SyscallFilter {
207        &()
208    }
209    fn process_fault(&self) -> &Self::ProcessFault {
210        &()
211    }
212    fn scheduler(&self) -> &Self::Scheduler {
213        self.scheduler
214    }
215    fn scheduler_timer(&self) -> &Self::SchedulerTimer {
216        &self.systick
217    }
218    fn watchdog(&self) -> &Self::WatchDog {
219        &()
220    }
221    fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
222        &()
223    }
224}
225
226#[inline(never)]
230unsafe fn start() -> (
231    &'static kernel::Kernel,
232    MicroBit,
233    &'static nrf52833::chip::NRF52<'static, Nrf52833DefaultPeripherals<'static>>,
234) {
235    nrf52833::init();
236
237    let ieee802154_ack_buf = static_init!(
238        [u8; nrf52833::ieee802154_radio::ACK_BUF_SIZE],
239        [0; nrf52833::ieee802154_radio::ACK_BUF_SIZE]
240    );
241    let nrf52833_peripherals = static_init!(
243        Nrf52833DefaultPeripherals,
244        Nrf52833DefaultPeripherals::new(ieee802154_ack_buf)
245    );
246
247    nrf52833_peripherals.init();
249
250    let base_peripherals = &nrf52833_peripherals.nrf52;
251
252    let processes = components::process_array::ProcessArrayComponent::new()
254        .finalize(components::process_array_component_static!(NUM_PROCS));
255    PROCESSES = Some(processes);
256
257    let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes.as_slice()));
259
260    let device_id = (*addr_of!(nrf52833::ficr::FICR_INSTANCE)).id();
265
266    let eui64 = components::eui64::Eui64Component::new(u64::from_le_bytes(device_id))
267        .finalize(components::eui64_component_static!());
268
269    let ieee802154 = components::ieee802154::Ieee802154RawComponent::new(
270        board_kernel,
271        capsules_extra::ieee802154::DRIVER_NUM,
272        &nrf52833_peripherals.ieee802154_radio,
273    )
274    .finalize(components::ieee802154_raw_component_static!(
275        nrf52833::ieee802154_radio::Radio,
276    ));
277    let memory_allocation_capability = create_capability!(capabilities::MemoryAllocationCapability);
284
285    kernel::debug::assign_gpios(
293        Some(&nrf52833_peripherals.gpio_port[LED_KERNEL_PIN]),
294        None,
295        None,
296    );
297
298    let gpio = components::gpio::GpioComponent::new(
303        board_kernel,
304        capsules_core::gpio::DRIVER_NUM,
305        components::gpio_component_helper!(
306            nrf52833::gpio::GPIOPin,
307            9 => &nrf52833_peripherals.gpio_port[GPIO_P9],
314            16 => &nrf52833_peripherals.gpio_port[GPIO_P16],
315        ),
316    )
317    .finalize(components::gpio_component_static!(nrf52833::gpio::GPIOPin));
318
319    let button = components::button::ButtonComponent::new(
323        board_kernel,
324        capsules_core::button::DRIVER_NUM,
325        components::button_component_helper!(
326            nrf52833::gpio::GPIOPin,
327            (
328                &nrf52833_peripherals.gpio_port[BUTTON_A],
329                kernel::hil::gpio::ActivationMode::ActiveLow,
330                kernel::hil::gpio::FloatingState::PullNone
331            ), (
333                &nrf52833_peripherals.gpio_port[BUTTON_B],
334                kernel::hil::gpio::ActivationMode::ActiveLow,
335                kernel::hil::gpio::FloatingState::PullNone
336            ), (
338                &nrf52833_peripherals.gpio_port[TOUCH_LOGO],
339                kernel::hil::gpio::ActivationMode::ActiveLow,
340                kernel::hil::gpio::FloatingState::PullNone
341            ), ),
343    )
344    .finalize(components::button_component_static!(
345        nrf52833::gpio::GPIOPin
346    ));
347
348    let rtc = &base_peripherals.rtc;
353    let _ = rtc.start();
354
355    let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
356        .finalize(components::alarm_mux_component_static!(nrf52::rtc::Rtc));
357    let alarm = components::alarm::AlarmDriverComponent::new(
358        board_kernel,
359        capsules_core::alarm::DRIVER_NUM,
360        mux_alarm,
361    )
362    .finalize(components::alarm_component_static!(nrf52::rtc::Rtc));
363
364    use kernel::hil::buzzer::Buzzer;
369    use kernel::hil::time::Alarm;
370
371    let mux_pwm = components::pwm::PwmMuxComponent::new(&base_peripherals.pwm0)
372        .finalize(components::pwm_mux_component_static!(nrf52833::pwm::Pwm));
373
374    let virtual_pwm_buzzer = components::pwm::PwmPinUserComponent::new(
375        mux_pwm,
376        nrf52833::pinmux::Pinmux::new(SPEAKER_PIN as u32),
377    )
378    .finalize(components::pwm_pin_user_component_static!(
379        nrf52833::pwm::Pwm
380    ));
381
382    let virtual_alarm_buzzer = static_init!(
383        capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, nrf52833::rtc::Rtc>,
384        capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm::new(mux_alarm)
385    );
386    virtual_alarm_buzzer.setup();
387
388    let pwm_buzzer = static_init!(
389        capsules_extra::buzzer_pwm::PwmBuzzer<
390            'static,
391            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
392                'static,
393                nrf52833::rtc::Rtc,
394            >,
395            capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52833::pwm::Pwm>,
396        >,
397        capsules_extra::buzzer_pwm::PwmBuzzer::new(
398            virtual_pwm_buzzer,
399            virtual_alarm_buzzer,
400            capsules_extra::buzzer_pwm::DEFAULT_MAX_BUZZ_TIME_MS,
401        )
402    );
403
404    let buzzer_driver = static_init!(
405        capsules_extra::buzzer_driver::Buzzer<
406            'static,
407            capsules_extra::buzzer_pwm::PwmBuzzer<
408                'static,
409                capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
410                    'static,
411                    nrf52833::rtc::Rtc,
412                >,
413                capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52833::pwm::Pwm>,
414            >,
415        >,
416        capsules_extra::buzzer_driver::Buzzer::new(
417            pwm_buzzer,
418            capsules_extra::buzzer_driver::DEFAULT_MAX_BUZZ_TIME_MS,
419            board_kernel.create_grant(
420                capsules_extra::buzzer_driver::DRIVER_NUM,
421                &memory_allocation_capability
422            )
423        )
424    );
425
426    pwm_buzzer.set_client(buzzer_driver);
427
428    virtual_alarm_buzzer.set_alarm_client(pwm_buzzer);
429
430    let virtual_pwm_driver = components::pwm::PwmPinUserComponent::new(
431        mux_pwm,
432        nrf52833::pinmux::Pinmux::new(GPIO_P8 as u32),
433    )
434    .finalize(components::pwm_pin_user_component_static!(
435        nrf52833::pwm::Pwm
436    ));
437
438    let pwm =
439        components::pwm::PwmDriverComponent::new(board_kernel, capsules_extra::pwm::DRIVER_NUM)
440            .finalize(components::pwm_driver_component_helper!(virtual_pwm_driver));
441
442    base_peripherals.uarte0.initialize(
447        nrf52::pinmux::Pinmux::new(UART_TX_PIN as u32),
448        nrf52::pinmux::Pinmux::new(UART_RX_PIN as u32),
449        None,
450        None,
451    );
452
453    let uart_mux = components::console::UartMuxComponent::new(&base_peripherals.uarte0, 115200)
455        .finalize(components::uart_mux_component_static!());
456
457    let console = components::console::ConsoleComponent::new(
459        board_kernel,
460        capsules_core::console::DRIVER_NUM,
461        uart_mux,
462    )
463    .finalize(components::console_component_static!());
464    components::debug_writer::DebugWriterComponent::new::<
466        <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
467    >(
468        uart_mux,
469        create_capability!(capabilities::SetDebugWriterCapability),
470    )
471    .finalize(components::debug_writer_component_static!());
472
473    let rng = components::rng::RngComponent::new(
478        board_kernel,
479        capsules_core::rng::DRIVER_NUM,
480        &base_peripherals.trng,
481    )
482    .finalize(components::rng_component_static!(nrf52833::trng::Trng));
483
484    base_peripherals.twi1.configure(
489        nrf52833::pinmux::Pinmux::new(I2C_SCL_PIN as u32),
490        nrf52833::pinmux::Pinmux::new(I2C_SDA_PIN as u32),
491    );
492
493    let sensors_i2c_bus = components::i2c::I2CMuxComponent::new(&base_peripherals.twi1, None)
494        .finalize(components::i2c_mux_component_static!(
495            nrf52833::i2c::TWI<'static>
496        ));
497
498    let lsm303agr = components::lsm303agr::Lsm303agrI2CComponent::new(
501        sensors_i2c_bus,
502        None,
503        None,
504        board_kernel,
505        capsules_extra::lsm303agr::DRIVER_NUM,
506    )
507    .finalize(components::lsm303agr_component_static!(
508        nrf52833::i2c::TWI<'static>
509    ));
510
511    if let Err(error) = lsm303agr.configure(
512        capsules_extra::lsm303xx::Lsm303AccelDataRate::DataRate25Hz,
513        false,
514        capsules_extra::lsm303xx::Lsm303Scale::Scale2G,
515        false,
516        true,
517        capsules_extra::lsm303xx::Lsm303MagnetoDataRate::DataRate3_0Hz,
518        capsules_extra::lsm303xx::Lsm303Range::Range1_9G,
519    ) {
520        debug!("Failed to configure LSM303AGR sensor ({:?})", error);
521    }
522
523    let ninedof = components::ninedof::NineDofComponent::new(
524        board_kernel,
525        capsules_extra::ninedof::DRIVER_NUM,
526    )
527    .finalize(components::ninedof_component_static!(lsm303agr));
528
529    let temperature = components::temperature::TemperatureComponent::new(
532        board_kernel,
533        capsules_extra::temperature::DRIVER_NUM,
534        &base_peripherals.temp,
535    )
536    .finalize(components::temperature_component_static!(
537        nrf52833::temperature::Temp
538    ));
539
540    base_peripherals.adc.calibrate();
544
545    let adc_mux = components::adc::AdcMuxComponent::new(&base_peripherals.adc)
546        .finalize(components::adc_mux_component_static!(nrf52833::adc::Adc));
547
548    let adc_syscall =
550        components::adc::AdcVirtualComponent::new(board_kernel, capsules_core::adc::DRIVER_NUM)
551            .finalize(components::adc_syscall_component_helper!(
552                components::adc::AdcComponent::new(
554                    adc_mux,
555                    nrf52833::adc::AdcChannelSetup::new(nrf52833::adc::AdcChannel::AnalogInput0)
556                )
557                .finalize(components::adc_component_static!(nrf52833::adc::Adc)),
558                components::adc::AdcComponent::new(
560                    adc_mux,
561                    nrf52833::adc::AdcChannelSetup::new(nrf52833::adc::AdcChannel::AnalogInput1)
562                )
563                .finalize(components::adc_component_static!(nrf52833::adc::Adc)),
564                components::adc::AdcComponent::new(
566                    adc_mux,
567                    nrf52833::adc::AdcChannelSetup::new(nrf52833::adc::AdcChannel::AnalogInput2)
568                )
569                .finalize(components::adc_component_static!(nrf52833::adc::Adc))
570            ));
571
572    let adc_microphone = components::adc_microphone::AdcMicrophoneComponent::new(
575        adc_mux,
576        nrf52833::adc::AdcChannelSetup::setup(
577            nrf52833::adc::AdcChannel::AnalogInput3,
578            nrf52833::adc::AdcChannelGain::Gain4,
579            nrf52833::adc::AdcChannelResistor::Bypass,
580            nrf52833::adc::AdcChannelResistor::Pulldown,
581            nrf52833::adc::AdcChannelSamplingTime::us3,
582        ),
583        Some(&nrf52833_peripherals.gpio_port[LED_MICROPHONE_PIN]),
584    )
585    .finalize(components::adc_microphone_component_static!(
586        nrf52833::adc::Adc,
588        50,
590        nrf52833::gpio::GPIOPin
592    ));
593
594    nrf52833_peripherals.gpio_port[LED_MICROPHONE_PIN].set_high_drive(true);
595
596    let sound_pressure = components::sound_pressure::SoundPressureComponent::new(
597        board_kernel,
598        capsules_extra::sound_pressure::DRIVER_NUM,
599        adc_microphone,
600    )
601    .finalize(components::sound_pressure_component_static!());
602
603    let mux_flash = components::flash::FlashMuxComponent::new(&base_peripherals.nvmc).finalize(
608        components::flash_mux_component_static!(nrf52833::nvmc::Nvmc),
609    );
610
611    let virtual_app_flash = components::flash::FlashUserComponent::new(mux_flash).finalize(
614        components::flash_user_component_static!(nrf52833::nvmc::Nvmc),
615    );
616
617    let app_flash = components::app_flash_driver::AppFlashComponent::new(
618        board_kernel,
619        capsules_extra::app_flash_driver::DRIVER_NUM,
620        virtual_app_flash,
621    )
622    .finalize(components::app_flash_component_static!(
623        capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52833::nvmc::Nvmc>,
624        512
625    ));
626
627    let ble_radio = components::ble::BLEComponent::new(
632        board_kernel,
633        capsules_extra::ble_advertising_driver::DRIVER_NUM,
634        &base_peripherals.ble_radio,
635        mux_alarm,
636    )
637    .finalize(components::ble_component_static!(
638        nrf52833::rtc::Rtc,
639        nrf52833::ble_radio::Radio
640    ));
641
642    let led_matrix = components::led_matrix::LedMatrixComponent::new(
647        mux_alarm,
648        components::led_line_component_static!(
649            nrf52833::gpio::GPIOPin,
650            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[0]],
651            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[1]],
652            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[2]],
653            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[3]],
654            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[4]],
655        ),
656        components::led_line_component_static!(
657            nrf52833::gpio::GPIOPin,
658            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[0]],
659            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[1]],
660            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[2]],
661            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[3]],
662            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[4]],
663        ),
664        kernel::hil::gpio::ActivationMode::ActiveLow,
665        kernel::hil::gpio::ActivationMode::ActiveHigh,
666        60,
667    )
668    .finalize(components::led_matrix_component_static!(
669        nrf52833::gpio::GPIOPin,
670        nrf52::rtc::Rtc<'static>,
671        5,
672        5
673    ));
674
675    let led = static_init!(
676        capsules_core::led::LedDriver<
677            'static,
678            capsules_extra::led_matrix::LedMatrixLed<
679                'static,
680                nrf52::gpio::GPIOPin<'static>,
681                capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
682                    'static,
683                    nrf52::rtc::Rtc<'static>,
684                >,
685            >,
686            25,
687        >,
688        capsules_core::led::LedDriver::new(components::led_matrix_leds!(
689            nrf52::gpio::GPIOPin<'static>,
690            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
691                'static,
692                nrf52::rtc::Rtc<'static>,
693            >,
694            led_matrix,
695            (0, 0),
696            (1, 0),
697            (2, 0),
698            (3, 0),
699            (4, 0),
700            (0, 1),
701            (1, 1),
702            (2, 1),
703            (3, 1),
704            (4, 1),
705            (0, 2),
706            (1, 2),
707            (2, 2),
708            (3, 2),
709            (4, 2),
710            (0, 3),
711            (1, 3),
712            (2, 3),
713            (3, 3),
714            (4, 3),
715            (0, 4),
716            (1, 4),
717            (2, 4),
718            (3, 4),
719            (4, 4)
720        )),
721    );
722
723    let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
727        .finalize(components::process_printer_text_component_static!());
728    PROCESS_PRINTER = Some(process_printer);
729
730    let _process_console = components::process_console::ProcessConsoleComponent::new(
731        board_kernel,
732        uart_mux,
733        mux_alarm,
734        process_printer,
735        Some(cortexm4::support::reset),
736    )
737    .finalize(components::process_console_component_static!(
738        nrf52833::rtc::Rtc
739    ));
740    let _ = _process_console.start();
741
742    let chip = static_init!(
743        nrf52833::chip::NRF52<Nrf52833DefaultPeripherals>,
744        nrf52833::chip::NRF52::new(nrf52833_peripherals)
745    );
746    CHIP = Some(chip);
747
748    let checking_policy = components::appid::checker_null::AppCheckerNullComponent::new()
754        .finalize(components::app_checker_null_component_static!());
755
756    let assigner = components::appid::assigner_tbf::AppIdAssignerTbfHeaderComponent::new()
758        .finalize(components::appid_assigner_tbf_header_component_static!());
759
760    let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
762        .finalize(components::process_checker_machine_component_static!());
763
764    let storage_permissions_policy =
769        components::storage_permissions::null::StoragePermissionsNullComponent::new().finalize(
770            components::storage_permissions_null_component_static!(
771                nrf52833::chip::NRF52<Nrf52833DefaultPeripherals>,
772                kernel::process::ProcessStandardDebugFull,
773            ),
774        );
775
776    extern "C" {
778        static _sapps: u8;
780        static _eapps: u8;
782        static mut _sappmem: u8;
784        static _eappmem: u8;
786    }
787
788    let app_flash_slice = core::slice::from_raw_parts(
789        core::ptr::addr_of!(_sapps),
790        core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
791    );
792    let app_memory_slice = core::slice::from_raw_parts_mut(
793        core::ptr::addr_of_mut!(_sappmem),
794        core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
795    );
796
797    let loader = components::loader::sequential::ProcessLoaderSequentialComponent::new(
799        checker,
800        board_kernel,
801        chip,
802        &FAULT_RESPONSE,
803        assigner,
804        storage_permissions_policy,
805        app_flash_slice,
806        app_memory_slice,
807    )
808    .finalize(components::process_loader_sequential_component_static!(
809        nrf52833::chip::NRF52<Nrf52833DefaultPeripherals>,
810        kernel::process::ProcessStandardDebugFull,
811        NUM_PROCS
812    ));
813
814    let dynamic_binary_storage =
820        components::dynamic_binary_storage::SequentialBinaryStorageComponent::new(
821            &base_peripherals.nvmc,
822            loader,
823        )
824        .finalize(components::sequential_binary_storage_component_static!(
825            nrf52833::nvmc::Nvmc,
826            nrf52833::chip::NRF52<Nrf52833DefaultPeripherals>,
827            kernel::process::ProcessStandardDebugFull,
828        ));
829
830    let dynamic_app_loader = components::app_loader::AppLoaderComponent::new(
832        board_kernel,
833        capsules_extra::app_loader::DRIVER_NUM,
834        dynamic_binary_storage,
835        dynamic_binary_storage,
836    )
837    .finalize(components::app_loader_component_static!(
838        DynamicBinaryStorage<'static>,
839        DynamicBinaryStorage<'static>,
840    ));
841
842    base_peripherals.clock.low_stop();
848    base_peripherals.clock.high_stop();
849    base_peripherals.clock.low_start();
850    base_peripherals.clock.high_start();
851    while !base_peripherals.clock.low_started() {}
852    while !base_peripherals.clock.high_started() {}
853
854    let scheduler = components::sched::round_robin::RoundRobinComponent::new(processes)
855        .finalize(components::round_robin_component_static!(NUM_PROCS));
856
857    let microbit = MicroBit {
858        ble_radio,
859        ieee802154,
860        eui64,
861        console,
862        gpio,
863        button,
864        led,
865        rng,
866        temperature,
867        lsm303agr,
868        ninedof,
869        buzzer_driver,
870        pwm,
871        sound_pressure,
872        adc: adc_syscall,
873        alarm,
874        app_flash,
875        ipc: kernel::ipc::IPC::new(
876            board_kernel,
877            kernel::ipc::DRIVER_NUM,
878            &memory_allocation_capability,
879        ),
880        dynamic_app_loader,
881
882        scheduler,
883        systick: cortexm4::systick::SysTick::new_with_calibration(64000000),
884    };
885
886    debug!("Initialization complete. Entering main loop.");
887
888    (board_kernel, microbit, chip)
889}
890
891#[no_mangle]
893pub unsafe fn main() {
894    let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
895
896    let (board_kernel, board, chip) = start();
897    board_kernel.kernel_loop(&board, chip, Some(&board.ipc), &main_loop_capability);
898}