1

Committer:
advxolltm
Date:
Mon Jun 06 16:37:12 2022 +0000
Revision:
22:fc88e265f425
Parent:
20:75635d50262e
123

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