wayne roberts / Mbed OS utility_sx12xx
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers radio_sx128x.cpp Source File

radio_sx128x.cpp

00001 #include "radio.h"
00002 #ifdef SX128x_H 
00003 
00004 #include <float.h>
00005 using namespace std::chrono;
00006 
00007 #if defined(TARGET_FF_ARDUINO) || defined(TARGET_FF_ARDUINO_UNO)    /* pins of SX126xDVK1xAS board */
00008     #define NRST_PIN        A0
00009     SPI spi(D11, D12, D13); // mosi, miso, sclk
00010     //           spi, nss, busy, dio1
00011     SX128x Radio::radio(spi,  D7,   D3,   D5, NRST_PIN);
00012 
00013     #define LED_ON      1
00014     #define LED_OFF     0
00015     DigitalOut tx_led(A4);
00016     DigitalOut rx_led(A5);
00017 
00018 
00019     DigitalOut ant_sw(A3);
00020     DigitalOut cps(D6); // SE2436L
00021 
00022     bool fe_enable; // SE2436L
00023 
00024     void Radio::chipModeChange()
00025     {
00026         if (radio.chipMode == CHIPMODE_NONE) {
00027             cps = 0;
00028             tx_led = LED_OFF;
00029             rx_led = LED_OFF;
00030         } else if (radio.chipMode == CHIPMODE_TX) {
00031             cps = fe_enable;
00032             tx_led = LED_ON;
00033             rx_led = LED_OFF;
00034         } else if (radio.chipMode == CHIPMODE_RX) {
00035             cps = fe_enable;
00036             tx_led = LED_OFF;
00037             rx_led = LED_ON;
00038         }
00039     }
00040 #endif /* TARGET_FF_ARDUINO */
00041 
00042 const char* const Radio::chipNum_str = "SX1280";
00043 
00044 uint8_t Radio::tx_param_buf[2];
00045 
00046 ModulationParams_t Radio::Radio::mpFLRC, Radio::Radio::mpBLE_GFSK, Radio::mpLORA;
00047 PacketParams_t Radio::ppGFSK, Radio::ppFLRC, Radio::ppLORA, Radio::ppBLE;
00048 
00049 const RadioEvents_t* Radio::RadioEvents;
00050 LowPowerTimer Radio::lpt;
00051 uint8_t Radio::pktType;
00052 uint16_t Radio::ppg;
00053 
00054 const char* const Radio::pktType_strs[] = {
00055     "GFSK   ",
00056     "LORA   ",
00057     "RANGING",
00058     "FLRC   ",
00059     "BLE    ",
00060     NULL
00061 };
00062 
00063 unsigned Radio::pktType_read(bool fw)
00064 {
00065     return radio.getPacketType();
00066 }
00067 
00068 menuMode_e Radio::pktType_write(unsigned idx)
00069 {
00070     radio.setPacketType(idx);
00071     return MENUMODE_REINIT_MENU;
00072 }
00073 
00074 const char* Radio::tx_ramp_strs[] = {
00075     "2 ", // 0
00076     "4 ", // 1
00077     "6 ", // 2
00078     "8 ", // 3
00079     "10", // 4
00080     "12", // 5
00081     "16", // 6
00082     "20",  // 7
00083     NULL
00084 };
00085 
00086 unsigned Radio::tx_ramp_read(bool fw)
00087 {
00088     PaPwrCtrl_t PaPwrCtrl;
00089     PaPwrCtrl.octet = radio.readReg(REG_ADDR_PA_PWR_CTRL, 1);
00090 
00091     switch (PaPwrCtrl.bits.ramp_time) {
00092         case 0: tx_param_buf[1] = RADIO_RAMP_02_US; break;
00093         case 1: tx_param_buf[1] = RADIO_RAMP_04_US; break;
00094         case 2: tx_param_buf[1] = RADIO_RAMP_06_US; break;
00095         case 3: tx_param_buf[1] = RADIO_RAMP_08_US; break;
00096         case 4: tx_param_buf[1] = RADIO_RAMP_10_US; break;
00097         case 5: tx_param_buf[1] = RADIO_RAMP_12_US; break;
00098         case 6: tx_param_buf[1] = RADIO_RAMP_16_US; break;
00099         case 7: tx_param_buf[1] = RADIO_RAMP_20_US; break;
00100     }
00101 
00102     return PaPwrCtrl.bits.ramp_time;
00103 }
00104 
00105 menuMode_e Radio::tx_ramp_write(unsigned val)
00106 {
00107     switch (val) {
00108         case 0: tx_param_buf[1] = RADIO_RAMP_02_US; break;
00109         case 1: tx_param_buf[1] = RADIO_RAMP_04_US; break;
00110         case 2: tx_param_buf[1] = RADIO_RAMP_06_US; break;
00111         case 3: tx_param_buf[1] = RADIO_RAMP_08_US; break;
00112         case 4: tx_param_buf[1] = RADIO_RAMP_10_US; break;
00113         case 5: tx_param_buf[1] = RADIO_RAMP_12_US; break;
00114         case 6: tx_param_buf[1] = RADIO_RAMP_16_US; break;
00115         case 7: tx_param_buf[1] = RADIO_RAMP_20_US; break;
00116     }
00117 
00118     radio.xfer(OPCODE_SET_TX_PARAMS, 2, 0, tx_param_buf);
00119 
00120     return MENUMODE_REDRAW;
00121 }
00122 
00123 #define TX_PWR_OFFSET           18
00124 
00125 void Radio::tx_dbm_print()
00126 {
00127     PaPwrCtrl_t PaPwrCtrl;
00128 
00129     PaPwrCtrl.octet = radio.readReg(REG_ADDR_PA_PWR_CTRL, 1);
00130     printf("%d", PaPwrCtrl.bits.tx_pwr - TX_PWR_OFFSET);
00131 
00132     tx_param_buf[0] = PaPwrCtrl.bits.tx_pwr;
00133 }
00134 
00135 bool Radio::tx_dbm_write(const char* str)
00136 {
00137     int dbm;
00138     sscanf(str, "%d", &dbm);
00139 
00140     tx_param_buf[0] = dbm + TX_PWR_OFFSET;
00141     radio.xfer(OPCODE_SET_TX_PARAMS, 2, 0, tx_param_buf);
00142     return false;
00143 }
00144 
00145 const uint8_t ramp_us[] = {
00146     2,  // 0
00147     4,  // 1
00148     6,  // 2
00149     8,  // 3
00150     10, // 4
00151     12, // 5
00152     16, // 6
00153     20  // 7
00154 };
00155 
00156 const char* const Radio::opmode_status_strs[] = {
00157     "<0>       ", // 0
00158     "<1>       ", // 1
00159     "STDBY_RC  ", // 2
00160     "STDBY_XOSC", // 3
00161     "FS        ", // 4
00162     "RX        ", // 5
00163     "TX        ", // 6
00164     "<7>       ", // 7
00165     NULL
00166 };
00167 
00168 const char* const Radio::opmode_select_strs[] = {
00169     "SLEEP     ", // 0
00170     "STDBY_RC  ", // 1
00171     "STDBY_XOSC", // 2
00172     "FS        ", // 3
00173     "RX        ", // 4
00174     "TX        ", // 5
00175     NULL
00176 };
00177 
00178 unsigned Radio::opmode_read(bool forWriting)
00179 {
00180     status_t status;
00181     status.octet = radio.xfer(OPCODE_GET_STATUS, 0, 0, NULL);
00182 
00183     if (forWriting) {
00184         /* translate opmode_status_strs to opmode_select_strs */
00185         switch (status.bits.chipMode) {
00186             case 2: return 1;   // STDBY_RC
00187             case 3: return 2; //STDBY_XOSC
00188             case 4: return 3; //FS
00189             case 5: return 4; // RX
00190             case 6: return 5; // TX
00191             default: return 0;
00192         }
00193     } else
00194         return status.bits.chipMode;
00195 }
00196 
00197 menuMode_e Radio::opmode_write(unsigned sel)
00198 {
00199     switch (sel) {
00200         case 0: // SLEEP
00201             radio.setSleep(true);
00202             break;
00203         case 1: // STDBY_RC
00204             radio.setStandby(STDBY_RC);
00205             break;
00206         case 2:  // STDBY_XOSC
00207             radio.setStandby(STDBY_XOSC);
00208             break; case 3:  // FS
00209             radio.setFS();
00210             break;
00211         case 4:  // RX
00212             radio.start_rx(0);
00213             break;
00214         case 5:  // TX
00215             {
00216                 uint8_t buf[3];
00217                 buf[0] = radio.periodBase;
00218                 buf[0] = 0;
00219                 buf[1] = 0;
00220                 radio.xfer(OPCODE_SET_TX, 3, 0, buf);
00221             }
00222             break;
00223     } // ..switch (menuState.sel_idx)
00224 
00225     return MENUMODE_REDRAW;
00226 }
00227 
00228 uint8_t Radio::get_payload_length()
00229 {
00230     uint8_t reg8;
00231 
00232     pktType = radio.getPacketType();
00233 
00234     switch (pktType) {
00235         case PACKET_TYPE_FLRC:
00236         case PACKET_TYPE_GFSK:
00237             reg8 = radio.readReg(REG_ADDR_PAYLOAD_LEN, 1);
00238             ppGFSK.gfskFLRC.PayloadLength = reg8;
00239             ppFLRC.gfskFLRC.PayloadLength = reg8;
00240             return ppFLRC.gfskFLRC.PayloadLength;
00241         case PACKET_TYPE_RANGING:
00242         case PACKET_TYPE_LORA:
00243             ppLORA.lora.PayloadLength = radio.readReg(REG_ADDR_LORA_TX_PAYLOAD_LENGTH, 1);
00244             return ppLORA.lora.PayloadLength;
00245         case PACKET_TYPE_BLE:
00246             return 0;   // TODO BLE
00247     }
00248 
00249     return 0;
00250 }
00251 
00252 void Radio::set_payload_length(uint8_t len)
00253 {
00254     pktType = radio.getPacketType();
00255 
00256     switch (pktType) {
00257         case PACKET_TYPE_FLRC:
00258             ppFLRC.gfskFLRC.PayloadLength = len;
00259             ppGFSK.gfskFLRC.PayloadLength = len;
00260             radio.xfer(OPCODE_SET_PACKET_PARAMS, 7, 0, ppFLRC.buf);
00261             break;
00262         case PACKET_TYPE_GFSK:
00263             ppFLRC.gfskFLRC.PayloadLength = len;
00264             ppGFSK.gfskFLRC.PayloadLength = len;
00265             radio.xfer(OPCODE_SET_PACKET_PARAMS, 7, 0, ppGFSK.buf);
00266             break;
00267         case PACKET_TYPE_RANGING:
00268         case PACKET_TYPE_LORA:
00269             ppLORA.lora.PayloadLength = len;
00270             radio.xfer(OPCODE_SET_PACKET_PARAMS, 5, 0, ppLORA.buf);
00271             break;
00272         case PACKET_TYPE_BLE:
00273             // TODO BLE
00274             break;
00275     }
00276 }
00277 
00278 void Radio::tx_payload_length_print()
00279 {
00280     printf("%u", get_payload_length());
00281 }
00282 
00283 bool Radio::tx_payload_length_write(const char* txt)
00284 {
00285     unsigned len;
00286 
00287     sscanf(txt, "%u", &len);
00288 
00289     set_payload_length(len);
00290 
00291     return false;
00292 }
00293 
00294 void Radio::hw_reset()
00295 {
00296     radio.hw_reset();
00297 
00298     manualRngDelay = false;
00299 }
00300 
00301 void Radio::clearIrqFlags()
00302 {
00303     uint8_t buf[2];
00304     buf[0] = 0xff;
00305     buf[1] = 0xff;
00306     radio.xfer(OPCODE_CLEAR_IRQ_STATUS, 2, 0, buf);
00307 }
00308 
00309 void Radio::readChip()
00310 {
00311     uint8_t reg8;
00312 
00313     reg8 = radio.readReg(REG_ADDR_PKTCTRL0, 1);
00314     ppGFSK.gfskFLRC.HeaderType = reg8 & 0x20;
00315     ppFLRC.gfskFLRC.HeaderType = reg8 & 0x20;
00316 
00317     reg8 = radio.readReg(REG_ADDR_PKTCTRL1, 1);
00318     ppGFSK.gfskFLRC.PreambleLength = reg8 & 0x70;
00319     ppFLRC.gfskFLRC.PreambleLength = reg8 & 0x70;
00320     ppGFSK.gfskFLRC.SyncWordLength = reg8 & 0x0e;
00321     ppFLRC.gfskFLRC.SyncWordLength = reg8 & 0x06;
00322     if (ppFLRC.gfskFLRC.SyncWordLength == 0x06)
00323         ppFLRC.gfskFLRC.SyncWordLength = FLRC_SYNC_WORD_LEN_P32S;
00324 
00325     reg8 = radio.readReg(REG_ADDR_PKT_SYNC_ADRS_CTRL, 1);
00326     ppGFSK.gfskFLRC.SyncWordMatch = reg8 & 0x70;
00327     ppFLRC.gfskFLRC.SyncWordMatch = reg8 & 0x70;
00328 
00329     reg8 = radio.readReg(REG_ADDR_PAYLOAD_LEN, 1);
00330     ppGFSK.gfskFLRC.PayloadLength = reg8;
00331     ppFLRC.gfskFLRC.PayloadLength = reg8;
00332 
00333     reg8 = radio.readReg(REG_ADDR_PKT_TX_HEADER, 1);    // TODO hi bit of payload length
00334     ppBLE.ble.ConnectionState = reg8 & 0xe0;
00335     ppBLE.ble.BleTestPayload = reg8 & 0x1c;
00336 
00337     reg8 = radio.readReg(REG_ADDR_PKT_BITSTREAM_CTRL, 1);
00338     ppBLE.ble.CrcLength = reg8 & 0x30;
00339     ppBLE.ble.Whitening = reg8 & 0x08;
00340     ppGFSK.gfskFLRC.CRCLength = reg8 & 0x30;
00341     ppFLRC.gfskFLRC.CRCLength = reg8 & 0x30;
00342     ppGFSK.gfskFLRC.Whitening = reg8 & 0x08;
00343     ppFLRC.gfskFLRC.Whitening = reg8 & 0x08;
00344 
00345     LoRaPktPar0.octet = radio.readReg(REG_ADDR_LORA_PKTPAR0, 1);
00346     switch (LoRaPktPar0.bits.modem_bw) {
00347         case 2: mpLORA.lora.bandwidth = LORA_BW_200; break;
00348         case 3: mpLORA.lora.bandwidth = LORA_BW_400; break;
00349         case 4: mpLORA.lora.bandwidth = LORA_BW_800; break;
00350         case 5: mpLORA.lora.bandwidth = LORA_BW_1600; break;
00351     }
00352     mpLORA.lora.spreadingFactor = LoRaPktPar0.bits.modem_sf << 4;
00353 
00354     {
00355         LoRaPktPar1_t LoRaPktPar1;
00356         LoRaPktPar1.octet = radio.readReg(REG_ADDR_LORA_PKTPAR1, 1);
00357         mpLORA.lora.codingRate = LoRaPktPar1.bits.coding_rate;
00358         ppLORA.lora.InvertIQ = LoRaPktPar1.bits.rxinvert_iq ? LORA_IQ_INVERTED : LORA_IQ_STD;
00359         ppLORA.lora.HeaderType = LoRaPktPar1.bits.implicit_header ? IMPLICIT_HEADER : EXPLICIT_HEADER;
00360         // LoRaPktPar1.bits.ppm_offset
00361     }
00362 
00363     {
00364         LoRaPreambleReg_t LoRaPreambleReg;
00365         LoRaPreambleReg.octet = radio.readReg(REG_ADDR_LORA_PREAMBLE, 1);
00366         ppLORA.lora.PreambleLength = LoRaPreambleReg.bits.preamble_symb1_nb * (1 << LoRaPreambleReg.bits.preamble_symb_nb_exp);
00367     }
00368     ppLORA.lora.PayloadLength = radio.readReg(REG_ADDR_LORA_TX_PAYLOAD_LENGTH, 1);
00369 
00370     {
00371         LoRaLrCtl_t LoRaLrCtl;
00372         LoRaLrCtl.octet = radio.readReg(REG_ADDR_LORA_LRCTL, 1);
00373         ppLORA.lora.crc = LoRaLrCtl.octet & 0x20; // LoRaLrCtl.bits.crc_en
00374     }
00375 
00376     {
00377         RegRxBw_t RegRxBw;
00378         unsigned bps;
00379         FloraPreambleHi_t FloraPreambleHi;
00380         float mi, fdev_hz;
00381         unsigned freqDev;
00382         FskModDfH_t FskModDfH;
00383         FskModDfH.octet = radio.readReg(REG_ADDR_FSK_MODDFH, 1);
00384         freqDev = FskModDfH.bits.freqDev;
00385         freqDev <<= 8;
00386         freqDev |= radio.readReg(REG_ADDR_FSK_MODDFL, 1);
00387         //printf("freqDev %x, %x\r\n", freqDev, freqDev);
00388         fdev_hz = freqDev * PLL_STEP_HZ;
00389         //printf("fdev hz:%f\r\n", fdev_hz);
00390 
00391         FloraPreambleHi.octet = radio.readReg(REG_ADDR_FLORA_PREAMBLE_HI, 1);
00392         switch (FloraPreambleHi.bits.data_rate) {
00393             case 0:
00394                 bps = 2.0e6;
00395                 //mpFLRC.flrc.bitrateBandwidth = ??; // 2.6
00396                 break;
00397             case 1:
00398                 bps = 1.6e6;
00399                 //mpFLRC.flrc.bitrateBandwidth = ??; // 2.08
00400                 break;
00401             case 2:
00402                 bps = 1.0e6;
00403                 mpFLRC.flrc.bitrateBandwidth = FLRC_BR_1_300_BW_1_2; // 1.3
00404                 break;
00405             case 3:
00406                 bps = 0.8e6;
00407                 mpFLRC.flrc.bitrateBandwidth = FLRC_BR_1_000_BW_1_2; // 1.04
00408                 break;
00409             case 4:
00410                 bps = 0.5e6;
00411                 mpFLRC.flrc.bitrateBandwidth = FLRC_BR_0_650_BW_0_6; // 0.65
00412                 break;
00413             case 5:
00414                 bps = 0.4e6;
00415                 mpFLRC.flrc.bitrateBandwidth = FLRC_BR_0_520_BW_0_6; // 0.52
00416                 break;
00417             case 6:
00418                 bps = 0.25e6;
00419                 mpFLRC.flrc.bitrateBandwidth = FLRC_BR_0_325_BW_0_3; // 0.325
00420                 break;
00421             case 7:
00422                 bps = 0.125e6;
00423                 mpFLRC.flrc.bitrateBandwidth = FLRC_BR_0_260_BW_0_3; // 0.26
00424                 break;
00425         }
00426 
00427         mi = (fdev_hz * 2.0) / bps;
00428         if (mi > 0.35) {
00429             mi -= 0.5;
00430             mi /= 0.25;
00431             mpBLE_GFSK.gfskBle.ModulationIndex = ((uint8_t)mi) + 1;
00432         } else
00433             mpBLE_GFSK.gfskBle.ModulationIndex = 0;
00434 
00435         RegRxBw.octet = radio.readReg(REG_ADDR_RXBW, 1);
00436 
00437         //printf("rx ");
00438         switch (RegRxBw.bits.bw) {
00439             case 0:
00440                 //printf("2.4");
00441                 if (FloraPreambleHi.bits.data_rate == 0)
00442                     mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_2_000_BW_2_4;
00443                 if (FloraPreambleHi.bits.data_rate == 1)
00444                     mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_1_600_BW_2_4;
00445                 if (FloraPreambleHi.bits.data_rate == 2)
00446                     mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_1_000_BW_2_4;
00447                 if (FloraPreambleHi.bits.data_rate == 3)
00448                     mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_800_BW_2_4;
00449                 break;
00450             case 1:
00451                 //printf("1.2");
00452                 if (FloraPreambleHi.bits.data_rate == 2)
00453                     mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_1_000_BW_1_2;
00454                 if (FloraPreambleHi.bits.data_rate == 3)
00455                     mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_800_BW_1_2;
00456                 if (FloraPreambleHi.bits.data_rate == 4)
00457                     mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_500_BW_1_2;
00458                 if (FloraPreambleHi.bits.data_rate == 5)
00459                     mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_400_BW_1_2;
00460                 break;
00461             case 2:
00462                 //printf("0.6");
00463                 if (FloraPreambleHi.bits.data_rate == 4)
00464                     mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_500_BW_0_6;
00465                 if (FloraPreambleHi.bits.data_rate == 5)
00466                     mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_400_BW_0_6;
00467                 if (FloraPreambleHi.bits.data_rate == 6)
00468                     mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_250_BW_0_6;
00469                 break;
00470             case 3:
00471                 //printf("0.3");
00472                 if (FloraPreambleHi.bits.data_rate == 6)
00473                     mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_250_BW_0_3;
00474                 if (FloraPreambleHi.bits.data_rate == 7)
00475                     mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_125_BW_0_3;
00476                 break;
00477         }
00478         //printf("MHz bw:%u\r\n", RegRxBw.bits.bw);
00479         mpBLE_GFSK.gfskBle.bitrateBandwidth = reg8;
00480     }
00481 
00482     {
00483         FskCfg_t FskCfg;
00484         FskCfg.octet = radio.readReg(REG_ADDR_FSK_CFG, 1);
00485         //printf("gf_bt:%u\r\n", FskCfg.bits.gf_bt);
00486         mpBLE_GFSK.gfskBle.ModulationShaping = FskCfg.bits.gf_bt << 4;
00487         mpFLRC.flrc.ModulationShaping = mpBLE_GFSK.gfskBle.ModulationShaping;
00488     }
00489 
00490     {
00491         PktBitStreamCtrl_t PktBitStreamCtrl;
00492         PktBitStreamCtrl.octet = radio.readReg(REG_ADDR_PKT_BITSTREAM_CTRL, 1);
00493         mpFLRC.flrc.CodingRate = PktBitStreamCtrl.octet & 0x06; // PktBitStreamCtrl.bits.flora_coding_rate 
00494     }
00495 
00496 }
00497 
00498 void Radio::rxDone(uint8_t size, const pktStatus_t* pktStatus)
00499 {
00500     float rssi, snr;
00501 
00502     if (pktStatus->ble_gfsk_flrc.sync.syncAddrsCode == 0) {
00503         int8_t s = pktStatus->lora.snr;
00504         rssi = -pktStatus->lora.rssiSync / 2.0;
00505         snr = s / 4.0;
00506     } else {
00507         rssi = -pktStatus->ble_gfsk_flrc.rssiSync / 2.0;
00508         snr = FLT_MIN;
00509     }
00510 
00511     RadioEvents->RxDone(size, rssi, snr);
00512 }
00513 
00514 void Radio::txDoneBottom()
00515 {
00516     if (RadioEvents->TxDone_botHalf)
00517         RadioEvents->TxDone_botHalf();
00518 }
00519 
00520 /*void Radio::cadDone(bool det)
00521 {
00522     log_printf("cadDone ");
00523     if (det)
00524         printf("CadDetected");
00525 
00526     printf("\r\n");
00527 }*/
00528 
00529 void Radio::boardInit(const RadioEvents_t* e)
00530 {
00531     hw_reset();
00532 
00533     radio.txDone = txDoneBottom;
00534     radio.rxDone = rxDone;
00535     radio.cadDone = cadDone;
00536 
00537     radio.chipModeChange = chipModeChange;
00538 
00539     readChip();
00540 
00541     RadioEvents = e;
00542 
00543     fe_enable = true;
00544 
00545     lpt.start();
00546 }
00547 
00548 void Radio::tx_carrier()
00549 {
00550     radio.xfer(OPCODE_SET_TX_CARRIER, 0, 0, NULL);
00551 
00552     radio.chipMode = CHIPMODE_TX;
00553     chipModeChange();
00554 }
00555 
00556 void Radio::tx_preamble()
00557 {
00558     radio.xfer(OPCODE_SET_TX_PREAMBLE, 0, 0, NULL);
00559 
00560     radio.chipMode = CHIPMODE_TX;
00561     chipModeChange();
00562 }
00563 
00564 void Radio::get_rssi()
00565 {
00566     uint8_t buf[3];
00567     radio.xfer(OPCODE_GET_RSSIINST, 0, 3, buf);
00568     log_printf("-%0.1f dBm\r\n", buf[1]/2.0);
00569 }
00570 
00571 
00572 void Radio::rngTx()
00573 {
00574     IrqFlags_t irqEnable;
00575     uint8_t buf[8];
00576 
00577     if (!manualRngDelay)
00578         rngUpdateDelayCal();
00579 
00580     irqEnable.word = 0;
00581     irqEnable.bits.TxDone = 1;
00582     irqEnable.bits.RxTxTimeout = 1;
00583     irqEnable.bits.RangingMasterTimeout = 1;
00584     irqEnable.bits.RangingMasterResultValid = 1;
00585     irqEnable.bits.RangingMasterRequestValid = 1;
00586 
00587     buf[0] = irqEnable.word >> 8;    // enable bits
00588     buf[1] = irqEnable.word; // enable bits
00589 
00590     irqEnable.bits.RangingMasterTimeout = 0;
00591     irqEnable.bits.RangingMasterResultValid = 0;
00592     irqEnable.bits.RangingMasterRequestValid = 0;
00593     buf[2] = irqEnable.word >> 8;     // dio1
00594     buf[3] = irqEnable.word;  // dio1
00595 
00596     buf[4] = 0; // dio2
00597     buf[5] = 0; // dio2
00598     buf[6] = 0; // dio3
00599     buf[7] = 0; // dio3
00600     radio.xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf);
00601 
00602     log_printf("rngTx\r\n");
00603 
00604     buf[0] = radio.periodBase;
00605     /* no timeout */
00606     buf[1] = 0;
00607     buf[2] = 0;
00608     radio.xfer(OPCODE_SET_TX, 3, 0, buf);
00609 
00610     radio.chipMode = CHIPMODE_TX;
00611     chipModeChange();
00612 }
00613 
00614 void Radio::txPkt()
00615 {
00616     uint8_t txlen = 0;
00617 
00618     pktType = radio.getPacketType();
00619 
00620     switch (pktType) {
00621         case PACKET_TYPE_FLRC:
00622         case PACKET_TYPE_GFSK:
00623             txlen = radio.readReg(REG_ADDR_PAYLOAD_LEN, 1);
00624             break;
00625         case PACKET_TYPE_BLE:
00626             return; // TODO BLE
00627         case PACKET_TYPE_RANGING:
00628             rngTx();
00629             return;
00630         case PACKET_TYPE_LORA:
00631             txlen = radio.readReg(REG_ADDR_LORA_TX_PAYLOAD_LENGTH, 1);
00632             break;
00633     }
00634     log_printf("txPkt%u\r\n", txlen);
00635 
00636     radio.setBufferBase(0, 0);
00637 
00638     radio.start_tx(txlen, 0);
00639 
00640 }
00641 
00642 #define REGBW_2_4MHZ    0
00643 #define REGBW_1_2MHZ    1
00644 #define REGBW_0_6MHZ    2
00645 #define REGBW_0_3MHZ    3
00646 
00647 unsigned Radio::gfsk_flrc_bpsbw_read(bool fw)
00648 {
00649     unsigned n = UINT_MAX;
00650     RegRxBw_t RegRxBw;
00651     FloraPreambleHi_t FloraPreambleHi;
00652     pktType = radio.getPacketType();
00653 
00654     FloraPreambleHi.octet = radio.readReg(REG_ADDR_FLORA_PREAMBLE_HI, 1);
00655 
00656     RegRxBw.octet = radio.readReg(REG_ADDR_RXBW, 1);
00657 
00658     if (pktType == PACKET_TYPE_GFSK) {
00659         switch (FloraPreambleHi.bits.data_rate) {
00660             case 0:
00661                 n = 0;  // 2Mbps, 2.4MHz
00662                 break;
00663             case 1:
00664                 n = 1;  // 1.6Mbps, 2.4MHz
00665                 break;
00666             case 2:
00667                 if (RegRxBw.bits.bw == REGBW_2_4MHZ)
00668                     n = 2;
00669                 else if (RegRxBw.bits.bw == REGBW_1_2MHZ)
00670                     n = 3;
00671                 break;
00672             case 3:
00673                 if (RegRxBw.bits.bw == REGBW_2_4MHZ) // 0.8Mbps  2.4   2.4MHz
00674                     n = 4;
00675                 else if (RegRxBw.bits.bw == REGBW_1_2MHZ) // 0.8Mbps  1.2MHz
00676                     n = 5;
00677                 break;
00678             case 4:
00679                 if (RegRxBw.bits.bw == REGBW_1_2MHZ)    // 0.5Mbps  1.2MHz
00680                     n = 6;
00681                 else if (RegRxBw.bits.bw == REGBW_0_6MHZ)   // 0.5Mbps  0.6MHz
00682                     n = 7;
00683                 break;
00684             case 5:
00685                 if (RegRxBw.bits.bw == REGBW_1_2MHZ)    // 0.4Mbps  1.2MHz
00686                     n = 8;
00687                 else if (RegRxBw.bits.bw == REGBW_0_6MHZ)   // 0.4Mbps  0.6MHz
00688                     n = 9;
00689                 break;
00690             case 6:
00691                 if (RegRxBw.bits.bw == REGBW_0_6MHZ)    // 0.25Mbps  0.6MHz
00692                     n = 10;
00693                 else if (RegRxBw.bits.bw == REGBW_0_3MHZ)   // 0.25Mbps  0.3MHz
00694                     n = 11;
00695                 break;
00696             case 7:
00697                 n = 12; // 0.125Mbps, assume bw=0.3MHz
00698                 break;
00699         } // ..switch (FloraPreambleHi.bits.data_rate)
00700     } else if (pktType == PACKET_TYPE_FLRC) {
00701         n = FloraPreambleHi.bits.data_rate;
00702         // datarate, bits 5,6,7..    bw bits 0,1,2
00703         switch (FloraPreambleHi.bits.data_rate) {
00704             case 0:
00705                 break;
00706             case 1:
00707                 break;
00708             case 2:
00709                 mpFLRC.flrc.bitrateBandwidth = FLRC_BR_1_300_BW_1_2;
00710                 break;
00711             case 3:
00712                 mpFLRC.flrc.bitrateBandwidth = FLRC_BR_1_000_BW_1_2;
00713                 break;
00714             case 4:
00715                 mpFLRC.flrc.bitrateBandwidth = FLRC_BR_0_650_BW_0_6;
00716                 break;
00717             case 5:
00718                 mpFLRC.flrc.bitrateBandwidth = FLRC_BR_0_520_BW_0_6;
00719                 break;
00720             case 6:
00721                 mpFLRC.flrc.bitrateBandwidth = FLRC_BR_0_325_BW_0_3;
00722                 break;
00723             case 7:
00724                 mpFLRC.flrc.bitrateBandwidth = FLRC_BR_0_260_BW_0_3;
00725                 break;
00726         } // ..switch (FloraPreambleHi.bits.data_rate)
00727     }
00728 
00729     return n;
00730 }
00731 
00732 menuMode_e Radio::gfsk_flrc_bpsbw_write(unsigned sidx)
00733 {
00734     pktType = radio.getPacketType();
00735 
00736     if (pktType == PACKET_TYPE_GFSK) {
00737         switch (sidx) {
00738             case 0: mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_2_000_BW_2_4; break;
00739             case 1: mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_1_600_BW_2_4; break;
00740             case 2: mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_1_000_BW_2_4; break;
00741             case 3: mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_1_000_BW_1_2; break;
00742             case 4: mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_800_BW_2_4; break;
00743             case 5: mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_800_BW_1_2; break;
00744             case 6: mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_500_BW_1_2; break;
00745             case 7: mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_500_BW_0_6; break;
00746             case 8: mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_400_BW_1_2; break;
00747             case 9: mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_400_BW_0_6; break;
00748             case 10: mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_250_BW_0_6; break;
00749             case 11: mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_250_BW_0_3; break;
00750             case 12: mpBLE_GFSK.gfskBle.bitrateBandwidth = GFSK_BLE_BR_0_125_BW_0_3; break;
00751         }
00752         radio.xfer(OPCODE_SET_MODULATION_PARAMS, 3, 0, mpBLE_GFSK.buf);
00753     } else if (pktType == PACKET_TYPE_FLRC) {
00754         switch (sidx) {
00755             case 2: mpFLRC.flrc.bitrateBandwidth = FLRC_BR_1_300_BW_1_2; break;
00756             case 3: mpFLRC.flrc.bitrateBandwidth = FLRC_BR_1_000_BW_1_2; break;
00757             case 4: mpFLRC.flrc.bitrateBandwidth = FLRC_BR_0_650_BW_0_6; break;
00758             case 5: mpFLRC.flrc.bitrateBandwidth = FLRC_BR_0_520_BW_0_6; break;
00759             case 6: mpFLRC.flrc.bitrateBandwidth = FLRC_BR_0_325_BW_0_3; break;
00760             case 7: mpFLRC.flrc.bitrateBandwidth = FLRC_BR_0_260_BW_0_3; break;
00761             default:
00762                 return MENUMODE_REDRAW;
00763         }
00764         radio.xfer(OPCODE_SET_MODULATION_PARAMS, 3, 0, mpFLRC.buf);
00765     }
00766 
00767     return MENUMODE_REDRAW;
00768 }
00769 
00770 static const char* const gfsk_bpsbw[] = {
00771     "  2.0Mbps 2.4MHz", //0 GFSK_BLE_BR_2_000_BW_2_4    0x04 // Mbps:2      bw:2.4MHz
00772     "  1.6Mbps 2.4MHz", //1 GFSK_BLE_BR_1_600_BW_2_4    0x28 // Mbps:1.6    bw:2.4MHz
00773     "  1.0Mbps 2.4MHz", //2 GFSK_BLE_BR_1_000_BW_2_4    0x4C // Mbps:1      bw:2.4MHz
00774     "  1.0Mbps 1.2MHz", //3 GFSK_BLE_BR_1_000_BW_1_2    0x45 // Mbps:1      bw:1.2MHz
00775     "  0.8Mbps 2.4MHz", //4 GFSK_BLE_BR_0_800_BW_2_4    0x70 // Mbps:0.8    bw:2.4MHz
00776     "  0.8Mbps 1.2MHz", //5 GFSK_BLE_BR_0_800_BW_1_2    0x69 // Mbps:0.8    bw:1.2MHz
00777     "  0.5Mbps 1.2MHz", //6 GFSK_BLE_BR_0_500_BW_1_2    0x8D // Mbps:0.5    bw:1.2MHz
00778     "  0.5Mbps 0.6MHz", //7 GFSK_BLE_BR_0_500_BW_0_6    0x86 // Mbps:0.5    bw:0.6MHz
00779     "  0.4Mbps 1.2MHz", //8 GFSK_BLE_BR_0_400_BW_1_2    0xB1 // Mbps:0.4    bw:1.2MHz
00780     "  0.4Mbps 0.6MHz", //9 GFSK_BLE_BR_0_400_BW_0_6    0xAA // Mbps:0.4    bw:0.6MHz
00781     " 0.25Mbps 0.6MHz", //10 GFSK_BLE_BR_0_250_BW_0_6    0xCE // Mbps:0.25   bw:0.6MHz
00782     " 0.25Mbps 0.3MHz", //11 GFSK_BLE_BR_0_250_BW_0_3    0xC7 // Mbps:0.25   bw:0.3MHz
00783     "0.125Mbps 0.3MHz", //12 GFSK_BLE_BR_0_125_BW_0_3    0xEF // Mbps:0.125  bw:0.3MHz
00784 //   01234567890123456
00785     NULL
00786 };
00787 
00788 const dropdown_item_t Radio::gfsk_bitrate_item = { _ITEM_DROPDOWN, gfsk_bpsbw, gfsk_bpsbw, gfsk_flrc_bpsbw_read, gfsk_flrc_bpsbw_write};
00789 
00790 void Radio::modindex_print()
00791 {
00792     float mi, Mbps, fdev_hz;
00793     unsigned bps, freqDev;
00794     FskModDfH_t FskModDfH;
00795     FloraPreambleHi_t FloraPreambleHi;
00796 
00797     FloraPreambleHi.octet = radio.readReg(REG_ADDR_FLORA_PREAMBLE_HI, 1);
00798     switch (FloraPreambleHi.bits.data_rate) {
00799         case 0: Mbps = 2.0; break;
00800         case 1: Mbps = 1.6; break;
00801         case 2: Mbps = 1.0; break;
00802         case 3: Mbps = 0.8; break;
00803         case 4: Mbps = 0.5; break;
00804         case 5: Mbps = 0.4; break;
00805         case 6: Mbps = 0.25; break;
00806         case 7: Mbps = 0.125; break;
00807     }
00808 
00809     FskModDfH.octet = radio.readReg(REG_ADDR_FSK_MODDFH, 1);
00810     freqDev = FskModDfH.bits.freqDev;
00811     freqDev <<= 8;
00812     freqDev |= radio.readReg(REG_ADDR_FSK_MODDFL, 1);
00813 
00814     fdev_hz = freqDev * PLL_STEP_HZ;
00815     bps = Mbps * 1e6;
00816     mi = (fdev_hz * 2.0) / bps;
00817 
00818     printf("%.2f", mi);
00819 }
00820 
00821 bool Radio::modindex_write(const char* valStr)
00822 {
00823     float f;
00824 
00825     if (sscanf(valStr, "%f", &f) == 1) {
00826         log_printf("scanned %f from \"%s\"\r\n", f);
00827         if (f > 0.35) {
00828             f -= 0.5;
00829             f /= 0.25;
00830             log_printf("set modindex:%f\r\n", f);
00831             mpBLE_GFSK.gfskBle.ModulationIndex = ((uint8_t)f) + 1;
00832             log_printf("to set %02x\r\n", mpBLE_GFSK.gfskBle.ModulationIndex);
00833         } else
00834             mpBLE_GFSK.gfskBle.ModulationIndex = 0;
00835 
00836         radio.xfer(OPCODE_SET_MODULATION_PARAMS, 3, 0, mpBLE_GFSK.buf);
00837     }
00838     return false;
00839 }
00840 
00841 const value_item_t Radio::gfsk_modindex_item = { _ITEM_VALUE, 5, modindex_print, modindex_write };
00842 
00843 static const char* const gfsk_flrc_bts[] = {
00844     "off",
00845     "1.0",
00846     "0.5",
00847     "0.3",
00848     NULL
00849 };
00850 
00851 unsigned Radio::gfsk_flrc_bt_read(bool fw)
00852 {
00853     FskCfg_t FskCfg;
00854     FskCfg.octet = radio.readReg(REG_ADDR_FSK_CFG, 1);
00855     return FskCfg.bits.gf_bt;
00856 }
00857 
00858 menuMode_e Radio::gfsk_flrc_bt_write(unsigned sidx)
00859 {
00860     mpBLE_GFSK.gfskBle.ModulationShaping = sidx << 4;
00861     radio.xfer(OPCODE_SET_MODULATION_PARAMS, 3, 0, mpBLE_GFSK.buf);
00862     return MENUMODE_REDRAW;
00863 }
00864 
00865 const dropdown_item_t Radio::gfsk_flrc_bt_item = { _ITEM_DROPDOWN, gfsk_flrc_bts, gfsk_flrc_bts, gfsk_flrc_bt_read, gfsk_flrc_bt_write};
00866 
00867 static const char* const gfsk_flrc_pblLens[] = {
00868     "4",
00869     "8",
00870     "12",
00871     "16",
00872     "20",
00873     "24",
00874     "28",
00875     "32",
00876     NULL,
00877 };
00878 
00879 unsigned Radio::gfsk_flrc_pl_read(bool fw)
00880 {
00881     PktCtrl1_t PktCtrl1;
00882     PktCtrl1.octet = radio.readReg(REG_ADDR_PKTCTRL1, 1);
00883     ppFLRC.gfskFLRC.PreambleLength = PktCtrl1.octet & 0x70;
00884     ppGFSK.gfskFLRC.PreambleLength = ppFLRC.gfskFLRC.PreambleLength;
00885     return PktCtrl1.gfsk.preamble_len;
00886 }
00887 
00888 menuMode_e Radio::gfsk_flrc_pl_write(unsigned sidx)
00889 {
00890     ppFLRC.gfskFLRC.PreambleLength = sidx << 4;
00891     ppGFSK.gfskFLRC.PreambleLength = ppFLRC.gfskFLRC.PreambleLength;
00892     radio.xfer(OPCODE_SET_PACKET_PARAMS, 7, 0, ppGFSK.buf);
00893     return MENUMODE_REDRAW;
00894 }
00895 
00896 const dropdown_item_t Radio::gfsk_flrc_preamble_item = { _ITEM_DROPDOWN, gfsk_flrc_pblLens, gfsk_flrc_pblLens, gfsk_flrc_pl_read, gfsk_flrc_pl_write};
00897 
00898 static const char* const gfsk_syncLens[] = {
00899     "1", // 0
00900     "2", // 1
00901     "3", // 2
00902     "4", // 3
00903     "5", // 4
00904     NULL,
00905 };
00906 
00907 unsigned Radio::gfsk_synclen_read(bool fw)
00908 {
00909     PktCtrl1_t PktCtrl1;
00910     PktCtrl1.octet = radio.readReg(REG_ADDR_PKTCTRL1, 1);
00911 
00912     ppGFSK.gfskFLRC.SyncWordLength = PktCtrl1.octet & 0x0e;
00913     ppFLRC.gfskFLRC.SyncWordLength = PktCtrl1.octet & 0x06;
00914 
00915     return PktCtrl1.gfsk.sync_adrs_len;
00916 }
00917 
00918 menuMode_e Radio::gfsk_synclen_write(unsigned sidx)
00919 {
00920     ppGFSK.gfskFLRC.SyncWordLength = sidx << 1;
00921     //log_printf("SWL %u %02x\r\n", sidx, ppGFSK.gfskFLRC.SyncWordLength);
00922     radio.xfer(OPCODE_SET_PACKET_PARAMS, 7, 0, ppGFSK.buf);
00923     //return MENUMODE_NONE;
00924     return MENUMODE_REDRAW;
00925 }
00926 
00927 const dropdown_item_t Radio::gfsk_synclen_item = { _ITEM_DROPDOWN, gfsk_syncLens, gfsk_syncLens, gfsk_synclen_read, gfsk_synclen_write};
00928 
00929 bool Radio::gfsk_flrc_fixvar_read()
00930 {
00931     PktCtrl0_t PktCtrl0;
00932     PktCtrl0.octet = radio.readReg(REG_ADDR_PKTCTRL0, 1);
00933 
00934     ppGFSK.gfskFLRC.HeaderType = PktCtrl0.octet & 0x20;
00935     ppFLRC.gfskFLRC.HeaderType = PktCtrl0.octet & 0x20;
00936 
00937     return PktCtrl0.bits.pkt_len_format;
00938 }
00939 
00940 bool Radio::gfsk_flrc_fixvar_push()
00941 {
00942     PacketParams_t* pp;
00943     pktType = radio.getPacketType();
00944 
00945     if (pktType == PACKET_TYPE_FLRC)
00946         pp = &ppFLRC;
00947     else if (pktType == PACKET_TYPE_GFSK)
00948         pp = &ppGFSK;
00949     else
00950         return false;
00951 
00952     if (pp->gfskFLRC.HeaderType == RADIO_PACKET_VARIABLE_LENGTH)
00953         pp->gfskFLRC.HeaderType = RADIO_PACKET_FIXED_LENGTH;
00954     else
00955         pp->gfskFLRC.HeaderType = RADIO_PACKET_VARIABLE_LENGTH;
00956 
00957     radio.xfer(OPCODE_SET_PACKET_PARAMS, 7, 0, pp->buf);
00958 
00959     return pp->gfskFLRC.HeaderType == RADIO_PACKET_VARIABLE_LENGTH;
00960 }
00961 
00962 const toggle_item_t Radio::gfsk_flrc_fixvar_item = { _ITEM_TOGGLE,
00963     "fixed   ",
00964     "variable",
00965     gfsk_flrc_fixvar_read, gfsk_flrc_fixvar_push
00966 };
00967 
00968 static const char* const gfsk_flrc_crclens[] = {
00969     "0 off",
00970     "1 byte",
00971     "2 bytes",
00972     NULL,
00973 };
00974 
00975 unsigned Radio::gfsk_flrc_crclen_read(bool fw)
00976 {
00977     PktBitStreamCtrl_t PktBitStreamCtrl;
00978     PktBitStreamCtrl.octet = radio.readReg(REG_ADDR_PKT_BITSTREAM_CTRL, 1);
00979     ppGFSK.gfskFLRC.CRCLength = PktBitStreamCtrl.octet & 0x30;
00980     return PktBitStreamCtrl.bits.crc_mode;
00981 }
00982 
00983 menuMode_e Radio::gfsk_flrc_crclen_write(unsigned sidx)
00984 {
00985     pktType = radio.getPacketType();
00986 
00987     ppGFSK.gfskFLRC.CRCLength = (sidx & 3) << 4;
00988     ppFLRC.gfskFLRC.CRCLength = (sidx & 3) << 4;
00989 
00990     if (pktType == PACKET_TYPE_GFSK)
00991         radio.xfer(OPCODE_SET_PACKET_PARAMS, 7, 0, ppGFSK.buf);
00992     else if (pktType == PACKET_TYPE_FLRC)
00993         radio.xfer(OPCODE_SET_PACKET_PARAMS, 7, 0, ppFLRC.buf);
00994 
00995     return MENUMODE_REDRAW;
00996 }
00997 
00998 const dropdown_item_t Radio::gfsk_flrc_crclen_item = { _ITEM_DROPDOWN, gfsk_flrc_crclens, gfsk_flrc_crclens, gfsk_flrc_crclen_read, gfsk_flrc_crclen_write};
00999 
01000 bool Radio::gfsk_flrc_whit_read()
01001 {
01002     PktBitStreamCtrl_t PktBitStreamCtrl;
01003     PktBitStreamCtrl.octet = radio.readReg(REG_ADDR_PKT_BITSTREAM_CTRL, 1);
01004     ppGFSK.gfskFLRC.Whitening = PktBitStreamCtrl.octet & 0x08;
01005     ppFLRC.gfskFLRC.Whitening = PktBitStreamCtrl.octet & 0x08;
01006     return PktBitStreamCtrl.bits.whit_disable;
01007 }
01008 
01009 bool Radio::gfsk_flrc_whit_push()
01010 {
01011     pktType = radio.getPacketType();
01012 
01013     if (ppGFSK.gfskFLRC.Whitening == WHITENING_DISABLE)
01014         ppGFSK.gfskFLRC.Whitening = WHITENING_ENABLE;
01015     else
01016         ppGFSK.gfskFLRC.Whitening = WHITENING_DISABLE;
01017 
01018     ppFLRC.gfskFLRC.Whitening = ppGFSK.gfskFLRC.Whitening;
01019 
01020     if (pktType == PACKET_TYPE_GFSK)
01021         radio.xfer(OPCODE_SET_PACKET_PARAMS, 7, 0, ppGFSK.buf);
01022     else if (pktType == PACKET_TYPE_FLRC)
01023         radio.xfer(OPCODE_SET_PACKET_PARAMS, 7, 0, ppFLRC.buf);
01024 
01025     return ppGFSK.gfskFLRC.Whitening == WHITENING_DISABLE;
01026 }
01027 
01028 const toggle_item_t Radio::gfsk_flrc_whit_item = { _ITEM_TOGGLE,
01029     "ENABLE ",
01030     "DISABLE",
01031     gfsk_flrc_whit_read, gfsk_flrc_whit_push
01032 };
01033 
01034 void Radio::gfsk_flrc_crcinit_print()
01035 {
01036     unsigned val = radio.readReg(0x9c8, 2);
01037     printf("0x%04x", val);
01038 }
01039 
01040 bool Radio::gfsk_flrc_crcinit_write(const char* txt)
01041 {
01042     unsigned val;
01043     sscanf(txt, "%x", &val);
01044     radio.writeReg(0x9c8, val, 2);
01045     return false;
01046 }
01047 
01048 const value_item_t Radio::gfsk_flrc_crcinit_item = { _ITEM_VALUE, 7, gfsk_flrc_crcinit_print, gfsk_flrc_crcinit_write };
01049 
01050 void Radio::gfsk_flrc_crcpoly_print(void)
01051 {
01052     unsigned val = radio.readReg(0x9c6, 2);
01053     printf("0x%04x", val);
01054 }
01055 
01056 bool Radio::gfsk_flrc_crcpoly_write(const char* txt)
01057 {
01058     unsigned val;
01059     sscanf(txt, "%x", &val);
01060     radio.writeReg(0x9c6, val, 2);
01061     return false;
01062 }
01063 
01064 const value_item_t Radio::gfsk_flrc_crcpoly_item = { _ITEM_VALUE, 7, gfsk_flrc_crcpoly_print, gfsk_flrc_crcpoly_write };
01065 
01066 bool Radio::gfsk_flrc_sync1en_read()
01067 {
01068     PktSyncAdrs_t PktSyncAdrs;
01069     PktSyncAdrs.octet = radio.readReg(REG_ADDR_PKT_SYNC_ADRS_CTRL, 1);
01070 
01071     ppGFSK.gfskFLRC.SyncWordMatch = PktSyncAdrs.octet & 0x70;
01072     ppFLRC.gfskFLRC.SyncWordMatch = PktSyncAdrs.octet & 0x70;
01073 
01074     return PktSyncAdrs.gfskflrc.sync_addr_mask & 1;
01075 }
01076 
01077 bool Radio::gfsk_flrc_sync2en_read()
01078 {
01079     PktSyncAdrs_t PktSyncAdrs;
01080     PktSyncAdrs.octet = radio.readReg(REG_ADDR_PKT_SYNC_ADRS_CTRL, 1);
01081 
01082     ppGFSK.gfskFLRC.SyncWordMatch = PktSyncAdrs.octet & 0x70;
01083     ppFLRC.gfskFLRC.SyncWordMatch = PktSyncAdrs.octet & 0x70;
01084 
01085     return ppGFSK.gfskFLRC.SyncWordMatch & 0x20;
01086 }
01087 
01088 bool Radio::gfsk_flrc_sync3en_read()
01089 {
01090     PktSyncAdrs_t PktSyncAdrs;
01091     PktSyncAdrs.octet = radio.readReg(REG_ADDR_PKT_SYNC_ADRS_CTRL, 1);
01092 
01093     ppGFSK.gfskFLRC.SyncWordMatch = PktSyncAdrs.octet & 0x70;
01094     ppFLRC.gfskFLRC.SyncWordMatch = PktSyncAdrs.octet & 0x70;
01095 
01096     return ppGFSK.gfskFLRC.SyncWordMatch & 0x40;
01097     //return PktSyncAdrs.gfskflrc.sync_addr_mask & 4;
01098 }
01099 
01100 bool Radio::gfsk_flrc_sync1en_push()
01101 {
01102     if (ppGFSK.gfskFLRC.SyncWordMatch & 0x10)
01103         ppGFSK.gfskFLRC.SyncWordMatch &= ~0x10;
01104     else
01105         ppGFSK.gfskFLRC.SyncWordMatch |= 0x10;
01106 
01107     radio.xfer(OPCODE_SET_PACKET_PARAMS, 7, 0, ppGFSK.buf);
01108 
01109     ppFLRC.gfskFLRC.SyncWordMatch = ppGFSK.gfskFLRC.SyncWordMatch;
01110 
01111     return ppGFSK.gfskFLRC.SyncWordMatch & 0x10;
01112 }
01113 
01114 bool Radio::gfsk_flrc_sync2en_push()
01115 {
01116     if (ppGFSK.gfskFLRC.SyncWordMatch & 0x20)
01117         ppGFSK.gfskFLRC.SyncWordMatch &= ~0x20;
01118     else
01119         ppGFSK.gfskFLRC.SyncWordMatch |= 0x20;
01120 
01121     radio.xfer(OPCODE_SET_PACKET_PARAMS, 7, 0, ppGFSK.buf);
01122 
01123     ppFLRC.gfskFLRC.SyncWordMatch = ppGFSK.gfskFLRC.SyncWordMatch;
01124 
01125     return ppGFSK.gfskFLRC.SyncWordMatch & 0x20;
01126 }
01127 
01128 bool Radio::gfsk_flrc_sync3en_push()
01129 {
01130     if (ppGFSK.gfskFLRC.SyncWordMatch & 0x40)
01131         ppGFSK.gfskFLRC.SyncWordMatch &= ~0x40;
01132     else
01133         ppGFSK.gfskFLRC.SyncWordMatch |= 0x40;
01134 
01135     radio.xfer(OPCODE_SET_PACKET_PARAMS, 7, 0, ppGFSK.buf);
01136 
01137     ppFLRC.gfskFLRC.SyncWordMatch = ppGFSK.gfskFLRC.SyncWordMatch;
01138 
01139     return ppGFSK.gfskFLRC.SyncWordMatch & 0x40;
01140 }
01141 
01142 const toggle_item_t Radio::gfsk_flrc_sync1en_item = { _ITEM_TOGGLE, "off:", " ON:", gfsk_flrc_sync1en_read, gfsk_flrc_sync1en_push};
01143 const toggle_item_t Radio::gfsk_flrc_sync2en_item = { _ITEM_TOGGLE, "off:", " ON:", gfsk_flrc_sync2en_read, gfsk_flrc_sync2en_push};
01144 const toggle_item_t Radio::gfsk_flrc_sync3en_item = { _ITEM_TOGGLE, "off:", " ON:", gfsk_flrc_sync3en_read, gfsk_flrc_sync3en_push};
01145 
01146 void Radio::gfsk_flrc_sync1_print(void)
01147 {
01148     uint64_t val;
01149     uint32_t val32 = radio.readReg(REG_ADDR_PKT_SYNC_ADRS_1+1, 4);
01150     uint32_t upper = radio.readReg(REG_ADDR_PKT_SYNC_ADRS_1, 1);
01151     val = upper;
01152     val <<= 32;
01153     val |= val32;
01154     printf("%llx", val);
01155 }
01156 
01157 void Radio::gfsk_flrc_sync2_print(void)
01158 {
01159     uint64_t val;
01160     uint32_t val32 = radio.readReg(REG_ADDR_PKT_SYNC_ADRS_2+1, 4);
01161     uint32_t upper = radio.readReg(REG_ADDR_PKT_SYNC_ADRS_2, 1);
01162     val = upper;
01163     val <<= 32;
01164     val |= val32;
01165     printf("%llx", val);
01166 }
01167 
01168 void Radio::gfsk_flrc_sync3_print(void)
01169 {
01170     uint64_t val;
01171     uint32_t val32 = radio.readReg(REG_ADDR_PKT_SYNC_ADRS_3+1, 4);
01172     uint32_t upper = radio.readReg(REG_ADDR_PKT_SYNC_ADRS_3, 1);
01173     val = upper;
01174     val <<= 32;
01175     val |= val32;
01176     printf("%llx", val);
01177 }
01178 
01179 bool Radio::gfsk_flrc_sync1_write(const char* txt)
01180 {
01181     uint32_t val32, upper;
01182     uint64_t val;
01183     sscanf(txt, "%llx", &val);
01184 
01185     val32 = val;
01186     val >>= 32;
01187     upper = val;
01188 
01189     radio.writeReg(REG_ADDR_PKT_SYNC_ADRS_1, upper, 1);
01190     radio.writeReg(REG_ADDR_PKT_SYNC_ADRS_1+1, val32, 4);
01191 
01192     return false;
01193 }
01194 
01195 bool Radio::gfsk_flrc_sync2_write(const char* txt)
01196 {
01197     uint32_t val32, upper;
01198     uint64_t val;
01199     sscanf(txt, "%llx", &val);
01200 
01201     val32 = val;
01202     val >>= 32;
01203     upper = val;
01204 
01205     radio.writeReg(REG_ADDR_PKT_SYNC_ADRS_2, upper, 1);
01206     radio.writeReg(REG_ADDR_PKT_SYNC_ADRS_2+1, val32, 4);
01207 
01208     return false;
01209 }
01210 
01211 bool Radio::gfsk_flrc_sync3_write(const char* txt)
01212 {
01213     uint32_t val32, upper;
01214     uint64_t val;
01215     sscanf(txt, "%llx", &val);
01216 
01217     val32 = val;
01218     val >>= 32;
01219     upper = val;
01220 
01221     radio.writeReg(REG_ADDR_PKT_SYNC_ADRS_3, upper, 1);
01222     radio.writeReg(REG_ADDR_PKT_SYNC_ADRS_3+1, val32, 4);
01223 
01224     return false;
01225 }
01226 
01227 const value_item_t Radio::gfsk_flrc_sync1_item = { _ITEM_VALUE, 10, gfsk_flrc_sync1_print, gfsk_flrc_sync1_write };
01228 const value_item_t Radio::gfsk_flrc_sync2_item = { _ITEM_VALUE, 10, gfsk_flrc_sync2_print, gfsk_flrc_sync2_write };
01229 const value_item_t Radio::gfsk_flrc_sync3_item = { _ITEM_VALUE, 10, gfsk_flrc_sync3_print, gfsk_flrc_sync3_write };
01230 
01231 
01232 const menu_t Radio::gfsk_menu[] = {
01233     { {FIRST_CHIP_MENU_ROW+1,  1},              NULL,  &gfsk_bitrate_item, FLAG_MSGTYPE_ALL },
01234     { {FIRST_CHIP_MENU_ROW+1, 19},      "mod index:", &gfsk_modindex_item, FLAG_MSGTYPE_ALL },
01235     { {FIRST_CHIP_MENU_ROW+1, 35},             "BT:",  &gfsk_flrc_bt_item, FLAG_MSGTYPE_ALL },
01236     { {FIRST_CHIP_MENU_ROW+1, 43}, "PreambleLength:", &gfsk_flrc_preamble_item, FLAG_MSGTYPE_ALL },
01237     { {FIRST_CHIP_MENU_ROW+1, 61},     "SyncLength:",  &gfsk_synclen_item, FLAG_MSGTYPE_ALL },
01238 
01239     { {FIRST_CHIP_MENU_ROW+2, 1},        "Length:", &gfsk_flrc_fixvar_item, FLAG_MSGTYPE_ALL },
01240     { {FIRST_CHIP_MENU_ROW+2, 18},    "crcLength:",   &gfsk_flrc_crclen_item, FLAG_MSGTYPE_ALL },
01241     { {FIRST_CHIP_MENU_ROW+2, 37},    "whitening:", &gfsk_flrc_whit_item, FLAG_MSGTYPE_ALL },
01242     { {FIRST_CHIP_MENU_ROW+2, 57},      "crcInit:",  &gfsk_flrc_crcinit_item, FLAG_MSGTYPE_ALL },
01243     { {FIRST_CHIP_MENU_ROW+2, 72},         "poly:",  &gfsk_flrc_crcpoly_item, FLAG_MSGTYPE_ALL },
01244 
01245     { {FIRST_CHIP_MENU_ROW+3,  1}, "sync1 ", &gfsk_flrc_sync1en_item, FLAG_MSGTYPE_ALL },
01246     { {FIRST_CHIP_MENU_ROW+3, 15},     NULL,   &gfsk_flrc_sync1_item, FLAG_MSGTYPE_ALL },
01247     { {FIRST_CHIP_MENU_ROW+3, 27}, "sync2 ", &gfsk_flrc_sync2en_item, FLAG_MSGTYPE_ALL },
01248     { {FIRST_CHIP_MENU_ROW+3, 41},     NULL,   &gfsk_flrc_sync2_item, FLAG_MSGTYPE_ALL },
01249     { {FIRST_CHIP_MENU_ROW+3, 53}, "sync3 ", &gfsk_flrc_sync3en_item, FLAG_MSGTYPE_ALL },
01250     { {FIRST_CHIP_MENU_ROW+3, 65},     NULL,   &gfsk_flrc_sync3_item, FLAG_MSGTYPE_ALL },
01251 
01252     { {0, 0}, NULL, NULL }
01253 };
01254 
01255 static const char* const flrc_bpsbw[] = {
01256     "2.6",
01257     "2.08",
01258     "1.3Mb/s   1.2MHz",
01259     "1.04Mb/s  1.2MHz",
01260     "0.65Mb/s  0.6MHz",
01261     "0.52Mb/s  0.6MHz",
01262     "0.325Mb/s 0.3MHz",
01263     "0.26Mb/s  0.3MHz",
01264     NULL
01265 };
01266 
01267 const dropdown_item_t Radio::flrc_bitrate_item = { _ITEM_DROPDOWN, flrc_bpsbw, flrc_bpsbw, gfsk_flrc_bpsbw_read, gfsk_flrc_bpsbw_write};
01268 
01269 static const char* const flrc_crs[] = {
01270     "1/2",
01271     "3/4",
01272     "1  ",
01273     NULL
01274 };
01275 unsigned Radio::flrc_cr_read(bool fw)
01276 {
01277     PktBitStreamCtrl_t PktBitStreamCtrl;
01278     PktBitStreamCtrl.octet = radio.readReg(REG_ADDR_PKT_BITSTREAM_CTRL, 1);
01279 
01280     mpFLRC.flrc.CodingRate = PktBitStreamCtrl.octet & 0x06; // PktBitStreamCtrl.bits.flora_coding_rate 
01281 
01282     return PktBitStreamCtrl.bits.flora_coding_rate;
01283 }
01284 
01285 menuMode_e Radio::flrc_cr_write(unsigned sidx)
01286 {
01287     mpFLRC.flrc.CodingRate = sidx << 1;
01288     radio.xfer(OPCODE_SET_MODULATION_PARAMS, 3, 0, mpFLRC.buf);
01289     return MENUMODE_REDRAW;
01290 }
01291 
01292 const dropdown_item_t Radio::flrc_cr_item = { _ITEM_DROPDOWN, flrc_crs, flrc_crs, flrc_cr_read, flrc_cr_write};
01293 
01294 static const char* const flrc_syncLens[] = {
01295     "SYNC OFF  ",
01296     "16BIT SYNC",
01297     "32BIT SYNC",
01298     NULL
01299 };
01300 
01301 unsigned Radio::flrc_synclen_read(bool fw)
01302 {
01303     PktCtrl1_t PktCtrl1;
01304     PktCtrl1.octet = radio.readReg(REG_ADDR_PKTCTRL1, 1);
01305     ppFLRC.gfskFLRC.SyncWordLength = PktCtrl1.octet & 0x06;
01306     if (ppFLRC.gfskFLRC.SyncWordLength == 0x06) {
01307         ppFLRC.gfskFLRC.SyncWordLength = FLRC_SYNC_WORD_LEN_P32S;
01308         return 2;
01309     }
01310 
01311     return PktCtrl1.flrc.sync_adrs_len;
01312 }
01313 
01314 menuMode_e Radio::flrc_synclen_write(unsigned sidx)
01315 {
01316     ppFLRC.gfskFLRC.SyncWordLength = sidx << 1;
01317     radio.xfer(OPCODE_SET_PACKET_PARAMS, 7, 0, ppFLRC.buf);
01318     return MENUMODE_REDRAW;
01319 }
01320 
01321 const dropdown_item_t Radio::flrc_synclen_item = { _ITEM_DROPDOWN, flrc_syncLens, flrc_syncLens, flrc_synclen_read, flrc_synclen_write};
01322 
01323 
01324 const menu_t Radio::flrc_menu[] = {
01325     { {FIRST_CHIP_MENU_ROW+1,  1},              NULL,  &flrc_bitrate_item, FLAG_MSGTYPE_ALL },
01326     { {FIRST_CHIP_MENU_ROW+1, 20},             "cr:",       &flrc_cr_item, FLAG_MSGTYPE_ALL },
01327     { {FIRST_CHIP_MENU_ROW+1, 27},             "BT:",      &gfsk_flrc_bt_item, FLAG_MSGTYPE_ALL },
01328     { {FIRST_CHIP_MENU_ROW+1, 34}, "PreambleLength:", &gfsk_flrc_preamble_item, FLAG_MSGTYPE_ALL },
01329     { {FIRST_CHIP_MENU_ROW+1, 52},     "SyncLength:",  &flrc_synclen_item, FLAG_MSGTYPE_ALL },
01330 
01331     { {FIRST_CHIP_MENU_ROW+2, 1},        "Length:", &gfsk_flrc_fixvar_item, FLAG_MSGTYPE_ALL },
01332     { {FIRST_CHIP_MENU_ROW+2, 18},    "crcLength:",   &gfsk_flrc_crclen_item, FLAG_MSGTYPE_ALL },
01333     { {FIRST_CHIP_MENU_ROW+2, 38},    "whitening:", &gfsk_flrc_whit_item, FLAG_MSGTYPE_ALL },
01334     { {FIRST_CHIP_MENU_ROW+2, 58},      "crcInit:",  &gfsk_flrc_crcinit_item, FLAG_MSGTYPE_ALL },
01335     { {FIRST_CHIP_MENU_ROW+2, 73},         "poly:",  &gfsk_flrc_crcpoly_item, FLAG_MSGTYPE_ALL },
01336 
01337     { {FIRST_CHIP_MENU_ROW+3,  1}, "sync1 ", &gfsk_flrc_sync1en_item, FLAG_MSGTYPE_ALL },
01338     { {FIRST_CHIP_MENU_ROW+3, 12},     NULL,   &gfsk_flrc_sync1_item, FLAG_MSGTYPE_ALL },
01339     { {FIRST_CHIP_MENU_ROW+3, 24}, "sync2 ", &gfsk_flrc_sync2en_item, FLAG_MSGTYPE_ALL },
01340     { {FIRST_CHIP_MENU_ROW+3, 35},     NULL,   &gfsk_flrc_sync2_item, FLAG_MSGTYPE_ALL },
01341     { {FIRST_CHIP_MENU_ROW+3, 47}, "sync3 ", &gfsk_flrc_sync3en_item, FLAG_MSGTYPE_ALL },
01342     { {FIRST_CHIP_MENU_ROW+3, 59},     NULL,   &gfsk_flrc_sync3_item, FLAG_MSGTYPE_ALL },
01343 
01344     { {0, 0}, NULL, NULL }
01345 };
01346 
01347 bool Radio::manualRngDelay;
01348 const uint16_t Radio::rngDelays[3][6] = {
01349     10299, 10271, 10244, 10242, 10230, 10246,
01350     11486, 11474, 11453, 11426, 11417, 11401,
01351     13308, 13493, 13528, 13515, 13430, 13376
01352 };
01353 
01354 void Radio::rngUpdateDelayCal()
01355 {
01356     LoRaPktPar0.octet = radio.readReg(REG_ADDR_LORA_PKTPAR0, 1);
01357 
01358     if (LoRaPktPar0.bits.modem_bw > 2 && LoRaPktPar0.bits.modem_sf < 11) {
01359         uint32_t delayCal = radio.readReg(REG_ADDR_LORA_DELAY_CAL, 3);
01360         delayCal &= ~0x3fffff;
01361         delayCal |= rngDelays[LoRaPktPar0.bits.modem_bw-3][LoRaPktPar0.bits.modem_sf-5];
01362         /*log_printf("%u = rngDelays[%u][%u]\r\n",
01363             rngDelays[LoRaPktPar0.bits.modem_bw-3][LoRaPktPar0.bits.modem_sf-5],
01364             LoRaPktPar0.bits.modem_bw-3, LoRaPktPar0.bits.modem_sf-5
01365         );*/
01366         radio.writeReg(REG_ADDR_LORA_DELAY_CAL, delayCal, 3);
01367     }
01368 }
01369 
01370 static const char* const lora_bws[] = {
01371     "  50KHz", // 0
01372     " 100KHz", // 1
01373     " 200KHz", // 2
01374     " 400KHz", // 3
01375     " 800KHz", // 4
01376     "1600KHz", // 5
01377     NULL
01378 };
01379 
01380 const float Radio::bwMHzs[] = { 0.05, 0.1, 0.2, 0.4, 0.8, 1.6 };
01381 
01382 LoRaPktPar0_t Radio::LoRaPktPar0;
01383 
01384 unsigned Radio::lora_bw_read(bool fw)
01385 {
01386     LoRaPktPar0.octet = radio.readReg(REG_ADDR_LORA_PKTPAR0, 1);
01387 
01388     return LoRaPktPar0.bits.modem_bw;
01389 }
01390 
01391 menuMode_e Radio::lora_bw_write(unsigned sidx)
01392 {
01393     switch (sidx) {
01394         case 0: mpLORA.lora.bandwidth = LORA_BW_50; break;
01395         case 1: mpLORA.lora.bandwidth = LORA_BW_100; break;
01396         case 2: mpLORA.lora.bandwidth = LORA_BW_200; break;
01397         case 3: mpLORA.lora.bandwidth = LORA_BW_400; break;
01398         case 4: mpLORA.lora.bandwidth = LORA_BW_800; break;
01399         case 5: mpLORA.lora.bandwidth = LORA_BW_1600; break;
01400     }
01401     radio.xfer(OPCODE_SET_MODULATION_PARAMS, 3, 0, mpLORA.buf);
01402 
01403     if (pktType == PACKET_TYPE_RANGING) {
01404         manualRngDelay = false;
01405         rngUpdateDelayCal();
01406     }
01407 
01408     return MENUMODE_REDRAW;
01409 }
01410 
01411 const dropdown_item_t Radio::lora_bw_item = { _ITEM_DROPDOWN, lora_bws, lora_bws, lora_bw_read, lora_bw_write};
01412 
01413 void Radio::lora_sf_print()
01414 {
01415     LoRaPktPar0.octet = radio.readReg(REG_ADDR_LORA_PKTPAR0, 1);
01416 
01417     printf("%u", LoRaPktPar0.bits.modem_sf);
01418 }
01419 
01420 bool Radio::lora_sf_write(const char* str)
01421 {
01422     unsigned n;
01423     if (sscanf(str, "%u", &n) == 1) {
01424         mpLORA.lora.spreadingFactor = n << 4;
01425         radio.xfer(OPCODE_SET_MODULATION_PARAMS, 3, 0, mpLORA.buf);
01426 
01427         if (pktType == PACKET_TYPE_RANGING) {
01428             manualRngDelay = false;
01429             rngUpdateDelayCal();
01430         }
01431     }
01432     return false;
01433 }
01434 
01435 const value_item_t Radio::lora_sf_item = { _ITEM_VALUE, 3, lora_sf_print, lora_sf_write };
01436 
01437 static const char* const lora_crs[] = {
01438     "4/5   ",
01439     "4/6   ",
01440     "4/7   ",
01441     "4/8   ",
01442     "4/5 LI",
01443     "4/6 LI",
01444     "4/7 LI",
01445     NULL
01446 };
01447 
01448 unsigned Radio::lora_cr_read(bool fw)
01449 {
01450     LoRaPktPar1_t LoRaPktPar1;
01451     LoRaPktPar1.octet = radio.readReg(REG_ADDR_LORA_PKTPAR1, 1);
01452     mpLORA.lora.codingRate = LoRaPktPar1.bits.coding_rate;
01453     return LoRaPktPar1.bits.coding_rate;
01454 }
01455 
01456 menuMode_e Radio::lora_cr_write(unsigned sidx)
01457 {
01458     mpLORA.lora.codingRate = sidx;
01459     radio.xfer(OPCODE_SET_MODULATION_PARAMS, 3, 0, mpLORA.buf);
01460     return MENUMODE_REDRAW;
01461 }
01462 
01463 const dropdown_item_t Radio::lora_cr_item = { _ITEM_DROPDOWN, lora_crs, lora_crs, lora_cr_read, lora_cr_write};
01464 
01465 void Radio::lora_pblLen_print()
01466 {
01467     LoRaPreambleReg_t LoRaPreambleReg;
01468     LoRaPreambleReg.octet = radio.readReg(REG_ADDR_LORA_PREAMBLE, 1);
01469     ppLORA.lora.PreambleLength = (1 << LoRaPreambleReg.bits.preamble_symb_nb_exp) * LoRaPreambleReg.bits.preamble_symb1_nb;
01470     printf("%u", ppLORA.lora.PreambleLength);
01471 }
01472 
01473 bool Radio::lora_pblLen_write(const char* str)
01474 {
01475     unsigned val, exp, mant;
01476     sscanf(str, "%u", &val);
01477 
01478     for (exp = 0; exp < 16; exp++) {
01479         mant = val / (1 << exp);
01480         if (mant < 16)
01481             break;
01482     }
01483 
01484     ppLORA.lora.PreambleLength = (exp << 4) + mant;
01485     radio.xfer(OPCODE_SET_PACKET_PARAMS, 5, 0, ppLORA.buf);
01486 
01487     return false;
01488 }
01489 
01490 const value_item_t Radio::lora_pblLen_item = { _ITEM_VALUE, 5, lora_pblLen_print, lora_pblLen_write};
01491 
01492 bool Radio::lora_fixlen_read()
01493 {
01494     LoRaPktPar1_t LoRaPktPar1;
01495     LoRaPktPar1.octet = radio.readReg(REG_ADDR_LORA_PKTPAR1, 1);
01496     ppLORA.lora.HeaderType = LoRaPktPar1.bits.implicit_header ? IMPLICIT_HEADER : EXPLICIT_HEADER;
01497     return LoRaPktPar1.bits.implicit_header;
01498 }
01499 
01500 bool Radio::lora_fixlen_push()
01501 {
01502     if (ppLORA.lora.HeaderType == EXPLICIT_HEADER)
01503         ppLORA.lora.HeaderType = IMPLICIT_HEADER;
01504     else
01505         ppLORA.lora.HeaderType = EXPLICIT_HEADER;
01506 
01507     radio.xfer(OPCODE_SET_PACKET_PARAMS, 5, 0, ppLORA.buf);
01508     return ppLORA.lora.HeaderType == IMPLICIT_HEADER;
01509 }
01510 
01511 const toggle_item_t Radio::lora_fixlen_item = { _ITEM_TOGGLE,
01512     "EXPLICIT", // 0
01513     "IMPLICIT", // 1
01514     lora_fixlen_read, lora_fixlen_push
01515 };
01516 
01517 bool Radio::lora_crcon_read()
01518 {
01519     LoRaLrCtl_t LoRaLrCtl;
01520     LoRaLrCtl.octet = radio.readReg(REG_ADDR_LORA_LRCTL, 1);
01521     ppLORA.lora.crc = LoRaLrCtl.octet & 0x20; // LoRaLrCtl.bits.crc_en
01522     return LoRaLrCtl.bits.crc_en;
01523 }
01524 
01525 bool Radio::lora_crcon_push()
01526 {
01527     if (ppLORA.lora.crc == LORA_CRC_ENABLE)
01528         ppLORA.lora.crc = LORA_CRC_DISABLE;
01529     else
01530         ppLORA.lora.crc = LORA_CRC_ENABLE;
01531 
01532     radio.xfer(OPCODE_SET_PACKET_PARAMS, 5, 0, ppLORA.buf);
01533 
01534     return ppLORA.lora.crc == LORA_CRC_ENABLE;
01535 }
01536 
01537 const toggle_item_t Radio::lora_crcon_item = { _ITEM_TOGGLE,
01538     "CRC_DISABLE", // 0
01539     "CRC_ENABLE ", // 1
01540     lora_crcon_read, lora_crcon_push
01541 };
01542 
01543 bool Radio::lora_iqinv_read()
01544 {
01545     LoRaPktPar1_t LoRaPktPar1;
01546     LoRaPktPar1.octet = radio.readReg(REG_ADDR_LORA_PKTPAR1, 1);
01547     ppLORA.lora.InvertIQ = LoRaPktPar1.bits.rxinvert_iq ? LORA_IQ_STD : LORA_IQ_INVERTED;
01548     return LoRaPktPar1.bits.rxinvert_iq ? 0 : 1;
01549 }
01550 
01551 bool Radio::lora_iqinv_push()
01552 {
01553     if (ppLORA.lora.InvertIQ == LORA_IQ_STD)
01554         ppLORA.lora.InvertIQ = LORA_IQ_INVERTED;
01555     else
01556         ppLORA.lora.InvertIQ = LORA_IQ_STD;
01557 
01558     radio.xfer(OPCODE_SET_PACKET_PARAMS, 5, 0, ppLORA.buf);
01559 
01560     return ppLORA.lora.InvertIQ == LORA_IQ_INVERTED;
01561 }
01562 
01563 const toggle_item_t Radio::lora_iqinv_item = { _ITEM_TOGGLE,
01564     "IQ_STD", // 0
01565     "IQ_INV", // 1
01566     lora_iqinv_read, lora_iqinv_push
01567 };
01568 
01569 void Radio::lora_ppg_print()
01570 {
01571     uint8_t val;
01572     ppg = radio.readReg(REG_ADDR_LORA_SYNC, 2);
01573 
01574     val = (ppg >> 8) & 0xf0;
01575     val |= (ppg & 0xf0) >> 4;
01576     printf("%02x", val);
01577 }
01578 
01579 bool Radio::lora_ppg_write(const char* txt)
01580 {
01581     unsigned val;
01582     if (sscanf(txt, "%x", &val) == 1) {
01583         ppg &= 0x0707;
01584         ppg |= (val & 0xf0) << 8;
01585         ppg |= (val & 0x0f) << 4;
01586         radio.writeReg(REG_ADDR_LORA_SYNC, ppg, 2);
01587     }
01588     return false;
01589 }
01590 
01591 const value_item_t Radio::lora_ppg_item = { _ITEM_VALUE, 4, lora_ppg_print, lora_ppg_write};
01592 
01593 void Radio::cad_push()
01594 {
01595     radio.setCAD();
01596 }
01597 
01598 const button_item_t Radio::lora_cad_item = { _ITEM_BUTTON, "CAD", cad_push };
01599 
01600 static const char* const lora_cadsymbs[] = {
01601     " 1",
01602     " 2",
01603     " 4",
01604     " 8",
01605     "16",
01606     NULL
01607 };
01608 
01609 unsigned Radio::lora_cadsymbs_read(bool forWriting)
01610 {
01611     unsigned n = radio.readReg(REG_ADDR_LORA_FE_GAIN, 1);
01612     return n >> 5;
01613 }
01614 
01615 menuMode_e Radio::lora_cadsymbs_write(unsigned sidx)
01616 {
01617     uint8_t buf = sidx << 5;
01618     radio.xfer(OPCODE_SET_CAD_PARAM, 1, 0, &buf);
01619     return MENUMODE_REDRAW;
01620 }
01621 
01622 const dropdown_item_t Radio::lora_cadsymbs_item = { _ITEM_DROPDOWN, lora_cadsymbs, lora_cadsymbs, lora_cadsymbs_read, lora_cadsymbs_write};
01623 
01624 const menu_t Radio::lora_menu[] = {
01625     { {FIRST_CHIP_MENU_ROW+1,  1},              NULL,     &lora_bw_item, FLAG_MSGTYPE_ALL, &rng_delay_item},
01626     { {FIRST_CHIP_MENU_ROW+1, 12},             "sf:",     &lora_sf_item, FLAG_MSGTYPE_ALL, &rng_delay_item},
01627     { {FIRST_CHIP_MENU_ROW+1, 20},             "cr:",     &lora_cr_item, FLAG_MSGTYPE_ALL },
01628     { {FIRST_CHIP_MENU_ROW+1, 30}, "PreambleLength:", &lora_pblLen_item, FLAG_MSGTYPE_ALL },
01629     { {FIRST_CHIP_MENU_ROW+2,  1},              NULL, &lora_fixlen_item, FLAG_MSGTYPE_ALL },
01630     { {FIRST_CHIP_MENU_ROW+2, 12},              NULL,  &lora_crcon_item, FLAG_MSGTYPE_ALL },
01631     { {FIRST_CHIP_MENU_ROW+2, 25},              NULL,  &lora_iqinv_item, FLAG_MSGTYPE_ALL },
01632     { {FIRST_CHIP_MENU_ROW+2, 35},            "ppg:",    &lora_ppg_item, FLAG_MSGTYPE_ALL },
01633 
01634     { {FIRST_CHIP_MENU_ROW+3,  1},          NULL,        &lora_cad_item, FLAG_MSGTYPE_ALL },
01635     { {FIRST_CHIP_MENU_ROW+3,  5},    "symbols:",   &lora_cadsymbs_item, FLAG_MSGTYPE_ALL },
01636 
01637     { {0, 0}, NULL, NULL }
01638 };
01639 
01640 bool Radio::tmp;
01641 
01642 bool Radio::rng_role_read()
01643 {
01644     //RngCfg0_t RngCfg0;
01645     //RngCfg0.octet = radio.readReg(REG_ADDR_RNGCFG0, 1);
01646 
01647     //return !RngCfg0.bits.ranging_resp_en;
01648     //log_printf("%02x ranging_resp_en: %u\r\n", RngCfg0.octet, RngCfg0.bits.ranging_resp_en);
01649     return tmp;
01650 }
01651 
01652 bool Radio::rng_role_push()
01653 {
01654     uint8_t buf;
01655 /*
01656     RngCfg0_t RngCfg0;
01657     RngCfg0.octet = radio.readReg(REG_ADDR_RNGCFG0, 1);
01658 
01659     buf = RngCfg0.bits.ranging_resp_en ? 0 : 1;
01660     log_printf("role %02x  %u\r\n", RngCfg0.octet, buf);
01661     radio.xfer(OPCODE_SET_RANGING_ROLE, 1, 0, &buf);
01662     return buf;
01663 */
01664     tmp ^= true;
01665     buf = tmp;
01666     radio.xfer(OPCODE_SET_RANGING_ROLE, 1, 0, &buf);
01667     return tmp;
01668 }
01669 
01670 const toggle_item_t Radio::rng_role_item = { _ITEM_TOGGLE,
01671     " SLAVE", // 0
01672     "MASTER", // 1
01673     rng_role_read, rng_role_push
01674 };
01675 
01676 void Radio::rng_id_send_print()
01677 {
01678     printf("%08x", radio.readReg(REG_ADDR_LORA_MASTER_REQ_ID, 4));
01679 }
01680 
01681 bool Radio::rng_id_send_write(const char* txt)
01682 {
01683     unsigned n;
01684     sscanf(txt, "%x", &n);
01685     radio.writeReg(REG_ADDR_LORA_MASTER_REQ_ID, n, 4);
01686     return false;
01687 }
01688 
01689 const value_item_t Radio::rng_id_send_item = { _ITEM_VALUE, 9, rng_id_send_print, rng_id_send_write};
01690 
01691 void Radio::rng_slave_id_print()
01692 {
01693     printf("%08x", radio.readReg(REG_ADDR_LORA_SLAVE_ID, 4));
01694 }
01695 
01696 bool Radio::rng_slave_id_write(const char* txt)
01697 {
01698     unsigned n;
01699     sscanf(txt, "%x", &n);
01700     radio.writeReg(REG_ADDR_LORA_SLAVE_ID, n, 4);
01701     return false;
01702 }
01703 
01704 const value_item_t Radio::rng_slave_id_item = { _ITEM_VALUE, 9, rng_slave_id_print, rng_slave_id_write};
01705 
01706 unsigned Radio::rng_idLength_read(bool forWriting)
01707 {
01708     RngDebTh2_t RngDebTh2;
01709     RngDebTh2.octet = radio.readReg(REG_ADDR_LORA_RNGDEBTH2, 1);
01710     return RngDebTh2.bits.ranging_id_check_length;
01711 }
01712 
01713 menuMode_e Radio::rng_idLength_write(unsigned sidx)
01714 {
01715     RngDebTh2_t RngDebTh2;
01716     RngDebTh2.octet = radio.readReg(REG_ADDR_LORA_RNGDEBTH2, 1);
01717     RngDebTh2.bits.ranging_id_check_length = sidx;
01718     radio.writeReg(REG_ADDR_LORA_RNGDEBTH2, RngDebTh2.octet, 1);
01719     return MENUMODE_REDRAW;
01720 }
01721 
01722 static const char* const rngLens[] = {
01723     " 8 bits",
01724     "16 bits",
01725     "24 bits",
01726     "32 bits",
01727     NULL
01728 };
01729 
01730 const dropdown_item_t Radio::rng_idLength_item = { _ITEM_DROPDOWN, rngLens, rngLens, rng_idLength_read, rng_idLength_write};
01731 
01732 
01733 void Radio::rng_delay_print(void)
01734 {
01735     if (pktType == PACKET_TYPE_RANGING) {
01736         printf("%u", radio.readReg(REG_ADDR_LORA_DELAY_CAL, 3) & 0x3fffff);
01737     }
01738 }
01739 
01740 bool Radio::rng_delay_write(const char* txt)
01741 {
01742     unsigned n;
01743     uint32_t delayCal = radio.readReg(REG_ADDR_LORA_DELAY_CAL, 3);
01744     sscanf(txt, "%u", &n);
01745     delayCal &= ~0x3fffff;
01746     delayCal |= n;
01747     radio.writeReg(REG_ADDR_LORA_DELAY_CAL, delayCal, 3);
01748 
01749     manualRngDelay = true;
01750     return false;
01751 }
01752 
01753 const value_item_t Radio::rng_delay_item = { _ITEM_VALUE, 7, rng_delay_print, rng_delay_write };
01754 
01755 unsigned Radio::rng_resultMux_read(bool)
01756 {
01757     RngCfg1_t RngCfg1;
01758     RngCfg1.octet = radio.readReg(REG_ADDR_RNGCFG1, 1);
01759     return RngCfg1.bits.ranging_result_mux_sel;
01760 }
01761 
01762 menuMode_e Radio::rng_resultMux_write(unsigned sidx)
01763 {
01764     RngCfg1_t RngCfg1;
01765     RngCfg1.octet = radio.readReg(REG_ADDR_RNGCFG1, 1);
01766     RngCfg1.bits.ranging_result_mux_sel = sidx;
01767     radio.writeReg(REG_ADDR_RNGCFG1, RngCfg1.octet, 1);
01768     return MENUMODE_REDRAW;
01769 }
01770 
01771 static const char* const rngResults[] = {
01772     "     raw   ",
01773     "  rssiAvg  ",
01774     " debiased  ",
01775     "finalFilter",
01776     NULL
01777 };
01778 
01779 const dropdown_item_t Radio::rng_resultMux_item = { _ITEM_DROPDOWN, rngResults, rngResults, rng_resultMux_read, rng_resultMux_write};
01780 
01781 
01782 void Radio::rng_wndFltSize_print()
01783 {
01784     printf("%u", radio.readReg(REG_ADDR_RNGFLTWNDSIZE, 1));
01785 }
01786 
01787 bool Radio::rng_wndFltSize_write(const char* txt)
01788 {
01789     unsigned n;
01790     sscanf(txt, "%u", &n);
01791     radio.writeReg(REG_ADDR_RNGFLTWNDSIZE, n, 1);
01792     return false;
01793 }
01794 
01795 const value_item_t Radio::rng_wndFltSize_item = { _ITEM_VALUE, 4, rng_wndFltSize_print, rng_wndFltSize_write};
01796 
01797 
01798 
01799 
01800 void Radio::rng_rngRssiThresh_print()
01801 {
01802     RngDebTh4H_t RngDebTh4H;
01803     RngDebTh4H.octet = radio.readReg(REG_ADDR_RNGDEBTH4H, 1);
01804     printf("%u", RngDebTh4H.bits.rng_rssi_threshold);
01805 }
01806 
01807 bool Radio::rng_rngRssiThresh_write(const char* txt)
01808 {
01809     unsigned n;
01810     RngDebTh4H_t RngDebTh4H;
01811     RngDebTh4H.octet = radio.readReg(REG_ADDR_RNGDEBTH4H, 1);
01812     sscanf(txt, "%u", &n);
01813     RngDebTh4H.bits.rng_rssi_threshold = n;
01814     radio.writeReg(REG_ADDR_RNGDEBTH4H, RngDebTh4H.octet, 1);
01815     return false;
01816 }
01817 
01818 const value_item_t Radio::rng_rngRssiThresh_item = { _ITEM_VALUE, 4, rng_rngRssiThresh_print, rng_rngRssiThresh_write};
01819 
01820 const menu_t Radio::rng_menu[] = {
01821     { {FIRST_CHIP_MENU_ROW+3, 19},          NULL,      &rng_role_item, FLAG_MSGTYPE_ALL },
01822     { {FIRST_CHIP_MENU_ROW+3, 28}, "ID to send:",      &rng_id_send_item, FLAG_MSGTYPE_ALL },
01823     { {FIRST_CHIP_MENU_ROW+3, 49},  "slave ID:",    &rng_slave_id_item, FLAG_MSGTYPE_ALL },
01824     { {FIRST_CHIP_MENU_ROW+3, 67},      NULL,    &rng_idLength_item, FLAG_MSGTYPE_ALL },
01825     { {FIRST_CHIP_MENU_ROW+4,  1},  "delay:",    &rng_delay_item, FLAG_MSGTYPE_ALL },
01826     { {FIRST_CHIP_MENU_ROW+4, 14}, "resultMux:", &rng_resultMux_item, FLAG_MSGTYPE_ALL },
01827     { {FIRST_CHIP_MENU_ROW+4, 37}, "windowFilterSize:", &rng_wndFltSize_item, FLAG_MSGTYPE_ALL },
01828     { {FIRST_CHIP_MENU_ROW+4, 59}, "rngRssiThresh:", &rng_rngRssiThresh_item, FLAG_MSGTYPE_ALL },
01829 
01830     { {0, 0}, NULL, NULL }
01831 };
01832 
01833 void Radio::xta_print()
01834 {
01835     uint8_t trim = radio.readReg(REG_ADDR_XTA_TRIM, 1);
01836     printf("%02x", trim);
01837 }
01838 
01839 bool Radio::xta_write(const char* txt)
01840 {
01841     unsigned trim;
01842     if (sscanf(txt, "%x", &trim) == 1)
01843         radio.writeReg(REG_ADDR_XTA_TRIM, trim, 1);
01844 
01845     return false;
01846 }
01847 
01848 const value_item_t Radio::xta_item = { _ITEM_VALUE, 3, xta_print, xta_write};
01849 
01850 void Radio::xtb_print()
01851 {
01852     uint8_t trim = radio.readReg(REG_ADDR_XTB_TRIM, 1);
01853     printf("%02x", trim);
01854 }
01855 
01856 bool Radio::xtb_write(const char* txt)
01857 {
01858     unsigned trim;
01859     if (sscanf(txt, "%x", &trim) == 1)
01860         radio.writeReg(REG_ADDR_XTB_TRIM, trim, 1);
01861 
01862     return false;
01863 }
01864 
01865 const value_item_t Radio::xtb_item = { _ITEM_VALUE, 3, xtb_print, xtb_write};
01866 
01867 const menu_t Radio::common_menu[] = {
01868     { {FIRST_CHIP_MENU_ROW, 1},         "XTA:",         &xta_item, FLAG_MSGTYPE_ALL },
01869     { {FIRST_CHIP_MENU_ROW, 8},         "XTB:",         &xtb_item, FLAG_MSGTYPE_ALL },
01870     { {0, 0}, NULL, NULL }
01871 };
01872 
01873 const menu_t* Radio::get_modem_menu()
01874 {
01875     pktType = radio.getPacketType();
01876 
01877     if (pktType == PACKET_TYPE_RANGING || pktType == PACKET_TYPE_LORA) {
01878         return lora_menu;
01879     } else if (pktType == PACKET_TYPE_FLRC) {
01880         return flrc_menu;
01881     } else if (pktType == PACKET_TYPE_GFSK) {
01882         return gfsk_menu;
01883     }
01884 
01885     return NULL;
01886 }
01887 
01888 const menu_t* Radio::get_modem_sub_menu()
01889 {
01890     if (pktType == PACKET_TYPE_RANGING) {
01891         return rng_menu;
01892     }
01893     return NULL;
01894 }
01895 
01896 bool Radio::service(int8_t statusRow)
01897 {
01898     static pktStatus_t prevPktStatus;
01899     static IrqFlags_t prevIrqFlags;
01900     IrqFlags_t irqFlags;
01901     bool ret = false;
01902     static long prev_now_ms;
01903     auto now_tp = time_point_cast<milliseconds>(Kernel::Clock::now());
01904     long now_ms = now_tp.time_since_epoch().count();    
01905 
01906     radio.service();
01907 
01908     if (statusRow > 0 && now_ms-prev_now_ms > 50) {
01909         int cmp = 0;
01910         pktStatus_t pktStatus;
01911         uint8_t buf[6];
01912         radio.xfer(OPCODE_GET_IRQ_STATUS, 0, 3, buf);
01913         irqFlags.word = buf[1] << 8;
01914         irqFlags.word |= buf[2];
01915 
01916         if (rx_led == LED_ON) {
01917             uint8_t slen;
01918             if (pktType == PACKET_TYPE_LORA || pktType == PACKET_TYPE_RANGING)
01919                 slen = 3;
01920             else
01921                 slen = 6;
01922 
01923             radio.xfer(OPCODE_GET_PACKET_STATUS, 0, slen, pktStatus.buf);
01924             cmp = memcmp(prevPktStatus.buf, pktStatus.buf, slen);
01925         }
01926 
01927         if (irqFlags.word != prevIrqFlags.word || cmp) {
01928             IrqFlags_t clearIrqFlags;
01929             clearIrqFlags.word = 0;
01930 
01931             printf("\e[%u;1f", statusRow);  // set (force) cursor to row;column
01932 
01933             if (cmp) {
01934                 if (pktType == PACKET_TYPE_FLRC || pktType == PACKET_TYPE_BLE || pktType == PACKET_TYPE_GFSK) {
01935                     if (pktStatus.ble_gfsk_flrc.errors.SyncError)
01936                         printf("SyncError ");
01937                     if (pktStatus.ble_gfsk_flrc.errors.LengthError)
01938                         printf("LengthError ");
01939                     if (pktStatus.ble_gfsk_flrc.errors.CrcError)
01940                         printf("CrcError ");
01941                     if (pktStatus.ble_gfsk_flrc.errors.AbortErr)
01942                         printf("AbortErr ");
01943                     if (pktStatus.ble_gfsk_flrc.errors.headerReceived)
01944                         printf("headerReceived ");
01945                     if (pktStatus.ble_gfsk_flrc.errors.packetReceived)
01946                         printf("packetReceived ");
01947                     if (pktStatus.ble_gfsk_flrc.errors.pktCtrlBusy)
01948                         printf("pktCtrlBusy ");
01949                 }
01950                 memcpy(prevPktStatus.buf, pktStatus.buf, sizeof(pktStatus_t));
01951                 printf(" | ");
01952             }
01953 
01954             if (irqFlags.bits.TxDone)
01955                 printf("TxDone ");
01956             if (irqFlags.bits.RxDone)
01957                 printf("RxDone ");
01958             if (irqFlags.bits.SyncWordValid)
01959                 printf("SyncWordValid ");
01960             if (irqFlags.bits.SyncWordError)
01961                 printf("SyncWordError ");
01962             if (irqFlags.bits.HeaderValid)
01963                 printf("HeaderValid ");
01964             if (irqFlags.bits.HeaderError)
01965                 printf("HeaderError ");
01966             if (irqFlags.bits.CrcError)
01967                 printf("CrcError ");
01968             if (irqFlags.bits.RangingSlaveResponseDone) {
01969                 printf("RangingSlaveResponseDone ");
01970                 clearIrqFlags.bits.RangingSlaveResponseDone = 1;
01971             } if (irqFlags.bits.RangingSlaveRequestDiscard) {
01972                 printf("RangingSlaveRequestDiscard ");
01973                 clearIrqFlags.bits.RangingSlaveRequestDiscard = 1;
01974             } if (irqFlags.bits.RangingMasterResultValid) {
01975                 printf("RangingMasterResultValid ");
01976             } if (irqFlags.bits.RangingMasterTimeout) {
01977                 radio.chipMode = CHIPMODE_NONE;
01978                 chipModeChange();
01979                 printf("RangingMasterTimeout ");
01980                 clearIrqFlags.bits.RangingMasterTimeout = 1;
01981             } if (irqFlags.bits.RangingMasterRequestValid) {
01982                 printf("RangingMasterRequestValid ");
01983                 clearIrqFlags.bits.RangingMasterRequestValid = 1;
01984             } if (irqFlags.bits.CadDone)
01985                 printf("CadDone ");
01986             if (irqFlags.bits.CadDetected)
01987                 printf("CadDetected ");
01988             if (irqFlags.bits.RxTxTimeout)
01989                 printf("RxTxTimeout ");
01990             if (irqFlags.bits.PreambleDetected)
01991                 printf("PreambleDetected ");
01992 
01993             printf("\e[K");
01994             ret = true;
01995 
01996             prevIrqFlags.word = irqFlags.word;
01997 
01998             if (irqFlags.bits.RangingMasterResultValid) {
01999                 float m;
02000                 unsigned rngResult, rngRssi;
02001                 radio.chipMode = CHIPMODE_NONE;
02002                 chipModeChange();
02003                 rngResult = radio.readReg(REG_ADDR_RNGRESULT, 3);
02004                 // Distance [m] = RangingResult*150/(2^12*BwMHz)
02005                 m = rngResult * 150 / (4096*bwMHzs[LoRaPktPar0.bits.modem_bw]);
02006                 rngRssi = radio.readReg(REG_ADDR_RNGRSSI, 1);
02007                 log_printf("%u rngResult %.2fm, RngRssi:%u bw%.1f\r\n", rngResult, m, rngRssi, bwMHzs[LoRaPktPar0.bits.modem_bw]);
02008                 clearIrqFlags.bits.RangingMasterResultValid = 1;
02009             }
02010 
02011             if (irqFlags.bits.RangingSlaveResponseDone)
02012                 log_printf("RangingSlaveResponseDone\r\n");
02013             if (irqFlags.bits.RangingSlaveRequestDiscard)
02014                 log_printf("RangingSlaveRequestDiscard\r\n");
02015             if (irqFlags.bits.RangingMasterRequestValid)
02016                 log_printf("RangingMasterRequestValid\r\n");
02017 
02018             if (clearIrqFlags.word != 0) {
02019                 buf[0] = clearIrqFlags.word >> 8;
02020                 buf[1] = (uint8_t)clearIrqFlags.word;
02021                 radio.xfer(OPCODE_CLEAR_IRQ_STATUS, 2, 0, buf);
02022             }
02023         } // ..if change
02024 
02025         prev_now_ms = now_ms;
02026     }
02027 
02028     return ret;
02029 }
02030 
02031 void Radio::Rx()
02032 {
02033     if (pktType == PACKET_TYPE_RANGING) {
02034         IrqFlags_t irqEnable;
02035         uint8_t buf[8];
02036 
02037         if (!manualRngDelay)
02038             rngUpdateDelayCal();
02039 
02040         irqEnable.word = 0;
02041         irqEnable.bits.RxDone = 1;
02042         irqEnable.bits.RxTxTimeout = 1;
02043         irqEnable.bits.RangingSlaveResponseDone = 1;
02044         irqEnable.bits.RangingSlaveRequestDiscard = 1;
02045         irqEnable.bits.RangingMasterRequestValid = 1;
02046 
02047         buf[0] = irqEnable.word >> 8;    // enable bits
02048         buf[1] = irqEnable.word; // enable bits
02049 
02050         irqEnable.bits.RangingSlaveResponseDone = 0;
02051         irqEnable.bits.RangingSlaveRequestDiscard = 0;
02052         irqEnable.bits.RangingMasterRequestValid = 0;
02053         buf[2] = irqEnable.word >> 8;     // dio1
02054         buf[3] = irqEnable.word;  // dio1
02055 
02056         buf[4] = 0; // dio2
02057         buf[5] = 0; // dio2
02058         buf[6] = 0; // dio3
02059         buf[7] = 0; // dio3
02060         radio.xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf);
02061 
02062         buf[0] = radio.periodBase;
02063         /* receive packets forever */
02064         buf[1] = 0xff;
02065         buf[2] = 0xff;
02066         radio.xfer(OPCODE_SET_RX, 3, 0, buf);
02067 
02068         radio.chipMode = CHIPMODE_RX;
02069         chipModeChange();
02070     } else
02071         radio.start_rx(0);
02072 }
02073 
02074 void Radio::setFS()
02075 {
02076     radio.setFS();
02077 }
02078 
02079 void Radio::test()
02080 {
02081 /*
02082     RngCfg0_t RngCfg0;
02083     RngCfg0.octet = radio.readReg(REG_ADDR_RNGCFG0, 1);
02084 
02085     log_printf("Rngcfg0 %02x\r\n", RngCfg0.octet);*/
02086     unsigned a;
02087     log_printf("%02x ", radio.readReg(0x910, 1));
02088     for (a = 0x911; a < 0x980; a++) {
02089         printf("%02x ", radio.readReg(a, 1));
02090         if ((a & 0x1f) == 0x1f)
02091             printf("\r\n%03x ", a+1);
02092     }
02093     printf("\r\n");
02094 }
02095 
02096 unsigned Radio::read_register(unsigned addr)
02097 {
02098     return radio.readReg(addr, 1);
02099 }
02100 
02101 void Radio::write_register(unsigned addr, unsigned val)
02102 {
02103     radio.writeReg(addr, val, 1);
02104 }
02105 
02106 #endif /* ..SX126x_H */