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>>;
88
89pub struct MicroBit {
91    ble_radio: &'static capsules_extra::ble_advertising_driver::BLE<
92        'static,
93        nrf52::ble_radio::Radio<'static>,
94        capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
95            'static,
96            nrf52::rtc::Rtc<'static>,
97        >,
98    >,
99    eui64: &'static capsules_extra::eui64::Eui64,
100    ieee802154: &'static Ieee802154RawDriver,
101    console: &'static capsules_core::console::Console<'static>,
102    gpio: &'static capsules_core::gpio::GPIO<'static, nrf52::gpio::GPIOPin<'static>>,
103    led: &'static capsules_core::led::LedDriver<
104        'static,
105        capsules_extra::led_matrix::LedMatrixLed<
106            'static,
107            nrf52::gpio::GPIOPin<'static>,
108            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
109                'static,
110                nrf52::rtc::Rtc<'static>,
111            >,
112        >,
113        25,
114    >,
115    button: &'static capsules_core::button::Button<'static, nrf52::gpio::GPIOPin<'static>>,
116    rng: &'static RngDriver,
117    ninedof: &'static capsules_extra::ninedof::NineDof<'static>,
118    lsm303agr: &'static capsules_extra::lsm303agr::Lsm303agrI2C<
119        'static,
120        capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, nrf52833::i2c::TWI<'static>>,
121    >,
122    temperature: &'static TemperatureDriver,
123    ipc: kernel::ipc::IPC<{ NUM_PROCS as u8 }>,
124    adc: &'static capsules_core::adc::AdcVirtualized<'static>,
125    alarm: &'static capsules_core::alarm::AlarmDriver<
126        'static,
127        capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
128            'static,
129            nrf52::rtc::Rtc<'static>,
130        >,
131    >,
132    buzzer_driver: &'static capsules_extra::buzzer_driver::Buzzer<
133        'static,
134        capsules_extra::buzzer_pwm::PwmBuzzer<
135            'static,
136            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
137                'static,
138                nrf52833::rtc::Rtc<'static>,
139            >,
140            capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52833::pwm::Pwm>,
141        >,
142    >,
143    pwm: &'static capsules_extra::pwm::Pwm<'static, 1>,
144    app_flash: &'static capsules_extra::app_flash_driver::AppFlash<'static>,
145    sound_pressure: &'static capsules_extra::sound_pressure::SoundPressureSensor<'static>,
146
147    scheduler: &'static RoundRobinSched<'static>,
148    systick: cortexm4::systick::SysTick,
149}
150
151impl SyscallDriverLookup for MicroBit {
152    fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
153    where
154        F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
155    {
156        match driver_num {
157            capsules_core::console::DRIVER_NUM => f(Some(self.console)),
158            capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
159            capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
160            capsules_core::button::DRIVER_NUM => f(Some(self.button)),
161            capsules_core::led::DRIVER_NUM => f(Some(self.led)),
162            capsules_extra::ninedof::DRIVER_NUM => f(Some(self.ninedof)),
163            capsules_core::adc::DRIVER_NUM => f(Some(self.adc)),
164            capsules_extra::temperature::DRIVER_NUM => f(Some(self.temperature)),
165            capsules_extra::lsm303agr::DRIVER_NUM => f(Some(self.lsm303agr)),
166            capsules_core::rng::DRIVER_NUM => f(Some(self.rng)),
167            capsules_extra::ble_advertising_driver::DRIVER_NUM => f(Some(self.ble_radio)),
168            capsules_extra::buzzer_driver::DRIVER_NUM => f(Some(self.buzzer_driver)),
169            capsules_extra::pwm::DRIVER_NUM => f(Some(self.pwm)),
170            capsules_extra::app_flash_driver::DRIVER_NUM => f(Some(self.app_flash)),
171            capsules_extra::sound_pressure::DRIVER_NUM => f(Some(self.sound_pressure)),
172            capsules_extra::eui64::DRIVER_NUM => f(Some(self.eui64)),
173            capsules_extra::ieee802154::DRIVER_NUM => f(Some(self.ieee802154)),
174            kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
175            _ => f(None),
176        }
177    }
178}
179
180impl KernelResources<nrf52833::chip::NRF52<'static, Nrf52833DefaultPeripherals<'static>>>
181    for MicroBit
182{
183    type SyscallDriverLookup = Self;
184    type SyscallFilter = ();
185    type ProcessFault = ();
186    type Scheduler = RoundRobinSched<'static>;
187    type SchedulerTimer = cortexm4::systick::SysTick;
188    type WatchDog = ();
189    type ContextSwitchCallback = ();
190
191    fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
192        self
193    }
194    fn syscall_filter(&self) -> &Self::SyscallFilter {
195        &()
196    }
197    fn process_fault(&self) -> &Self::ProcessFault {
198        &()
199    }
200    fn scheduler(&self) -> &Self::Scheduler {
201        self.scheduler
202    }
203    fn scheduler_timer(&self) -> &Self::SchedulerTimer {
204        &self.systick
205    }
206    fn watchdog(&self) -> &Self::WatchDog {
207        &()
208    }
209    fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
210        &()
211    }
212}
213
214#[inline(never)]
218unsafe fn start() -> (
219    &'static kernel::Kernel,
220    MicroBit,
221    &'static nrf52833::chip::NRF52<'static, Nrf52833DefaultPeripherals<'static>>,
222) {
223    nrf52833::init();
224
225    let ieee802154_ack_buf = static_init!(
226        [u8; nrf52833::ieee802154_radio::ACK_BUF_SIZE],
227        [0; nrf52833::ieee802154_radio::ACK_BUF_SIZE]
228    );
229    let nrf52833_peripherals = static_init!(
231        Nrf52833DefaultPeripherals,
232        Nrf52833DefaultPeripherals::new(ieee802154_ack_buf)
233    );
234
235    nrf52833_peripherals.init();
237
238    let base_peripherals = &nrf52833_peripherals.nrf52;
239
240    let processes = components::process_array::ProcessArrayComponent::new()
242        .finalize(components::process_array_component_static!(NUM_PROCS));
243    PROCESSES = Some(processes);
244
245    let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes.as_slice()));
247
248    let device_id = (*addr_of!(nrf52833::ficr::FICR_INSTANCE)).id();
253
254    let eui64 = components::eui64::Eui64Component::new(u64::from_le_bytes(device_id))
255        .finalize(components::eui64_component_static!());
256
257    let ieee802154 = components::ieee802154::Ieee802154RawComponent::new(
258        board_kernel,
259        capsules_extra::ieee802154::DRIVER_NUM,
260        &nrf52833_peripherals.ieee802154_radio,
261    )
262    .finalize(components::ieee802154_raw_component_static!(
263        nrf52833::ieee802154_radio::Radio,
264    ));
265    let process_management_capability =
272        create_capability!(capabilities::ProcessManagementCapability);
273    let memory_allocation_capability = create_capability!(capabilities::MemoryAllocationCapability);
274
275    kernel::debug::assign_gpios(
283        Some(&nrf52833_peripherals.gpio_port[LED_KERNEL_PIN]),
284        None,
285        None,
286    );
287
288    let gpio = components::gpio::GpioComponent::new(
293        board_kernel,
294        capsules_core::gpio::DRIVER_NUM,
295        components::gpio_component_helper!(
296            nrf52833::gpio::GPIOPin,
297            9 => &nrf52833_peripherals.gpio_port[GPIO_P9],
304            16 => &nrf52833_peripherals.gpio_port[GPIO_P16],
305        ),
306    )
307    .finalize(components::gpio_component_static!(nrf52833::gpio::GPIOPin));
308
309    let button = components::button::ButtonComponent::new(
313        board_kernel,
314        capsules_core::button::DRIVER_NUM,
315        components::button_component_helper!(
316            nrf52833::gpio::GPIOPin,
317            (
318                &nrf52833_peripherals.gpio_port[BUTTON_A],
319                kernel::hil::gpio::ActivationMode::ActiveLow,
320                kernel::hil::gpio::FloatingState::PullNone
321            ), (
323                &nrf52833_peripherals.gpio_port[BUTTON_B],
324                kernel::hil::gpio::ActivationMode::ActiveLow,
325                kernel::hil::gpio::FloatingState::PullNone
326            ), (
328                &nrf52833_peripherals.gpio_port[TOUCH_LOGO],
329                kernel::hil::gpio::ActivationMode::ActiveLow,
330                kernel::hil::gpio::FloatingState::PullNone
331            ), ),
333    )
334    .finalize(components::button_component_static!(
335        nrf52833::gpio::GPIOPin
336    ));
337
338    let rtc = &base_peripherals.rtc;
343    let _ = rtc.start();
344
345    let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
346        .finalize(components::alarm_mux_component_static!(nrf52::rtc::Rtc));
347    let alarm = components::alarm::AlarmDriverComponent::new(
348        board_kernel,
349        capsules_core::alarm::DRIVER_NUM,
350        mux_alarm,
351    )
352    .finalize(components::alarm_component_static!(nrf52::rtc::Rtc));
353
354    use kernel::hil::buzzer::Buzzer;
359    use kernel::hil::time::Alarm;
360
361    let mux_pwm = components::pwm::PwmMuxComponent::new(&base_peripherals.pwm0)
362        .finalize(components::pwm_mux_component_static!(nrf52833::pwm::Pwm));
363
364    let virtual_pwm_buzzer = components::pwm::PwmPinUserComponent::new(
365        mux_pwm,
366        nrf52833::pinmux::Pinmux::new(SPEAKER_PIN as u32),
367    )
368    .finalize(components::pwm_pin_user_component_static!(
369        nrf52833::pwm::Pwm
370    ));
371
372    let virtual_alarm_buzzer = static_init!(
373        capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, nrf52833::rtc::Rtc>,
374        capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm::new(mux_alarm)
375    );
376    virtual_alarm_buzzer.setup();
377
378    let pwm_buzzer = static_init!(
379        capsules_extra::buzzer_pwm::PwmBuzzer<
380            'static,
381            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
382                'static,
383                nrf52833::rtc::Rtc,
384            >,
385            capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52833::pwm::Pwm>,
386        >,
387        capsules_extra::buzzer_pwm::PwmBuzzer::new(
388            virtual_pwm_buzzer,
389            virtual_alarm_buzzer,
390            capsules_extra::buzzer_pwm::DEFAULT_MAX_BUZZ_TIME_MS,
391        )
392    );
393
394    let buzzer_driver = static_init!(
395        capsules_extra::buzzer_driver::Buzzer<
396            'static,
397            capsules_extra::buzzer_pwm::PwmBuzzer<
398                'static,
399                capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
400                    'static,
401                    nrf52833::rtc::Rtc,
402                >,
403                capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52833::pwm::Pwm>,
404            >,
405        >,
406        capsules_extra::buzzer_driver::Buzzer::new(
407            pwm_buzzer,
408            capsules_extra::buzzer_driver::DEFAULT_MAX_BUZZ_TIME_MS,
409            board_kernel.create_grant(
410                capsules_extra::buzzer_driver::DRIVER_NUM,
411                &memory_allocation_capability
412            )
413        )
414    );
415
416    pwm_buzzer.set_client(buzzer_driver);
417
418    virtual_alarm_buzzer.set_alarm_client(pwm_buzzer);
419
420    let virtual_pwm_driver = components::pwm::PwmPinUserComponent::new(
421        mux_pwm,
422        nrf52833::pinmux::Pinmux::new(GPIO_P8 as u32),
423    )
424    .finalize(components::pwm_pin_user_component_static!(
425        nrf52833::pwm::Pwm
426    ));
427
428    let pwm =
429        components::pwm::PwmDriverComponent::new(board_kernel, capsules_extra::pwm::DRIVER_NUM)
430            .finalize(components::pwm_driver_component_helper!(virtual_pwm_driver));
431
432    base_peripherals.uarte0.initialize(
437        nrf52::pinmux::Pinmux::new(UART_TX_PIN as u32),
438        nrf52::pinmux::Pinmux::new(UART_RX_PIN as u32),
439        None,
440        None,
441    );
442
443    let uart_mux = components::console::UartMuxComponent::new(&base_peripherals.uarte0, 115200)
445        .finalize(components::uart_mux_component_static!());
446
447    let console = components::console::ConsoleComponent::new(
449        board_kernel,
450        capsules_core::console::DRIVER_NUM,
451        uart_mux,
452    )
453    .finalize(components::console_component_static!());
454    components::debug_writer::DebugWriterComponent::new::<
456        <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
457    >(
458        uart_mux,
459        create_capability!(capabilities::SetDebugWriterCapability),
460    )
461    .finalize(components::debug_writer_component_static!());
462
463    let rng = components::rng::RngComponent::new(
468        board_kernel,
469        capsules_core::rng::DRIVER_NUM,
470        &base_peripherals.trng,
471    )
472    .finalize(components::rng_component_static!(nrf52833::trng::Trng));
473
474    base_peripherals.twi1.configure(
479        nrf52833::pinmux::Pinmux::new(I2C_SCL_PIN as u32),
480        nrf52833::pinmux::Pinmux::new(I2C_SDA_PIN as u32),
481    );
482
483    let sensors_i2c_bus = components::i2c::I2CMuxComponent::new(&base_peripherals.twi1, None)
484        .finalize(components::i2c_mux_component_static!(
485            nrf52833::i2c::TWI<'static>
486        ));
487
488    let lsm303agr = components::lsm303agr::Lsm303agrI2CComponent::new(
491        sensors_i2c_bus,
492        None,
493        None,
494        board_kernel,
495        capsules_extra::lsm303agr::DRIVER_NUM,
496    )
497    .finalize(components::lsm303agr_component_static!(
498        nrf52833::i2c::TWI<'static>
499    ));
500
501    if let Err(error) = lsm303agr.configure(
502        capsules_extra::lsm303xx::Lsm303AccelDataRate::DataRate25Hz,
503        false,
504        capsules_extra::lsm303xx::Lsm303Scale::Scale2G,
505        false,
506        true,
507        capsules_extra::lsm303xx::Lsm303MagnetoDataRate::DataRate3_0Hz,
508        capsules_extra::lsm303xx::Lsm303Range::Range1_9G,
509    ) {
510        debug!("Failed to configure LSM303AGR sensor ({:?})", error);
511    }
512
513    let ninedof = components::ninedof::NineDofComponent::new(
514        board_kernel,
515        capsules_extra::ninedof::DRIVER_NUM,
516    )
517    .finalize(components::ninedof_component_static!(lsm303agr));
518
519    let temperature = components::temperature::TemperatureComponent::new(
522        board_kernel,
523        capsules_extra::temperature::DRIVER_NUM,
524        &base_peripherals.temp,
525    )
526    .finalize(components::temperature_component_static!(
527        nrf52833::temperature::Temp
528    ));
529
530    base_peripherals.adc.calibrate();
534
535    let adc_mux = components::adc::AdcMuxComponent::new(&base_peripherals.adc)
536        .finalize(components::adc_mux_component_static!(nrf52833::adc::Adc));
537
538    let adc_syscall =
540        components::adc::AdcVirtualComponent::new(board_kernel, capsules_core::adc::DRIVER_NUM)
541            .finalize(components::adc_syscall_component_helper!(
542                components::adc::AdcComponent::new(
544                    adc_mux,
545                    nrf52833::adc::AdcChannelSetup::new(nrf52833::adc::AdcChannel::AnalogInput0)
546                )
547                .finalize(components::adc_component_static!(nrf52833::adc::Adc)),
548                components::adc::AdcComponent::new(
550                    adc_mux,
551                    nrf52833::adc::AdcChannelSetup::new(nrf52833::adc::AdcChannel::AnalogInput1)
552                )
553                .finalize(components::adc_component_static!(nrf52833::adc::Adc)),
554                components::adc::AdcComponent::new(
556                    adc_mux,
557                    nrf52833::adc::AdcChannelSetup::new(nrf52833::adc::AdcChannel::AnalogInput2)
558                )
559                .finalize(components::adc_component_static!(nrf52833::adc::Adc))
560            ));
561
562    let adc_microphone = components::adc_microphone::AdcMicrophoneComponent::new(
565        adc_mux,
566        nrf52833::adc::AdcChannelSetup::setup(
567            nrf52833::adc::AdcChannel::AnalogInput3,
568            nrf52833::adc::AdcChannelGain::Gain4,
569            nrf52833::adc::AdcChannelResistor::Bypass,
570            nrf52833::adc::AdcChannelResistor::Pulldown,
571            nrf52833::adc::AdcChannelSamplingTime::us3,
572        ),
573        Some(&nrf52833_peripherals.gpio_port[LED_MICROPHONE_PIN]),
574    )
575    .finalize(components::adc_microphone_component_static!(
576        nrf52833::adc::Adc,
578        50,
580        nrf52833::gpio::GPIOPin
582    ));
583
584    nrf52833_peripherals.gpio_port[LED_MICROPHONE_PIN].set_high_drive(true);
585
586    let sound_pressure = components::sound_pressure::SoundPressureComponent::new(
587        board_kernel,
588        capsules_extra::sound_pressure::DRIVER_NUM,
589        adc_microphone,
590    )
591    .finalize(components::sound_pressure_component_static!());
592
593    let mux_flash = components::flash::FlashMuxComponent::new(&base_peripherals.nvmc).finalize(
598        components::flash_mux_component_static!(nrf52833::nvmc::Nvmc),
599    );
600
601    let virtual_app_flash = components::flash::FlashUserComponent::new(mux_flash).finalize(
604        components::flash_user_component_static!(nrf52833::nvmc::Nvmc),
605    );
606
607    let app_flash = components::app_flash_driver::AppFlashComponent::new(
608        board_kernel,
609        capsules_extra::app_flash_driver::DRIVER_NUM,
610        virtual_app_flash,
611    )
612    .finalize(components::app_flash_component_static!(
613        capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52833::nvmc::Nvmc>,
614        512
615    ));
616
617    let ble_radio = components::ble::BLEComponent::new(
622        board_kernel,
623        capsules_extra::ble_advertising_driver::DRIVER_NUM,
624        &base_peripherals.ble_radio,
625        mux_alarm,
626    )
627    .finalize(components::ble_component_static!(
628        nrf52833::rtc::Rtc,
629        nrf52833::ble_radio::Radio
630    ));
631
632    let led_matrix = components::led_matrix::LedMatrixComponent::new(
637        mux_alarm,
638        components::led_line_component_static!(
639            nrf52833::gpio::GPIOPin,
640            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[0]],
641            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[1]],
642            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[2]],
643            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[3]],
644            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[4]],
645        ),
646        components::led_line_component_static!(
647            nrf52833::gpio::GPIOPin,
648            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[0]],
649            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[1]],
650            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[2]],
651            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[3]],
652            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[4]],
653        ),
654        kernel::hil::gpio::ActivationMode::ActiveLow,
655        kernel::hil::gpio::ActivationMode::ActiveHigh,
656        60,
657    )
658    .finalize(components::led_matrix_component_static!(
659        nrf52833::gpio::GPIOPin,
660        nrf52::rtc::Rtc<'static>,
661        5,
662        5
663    ));
664
665    let led = static_init!(
666        capsules_core::led::LedDriver<
667            'static,
668            capsules_extra::led_matrix::LedMatrixLed<
669                'static,
670                nrf52::gpio::GPIOPin<'static>,
671                capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
672                    'static,
673                    nrf52::rtc::Rtc<'static>,
674                >,
675            >,
676            25,
677        >,
678        capsules_core::led::LedDriver::new(components::led_matrix_leds!(
679            nrf52::gpio::GPIOPin<'static>,
680            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
681                'static,
682                nrf52::rtc::Rtc<'static>,
683            >,
684            led_matrix,
685            (0, 0),
686            (1, 0),
687            (2, 0),
688            (3, 0),
689            (4, 0),
690            (0, 1),
691            (1, 1),
692            (2, 1),
693            (3, 1),
694            (4, 1),
695            (0, 2),
696            (1, 2),
697            (2, 2),
698            (3, 2),
699            (4, 2),
700            (0, 3),
701            (1, 3),
702            (2, 3),
703            (3, 3),
704            (4, 3),
705            (0, 4),
706            (1, 4),
707            (2, 4),
708            (3, 4),
709            (4, 4)
710        )),
711    );
712
713    let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
717        .finalize(components::process_printer_text_component_static!());
718    PROCESS_PRINTER = Some(process_printer);
719
720    let _process_console = components::process_console::ProcessConsoleComponent::new(
721        board_kernel,
722        uart_mux,
723        mux_alarm,
724        process_printer,
725        Some(cortexm4::support::reset),
726    )
727    .finalize(components::process_console_component_static!(
728        nrf52833::rtc::Rtc
729    ));
730    let _ = _process_console.start();
731
732    base_peripherals.clock.low_stop();
738    base_peripherals.clock.high_stop();
739    base_peripherals.clock.low_start();
740    base_peripherals.clock.high_start();
741    while !base_peripherals.clock.low_started() {}
742    while !base_peripherals.clock.high_started() {}
743
744    let scheduler = components::sched::round_robin::RoundRobinComponent::new(processes)
745        .finalize(components::round_robin_component_static!(NUM_PROCS));
746
747    let microbit = MicroBit {
748        ble_radio,
749        ieee802154,
750        eui64,
751        console,
752        gpio,
753        button,
754        led,
755        rng,
756        temperature,
757        lsm303agr,
758        ninedof,
759        buzzer_driver,
760        pwm,
761        sound_pressure,
762        adc: adc_syscall,
763        alarm,
764        app_flash,
765        ipc: kernel::ipc::IPC::new(
766            board_kernel,
767            kernel::ipc::DRIVER_NUM,
768            &memory_allocation_capability,
769        ),
770
771        scheduler,
772        systick: cortexm4::systick::SysTick::new_with_calibration(64000000),
773    };
774
775    let chip = static_init!(
776        nrf52833::chip::NRF52<Nrf52833DefaultPeripherals>,
777        nrf52833::chip::NRF52::new(nrf52833_peripherals)
778    );
779    CHIP = Some(chip);
780
781    debug!("Initialization complete. Entering main loop.");
782
783    extern "C" {
789        static _sapps: u8;
791        static _eapps: u8;
793        static mut _sappmem: u8;
795        static _eappmem: u8;
797    }
798
799    kernel::process::load_processes(
800        board_kernel,
801        chip,
802        core::slice::from_raw_parts(
803            core::ptr::addr_of!(_sapps),
804            core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
805        ),
806        core::slice::from_raw_parts_mut(
807            core::ptr::addr_of_mut!(_sappmem),
808            core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
809        ),
810        &FAULT_RESPONSE,
811        &process_management_capability,
812    )
813    .unwrap_or_else(|err| {
814        debug!("Error loading processes!");
815        debug!("{:?}", err);
816    });
817
818    (board_kernel, microbit, chip)
819}
820
821#[no_mangle]
823pub unsafe fn main() {
824    let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
825
826    let (board_kernel, board, chip) = start();
827    board_kernel.kernel_loop(&board, chip, Some(&board.ipc), &main_loop_capability);
828}