279 lines
8.6 KiB
C++
Executable File
279 lines
8.6 KiB
C++
Executable File
/*
|
|
* Functions for using SX127x in FSK mode (mainly receive)
|
|
* Copyright (C) 2019 Hansi Reiser, dl9rdz
|
|
*
|
|
* Partially based on the SX1278 libraray for managing Semtech modules
|
|
* Copyright (C) 2015 Wireless Open Source
|
|
* http://wirelessopensource.com
|
|
*
|
|
* SPDX-License-Identifier: LGPL-2.1+
|
|
*/
|
|
|
|
#ifndef SX1278FSK_h
|
|
#define SX1278FSK_h
|
|
|
|
/******************************************************************************
|
|
* Includes
|
|
******************************************************************************/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <Arduino.h>
|
|
#include <SPI.h>
|
|
|
|
#ifndef inttypes_h
|
|
#include <inttypes.h>
|
|
#endif
|
|
|
|
|
|
/******************************************************************************
|
|
* Definitions & Declarations
|
|
*****************************************************************************/
|
|
|
|
#define SX127X_CRYSTAL_FREQ 32000000
|
|
#define SX127X_FSTEP (SX127X_CRYSTAL_FREQ*1.0/(1<<19))
|
|
|
|
#define SX1278FSK_debug_mode 0
|
|
|
|
#define SX1278_SS SS
|
|
|
|
//! MACROS //
|
|
#define bitRead(value, bit) (((value) >> (bit)) & 0x01) // read a bit
|
|
#define bitSet(value, bit) ((value) |= (1UL << (bit))) // set bit to '1'
|
|
#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) // set bit to '0'
|
|
|
|
|
|
//! REGISTERS //
|
|
// FSK Commun LORA
|
|
#define REG_FIFO 0x00
|
|
#define REG_OP_MODE 0x01
|
|
#define REG_BITRATE_MSB 0x02
|
|
#define REG_BITRATE_LSB 0x03
|
|
#define REG_FDEV_MSB 0x04
|
|
#define REG_FDEV_LSB 0x05
|
|
#define REG_FRF_MSB 0x06
|
|
#define REG_FRF_MID 0x07
|
|
#define REG_FRF_LSB 0x08
|
|
#define REG_PA_CONFIG 0x09
|
|
#define REG_PA_RAMP 0x0A
|
|
#define REG_OCP 0x0B
|
|
#define REG_LNA 0x0C
|
|
#define REG_RX_CONFIG 0x0D
|
|
#define REG_FIFO_ADDR_PTR 0x0D
|
|
#define REG_RSSI_CONFIG 0x0E
|
|
#define REG_FIFO_TX_BASE_ADDR 0x0E
|
|
#define REG_RSSI_COLLISION 0x0F
|
|
#define REG_FIFO_RX_BASE_ADDR 0x0F
|
|
#define REG_RSSI_THRESH 0x10
|
|
#define REG_FIFO_RX_CURRENT_ADDR 0x10
|
|
#define REG_RSSI_VALUE_FSK 0x11
|
|
#define REG_IRQ_FLAGS_MASK 0x11
|
|
#define REG_RX_BW 0x12
|
|
#define REG_IRQ_FLAGS 0x12
|
|
#define REG_AFC_BW 0x13
|
|
#define REG_RX_NB_BYTES 0x13
|
|
#define REG_OOK_PEAK 0x14
|
|
#define REG_RX_HEADER_CNT_VALUE_MSB 0x14
|
|
#define REG_OOK_FIX 0x15
|
|
#define REG_RX_HEADER_CNT_VALUE_LSB 0x15
|
|
#define REG_OOK_AVG 0x16
|
|
#define REG_RX_PACKET_CNT_VALUE_MSB 0x16
|
|
#define REG_RX_PACKET_CNT_VALUE_LSB 0x17
|
|
#define REG_MODEM_STAT 0x18
|
|
#define REG_PKT_SNR_VALUE 0x19
|
|
#define REG_AFC_FEI 0x1A
|
|
#define REG_PKT_RSSI_VALUE 0x1A
|
|
#define REG_AFC_MSB 0x1B
|
|
#define REG_RSSI_VALUE_LORA 0x1B
|
|
#define REG_AFC_LSB 0x1C
|
|
#define REG_HOP_CHANNEL 0x1C
|
|
#define REG_FEI_MSB 0x1D
|
|
#define REG_MODEM_CONFIG1 0x1D
|
|
#define REG_FEI_LSB 0x1E
|
|
#define REG_MODEM_CONFIG2 0x1E
|
|
#define REG_PREAMBLE_DETECT 0x1F
|
|
#define REG_SYMB_TIMEOUT_LSB 0x1F
|
|
#define REG_RX_TIMEOUT1 0x20
|
|
#define REG_PREAMBLE_MSB_LORA 0x20
|
|
#define REG_RX_TIMEOUT2 0x21
|
|
#define REG_PREAMBLE_LSB_LORA 0x21
|
|
#define REG_RX_TIMEOUT3 0x22
|
|
#define REG_PAYLOAD_LENGTH_LORA 0x22
|
|
#define REG_RX_DELAY 0x23
|
|
#define REG_MAX_PAYLOAD_LENGTH 0x23
|
|
#define REG_OSC 0x24
|
|
#define REG_HOP_PERIOD 0x24
|
|
#define REG_PREAMBLE_MSB_FSK 0x25
|
|
#define REG_FIFO_RX_BYTE_ADDR 0x25
|
|
#define REG_PREAMBLE_LSB_FSK 0x26
|
|
#define REG_MODEM_CONFIG3 0x26
|
|
#define REG_SYNC_CONFIG 0x27
|
|
#define REG_SYNC_VALUE1 0x28
|
|
#define REG_LORA_FEI_MSB 0x28
|
|
#define REG_SYNC_VALUE2 0x29
|
|
#define REG_LORA_FEI_MID 0x29
|
|
#define REG_SYNC_VALUE3 0x2A
|
|
#define REG_LORA_FEI_LSB 0x2A
|
|
#define REG_SYNC_VALUE4 0x2B
|
|
#define REG_SYNC_VALUE5 0x2C
|
|
#define REG_RSSI_WIDEBAND 0x2C
|
|
#define REG_SYNC_VALUE6 0x2D
|
|
#define REG_SYNC_VALUE7 0x2E
|
|
#define REG_SYNC_VALUE8 0x2F
|
|
#define REG_PACKET_CONFIG1 0x30
|
|
#define REG_PACKET_CONFIG2 0x31
|
|
#define REG_DETECT_OPTIMIZE 0x31
|
|
#define REG_PAYLOAD_LENGTH_FSK 0x32
|
|
#define REG_NODE_ADRS 0x33
|
|
#define REG_INVERT_IQ 0x33
|
|
#define REG_BROADCAST_ADRS 0x34
|
|
#define REG_FIFO_THRESH 0x35
|
|
#define REG_SEQ_CONFIG1 0x36
|
|
#define REG_SEQ_CONFIG2 0x37
|
|
#define REG_DETECTION_THRESHOLD 0x37
|
|
#define REG_TIMER_RESOL 0x38
|
|
#define REG_TIMER1_COEF 0x39
|
|
#define REG_SYNC_WORD 0x39
|
|
#define REG_TIMER2_COEF 0x3A
|
|
#define REG_IMAGE_CAL 0x3B
|
|
#define REG_TEMP 0x3C
|
|
#define REG_LOW_BAT 0x3D
|
|
#define REG_IRQ_FLAGS1 0x3E
|
|
#define REG_IRQ_FLAGS2 0x3F
|
|
#define REG_DIO_MAPPING1 0x40
|
|
#define REG_DIO_MAPPING2 0x41
|
|
#define REG_VERSION 0x42
|
|
#define REG_PLL_HOP 0x44
|
|
#define REG_TCXO 0x4B
|
|
#define REG_PA_DAC 0x4D
|
|
#define REG_FORMER_TEMP 0x5B
|
|
#define REG_BIT_RATE_FRAC 0x5D
|
|
#define REG_AGC_REF 0x61
|
|
#define REG_AGC_THRESH1 0x62
|
|
#define REG_AGC_THRESH2 0x63
|
|
#define REG_AGC_THRESH3 0x64
|
|
#define REG_PLL 0x70
|
|
|
|
|
|
//FSK MODES:
|
|
const uint8_t FSK_SLEEP_MODE = 0x00;
|
|
const uint8_t FSK_STANDBY_MODE = 0x01;
|
|
const uint8_t FSK_TX_MODE = 0x03;
|
|
const uint8_t FSK_RX_MODE = 0x05;
|
|
|
|
|
|
/******************************************************************************
|
|
* SX1278FSK Class
|
|
* Functions and variables for managing SX127x transceiver chips in FSK mode,
|
|
* mainly for receiving radiosonde transmissions
|
|
******************************************************************************/
|
|
class SX1278FSK
|
|
{
|
|
public:
|
|
// class constructor
|
|
SX1278FSK();
|
|
|
|
// Turn on SX1278 module (return 0 on sucess, 1 otherwise)
|
|
uint8_t ON();
|
|
|
|
// Turn off SX1278 module
|
|
void OFF();
|
|
|
|
// Read internal register
|
|
byte readRegister(byte address);
|
|
|
|
// Write internal register
|
|
void writeRegister(byte address, byte data);
|
|
|
|
// Clear IRQ flags
|
|
void clearIRQFlags();
|
|
|
|
// Activate FSK mode (return 0 on success, 1 otherwise)
|
|
uint8_t setFSK();
|
|
|
|
// Configures bitrate register (closest approximation to requested bitrate)
|
|
uint8_t setBitrate(float bps);
|
|
float getBitrate();
|
|
|
|
// Configures RX bandwidth (next largest supported bandwith if exact value not possible)
|
|
uint8_t setRxBandwidth(float bps);
|
|
float getRxBandwidth();
|
|
|
|
// Configures AFC bandwidth (next largest supported bandwith if exact value not possible)
|
|
uint8_t setAFCBandwidth(float bps);
|
|
float getAFCBandwidth();
|
|
|
|
// Configures RX frequency (closest approximation to requested frequency)
|
|
uint8_t setFrequency(float freq);
|
|
float getFrequency();
|
|
|
|
int getLNAGain();
|
|
uint8_t setLNAGain(int gain);
|
|
|
|
uint8_t getRxConf();
|
|
uint8_t setRxConf(uint8_t conf);
|
|
|
|
uint8_t setSyncConf(uint8_t conf, int len, const uint8_t *syncpattern);
|
|
uint8_t getSyncConf();
|
|
|
|
uint8_t setPreambleDetect(uint8_t conf);
|
|
uint8_t getPreambleDetect();
|
|
|
|
uint8_t setPacketConfig(uint8_t conf1, uint8_t conf2);
|
|
uint16_t getPacketConfig();
|
|
|
|
// Get configured preamble length (used for TX only?)
|
|
uint16_t getPreambleLength();
|
|
|
|
// Sets the preamble length.
|
|
uint8_t setPreambleLength(uint16_t l);
|
|
|
|
// Gets the payload length (expected length for receive)
|
|
int getPayloadLength();
|
|
uint8_t setPayloadLength(int len);
|
|
|
|
// Get current RSSI value
|
|
int16_t getRSSI();
|
|
|
|
// Get current FEI (frequency error indication) value
|
|
int32_t getFEI();
|
|
|
|
// Get current AFC value
|
|
int32_t getAFC();
|
|
|
|
// Get the maximum current supply by the module.
|
|
int getMaxCurrent();
|
|
|
|
// Set the maximum current supply by the module.
|
|
int8_t setMaxCurrent(uint8_t rate);
|
|
|
|
// Put the module in reception mode.
|
|
//return '0' on success, '1' otherwise
|
|
uint8_t receive();
|
|
|
|
// Receive a packet
|
|
uint8_t receivePacketTimeout(uint32_t wait, byte *data);
|
|
|
|
|
|
|
|
#if 0
|
|
//! It gets the internal temperature of the module.
|
|
/*!
|
|
It stores in global '_temp' variable the module temperature.
|
|
\return '0' on success, '1' otherwise
|
|
*/
|
|
uint8_t getTemp();
|
|
|
|
//! It prints the registers related to RX via USB
|
|
/*!
|
|
* \return void
|
|
*/
|
|
void showRxRegisters();
|
|
#endif
|
|
|
|
};
|
|
|
|
extern SX1278FSK sx1278;
|
|
|
|
#endif
|