capsules_extra/
analog_sensor.rs1use kernel::hil;
13use kernel::utilities::cells::OptionalCell;
14use kernel::ErrorCode;
15
16pub enum AnalogLightSensorType {
19    LightDependentResistor,
20}
21
22pub struct AnalogLightSensor<'a, A: hil::adc::Adc<'a>> {
23    adc: &'a A,
24    channel: &'a <A as hil::adc::Adc<'a>>::Channel,
25    sensor_type: AnalogLightSensorType,
26    client: OptionalCell<&'a dyn hil::sensors::AmbientLightClient>,
27}
28
29impl<'a, A: hil::adc::Adc<'a>> AnalogLightSensor<'a, A> {
30    pub fn new(
31        adc: &'a A,
32        channel: &'a <A as kernel::hil::adc::Adc<'a>>::Channel,
33        sensor_type: AnalogLightSensorType,
34    ) -> Self {
35        Self {
36            adc,
37            channel,
38            sensor_type,
39            client: OptionalCell::empty(),
40        }
41    }
42}
43
44impl<'a, A: hil::adc::Adc<'a>> hil::adc::Client for AnalogLightSensor<'a, A> {
46    fn sample_ready(&self, sample: u16) {
47        let measurement: usize = match self.sensor_type {
49            AnalogLightSensorType::LightDependentResistor => {
50                (sample as usize * 5000) / 65535
52            }
53        };
54        self.client.map(|client| client.callback(measurement));
55    }
56}
57
58impl<'a, A: hil::adc::Adc<'a>> hil::sensors::AmbientLight<'a> for AnalogLightSensor<'a, A> {
59    fn set_client(&self, client: &'a dyn hil::sensors::AmbientLightClient) {
60        self.client.set(client);
61    }
62
63    fn read_light_intensity(&self) -> Result<(), ErrorCode> {
64        self.adc.sample(self.channel)
65    }
66}
67
68pub enum AnalogTemperatureSensorType {
71    MicrochipMcp9700,
72}
73
74pub struct AnalogTemperatureSensor<'a, A: hil::adc::Adc<'a>> {
75    adc: &'a A,
76    channel: &'a <A as hil::adc::Adc<'a>>::Channel,
77    sensor_type: AnalogTemperatureSensorType,
78    client: OptionalCell<&'a dyn hil::sensors::TemperatureClient>,
79}
80
81impl<'a, A: hil::adc::Adc<'a>> AnalogTemperatureSensor<'a, A> {
82    pub fn new(
83        adc: &'a A,
84        channel: &'a <A as kernel::hil::adc::Adc<'a>>::Channel,
85        sensor_type: AnalogTemperatureSensorType,
86    ) -> Self {
87        Self {
88            adc,
89            channel,
90            sensor_type,
91            client: OptionalCell::empty(),
92        }
93    }
94}
95
96impl<'a, A: hil::adc::Adc<'a>> hil::adc::Client for AnalogTemperatureSensor<'a, A> {
98    fn sample_ready(&self, sample: u16) {
99        let measurement = match self.sensor_type {
101            AnalogTemperatureSensorType::MicrochipMcp9700 => {
103                self.adc
104                    .get_voltage_reference_mv()
105                    .map_or(Err(ErrorCode::FAIL), |ref_mv| {
106                        let reading_mv = (sample as usize * ref_mv) / 65535;
108                        Ok((reading_mv as i32 - 500) * 10)
110                    })
111            }
112        };
113        self.client.map(|client| client.callback(measurement));
114    }
115}
116
117impl<'a, A: hil::adc::Adc<'a>> hil::sensors::TemperatureDriver<'a>
118    for AnalogTemperatureSensor<'a, A>
119{
120    fn set_client(&self, client: &'a dyn hil::sensors::TemperatureClient) {
121        self.client.set(client);
122    }
123
124    fn read_temperature(&self) -> Result<(), ErrorCode> {
125        self.adc.sample(self.channel)
126    }
127}