1#![no_std]
10#![no_main]
11#![deny(missing_docs)]
12
13use core::ptr::addr_of;
14
15use capsules_core::virtualizers::virtual_aes_ccm::MuxAES128CCM;
16
17use kernel::capabilities;
18use kernel::component::Component;
19use kernel::hil;
20use kernel::hil::buzzer::Buzzer;
21use kernel::hil::i2c::I2CMaster;
22use kernel::hil::led::LedHigh;
23use kernel::hil::symmetric_encryption::AES128;
24use kernel::hil::time::Alarm;
25use kernel::hil::time::Counter;
26use kernel::hil::usb::Client;
27use kernel::platform::chip::Chip;
28use kernel::platform::{KernelResources, SyscallDriverLookup};
29use kernel::process::ProcessArray;
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 ProcessArray<NUM_PROCS>> = None;
113static mut CHIP: Option<&'static nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>> = None;
114static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::ProcessPrinterText> =
115 None;
116static mut CDC_REF_FOR_PANIC: Option<
117 &'static capsules_extra::usb::cdc::CdcAcm<
118 'static,
119 nrf52::usbd::Usbd,
120 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, nrf52::rtc::Rtc>,
121 >,
122> = None;
123static mut NRF52_POWER: Option<&'static nrf52840::power::Power> = None;
124
125kernel::stack_size! {0x1000}
126
127fn baud_rate_reset_bootloader_enter() {
129 unsafe {
130 NRF52_POWER.unwrap().set_gpregret(0x90);
133 cortexm4::scb::reset();
136 }
137}
138
139type SHT3xSensor = components::sht3x::SHT3xComponentType<
140 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, nrf52::rtc::Rtc<'static>>,
141 capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, nrf52840::i2c::TWI<'static>>,
142>;
143type TemperatureDriver = components::temperature::TemperatureComponentType<SHT3xSensor>;
144type HumidityDriver = components::humidity::HumidityComponentType<SHT3xSensor>;
145type RngDriver = components::rng::RngComponentType<nrf52840::trng::Trng<'static>>;
146
147type Ieee802154Driver = components::ieee802154::Ieee802154ComponentType<
148 nrf52840::ieee802154_radio::Radio<'static>,
149 nrf52840::aes::AesECB<'static>,
150>;
151
152pub struct Platform {
154 ble_radio: &'static capsules_extra::ble_advertising_driver::BLE<
155 'static,
156 nrf52::ble_radio::Radio<'static>,
157 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
158 'static,
159 nrf52::rtc::Rtc<'static>,
160 >,
161 >,
162 ieee802154_radio: &'static Ieee802154Driver,
163 console: &'static capsules_core::console::Console<'static>,
164 proximity: &'static capsules_extra::proximity::ProximitySensor<'static>,
165 gpio: &'static capsules_core::gpio::GPIO<'static, nrf52::gpio::GPIOPin<'static>>,
166 led: &'static capsules_core::led::LedDriver<
167 'static,
168 LedHigh<'static, nrf52::gpio::GPIOPin<'static>>,
169 2,
170 >,
171 button: &'static capsules_core::button::Button<'static, nrf52::gpio::GPIOPin<'static>>,
172 screen: &'static capsules_extra::screen::screen::Screen<'static>,
173 rng: &'static RngDriver,
174 ipc: kernel::ipc::IPC<{ NUM_PROCS as u8 }>,
175 alarm: &'static capsules_core::alarm::AlarmDriver<
176 'static,
177 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
178 'static,
179 nrf52::rtc::Rtc<'static>,
180 >,
181 >,
182 buzzer: &'static capsules_extra::buzzer_driver::Buzzer<
183 'static,
184 capsules_extra::buzzer_pwm::PwmBuzzer<
185 'static,
186 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
187 'static,
188 nrf52840::rtc::Rtc<'static>,
189 >,
190 capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52840::pwm::Pwm>,
191 >,
192 >,
193 adc: &'static capsules_core::adc::AdcVirtualized<'static>,
194 temperature: &'static TemperatureDriver,
195 humidity: &'static HumidityDriver,
196 scheduler: &'static RoundRobinSched<'static>,
197 systick: cortexm4::systick::SysTick,
198}
199
200impl SyscallDriverLookup for Platform {
201 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
202 where
203 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
204 {
205 match driver_num {
206 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
207 capsules_extra::proximity::DRIVER_NUM => f(Some(self.proximity)),
208 capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
209 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
210 capsules_core::led::DRIVER_NUM => f(Some(self.led)),
211 capsules_core::button::DRIVER_NUM => f(Some(self.button)),
212 capsules_core::adc::DRIVER_NUM => f(Some(self.adc)),
213 capsules_extra::screen::screen::DRIVER_NUM => f(Some(self.screen)),
214 capsules_core::rng::DRIVER_NUM => f(Some(self.rng)),
215 capsules_extra::ble_advertising_driver::DRIVER_NUM => f(Some(self.ble_radio)),
216 capsules_extra::ieee802154::DRIVER_NUM => f(Some(self.ieee802154_radio)),
217 capsules_extra::buzzer_driver::DRIVER_NUM => f(Some(self.buzzer)),
218 kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
219 capsules_extra::temperature::DRIVER_NUM => f(Some(self.temperature)),
220 capsules_extra::humidity::DRIVER_NUM => f(Some(self.humidity)),
221 _ => f(None),
222 }
223 }
224}
225
226impl KernelResources<nrf52::chip::NRF52<'static, Nrf52840DefaultPeripherals<'static>>>
227 for Platform
228{
229 type SyscallDriverLookup = Self;
230 type SyscallFilter = ();
231 type ProcessFault = ();
232 type Scheduler = RoundRobinSched<'static>;
233 type SchedulerTimer = cortexm4::systick::SysTick;
234 type WatchDog = ();
235 type ContextSwitchCallback = ();
236
237 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
238 self
239 }
240 fn syscall_filter(&self) -> &Self::SyscallFilter {
241 &()
242 }
243 fn process_fault(&self) -> &Self::ProcessFault {
244 &()
245 }
246 fn scheduler(&self) -> &Self::Scheduler {
247 self.scheduler
248 }
249 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
250 &self.systick
251 }
252 fn watchdog(&self) -> &Self::WatchDog {
253 &()
254 }
255 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
256 &()
257 }
258}
259
260#[inline(never)]
264unsafe fn start() -> (
265 &'static kernel::Kernel,
266 Platform,
267 &'static nrf52840::chip::NRF52<'static, Nrf52840DefaultPeripherals<'static>>,
268) {
269 nrf52840::init();
270
271 let ieee802154_ack_buf = static_init!(
272 [u8; nrf52840::ieee802154_radio::ACK_BUF_SIZE],
273 [0; nrf52840::ieee802154_radio::ACK_BUF_SIZE]
274 );
275 let nrf52840_peripherals = static_init!(
277 Nrf52840DefaultPeripherals,
278 Nrf52840DefaultPeripherals::new(ieee802154_ack_buf)
279 );
280
281 nrf52840_peripherals.init();
283
284 let base_peripherals = &nrf52840_peripherals.nrf52;
285
286 NRF52_POWER = Some(&base_peripherals.pwr_clk);
289
290 let processes = components::process_array::ProcessArrayComponent::new()
292 .finalize(components::process_array_component_static!(NUM_PROCS));
293 PROCESSES = Some(processes);
294
295 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes.as_slice()));
297
298 let process_management_capability =
305 create_capability!(capabilities::ProcessManagementCapability);
306 let memory_allocation_capability = create_capability!(capabilities::MemoryAllocationCapability);
307
308 kernel::debug::assign_gpios(
316 Some(&nrf52840_peripherals.gpio_port[LED_KERNEL_PIN]),
317 None,
318 None,
319 );
320
321 let gpio = components::gpio::GpioComponent::new(
326 board_kernel,
327 capsules_core::gpio::DRIVER_NUM,
328 components::gpio_component_helper!(
329 nrf52840::gpio::GPIOPin,
330 6 => &nrf52840_peripherals.gpio_port[GPIO_D6],
339 7 => &nrf52840_peripherals.gpio_port[GPIO_D7],
340 8 => &nrf52840_peripherals.gpio_port[GPIO_D8],
341 9 => &nrf52840_peripherals.gpio_port[GPIO_D9],
342
343 13 => &nrf52840_peripherals.gpio_port[GPIO_D13],
350 14 => &nrf52840_peripherals.gpio_port[GPIO_D14],
351 15 => &nrf52840_peripherals.gpio_port[GPIO_D15],
352 16 => &nrf52840_peripherals.gpio_port[GPIO_D16]
353 ),
354 )
355 .finalize(components::gpio_component_static!(nrf52840::gpio::GPIOPin));
356
357 let led = components::led::LedsComponent::new().finalize(components::led_component_static!(
362 LedHigh<'static, nrf52840::gpio::GPIOPin>,
363 LedHigh::new(&nrf52840_peripherals.gpio_port[LED_RED_PIN]),
364 LedHigh::new(&nrf52840_peripherals.gpio_port[LED_WHITE_PIN])
365 ));
366
367 let button = components::button::ButtonComponent::new(
371 board_kernel,
372 capsules_core::button::DRIVER_NUM,
373 components::button_component_helper!(
374 nrf52840::gpio::GPIOPin,
375 (
376 &nrf52840_peripherals.gpio_port[BUTTON_LEFT],
377 kernel::hil::gpio::ActivationMode::ActiveLow,
378 kernel::hil::gpio::FloatingState::PullUp
379 ), (
381 &nrf52840_peripherals.gpio_port[BUTTON_RIGHT],
382 kernel::hil::gpio::ActivationMode::ActiveLow,
383 kernel::hil::gpio::FloatingState::PullUp
384 ) ),
386 )
387 .finalize(components::button_component_static!(
388 nrf52840::gpio::GPIOPin
389 ));
390
391 let rtc = &base_peripherals.rtc;
396 let _ = rtc.start();
397
398 let mux_alarm = components::alarm::AlarmMuxComponent::new(rtc)
399 .finalize(components::alarm_mux_component_static!(nrf52::rtc::Rtc));
400 let alarm = components::alarm::AlarmDriverComponent::new(
401 board_kernel,
402 capsules_core::alarm::DRIVER_NUM,
403 mux_alarm,
404 )
405 .finalize(components::alarm_component_static!(nrf52::rtc::Rtc));
406
407 let mux_pwm = static_init!(
412 capsules_core::virtualizers::virtual_pwm::MuxPwm<'static, nrf52840::pwm::Pwm>,
413 capsules_core::virtualizers::virtual_pwm::MuxPwm::new(&base_peripherals.pwm0)
414 );
415 let virtual_pwm_buzzer = static_init!(
416 capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52840::pwm::Pwm>,
417 capsules_core::virtualizers::virtual_pwm::PwmPinUser::new(
418 mux_pwm,
419 nrf52840::pinmux::Pinmux::new(SPEAKER_PIN as u32)
420 )
421 );
422 virtual_pwm_buzzer.add_to_mux();
423
424 let virtual_alarm_buzzer = static_init!(
425 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, nrf52840::rtc::Rtc>,
426 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm::new(mux_alarm)
427 );
428 virtual_alarm_buzzer.setup();
429
430 let pwm_buzzer = static_init!(
431 capsules_extra::buzzer_pwm::PwmBuzzer<
432 'static,
433 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
434 'static,
435 nrf52840::rtc::Rtc,
436 >,
437 capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52840::pwm::Pwm>,
438 >,
439 capsules_extra::buzzer_pwm::PwmBuzzer::new(
440 virtual_pwm_buzzer,
441 virtual_alarm_buzzer,
442 capsules_extra::buzzer_pwm::DEFAULT_MAX_BUZZ_TIME_MS,
443 )
444 );
445
446 let buzzer = static_init!(
447 capsules_extra::buzzer_driver::Buzzer<
448 'static,
449 capsules_extra::buzzer_pwm::PwmBuzzer<
450 'static,
451 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<
452 'static,
453 nrf52840::rtc::Rtc,
454 >,
455 capsules_core::virtualizers::virtual_pwm::PwmPinUser<'static, nrf52840::pwm::Pwm>,
456 >,
457 >,
458 capsules_extra::buzzer_driver::Buzzer::new(
459 pwm_buzzer,
460 capsules_extra::buzzer_driver::DEFAULT_MAX_BUZZ_TIME_MS,
461 board_kernel.create_grant(
462 capsules_extra::buzzer_driver::DRIVER_NUM,
463 &memory_allocation_capability
464 )
465 )
466 );
467
468 pwm_buzzer.set_client(buzzer);
469
470 virtual_alarm_buzzer.set_alarm_client(pwm_buzzer);
471
472 let serial_number_buf = static_init!([u8; 17], [0; 17]);
482 let serial_number_string: &'static str =
483 (*addr_of!(nrf52::ficr::FICR_INSTANCE)).address_str(serial_number_buf);
484 let strings = static_init!(
485 [&str; 3],
486 [
487 "Adafruit", "CLUE nRF52840 - TockOS", serial_number_string, ]
491 );
492
493 let cdc = components::cdc::CdcAcmComponent::new(
494 &nrf52840_peripherals.usbd,
495 capsules_extra::usb::cdc::MAX_CTRL_PACKET_SIZE_NRF52840,
496 0x239a,
497 0x8071,
498 strings,
499 mux_alarm,
500 Some(&baud_rate_reset_bootloader_enter),
501 )
502 .finalize(components::cdc_acm_component_static!(
503 nrf52::usbd::Usbd,
504 nrf52::rtc::Rtc
505 ));
506 CDC_REF_FOR_PANIC = Some(cdc); let uart_mux = components::console::UartMuxComponent::new(cdc, 115200)
510 .finalize(components::uart_mux_component_static!());
511
512 let console = components::console::ConsoleComponent::new(
514 board_kernel,
515 capsules_core::console::DRIVER_NUM,
516 uart_mux,
517 )
518 .finalize(components::console_component_static!());
519 components::debug_writer::DebugWriterComponent::new(
521 uart_mux,
522 create_capability!(capabilities::SetDebugWriterCapability),
523 )
524 .finalize(components::debug_writer_component_static!());
525
526 let rng = components::rng::RngComponent::new(
531 board_kernel,
532 capsules_core::rng::DRIVER_NUM,
533 &base_peripherals.trng,
534 )
535 .finalize(components::rng_component_static!(nrf52840::trng::Trng));
536
537 base_peripherals.adc.calibrate();
541
542 let adc_mux = components::adc::AdcMuxComponent::new(&base_peripherals.adc)
543 .finalize(components::adc_mux_component_static!(nrf52840::adc::Adc));
544
545 let adc_syscall =
546 components::adc::AdcVirtualComponent::new(board_kernel, capsules_core::adc::DRIVER_NUM)
547 .finalize(components::adc_syscall_component_helper!(
548 components::adc::AdcComponent::new(
550 adc_mux,
551 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput7)
552 )
553 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
554 components::adc::AdcComponent::new(
556 adc_mux,
557 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput5)
558 )
559 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
560 components::adc::AdcComponent::new(
562 adc_mux,
563 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput2)
564 )
565 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
566 components::adc::AdcComponent::new(
568 adc_mux,
569 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput3)
570 )
571 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
572 components::adc::AdcComponent::new(
574 adc_mux,
575 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput1)
576 )
577 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
578 components::adc::AdcComponent::new(
580 adc_mux,
581 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput4)
582 )
583 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
584 components::adc::AdcComponent::new(
586 adc_mux,
587 nrf52840::adc::AdcChannelSetup::new(nrf52840::adc::AdcChannel::AnalogInput0)
588 )
589 .finalize(components::adc_component_static!(nrf52840::adc::Adc)),
590 ));
591
592 let sensors_i2c_bus = static_init!(
597 capsules_core::virtualizers::virtual_i2c::MuxI2C<'static, nrf52840::i2c::TWI>,
598 capsules_core::virtualizers::virtual_i2c::MuxI2C::new(&base_peripherals.twi1, None,)
599 );
600 kernel::deferred_call::DeferredCallClient::register(sensors_i2c_bus);
601 base_peripherals.twi1.configure(
602 nrf52840::pinmux::Pinmux::new(I2C_SCL_PIN as u32),
603 nrf52840::pinmux::Pinmux::new(I2C_SDA_PIN as u32),
604 );
605 base_peripherals.twi1.set_master_client(sensors_i2c_bus);
606
607 let apds9960 = components::apds9960::Apds9960Component::new(
608 sensors_i2c_bus,
609 0x39,
610 &nrf52840_peripherals.gpio_port[APDS9960_PIN],
611 )
612 .finalize(components::apds9960_component_static!(nrf52840::i2c::TWI));
613 let proximity = components::proximity::ProximityComponent::new(
614 apds9960,
615 board_kernel,
616 capsules_extra::proximity::DRIVER_NUM,
617 )
618 .finalize(components::proximity_component_static!());
619
620 let sht3x = components::sht3x::SHT3xComponent::new(
621 sensors_i2c_bus,
622 capsules_extra::sht3x::BASE_ADDR,
623 mux_alarm,
624 )
625 .finalize(components::sht3x_component_static!(
626 nrf52::rtc::Rtc<'static>,
627 nrf52840::i2c::TWI
628 ));
629
630 let temperature = components::temperature::TemperatureComponent::new(
631 board_kernel,
632 capsules_extra::temperature::DRIVER_NUM,
633 sht3x,
634 )
635 .finalize(components::temperature_component_static!(SHT3xSensor));
636
637 let humidity = components::humidity::HumidityComponent::new(
638 board_kernel,
639 capsules_extra::humidity::DRIVER_NUM,
640 sht3x,
641 )
642 .finalize(components::humidity_component_static!(SHT3xSensor));
643
644 let spi_mux = components::spi::SpiMuxComponent::new(&base_peripherals.spim0)
649 .finalize(components::spi_mux_component_static!(nrf52840::spi::SPIM));
650
651 base_peripherals.spim0.configure(
652 nrf52840::pinmux::Pinmux::new(ST7789H2_MOSI as u32),
653 nrf52840::pinmux::Pinmux::new(ST7789H2_MISO as u32),
654 nrf52840::pinmux::Pinmux::new(ST7789H2_SCK as u32),
655 );
656
657 let bus = components::bus::SpiMasterBusComponent::new(
658 spi_mux,
659 hil::spi::cs::IntoChipSelect::<_, hil::spi::cs::ActiveLow>::into_cs(
660 &nrf52840_peripherals.gpio_port[ST7789H2_CS],
661 ),
662 20_000_000,
663 kernel::hil::spi::ClockPhase::SampleLeading,
664 kernel::hil::spi::ClockPolarity::IdleLow,
665 )
666 .finalize(components::spi_bus_component_static!(nrf52840::spi::SPIM));
667
668 let tft = components::st77xx::ST77XXComponent::new(
669 mux_alarm,
670 bus,
671 Some(&nrf52840_peripherals.gpio_port[ST7789H2_DC]),
672 Some(&nrf52840_peripherals.gpio_port[ST7789H2_RESET]),
673 &capsules_extra::st77xx::ST7789H2,
674 )
675 .finalize(components::st77xx_component_static!(
676 capsules_extra::bus::SpiMasterBus<
678 'static,
679 capsules_core::virtualizers::virtual_spi::VirtualSpiMasterDevice<
680 'static,
681 nrf52840::spi::SPIM,
682 >,
683 >,
684 nrf52840::rtc::Rtc,
686 nrf52::gpio::GPIOPin<'static>
688 ));
689
690 let _ = tft.init();
691
692 let screen = components::screen::ScreenComponent::new(
693 board_kernel,
694 capsules_extra::screen::screen::DRIVER_NUM,
695 tft,
696 Some(tft),
697 )
698 .finalize(components::screen_component_static!(57600));
699
700 let ble_radio = components::ble::BLEComponent::new(
705 board_kernel,
706 capsules_extra::ble_advertising_driver::DRIVER_NUM,
707 &base_peripherals.ble_radio,
708 mux_alarm,
709 )
710 .finalize(components::ble_component_static!(
711 nrf52840::rtc::Rtc,
712 nrf52840::ble_radio::Radio
713 ));
714
715 let aes_mux = static_init!(
716 MuxAES128CCM<'static, nrf52840::aes::AesECB>,
717 MuxAES128CCM::new(&base_peripherals.ecb,)
718 );
719 kernel::deferred_call::DeferredCallClient::register(aes_mux);
720 base_peripherals.ecb.set_client(aes_mux);
721
722 let device_id = (*addr_of!(nrf52840::ficr::FICR_INSTANCE)).id();
723
724 let device_id_bottom_16 = u16::from_le_bytes([device_id[0], device_id[1]]);
725
726 let (ieee802154_radio, _mux_mac) = components::ieee802154::Ieee802154Component::new(
727 board_kernel,
728 capsules_extra::ieee802154::DRIVER_NUM,
729 &nrf52840_peripherals.ieee802154_radio,
730 aes_mux,
731 PAN_ID,
732 device_id_bottom_16,
733 device_id,
734 )
735 .finalize(components::ieee802154_component_static!(
736 nrf52840::ieee802154_radio::Radio,
737 nrf52840::aes::AesECB<'static>
738 ));
739
740 let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
741 .finalize(components::process_printer_text_component_static!());
742 PROCESS_PRINTER = Some(process_printer);
743
744 let pconsole = components::process_console::ProcessConsoleComponent::new(
745 board_kernel,
746 uart_mux,
747 mux_alarm,
748 process_printer,
749 Some(cortexm4::support::reset),
750 )
751 .finalize(components::process_console_component_static!(
752 nrf52840::rtc::Rtc
753 ));
754 let _ = pconsole.start();
755
756 nrf52_components::NrfClockComponent::new(&base_peripherals.clock).finalize(());
763
764 let scheduler = components::sched::round_robin::RoundRobinComponent::new(processes)
765 .finalize(components::round_robin_component_static!(NUM_PROCS));
766
767 let platform = Platform {
768 ble_radio,
769 ieee802154_radio,
770 console,
771 proximity,
772 led,
773 gpio,
774 adc: adc_syscall,
775 screen,
776 button,
777 rng,
778 buzzer,
779 alarm,
780 ipc: kernel::ipc::IPC::new(
781 board_kernel,
782 kernel::ipc::DRIVER_NUM,
783 &memory_allocation_capability,
784 ),
785 temperature,
786 humidity,
787 scheduler,
788 systick: cortexm4::systick::SysTick::new_with_calibration(64000000),
789 };
790
791 let chip = static_init!(
792 nrf52840::chip::NRF52<Nrf52840DefaultPeripherals>,
793 nrf52840::chip::NRF52::new(nrf52840_peripherals)
794 );
795 CHIP = Some(chip);
796
797 chip.mpu().clear_mpu();
799
800 cdc.enable();
802 cdc.attach();
803
804 debug!("Initialization complete. Entering main loop.");
805
806 extern "C" {
812 static _sapps: u8;
814 static _eapps: u8;
816 static mut _sappmem: u8;
818 static _eappmem: u8;
820 }
821
822 kernel::process::load_processes(
823 board_kernel,
824 chip,
825 core::slice::from_raw_parts(
826 core::ptr::addr_of!(_sapps),
827 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
828 ),
829 core::slice::from_raw_parts_mut(
830 core::ptr::addr_of_mut!(_sappmem),
831 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
832 ),
833 &FAULT_RESPONSE,
834 &process_management_capability,
835 )
836 .unwrap_or_else(|err| {
837 debug!("Error loading processes!");
838 debug!("{:?}", err);
839 });
840
841 (board_kernel, platform, chip)
842}
843
844#[no_mangle]
846pub unsafe fn main() {
847 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
848
849 let (board_kernel, board, chip) = start();
850 board_kernel.kernel_loop(&board, chip, Some(&board.ipc), &main_loop_capability);
851}