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:
Thu Dec 06 17:57:21 2018 -0800
Revision:
8:0518c6e68b79
Parent:
7:ba81f66e56d1
Child:
9:97a6de3dbc86
sx127x clear old interrupt on startup

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