RFM69 ChibiOS driver

This is the page for my driver for HopeRF's RFM69HW/HCW radio module for the ChibiOS operating system.


The driver doesn't have much functionalities for now, but the essentials are here to do useful work:

  • Packet transmission and reception
  • Direct read / write access to RFM69 registers, so you can put basically any settings you could want.
  • The driver is fully interrupt-driven, and thus integrates well this ChibiOS.
  • It doesn't use internal copy, data is directly read into the user-provided buffer

LowPowerLab driver for the Arduino was my starting point, but they're quite different now:

  • The only transmission mode supported is packet that can be fitted in RFM69 FIFO (that is 61 bytes useful payload).
    • Only variable length packet are supported (not RFM69's "fixed size packet"), stated another way, you lose one payload byte to carry the packet length.
  • Acknowledge mode is not supported
  • The driver doesn't stuff additional bytes inside the payload (sender id byte, target id byte and a control byte to request for ACK), however there's a compatibility mode so this driver produces frames that are compatible with LowPowerLab's.

Understanding RFM69 FIFO

(In short: if there's a packet you haven't read and you send a packet, you lose the packet you haven't read).

Setting up


This driver is using 6 wires on the RFM69: 4 for SPI communication, an interrupt line used to notify the MCU that a packet has been read or written, and a reset line that in my view is essential.



ChibiOS internals

void rfm69ObjectInit(RFM69Driver *devp)
description Initialize the driver
devp RFM69Driver * pointer to the driver to be initialized

Initializing & stopping

void rfm69Start(RFM69Driver *devp, RFM69Config *config) void rfm69Stop(RFM69Driver *devp) {

Reading and writing

void rfm69Read(RFM69Driver *devp, void *buf, uint8_t bufferSize)
description Block until data is available, then return it. If the buffer is big enough to accomodate the payload and an additionnal byte, the payload is '\0'-terminated.
devp pointer to the initialized driver
buf pointer to the buffer to receive the data
bufferSize available size in the buffer

NB: there's only one buffer in the RFM69 used both for reading and writing. If a packet was being received when sending a packet, the received packet is discarded.

Low level access to RFM69

void rfm69WriteReg(RFM69Driver *devp, uint8_t addr, uint8_t v) uint8_t rfm69ReadReg(RFM69Driver *devp, uint8_t addr) void rfm69SetFrequency(RFM69Driver *devp, const rfm69_frequency_t *freq) void rfm69SetBitrate(RFM69Driver *devp, const rfm69_bitrate_t *br) void rfm69Reset(ioportid_t ioport, uint16_t pad) unsigned int rfm69ReadAvailable(RFM69Driver *devp) uint8_t rfm69ReadRSSI(RFM69Driver *devp) void rfm69Send(RFM69Driver *devp, uint8_t bufferSize, const void *buf)