microbit_v2_test_dynamic_app_load/
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//! Tock kernel for the Micro:bit v2.
6//!
7//! It is based on nRF52833 SoC (Cortex M4 core with a BLE).
8
9#![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
28// Kernel LED (same as microphone LED)
29const LED_KERNEL_PIN: Pin = Pin::P0_20;
30const LED_MICROPHONE_PIN: Pin = Pin::P0_20;
31
32// Buttons
33const BUTTON_A: Pin = Pin::P0_14;
34const BUTTON_B: Pin = Pin::P0_23;
35const TOUCH_LOGO: Pin = Pin::P1_04;
36
37// GPIOs
38
39// P0, P1 and P2 are used as ADC, comment them in the ADC section to use them as GPIO
40const _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
50/// LED matrix
51const 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
54// Speaker
55
56const SPEAKER_PIN: Pin = Pin::P0_00;
57
58/// I2C pins for all of the sensors.
59const I2C_SDA_PIN: Pin = Pin::P0_16;
60const I2C_SCL_PIN: Pin = Pin::P0_08;
61
62/// UART Writer for panic!()s.
63pub mod io;
64
65// State for loading and holding applications.
66// How should the kernel respond when a process faults.
67const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
68    capsules_system::process_policies::PanicFaultPolicy {};
69
70// Number of concurrent processes this platform supports.
71const NUM_PROCS: usize = 4;
72
73/// Static variables used by io.rs.
74static mut PROCESSES: Option<&'static ProcessArray<NUM_PROCS>> = None;
75static mut CHIP: Option<&'static nrf52833::chip::NRF52<Nrf52833DefaultPeripherals>> = None;
76static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::ProcessPrinterText> =
77    None;
78
79/// Dummy buffer that causes the linker to reserve enough space for the stack.
80#[no_mangle]
81#[link_section = ".stack_buffer"]
82static mut STACK_MEMORY: [u8; 0x2000] = [0; 0x2000];
83// debug mode requires more stack space
84// static mut STACK_MEMORY: [u8; 0x2000] = [0; 0x2000];
85
86type TemperatureDriver =
87    components::temperature::TemperatureComponentType<nrf52::temperature::Temp<'static>>;
88type RngDriver = components::rng::RngComponentType<nrf52833::trng::Trng<'static>>;
89type Ieee802154RawDriver =
90    components::ieee802154::Ieee802154RawComponentType<nrf52833::ieee802154_radio::Radio<'static>>;
91type NonVolatilePages = components::dynamic_binary_storage::NVPages<nrf52833::nvmc::Nvmc>;
92type DynamicBinaryStorage<'a> = kernel::dynamic_binary_storage::SequentialDynamicBinaryStorage<
93    'static,
94    'static,
95    nrf52833::chip::NRF52<'a, Nrf52833DefaultPeripherals<'a>>,
96    kernel::process::ProcessStandardDebugFull,
97    NonVolatilePages,
98>;
99/// Supported drivers by the platform
100pub struct MicroBit {
101    ble_radio: &'static capsules_extra::ble_advertising_driver::BLE<
102        'static,
103        nrf52::ble_radio::Radio<'static>,
104        capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
105            'static,
106            nrf52::rtc::Rtc<'static>,
107        >,
108    >,
109    eui64: &'static capsules_extra::eui64::Eui64,
110    ieee802154: &'static Ieee802154RawDriver,
111    console: &'static capsules_core::console::Console<'static>,
112    gpio: &'static capsules_core::gpio::GPIO<'static, nrf52::gpio::GPIOPin<'static>>,
113    led: &'static capsules_core::led::LedDriver<
114        'static,
115        capsules_extra::led_matrix::LedMatrixLed<
116            'static,
117            nrf52::gpio::GPIOPin<'static>,
118            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
119                'static,
120                nrf52::rtc::Rtc<'static>,
121            >,
122        >,
123        25,
124    >,
125    button: &'static capsules_core::button::Button<'static, nrf52::gpio::GPIOPin<'static>>,
126    rng: &'static RngDriver,
127    ninedof: &'static capsules_extra::ninedof::NineDof<'static>,
128    lsm303agr: &'static capsules_extra::lsm303agr::Lsm303agrI2C<
129        'static,
130        capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, nrf52833::i2c::TWI<'static>>,
131    >,
132    temperature: &'static TemperatureDriver,
133    ipc: kernel::ipc::IPC<{ NUM_PROCS as u8 }>,
134    adc: &'static capsules_core::adc::AdcVirtualized<'static>,
135    alarm: &'static capsules_core::alarm::AlarmDriver<
136        'static,
137        capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
138            'static,
139            nrf52::rtc::Rtc<'static>,
140        >,
141    >,
142    buzzer_driver: &'static capsules_extra::buzzer_driver::Buzzer<
143        'static,
144        capsules_extra::buzzer_pwm::PwmBuzzer<
145            'static,
146            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
147                'static,
148                nrf52833::rtc::Rtc<'static>,
149            >,
150            capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52833::pwm::Pwm>,
151        >,
152    >,
153    pwm: &'static capsules_extra::pwm::Pwm<'static, 1>,
154    app_flash: &'static capsules_extra::app_flash_driver::AppFlash<'static>,
155    sound_pressure: &'static capsules_extra::sound_pressure::SoundPressureSensor<'static>,
156    dynamic_app_loader: &'static capsules_extra::app_loader::AppLoader<
157        DynamicBinaryStorage<'static>,
158        DynamicBinaryStorage<'static>,
159    >,
160
161    scheduler: &'static RoundRobinSched<'static>,
162    systick: cortexm4::systick::SysTick,
163}
164
165impl SyscallDriverLookup for MicroBit {
166    fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
167    where
168        F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
169    {
170        match driver_num {
171            capsules_core::console::DRIVER_NUM => f(Some(self.console)),
172            capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
173            capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
174            capsules_core::button::DRIVER_NUM => f(Some(self.button)),
175            capsules_core::led::DRIVER_NUM => f(Some(self.led)),
176            capsules_extra::ninedof::DRIVER_NUM => f(Some(self.ninedof)),
177            capsules_core::adc::DRIVER_NUM => f(Some(self.adc)),
178            capsules_extra::temperature::DRIVER_NUM => f(Some(self.temperature)),
179            capsules_extra::lsm303agr::DRIVER_NUM => f(Some(self.lsm303agr)),
180            capsules_core::rng::DRIVER_NUM => f(Some(self.rng)),
181            capsules_extra::ble_advertising_driver::DRIVER_NUM => f(Some(self.ble_radio)),
182            capsules_extra::buzzer_driver::DRIVER_NUM => f(Some(self.buzzer_driver)),
183            capsules_extra::pwm::DRIVER_NUM => f(Some(self.pwm)),
184            capsules_extra::app_flash_driver::DRIVER_NUM => f(Some(self.app_flash)),
185            capsules_extra::sound_pressure::DRIVER_NUM => f(Some(self.sound_pressure)),
186            capsules_extra::eui64::DRIVER_NUM => f(Some(self.eui64)),
187            capsules_extra::ieee802154::DRIVER_NUM => f(Some(self.ieee802154)),
188            kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
189            capsules_extra::app_loader::DRIVER_NUM => f(Some(self.dynamic_app_loader)),
190            _ => f(None),
191        }
192    }
193}
194
195impl KernelResources<nrf52833::chip::NRF52<'static, Nrf52833DefaultPeripherals<'static>>>
196    for MicroBit
197{
198    type SyscallDriverLookup = Self;
199    type SyscallFilter = ();
200    type ProcessFault = ();
201    type Scheduler = RoundRobinSched<'static>;
202    type SchedulerTimer = cortexm4::systick::SysTick;
203    type WatchDog = ();
204    type ContextSwitchCallback = ();
205
206    fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
207        self
208    }
209    fn syscall_filter(&self) -> &Self::SyscallFilter {
210        &()
211    }
212    fn process_fault(&self) -> &Self::ProcessFault {
213        &()
214    }
215    fn scheduler(&self) -> &Self::Scheduler {
216        self.scheduler
217    }
218    fn scheduler_timer(&self) -> &Self::SchedulerTimer {
219        &self.systick
220    }
221    fn watchdog(&self) -> &Self::WatchDog {
222        &()
223    }
224    fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
225        &()
226    }
227}
228
229/// This is in a separate, inline(never) function so that its stack frame is
230/// removed when this function returns. Otherwise, the stack space used for
231/// these static_inits is wasted.
232#[inline(never)]
233unsafe fn start() -> (
234    &'static kernel::Kernel,
235    MicroBit,
236    &'static nrf52833::chip::NRF52<'static, Nrf52833DefaultPeripherals<'static>>,
237) {
238    nrf52833::init();
239
240    let ieee802154_ack_buf = static_init!(
241        [u8; nrf52833::ieee802154_radio::ACK_BUF_SIZE],
242        [0; nrf52833::ieee802154_radio::ACK_BUF_SIZE]
243    );
244    // Initialize chip peripheral drivers
245    let nrf52833_peripherals = static_init!(
246        Nrf52833DefaultPeripherals,
247        Nrf52833DefaultPeripherals::new(ieee802154_ack_buf)
248    );
249
250    // set up circular peripheral dependencies
251    nrf52833_peripherals.init();
252
253    let base_peripherals = &nrf52833_peripherals.nrf52;
254
255    // Create an array to hold process references.
256    let processes = components::process_array::ProcessArrayComponent::new()
257        .finalize(components::process_array_component_static!(NUM_PROCS));
258    PROCESSES = Some(processes);
259
260    // Setup space to store the core kernel data structure.
261    let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes.as_slice()));
262
263    //--------------------------------------------------------------------------
264    // RAW 802.15.4
265    //--------------------------------------------------------------------------
266
267    let device_id = (*addr_of!(nrf52833::ficr::FICR_INSTANCE)).id();
268
269    let eui64 = components::eui64::Eui64Component::new(u64::from_le_bytes(device_id))
270        .finalize(components::eui64_component_static!());
271
272    let ieee802154 = components::ieee802154::Ieee802154RawComponent::new(
273        board_kernel,
274        capsules_extra::ieee802154::DRIVER_NUM,
275        &nrf52833_peripherals.ieee802154_radio,
276    )
277    .finalize(components::ieee802154_raw_component_static!(
278        nrf52833::ieee802154_radio::Radio,
279    ));
280    //--------------------------------------------------------------------------
281    // CAPABILITIES
282    //--------------------------------------------------------------------------
283
284    // Create capabilities that the board needs to call certain protected kernel
285    // functions.
286    let memory_allocation_capability = create_capability!(capabilities::MemoryAllocationCapability);
287
288    //--------------------------------------------------------------------------
289    // DEBUG GPIO
290    //--------------------------------------------------------------------------
291
292    // Configure kernel debug GPIOs as early as possible. These are used by the
293    // `debug_gpio!(0, toggle)` macro. We uconfigure these early so that the
294    // macro is available during most of the setup code and kernel exection.
295    kernel::debug::assign_gpios(
296        Some(&nrf52833_peripherals.gpio_port[LED_KERNEL_PIN]),
297        None,
298        None,
299    );
300
301    //--------------------------------------------------------------------------
302    // GPIO
303    //--------------------------------------------------------------------------
304
305    let gpio = components::gpio::GpioComponent::new(
306        board_kernel,
307        capsules_core::gpio::DRIVER_NUM,
308        components::gpio_component_helper!(
309            nrf52833::gpio::GPIOPin,
310            // Used as ADC, comment them out in the ADC section to use them as GPIO
311            // 0 => &nrf52833_peripherals.gpio_port[GPIO_P0],
312            // 1 => &nrf52833_peripherals.gpio_port[_GPIO_P1],
313            // 2 => &nrf52833_peripherals.gpio_port[_GPIO_P2],
314            // Used as PWM, comment them out in the PWM section to use them as GPIO
315            //8 => &nrf52833_peripherals.gpio_port[GPIO_P8],
316            9 => &nrf52833_peripherals.gpio_port[GPIO_P9],
317            16 => &nrf52833_peripherals.gpio_port[GPIO_P16],
318        ),
319    )
320    .finalize(components::gpio_component_static!(nrf52833::gpio::GPIOPin));
321
322    //--------------------------------------------------------------------------
323    // Buttons
324    //--------------------------------------------------------------------------
325    let button = components::button::ButtonComponent::new(
326        board_kernel,
327        capsules_core::button::DRIVER_NUM,
328        components::button_component_helper!(
329            nrf52833::gpio::GPIOPin,
330            (
331                &nrf52833_peripherals.gpio_port[BUTTON_A],
332                kernel::hil::gpio::ActivationMode::ActiveLow,
333                kernel::hil::gpio::FloatingState::PullNone
334            ), // A
335            (
336                &nrf52833_peripherals.gpio_port[BUTTON_B],
337                kernel::hil::gpio::ActivationMode::ActiveLow,
338                kernel::hil::gpio::FloatingState::PullNone
339            ), // B
340            (
341                &nrf52833_peripherals.gpio_port[TOUCH_LOGO],
342                kernel::hil::gpio::ActivationMode::ActiveLow,
343                kernel::hil::gpio::FloatingState::PullNone
344            ), // Touch Logo
345        ),
346    )
347    .finalize(components::button_component_static!(
348        nrf52833::gpio::GPIOPin
349    ));
350
351    //--------------------------------------------------------------------------
352    // ALARM & TIMER
353    //--------------------------------------------------------------------------
354
355    let rtc = &base_peripherals.rtc;
356    let _ = rtc.start();
357
358    let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
359        .finalize(components::alarm_mux_component_static!(nrf52::rtc::Rtc));
360    let alarm = components::alarm::AlarmDriverComponent::new(
361        board_kernel,
362        capsules_core::alarm::DRIVER_NUM,
363        mux_alarm,
364    )
365    .finalize(components::alarm_component_static!(nrf52::rtc::Rtc));
366
367    //--------------------------------------------------------------------------
368    // PWM & BUZZER
369    //--------------------------------------------------------------------------
370
371    use kernel::hil::buzzer::Buzzer;
372    use kernel::hil::time::Alarm;
373
374    let mux_pwm = components::pwm::PwmMuxComponent::new(&base_peripherals.pwm0)
375        .finalize(components::pwm_mux_component_static!(nrf52833::pwm::Pwm));
376
377    let virtual_pwm_buzzer = components::pwm::PwmPinUserComponent::new(
378        mux_pwm,
379        nrf52833::pinmux::Pinmux::new(SPEAKER_PIN as u32),
380    )
381    .finalize(components::pwm_pin_user_component_static!(
382        nrf52833::pwm::Pwm
383    ));
384
385    let virtual_alarm_buzzer = static_init!(
386        capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, nrf52833::rtc::Rtc>,
387        capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm::new(mux_alarm)
388    );
389    virtual_alarm_buzzer.setup();
390
391    let pwm_buzzer = static_init!(
392        capsules_extra::buzzer_pwm::PwmBuzzer<
393            'static,
394            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
395                'static,
396                nrf52833::rtc::Rtc,
397            >,
398            capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52833::pwm::Pwm>,
399        >,
400        capsules_extra::buzzer_pwm::PwmBuzzer::new(
401            virtual_pwm_buzzer,
402            virtual_alarm_buzzer,
403            capsules_extra::buzzer_pwm::DEFAULT_MAX_BUZZ_TIME_MS,
404        )
405    );
406
407    let buzzer_driver = static_init!(
408        capsules_extra::buzzer_driver::Buzzer<
409            'static,
410            capsules_extra::buzzer_pwm::PwmBuzzer<
411                'static,
412                capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
413                    'static,
414                    nrf52833::rtc::Rtc,
415                >,
416                capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52833::pwm::Pwm>,
417            >,
418        >,
419        capsules_extra::buzzer_driver::Buzzer::new(
420            pwm_buzzer,
421            capsules_extra::buzzer_driver::DEFAULT_MAX_BUZZ_TIME_MS,
422            board_kernel.create_grant(
423                capsules_extra::buzzer_driver::DRIVER_NUM,
424                &memory_allocation_capability
425            )
426        )
427    );
428
429    pwm_buzzer.set_client(buzzer_driver);
430
431    virtual_alarm_buzzer.set_alarm_client(pwm_buzzer);
432
433    let virtual_pwm_driver = components::pwm::PwmPinUserComponent::new(
434        mux_pwm,
435        nrf52833::pinmux::Pinmux::new(GPIO_P8 as u32),
436    )
437    .finalize(components::pwm_pin_user_component_static!(
438        nrf52833::pwm::Pwm
439    ));
440
441    let pwm =
442        components::pwm::PwmDriverComponent::new(board_kernel, capsules_extra::pwm::DRIVER_NUM)
443            .finalize(components::pwm_driver_component_helper!(virtual_pwm_driver));
444
445    //--------------------------------------------------------------------------
446    // UART & CONSOLE & DEBUG
447    //--------------------------------------------------------------------------
448
449    base_peripherals.uarte0.initialize(
450        nrf52::pinmux::Pinmux::new(UART_TX_PIN as u32),
451        nrf52::pinmux::Pinmux::new(UART_RX_PIN as u32),
452        None,
453        None,
454    );
455
456    // Create a shared UART channel for the console and for kernel debug.
457    let uart_mux = components::console::UartMuxComponent::new(&base_peripherals.uarte0, 115200)
458        .finalize(components::uart_mux_component_static!());
459
460    // Setup the console.
461    let console = components::console::ConsoleComponent::new(
462        board_kernel,
463        capsules_core::console::DRIVER_NUM,
464        uart_mux,
465    )
466    .finalize(components::console_component_static!());
467    // Create the debugger object that handles calls to `debug!()`.
468    components::debug_writer::DebugWriterComponent::new(
469        uart_mux,
470        create_capability!(capabilities::SetDebugWriterCapability),
471    )
472    .finalize(components::debug_writer_component_static!());
473
474    //--------------------------------------------------------------------------
475    // RANDOM NUMBERS
476    //--------------------------------------------------------------------------
477
478    let rng = components::rng::RngComponent::new(
479        board_kernel,
480        capsules_core::rng::DRIVER_NUM,
481        &base_peripherals.trng,
482    )
483    .finalize(components::rng_component_static!(nrf52833::trng::Trng));
484
485    //--------------------------------------------------------------------------
486    // SENSORS
487    //--------------------------------------------------------------------------
488
489    base_peripherals.twi1.configure(
490        nrf52833::pinmux::Pinmux::new(I2C_SCL_PIN as u32),
491        nrf52833::pinmux::Pinmux::new(I2C_SDA_PIN as u32),
492    );
493
494    let sensors_i2c_bus = components::i2c::I2CMuxComponent::new(&base_peripherals.twi1, None)
495        .finalize(components::i2c_mux_component_static!(
496            nrf52833::i2c::TWI<'static>
497        ));
498
499    // LSM303AGR
500
501    let lsm303agr = components::lsm303agr::Lsm303agrI2CComponent::new(
502        sensors_i2c_bus,
503        None,
504        None,
505        board_kernel,
506        capsules_extra::lsm303agr::DRIVER_NUM,
507    )
508    .finalize(components::lsm303agr_component_static!(
509        nrf52833::i2c::TWI<'static>
510    ));
511
512    if let Err(error) = lsm303agr.configure(
513        capsules_extra::lsm303xx::Lsm303AccelDataRate::DataRate25Hz,
514        false,
515        capsules_extra::lsm303xx::Lsm303Scale::Scale2G,
516        false,
517        true,
518        capsules_extra::lsm303xx::Lsm303MagnetoDataRate::DataRate3_0Hz,
519        capsules_extra::lsm303xx::Lsm303Range::Range1_9G,
520    ) {
521        debug!("Failed to configure LSM303AGR sensor ({:?})", error);
522    }
523
524    let ninedof = components::ninedof::NineDofComponent::new(
525        board_kernel,
526        capsules_extra::ninedof::DRIVER_NUM,
527    )
528    .finalize(components::ninedof_component_static!(lsm303agr));
529
530    // Temperature
531
532    let temperature = components::temperature::TemperatureComponent::new(
533        board_kernel,
534        capsules_extra::temperature::DRIVER_NUM,
535        &base_peripherals.temp,
536    )
537    .finalize(components::temperature_component_static!(
538        nrf52833::temperature::Temp
539    ));
540
541    //--------------------------------------------------------------------------
542    // ADC
543    //--------------------------------------------------------------------------
544    base_peripherals.adc.calibrate();
545
546    let adc_mux = components::adc::AdcMuxComponent::new(&base_peripherals.adc)
547        .finalize(components::adc_mux_component_static!(nrf52833::adc::Adc));
548
549    // Comment out the following to use P0, P1 and P2 as GPIO
550    let adc_syscall =
551        components::adc::AdcVirtualComponent::new(board_kernel, capsules_core::adc::DRIVER_NUM)
552            .finalize(components::adc_syscall_component_helper!(
553                // ADC Ring 0 (P0)
554                components::adc::AdcComponent::new(
555                    adc_mux,
556                    nrf52833::adc::AdcChannelSetup::new(nrf52833::adc::AdcChannel::AnalogInput0)
557                )
558                .finalize(components::adc_component_static!(nrf52833::adc::Adc)),
559                // ADC Ring 1 (P1)
560                components::adc::AdcComponent::new(
561                    adc_mux,
562                    nrf52833::adc::AdcChannelSetup::new(nrf52833::adc::AdcChannel::AnalogInput1)
563                )
564                .finalize(components::adc_component_static!(nrf52833::adc::Adc)),
565                // ADC Ring 2 (P2)
566                components::adc::AdcComponent::new(
567                    adc_mux,
568                    nrf52833::adc::AdcChannelSetup::new(nrf52833::adc::AdcChannel::AnalogInput2)
569                )
570                .finalize(components::adc_component_static!(nrf52833::adc::Adc))
571            ));
572
573    // Microphone
574
575    let adc_microphone = components::adc_microphone::AdcMicrophoneComponent::new(
576        adc_mux,
577        nrf52833::adc::AdcChannelSetup::setup(
578            nrf52833::adc::AdcChannel::AnalogInput3,
579            nrf52833::adc::AdcChannelGain::Gain4,
580            nrf52833::adc::AdcChannelResistor::Bypass,
581            nrf52833::adc::AdcChannelResistor::Pulldown,
582            nrf52833::adc::AdcChannelSamplingTime::us3,
583        ),
584        Some(&nrf52833_peripherals.gpio_port[LED_MICROPHONE_PIN]),
585    )
586    .finalize(components::adc_microphone_component_static!(
587        // adc
588        nrf52833::adc::Adc,
589        // buffer size
590        50,
591        // gpio
592        nrf52833::gpio::GPIOPin
593    ));
594
595    nrf52833_peripherals.gpio_port[LED_MICROPHONE_PIN].set_high_drive(true);
596
597    let sound_pressure = components::sound_pressure::SoundPressureComponent::new(
598        board_kernel,
599        capsules_extra::sound_pressure::DRIVER_NUM,
600        adc_microphone,
601    )
602    .finalize(components::sound_pressure_component_static!());
603
604    //--------------------------------------------------------------------------
605    // STORAGE
606    //--------------------------------------------------------------------------
607
608    let mux_flash = components::flash::FlashMuxComponent::new(&base_peripherals.nvmc).finalize(
609        components::flash_mux_component_static!(nrf52833::nvmc::Nvmc),
610    );
611
612    // App Flash
613
614    let virtual_app_flash = components::flash::FlashUserComponent::new(mux_flash).finalize(
615        components::flash_user_component_static!(nrf52833::nvmc::Nvmc),
616    );
617
618    let app_flash = components::app_flash_driver::AppFlashComponent::new(
619        board_kernel,
620        capsules_extra::app_flash_driver::DRIVER_NUM,
621        virtual_app_flash,
622    )
623    .finalize(components::app_flash_component_static!(
624        capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52833::nvmc::Nvmc>,
625        512
626    ));
627
628    //--------------------------------------------------------------------------
629    // WIRELESS
630    //--------------------------------------------------------------------------
631
632    let ble_radio = components::ble::BLEComponent::new(
633        board_kernel,
634        capsules_extra::ble_advertising_driver::DRIVER_NUM,
635        &base_peripherals.ble_radio,
636        mux_alarm,
637    )
638    .finalize(components::ble_component_static!(
639        nrf52833::rtc::Rtc,
640        nrf52833::ble_radio::Radio
641    ));
642
643    //--------------------------------------------------------------------------
644    // LED Matrix
645    //--------------------------------------------------------------------------
646
647    let led_matrix = components::led_matrix::LedMatrixComponent::new(
648        mux_alarm,
649        components::led_line_component_static!(
650            nrf52833::gpio::GPIOPin,
651            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[0]],
652            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[1]],
653            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[2]],
654            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[3]],
655            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[4]],
656        ),
657        components::led_line_component_static!(
658            nrf52833::gpio::GPIOPin,
659            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[0]],
660            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[1]],
661            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[2]],
662            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[3]],
663            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[4]],
664        ),
665        kernel::hil::gpio::ActivationMode::ActiveLow,
666        kernel::hil::gpio::ActivationMode::ActiveHigh,
667        60,
668    )
669    .finalize(components::led_matrix_component_static!(
670        nrf52833::gpio::GPIOPin,
671        nrf52::rtc::Rtc<'static>,
672        5,
673        5
674    ));
675
676    let led = static_init!(
677        capsules_core::led::LedDriver<
678            'static,
679            capsules_extra::led_matrix::LedMatrixLed<
680                'static,
681                nrf52::gpio::GPIOPin<'static>,
682                capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
683                    'static,
684                    nrf52::rtc::Rtc<'static>,
685                >,
686            >,
687            25,
688        >,
689        capsules_core::led::LedDriver::new(components::led_matrix_leds!(
690            nrf52::gpio::GPIOPin<'static>,
691            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
692                'static,
693                nrf52::rtc::Rtc<'static>,
694            >,
695            led_matrix,
696            (0, 0),
697            (1, 0),
698            (2, 0),
699            (3, 0),
700            (4, 0),
701            (0, 1),
702            (1, 1),
703            (2, 1),
704            (3, 1),
705            (4, 1),
706            (0, 2),
707            (1, 2),
708            (2, 2),
709            (3, 2),
710            (4, 2),
711            (0, 3),
712            (1, 3),
713            (2, 3),
714            (3, 3),
715            (4, 3),
716            (0, 4),
717            (1, 4),
718            (2, 4),
719            (3, 4),
720            (4, 4)
721        )),
722    );
723
724    //--------------------------------------------------------------------------
725    // Process Console
726    //--------------------------------------------------------------------------
727    let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
728        .finalize(components::process_printer_text_component_static!());
729    PROCESS_PRINTER = Some(process_printer);
730
731    let _process_console = components::process_console::ProcessConsoleComponent::new(
732        board_kernel,
733        uart_mux,
734        mux_alarm,
735        process_printer,
736        Some(cortexm4::support::reset),
737    )
738    .finalize(components::process_console_component_static!(
739        nrf52833::rtc::Rtc
740    ));
741    let _ = _process_console.start();
742
743    let chip = static_init!(
744        nrf52833::chip::NRF52<Nrf52833DefaultPeripherals>,
745        nrf52833::chip::NRF52::new(nrf52833_peripherals)
746    );
747    CHIP = Some(chip);
748
749    //--------------------------------------------------------------------------
750    // Credential Checking
751    //--------------------------------------------------------------------------
752
753    // Create the credential checker.
754    let checking_policy = components::appid::checker_null::AppCheckerNullComponent::new()
755        .finalize(components::app_checker_null_component_static!());
756
757    // Create the AppID assigner.
758    let assigner = components::appid::assigner_tbf::AppIdAssignerTbfHeaderComponent::new()
759        .finalize(components::appid_assigner_tbf_header_component_static!());
760
761    // Create the process checking machine.
762    let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
763        .finalize(components::process_checker_machine_component_static!());
764
765    //--------------------------------------------------------------------------
766    // STORAGE PERMISSIONS
767    //--------------------------------------------------------------------------
768
769    let storage_permissions_policy =
770        components::storage_permissions::null::StoragePermissionsNullComponent::new().finalize(
771            components::storage_permissions_null_component_static!(
772                nrf52833::chip::NRF52<Nrf52833DefaultPeripherals>,
773                kernel::process::ProcessStandardDebugFull,
774            ),
775        );
776
777    // These symbols are defined in the standard Tock linker script.
778    extern "C" {
779        /// Beginning of the ROM region containing app images.
780        static _sapps: u8;
781        /// End of the ROM region containing app images.
782        static _eapps: u8;
783        /// Beginning of the RAM region for app memory.
784        static mut _sappmem: u8;
785        /// End of the RAM region for app memory.
786        static _eappmem: u8;
787    }
788
789    let app_flash_slice = core::slice::from_raw_parts(
790        core::ptr::addr_of!(_sapps),
791        core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
792    );
793    let app_memory_slice = core::slice::from_raw_parts_mut(
794        core::ptr::addr_of_mut!(_sappmem),
795        core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
796    );
797
798    // Create and start the asynchronous process loader.
799    let loader = components::loader::sequential::ProcessLoaderSequentialComponent::new(
800        checker,
801        board_kernel,
802        chip,
803        &FAULT_RESPONSE,
804        assigner,
805        storage_permissions_policy,
806        app_flash_slice,
807        app_memory_slice,
808    )
809    .finalize(components::process_loader_sequential_component_static!(
810        nrf52833::chip::NRF52<Nrf52833DefaultPeripherals>,
811        kernel::process::ProcessStandardDebugFull,
812        NUM_PROCS
813    ));
814
815    //--------------------------------------------------------------------------
816    // Dynamic App Loading
817    //--------------------------------------------------------------------------
818
819    // Create the dynamic binary flasher.
820    let dynamic_binary_storage =
821        components::dynamic_binary_storage::SequentialBinaryStorageComponent::new(
822            &base_peripherals.nvmc,
823            loader,
824        )
825        .finalize(components::sequential_binary_storage_component_static!(
826            nrf52833::nvmc::Nvmc,
827            nrf52833::chip::NRF52<Nrf52833DefaultPeripherals>,
828            kernel::process::ProcessStandardDebugFull,
829        ));
830
831    // Create the dynamic app loader capsule.
832    let dynamic_app_loader = components::app_loader::AppLoaderComponent::new(
833        board_kernel,
834        capsules_extra::app_loader::DRIVER_NUM,
835        dynamic_binary_storage,
836        dynamic_binary_storage,
837    )
838    .finalize(components::app_loader_component_static!(
839        DynamicBinaryStorage<'static>,
840        DynamicBinaryStorage<'static>,
841    ));
842
843    //--------------------------------------------------------------------------
844    // FINAL SETUP AND BOARD BOOT
845    //--------------------------------------------------------------------------
846
847    // it seems that microbit v2 has no external clock
848    base_peripherals.clock.low_stop();
849    base_peripherals.clock.high_stop();
850    base_peripherals.clock.low_start();
851    base_peripherals.clock.high_start();
852    while !base_peripherals.clock.low_started() {}
853    while !base_peripherals.clock.high_started() {}
854
855    let scheduler = components::sched::round_robin::RoundRobinComponent::new(processes)
856        .finalize(components::round_robin_component_static!(NUM_PROCS));
857
858    let microbit = MicroBit {
859        ble_radio,
860        ieee802154,
861        eui64,
862        console,
863        gpio,
864        button,
865        led,
866        rng,
867        temperature,
868        lsm303agr,
869        ninedof,
870        buzzer_driver,
871        pwm,
872        sound_pressure,
873        adc: adc_syscall,
874        alarm,
875        app_flash,
876        ipc: kernel::ipc::IPC::new(
877            board_kernel,
878            kernel::ipc::DRIVER_NUM,
879            &memory_allocation_capability,
880        ),
881        dynamic_app_loader,
882
883        scheduler,
884        systick: cortexm4::systick::SysTick::new_with_calibration(64000000),
885    };
886
887    debug!("Initialization complete. Entering main loop.");
888
889    (board_kernel, microbit, chip)
890}
891
892/// Main function called after RAM initialized.
893#[no_mangle]
894pub unsafe fn main() {
895    let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
896
897    let (board_kernel, board, chip) = start();
898    board_kernel.kernel_loop(&board, chip, Some(&board.ipc), &main_loop_capability);
899}