]> Repositories - Adafruit_Blinka-hackapet.git/blob - src/adafruit_blinka/microcontroller/generic_linux/sysfs_analogin.py
Update libgpiod_pulsein to latest binaries
[Adafruit_Blinka-hackapet.git] / src / adafruit_blinka / microcontroller / generic_linux / sysfs_analogin.py
1 # SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
2 #
3 # SPDX-License-Identifier: MIT
4 """
5 `analogio` - Analog input control
6 =================================================
7 Read the SysFS ADC using IIO (Industrial Input/Output) and return the value
8
9 See `CircuitPython:analogio` in CircuitPython for more details.
10 * Author(s): Melissa LeBlanc-Williams
11 """
12
13 import os
14 from adafruit_blinka import ContextManaged
15
16 try:
17     from microcontroller.pin import analogIns
18 except ImportError:
19     raise RuntimeError("No Analog Inputs defined for this board") from ImportError
20
21
22 class AnalogIn(ContextManaged):
23     """Analog Input Class"""
24
25     # Sysfs paths
26     _sysfs_path = "/sys/bus/iio/devices/"
27     _device_path = "iio:device{}"
28
29     # Channel paths
30     _channel_path = "in_voltage{}_raw"
31     _scale_path = "in_voltage_scale"
32
33     def __init__(self, adc_id):
34         """Instantiate an AnalogIn object and verify the sysfs IIO
35         corresponding to the specified channel and pin.
36
37         Args:
38             adc_id (int): Analog Input ID as defined in microcontroller.pin
39
40         Returns:
41             AnalogIn: AnalogIn object.
42
43         Raises:
44             TypeError: if `channel` or `pin` types are invalid.
45             ValueError: if AnalogIn channel does not exist.
46
47         """
48
49         self.id = adc_id
50         self._device = None
51         self._channel = None
52         self._open(adc_id)
53
54     def __enter__(self):
55         return self
56
57     def _open(self, adc_id):
58         self._device = None
59         for adcpair in analogIns:
60             if adcpair[0] == adc_id:
61                 self._device = adcpair[1]
62                 self._channel = adcpair[2]
63
64         if self._device is None:
65             raise RuntimeError("No AnalogIn device found for the given ID")
66
67         device_path = os.path.join(
68             self._sysfs_path, self._device_path.format(self._device)
69         )
70
71         if not os.path.isdir(device_path):
72             raise ValueError(
73                 "AnalogIn device does not exist, check that the required modules are loaded."
74             )
75
76     @property
77     def value(self):
78         """Read the ADC and return the value as an integer"""
79         path = os.path.join(
80             self._sysfs_path,
81             self._device_path.format(self._device),
82             self._channel_path.format(self._channel),
83         )
84
85         with open(path, "r", encoding="utf-8") as analog_in:
86             return int(analog_in.read().strip())
87
88     # pylint: disable=no-self-use
89     @value.setter
90     def value(self, value):
91         # emulate what CircuitPython does
92         raise AttributeError("'AnalogIn' object has no attribute 'value'")
93
94     # pylint: enable=no-self-use
95
96     def deinit(self):
97         self._device = None
98         self._channel = None