wayne roberts / sx126x

Dependents:   alarm_slave iq_sx126x sx126x_simple_TX_shield_2020a sx126x_simple_RX_shield_2020a ... more

Committer:
Wayne Roberts
Date:
Wed May 16 11:20:24 2018 -0700
Revision:
0:c79a1f70c110
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wayne Roberts 0:c79a1f70c110 1 #include "mbed.h"
Wayne Roberts 0:c79a1f70c110 2
Wayne Roberts 0:c79a1f70c110 3 #define RC_TICKS_PER_MS 0.015625 /* 64KHz */
Wayne Roberts 0:c79a1f70c110 4
Wayne Roberts 0:c79a1f70c110 5 /***************************************************************/
Wayne Roberts 0:c79a1f70c110 6 #define OPCODE_CLEAR_IRQ_STATUS 0x02
Wayne Roberts 0:c79a1f70c110 7 #define OPCODE_CLEAR_DEVICE_ERRORS 0x07
Wayne Roberts 0:c79a1f70c110 8 #define OPCODE_SET_DIO_IRQ_PARAMS 0x08
Wayne Roberts 0:c79a1f70c110 9 #define OPCODE_WRITE_REGISTER 0x0d
Wayne Roberts 0:c79a1f70c110 10 #define OPCODE_WRITE_BUFFER 0x0e
Wayne Roberts 0:c79a1f70c110 11 #define OPCODE_GET_PACKET_TYPE 0x11
Wayne Roberts 0:c79a1f70c110 12 #define OPCODE_GET_IRQ_STATUS 0x12
Wayne Roberts 0:c79a1f70c110 13 #define OPCODE_GET_RX_BUFFER_STATUS 0x13
Wayne Roberts 0:c79a1f70c110 14 #define OPCODE_GET_PACKET_STATUS 0x14
Wayne Roberts 0:c79a1f70c110 15 #define OPCODE_GET_RSSIINST 0x15
Wayne Roberts 0:c79a1f70c110 16 #define OPCODE_GET_DEVICE_ERRORS 0x17
Wayne Roberts 0:c79a1f70c110 17 #define OPCODE_READ_REGISTER 0x1d
Wayne Roberts 0:c79a1f70c110 18 #define OPCODE_READ_BUFFER 0x1e
Wayne Roberts 0:c79a1f70c110 19 #define OPCODE_SET_STANDBY 0x80
Wayne Roberts 0:c79a1f70c110 20 #define OPCODE_SET_RX 0x82
Wayne Roberts 0:c79a1f70c110 21 #define OPCODE_SET_TX 0x83
Wayne Roberts 0:c79a1f70c110 22 #define OPCODE_SET_SLEEP 0x84
Wayne Roberts 0:c79a1f70c110 23 #define OPCODE_SET_RF_FREQUENCY 0x86
Wayne Roberts 0:c79a1f70c110 24 #define OPCODE_CALIBRATE 0x89
Wayne Roberts 0:c79a1f70c110 25 #define OPCODE_SET_PACKET_TYPE 0x8a
Wayne Roberts 0:c79a1f70c110 26 #define OPCODE_SET_MODULATION_PARAMS 0x8b
Wayne Roberts 0:c79a1f70c110 27 #define OPCODE_SET_PACKET_PARAMS 0x8c
Wayne Roberts 0:c79a1f70c110 28 #define OPCODE_SET_TX_PARAMS 0x8e
Wayne Roberts 0:c79a1f70c110 29 #define OPCODE_SET_BUFFER_BASE_ADDR 0x8f
Wayne Roberts 0:c79a1f70c110 30 #define OPCODE_SET_PA_CONFIG 0x95
Wayne Roberts 0:c79a1f70c110 31 #define OPCODE_SET_REGULATOR_MODE 0x96
Wayne Roberts 0:c79a1f70c110 32 #define OPCODE_SET_DIO3_AS_TCXO_CTRL 0x97
Wayne Roberts 0:c79a1f70c110 33 #define OPCODE_SET_DIO2_AS_RFSWITCH 0x9d
Wayne Roberts 0:c79a1f70c110 34 #define OPCODE_SET_LORA_SYMBOL_TIMEOUT 0xa0
Wayne Roberts 0:c79a1f70c110 35 #define OPCODE_GET_STATUS 0xc0
Wayne Roberts 0:c79a1f70c110 36 #define OPCODE_SET_TX_CONTINUOUS 0xd1
Wayne Roberts 0:c79a1f70c110 37 /***************************************************************/
Wayne Roberts 0:c79a1f70c110 38 #define PACKET_TYPE_GFSK 1
Wayne Roberts 0:c79a1f70c110 39 #define PACKET_TYPE_LORA 1
Wayne Roberts 0:c79a1f70c110 40
Wayne Roberts 0:c79a1f70c110 41 #define HEADER_TYPE_VARIABLE_LENGTH 0
Wayne Roberts 0:c79a1f70c110 42 #define HEADER_TYPE_FIXED_LENGTH 1
Wayne Roberts 0:c79a1f70c110 43
Wayne Roberts 0:c79a1f70c110 44 #define CRC_OFF 0
Wayne Roberts 0:c79a1f70c110 45 #define CRC_ON 0
Wayne Roberts 0:c79a1f70c110 46
Wayne Roberts 0:c79a1f70c110 47 #define STANDARD_IQ 0
Wayne Roberts 0:c79a1f70c110 48 #define INVERTED_IQ 1
Wayne Roberts 0:c79a1f70c110 49
Wayne Roberts 0:c79a1f70c110 50 /* direct register access */
Wayne Roberts 0:c79a1f70c110 51 #define REG_ADDR_LORA_CONFIG0 0x0703 // 8bit bw/sf
Wayne Roberts 0:c79a1f70c110 52 #define REG_ADDR_LORA_IRQ_MASK 0x070a // 24bit
Wayne Roberts 0:c79a1f70c110 53 #define REG_ADDR_LORA_SYNC 0x0740 // config22, config23: frame sync peak position
Wayne Roberts 0:c79a1f70c110 54 #define REG_ADDR_RANDOM 0x0819
Wayne Roberts 0:c79a1f70c110 55 #define REG_ADDR_OCP 0x08e7
Wayne Roberts 0:c79a1f70c110 56 #define REG_ADDR_
Wayne Roberts 0:c79a1f70c110 57
Wayne Roberts 0:c79a1f70c110 58 #define SET_RAMP_10U 0x00
Wayne Roberts 0:c79a1f70c110 59 #define SET_RAMP_20U 0x01
Wayne Roberts 0:c79a1f70c110 60 #define SET_RAMP_40U 0x02
Wayne Roberts 0:c79a1f70c110 61 #define SET_RAMP_80U 0x03
Wayne Roberts 0:c79a1f70c110 62 #define SET_RAMP_200U 0x04
Wayne Roberts 0:c79a1f70c110 63 #define SET_RAMP_800U 0x05
Wayne Roberts 0:c79a1f70c110 64 #define SET_RAMP_1700U 0x06
Wayne Roberts 0:c79a1f70c110 65 #define SET_RAMP_3400U 0x07
Wayne Roberts 0:c79a1f70c110 66
Wayne Roberts 0:c79a1f70c110 67 typedef union {
Wayne Roberts 0:c79a1f70c110 68 struct {
Wayne Roberts 0:c79a1f70c110 69 uint8_t rtcWakeup : 1; // 0
Wayne Roberts 0:c79a1f70c110 70 uint8_t rfu : 1; // 1
Wayne Roberts 0:c79a1f70c110 71 uint8_t warmStart : 1; // 2
Wayne Roberts 0:c79a1f70c110 72 } bits;
Wayne Roberts 0:c79a1f70c110 73 uint8_t octet;
Wayne Roberts 0:c79a1f70c110 74 } sleepConfig_t;
Wayne Roberts 0:c79a1f70c110 75
Wayne Roberts 0:c79a1f70c110 76 typedef union {
Wayne Roberts 0:c79a1f70c110 77 struct {
Wayne Roberts 0:c79a1f70c110 78 uint8_t PreambleLengthHi; // param1
Wayne Roberts 0:c79a1f70c110 79 uint8_t PreambleLengthLo; // param2
Wayne Roberts 0:c79a1f70c110 80 uint8_t HeaderType; // param3
Wayne Roberts 0:c79a1f70c110 81 uint8_t PayloadLength; // param4
Wayne Roberts 0:c79a1f70c110 82 uint8_t CRCType; // param5
Wayne Roberts 0:c79a1f70c110 83 uint8_t InvertIQ; // param6
Wayne Roberts 0:c79a1f70c110 84 uint8_t unused[2];
Wayne Roberts 0:c79a1f70c110 85 } lora;
Wayne Roberts 0:c79a1f70c110 86 struct {
Wayne Roberts 0:c79a1f70c110 87 uint8_t PreambleLengthHi; // param1
Wayne Roberts 0:c79a1f70c110 88 uint8_t PreambleLengthLo; // param2
Wayne Roberts 0:c79a1f70c110 89 uint8_t PreambleDetectorLength; // param3
Wayne Roberts 0:c79a1f70c110 90 uint8_t SyncWordLength; // param4
Wayne Roberts 0:c79a1f70c110 91 uint8_t AddrComp; // param5
Wayne Roberts 0:c79a1f70c110 92 uint8_t PacketType; // param6
Wayne Roberts 0:c79a1f70c110 93 uint8_t PayloadLength; // param7
Wayne Roberts 0:c79a1f70c110 94 uint8_t CRCType; // param8
Wayne Roberts 0:c79a1f70c110 95 } gfsk;
Wayne Roberts 0:c79a1f70c110 96 uint8_t buf[8];
Wayne Roberts 0:c79a1f70c110 97 } PacketParams_t;
Wayne Roberts 0:c79a1f70c110 98
Wayne Roberts 0:c79a1f70c110 99
Wayne Roberts 0:c79a1f70c110 100 #define LORA_BW_7 0x00 //( .81 kHz real
Wayne Roberts 0:c79a1f70c110 101 #define LORA_BW_10 0x08 // 10.42 kHz real
Wayne Roberts 0:c79a1f70c110 102 #define LORA_BW_15 0x01 // 15.63 kHz real
Wayne Roberts 0:c79a1f70c110 103 #define LORA_BW_20 0x09 // 20.83 kHz real
Wayne Roberts 0:c79a1f70c110 104 #define LORA_BW_31 0x02 // 31.25 kHz real
Wayne Roberts 0:c79a1f70c110 105 #define LORA_BW_41 0x0A // 41.67 kHz real
Wayne Roberts 0:c79a1f70c110 106 #define LORA_BW_62 0x03 // 62.50 kHz real
Wayne Roberts 0:c79a1f70c110 107 #define LORA_BW_125 0x04 // 125 kHz real
Wayne Roberts 0:c79a1f70c110 108 #define LORA_BW_250 0x05 // 250 kHz real
Wayne Roberts 0:c79a1f70c110 109 #define LORA_BW_500 0x06 // 500 kHz real
Wayne Roberts 0:c79a1f70c110 110
Wayne Roberts 0:c79a1f70c110 111 #define LORA_CR_4_5 1
Wayne Roberts 0:c79a1f70c110 112 #define LORA_CR_4_6 2
Wayne Roberts 0:c79a1f70c110 113 #define LORA_CR_4_7 3
Wayne Roberts 0:c79a1f70c110 114 #define LORA_CR_4_8 4
Wayne Roberts 0:c79a1f70c110 115
Wayne Roberts 0:c79a1f70c110 116 typedef enum {
Wayne Roberts 0:c79a1f70c110 117 STBY_RC = 0,
Wayne Roberts 0:c79a1f70c110 118 STBY_XOSC
Wayne Roberts 0:c79a1f70c110 119 } stby_t;
Wayne Roberts 0:c79a1f70c110 120
Wayne Roberts 0:c79a1f70c110 121 typedef union {
Wayne Roberts 0:c79a1f70c110 122 struct {
Wayne Roberts 0:c79a1f70c110 123 uint8_t spreadingFactor; // param1
Wayne Roberts 0:c79a1f70c110 124 uint8_t bandwidth; // param2
Wayne Roberts 0:c79a1f70c110 125 uint8_t codingRate; // param3
Wayne Roberts 0:c79a1f70c110 126 uint8_t LowDatarateOptimize; // param4
Wayne Roberts 0:c79a1f70c110 127 } lora;
Wayne Roberts 0:c79a1f70c110 128 struct {
Wayne Roberts 0:c79a1f70c110 129 uint8_t bitrateHi; // param1
Wayne Roberts 0:c79a1f70c110 130 uint8_t bitrateMid; // param2
Wayne Roberts 0:c79a1f70c110 131 uint8_t bitrateLo; // param3
Wayne Roberts 0:c79a1f70c110 132 uint8_t PulseShape; // param4
Wayne Roberts 0:c79a1f70c110 133 uint8_t bandwith; // param5
Wayne Roberts 0:c79a1f70c110 134 uint8_t fdevHi; // param6
Wayne Roberts 0:c79a1f70c110 135 uint8_t fdevMid; // param7
Wayne Roberts 0:c79a1f70c110 136 uint8_t fdevLo; // param8
Wayne Roberts 0:c79a1f70c110 137 } gfsk;
Wayne Roberts 0:c79a1f70c110 138 uint8_t buf[8];
Wayne Roberts 0:c79a1f70c110 139 } ModulationParams_t;
Wayne Roberts 0:c79a1f70c110 140
Wayne Roberts 0:c79a1f70c110 141 typedef union {
Wayne Roberts 0:c79a1f70c110 142 struct { //
Wayne Roberts 0:c79a1f70c110 143 uint8_t TxDone : 1; // 0
Wayne Roberts 0:c79a1f70c110 144 uint8_t RxDone : 1; // 1
Wayne Roberts 0:c79a1f70c110 145 uint8_t PreambleDetected : 1; // 2
Wayne Roberts 0:c79a1f70c110 146 uint8_t SyncWordValid : 1; // 3
Wayne Roberts 0:c79a1f70c110 147 uint8_t HeaderValid : 1; // 4
Wayne Roberts 0:c79a1f70c110 148 uint8_t HeaderErr : 1; // 5
Wayne Roberts 0:c79a1f70c110 149 uint8_t CrCerr : 1; // 6
Wayne Roberts 0:c79a1f70c110 150 uint8_t CadDone : 1; // 7
Wayne Roberts 0:c79a1f70c110 151 uint8_t CadDetected : 1; // 8
Wayne Roberts 0:c79a1f70c110 152 uint8_t Timeout : 1; // 9
Wayne Roberts 0:c79a1f70c110 153 } bits;
Wayne Roberts 0:c79a1f70c110 154 uint16_t word;
Wayne Roberts 0:c79a1f70c110 155 } IrqFlags_t;
Wayne Roberts 0:c79a1f70c110 156
Wayne Roberts 0:c79a1f70c110 157 typedef union {
Wayne Roberts 0:c79a1f70c110 158 struct { //
Wayne Roberts 0:c79a1f70c110 159 uint8_t _reserved : 1; // 0
Wayne Roberts 0:c79a1f70c110 160 uint8_t cmdStatus : 3; // 1,2,3
Wayne Roberts 0:c79a1f70c110 161 uint8_t chipMode : 3; // 4,5,6
Wayne Roberts 0:c79a1f70c110 162 uint8_t reserved_ : 1; // 7
Wayne Roberts 0:c79a1f70c110 163 } bits;
Wayne Roberts 0:c79a1f70c110 164 uint8_t octet;
Wayne Roberts 0:c79a1f70c110 165 } status_t;
Wayne Roberts 0:c79a1f70c110 166
Wayne Roberts 0:c79a1f70c110 167 class SX126x {
Wayne Roberts 0:c79a1f70c110 168 public:
Wayne Roberts 0:c79a1f70c110 169 SX126x(SPI&, PinName nss, PinName busy, PinName dio1);
Wayne Roberts 0:c79a1f70c110 170
Wayne Roberts 0:c79a1f70c110 171
Wayne Roberts 0:c79a1f70c110 172 void hw_reset(PinName nrst);
Wayne Roberts 0:c79a1f70c110 173 void xfer(uint8_t opcode, uint8_t len, uint8_t* buf);
Wayne Roberts 0:c79a1f70c110 174 void setPacketType(uint8_t);
Wayne Roberts 0:c79a1f70c110 175 uint8_t setMHz(float);
Wayne Roberts 0:c79a1f70c110 176
Wayne Roberts 0:c79a1f70c110 177 /* start_tx and start_rx assumes DIO1 is connected, and only pin used to generate radio interrupt */
Wayne Roberts 0:c79a1f70c110 178 void start_tx(uint8_t pktLen); // tx_buf must be filled prior to calling
Wayne Roberts 0:c79a1f70c110 179
Wayne Roberts 0:c79a1f70c110 180 #define RX_TIMEOUT_SINGLE 0x000000
Wayne Roberts 0:c79a1f70c110 181 #define RX_TIMEOUT_CONTINUOUS 0xffffff
Wayne Roberts 0:c79a1f70c110 182 void start_rx(unsigned);
Wayne Roberts 0:c79a1f70c110 183
Wayne Roberts 0:c79a1f70c110 184 void ReadBuffer(uint8_t size);
Wayne Roberts 0:c79a1f70c110 185 void SetDIO2AsRfSwitchCtrl(uint8_t);
Wayne Roberts 0:c79a1f70c110 186 void set_tx_dbm(bool is1262, int8_t dbm);
Wayne Roberts 0:c79a1f70c110 187 uint32_t readReg(uint16_t addr, uint8_t len);
Wayne Roberts 0:c79a1f70c110 188 void writeReg(uint16_t addr, uint32_t data, uint8_t len);
Wayne Roberts 0:c79a1f70c110 189 void setStandby(stby_t);
Wayne Roberts 0:c79a1f70c110 190 void setSleep(bool warmStart, bool rtcWakeup);
Wayne Roberts 0:c79a1f70c110 191
Wayne Roberts 0:c79a1f70c110 192 static Callback<void()> dio1_topHalf; // low latency ISR context
Wayne Roberts 0:c79a1f70c110 193 void service(void);
Wayne Roberts 0:c79a1f70c110 194 Callback<void()> txDone; // user context
Wayne Roberts 0:c79a1f70c110 195 void (*rxDone)(uint8_t size, float rssi, float snr); // user context
Wayne Roberts 0:c79a1f70c110 196 void (*timeout)(bool tx); // user context
Wayne Roberts 0:c79a1f70c110 197
Wayne Roberts 0:c79a1f70c110 198 //! RF transmit packet buffer
Wayne Roberts 0:c79a1f70c110 199 uint8_t tx_buf[256]; // lora fifo size
Wayne Roberts 0:c79a1f70c110 200
Wayne Roberts 0:c79a1f70c110 201 //! RF receive packet buffer
Wayne Roberts 0:c79a1f70c110 202 uint8_t rx_buf[256]; // lora fifo size
Wayne Roberts 0:c79a1f70c110 203
Wayne Roberts 0:c79a1f70c110 204 /** Test if dio1 pin is asserted
Wayne Roberts 0:c79a1f70c110 205 */
Wayne Roberts 0:c79a1f70c110 206 inline bool getDIO1(void) { return dio1.read(); }
Wayne Roberts 0:c79a1f70c110 207 void PrintChipStatus(status_t);
Wayne Roberts 0:c79a1f70c110 208
Wayne Roberts 0:c79a1f70c110 209 private:
Wayne Roberts 0:c79a1f70c110 210 SPI& spi;
Wayne Roberts 0:c79a1f70c110 211 DigitalOut nss;
Wayne Roberts 0:c79a1f70c110 212 DigitalIn busy;
Wayne Roberts 0:c79a1f70c110 213 InterruptIn dio1;
Wayne Roberts 0:c79a1f70c110 214 static void dio1isr(void);
Wayne Roberts 0:c79a1f70c110 215 bool sleeping;
Wayne Roberts 0:c79a1f70c110 216 bool txing;
Wayne Roberts 0:c79a1f70c110 217 };
Wayne Roberts 0:c79a1f70c110 218