diff --git a/boards/apollo3/lora_things_plus/src/main.rs b/boards/apollo3/lora_things_plus/src/main.rs index 6ce3c059f32..6403bb06455 100644 --- a/boards/apollo3/lora_things_plus/src/main.rs +++ b/boards/apollo3/lora_things_plus/src/main.rs @@ -14,7 +14,7 @@ //! and //! for details on the pin break outs //! -//! ION0: Qwiic I2C +//! IOM0: Qwiic I2C //! IOM1: Not connected //! IOM2: Broken out SPI //! IOM3: Semtech SX1262 @@ -42,12 +42,16 @@ use apollo3::chip::Apollo3DefaultPeripherals; use capsules_core::virtualizers::virtual_alarm::MuxAlarm; use capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm; +use components::atecc508a::Atecc508aComponent; use components::bme280::Bme280Component; use components::ccs811::Ccs811Component; use kernel::capabilities; use kernel::component::Component; +use kernel::hil::entropy::Entropy32; +use kernel::hil::gpio::{Configure, Output}; use kernel::hil::i2c::I2CMaster; use kernel::hil::led::LedHigh; +use kernel::hil::rng::Rng; use kernel::hil::spi::SpiMaster; use kernel::hil::time::Counter; use kernel::platform::{KernelResources, SyscallDriverLookup}; @@ -91,6 +95,7 @@ static mut ALARM: Option<&'static MuxAlarm<'static, apollo3::stimer::STimer<'sta // Test access to sensors static mut BME280: Option<&'static capsules_extra::bme280::Bme280<'static>> = None; static mut CCS811: Option<&'static capsules_extra::ccs811::Ccs811<'static>> = None; +static mut ATECC508A: Option<&'static capsules_extra::atecc508a::Atecc508a<'static>> = None; /// Dummy buffer that causes the linker to reserve enough space for the stack. #[no_mangle] @@ -139,6 +144,7 @@ struct LoRaThingsPlus { temperature: &'static capsules_extra::temperature::TemperatureSensor<'static>, humidity: &'static capsules_extra::humidity::HumiditySensor<'static>, air_quality: &'static capsules_extra::air_quality::AirQualitySensor<'static>, + rng: &'static capsules_core::rng::RngDriver<'static>, scheduler: &'static RoundRobinSched<'static>, systick: cortexm4::systick::SysTick, } @@ -162,6 +168,7 @@ impl SyscallDriverLookup for LoRaThingsPlus { 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_core::rng::DRIVER_NUM => f(Some(self.rng)), _ => f(None), } } @@ -227,6 +234,13 @@ unsafe fn setup() -> ( let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&PROCESSES)); + // The ATECC508A requires the SDA line to be low for at least 60us + // to power on. So we set the GPIO low here and then the enable_i2c() + // will set it high for I2C operations. That is long enough to init + // the device + peripherals.gpio_port[6].make_output(); + peripherals.gpio_port[6].clear(); + // Power up components pwr_ctrl.enable_uart0(); pwr_ctrl.enable_iom0(); @@ -237,10 +251,6 @@ unsafe fn setup() -> ( let _ = &peripherals .gpio_port .enable_uart(&peripherals.gpio_port[48], &peripherals.gpio_port[49]); - // Enable SDA and SCL for I2C (exposed via Qwiic) - let _ = &peripherals - .gpio_port - .enable_i2c(&peripherals.gpio_port[6], &peripherals.gpio_port[5]); // Enable Main SPI let _ = &peripherals.gpio_port.enable_spi( &peripherals.gpio_port[27], @@ -315,6 +325,11 @@ unsafe fn setup() -> ( .finalize(components::process_printer_text_component_static!()); PROCESS_PRINTER = Some(process_printer); + // Enable SDA and SCL for I2C (exposed via Qwiic) + let _ = &peripherals + .gpio_port + .enable_i2c(&peripherals.gpio_port[6], &peripherals.gpio_port[5]); + // Init the I2C device attached via Qwiic let i2c_master_buffer = static_init!( [u8; capsules_core::i2c_master::BUFFER_LENGTH], @@ -367,6 +382,30 @@ unsafe fn setup() -> ( .finalize(components::air_quality_component_static!()); CCS811 = Some(ccs811); + let atecc508a = Atecc508aComponent::new(mux_i2c, 0x60).finalize( + components::atecc508a_component_static!(apollo3::iom::Iom<'static>), + ); + + atecc508a.read_config_zone().unwrap(); + + // Convert hardware RNG to the Random interface. + let entropy_to_random = static_init!( + capsules_core::rng::Entropy32ToRandom<'static>, + capsules_core::rng::Entropy32ToRandom::new(atecc508a) + ); + atecc508a.set_client(entropy_to_random); + // Setup RNG for userspace + let rng = static_init!( + capsules_core::rng::RngDriver<'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); + + ATECC508A = Some(atecc508a); + // Init the broken out SPI controller let external_mux_spi = components::spi::SpiMuxComponent::new(&peripherals.iom2).finalize( components::spi_mux_component_static!(apollo3::iom::Iom<'static>), @@ -471,6 +510,7 @@ unsafe fn setup() -> ( temperature, humidity, air_quality, + rng, scheduler, systick, } diff --git a/boards/apollo3/lora_things_plus/src/tests/csrng.rs b/boards/apollo3/lora_things_plus/src/tests/csrng.rs new file mode 100644 index 00000000000..2e1a490fda5 --- /dev/null +++ b/boards/apollo3/lora_things_plus/src/tests/csrng.rs @@ -0,0 +1,33 @@ +// Licensed under the Apache License, Version 2.0 or the MIT License. +// SPDX-License-Identifier: Apache-2.0 OR MIT +// Copyright Tock Contributors 2022. + +//! Test that the RNG works + +use crate::tests::run_kernel_op; +use crate::ATECC508A; +use capsules_core::test::rng::TestEntropy32; +use kernel::debug; +use kernel::hil::entropy::Entropy32; +use kernel::static_init; + +#[test_case] +fn run_csrng_entropy32() { + // We need to make sure the device is setup + run_kernel_op(10_000); + + debug!("check run CSRNG Entropy 32... "); + run_kernel_op(100); + + unsafe { + let rng = ATECC508A.unwrap(); + + let t = static_init!(TestEntropy32<'static>, TestEntropy32::new(rng)); + rng.set_client(t); + + t.run(); + } + run_kernel_op(10_000); + debug!(" [ok]"); + run_kernel_op(100); +} diff --git a/boards/apollo3/lora_things_plus/src/tests/mod.rs b/boards/apollo3/lora_things_plus/src/tests/mod.rs index 3e815074963..4a47a55c967 100644 --- a/boards/apollo3/lora_things_plus/src/tests/mod.rs +++ b/boards/apollo3/lora_things_plus/src/tests/mod.rs @@ -34,6 +34,7 @@ fn trivial_assertion() { run_kernel_op(10000); } +mod csrng; mod environmental_sensors; mod multi_alarm; mod spi_controller;