grideye/
lib.rs

1// ------------------------------------------------------------------------------
2// Copyright 2018 Uwe Arzt, mail@uwe-arzt.de
3// SPDX-License-Identifier: Apache-2.0
4// ------------------------------------------------------------------------------
5
6//! Driver for Panasonic AMG88(33)
7
8#![no_std]
9
10use embedded_hal as hal;
11use libm;
12
13use bit_field::BitField;
14
15use crate::hal::blocking::delay::DelayMs;
16use crate::hal::blocking::i2c::{Read, Write, WriteRead};
17
18/// Errors
19#[derive(Debug)]
20pub enum Error<E> {
21    /// I2C bus error
22    I2c(E),
23}
24/// I²C address
25#[derive(Copy, Clone)]
26pub enum Address {
27    Standard = 0x69,
28    Alternate = 0x68,
29}
30
31#[allow(dead_code)]
32#[derive(Copy, Clone)]
33enum Register {
34    PowerControl = 0x00,
35    Reset = 0x01,
36    Framerate = 0x02,
37    IntControl = 0x03,
38    Status = 0x04,
39    StatusClear = 0x05,
40    Average = 0x07,
41    IntLevelUpperLsb = 0x08,
42    IntLevelUpperMsb = 0x09,
43    IntLevelLowerLsb = 0x0A,
44    IntLevelLowerMsb = 0x0B,
45    IntLevelHystLsb = 0x0C,
46    IntLevelHystMsb = 0x0D,
47    ThermistorLsb = 0x0E,
48    ThermistorMsb = 0x0F,
49    IntTableInt0 = 0x10,
50    ReservedAverage = 0x1F,
51    TemperatureStart = 0x80,
52}
53
54#[derive(Copy, Clone)]
55pub enum Power {
56    Wakeup = 0x00,
57    Sleep = 0x10,
58    Standby60Seconds = 0x20,
59    Standby10Seconds = 0x21,
60}
61
62#[derive(Copy, Clone)]
63pub enum Framerate {
64    Fps10 = 0x00,
65    Fps1 = 0x01,
66}
67
68#[allow(dead_code)]
69pub struct GridEye<I2C, D> {
70    i2c: I2C,
71    delay: D,
72    address: Address,
73}
74
75impl<I2C, D, E> GridEye<I2C, D>
76where
77    I2C: Read<Error = E> + Write<Error = E> + WriteRead<Error = E>,
78    D: DelayMs<u8>,
79{
80    /// Creates a new driver
81    pub fn new(i2c: I2C, delay: D, address: Address) -> Self {
82        GridEye {
83            i2c,
84            delay,
85            address,
86        }
87    }
88
89    // ---- Sensor array ---------------------------------------------------------------------------
90    /// Get pixel value for pixel 0-63 as raw value
91    pub fn get_pixel_temperature_raw(&mut self, pixel: u8) -> Result<u16, Error<E>> {
92        let pixel_low = Register::TemperatureStart as u8 + (2 * pixel);
93        self.get_register_as_u16(pixel_low)
94    }
95
96    /// Get pixel value for pixel 0-63 as celsius
97    pub fn get_pixel_temperature_celsius(&mut self, pixel: u8) -> Result<f32, Error<E>> {
98        let temperature = self.get_pixel_temperature_raw(pixel)?;
99        Ok(temperature_u12_to_f32_celsius(temperature, 0.25))
100    }
101
102    // ---- Device temperature ---------------------------------------------------------------------
103    pub fn get_device_temperature_raw(&mut self) -> Result<u16, Error<E>> {
104        self.get_register_as_u16(Register::ThermistorLsb as u8)
105    }
106
107    pub fn get_device_temperature_celsius(&mut self) -> Result<f32, Error<E>> {
108        let temperature = self.get_device_temperature_raw()?;
109        Ok(temperature_u12_to_f32_celsius(temperature, 0.0625))
110    }
111
112    // ---- framerate ------------------------------------------------------------------------------
113    pub fn set_framerate(&mut self, framerate: Framerate) -> Result<(), Error<E>> {
114        self.set_register(Register::Framerate, framerate as u8)
115    }
116    pub fn get_framerate(&mut self) -> Result<(Framerate), Error<E>> {
117        let fps = self.get_register(Register::Framerate as u8)?;
118        if fps == 0 {
119            Ok(Framerate::Fps10)
120        } else {
121            Ok(Framerate::Fps1)
122        }
123    }
124
125    // ---- other ----------------------------------------------------------------------------------
126    pub fn power(&mut self, power: Power) -> Result<(), Error<E>> {
127        self.set_register(Register::PowerControl, power as u8)
128    }
129
130    // ---- interrupt ------------------------------------------------------------------------------
131    pub fn enable_interrupt(&mut self) -> Result<(), Error<E>> {
132        let mut icr = self.get_register(Register::IntControl as u8)?;
133        self.set_register(Register::IntControl, *icr.set_bit(0, true))?;
134        Ok(())
135    }
136    pub fn disable_interrupt(&mut self) -> Result<(), Error<E>> {
137        let mut icr = self.get_register(Register::IntControl as u8)?;
138        self.set_register(Register::IntControl, *icr.set_bit(0, false))?;
139        Ok(())
140    }
141    pub fn interrupt_enabled(&mut self) -> Result<bool, Error<E>> {
142        let icr = self.get_register(Register::IntControl as u8)?;
143        Ok(icr.get_bit(1))
144    }
145    pub fn interrupt_mode_absolut(&mut self) -> Result<(), Error<E>> {
146        let mut icr = self.get_register(Register::IntControl as u8)?;
147        self.set_register(Register::IntControl, *icr.set_bit(1, true))?;
148        Ok(())
149    }
150    pub fn interrupt_mode_difference(&mut self) -> Result<(), Error<E>> {
151        let mut icr = self.get_register(Register::IntControl as u8)?;
152        self.set_register(Register::IntControl, *icr.set_bit(1, true))?;
153        Ok(())
154    }
155
156    // ---- status ---------------------------------------------------------------------------------
157    pub fn interrupt_flag_set(&mut self) -> Result<bool, Error<E>> {
158        let status = self.get_register(Register::IntControl as u8)?;
159        Ok(status.get_bit(1))
160    }
161    pub fn pixel_temperature_out_ok(&mut self) -> Result<bool, Error<E>> {
162        let status = self.get_register(Register::IntControl as u8)?;
163        Ok(status.get_bit(2))
164    }
165    pub fn device_temperature_out_ok(&mut self) -> Result<bool, Error<E>> {
166        let status = self.get_register(Register::IntControl as u8)?;
167        Ok(status.get_bit(3))
168    }
169    pub fn clear_interrupt_flag(&mut self) -> Result<(), Error<E>> {
170        self.set_register(Register::StatusClear, 0x02)?;
171        Ok(())
172    }
173    pub fn clear_pixel_temperatur_overflow(&mut self) -> Result<(), Error<E>> {
174        self.set_register(Register::StatusClear, 0x04)?;
175        Ok(())
176    }
177    pub fn clear_device_temperature_overflow(&mut self) -> Result<(), Error<E>> {
178        self.set_register(Register::StatusClear, 0x08)?;
179        Ok(())
180    }
181    pub fn clear_all_overflow(&mut self) -> Result<(), Error<E>> {
182        self.set_register(Register::StatusClear, 0x0c)?;
183        Ok(())
184    }
185    pub fn clear_all_status(&mut self) -> Result<(), Error<E>> {
186        self.set_register(Register::StatusClear, 0x0e)?;
187        Ok(())
188    }
189
190    // ---- pixel interrupt ------------------------------------------------------------------------
191    pub fn pixel_interrupt_enabled(&mut self, pixel: u8) -> Result<bool, Error<E>> {
192        let intreg = (Register::IntTableInt0 as u8) + (pixel / 8);
193        let pos = pixel % 8;
194
195        let inttable = self.get_register(intreg)?;
196        Ok(inttable.get_bit(pos as usize))
197    }
198
199    // ----  average -------------------------------------------------------------------------------
200    pub fn enable_moving_average(&mut self) -> Result<(), Error<E>> {
201        self.set_register(Register::ReservedAverage, 0x50)?;
202        self.set_register(Register::ReservedAverage, 0x45)?;
203        self.set_register(Register::ReservedAverage, 0x57)?;
204        self.set_register(Register::Average, 0x20)?;
205        self.set_register(Register::ReservedAverage, 0x00)?;
206        Ok(())
207    }
208
209    pub fn disable_moving_average(&mut self) -> Result<(), Error<E>> {
210        self.set_register(Register::ReservedAverage, 0x50)?;
211        self.set_register(Register::ReservedAverage, 0x45)?;
212        self.set_register(Register::ReservedAverage, 0x57)?;
213        self.set_register(Register::Average, 0x00)?;
214        self.set_register(Register::ReservedAverage, 0x00)?;
215        Ok(())
216    }
217
218    pub fn moving_average_enabled(&mut self) -> Result<bool, Error<E>> {
219        let avg = self.get_register(Register::Average as u8)?;
220        Ok(avg.get_bit(5))
221    }
222
223    // ---- interrupt value ------------------------------------------------------------------------
224    pub fn set_upper_int_value_celsius(&mut self, celsius: f32) -> Result<(), Error<E>> {
225        self.set_upper_int_value_raw(temperature_f32_to_u16_celsius(celsius))
226    }
227
228    pub fn set_upper_int_value_raw(&mut self, value: u16) -> Result<(), Error<E>> {
229        let bytes = value.to_le_bytes();
230        self.set_register(Register::IntLevelUpperLsb, bytes[0])?;
231        self.set_register(Register::IntLevelUpperMsb, bytes[1])?;
232        Ok(())
233    }
234
235    pub fn set_lower_int_value_celsius(&mut self, celsius: f32) -> Result<(), Error<E>> {
236        self.set_lower_int_value_raw(temperature_f32_to_u16_celsius(celsius))
237    }
238
239    pub fn set_lower_int_value_raw(&mut self, value: u16) -> Result<(), Error<E>> {
240        let bytes = value.to_le_bytes();
241        self.set_register(Register::IntLevelLowerLsb, bytes[0])?;
242        self.set_register(Register::IntLevelLowerMsb, bytes[1])?;
243        Ok(())
244    }
245
246    pub fn set_int_hysteresis_celsius(&mut self, celsius: f32) -> Result<(), Error<E>> {
247        self.set_int_hysteresis_raw(temperature_f32_to_u16_celsius(celsius))
248    }
249
250    pub fn set_int_hysteresis_raw(&mut self, value: u16) -> Result<(), Error<E>> {
251        let bytes = value.to_le_bytes();
252        self.set_register(Register::IntLevelHystLsb, bytes[0])?;
253        self.set_register(Register::IntLevelHystMsb, bytes[1])?;
254        Ok(())
255    }
256
257    pub fn upper_int_value_celsius(&mut self) -> Result<f32, Error<E>> {
258        let temperature = self.upper_int_value_raw()?;
259        Ok(temperature_u12_to_f32_celsius(temperature, 0.25))
260    }
261
262    pub fn upper_int_value_raw(&mut self) -> Result<u16, Error<E>> {
263        let intval = self.get_register_as_u16(Register::IntLevelUpperLsb as u8)?;
264        Ok(intval)
265    }
266
267    pub fn lower_int_value_celsius(&mut self) -> Result<f32, Error<E>> {
268        let temperature = self.lower_int_value_raw()?;
269        Ok(temperature_u12_to_f32_celsius(temperature, 0.25))
270    }
271
272    pub fn lower_int_value_raw(&mut self) -> Result<u16, Error<E>> {
273        let intval = self.get_register_as_u16(Register::IntLevelLowerLsb as u8)?;
274        Ok(intval)
275    }
276 
277    pub fn hysteresis_int_value_celsius(&mut self) -> Result<f32, Error<E>> {
278        let temperature = self.hysteresis_int_value_raw()?;
279        Ok(temperature_u12_to_f32_celsius(temperature, 0.25))
280    }
281
282    pub fn hysteresis_int_value_raw(&mut self) -> Result<u16, Error<E>> {
283        let intval = self.get_register_as_u16(Register::IntLevelHystLsb as u8)?;
284        Ok(intval)
285    }
286
287    // ---- internal -------------------------------------------------------------------------------
288    fn set_register(&mut self, register: Register, value: u8) -> Result<(), Error<E>> {
289        let cmd_bytes = [register as u8, value];
290        self.i2c
291            .write(self.address as u8, &cmd_bytes)
292            .map_err(Error::I2c)
293    }
294
295    fn get_register(&mut self, register: u8) -> Result<u8, Error<E>> {
296        let cmd = [register];
297        self.i2c
298            .write(self.address as u8, &cmd)
299            .map_err(Error::I2c)?;
300        let mut buffer = [0];
301        self.i2c
302            .read(self.address as u8, &mut buffer)
303            .map_err(Error::I2c)?;
304        Ok(buffer[0])
305    }
306
307    fn get_register_as_u16(&mut self, register: u8) -> Result<u16, Error<E>> {
308        let cmd = [register];
309        self.i2c
310            .write(self.address as u8, &cmd)
311            .map_err(Error::I2c)?;
312        let mut buffer = [0, 0];
313        self.i2c
314            .read(self.address as u8, &mut buffer)
315            .map_err(Error::I2c)?;
316        Ok(((buffer[1] as u16) << 8) + (buffer[0] as u16))
317    }
318}
319// ---- conversion -----------------------------------------------------------------------------
320fn temperature_u12_to_f32_celsius(temperature: u16, factor: f32) -> f32 {
321    // check if temperature is negative
322    if !temperature.get_bit(11) {
323        temperature as f32 * factor
324    } else {
325        let mut bnot = !temperature;
326        let temp = *bnot.set_bits(11..16, 0b00000);
327        temp as f32 * -factor
328    }
329}
330fn temperature_f32_to_u16_celsius(mut celsius: f32) -> u16 {
331       let mut neg = false;
332        if celsius < 0.0 {
333            celsius = libm::fabsf(celsius);
334            neg = true;
335        }
336        let mut temp = celsius as u16;
337        if neg {
338            temp = *temp.set_bit(11, true);
339        }
340        return temp
341}