Skip to content

Instantly share code, notes, and snippets.

@fhessel
Last active April 7, 2019 18:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fhessel/52aaf5d200e38a0452517740ca3b1308 to your computer and use it in GitHub Desktop.
Save fhessel/52aaf5d200e38a0452517740ca3b1308 to your computer and use it in GitHub Desktop.
RIOT application using plain SPI access on a Raspberry Pi with a LoRa Hat

To run this application:

  • Connect the Raspberry Pi and the Dragino LoRa GPS Hat. Make sure the NSS pin of the Hat (#22 on the header) is either connected to pin #24 (CE0) or #26 (CE1) on the Pi.
  • Copy all files into a directory and adjust RIOTBASE accordingly
  • Run make all
  • Start the application with --spi=0:0:/dev/spidev0.0 for CE0 or --spi=0:0:/dev/spidev0.1 for CE1
#include "loramodem.h"
#include <string.h>
#include <stdio.h>
#include "periph/spi.h"
uint8_t read_reg(uint8_t regid) {
int res = spi_acquire(SPI_DEV(0), SPI_HWCS(0), SPI_MODE_0, SPI_CLK_5MHZ);
if (res == SPI_OK) {
uint8_t buf[2] = {(uint8_t)(regid & 0x7f), 0x00};
spi_transfer_bytes(SPI_DEV(0), SPI_HWCS(0), false, buf, buf, 2);
spi_release(SPI_DEV(0));
return buf[1];
}
return 0;
}
uint8_t write_reg(uint8_t regid, uint8_t value) {
uint8_t buf[2] = {(uint8_t)(regid | 0x80), value};
int res = spi_acquire(SPI_DEV(0), SPI_HWCS(0), SPI_MODE_0, SPI_CLK_5MHZ);
if (res == SPI_OK) {
spi_transfer_bytes(SPI_DEV(0), SPI_HWCS(0), false, buf, buf, 2);
spi_release(SPI_DEV(0));
return buf[1];
}
return 0;
}
static uint8_t write_reg_burst(uint8_t regid, uint8_t * val, uint8_t len) {
uint8_t buf[1] = {(uint8_t)(regid | 0x80)};
int res = spi_acquire(SPI_DEV(0), SPI_HWCS(0), SPI_MODE_0, SPI_CLK_5MHZ);
if (res == SPI_OK) {
spi_transfer_bytes(SPI_DEV(0), SPI_HWCS(0), true, buf, NULL, 1);
spi_transfer_bytes(SPI_DEV(0), SPI_HWCS(0), false, val, NULL, len);
spi_release(SPI_DEV(0));
return 0;
}
return 1;
}
/**
* Reads register at addr, replaces the masked bytes with value and writes all back.
*
* value should already be shifted correctly
*/
static void write_reg_masked(uint8_t addr, uint8_t mask, uint8_t value) {
write_reg(addr, (mask & value) | (~mask & read_reg(addr)));
}
int loramodem_setup(void) {
// Check the modem version
uint8_t version = read_reg(REG1276_VERSION);
if (version != VERSION_SX1276) {
printf("Got version %02x\n",version);
return 1;
}
// Go to sleep mode (required to switch to LoRa mode)
loramodem_set_opmode(OPMODE_SLEEP);
// Set LoRa mode
write_reg_masked(REG1276_OPMODE, MSK1276_OPMODE_MODULATION, VAL1276_OPMODE_MODULATION_LORA);
// Enable AGC auto on
write_reg_masked(REG1276_LORA_MODEMCONFIG3, MSK1276_LORA_MODEMCONFIG3_AGCAUTOON, 0xff);
// Disable channel hopping
write_reg(REG1276_LORA_HOPPERIOD, 0x00);
// Payload length settings: We want all payloads, independend of their length:
write_reg(REG1276_LORA_MAXPAYLOADLENGTH,0xFF);
// LNA to max gain:
write_reg_masked(REG1276_LNA, MSK1276_LNA_GAIN, VAL1276_LNA_GAIN_MAX);
write_reg_masked(REG1276_LNA, MSK1276_LNA_BOOST, VAL1276_LNA_BOOST_ON);
// For TX power
write_reg(REG1276_PACONFIG,
(MSK1276_PACONFIG_PASELECT & VAL1276_PACONFIG_PASELECT_PABOOST) |
(MSK1276_PACONFIG_OUTPUTPOWER & 0xf)
);
write_reg_masked(REG1276_PADAC, MSK1276_PADAC_PADAC, VAL1276_PADAC_PADAC_DEFAULT);
// Set the FIFO access pointer to the beginning of the RX buffer
write_reg(REG1276_LORA_FIFOADDRPTR, read_reg(REG1276_LORA_FIFORXBASEADDR));
// Set the TX Buffer to the RX buffer
write_reg(REG1276_LORA_FIFOTXBASEADDR, 0x00);
write_reg(REG1276_LORA_SYMBTIMEOUTLSB, 0x08);
write_reg(REG1276_LORA_PAYLOADLENGTH, 0xFF);
// Setup a default channel
loramodem_set_frequency(868100000);
loramodem_set_sf(7);
loramodem_set_bw(BW125);
loramodem_set_cr(CR4_5);
loramodem_set_syncword(0x12);
// Go to standby mode
loramodem_set_opmode(OPMODE_STANDBY);
return 0;
}
void loramodem_set_frequency(uint32_t freq) {
uint64_t frf = (uint64_t)(((uint64_t)freq) << 19) / 32000000;
write_reg(REG1276_FRFMSB, (uint8_t)(frf>>16) );
write_reg(REG1276_FRFMID, (uint8_t)(frf>> 8) );
write_reg(REG1276_FRFLSB, (uint8_t)(frf>> 0) );
}
uint32_t loramodem_get_frequency(void) {
uint64_t frf =
((uint64_t)(read_reg(REG1276_FRFMSB)) << 16) +
((uint64_t)(read_reg(REG1276_FRFMID)) << 8) +
(uint64_t)(read_reg(REG1276_FRFLSB));
frf*=32000000;
return frf >> 19;
}
void loramodem_set_sf(uint8_t sf) {
write_reg_masked(REG1276_LORA_MODEMCONFIG2, MSK1276_LORA_MODEMCONFIG2_SF, sf << 4);
// For higher SFs, we should set this in MODEMCONFIG3 too:
uint8_t ldo = sf >= 11 ? 1 : 0;
write_reg_masked(REG1276_LORA_MODEMCONFIG3, MSK1276_LORA_MODEMCONFIG3_LOWDATARATEOPTIMIZE, ldo << 3);
}
uint8_t loramodem_get_sf(void) {
return (read_reg(REG1276_LORA_MODEMCONFIG2) & MSK1276_LORA_MODEMCONFIG2_SF) >> 4;
}
void loramodem_set_bw(bw_t bw) {
uint8_t bwVal = VAL1276_LORA_MODEMCONFIG1_BW125;
if (bw == BW250) {
bwVal = VAL1276_LORA_MODEMCONFIG1_BW250;
} else if (bw == BW500) {
bwVal = VAL1276_LORA_MODEMCONFIG1_BW500;
}
write_reg_masked(REG1276_LORA_MODEMCONFIG1, MSK1276_LORA_MODEMCONFIG1_BW, bwVal);
}
bw_t loramodem_get_bw(void) {
uint8_t res = ((read_reg(REG1276_LORA_MODEMCONFIG1) & MSK1276_LORA_MODEMCONFIG1_BW));
if (res == VAL1276_LORA_MODEMCONFIG1_BW250) return BW250;
if (res == VAL1276_LORA_MODEMCONFIG1_BW500) return BW500;
return BW125;
}
void loramodem_set_cr(cr_t cr) {
write_reg_masked(REG1276_LORA_MODEMCONFIG1, MSK1276_LORA_MODEMCONFIG1_CR, cr << 1);
}
cr_t loramodem_get_cr(void) {
return (cr_t)((read_reg(REG1276_LORA_MODEMCONFIG1) & MSK1276_LORA_MODEMCONFIG1_CR) >> 1);
}
void loramodem_set_syncword(uint8_t syncword) {
write_reg(REG1276_LORA_SYNCWORD, syncword);
}
uint8_t loramodem_get_syncword(void) {
return read_reg(REG1276_LORA_SYNCWORD);
}
void loramodem_set_opmode(opmode_t opmode) {
write_reg_masked(REG1276_OPMODE, MSK1276_OPMODE_MODE, opmode);
}
opmode_t loramodem_get_opmode(void) {
return (opmode_t)(read_reg(REG1276_OPMODE) & MSK1276_OPMODE_MODE);
}
int loramodem_receive(loraframe_t *frame) {
// Read and reset RX_DONE
uint8_t irq = write_reg(REG1276_LORA_IRQFLAGS, VAL1276_LORA_IRQFLAGS_RXDONE);
if ((irq & VAL1276_LORA_IRQFLAGS_RXDONE) > 0) {
// Check for CRC error (we just flag it, but don't discard the message)
frame->crcError = (irq & VAL1276_LORA_IRQFLAGS_PAYLOADCRCERROR) > 0;
// Reset CRCError if necessary
if (frame->crcError) {
write_reg(REG1276_LORA_IRQFLAGS, VAL1276_LORA_IRQFLAGS_PAYLOADCRCERROR);
}
// Get position of length of the last message
uint8_t rxCurrentAddr = read_reg(REG1276_LORA_RXCURRENTADDR);
frame->payload_len = read_reg(REG1276_LORA_RXNBBYTES);
// Adjust the fifo to the message and read it
write_reg(REG1276_LORA_FIFOADDRPTR, rxCurrentAddr);
for(int i = 0; i < frame->payload_len; i++) {
frame->payload[i] = read_reg(REG1276_FIFO);
}
// Return success
return 0;
} else {
// Nothing received
return 2;
}
}
int loramodem_transmit(loraframe_t *frame, bool awaitTxDone) {
// Assure standby, so that we have fifo access
loramodem_set_opmode(OPMODE_STANDBY);
// Clear interrupts
write_reg(REG1276_LORA_IRQFLAGS, 0xff);
// Assure that we get an interrupt for txDone (otherwise awaitTxDone would lead to an endless loop)
write_reg_masked(REG1276_LORA_IRQFLAGSMASK, VAL1276_LORA_IRQFLAGS_TXDONE, 0x00);
// Configure the position in the fifo buffer to the beginning
write_reg(REG1276_LORA_FIFOTXBASEADDR, 0x00);
write_reg(REG1276_LORA_FIFOADDRPTR, 0x00);
// Set the length of the message
write_reg(REG1276_LORA_PAYLOADLENGTH, frame->payload_len);
// Write the data into the fifo buffer
if (write_reg_burst(REG1276_FIFO, frame->payload, frame->payload_len) == 0) {
// Setting the modem to opmode tx will send the content of the fifo
loramodem_set_opmode(OPMODE_TX);
// If required, wait for txDone:
if (awaitTxDone) {
while(!loramodem_txdone(true));
}
return 0;
} else {
return 1;
}
}
bool loramodem_txdone(bool reset) {
if (reset) {
return (write_reg(REG1276_LORA_IRQFLAGS, VAL1276_LORA_IRQFLAGS_TXDONE) & VAL1276_LORA_IRQFLAGS_TXDONE) != 0;
} else {
return (read_reg(REG1276_LORA_IRQFLAGS) & VAL1276_LORA_IRQFLAGS_TXDONE) != 0;
}
}
#ifndef LORAMODEM_H
#define LORAMODEM_H
#include <stdint.h>
#include <stdbool.h>
#include "registers_sx1276.h"
/**
* Value of the version register if the modem is the sx1276 or compatible
*/
#define VERSION_SX1276 0x12
/** Enum with possible bandwidth values */
typedef enum {
/* Bandwidth of 125 kHz */
BW125 = 125,
/* Bandwidth of 250 kHz */
BW250 = 250,
/* Bandwidth of 500 kHz */
BW500 = 500
} bw_t;
/** Enum with possible values for the coding rate (forward error correction) */
typedef enum {
/** 4/5 coding */
CR4_5 = 1,
/** 4/6 coding */
CR4_6 = 2,
/** 4/7 coding */
CR4_7 = 3,
/** 4/8 coding */
CR4_8 = 4
} cr_t;
/** Enum with possible values for the mode of operation */
typedef enum {
/** Sleep */
OPMODE_SLEEP = VAL1276_OPMODE_MODE_SLEEP,
/** Standby */
OPMODE_STANDBY = VAL1276_OPMODE_MODE_STANDBY,
/** Frequency synthesis for RX */
OPMODE_FSRX = VAL1276_OPMODE_MODE_FSRX,
/** Continuous RX mode, will stay in RX after rxDone */
OPMODE_RXCONT = VAL1276_OPMODE_MODE_RXCONTINUOUS,
/** Single RX mode, will turn to standby after rxDone */
OPMODE_RXSINGLE = VAL1276_OPMODE_MODE_RXSINGLE,
/** Frequency synthesis for TX */
OPMODE_FSTX = VAL1276_OPMODE_MODE_FSTX,
/** Transmission mode, will send bytes from the fifo and then return to standby */
OPMODE_TX = VAL1276_OPMODE_MODE_TX,
/** Channel activity detection */
OPMODE_CAD = VAL1276_OPMODE_MODE_CAD,
} opmode_t ;
/** Very basic struct to send and receive lora frames */
typedef struct loraframe {
/** The payload of the frame */
uint8_t payload[255];
/** The length of the payload (bytes in payload field that are actually used) */
uint8_t payload_len;
/** If a CRC error has occured */
bool crcError;
} loraframe_t ;
/**
* Configures the modem
*
* Will return 0 on success.
*/
int loramodem_setup(void);
/** Reads a single register from the modem */
uint8_t read_reg(uint8_t regid);
/** Writes a single register to the modem and returns the former value */
uint8_t write_reg(uint8_t regid, uint8_t val);
/** Sets the frequency of the modem, in Hz */
void loramodem_set_frequency(uint32_t freq);
/** Returns the frequency of the modem, in Hz. Reads the actual register */
uint32_t loramodem_get_frequency(void);
/** Sets the spreading factor */
void loramodem_set_sf(uint8_t sf);
/** Returns the spreading factor of the modem. Reads the actual register */
uint8_t loramodem_get_sf(void);
/** Sets the bandwidth */
void loramodem_set_bw(bw_t bw);
/** Returns the bandwidth of the modem. Reads the actual register */
bw_t loramodem_get_bw(void);
/** Sets the coding rate */
void loramodem_set_cr(cr_t bw);
/** Returns the coding rate of the modem. Reads the actual register */
cr_t loramodem_get_cr(void);
/** Sets the LoRa syncword. Use 0x12 for private networks (modem default) or 0x34 for public LoRaWAN */
void loramodem_set_syncword(uint8_t syncword);
/** Returns the LoRa syncword. Reads the actual register. */
uint8_t loramodem_get_syncword(void);
/** Configures the mode of operation */
void loramodem_set_opmode(opmode_t opmode);
/** Returns the current mode of operation */
opmode_t loramodem_get_opmode(void);
/**
* Tries to receive a message. Returns 0 if it was successful.
*
* Check crc field of the frame to check if a CRC error occured.
*/
int loramodem_receive(loraframe_t *frame);
/**
* Transmits the frame.
*
* If awaitTxDone is set to true, the call will block until the txDone interrupt arrives.
*/
int loramodem_transmit(loraframe_t *frame, bool awaitTxDone);
/**
* Returns the state of the txDone interrupt. If reset is set to true, it will be cleared afterwards
*/
bool loramodem_txdone(bool reset);
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "periph/gpio.h"
#include "periph/spi.h"
#include "thread.h"
#include "shell.h"
#include "shell_commands.h"
#include "xtimer.h"
#include "loramodem.h"
/** Parse a byte either from decimal representation or as "0x42" */
static int parsenum(char * arg) {
size_t arglen = strlen(arg);
int val = 0;
if (arglen >= 2 && arg[0] == '0' && arg[1] == 'x') {
val = strtol(arg+2, NULL, 16);
} else {
val = strtol(arg, NULL, 10);
}
if (val > 0xff) {
return -1;
}
return val;
}
/** Command line handler for "read register" */
static int _cmdregread(int argc, char **argv) {
if (argc != 2) {
printf("Usage: regread <id>\n");
return 1;
}
int regid = parsenum(argv[1]);
if (regid < 0) {
printf("Invalid register\n");
return 1;
}
printf("Register 0x%02x=0x%02x\n", regid, read_reg(regid));
return 0;
}
/** Command line handler for "write register" */
static int _cmdregwrite(int argc, char **argv) {
if (argc != 3) {
printf("Usage: regwrite <id> <val>\n");
return 1;
}
int regid = parsenum(argv[1]);
int val = parsenum(argv[2]);
if (regid < 0 || val < 0) {
printf("Invalid register/value\n");
return 1;
}
write_reg(regid, val);
printf("Register 0x%02x=0x%02x\n", regid, read_reg(regid));
return 0;
}
/** Command line handler for receive message */
static int _cmdrecvmsg(int argc, char **argv)
{
(void)argc;
(void)argv;
loramodem_set_opmode(OPMODE_RXCONT);
/* Try for ~10 seconds */
printf("Receiving...");
loraframe_t frame;
uint16_t i = 0;
while(i < 10000) {
if (loramodem_receive(&frame) == 0) {
break;
}
xtimer_usleep(1000);
i+=1;
}
loramodem_set_opmode(OPMODE_STANDBY);
if (i == 10000) {
printf(" Timeout\n");
return 1;
} else {
printf(" Success\nGot:");
for (uint8_t c = 0; c < frame.payload_len; c++) {
printf(" %02x", frame.payload[c]);
}
printf("\n");
return 0;
}
}
/** Command line handler for send message */
static int _cmdsendmsg(int argc, char **argv)
{
if (argc < 2) {
puts("Missing argument");
return 1;
}
loraframe_t frame;
size_t len = strlen(argv[1]);
frame.payload_len = len > 0xff ? 0xff : len;
memcpy(&(frame.payload), (uint8_t*)argv[1], frame.payload_len);
printf("Send:");
for (uint8_t c = 0; c < frame.payload_len; c++) {
printf(" %02x", frame.payload[c]);
}
if (loramodem_transmit(&frame, true) == 0) {
printf("\nDone\n");
return 0;
} else {
printf("\nFailure\n");
return 1;
}
}
static const shell_command_t shell_commands[] = {
{ "regread", "Read modem register", _cmdregread },
{ "regwrite", "Write modem register", _cmdregwrite },
{ "recv", "Receive a message", _cmdrecvmsg },
{ "send", "Send a message", _cmdsendmsg },
{ NULL, NULL, NULL }
};
int main(void)
{
if (loramodem_setup() != 0) {
printf("loramodem_setup() failed!\n");
printf("Note:\n");
printf("If you are using a Raspberry Pi Rev. 2 or 3, you need to connect pin 22 of the LoRa Hat to\n");
printf("pin 24 (spidev0.0) or pin 26 (spidev0.1) to make this work!\n");
printf("See example 4 of: http://wiki.dragino.com/index.php?title=Lora/GPS_HAT\n");
} else {
printf("LoRa modem ready.\n");
printf("Use send <msg> or recv to send or receive.\n");
printf("Channel is fixed to: 868.1 MHz, 125 kHz bandwidth, 4/5 coding rate, SF7, 0x12 sync word\n");
}
char line_buf[SHELL_DEFAULT_BUFSIZE];
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
return 0;
}
# name of your application
APPLICATION = riot-native-loramodem
# If no BOARD is found in the environment, use this default:
BOARD ?= native
# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..
# Comment this out to disable code in RIOT that does safety checking
# which is not needed in a production environment but helps in the
# development process:
DEVELHELP ?= 1
# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1
# Modules to include:
USEMODULE += shell
USEMODULE += shell_commands
USEMODULE += ps
USEMODULE += xtimer
FEATURES_REQUIRED += periph_spi
include $(RIOTBASE)/Makefile.include
#ifndef REGISTERS_SX127X_H
#define REGISTERS_SX127X_H
// From the Semtech SX1276/77/78/79 datasheet, chapter 6.1, table 41
#define REG1276_FIFO 0x00
#define REG1276_OPMODE 0x01
#define REG1276_FSK_BITRATEMSB 0x02
#define REG1276_FSK_BITRATELSB 0x03
#define REG1276_FSK_FDEVMSB 0x04
#define REG1276_FSK_FDEVLSB 0x05
#define REG1276_FRFMSB 0x06
#define REG1276_FRFMID 0x07
#define REG1276_FRFLSB 0x08
#define REG1276_PACONFIG 0x09
#define REG1276_PARAMP 0x0A
#define REG1276_OCP 0x0B
#define REG1276_LNA 0x0C
#define REG1276_FSK_RXCONFIG 0x0D
#define REG1276_LORA_FIFOADDRPTR 0x0D
#define REG1276_FSK_RSSICONFIG 0x0E
#define REG1276_LORA_FIFOTXBASEADDR 0x0E
#define REG1276_FSK_RSSICOLLISION 0x0F
#define REG1276_LORA_FIFORXBASEADDR 0x0F
#define REG1276_FSK_RSSITHRESH 0x10
#define REG1276_LORA_RXCURRENTADDR 0x10
#define REG1276_FSK_RSSIVALUE 0x11
#define REG1276_LORA_IRQFLAGSMASK 0x11
#define REG1276_FSK_RXBW 0x12
#define REG1276_LORA_IRQFLAGS 0x12
#define REG1276_FSK_AFCBW 0x13
#define REG1276_LORA_RXNBBYTES 0x13
#define REG1276_FSK_OOKPEAK 0x14
#define REG1276_LORA_RXHEADERCNTVALUEMSB 0x14
#define REG1276_FSK_OOKFIX 0x15
#define REG1276_LORA_RXHEADERCNTVALUELSB 0x15
#define REG1276_FSK_OOKAVG 0x16
#define REG1276_LORA_RXPACKETCNTVALUEMSB 0x16
#define REG1276_LORA_RXPACKETCNTVALUELSB 0x17
#define REG1276_LORA_MODEMSTAT 0x18
#define REG1276_LORA_PKTSNRVALUE 0x19
#define REG1276_FSK_AFCFEI 0x1A
#define REG1276_LORA_PKTRSSIVALUE 0x1A
#define REG1276_FSK_AFCMSB 0x1B
#define REG1276_LORA_RSSIVALUE 0x1B
#define REG1276_FSK_AFCLSB 0x1C
#define REG1276_LORA_HOPCHANNEL 0x1C
#define REG1276_FSK_FEIMSB 0x1D
#define REG1276_LORA_MODEMCONFIG1 0x1D
#define REG1276_FSK_FEILSB 0x1E
#define REG1276_LORA_MODEMCONFIG2 0x1E
#define REG1276_FSK_PREAMBLEDETECT 0x1F
#define REG1276_LORA_SYMBTIMEOUTLSB 0x1F
#define REG1276_FSK_RXTIMEOUT1 0x20
#define REG1276_LORA_PREAMBLEMSB 0x20
#define REG1276_FSK_RXTIMEOUT2 0x21
#define REG1276_LORA_PREAMBLELSB 0x21
#define REG1276_FSK_RXTIMEOUT3 0x22
#define REG1276_LORA_PAYLOADLENGTH 0x22
#define REG1276_FSK_RXDELAY 0x23
#define REG1276_LORA_MAXPAYLOADLENGTH 0x23
#define REG1276_FSK_OSC 0x24
#define REG1276_LORA_HOPPERIOD 0x24
#define REG1276_FSK_PREAMBLEMSB 0x25
#define REG1276_LORA_FIFORXBYTEADDR 0x25
#define REG1276_FSK_PREAMBLELSB 0x26
#define REG1276_LORA_MODEMCONFIG3 0x26
#define REG1276_FSK_SYNCCONFIG 0x27
#define REG1276_FSK_SYNCVALUE1 0x28
#define REG1276_LORA_FEIMSB 0x28
#define REG1276_FSK_SYNCVALUE2 0x29
#define REG1276_LORA_FEIMID 0x29
#define REG1276_FSK_SYNCVALUE3 0x2A
#define REG1276_LORA_FEILSB 0x2A
#define REG1276_FSK_SYNCVALUE4 0x2B
#define REG1276_FSK_SYNCVALUE5 0x2C
#define REG1276_LORA_RSSIWIDEBAND 0x2C
#define REG1276_FSK_SYNCVALUE6 0x2D
#define REG1276_FSK_SYNCVALUE7 0x2E
#define REG1276_FSK_SYNCVALUE8 0x2F
#define REG1276_FSK_PACKETCONFIG1 0x30
#define REG1276_FSK_PACKETCONFIG2 0x31
#define REG1276_LORA_DETECTOPTIMIZE 0x31
#define REG1276_FSK_PAYLOADLENGTH 0x32
#define REG1276_FSK_NODEADRS 0x33
#define REG1276_LORA_INVERTIQ 0x34
#define REG1276_FSK_BROADCASTADRS 0x34
#define REG1276_FSK_FIFOTHRESH 0x35
#define REG1276_FSK_SEQCONFIG1 0x36
#define REG1276_FSK_SEQCONFIG2 0x37
#define REG1276_LORA_DETECTIONTHRESHOLD 0x37
#define REG1276_FSK_TIMERRESOL 0x38
#define REG1276_FSK_TIMER1COEF 0x39
#define REG1276_LORA_SYNCWORD 0x39
#define REG1276_FSK_TIMER2COEF 0x3A
#define REG1276_FSK_IMAGECAL 0x3B
#define REG1276_FSK_TEMP 0x3C
#define REG1276_FSK_LOWBATT 0x3D
#define REG1276_FSK_IRQFLAGS1 0x3E
#define REG1276_FSK_IRQFLAGS2 0x3F
#define REG1276_DIO_MAPPING1 0x40
#define REG1276_DIO_MAPPING2 0x41
#define REG1276_VERSION 0x42
#define REG1276_FSK_PLLHOP 0x44
#define REG1276_TXCO 0x4B
#define REG1276_PADAC 0x4D
#define REG1276_FORMERTEMP 0x5B
#define REG1276_FSK_BITRATEFRAC 0x5D
#define REG1276_AGCREF 0x61
#define REG1276_AGCTRHESH1 0x62
#define REG1276_AGCTHRESH2 0x63
#define REG1276_AGCTRHESH3 0x64
#define REG1276_PLL 0x70
// Values for registers
#define MSK1276_OPMODE_MODULATION 0x80
#define VAL1276_OPMODE_MODULATION_LORA 0x80
#define VAL1276_OPMODE_MODULATION_FSK 0x00
#define MSK1276_OPMODE_MODE 0x07
#define VAL1276_OPMODE_MODE_SLEEP 0x00
#define VAL1276_OPMODE_MODE_STANDBY 0x01
#define VAL1276_OPMODE_MODE_FSTX 0x02
#define VAL1276_OPMODE_MODE_TX 0x03
#define VAL1276_OPMODE_MODE_FSRX 0x04
#define VAL1276_OPMODE_MODE_RXCONTINUOUS 0x05
#define VAL1276_OPMODE_MODE_RXSINGLE 0x06
#define VAL1276_OPMODE_MODE_CAD 0x07
#define MSK1276_PACONFIG_PASELECT 0x80
#define VAL1276_PACONFIG_PASELECT_RFO 0x00
#define VAL1276_PACONFIG_PASELECT_PABOOST 0x80
#define MSK1276_PACONFIG_OUTPUTPOWER 0x0f
#define VAL1276_LORA_IRQFLAGS_RXTIMEOUT 0x80
#define VAL1276_LORA_IRQFLAGS_RXDONE 0x40
#define VAL1276_LORA_IRQFLAGS_PAYLOADCRCERROR 0x20
#define VAL1276_LORA_IRQFLAGS_VALIDHEADER 0x10
#define VAL1276_LORA_IRQFLAGS_TXDONE 0x08
#define VAL1276_LORA_IRQFLAGS_CADDONE 0x04
#define VAL1276_LORA_IRQFLAGS_FHSSCHANGECHANNEL 0x02
#define VAL1276_LORA_IRQFLAGS_CADDETECTED 0x01
#define VAL1276_LORA_MODEMSTAT_RXACTIVE 0x04
#define MSK1276_LNA_GAIN 0xe0
#define VAL1276_LNA_GAIN_MAX 0x20
#define VAL1276_LNA_GAIN_MIN 0xc0
#define MSK1276_LNA_BOOST 0x03
#define VAL1276_LNA_BOOST_ON 0x03
#define VAL1276_LNA_BOOST_OFF 0x00
#define MSK1276_LORA_MODEMCONFIG1_BW 0xf0
#define VAL1276_LORA_MODEMCONFIG1_BW125 0x70
#define VAL1276_LORA_MODEMCONFIG1_BW250 0x80
#define VAL1276_LORA_MODEMCONFIG1_BW500 0x90
#define MSK1276_LORA_MODEMCONFIG1_CR 0x0e
#define MSK1276_LORA_MODEMCONFIG2_SF 0xf0
#define MSK1276_LORA_MODEMCONFIG2_TXCONTINUOUS 0x08
#define MSK1276_LORA_MODEMCONFIG2_RXPAYLOADCRC 0x04
#define MSK1276_LORA_MODEMCONFIG2_SYMBTIMEOUT 0x03
#define MSK1276_LORA_MODEMCONFIG3_LOWDATARATEOPTIMIZE 0x08
#define MSK1276_LORA_MODEMCONFIG3_AGCAUTOON 0x04
#define MSK1276_DIO_MAPPING1_DIO0 0xc0
#define MSK1276_DIO_MAPPING1_DIO1 0x30
#define MSK1276_DIO_MAPPING1_DIO2 0x0c
#define MSK1276_DIO_MAPPING1_DIO3 0x03
#define MSK1276_DIO_MAPPING1_DIO4 0xc0
#define MSK1276_DIO_MAPPING1_DIO5 0x30
#define MSK1276_PADAC_PADAC 0x07
#define VAL1276_PADAC_PADAC_DEFAULT 0x00
#define VAL1276_PADAC_PADAC_BOOST 0x07
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment