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