Code Monkey home page Code Monkey logo

cyanobyte's Introduction

Cyanobyte - Machine readable datasheets for documentation & codegen

logo

This project is an example of how to describe peripherals with an intermediary layer (YAML files) which can be used to generate library files for a peripheral.

It can also generate reference documentation for a peripheral, useful for embedding into datasheets.

The tool works well for I2C devices, while SPI support is in progress.

This is not an official Google product.

Setup

Note: This project requires Python3. You can install using pip

pip install cyanobyte

Run Codegen

cyanobyte-codegen -t templates/doc.md -o ./build peripherals/MCP4725.yaml

Options

  • -t - A template file. You can provide multiple template files.
  • -o - The output directory where files will be generated.
  • -e - The directory that emboss folder is stored.
  • -d - Debug flag to print out additional information.
  • -c - Clean the output directory before generating files.

One or multiple files can be passed as an argument.

Clean

rm -rf ./build

Run Validator

cyanobyte-validator peripherals/MCP9808.yaml

One or multiple files can be passed as an argument.

Peripheral YAML file

The current spec is described in docs/cyanobyte.md. You can find all examples in the peripherals/ directory.

Test

Lint

python3 -m pylint --rcfile=test/pylintrc cyanobyte/*.py
python3 -m pylint --rcfile=test/pylintrc test/sampleData/*.py

Unit test

python3 -m unittest test.test_codegen

Templates

The templates directory includes a set of canonical templates which can be used with this codegen tool.

The peripherals directory includes a set of peripheral description files that have been created along with the project. It is not an exhaustive list.

Development setup

pip install -r requirements.txt --user

For more advanced development, also install the dev list. pip install -r requirements-dev.txt --user

Projects using Cyanobyte

File an issue or pull request to add your project to the list.

Contributors

Contributions are welcome! See CONTRIBUTING.md for more information.

When a pull request is submitted, a continuous integration task is run. The CI task must be completed successfully before a patch is merged. You can see the specific rules run in cloudbuild.yaml.

License

See LICENSE

cyanobyte's People

Contributors

chloeyutianyi avatar chrisfrederickson avatar fleker avatar howellhou avatar osterwood avatar polfeliu avatar rohitsam avatar sheppardd1 avatar smootz6 avatar tgordon555 avatar tlentali avatar urish avatar utnansn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cyanobyte's Issues

Add copyright year to spec info

To do the generation of copyright headers, one needs to know both the copyright owner and the year of the copyright. Both can be represented as strings that we plop right into the header, as shown in #20.

Support for template directories

As the templates increase in complexity, they will almost certainly be comprised of multiple files that will always be used together. We should allow the user to pass in a template directory.

Eventually, do we want to have a set of builtin templates that are referenced by name (e.g. python instead of a path to a directory)?

Template options configuration file

As template files grow more complex and customizable, it may be useful to have a standardized way of providing certain types of options through a config file while generating.

codegen ... --config ./my-config.yaml

This could be organized in a flat or extended way. This object would get passed into each template file to allow for different options to be selected.

Flat:

smbusLib: smbus
python:
  smbusLib: smbus2

Spec should include endianness

If the communication protocol is i2c, there should be a way to specify endianness. Some devices are little endian, while others are big endian. If there's a mismatch, all of the data will be sent incorrectly.

i2c:
    addressType: '7-bit'
    address: 0x18
    addressMask: 0x78
    endian: little endian // or big endian

Pseudo-yaml should support functions as parameter

What if I need an operation that pseduo-yaml doesn't support? Allow parameters to be of type function. In C this would be a function pointer. In Java this would be an interface. It's just some way of making the spec flexible enough to support the most esoteric operations.

Add changelog generation

Once we start tagging releases, we can add this to the cloud build sequence to get changelogs:

- name: 'gcr.io/cloud-builders/git'
  entrypoint: 'bash'
  args: ['-c', './git-presubmit-linter/tools/changelog.sh > changelog.txt']
  id: 'Generate changelog'
  waitFor: ['Download Git Presubmit Linter']

Naming for `functions`

The top-level category of functions is probably not the best name, if its intention is to describe the various fields and properties in the register, as well as computed values. Functions elicits more of a general compute tool, such as a function called reset, whereas this section seems to describe something like virtual registers, fields, properties, values, parameters, or some other synonym.

Codegen for pseudo-yaml

Allow codegen to render something like:

A step 1 would allow for simple input/output and logic. Additional support for pseudo-yaml can be part of follow-up.

            - asTemp:
                input: test
                variables:
                    - temp: float32
                logic:
                    - if: value > 256
                        - temp:= value
                    - else:
                        - temp:= 0
                return: temp

Add a `package` field to spec

Libraries are based around a logical hierarchy. In some languages, like Kotlin, this hierarchy is known as a package. Providing a package can help in the case of generating a variety of files in one command.

Package names are typically inverses of the owners' website.

info:
    title: Mcp4725
    package: com.microchip

Support register-level access in python generated code

We should probably support lower-level register access in the generated python code. There may be peripherals with edge cases that the value level access can not easily accommodate. Giving access at the register level ensures that the generated code is always usable.

If we do support register level access, the python generated code should use python's builtin getters and setters.

Add BLE?

Should we add wireless specs such as BLE as goals for communication protocols in the spec?

Spec validator tool

There should be a tool that validates possible fields. This could be done as a custom linter, or convert the YAML to JSON as part of the linter and use JSON Schema.

Once this happens, we should add CI tests for it and keep it up to date as we make spec changes.

Pseudoyaml - Consider adding delay function

There may be a need to manually add delays to execution of a pseudoyaml block.

This can be added as another function.

exampleWhileLoop:
    input:
        - x: int32
    logic:
        - i:= 0
        - while: i < 10
            - acc := acc + i
            - i := 1
            - delay: 500 // milliseconds by default?
        - return: acc

Spec for calling functions with a function

How to call a different function, with parameters

calcFahrenheit:
  - logic:
    - a : = temp_celsius
      - i: 7

Becomes something like:

def calcFahrenheit():
  a = temp_celsius(i = 7)

Order matters for languages without named arguments.

Python docstring format

We should standardize the python docstring format (and other style-related things). Thoughts on which type to use?

Register spec compatibility with CMSYS

Curious if you've consider compatibility with the CMSYS-SVD spec for describing registers.

It's used by ARM to describe variant of hardware register of Cortex-M variant, but I believe most of the concept they're using could be applied to peripherals register as well:

Example:

...
  <register>
          <name>SR</name>
          <description>Status Register</description>
          <addressOffset>0x04</addressOffset>
          <size>16</size>
          <access>read-write</access>
          <resetValue>0x00000000</resetValue>
          <resetMask>0xD701</resetMask>

          <fields>
            <!-- RUN: Shows if Timer is running -->
            <field>
              <name>RUN</name>
              <description>Shows if Timer is running or not</description>
              <bitRange>[0:0]</bitRange>
              <access>read-only</access>
              <enumeratedValues>
                <enumeratedValue>
                  <name>Stopped</name>
                  <description>Timer is not running</description>
                  <value>0</value>
                </enumeratedValue>
                <enumeratedValue>
                  <name>Running</name>
                  <description>Timer is running</description>
                  <value>1</value>
                </enumeratedValue>
              </enumeratedValues>
            </field>
...

Fix package discrepancy if missing

If a peripheral omits a package name, or misspells it, the validator is fine. However, the codegen will throw an error if it cannot be found.

Specification extensions

Have some sort of way to provide additional peripheral data in the spec if it doesn't have a specific key.

Enable a hardware chip to go to two different addresses

Some I2C devices can have more than one possible hardware address, often with a jumper or pin you drive HIGH/LOW.

To handle these, we could have a constant address or a list. If it's a list, transform the constructor to have the address. This address is then validated before continuing.

i2c:
    address:
        - 0x18
        - 0x19 # If GPIO1 is logic HIGH
mcp9808 = Mcp9808(0x18)

Should this be an enum that is exported?

mcp9808 = Mcp9808(Mcp9808.I2C_ADDRESS_0x18)

Add CI task to check dependency licenses?

We can create a Cloud Build configuration which only gets triggered when the requirements.txt is changed, to check the license for each one to verify that they are good OSS licenses like MIT or Apache-2.0. This can be through a shell script.

Should we add this extra CI task, or is it not worth the time?

Integrate CI

We should incorporate CI tests on each pull request. If we go with Cloud Build, we should be able to easily hook into things like cloud storage to host generated files.

Make spec->license->name spdx compliant

Using a standardized set of labels will promote the use of codegen and other automated tooling. SPDX has a formal list of licenses and identifiers.
https://spdx.org/licenses/

In the spec, we'd modify:

license:
        name: 'Apache-2.0'
        url: 'https://www.apache.org/licenses/LICENSE-2.0.html'

But since this is a standard, we could omit the url field as it'd only link to one place by default.

license:
        name: 'Apache-2.0'

Possible issues with path in Windows

Currently, all of the paths are hard-coded to use forward slashes. This may cause issues in Windows. We should us the os.path package when dealing with paths.

    packagePath = peripheralData['package'].replace('.', '/')
    outputFilePath = os.path.join(outputDir, os.path.normpath(packagePath))

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.