Skip to main content

kernel/hil/
sensors.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Interfaces for environment sensors
6
7use crate::errorcode::ErrorCode;
8
9/// A basic interface for a temperature sensor
10pub trait TemperatureDriver<'a> {
11    fn set_client(&self, client: &'a dyn TemperatureClient);
12    fn read_temperature(&self) -> Result<(), ErrorCode>;
13}
14
15/// Client for receiving temperature readings.
16pub trait TemperatureClient {
17    /// Called when a temperature reading has completed.
18    ///
19    /// - `value`: the most recently read temperature in hundredths of degrees
20    ///   centigrade (centiCelsius), or Err on failure.
21    fn callback(&self, value: Result<i32, ErrorCode>);
22}
23
24/// A basic interface for a humidity sensor
25pub trait HumidityDriver<'a> {
26    fn set_client(&self, client: &'a dyn HumidityClient);
27    fn read_humidity(&self) -> Result<(), ErrorCode>;
28}
29
30/// Client for receiving humidity readings.
31pub trait HumidityClient {
32    /// Called when a humidity reading has completed.
33    ///
34    /// - `value`: the most recently read humidity in hundredths of percent.
35    fn callback(&self, value: usize);
36}
37
38/// A basic interface for a moisture sensor
39pub trait MoistureDriver<'a> {
40    fn set_client(&self, client: &'a dyn MoistureClient);
41
42    /// Read the moisture value from a sensor. The value is returned
43    /// via the `MoistureClient` callback.
44    ///
45    /// This function might return the following errors:
46    /// - `BUSY`: Indicates that the hardware is busy with an existing operation
47    ///   or initialisation/calibration.
48    /// - `NOSUPPORT`: Indicates that this data type isn't supported.
49    fn read_moisture(&self) -> Result<(), ErrorCode>;
50}
51
52/// Client for receiving moisture readings.
53pub trait MoistureClient {
54    /// Called when a moisture reading has completed.
55    ///
56    /// - `value`: the most recently read moisture in hundredths of percent, or
57    ///   Err on failure.
58    ///
59    /// This function might return the following errors:
60    /// - `BUSY`: Indicates that the hardware is busy with an existing operation
61    ///   or initialisation/calibration.
62    /// - `NOSUPPORT`: Indicates that this data type isn't supported.
63    fn callback(&self, value: Result<usize, ErrorCode>);
64}
65
66/// A basic interface for a Air Quality sensor
67pub trait AirQualityDriver<'a> {
68    /// Set the client to be notified when the capsule has data ready.
69    fn set_client(&self, client: &'a dyn AirQualityClient);
70
71    /// Specify the temperature and humidity used in calculating the air
72    /// quality.
73    ///
74    /// The temperature is specified in degrees Celsius and the humidity
75    /// is specified as a percentage.
76    ///
77    /// This is an optional call and doesn't have to be used, but on most
78    /// hardware can be used to improve the measurement accuracy.
79    ///
80    /// This function might return the following errors:
81    /// - `BUSY`: Indicates that the hardware is busy with an existing operation
82    ///   or initialisation/calibration.
83    /// - `NOSUPPORT`: Indicates that this data type isn't supported.
84    fn specify_environment(
85        &self,
86        temp: Option<i32>,
87        humidity: Option<u32>,
88    ) -> Result<(), ErrorCode>;
89
90    /// Read the CO2 or equivalent CO2 (eCO2) from the sensor.
91    /// This will trigger the `AirQualityClient` `co2_data_available()`
92    /// callback when the data is ready.
93    ///
94    /// This function might return the following errors:
95    /// - `BUSY`: Indicates that the hardware is busy with an existing operation
96    ///   or initialisation/calibration.
97    /// - `NOSUPPORT`: Indicates that this data type isn't supported.
98    fn read_co2(&self) -> Result<(), ErrorCode>;
99
100    /// Read the Total Organic Compound (TVOC) from the sensor.
101    /// This will trigger the `AirQualityClient` `tvoc_data_available()`
102    /// callback when the data is ready.
103    ///
104    /// This function might return the following errors:
105    /// - `BUSY`: Indicates that the hardware is busy with an existing operation
106    ///   or initialisation/calibration.
107    /// - `NOSUPPORT`: Indicates that this data type isn't supported.
108    fn read_tvoc(&self) -> Result<(), ErrorCode>;
109}
110
111/// Client for receiving Air Quality readings
112pub trait AirQualityClient {
113    /// Called when the environment specify command has completed.
114    fn environment_specified(&self, result: Result<(), ErrorCode>);
115
116    /// Called when a CO2 or equivalent CO2 (eCO2) reading has completed.
117    ///
118    /// - `value`: will contain the latest CO2 reading in ppm. An example value
119    ///   might be `400`.
120    fn co2_data_available(&self, value: Result<u32, ErrorCode>);
121
122    /// Called when a Total Organic Compound (TVOC) reading has completed.
123    ///
124    /// - `value`: will contain the latest TVOC reading in ppb. An example value
125    ///   might be `0`.
126    fn tvoc_data_available(&self, value: Result<u32, ErrorCode>);
127}
128
129/// A basic interface for a proximity sensor
130pub trait ProximityDriver<'a> {
131    fn set_client(&self, client: &'a dyn ProximityClient);
132
133    /// Callback issued after sensor reads proximity value
134    fn read_proximity(&self) -> Result<(), ErrorCode>;
135
136    /// Callback issued after sensor reads proximity value greater
137    /// than 'high_threshold' or less than 'low_threshold'
138    ///
139    /// To elaborate, the callback is not issued by the driver until
140    /// (prox_reading >= high_threshold || prox_reading <= low_threshold).
141    /// When (prox_reading >= high_threshold || prox_reading <= low_threshold)
142    /// is read by the sensor, an I2C interrupt is generated and sent to the
143    /// kernel which prompts the driver to collect the proximity reading from
144    /// the sensor and perform the callback. Any apps issuing this command will
145    /// have to wait for the proximity reading to fall within the
146    /// aforementioned ranges in order to received a callback. Threshold: A
147    /// value of range [0 , 255] which represents at what proximity reading
148    /// ranges an interrupt will occur.
149    fn read_proximity_on_interrupt(
150        &self,
151        low_threshold: u8,
152        high_threshold: u8,
153    ) -> Result<(), ErrorCode>;
154}
155
156pub trait ProximityClient {
157    /// Called when a proximity reading has completed.
158    ///
159    /// - `value`: the most recently read proximity value which ranges
160    ///   [0 , 255]... where 255 -> object is closest readable distance, 0 ->
161    ///   object is farthest readable distance.
162    fn callback(&self, value: u8);
163}
164
165/// A basic interface for an ambient light sensor.
166pub trait AmbientLight<'a> {
167    /// Set the client to be notified when the capsule has data ready or has
168    /// finished some command.  This is likely called in a board's `main.rs`.
169    fn set_client(&self, client: &'a dyn AmbientLightClient);
170
171    /// Get a single instantaneous reading of the ambient light intensity.
172    fn read_light_intensity(&self) -> Result<(), ErrorCode> {
173        Err(ErrorCode::NODEVICE)
174    }
175}
176
177/// Client for receiving light intensity readings.
178pub trait AmbientLightClient {
179    /// Called when an ambient light reading has completed.
180    ///
181    /// - `lux`: the most recently read ambient light reading in lux (lx).
182    fn callback(&self, lux: usize);
183}
184
185/// A basic interface for a 9-DOF compatible chip.
186///
187/// This trait provides a standard interface for chips that implement
188/// some or all of a nine degrees of freedom (accelerometer, magnetometer,
189/// gyroscope) sensor. Any interface functions that a chip cannot implement
190/// can be ignored by the chip capsule and an error will automatically be
191/// returned.
192pub trait NineDof<'a> {
193    /// Set the client to be notified when the capsule has data ready or
194    /// has finished some command. This is likely called in a board's main.rs
195    /// and is set to the virtual_ninedof.rs driver.
196    fn set_client(&self, client: &'a dyn NineDofClient);
197
198    /// Get a single instantaneous reading of the acceleration in the
199    /// X,Y,Z directions.
200    fn read_accelerometer(&self) -> Result<(), ErrorCode> {
201        Err(ErrorCode::NODEVICE)
202    }
203
204    /// Get a single instantaneous reading from the magnetometer in all
205    /// three directions.
206    fn read_magnetometer(&self) -> Result<(), ErrorCode> {
207        Err(ErrorCode::NODEVICE)
208    }
209
210    /// Get a single instantaneous reading from the gyroscope of the rotation
211    /// around all three axes.
212    fn read_gyroscope(&self) -> Result<(), ErrorCode> {
213        Err(ErrorCode::NODEVICE)
214    }
215}
216
217/// Client for receiving done events from the chip.
218pub trait NineDofClient {
219    /// Signals a command has finished. The arguments will most likely be passed
220    /// over the syscall interface to an application.
221    fn callback(&self, arg1: usize, arg2: usize, arg3: usize);
222}
223
224/// Basic Interface for Sound Pressure
225pub trait SoundPressure<'a> {
226    /// Read the sound pressure level
227    fn read_sound_pressure(&self) -> Result<(), ErrorCode>;
228
229    /// Enable
230    ///
231    /// As this is usually a microphone, some boards require an explicit enable
232    /// so that they can turn on an LED. This function enables that microphone and LED.
233    /// Not calling this function may result in inaccurate readings.
234    fn enable(&self) -> Result<(), ErrorCode>;
235
236    /// Disable
237    ///
238    /// As this is usually a microphone, some boards require an explicit enable
239    /// so that they can turn on an LED. This function turns off that microphone. Readings
240    /// performed after this function call might return inaccurate.
241    fn disable(&self) -> Result<(), ErrorCode>;
242
243    /// Set the client
244    fn set_client(&self, client: &'a dyn SoundPressureClient);
245}
246
247pub trait SoundPressureClient {
248    /// Signals the sound pressure in dB
249    fn callback(&self, ret: Result<(), ErrorCode>, sound_pressure: u8);
250}
251
252/// A Basic interface for a barometer sensor.
253pub trait PressureDriver<'a> {
254    /// Used to initialize a atmospheric pressure reading
255    ///
256    /// This function might return the following errors:
257    /// - `BUSY`: Indicates that the hardware is busy with an existing operation
258    ///   or initialisation/calibration.
259    /// - `FAIL`: Failed to correctly communicate over communication protocol.
260    /// - `NOSUPPORT`: Indicates that this data type isn't supported.
261    fn read_atmospheric_pressure(&self) -> Result<(), ErrorCode>;
262
263    /// Set the client
264    fn set_client(&self, client: &'a dyn PressureClient);
265}
266
267pub trait PressureClient {
268    /// Called when a atmospheric pressure reading has completed.
269    ///
270    /// Returns the value in hPa.
271    fn callback(&self, pressure: Result<u32, ErrorCode>);
272}
273
274/// A basic interface for distance sensor.
275pub trait Distance<'a> {
276    /// Set the client
277    fn set_client(&self, client: &'a dyn DistanceClient);
278
279    /// Initiates a distance reading from the sensor.
280    ///
281    /// This function might return the following errors:
282    /// - `BUSY`: Indicates that the hardware is currently busy.
283    /// - `FAIL`: Indicates that there was a failure in communication.
284    fn read_distance(&self) -> Result<(), ErrorCode>;
285
286    /// Get the maximum distance the sensor can measure in mm
287    fn get_maximum_distance(&self) -> u32;
288
289    /// Get the minimum distance the sensor can measure in mm
290    fn get_minimum_distance(&self) -> u32;
291}
292
293/// Client for receiving distance readings.
294pub trait DistanceClient {
295    /// Called when a distance measurement has completed.
296    ///
297    /// - `distance`: the most recently measured distance in millimeters. If
298    ///   there was an error, this will be `Err(ErrorCode)`.
299    fn callback(&self, distance: Result<u32, ErrorCode>);
300}
301
302/// A basic interface for a rain fall sensor
303pub trait RainFallDriver<'a> {
304    fn set_client(&self, client: &'a dyn RainFallClient);
305
306    /// Read the rain fall value from a sensor. The value is returned
307    /// via the `RainFallClient` callback.
308    ///
309    /// - `hours`: the number of hours of rainfall to report. 1 to 24 hours are
310    ///   valid values (if supported by the hardware).
311    ///
312    /// This function might return the following errors:
313    /// - `BUSY`: Indicates that the hardware is busy with an existing operation
314    ///   or initialisation/calibration.
315    /// - `NOSUPPORT`: Indicates that the value of `hours` is not supported.
316    fn read_rainfall(&self, hours: usize) -> Result<(), ErrorCode>;
317}
318
319/// Client for receiving moisture readings.
320pub trait RainFallClient {
321    /// Called when a moisture reading has completed.
322    ///
323    /// - `value`: the number of um of rain in the time period specified, or Err
324    ///   on failure.
325    ///
326    /// This function might return the following errors:
327    /// - `BUSY`: Indicates that the hardware is busy with an existing operation
328    ///   or initialisation/calibration.
329    /// - `NOSUPPORT`: Indicates that the value of `hours` is not supported.
330    fn callback(&self, value: Result<usize, ErrorCode>);
331}