use kernel::hil;
use kernel::utilities::cells::OptionalCell;
use kernel::ErrorCode;
pub enum AnalogLightSensorType {
LightDependentResistor,
}
pub struct AnalogLightSensor<'a, A: hil::adc::Adc<'a>> {
adc: &'a A,
channel: &'a <A as hil::adc::Adc<'a>>::Channel,
sensor_type: AnalogLightSensorType,
client: OptionalCell<&'a dyn hil::sensors::AmbientLightClient>,
}
impl<'a, A: hil::adc::Adc<'a>> AnalogLightSensor<'a, A> {
pub fn new(
adc: &'a A,
channel: &'a <A as kernel::hil::adc::Adc<'a>>::Channel,
sensor_type: AnalogLightSensorType,
) -> AnalogLightSensor<'a, A> {
AnalogLightSensor {
adc,
channel,
sensor_type,
client: OptionalCell::empty(),
}
}
}
impl<'a, A: hil::adc::Adc<'a>> hil::adc::Client for AnalogLightSensor<'a, A> {
fn sample_ready(&self, sample: u16) {
let measurement: usize = match self.sensor_type {
AnalogLightSensorType::LightDependentResistor => {
(sample as usize * 5000) / 65535
}
};
self.client.map(|client| client.callback(measurement));
}
}
impl<'a, A: hil::adc::Adc<'a>> hil::sensors::AmbientLight<'a> for AnalogLightSensor<'a, A> {
fn set_client(&self, client: &'a dyn hil::sensors::AmbientLightClient) {
self.client.set(client);
}
fn read_light_intensity(&self) -> Result<(), ErrorCode> {
self.adc.sample(self.channel)
}
}
pub enum AnalogTemperatureSensorType {
MicrochipMcp9700,
}
pub struct AnalogTemperatureSensor<'a, A: hil::adc::Adc<'a>> {
adc: &'a A,
channel: &'a <A as hil::adc::Adc<'a>>::Channel,
sensor_type: AnalogTemperatureSensorType,
client: OptionalCell<&'a dyn hil::sensors::TemperatureClient>,
}
impl<'a, A: hil::adc::Adc<'a>> AnalogTemperatureSensor<'a, A> {
pub fn new(
adc: &'a A,
channel: &'a <A as kernel::hil::adc::Adc<'a>>::Channel,
sensor_type: AnalogLightSensorType,
) -> AnalogLightSensor<'a, A> {
AnalogLightSensor {
adc,
channel,
sensor_type,
client: OptionalCell::empty(),
}
}
}
impl<'a, A: hil::adc::Adc<'a>> hil::adc::Client for AnalogTemperatureSensor<'a, A> {
fn sample_ready(&self, sample: u16) {
let measurement = match self.sensor_type {
AnalogTemperatureSensorType::MicrochipMcp9700 => {
self.adc
.get_voltage_reference_mv()
.map_or(Err(ErrorCode::FAIL), |ref_mv| {
let reading_mv = (sample as usize * ref_mv) / 65535;
Ok((reading_mv as i32 - 500) * 10)
})
}
};
self.client.map(|client| client.callback(measurement));
}
}
impl<'a, A: hil::adc::Adc<'a>> hil::sensors::TemperatureDriver<'a>
for AnalogTemperatureSensor<'a, A>
{
fn set_client(&self, client: &'a dyn hil::sensors::TemperatureClient) {
self.client.set(client);
}
fn read_temperature(&self) -> Result<(), ErrorCode> {
self.adc.sample(self.channel)
}
}