1#![no_std]
10#![no_main]
11#![deny(missing_docs)]
12
13use core::ptr::addr_of;
14
15use kernel::capabilities;
16use kernel::component::Component;
17use kernel::hil::time::Counter;
18use kernel::platform::{KernelResources, SyscallDriverLookup};
19use kernel::process::ProcessArray;
20use kernel::scheduler::round_robin::RoundRobinSched;
21
22#[allow(unused_imports)]
23use kernel::{create_capability, debug, debug_gpio, debug_verbose, static_init};
24
25use nrf52833::gpio::Pin;
26use nrf52833::interrupt_service::Nrf52833DefaultPeripherals;
27
28const LED_KERNEL_PIN: Pin = Pin::P0_20;
30const LED_MICROPHONE_PIN: Pin = Pin::P0_20;
31
32const BUTTON_A: Pin = Pin::P0_14;
34const BUTTON_B: Pin = Pin::P0_23;
35const TOUCH_LOGO: Pin = Pin::P1_04;
36
37const _GPIO_P0: Pin = Pin::P0_02;
41const _GPIO_P1: Pin = Pin::P0_03;
42const _GPIO_P2: Pin = Pin::P0_04;
43const GPIO_P8: Pin = Pin::P0_10;
44const GPIO_P9: Pin = Pin::P0_09;
45const GPIO_P16: Pin = Pin::P1_02;
46
47const UART_TX_PIN: Pin = Pin::P0_06;
48const UART_RX_PIN: Pin = Pin::P1_08;
49
50const LED_MATRIX_COLS: [Pin; 5] = [Pin::P0_28, Pin::P0_11, Pin::P0_31, Pin::P1_05, Pin::P0_30];
52const LED_MATRIX_ROWS: [Pin; 5] = [Pin::P0_21, Pin::P0_22, Pin::P0_15, Pin::P0_24, Pin::P0_19];
53
54const SPEAKER_PIN: Pin = Pin::P0_00;
57
58const I2C_SDA_PIN: Pin = Pin::P0_16;
60const I2C_SCL_PIN: Pin = Pin::P0_08;
61
62pub mod io;
64
65const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
68 capsules_system::process_policies::PanicFaultPolicy {};
69
70const NUM_PROCS: usize = 4;
72
73type ChipHw = nrf52833::chip::NRF52<'static, Nrf52833DefaultPeripherals<'static>>;
74
75static mut PROCESSES: Option<&'static ProcessArray<NUM_PROCS>> = None;
77static mut CHIP: Option<&'static nrf52833::chip::NRF52<Nrf52833DefaultPeripherals>> = None;
78static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::ProcessPrinterText> =
79 None;
80
81kernel::stack_size! {0x2000}
82
83type TemperatureDriver =
84 components::temperature::TemperatureComponentType<nrf52::temperature::Temp<'static>>;
85type RngDriver = components::rng::RngComponentType<nrf52833::trng::Trng<'static>>;
86type Ieee802154RawDriver =
87 components::ieee802154::Ieee802154RawComponentType<nrf52833::ieee802154_radio::Radio<'static>>;
88type NonVolatilePages = components::dynamic_binary_storage::NVPages<nrf52833::nvmc::Nvmc>;
89type DynamicBinaryStorage<'a> = kernel::dynamic_binary_storage::SequentialDynamicBinaryStorage<
90 'static,
91 'static,
92 nrf52833::chip::NRF52<'a, Nrf52833DefaultPeripherals<'a>>,
93 kernel::process::ProcessStandardDebugFull,
94 NonVolatilePages,
95>;
96pub struct MicroBit {
98 ble_radio: &'static capsules_extra::ble_advertising_driver::BLE<
99 'static,
100 nrf52::ble_radio::Radio<'static>,
101 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
102 'static,
103 nrf52::rtc::Rtc<'static>,
104 >,
105 >,
106 eui64: &'static capsules_extra::eui64::Eui64,
107 ieee802154: &'static Ieee802154RawDriver,
108 console: &'static capsules_core::console::Console<'static>,
109 gpio: &'static capsules_core::gpio::GPIO<'static, nrf52::gpio::GPIOPin<'static>>,
110 led: &'static capsules_core::led::LedDriver<
111 'static,
112 capsules_extra::led_matrix::LedMatrixLed<
113 'static,
114 nrf52::gpio::GPIOPin<'static>,
115 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
116 'static,
117 nrf52::rtc::Rtc<'static>,
118 >,
119 >,
120 25,
121 >,
122 button: &'static capsules_core::button::Button<'static, nrf52::gpio::GPIOPin<'static>>,
123 rng: &'static RngDriver,
124 ninedof: &'static capsules_extra::ninedof::NineDof<'static>,
125 lsm303agr: &'static capsules_extra::lsm303agr::Lsm303agrI2C<
126 'static,
127 capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, nrf52833::i2c::TWI<'static>>,
128 >,
129 temperature: &'static TemperatureDriver,
130 ipc: kernel::ipc::IPC<{ NUM_PROCS as u8 }>,
131 adc: &'static capsules_core::adc::AdcVirtualized<'static>,
132 alarm: &'static capsules_core::alarm::AlarmDriver<
133 'static,
134 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
135 'static,
136 nrf52::rtc::Rtc<'static>,
137 >,
138 >,
139 buzzer_driver: &'static capsules_extra::buzzer_driver::Buzzer<
140 'static,
141 capsules_extra::buzzer_pwm::PwmBuzzer<
142 'static,
143 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
144 'static,
145 nrf52833::rtc::Rtc<'static>,
146 >,
147 capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52833::pwm::Pwm>,
148 >,
149 >,
150 pwm: &'static capsules_extra::pwm::Pwm<'static, 1>,
151 app_flash: &'static capsules_extra::app_flash_driver::AppFlash<'static>,
152 sound_pressure: &'static capsules_extra::sound_pressure::SoundPressureSensor<'static>,
153 dynamic_app_loader: &'static capsules_extra::app_loader::AppLoader<
154 DynamicBinaryStorage<'static>,
155 DynamicBinaryStorage<'static>,
156 >,
157
158 scheduler: &'static RoundRobinSched<'static>,
159 systick: cortexm4::systick::SysTick,
160}
161
162impl SyscallDriverLookup for MicroBit {
163 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
164 where
165 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
166 {
167 match driver_num {
168 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
169 capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
170 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
171 capsules_core::button::DRIVER_NUM => f(Some(self.button)),
172 capsules_core::led::DRIVER_NUM => f(Some(self.led)),
173 capsules_extra::ninedof::DRIVER_NUM => f(Some(self.ninedof)),
174 capsules_core::adc::DRIVER_NUM => f(Some(self.adc)),
175 capsules_extra::temperature::DRIVER_NUM => f(Some(self.temperature)),
176 capsules_extra::lsm303agr::DRIVER_NUM => f(Some(self.lsm303agr)),
177 capsules_core::rng::DRIVER_NUM => f(Some(self.rng)),
178 capsules_extra::ble_advertising_driver::DRIVER_NUM => f(Some(self.ble_radio)),
179 capsules_extra::buzzer_driver::DRIVER_NUM => f(Some(self.buzzer_driver)),
180 capsules_extra::pwm::DRIVER_NUM => f(Some(self.pwm)),
181 capsules_extra::app_flash_driver::DRIVER_NUM => f(Some(self.app_flash)),
182 capsules_extra::sound_pressure::DRIVER_NUM => f(Some(self.sound_pressure)),
183 capsules_extra::eui64::DRIVER_NUM => f(Some(self.eui64)),
184 capsules_extra::ieee802154::DRIVER_NUM => f(Some(self.ieee802154)),
185 kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
186 capsules_extra::app_loader::DRIVER_NUM => f(Some(self.dynamic_app_loader)),
187 _ => f(None),
188 }
189 }
190}
191
192impl KernelResources<nrf52833::chip::NRF52<'static, Nrf52833DefaultPeripherals<'static>>>
193 for MicroBit
194{
195 type SyscallDriverLookup = Self;
196 type SyscallFilter = ();
197 type ProcessFault = ();
198 type Scheduler = RoundRobinSched<'static>;
199 type SchedulerTimer = cortexm4::systick::SysTick;
200 type WatchDog = ();
201 type ContextSwitchCallback = ();
202
203 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
204 self
205 }
206 fn syscall_filter(&self) -> &Self::SyscallFilter {
207 &()
208 }
209 fn process_fault(&self) -> &Self::ProcessFault {
210 &()
211 }
212 fn scheduler(&self) -> &Self::Scheduler {
213 self.scheduler
214 }
215 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
216 &self.systick
217 }
218 fn watchdog(&self) -> &Self::WatchDog {
219 &()
220 }
221 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
222 &()
223 }
224}
225
226#[inline(never)]
230unsafe fn start() -> (
231 &'static kernel::Kernel,
232 MicroBit,
233 &'static nrf52833::chip::NRF52<'static, Nrf52833DefaultPeripherals<'static>>,
234) {
235 nrf52833::init();
236
237 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 let nrf52833_peripherals = static_init!(
248 Nrf52833DefaultPeripherals,
249 Nrf52833DefaultPeripherals::new(ieee802154_ack_buf)
250 );
251
252 nrf52833_peripherals.init();
254
255 let base_peripherals = &nrf52833_peripherals.nrf52;
256
257 let processes = components::process_array::ProcessArrayComponent::new()
259 .finalize(components::process_array_component_static!(NUM_PROCS));
260 PROCESSES = Some(processes);
261
262 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes.as_slice()));
264
265 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 let memory_allocation_capability = create_capability!(capabilities::MemoryAllocationCapability);
289
290 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 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 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 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 ), (
341 &nrf52833_peripherals.gpio_port[BUTTON_B],
342 kernel::hil::gpio::ActivationMode::ActiveLow,
343 kernel::hil::gpio::FloatingState::PullNone
344 ), (
346 &nrf52833_peripherals.gpio_port[TOUCH_LOGO],
347 kernel::hil::gpio::ActivationMode::ActiveLow,
348 kernel::hil::gpio::FloatingState::PullNone
349 ), ),
351 )
352 .finalize(components::button_component_static!(
353 nrf52833::gpio::GPIOPin
354 ));
355
356 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 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 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 let uart_mux = components::console::UartMuxComponent::new(&base_peripherals.uarte0, 115200)
463 .finalize(components::uart_mux_component_static!());
464
465 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 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 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 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 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 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 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 let adc_syscall =
558 components::adc::AdcVirtualComponent::new(board_kernel, capsules_core::adc::DRIVER_NUM)
559 .finalize(components::adc_syscall_component_helper!(
560 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 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 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 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 nrf52833::adc::Adc,
596 50,
598 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 let mux_flash = components::flash::FlashMuxComponent::new(&base_peripherals.nvmc).finalize(
616 components::flash_mux_component_static!(nrf52833::nvmc::Nvmc),
617 );
618
619 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 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 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 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 let checking_policy = components::appid::checker_null::AppCheckerNullComponent::new()
762 .finalize(components::app_checker_null_component_static!());
763
764 let assigner = components::appid::assigner_tbf::AppIdAssignerTbfHeaderComponent::new()
766 .finalize(components::appid_assigner_tbf_header_component_static!());
767
768 let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
770 .finalize(components::process_checker_machine_component_static!());
771
772 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 extern "C" {
786 static _sapps: u8;
788 static _eapps: u8;
790 static mut _sappmem: u8;
792 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 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 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 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 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#[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}