pax_global_header00006660000000000000000000000064144337170660014525gustar00rootroot0000000000000052 comment=117f1f19f08a2c6edd11ef0281586ba5301dd649 adafruit-Adafruit_Python_PureIO-117f1f1/000077500000000000000000000000001443371706600201755ustar00rootroot00000000000000adafruit-Adafruit_Python_PureIO-117f1f1/.github/000077500000000000000000000000001443371706600215355ustar00rootroot00000000000000adafruit-Adafruit_Python_PureIO-117f1f1/.github/ISSUE_TEMPLATE.md000066400000000000000000000053031443371706600242430ustar00rootroot00000000000000 Thank you for opening an issue on an Adafruit Python library repository. To improve the speed of resolution please review the following guidelines and common troubleshooting steps below before creating the issue: - **Do not use GitHub issues for troubleshooting projects and issues.** Instead use the forums at http://forums.adafruit.com to ask questions and troubleshoot why something isn't working as expected. In many cases the problem is a common issue that you will more quickly receive help from the forum community. GitHub issues are meant for known defects in the code. If you don't know if there is a defect in the code then start with troubleshooting on the forum first. - **If following a tutorial or guide be sure you didn't miss a step.** Carefully check all of the steps and commands to run have been followed. Consult the forum if you're unsure or have questions about steps in a guide/tutorial. - **For Python/Raspberry Pi projects check these very common issues to ensure they don't apply**: - If you are receiving an **ImportError: No module named...** error then a library the code depends on is not installed. Check the tutorial/guide or README to ensure you have installed the necessary libraries. Usually the missing library can be installed with the `pip` tool, but check the tutorial/guide for the exact command. - **Be sure you are supplying adequate power to the board.** Check the specs of your board and power in an external power supply. In many cases just plugging a board into your computer is not enough to power it and other peripherals. - **Double check all soldering joints and connections.** Flakey connections cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints. If you're sure this issue is a defect in the code and checked the steps above please fill in the following fields to provide enough troubleshooting information. You may delete the guideline and text above to just leave the following details: - Platform/operating system (i.e. Raspberry Pi with Raspbian operating system, Windows 32-bit, Windows 64-bit, Mac OSX 64-bit, etc.): **INSERT PLATFORM/OPERATING SYSTEM HERE** - Python version (run `python -version` or `python3 -version`): **INSERT PYTHON VERSION HERE** - Error message you are receiving, including any Python exception traces: **INSERT ERROR MESAGE/EXCEPTION TRACES HERE*** - List the steps to reproduce the problem below (if possible attach code or commands to run): **LIST REPRO STEPS BELOW** adafruit-Adafruit_Python_PureIO-117f1f1/.github/PULL_REQUEST_TEMPLATE.md000066400000000000000000000027401443371706600253410ustar00rootroot00000000000000 Thank you for creating a pull request to contribute to Adafruit's GitHub code! Before you open the request please review the following guidelines and tips to help it be more easily integrated: - **Describe the scope of your change--i.e. what the change does and what parts of the code were modified.** This will help us understand any risks of integrating the code. - **Describe any known limitations with your change.** For example if the change doesn't apply to a supported platform of the library please mention it. - **Please run any tests or examples that can exercise your modified code.** We strive to not break users of the code and running tests/examples helps with this process. Thank you again for contributing! We will try to test and integrate the change as soon as we can, but be aware we have many GitHub repositories to manage and can't immediately respond to every request. There is no need to bump or check in on a pull request (it will clutter the discussion of the request). Also don't be worried if the request is closed or not integrated--sometimes the priorities of Adafruit's GitHub code (education, ease of use) might not match the priorities of the pull request. Don't fret, the open source community thrives on forks and GitHub makes it easy to keep your changes in a forked repo. After reviewing the guidelines above you can delete this text from the pull request. adafruit-Adafruit_Python_PureIO-117f1f1/.github/workflows/000077500000000000000000000000001443371706600235725ustar00rootroot00000000000000adafruit-Adafruit_Python_PureIO-117f1f1/.github/workflows/build.yml000066400000000000000000000034771443371706600254270ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries # # SPDX-License-Identifier: MIT name: Build CI on: [pull_request, push] jobs: test: runs-on: ubuntu-latest steps: - name: Translate Repo Name For Build Tools filename_prefix id: repo-name run: echo "repo-name=Adafruit-PureIO" >> $GITHUB_OUTPUT - name: Set up Python 3.x uses: actions/setup-python@v4 with: python-version: '3.x' - name: Versions run: | python3 --version - name: Checkout Current Repo uses: actions/checkout@v3 with: submodules: true - name: Checkout tools repo uses: actions/checkout@v3 with: repository: adafruit/actions-ci-circuitpython-libs path: actions-ci - name: Install dependencies # (e.g. - apt-get: gettext, etc; pip: circuitpython-build-tools, requirements.txt; etc.) run: | source actions-ci/install.sh - name: Pip install pre-commit & Sphinx run: | pip install --force-reinstall pre-commit Sphinx sphinx-rtd-theme - name: Library version run: git describe --dirty --always --tags - name: Run pre-commit run: pre-commit run --all-files - name: Build docs working-directory: docs run: sphinx-build -E -W -b html . _build/html - name: Check For pyproject.toml id: need-pypi run: | echo pyproject-toml=$( find . -wholename './pyproject.toml' ) >> $GITHUB_OUTPUT - name: Build Python package if: contains(steps.need-pypi.outputs.pyproject-toml, 'pyproject.toml') run: | pip install --upgrade build twine find -type f -not -path "./.*" -not -path "./docs*" \( -name "*.py" -o -name "*.toml" \) -exec sed -i -e "s/0.0.0+auto.0/1.2.3/" {} + python -m build twine check dist/* adafruit-Adafruit_Python_PureIO-117f1f1/.github/workflows/release.yml000066400000000000000000000023731443371706600257420ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries # # SPDX-License-Identifier: MIT name: Release Actions on: release: types: [published] jobs: upload-pypi: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Check For pyproject.toml id: need-pypi run: | echo pyproject-toml=$( find . -wholename './pyproject.toml' ) >> $GITHUB_OUTPUT - name: Set up Python if: contains(steps.need-pypi.outputs.pyproject-toml, 'pyproject.toml') uses: actions/setup-python@v4 with: python-version: '3.x' - name: Install dependencies if: contains(steps.need-pypi.outputs.pyproject-toml, 'pyproject.toml') run: | python -m pip install --upgrade pip pip install --upgrade build twine - name: Build and publish if: contains(steps.need-pypi.outputs.pyproject-toml, 'pyproject.toml') env: TWINE_USERNAME: ${{ secrets.pypi_username }} TWINE_PASSWORD: ${{ secrets.pypi_password }} run: | find -type f -not -path "./.*" -not -path "./docs*" \( -name "*.py" -o -name "*.toml" \) -exec sed -i -e "s/0.0.0+auto.0/${{github.event.release.tag_name}}/" {} + python -m build twine upload dist/* adafruit-Adafruit_Python_PureIO-117f1f1/.gitignore000066400000000000000000000016061443371706600221700ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries # # SPDX-License-Identifier: MIT setuptools-* # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python env/ build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ *.egg-info/ .installed.cfg *.egg # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *,cover .hypothesis/ # Translations *.mo *.pot # Django stuff: *.log # Sphinx documentation docs/_build/ # PyBuilder target/ #Ipython Notebook .ipynb_checkpoints .DS_STORE adafruit-Adafruit_Python_PureIO-117f1f1/.pre-commit-config.yaml000066400000000000000000000023261443371706600244610ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2020 Diego Elio Pettenò # # SPDX-License-Identifier: Unlicense repos: - repo: https://github.com/python/black rev: 23.3.0 hooks: - id: black - repo: https://github.com/fsfe/reuse-tool rev: v1.1.2 hooks: - id: reuse - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 hooks: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/pycqa/pylint rev: v2.17.4 hooks: - id: pylint name: pylint (library code) types: [python] args: - --disable=consider-using-f-string exclude: "^(docs/|examples/|tests/|setup.py$)" - id: pylint name: pylint (example code) description: Run pylint rules on "examples/*.py" files types: [python] files: "^examples/" args: - --disable=missing-docstring,invalid-name,consider-using-f-string,duplicate-code - id: pylint name: pylint (test code) description: Run pylint rules on "tests/*.py" files types: [python] files: "^tests/" args: - --disable=missing-docstring,consider-using-f-string,duplicate-code adafruit-Adafruit_Python_PureIO-117f1f1/.pylintrc000066400000000000000000000515541443371706600220540ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries # # SPDX-License-Identifier: MIT [MAIN] # Analyse import fallback blocks. This can be used to support both Python 2 and # 3 compatible code, which means that the block might have code that exists # only in one or another interpreter, leading to false positives when analysed. analyse-fallback-blocks=no # Clear in-memory caches upon conclusion of linting. Useful if running pylint # in a server-like mode. clear-cache-post-run=no # Load and enable all available extensions. Use --list-extensions to see a list # all available extensions. #enable-all-extensions= # In error mode, messages with a category besides ERROR or FATAL are # suppressed, and no reports are done by default. Error mode is compatible with # disabling specific errors. #errors-only= # Always return a 0 (non-error) status code, even if lint errors are found. # This is primarily useful in continuous integration scripts. #exit-zero= # A comma-separated list of package or module names from where C extensions may # be loaded. Extensions are loading into the active Python interpreter and may # run arbitrary code. extension-pkg-allow-list= # A comma-separated list of package or module names from where C extensions may # be loaded. Extensions are loading into the active Python interpreter and may # run arbitrary code. (This is an alternative name to extension-pkg-allow-list # for backward compatibility.) extension-pkg-whitelist= # Return non-zero exit code if any of these messages/categories are detected, # even if score is above --fail-under value. Syntax same as enable. Messages # specified are enabled, while categories only check already-enabled messages. fail-on= # Specify a score threshold under which the program will exit with error. fail-under=10 # Interpret the stdin as a python script, whose filename needs to be passed as # the module_or_package argument. #from-stdin= # Files or directories to be skipped. They should be base names, not paths. ignore=CVS # Add files or directories matching the regular expressions patterns to the # ignore-list. The regex matches against paths and can be in Posix or Windows # format. Because '\\' represents the directory delimiter on Windows systems, # it can't be used as an escape character. ignore-paths= # Files or directories matching the regular expression patterns are skipped. # The regex matches against base names, not paths. The default value ignores # Emacs file locks ignore-patterns=^\.# # List of module names for which member attributes should not be checked # (useful for modules/projects where namespaces are manipulated during runtime # and thus existing member attributes cannot be deduced by static analysis). It # supports qualified module names, as well as Unix pattern matching. ignored-modules= # Python code to execute, usually for sys.path manipulation such as # pygtk.require(). #init-hook= # Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the # number of processors available to use, and will cap the count on Windows to # avoid hangs. jobs=1 # Control the amount of potential inferred values when inferring a single # object. This can help the performance when dealing with large functions or # complex, nested conditions. limit-inference-results=100 # List of plugins (as comma separated values of python module names) to load, # usually to register additional checkers. load-plugins= # Pickle collected data for later comparisons. persistent=yes # Minimum Python version to use for version dependent checks. Will default to # the version used to run pylint. py-version=3.11 # Discover python modules and packages in the file system subtree. recursive=no # Add paths to the list of the source roots. Supports globbing patterns. The # source root is an absolute path or a path relative to the current working # directory used to determine a package namespace for modules located under the # source root. source-roots= # When enabled, pylint would attempt to guess common misconfiguration and emit # user-friendly hints instead of false-positive error messages. suggestion-mode=yes # Allow loading of arbitrary C extensions. Extensions are imported into the # active Python interpreter and may run arbitrary code. unsafe-load-any-extension=no # In verbose mode, extra non-checker-related info will be displayed. #verbose= [BASIC] # Naming style matching correct argument names. argument-naming-style=snake_case # Regular expression matching correct argument names. Overrides argument- # naming-style. If left empty, argument names will be checked with the set # naming style. #argument-rgx= # Naming style matching correct attribute names. attr-naming-style=snake_case # Regular expression matching correct attribute names. Overrides attr-naming- # style. If left empty, attribute names will be checked with the set naming # style. #attr-rgx= # Bad variable names which should always be refused, separated by a comma. bad-names=foo, bar, baz, toto, tutu, tata # Bad variable names regexes, separated by a comma. If names match any regex, # they will always be refused bad-names-rgxs= # Naming style matching correct class attribute names. class-attribute-naming-style=any # Regular expression matching correct class attribute names. Overrides class- # attribute-naming-style. If left empty, class attribute names will be checked # with the set naming style. #class-attribute-rgx= # Naming style matching correct class constant names. class-const-naming-style=UPPER_CASE # Regular expression matching correct class constant names. Overrides class- # const-naming-style. If left empty, class constant names will be checked with # the set naming style. #class-const-rgx= # Naming style matching correct class names. class-naming-style=PascalCase # Regular expression matching correct class names. Overrides class-naming- # style. If left empty, class names will be checked with the set naming style. #class-rgx= # Naming style matching correct constant names. const-naming-style=UPPER_CASE # Regular expression matching correct constant names. Overrides const-naming- # style. If left empty, constant names will be checked with the set naming # style. #const-rgx= # Minimum line length for functions/classes that require docstrings, shorter # ones are exempt. docstring-min-length=-1 # Naming style matching correct function names. function-naming-style=snake_case # Regular expression matching correct function names. Overrides function- # naming-style. If left empty, function names will be checked with the set # naming style. #function-rgx= # Good variable names which should always be accepted, separated by a comma. good-names=i, j, k, ex, Run, _ # Good variable names regexes, separated by a comma. If names match any regex, # they will always be accepted good-names-rgxs= # Include a hint for the correct naming format with invalid-name. include-naming-hint=no # Naming style matching correct inline iteration names. inlinevar-naming-style=any # Regular expression matching correct inline iteration names. Overrides # inlinevar-naming-style. If left empty, inline iteration names will be checked # with the set naming style. #inlinevar-rgx= # Naming style matching correct method names. method-naming-style=snake_case # Regular expression matching correct method names. Overrides method-naming- # style. If left empty, method names will be checked with the set naming style. #method-rgx= # Naming style matching correct module names. module-naming-style=snake_case # Regular expression matching correct module names. Overrides module-naming- # style. If left empty, module names will be checked with the set naming style. #module-rgx= # Colon-delimited sets of names that determine each other's naming style when # the name regexes allow several styles. name-group= # Regular expression which should only match function or class names that do # not require a docstring. no-docstring-rgx=^_ # List of decorators that produce properties, such as abc.abstractproperty. Add # to this list to register other decorators that produce valid properties. # These decorators are taken in consideration only for invalid-name. property-classes=abc.abstractproperty # Regular expression matching correct type alias names. If left empty, type # alias names will be checked with the set naming style. #typealias-rgx= # Regular expression matching correct type variable names. If left empty, type # variable names will be checked with the set naming style. #typevar-rgx= # Naming style matching correct variable names. variable-naming-style=snake_case # Regular expression matching correct variable names. Overrides variable- # naming-style. If left empty, variable names will be checked with the set # naming style. #variable-rgx= [CLASSES] # Warn about protected attribute access inside special methods check-protected-access-in-special-methods=no # List of method names used to declare (i.e. assign) instance attributes. defining-attr-methods=__init__, __new__, setUp, asyncSetUp, __post_init__ # List of member names, which should be excluded from the protected access # warning. exclude-protected=_asdict,_fields,_replace,_source,_make,os._exit # List of valid names for the first argument in a class method. valid-classmethod-first-arg=cls # List of valid names for the first argument in a metaclass class method. valid-metaclass-classmethod-first-arg=mcs [DESIGN] # List of regular expressions of class ancestor names to ignore when counting # public methods (see R0903) exclude-too-few-public-methods= # List of qualified class names to ignore when counting class parents (see # R0901) ignored-parents= # Maximum number of arguments for function / method. max-args=5 # Maximum number of attributes for a class (see R0902). max-attributes=7 # Maximum number of boolean expressions in an if statement (see R0916). max-bool-expr=5 # Maximum number of branch for function / method body. max-branches=12 # Maximum number of locals for function / method body. max-locals=15 # Maximum number of parents for a class (see R0901). max-parents=7 # Maximum number of public methods for a class (see R0904). max-public-methods=20 # Maximum number of return / yield for function / method body. max-returns=6 # Maximum number of statements in function / method body. max-statements=50 # Minimum number of public methods for a class (see R0903). min-public-methods=2 [EXCEPTIONS] # Exceptions that will emit a warning when caught. overgeneral-exceptions=builtins.BaseException,builtins.Exception [FORMAT] # Expected format of line ending, e.g. empty (any line ending), LF or CRLF. expected-line-ending-format= # Regexp for a line that is allowed to be longer than the limit. ignore-long-lines=^\s*(# )??$ # Number of spaces of indent required inside a hanging or continued line. indent-after-paren=4 # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 # tab). indent-string=' ' # Maximum number of characters on a single line. max-line-length=100 # Maximum number of lines in a module. max-module-lines=1000 # Allow the body of a class to be on the same line as the declaration if body # contains single statement. single-line-class-stmt=no # Allow the body of an if to be on the same line as the test if there is no # else. single-line-if-stmt=no [IMPORTS] # List of modules that can be imported at any level, not just the top level # one. allow-any-import-level= # Allow explicit reexports by alias from a package __init__. allow-reexport-from-package=no # Allow wildcard imports from modules that define __all__. allow-wildcard-with-all=no # Deprecated modules which should not be used, separated by a comma. deprecated-modules= # Output a graph (.gv or any supported image format) of external dependencies # to the given file (report RP0402 must not be disabled). ext-import-graph= # Output a graph (.gv or any supported image format) of all (i.e. internal and # external) dependencies to the given file (report RP0402 must not be # disabled). import-graph= # Output a graph (.gv or any supported image format) of internal dependencies # to the given file (report RP0402 must not be disabled). int-import-graph= # Force import order to recognize a module as part of the standard # compatibility libraries. known-standard-library= # Force import order to recognize a module as part of a third party library. known-third-party=enchant # Couples of modules and preferred modules, separated by a comma. preferred-modules= [LOGGING] # The type of string formatting that logging methods do. `old` means using % # formatting, `new` is for `{}` formatting. logging-format-style=old # Logging modules to check that the string format arguments are in logging # function parameter format. logging-modules=logging [MESSAGES CONTROL] # Only show warnings with the listed confidence levels. Leave empty to show # all. Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE, # UNDEFINED. confidence=HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE, UNDEFINED # Disable the message, report, category or checker with the given id(s). You # can either give multiple identifiers separated by comma (,) or put this # option multiple times (only on the command line, not in the configuration # file where it should appear only once). You can also use "--disable=all" to # disable everything first and then re-enable specific checks. For example, if # you want to run only the similarities checker, you can use "--disable=all # --enable=similarities". If you want to run only the classes checker, but have # no Warning level messages displayed, use "--disable=all --enable=classes # --disable=W". disable=raw-checker-failed, bad-inline-option, locally-disabled, file-ignored, suppressed-message, useless-suppression, deprecated-pragma, use-symbolic-message-instead, invalid-name, import-error # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option # multiple time (only on the command line, not in the configuration file where # it should appear only once). See also the "--disable" option for examples. enable=c-extension-no-member [METHOD_ARGS] # List of qualified names (i.e., library.method) which require a timeout # parameter e.g. 'requests.api.get,requests.api.post' timeout-methods=requests.api.delete,requests.api.get,requests.api.head,requests.api.options,requests.api.patch,requests.api.post,requests.api.put,requests.api.request [MISCELLANEOUS] # List of note tags to take in consideration, separated by a comma. notes=FIXME, XXX, TODO # Regular expression of note tags to take in consideration. notes-rgx= [REFACTORING] # Maximum number of nested blocks for function / method body max-nested-blocks=5 # Complete name of functions that never returns. When checking for # inconsistent-return-statements if a never returning function is called then # it will be considered as an explicit return statement and no message will be # printed. never-returning-functions=sys.exit,argparse.parse_error [REPORTS] # Python expression which should return a score less than or equal to 10. You # have access to the variables 'fatal', 'error', 'warning', 'refactor', # 'convention', and 'info' which contain the number of messages in each # category, as well as 'statement' which is the total number of statements # analyzed. This score is used by the global evaluation report (RP0004). evaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)) # Template used to display messages. This is a python new-style format string # used to format the message information. See doc for all details. msg-template= # Set the output format. Available formats are text, parseable, colorized, json # and msvs (visual studio). You can also give a reporter class, e.g. # mypackage.mymodule.MyReporterClass. #output-format= # Tells whether to display a full report or only the messages. reports=no # Activate the evaluation score. score=yes [SIMILARITIES] # Comments are removed from the similarity computation ignore-comments=yes # Docstrings are removed from the similarity computation ignore-docstrings=yes # Imports are removed from the similarity computation ignore-imports=yes # Signatures are removed from the similarity computation ignore-signatures=yes # Minimum lines number of a similarity. min-similarity-lines=4 [SPELLING] # Limits count of emitted suggestions for spelling mistakes. max-spelling-suggestions=4 # Spelling dictionary name. No available dictionaries : You need to install # both the python package and the system dependency for enchant to work.. spelling-dict= # List of comma separated words that should be considered directives if they # appear at the beginning of a comment and should not be checked. spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy: # List of comma separated words that should not be checked. spelling-ignore-words= # A path to a file that contains the private dictionary; one word per line. spelling-private-dict-file= # Tells whether to store unknown words to the private dictionary (see the # --spelling-private-dict-file option) instead of raising a message. spelling-store-unknown-words=no [STRING] # This flag controls whether inconsistent-quotes generates a warning when the # character used as a quote delimiter is used inconsistently within a module. check-quote-consistency=no # This flag controls whether the implicit-str-concat should generate a warning # on implicit string concatenation in sequences defined over several lines. check-str-concat-over-line-jumps=no [TYPECHECK] # List of decorators that produce context managers, such as # contextlib.contextmanager. Add to this list to register other decorators that # produce valid context managers. contextmanager-decorators=contextlib.contextmanager # List of members which are set dynamically and missed by pylint inference # system, and so shouldn't trigger E1101 when accessed. Python regular # expressions are accepted. generated-members= # Tells whether to warn about missing members when the owner of the attribute # is inferred to be None. ignore-none=yes # This flag controls whether pylint should warn about no-member and similar # checks whenever an opaque object is returned when inferring. The inference # can return multiple potential results while evaluating a Python object, but # some branches might not be evaluated, which results in partial inference. In # that case, it might be useful to still emit no-member and other checks for # the rest of the inferred objects. ignore-on-opaque-inference=yes # List of symbolic message names to ignore for Mixin members. ignored-checks-for-mixins=no-member, not-async-context-manager, not-context-manager, attribute-defined-outside-init # List of class names for which member attributes should not be checked (useful # for classes with dynamically set attributes). This supports the use of # qualified names. ignored-classes=optparse.Values,thread._local,_thread._local,argparse.Namespace # Show a hint with possible names when a member name was not found. The aspect # of finding the hint is based on edit distance. missing-member-hint=yes # The minimum edit distance a name should have in order to be considered a # similar match for a missing member name. missing-member-hint-distance=1 # The total number of similar names that should be taken in consideration when # showing a hint for a missing member. missing-member-max-choices=1 # Regex pattern to define which classes are considered mixins. mixin-class-rgx=.*[Mm]ixin # List of decorators that change the signature of a decorated function. signature-mutators= [VARIABLES] # List of additional names supposed to be defined in builtins. Remember that # you should avoid defining new builtins when possible. additional-builtins= # Tells whether unused global variables should be treated as a violation. allow-global-unused-variables=yes # List of names allowed to shadow builtins allowed-redefined-builtins= # List of strings which can identify a callback function by name. A callback # name must start or end with one of those strings. callbacks=cb_, _cb # A regular expression matching the name of dummy variables (i.e. expected to # not be used). dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ # Argument names that match this expression will be ignored. ignored-argument-names=_.*|^ignored_|^unused_ # Tells whether we should check for unused import in __init__ files. init-import=no # List of qualified module names which can have objects that can redefine # builtins. redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io adafruit-Adafruit_Python_PureIO-117f1f1/Adafruit_PureIO/000077500000000000000000000000001443371706600231575ustar00rootroot00000000000000adafruit-Adafruit_Python_PureIO-117f1f1/Adafruit_PureIO/__init__.py000066400000000000000000000001611443371706600252660ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries # # SPDX-License-Identifier: MIT adafruit-Adafruit_Python_PureIO-117f1f1/Adafruit_PureIO/smbus.py000066400000000000000000000350301443371706600246630ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2016 Tony DiCola for Adafruit Industries # # SPDX-License-Identifier: MIT """ `Adafruit_PureIO.smbus` ================================================================================ Pure python (i.e. no native extensions) access to Linux IO I2C interface that mimics the Python SMBus API. * Author(s): Tony DiCola, Lady Ada, Melissa LeBlanc-Williams Implementation Notes -------------------- **Software and Dependencies:** * Linux and Python 3.5 or Higher """ from ctypes import c_uint8, c_uint16, c_uint32, cast, pointer, POINTER from ctypes import create_string_buffer, Structure from fcntl import ioctl import struct # pylint: disable=fixme # I2C C API constants (from linux kernel headers) I2C_M_TEN = 0x0010 # this is a ten bit chip address I2C_M_RD = 0x0001 # read data, from slave to master I2C_M_STOP = 0x8000 # if I2C_FUNC_PROTOCOL_MANGLING I2C_M_NOSTART = 0x4000 # if I2C_FUNC_NOSTART I2C_M_REV_DIR_ADDR = 0x2000 # if I2C_FUNC_PROTOCOL_MANGLING I2C_M_IGNORE_NAK = 0x1000 # if I2C_FUNC_PROTOCOL_MANGLING I2C_M_NO_RD_ACK = 0x0800 # if I2C_FUNC_PROTOCOL_MANGLING I2C_M_RECV_LEN = 0x0400 # length will be first received byte I2C_SLAVE = 0x0703 # Use this slave address I2C_SLAVE_FORCE = 0x0706 # Use this slave address, even if # is already in use by a driver! I2C_TENBIT = 0x0704 # 0 for 7 bit addrs, != 0 for 10 bit I2C_FUNCS = 0x0705 # Get the adapter functionality mask I2C_RDWR = 0x0707 # Combined R/W transfer (one STOP only) I2C_PEC = 0x0708 # != 0 to use PEC with SMBus I2C_SMBUS = 0x0720 # SMBus transfer # ctypes versions of I2C structs defined by kernel. # Tone down pylint for the Python classes that mirror C structs. # pylint: disable=invalid-name,too-few-public-methods class i2c_msg(Structure): """Linux i2c_msg struct.""" _fields_ = [ ("addr", c_uint16), ("flags", c_uint16), ("len", c_uint16), ("buf", POINTER(c_uint8)), ] class i2c_rdwr_ioctl_data(Structure): # pylint: disable=invalid-name """Linux i2c data struct.""" _fields_ = [("msgs", POINTER(i2c_msg)), ("nmsgs", c_uint32)] # pylint: enable=invalid-name,too-few-public-methods # pylint: disable=attribute-defined-outside-init def make_i2c_rdwr_data(messages): """Utility function to create and return an i2c_rdwr_ioctl_data structure populated with a list of specified I2C messages. The messages parameter should be a list of tuples which represent the individual I2C messages to send in this transaction. Tuples should contain 4 elements: address value, flags value, buffer length, ctypes c_uint8 pointer to buffer. """ # Create message array and populate with provided data. msg_data_type = i2c_msg * len(messages) msg_data = msg_data_type() for i, message in enumerate(messages): msg_data[i].addr = message[0] & 0x7F msg_data[i].flags = message[1] msg_data[i].len = message[2] msg_data[i].buf = message[3] # Now build the data structure. data = i2c_rdwr_ioctl_data() data.msgs = msg_data data.nmsgs = len(messages) return data # pylint: enable=attribute-defined-outside-init # Create an interface that mimics the Python SMBus API. class SMBus: """I2C interface that mimics the Python SMBus API but is implemented with pure Python calls to ioctl and direct /dev/i2c device access. """ def __init__(self, bus=None): """Create a new smbus instance. Bus is an optional parameter that specifies the I2C bus number to use, for example 1 would use device /dev/i2c-1. If bus is not specified then the open function should be called to open the bus. """ self._device = None if bus is not None: self.open(bus) def __del__(self): """Clean up any resources used by the SMBus instance.""" self.close() def __enter__(self): """Context manager enter function.""" # Just return this object so it can be used in a with statement, like # with SMBus(1) as bus: # # do stuff! return self def __exit__(self, exc_type, exc_val, exc_tb): """Context manager exit function, ensures resources are cleaned up.""" self.close() return False # Don't suppress exceptions. def open(self, bus): """Open the smbus interface on the specified bus.""" # Close the device if it's already open. if self._device is not None: self.close() # Try to open the file for the specified bus. Must turn off buffering # or else Python 3 fails (see: https://bugs.python.org/issue20074) # pylint: disable=consider-using-with self._device = open(f"/dev/i2c-{bus}", "r+b", buffering=0) # pylint: enable=consider-using-with # TODO: Catch IOError and throw a better error message that describes # what's wrong (i.e. I2C may not be enabled or the bus doesn't exist). def close(self): """Close the smbus connection. You cannot make any other function calls on the bus unless open is called!""" if self._device is not None: self._device.close() self._device = None def _select_device(self, addr): """Set the address of the device to communicate with on the I2C bus.""" ioctl(self._device.fileno(), I2C_SLAVE, addr & 0x7F) def read_byte(self, addr): """Read a single byte from the specified device.""" assert ( self._device is not None ), "Bus must be opened before operations are made against it!" self._select_device(addr) return ord(self._device.read(1)) def read_bytes(self, addr, number): """Read many bytes from the specified device.""" assert ( self._device is not None ), "Bus must be opened before operations are made against it!" self._select_device(addr) return self._device.read(number) def read_byte_data(self, addr, cmd): """Read a single byte from the specified cmd register of the device.""" assert ( self._device is not None ), "Bus must be opened before operations are made against it!" # Build ctypes values to marshall between ioctl and Python. reg = c_uint8(cmd) result = c_uint8() # Build ioctl request. request = make_i2c_rdwr_data( [ (addr, 0, 1, pointer(reg)), # Write cmd register. (addr, I2C_M_RD, 1, pointer(result)), # Read 1 byte as result. ] ) # Make ioctl call and return result data. ioctl(self._device.fileno(), I2C_RDWR, request) return result.value def read_word_data(self, addr, cmd): """Read a word (2 bytes) from the specified cmd register of the device. Note that this will interpret data using the endianness of the processor running Python (typically little endian)! """ assert ( self._device is not None ), "Bus must be opened before operations are made against it!" # Build ctypes values to marshall between ioctl and Python. reg = c_uint8(cmd) result = c_uint16() # Build ioctl request. request = make_i2c_rdwr_data( [ (addr, 0, 1, pointer(reg)), # Write cmd register. ( addr, I2C_M_RD, 2, cast(pointer(result), POINTER(c_uint8)), ), # Read word (2 bytes). ] ) # Make ioctl call and return result data. ioctl(self._device.fileno(), I2C_RDWR, request) return result.value def read_block_data(self, addr, cmd): """Perform a block read from the specified cmd register of the device. The amount of data read is determined by the first byte send back by the device. Data is returned as a bytearray. """ # TODO: Unfortunately this will require calling the low level I2C # access ioctl to trigger a proper read_block_data. The amount of data # returned isn't known until the device starts responding so an I2C_RDWR # ioctl won't work. raise NotImplementedError() def read_i2c_block_data(self, addr, cmd, length=32): """Perform a read from the specified cmd register of device. Length number of bytes (default of 32) will be read and returned as a bytearray. """ assert ( self._device is not None ), "Bus must be opened before operations are made against it!" # Build ctypes values to marshall between ioctl and Python. # convert register into bytearray if not isinstance(cmd, (bytes, bytearray)): reg = cmd # backup cmd = bytearray(1) cmd[0] = reg cmdstring = create_string_buffer(len(cmd)) for i, val in enumerate(cmd): cmdstring[i] = val result = create_string_buffer(length) # Build ioctl request. request = make_i2c_rdwr_data( [ ( addr, 0, len(cmd), cast(cmdstring, POINTER(c_uint8)), ), # Write cmd register. (addr, I2C_M_RD, length, cast(result, POINTER(c_uint8))), # Read data. ] ) # Make ioctl call and return result data. ioctl(self._device.fileno(), I2C_RDWR, request) return bytearray( result.raw ) # Use .raw instead of .value which will stop at a null byte! def write_quick(self, addr): """Write a single byte to the specified device.""" # What a strange function, from the python-smbus source this appears to # just write a single byte that initiates a write to the specified device # address (but writes no data!). The functionality is duplicated below # but the actual use case for this is unknown. assert ( self._device is not None ), "Bus must be opened before operations are made against it!" # Build ioctl request. request = make_i2c_rdwr_data( [ (addr, 0, 0, None), ] ) # Write with no data. # Make ioctl call and return result data. ioctl(self._device.fileno(), I2C_RDWR, request) def write_byte(self, addr, val): """Write a single byte to the specified device.""" assert ( self._device is not None ), "Bus must be opened before operations are made against it!" self._select_device(addr) data = bytearray(1) data[0] = val & 0xFF self._device.write(data) def write_bytes(self, addr, buf): """Write many bytes to the specified device. buf is a bytearray""" assert ( self._device is not None ), "Bus must be opened before operations are made against it!" self._select_device(addr) self._device.write(buf) def write_byte_data(self, addr, cmd, val): """Write a byte of data to the specified cmd register of the device.""" assert ( self._device is not None ), "Bus must be opened before operations are made against it!" # Construct a string of data to send with the command register and byte value. data = bytearray(2) data[0] = cmd & 0xFF data[1] = val & 0xFF # Send the data to the device. self._select_device(addr) self._device.write(data) def write_word_data(self, addr, cmd, val): """Write a word (2 bytes) of data to the specified cmd register of the device. Note that this will write the data in the endianness of the processor running Python (typically little endian)! """ assert ( self._device is not None ), "Bus must be opened before operations are made against it!" # Construct a string of data to send with the command register and word value. data = struct.pack("=BH", cmd & 0xFF, val & 0xFFFF) # Send the data to the device. self._select_device(addr) self._device.write(data) def write_block_data(self, addr, cmd, vals): """Write a block of data to the specified cmd register of the device. The amount of data to write should be the first byte inside the vals string/bytearray and that count of bytes of data to write should follow it. """ # Just use the I2C block data write to write the provided values and # their length as the first byte. data = bytearray(len(vals) + 1) data[0] = len(vals) & 0xFF data[1:] = vals[0:] self.write_i2c_block_data(addr, cmd, data) def write_i2c_block_data(self, addr, cmd, vals): """Write a buffer of data to the specified cmd register of the device.""" assert ( self._device is not None ), "Bus must be opened before operations are made against it!" # Construct a string of data to send, including room for the command register. data = bytearray(len(vals) + 1) data[0] = cmd & 0xFF # Command register at the start. data[1:] = vals[0:] # Copy in the block data (ugly but necessary to ensure # the entire write happens in one transaction). # Send the data to the device. self._select_device(addr) self._device.write(data) def process_call(self, addr, cmd, val): """Perform a smbus process call by writing a word (2 byte) value to the specified register of the device, and then reading a word of response data (which is returned). """ assert ( self._device is not None ), "Bus must be opened before operations are made against it!" # Build ctypes values to marshall between ioctl and Python. data = create_string_buffer(struct.pack("=BH", cmd, val)) result = c_uint16() # Build ioctl request. request = make_i2c_rdwr_data( [ (addr, 0, 3, cast(pointer(data), POINTER(c_uint8))), # Write data. ( addr, I2C_M_RD, 2, cast(pointer(result), POINTER(c_uint8)), ), # Read word (2 bytes). ] ) # Make ioctl call and return result data. ioctl(self._device.fileno(), I2C_RDWR, request) # Note the python-smbus code appears to have a rather serious bug and # does not return the result value! This is fixed below by returning it. return result.value adafruit-Adafruit_Python_PureIO-117f1f1/Adafruit_PureIO/spi.py000066400000000000000000000263431443371706600243340ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries # # SPDX-License-Identifier: MIT """ `Adafruit_PureIO.spi` ================================================================================ Pure python (i.e. no native extensions) access to Linux IO SPI interface that is similar to the SpiDev API. Based heavily on https://github.com/tomstokes/python-spi/. * Author(s): Tom Stokes, Melissa LeBlanc-Williams Implementation Notes -------------------- **Software and Dependencies:** * Linux and Python 3.5 or Higher """ # imports from ctypes import create_string_buffer, string_at, addressof from fcntl import ioctl import struct import platform import os.path from os import environ import array __version__ = "0.0.0+auto.0" __repo__ = "https://github.com/adafruit/Adafruit_Python_PureIO.git" # SPI C API constants (from linux kernel headers) SPI_CPHA = 0x01 SPI_CPOL = 0x02 SPI_CS_HIGH = 0x04 SPI_LSB_FIRST = 0x08 SPI_THREE_WIRE = 0x10 SPI_LOOP = 0x20 SPI_NO_CS = 0x40 SPI_READY = 0x80 SPI_TX_DUAL = 0x100 SPI_TX_QUAD = 0x200 SPI_RX_DUAL = 0x400 SPI_RX_QUAD = 0x800 SPI_MODE_0 = 0 SPI_MODE_1 = SPI_CPHA SPI_MODE_2 = SPI_CPOL SPI_MODE_3 = SPI_CPHA | SPI_CPOL SPI_DEFAULT_CHUNK_SIZE = 4096 def _ioc_encode(direction, number, structure): """ ioctl command encoding helper function Calculates the appropriate spidev ioctl op argument given the direction, command number, and argument structure in python's struct.pack format. Returns a tuple of the calculated op and the struct.pack format See Linux kernel source file /include/uapi/asm/ioctl.h """ ioc_magic = ord("k") ioc_nrbits = 8 ioc_typebits = 8 if platform.machine() == "mips": ioc_sizebits = 13 else: ioc_sizebits = 14 ioc_nrshift = 0 ioc_typeshift = ioc_nrshift + ioc_nrbits ioc_sizeshift = ioc_typeshift + ioc_typebits ioc_dirshift = ioc_sizeshift + ioc_sizebits size = struct.calcsize(structure) operation = ( (direction << ioc_dirshift) | (ioc_magic << ioc_typeshift) | (number << ioc_nrshift) | (size << ioc_sizeshift) ) return direction, operation, structure # pylint: disable=too-many-instance-attributes, too-many-branches class SPI: """ This class is similar to SpiDev, but instead of opening and closing for each call, it is set up on initialization making it fast. """ _IOC_TRANSFER_FORMAT = "QQIIHBBBBH" if platform.machine() == "mips": # Direction is 3 bits _IOC_READ = 2 _IOC_WRITE = 4 else: # Direction is 2 bits _IOC_WRITE = 1 _IOC_READ = 2 # _IOC_MESSAGE is a special case, so we ony need the ioctl operation _IOC_MESSAGE = _ioc_encode(_IOC_WRITE, 0, _IOC_TRANSFER_FORMAT)[1] _IOC_RD_MODE = _ioc_encode(_IOC_READ, 1, "B") _IOC_WR_MODE = _ioc_encode(_IOC_WRITE, 1, "B") _IOC_RD_LSB_FIRST = _ioc_encode(_IOC_READ, 2, "B") _IOC_WR_LSB_FIRST = _ioc_encode(_IOC_WRITE, 2, "B") _IOC_RD_BITS_PER_WORD = _ioc_encode(_IOC_READ, 3, "B") _IOC_WR_BITS_PER_WORD = _ioc_encode(_IOC_WRITE, 3, "B") _IOC_RD_MAX_SPEED_HZ = _ioc_encode(_IOC_READ, 4, "I") _IOC_WR_MAX_SPEED_HZ = _ioc_encode(_IOC_WRITE, 4, "I") _IOC_RD_MODE32 = _ioc_encode(_IOC_READ, 5, "I") _IOC_WR_MODE32 = _ioc_encode(_IOC_WRITE, 5, "I") # pylint: disable=too-many-arguments def __init__( self, device, max_speed_hz=None, bits_per_word=None, phase=None, polarity=None, cs_high=None, lsb_first=None, three_wire=None, loop=None, no_cs=None, ready=None, ): """ Create spidev interface object. """ if isinstance(device, tuple): (bus, dev) = device device = f"/dev/spidev{bus:d}.{dev:d}" if not os.path.exists(device): raise IOError(f"{device} does not exist") self.handle = os.open(device, os.O_RDWR) self.chunk_size = SPI_DEFAULT_CHUNK_SIZE if environ.get("SPI_BUFSIZE") is not None: try: self.chunk_size = int(os.environ.get("SPI_BUFSIZE")) except ValueError: self.chunk_size = SPI_DEFAULT_CHUNK_SIZE if max_speed_hz is not None: self.max_speed_hz = max_speed_hz if bits_per_word is not None: self.bits_per_word = bits_per_word if phase is not None: self.phase = phase if polarity is not None: self.polarity = polarity if cs_high is not None: self.cs_high = cs_high if lsb_first is not None: self.lsb_first = lsb_first if three_wire is not None: self.three_wire = three_wire if loop is not None: self.loop = loop if no_cs is not None: self.no_cs = no_cs if ready is not None: self.ready = ready # pylint: enable=too-many-arguments def _ioctl(self, ioctl_data, data=None): """ ioctl helper function. Performs an ioctl on self.handle. If the ioctl is an SPI read type ioctl, returns the result value. """ (direction, ioctl_bytes, structure) = ioctl_data if direction == SPI._IOC_READ: arg = array.array(structure, [0]) ioctl(self.handle, ioctl_bytes, arg, True) return arg[0] arg = struct.pack("=" + structure, data) ioctl(self.handle, ioctl_bytes, arg) return None def _get_mode_field(self, field): """Helper function to get specific spidev mode bits""" return bool(self._ioctl(SPI._IOC_RD_MODE) & field) def _set_mode_field(self, field, value): """Helper function to set a spidev mode bit""" mode = self._ioctl(SPI._IOC_RD_MODE) if value: mode |= field else: mode &= ~field self._ioctl(SPI._IOC_WR_MODE, mode) @property def phase(self): """SPI clock phase bit""" return self._get_mode_field(SPI_CPHA) @phase.setter def phase(self, phase): self._set_mode_field(SPI_CPHA, phase) @property def polarity(self): """SPI polarity bit""" return self._get_mode_field(SPI_CPOL) @polarity.setter def polarity(self, polarity): self._set_mode_field(SPI_CPOL, polarity) @property def cs_high(self): """SPI chip select active level""" return self._get_mode_field(SPI_CS_HIGH) @cs_high.setter def cs_high(self, cs_high): self._set_mode_field(SPI_CS_HIGH, cs_high) @property def lsb_first(self): """Bit order of SPI word transfers""" return self._get_mode_field(SPI_LSB_FIRST) @lsb_first.setter def lsb_first(self, lsb_first): self._set_mode_field(SPI_LSB_FIRST, lsb_first) @property def three_wire(self): """SPI 3-wire mode""" return self._get_mode_field(SPI_THREE_WIRE) @three_wire.setter def three_wire(self, three_wire): self._set_mode_field(SPI_THREE_WIRE, three_wire) @property def loop(self): """SPI loopback mode""" return self._get_mode_field(SPI_LOOP) @loop.setter def loop(self, loop): self._set_mode_field(SPI_LOOP, loop) @property def no_cs(self): """No chipselect. Single device on bus.""" return self._get_mode_field(SPI_NO_CS) @no_cs.setter def no_cs(self, no_cs): self._set_mode_field(SPI_NO_CS, no_cs) @property def ready(self): """Slave pulls low to pause""" return self._get_mode_field(SPI_READY) @ready.setter def ready(self, ready): self._set_mode_field(SPI_READY, ready) @property def max_speed_hz(self): """Maximum SPI transfer speed in Hz. Note that the controller cannot necessarily assign the requested speed. """ return self._ioctl(SPI._IOC_RD_MAX_SPEED_HZ) @max_speed_hz.setter def max_speed_hz(self, max_speed_hz): self._ioctl(SPI._IOC_WR_MAX_SPEED_HZ, max_speed_hz) @property def bits_per_word(self): """Number of bits per word of SPI transfer. A value of 0 is equivalent to 8 bits per word """ return self._ioctl(SPI._IOC_RD_BITS_PER_WORD) @bits_per_word.setter def bits_per_word(self, bits_per_word): self._ioctl(SPI._IOC_WR_BITS_PER_WORD, bits_per_word) @property def mode(self): """Mode that SPI is currently running in""" return self._ioctl(SPI._IOC_RD_MODE) @mode.setter def mode(self, mode): self._ioctl(SPI._IOC_WR_MODE, mode) def writebytes(self, data, max_speed_hz=0, bits_per_word=0, delay=0): """Perform half-duplex SPI write.""" data = array.array("B", data).tobytes() # length = len(data) chunks = [ data[i : i + self.chunk_size] for i in range(0, len(data), self.chunk_size) ] for chunk in chunks: length = len(chunk) transmit_buffer = create_string_buffer(chunk) spi_ioc_transfer = struct.pack( SPI._IOC_TRANSFER_FORMAT, addressof(transmit_buffer), 0, length, max_speed_hz, delay, bits_per_word, 0, 0, 0, 0, ) try: ioctl(self.handle, SPI._IOC_MESSAGE, spi_ioc_transfer) except TimeoutError as err: raise Exception( # pylint: disable=broad-exception-raised "ioctl timeout. Please try a different SPI frequency or less data." ) from err def readbytes(self, length, max_speed_hz=0, bits_per_word=0, delay=0): """Perform half-duplex SPI read as a binary string""" receive_buffer = create_string_buffer(length) spi_ioc_transfer = struct.pack( SPI._IOC_TRANSFER_FORMAT, 0, addressof(receive_buffer), length, max_speed_hz, delay, bits_per_word, 0, 0, 0, 0, ) ioctl(self.handle, SPI._IOC_MESSAGE, spi_ioc_transfer) return string_at(receive_buffer, length) def transfer(self, data, max_speed_hz=0, bits_per_word=0, delay=0): """Perform full-duplex SPI transfer""" data = array.array("B", data).tobytes() receive_data = [] chunks = [ data[i : i + self.chunk_size] for i in range(0, len(data), self.chunk_size) ] for chunk in chunks: length = len(chunk) receive_buffer = create_string_buffer(length) transmit_buffer = create_string_buffer(chunk) spi_ioc_transfer = struct.pack( SPI._IOC_TRANSFER_FORMAT, addressof(transmit_buffer), addressof(receive_buffer), length, max_speed_hz, delay, bits_per_word, 0, 0, 0, 0, ) ioctl(self.handle, SPI._IOC_MESSAGE, spi_ioc_transfer) receive_data += string_at(receive_buffer, length) return receive_data adafruit-Adafruit_Python_PureIO-117f1f1/CODE_OF_CONDUCT.md000066400000000000000000000140041443371706600227730ustar00rootroot00000000000000 # Adafruit Community Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and leaders pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level or type of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards We are committed to providing a friendly, safe and welcoming environment for all. Examples of behavior that contributes to creating a positive environment include: * Be kind and courteous to others * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Collaborating with other community members * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and sexual attention or advances * The use of inappropriate images, including in a community member's avatar * The use of inappropriate language, including in a community member's nickname * Any spamming, flaming, baiting or other attention-stealing behavior * Excessive or unwelcome helping; answering outside the scope of the question asked * Trolling, insulting/derogatory comments, and personal or political attacks * Promoting or spreading disinformation, lies, or conspiracy theories against a person, group, organisation, project, or community * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate The goal of the standards and moderation guidelines outlined here is to build and maintain a respectful community. We ask that you don’t just aim to be "technically unimpeachable", but rather try to be your best self. We value many things beyond technical expertise, including collaboration and supporting others within our community. Providing a positive experience for other community members can have a much more significant impact than simply providing the correct answer. ## Our Responsibilities Project leaders are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project leaders have the right and responsibility to remove, edit, or reject messages, comments, commits, code, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any community member for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Moderation Instances of behaviors that violate the Adafruit Community Code of Conduct may be reported by any member of the community. Community members are encouraged to report these situations, including situations they witness involving other community members. You may report in the following ways: In any situation, you may send an email to . On the Adafruit Discord, you may send an open message from any channel to all Community Moderators by tagging @community moderators. You may also send an open message from any channel, or a direct message to @kattni#1507, @tannewt#4653, @Dan Halbert#1614, @cater#2442, @sommersoft#0222, @Mr. Certainly#0472 or @Andon#8175. Email and direct message reports will be kept confidential. In situations on Discord where the issue is particularly egregious, possibly illegal, requires immediate action, or violates the Discord terms of service, you should also report the message directly to Discord. These are the steps for upholding our community’s standards of conduct. 1. Any member of the community may report any situation that violates the Adafruit Community Code of Conduct. All reports will be reviewed and investigated. 2. If the behavior is an egregious violation, the community member who committed the violation may be banned immediately, without warning. 3. Otherwise, moderators will first respond to such behavior with a warning. 4. Moderators follow a soft "three strikes" policy - the community member may be given another chance, if they are receptive to the warning and change their behavior. 5. If the community member is unreceptive or unreasonable when warned by a moderator, or the warning goes unheeded, they may be banned for a first or second offense. Repeated offenses will result in the community member being banned. ## Scope This Code of Conduct and the enforcement policies listed above apply to all Adafruit Community venues. This includes but is not limited to any community spaces (both public and private), the entire Adafruit Discord server, and Adafruit GitHub repositories. Examples of Adafruit Community spaces include but are not limited to meet-ups, audio chats on the Adafruit Discord, or interaction at a conference. This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. As a community member, you are representing our community, and are expected to behave accordingly. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at , and the [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html). For other projects adopting the Adafruit Community Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion. adafruit-Adafruit_Python_PureIO-117f1f1/LICENSE000066400000000000000000000021331443371706600212010ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2020 Melissa LeBlanc-Williams for Adafruit Industries Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. adafruit-Adafruit_Python_PureIO-117f1f1/LICENSES/000077500000000000000000000000001443371706600214025ustar00rootroot00000000000000adafruit-Adafruit_Python_PureIO-117f1f1/LICENSES/CC-BY-4.0.txt000066400000000000000000000406561443371706600232520ustar00rootroot00000000000000Creative Commons Attribution 4.0 International Creative Commons Corporation ("Creative Commons") is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an "as-is" basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible. Using Creative Commons Public Licenses Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses. Considerations for licensors: Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. More considerations for licensors : wiki.creativecommons.org/Considerations_for_licensors Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor's permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. More considerations for the public : wiki.creativecommons.org/Considerations_for_licensees Creative Commons Attribution 4.0 International Public License By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. Section 1 – Definitions. a. Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. b. Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. c. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. d. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. e. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. f. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License. g. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. h. Licensor means the individual(s) or entity(ies) granting rights under this Public License. i. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. j. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. k. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning. Section 2 – Scope. a. License grant. 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: A. reproduce and Share the Licensed Material, in whole or in part; and B. produce, reproduce, and Share Adapted Material. 2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. 3. Term. The term of this Public License is specified in Section 6(a). 4. Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material. 5. Downstream recipients. A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. B. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material. 6. No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i). b. Other rights. 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. 2. Patent and trademark rights are not licensed under this Public License. 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties. Section 3 – License Conditions. Your exercise of the Licensed Rights is expressly made subject to the following conditions. a. Attribution. 1. If You Share the Licensed Material (including in modified form), You must: A. retain the following if it is supplied by the Licensor with the Licensed Material: i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated); ii. a copyright notice; iii. a notice that refers to this Public License; iv. a notice that refers to the disclaimer of warranties; v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. 4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License. Section 4 – Sui Generis Database Rights. Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material: a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database; b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights. Section 5 – Disclaimer of Warranties and Limitation of Liability. a. Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You. b. To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You. c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability. Section 6 – Term and Termination. a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates: 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or 2. upon express reinstatement by the Licensor. c. For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License. d. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License. e. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. Section 7 – Other Terms and Conditions. a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed. b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License. Section 8 – Interpretation. a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License. b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions. c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor. d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the "Licensor." The text of the Creative Commons public licenses is dedicated to the public domain under the CC0 Public Domain Dedication. Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark "Creative Commons" or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses. Creative Commons may be contacted at creativecommons.org. adafruit-Adafruit_Python_PureIO-117f1f1/LICENSES/MIT.txt000066400000000000000000000021241443371706600225730ustar00rootroot00000000000000MIT License Copyright (c) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. adafruit-Adafruit_Python_PureIO-117f1f1/LICENSES/Unlicense.txt000066400000000000000000000022731443371706600240740ustar00rootroot00000000000000This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to adafruit-Adafruit_Python_PureIO-117f1f1/README.rst000066400000000000000000000036301443371706600216660ustar00rootroot00000000000000Introduction ============ .. image:: https://readthedocs.org/projects/adafruit-pureio/badge/?version=latest :target: https://adafruit-pureio.readthedocs.io/en/latest/ :alt: Documentation Status .. image:: https://img.shields.io/discord/327254708534116352.svg :target: https://adafru.it/discord :alt: Discord .. image:: https://github.com/adafruit/Adafruit_Python_PureIO/workflows/Build%20CI/badge.svg :target: https://github.com/adafruit/Adafruit_Python_PureIO/actions :alt: Build Status .. image:: https://img.shields.io/badge/code%20style-black-000000.svg :target: https://github.com/psf/black :alt: Code Style: Black Pure python (i.e. no native extensions) access to Linux IO including I2C and SPI. Drop in replacement for smbus and spidev modules. Dependencies ============= This driver depends on: * Python 3.5 or higher Installing from PyPI ===================== On supported GNU/Linux systems like the Raspberry Pi, you can install the driver locally `from PyPI `_. To install for current user: .. code-block:: shell pip3 install Adafruit-PureIO To install system-wide (this may be required in some cases): .. code-block:: shell sudo pip3 install Adafruit-PureIO To install in a virtual environment in your current project: .. code-block:: shell mkdir project-name && cd project-name python3 -m venv .env source .env/bin/activate pip3 install Adafruit-PureIO Contributing ============ Contributions are welcome! Please read our `Code of Conduct `_ before contributing to help this project stay welcoming. Documentation ============= For information on building library documentation, please check out `this guide `_. adafruit-Adafruit_Python_PureIO-117f1f1/README.rst.license000066400000000000000000000001541443371706600233050ustar00rootroot00000000000000SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries SPDX-License-Identifier: MIT adafruit-Adafruit_Python_PureIO-117f1f1/docs/000077500000000000000000000000001443371706600211255ustar00rootroot00000000000000adafruit-Adafruit_Python_PureIO-117f1f1/docs/_static/000077500000000000000000000000001443371706600225535ustar00rootroot00000000000000adafruit-Adafruit_Python_PureIO-117f1f1/docs/_static/favicon.ico000066400000000000000000000104761443371706600247040ustar00rootroot00000000000000  (( @ 'w",h&PƆ(ׄ)hP8  ":60/M1S*( a$4 0  UzX̓[:fۏ/e/e,_) +_.IYYr A6"Lŵ[f S ȋ%ӏ/e/e-a! {U%ɂJΉP݋\8KK_(BɂM+ 5 '̏/e/e/e8'*[/e/e/e/e/e/e/e1d/e.mvOЫF= W*M$7/f/e0-?Σ9re0d/e/d)/e/e/e/e/e/e/e/e/e/e/e/e/ewI$2!/e/e,B/e/ez(V2E=6-E+ :674 B5.H3Ã+]/e/e/e/e/e(},B e"H/%# &XRp^/e/ei#K^ ΍_FˋFˁEs.#o%N׏/e/e/e/e2 Y+H-/e/eo%NZS2qگ\UŎ+y?jӧOcĎ#˺j`1cIxU;Ə/e/e-_  3yJ6( ŏ/e/e~*Z9(s%Rl$Mu&R݁+Z/d/e/e/e0deVF+&~*Xm%Mzu'TH3`+UX́[>]/e/e VhS c-V?k/M<19-*Z/e/eA_TVQf!)(>+r/e/e8Yq̈Nǎ߻g}IPB3/e/eH8'" 8+~ =/e/eB0+^/e/e/e2dXZċbHx6',^+  >1E̹bz/e/ey)V 1"g"Iҏ/e/e/e/eeNCl5 ,m/e/e L :(e"Hk#L<* j"FNTvR/e/e6&GQǏ/e/e|(Wj1Izċ+u/e/e Z~M/e/eH3&GT /e/e-_,o/e/e/e#  p,^/e/e/eQ:/ aNq%Pڏ/e/e/e-_v M3^.c/e/e/e/e$IHz'& $p%O܏/e/e/e/e/e/e' Gb E݂+\-_r%P,]/e/e/e/e/e2#P96'/e/e/ez=A_C͇-_/e/e/e6' r%P.c/e/e}+YiU!۱f(~*Z/e &! w'Sj#KԿٹw'Sߏ/e+\ q&Pu(Sd5Om$Nҏ/e+^y0"[@U<0!   3,adafruit-Adafruit_Python_PureIO-117f1f1/docs/_static/favicon.ico.license000066400000000000000000000001511443371706600263120ustar00rootroot00000000000000SPDX-FileCopyrightText: 2018 Phillip Torrone for Adafruit Industries SPDX-License-Identifier: CC-BY-4.0 adafruit-Adafruit_Python_PureIO-117f1f1/docs/api.rst000066400000000000000000000005011443371706600224240ustar00rootroot00000000000000 .. If you created a package, create one automodule per module in the package. .. If your library file(s) are nested in a directory (e.g. /adafruit_foo/foo.py) .. use this format as the module name: "adafruit_foo.foo" .. automodule:: Adafruit_PureIO.smbus :members: .. automodule:: Adafruit_PureIO.spi :members: adafruit-Adafruit_Python_PureIO-117f1f1/docs/api.rst.license000066400000000000000000000001541443371706600240510ustar00rootroot00000000000000SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries SPDX-License-Identifier: MIT adafruit-Adafruit_Python_PureIO-117f1f1/docs/conf.py000066400000000000000000000125361443371706600224330ustar00rootroot00000000000000# -*- coding: utf-8 -*- # SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries # # SPDX-License-Identifier: MIT import os import sys sys.path.insert(0, os.path.abspath("..")) # -- General configuration ------------------------------------------------ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ "sphinx.ext.autodoc", "sphinx.ext.intersphinx", "sphinx.ext.napoleon", "sphinx.ext.todo", ] # TODO: Please Read! # Uncomment the below if you use native CircuitPython modules such as # digitalio, micropython and busio. List the modules you use. Without it, the # autodoc module docs will fail to generate with a warning. # autodoc_mock_imports = ["digitalio", "busio"] intersphinx_mapping = { "python": ("https://docs.python.org/3.5", None), "CircuitPython": ("https://circuitpython.readthedocs.io/en/latest/", None), } # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] source_suffix = ".rst" # The master toctree document. master_doc = "index" # General information about the project. project = "Adafruit PureIO Library" copyright = "2020 Melissa LeBlanc-Williams" author = "Melissa LeBlanc-Williams" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = "1.0" # The full version, including alpha/beta/rc tags. release = "1.0" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = "en" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path exclude_patterns = [ "_build", "Thumbs.db", ".DS_Store", ".env", "CODE_OF_CONDUCT.md", ] # The reST default role (used for this markup: `text`) to use for all # documents. # default_role = "any" # If true, '()' will be appended to :func: etc. cross-reference text. # add_function_parentheses = True # The name of the Pygments (syntax highlighting) style to use. pygments_style = "sphinx" # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False # If this is True, todo emits a warning for each TODO entries. The default is False. todo_emit_warnings = True napoleon_numpy_docstring = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # on_rtd = os.environ.get("READTHEDOCS", None) == "True" if not on_rtd: # only import and set the theme if we're building docs locally try: import sphinx_rtd_theme html_theme = "sphinx_rtd_theme" html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), "."] except: html_theme = "default" html_theme_path = ["."] else: html_theme_path = ["."] # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] # The name of an image file (relative to this directory) to use as a favicon of # the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. # html_favicon = "_static/favicon.ico" # Output file base name for HTML help builder. htmlhelp_basename = "AdafruitPureioLibrarydoc" # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # 'preamble': '', # Latex figure (float) alignment # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ ( master_doc, "AdafruitPureIOLibrary.tex", "AdafruitPureIO Library Documentation", author, "manual", ), ] # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ( master_doc, "AdafruitPureIOlibrary", "Adafruit PureIO Library Documentation", [author], 1, ), ] # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ( master_doc, "AdafruitPureIOLibrary", "Adafruit PureIO Library Documentation", author, "AdafruitPureIOLibrary", "One line description of project.", "Miscellaneous", ), ] adafruit-Adafruit_Python_PureIO-117f1f1/docs/index.rst000066400000000000000000000015121443371706600227650ustar00rootroot00000000000000.. include:: ../README.rst Table of Contents ================= .. toctree:: :maxdepth: 4 :hidden: self .. toctree:: :caption: API Reference :maxdepth: 3 api .. toctree:: :caption: Tutorials .. toctree:: :caption: Related Products .. toctree:: :caption: Other Links Download CircuitPython Reference Documentation CircuitPython Support Forum Discord Chat Adafruit Learning System Adafruit Blog Adafruit Store Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` adafruit-Adafruit_Python_PureIO-117f1f1/docs/index.rst.license000066400000000000000000000001541443371706600244070ustar00rootroot00000000000000SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries SPDX-License-Identifier: MIT adafruit-Adafruit_Python_PureIO-117f1f1/optional_requirements.txt000066400000000000000000000001461443371706600253670ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 Alec Delaney, for Adafruit Industries # # SPDX-License-Identifier: MIT adafruit-Adafruit_Python_PureIO-117f1f1/pyproject.toml000066400000000000000000000027021443371706600231120ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 Alec Delaney for Adafruit Industries # # SPDX-License-Identifier: MIT [build-system] requires = [ "setuptools", "wheel", "setuptools-scm", ] [project] name = "Adafruit_PureIO" description = "Pure python (i.e. no native extensions) access to Linux IO including I2C and SPI. Drop in replacement for smbus and spidev modules." version = "0.0.0+auto.0" readme = "README.rst" authors = [ {name = "Adafruit Industries", email = "circuitpython@adafruit.com"} ] urls = {Homepage = "https://github.com/adafruit/Adafruit_Python_PureIO"} keywords = [ "adafruit", "blinka", "micropython", "pureio", "ioctl", "spi", "i2c", "python", ] license = {text = "MIT"} classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Topic :: Software Development :: Libraries", "Topic :: System :: Hardware", "License :: OSI Approved :: MIT License", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: Implementation :: CPython", ] requires-python = ">=3.5.0" dynamic = ["dependencies", "optional-dependencies"] [tool.setuptools] packages = ["Adafruit_PureIO"] [tool.setuptools.dynamic] dependencies = {file = ["requirements.txt"]} optional-dependencies = {optional = {file = ["optional_requirements.txt"]}} adafruit-Adafruit_Python_PureIO-117f1f1/requirements.txt000066400000000000000000000000001443371706600234470ustar00rootroot00000000000000adafruit-Adafruit_Python_PureIO-117f1f1/tests/000077500000000000000000000000001443371706600213375ustar00rootroot00000000000000adafruit-Adafruit_Python_PureIO-117f1f1/tests/test_I2C.py000066400000000000000000000035331443371706600233310ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries # # SPDX-License-Identifier: MIT # Basic smbus test. This is pretty ugly and meant to be run against a ADS1x15 # and some output inspected by a Saleae logic analyzer. TODO: Refactor into # something that can test without hardware? import binascii from Adafruit_PureIO import smbus DEVICE_ADDR = 0x48 REGISTER = 0x01 # Test open and close. i2c = smbus.SMBus() i2c.open(1) val = i2c.read_byte(DEVICE_ADDR) print("read_byte from 0x{0:0X}: 0x{1:0X}".format(REGISTER, val)) i2c.close() # Test initializer open. i2c = smbus.SMBus(1) val = i2c.read_byte(DEVICE_ADDR) print("read_byte from 0x{0:0X}: 0x{1:0X}".format(REGISTER, val)) i2c.close() # Test various data reads. with smbus.SMBus(1) as i2c: val = i2c.read_byte(DEVICE_ADDR) print("read_byte from 0x{0:0X}: 0x{1:0X}".format(REGISTER, val)) val = i2c.read_byte_data(DEVICE_ADDR, REGISTER) print("read_byte_data from 0x{0:0X}: 0x{1:0X}".format(REGISTER, val)) val = i2c.read_word_data(DEVICE_ADDR, REGISTER) print("read_word_data from 0x{0:0X}: 0x{1:04X}".format(REGISTER, val)) val = i2c.read_i2c_block_data(DEVICE_ADDR, REGISTER, 2) print( "read_i2c_block_data from 0x{0:0X}: 0x{1}".format( REGISTER, binascii.hexlify(val) ) ) # Test various data writes. with smbus.SMBus(1) as i2c: i2c.write_byte(DEVICE_ADDR, REGISTER) i2c.write_byte_data(DEVICE_ADDR, REGISTER, 0x85) i2c.write_word_data(DEVICE_ADDR, REGISTER, 0x8385) i2c.write_i2c_block_data(DEVICE_ADDR, REGISTER, [0x85, 0x83]) # i2c.write_block_data(DEVICE_ADDR, REGISTER, [0x85, 0x83]) i2c.write_quick(DEVICE_ADDR) # Process call test. with smbus.SMBus(1) as i2c: val = i2c.process_call(DEVICE_ADDR, REGISTER, 0x8385) print("process_call from 0x{0:0X}: 0x{1:04X}".format(REGISTER, val))