]> Repositories - Adafruit_Blinka-hackapet.git/blob - src/adafruit_blinka/microcontroller/generic_linux/sysfs_analogout.py
Merge branch 'main' of https://github.com/adafruit/Adafruit_Blinka into i2c-freq...
[Adafruit_Blinka-hackapet.git] / src / adafruit_blinka / microcontroller / generic_linux / sysfs_analogout.py
1 # SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
2 #
3 # SPDX-License-Identifier: MIT
4 """
5 `analogio` - Analog output control
6 =================================================
7 Write the SysFS DAC using IIO (Industrial Input/Output)
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 analogOuts
18 except ImportError:
19     raise RuntimeError("No Analog Outputs defined for this board") from ImportError
20
21
22 class AnalogOut(ContextManaged):
23     """Analog Output Class"""
24
25     # Sysfs paths
26     _sysfs_path = "/sys/bus/iio/devices/"
27     _device_path = "iio:device{}"
28
29     # Channel paths
30     _channel_path = "out_voltage{}_raw"
31     _scale_path = "out_voltage_scale"
32
33     def __init__(self, dac_id):
34         """Instantiate an AnalogOut object and verify the sysfs IIO
35         corresponding to the specified channel and pin.
36
37         Args:
38             dac_id (int): Analog Output ID as defined in microcontroller.pin
39
40         Returns:
41             AnalogOut: AnalogOut object.
42
43         Raises:
44             TypeError: if `channel` or `pin` types are invalid.
45             ValueError: if AnalogOut channel does not exist.
46
47         """
48
49         self.id = dac_id
50         self._device = None
51         self._channel = None
52         self._open(dac_id)
53
54     def __enter__(self):
55         return self
56
57     def _open(self, dac_id):
58         self._device = None
59         for dacpair in analogOuts:
60             if dacpair[0] == dac_id:
61                 self._device = dacpair[1]
62                 self._channel = dacpair[2]
63
64         if self._device is None:
65             raise RuntimeError("No AnalogOut 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                 "AnalogOut device does not exist, check that the required modules are loaded."
74             )
75
76     @property
77     def value(self):
78         """Return an error. This is output only."""
79         # emulate what CircuitPython does
80         raise AttributeError("unreadable attribute")
81
82     @value.setter
83     def value(self, value):
84         """Write to the DAC"""
85         path = os.path.join(
86             self._sysfs_path,
87             self._device_path.format(self._device),
88             self._channel_path.format(self._channel),
89         )
90
91         with open(path, "w", encoding="utf-8") as analog_out:
92             return analog_out.write(value + "\n")
93
94     def deinit(self):
95         self._device = None
96         self._channel = None