2 releases

0.1.1 Aug 7, 2020
0.1.0 Jul 28, 2020

#92 in #register

MIT license

17KB
372 lines

bitinfo

CircleCI Version info

bitinfo is a tool to make it easier work with registers by decoding their values.

What?

Let's start with an example of how the tool works. Say you're debugging a new sensor and want to see if a register holds the expected value. You read it and get a cryptic 0x4E0. This can be decoded by hand, but that's where bitinfo comes in. Isn't this better than decoding by hand?

borgel$ bitinfo STPM.DSP_CR3.0x4E0
 STPM.DSP_CR3 0x4E0 -> |                                           |
-----------------------+-------------------------------------------+-----------------------------------------------------------------------
 SAG_TIME_THR          | 1248                                      | The sag time
 ZCR_SEL               | V1 / 7.8125 kHz                           | Selection bit for ZCR/CLK pin, (output depends on ZCR/CLK enable bit)
 ZCR_EN                | CLK                                       |
 TMP_TOL               | 12.5%                                     | Tamper tolerance
 TMP_EN                | tamper disable                            | Tamper detect enable
 S/W Reset             | 0x0                                       | Software reset
 S/W Latch 1           | 0x0                                       |
 S/W Latch 2           | 0x0                                       |
 S/W Auto Latch        | Disabled                                  | Auto latch
 LED_OFF1              | LED output on                             | LED pin output disable
 LED_OFF2              | LED output on                             | LED pin output disable
 EN_CUM                | Cumulative is the sum of channel energies | Cumulative energy calculaton
 REF_FRQ               | 50 Hz                                     | Reference line frequency

bitinfo lets the developer specify configuration files describing a hierarchy of device registers (in this case STPM.DSP_CR3) then decode arbitary numeric values based on those descriptions.

Get It

For now available on all platforms with a Rust toolchain at http://crates.io. Just

cargo install --force bitinfo
# the `--force` forces `cargo` to install the latest version if you have an earlier one

Use It

Using bitinfo requires two areas of knowledge; how to invoke it and how to configure register descriptions.

Invocation

Once installed, bitinfo is a single binary which may be invoked from a shell. bitinfo will help you describe a number, even if it doesn't know how to decode it as a specific register value.

borgel$ bitinfo 0xa5
165 -> 165 0xA5 0b10100101
borgel$ bitinfo 0x0F0
 240 | 240 0xF0 0b11110000

Any common numerical format works fine (0x hex, 0b binary, and 0 decimal).

It can also describe the i'th bits set.

borgel$ bitinfo --bits 0xa5
 165 | 165 0xA5 0b10100101
-----+---------------------
     | 0th set
     | 2th set
     | 5th set
     | 7th set

But the tool is much more useful when describing values for which it has descriptive configuration files. If working in a directory tree which includes bitinfo configuration files, queries may be made specifying a certain device.

borgel$ bitinfo R2-Device.Register1.0x1A
 R2-Device.Register1 0x1A -> |
-----------------------------+--------------------
 A nibble of decimals        | 10
 A bamboozler to control     | Bamboozler enabled

In order to decode a specific register bitinfo must

  • Have the appropriate configuration file visible along its search path
  • Be invoked with a named reference to the register to decode with, which must exist in an appropriately named, visible, config file

Keep in mind

  • Separators must be any combination of .:/
  • Device and register names are case sensitive and must exactly match the configuration file

Configuration

bitinfo uses configuration files to describe registers and fields which it can decode. To see a heavily annotated example configuration which describes all allowable fields check this sample in the examples directory.

Configuration files must be named following the pattern .bitinfo.<optional name>.yaml to be detected by the tool. The optional name may be handy for organisational purposes to allow a project to clearly describe multiple configuration files in one place but may be omitted. It is not current used during decoding.

bitinfo searches for configuration files in two ways: checking every directory upward including the current one, and by specifying a directory on the commandline. Each execution bitinfo will search these paths and load every config file matching the name pattern. It searches all configurations together in order to resolve a user query, so a large project can spread register descriptions across many files.

The expected use case is for a project to include configurations either at the root of the project (so they are visible everywhere below) or to include configurations specific to certain modules near those modules' source.

Examples

An unusually simple configuration may look something like this:

R1-Device:
   description: This is the top level of organization. Think part number like LIS2DH or STM32F104
   preferred_format: hex
   fields:
      BField1:
         start: 0
         width: 1
         description: I'm not sure what a bamboozler is, are you?
         # sometimes it can be handy to describe what the flag states mean
         patterns:
            0b0: Bamboozler disabled
            0b1: Bamboozler enabled

To a query with this device would look like this

# bamboozler disabled
borgel$ bitinfo --configs ../examples/ R1-Device.0
 R1-Device 0x1A -> |                     |
-------------------+---------------------+---------------------------------------------
 BField1           | Bamboozler disabled | I'm not sure what a bamboozler is, are you?

# and with the bamboozler enabled
borgel$ bitinfo --configs ../examples/ R1-Device.1
 R1-Device 0x0A -> |                    |
-------------------+--------------------+---------------------------------------------
 BField1           | Bamboozler enabled | I'm not sure what a bamboozler is, are you?

This is somewhat simplified. The most common configurations include at least one additional layer of organization and look something more like this:

R2-Device:
   description: This is the top level of organization. Often an entire device (CPU, complex sensor, etc)
   registers:
      Register1:
         description: A second level of organization. Think of a peripheral or register in a CPU or sensor
         fields:
            A decimal slice:
               start: 0
               width: 4
               preferred_format: dec
            BField2:
               start: 4
               width: 1
               patterns:
                  0b0: Bamboozler disabled
                  0b1: Bamboozler enabled

Note that registers here can be nested to arbitrary depth.

To a query with the above device, the command would look like this

borgel$ bitinfo --configs ../examples/ R2-Device.Register1.0x1A
 R2-Device.Register1 0x1A -> |
-----------------------------+--------------------
 A nibble of decimals        | 10
 A bamboozler to control     | Bamboozler enabled

Please note the above examples were run relative to the source directory in the repository, which is why the examples directory is passed in as an explicit search path.

See the examples directory for detailed explanations of the available fields and their usage.

Known Limitations

  • Though there is no reason it needs to be limited to 32 bit registers, there are a places where this is assumed
  • Only available via a fully working Rust install (but on any platform!)
  • Limited output format options (specifically, no options)
  • Probably more. PRs welcome!

Dependencies

~8–18MB
~222K SLoC