#![no_std]
#![cfg_attr(not(doc), no_main)]
#![deny(missing_docs)]
#![feature(custom_test_frameworks)]
#![test_runner(test_runner)]
#![reexport_test_harness_main = "test_main"]
use core::ptr::addr_of;
use core::ptr::addr_of_mut;
use apollo3::chip::Apollo3DefaultPeripherals;
use capsules_core::virtualizers::virtual_alarm::MuxAlarm;
use capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm;
use components::bme280::Bme280Component;
use components::ccs811::Ccs811Component;
use kernel::capabilities;
use kernel::component::Component;
use kernel::hil::flash::HasClient;
use kernel::hil::hasher::Hasher;
use kernel::hil::i2c::I2CMaster;
use kernel::hil::led::LedHigh;
use kernel::hil::spi::SpiMaster;
use kernel::hil::time::Counter;
use kernel::platform::{KernelResources, SyscallDriverLookup};
use kernel::scheduler::round_robin::RoundRobinSched;
use kernel::{create_capability, debug, static_init};
#[cfg(feature = "atecc508a")]
use {
capsules_core::virtualizers::virtual_i2c::MuxI2C,
components::atecc508a::Atecc508aComponent,
kernel::hil::entropy::Entropy32,
kernel::hil::gpio::{Configure, Output},
kernel::hil::rng::Rng,
};
#[cfg(feature = "chirp_i2c_moisture")]
use capsules_core::virtualizers::virtual_i2c::MuxI2C;
pub mod io;
#[cfg(test)]
mod tests;
const NUM_PROCS: usize = 4;
static mut PROCESSES: [Option<&'static dyn kernel::process::Process>; NUM_PROCS] = [None; 4];
static mut CHIP: Option<&'static apollo3::chip::Apollo3<Apollo3DefaultPeripherals>> = None;
static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::ProcessPrinterText> =
None;
const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
capsules_system::process_policies::PanicFaultPolicy {};
static mut PERIPHERALS: Option<&'static Apollo3DefaultPeripherals> = None;
#[cfg(test)]
static mut BOARD: Option<&'static kernel::Kernel> = None;
#[cfg(test)]
static mut PLATFORM: Option<&'static LoRaThingsPlus> = None;
#[cfg(test)]
static mut MAIN_CAP: Option<&dyn kernel::capabilities::MainLoopCapability> = None;
static mut ALARM: Option<&'static MuxAlarm<'static, apollo3::stimer::STimer<'static>>> = None;
static mut BME280: Option<
&'static capsules_extra::bme280::Bme280<
'static,
capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, apollo3::iom::Iom<'static>>,
>,
> = None;
static mut CCS811: Option<&'static capsules_extra::ccs811::Ccs811<'static>> = None;
#[cfg(feature = "atecc508a")]
static mut ATECC508A: Option<&'static capsules_extra::atecc508a::Atecc508a<'static>> = None;
#[no_mangle]
#[link_section = ".stack_buffer"]
pub static mut STACK_MEMORY: [u8; 0x1000] = [0; 0x1000];
const LORA_SPI_DRIVER_NUM: usize = capsules_core::driver::NUM::LoRaPhySPI as usize;
const LORA_GPIO_DRIVER_NUM: usize = capsules_core::driver::NUM::LoRaPhyGPIO as usize;
type ChirpI2cMoistureType = components::chirp_i2c_moisture::ChirpI2cMoistureComponentType<
capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, apollo3::iom::Iom<'static>>,
>;
type BME280Sensor = components::bme280::Bme280ComponentType<
capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, apollo3::iom::Iom<'static>>,
>;
type TemperatureDriver = components::temperature::TemperatureComponentType<BME280Sensor>;
type HumidityDriver = components::humidity::HumidityComponentType<BME280Sensor>;
struct LoRaThingsPlus {
alarm: &'static capsules_core::alarm::AlarmDriver<
'static,
VirtualMuxAlarm<'static, apollo3::stimer::STimer<'static>>,
>,
led: &'static capsules_core::led::LedDriver<
'static,
LedHigh<'static, apollo3::gpio::GpioPin<'static>>,
1,
>,
gpio: &'static capsules_core::gpio::GPIO<'static, apollo3::gpio::GpioPin<'static>>,
console: &'static capsules_core::console::Console<'static>,
i2c_master:
&'static capsules_core::i2c_master::I2CMasterDriver<'static, apollo3::iom::Iom<'static>>,
external_spi_controller: &'static capsules_core::spi_controller::Spi<
'static,
capsules_core::virtualizers::virtual_spi::VirtualSpiMasterDevice<
'static,
apollo3::iom::Iom<'static>,
>,
>,
sx1262_spi_controller: &'static capsules_core::spi_controller::Spi<
'static,
capsules_core::virtualizers::virtual_spi::VirtualSpiMasterDevice<
'static,
apollo3::iom::Iom<'static>,
>,
>,
sx1262_gpio: &'static capsules_core::gpio::GPIO<'static, apollo3::gpio::GpioPin<'static>>,
temperature: &'static TemperatureDriver,
humidity: &'static HumidityDriver,
air_quality: &'static capsules_extra::air_quality::AirQualitySensor<'static>,
moisture: Option<&'static components::moisture::MoistureComponentType<ChirpI2cMoistureType>>,
rng: Option<
&'static capsules_core::rng::RngDriver<
'static,
capsules_core::rng::Entropy32ToRandom<
'static,
capsules_extra::atecc508a::Atecc508a<'static>,
>,
>,
>,
scheduler: &'static RoundRobinSched<'static>,
systick: cortexm4::systick::SysTick,
kv_driver: &'static capsules_extra::kv_driver::KVStoreDriver<
'static,
capsules_extra::virtual_kv::VirtualKVPermissions<
'static,
capsules_extra::kv_store_permissions::KVStorePermissions<
'static,
capsules_extra::tickv_kv_store::TicKVKVStore<
'static,
capsules_extra::tickv::TicKVSystem<
'static,
capsules_core::virtualizers::virtual_flash::FlashUser<
'static,
apollo3::flashctrl::FlashCtrl<'static>,
>,
capsules_extra::sip_hash::SipHasher24<'static>,
{ apollo3::flashctrl::PAGE_SIZE },
>,
[u8; 8],
>,
>,
>,
>,
}
#[cfg(feature = "atecc508a")]
fn atecc508a_wakeup() {
let peripherals = (unsafe { PERIPHERALS }).unwrap();
peripherals.gpio_port[6].make_output();
peripherals.gpio_port[6].clear();
for _i in 0..700 {
cortexm4::support::nop();
}
let _ = &peripherals
.gpio_port
.enable_i2c(&peripherals.gpio_port[6], &peripherals.gpio_port[5]);
}
#[cfg(feature = "atecc508a")]
unsafe fn setup_atecc508a(
board_kernel: &'static kernel::Kernel,
memory_allocation_cap: &dyn capabilities::MemoryAllocationCapability,
mux_i2c: &'static MuxI2C<'static, apollo3::iom::Iom<'static>>,
) -> &'static capsules_core::rng::RngDriver<
'static,
capsules_core::rng::Entropy32ToRandom<'static, capsules_extra::atecc508a::Atecc508a<'static>>,
> {
let atecc508a = Atecc508aComponent::new(mux_i2c, 0x60, atecc508a_wakeup).finalize(
components::atecc508a_component_static!(apollo3::iom::Iom<'static>),
);
ATECC508A = Some(atecc508a);
let entropy_to_random = static_init!(
capsules_core::rng::Entropy32ToRandom<
'static,
capsules_extra::atecc508a::Atecc508a<'static>,
>,
capsules_core::rng::Entropy32ToRandom::new(atecc508a)
);
atecc508a.set_client(entropy_to_random);
let rng_local = static_init!(
capsules_core::rng::RngDriver<
'static,
capsules_core::rng::Entropy32ToRandom<
'static,
capsules_extra::atecc508a::Atecc508a<'static>,
>,
>,
capsules_core::rng::RngDriver::new(
entropy_to_random,
board_kernel.create_grant(capsules_core::rng::DRIVER_NUM, memory_allocation_cap)
)
);
entropy_to_random.set_client(rng_local);
rng_local
}
#[cfg(feature = "chirp_i2c_moisture")]
unsafe fn setup_chirp_i2c_moisture(
board_kernel: &'static kernel::Kernel,
_memory_allocation_cap: &dyn capabilities::MemoryAllocationCapability,
mux_i2c: &'static MuxI2C<'static, apollo3::iom::Iom<'static>>,
) -> &'static components::moisture::MoistureComponentType<ChirpI2cMoistureType> {
let chirp_moisture =
components::chirp_i2c_moisture::ChirpI2cMoistureComponent::new(mux_i2c, 0x20).finalize(
components::chirp_i2c_moisture_component_static!(apollo3::iom::Iom<'static>),
);
let moisture = components::moisture::MoistureComponent::new(
board_kernel,
capsules_extra::moisture::DRIVER_NUM,
chirp_moisture,
)
.finalize(components::moisture_component_static!(ChirpI2cMoistureType));
moisture
}
impl SyscallDriverLookup for LoRaThingsPlus {
fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
where
F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
{
match driver_num {
capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
capsules_core::led::DRIVER_NUM => f(Some(self.led)),
capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
capsules_core::console::DRIVER_NUM => f(Some(self.console)),
capsules_core::i2c_master::DRIVER_NUM => f(Some(self.i2c_master)),
capsules_core::spi_controller::DRIVER_NUM => f(Some(self.external_spi_controller)),
LORA_SPI_DRIVER_NUM => f(Some(self.sx1262_spi_controller)),
LORA_GPIO_DRIVER_NUM => f(Some(self.sx1262_gpio)),
capsules_extra::temperature::DRIVER_NUM => f(Some(self.temperature)),
capsules_extra::humidity::DRIVER_NUM => f(Some(self.humidity)),
capsules_extra::air_quality::DRIVER_NUM => f(Some(self.air_quality)),
capsules_extra::kv_driver::DRIVER_NUM => f(Some(self.kv_driver)),
capsules_core::rng::DRIVER_NUM => {
if let Some(rng) = self.rng {
f(Some(rng))
} else {
f(None)
}
}
capsules_extra::moisture::DRIVER_NUM => {
if let Some(moisture) = self.moisture {
f(Some(moisture))
} else {
f(None)
}
}
_ => f(None),
}
}
}
impl KernelResources<apollo3::chip::Apollo3<Apollo3DefaultPeripherals>> for LoRaThingsPlus {
type SyscallDriverLookup = Self;
type SyscallFilter = ();
type ProcessFault = ();
type Scheduler = RoundRobinSched<'static>;
type SchedulerTimer = cortexm4::systick::SysTick;
type WatchDog = ();
type ContextSwitchCallback = ();
fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
self
}
fn syscall_filter(&self) -> &Self::SyscallFilter {
&()
}
fn process_fault(&self) -> &Self::ProcessFault {
&()
}
fn scheduler(&self) -> &Self::Scheduler {
self.scheduler
}
fn scheduler_timer(&self) -> &Self::SchedulerTimer {
&self.systick
}
fn watchdog(&self) -> &Self::WatchDog {
&()
}
fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
&()
}
}
#[inline(never)]
unsafe fn setup() -> (
&'static kernel::Kernel,
&'static LoRaThingsPlus,
&'static apollo3::chip::Apollo3<Apollo3DefaultPeripherals>,
) {
let peripherals = static_init!(Apollo3DefaultPeripherals, Apollo3DefaultPeripherals::new());
PERIPHERALS = Some(peripherals);
let mcu_ctrl = apollo3::mcuctrl::McuCtrl::new();
let pwr_ctrl = apollo3::pwrctrl::PwrCtrl::new();
let clkgen = apollo3::clkgen::ClkGen::new();
clkgen.set_clock_frequency(apollo3::clkgen::ClockFrequency::Freq48MHz);
let memory_allocation_cap = create_capability!(capabilities::MemoryAllocationCapability);
let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&*addr_of!(PROCESSES)));
pwr_ctrl.enable_uart0();
pwr_ctrl.enable_iom0();
pwr_ctrl.enable_iom2();
pwr_ctrl.enable_iom3();
peripherals.init();
peripherals
.gpio_port
.enable_uart(&peripherals.gpio_port[48], &peripherals.gpio_port[49]);
peripherals.gpio_port.enable_spi(
&peripherals.gpio_port[27],
&peripherals.gpio_port[28],
&peripherals.gpio_port[25],
);
peripherals.gpio_port.enable_spi(
&peripherals.gpio_port[42],
&peripherals.gpio_port[38],
&peripherals.gpio_port[43],
);
peripherals.gpio_port.enable_sx1262_radio_pins();
kernel::debug::assign_gpios(Some(&peripherals.gpio_port[26]), None, None);
let uart_mux = components::console::UartMuxComponent::new(&peripherals.uart0, 115200)
.finalize(components::uart_mux_component_static!());
let console = components::console::ConsoleComponent::new(
board_kernel,
capsules_core::console::DRIVER_NUM,
uart_mux,
)
.finalize(components::console_component_static!());
components::debug_writer::DebugWriterComponent::new(uart_mux)
.finalize(components::debug_writer_component_static!());
let led = components::led::LedsComponent::new().finalize(components::led_component_static!(
LedHigh<'static, apollo3::gpio::GpioPin>,
LedHigh::new(&peripherals.gpio_port[19]),
));
let gpio = components::gpio::GpioComponent::new(
board_kernel,
capsules_core::gpio::DRIVER_NUM,
components::gpio_component_helper!(
apollo3::gpio::GpioPin,
0 => &peripherals.gpio_port[13], 1 => &peripherals.gpio_port[12], 2 => &peripherals.gpio_port[32], 3 => &peripherals.gpio_port[35], 4 => &peripherals.gpio_port[34], ),
)
.finalize(components::gpio_component_static!(apollo3::gpio::GpioPin));
let _ = peripherals.stimer.start();
let mux_alarm = components::alarm::AlarmMuxComponent::new(&peripherals.stimer).finalize(
components::alarm_mux_component_static!(apollo3::stimer::STimer),
);
let alarm = components::alarm::AlarmDriverComponent::new(
board_kernel,
capsules_core::alarm::DRIVER_NUM,
mux_alarm,
)
.finalize(components::alarm_component_static!(apollo3::stimer::STimer));
ALARM = Some(mux_alarm);
let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
.finalize(components::process_printer_text_component_static!());
PROCESS_PRINTER = Some(process_printer);
peripherals
.gpio_port
.enable_i2c(&peripherals.gpio_port[6], &peripherals.gpio_port[5]);
let i2c_master_buffer = static_init!(
[u8; capsules_core::i2c_master::BUFFER_LENGTH],
[0; capsules_core::i2c_master::BUFFER_LENGTH]
);
let i2c_master = static_init!(
capsules_core::i2c_master::I2CMasterDriver<'static, apollo3::iom::Iom<'static>>,
capsules_core::i2c_master::I2CMasterDriver::new(
&peripherals.iom0,
i2c_master_buffer,
board_kernel.create_grant(
capsules_core::i2c_master::DRIVER_NUM,
&memory_allocation_cap
)
)
);
peripherals.iom0.set_master_client(i2c_master);
peripherals.iom0.enable();
let mux_i2c = components::i2c::I2CMuxComponent::new(&peripherals.iom0, None).finalize(
components::i2c_mux_component_static!(apollo3::iom::Iom<'static>),
);
let bme280 = Bme280Component::new(mux_i2c, 0x77).finalize(
components::bme280_component_static!(apollo3::iom::Iom<'static>),
);
let temperature = components::temperature::TemperatureComponent::new(
board_kernel,
capsules_extra::temperature::DRIVER_NUM,
bme280,
)
.finalize(components::temperature_component_static!(BME280Sensor));
let humidity = components::humidity::HumidityComponent::new(
board_kernel,
capsules_extra::humidity::DRIVER_NUM,
bme280,
)
.finalize(components::humidity_component_static!(BME280Sensor));
BME280 = Some(bme280);
let ccs811 = Ccs811Component::new(mux_i2c, 0x5B).finalize(
components::ccs811_component_static!(apollo3::iom::Iom<'static>),
);
let air_quality = components::air_quality::AirQualityComponent::new(
board_kernel,
capsules_extra::temperature::DRIVER_NUM,
ccs811,
)
.finalize(components::air_quality_component_static!());
CCS811 = Some(ccs811);
#[cfg(feature = "chirp_i2c_moisture")]
let moisture = Some(setup_chirp_i2c_moisture(
board_kernel,
&memory_allocation_cap,
mux_i2c,
));
#[cfg(not(feature = "chirp_i2c_moisture"))]
let moisture = None;
#[cfg(feature = "atecc508a")]
let rng = Some(setup_atecc508a(
board_kernel,
&memory_allocation_cap,
mux_i2c,
));
#[cfg(not(feature = "atecc508a"))]
let rng = None;
let external_mux_spi = components::spi::SpiMuxComponent::new(&peripherals.iom2).finalize(
components::spi_mux_component_static!(apollo3::iom::Iom<'static>),
);
let external_spi_controller = components::spi::SpiSyscallComponent::new(
board_kernel,
external_mux_spi,
kernel::hil::spi::cs::IntoChipSelect::<_, kernel::hil::spi::cs::ActiveLow>::into_cs(
&peripherals.gpio_port[11], ),
capsules_core::spi_controller::DRIVER_NUM,
)
.finalize(components::spi_syscall_component_static!(
apollo3::iom::Iom<'static>
));
let sx1262_mux_spi = components::spi::SpiMuxComponent::new(&peripherals.iom3).finalize(
components::spi_mux_component_static!(apollo3::iom::Iom<'static>),
);
let sx1262_spi_controller = components::spi::SpiSyscallComponent::new(
board_kernel,
sx1262_mux_spi,
kernel::hil::spi::cs::IntoChipSelect::<_, kernel::hil::spi::cs::ActiveLow>::into_cs(
&peripherals.gpio_port[36], ),
LORA_SPI_DRIVER_NUM,
)
.finalize(components::spi_syscall_component_static!(
apollo3::iom::Iom<'static>
));
peripherals
.iom3
.specify_chip_select(kernel::hil::spi::cs::IntoChipSelect::<
_,
kernel::hil::spi::cs::ActiveLow,
>::into_cs(
&peripherals.gpio_port[36], ))
.unwrap();
let sx1262_gpio = components::gpio::GpioComponent::new(
board_kernel,
LORA_GPIO_DRIVER_NUM,
components::gpio_component_helper!(
apollo3::gpio::GpioPin,
0 => &peripherals.gpio_port[36], 1 => &peripherals.gpio_port[39], 2 => &peripherals.gpio_port[40], 3 => &peripherals.gpio_port[47], 4 => &peripherals.gpio_port[44], ),
)
.finalize(components::gpio_component_static!(apollo3::gpio::GpioPin));
mcu_ctrl.disable_ble();
let flash_ctrl_read_buf = static_init!(
[u8; apollo3::flashctrl::PAGE_SIZE],
[0; apollo3::flashctrl::PAGE_SIZE]
);
let page_buffer = static_init!(
apollo3::flashctrl::Apollo3Page,
apollo3::flashctrl::Apollo3Page::default()
);
let mux_flash = components::flash::FlashMuxComponent::new(&peripherals.flash_ctrl).finalize(
components::flash_mux_component_static!(apollo3::flashctrl::FlashCtrl),
);
let sip_hash = static_init!(
capsules_extra::sip_hash::SipHasher24,
capsules_extra::sip_hash::SipHasher24::new()
);
kernel::deferred_call::DeferredCallClient::register(sip_hash);
let tickv = components::tickv::TicKVComponent::new(
sip_hash,
mux_flash, core::ptr::addr_of!(_skv_data) as usize / apollo3::flashctrl::PAGE_SIZE, core::ptr::addr_of!(_lkv_data) as usize - apollo3::flashctrl::PAGE_SIZE,
flash_ctrl_read_buf, page_buffer, )
.finalize(components::tickv_component_static!(
apollo3::flashctrl::FlashCtrl,
capsules_extra::sip_hash::SipHasher24,
{ apollo3::flashctrl::PAGE_SIZE }
));
HasClient::set_client(&peripherals.flash_ctrl, mux_flash);
sip_hash.set_client(tickv);
let kv_store = components::kv::TicKVKVStoreComponent::new(tickv).finalize(
components::tickv_kv_store_component_static!(
capsules_extra::tickv::TicKVSystem<
capsules_core::virtualizers::virtual_flash::FlashUser<
apollo3::flashctrl::FlashCtrl,
>,
capsules_extra::sip_hash::SipHasher24<'static>,
{ apollo3::flashctrl::PAGE_SIZE },
>,
capsules_extra::tickv::TicKVKeyType,
),
);
let kv_store_permissions = components::kv::KVStorePermissionsComponent::new(kv_store).finalize(
components::kv_store_permissions_component_static!(
capsules_extra::tickv_kv_store::TicKVKVStore<
capsules_extra::tickv::TicKVSystem<
capsules_core::virtualizers::virtual_flash::FlashUser<
apollo3::flashctrl::FlashCtrl,
>,
capsules_extra::sip_hash::SipHasher24<'static>,
{ apollo3::flashctrl::PAGE_SIZE },
>,
capsules_extra::tickv::TicKVKeyType,
>
),
);
let mux_kv = components::kv::KVPermissionsMuxComponent::new(kv_store_permissions).finalize(
components::kv_permissions_mux_component_static!(
capsules_extra::kv_store_permissions::KVStorePermissions<
capsules_extra::tickv_kv_store::TicKVKVStore<
capsules_extra::tickv::TicKVSystem<
capsules_core::virtualizers::virtual_flash::FlashUser<
apollo3::flashctrl::FlashCtrl,
>,
capsules_extra::sip_hash::SipHasher24<'static>,
{ apollo3::flashctrl::PAGE_SIZE },
>,
capsules_extra::tickv::TicKVKeyType,
>,
>
),
);
let virtual_kv_driver = components::kv::VirtualKVPermissionsComponent::new(mux_kv).finalize(
components::virtual_kv_permissions_component_static!(
capsules_extra::kv_store_permissions::KVStorePermissions<
capsules_extra::tickv_kv_store::TicKVKVStore<
capsules_extra::tickv::TicKVSystem<
capsules_core::virtualizers::virtual_flash::FlashUser<
apollo3::flashctrl::FlashCtrl,
>,
capsules_extra::sip_hash::SipHasher24<'static>,
{ apollo3::flashctrl::PAGE_SIZE },
>,
capsules_extra::tickv::TicKVKeyType,
>,
>
),
);
let kv_driver = components::kv::KVDriverComponent::new(
virtual_kv_driver,
board_kernel,
capsules_extra::kv_driver::DRIVER_NUM,
)
.finalize(components::kv_driver_component_static!(
capsules_extra::virtual_kv::VirtualKVPermissions<
capsules_extra::kv_store_permissions::KVStorePermissions<
capsules_extra::tickv_kv_store::TicKVKVStore<
capsules_extra::tickv::TicKVSystem<
capsules_core::virtualizers::virtual_flash::FlashUser<
apollo3::flashctrl::FlashCtrl,
>,
capsules_extra::sip_hash::SipHasher24<'static>,
{ apollo3::flashctrl::PAGE_SIZE },
>,
capsules_extra::tickv::TicKVKeyType,
>,
>,
>
));
mcu_ctrl.print_chip_revision();
debug!("Initialization complete. Entering main loop");
extern "C" {
static _sapps: u8;
static _eapps: u8;
static mut _sappmem: u8;
static _eappmem: u8;
static _skv_data: u8;
static _lkv_data: u8;
}
let scheduler = components::sched::round_robin::RoundRobinComponent::new(&*addr_of!(PROCESSES))
.finalize(components::round_robin_component_static!(NUM_PROCS));
let systick = cortexm4::systick::SysTick::new_with_calibration(48_000_000);
let artemis_nano = static_init!(
LoRaThingsPlus,
LoRaThingsPlus {
alarm,
led,
gpio,
console,
i2c_master,
external_spi_controller,
sx1262_spi_controller,
sx1262_gpio,
temperature,
humidity,
air_quality,
moisture,
rng,
scheduler,
systick,
kv_driver,
}
);
let chip = static_init!(
apollo3::chip::Apollo3<Apollo3DefaultPeripherals>,
apollo3::chip::Apollo3::new(peripherals)
);
CHIP = Some(chip);
let checking_policy;
#[cfg(feature = "atecc508a")]
{
let sha = components::sha::ShaSoftware256Component::new()
.finalize(components::sha_software_256_component_static!());
let public_key = static_init!(
[u8; 64],
[
0x14, 0x14, 0xc4, 0xc5, 0xa0, 0xd2, 0xfd, 0xa0, 0x5a, 0x46, 0x9a, 0x0e, 0x82, 0xa7,
0x7e, 0x75, 0x85, 0x03, 0x2a, 0xf6, 0x1a, 0x25, 0x2a, 0x91, 0x1d, 0x41, 0xf8, 0xcf,
0xd6, 0x76, 0x05, 0xd6, 0x3c, 0x6a, 0xcf, 0x9d, 0x98, 0x8c, 0xfa, 0x45, 0x1e, 0xfb,
0x9d, 0x90, 0xaf, 0xdf, 0x16, 0xc8, 0xa4, 0xe5, 0x17, 0x74, 0x01, 0xeb, 0xcd, 0x91,
0x0a, 0xa3, 0x05, 0xd5, 0x84, 0xaa, 0x6a, 0x56
]
);
ATECC508A.unwrap().set_public_key(Some(public_key));
checking_policy = components::appid::checker_signature::AppCheckerSignatureComponent::new(
sha,
ATECC508A.unwrap(),
tock_tbf::types::TbfFooterV2CredentialsType::EcdsaNistP256,
)
.finalize(components::app_checker_signature_component_static!(
capsules_extra::atecc508a::Atecc508a<'static>,
capsules_extra::sha256::Sha256Software<'static>,
32,
64,
));
};
#[cfg(not(feature = "atecc508a"))]
{
checking_policy = components::appid::checker_null::AppCheckerNullComponent::new()
.finalize(components::app_checker_null_component_static!());
}
let assigner = components::appid::assigner_name::AppIdAssignerNamesComponent::new()
.finalize(components::appid_assigner_names_component_static!());
let checker = components::appid::checker::ProcessCheckerMachineComponent::new(checking_policy)
.finalize(components::process_checker_machine_component_static!());
let storage_permissions_policy =
components::storage_permissions::tbf_header::StoragePermissionsTbfHeaderComponent::new()
.finalize(
components::storage_permissions_tbf_header_component_static!(
apollo3::chip::Apollo3<Apollo3DefaultPeripherals>,
kernel::process::ProcessStandardDebugFull,
),
);
let _loader = components::loader::sequential::ProcessLoaderSequentialComponent::new(
checker,
&mut *addr_of_mut!(PROCESSES),
board_kernel,
chip,
&FAULT_RESPONSE,
assigner,
storage_permissions_policy,
)
.finalize(components::process_loader_sequential_component_static!(
apollo3::chip::Apollo3<Apollo3DefaultPeripherals>,
kernel::process::ProcessStandardDebugFull,
NUM_PROCS,
));
(board_kernel, artemis_nano, chip)
}
#[no_mangle]
pub unsafe fn main() {
apollo3::init();
#[cfg(test)]
test_main();
#[cfg(not(test))]
{
let (board_kernel, sf_lora_thing_plus_board, chip) = setup();
let main_loop_cap = create_capability!(capabilities::MainLoopCapability);
board_kernel.kernel_loop(
sf_lora_thing_plus_board,
chip,
None::<&kernel::ipc::IPC<{ NUM_PROCS as u8 }>>,
&main_loop_cap,
);
}
}
#[cfg(test)]
use kernel::platform::watchdog::WatchDog;
#[cfg(test)]
fn test_runner(tests: &[&dyn Fn()]) {
unsafe {
let (board_kernel, sf_lora_thing_plus_board, _chip) = setup();
BOARD = Some(board_kernel);
PLATFORM = Some(&sf_lora_thing_plus_board);
MAIN_CAP = Some(&create_capability!(capabilities::MainLoopCapability));
PLATFORM.map(|p| {
p.watchdog().setup();
});
for test in tests {
test();
}
}
loop {}
}