{ "info": { "author": "Noah Huppert", "author_email": "developer.noah@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "Python I2C Register |Build Status| |Test Coverage|\n==================================================\n\nPython wrapper library around the common I2C controller register\npattern.\n\nI2C Register is a python library which aims to make communicating with\nregisters on I2C devices dead simple. It is meant to directly transfer\nthe Register Definitions pages of a data sheet into your program.\n\nTable Of Contents\n=================\n\n- `Installation <#installation>`__\n- `Quick Example <#quick-example>`__\n- `Systems Overview <#systems-overview>`__\n\n - `Creating a RegisterList <#creating-a-registerlist>`__\n - `Defining Registers <#defining-registers>`__\n - `Adding RegisterSegments <#adding-registersegments>`__\n - `Reading from RegisterSegments <#reading-from-registersegments>`__\n - `Writing to RegisterSegments <#writing-to-registersegments>`__\n\n- `Writting Wrapper Classes <#writing-wrapper-classes>`__\n- `Development <#development>`__\n\n - `Running Tests <#running-tests>`__\n\n- `Distribution <#distribution>`__\n\n - `Setup <#setup>`__\n - `Steps <#steps>`__\n\nInstallation\n============\n\nI2C Register is available as a PIP package with the name\n``py-i2c-register``.\n\nSimply use PIP to install:\n\n.. code:: bash\n\n pip install --user py-i2c-register\n\nYou will then be able to include the ``py_i2c_register`` module and its\nvarious classes:\n\n.. code:: python\n\n from py_i2c_register.register_list import RegisterList\n from py_i2c_register.register import Register\n from py_i2c_register.register_segment import RegisterSegment\n\nQuick Example\n=============\n\nTake these control register definitions from a data sheet:\n\n.. figure:: https://github.com/Noah-Huppert/py-i2c-register/blob/master/docs/img/example-register-defs-p1.png?raw=true\n :alt: Example Hardware Data Sheet Register Definitions page 1\n\n Example Hardware Data Sheet Register Definitions page 1\n\n.. figure:: https://github.com/Noah-Huppert/py-i2c-register/blob/master/docs/img/example-register-defs-p2.png?raw=true\n :alt: Example Hardware Data Sheet Register Definitions page 2\n\n Example Hardware Data Sheet Register Definitions page 2\n\nWith the help of the I2C Register library they can easily be represented\nand manipulated.\n\n.. code:: python\n\n from py_i2c_register.register_list import RegisterList\n from py_i2c_register.register import Register\n\n # Create RegisterList instance to hold registers, device's i2c address is 0x62\n controls = RegisterList(0x62, i2c, {})\n\n # Add a definition for an ACQ_COMMAND (Acquisition Command) register, address 0x00 with WRITE permissions\n controls.add(\"ACQ_COMMAND\", 0x00, Register.WRITE, {})\\\n .add(\"ACQ_COMMAND\", 0, 7, [0] * 8) # Define the segment of bits to read with LSB index of 0 and MSB index of 7\n \n # Add a definition for a STATUS register, address 0x01 with READ permissions\n controls.add(\"STATUS\", 0x01, Register.READ, {}) \\\n # Define various individual Register Segments which each signify different parts of the status\n .add(\"PROC_ERROR_FLAG\", 6, 6, [0]) \\\n .add(\"HEALTH_FLAG\", 5, 5, [0]) \\\n .add(\"SECONDARY_RET_FLAG\", 4, 4, [0]) \\\n .add(\"INVALID_SIGNAL_FLAG\", 3, 3, [0]) \\\n .add(\"SIGNAL_OVERFLOW_FLAG\", 2, 2, [0]) \\\n .add(\"REFERENCE_OVERFLOW_FLAG\", 1, 1, [0]) \\\n .add(\"BUSY_FLAG\", 0, 0, [0])\n \n # Add a definition for a VELOCITY register, address 0x09 with READ permissions\n controls.add(\"VELOCITY\", 0x09, Register.READ, {})\\\n .add(\"VELOCITY\", 0, 7, [0] * 8) # Define the segment of bits to read for velocity value with LSB index of 0 and MSB index of 7\n\n \n # Super simple to read and write values\n # Set ACQ_COMMAND Register bits to value of 0x04, then write to register\n controls.set_bits_from_int(\"ACQ_COMMAND\", \"ACQ_COMMAND\", 0x04, write_after=True) \n\n # Read STATUS register for BUSY_FLAG value and convert to an integer\n busy = controls.to_int(\"STATUS\", \"BUSY_FLAG\", read_first=True)\n\n # Read VELOCITY register and convert to two's compliment integer\n velocity = controls.to_twos_comp_int(\"VELOCITY\", \"VELOCITY\", read_first=True)\n\nSystems Overview\n================\n\nThe main class this library provides is the ``RegisterList`` class. This\nclass manages a list of ``Register`` definitions. It also provides some\nuseful helper methods to make performing certain common actions quick\nand easy.\n\nCreating a RegisterList\n-----------------------\n\nTo create a ``RegisterList`` import the ``register_list.RegisterList``\nclass. Then call the constructor giving it a I2C device address, an `I2C\nObject `__, and any ``Register``\\ s you have\nalready defined:\n\n.. code:: python\n\n from py_i2c_register.register_list import RegisterList\n controls = RegisterList(0x62, i2c, {})\n\nThe provided I2C Device address will be used to contact the device which\nholds the registers over I2C. The `I2C Object `__\ndepends on your platform, see the\n`documentation `__ for more information. In most\ncases you can provide an empty ``Register`` map as well.\n\nDefining Registers\n------------------\n\nAfter you create a ``RegisterList`` you must define some ``Register``\\ s\nto control. A ``Register`` is defined by a name (for easy programmatic\naccess), an I2C address, and a string containing IO operation\npermissions. The ``RegisterList`` class provides a useful\n``add(reg_name, reg_addr, reg_permissions, reg_segments)`` method for\nadding ``Register``\\ s.\n\n.. code:: python\n\n from py_i2c_register.register import Register\n controls.add(\"REGISTER_NAME\", 0x00, Registers.READ + Register.WRITE, {})\n\nThis would define a ``Register`` with the name ``REGISTER_NAME``, the\naddress ``0x00`` and the permission to read and write to/from it.\n\nAdding RegisterSegments\n-----------------------\n\nTo actually read or write to/from a ``Register`` you need to define at\nleast one ``RegisterSegment``. These describe how bits read from\nregisters map to sub values. This could be useful if a device for\nexample: provides a health register and each bit represents a different\nsystem's health. You define ``RegisterSegment``\\ s by giving a name (for\neasy programmatic access) and the index of the segment's least and most\nsignificant bits. The previously mentioned ``RegisterList.add()`` method\nreturns the ``Register`` that it just created. You can then in turn use\na similar helper method that ``Register`` provides called\n``add(seg_name, lsb_i, msb_i, default_bits)``:\n\n.. code:: python\n\n controls.add(\"HEALTH\", 0x00, Registers.READ, {})\\\n .add(\"LEFT_MOTOR_FLAG\", 2, 2, [0])\\\n .add(\"RIGHT_MOTOR_FLAG\", 1, 1, [0])\\\n .add(\"NETWORK_FLAG\", 0, 0, [0])\n\nThis would define a ``Register`` named ``HEALTH`` at address ``0x00``\nwith read permissions. This ``Register`` would have 3\n``RegisterSegment``\\ s. These 3 register segments would look at bits 0,\n1, and 2 for the status of the left and right motors as well as some\nmade up network module.\n\nReading from RegisterSegments\n-----------------------------\n\nThe ``RegisterList`` provides some useful helper methods for reading\n``RegisterSegment``\\ s as integer values. They are called ``to_int`` and\n``to_twos_comp_int``. They both take the name of a ``Register`` and\n``RegisterSegment`` to read. Optionally you can pass a ``read_first``\nvalue. When ``True`` these methods will read the ``Register`` off the\nI2C device before returning the ``RegisterSegment`` value:\n\n.. code:: python\n\n network_status = controls.to_int(\"HEALTH\", \"NETWORK_FLAG\", read_first=True)\n velocity = controls.to_twos_comp_int(\"VELOCITY\", \"VELOCITY\", read_first=True)\n\nThis would read the ``NETWORK_FLAG`` segment of the ``HEALTH`` register\nand the ``VELOCITY`` segment of the ``VELOCITY`` register.\n\nOntop of using ``RegisterList``\\ s helper methods one can access raw\n``RegisterSegment`` values via the ``RegisterSegment.bits`` array. This\narray contains the raw ``0`` or ``1`` values of the register. Just be\nsure to call ``Register.read`` before accessing the\n``RegisterSegment.bits`` array:\n\n.. code:: python\n\n controls.get(\"VELOCITY\").read()\n velocity_bits = controls.get(\"VELOCITY\").get(\"VELOCITY\").bits\n\nWriting to RegisterSegments\n---------------------------\n\nThe ``RegisterList`` class provides the ``set_bits`` and\n``set_bits_from_int`` helper methods. Similar to the reading helper\nmethods mentioned above ``set_bits`` and ``set_bits_from_int`` both also\ntake a ``Register`` and ``RegisterSegment`` name as their first two\nparameters. The third value of both functions is the value to set. In\nthe case of the ``set_bits`` method it is expected to be an array of\nbits to set. In the case of the ``set_bits_from_int`` method it is\nexpected to be an integer value to set. The ``set_bits`` and\n``set_bits_from_int`` methods also offer an optional ``write_after``\nflag. If ``True`` they will write the value of the ``Register`` to the\nI2C device after the value has been set.\n\n.. code:: python\n\n controls.set_bits(\"ACQ_COMMAND\", \"ACQ_COMMAND\", [0, 0, 0, 0, 0, 1, 0, 0], write_after=True) \n controls.set_bits_from_int(\"ACQ_COMMAND\", \"ACQ_COMMAND\", 0x04, write_after=True) \n\nThis would set the ``ACQ_COMMAND`` segment of the ``ACQ_COMMAND``\nregister to the value ``0x04`` using the ``set_bits`` and\n``set_bits_from_int`` methods.\n\nWriting Wrapper Classes\n=======================\n\nI2C Register's simple architecture lends itself well to being used in\nhardware wrapper classes. All one must do is create a class with its own\n``RegisterList`` instance. Then add ``Register`` and ``RegisterSegment``\ndefinitions in the ``__init__()`` method:\n\n.. code:: python\n\n from py_i2c_register.register_list import RegisterList\n from py_i2c_register.register import Register\n\n class LidarLiteV3():\n # Register and Segment name constants\n REG_ACQ_COMMAND = \"ACQ_COMMAND\"\n SEG_ACQ_COMMAND = REG_ACQ_COMMAND\n\n REG_STATUS = \"STATUS\"\n SEG_PROC_ERROR_FLAG = \"PROC_ERROR_FLAG\"\n SEG_HEALTH_FLAG = \"HEALTH_FLAG\"\n SEG_SECONDARY_RET_FLAG = \"SECONDARY_RET_FLAG\"\n SEG_INVALID_SIGNAL_FLAG = \"INVALID_SIGNAL_FLAG\"\n SEG_SIGNAL_OVERFLOW_FLAG = \"SIGNAL_OVERFLOW_FLAG\"\n SEG_REFERENCE_OVERFLOW_FLAG = \"REFERENCE_OVERFLOW_FLAG\"\n SEG_BUSY_FLAG = \"BUSY_FLAG\"\n\n REG_VELOCITY = \"VELOCITY\"\n SEG_VELOCITY= REG_VELOCITY\n \n REG_DISTANCE = \"DISTANCE\"\n SEG_DISTANCE = REG_DISTANCE\n \n def __init__(self):\n # Create some device specific I2C Object\n self.i2c = ...\n \n # Configure control registers\n self.controls = RegisterList(0x62, self.i2c, {})\n self.controls.add(LightLiteV3.REG_ACQ_COMMAND, 0x00, Register.WRITE, {}) \\\n .add(LightLiteV3.SEG_ACQ_COMMAND, 0, 7, [0] * 8)\n\n self.controls.add(LightLiteV3.REG_STATUS, 0x01, Register.READ, {}) \\\n .add(LightLiteV3.SEG_PROC_ERROR_FLAG, 6, 6, [0]) \\\n .add(LightLiteV3.SEG_HEALTH_FLAG, 5, 5, [0]) \\\n .add(LightLiteV3.SEG_SECONDARY_RET_FLAG, 4, 4, [0]) \\\n .add(LightLiteV3.SEG_INVALID_SIGNAL_FLAG, 3, 3, [0]) \\\n .add(LightLiteV3.SEG_SIGNAL_OVERFLOW_FLAG, 2, 2, [0]) \\\n .add(LightLiteV3.SEG_REFERENCE_OVERFLOW_FLAG, 1, 1, [0]) \\\n .add(LightLiteV3.SEG_BUSY_FLAG, 0, 0, [0])\n\n self.controls.add(LightLiteV3.REG_VELOCITY, 0x09, Register.READ, {})\\\n .add(LightLiteV3.SEG_VELOCITY, 0, 7, [0] * 8)\n\n self.controls.add(LightLiteV3.REG_DISTANCE, 0x8f, Register.READ, {})\\\n .add(LightLiteV3.SEG_DISTANCE, 0, 15, [0] * 16)\n \n # Provide useful helper methods\n def measure(self):\n self.controls.set_bits_from_int(LidarLiteV3.REG_ACQ_COMMAND, LidarLiteV3.SEG_ACQ_COMMAND, 0x04, write_after=True)\n \n def distance(self):\n return self.controls.to_int(LidarLiteV3.REG_DISTANCE, LidarLiteV3.SEG_DISTANCE, read_first=True)\n \n def velocity(self):\n return self.controls.to_int(LidarLiteV3.REG_VELOCITY, LidarLiteV3.SEG_VELOCITY, read_first=True)\n\n # Now using your hardware has never been easier\n lidar = LidarLiteV3()\n\n while True:\n lidar.measure()\n print(\"Car is going {} m/s when it was {} m away\".format(lidar.velocity(), lidar.distance()))\n\nDevelopment\n===========\n\nThe code for I2C Register is located in the ``py_i2c_register``\ndirectory. Feel free to contribute by opening a pull request. I try to\ntest and document as much as I can.\n\nSupported Python Versions: 2.7, 3.6\n\nRunning Tests\n-------------\n\nTo run tests a couple python packages are required. To install them you\ncan run the ``test-install`` Make target:\n\n.. code:: bash\n\n make test-install\n\nYou can then run test by executing the ``test`` Make target:\n\n.. code:: bash\n\n make test\n\nTo see a more detailed HTML report you can run the ``test-html`` Make\ntarget. The results will then be saved to ``htmlcov/index.html``.\n\nDistribution\n============\n\nThis repository provides a PIP package called ``py-i2c-register``. To\npublish this distribution a variety of helpers are provided in the\nMakefile.\n\nSetup\n-----\n\nThe `Pandoc `__ tool is required for the release\nprocess along with some miscellaneous Python packages. Please refer to\nthe `Pandoc Website `__ for\ninstallation instructions. You can install the misc. Python packages\nwith the ``dist-install`` Make target:\n\n.. code:: bash\n\n make dist-install\n\nYou can verify that all distribution dependencies are install and\naccessible by running the ``dist-check`` Make target. If it exits\nsuccessfully all dependencies were found.\n\nFinally you must create ``.pypirc`` file in your home directory with the\ncontents:\n\n::\n\n [distutils]\n index-servers=pypi\n\n [pypi]\n repository = https://upload.pypi.org/legacy/\n username = Your Username\n password = Your Password\n\nThis gives the PyPi release tool some basic configuration options and\nyour credentials.\n\nSteps\n-----\n\nThis section details the steps required to release this package.\n\n1. Test\n\n - Ensure that all tests pass by running the ``test`` Make target:\n\n .. code:: bash\n\n make test \n\n2. Clean and build\n\n - Clean up previous distribution materials by running the\n ``dist-clean`` Make target:\n\n .. code:: bash\n\n make dist-clean\n\n - Build the distribution by running the ``dist-build`` Make target:\n\n .. code:: bash\n\n make dist-build\n\n3. Upload\n\n - Upload the distribution to PyPi by running the ``dist-upload``\n Make target:\n\n .. code:: bash\n\n make dist-upload\n\n - This requires that you have a ``.pypirc`` file setup with your\n username and password\n\nThe Makefile provides a useful target which runs steps 1 and 2 under one\ncommand named ``dist``. However the upload step must still be completed\nseparately.\n\n.. |Build Status| image:: https://travis-ci.org/Noah-Huppert/py-i2c-register.svg?branch=master\n :target: https://travis-ci.org/Noah-Huppert/py-i2c-register\n.. |Test Coverage| image:: https://codeclimate.com/github/Noah-Huppert/py-i2c-register/badges/coverage.svg\n :target: https://codeclimate.com/github/Noah-Huppert/py-i2c-register/coverage", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/Noah-Huppert/py-i2c-register", "keywords": "library i2c registers", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "py-i2c-register", "package_url": "https://pypi.org/project/py-i2c-register/", "platform": "", "project_url": "https://pypi.org/project/py-i2c-register/", "project_urls": { "Homepage": "https://github.com/Noah-Huppert/py-i2c-register" }, "release_url": "https://pypi.org/project/py-i2c-register/0.0.8/", "requires_dist": null, "requires_python": "", "summary": "Python wrapper library around the common I2C controller register pattern.", "version": "0.0.8" }, "last_serial": 2753153, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "08c590c5ced7c42c46a6e1e1f124166c", "sha256": "fe7c95be58d1933a2992b0ee3000bbd437a9618252f568af49e370db58617e95" }, "downloads": -1, "filename": "py-i2c-register-0.0.1.tar.gz", "has_sig": false, "md5_digest": "08c590c5ced7c42c46a6e1e1f124166c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13492, "upload_time": "2017-04-04T15:39:43", "url": "https://files.pythonhosted.org/packages/76/bc/810e200ce20964c216c8bebb57801bb3e8c9a7fad678364ef0eec33c76f8/py-i2c-register-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "75d9a6360a4ee524b1835026c49531e9", "sha256": "ec36133b11891cae50db901c4499a0645d5069e1284989fe9a89951929318cdf" }, "downloads": -1, "filename": "py-i2c-register-0.0.2.tar.gz", "has_sig": false, "md5_digest": "75d9a6360a4ee524b1835026c49531e9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13493, "upload_time": "2017-04-04T15:41:45", "url": "https://files.pythonhosted.org/packages/bf/64/32eb86efbe91f165d764105a60ba5c5a61bfa8e5799225fe2f5149dc42e8/py-i2c-register-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "02bfe771539154400f7b9f6754d7692e", "sha256": "d6888ce14924dadff8ff26930430196571289059ed8e69a0f3d2a52f36ab5a54" }, "downloads": -1, "filename": "py-i2c-register-0.0.3.tar.gz", "has_sig": false, "md5_digest": "02bfe771539154400f7b9f6754d7692e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15083, "upload_time": "2017-04-04T16:49:47", "url": "https://files.pythonhosted.org/packages/75/65/f6ba24fa25495d99e702798d84c3037f9bdbb15c794336e3a4fc9ce701f8/py-i2c-register-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "6c46d8006bf0007926ebc74df9b2aa02", "sha256": "9826f2f1683f5de9539d668f056b1a57b2628783edde0329994dcedcd68ac18d" }, "downloads": -1, "filename": "py-i2c-register-0.0.4.tar.gz", "has_sig": false, "md5_digest": "6c46d8006bf0007926ebc74df9b2aa02", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15094, "upload_time": "2017-04-04T16:55:26", "url": "https://files.pythonhosted.org/packages/b7/97/a0ed424e24c614020776a12461521cc88f1e104221d059e5b2297d783d69/py-i2c-register-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "35347ca57102854cd38e5369def83665", "sha256": "832def38050839bcf07f952ad06ea1cf5d790f51e7dd901068e6ef1a3ce721ca" }, "downloads": -1, "filename": "py-i2c-register-0.0.5.tar.gz", "has_sig": false, "md5_digest": "35347ca57102854cd38e5369def83665", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15096, "upload_time": "2017-04-04T17:01:40", "url": "https://files.pythonhosted.org/packages/7e/dd/77ececa1f1bb8c7706e04d3bb86bde74399a3bb7deb3408434f5b28289f4/py-i2c-register-0.0.5.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "8fcbe06c3c3076cf2bff622a7c9a0612", "sha256": "c9df83df480728093ba6056e3789d74a4c4692c9727e508e26bcbc46e5c49e2e" }, "downloads": -1, "filename": "py-i2c-register-0.0.6.tar.gz", "has_sig": false, "md5_digest": "8fcbe06c3c3076cf2bff622a7c9a0612", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15112, "upload_time": "2017-04-04T17:04:50", "url": "https://files.pythonhosted.org/packages/19/41/fc689c1ea6285571b9648c2e4b1cfdda5e7db45e6e5fd88f24e64ac37024/py-i2c-register-0.0.6.tar.gz" } ], "0.0.7": [ { "comment_text": "", "digests": { "md5": "7a321f8c03cfd6c17819c6cd5108f68e", "sha256": "87db22a037f222cb0774b18e37ba38340b96a7f5b9899d8049561c26de06dfbc" }, "downloads": -1, "filename": "py-i2c-register-0.0.7.tar.gz", "has_sig": false, "md5_digest": "7a321f8c03cfd6c17819c6cd5108f68e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16157, "upload_time": "2017-04-04T20:48:23", "url": "https://files.pythonhosted.org/packages/c5/bc/481ca780b7c99f150aa6194090fc72608b3d389c53e5761736802f24ab9e/py-i2c-register-0.0.7.tar.gz" } ], "0.0.8": [ { "comment_text": "", "digests": { "md5": "18909219c7f9e1c84885b7a6bf706137", "sha256": "42ac9c9475252a177a08745b34888d69c91d69149249cb50c7faf082127094a7" }, "downloads": -1, "filename": "py-i2c-register-0.0.8.tar.gz", "has_sig": false, "md5_digest": "18909219c7f9e1c84885b7a6bf706137", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16241, "upload_time": "2017-04-04T21:00:37", "url": "https://files.pythonhosted.org/packages/d4/83/9cdb8238b72eab114a6fc101598a44bf0749e0e05f386aa4f3f0553f86e2/py-i2c-register-0.0.8.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "18909219c7f9e1c84885b7a6bf706137", "sha256": "42ac9c9475252a177a08745b34888d69c91d69149249cb50c7faf082127094a7" }, "downloads": -1, "filename": "py-i2c-register-0.0.8.tar.gz", "has_sig": false, "md5_digest": "18909219c7f9e1c84885b7a6bf706137", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16241, "upload_time": "2017-04-04T21:00:37", "url": "https://files.pythonhosted.org/packages/d4/83/9cdb8238b72eab114a6fc101598a44bf0749e0e05f386aa4f3f0553f86e2/py-i2c-register-0.0.8.tar.gz" } ] }