Firmware
========
The firmware uses `platformio `_ and the
Arduino framework.
The common dependencies are
+ Mikal Hart's `Streaming `_
library
+ Mike McCauley's `RadioHead `_ library
+ Rhys Weatherley's `Crypto `_ library
Additionally, the LoPy4 platform uses Jan Mrázek's
`SmartLeds `_
library to control the WS2812 LED.
Board support
-------------
The ``include/board.h`` header is used to pull in the appropriate
board-specific definitions. The board definition is setup in
the `platformio.ini` configuration file. The current board definitions
are
+ ``__feather__`` for the Feather M0 with RFM95 radio. The board-specific
code is in ``src/feather.cpp``.
+ ``__lopy4__`` for the LoPy4. The board-specific code is in
``src/lopy4.cpp``.
EEPROM
------
The eeprom library provides support for 24LCxxx I2C EEPROMs; in the future,
this may expand to the 25LCxxx SPI EEPROMs. Boards are expected to have a
single EEPROM at the default address (EEPROM_BASE_ADDRESS), and a single
instance of this class is instantiated in the main code. It provides the
following methods:
+ ``bool write(uint16_t addr, uint8_t *data, uint8_t len)`` attempts to
write ``len`` bytes of ``data`` starting at ``addr``. The maximum length
of data that can be written this way is governed by the EEPROM's size;
a 24LC256 can write up to 64 bytes of data at a time.
+ ``bool wait()`` blocks until the EEPROM has finished writing. This is
referred as ACK polling in the datasheet; essentially, after writing
a block of data, the EEPROM needs to take some time to write the data.
It will be unavailable for other operations until it has completed its
write cycle. This really only needs to be called shortly after writing
if more writes are needed (e.g. when writing a large buffer of data).
+ ``bool read(uint16_t addr, uint8_t *data, uint8_t len)`` attempts to
read ``len`` bytes of ``data`` from ``addr``; the maximum read size
is the same as the maximum write size.
EEPROM support is included with the ``include/eeprom.h`` header, and
the source is in ``src/eeprom.cpp``.
Generally, the EEPROM is only needed at boot up to read the node's
identity, but it is available for future uses as needed, subject to
the memory layout described below.
The EEPROM's memory layout is
+ $0000 - $0003: Node ID, a uint32
+ $0004 - $0023: Identity key, a 32-byte Ed25519 private key
+ $0024 - $002C: The RNG seed
+ $002D - $0032: The node's provisioning datetime
At a high level, the following blocks are used:
+ $0000 - $0032: node's identity
Identity
--------
Central to this project is the notion of a node's identity. The
:doc:`identity` docs give an overview of this. The identity header
defines a node's identity in the ``Identity`` structure, and provides
the following functions:
+ ``bool load_identity(EEPROM_24LC &eeprom)`` tries to read the node's
identity information from the eeprom and performs the necessary setup
like deriving the public key. If this fails, startup must fail.
+ ``bool zeroise_identity(EEPROM_24LC &eeprom)`` erases the node's
identity. This information is no longer recoverable from the node.
It also makes the node's identity available via the ``identity`` variable.
Radio
-----
This provides support for the LoRa radio; it may eventually encompass
support for other radios. It requires the following definitions to
be present, which should be done in the relevant board header:
+ ``RF95_CS``
+ ``RF95_RST``
+ ``RF95_INT``
These are required by the RadioHead library to set up the radio driver.
The header file, ``include/radio.h``, provides the following definitions
as well:
+ ``RF_FREQ`` (which defaults to 915.0 MHz) sets the centre frequency for
the radio.
+ ``RF_INIT_TXPWR`` (which defaults to 20) sets the initial power when
the radio is enabled.
The following functions are provided (and implemented in ``src/radio.cpp``):
+ ``bool enable_lora()`` enables and activates the radio, placing it into
an idle state.
+ ``void disable_lora()`` disables the radio by putting it into sleep
mode and driving the RST pin low.
+ ``void lora_tx_power(int8_t power)`` sets the transmitter power for the
radio.