Hardware Abstraction Layer, permitting any LoRa application to use any LoRa radio chip

Dependents:   alarm_slave alarm_master lora_p2p lorawan1v1 ... more

radio chip selection

Radio chip driver is not included, allowing choice of radio device.
If you're using SX1272 or SX1276, then import sx127x driver into your program.
if you're using SX1261 or SX1262, then import sx126x driver into your program.
if you're using SX1280, then import sx1280 driver into your program.
if you're using LR1110, then import LR1110 driver into your program.
If you're using NAmote72 or Murata discovery, then you must import only sx127x driver.
If you're using Type1SJ select target DISCO_L072CZ_LRWAN1 and import sx126x driver into your program.

Pin assigned to arduino LoRa radio shield form-factor

Committer:
Wayne Roberts
Date:
Wed Oct 30 12:50:54 2019 -0700
Revision:
16:34de2ab7eb32
Parent:
15:e1c04ec39aa4
Child:
17:5f34cbe2ac53
take care of sx127x interrupt in glitch

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wayne Roberts 0:9c052ff8dd6a 1 #include "radio.h"
Wayne Roberts 0:9c052ff8dd6a 2 #ifdef SX128x_H
Wayne Roberts 0:9c052ff8dd6a 3 #include "SPIu.h"
Wayne Roberts 0:9c052ff8dd6a 4 #include <float.h>
Wayne Roberts 0:9c052ff8dd6a 5
Wayne Roberts 0:9c052ff8dd6a 6 #ifdef TARGET_FF_ARDUINO /* pins of SX126xDVK1xAS board */
Wayne Roberts 1:e79b0a55135f 7 #define NRST_PIN A0
Wayne Roberts 0:9c052ff8dd6a 8 SPIu spi(D11, D12, D13); // mosi, miso, sclk
Wayne Roberts 0:9c052ff8dd6a 9 // spi, nss, busy, dio1
Wayne Roberts 1:e79b0a55135f 10 SX128x Radio::radio(spi, D7, D3, D5, NRST_PIN);
Wayne Roberts 0:9c052ff8dd6a 11
Wayne Roberts 0:9c052ff8dd6a 12 #define LED_ON 1
Wayne Roberts 0:9c052ff8dd6a 13 #define LED_OFF 0
Wayne Roberts 0:9c052ff8dd6a 14 DigitalOut tx_led(A4);
Wayne Roberts 0:9c052ff8dd6a 15 DigitalOut rx_led(A5);
Wayne Roberts 0:9c052ff8dd6a 16
Wayne Roberts 0:9c052ff8dd6a 17
Wayne Roberts 0:9c052ff8dd6a 18 DigitalOut ant_sw(A3);
Wayne Roberts 0:9c052ff8dd6a 19 DigitalOut cps(D6); // SE2436L
Wayne Roberts 0:9c052ff8dd6a 20
Wayne Roberts 0:9c052ff8dd6a 21 bool fe_enable; // SE2436L
Wayne Roberts 0:9c052ff8dd6a 22
Wayne Roberts 0:9c052ff8dd6a 23 void Radio::chipModeChange()
Wayne Roberts 0:9c052ff8dd6a 24 {
Wayne Roberts 0:9c052ff8dd6a 25 if (radio.chipMode == CHIPMODE_NONE) {
Wayne Roberts 0:9c052ff8dd6a 26 cps = 0;
Wayne Roberts 0:9c052ff8dd6a 27 tx_led = LED_OFF;
Wayne Roberts 0:9c052ff8dd6a 28 rx_led = LED_OFF;
Wayne Roberts 0:9c052ff8dd6a 29 } else if (radio.chipMode == CHIPMODE_TX) {
Wayne Roberts 0:9c052ff8dd6a 30 cps = fe_enable;
Wayne Roberts 0:9c052ff8dd6a 31 tx_led = LED_ON;
Wayne Roberts 0:9c052ff8dd6a 32 rx_led = LED_OFF;
Wayne Roberts 0:9c052ff8dd6a 33 } else if (radio.chipMode == CHIPMODE_RX) {
Wayne Roberts 0:9c052ff8dd6a 34 cps = fe_enable;
Wayne Roberts 0:9c052ff8dd6a 35 tx_led = LED_OFF;
Wayne Roberts 0:9c052ff8dd6a 36 rx_led = LED_ON;
Wayne Roberts 0:9c052ff8dd6a 37 }
Wayne Roberts 0:9c052ff8dd6a 38 }
Wayne Roberts 0:9c052ff8dd6a 39 #endif /* TARGET_FF_ARDUINO */
Wayne Roberts 0:9c052ff8dd6a 40
Wayne Roberts 0:9c052ff8dd6a 41 #ifdef TARGET_FF_MORPHO
Wayne Roberts 0:9c052ff8dd6a 42 DigitalOut pc3(PC_3); // debug RX indication, for nucleo boards
Wayne Roberts 7:ba81f66e56d1 43 #define RX_INDICATION pc3
Wayne Roberts 0:9c052ff8dd6a 44 #endif /* TARGET_FF_MORPHO */
Wayne Roberts 0:9c052ff8dd6a 45
Wayne Roberts 0:9c052ff8dd6a 46
Wayne Roberts 0:9c052ff8dd6a 47 LowPowerTimer Radio::lpt;
Wayne Roberts 0:9c052ff8dd6a 48
Wayne Roberts 0:9c052ff8dd6a 49 PacketParams_t Radio::ppGFSK;
Wayne Roberts 0:9c052ff8dd6a 50 PacketParams_t Radio::ppLORA;
Wayne Roberts 0:9c052ff8dd6a 51 PacketParams_t Radio::ppFLRC;
Wayne Roberts 0:9c052ff8dd6a 52
Wayne Roberts 0:9c052ff8dd6a 53 ModulationParams_t Radio::mpBLE_GFSK;
Wayne Roberts 0:9c052ff8dd6a 54 ModulationParams_t Radio::mpFLRC;
Wayne Roberts 0:9c052ff8dd6a 55 ModulationParams_t Radio::mpLORA;
Wayne Roberts 0:9c052ff8dd6a 56
Wayne Roberts 0:9c052ff8dd6a 57 const RadioEvents_t* RadioEvents;
Wayne Roberts 0:9c052ff8dd6a 58 volatile us_timestamp_t Radio::irqAt;
Wayne Roberts 0:9c052ff8dd6a 59
Wayne Roberts 9:97a6de3dbc86 60 unsigned Radio::symbolPeriodUs;
Wayne Roberts 9:97a6de3dbc86 61 unsigned Radio::nSymbs;
Wayne Roberts 9:97a6de3dbc86 62 unsigned Radio::rxTimeoutMs;
Wayne Roberts 9:97a6de3dbc86 63
Wayne Roberts 0:9c052ff8dd6a 64 void Radio::readChip()
Wayne Roberts 0:9c052ff8dd6a 65 {
Wayne Roberts 0:9c052ff8dd6a 66 uint8_t reg8;
Wayne Roberts 0:9c052ff8dd6a 67
Wayne Roberts 0:9c052ff8dd6a 68 reg8 = radio.readReg(REG_ADDR_PKTCTRL0, 1);
Wayne Roberts 0:9c052ff8dd6a 69 ppGFSK.gfskFLRC.HeaderType = reg8 & 0x20;
Wayne Roberts 0:9c052ff8dd6a 70 ppFLRC.gfskFLRC.HeaderType = reg8 & 0x20;
Wayne Roberts 0:9c052ff8dd6a 71
Wayne Roberts 0:9c052ff8dd6a 72 reg8 = radio.readReg(REG_ADDR_PKTCTRL1, 1);
Wayne Roberts 0:9c052ff8dd6a 73 ppGFSK.gfskFLRC.PreambleLength = reg8 & 0x70;
Wayne Roberts 0:9c052ff8dd6a 74 ppFLRC.gfskFLRC.PreambleLength = reg8 & 0x70;
Wayne Roberts 0:9c052ff8dd6a 75 ppGFSK.gfskFLRC.SyncWordLength = reg8 & 0x0e;
Wayne Roberts 0:9c052ff8dd6a 76 ppFLRC.gfskFLRC.SyncWordLength = reg8 & 0x06;
Wayne Roberts 0:9c052ff8dd6a 77 if (ppFLRC.gfskFLRC.SyncWordLength == 0x06)
Wayne Roberts 0:9c052ff8dd6a 78 ppFLRC.gfskFLRC.SyncWordLength = FLRC_SYNC_WORD_LEN_P32S;
Wayne Roberts 0:9c052ff8dd6a 79
Wayne Roberts 0:9c052ff8dd6a 80 reg8 = radio.readReg(REG_ADDR_PKT_SYNC_ADRS_CTRL, 1);
Wayne Roberts 0:9c052ff8dd6a 81 ppGFSK.gfskFLRC.SyncWordMatch = reg8 & 0x70;
Wayne Roberts 0:9c052ff8dd6a 82 ppFLRC.gfskFLRC.SyncWordMatch = reg8 & 0x70;
Wayne Roberts 0:9c052ff8dd6a 83
Wayne Roberts 0:9c052ff8dd6a 84 reg8 = radio.readReg(REG_ADDR_PAYLOAD_LEN, 1);
Wayne Roberts 0:9c052ff8dd6a 85 ppGFSK.gfskFLRC.PayloadLength = reg8;
Wayne Roberts 0:9c052ff8dd6a 86 ppFLRC.gfskFLRC.PayloadLength = reg8;
Wayne Roberts 0:9c052ff8dd6a 87
Wayne Roberts 0:9c052ff8dd6a 88 reg8 = radio.readReg(REG_ADDR_PKT_TX_HEADER, 1); // TODO hi bit of payload length
Wayne Roberts 0:9c052ff8dd6a 89 //ppBLE.ble.ConnectionState = reg8 & 0xe0;
Wayne Roberts 0:9c052ff8dd6a 90 //ppBLE.ble.BleTestPayload = reg8 & 0x1c;
Wayne Roberts 0:9c052ff8dd6a 91
Wayne Roberts 0:9c052ff8dd6a 92 reg8 = radio.readReg(REG_ADDR_PKT_BITSTREAM_CTRL, 1);
Wayne Roberts 0:9c052ff8dd6a 93 //ppBLE.ble.CrcLength = reg8 & 0x30;
Wayne Roberts 0:9c052ff8dd6a 94 //ppBLE.ble.Whitening = reg8 & 0x08;
Wayne Roberts 0:9c052ff8dd6a 95 ppGFSK.gfskFLRC.CRCLength = reg8 & 0x30;
Wayne Roberts 0:9c052ff8dd6a 96 ppFLRC.gfskFLRC.CRCLength = reg8 & 0x30;
Wayne Roberts 0:9c052ff8dd6a 97 ppGFSK.gfskFLRC.Whitening = reg8 & 0x08;
Wayne Roberts 0:9c052ff8dd6a 98 ppFLRC.gfskFLRC.Whitening = reg8 & 0x08;
Wayne Roberts 0:9c052ff8dd6a 99
Wayne Roberts 0:9c052ff8dd6a 100 {
Wayne Roberts 0:9c052ff8dd6a 101 LoRaPktPar0_t LoRaPktPar0;
Wayne Roberts 0:9c052ff8dd6a 102 LoRaPktPar0.octet = radio.readReg(REG_ADDR_LORA_PKTPAR0, 1);
Wayne Roberts 0:9c052ff8dd6a 103 switch (LoRaPktPar0.bits.modem_bw) {
Wayne Roberts 0:9c052ff8dd6a 104 case 2: mpLORA.lora.bandwidth = LORA_BW_200; break;
Wayne Roberts 0:9c052ff8dd6a 105 case 3: mpLORA.lora.bandwidth = LORA_BW_400; break;
Wayne Roberts 0:9c052ff8dd6a 106 case 4: mpLORA.lora.bandwidth = LORA_BW_800; break;
Wayne Roberts 0:9c052ff8dd6a 107 case 5: mpLORA.lora.bandwidth = LORA_BW_1600; break;
Wayne Roberts 0:9c052ff8dd6a 108 }
Wayne Roberts 0:9c052ff8dd6a 109 mpLORA.lora.spreadingFactor = LoRaPktPar0.bits.modem_sf << 4;
Wayne Roberts 0:9c052ff8dd6a 110 }
Wayne Roberts 0:9c052ff8dd6a 111
Wayne Roberts 0:9c052ff8dd6a 112 {
Wayne Roberts 0:9c052ff8dd6a 113 LoRaPktPar1_t LoRaPktPar1;
Wayne Roberts 0:9c052ff8dd6a 114 LoRaPktPar1.octet = radio.readReg(REG_ADDR_LORA_PKTPAR1, 1);
Wayne Roberts 0:9c052ff8dd6a 115 mpLORA.lora.codingRate = LoRaPktPar1.bits.coding_rate;
Wayne Roberts 1:e79b0a55135f 116 ppLORA.lora.InvertIQ = LoRaPktPar1.octet & LORA_IQ_STD; // LoRaPktPar1.bits.rxinvert_iq
Wayne Roberts 1:e79b0a55135f 117 ppLORA.lora.HeaderType = LoRaPktPar1.bits.implicit_header ? IMPLICIT_HEADER : EXPLICIT_HEADER;
Wayne Roberts 0:9c052ff8dd6a 118 // LoRaPktPar1.bits.ppm_offset
Wayne Roberts 0:9c052ff8dd6a 119 }
Wayne Roberts 0:9c052ff8dd6a 120
Wayne Roberts 0:9c052ff8dd6a 121 {
Wayne Roberts 0:9c052ff8dd6a 122 LoRaPreambleReg_t LoRaPreambleReg;
Wayne Roberts 0:9c052ff8dd6a 123 LoRaPreambleReg.octet = radio.readReg(REG_ADDR_LORA_PREAMBLE, 1);
Wayne Roberts 0:9c052ff8dd6a 124 ppLORA.lora.PreambleLength = LoRaPreambleReg.bits.preamble_symb1_nb * (1 << LoRaPreambleReg.bits.preamble_symb_nb_exp);
Wayne Roberts 0:9c052ff8dd6a 125 }
Wayne Roberts 0:9c052ff8dd6a 126 ppLORA.lora.PayloadLength = radio.readReg(REG_ADDR_LORA_TX_PAYLOAD_LENGTH, 1);
Wayne Roberts 0:9c052ff8dd6a 127
Wayne Roberts 0:9c052ff8dd6a 128 {
Wayne Roberts 0:9c052ff8dd6a 129 LoRaLrCtl_t LoRaLrCtl;
Wayne Roberts 0:9c052ff8dd6a 130 LoRaLrCtl.octet = radio.readReg(REG_ADDR_LORA_LRCTL, 1);
Wayne Roberts 0:9c052ff8dd6a 131 ppLORA.lora.crc = LoRaLrCtl.octet & 0x20; // LoRaLrCtl.bits.crc_en
Wayne Roberts 0:9c052ff8dd6a 132 }
Wayne Roberts 0:9c052ff8dd6a 133
Wayne Roberts 0:9c052ff8dd6a 134 {
Wayne Roberts 0:9c052ff8dd6a 135 RegRxBw_t RegRxBw;
Wayne Roberts 0:9c052ff8dd6a 136 unsigned bps;
Wayne Roberts 0:9c052ff8dd6a 137 FloraPreambleHi_t FloraPreambleHi;
Wayne Roberts 0:9c052ff8dd6a 138 float mi, fdev_hz;
Wayne Roberts 0:9c052ff8dd6a 139 unsigned freqDev;
Wayne Roberts 0:9c052ff8dd6a 140 FskModDfH_t FskModDfH;
Wayne Roberts 0:9c052ff8dd6a 141 FskModDfH.octet = radio.readReg(REG_ADDR_FSK_MODDFH, 1);
Wayne Roberts 0:9c052ff8dd6a 142 freqDev = FskModDfH.bits.freqDev;
Wayne Roberts 0:9c052ff8dd6a 143 freqDev <<= 8;
Wayne Roberts 0:9c052ff8dd6a 144 freqDev |= radio.readReg(REG_ADDR_FSK_MODDFL, 1);
Wayne Roberts 0:9c052ff8dd6a 145 fdev_hz = freqDev * PLL_STEP_HZ;
Wayne Roberts 0:9c052ff8dd6a 146
Wayne Roberts 0:9c052ff8dd6a 147 FloraPreambleHi.octet = radio.readReg(REG_ADDR_FLORA_PREAMBLE_HI, 1);
Wayne Roberts 0:9c052ff8dd6a 148 switch (FloraPreambleHi.bits.data_rate) {
Wayne Roberts 0:9c052ff8dd6a 149 case 0:
Wayne Roberts 0:9c052ff8dd6a 150 bps = 2.0e6;
Wayne Roberts 0:9c052ff8dd6a 151 //mpFLRC.flrc.bitrateBandwidth = ??; // 2.6
Wayne Roberts 0:9c052ff8dd6a 152 break;
Wayne Roberts 0:9c052ff8dd6a 153 case 1:
Wayne Roberts 0:9c052ff8dd6a 154 bps = 1.6e6;
Wayne Roberts 0:9c052ff8dd6a 155 //mpFLRC.flrc.bitrateBandwidth = ??; // 2.08
Wayne Roberts 0:9c052ff8dd6a 156 break;
Wayne Roberts 0:9c052ff8dd6a 157 case 2:
Wayne Roberts 0:9c052ff8dd6a 158 bps = 1.0e6;
Wayne Roberts 0:9c052ff8dd6a 159 mpFLRC.flrc.bitrateBandwidth = FLRC_BR_1_300_BW_1_2; // 1.3
Wayne Roberts 0:9c052ff8dd6a 160 break;
Wayne Roberts 0:9c052ff8dd6a 161 case 3:
Wayne Roberts 0:9c052ff8dd6a 162 bps = 0.8e6;
Wayne Roberts 0:9c052ff8dd6a 163 mpFLRC.flrc.bitrateBandwidth = FLRC_BR_1_000_BW_1_2; // 1.04
Wayne Roberts 0:9c052ff8dd6a 164 break;
Wayne Roberts 0:9c052ff8dd6a 165 case 4:
Wayne Roberts 0:9c052ff8dd6a 166 bps = 0.5e6;
Wayne Roberts 0:9c052ff8dd6a 167 mpFLRC.flrc.bitrateBandwidth = FLRC_BR_0_650_BW_0_6; // 0.65
Wayne Roberts 0:9c052ff8dd6a 168 break;
Wayne Roberts 0:9c052ff8dd6a 169 case 5:
Wayne Roberts 0:9c052ff8dd6a 170 bps = 0.4e6;
Wayne Roberts 0:9c052ff8dd6a 171 mpFLRC.flrc.bitrateBandwidth = FLRC_BR_0_520_BW_0_6; // 0.52
Wayne Roberts 0:9c052ff8dd6a 172 break;
Wayne Roberts 0:9c052ff8dd6a 173 case 6:
Wayne Roberts 0:9c052ff8dd6a 174 bps = 0.25e6;
Wayne Roberts 0:9c052ff8dd6a 175 mpFLRC.flrc.bitrateBandwidth = FLRC_BR_0_325_BW_0_3; // 0.325
Wayne Roberts 0:9c052ff8dd6a 176 break;
Wayne Roberts 0:9c052ff8dd6a 177 case 7:
Wayne Roberts 0:9c052ff8dd6a 178 bps = 0.125e6;
Wayne Roberts 0:9c052ff8dd6a 179 mpFLRC.flrc.bitrateBandwidth = FLRC_BR_0_260_BW_0_3; // 0.26
Wayne Roberts 0:9c052ff8dd6a 180 break;
Wayne Roberts 0:9c052ff8dd6a 181 }
Wayne Roberts 0:9c052ff8dd6a 182
Wayne Roberts 0:9c052ff8dd6a 183 mi = (fdev_hz * 2.0) / bps;
Wayne Roberts 0:9c052ff8dd6a 184 if (mi > 0.35) {
Wayne Roberts 0:9c052ff8dd6a 185 mi -= 0.5;
Wayne Roberts 0:9c052ff8dd6a 186 mi /= 0.25;
Wayne Roberts 0:9c052ff8dd6a 187 mpBLE_GFSK.gfskBle.ModulationIndex = ((uint8_t)mi) + 1;
Wayne Roberts 0:9c052ff8dd6a 188 } else
Wayne Roberts 0:9c052ff8dd6a 189 mpBLE_GFSK.gfskBle.ModulationIndex = 0;
Wayne Roberts 0:9c052ff8dd6a 190
Wayne Roberts 0:9c052ff8dd6a 191 RegRxBw.octet = radio.readReg(REG_ADDR_RXBW, 1);
Wayne Roberts 0:9c052ff8dd6a 192
Wayne Roberts 0:9c052ff8dd6a 193 switch (RegRxBw.bits.bw) {
Wayne Roberts 0:9c052ff8dd6a 194 case 0:
Wayne Roberts 0:9c052ff8dd6a 195 if (FloraPreambleHi.bits.data_rate == 0)
Wayne Roberts 0:9c052ff8dd6a 196 mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_2_000_BW_2_4;
Wayne Roberts 0:9c052ff8dd6a 197 if (FloraPreambleHi.bits.data_rate == 1)
Wayne Roberts 0:9c052ff8dd6a 198 mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_1_600_BW_2_4;
Wayne Roberts 0:9c052ff8dd6a 199 if (FloraPreambleHi.bits.data_rate == 2)
Wayne Roberts 0:9c052ff8dd6a 200 mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_1_000_BW_2_4;
Wayne Roberts 0:9c052ff8dd6a 201 if (FloraPreambleHi.bits.data_rate == 3)
Wayne Roberts 0:9c052ff8dd6a 202 mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_800_BW_2_4;
Wayne Roberts 0:9c052ff8dd6a 203 break;
Wayne Roberts 0:9c052ff8dd6a 204 case 1:
Wayne Roberts 0:9c052ff8dd6a 205 if (FloraPreambleHi.bits.data_rate == 2)
Wayne Roberts 0:9c052ff8dd6a 206 mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_1_000_BW_1_2;
Wayne Roberts 0:9c052ff8dd6a 207 if (FloraPreambleHi.bits.data_rate == 3)
Wayne Roberts 0:9c052ff8dd6a 208 mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_800_BW_1_2;
Wayne Roberts 0:9c052ff8dd6a 209 if (FloraPreambleHi.bits.data_rate == 4)
Wayne Roberts 0:9c052ff8dd6a 210 mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_500_BW_1_2;
Wayne Roberts 0:9c052ff8dd6a 211 if (FloraPreambleHi.bits.data_rate == 5)
Wayne Roberts 0:9c052ff8dd6a 212 mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_400_BW_1_2;
Wayne Roberts 0:9c052ff8dd6a 213 break;
Wayne Roberts 0:9c052ff8dd6a 214 case 2:
Wayne Roberts 0:9c052ff8dd6a 215 if (FloraPreambleHi.bits.data_rate == 4)
Wayne Roberts 0:9c052ff8dd6a 216 mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_500_BW_0_6;
Wayne Roberts 0:9c052ff8dd6a 217 if (FloraPreambleHi.bits.data_rate == 5)
Wayne Roberts 0:9c052ff8dd6a 218 mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_400_BW_0_6;
Wayne Roberts 0:9c052ff8dd6a 219 if (FloraPreambleHi.bits.data_rate == 6)
Wayne Roberts 0:9c052ff8dd6a 220 mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_250_BW_0_6;
Wayne Roberts 0:9c052ff8dd6a 221 break;
Wayne Roberts 0:9c052ff8dd6a 222 case 3:
Wayne Roberts 0:9c052ff8dd6a 223 if (FloraPreambleHi.bits.data_rate == 6)
Wayne Roberts 0:9c052ff8dd6a 224 mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_250_BW_0_3;
Wayne Roberts 0:9c052ff8dd6a 225 if (FloraPreambleHi.bits.data_rate == 7)
Wayne Roberts 0:9c052ff8dd6a 226 mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_125_BW_0_3;
Wayne Roberts 0:9c052ff8dd6a 227 break;
Wayne Roberts 0:9c052ff8dd6a 228 }
Wayne Roberts 0:9c052ff8dd6a 229 mpBLE_GFSK.gfskBle.bitrateBandwidth = reg8;
Wayne Roberts 0:9c052ff8dd6a 230 }
Wayne Roberts 0:9c052ff8dd6a 231
Wayne Roberts 0:9c052ff8dd6a 232 {
Wayne Roberts 0:9c052ff8dd6a 233 FskCfg_t FskCfg;
Wayne Roberts 0:9c052ff8dd6a 234 FskCfg.octet = radio.readReg(REG_ADDR_FSK_CFG, 1);
Wayne Roberts 0:9c052ff8dd6a 235 mpBLE_GFSK.gfskBle.ModulationShaping = FskCfg.bits.gf_bt << 4;
Wayne Roberts 0:9c052ff8dd6a 236 mpFLRC.flrc.ModulationShaping = mpBLE_GFSK.gfskBle.ModulationShaping;
Wayne Roberts 0:9c052ff8dd6a 237 }
Wayne Roberts 0:9c052ff8dd6a 238
Wayne Roberts 0:9c052ff8dd6a 239 {
Wayne Roberts 0:9c052ff8dd6a 240 PktBitStreamCtrl_t PktBitStreamCtrl;
Wayne Roberts 0:9c052ff8dd6a 241 PktBitStreamCtrl.octet = radio.readReg(REG_ADDR_PKT_BITSTREAM_CTRL, 1);
Wayne Roberts 0:9c052ff8dd6a 242 mpFLRC.flrc.CodingRate = PktBitStreamCtrl.octet & 0x06; // PktBitStreamCtrl.bits.flora_coding_rate
Wayne Roberts 0:9c052ff8dd6a 243 }
Wayne Roberts 0:9c052ff8dd6a 244
Wayne Roberts 0:9c052ff8dd6a 245 }
Wayne Roberts 0:9c052ff8dd6a 246
Wayne Roberts 0:9c052ff8dd6a 247 void Radio:: diox_top_half()
Wayne Roberts 0:9c052ff8dd6a 248 {
Wayne Roberts 0:9c052ff8dd6a 249 irqAt = lpt.read_us();
Wayne Roberts 0:9c052ff8dd6a 250
Wayne Roberts 14:94993ae5b164 251 if (RadioEvents->DioPin_top_half)
Wayne Roberts 14:94993ae5b164 252 RadioEvents->DioPin_top_half();
Wayne Roberts 14:94993ae5b164 253
Wayne Roberts 0:9c052ff8dd6a 254 if (radio.chipMode == CHIPMODE_TX) {
Wayne Roberts 0:9c052ff8dd6a 255 /* TxDone handling requires low latency */
Wayne Roberts 0:9c052ff8dd6a 256 if (RadioEvents->TxDone_topHalf) {
Wayne Roberts 0:9c052ff8dd6a 257 RadioEvents->TxDone_topHalf();
Wayne Roberts 0:9c052ff8dd6a 258 }
Wayne Roberts 7:ba81f66e56d1 259 } else {
Wayne Roberts 7:ba81f66e56d1 260 #ifdef RX_INDICATION
Wayne Roberts 7:ba81f66e56d1 261 RX_INDICATION = 0;
Wayne Roberts 7:ba81f66e56d1 262 #endif
Wayne Roberts 0:9c052ff8dd6a 263 }
Wayne Roberts 0:9c052ff8dd6a 264 }
Wayne Roberts 0:9c052ff8dd6a 265
Wayne Roberts 0:9c052ff8dd6a 266 void Radio::rxDone(uint8_t size, const pktStatus_t* pktStatus)
Wayne Roberts 0:9c052ff8dd6a 267 {
Wayne Roberts 0:9c052ff8dd6a 268 float rssi, snr;
Wayne Roberts 0:9c052ff8dd6a 269
Wayne Roberts 0:9c052ff8dd6a 270 if (pktStatus->ble_gfsk_flrc.sync.syncAddrsCode == 0) {
Wayne Roberts 0:9c052ff8dd6a 271 int8_t s = pktStatus->lora.snr;
Wayne Roberts 0:9c052ff8dd6a 272 rssi = -pktStatus->lora.rssiSync / 2.0;
Wayne Roberts 0:9c052ff8dd6a 273 snr = s / 4.0;
Wayne Roberts 0:9c052ff8dd6a 274 } else {
Wayne Roberts 0:9c052ff8dd6a 275 rssi = -pktStatus->ble_gfsk_flrc.rssiSync / 2.0;
Wayne Roberts 0:9c052ff8dd6a 276 snr = FLT_MIN;
Wayne Roberts 0:9c052ff8dd6a 277 }
Wayne Roberts 0:9c052ff8dd6a 278
Wayne Roberts 0:9c052ff8dd6a 279 RadioEvents->RxDone(size, rssi, snr);
Wayne Roberts 0:9c052ff8dd6a 280 }
Wayne Roberts 0:9c052ff8dd6a 281
Wayne Roberts 0:9c052ff8dd6a 282 void Radio::timeout_callback(bool tx)
Wayne Roberts 0:9c052ff8dd6a 283 {
Wayne Roberts 0:9c052ff8dd6a 284 if (!tx) {
Wayne Roberts 0:9c052ff8dd6a 285 if (RadioEvents->RxTimeout)
Wayne Roberts 0:9c052ff8dd6a 286 RadioEvents->RxTimeout();
Wayne Roberts 7:ba81f66e56d1 287 #ifdef RX_INDICATION
Wayne Roberts 7:ba81f66e56d1 288 RX_INDICATION = 0;
Wayne Roberts 7:ba81f66e56d1 289 #endif
Wayne Roberts 16:34de2ab7eb32 290 } else if (RadioEvents->TxTimeout)
Wayne Roberts 16:34de2ab7eb32 291 RadioEvents->TxTimeout();
Wayne Roberts 0:9c052ff8dd6a 292 }
Wayne Roberts 0:9c052ff8dd6a 293
Wayne Roberts 0:9c052ff8dd6a 294 void Radio::txDoneBottom()
Wayne Roberts 0:9c052ff8dd6a 295 {
Wayne Roberts 0:9c052ff8dd6a 296 if (RadioEvents->TxDone_botHalf)
Wayne Roberts 0:9c052ff8dd6a 297 RadioEvents->TxDone_botHalf();
Wayne Roberts 0:9c052ff8dd6a 298 }
Wayne Roberts 0:9c052ff8dd6a 299
Wayne Roberts 13:a354f82d12d9 300 void Radio::Init(const RadioEvents_t* e, unsigned spi_hz)
Wayne Roberts 0:9c052ff8dd6a 301 {
Wayne Roberts 0:9c052ff8dd6a 302 uint64_t sa;
Wayne Roberts 0:9c052ff8dd6a 303
Wayne Roberts 0:9c052ff8dd6a 304 radio.txDone = txDoneBottom;
Wayne Roberts 0:9c052ff8dd6a 305 radio.rxDone = rxDone;
Wayne Roberts 0:9c052ff8dd6a 306 radio.timeout = timeout_callback;
Wayne Roberts 0:9c052ff8dd6a 307 radio.chipModeChange = chipModeChange;
Wayne Roberts 0:9c052ff8dd6a 308 radio.diox_topHalf = diox_top_half;
Wayne Roberts 0:9c052ff8dd6a 309
Wayne Roberts 13:a354f82d12d9 310 spi.frequency(spi_hz);
Wayne Roberts 0:9c052ff8dd6a 311 readChip();
Wayne Roberts 0:9c052ff8dd6a 312
Wayne Roberts 0:9c052ff8dd6a 313 radio.setRegulator(0); // default to LDO
Wayne Roberts 0:9c052ff8dd6a 314
Wayne Roberts 0:9c052ff8dd6a 315 sa = 0xc194c1;
Wayne Roberts 0:9c052ff8dd6a 316 radio.setSyncAddr(1, sa);
Wayne Roberts 0:9c052ff8dd6a 317
Wayne Roberts 0:9c052ff8dd6a 318 RadioEvents = e;
Wayne Roberts 0:9c052ff8dd6a 319 lpt.start();
Wayne Roberts 0:9c052ff8dd6a 320
Wayne Roberts 0:9c052ff8dd6a 321 fe_enable = true;
Wayne Roberts 0:9c052ff8dd6a 322
Wayne Roberts 0:9c052ff8dd6a 323 radio.periodBase = 2; // 1ms resolution
Wayne Roberts 9:97a6de3dbc86 324 nSymbs = 8;
Wayne Roberts 0:9c052ff8dd6a 325 }
Wayne Roberts 0:9c052ff8dd6a 326
Wayne Roberts 7:ba81f66e56d1 327 float Radio::GetRssiInst()
Wayne Roberts 7:ba81f66e56d1 328 {
Wayne Roberts 7:ba81f66e56d1 329 uint8_t buf[2];
Wayne Roberts 7:ba81f66e56d1 330 radio.xfer(OPCODE_GET_RSSIINST, 0, 2, buf);
Wayne Roberts 7:ba81f66e56d1 331 return buf[1] / -2.0;
Wayne Roberts 7:ba81f66e56d1 332 }
Wayne Roberts 7:ba81f66e56d1 333
Wayne Roberts 0:9c052ff8dd6a 334 int Radio::Send(uint8_t size, timestamp_t maxListenTime, timestamp_t channelFreeTime, int rssiThresh)
Wayne Roberts 0:9c052ff8dd6a 335 {
Wayne Roberts 0:9c052ff8dd6a 336 uint8_t buf[8];
Wayne Roberts 1:e79b0a55135f 337 uint8_t pktType = radio.getPacketType();
Wayne Roberts 0:9c052ff8dd6a 338
Wayne Roberts 1:e79b0a55135f 339 if (pktType == PACKET_TYPE_LORA) {
Wayne Roberts 1:e79b0a55135f 340 ppLORA.lora.PayloadLength = size;
Wayne Roberts 1:e79b0a55135f 341 radio.xfer(OPCODE_SET_PACKET_PARAMS, 5, 0, ppLORA.buf);
Wayne Roberts 1:e79b0a55135f 342 } else if (pktType == PACKET_TYPE_GFSK) {
Wayne Roberts 0:9c052ff8dd6a 343 ppGFSK.gfskFLRC.PayloadLength = size;
Wayne Roberts 0:9c052ff8dd6a 344 radio.xfer(OPCODE_SET_PACKET_PARAMS, 7, 0, ppGFSK.buf);
Wayne Roberts 0:9c052ff8dd6a 345 }
Wayne Roberts 0:9c052ff8dd6a 346
Wayne Roberts 0:9c052ff8dd6a 347 if (maxListenTime > 0) {
Wayne Roberts 0:9c052ff8dd6a 348 int rssi;
Wayne Roberts 0:9c052ff8dd6a 349 us_timestamp_t startAt, chFreeAt, now;
Wayne Roberts 0:9c052ff8dd6a 350 radio.start_rx(-1);
Wayne Roberts 0:9c052ff8dd6a 351 startAt = lpt.read_us();
Wayne Roberts 0:9c052ff8dd6a 352 Lstart:
Wayne Roberts 0:9c052ff8dd6a 353 do {
Wayne Roberts 0:9c052ff8dd6a 354 now = lpt.read_us();
Wayne Roberts 0:9c052ff8dd6a 355 if ((now - startAt) > maxListenTime) {
Wayne Roberts 0:9c052ff8dd6a 356 return -1;
Wayne Roberts 0:9c052ff8dd6a 357 }
Wayne Roberts 0:9c052ff8dd6a 358 radio.xfer(OPCODE_GET_RSSIINST, 0, 2, buf);
Wayne Roberts 0:9c052ff8dd6a 359 rssi = buf[1] / -2;
Wayne Roberts 0:9c052ff8dd6a 360 } while (rssi > rssiThresh);
Wayne Roberts 0:9c052ff8dd6a 361 chFreeAt = lpt.read_us();
Wayne Roberts 0:9c052ff8dd6a 362 do {
Wayne Roberts 0:9c052ff8dd6a 363 now = lpt.read_us();
Wayne Roberts 0:9c052ff8dd6a 364 radio.xfer(OPCODE_GET_RSSIINST, 0, 2, buf);
Wayne Roberts 0:9c052ff8dd6a 365 rssi = buf[1] / -2;
Wayne Roberts 0:9c052ff8dd6a 366 if (rssi > rssiThresh) {
Wayne Roberts 0:9c052ff8dd6a 367 goto Lstart;
Wayne Roberts 0:9c052ff8dd6a 368 }
Wayne Roberts 0:9c052ff8dd6a 369 } while ((now - chFreeAt) < channelFreeTime);
Wayne Roberts 0:9c052ff8dd6a 370 }
Wayne Roberts 0:9c052ff8dd6a 371
Wayne Roberts 0:9c052ff8dd6a 372 radio.start_tx(size, 4000);
Wayne Roberts 0:9c052ff8dd6a 373
Wayne Roberts 0:9c052ff8dd6a 374 return 0;
Wayne Roberts 0:9c052ff8dd6a 375 }
Wayne Roberts 0:9c052ff8dd6a 376
Wayne Roberts 16:34de2ab7eb32 377 extern RawSerial pc;
Wayne Roberts 0:9c052ff8dd6a 378 void Radio::service()
Wayne Roberts 0:9c052ff8dd6a 379 {
Wayne Roberts 0:9c052ff8dd6a 380 radio.service();
Wayne Roberts 0:9c052ff8dd6a 381 }
Wayne Roberts 0:9c052ff8dd6a 382
Wayne Roberts 0:9c052ff8dd6a 383 bool Radio::CheckRfFrequency(unsigned hz)
Wayne Roberts 0:9c052ff8dd6a 384 {
Wayne Roberts 0:9c052ff8dd6a 385 return true;
Wayne Roberts 0:9c052ff8dd6a 386 }
Wayne Roberts 0:9c052ff8dd6a 387
Wayne Roberts 0:9c052ff8dd6a 388 void Radio::Sleep()
Wayne Roberts 0:9c052ff8dd6a 389 {
Wayne Roberts 0:9c052ff8dd6a 390 radio.setSleep(true);
Wayne Roberts 0:9c052ff8dd6a 391 }
Wayne Roberts 0:9c052ff8dd6a 392
Wayne Roberts 0:9c052ff8dd6a 393 void Radio::SetPublicNetwork(bool en)
Wayne Roberts 0:9c052ff8dd6a 394 {
Wayne Roberts 8:0518c6e68b79 395 /* uint16_t ppg;
Wayne Roberts 0:9c052ff8dd6a 396
Wayne Roberts 0:9c052ff8dd6a 397 if (en)
Wayne Roberts 0:9c052ff8dd6a 398 ppg = 0x3444;
Wayne Roberts 0:9c052ff8dd6a 399 else
Wayne Roberts 0:9c052ff8dd6a 400 ppg = 0x1424;
Wayne Roberts 0:9c052ff8dd6a 401
Wayne Roberts 0:9c052ff8dd6a 402 radio.writeReg(REG_ADDR_LORA_SYNC, ppg, 2);
Wayne Roberts 8:0518c6e68b79 403 */
Wayne Roberts 0:9c052ff8dd6a 404 }
Wayne Roberts 0:9c052ff8dd6a 405
Wayne Roberts 0:9c052ff8dd6a 406 uint32_t Radio::lora_toa_us( uint8_t pktLen )
Wayne Roberts 0:9c052ff8dd6a 407 {
Wayne Roberts 0:9c052ff8dd6a 408 double bwKHz;
Wayne Roberts 0:9c052ff8dd6a 409 LoRaPktPar0_t LoRaPktPar0;
Wayne Roberts 0:9c052ff8dd6a 410 LoRaLrCtl_t LoRaLrCtl;
Wayne Roberts 0:9c052ff8dd6a 411 LoRaPktPar1_t LoRaPktPar1;
Wayne Roberts 0:9c052ff8dd6a 412 uint8_t LowDatarateOptimize;
Wayne Roberts 0:9c052ff8dd6a 413
Wayne Roberts 0:9c052ff8dd6a 414 {
Wayne Roberts 0:9c052ff8dd6a 415 LoRaPktPar1.octet = radio.readReg(REG_ADDR_LORA_PKTPAR1, 1);
Wayne Roberts 0:9c052ff8dd6a 416 LowDatarateOptimize = LoRaPktPar1.bits.ppm_offset ? 1 : 0;
Wayne Roberts 1:e79b0a55135f 417 ppLORA.lora.HeaderType = LoRaPktPar1.bits.implicit_header ? IMPLICIT_HEADER : EXPLICIT_HEADER;
Wayne Roberts 1:e79b0a55135f 418 ppLORA.lora.InvertIQ = LoRaPktPar1.octet & LORA_IQ_STD; // LoRaPktPar1.bits.rxinvert_iq
Wayne Roberts 0:9c052ff8dd6a 419 mpLORA.lora.codingRate = LoRaPktPar1.bits.coding_rate;
Wayne Roberts 0:9c052ff8dd6a 420 }
Wayne Roberts 0:9c052ff8dd6a 421
Wayne Roberts 0:9c052ff8dd6a 422 {
Wayne Roberts 0:9c052ff8dd6a 423 LoRaLrCtl.octet = radio.readReg(REG_ADDR_LORA_LRCTL, 1);
Wayne Roberts 0:9c052ff8dd6a 424 ppLORA.lora.crc = LoRaLrCtl.octet & 0x20; // LoRaLrCtl.bits.crc_en
Wayne Roberts 0:9c052ff8dd6a 425 }
Wayne Roberts 0:9c052ff8dd6a 426
Wayne Roberts 0:9c052ff8dd6a 427 {
Wayne Roberts 0:9c052ff8dd6a 428 LoRaPreambleReg_t LoRaPreambleReg;
Wayne Roberts 0:9c052ff8dd6a 429 LoRaPreambleReg.octet = radio.readReg(REG_ADDR_LORA_PREAMBLE, 1);
Wayne Roberts 0:9c052ff8dd6a 430 ppLORA.lora.PreambleLength = LoRaPreambleReg.bits.preamble_symb1_nb * (1 << LoRaPreambleReg.bits.preamble_symb_nb_exp);
Wayne Roberts 0:9c052ff8dd6a 431 }
Wayne Roberts 0:9c052ff8dd6a 432
Wayne Roberts 0:9c052ff8dd6a 433 {
Wayne Roberts 0:9c052ff8dd6a 434 LoRaPktPar0.octet = radio.readReg(REG_ADDR_LORA_PKTPAR0, 1);
Wayne Roberts 0:9c052ff8dd6a 435 switch (LoRaPktPar0.bits.modem_bw) {
Wayne Roberts 0:9c052ff8dd6a 436 case 0: bwKHz = 50; break;
Wayne Roberts 0:9c052ff8dd6a 437 case 1: bwKHz = 100; break;
Wayne Roberts 0:9c052ff8dd6a 438 case 2: mpLORA.lora.bandwidth = LORA_BW_200; bwKHz = 200; break;
Wayne Roberts 0:9c052ff8dd6a 439 case 3: mpLORA.lora.bandwidth = LORA_BW_400; bwKHz = 400; break;
Wayne Roberts 0:9c052ff8dd6a 440 case 4: mpLORA.lora.bandwidth = LORA_BW_800; bwKHz = 800; break;
Wayne Roberts 0:9c052ff8dd6a 441 case 5: mpLORA.lora.bandwidth = LORA_BW_1600; bwKHz = 1600; break;
Wayne Roberts 0:9c052ff8dd6a 442 default: bwKHz = 0; break;
Wayne Roberts 0:9c052ff8dd6a 443 }
Wayne Roberts 0:9c052ff8dd6a 444 mpLORA.lora.spreadingFactor = LoRaPktPar0.bits.modem_sf << 4;
Wayne Roberts 0:9c052ff8dd6a 445 }
Wayne Roberts 0:9c052ff8dd6a 446
Wayne Roberts 0:9c052ff8dd6a 447 // Symbol rate : time for one symbol (secs)
Wayne Roberts 0:9c052ff8dd6a 448 double rs = bwKHz / (1 << LoRaPktPar0.bits.modem_sf);
Wayne Roberts 0:9c052ff8dd6a 449 double ts = 1 / rs;
Wayne Roberts 0:9c052ff8dd6a 450 // time of preamble
Wayne Roberts 0:9c052ff8dd6a 451 //
Wayne Roberts 0:9c052ff8dd6a 452 double tPreamble = ( ppLORA.lora.PreambleLength + 4.25 ) * ts;
Wayne Roberts 0:9c052ff8dd6a 453 // Symbol length of payload and time
Wayne Roberts 0:9c052ff8dd6a 454
Wayne Roberts 0:9c052ff8dd6a 455 double tmp = ceil( ( 8 * pktLen - 4 * LoRaPktPar0.bits.modem_sf +
Wayne Roberts 0:9c052ff8dd6a 456 28 + 16 * LoRaLrCtl.bits.crc_en -
Wayne Roberts 0:9c052ff8dd6a 457 ( LoRaPktPar1.bits.implicit_header ? 20 : 0 ) ) /
Wayne Roberts 0:9c052ff8dd6a 458 ( double )( 4 * ( LoRaPktPar0.bits.modem_sf -
Wayne Roberts 0:9c052ff8dd6a 459 ( ( LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) ) *
Wayne Roberts 0:9c052ff8dd6a 460 ( LoRaPktPar1.bits.coding_rate + 4 );
Wayne Roberts 0:9c052ff8dd6a 461
Wayne Roberts 0:9c052ff8dd6a 462 double nPayload = 8 + ( ( tmp > 0 ) ? tmp : 0 );
Wayne Roberts 0:9c052ff8dd6a 463 double tPayload = nPayload * ts;
Wayne Roberts 0:9c052ff8dd6a 464 // Time on air
Wayne Roberts 0:9c052ff8dd6a 465 double tOnAir = tPreamble + tPayload;
Wayne Roberts 0:9c052ff8dd6a 466 // return microseconds
Wayne Roberts 0:9c052ff8dd6a 467 return floor( tOnAir * 1000 + 0.999 );
Wayne Roberts 0:9c052ff8dd6a 468 }
Wayne Roberts 0:9c052ff8dd6a 469
Wayne Roberts 0:9c052ff8dd6a 470 void Radio::GFSKModemConfig(unsigned bps, unsigned bw_hz, unsigned fdev_hz)
Wayne Roberts 0:9c052ff8dd6a 471 {
Wayne Roberts 0:9c052ff8dd6a 472 uint8_t u8;
Wayne Roberts 0:9c052ff8dd6a 473 float mi, Mbps = bps / 1000000.0;
Wayne Roberts 0:9c052ff8dd6a 474
Wayne Roberts 0:9c052ff8dd6a 475 if (Mbps > 1.6) {
Wayne Roberts 0:9c052ff8dd6a 476 /* 2.0Mbps */
Wayne Roberts 0:9c052ff8dd6a 477 u8 = GFSK_BLE_BR_2_000_BW_2_4;
Wayne Roberts 0:9c052ff8dd6a 478 } else if (Mbps > 1.0) {
Wayne Roberts 0:9c052ff8dd6a 479 /* 1.6Mbps */
Wayne Roberts 0:9c052ff8dd6a 480 u8 = GFSK_BLE_BR_1_600_BW_2_4;
Wayne Roberts 0:9c052ff8dd6a 481 } else if (Mbps > 0.8) {
Wayne Roberts 0:9c052ff8dd6a 482 /* 1.0Mbps */
Wayne Roberts 0:9c052ff8dd6a 483 /*if (bwMHz > 1.2)
Wayne Roberts 0:9c052ff8dd6a 484 u8 = GFSK_BLE_BR_1_000_BW_2_4;
Wayne Roberts 0:9c052ff8dd6a 485 else*/
Wayne Roberts 0:9c052ff8dd6a 486 u8 = GFSK_BLE_BR_1_000_BW_1_2;
Wayne Roberts 0:9c052ff8dd6a 487 } else if (Mbps > 0.5) {
Wayne Roberts 0:9c052ff8dd6a 488 /* 0.8Mbps */
Wayne Roberts 0:9c052ff8dd6a 489 /*if (bwMHz > 1.2)
Wayne Roberts 0:9c052ff8dd6a 490 u8 = GFSK_BLE_BR_0_800_BW_2_4;
Wayne Roberts 0:9c052ff8dd6a 491 else*/
Wayne Roberts 0:9c052ff8dd6a 492 u8 = GFSK_BLE_BR_0_800_BW_1_2;
Wayne Roberts 0:9c052ff8dd6a 493 } else if (Mbps > 0.4) {
Wayne Roberts 0:9c052ff8dd6a 494 /* 0.5Mbps */
Wayne Roberts 0:9c052ff8dd6a 495 /*if (bwMHz > 0.6)
Wayne Roberts 0:9c052ff8dd6a 496 u8 = GFSK_BLE_BR_0_500_BW_1_2;
Wayne Roberts 0:9c052ff8dd6a 497 else*/
Wayne Roberts 0:9c052ff8dd6a 498 u8 = GFSK_BLE_BR_0_500_BW_0_6;
Wayne Roberts 0:9c052ff8dd6a 499 } else if (Mbps > 0.25) {
Wayne Roberts 0:9c052ff8dd6a 500 /* 0.4Mbps */
Wayne Roberts 0:9c052ff8dd6a 501 /*if (bwMHz > 0.6)
Wayne Roberts 0:9c052ff8dd6a 502 u8 = GFSK_BLE_BR_0_400_BW_1_2;
Wayne Roberts 0:9c052ff8dd6a 503 else*/
Wayne Roberts 0:9c052ff8dd6a 504 u8 = GFSK_BLE_BR_0_400_BW_0_6;
Wayne Roberts 0:9c052ff8dd6a 505 } else if (Mbps > 0.125) {
Wayne Roberts 0:9c052ff8dd6a 506 /* 0.25Mbps */
Wayne Roberts 0:9c052ff8dd6a 507 /*if (bwMHz > 0.3)
Wayne Roberts 0:9c052ff8dd6a 508 u8 = GFSK_BLE_BR_0_250_BW_0_6;
Wayne Roberts 0:9c052ff8dd6a 509 else*/
Wayne Roberts 0:9c052ff8dd6a 510 u8 = GFSK_BLE_BR_0_250_BW_0_3;
Wayne Roberts 0:9c052ff8dd6a 511 } else {
Wayne Roberts 0:9c052ff8dd6a 512 /* 0.125Mbps */
Wayne Roberts 0:9c052ff8dd6a 513 u8 = GFSK_BLE_BR_0_125_BW_0_3;
Wayne Roberts 0:9c052ff8dd6a 514 }
Wayne Roberts 0:9c052ff8dd6a 515
Wayne Roberts 0:9c052ff8dd6a 516 mpBLE_GFSK.gfskBle.bitrateBandwidth = u8;
Wayne Roberts 0:9c052ff8dd6a 517
Wayne Roberts 0:9c052ff8dd6a 518 mpBLE_GFSK.gfskBle.ModulationShaping = BT_OFF;
Wayne Roberts 0:9c052ff8dd6a 519
Wayne Roberts 0:9c052ff8dd6a 520 mi = (fdev_hz * 2.0) / bps;
Wayne Roberts 0:9c052ff8dd6a 521 if (mi > 0.35) {
Wayne Roberts 0:9c052ff8dd6a 522 mi -= 0.5;
Wayne Roberts 0:9c052ff8dd6a 523 mi /= 0.25;
Wayne Roberts 0:9c052ff8dd6a 524 mpBLE_GFSK.gfskBle.ModulationIndex = ((uint8_t)mi) + 1;
Wayne Roberts 0:9c052ff8dd6a 525 } else
Wayne Roberts 0:9c052ff8dd6a 526 mpBLE_GFSK.gfskBle.ModulationIndex = 0;
Wayne Roberts 0:9c052ff8dd6a 527
Wayne Roberts 0:9c052ff8dd6a 528 radio.xfer(OPCODE_SET_MODULATION_PARAMS, 3, 0, mpBLE_GFSK.buf);
Wayne Roberts 0:9c052ff8dd6a 529 }
Wayne Roberts 0:9c052ff8dd6a 530
Wayne Roberts 0:9c052ff8dd6a 531 void Radio::GFSKPacketConfig(unsigned preambleLen, bool fixLen, bool crcOn)
Wayne Roberts 0:9c052ff8dd6a 532 {
Wayne Roberts 0:9c052ff8dd6a 533 ppGFSK.gfskFLRC.PreambleLength = (preambleLen - 4) / 4;
Wayne Roberts 0:9c052ff8dd6a 534 ppGFSK.gfskFLRC.PreambleLength <<= 4;
Wayne Roberts 0:9c052ff8dd6a 535 ppGFSK.gfskFLRC.SyncWordLength = (3 - 1) << 1; // 3 byte 0xc194c1
Wayne Roberts 0:9c052ff8dd6a 536 ppGFSK.gfskFLRC.HeaderType = fixLen ? RADIO_PACKET_FIXED_LENGTH : RADIO_PACKET_VARIABLE_LENGTH;
Wayne Roberts 0:9c052ff8dd6a 537 ppGFSK.gfskFLRC.CRCLength = crcOn ? RADIO_CRC_2_BYTES : RADIO_CRC_OFF;
Wayne Roberts 0:9c052ff8dd6a 538
Wayne Roberts 0:9c052ff8dd6a 539 // TODO ppGFSK.gfskFLRC.PayloadLength = ;
Wayne Roberts 0:9c052ff8dd6a 540
Wayne Roberts 0:9c052ff8dd6a 541 radio.xfer(OPCODE_SET_PACKET_PARAMS, 7, 0, ppGFSK.buf);
Wayne Roberts 0:9c052ff8dd6a 542 }
Wayne Roberts 0:9c052ff8dd6a 543
Wayne Roberts 13:a354f82d12d9 544 void Radio::SetLoRaSymbolTimeout(uint16_t symbs)
Wayne Roberts 0:9c052ff8dd6a 545 {
Wayne Roberts 9:97a6de3dbc86 546 nSymbs = symbs;
Wayne Roberts 9:97a6de3dbc86 547 rxTimeoutMs = nSymbs * (symbolPeriodUs / 1000.0);
Wayne Roberts 0:9c052ff8dd6a 548 }
Wayne Roberts 0:9c052ff8dd6a 549
Wayne Roberts 0:9c052ff8dd6a 550 void Radio::LoRaModemConfig(unsigned bwKHz, uint8_t sf, uint8_t cr)
Wayne Roberts 0:9c052ff8dd6a 551 {
Wayne Roberts 1:e79b0a55135f 552 if (radio.getPacketType() != PACKET_TYPE_LORA)
Wayne Roberts 1:e79b0a55135f 553 radio.setPacketType(PACKET_TYPE_LORA);
Wayne Roberts 1:e79b0a55135f 554
Wayne Roberts 12:fcfafd17ae1b 555 if (bwKHz > 800)
Wayne Roberts 0:9c052ff8dd6a 556 mpLORA.lora.bandwidth = LORA_BW_1600;
Wayne Roberts 12:fcfafd17ae1b 557 else if (bwKHz > 400)
Wayne Roberts 0:9c052ff8dd6a 558 mpLORA.lora.bandwidth = LORA_BW_800;
Wayne Roberts 12:fcfafd17ae1b 559 else if (bwKHz > 200)
Wayne Roberts 0:9c052ff8dd6a 560 mpLORA.lora.bandwidth = LORA_BW_400;
Wayne Roberts 12:fcfafd17ae1b 561 else if (bwKHz > 100)
Wayne Roberts 0:9c052ff8dd6a 562 mpLORA.lora.bandwidth = LORA_BW_200;
Wayne Roberts 12:fcfafd17ae1b 563 else if (bwKHz > 50)
Wayne Roberts 12:fcfafd17ae1b 564 mpLORA.lora.bandwidth = LORA_BW_100;
Wayne Roberts 12:fcfafd17ae1b 565 else
Wayne Roberts 12:fcfafd17ae1b 566 mpLORA.lora.bandwidth = LORA_BW_50;
Wayne Roberts 0:9c052ff8dd6a 567
Wayne Roberts 0:9c052ff8dd6a 568 mpLORA.lora.codingRate = cr;
Wayne Roberts 0:9c052ff8dd6a 569
Wayne Roberts 0:9c052ff8dd6a 570 mpLORA.lora.spreadingFactor = sf << 4;
Wayne Roberts 0:9c052ff8dd6a 571
Wayne Roberts 0:9c052ff8dd6a 572 radio.xfer(OPCODE_SET_MODULATION_PARAMS, 3, 0, mpLORA.buf);
Wayne Roberts 9:97a6de3dbc86 573
Wayne Roberts 9:97a6de3dbc86 574 symbolPeriodUs = (1 << sf) / (bwKHz / 1000.0); // bw in MHz gives microseconds
Wayne Roberts 9:97a6de3dbc86 575 rxTimeoutMs = nSymbs * (symbolPeriodUs / 1000.0);
Wayne Roberts 0:9c052ff8dd6a 576 }
Wayne Roberts 0:9c052ff8dd6a 577
Wayne Roberts 0:9c052ff8dd6a 578 void Radio::LoRaPacketConfig(unsigned preambleLen, bool fixLen, bool crcOn, bool invIQ)
Wayne Roberts 0:9c052ff8dd6a 579 {
Wayne Roberts 1:e79b0a55135f 580 if (radio.getPacketType() != PACKET_TYPE_LORA)
Wayne Roberts 1:e79b0a55135f 581 radio.setPacketType(PACKET_TYPE_LORA);
Wayne Roberts 1:e79b0a55135f 582
Wayne Roberts 0:9c052ff8dd6a 583 ppLORA.lora.PreambleLength = preambleLen;
Wayne Roberts 0:9c052ff8dd6a 584 ppLORA.lora.HeaderType = fixLen ? IMPLICIT_HEADER : EXPLICIT_HEADER;
Wayne Roberts 0:9c052ff8dd6a 585 ppLORA.lora.crc = crcOn ? LORA_CRC_ENABLE : LORA_CRC_DISABLE;
Wayne Roberts 0:9c052ff8dd6a 586 ppLORA.lora.InvertIQ = invIQ ? LORA_IQ_INVERTED : LORA_IQ_STD;
Wayne Roberts 0:9c052ff8dd6a 587
Wayne Roberts 0:9c052ff8dd6a 588 radio.xfer(OPCODE_SET_PACKET_PARAMS, 5, 0, ppLORA.buf);
Wayne Roberts 0:9c052ff8dd6a 589 }
Wayne Roberts 0:9c052ff8dd6a 590
Wayne Roberts 0:9c052ff8dd6a 591 void Radio::SetChannel(unsigned hz)
Wayne Roberts 0:9c052ff8dd6a 592 {
Wayne Roberts 0:9c052ff8dd6a 593 radio.setMHz(hz / 1000000.0);
Wayne Roberts 0:9c052ff8dd6a 594 }
Wayne Roberts 0:9c052ff8dd6a 595
Wayne Roberts 0:9c052ff8dd6a 596 uint32_t Radio::Random(void)
Wayne Roberts 0:9c052ff8dd6a 597 {
Wayne Roberts 0:9c052ff8dd6a 598 uint8_t buf[2];
Wayne Roberts 0:9c052ff8dd6a 599 uint32_t ret = 0;
Wayne Roberts 0:9c052ff8dd6a 600 unsigned n;
Wayne Roberts 0:9c052ff8dd6a 601
Wayne Roberts 0:9c052ff8dd6a 602 radio.start_rx(-1);
Wayne Roberts 0:9c052ff8dd6a 603
Wayne Roberts 0:9c052ff8dd6a 604 for (n = 0; n < 8; n++) {
Wayne Roberts 0:9c052ff8dd6a 605 uint32_t r, s;
Wayne Roberts 0:9c052ff8dd6a 606 wait_us(5000);
Wayne Roberts 0:9c052ff8dd6a 607 radio.xfer(OPCODE_GET_RSSIINST, 0, 2, buf);
Wayne Roberts 0:9c052ff8dd6a 608 r = buf[1];
Wayne Roberts 0:9c052ff8dd6a 609 s = n * 4;
Wayne Roberts 0:9c052ff8dd6a 610 r <<= s;
Wayne Roberts 0:9c052ff8dd6a 611 ret ^= r;
Wayne Roberts 0:9c052ff8dd6a 612 }
Wayne Roberts 0:9c052ff8dd6a 613
Wayne Roberts 0:9c052ff8dd6a 614 radio.setStandby(STDBY_RC);
Wayne Roberts 0:9c052ff8dd6a 615
Wayne Roberts 0:9c052ff8dd6a 616 return ret;
Wayne Roberts 0:9c052ff8dd6a 617 }
Wayne Roberts 0:9c052ff8dd6a 618
Wayne Roberts 0:9c052ff8dd6a 619 void Radio::Rx(unsigned timeout)
Wayne Roberts 0:9c052ff8dd6a 620 {
Wayne Roberts 7:ba81f66e56d1 621 #ifdef RX_INDICATION
Wayne Roberts 7:ba81f66e56d1 622 RX_INDICATION = 1;
Wayne Roberts 7:ba81f66e56d1 623 #endif
Wayne Roberts 9:97a6de3dbc86 624 if (timeout == 0)
Wayne Roberts 9:97a6de3dbc86 625 radio.start_rx(0); // continuous rx
Wayne Roberts 9:97a6de3dbc86 626 else {
Wayne Roberts 9:97a6de3dbc86 627 radio.start_rx(rxTimeoutMs);
Wayne Roberts 9:97a6de3dbc86 628 }
Wayne Roberts 0:9c052ff8dd6a 629 }
Wayne Roberts 0:9c052ff8dd6a 630
Wayne Roberts 0:9c052ff8dd6a 631 void Radio::Standby()
Wayne Roberts 0:9c052ff8dd6a 632 {
Wayne Roberts 0:9c052ff8dd6a 633 radio.setStandby(STDBY_RC);
Wayne Roberts 0:9c052ff8dd6a 634 }
Wayne Roberts 0:9c052ff8dd6a 635
Wayne Roberts 13:a354f82d12d9 636 #define TX_PWR_OFFSET 18
Wayne Roberts 0:9c052ff8dd6a 637 void Radio::set_tx_dbm(int8_t dbm)
Wayne Roberts 0:9c052ff8dd6a 638 {
Wayne Roberts 5:ab124d3842a8 639 if (dbm == PA_OFF_DBM) {
Wayne Roberts 5:ab124d3842a8 640 /* TODO: shut off PA */
Wayne Roberts 13:a354f82d12d9 641 radio.set_tx_dbm(0);
Wayne Roberts 5:ab124d3842a8 642 } else {
Wayne Roberts 13:a354f82d12d9 643 /* power range -18dBm to +13dBm */
Wayne Roberts 13:a354f82d12d9 644 radio.set_tx_dbm(dbm + TX_PWR_OFFSET);
Wayne Roberts 5:ab124d3842a8 645 }
Wayne Roberts 0:9c052ff8dd6a 646 }
Wayne Roberts 0:9c052ff8dd6a 647
Wayne Roberts 0:9c052ff8dd6a 648 void Radio::SetTxContinuousWave(unsigned hz, int8_t dbm, unsigned timeout_us)
Wayne Roberts 0:9c052ff8dd6a 649 {
Wayne Roberts 0:9c052ff8dd6a 650 SetChannel(hz);
Wayne Roberts 0:9c052ff8dd6a 651 radio.set_tx_dbm(dbm);
Wayne Roberts 0:9c052ff8dd6a 652 radio.xfer(OPCODE_SET_TX_CARRIER, 0, 0, NULL);
Wayne Roberts 0:9c052ff8dd6a 653 }
Wayne Roberts 0:9c052ff8dd6a 654
Wayne Roberts 1:e79b0a55135f 655 void Radio::SetRxMaxPayloadLength(uint8_t max)
Wayne Roberts 0:9c052ff8dd6a 656 {
Wayne Roberts 1:e79b0a55135f 657 uint8_t pktType = radio.getPacketType();
Wayne Roberts 1:e79b0a55135f 658
Wayne Roberts 1:e79b0a55135f 659 if (pktType == PACKET_TYPE_GFSK)
Wayne Roberts 0:9c052ff8dd6a 660 ppGFSK.gfskFLRC.PayloadLength = max;
Wayne Roberts 1:e79b0a55135f 661 else if (pktType == PACKET_TYPE_LORA)
Wayne Roberts 0:9c052ff8dd6a 662 ppLORA.lora.PayloadLength = max;
Wayne Roberts 0:9c052ff8dd6a 663 }
Wayne Roberts 0:9c052ff8dd6a 664
Wayne Roberts 0:9c052ff8dd6a 665 #endif /* ..SX126x_H */