blob: 567f67bfd011906219b1348dc28891459a5c15f6 [file] [log] [blame]
use crate::adc::AdcDriver;
use crate::buttons::ButtonDriver;
use crate::console::ConsoleDriver;
use crate::gpio::GpioDriver;
use crate::led::LedDriver;
use crate::result::OtherError;
use crate::result::TockError;
use crate::result::TockResult;
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::BleAdvertisingDriver;
use crate::simple_ble::BleScanningDriver;
use crate::temperature::TemperatureDriver;
use crate::timer::DriverContext;
use core::cell::Cell;
/// Struct containing all drivers constructible through [retrieve_drivers()]
#[non_exhaustive]
pub struct Drivers {
pub console_driver: ConsoleDriver,
pub led_driver: LedDriver,
pub timer_context: DriverContext,
pub gpio_driver: GpioDriver,
pub temperature_driver: TemperatureDriver,
pub button_driver: ButtonDriver,
pub adc_driver: AdcDriver,
pub rng_driver: RngDriver,
pub ble_advertising_driver: BleAdvertisingDriver,
pub ble_scanning_driver: BleScanningDriver,
pub ambient_light_sensor: AmbientLightSensor,
pub temperature_sensor: TemperatureSensor,
pub humidity_sensor: HumiditySensor,
pub ninedof_driver: NinedofDriver,
}
/// Retrieve [Drivers] struct. Returns struct only once.
pub fn retrieve_drivers() -> TockResult<Drivers> {
match unsafe { DRIVERS_SINGLETON.take() } {
Some(drivers) => Ok(drivers),
None => Err(TockError::Other(OtherError::DriverAlreadyTaken)),
}
}
/// 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_driver: AdcDriver,
ble_advertising_driver: BleAdvertisingDriver,
ble_scanning_driver: BleScanningDriver,
button_driver: ButtonDriver,
console_driver: ConsoleDriver,
led_driver: LedDriver,
timer_context: DriverContext {
active_timer: Cell::new(None),
},
gpio_driver: GpioDriver,
temperature_driver: TemperatureDriver,
rng_driver: RngDriver,
ambient_light_sensor: AmbientLightSensor,
temperature_sensor: TemperatureSensor,
humidity_sensor: HumiditySensor,
ninedof_driver: NinedofDriver,
};
static mut DRIVERS_SINGLETON: Option<Drivers> = Some(DRIVERS);
#[cfg(test)]
mod test {
use super::DRIVERS;
use super::DRIVERS_SINGLETON;
use crate::retrieve_drivers;
#[test]
pub fn can_be_retrieved_once() {
reset_drivers_singleton();
assert!(retrieve_drivers().is_ok());
assert!(retrieve_drivers().is_err());
}
fn reset_drivers_singleton() {
unsafe {
DRIVERS_SINGLETON = Some(DRIVERS);
};
}
}