|
| 1 | +#!/usr/bin/env python3 |
| 2 | +""" |
| 3 | +ADS111x - Ultra-Small, Low-Power, I2C-Compatible, 860-SPS, 16-Bit ADCs |
| 4 | + With Internal Reference, Oscillator, and Programmable Comparator |
| 5 | +
|
| 6 | +datasheet: https://www.ti.com/lit/ds/symlink/ads1115.pdf |
| 7 | +""" |
| 8 | + |
| 9 | +import logging |
| 10 | + |
| 11 | +# module busio provides no type hints |
| 12 | +import busio # type: ignore |
| 13 | +from attrs import define |
| 14 | +from feeph.i2c import BurstHandler |
| 15 | + |
| 16 | +from feeph.ads1xxx.ads111x import Ads111x |
| 17 | + |
| 18 | +LH = logging.getLogger('feeph.ads1xxx') |
| 19 | + |
| 20 | + |
| 21 | +@define |
| 22 | +class Ads1115Config: |
| 23 | + """ |
| 24 | + The 16-bit Config register is used to control the operating mode, input |
| 25 | + selection, data rate, full-scale range, and comparator modes. |
| 26 | + """ |
| 27 | + # fmt: off |
| 28 | + OSSA: int # 0b#..._...._...._.... status or single shot start |
| 29 | + IMUX: int # 0b.###_...._...._.... input multiplexer configuration |
| 30 | + PGA: int # 0b...._###._...._.... programmable gain amplifier |
| 31 | + MODE: int # 0b...._...#_...._.... operating mode |
| 32 | + DR: int # 0b...._...._###._.... data rate |
| 33 | + COMP_MOD: int # 0b...._...._...#_.... comparator mode |
| 34 | + COMP_POL: int # 0b...._...._...._#... comparator polarity |
| 35 | + COMP_LAT: int # 0b...._...._...._.#.. latching comparator |
| 36 | + COMP_QUE: int # 0b...._...._...._..## comparator queue & disable |
| 37 | + # fmt: on |
| 38 | + |
| 39 | + |
| 40 | +DEFAULTS = { |
| 41 | + 0x01: 0x8583, |
| 42 | + 0x02: 0x8000, |
| 43 | + 0x03: 0x7FFF, |
| 44 | +} |
| 45 | + |
| 46 | + |
| 47 | +class Ads1115(Ads111x): |
| 48 | + # 0x00 - conversion register (2 bytes, ro, default: 0x0000) |
| 49 | + # 0x01 - config register (2 bytes, rw, default: 0x8583) |
| 50 | + # 0x10 - lo_thresh register (2 bytes, rw, default: 0x0080) |
| 51 | + # 0x11 - hi_thresh register (2 bytes, rw, default: 0xFF7F) |
| 52 | + |
| 53 | + def __init__(self, i2c_bus: busio.I2C): |
| 54 | + self._i2c_bus = i2c_bus |
| 55 | + self._i2c_adr = 0x48 # the I²C bus address is hardcoded |
| 56 | + |
| 57 | + def get_config(self) -> Ads1115Config: |
| 58 | + with BurstHandler(i2c_bus=self._i2c_bus, i2c_adr=self._i2c_adr) as bh: |
| 59 | + value = bh.read_register(0x01, byte_count=2) |
| 60 | + params = { |
| 61 | + "OSSA": value & 0b1000_0000_0000_0000, |
| 62 | + "IMUX": value & 0b0111_0000_0000_0000, |
| 63 | + "PGA": value & 0b0000_1110_0000_0000, |
| 64 | + "MODE": value & 0b0000_0001_0000_0000, |
| 65 | + "DR": value & 0b0000_0000_1110_0000, |
| 66 | + "COMP_MOD": value & 0b0000_0000_0001_0000, |
| 67 | + "COMP_POL": value & 0b0000_0000_0000_1000, |
| 68 | + "COMP_LAT": value & 0b0000_0000_0000_0100, |
| 69 | + "COMP_QUE": value & 0b0000_0000_0000_0011, |
| 70 | + } |
| 71 | + return Ads1115Config(**params) |
| 72 | + |
| 73 | + def set_config(self, config: Ads1115Config): |
| 74 | + value = 0b0000_0000_0000_0000 |
| 75 | + value &= config.OSSA |
| 76 | + value &= config.IMUX |
| 77 | + value &= config.PGA |
| 78 | + value &= config.MODE |
| 79 | + value &= config.DR |
| 80 | + value &= config.COMP_MOD |
| 81 | + value &= config.COMP_POL |
| 82 | + value &= config.COMP_LAT |
| 83 | + value &= config.COMP_QUE |
| 84 | + with BurstHandler(i2c_bus=self._i2c_bus, i2c_adr=self._i2c_adr) as bh: |
| 85 | + bh.write_register(0x01, value, byte_count=2) |
| 86 | + |
| 87 | + def reset_device_registers(self): |
| 88 | + with BurstHandler(i2c_bus=self._i2c_bus, i2c_adr=self._i2c_adr) as bh: |
| 89 | + for register, value in DEFAULTS.items(): |
| 90 | + bh.write_register(register, value, byte_count=2) |
| 91 | + |
| 92 | + # --------------------------------------------------------------------- |
| 93 | + |
| 94 | + def get_measurement(self) -> int: |
| 95 | + return 0 |
| 96 | + |
| 97 | + # --------------------------------------------------------------------- |
0 commit comments