embedded_ads1220/
lib.rs

1#![no_std]
2#![no_main]
3use embedded_hal::digital::{ErrorType, InputPin};
4use embedded_hal::spi::SpiDevice;
5
6#[cfg(feature = "defmt")]
7use defmt::debug;
8use embedded_hal::delay::DelayNs;
9
10pub const BYTES_PER_SAMPLE: u8 = 4;
11
12// ADS1220 SPI Commands
13pub const SPI_MASTER_DUMMY: u8 = 0xFF;
14pub const RESET: u8 = 0x06;
15pub const START: u8 = 0x08;
16pub const WREG: u8 = 0x40;
17pub const RREG: u8 = 0x20;
18
19// Config registers
20pub const CONFIG_REG0_ADDRESS: u8 = 0x00;
21pub const CONFIG_REG1_ADDRESS: u8 = 0x01;
22pub const CONFIG_REG2_ADDRESS: u8 = 0x02;
23pub const CONFIG_REG3_ADDRESS: u8 = 0x03;
24
25pub const REG_CONFIG3_IDAC1_ROUTING_MASK: u8 = 0xE0;
26pub const REG_CONFIG3_IDAC2_ROUTING_MASK: u8 = 0x1C;
27pub const REG_CONFIG2_VREF_MASK: u8 = 0xC0;
28pub const REG_CONFIG2_FIR_MASK: u8 = 0x30;
29pub const REG_CONFIG2_IDAC_CURRENT_MASK: u8 = 0x07;
30pub const REG_CONFIG1_MODE_MASK: u8 = 0x18;
31pub const REG_CONFIG1_DR_MASK: u8 = 0xE0;
32pub const REG_CONFIG0_PGA_GAIN_MASK: u8 = 0x0E;
33pub const REG_CONFIG0_MUX_MASK: u8 = 0xF0;
34
35pub const IDAC1_DISABLE: u8 = 0x00;
36pub const IDAC1_AIN0: u8 = 0x20;
37pub const IDAC1_AIN1: u8 = 0x40;
38pub const IDAC1_AIN2: u8 = 0x60;
39pub const IDAC1_AIN3: u8 = 0x80;
40pub const IDAC1_REFP0: u8 = 0xA0;
41pub const IDAC1_REFN0: u8 = 0xC0;
42pub const IDAC1_RESERVED: u8 = 0xE0;
43
44pub const IDAC2_DISABLE: u8 = 0x00;
45pub const IDAC2_AIN0: u8 = 0x04;
46pub const IDAC2_AIN1: u8 = 0x08;
47pub const IDAC2_AIN2: u8 = 0x60;
48pub const IDAC2_AIN3: u8 = 0x0C;
49pub const IDAC2_REFP0: u8 = 0x10;
50pub const IDAC2_REFN0: u8 = 0x14;
51pub const IDAC2_RESERVED: u8 = 0x1C;
52
53pub const IDAC_OFF: u8 = 0x00;
54pub const IDAC_10: u8 = 0x01;
55pub const IDAC_50: u8 = 0x02;
56pub const IDAC_100: u8 = 0x03;
57pub const IDAC_250: u8 = 0x04;
58pub const IDAC_500: u8 = 0x05;
59pub const IDAC_1000: u8 = 0x06;
60pub const IDAC_1500: u8 = 0x07;
61
62pub const FIR_OFF: u8 = 0x00;
63pub const FIR_5060: u8 = 0x10;
64pub const FIR_50HZ: u8 = 0x20;
65pub const FIR_60HZ: u8 = 0x30;
66
67pub const VREF_2048: u8 = 0x00;
68pub const VREF_REFP0: u8 = 0x40;
69pub const VREF_AIN0: u8 = 0x80;
70pub const VREF_ANALOG: u8 = 0xC0;
71
72pub const MODE_NORMAL: u8 = 0x00;
73pub const MODE_DUTY_CYCLE: u8 = 0x08;
74pub const MODE_TURBO: u8 = 0x10;
75pub const MODE_RESERVED: u8 = 0x18;
76
77pub const DR_20SPS: u8 = 0x00;
78pub const DR_45SPS: u8 = 0x02;
79pub const DR_90SPS: u8 = 0x04;
80pub const DR_175SPS: u8 = 0x06;
81pub const DR_330SPS: u8 = 0x08;
82pub const DR_600SPS: u8 = 0xA0;
83pub const DR_1000SPS: u8 = 0xC0;
84
85pub const PGA_GAIN_1: u8 = 0x00;
86pub const PGA_GAIN_2: u8 = 0x02;
87pub const PGA_GAIN_4: u8 = 0x04;
88pub const PGA_GAIN_8: u8 = 0x06;
89pub const PGA_GAIN_16: u8 = 0x08;
90pub const PGA_GAIN_32: u8 = 0x0A;
91pub const PGA_GAIN_64: u8 = 0x0C;
92pub const PGA_GAIN_128: u8 = 0x0E;
93
94pub const MUX_AIN0_AIN1: u8 = 0x00;
95pub const MUX_AIN0_AIN2: u8 = 0x10;
96pub const MUX_AIN0_AIN3: u8 = 0x20;
97pub const MUX_AIN1_AIN2: u8 = 0x30;
98pub const MUX_AIN1_AIN3: u8 = 0x40;
99pub const MUX_AIN2_AIN3: u8 = 0x50;
100pub const MUX_AIN1_AIN0: u8 = 0x60;
101pub const MUX_AIN3_AIN2: u8 = 0x70;
102pub const MUX_AIN0_AVSS: u8 = 0x80;
103pub const MUX_AIN1_AVSS: u8 = 0x90;
104pub const MUX_AIN2_AVSS: u8 = 0xA0;
105pub const MUX_AIN3_AVSS: u8 = 0xB0;
106
107pub const MUX_SE_CH0: u8 = 0x80;
108pub const MUX_SE_CH1: u8 = 0x90;
109pub const MUX_SE_CH2: u8 = 0xA0;
110pub const MUX_SE_CH3: u8 = 0xB0;
111
112pub const VREF_MASK: u8 = (1 << 6) | (1 << 7);
113pub const VREF_INT: u8 = 0 << 6;
114pub const VREF_EXT: u8 = 1 << 6;
115
116pub struct ADS1220<SPI, DR> {
117    spi: SPI,
118    dr: DR,
119    m_config_reg0: u8,
120    m_config_reg1: u8,
121    m_config_reg2: u8,
122    m_config_reg3: u8,
123}
124
125#[derive(Copy, Clone, Debug)]
126pub enum ADS1220Error<SPI, DR> {
127    Spi(SPI),
128    Dr(DR),
129    // Add other errors for your driver here.
130}
131
132impl<SPI, DR> ADS1220<SPI, DR>
133where
134    SPI: SpiDevice,
135    DR: InputPin,
136{
137    pub fn new(
138        spi: SPI,
139        dr: DR,
140    ) -> Self {
141        ADS1220 {
142            spi,
143            dr,
144            m_config_reg0: 0x00,
145            m_config_reg1: 0x00,
146            m_config_reg2: 0x00,
147            m_config_reg3: 0x00,
148        }
149    }
150
151    pub fn write_register(&mut self, address: u8, value: u8) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
152        self.spi.write(&[WREG | (address << 2)]).map_err(ADS1220Error::Spi)?;
153        self.spi.write(&mut [value]).map_err(ADS1220Error::Spi)?;
154        Ok(())
155    }
156
157    pub fn read_register(&mut self, address: u8) -> Result<u8, ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
158        let mut result: [u8; 1] = [0x00];
159        self.spi.write(&[RREG | (address << 2)]).map_err(ADS1220Error::Spi)?;
160        self.spi.write(&[SPI_MASTER_DUMMY]).map_err(ADS1220Error::Spi)?;
161        self.spi.read(&mut result).map_err(ADS1220Error::Spi)?;
162        Ok(result[0])
163    }
164
165    pub fn begin(&mut self, delay: &mut dyn DelayNs) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
166        self.reset()?;
167        delay.delay_us(50);
168
169        self.m_config_reg0 = 0x00; // Default settings: AINP=AIN0, AINN=AIN1, Gain 1, PGA enabled
170        self.m_config_reg1 = 0x04; // Default settings: DR=20 SPS, Mode=Normal, Conv mode=continuous, Temp Sensor disabled, Current Source off
171        self.m_config_reg2 = 0x10; // Default settings: Vref internal, 50/60Hz rejection, power open, IDAC off
172        self.m_config_reg3 = 0x00; //  Default settings: IDAC1 disabled, IDAC2 disabled, DRDY pin only
173
174        self.write_register(CONFIG_REG0_ADDRESS, self.m_config_reg0)?;
175        self.write_register(CONFIG_REG1_ADDRESS, self.m_config_reg1)?;
176        self.write_register(CONFIG_REG2_ADDRESS, self.m_config_reg2)?;
177        self.write_register(CONFIG_REG3_ADDRESS, self.m_config_reg3)?;
178        Ok(())
179    }
180
181    #[cfg(feature = "defmt")]
182    pub fn print_register_values(&mut self) {
183        let config_reg0 = self.read_register(CONFIG_REG0_ADDRESS).unwrap();
184        let config_reg1 = self.read_register(CONFIG_REG1_ADDRESS).unwrap();
185        let config_reg2 = self.read_register(CONFIG_REG2_ADDRESS).unwrap();
186        let config_reg3 = self.read_register(CONFIG_REG3_ADDRESS).unwrap();
187
188        debug!("Config_Reg : ");
189        debug!("{:#04X}", config_reg0);
190        debug!("{:#04X}", config_reg1);
191        debug!("{:#04X}", config_reg2);
192        debug!("{:#04X}", config_reg3);
193    }
194
195    pub fn spi_command(&mut self, data: u8) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
196        self.spi.write(&mut [data]).map_err(ADS1220Error::Spi)?;
197        Ok(())
198    }
199
200    pub fn reset(&mut self) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
201        self.spi_command(RESET)
202    }
203
204    pub fn start_conv(&mut self) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
205        self.spi_command(START)
206    }
207
208    pub fn select_mux_channels(&mut self, channels_conf: u8) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
209        self.m_config_reg0 &= !REG_CONFIG0_MUX_MASK;
210        self.m_config_reg0 |= channels_conf;
211        self.write_register(CONFIG_REG0_ADDRESS, self.m_config_reg0)
212    }
213
214    pub fn set_pga_gain(&mut self, pga_gain: u8) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
215        self.m_config_reg0 &= !REG_CONFIG0_PGA_GAIN_MASK;
216        self.m_config_reg0 |= pga_gain;
217        self.write_register(CONFIG_REG0_ADDRESS, self.m_config_reg0)
218    }
219
220    pub fn pga_on(&mut self) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
221        self.m_config_reg0 &= !(1 << (0));
222        self.write_register(CONFIG_REG0_ADDRESS, self.m_config_reg0)
223    }
224
225    pub fn pga_off(&mut self) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
226        self.m_config_reg0 |= !(1 << (0));
227        self.write_register(CONFIG_REG0_ADDRESS, self.m_config_reg0)
228    }
229
230    pub fn set_data_rate(&mut self, data_rate: u8) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
231        self.m_config_reg1 &= !REG_CONFIG1_DR_MASK;
232        self.m_config_reg1 |= data_rate;
233        self.write_register(CONFIG_REG1_ADDRESS, self.m_config_reg1)
234    }
235
236    pub fn set_operation_mode(&mut self, mode: u8) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
237        self.m_config_reg1 &= !REG_CONFIG1_MODE_MASK;
238        self.m_config_reg1 |= mode;
239        self.write_register(CONFIG_REG1_ADDRESS, self.m_config_reg1)
240    }
241
242    pub fn set_conv_mode_single_shot(&mut self) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
243        self.m_config_reg1 |= !(1 << (2));
244        self.write_register(CONFIG_REG1_ADDRESS, self.m_config_reg1)
245    }
246
247    pub fn set_conv_mode_continuous(&mut self) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
248        self.m_config_reg1 |= 1 << (2);
249        self.write_register(CONFIG_REG1_ADDRESS, self.m_config_reg1)
250    }
251
252    pub fn temp_sensor_mode_disable(&mut self) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
253        self.m_config_reg1 &= !(1 << (1));
254        self.write_register(CONFIG_REG1_ADDRESS, self.m_config_reg1)
255    }
256
257    pub fn temp_sensor_mode_enable(&mut self) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
258        self.m_config_reg1 |= 1 << (1);
259        self.write_register(CONFIG_REG1_ADDRESS, self.m_config_reg1)
260    }
261
262    pub fn current_sources_off(&mut self) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
263        self.m_config_reg1 &= !(1 << (0));
264        self.write_register(CONFIG_REG1_ADDRESS, self.m_config_reg1)
265    }
266
267    pub fn current_sources_on(&mut self) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
268        self.m_config_reg1 |= 1 << (0);
269        self.write_register(CONFIG_REG1_ADDRESS, self.m_config_reg1)
270    }
271
272    pub fn set_vref(&mut self, vref: u8) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
273        self.m_config_reg2 &= !REG_CONFIG2_VREF_MASK;
274        self.m_config_reg2 |= vref;
275        self.write_register(CONFIG_REG2_ADDRESS, self.m_config_reg2)
276    }
277
278    pub fn set_fir_filter(&mut self, filter: u8) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
279        self.m_config_reg2 &= !REG_CONFIG2_FIR_MASK;
280        self.m_config_reg2 |= filter;
281        self.write_register(CONFIG_REG2_ADDRESS, self.m_config_reg2)
282    }
283
284    pub fn low_side_switch_open(&mut self) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
285        self.m_config_reg2 &= !(1 << (3));
286        self.write_register(CONFIG_REG2_ADDRESS, self.m_config_reg2)
287    }
288
289    pub fn low_side_switch_closed(&mut self) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
290        self.m_config_reg2 |= 1 << (3);
291        self.write_register(CONFIG_REG2_ADDRESS, self.m_config_reg2)
292    }
293
294    pub fn set_idac_current(&mut self, idac_current: u8) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
295        self.m_config_reg2 &= !REG_CONFIG2_IDAC_CURRENT_MASK;
296        self.m_config_reg2 |= idac_current;
297        self.write_register(CONFIG_REG2_ADDRESS, self.m_config_reg2)
298    }
299
300    pub fn set_idac1_route(&mut self, idac1_routing: u8) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
301        self.m_config_reg3 &= !REG_CONFIG3_IDAC1_ROUTING_MASK;
302        self.m_config_reg3 |= idac1_routing;
303        self.write_register(CONFIG_REG3_ADDRESS, self.m_config_reg3)
304    }
305
306    pub fn set_idac2_route(&mut self, idac2_routing: u8) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
307        self.m_config_reg3 &= !REG_CONFIG3_IDAC2_ROUTING_MASK;
308        self.m_config_reg3 |= idac2_routing;
309        self.write_register(CONFIG_REG3_ADDRESS, self.m_config_reg3)
310    }
311
312    pub fn set_drdy_mode_default(&mut self) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
313        self.m_config_reg3 &= !(1 << (3));
314        self.write_register(CONFIG_REG3_ADDRESS, self.m_config_reg3)
315    }
316
317    pub fn set_drdy_mode_dout(&mut self) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
318        self.m_config_reg3 |= 1 << (3);
319        self.write_register(CONFIG_REG3_ADDRESS, self.m_config_reg3)
320    }
321
322    pub fn set_internal_reference(&mut self) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
323        self.m_config_reg2 &= !VREF_MASK;
324        self.m_config_reg2 |= VREF_INT;
325        self.write_register(CONFIG_REG2_ADDRESS, self.m_config_reg2)
326    }
327
328    pub fn set_external_reference(&mut self) -> Result<(), ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
329        self.m_config_reg2 &= !VREF_MASK;
330        self.m_config_reg2 |= VREF_EXT;
331        self.write_register(CONFIG_REG2_ADDRESS, self.m_config_reg2)
332    }
333
334    pub fn get_config_reg(&mut self) -> Result<[u8; 4], ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
335        self.m_config_reg0 = self.read_register(CONFIG_REG0_ADDRESS)?;
336        self.m_config_reg1 = self.read_register(CONFIG_REG1_ADDRESS)?;
337        self.m_config_reg2 = self.read_register(CONFIG_REG2_ADDRESS)?;
338        self.m_config_reg3 = self.read_register(CONFIG_REG3_ADDRESS)?;
339
340        Ok([
341            self.m_config_reg0,
342            self.m_config_reg1,
343            self.m_config_reg2,
344            self.m_config_reg3
345        ])
346    }
347
348    pub fn wait_for_data(&mut self, delay: &mut dyn DelayNs, mut timeout_ms: u64) -> bool {
349        while self.dr.is_high().unwrap() {
350            if timeout_ms > 0 {
351                delay.delay_ms(1);
352                timeout_ms -= 1;
353            } else {
354                return false;
355            }
356        }
357        true
358    }
359
360    pub fn read_data(&mut self) -> Result<[u8; 3], ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
361        let mut buf: [u8; 3] = [0x00; 3];
362        self.spi.read(&mut buf).map_err(ADS1220Error::Spi)?;
363        Ok(buf)
364    }
365
366    pub fn data_to_int(&mut self, data: [u8; 3]) -> i32 {
367        let mut result: i32;
368        result = data[0] as i32;
369        result = (result << 8) | data[1] as i32;
370        result = (result << 8) | data[2] as i32;
371
372        if (data[0] & (1 << 7)) == 0 {
373            result |= 0xFF000000u32 as i32;
374        }
375        result
376    }
377
378    pub fn read_wait_for_data(&mut self, delay: &mut dyn DelayNs) -> Result<i32, ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
379        if !self.wait_for_data(delay, 60) {
380            return Ok(0);
381        }
382        self.read_data().map(|t| self.data_to_int(t))
383    }
384
385    pub fn read_data_samples(&mut self) -> Result<i32, ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
386        let mut buf: [u8; 3] = [0x00; 3];
387        let result: i32;
388        let mut bit24: i32;
389
390        self.spi.read(&mut buf).map_err(ADS1220Error::Spi)?;
391
392        bit24 = buf[0] as i32;
393        bit24 = (bit24 << 8) | buf[1] as i32;
394        bit24 = (bit24 << 8) | buf[2] as i32;
395        bit24 = bit24 << 8;
396        result = bit24 >> 8;
397        Ok(result)
398    }
399
400    pub fn read_single_shot(&mut self) -> Result<i32, ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
401        self.start_conv()?;
402        self.read_data().map(|t| self.data_to_int(t))
403    }
404
405    pub fn read_single_shot_wait_for_data(&mut self, delay: &mut dyn DelayNs) -> Result<i32, ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
406        self.start_conv()?;
407        self.read_wait_for_data(delay)
408    }
409
410    pub fn read_single_shot_single_ended(&mut self, channels_conf: u8) -> Result<i32, ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
411        self.select_mux_channels(channels_conf)?;
412        self.read_single_shot()
413    }
414
415    pub fn read_single_shot_single_ended_wait_for_data(&mut self, delay: &mut dyn DelayNs, channels_conf: u8) -> Result<i32, ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
416        self.select_mux_channels(channels_conf)?;
417        self.read_single_shot_wait_for_data(delay)
418    }
419
420    pub fn data_ready(&mut self) -> Result<bool, ADS1220Error<SPI::Error, <DR as ErrorType>::Error>> {
421        self.dr.is_low().map_err(ADS1220Error::Dr)
422    }
423
424    #[cfg(feature = "defmt")]
425    pub fn status(&mut self) {
426        // let current_time: Instant = Instant::now();
427        let ready = self.data_ready().unwrap();
428        let pending = if ready { BYTES_PER_SAMPLE } else { 0 };
429        debug!("ads1220 status: ready={}, pending_bytes={:#X}", ready, pending)
430    }
431}