1#![no_std]
10#![no_main]
11#![deny(missing_docs)]
12
13use core::ptr::addr_of;
14use core::ptr::addr_of_mut;
15
16use capsules_core::virtualizers::virtual_aes_ccm::MuxAES128CCM;
17
18use kernel::capabilities;
19use kernel::component::Component;
20use kernel::hil;
21use kernel::hil::buzzer::Buzzer;
22use kernel::hil::i2c::I2CMaster;
23use kernel::hil::led::LedHigh;
24use kernel::hil::symmetric_encryption::AES128;
25use kernel::hil::time::Alarm;
26use kernel::hil::time::Counter;
27use kernel::hil::usb::Client;
28use kernel::platform::chip::Chip;
29use kernel::platform::{KernelResources, SyscallDriverLookup};
30use kernel::scheduler::round_robin::RoundRobinSched;
31#[allow(unused_imports)]
32use kernel::{create_capability, debug, debug_gpio, debug_verbose, static_init};
33
34use nrf52840::gpio::Pin;
35use nrf52840::interrupt_service::Nrf52840DefaultPeripherals;
36
37const LED_RED_PIN: Pin = Pin::P1_01;
39const LED_WHITE_PIN: Pin = Pin::P0_10;
40
41const LED_KERNEL_PIN: Pin = Pin::P1_01;
42
43const SPEAKER_PIN: Pin = Pin::P1_00;
45
46const BUTTON_LEFT: Pin = Pin::P1_02;
48const BUTTON_RIGHT: Pin = Pin::P1_10;
49
50#[allow(dead_code)]
51const GPIO_D0: Pin = Pin::P0_04;
52#[allow(dead_code)]
53const GPIO_D1: Pin = Pin::P0_05;
54#[allow(dead_code)]
55const GPIO_D2: Pin = Pin::P0_03;
56#[allow(dead_code)]
57const GPIO_D3: Pin = Pin::P0_28;
58#[allow(dead_code)]
59const GPIO_D4: Pin = Pin::P0_02;
60
61const GPIO_D6: Pin = Pin::P1_09;
62const GPIO_D7: Pin = Pin::P0_07;
63const GPIO_D8: Pin = Pin::P1_07;
64const GPIO_D9: Pin = Pin::P0_27;
65
66#[allow(dead_code)]
67const GPIO_D10: Pin = Pin::P0_30;
68#[allow(dead_code)]
69const GPIO_D12: Pin = Pin::P0_31;
70
71const GPIO_D13: Pin = Pin::P0_08;
72const GPIO_D14: Pin = Pin::P0_06;
73const GPIO_D15: Pin = Pin::P0_26;
74const GPIO_D16: Pin = Pin::P0_29;
75
76const _UART_TX_PIN: Pin = Pin::P0_05;
77const _UART_RX_PIN: Pin = Pin::P0_04;
78
79const I2C_SDA_PIN: Pin = Pin::P0_24;
81const I2C_SCL_PIN: Pin = Pin::P0_25;
82
83const APDS9960_PIN: Pin = Pin::P0_09;
85
86const PAN_ID: u16 = 0xABCD;
88
89const ST7789H2_SCK: Pin = Pin::P0_14;
91const ST7789H2_MOSI: Pin = Pin::P0_15;
92const ST7789H2_MISO: Pin = Pin::P0_26; const ST7789H2_CS: Pin = Pin::P0_12;
94const ST7789H2_DC: Pin = Pin::P0_13;
95const ST7789H2_RESET: Pin = Pin::P1_03;
96
97const _ST7789H2_LITE: Pin = Pin::P1_05;
99
100pub mod io;
102
103const FAULT_RESPONSE: capsules_system::process_policies::StopWithDebugFaultPolicy =
106 capsules_system::process_policies::StopWithDebugFaultPolicy {};
107
108const NUM_PROCS: usize = 8;
110
111static mut PROCESSES: [Option<&'static dyn kernel::process::Process>; NUM_PROCS] =
112 [None; NUM_PROCS];
113
114static mut CHIP: Option<&'static nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>> = None;
115static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::ProcessPrinterText> =
116 None;
117static mut CDC_REF_FOR_PANIC: Option<
118 &'static capsules_extra::usb::cdc::CdcAcm<
119 'static,
120 nrf52::usbd::Usbd,
121 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, nrf52::rtc::Rtc>,
122 >,
123> = None;
124static mut NRF52_POWER: Option<&'static nrf52840::power::Power> = None;
125
126#[no_mangle]
128#[link_section = ".stack_buffer"]
129pub static mut STACK_MEMORY: [u8; 0x1000] = [0; 0x1000];
130
131fn baud_rate_reset_bootloader_enter() {
133 unsafe {
134 NRF52_POWER.unwrap().set_gpregret(0x90);
137 cortexm4::scb::reset();
140 }
141}
142
143type SHT3xSensor = components::sht3x::SHT3xComponentType<
144 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, nrf52::rtc::Rtc<'static>>,
145 capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, nrf52840::i2c::TWI<'static>>,
146>;
147type TemperatureDriver = components::temperature::TemperatureComponentType<SHT3xSensor>;
148type HumidityDriver = components::humidity::HumidityComponentType<SHT3xSensor>;
149type RngDriver = components::rng::RngComponentType<nrf52840::trng::Trng<'static>>;
150
151type Ieee802154Driver = components::ieee802154::Ieee802154ComponentType<
152 nrf52840::ieee802154_radio::Radio<'static>,
153 nrf52840::aes::AesECB<'static>,
154>;
155
156pub struct Platform {
158 ble_radio: &'static capsules_extra::ble_advertising_driver::BLE<
159 'static,
160 nrf52::ble_radio::Radio<'static>,
161 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
162 'static,
163 nrf52::rtc::Rtc<'static>,
164 >,
165 >,
166 ieee802154_radio: &'static Ieee802154Driver,
167 console: &'static capsules_core::console::Console<'static>,
168 proximity: &'static capsules_extra::proximity::ProximitySensor<'static>,
169 gpio: &'static capsules_core::gpio::GPIO<'static, nrf52::gpio::GPIOPin<'static>>,
170 led: &'static capsules_core::led::LedDriver<
171 'static,
172 LedHigh<'static, nrf52::gpio::GPIOPin<'static>>,
173 2,
174 >,
175 button: &'static capsules_core::button::Button<'static, nrf52::gpio::GPIOPin<'static>>,
176 screen: &'static capsules_extra::screen::Screen<'static>,
177 rng: &'static RngDriver,
178 ipc: kernel::ipc::IPC<{ NUM_PROCS as u8 }>,
179 alarm: &'static capsules_core::alarm::AlarmDriver<
180 'static,
181 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
182 'static,
183 nrf52::rtc::Rtc<'static>,
184 >,
185 >,
186 buzzer: &'static capsules_extra::buzzer_driver::Buzzer<
187 'static,
188 capsules_extra::buzzer_pwm::PwmBuzzer<
189 'static,
190 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
191 'static,
192 nrf52840::rtc::Rtc<'static>,
193 >,
194 capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52840::pwm::Pwm>,
195 >,
196 >,
197 adc: &'static capsules_core::adc::AdcVirtualized<'static>,
198 temperature: &'static TemperatureDriver,
199 humidity: &'static HumidityDriver,
200 scheduler: &'static RoundRobinSched<'static>,
201 systick: cortexm4::systick::SysTick,
202}
203
204impl SyscallDriverLookup for Platform {
205 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
206 where
207 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
208 {
209 match driver_num {
210 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
211 capsules_extra::proximity::DRIVER_NUM => f(Some(self.proximity)),
212 capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
213 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
214 capsules_core::led::DRIVER_NUM => f(Some(self.led)),
215 capsules_core::button::DRIVER_NUM => f(Some(self.button)),
216 capsules_core::adc::DRIVER_NUM => f(Some(self.adc)),
217 capsules_extra::screen::DRIVER_NUM => f(Some(self.screen)),
218 capsules_core::rng::DRIVER_NUM => f(Some(self.rng)),
219 capsules_extra::ble_advertising_driver::DRIVER_NUM => f(Some(self.ble_radio)),
220 capsules_extra::ieee802154::DRIVER_NUM => f(Some(self.ieee802154_radio)),
221 capsules_extra::buzzer_driver::DRIVER_NUM => f(Some(self.buzzer)),
222 kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
223 capsules_extra::temperature::DRIVER_NUM => f(Some(self.temperature)),
224 capsules_extra::humidity::DRIVER_NUM => f(Some(self.humidity)),
225 _ => f(None),
226 }
227 }
228}
229
230impl KernelResources<nrf52::chip::NRF52<'static, Nrf52840DefaultPeripherals<'static>>>
231 for Platform
232{
233 type SyscallDriverLookup = Self;
234 type SyscallFilter = ();
235 type ProcessFault = ();
236 type Scheduler = RoundRobinSched<'static>;
237 type SchedulerTimer = cortexm4::systick::SysTick;
238 type WatchDog = ();
239 type ContextSwitchCallback = ();
240
241 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
242 self
243 }
244 fn syscall_filter(&self) -> &Self::SyscallFilter {
245 &()
246 }
247 fn process_fault(&self) -> &Self::ProcessFault {
248 &()
249 }
250 fn scheduler(&self) -> &Self::Scheduler {
251 self.scheduler
252 }
253 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
254 &self.systick
255 }
256 fn watchdog(&self) -> &Self::WatchDog {
257 &()
258 }
259 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
260 &()
261 }
262}
263
264#[inline(never)]
268unsafe fn start() -> (
269 &'static kernel::Kernel,
270 Platform,
271 &'static nrf52840::chip::NRF52<'static, Nrf52840DefaultPeripherals<'static>>,
272) {
273 nrf52840::init();
274
275 let ieee802154_ack_buf = static_init!(
276 [u8; nrf52840::ieee802154_radio::ACK_BUF_SIZE],
277 [0; nrf52840::ieee802154_radio::ACK_BUF_SIZE]
278 );
279 let nrf52840_peripherals = static_init!(
281 Nrf52840DefaultPeripherals,
282 Nrf52840DefaultPeripherals::new(ieee802154_ack_buf)
283 );
284
285 nrf52840_peripherals.init();
287
288 let base_peripherals = &nrf52840_peripherals.nrf52;
289
290 NRF52_POWER = Some(&base_peripherals.pwr_clk);
293
294 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&*addr_of!(PROCESSES)));
295
296 let process_management_capability =
303 create_capability!(capabilities::ProcessManagementCapability);
304 let memory_allocation_capability = create_capability!(capabilities::MemoryAllocationCapability);
305
306 kernel::debug::assign_gpios(
314 Some(&nrf52840_peripherals.gpio_port[LED_KERNEL_PIN]),
315 None,
316 None,
317 );
318
319 let gpio = components::gpio::GpioComponent::new(
324 board_kernel,
325 capsules_core::gpio::DRIVER_NUM,
326 components::gpio_component_helper!(
327 nrf52840::gpio::GPIOPin,
328 6 => &nrf52840_peripherals.gpio_port[GPIO_D6],
337 7 => &nrf52840_peripherals.gpio_port[GPIO_D7],
338 8 => &nrf52840_peripherals.gpio_port[GPIO_D8],
339 9 => &nrf52840_peripherals.gpio_port[GPIO_D9],
340
341 13 => &nrf52840_peripherals.gpio_port[GPIO_D13],
348 14 => &nrf52840_peripherals.gpio_port[GPIO_D14],
349 15 => &nrf52840_peripherals.gpio_port[GPIO_D15],
350 16 => &nrf52840_peripherals.gpio_port[GPIO_D16]
351 ),
352 )
353 .finalize(components::gpio_component_static!(nrf52840::gpio::GPIOPin));
354
355 let led = components::led::LedsComponent::new().finalize(components::led_component_static!(
360 LedHigh<'static, nrf52840::gpio::GPIOPin>,
361 LedHigh::new(&nrf52840_peripherals.gpio_port[LED_RED_PIN]),
362 LedHigh::new(&nrf52840_peripherals.gpio_port[LED_WHITE_PIN])
363 ));
364
365 let button = components::button::ButtonComponent::new(
369 board_kernel,
370 capsules_core::button::DRIVER_NUM,
371 components::button_component_helper!(
372 nrf52840::gpio::GPIOPin,
373 (
374 &nrf52840_peripherals.gpio_port[BUTTON_LEFT],
375 kernel::hil::gpio::ActivationMode::ActiveLow,
376 kernel::hil::gpio::FloatingState::PullUp
377 ), (
379 &nrf52840_peripherals.gpio_port[BUTTON_RIGHT],
380 kernel::hil::gpio::ActivationMode::ActiveLow,
381 kernel::hil::gpio::FloatingState::PullUp
382 ) ),
384 )
385 .finalize(components::button_component_static!(
386 nrf52840::gpio::GPIOPin
387 ));
388
389 let rtc = &base_peripherals.rtc;
394 let _ = rtc.start();
395
396 let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
397 .finalize(components::alarm_mux_component_static!(nrf52::rtc::Rtc));
398 let alarm = components::alarm::AlarmDriverComponent::new(
399 board_kernel,
400 capsules_core::alarm::DRIVER_NUM,
401 mux_alarm,
402 )
403 .finalize(components::alarm_component_static!(nrf52::rtc::Rtc));
404
405 let mux_pwm = static_init!(
410 capsules_core::virtualizers::virtual_pwm::MuxPwm<'static, nrf52840::pwm::Pwm>,
411 capsules_core::virtualizers::virtual_pwm::MuxPwm::new(&base_peripherals.pwm0)
412 );
413 let virtual_pwm_buzzer = static_init!(
414 capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52840::pwm::Pwm>,
415 capsules_core::virtualizers::virtual_pwm::PwmPinUser::new(
416 mux_pwm,
417 nrf52840::pinmux::Pinmux::new(SPEAKER_PIN as u32)
418 )
419 );
420 virtual_pwm_buzzer.add_to_mux();
421
422 let virtual_alarm_buzzer = static_init!(
423 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, nrf52840::rtc::Rtc>,
424 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm::new(mux_alarm)
425 );
426 virtual_alarm_buzzer.setup();
427
428 let pwm_buzzer = static_init!(
429 capsules_extra::buzzer_pwm::PwmBuzzer<
430 'static,
431 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
432 'static,
433 nrf52840::rtc::Rtc,
434 >,
435 capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52840::pwm::Pwm>,
436 >,
437 capsules_extra::buzzer_pwm::PwmBuzzer::new(
438 virtual_pwm_buzzer,
439 virtual_alarm_buzzer,
440 capsules_extra::buzzer_pwm::DEFAULT_MAX_BUZZ_TIME_MS,
441 )
442 );
443
444 let buzzer = static_init!(
445 capsules_extra::buzzer_driver::Buzzer<
446 'static,
447 capsules_extra::buzzer_pwm::PwmBuzzer<
448 'static,
449 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
450 'static,
451 nrf52840::rtc::Rtc,
452 >,
453 capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52840::pwm::Pwm>,
454 >,
455 >,
456 capsules_extra::buzzer_driver::Buzzer::new(
457 pwm_buzzer,
458 capsules_extra::buzzer_driver::DEFAULT_MAX_BUZZ_TIME_MS,
459 board_kernel.create_grant(
460 capsules_extra::buzzer_driver::DRIVER_NUM,
461 &memory_allocation_capability
462 )
463 )
464 );
465
466 pwm_buzzer.set_client(buzzer);
467
468 virtual_alarm_buzzer.set_alarm_client(pwm_buzzer);
469
470 let serial_number_buf = static_init!([u8; 17], [0; 17]);
480 let serial_number_string: &'static str =
481 (*addr_of!(nrf52::ficr::FICR_INSTANCE)).address_str(serial_number_buf);
482 let strings = static_init!(
483 [&str; 3],
484 [
485 "Adafruit", "CLUE nRF52840 - TockOS", serial_number_string, ]
489 );
490
491 let cdc = components::cdc::CdcAcmComponent::new(
492 &nrf52840_peripherals.usbd,
493 capsules_extra::usb::cdc::MAX_CTRL_PACKET_SIZE_NRF52840,
494 0x239a,
495 0x8071,
496 strings,
497 mux_alarm,
498 Some(&baud_rate_reset_bootloader_enter),
499 )
500 .finalize(components::cdc_acm_component_static!(
501 nrf52::usbd::Usbd,
502 nrf52::rtc::Rtc
503 ));
504 CDC_REF_FOR_PANIC = Some(cdc); let uart_mux = components::console::UartMuxComponent::new(cdc, 115200)
508 .finalize(components::uart_mux_component_static!());
509
510 let console = components::console::ConsoleComponent::new(
512 board_kernel,
513 capsules_core::console::DRIVER_NUM,
514 uart_mux,
515 )
516 .finalize(components::console_component_static!());
517 components::debug_writer::DebugWriterComponent::new(
519 uart_mux,
520 create_capability!(capabilities::SetDebugWriterCapability),
521 )
522 .finalize(components::debug_writer_component_static!());
523
524 let rng = components::rng::RngComponent::new(
529 board_kernel,
530 capsules_core::rng::DRIVER_NUM,
531 &base_peripherals.trng,
532 )
533 .finalize(components::rng_component_static!(nrf52840::trng::Trng));
534
535 base_peripherals.adc.calibrate();
539
540 let adc_mux = components::adc::AdcMuxComponent::new(&base_peripherals.adc)
541 .finalize(components::adc_mux_component_static!(nrf52840::adc::Adc));
542
543 let adc_syscall =
544 components::adc::AdcVirtualComponent::new(board_kernel, capsules_core::adc::DRIVER_NUM)
545 .finalize(components::adc_syscall_component_helper!(
546 components::adc::AdcComponent::new(
548 adc_mux,
549 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput7)
550 )
551 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
552 components::adc::AdcComponent::new(
554 adc_mux,
555 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput5)
556 )
557 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
558 components::adc::AdcComponent::new(
560 adc_mux,
561 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput2)
562 )
563 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
564 components::adc::AdcComponent::new(
566 adc_mux,
567 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput3)
568 )
569 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
570 components::adc::AdcComponent::new(
572 adc_mux,
573 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput1)
574 )
575 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
576 components::adc::AdcComponent::new(
578 adc_mux,
579 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput4)
580 )
581 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
582 components::adc::AdcComponent::new(
584 adc_mux,
585 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput0)
586 )
587 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
588 ));
589
590 let sensors_i2c_bus = static_init!(
595 capsules_core::virtualizers::virtual_i2c::MuxI2C<'static, nrf52840::i2c::TWI>,
596 capsules_core::virtualizers::virtual_i2c::MuxI2C::new(&base_peripherals.twi1, None,)
597 );
598 kernel::deferred_call::DeferredCallClient::register(sensors_i2c_bus);
599 base_peripherals.twi1.configure(
600 nrf52840::pinmux::Pinmux::new(I2C_SCL_PIN as u32),
601 nrf52840::pinmux::Pinmux::new(I2C_SDA_PIN as u32),
602 );
603 base_peripherals.twi1.set_master_client(sensors_i2c_bus);
604
605 let apds9960 = components::apds9960::Apds9960Component::new(
606 sensors_i2c_bus,
607 0x39,
608 &nrf52840_peripherals.gpio_port[APDS9960_PIN],
609 )
610 .finalize(components::apds9960_component_static!(nrf52840::i2c::TWI));
611 let proximity = components::proximity::ProximityComponent::new(
612 apds9960,
613 board_kernel,
614 capsules_extra::proximity::DRIVER_NUM,
615 )
616 .finalize(components::proximity_component_static!());
617
618 let sht3x = components::sht3x::SHT3xComponent::new(
619 sensors_i2c_bus,
620 capsules_extra::sht3x::BASE_ADDR,
621 mux_alarm,
622 )
623 .finalize(components::sht3x_component_static!(
624 nrf52::rtc::Rtc<'static>,
625 nrf52840::i2c::TWI
626 ));
627
628 let temperature = components::temperature::TemperatureComponent::new(
629 board_kernel,
630 capsules_extra::temperature::DRIVER_NUM,
631 sht3x,
632 )
633 .finalize(components::temperature_component_static!(SHT3xSensor));
634
635 let humidity = components::humidity::HumidityComponent::new(
636 board_kernel,
637 capsules_extra::humidity::DRIVER_NUM,
638 sht3x,
639 )
640 .finalize(components::humidity_component_static!(SHT3xSensor));
641
642 let spi_mux = components::spi::SpiMuxComponent::new(&base_peripherals.spim0)
647 .finalize(components::spi_mux_component_static!(nrf52840::spi::SPIM));
648
649 base_peripherals.spim0.configure(
650 nrf52840::pinmux::Pinmux::new(ST7789H2_MOSI as u32),
651 nrf52840::pinmux::Pinmux::new(ST7789H2_MISO as u32),
652 nrf52840::pinmux::Pinmux::new(ST7789H2_SCK as u32),
653 );
654
655 let bus = components::bus::SpiMasterBusComponent::new(
656 spi_mux,
657 hil::spi::cs::IntoChipSelect::<_, hil::spi::cs::ActiveLow>::into_cs(
658 &nrf52840_peripherals.gpio_port[ST7789H2_CS],
659 ),
660 20_000_000,
661 kernel::hil::spi::ClockPhase::SampleLeading,
662 kernel::hil::spi::ClockPolarity::IdleLow,
663 )
664 .finalize(components::spi_bus_component_static!(nrf52840::spi::SPIM));
665
666 let tft = components::st77xx::ST77XXComponent::new(
667 mux_alarm,
668 bus,
669 Some(&nrf52840_peripherals.gpio_port[ST7789H2_DC]),
670 Some(&nrf52840_peripherals.gpio_port[ST7789H2_RESET]),
671 &capsules_extra::st77xx::ST7789H2,
672 )
673 .finalize(components::st77xx_component_static!(
674 capsules_extra::bus::SpiMasterBus<
676 'static,
677 capsules_core::virtualizers::virtual_spi::VirtualSpiMasterDevice<
678 'static,
679 nrf52840::spi::SPIM,
680 >,
681 >,
682 nrf52840::rtc::Rtc,
684 nrf52::gpio::GPIOPin<'static>
686 ));
687
688 let _ = tft.init();
689
690 let screen = components::screen::ScreenComponent::new(
691 board_kernel,
692 capsules_extra::screen::DRIVER_NUM,
693 tft,
694 Some(tft),
695 )
696 .finalize(components::screen_component_static!(57600));
697
698 let ble_radio = components::ble::BLEComponent::new(
703 board_kernel,
704 capsules_extra::ble_advertising_driver::DRIVER_NUM,
705 &base_peripherals.ble_radio,
706 mux_alarm,
707 )
708 .finalize(components::ble_component_static!(
709 nrf52840::rtc::Rtc,
710 nrf52840::ble_radio::Radio
711 ));
712
713 let aes_mux = static_init!(
714 MuxAES128CCM<'static, nrf52840::aes::AesECB>,
715 MuxAES128CCM::new(&base_peripherals.ecb,)
716 );
717 kernel::deferred_call::DeferredCallClient::register(aes_mux);
718 base_peripherals.ecb.set_client(aes_mux);
719
720 let device_id = (*addr_of!(nrf52840::ficr::FICR_INSTANCE)).id();
721
722 let device_id_bottom_16 = u16::from_le_bytes([device_id[0], device_id[1]]);
723
724 let (ieee802154_radio, _mux_mac) = components::ieee802154::Ieee802154Component::new(
725 board_kernel,
726 capsules_extra::ieee802154::DRIVER_NUM,
727 &nrf52840_peripherals.ieee802154_radio,
728 aes_mux,
729 PAN_ID,
730 device_id_bottom_16,
731 device_id,
732 )
733 .finalize(components::ieee802154_component_static!(
734 nrf52840::ieee802154_radio::Radio,
735 nrf52840::aes::AesECB<'static>
736 ));
737
738 let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
739 .finalize(components::process_printer_text_component_static!());
740 PROCESS_PRINTER = Some(process_printer);
741
742 let pconsole = components::process_console::ProcessConsoleComponent::new(
743 board_kernel,
744 uart_mux,
745 mux_alarm,
746 process_printer,
747 Some(cortexm4::support::reset),
748 )
749 .finalize(components::process_console_component_static!(
750 nrf52840::rtc::Rtc
751 ));
752 let _ = pconsole.start();
753
754 nrf52_components::NrfClockComponent::new(&base_peripherals.clock).finalize(());
761
762 let scheduler = components::sched::round_robin::RoundRobinComponent::new(&*addr_of!(PROCESSES))
763 .finalize(components::round_robin_component_static!(NUM_PROCS));
764
765 let platform = Platform {
766 ble_radio,
767 ieee802154_radio,
768 console,
769 proximity,
770 led,
771 gpio,
772 adc: adc_syscall,
773 screen,
774 button,
775 rng,
776 buzzer,
777 alarm,
778 ipc: kernel::ipc::IPC::new(
779 board_kernel,
780 kernel::ipc::DRIVER_NUM,
781 &memory_allocation_capability,
782 ),
783 temperature,
784 humidity,
785 scheduler,
786 systick: cortexm4::systick::SysTick::new_with_calibration(64000000),
787 };
788
789 let chip = static_init!(
790 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
791 nrf52840::chip::NRF52::new(nrf52840_peripherals)
792 );
793 CHIP = Some(chip);
794
795 chip.mpu().clear_mpu();
797
798 cdc.enable();
800 cdc.attach();
801
802 debug!("Initialization complete. Entering main loop.");
803
804 extern "C" {
810 static _sapps: u8;
812 static _eapps: u8;
814 static mut _sappmem: u8;
816 static _eappmem: u8;
818 }
819
820 kernel::process::load_processes(
821 board_kernel,
822 chip,
823 core::slice::from_raw_parts(
824 core::ptr::addr_of!(_sapps),
825 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
826 ),
827 core::slice::from_raw_parts_mut(
828 core::ptr::addr_of_mut!(_sappmem),
829 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
830 ),
831 &mut *addr_of_mut!(PROCESSES),
832 &FAULT_RESPONSE,
833 &process_management_capability,
834 )
835 .unwrap_or_else(|err| {
836 debug!("Error loading processes!");
837 debug!("{:?}", err);
838 });
839
840 (board_kernel, platform, chip)
841}
842
843#[no_mangle]
845pub unsafe fn main() {
846 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
847
848 let (board_kernel, board, chip) = start();
849 board_kernel.kernel_loop(&board, chip, Some(&board.ipc), &main_loop_capability);
850}