Skip to main content

A framework for accessing integrated circuits via descriptors

Project description

Frico - Framework for Integrated Circuits

PyPI version

Frico is a framework for interfacing with integrated circuits. It uses Python's data descriptor functionality to present an interface similar to common database ORMs like Django or SQLAlchemy. A device is defined as a class, the attributes of that class represent the types of data stored in the device's registers, and those attributes can be read or written on an instance of the device class with the framework managing IO.

Installation

Frico is published on PyPI and is simple to install via pip, for example:

python3 -m pip install frico

Frico only supports Python 3 and includes type annotations.

If you want to contribute to Frico, you can set up a development environment using the provided Makefile:

git clone git@github.com:mmangus/frico.git &&\
cd frico &&\
make

Use make test to test changes (runs automatically pre-commit).

Getting started

A Frico project will have three layers. Devices contain blocks and blocks contain parsers, like so:

|==========================|
| Device                   |
|--------------------------|
|   RegisterBlockA         |
|..........................|
|     RegisterParser(0x00) |
|     RegisterParser(0x01) |
|--------------------------|
|   RegisterBlockB         |
|..........................|
|     RegisterParser(0x02) |
|     RegisterParser(0x03) |
|     ...etc               |
|--------------------------|
|   ...etc                 |
|==========================|

A chip is represented as a subclass of I2CDevice (SPIDevice coming soon), and the data stored on of that chip is represented by subclasses of RegisterBlock. A RegisterBlock can translate between a high-level Python object and a low- level representation of that object in the device registers. Blocks use RegisterParsers to access specific addresses in the device registers and manipulate their values.

Suppose you have a very simple real-time clock that keeps the current time using 6 8-bit registers: second, minute, hour, day, month, and year (00-99), all encoded as binary-coded decimal (BCD) - the first nibble of 4 bits in each register is the 10s place and the second nibble is the 1s place, like this:

|=======================================================================|
| Addr. | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
|-------|-------------------------------|-------------------------------|
| 0x00  |      Seconds - tens           |         Seconds - ones        |
| 0x01  |      Minutes - tens           |         Minutes - ones        |
| 0x02  |        Hours - tens           |           Hours - ones        |
| 0x03  |          Day - tens           |             Day - ones        |
| 0x04  |        Month - tens           |           Month - ones        |
| 0x05  |         Year - tens           |            Year - ones        |
|=======================================================================|

Frico includes an abstract DatetimeRegisterBlock which lets you translate datetime objects to/from the device's registers with minimal effort. Subclasses of DatetimeRegisterBlock define attributes of type RegisterParser[int] to map components of a datetime object to the values of specific register addresses. In this example, we can use the built-in BCDParser for almost every register. The only exception is the year, which should have 2000 added to its value on read and subtracted from a given value on write.

from datetime import datetime
from frico.blocks import DatetimeRegisterBlock
from frico.devices import I2CDevice
from frico.parsers import BCDParser
from frico.typing import RegisterState


class YearParser(BCDParser):
    def _value(self) -> int:
        return super()._value() + 2000

    def _prepare_update(self, value: int) -> RegisterState:
        value -= 2000
        return super()._prepare_update(value)


class Time(DatetimeRegisterBlock):
    second = BCDParser(0x00)
    minute = BCDParser(0x01)
    hour = BCDParser(0x02)
    day_of_month = BCDParser(0x03)
    month = BCDParser(0x04)
    year = YearParser(0x05)


class RTC(I2CDevice):
    I2C_ADDRESS = 0x68  # the I2C device address
    I2C_READ_LEN = 0x06  # number of bytes readable from the device
    I2C_READ_START = 0x00
    time = Time()


rtc = RTC()  # sets up I2C communication via SMBus
print(rtc.time)  # accesses the clock registers and prints a datetime
rtc.time = datetime.now()  # set the clock registers from a datetime

For a more complete example, see FricoRTC

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

frico-0.0.7.tar.gz (12.5 kB view details)

Uploaded Source

Built Distribution

frico-0.0.7-py3-none-any.whl (12.7 kB view details)

Uploaded Python 3

File details

Details for the file frico-0.0.7.tar.gz.

File metadata

  • Download URL: frico-0.0.7.tar.gz
  • Upload date:
  • Size: 12.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/3.7.3 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.8.5

File hashes

Hashes for frico-0.0.7.tar.gz
Algorithm Hash digest
SHA256 292295e1661ff8468163bbde79935dd957ee98b1a2ccaa7b2ac7d1e49282fc9c
MD5 8732f70a13777efcaf83a4d26db25062
BLAKE2b-256 9508a09882003c3142dee1380f215ab7775f75b495f3bb4cbb8ce6d8a99fc3df

See more details on using hashes here.

File details

Details for the file frico-0.0.7-py3-none-any.whl.

File metadata

  • Download URL: frico-0.0.7-py3-none-any.whl
  • Upload date:
  • Size: 12.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/3.7.3 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.8.5

File hashes

Hashes for frico-0.0.7-py3-none-any.whl
Algorithm Hash digest
SHA256 5f3fbe52952b5b8c43e6c63a0179e9c1ab6f864207a89d9d277632384ae34ea4
MD5 2da859c9f31f99e4e29c42ca79392143
BLAKE2b-256 3852eeb0cca5946a4b6bd404281c6395f0b6bc950fb309d7ff933444ea18c3d1

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page