capsules_extra/
temperature_rp2040.rs1use core::cell::Cell;
8use kernel::hil::adc;
9use kernel::hil::sensors;
10use kernel::utilities::cells::OptionalCell;
11use kernel::ErrorCode;
12
13use capsules_core::driver;
14pub const DRIVER_NUM: usize = driver::NUM::Temperature as usize;
15
16#[derive(Copy, Clone, PartialEq)]
17pub enum Status {
18 Read,
19 Idle,
20}
21
22pub struct TemperatureRp2040<'a, A: adc::AdcChannel<'a>> {
23 adc: &'a A,
24 slope: f32,
25 v_27: f32,
26 temperature_client: OptionalCell<&'a dyn sensors::TemperatureClient>,
27 status: Cell<Status>,
28}
29
30impl<'a, A: adc::AdcChannel<'a>> TemperatureRp2040<'a, A> {
31 pub fn new(adc: &'a A, slope: f32, v_27: f32) -> TemperatureRp2040<'a, A> {
34 TemperatureRp2040 {
35 adc,
36 slope,
37 v_27,
38 temperature_client: OptionalCell::empty(),
39 status: Cell::new(Status::Idle),
40 }
41 }
42}
43
44impl<'a, A: adc::AdcChannel<'a>> adc::Client for TemperatureRp2040<'a, A> {
45 fn sample_ready(&self, sample: u16) {
46 self.status.set(Status::Idle);
47 self.temperature_client.map(|client| {
48 client.callback(Ok(((27.0
49 - (((sample as f32 * 3.3 / 65535.0) - self.v_27) * 1000.0 / self.slope))
50 * 100.0) as i32));
51 });
52 }
53}
54
55impl<'a, A: adc::AdcChannel<'a>> sensors::TemperatureDriver<'a> for TemperatureRp2040<'a, A> {
56 fn set_client(&self, temperature_client: &'a dyn sensors::TemperatureClient) {
57 self.temperature_client.replace(temperature_client);
58 }
59
60 fn read_temperature(&self) -> Result<(), ErrorCode> {
61 if self.status.get() == Status::Idle {
62 self.status.set(Status::Read);
63 let _ = self.adc.sample();
64 Ok(())
65 } else {
66 Err(ErrorCode::BUSY)
67 }
68 }
69}