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