Documentation ¶
Overview ¶
The SX1276 package interfaces with a HopeRF RFM95/96/97/98 LoRA radio connected to an SPI bus.
The RFM9x modules use a Semtech SX1276 radio chip. This package has also been tested with a Dorji DRF1278 module and it should work fine with other radio modules using the same chip. Note that the SX1276, SX1277, SX1278, and SX1279 all function identically and only differ in which RF bands they support.
The driver is fully interrupt driven and requires that the radio's DIO0 pin be connected to an interrupt capable GPIO pin. The transmit and receive interface uses a pair of tx and rx channels, each having a small amount of buffering.
In general, other than a few user errors (such as passing too large a packet to Send) there should be no errors during the radio's operation unless there is a hardware failure. For this reason radio interface errors are treated as fatal: if such an error occurs the rx channel is closed and the error is recorded in the Radio struct where it can be retrieved using the Error function. The object will be unusable for further operation and the client code will have to create and initialize a fresh object which will re-establish communication with the radio chip.
Limitations ¶
This driver uses the SX1276 in LoRA mode only.
Only the explicit header mode is supported, this means that spreading factor 6 cannot be used and thus the maximum data rate available is 21875bps.
The methods on the Radio object are not concurrency safe. Since they all deal with configuration this should not pose difficulties. The Error function may be called from multiple goroutines and obviously the TX and RX channels work well with concurrency.
Index ¶
Constants ¶
const ( DataNoAck = iota // data packet, no ack requested DataAck // data packet, ack requested Ack // ACK packet Special // special packet, unused for now )
Packet kinds
const ( REG_FIFO = 0x00 REG_OPMODE = 0x01 REG_FRFMSB = 0x06 REG_PACONFIG = 0x09 REG_OCP = 0x0B REG_LNA = 0x0C REG_FIFOPTR = 0x0D REG_FIFOTXBASE = 0x0E REG_FIFORXBASE = 0x0F REG_FIFORXCURR = 0x10 REG_IRQMASK = 0x11 REG_IRQFLAGS = 0x12 REG_RXBYTES = 0x13 REG_MODEMSTAT = 0x18 REG_PKTSNR = 0x19 REG_PKTRSSI = 0x1A REG_CURRSSI = 0x1B REG_HOPCHAN = 0x1C REG_MODEMCONF1 = 0x1D REG_MODEMCONF2 = 0x1E REG_SYMBTIMEOUT = 0x1F REG_PREAMBLE = 0x21 REG_PAYLENGTH = 0x22 REG_PAYMAX = 0x23 REG_FIFORXLAST = 0x25 REG_MODEMCONF3 = 0x26 REG_PPMCORR = 0x27 REG_FEI = 0x28 REG_DETECTOPT = 0x31 REG_DETECTTHR = 0x37 REG_SYNC = 0x39 REG_DIOMAPPING1 = 0x40 REG_DIOMAPPING2 = 0x41 REG_VERSION = 0x42 REG_TCXO = 0x4B REG_PADAC = 0x4D REG_FORMERTEMP = 0x5B )
const ( MODE_SLEEP = iota MODE_STANDBY MODE_FS_TX // frequency synthesis TX MODE_TX // TX MODE_FS_RX // frequency synthesis RX MODE_RX_CONT // RX continuous MODE_RX_SINGLE // RX single MODE_CAD // channel activity detection )
const ( // IRQ mask and flags registers IRQ_RXTIMEOUT = 1 << 7 IRQ_RXDONE = 1 << 6 IRQ_CRCERR = 1 << 5 IRQ_VALIDHDR = 1 << 4 IRQ_TXDONE = 1 << 3 IRQ_CADDONE = 1 << 2 IRQ_FHSCHG = 1 << 1 IRQ_CADDETECT = 1 << 0 )
Variables ¶
var Configs = map[string]Config{
"lora.bw500cr45sf7": {0x92, 0x74, 0x04, "31250bps, 20B in 14ms"},
"lora.bw125cr45sf7": {0x72, 0x74, 0x04, " 7813bps, 20B in 57ms"},
"lora.bw125cr48sf12": {0x78, 0xc4, 0x04, " 183bps, 20B in 1712ms"},
"lora.bw31cr48sf9": {0x48, 0x94, 0x04, " 275bps, 20B in 987ms"},
"lorawan.bw125sf12": {0x72, 0xc4, 0x0C, " 250bps, 20B in 1319ms, -137dBm"},
"lorawan.bw125sf11": {0x72, 0xb4, 0x0C, " 440bps, 20B in 660ms, -136dBm"},
"lorawan.bw125sf10": {0x72, 0xa4, 0x04, " 980bps, 20B in 370ms, -134dBm"},
"lorawan.bw125sf9": {0x72, 0x94, 0x04, " 1760bps, 20B in 185ms, -131dBm"},
"lorawan.bw125sf8": {0x72, 0x84, 0x04, " 3125bps, 20B in 103ms, -128dBm"},
"lorawan.bw125sf7": {0x72, 0x74, 0x04, " 5470bps, 20B in 57ms, -125dBm"},
"lorawan.bw250sf7": {0x82, 0x74, 0x04, "11000bps, 20B in 28ms, -122dBm"},
}
Configs is the table of supported configurations and their corresponding register settings. In order to operate at a new bit rate the table can be extended by the client. The names use bw: bandwidth in kHz, cr: coding rate 4/5..4/8, and sf: spreading factor.
Functions ¶
func JLLEncode ¶
JLLEncode encodes a JeeLabs LoRa (JLL) packet.
A JLL packet consists of a header byte, a packet type byte, the payload, and optionally an info trailer. If the rssi parameter is 0 JLLEncode does not append the info trailer.
The packet header byte is very similar to the rf12 JeeLabs header: http://jeelabs.org/2011/06/10/rf12-broadcasts-and-acks/index.html Bit 7 ctrl: 0=data 1=special. Bit 6 dest: 0=to-GW 1=from-GW. Bit 5 ack : 0=no-ack 1=ack-req. Bits 0-4: 32 nodes, 0=broadcast, 31=anonymous tx-only no-ack nodes. The following ctrl/ack combinations are used: c=0, a=0 : data, no ack requested. c=0, a=1 : data, ack requested. c=1, a=0 : ack. c=1, a=1 : special (undefined for now).
The packet type byte indicates what the format of the payload is and supports 127 different payload formats using bits 0..6. The topmost bit is used to indicate whether an info trailer is present (value 1) or not (value 0). The info trailer consists of 2 bytes: min(RSSI[dBm]+164,127) and FEI[Hz]/128 (signed) of the the most recent packet received from the other party. The top bit of the RSSI byte is unused.
Two packet types are reserved:
0: empty packet, typically used for acks, may have an info trailer. 1: node details: Vstart[mV], Vend[mV], Temp[cC], PktSent, PktRecv, Pout[dBm], Fadj[Hz], RSSIavg[dBm].
Types ¶
type Config ¶
type Config struct { Conf1 byte // ModemConfig1: bw, coding rate, implicit/expl header Conf2 byte // ModemConfig2: sperading, mode, crc Conf3 byte // ModemConfig3: low data rate opt, LNA gain Info string // info for humans }
Config describes the SX127x configuration to achieve a specific bandwidth, spreading factor, and coding rate.
type JLLRxPacket ¶
type JLLRxPacket struct { Kind byte // one of the 4 packet kinds ToGW bool // direction: to/from gateway Node byte // node number Fmt byte // packet format RemRSSI int // rssi from trailer, 0 if none RemFEI int // fei from trailer, none if rssi==0 RxPacket }
JLLRxPacket holds a decoded JeeLabs LoRa packet.
func JLLDecode ¶
func JLLDecode(packet *RxPacket) (*JLLRxPacket, error)
JLLDecode decodes a JeeLabs LoRa packet. See JLLEncode for a description of the packet format.
type LogPrintf ¶
type LogPrintf func(format string, v ...interface{})
LogPrintf is a function used by the driver to print logging info.
type Radio ¶
type Radio struct { // state sync.Mutex // guard concurrent access to the radio // contains filtered or unexported fields }
Radio represents a Semtech SX127x LoRA radio.
func New ¶
New initializes an sx1276 Radio given an spi.Conn and an interrupt pin, and places the radio in receive mode.
To transmit, push packet payloads into the returned txChan. Received packets will be sent on the returned rxChan, which has a small amount of buffering. The rxChan will be closed if a persistent error occurs when communicating with the device, use the Error() function to retrieve the error.
func (*Radio) Receive ¶
worker is an endless loop that processes interrupts for reception as well as packets enqueued for transmit.
func (*Radio) SetConfig ¶
SetConfig sets the modem configuration using one of the entries in the Configs table. If the entry specified does not exist, nothing is changed.
func (*Radio) SetFrequency ¶
SetFrequency changes the center frequency at which the radio transmits and receives. The frequency can be specified at any scale (hz, khz, mhz). The frequency value is not checked and invalid values will simply cause the radio not to work particularly well.
func (*Radio) SetLogger ¶
SetLogger sets a logging function, nil may be used to disable logging, which is the default.
func (*Radio) SetPower ¶
SetPower configures the radio for the specified output power. It only supports the high-power amp because RFM9x modules don't have the lower-power amps connected to anything.
The datasheet is confusing about how PaConfig gets set and the formula for OutputPower looks incorrect. Fortunately Semtech provides reference code...
type RadioOpts ¶
type RadioOpts struct { Sync byte // RF sync byte Freq uint32 // center frequency in Hz, Khz, or Mhz Config string // entry in Configs table to use Logger LogPrintf // function to use for logging }
RadioOpts contains options used when initilizing a Radio.
type RxPacket ¶
type RxPacket struct { Payload []byte // payload, excluding length & crc Snr int // signal-to-noise in dB for packet Rssi int // rssi in dB for packet Fei int // frequency error in Hz for packet Lna int // dB of LNA applied At time.Time // time of recv interrupt }
RxPacket is a received packet with stats.