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
73type ChipHw = nrf52833::chip::NRF52<'static, Nrf52833DefaultPeripherals<'static>>;
74
75/// Static variables used by io.rs.
76static 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>;
96/// Supported drivers by the platform
97pub 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/// This is in a separate, inline(never) function so that its stack frame is
227/// removed when this function returns. Otherwise, the stack space used for
228/// these static_inits is wasted.
229#[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    // Initialize deferred calls very early.
238    kernel::deferred_call::initialize_deferred_call_state::<
239        <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
240    >();
241
242    let ieee802154_ack_buf = static_init!(
243        [u8; nrf52833::ieee802154_radio::ACK_BUF_SIZE],
244        [0; nrf52833::ieee802154_radio::ACK_BUF_SIZE]
245    );
246    // Initialize chip peripheral drivers
247    let nrf52833_peripherals = static_init!(
248        Nrf52833DefaultPeripherals,
249        Nrf52833DefaultPeripherals::new(ieee802154_ack_buf)
250    );
251
252    // set up circular peripheral dependencies
253    nrf52833_peripherals.init();
254
255    let base_peripherals = &nrf52833_peripherals.nrf52;
256
257    // Create an array to hold process references.
258    let processes = components::process_array::ProcessArrayComponent::new()
259        .finalize(components::process_array_component_static!(NUM_PROCS));
260    PROCESSES = Some(processes);
261
262    // Setup space to store the core kernel data structure.
263    let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes.as_slice()));
264
265    //--------------------------------------------------------------------------
266    // RAW 802.15.4
267    //--------------------------------------------------------------------------
268
269    let device_id = (*addr_of!(nrf52833::ficr::FICR_INSTANCE)).id();
270
271    let eui64 = components::eui64::Eui64Component::new(u64::from_le_bytes(device_id))
272        .finalize(components::eui64_component_static!());
273
274    let ieee802154 = components::ieee802154::Ieee802154RawComponent::new(
275        board_kernel,
276        capsules_extra::ieee802154::DRIVER_NUM,
277        &nrf52833_peripherals.ieee802154_radio,
278    )
279    .finalize(components::ieee802154_raw_component_static!(
280        nrf52833::ieee802154_radio::Radio,
281    ));
282    //--------------------------------------------------------------------------
283    // CAPABILITIES
284    //--------------------------------------------------------------------------
285
286    // Create capabilities that the board needs to call certain protected kernel
287    // functions.
288    let memory_allocation_capability = create_capability!(capabilities::MemoryAllocationCapability);
289
290    //--------------------------------------------------------------------------
291    // DEBUG GPIO
292    //--------------------------------------------------------------------------
293
294    // Configure kernel debug GPIOs as early as possible. These are used by the
295    // `debug_gpio!(0, toggle)` macro. We uconfigure these early so that the
296    // macro is available during most of the setup code and kernel exection.
297    let debug_gpios = static_init!(
298        [&'static dyn kernel::hil::gpio::Pin; 1],
299        [&nrf52833_peripherals.gpio_port[LED_KERNEL_PIN]]
300    );
301    kernel::debug::initialize_debug_gpio::<
302        <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
303    >();
304    kernel::debug::assign_gpios(debug_gpios);
305
306    //--------------------------------------------------------------------------
307    // GPIO
308    //--------------------------------------------------------------------------
309
310    let gpio = components::gpio::GpioComponent::new(
311        board_kernel,
312        capsules_core::gpio::DRIVER_NUM,
313        components::gpio_component_helper!(
314            nrf52833::gpio::GPIOPin,
315            // Used as ADC, comment them out in the ADC section to use them as GPIO
316            // 0 => &nrf52833_peripherals.gpio_port[GPIO_P0],
317            // 1 => &nrf52833_peripherals.gpio_port[_GPIO_P1],
318            // 2 => &nrf52833_peripherals.gpio_port[_GPIO_P2],
319            // Used as PWM, comment them out in the PWM section to use them as GPIO
320            //8 => &nrf52833_peripherals.gpio_port[GPIO_P8],
321            9 => &nrf52833_peripherals.gpio_port[GPIO_P9],
322            16 => &nrf52833_peripherals.gpio_port[GPIO_P16],
323        ),
324    )
325    .finalize(components::gpio_component_static!(nrf52833::gpio::GPIOPin));
326
327    //--------------------------------------------------------------------------
328    // Buttons
329    //--------------------------------------------------------------------------
330    let button = components::button::ButtonComponent::new(
331        board_kernel,
332        capsules_core::button::DRIVER_NUM,
333        components::button_component_helper!(
334            nrf52833::gpio::GPIOPin,
335            (
336                &nrf52833_peripherals.gpio_port[BUTTON_A],
337                kernel::hil::gpio::ActivationMode::ActiveLow,
338                kernel::hil::gpio::FloatingState::PullNone
339            ), // A
340            (
341                &nrf52833_peripherals.gpio_port[BUTTON_B],
342                kernel::hil::gpio::ActivationMode::ActiveLow,
343                kernel::hil::gpio::FloatingState::PullNone
344            ), // B
345            (
346                &nrf52833_peripherals.gpio_port[TOUCH_LOGO],
347                kernel::hil::gpio::ActivationMode::ActiveLow,
348                kernel::hil::gpio::FloatingState::PullNone
349            ), // Touch Logo
350        ),
351    )
352    .finalize(components::button_component_static!(
353        nrf52833::gpio::GPIOPin
354    ));
355
356    //--------------------------------------------------------------------------
357    // ALARM & TIMER
358    //--------------------------------------------------------------------------
359
360    let rtc = &base_peripherals.rtc;
361    let _ = rtc.start();
362
363    let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
364        .finalize(components::alarm_mux_component_static!(nrf52::rtc::Rtc));
365    let alarm = components::alarm::AlarmDriverComponent::new(
366        board_kernel,
367        capsules_core::alarm::DRIVER_NUM,
368        mux_alarm,
369    )
370    .finalize(components::alarm_component_static!(nrf52::rtc::Rtc));
371
372    //--------------------------------------------------------------------------
373    // PWM & BUZZER
374    //--------------------------------------------------------------------------
375
376    use kernel::hil::buzzer::Buzzer;
377    use kernel::hil::time::Alarm;
378
379    let mux_pwm = components::pwm::PwmMuxComponent::new(&base_peripherals.pwm0)
380        .finalize(components::pwm_mux_component_static!(nrf52833::pwm::Pwm));
381
382    let virtual_pwm_buzzer = components::pwm::PwmPinUserComponent::new(
383        mux_pwm,
384        nrf52833::pinmux::Pinmux::new(SPEAKER_PIN as u32),
385    )
386    .finalize(components::pwm_pin_user_component_static!(
387        nrf52833::pwm::Pwm
388    ));
389
390    let virtual_alarm_buzzer = static_init!(
391        capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, nrf52833::rtc::Rtc>,
392        capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm::new(mux_alarm)
393    );
394    virtual_alarm_buzzer.setup();
395
396    let pwm_buzzer = static_init!(
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        capsules_extra::buzzer_pwm::PwmBuzzer::new(
406            virtual_pwm_buzzer,
407            virtual_alarm_buzzer,
408            capsules_extra::buzzer_pwm::DEFAULT_MAX_BUZZ_TIME_MS,
409        )
410    );
411
412    let buzzer_driver = static_init!(
413        capsules_extra::buzzer_driver::Buzzer<
414            'static,
415            capsules_extra::buzzer_pwm::PwmBuzzer<
416                'static,
417                capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
418                    'static,
419                    nrf52833::rtc::Rtc,
420                >,
421                capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52833::pwm::Pwm>,
422            >,
423        >,
424        capsules_extra::buzzer_driver::Buzzer::new(
425            pwm_buzzer,
426            capsules_extra::buzzer_driver::DEFAULT_MAX_BUZZ_TIME_MS,
427            board_kernel.create_grant(
428                capsules_extra::buzzer_driver::DRIVER_NUM,
429                &memory_allocation_capability
430            )
431        )
432    );
433
434    pwm_buzzer.set_client(buzzer_driver);
435
436    virtual_alarm_buzzer.set_alarm_client(pwm_buzzer);
437
438    let virtual_pwm_driver = components::pwm::PwmPinUserComponent::new(
439        mux_pwm,
440        nrf52833::pinmux::Pinmux::new(GPIO_P8 as u32),
441    )
442    .finalize(components::pwm_pin_user_component_static!(
443        nrf52833::pwm::Pwm
444    ));
445
446    let pwm =
447        components::pwm::PwmDriverComponent::new(board_kernel, capsules_extra::pwm::DRIVER_NUM)
448            .finalize(components::pwm_driver_component_helper!(virtual_pwm_driver));
449
450    //--------------------------------------------------------------------------
451    // UART & CONSOLE & DEBUG
452    //--------------------------------------------------------------------------
453
454    base_peripherals.uarte0.initialize(
455        nrf52::pinmux::Pinmux::new(UART_TX_PIN as u32),
456        nrf52::pinmux::Pinmux::new(UART_RX_PIN as u32),
457        None,
458        None,
459    );
460
461    // Create a shared UART channel for the console and for kernel debug.
462    let uart_mux = components::console::UartMuxComponent::new(&base_peripherals.uarte0, 115200)
463        .finalize(components::uart_mux_component_static!());
464
465    // Setup the console.
466    let console = components::console::ConsoleComponent::new(
467        board_kernel,
468        capsules_core::console::DRIVER_NUM,
469        uart_mux,
470    )
471    .finalize(components::console_component_static!());
472    // Create the debugger object that handles calls to `debug!()`.
473    components::debug_writer::DebugWriterComponent::new::<
474        <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
475    >(
476        uart_mux,
477        create_capability!(capabilities::SetDebugWriterCapability),
478    )
479    .finalize(components::debug_writer_component_static!());
480
481    //--------------------------------------------------------------------------
482    // RANDOM NUMBERS
483    //--------------------------------------------------------------------------
484
485    let rng = components::rng::RngComponent::new(
486        board_kernel,
487        capsules_core::rng::DRIVER_NUM,
488        &base_peripherals.trng,
489    )
490    .finalize(components::rng_component_static!(nrf52833::trng::Trng));
491
492    //--------------------------------------------------------------------------
493    // SENSORS
494    //--------------------------------------------------------------------------
495
496    base_peripherals.twi1.configure(
497        nrf52833::pinmux::Pinmux::new(I2C_SCL_PIN as u32),
498        nrf52833::pinmux::Pinmux::new(I2C_SDA_PIN as u32),
499    );
500
501    let sensors_i2c_bus = components::i2c::I2CMuxComponent::new(&base_peripherals.twi1, None)
502        .finalize(components::i2c_mux_component_static!(
503            nrf52833::i2c::TWI<'static>
504        ));
505
506    // LSM303AGR
507
508    let lsm303agr = components::lsm303agr::Lsm303agrI2CComponent::new(
509        sensors_i2c_bus,
510        None,
511        None,
512        board_kernel,
513        capsules_extra::lsm303agr::DRIVER_NUM,
514    )
515    .finalize(components::lsm303agr_component_static!(
516        nrf52833::i2c::TWI<'static>
517    ));
518
519    if let Err(error) = lsm303agr.configure(
520        capsules_extra::lsm303xx::Lsm303AccelDataRate::DataRate25Hz,
521        false,
522        capsules_extra::lsm303xx::Lsm303Scale::Scale2G,
523        false,
524        true,
525        capsules_extra::lsm303xx::Lsm303MagnetoDataRate::DataRate3_0Hz,
526        capsules_extra::lsm303xx::Lsm303Range::Range1_9G,
527    ) {
528        debug!("Failed to configure LSM303AGR sensor ({:?})", error);
529    }
530
531    let ninedof = components::ninedof::NineDofComponent::new(
532        board_kernel,
533        capsules_extra::ninedof::DRIVER_NUM,
534    )
535    .finalize(components::ninedof_component_static!(lsm303agr));
536
537    // Temperature
538
539    let temperature = components::temperature::TemperatureComponent::new(
540        board_kernel,
541        capsules_extra::temperature::DRIVER_NUM,
542        &base_peripherals.temp,
543    )
544    .finalize(components::temperature_component_static!(
545        nrf52833::temperature::Temp
546    ));
547
548    //--------------------------------------------------------------------------
549    // ADC
550    //--------------------------------------------------------------------------
551    base_peripherals.adc.calibrate();
552
553    let adc_mux = components::adc::AdcMuxComponent::new(&base_peripherals.adc)
554        .finalize(components::adc_mux_component_static!(nrf52833::adc::Adc));
555
556    // Comment out the following to use P0, P1 and P2 as GPIO
557    let adc_syscall =
558        components::adc::AdcVirtualComponent::new(board_kernel, capsules_core::adc::DRIVER_NUM)
559            .finalize(components::adc_syscall_component_helper!(
560                // ADC Ring 0 (P0)
561                components::adc::AdcComponent::new(
562                    adc_mux,
563                    nrf52833::adc::AdcChannelSetup::new(nrf52833::adc::AdcChannel::AnalogInput0)
564                )
565                .finalize(components::adc_component_static!(nrf52833::adc::Adc)),
566                // ADC Ring 1 (P1)
567                components::adc::AdcComponent::new(
568                    adc_mux,
569                    nrf52833::adc::AdcChannelSetup::new(nrf52833::adc::AdcChannel::AnalogInput1)
570                )
571                .finalize(components::adc_component_static!(nrf52833::adc::Adc)),
572                // ADC Ring 2 (P2)
573                components::adc::AdcComponent::new(
574                    adc_mux,
575                    nrf52833::adc::AdcChannelSetup::new(nrf52833::adc::AdcChannel::AnalogInput2)
576                )
577                .finalize(components::adc_component_static!(nrf52833::adc::Adc))
578            ));
579
580    // Microphone
581
582    let adc_microphone = components::adc_microphone::AdcMicrophoneComponent::new(
583        adc_mux,
584        nrf52833::adc::AdcChannelSetup::setup(
585            nrf52833::adc::AdcChannel::AnalogInput3,
586            nrf52833::adc::AdcChannelGain::Gain4,
587            nrf52833::adc::AdcChannelResistor::Bypass,
588            nrf52833::adc::AdcChannelResistor::Pulldown,
589            nrf52833::adc::AdcChannelSamplingTime::us3,
590        ),
591        Some(&nrf52833_peripherals.gpio_port[LED_MICROPHONE_PIN]),
592    )
593    .finalize(components::adc_microphone_component_static!(
594        // adc
595        nrf52833::adc::Adc,
596        // buffer size
597        50,
598        // gpio
599        nrf52833::gpio::GPIOPin
600    ));
601
602    nrf52833_peripherals.gpio_port[LED_MICROPHONE_PIN].set_high_drive(true);
603
604    let sound_pressure = components::sound_pressure::SoundPressureComponent::new(
605        board_kernel,
606        capsules_extra::sound_pressure::DRIVER_NUM,
607        adc_microphone,
608    )
609    .finalize(components::sound_pressure_component_static!());
610
611    //--------------------------------------------------------------------------
612    // STORAGE
613    //--------------------------------------------------------------------------
614
615    let mux_flash = components::flash::FlashMuxComponent::new(&base_peripherals.nvmc).finalize(
616        components::flash_mux_component_static!(nrf52833::nvmc::Nvmc),
617    );
618
619    // App Flash
620
621    let virtual_app_flash = components::flash::FlashUserComponent::new(mux_flash).finalize(
622        components::flash_user_component_static!(nrf52833::nvmc::Nvmc),
623    );
624
625    let app_flash = components::app_flash_driver::AppFlashComponent::new(
626        board_kernel,
627        capsules_extra::app_flash_driver::DRIVER_NUM,
628        virtual_app_flash,
629    )
630    .finalize(components::app_flash_component_static!(
631        capsules_core::virtualizers::virtual_flash::FlashUser<'static, nrf52833::nvmc::Nvmc>,
632        512
633    ));
634
635    //--------------------------------------------------------------------------
636    // WIRELESS
637    //--------------------------------------------------------------------------
638
639    let ble_radio = components::ble::BLEComponent::new(
640        board_kernel,
641        capsules_extra::ble_advertising_driver::DRIVER_NUM,
642        &base_peripherals.ble_radio,
643        mux_alarm,
644    )
645    .finalize(components::ble_component_static!(
646        nrf52833::rtc::Rtc,
647        nrf52833::ble_radio::Radio
648    ));
649
650    //--------------------------------------------------------------------------
651    // LED Matrix
652    //--------------------------------------------------------------------------
653
654    let led_matrix = components::led_matrix::LedMatrixComponent::new(
655        mux_alarm,
656        components::led_line_component_static!(
657            nrf52833::gpio::GPIOPin,
658            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[0]],
659            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[1]],
660            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[2]],
661            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[3]],
662            &nrf52833_peripherals.gpio_port[LED_MATRIX_COLS[4]],
663        ),
664        components::led_line_component_static!(
665            nrf52833::gpio::GPIOPin,
666            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[0]],
667            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[1]],
668            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[2]],
669            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[3]],
670            &nrf52833_peripherals.gpio_port[LED_MATRIX_ROWS[4]],
671        ),
672        kernel::hil::gpio::ActivationMode::ActiveLow,
673        kernel::hil::gpio::ActivationMode::ActiveHigh,
674        60,
675    )
676    .finalize(components::led_matrix_component_static!(
677        nrf52833::gpio::GPIOPin,
678        nrf52::rtc::Rtc<'static>,
679        5,
680        5
681    ));
682
683    let led = static_init!(
684        capsules_core::led::LedDriver<
685            'static,
686            capsules_extra::led_matrix::LedMatrixLed<
687                'static,
688                nrf52::gpio::GPIOPin<'static>,
689                capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
690                    'static,
691                    nrf52::rtc::Rtc<'static>,
692                >,
693            >,
694            25,
695        >,
696        capsules_core::led::LedDriver::new(components::led_matrix_leds!(
697            nrf52::gpio::GPIOPin<'static>,
698            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
699                'static,
700                nrf52::rtc::Rtc<'static>,
701            >,
702            led_matrix,
703            (0, 0),
704            (1, 0),
705            (2, 0),
706            (3, 0),
707            (4, 0),
708            (0, 1),
709            (1, 1),
710            (2, 1),
711            (3, 1),
712            (4, 1),
713            (0, 2),
714            (1, 2),
715            (2, 2),
716            (3, 2),
717            (4, 2),
718            (0, 3),
719            (1, 3),
720            (2, 3),
721            (3, 3),
722            (4, 3),
723            (0, 4),
724            (1, 4),
725            (2, 4),
726            (3, 4),
727            (4, 4)
728        )),
729    );
730
731    //--------------------------------------------------------------------------
732    // Process Console
733    //--------------------------------------------------------------------------
734    let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
735        .finalize(components::process_printer_text_component_static!());
736    PROCESS_PRINTER = Some(process_printer);
737
738    let _process_console = components::process_console::ProcessConsoleComponent::new(
739        board_kernel,
740        uart_mux,
741        mux_alarm,
742        process_printer,
743        Some(cortexm4::support::reset),
744    )
745    .finalize(components::process_console_component_static!(
746        nrf52833::rtc::Rtc
747    ));
748    let _ = _process_console.start();
749
750    let chip = static_init!(
751        nrf52833::chip::NRF52<Nrf52833DefaultPeripherals>,
752        nrf52833::chip::NRF52::new(nrf52833_peripherals)
753    );
754    CHIP = Some(chip);
755
756    //--------------------------------------------------------------------------
757    // Credential Checking
758    //--------------------------------------------------------------------------
759
760    // Create the credential checker.
761    let checking_policy = components::appid::checker_null::AppCheckerNullComponent::new()
762        .finalize(components::app_checker_null_component_static!());
763
764    // Create the AppID assigner.
765    let assigner = components::appid::assigner_tbf::AppIdAssignerTbfHeaderComponent::new()
766        .finalize(components::appid_assigner_tbf_header_component_static!());
767
768    // Create the process checking machine.
769    let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
770        .finalize(components::process_checker_machine_component_static!());
771
772    //--------------------------------------------------------------------------
773    // STORAGE PERMISSIONS
774    //--------------------------------------------------------------------------
775
776    let storage_permissions_policy =
777        components::storage_permissions::null::StoragePermissionsNullComponent::new().finalize(
778            components::storage_permissions_null_component_static!(
779                nrf52833::chip::NRF52<Nrf52833DefaultPeripherals>,
780                kernel::process::ProcessStandardDebugFull,
781            ),
782        );
783
784    // These symbols are defined in the standard Tock linker script.
785    extern "C" {
786        /// Beginning of the ROM region containing app images.
787        static _sapps: u8;
788        /// End of the ROM region containing app images.
789        static _eapps: u8;
790        /// Beginning of the RAM region for app memory.
791        static mut _sappmem: u8;
792        /// End of the RAM region for app memory.
793        static _eappmem: u8;
794    }
795
796    let app_flash_slice = core::slice::from_raw_parts(
797        core::ptr::addr_of!(_sapps),
798        core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
799    );
800    let app_memory_slice = core::slice::from_raw_parts_mut(
801        core::ptr::addr_of_mut!(_sappmem),
802        core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
803    );
804
805    // Create and start the asynchronous process loader.
806    let loader = components::loader::sequential::ProcessLoaderSequentialComponent::new(
807        checker,
808        board_kernel,
809        chip,
810        &FAULT_RESPONSE,
811        assigner,
812        storage_permissions_policy,
813        app_flash_slice,
814        app_memory_slice,
815    )
816    .finalize(components::process_loader_sequential_component_static!(
817        nrf52833::chip::NRF52<Nrf52833DefaultPeripherals>,
818        kernel::process::ProcessStandardDebugFull,
819        NUM_PROCS
820    ));
821
822    //--------------------------------------------------------------------------
823    // Dynamic App Loading
824    //--------------------------------------------------------------------------
825
826    // Create the dynamic binary flasher.
827    let dynamic_binary_storage =
828        components::dynamic_binary_storage::SequentialBinaryStorageComponent::new(
829            &base_peripherals.nvmc,
830            loader,
831        )
832        .finalize(components::sequential_binary_storage_component_static!(
833            nrf52833::nvmc::Nvmc,
834            nrf52833::chip::NRF52<Nrf52833DefaultPeripherals>,
835            kernel::process::ProcessStandardDebugFull,
836        ));
837
838    // Create the dynamic app loader capsule.
839    let dynamic_app_loader = components::app_loader::AppLoaderComponent::new(
840        board_kernel,
841        capsules_extra::app_loader::DRIVER_NUM,
842        dynamic_binary_storage,
843        dynamic_binary_storage,
844    )
845    .finalize(components::app_loader_component_static!(
846        DynamicBinaryStorage<'static>,
847        DynamicBinaryStorage<'static>,
848    ));
849
850    //--------------------------------------------------------------------------
851    // FINAL SETUP AND BOARD BOOT
852    //--------------------------------------------------------------------------
853
854    // it seems that microbit v2 has no external clock
855    base_peripherals.clock.low_stop();
856    base_peripherals.clock.high_stop();
857    base_peripherals.clock.low_start();
858    base_peripherals.clock.high_start();
859    while !base_peripherals.clock.low_started() {}
860    while !base_peripherals.clock.high_started() {}
861
862    let scheduler = components::sched::round_robin::RoundRobinComponent::new(processes)
863        .finalize(components::round_robin_component_static!(NUM_PROCS));
864
865    let microbit = MicroBit {
866        ble_radio,
867        ieee802154,
868        eui64,
869        console,
870        gpio,
871        button,
872        led,
873        rng,
874        temperature,
875        lsm303agr,
876        ninedof,
877        buzzer_driver,
878        pwm,
879        sound_pressure,
880        adc: adc_syscall,
881        alarm,
882        app_flash,
883        ipc: kernel::ipc::IPC::new(
884            board_kernel,
885            kernel::ipc::DRIVER_NUM,
886            &memory_allocation_capability,
887        ),
888        dynamic_app_loader,
889
890        scheduler,
891        systick: cortexm4::systick::SysTick::new_with_calibration(64000000),
892    };
893
894    debug!("Initialization complete. Entering main loop.");
895
896    (board_kernel, microbit, chip)
897}
898
899/// Main function called after RAM initialized.
900#[no_mangle]
901pub unsafe fn main() {
902    let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
903
904    let (board_kernel, board, chip) = start();
905    board_kernel.kernel_loop(&board, chip, Some(&board.ipc), &main_loop_capability);
906}