blob: 860469168bdac0a2ef54a1834558b61bfe382682 [file] [log] [blame]
use crate::adc::AdcDriverFactory;
use crate::buttons::ButtonsDriverFactory;
use crate::console::ConsoleDriver;
use crate::ctap::CtapDriverFactory;
use crate::gpio::GpioDriverFactory;
use crate::hmac::HmacDriverFactory;
use crate::i2c_master::I2cDriverFactory;
use crate::i2c_master_slave::I2cMSDriverFactory;
use crate::leds::LedsDriverFactory;
use crate::result::OtherError;
use crate::result::TockError;
use crate::rng::RngDriver;
use crate::sensors::ninedof::NinedofDriver;
use crate::sensors::AmbientLightSensor;
use crate::sensors::HumiditySensor;
use crate::sensors::TemperatureSensor;
use crate::simple_ble::BleAdvertisingDriverFactory;
use crate::simple_ble::BleScanningDriverFactory;
use crate::temperature::TemperatureDriverFactory;
use crate::timer::DriverContext;
use core::cell::Cell;
/// Struct containing all drivers constructible through [retrieve_drivers()]
#[non_exhaustive]
pub struct Drivers {
pub console: ConsoleDriver,
pub ctap: CtapDriverFactory,
pub leds: LedsDriverFactory,
pub timer: DriverContext,
pub gpio: GpioDriverFactory,
pub hmac: HmacDriverFactory,
pub temperature: TemperatureDriverFactory,
pub buttons: ButtonsDriverFactory,
pub adc: AdcDriverFactory,
pub i2c_ms: I2cMSDriverFactory,
pub i2c: I2cDriverFactory,
pub rng: RngDriver,
pub ble_advertising: BleAdvertisingDriverFactory,
pub ble_scanning: BleScanningDriverFactory,
pub ambient_light_sensor: AmbientLightSensor,
pub temperature_sensor: TemperatureSensor,
pub humidity_sensor: HumiditySensor,
pub ninedof: NinedofDriver,
}
/// Retrieve [Drivers] struct. Returns struct only once.
pub fn retrieve_drivers() -> Result<Drivers, DriversAlreadyTakenError> {
static mut DRIVER_TAKEN: bool = false;
unsafe {
if DRIVER_TAKEN {
Err(DriversAlreadyTakenError)
} else {
DRIVER_TAKEN = true;
Ok(retrieve_drivers_unsafe())
}
}
}
/// Retrieve [Drivers] struct without check whether it has already been taken
/// at a different point.
/// # Safety
/// This shall only used in special situations where drivers cannot be passed as arguments
/// as in the panic handler. Otherwise global mutable state (as shared buffers) may be exposed
/// in an unsafe manner.
pub unsafe fn retrieve_drivers_unsafe() -> Drivers {
DRIVERS
}
#[allow(clippy::declare_interior_mutable_const)]
const DRIVERS: Drivers = Drivers {
adc: AdcDriverFactory,
ble_advertising: BleAdvertisingDriverFactory,
ble_scanning: BleScanningDriverFactory,
buttons: ButtonsDriverFactory,
console: ConsoleDriver,
ctap: CtapDriverFactory,
leds: LedsDriverFactory,
timer: DriverContext {
active_timer: Cell::new(None),
},
gpio: GpioDriverFactory,
hmac: HmacDriverFactory,
i2c_ms: I2cMSDriverFactory,
i2c: I2cDriverFactory,
temperature: TemperatureDriverFactory,
rng: RngDriver,
ambient_light_sensor: AmbientLightSensor,
temperature_sensor: TemperatureSensor,
humidity_sensor: HumiditySensor,
ninedof: NinedofDriver,
};
pub struct DriversAlreadyTakenError;
impl From<DriversAlreadyTakenError> for TockError {
fn from(_: DriversAlreadyTakenError) -> Self {
TockError::Other(OtherError::DriversAlreadyTaken)
}
}