From: Bdale Garbee Date: Sun, 19 Jan 2025 02:41:23 +0000 (-0700) Subject: fresh backup of target work to date on Python code, etc X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=4817f7968cbb68412c992ac906e8d580d4294a74;p=fw%2Fquantimotor fresh backup of target work to date on Python code, etc --- diff --git a/Backup/bcm2837-rpi-zero-2-w.dts b/Backup/bcm2837-rpi-zero-2-w.dts new file mode 100644 index 0000000..e0cba2f --- /dev/null +++ b/Backup/bcm2837-rpi-zero-2-w.dts @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Stefan Wahren + */ + +/dts-v1/; +#include "bcm2837.dtsi" +#include "bcm2836-rpi.dtsi" +#include "bcm283x-rpi-usb-otg.dtsi" +#include "bcm283x-rpi-wifi-bt.dtsi" + +/ { + compatible = "raspberrypi,model-zero-2-w", "brcm,bcm2837"; + model = "Raspberry Pi Zero 2 W"; + + memory@0 { + device_type = "memory"; + reg = <0 0x20000000>; + }; + + chosen { + /* 8250 auxiliary UART instead of pl011 */ + stdout-path = "serial1:115200n8"; + }; + + leds { + led-act { + gpios = <&gpio 29 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&bt { + shutdown-gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; +}; + +&gpio { + /* + * This is based on the official GPU firmware DT blob. + * + * Legend: + * "NC" = not connected (no rail from the SoC) + * "FOO" = GPIO line named "FOO" on the schematic + * "FOO_N" = GPIO line named "FOO" on schematic, active low + */ + gpio-line-names = "ID_SDA", + "ID_SCL", + "SDA1", + "SCL1", + "GPIO_GCLK", + "GPIO5", + "GPIO6", + "SPI_CE1_N", + "SPI_CE0_N", + "SPI_MISO", + "SPI_MOSI", + "SPI_SCLK", + "GPIO12", + "GPIO13", + /* Serial port */ + "TXD0", + "RXD0", + "GPIO16", + "GPIO17", + "GPIO18", + "GPIO19", + "GPIO20", + "GPIO21", + "GPIO22", + "GPIO23", + "GPIO24", + "GPIO25", + "GPIO26", + "GPIO27", + "HDMI_HPD_N", + "STATUS_LED_N", + "NC", /* GPIO30 */ + "NC", /* GPIO31 */ + "NC", /* GPIO32 */ + "NC", /* GPIO33 */ + "NC", /* GPIO34 */ + "NC", /* GPIO35 */ + "NC", /* GPIO36 */ + "NC", /* GPIO37 */ + "NC", /* GPIO38 */ + "NC", /* GPIO39 */ + "CAM_GPIO0", /* GPIO40 */ + "WL_ON", /* GPIO41 */ + "BT_ON", /* GPIO42 */ + "WIFI_CLK", /* GPIO43 */ + "SDA0", /* GPIO44 */ + "SCL0", /* GPIO45 */ + "SMPS_SCL", + "SMPS_SDA", + /* Used by SD Card */ + "SD_CLK_R", + "SD_CMD_R", + "SD_DATA0_R", + "SD_DATA1_R", + "SD_DATA2_R", + "SD_DATA3_R"; + + pinctrl-0 = <&gpioout &alt0>; +}; + +&hdmi { + hpd-gpios = <&gpio 28 GPIO_ACTIVE_LOW>; + power-domains = <&power RPI_POWER_DOMAIN_HDMI>; + status = "okay"; +}; + +&sdhci { + pinctrl-0 = <&emmc_gpio34 &gpclk2_gpio43>; +}; + +&sdhost { + pinctrl-names = "default"; + pinctrl-0 = <&sdhost_gpio48>; + bus-width = <4>; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio32 &uart0_ctsrts_gpio30>; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_gpio14>; + status = "okay"; +}; + +&wifi_pwrseq { + reset-gpios = <&gpio 41 GPIO_ACTIVE_LOW>; +}; + +&spi { + status = "okay"; + + pinctrl-names = "default"; + cs-gpios = <&gpio 8 GPIO_ACTIVE_LOW>, <&gpio 7 GPIO_ACTIVE_LOW>; + + #address-cells = <1>; + #size-cells = <0>; + + ads8688: ads8688@0 { + compatible = "ti,ads8688"; + reg = <0>; + spi-max-frequency = <1000000>; + }; +}; diff --git a/Backup/highspeedread.py b/Backup/highspeedread.py new file mode 100755 index 0000000..23e3906 --- /dev/null +++ b/Backup/highspeedread.py @@ -0,0 +1,40 @@ +#! /usr/bin/python3 + +# use the libiio library directly, instead of the Python bindings, +# for highest performance, needs package libiio-dev installed + +import ctypes +import time + +# Load the libiio library +libiio = ctypes.cdll.LoadLibrary("libiio.so") + +# Initialize the IIO context +ctx = libiio.iio_create_context_from_uri("local:") + +# Get the device +dev = libiio.iio_context_find_device(ctx, "ads8688") + +# Get the channel +chan = libiio.iio_device_find_channel(dev, "voltage0", 0) + +# Enable the channel +libiio.iio_channel_enable(chan) + +# Read samples in a loop +num_samples = 1000 +buffer = (ctypes.c_int16 * num_samples)() + +start_time = time.time() +for i in range(num_samples): + libiio.iio_channel_read(chan, buffer, num_samples * 2) + +end_time = time.time() + +# Disable the channel +libiio.iio_channel_disable(chan) + +# Destroy the context +libiio.iio_context_destroy(ctx) + +print("Read {} samples in {} seconds".format(num_samples, end_time - start_time)) diff --git a/Backup/iio_attr.py b/Backup/iio_attr.py new file mode 100755 index 0000000..803d8fa --- /dev/null +++ b/Backup/iio_attr.py @@ -0,0 +1,491 @@ +#!/usr/bin/env python3 +""" +Copyright (C) 2020 Analog Devices, Inc. +Author: Cristian Iacob + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +""" + +import sys +import argparse +import iio + + +def _str_match(string, other_string, ignore_case): + if ignore_case: + string = string.lower() + other_string = other_string.lower() + + return string == other_string + + +class Arguments: + """Class for parsing the input arguments.""" + + def __init__(self): + """Arguments class constructor.""" + self.device = None + self.channel = None + self.attr = None + self.buffer = None + self.search_context = False + self.search_device = False + self.search_channel = False + self.search_buffer = False + self.search_debug = False + self.detect_context = None + self.arg_uri = None + self.input_only = None + self.output_only = None + self.scan_only = None + self.ignore_case = None + self.quiet = None + + self.parser = argparse.ArgumentParser(description="iio_attr") + self._add_required_mutex_group() + self._add_help_group() + self._add_context_group() + self._add_channel_group() + args = self.parser.parse_args() + self._read_arguments(args) + + def _add_required_mutex_group(self): + self._required_mutex_group = self.parser.add_mutually_exclusive_group(required=True) + self._required_mutex_group.add_argument("-d", "--device-attr", + type=str, metavar="", nargs="*", + help="Usage: [device] [attr] [value]\nRead/Write device attributes") + self._required_mutex_group.add_argument("-c", "--channel-attr", + type=str, metavar="", nargs="*", + help="Usage: [device] [channel] [attr] [value]\n" + "Read/Write channel attributes.") + self._required_mutex_group.add_argument("-B", "--buffer-attr", + type=str, metavar="", nargs="*", + help="Usage: [device] [attr] [value]\nRead/Write buffer attributes.") + self._required_mutex_group.add_argument("-D", "--debug-attr", + type=str, metavar="", nargs="*", + help="Usage: [device] [attr] [value]\nRead/Write debug attributes.") + self._required_mutex_group.add_argument("-C", "--context-attr", + type=str, metavar="", nargs="*", + help="Usage: [attr]\nRead IIO context attributes.") + + def _add_help_group(self): + self._help_group = self.parser.add_argument_group("General") + self._help_group.add_argument("-I", "--ignore-case", action="store_true", help="Ignore case distinctions.") + self._help_group.add_argument("-q", "--quiet", action="store_true", help="Return result only.") + + def _add_context_group(self): + self._context_group = self.parser.add_argument_group("Context connection") + self._context_group.add_argument("-u", "--uri", metavar="", type=str, nargs=1, + help="Use the context at the provided URI.") + self._context_group.add_argument("-a", "--auto", action="store_true", + help="Use the first context found.") + + def _add_channel_group(self): + self._channel_group = self.parser.add_argument_group("Channel qualifiers") + self._channel_group.add_argument("-i", "--input-channel", action="store_true", + help="Filter Input Channels only.") + self._channel_group.add_argument("-o", "--output-channel", action="store_true", + help="Filter Output Channels only.") + self._channel_group.add_argument("-s", "--scan-channel", action="store_true", + help="Filter Scan Channels only.") + + def _read_optional_arguments(self, args): + self.detect_context = args.auto + self.arg_uri = args.uri[0] if args.uri is not None else None + self.input_only = args.input_channel + self.output_only = args.output_channel + self.scan_only = args.scan_channel + self.ignore_case = args.ignore_case + self.quiet = args.quiet + + def _read_device_arguments(self, args): + if len(args.device_attr) >= 4: + print("Too many options for searching for device attributes") + sys.exit(1) + + self.search_device = True + self.device = args.device_attr[0] if len(args.device_attr) >= 1 else None + self.attr = args.device_attr[1] if len(args.device_attr) >= 2 else None + self.buffer = args.device_attr[2] if len(args.device_attr) >= 3 else None + + def _read_channel_arguments(self, args): + if len(args.channel_attr) >= 5: + print("Too many options for searching for channel attributes") + sys.exit(1) + + self.search_channel = True + self.device = args.channel_attr[0] if len(args.channel_attr) >= 1 else None + self.channel = args.channel_attr[1] if len(args.channel_attr) >= 2 else None + self.attr = args.channel_attr[2] if len(args.channel_attr) >= 3 else None + self.buffer = args.channel_attr[3] if len(args.channel_attr) >= 4 else None + + def _read_buffer_arguments(self, args): + if len(args.buffer_attr) >= 4: + print("Too many options for searching for buffer attributes") + sys.exit(1) + + self.search_buffer = True + self.device = args.buffer_attr[0] if len(args.buffer_attr) >= 1 else None + self.attr = args.buffer_attr[1] if len(args.buffer_attr) >= 2 else None + self.buffer = args.buffer_attr[2] if len(args.buffer_attr) >= 3 else None + + def _read_debug_arguments(self, args): + if len(args.debug_attr) >= 4: + print("Too many options for searching for debug attributes") + sys.exit(1) + + self.search_debug = True + self.device = args.debug_attr[0] if len(args.debug_attr) >= 1 else None + self.attr = args.debug_attr[1] if len(args.debug_attr) >= 2 else None + self.buffer = args.debug_attr[2] if len(args.debug_attr) >= 3 else None + + def _read_context_arguments(self, args): + if len(args.context_attr) >= 2: + print("Too many options for searching for context attributes") + sys.exit(1) + + self.search_context = True + self.attr = args.context_attr[0] if len(args.context_attr) >= 1 else None + + def _read_arguments(self, args): + self._read_optional_arguments(args) + if args.device_attr is not None: + self._read_device_arguments(args) + if args.channel_attr is not None: + self._read_channel_arguments(args) + if args.buffer_attr is not None: + self._read_buffer_arguments(args) + if args.debug_attr is not None: + self._read_debug_arguments(args) + if args.context_attr is not None: + self._read_context_arguments(args) + + +class ContextBuilder: + """Class for creating the requested context.""" + + def __init__(self, arguments): + """ + Class constructor. + + Args: + arguments: type=Arguments + Contains the input arguments. + """ + self.ctx = None + self.arguments = arguments + + def _auto(self): + contexts = iio.scan_contexts() + if len(contexts) == 0: + raise Exception("No IIO context found.\n") + if len(contexts) == 1: + uri, _ = contexts.popitem() + self.ctx = iio.Context(_context=uri) + else: + print("Multiple contexts found. Please select one using --uri!") + for uri, _ in contexts.items(): + print(uri) + sys.exit(0) + + return self + + def _uri(self): + self.ctx = iio.Context(_context=self.arguments.arg_uri) + return self + + def _default(self): + self.ctx = iio.Context() + return self + + def create(self): + """Create the requested context.""" + try: + if self.arguments.detect_context: + self._auto() + elif self.arguments.arg_uri: + self._uri() + else: + self._default() + except FileNotFoundError: + raise Exception("Unable to create IIO context!\n") + + return self.ctx + + +class Information: + """Class for receiving the requested information about the attributes.""" + + def __init__(self, arguments, context): + """ + Class constructor. + + Args: + arguments: type=Arguments + Contains the input arguments. + context: type=iio.Context + The created context. + """ + self.arguments = arguments + self.context = context + + def write_information(self): + """Write the requested information.""" + self._context_information() + + if self.arguments.search_device or self.arguments.search_channel or \ + self.arguments.search_buffer or self.arguments.search_debug: + self._devices_information() + + def _context_information(self): + if self.context is None: + print("Unable to create IIO context") + sys.exit(1) + + if self.arguments.search_context: + if self.arguments.attr is None and len(self.context.attrs) > 0: + print("IIO context with " + str(len(self.context.attrs)) + " attributes:") + + for key, value in self.context.attrs.items(): + if self.arguments.attr is None or \ + _str_match(key, self.arguments.attr, self.arguments.ignore_case): + print(key + ": " + value) + + def _devices_information(self): + if self.arguments.device is None: + print("IIO context has " + str(len(self.context.devices)) + " devices:") + + for dev in self.context.devices: + self._device_information(dev) + self._device_attributes_information(dev) + self._buffer_attributes_information(dev) + self._debug_attributes_information(dev) + + def _device_information(self, dev): + if self.arguments.device is not None and \ + not _str_match(dev.name, self.arguments.device, self.arguments.ignore_case): + return + + if self.arguments.device is None: + print("\t" + dev.id + ":", end="") + + if dev.name is not None: + print(" " + dev.name, end="") + + print(", ", end="") + + if self.arguments.search_channel and self.arguments.device is None: + print("found " + str(len(dev.channels)) + " channels") + + for channel in dev.channels: + self._channel_information(dev, channel) + + def _channel_information(self, dev, channel): + channel_stop = not self.arguments.search_channel or self.arguments.device is None + input_stop = self.arguments.input_only and channel.output + output_stop = self.arguments.output_only and not channel.output + scan_stop = self.arguments.scan_only and not channel.scan_element + + if channel_stop or input_stop or output_stop or scan_stop: + return + + type_name = "output" if channel.output else "input" + + if not _str_match(self.arguments.device, dev.name, self.arguments.ignore_case): + return + + if self.arguments.channel is not None and \ + not _str_match(channel.id, self.arguments.channel, self.arguments.ignore_case) and \ + (channel.name is None or (channel.name is not None and + not _str_match(channel.name, self.arguments.channel, + self.arguments.ignore_case))): + return + + if (not self.arguments.scan_only and self.arguments.channel is None) or \ + (self.arguments.scan_only and channel.scan_element): + print("dev \'" + dev.name + "\', channel \'" + channel.id + "\'", end="") + + if channel.name is not None: + print(", id \'" + channel.name + "\'", end="") + + print(" (" + type_name, end="") + + if channel.scan_element: + self._scan_channel_information(channel) + else: + print("), ", end="") + + self._channel_attributes_information(dev, channel) + + def _scan_channel_information(self, channel): + sign = "s" if channel.data_format.is_signed else "u" + if channel.data_format.is_fully_defined: + sign = sign.upper() + + if channel.data_format.repeat > 1: + print("X" + str(channel.data_format.repeat), end="") + + print(", index: " + str(channel.index) + ", format: " + + "b" if channel.data_format.is_be else "l" + + "e:" + sign + str(channel.data_format.bits) + + "/" + str(channel.data_format.length) + str(channel.data_format.repeat) + + ">>" + str(channel.data_format.shift)) + + print("" if self.arguments.scan_only else ", ", end="") + + def _channel_attributes_information(self, dev, channel): + if self.arguments.channel is None: + print("found " + str(len(channel.attrs)) + " channel-specific attributes") + + if len(channel.attrs) == 0 or self.arguments.channel is None: + return + + for key, _ in channel.attrs.items(): + if self.arguments.attr is not None and \ + not _str_match(key, self.arguments.attr, self.arguments.ignore_case): + continue + self._channel_attribute_information(dev, channel, key) + + def _channel_attribute_information(self, dev, channel, attr): + if self.arguments.buffer is None or not self.arguments.quiet: + type_name = "output" if channel.output else "input" + + if not self.arguments.quiet: + print("dev \'" + dev.name + "\', channel \'" + channel.id + "\' (" + type_name + "), ", end="") + + if channel.name is not None: + print("id \'" + channel.name + "\', ", end="") + + print("attr \'" + attr + "\', ", end="") + + try: + print(channel.attrs[attr].value if self.arguments.quiet else + "value \'" + channel.attrs[attr].value + "\'") + except OSError as err: + print("ERROR: " + err.strerror + " (-" + str(err.errno) + ")") + + if self.arguments.buffer is not None: + channel.attrs[attr].value = self.arguments.buffer + + if not self.arguments.quiet: + print("wrote " + str(len(self.arguments.buffer)) + " bytes to " + attr) + + self.arguments.buffer = None + self._channel_attribute_information(dev, channel, attr) + + def _device_attributes_information(self, dev): + if self.arguments.search_device and self.arguments.device is None: + print("found " + str(len(dev.attrs)) + " device attributes") + + if self.arguments.search_device and self.arguments.device is not None and len(dev.attrs) > 0: + for key, _ in dev.attrs.items(): + if self.arguments.attr is not None and \ + not _str_match(key, self.arguments.attr, self.arguments.ignore_case): + continue + + self._device_attribute_information(dev, key) + + def _device_attribute_information(self, dev, attr): + if self.arguments.buffer is None or not self.arguments.quiet: + if not self.arguments.quiet: + print("dev \'" + dev.name + "\', attr \'" + attr + "\', value: ", end="") + + try: + print(dev.attrs[attr].value if self.arguments.quiet else "\'" + dev.attrs[attr].value + "\'") + except OSError as err: + print("ERROR: " + err.strerror + " (-" + str(err.errno) + ")") + + if self.arguments.buffer is not None: + dev.attrs[attr].value = self.arguments.buffer + + if not self.arguments.quiet: + print("wrote " + str(len(self.arguments.buffer)) + " bytes to " + attr) + + self.arguments.buffer = None + self._device_attribute_information(dev, attr) + + def _buffer_attributes_information(self, dev): + if self.arguments.search_buffer and self.arguments.device is None: + print("found " + str(len(dev.buffer_attrs)) + " buffer attributes") + elif self.arguments.search_buffer and _str_match(self.arguments.device, dev.name, self.arguments.ignore_case) \ + and len(dev.buffer_attrs) > 0: + for key, _ in dev.buffer_attrs.items(): + if (self.arguments.attr is not None and + _str_match(key, self.arguments.attr, self.arguments.ignore_case)) or \ + self.arguments.attr is None: + self._buffer_attribute_information(dev, key) + + def _buffer_attribute_information(self, dev, attr): + if self.arguments.buffer is None or not self.arguments.quiet: + if not self.arguments.quiet: + print("dev \'" + dev.name + "\', buffer attr \'" + attr + "\', value: ", end="") + + try: + print(dev.buffer_attrs[attr].value if self.arguments.quiet else + "\'" + dev.buffer_attrs[attr].value + "\'") + except OSError as err: + print("ERROR: " + err.strerror + " (-" + str(err.errno) + ")") + + if self.arguments.buffer is not None: + dev.buffer_attrs[attr].value = self.arguments.buffer + + if not self.arguments.quiet: + print("wrote " + str(len(self.arguments.buffer)) + " bytes to " + attr) + + self.arguments.buffer = None + self._buffer_attribute_information(dev, attr) + + def _debug_attributes_information(self, dev): + if self.arguments.search_debug and self.arguments.device is None: + print("found " + str(len(dev.debug_attrs)) + " debug attributes") + elif self.arguments.search_debug and _str_match(self.arguments.device, dev.name, self.arguments.ignore_case) \ + and len(dev.debug_attrs) > 0: + for key, _ in dev.debug_attrs.items(): + if (self.arguments.attr is not None and _str_match(key, self.arguments.attr, self.arguments.quiet)) \ + or self.arguments.attr is None: + self._debug_attribute_information(dev, key) + + def _debug_attribute_information(self, dev, attr): + if self.arguments.buffer is None or not self.arguments.quiet: + if not self.arguments.quiet: + print("dev \'" + dev.name + "\', debug attr \'" + attr + "\', value: ", end="") + + try: + print(dev.debug_attrs[attr].value if self.arguments.quiet else + "\'" + dev.debug_attrs[attr].value + "\'") + except OSError as err: + print("ERROR: " + err.strerror + " (-" + str(err.errno) + ")") + + if self.arguments.buffer is not None: + dev.debug_attrs[attr].value = self.arguments.buffer + + if not self.arguments.quiet: + print("wrote " + str(len(self.arguments.buffer)) + " bytes to " + attr) + + self.arguments.buffer = None + self._debug_attribute_information(dev, attr) + + +def main(): + """Module's main method.""" + arguments = Arguments() + context_builder = ContextBuilder(arguments) + context = context_builder.create() + information = Information(arguments, context) + information.write_information() + + +if __name__ == "__main__": + main() diff --git a/Backup/iio_info.py b/Backup/iio_info.py new file mode 100755 index 0000000..f45eeb6 --- /dev/null +++ b/Backup/iio_info.py @@ -0,0 +1,209 @@ +#!/usr/bin/env python3 +""" +Hacked wildly by Bdale, merging bits of iio_attr.py until it works +Copyright 2025 Bdale Garbee + +Copyright (C) 2015 Analog Devices, Inc. +Author: Paul Cercueil + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +""" + +import sys +import argparse +import iio + +def _str_match(string, other_string, ignore_case): + if ignore_case: + string = string.lower() + other_string = other_string.lower() + + return string == other_string + + +class Arguments: + """Class for parsing the input arguments.""" + + def __init__(self): + """Arguments class constructor.""" + self.device = None + self.channel = None + self.attr = None + self.buffer = None + self.search_context = False + self.search_device = False + self.search_channel = False + self.search_buffer = False + self.search_debug = False + self.detect_context = None + self.arg_uri = None + self.input_only = None + self.output_only = None + self.scan_only = None + self.ignore_case = None + self.quiet = None + + def _read_arguments(self, args): + self.search_device = True + self.device = args.device_attr[0] if len(args.device_attr) >= 1 else None + self.attr = args.device_attr[1] if len(args.device_attr) >= 2 else None + self.buffer = args.device_attr[2] if len(args.device_attr) >= 3 else None + +class ContextBuilder: + """Class for creating the requested context.""" + + def __init__(self, arguments): + """ + Class constructor. + + Args: + arguments: type=Arguments + Contains the input arguments. + """ + self.ctx = None + self.arguments = arguments + + def _auto(self): + contexts = iio.scan_contexts() + if len(contexts) == 0: + raise Exception("No IIO context found.\n") + if len(contexts) == 1: + uri, _ = contexts.popitem() + self.ctx = iio.Context(_context=uri) + else: + print("Multiple contexts found. Please select one using --uri!") + for uri, _ in contexts.items(): + print(uri) + sys.exit(0) + + return self + + def _uri(self): +# self.ctx = iio.Context(_context=self.arguments.arg_uri) + self.ctx = None + return self + + def _default(self): + self.ctx = iio.Context() + return self + + def create(self): + """Create the requested context.""" + try: + if self.arguments.detect_context: + self._auto() + elif self.arguments.arg_uri: + self._uri() + else: + self._default() + except FileNotFoundError: + raise Exception("Unable to create IIO context!\n") + + return self.ctx + + +class Information: + """Class for retrieving the requested information.""" + + def __init__(self, context): + """ + Class constructor. + + Args: + context: type=iio.Context + Context used for retrieving the information. + """ + self.context = context + + def write_information(self): + """Write the information about the current context.""" + self._context_info() + + def _context_info(self): + print("IIO context created: " + self.context.name) + print("Backend version: %u.%u (git tag: %s" % self.context.version) + print("Backend description string: " + self.context.description) + + if len(self.context.attrs) > 0: + print("IIO context has %u attributes: " % len(self.context.attrs)) + + for attr, value in self.context.attrs.items(): + print("\t" + attr + ": " + value) + + print("IIO context has %u devices:" % len(self.context.devices)) + + for dev in self.context.devices: + self._device_info(dev) + + def _device_info(self, dev): + print("\t" + dev.id + ": " + dev.name) + + if dev is iio.Trigger: + print("Found trigger! Rate: %u HZ" % dev.frequency) + + print("\t\t%u channels found: " % len(dev.channels)) + for channel in dev.channels: + self._channel_info(channel) + + if len(dev.attrs) > 0: + print("\t\t%u device-specific attributes found: " % len(dev.attrs)) + for device_attr in dev.attrs: + self._device_attribute_info(dev, device_attr) + + if len(dev.debug_attrs) > 0: + print("\t\t%u debug attributes found: " % len(dev.debug_attrs)) + for debug_attr in dev.debug_attrs: + self._device_debug_attribute_info(dev, debug_attr) + + def _channel_info(self, channel): + print("\t\t\t%s: %s (%s)" % (channel.id, channel.name or "", "output" if channel.output else "input")) + if len(channel.attrs) > 0: + print("\t\t\t%u channel-specific attributes found: " % len(channel.attrs)) + for channel_attr in channel.attrs: + self._channel_attribute_info(channel, channel_attr) + + @staticmethod + def _channel_attribute_info(channel, channel_attr): + try: + print("\t\t\t\t" + channel_attr + ", value: " + channel.attrs[channel_attr].value) + except OSError as err: + print("Unable to read " + channel_attr + ": " + err.strerror) + + @staticmethod + def _device_attribute_info(dev, device_attr): + try: + print("\t\t\t" + device_attr + ", value: " + dev.attrs[device_attr].value) + except OSError as err: + print("Unable to read " + device_attr + ": " + err.strerror) + + @staticmethod + def _device_debug_attribute_info(dev, debug_attr): + try: + print("\t\t\t" + debug_attr + ", value: " + dev.debug_attrs[debug_attr].value) + except OSError as err: + print("Unable to read " + debug_attr + ": " + err.strerror) + + +def main(): + """Module's main method.""" + arguments = Arguments() + context_builder = ContextBuilder(arguments) + context = context_builder.create() + information = Information(context) + information.write_information() + + +if __name__ == "__main__": + main() diff --git a/Backup/iio_readdev.py b/Backup/iio_readdev.py new file mode 100755 index 0000000..86e4ad4 --- /dev/null +++ b/Backup/iio_readdev.py @@ -0,0 +1,246 @@ +#!/usr/bin/env python3 +""" +Copyright (C) 2020 Analog Devices, Inc. +Author: Cristian Iacob + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +""" + +import sys +import argparse +import iio + + +class Arguments: + """Class for parsing the input arguments.""" + + def __init__(self): + """Arguments class constructor.""" + self.parser = argparse.ArgumentParser(description="iio_readdev") + self._add_parser_arguments() + args = self.parser.parse_args() + + self.network = str(args.network) if args.network else None + self.arg_uri = str(args.uri) if args.uri else None + self.scan_for_context = args.auto + self.buffer_size = int(args.buffer_size) if args.buffer_size else 256 + self.num_samples = int(args.samples) if args.samples else 0 + self.timeout = int(args.timeout) if args.timeout else 0 + self.device_name = args.device[0] + self.channels = args.channel + + def _add_parser_arguments(self): + self.parser.add_argument( + "-n", + "--network", + type=str, + metavar="", + help="Use the network backend with the provided hostname.", + ) + self.parser.add_argument( + "-u", + "--uri", + type=str, + metavar="", + help="Use the context with the provided URI.", + ) + self.parser.add_argument( + "-b", + "--buffer-size", + type=int, + metavar="", + help="Size of the capture buffer. Default is 256.", + ) + self.parser.add_argument( + "-s", + "--samples", + type=int, + metavar="", + help="Number of samples to capture, 0 = infinite. Default is 0.", + ) + self.parser.add_argument( + "-T", + "--timeout", + type=int, + metavar="", + help="Buffer timeout in milliseconds. 0 = no timeout", + ) + self.parser.add_argument( + "-a", + "--auto", + action="store_true", + help="Scan for available contexts and if only one is available use it.", + ) + self.parser.add_argument("device", type=str, nargs=1) + self.parser.add_argument("channel", type=str, nargs="*") + + +class ContextBuilder: + """Class for creating the requested context.""" + + def __init__(self, arguments): + """ + Class constructor. + + Args: + arguments: type=Arguments + Contains the input arguments. + """ + self.ctx = None + self.arguments = arguments + + def _timeout(self): + if self.arguments.timeout >= 0: + self.ctx.timeout = self.arguments.timeout + return self + + def _auto(self): + contexts = iio.scan_contexts() + if len(contexts) == 0: + raise Exception("No IIO context found.\n") + if len(contexts) == 1: + uri, _ = contexts.popitem() + self.ctx = iio.Context(_context=uri) + else: + print("Multiple contexts found. Please select one using --uri!") + for uri, _ in contexts.items(): + print(uri) + sys.exit(0) + + return self + + def _uri(self): + self.ctx = iio.Context(_context=self.arguments.arg_uri) + return self + + def _network(self): + self.ctx = iio.NetworkContext(self.arguments.network) + return self + + def _default(self): + self.ctx = iio.Context() + return self + + def create(self): + """Create the requested context.""" + try: + if self.arguments.scan_for_context: + self._auto() + elif self.arguments.arg_uri: + self._uri() + else: + self._default() + except FileNotFoundError: + raise Exception("Unable to create IIO context!\n") + + self._timeout() + + return self.ctx + + +class BufferBuilder: + """Class for creating the buffer.""" + + def __init__(self, ctx, arguments): + """ + Class constructor. + + Args: + ctx: type=iio.Context + This buffer's context. + arguments: type=Arguments + Contains the input arguments. + """ + self.ctx = ctx + self.arguments = arguments + self.dev = None + + def _device(self): + self.dev = self.ctx.find_device(self.arguments.device_name) + + if self.dev is None: + raise Exception("Device %s not found!" % self.arguments.device_name) + + return self + + def _channels(self): + if len(self.arguments.channels) == 0: + for channel in self.dev.channels: + channel.enabled = True + else: + for channel_idx in self.arguments.channels: + self.dev.channels[int(channel_idx)].enabled = True + + return self + + def create(self): + """Create the IIO buffer.""" + self._device() + self._channels() + buffer = iio.Buffer(self.dev, self.arguments.buffer_size) + + if buffer is None: + raise Exception("Unable to create buffer!\n") + + return buffer + + +class DataReader: + """Class for reading samples from the device.""" + + def __init__(self, ctx, arguments): + """ + Class constructor. + + Args: + ctx: type=iio.Context + Current context. + arguments: type=Arguments + Contains the input arguments. + """ + buffer_builder = BufferBuilder(ctx, arguments) + self.buffer = buffer_builder.create() + self.device = buffer_builder.dev + self.arguments = arguments + + def read(self): + """Read data from the buffer.""" + while True: + self.buffer.refill() + samples = self.buffer.read() + + if self.arguments.num_samples > 0: + sys.stdout.buffer.write( + samples[: min(self.arguments.num_samples * self.device.sample_size, len(samples))] + ) + self.arguments.num_samples -= min( + self.arguments.num_samples, len(samples) + ) + + if self.arguments.num_samples == 0: + break + else: + sys.stdout.buffer.write(bytes(samples)) + + +def main(): + """Module's main method.""" + arguments = Arguments() + context_builder = ContextBuilder(arguments) + reader = DataReader(context_builder.create(), arguments) + reader.read() + +if __name__ == "__main__": + main() diff --git a/Backup/iio_writedev.py b/Backup/iio_writedev.py new file mode 100755 index 0000000..bb00904 --- /dev/null +++ b/Backup/iio_writedev.py @@ -0,0 +1,269 @@ +#!/usr/bin/env python +""" +Copyright (C) 2020 Analog Devices, Inc. +Author: Cristian Iacob + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +""" + +import time +import sys +import argparse +import iio + + +class Arguments: + """Class for parsing the input arguments.""" + + def __init__(self): + """Arguments class constructor.""" + self.parser = argparse.ArgumentParser(description="iio_writedev") + self._add_parser_arguments() + args = self.parser.parse_args() + + self.network = str(args.network) if args.network else None + self.arg_uri = str(args.uri) if args.uri else None + self.scan_for_context = args.auto + self.buffer_size = int(args.buffer_size) if args.buffer_size else 256 + self.num_samples = int(args.samples) if args.samples else 0 + self.timeout = int(args.timeout) if args.timeout else 0 + self.cyclic = args.cyclic + self.device_name = args.device[0] + self.channels = args.channel + + def _add_parser_arguments(self): + self.parser.add_argument( + "-n", + "--network", + type=str, + metavar="", + help="Use the network backend with the provided hostname.", + ) + self.parser.add_argument( + "-u", + "--uri", + type=str, + metavar="", + help="Use the context with the provided URI.", + ) + self.parser.add_argument( + "-b", + "--buffer-size", + type=int, + metavar="", + help="Size of the capture buffer. Default is 256.", + ) + self.parser.add_argument( + "-s", + "--samples", + type=int, + metavar="", + help="Number of samples to capture, 0 = infinite. Default is 0.", + ) + self.parser.add_argument( + "-T", + "--timeout", + type=int, + metavar="", + help="Buffer timeout in milliseconds. 0 = no timeout", + ) + self.parser.add_argument( + "-a", + "--auto", + action="store_true", + help="Scan for available contexts and if only one is available use it.", + ) + self.parser.add_argument( + "-c", "--cyclic", action="store_true", help="Use cyclic buffer mode." + ) + self.parser.add_argument("device", type=str, nargs=1) + self.parser.add_argument("channel", type=str, nargs="*") + + +class ContextBuilder: + """Class for creating the requested context.""" + + def __init__(self, arguments): + """ + Class constructor. + + Args: + arguments: type=Arguments + Contains the input arguments. + """ + self.ctx = None + self.arguments = arguments + + def _timeout(self): + if self.arguments.timeout >= 0: + self.ctx.timeout = self.arguments.timeout + return self + + def _auto(self): + contexts = iio.scan_contexts() + if len(contexts) == 0: + raise Exception("No IIO context found.\n") + if len(contexts) == 1: + uri, _ = contexts.popitem() + self.ctx = iio.Context(_context=uri) + else: + print("Multiple contexts found. Please select one using --uri!") + for uri, _ in contexts.items(): + print(uri) + sys.exit(0) + + return self + + def _uri(self): + self.ctx = iio.Context(_context=self.arguments.arg_uri) + return self + + def _network(self): + self.ctx = iio.NetworkContext(self.arguments.network) + return self + + def _default(self): + self.ctx = iio.Context() + return self + + def create(self): + """Create the requested context.""" + try: + if self.arguments.scan_for_context: + self._auto() + elif self.arguments.arg_uri: + self._uri() + elif self.arguments.arg_ip: + self._network() + else: + self._default() + except FileNotFoundError: + raise Exception("Unable to create IIO context!\n") + + self._timeout() + + return self.ctx + + +class BufferBuilder: + """Class for creating the buffer.""" + + def __init__(self, ctx, arguments): + """ + Class constructor. + + Args: + ctx: type=iio.Context + This buffer's context. + arguments: type=Arguments + Contains the input arguments. + """ + self.ctx = ctx + self.arguments = arguments + self.dev = None + + def _device(self): + self.dev = self.ctx.find_device(self.arguments.device_name) + + if self.dev is None: + raise Exception("Device %s not found!" % self.arguments.device_name) + + return self + + def _channels(self): + if len(self.arguments.channels) == 0: + for channel in self.dev.channels: + channel.enabled = True + else: + for channel_idx in self.arguments.channels: + self.dev.channels[int(channel_idx)].enabled = True + + return self + + def create(self): + """Create the IIO buffer.""" + self._device() + self._channels() + buffer = iio.Buffer(self.dev, self.arguments.buffer_size, self.arguments.cyclic) + + if buffer is None: + raise Exception("Unable to create buffer!\n") + + return buffer + + +class DataWriter: + """Class for writing samples to the device.""" + + def __init__(self, ctx, arguments): + """ + Class constructor. + + Args: + ctx: type=iio.Context + Current context. + arguments: type=Arguments + Contains the input arguments. + """ + buffer_builder = BufferBuilder(ctx, arguments) + self.buffer = buffer_builder.create() + self.device = buffer_builder.dev + self.arguments = arguments + + def write(self): + """Push data into the buffer.""" + app_running = True + num_samples = self.arguments.num_samples + + while app_running: + bytes_to_read = ( + len(self.buffer) + if num_samples == 0 + else min(len(self.buffer), num_samples * self.device.sample_size) + ) + write_len = bytes_to_read + data = [] + + while bytes_to_read > 0: + read_data = sys.stdin.buffer.read(bytes_to_read) + if len(read_data) == 0: + sys.exit(0) + bytes_to_read -= len(read_data) + data.extend(read_data) + + if self.buffer.write(bytearray(data)) == 0: + raise Exception("Unable to push buffer!") + + self.buffer.push() + + while app_running and self.arguments.cyclic: + time.sleep(1) + + if num_samples > 0: + num_samples -= write_len // self.device.sample_size + if num_samples == 0: + app_running = False + + +def main(): + """Module's main method.""" + arguments = Arguments() + context_builder = ContextBuilder(arguments) + writer = DataWriter(context_builder.create(), arguments) + writer.write() + + +if __name__ == "__main__": + main() diff --git a/Backup/quantimotor.py b/Backup/quantimotor.py new file mode 100755 index 0000000..9947382 --- /dev/null +++ b/Backup/quantimotor.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 +# Copyright (C) 2025 Bdale Garbee . GPLv3+ + +import gpiod +import iio +import signal +import sys +import time + +ctx = iio.LocalContext() +ctrl = ctx.find_device('ads8688') +# configuration for each channel on ADS8688 +OFFSET = "0" +SCALE = "0.078127104" +#VOLTAGES = ['voltage0', 'voltage1', 'voltage2', 'voltage3', 'voltage4', 'voltage5', 'voltage6', 'voltage7'] +VOLTAGES = ['voltage0', 'voltage1'] + +from gpiod.line import Direction, Value + +def handler(signum, frame): + print('Ctrl+C pressed, shutting down cleanly.') + set_line_values( + "/dev/gpiochip0", + { 4: Value.INACTIVE, # indicate 'not ready' to LPC + 16: Value.INACTIVE, # pyro off + 17: Value.INACTIVE, # alarm b off + 20: Value.INACTIVE, # turn continuity LED off + 21: Value.INACTIVE, # turn armed LED off + 25: Value.INACTIVE, # put ADS8688 in reset + 27: Value.INACTIVE # alarm a off + } + ) + exit(1) + +signal.signal(signal.SIGINT, handler) + +def set_line_values(chip_path, line_values): + value_str = {Value.ACTIVE: "Active", Value.INACTIVE: "Inactive"} + + request = gpiod.request_lines( + chip_path, + consumer=sys.argv[0], + config={ + tuple(line_values.keys()): gpiod.LineSettings(direction=Direction.OUTPUT) + }, + ) + request.set_values(line_values) + +if __name__ == "__main__": + try: + # initialize hardware + set_line_values( + "/dev/gpiochip0", + {25: Value.ACTIVE, # take ADS8688 out of reset + 4: Value.ACTIVE, # indicate 'ready' to LPC + 16: Value.ACTIVE, # pyro on + 17: Value.ACTIVE, # alarm b on + 20: Value.ACTIVE, # turn continuity LED on + 21: Value.INACTIVE, # turn armed LED off + 27: Value.ACTIVE # alarm a on + } + ) + + # configure ADC channels + for id in VOLTAGES: + chan = ctrl.find_channel(id) + chan.attrs['offset'].value = OFFSET + chan.attrs['scale'].value = SCALE + + # Iterate until ctrl/c + while True: + for id in VOLTAGES: + chan = ctrl.find_channel(id) + rawstring = chan.attrs['raw'].value + voltage = (float(rawstring) + float(OFFSET)) * float(SCALE) / 1000 + print("{0}: {1:0.3f}, ".format( chan.id, voltage), end="") + print() + time.sleep(1) + + except OSError as ex: + print(ex, "\nD'oh!") + diff --git a/Backup/setup.sh b/Backup/setup.sh new file mode 100755 index 0000000..0bbeb0a --- /dev/null +++ b/Backup/setup.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +sudo iio_attr -c iio:device0 voltage0 scale 0.078127104 +sudo iio_attr -c iio:device0 voltage0 offset 0 + +sudo iio_attr -c iio:device0 voltage1 scale 0.078127104 +sudo iio_attr -c iio:device0 voltage1 offset 0 + +sudo iio_attr -c iio:device0 voltage2 scale 0.078127104 +sudo iio_attr -c iio:device0 voltage2 offset 0 + +sudo iio_attr -c iio:device0 voltage3 scale 0.078127104 +sudo iio_attr -c iio:device0 voltage3 offset 0 + +sudo iio_attr -c iio:device0 voltage4 scale 0.078127104 +sudo iio_attr -c iio:device0 voltage4 offset 0 + +sudo iio_attr -c iio:device0 voltage5 scale 0.078127104 +sudo iio_attr -c iio:device0 voltage5 offset 0 + +sudo iio_attr -c iio:device0 voltage6 scale 0.078127104 +sudo iio_attr -c iio:device0 voltage6 offset 0 + +sudo iio_attr -c iio:device0 voltage7 scale 0.078127104 +sudo iio_attr -c iio:device0 voltage7 offset 0 + diff --git a/Backup/simpleread.py b/Backup/simpleread.py new file mode 100755 index 0000000..0739714 --- /dev/null +++ b/Backup/simpleread.py @@ -0,0 +1,22 @@ +#! /usr/bin/python3 + +import time, iio + +ctx = iio.LocalContext() +ctrl = ctx.find_device('ads8688') + +# configuration for each channel on ADS8688 +OFFSET = "0" +SCALE = "0.078127104" + +voltages = ['voltage0', 'voltage1', 'voltage2', 'voltage3'] +for id in voltages: + chan = ctrl.find_channel(id) + + chan.attrs['offset'].value = OFFSET + chan.attrs['scale'].value = SCALE + + rawstring = chan.attrs['raw'].value + voltage = (float(rawstring) + float(OFFSET)) * float(SCALE) / 1000 + print("{0}.raw:\t{1}".format( chan.id, rawstring) ) + print("{0}.voltage:\t {1}".format( chan.id, voltage) ) diff --git a/Backup/snippet.py b/Backup/snippet.py new file mode 100644 index 0000000..141be67 --- /dev/null +++ b/Backup/snippet.py @@ -0,0 +1,10 @@ +import iio + +for ctxname in iio.scan_contexts(): + ctx = iio.Context(ctxname) + for dev in ctx.devices: + if dev.channels: + for chan in dev.channels: + print("{} - {} - {}".format(ctxname, dev.name, chan._id)) + else: + print("{} - {}".format(ctxname, dev.name)) diff --git a/Backup/toggle_line_value.py b/Backup/toggle_line_value.py new file mode 100755 index 0000000..3c51910 --- /dev/null +++ b/Backup/toggle_line_value.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-FileCopyrightText: 2023 Kent Gibson + +"""Minimal example of toggling a single line.""" + +import gpiod +import time + +from gpiod.line import Direction, Value + + +def toggle_value(value): + if value == Value.INACTIVE: + return Value.ACTIVE + return Value.INACTIVE + + +def toggle_line_value(chip_path, line_offset): + value_str = {Value.ACTIVE: "Active", Value.INACTIVE: "Inactive"} + value = Value.ACTIVE + + with gpiod.request_lines( + chip_path, + consumer="toggle-line-value", + config={ + line_offset: gpiod.LineSettings( + direction=Direction.OUTPUT, output_value=value + ) + }, + ) as request: + while True: + print("{}={}".format(line_offset, value_str[value])) + time.sleep(1) + value = toggle_value(value) + request.set_value(line_offset, value) + + +if __name__ == "__main__": + try: + toggle_line_value("/dev/gpiochip0", 20) + except OSError as ex: + print(ex, "\nCustomise the example configuration to suit your situation") diff --git a/Backup/toggle_multiple_line_values.py b/Backup/toggle_multiple_line_values.py new file mode 100755 index 0000000..3f0dea8 --- /dev/null +++ b/Backup/toggle_multiple_line_values.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-FileCopyrightText: 2023 Kent Gibson + +"""Minimal example of toggling multiple lines.""" + +import gpiod +import time + +from gpiod.line import Direction, Value + + +def toggle_value(value): + if value == Value.INACTIVE: + return Value.ACTIVE + return Value.INACTIVE + + +def toggle_multiple_line_values(chip_path, line_values): + value_str = {Value.ACTIVE: "Active", Value.INACTIVE: "Inactive"} + + request = gpiod.request_lines( + chip_path, + consumer="toggle-multiple-line-values", + config={ + tuple(line_values.keys()): gpiod.LineSettings(direction=Direction.OUTPUT) + }, + output_values=line_values, + ) + + while True: + print( + " ".join("{}={}".format(l, value_str[v]) for (l, v) in line_values.items()) + ) + time.sleep(5) + for l, v in line_values.items(): + line_values[l] = toggle_value(v) + request.set_values(line_values) + + +if __name__ == "__main__": + try: + toggle_multiple_line_values( + "/dev/gpiochip0", {25: Value.ACTIVE, 4: Value.ACTIVE, 20: Value.ACTIVE, 21: Value.INACTIVE} + ) + except OSError as ex: + print(ex, "\nCustomise the example configuration to suit your situation")