SCPI interface to SX1272 and SX1276

Dependencies:   SX127x lib_gps lib_mma8451q lib_mpl3115a2 lib_sx9500 libscpi mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers scpi-def.cpp Source File

scpi-def.cpp

00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include "scpi/scpi.h"
00005 #include "scpi-def.h"
00006 
00007 //#include "sx12xx.h"
00008 #include "sx127x_lora.h"
00009 #include "sx127x_fsk.h"
00010 
00011 /******************************************************************************/
00012 #ifdef TARGET_MOTE_L152RC
00013 #include "gps.h"
00014 #include "mma8451q.h"
00015 #include "mpl3115a2.h"
00016 #include "sx9500.h"
00017 
00018 #define RFSW1                    PC_4 //NorAm_Mote RFSwitch_CNTR_1
00019 #define RFSW2                    PC_13 //NorAm_Mote RFSwitch_CNTR_2
00020 #define RADIO_RESET              PC_2 //NorAm_Mote Reset_sx
00021 #define RADIO_MOSI               PB_15 //NorAm_Mote SPI2 Mosi
00022 #define RADIO_MISO               PB_14 //NorAm_Mote SPI2 Miso
00023 #define RADIO_SCLK               PB_13 //NorAm_Mote  SPI2 Clk
00024 #define RADIO_NSS                PB_12 //NorAm_Mote SPI2 Nss
00025 #define RADIO_DIO_0              PC_6 //NorAm_Mote DIO0 
00026 #define RADIO_DIO_1              PC_10 //NorAm_Mote DIO1
00027 #define RADIO_DIO_2              PC_8 //NorAm_Mote DIO2 
00028 #define RADIO_DIO_3              PB_4 //NorAm_Mote DIO3 
00029 #define RADIO_DIO_4              PB_5 //NorAm_Mote DIO4 
00030 #define RADIO_DIO_5              PB_6 //NorAm_Mote DIO5
00031 
00032 SPI spi(RADIO_MOSI, RADIO_MISO, RADIO_SCLK);
00033 //             dio0, dio1, nss, spi, rst
00034 SX127x radio(RADIO_DIO_0, RADIO_DIO_1, RADIO_NSS, spi, RADIO_RESET);
00035 
00036 DigitalOut rfsw1(RFSW1);
00037 DigitalOut rfsw2(RFSW2);
00038 
00039 void rfsw_callback()
00040 {
00041     if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER) {  // start of transmission
00042         //if (radio.HF)
00043         if (radio.RegPaConfig.bits.PaSelect) { // if PA_BOOST
00044             rfsw2 = 0;
00045             rfsw1 = 1;
00046         } else { // RFO to power amp
00047             rfsw2 = 1;
00048             rfsw1 = 0;            
00049         }
00050         //hdr_fem_csd = 1;    //debug
00051     } else if (radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER || radio.RegOpMode.bits.Mode == RF_OPMODE_CAD) { // start of reception
00052         //if (radio.HF)
00053         rfsw2 = 1;
00054         rfsw1 = 1;
00055         //hdr_fem_csd = 0;    //debug
00056     } else { // RF switch shutdown
00057         rfsw2 = 0;
00058         rfsw1 = 0;     
00059         //hdr_fem_csd = 0;    //debug         
00060     }
00061 }
00062 
00063 DigitalOut pd2(PD_2);
00064 
00065 DigitalIn dio2_pin(RADIO_DIO_2);
00066 DigitalIn dio3_pin(RADIO_DIO_3);
00067 DigitalIn dio4_pin(RADIO_DIO_4);
00068 DigitalIn dio5_pin(RADIO_DIO_5);
00069 
00070 AnalogIn *bat;
00071 #define AIN_VREF        3.3     // stm32 internal refernce
00072 #define AIN_VBAT_DIV    2       // resistor divider
00073 
00074 /*  gps(tx, rx, en); */
00075 DigitalOut gps_en(PB_11);
00076 GPS gps(PB_6, PB_7, PB_11);
00077 uint32_t gps_coord_cnt;
00078 
00079 DigitalIn i2c_int_pin(PB_4);
00080 I2C i2c(I2C_SDA, I2C_SCL);
00081 MMA8451Q mma8451q(i2c, i2c_int_pin);
00082 MPL3115A2 mpl3115a2(i2c, i2c_int_pin);
00083 SX9500 sx9500(i2c, PA_9, PA_10);
00084 
00085 typedef enum {
00086     MOTE_NONE = 0,
00087     MOTE_V2,
00088     MOTE_V3
00089 } mote_version_e;
00090 mote_version_e mote_version = MOTE_NONE;
00091 
00092 DigitalOut pc_7(PC_7);
00093 DigitalIn pc_1(PC_1);
00094 #else // sx1276 shield...
00095 
00096 SPI spi(D11, D12, D13); // mosi, miso, sclk
00097 //           dio0, dio1, nss, spi, rst
00098 SX127x radio(  D2,   D3, D10, spi, A0); // sx1276 arduino shield
00099 
00100 #ifdef TARGET_LPC11U6X
00101 DigitalOut rfsw(P0_23);
00102 #else
00103 DigitalOut rfsw(A4);    // for SX1276 arduino shield
00104 #endif
00105 
00106 void rfsw_callback()
00107 {
00108     if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER)
00109         rfsw = 1;
00110     else
00111         rfsw = 0;
00112 }
00113 
00114 DigitalIn dio2_pin(D4);
00115 DigitalIn dio3_pin(D5);
00116 DigitalIn dio4_pin(A3);
00117 DigitalIn dio5_pin(D9);
00118 
00119 #endif /* !TARGET_MOTE_L152RC */
00120 
00121 SX127x_fsk fsk(radio);
00122 SX127x_lora lora(radio);
00123 
00124 volatile bool tx_busy = false;
00125 
00126 bool is_lora()
00127 {
00128     radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
00129     return radio.RegOpMode.bits.LongRangeMode;
00130 }
00131 
00132 void
00133 service_radio()
00134 {
00135     service_action_e act;
00136     
00137     if (radio.RegOpMode.bits.LongRangeMode) {
00138         act = lora.service();
00139         switch (act) {
00140             case SERVICE_READ_FIFO:
00141                 //printf("lora SERVICE_READ_FIFO\r\n");
00142                 SCPI_RegSetBits(&scpi_context, SCPI_REG_QUES, 0x200);    // bit 9 for packet received
00143                 break;
00144             case SERVICE_TX_DONE:
00145                 tx_busy = false;
00146                 break;
00147             case SERVICE_ERROR:
00148             case SERVICE_NONE:
00149                 break;
00150         } // ...switch (act)
00151     } else {
00152         /* FSK: */
00153         act = fsk.service();     
00154         switch (act) {
00155             case SERVICE_READ_FIFO:
00156                 SCPI_RegSetBits(&scpi_context, SCPI_REG_QUES, 0x200);    // bit 9 for packet received
00157                 break;            
00158             case SERVICE_TX_DONE:
00159                 tx_busy = false;
00160                 break;
00161             case SERVICE_ERROR:
00162             case SERVICE_NONE:
00163                 break;
00164         } // ...switch (act)           
00165     }
00166     
00167 #ifdef TARGET_MOTE_L152RC
00168     gps.service();
00169     if (gps.LatitudeBinary != 0) {
00170         gps.LatitudeBinary = 0;
00171         //printf("gps long:%f, lat:%f  Vbat:%.2fV\r\n", gps.Longitude, gps.Latitude, ain_bat->read()*AIN_VREF*AIN_VBAT_DIV);
00172         gps_coord_cnt++;
00173     }    
00174 #endif /* TARGET_MOTE_L152RC */
00175 }
00176 
00177 scpi_result_t tx_busyQ(scpi_t * context)
00178 {
00179     SCPI_ResultBool(context, tx_busy);
00180     return SCPI_RES_OK;
00181 }
00182 
00183 scpi_result_t SCPI_Reset(scpi_t * context)
00184 {
00185     radio.hw_reset();
00186     printf("**Reset\r\n");
00187     tx_busy = false;
00188     return SCPI_RES_OK;
00189 }
00190 
00191 const scpi_choice_def_t pa_selects[] = {
00192     { "RFO", 0 },
00193     { "PA_BOOST", 1 },       
00194     SCPI_CHOICE_LIST_END
00195 };
00196 
00197 scpi_result_t radio_PASelect(scpi_t* context)
00198 {
00199     int32_t value;
00200     
00201     if (!SCPI_ParamChoice(context, pa_selects, &value, TRUE))
00202         return SCPI_RES_ERR;  
00203         
00204     radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
00205     radio.RegPaConfig.bits.PaSelect = value;
00206     radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);
00207     
00208     if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER)
00209         rfsw_callback();    
00210     
00211     return SCPI_RES_OK;
00212 }
00213     
00214 scpi_result_t radio_PASelectQ(scpi_t* context)
00215 {
00216     int idx;
00217     
00218     radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
00219     idx = radio.RegPaConfig.bits.PaSelect;
00220         
00221     SCPI_ResultText(context, pa_selects[idx].name);
00222     return SCPI_RES_OK;    
00223 }
00224 
00225 const scpi_choice_def_t modulations[] = {
00226     { "FSK", 1 },
00227     { "OOK", 2 },
00228     { "LORa", 3 },        
00229     SCPI_CHOICE_LIST_END
00230 };
00231 
00232 scpi_result_t radio_modulation(scpi_t* context)
00233 {
00234     int32_t value;
00235     
00236     /* scpi_bool_t SCPI_ParamChoice(scpi_t * context, const scpi_choice_def_t * options, int32_t * value, scpi_bool_t mandatory); */
00237     if (!SCPI_ParamChoice(context, modulations, &value, TRUE))
00238         return SCPI_RES_ERR;
00239 
00240     radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
00241     if (value == 3) {
00242         if (!radio.RegOpMode.bits.LongRangeMode)
00243             lora.enable();
00244     } else {
00245         if (radio.RegOpMode.bits.LongRangeMode)
00246             fsk.enable(false);
00247         if (radio.RegOpMode.bits.ModulationType) { // radio is OOK
00248             if (value == 1) {   // change to FSK
00249                 radio.RegOpMode.bits.ModulationType = 0;
00250                 radio.write_reg(REG_OPMODE, radio.RegOpMode.octet);
00251             }
00252         } else { // radio is FSK
00253             if (value == 2) {   // change to OOK
00254                 radio.RegOpMode.bits.ModulationType = 1;
00255                 radio.write_reg(REG_OPMODE, radio.RegOpMode.octet);
00256             }
00257         }
00258     }
00259  
00260    return SCPI_RES_OK;
00261 }
00262 
00263 scpi_result_t radio_modulationQ(scpi_t* context)
00264 {
00265     int idx;
00266     
00267     if (is_lora()) {
00268         idx = 2;    // lora
00269     } else {
00270         if (radio.RegOpMode.bits.ModulationType)
00271             idx = 1;    // ook
00272         else
00273             idx = 0;    // fsk
00274     }
00275     
00276     SCPI_ResultText(context, modulations[idx].name);
00277     return SCPI_RES_OK;
00278 }
00279 
00280 scpi_result_t fsk_fdev(scpi_t* context)
00281 {
00282     int32_t i;
00283     
00284     if (!SCPI_ParamInt(context, &i, TRUE))
00285         return SCPI_RES_ERR;
00286             
00287     if (is_lora())
00288         return SCPI_RES_ERR;
00289         
00290     fsk.set_tx_fdev_hz(i);
00291     return SCPI_RES_OK;
00292 }
00293 
00294 scpi_result_t fsk_fdevQ(scpi_t* context)
00295 {
00296     if (is_lora())
00297         return SCPI_RES_ERR;
00298         
00299     SCPI_ResultInt(context, fsk.get_tx_fdev_hz());    
00300     return SCPI_RES_OK;      
00301 }
00302 
00303 const scpi_choice_def_t rxtrigs[] = {
00304     { "OFF", 0 },
00305     { "RSSI", 1 },
00306     { "PRE", 6 },        
00307     { "BOTH", 7 },          
00308     SCPI_CHOICE_LIST_END
00309 };
00310 
00311 scpi_result_t fsk_rxtrig(scpi_t* context)
00312 {
00313     int32_t value;
00314     
00315     if (is_lora())
00316         return SCPI_RES_ERR;
00317         
00318     if (!SCPI_ParamChoice(context, rxtrigs, &value, TRUE))
00319         return SCPI_RES_ERR;           
00320         
00321     fsk.RegRxConfig.octet = radio.read_reg(REG_FSK_RXCONFIG);       
00322     fsk.RegRxConfig.bits.RxTrigger = value;
00323     radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet);
00324     return SCPI_RES_OK;
00325 }
00326 
00327 scpi_result_t fsk_rxtrigQ(scpi_t* context)
00328 {
00329     int idx;
00330     
00331     if (is_lora())
00332         return SCPI_RES_ERR;    
00333         
00334     fsk.RegRxConfig.octet = radio.read_reg(REG_FSK_RXCONFIG);
00335     idx = fsk.RegRxConfig.bits.RxTrigger;
00336     SCPI_ResultText(context, rxtrigs[idx].name);
00337     return SCPI_RES_OK;             
00338 }
00339 
00340 scpi_result_t fsk_bt(scpi_t* context)
00341 {
00342     double bt;    
00343     
00344     if (is_lora())
00345         return SCPI_RES_ERR;        
00346     
00347     if (!SCPI_ParamDouble(context, &bt, TRUE))
00348         return SCPI_RES_ERR; 
00349                 
00350     if (bt < 0.2)                
00351         radio.RegOpMode.bits.ModulationShaping = 0; // no shaping
00352     else if (bt < 0.4)
00353         radio.RegOpMode.bits.ModulationShaping = 3; // BT0.3  (most shaping)
00354     else if (bt < 0.9)
00355         radio.RegOpMode.bits.ModulationShaping = 2; // BT0.5
00356     else
00357         radio.RegOpMode.bits.ModulationShaping = 1; // BT1.0
00358         
00359     radio.write_reg(REG_OPMODE, radio.RegOpMode.octet);       
00360     return SCPI_RES_OK;    
00361 }
00362 
00363 scpi_result_t fsk_btQ(scpi_t* context)
00364 {
00365     double bt;
00366     
00367     if (is_lora())
00368         return SCPI_RES_ERR;        
00369         
00370     switch (radio.RegOpMode.bits.ModulationShaping) {
00371         case 0: bt = 0.0; break;
00372         case 1: bt = 1.0; break;
00373         case 2: bt = 0.5; break;
00374         case 3: bt = 0.3; break;
00375     }
00376     
00377     SCPI_ResultDouble(context, bt);
00378     return SCPI_RES_OK;    
00379 }
00380 
00381 const scpi_choice_def_t datamodes[] = {
00382     { "CONT", 0 },
00383     { "PKT", 1 },       
00384     SCPI_CHOICE_LIST_END
00385 };
00386 
00387 scpi_result_t fsk_datamode(scpi_t* context)
00388 {
00389     int32_t value;
00390     
00391     if (!SCPI_ParamChoice(context, datamodes, &value, TRUE))
00392         return SCPI_RES_ERR;
00393             
00394     if (is_lora())
00395         return SCPI_RES_ERR;  
00396         
00397     fsk.RegPktConfig2.word = radio.read_u16(REG_FSK_PACKETCONFIG2);
00398     fsk.RegPktConfig2.bits.DataModePacket = value;
00399     radio.write_u16(REG_FSK_PACKETCONFIG2, fsk.RegPktConfig2.word);
00400     return SCPI_RES_OK;
00401 }
00402 
00403 scpi_result_t fsk_datamodeQ(scpi_t* context)
00404 {
00405     int idx;
00406     
00407     if (is_lora())
00408         return SCPI_RES_ERR;       
00409     
00410     fsk.RegPktConfig2.word = radio.read_u16(REG_FSK_PACKETCONFIG2);
00411     idx = fsk.RegPktConfig2.bits.DataModePacket;    
00412     SCPI_ResultText(context, datamodes[idx].name);
00413     return SCPI_RES_OK;
00414 }
00415   
00416 const scpi_choice_def_t dcfrees[] = {
00417     { "OFF", 0 },
00418     { "MAN", 1 },
00419     { "WHIT", 2 },        
00420     SCPI_CHOICE_LIST_END
00421 };
00422 
00423 scpi_result_t fsk_dcfree(scpi_t* context)
00424 {
00425     int32_t value;
00426         
00427     if (is_lora())
00428         return SCPI_RES_ERR;    
00429    
00430     if (!SCPI_ParamChoice(context, dcfrees, &value, TRUE))
00431         return SCPI_RES_ERR;        
00432         
00433     fsk.RegPktConfig1.octet = radio.read_reg(REG_FSK_PACKETCONFIG1);        
00434     fsk.RegPktConfig1.bits.DcFree = value;
00435     radio.write_reg(REG_FSK_PACKETCONFIG1, fsk.RegPktConfig1.octet);
00436     return SCPI_RES_OK;    
00437 }
00438 
00439 scpi_result_t fsk_dcfreeQ(scpi_t* context)
00440 {
00441     int idx;
00442     
00443     if (is_lora())
00444         return SCPI_RES_ERR;
00445         
00446     fsk.RegPktConfig1.octet = radio.read_reg(REG_FSK_PACKETCONFIG1);        
00447     idx = fsk.RegPktConfig1.bits.DcFree ;
00448     SCPI_ResultText(context, dcfrees[idx].name);
00449     return SCPI_RES_OK;
00450 }
00451 
00452 scpi_result_t fsk_rxbw(scpi_t* context)
00453 {
00454     int32_t i;
00455     
00456     if (!SCPI_ParamInt(context, &i, TRUE))
00457         return SCPI_RES_ERR; 
00458         
00459     if (is_lora())
00460         return SCPI_RES_ERR;
00461         
00462     fsk.set_rx_dcc_bw_hz(i, 0);
00463     return SCPI_RES_OK;
00464 }
00465 
00466 scpi_result_t fsk_rxbwQ(scpi_t* context)
00467 {
00468     if (is_lora())
00469         return SCPI_RES_ERR;    
00470         
00471     SCPI_ResultInt(context, fsk.get_rx_bw_hz(REG_FSK_RXBW));    
00472     return SCPI_RES_OK;          
00473 }
00474 
00475 scpi_result_t fsk_afcbw(scpi_t* context)
00476 {
00477     int32_t i;
00478     
00479     if (!SCPI_ParamInt(context, &i, TRUE))
00480         return SCPI_RES_ERR; 
00481         
00482     if (is_lora())        
00483         return SCPI_RES_ERR;
00484         
00485     fsk.set_rx_dcc_bw_hz(i, 1);
00486     return SCPI_RES_OK;
00487 }
00488 
00489 scpi_result_t fsk_afcbwQ(scpi_t* context)
00490 {
00491     if (is_lora())    
00492         return SCPI_RES_ERR;    
00493         
00494     SCPI_ResultInt(context, fsk.get_rx_bw_hz(REG_FSK_AFCBW));    
00495     return SCPI_RES_OK;          
00496 } 
00497 
00498 scpi_result_t fsk_bitrate(scpi_t* context)
00499 {
00500     int32_t i;
00501     
00502     if (!SCPI_ParamInt(context, &i, TRUE))
00503         return SCPI_RES_ERR;
00504             
00505     if (is_lora())            
00506         return SCPI_RES_ERR;    
00507         
00508     fsk.set_bitrate(i);
00509     return SCPI_RES_OK;     
00510 }
00511 
00512 scpi_result_t fsk_bitrateQ(scpi_t* context)
00513 {
00514     if (is_lora())    
00515         return SCPI_RES_ERR;    
00516     
00517     SCPI_ResultInt(context, fsk.get_bitrate());    
00518     return SCPI_RES_OK;    
00519 }
00520 
00521 scpi_result_t fsk_prelen(scpi_t* context)
00522 {
00523     int32_t i;
00524     
00525     if (!SCPI_ParamInt(context, &i, TRUE))
00526         return SCPI_RES_ERR;
00527         
00528     if (is_lora())        
00529         return SCPI_RES_ERR;     
00530         
00531     radio.write_u16(REG_FSK_PREAMBLEMSB, i); 
00532     return SCPI_RES_OK;          
00533 }
00534 
00535 scpi_result_t fsk_prelenQ(scpi_t* context)
00536 {
00537     if (is_lora())    
00538         return SCPI_RES_ERR;     
00539         
00540     SCPI_ResultInt(context, radio.read_u16(REG_FSK_PREAMBLEMSB) );    
00541     return SCPI_RES_OK;      
00542 } 
00543 
00544 scpi_result_t fsk_sync(scpi_t* context)
00545 {
00546     char buffer[100];
00547     size_t _copy_len, _len, i;
00548     uint8_t addr;
00549     uint8_t sync_size;
00550         
00551     if (is_lora())        
00552         return SCPI_RES_ERR;
00553         
00554     memset(buffer, 0, sizeof(buffer));    
00555     SCPI_ParamCopyText(context, buffer, 100, &_copy_len, false);
00556     for (_len = 0; buffer[_len] != 0; _len++)
00557         ;  
00558    
00559     fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
00560     sync_size = 0;
00561     addr = REG_FSK_SYNCVALUE1;
00562     for (i = 0; i < _len; i+=2) {
00563         int o;
00564         sscanf(buffer+i, "%02x", &o);
00565         radio.write_reg(addr++, o);
00566         sync_size++;
00567     }    
00568     if (sync_size > 0)
00569         fsk.RegSyncConfig.bits.SyncSize = sync_size - 1;
00570         
00571     radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet);
00572     
00573     return SCPI_RES_OK;
00574 }
00575 
00576 scpi_result_t fsk_syncQ(scpi_t* context)
00577 {
00578     int i;
00579     char txt[64];
00580     char *ptr = txt;
00581     
00582     if (is_lora())    
00583         return SCPI_RES_ERR;
00584         
00585     fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
00586     for (i = 0; i <= fsk.RegSyncConfig.bits.SyncSize; i++) {
00587         uint8_t o = radio.read_reg(i + REG_FSK_SYNCVALUE1);
00588         sprintf(ptr, "%02x", o);
00589         ptr += 2;
00590     }
00591     
00592     SCPI_ResultText(context, txt);
00593     return SCPI_RES_OK;
00594 }
00595 
00596 scpi_result_t radio_rssiQ(scpi_t* context)
00597 {
00598     int reg_val;
00599     
00600     radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
00601     if (radio.RegOpMode.bits.Mode != RF_OPMODE_RECEIVER)
00602         return SCPI_RES_ERR;
00603 
00604     if (is_lora()) {
00605         reg_val = radio.read_reg(REG_LR_RSSIVALUE);    // 0x1b: dbm = -125 + regvalue
00606         SCPI_ResultDouble(context, -125 + reg_val);
00607     } else {
00608         reg_val = radio.read_reg(REG_FSK_RSSIVALUE);   // 0x11: dBm = -regvalue/2
00609         SCPI_ResultDouble(context, -reg_val/2.0);
00610     }
00611     
00612     return SCPI_RES_OK;
00613 }
00614 
00615 scpi_result_t radio_binFifo(scpi_t* context)
00616 {
00617     size_t len;
00618     const char* buf = (const char *)radio.tx_buf;
00619              
00620      /*scpi_bool_t SCPI_ParamArbitraryBlock(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory);*/
00621      if (!SCPI_ParamArbitraryBlock(context, &buf, &len, TRUE))
00622         return SCPI_RES_ERR; 
00623 
00624     radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG); // pull PaSelect
00625     if (is_lora()) {
00626         lora.RegPayloadLength = len;
00627         radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
00628         lora.start_tx(lora.RegPayloadLength);        
00629     } else {
00630         fsk.start_tx(len);
00631     }    
00632     
00633     tx_busy = true;
00634     
00635     return SCPI_RES_OK;            
00636 }
00637 
00638 scpi_result_t radio_binFifoQ(scpi_t* context)
00639 {
00640     size_t len;
00641     const char* buf = (const char *)radio.rx_buf;
00642 
00643     if (is_lora()) {
00644         len = lora.RegRxNbBytes;  
00645     } else {
00646         len = fsk.rx_buf_length;
00647     }
00648     
00649     //size_t SCPI_ResultArbitraryBlock(scpi_t * context, const char * data, size_t len);
00650     if (SCPI_ResultArbitraryBlock(context, buf, len) == len)
00651         return SCPI_RES_OK;    
00652     else
00653         return SCPI_RES_ERR; 
00654 }
00655 
00656 scpi_result_t radio_fifoQ(scpi_t* context)
00657 {
00658     int i;
00659     char txt[520];
00660     char *ptr = txt;
00661         
00662     if (is_lora()) {
00663         for (i = 0; i < lora.RegRxNbBytes; i++) {
00664             sprintf(ptr, "%02x", radio.rx_buf[i]);
00665             ptr += 2;
00666         }        
00667     } else {
00668         for (i = 0; i < fsk.rx_buf_length; i++) {
00669             sprintf(ptr, "%02x", radio.rx_buf[i]);
00670             ptr += 2;
00671         }   
00672     }
00673     
00674     SCPI_ResultText(context, txt);
00675     return SCPI_RES_OK;
00676 }
00677 
00678 scpi_result_t radio_fifo(scpi_t* context)
00679 {
00680     char buffer[100];
00681     size_t copy_len, i, len;
00682     
00683     if (tx_busy)
00684         return SCPI_RES_ERR;
00685                 
00686     memset(buffer, 0, sizeof(buffer));
00687     SCPI_ParamCopyText(context, buffer, 100, &copy_len, false);
00688 
00689     for (len = 0; buffer[len] != 0; len++)
00690         ;
00691 
00692     for (i = 0; i < len; i++)
00693         radio.tx_buf[i] = buffer[i];
00694     
00695     radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);    
00696     if (is_lora()) {
00697         lora.RegPayloadLength = len;
00698         radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
00699         lora.start_tx(lora.RegPayloadLength);        
00700     } else {
00701         /* fsk todo */
00702         fsk.start_tx(len);
00703     }    
00704     
00705     tx_busy = true;
00706     
00707     return SCPI_RES_OK;    
00708 }
00709 
00710 const scpi_choice_def_t opmodes[] = {
00711     { "SLE", 0 },
00712     { "STB", 1 },
00713     { "FST", 2 },        
00714     { "TX", 3 },
00715     { "FSR", 4 },
00716     { "RXC", 5 },       
00717     { "RXS", 6 },         
00718     { "CAD", 7 },         
00719     SCPI_CHOICE_LIST_END
00720 };
00721 
00722 scpi_result_t radio_opmode(scpi_t* context)
00723 {
00724     int32_t value;
00725     
00726     if (!SCPI_ParamChoice(context, opmodes, &value, TRUE))
00727         return SCPI_RES_ERR;    
00728  
00729     if (value == RF_OPMODE_TRANSMITTER)
00730         radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);     // pull PaSelect
00731     else
00732         tx_busy = false;        
00733                
00734     radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);   
00735     radio.set_opmode((chip_mode_e)value);
00736 
00737     return SCPI_RES_OK;        
00738 }
00739 
00740 scpi_result_t radio_opmodeQ(scpi_t* context)
00741 {
00742     int idx;
00743     
00744     radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
00745     idx = radio.RegOpMode.bits.Mode;
00746     SCPI_ResultText(context, opmodes[idx].name);
00747     
00748     return SCPI_RES_OK;
00749 }
00750 
00751 
00752 /*scpi_result_t wbr_set_bit9(scpi_t* context)
00753 {
00754     SCPI_RegSetBits(context, SCPI_REG_QUES, 0x200);
00755     printf("set bit9\r\n");
00756     return SCPI_RES_OK;
00757 }*/
00758 scpi_result_t radio_ocp(scpi_t* context)
00759 {
00760     int32_t i;
00761     
00762     if (!SCPI_ParamInt(context, &i, TRUE))
00763         return SCPI_RES_ERR;     
00764         
00765     radio.RegOcp.octet = radio.read_reg(REG_OCP);
00766     if (i < 130)
00767         radio.RegOcp.bits.OcpTrim = (i - 45) / 5;
00768     else
00769         radio.RegOcp.bits.OcpTrim = (i + 30) / 10;
00770     radio.write_reg(REG_OCP, radio.RegOcp.octet);   
00771     return SCPI_RES_OK; 
00772 }
00773 
00774 scpi_result_t radio_ocpQ(scpi_t* context)
00775 {
00776     int32_t i;
00777     
00778     radio.RegOcp.octet = radio.read_reg(REG_OCP);
00779     
00780     if (radio.RegOcp.bits.OcpTrim < 16)
00781         i = 45 + (5 * radio.RegOcp.bits.OcpTrim);
00782     else if (radio.RegOcp.bits.OcpTrim < 28)
00783         i = (10 * radio.RegOcp.bits.OcpTrim) - 30;
00784     else
00785         i = 240;    
00786         
00787     SCPI_ResultInt(context, i);    
00788     return SCPI_RES_OK;         
00789 }
00790 
00791 scpi_result_t radio_bgr(scpi_t* context)
00792 {
00793     RegPdsTrim1_t pds_trim;
00794     int32_t i;
00795     
00796     if (!SCPI_ParamInt(context, &i, TRUE))
00797         return SCPI_RES_ERR;  
00798             
00799     if (radio.type == SX1276) {
00800         pds_trim.octet = radio.read_reg(REG_PDSTRIM1_SX1276);
00801         pds_trim.bits.prog_txdac = i;
00802         radio.write_reg(REG_PDSTRIM1_SX1276, pds_trim.octet);
00803     } else if (radio.type == SX1272) { 
00804         pds_trim.octet = radio.read_reg(REG_PDSTRIM1_SX1272);       
00805         pds_trim.bits.prog_txdac = i;
00806         radio.write_reg(REG_PDSTRIM1_SX1272, pds_trim.octet);
00807     } else
00808         return SCPI_RES_ERR; 
00809     
00810     return SCPI_RES_OK;
00811 }
00812 
00813 scpi_result_t radio_bgrQ(scpi_t* context)
00814 {
00815     RegPdsTrim1_t pds_trim;
00816       
00817     if (radio.type == SX1276)
00818         pds_trim.octet = radio.read_reg(REG_PDSTRIM1_SX1276);    
00819     else if (radio.type == SX1272)
00820         pds_trim.octet = radio.read_reg(REG_PDSTRIM1_SX1272);
00821     else
00822         return SCPI_RES_ERR;
00823         
00824     SCPI_ResultInt(context, pds_trim.bits.prog_txdac);  
00825     return SCPI_RES_OK;        
00826 }
00827 
00828 scpi_result_t radio_lnaBoost(scpi_t* context)
00829 {
00830     scpi_bool_t param1;
00831     
00832     if (!SCPI_ParamBool(context, &param1, TRUE))
00833         return SCPI_RES_ERR;
00834             
00835     radio.RegLna.octet = radio.read_reg(REG_LNA);  
00836     if (param1)
00837         radio.RegLna.bits.LnaBoostHF = 3;
00838     else
00839         radio.RegLna.bits.LnaBoostHF = 0;
00840         
00841     radio.write_reg(REG_LNA, radio.RegLna.octet);
00842     return SCPI_RES_OK;
00843 }
00844 
00845 scpi_result_t radio_lnaBoostQ(scpi_t* context)
00846 {
00847     radio.RegLna.octet = radio.read_reg(REG_LNA);
00848     if (radio.RegLna.bits.LnaBoostHF)
00849         SCPI_ResultBool(context, 1);
00850     else
00851         SCPI_ResultBool(context, 0);
00852     
00853     return SCPI_RES_OK;     
00854 }
00855 
00856 scpi_result_t radio_power(scpi_t* context)
00857 {
00858     int32_t i;
00859     
00860     if (!SCPI_ParamInt(context, &i, TRUE))
00861         return SCPI_RES_ERR;  
00862             
00863     radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
00864     radio.RegPaConfig.bits.OutputPower = i;
00865     radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);
00866 
00867     return SCPI_RES_OK;    
00868 }
00869 
00870 scpi_result_t radio_powerQ(scpi_t* context)
00871 {
00872     radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
00873     SCPI_ResultInt(context, radio.RegPaConfig.bits.OutputPower);  
00874     return SCPI_RES_OK;
00875 }
00876 
00877 scpi_result_t radio_diomap(scpi_t* context)
00878 {
00879     int32_t dioN, map_value;
00880     
00881     if (!SCPI_ParamInt(context, &dioN, TRUE))
00882         return SCPI_RES_ERR;  
00883         
00884     if (!SCPI_ParamInt(context, &map_value, TRUE))
00885         return SCPI_RES_ERR;    
00886       
00887     if (dioN < 4) {
00888         radio.RegDioMapping1.octet = radio.read_reg(REG_DIOMAPPING1);
00889         switch (dioN) {
00890             case 0: radio.RegDioMapping1.bits.Dio0Mapping = map_value; break;
00891             case 1: radio.RegDioMapping1.bits.Dio1Mapping = map_value; break;
00892             case 2: radio.RegDioMapping1.bits.Dio2Mapping = map_value; break;
00893             case 3: radio.RegDioMapping1.bits.Dio3Mapping = map_value; break;
00894         } // ...switch (dioN)
00895         radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
00896     } else {
00897         radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
00898         switch (dioN) {
00899             case 4: radio.RegDioMapping2.bits.Dio4Mapping = map_value; break;
00900             case 5: radio.RegDioMapping2.bits.Dio5Mapping = map_value; break;
00901         } // ...switch (dioN)        
00902         radio.write_reg(REG_DIOMAPPING2, radio.RegDioMapping2.octet);
00903     }
00904     
00905     return SCPI_RES_OK;
00906 }
00907 
00908 scpi_result_t radio_diomapQ(scpi_t* context)
00909 {
00910     int32_t dioN, map_value = -1;
00911     
00912     if (!SCPI_ParamInt(context, &dioN, TRUE))
00913         return SCPI_RES_ERR; 
00914         
00915     if (dioN < 4) {
00916         radio.RegDioMapping1.octet = radio.read_reg(REG_DIOMAPPING1);
00917         switch (dioN) {
00918             case 0: map_value = radio.RegDioMapping1.bits.Dio0Mapping; break;
00919             case 1: map_value = radio.RegDioMapping1.bits.Dio1Mapping; break;
00920             case 2: map_value = radio.RegDioMapping1.bits.Dio2Mapping; break;
00921             case 3: map_value = radio.RegDioMapping1.bits.Dio3Mapping; break;
00922         } // ...switch (dioN)        
00923     } else {
00924         radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
00925         switch (dioN) {
00926             case 4: map_value = radio.RegDioMapping2.bits.Dio4Mapping; break;
00927             case 5: map_value = radio.RegDioMapping2.bits.Dio5Mapping; break;
00928         } // ...switch (dioN)          
00929     }
00930     
00931     SCPI_ResultInt(context, map_value);
00932     return SCPI_RES_OK;    
00933 }
00934 
00935 scpi_result_t radio_reg(scpi_t* context)
00936 {
00937     int32_t addr, data;
00938 
00939     if (!SCPI_ParamInt(context, &addr, TRUE))
00940         return SCPI_RES_ERR;  
00941         
00942     if (!SCPI_ParamInt(context, &data, TRUE))
00943         return SCPI_RES_ERR;  
00944 
00945     radio.write_reg(addr, data);
00946         
00947     return SCPI_RES_OK;
00948 }
00949 
00950 scpi_result_t radio_regQ(scpi_t* context)
00951 {
00952     int32_t addr;
00953     
00954     if (!SCPI_ParamInt(context, &addr, TRUE))
00955         return SCPI_RES_ERR; 
00956      
00957     SCPI_ResultIntBase(context, radio.read_reg(addr), 16);
00958     return SCPI_RES_OK;     
00959 }
00960 
00961 
00962 scpi_result_t radio_dioQ(scpi_t* context)
00963 {
00964     int32_t dioN, value = -1;
00965     
00966     if (!SCPI_ParamInt(context, &dioN, TRUE))
00967         return SCPI_RES_ERR;     
00968         
00969     switch (dioN) {
00970         case 0: value = radio.dio0.read(); break;
00971         case 1: value = radio.dio1.read(); break;
00972         case 2: value = dio2_pin.read(); break;
00973         case 3: value = dio3_pin.read(); break;
00974         case 4: value = dio4_pin.read(); break;
00975         case 5: value = dio5_pin.read(); break;
00976         default:      
00977             return SCPI_RES_ERR;          
00978     } // ..switch (dioN)      
00979     
00980     SCPI_ResultInt(context, value);
00981     return SCPI_RES_OK;    
00982 }
00983 
00984 scpi_result_t radio_freq(scpi_t* context)
00985 {
00986     double MHz;
00987     
00988     if (!SCPI_ParamDouble(context, &MHz, TRUE))
00989         return SCPI_RES_ERR; 
00990     
00991     radio.set_frf_MHz(MHz);
00992     
00993     return SCPI_RES_OK;
00994 }
00995 
00996 scpi_result_t radio_freqQ(scpi_t* context)
00997 {
00998     SCPI_ResultDouble(context, radio.get_frf_MHz());
00999     return SCPI_RES_OK;
01000 }
01001 
01002 scpi_result_t lora_cr(scpi_t* context)
01003 {
01004     int32_t i;
01005     
01006     if (!SCPI_ParamInt(context, &i, TRUE))
01007         return SCPI_RES_ERR;
01008 
01009     if (!is_lora())            
01010         return SCPI_RES_ERR;    
01011         
01012     lora.setCodingRate(i);
01013     return SCPI_RES_OK;    
01014 }
01015 
01016 scpi_result_t lora_crQ(scpi_t* context)
01017 {
01018     if (!is_lora())     
01019         return SCPI_RES_ERR;    
01020 
01021      SCPI_ResultInt(context, lora.getCodingRate(false));
01022      return SCPI_RES_OK;   
01023 }  
01024 
01025 scpi_result_t lora_invrx(scpi_t* context)
01026 {
01027     scpi_bool_t param1;
01028     
01029     if (!SCPI_ParamBool(context, &param1, TRUE))
01030         return SCPI_RES_ERR;
01031             
01032     if (!is_lora())     
01033         return SCPI_RES_ERR;   
01034         
01035     lora.invert_rx(param1);
01036     return SCPI_RES_OK; 
01037 }
01038 
01039 scpi_result_t lora_invrxQ(scpi_t* context)
01040 {
01041     if (!is_lora())     
01042         return SCPI_RES_ERR;   
01043         
01044     lora.RegTest33.octet = radio.read_reg(REG_LR_TEST33);
01045     SCPI_ResultBool(context, lora.RegTest33.bits.invert_i_q );
01046     return SCPI_RES_OK;                
01047 }
01048 
01049 scpi_result_t lora_invtx(scpi_t* context)
01050 {
01051     scpi_bool_t param1;
01052     
01053     if (!SCPI_ParamBool(context, &param1, TRUE))
01054         return SCPI_RES_ERR;
01055             
01056     if (!is_lora())     
01057         return SCPI_RES_ERR;  
01058         
01059     lora.invert_tx(param1);
01060     return SCPI_RES_OK;           
01061 }
01062 
01063 scpi_result_t lora_invtxQ(scpi_t* context)
01064 {
01065     if (!is_lora())     
01066         return SCPI_RES_ERR;  
01067         
01068     lora.RegTest33.octet = radio.read_reg(REG_LR_TEST33);
01069     SCPI_ResultBool(context, !lora.RegTest33.bits.chirp_invert_tx);        
01070     return SCPI_RES_OK;    
01071 }
01072 
01073 scpi_result_t lora_crc(scpi_t* context)
01074 {
01075     scpi_bool_t param1;
01076     
01077     if (!SCPI_ParamBool(context, &param1, TRUE))
01078         return SCPI_RES_ERR;
01079             
01080     if (!is_lora())             
01081         return SCPI_RES_ERR;       
01082 
01083     lora.setRxPayloadCrcOn(param1);
01084     return SCPI_RES_OK;    
01085 }
01086 
01087 scpi_result_t lora_crcQ(scpi_t* context)
01088 {
01089     if (!is_lora())     
01090         return SCPI_RES_ERR;   
01091         
01092     SCPI_ResultBool(context, lora.getRxPayloadCrcOn());
01093     return SCPI_RES_OK;         
01094 }
01095  
01096 scpi_result_t lora_ih(scpi_t* context)
01097 {
01098     scpi_bool_t param1;
01099     
01100     if (!SCPI_ParamBool(context, &param1, TRUE))
01101         return SCPI_RES_ERR;
01102             
01103     if (!is_lora())             
01104         return SCPI_RES_ERR;    
01105 
01106     lora.setHeaderMode(param1);   
01107     return SCPI_RES_OK;    
01108 }
01109 
01110 scpi_result_t lora_ihQ(scpi_t* context)
01111 {
01112     if (!is_lora())     
01113         return SCPI_RES_ERR;     
01114         
01115     SCPI_ResultBool(context, lora.getHeaderMode());
01116     return SCPI_RES_OK;
01117 }
01118 
01119 scpi_result_t lora_ldro(scpi_t* context)
01120 {
01121     scpi_bool_t param1;
01122     
01123     if (!SCPI_ParamBool(context, &param1, TRUE))
01124         return SCPI_RES_ERR;
01125 
01126     if (!is_lora())             
01127         return SCPI_RES_ERR; 
01128         
01129     if (radio.type == SX1272) {
01130         lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
01131         lora.RegModemConfig.sx1272bits.LowDataRateOptimize = param1;
01132         radio.write_reg(REG_LR_MODEMCONFIG, lora.RegModemConfig.octet);
01133     } else if (radio.type == SX1276) {
01134         lora.RegModemConfig3.octet = radio.read_reg(REG_LR_MODEMCONFIG3);
01135         lora.RegModemConfig3.sx1276bits.LowDataRateOptimize = param1;
01136         radio.write_reg(REG_LR_MODEMCONFIG3, lora.RegModemConfig3.octet);
01137     } else
01138         return SCPI_RES_ERR; 
01139     
01140     return SCPI_RES_OK;                
01141 }
01142 
01143 scpi_result_t lora_ldroQ(scpi_t* context)
01144 {
01145     scpi_bool_t param1;
01146     
01147     if (!is_lora())     
01148         return SCPI_RES_ERR;   
01149         
01150     if (radio.type == SX1272) {
01151         lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
01152         param1 = lora.RegModemConfig.sx1272bits.LowDataRateOptimize;
01153     } else if (radio.type == SX1276) {
01154         lora.RegModemConfig3.octet = radio.read_reg(REG_LR_MODEMCONFIG3);
01155         param1 = lora.RegModemConfig3.sx1276bits.LowDataRateOptimize;
01156     } else
01157         return SCPI_RES_ERR;         
01158         
01159     SCPI_ResultBool(context, param1);
01160     return SCPI_RES_OK;    
01161 }
01162 
01163 scpi_result_t lora_bw(scpi_t* context)
01164 {
01165     double KHz;
01166         
01167     if (!is_lora())         
01168         return SCPI_RES_ERR;
01169         
01170     if (!SCPI_ParamDouble(context, &KHz, TRUE))
01171         return SCPI_RES_ERR;         
01172             
01173     lora.setBw_KHz(KHz);
01174     return SCPI_RES_OK;
01175 }
01176 
01177 scpi_result_t lora_bwQ(scpi_t* context)
01178 {
01179     int bw;
01180     double khz;
01181     
01182     if (!is_lora()) 
01183         return SCPI_RES_ERR;
01184         
01185     bw = lora.getBw();
01186     
01187     if (radio.type == SX1272) {
01188         switch (bw) {
01189             case 0: khz = 125; break;
01190             case 1: khz = 250; break;
01191             case 2: khz = 500; break;                
01192             default: return SCPI_RES_ERR;
01193         }
01194     } else if (radio.type == SX1276) {
01195         switch (bw) {
01196             case 0: khz = 7.8; break;
01197             case 1: khz = 10.4; break;
01198             case 2: khz = 15.6; break;
01199             case 3: khz = 20.8; break;
01200             case 4: khz = 31.25; break;
01201             case 5: khz = 41.7; break;
01202             case 6: khz = 62.5; break;
01203             case 7: khz = 125; break;
01204             case 8: khz = 250; break;
01205             case 9: khz = 500; break;            
01206             default: return SCPI_RES_ERR;
01207         }
01208     } else
01209         return SCPI_RES_ERR;
01210     
01211     SCPI_ResultDouble(context, khz);
01212     return SCPI_RES_OK;    
01213 }
01214 
01215 scpi_result_t lora_sf(scpi_t* context)
01216 {
01217     int32_t i;
01218         
01219     if (!is_lora())         
01220         return SCPI_RES_ERR;      
01221     
01222     if (!SCPI_ParamInt(context, &i, TRUE))
01223         return SCPI_RES_ERR;          
01224         
01225     lora.setSf(i);
01226     return SCPI_RES_OK; 
01227 }
01228 
01229 scpi_result_t lora_sfQ(scpi_t* context)
01230 {
01231     if (!is_lora())     
01232         return SCPI_RES_ERR;    
01233         
01234      SCPI_ResultInt(context, lora.getSf());
01235      return SCPI_RES_OK; 
01236 }
01237 
01238 scpi_result_t lora_feiQ(scpi_t* context)
01239 {
01240     if (!is_lora())     
01241         return SCPI_RES_ERR;     
01242         
01243     SCPI_ResultInt(context, lora.get_freq_error_Hz());    
01244     return SCPI_RES_OK;                
01245 }
01246 
01247 scpi_result_t lora_pktsnrQ(scpi_t* context)
01248 {
01249     if (!is_lora())     
01250         return SCPI_RES_ERR;     
01251         
01252     SCPI_ResultDouble(context, lora.RegPktSnrValue / 4.0);
01253     return SCPI_RES_OK;                
01254 }
01255 
01256 scpi_result_t lora_pktrssiQ(scpi_t* context)
01257 {
01258     if (!is_lora())     
01259         return SCPI_RES_ERR;
01260         
01261     SCPI_ResultDouble(context, lora.get_pkt_rssi());
01262     return SCPI_RES_OK;
01263 }
01264 
01265 
01266 scpi_result_t lora_prelen(scpi_t* context)
01267 {
01268     int32_t i;
01269         
01270     if (!is_lora())         
01271         return SCPI_RES_ERR;
01272     
01273     if (!SCPI_ParamInt(context, &i, TRUE))
01274         return SCPI_RES_ERR;    
01275         
01276     lora.RegPreamble = i;
01277     radio.write_u16(REG_LR_PREAMBLEMSB, lora.RegPreamble);  
01278     return SCPI_RES_OK;       
01279 }
01280 
01281 scpi_result_t lora_prelenQ(scpi_t* context)
01282 {
01283     if (!is_lora())     
01284         return SCPI_RES_ERR;
01285         
01286     lora.RegPreamble = radio.read_u16(REG_LR_PREAMBLEMSB);
01287     SCPI_ResultInt(context, lora.RegPreamble);    
01288     return SCPI_RES_OK;      
01289 }
01290 
01291 scpi_result_t lora_txc(scpi_t* context)
01292 {
01293     scpi_bool_t param1;
01294     
01295     if (!is_lora())     
01296         return SCPI_RES_ERR;         
01297     
01298     if (!SCPI_ParamBool(context, &param1, TRUE))
01299         return SCPI_RES_ERR;
01300         
01301     lora.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);        
01302     lora.RegModemConfig2.sx1276bits.TxContinuousMode = param1;
01303     radio.write_reg(REG_LR_MODEMCONFIG2, lora.RegModemConfig2.octet);    
01304     
01305     return SCPI_RES_OK;
01306 }
01307 
01308 scpi_result_t lora_txcQ(scpi_t* context)
01309 {
01310     if (!is_lora())     
01311         return SCPI_RES_ERR;        
01312         
01313     lora.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);        
01314     SCPI_ResultBool(context, lora.RegModemConfig2.sx1276bits.TxContinuousMode);
01315     
01316     return SCPI_RES_OK;    
01317 }
01318 
01319 
01320 #ifdef TARGET_MOTE_L152RC
01321 scpi_result_t pd2_set(scpi_t* context)
01322 {
01323     scpi_bool_t param1;
01324     
01325     if (!SCPI_ParamBool(context, &param1, TRUE))
01326         return SCPI_RES_ERR;
01327 
01328     pd2 = param1;
01329     return SCPI_RES_OK;
01330 }
01331 
01332 scpi_result_t pd2_get(scpi_t* context)
01333 {
01334     SCPI_ResultBool(context, pd2.read());
01335     return SCPI_RES_OK;
01336 }
01337 
01338 scpi_result_t rfswQ(scpi_t* context)
01339 {
01340     SCPI_ResultBool(context, rfsw1.read());
01341     SCPI_ResultBool(context, rfsw2.read());
01342     return SCPI_RES_OK;
01343 }
01344 
01345 scpi_result_t vbatQ(scpi_t* context)
01346 {
01347     bool bat_flag = false;
01348     bool BatOffState;
01349     
01350     if(gps.en_invert == true)
01351         BatOffState = true;
01352     else
01353         BatOffState = false;
01354     
01355     if(gps_en == BatOffState)
01356     {
01357         bat_flag = true;
01358         gps.enable(1);
01359     }
01360         
01361     SCPI_ResultDouble(context, bat->read()*AIN_VREF*AIN_VBAT_DIV);
01362     
01363     if(bat_flag)
01364         gps.enable(0);
01365         
01366     return SCPI_RES_OK;      
01367 }
01368 
01369 scpi_result_t gps_enable(scpi_t* context)
01370 {
01371     scpi_bool_t param1;
01372     
01373     if (!SCPI_ParamBool(context, &param1, TRUE))
01374         return SCPI_RES_ERR;    
01375         
01376     gps.enable(param1);
01377     return SCPI_RES_OK;
01378 }
01379 
01380 scpi_result_t gps_enableQ(scpi_t* context)
01381 {
01382     SCPI_ResultBool(context, gps.enabled());
01383     
01384     return SCPI_RES_OK;      
01385 }
01386 
01387 scpi_result_t gps_numCords(scpi_t* context)
01388 {
01389     int32_t i;
01390     
01391     if (!SCPI_ParamInt(context, &i, TRUE))
01392         return SCPI_RES_ERR;   
01393         
01394     gps_coord_cnt = i; 
01395     return SCPI_RES_OK;
01396 }
01397 
01398 scpi_result_t gps_numCordsQ(scpi_t* context)
01399 {
01400     SCPI_ResultInt(context, gps_coord_cnt);    
01401     return SCPI_RES_OK;    
01402 }
01403 
01404 scpi_result_t gps_longitude(scpi_t* context)
01405 {
01406     if (!SCPI_ParamDouble(context, &gps.Longitude, TRUE))
01407         return SCPI_RES_ERR;   
01408         
01409     return SCPI_RES_OK;         
01410 }
01411 
01412 scpi_result_t gps_longitudeQ(scpi_t* context)
01413 {
01414     SCPI_ResultDouble(context, gps.Longitude);
01415     return SCPI_RES_OK;     
01416 }
01417 
01418 scpi_result_t gps_latitude(scpi_t* context)
01419 {
01420     if (!SCPI_ParamDouble(context, &gps.Latitude, TRUE))
01421         return SCPI_RES_ERR;   
01422         
01423     return SCPI_RES_OK;           
01424 }
01425 
01426 scpi_result_t gps_latitudeQ(scpi_t* context)
01427 {
01428     SCPI_ResultDouble(context, gps.Latitude);
01429     return SCPI_RES_OK; 
01430 } 
01431 
01432 scpi_result_t mma_idQ(scpi_t* context)
01433 {
01434     SCPI_ResultIntBase(context, mma8451q.read_single(MMA8451_ID), 16);
01435     return SCPI_RES_OK;      
01436 }
01437 
01438 scpi_result_t mpl_idQ(scpi_t* context)
01439 {
01440     SCPI_ResultIntBase(context, mpl3115a2.read(MPL3115_ID), 16);
01441     return SCPI_RES_OK;       
01442 }
01443 
01444 scpi_result_t sx9500_reset(scpi_t* context)
01445 {
01446     sx9500.reset();
01447     return SCPI_RES_OK;
01448 }
01449 
01450 scpi_result_t sx9500_reg(scpi_t* context)
01451 {
01452     int32_t addr, data;
01453 
01454     if (!SCPI_ParamInt(context, &addr, TRUE))
01455         return SCPI_RES_ERR;  
01456         
01457     if (!SCPI_ParamInt(context, &data, TRUE))
01458         return SCPI_RES_ERR;  
01459 
01460     sx9500.write(addr, data);
01461         
01462     return SCPI_RES_OK;
01463 }
01464 
01465 scpi_result_t sx9500_regQ(scpi_t* context)
01466 {
01467     int32_t addr;
01468     
01469     if (!SCPI_ParamInt(context, &addr, TRUE))
01470         return SCPI_RES_ERR; 
01471      
01472     SCPI_ResultIntBase(context, sx9500.read_single(addr), 16);
01473     return SCPI_RES_OK;     
01474 }
01475 
01476 #endif /* TARGET_MOTE_L152RC */
01477 
01478 static const scpi_command_t scpi_commands[] = {
01479     // http://na.support.keysight.com/pna/help/latest/Programming/GP-IB_Command_Finder/Common_Commands.htm
01480     /* IEEE Mandated Commands (SCPI std V1999.0 4.1.1) */
01481     { .pattern = "*CLS", .callback = SCPI_CoreCls,},    // clear status
01482     { .pattern = "*ESE", .callback = SCPI_CoreEse,},    // standard event status enable
01483     { .pattern = "*ESE?", .callback = SCPI_CoreEseQ,},
01484     { .pattern = "*ESR?", .callback = SCPI_CoreEsrQ,},  // event status query
01485     { .pattern = "*IDN?", .callback = SCPI_CoreIdnQ,},  // identification query
01486     { .pattern = "*OPC", .callback = SCPI_CoreOpc,},    // operation complete command
01487     { .pattern = "*OPC?", .callback = SCPI_CoreOpcQ,},  // operation complete query
01488     { .pattern = "*RST", .callback = SCPI_CoreRst,},    // reset command
01489     { .pattern = "*SRE", .callback = SCPI_CoreSre,},    // service request enable command
01490     { .pattern = "*SRE?", .callback = SCPI_CoreSreQ,},  // service request enable query
01491     { .pattern = "*STB?", .callback = SCPI_CoreStbQ,},  // status byte register query
01492     { .pattern = "*TST?", .callback = SCPI_CoreTstQ,},  // self-test query
01493     { .pattern = "*WAI", .callback = SCPI_CoreWai,},    // wait to continue
01494 
01495     /* Required SCPI commands (SCPI std V1999.0 4.2.1) */
01496     {.pattern = "SYSTem:ERRor[:NEXT]?", .callback = SCPI_SystemErrorNextQ,},
01497     {.pattern = "SYSTem:ERRor:COUNt?", .callback = SCPI_SystemErrorCountQ,},
01498     {.pattern = "SYSTem:VERSion?", .callback = SCPI_SystemVersionQ,},
01499 
01500     //{.pattern = "STATus:OPERation?", .callback = scpi_stub_callback,},
01501     //{.pattern = "STATus:OPERation:EVENt?", .callback = scpi_stub_callback,},
01502     //{.pattern = "STATus:OPERation:CONDition?", .callback = scpi_stub_callback,},
01503     //{.pattern = "STATus:OPERation:ENABle", .callback = scpi_stub_callback,},
01504     //{.pattern = "STATus:OPERation:ENABle?", .callback = scpi_stub_callback,},
01505 
01506     {.pattern = "STATus:QUEStionable[:EVENt]?", .callback = SCPI_StatusQuestionableEventQ,},
01507     //{.pattern = "STATus:QUEStionable:CONDition?", .callback = scpi_stub_callback,},
01508     {.pattern = "STATus:QUEStionable:ENABle", .callback = SCPI_StatusQuestionableEnable,},
01509     {.pattern = "STATus:QUEStionable:ENABle?", .callback = SCPI_StatusQuestionableEnableQ,},
01510 
01511     {.pattern = "STATus:PRESet", .callback = SCPI_StatusPreset,},
01512 
01513     /* DMM */
01514     /*   
01515     {.pattern = "SYSTem:COMMunication:TCPIP:CONTROL?", .callback = SCPI_SystemCommTcpipControlQ,},
01516 
01517     {.pattern = "TEST:BOOL", .callback = TEST_Bool,},
01518     {.pattern = "TEST#:NUMbers#", .callback = TEST_Numbers,},*/
01519     
01520     /*{.pattern = "TEST:CHOice?", .callback = TEST_ChoiceQ,},*/
01521     
01522     {.pattern = "BUSY?", .callback = tx_busyQ,},
01523 
01524     {.pattern = "RAdio:FIfo", .callback = radio_fifo,},
01525     {.pattern = "RAdio:FIfo?", .callback = radio_fifoQ,},
01526     {.pattern = "RAdio:BINFIfo", .callback = radio_binFifo,},
01527     {.pattern = "RAdio:BINFIfo?", .callback = radio_binFifoQ,},
01528     {.pattern = "RAdio:MODulation", .callback = radio_modulation,},
01529     {.pattern = "RAdio:MODulation?", .callback = radio_modulationQ,},
01530     {.pattern = "RAdio:RSSI?", .callback = radio_rssiQ,},
01531     {.pattern = "RAdio:OPmode", .callback = radio_opmode,},
01532     {.pattern = "RAdio:OPmode?", .callback = radio_opmodeQ,},
01533     {.pattern = "RAdio:PASelect", .callback = radio_PASelect,},
01534     {.pattern = "RAdio:PASelect?", .callback = radio_PASelectQ,},
01535     {.pattern = "RAdio:OCP", .callback = radio_ocp,},
01536     {.pattern = "RAdio:OCP?", .callback = radio_ocpQ,},
01537     {.pattern = "RAdio:POWer", .callback = radio_power,},
01538     {.pattern = "RAdio:POWer?", .callback = radio_powerQ,},
01539     {.pattern = "RAdio:BGR", .callback = radio_bgr,},
01540     {.pattern = "RAdio:BGR?", .callback = radio_bgrQ,},
01541     {.pattern = "RAdio:LNABoost", .callback = radio_lnaBoost,},
01542     {.pattern = "RAdio:LNABoost?", .callback = radio_lnaBoostQ,},    
01543     {.pattern = "RAdio:FREQuency", .callback = radio_freq,},
01544     {.pattern = "RAdio:FREQuency?", .callback = radio_freqQ,},
01545     {.pattern = "RAdio:DIOMap", .callback = radio_diomap,},
01546     {.pattern = "RAdio:DIOMap?", .callback = radio_diomapQ,},
01547     {.pattern = "RAdio:DIO?", .callback = radio_dioQ,},
01548     {.pattern = "RAdio:REGister", .callback = radio_reg,},
01549     {.pattern = "RAdio:REGister?", .callback = radio_regQ,},
01550        
01551     {.pattern = "RAdio:FSK:SYNC", .callback = fsk_sync,},
01552     {.pattern = "RAdio:FSK:SYNC?", .callback = fsk_syncQ,}, 
01553     {.pattern = "RAdio:FSK:FDev", .callback = fsk_fdev,},
01554     {.pattern = "RAdio:FSK:FDev?", .callback = fsk_fdevQ,}, 
01555     {.pattern = "RAdio:FSK:BITRate", .callback = fsk_bitrate,},
01556     {.pattern = "RAdio:FSK:BITRate?", .callback = fsk_bitrateQ,},     
01557     {.pattern = "RAdio:FSK:PRELen", .callback = fsk_prelen,},
01558     {.pattern = "RAdio:FSK:PRELen?", .callback = fsk_prelenQ,},  
01559     {.pattern = "RAdio:FSK:RXBW", .callback = fsk_rxbw,},
01560     {.pattern = "RAdio:FSK:RXBW?", .callback = fsk_rxbwQ,},        
01561     {.pattern = "RAdio:FSK:AFCBW", .callback = fsk_afcbw,},
01562     {.pattern = "RAdio:FSK:AFCBW?", .callback = fsk_afcbwQ,}, 
01563     {.pattern = "RAdio:FSK:DCFree", .callback = fsk_dcfree,},
01564     {.pattern = "RAdio:FSK:DCFree?", .callback = fsk_dcfreeQ,},       
01565     {.pattern = "RAdio:FSK:RXTrigger", .callback = fsk_rxtrig,},
01566     {.pattern = "RAdio:FSK:RXTrigger?", .callback = fsk_rxtrigQ,},     
01567     {.pattern = "RAdio:FSK:DATAMode", .callback = fsk_datamode,},
01568     {.pattern = "RAdio:FSK:DATAMode?", .callback = fsk_datamodeQ,}, 
01569     {.pattern = "RAdio:FSK:BT", .callback = fsk_bt,},
01570     {.pattern = "RAdio:FSK:BT?", .callback = fsk_btQ,},     
01571     
01572     {.pattern = "RAdio:LORa:BW", .callback = lora_bw,},
01573     {.pattern = "RAdio:LORa:BW?", .callback = lora_bwQ,},    
01574     {.pattern = "RAdio:LORa:SF", .callback = lora_sf,},
01575     {.pattern = "RAdio:LORa:SF?", .callback = lora_sfQ,},     
01576     {.pattern = "RAdio:LORa:TXContinuous", .callback = lora_txc,},
01577     {.pattern = "RAdio:LORa:TXContinuous?", .callback = lora_txcQ,},         
01578     {.pattern = "RAdio:LORa:PRELen", .callback = lora_prelen,},
01579     {.pattern = "RAdio:LORa:PRELen?", .callback = lora_prelenQ,},    
01580     {.pattern = "RAdio:LORa:CR", .callback = lora_cr,},
01581     {.pattern = "RAdio:LORa:CR?", .callback = lora_crQ,},      
01582     {.pattern = "RAdio:LORa:LDRO", .callback = lora_ldro,},
01583     {.pattern = "RAdio:LORa:LDRO?", .callback = lora_ldroQ,},
01584     {.pattern = "RAdio:LORa:FEI?", .callback = lora_feiQ,},         
01585     {.pattern = "RAdio:LORa:PKTSnr?", .callback = lora_pktsnrQ,},   
01586     {.pattern = "RAdio:LORa:PKTRssi?", .callback = lora_pktrssiQ,},     
01587     {.pattern = "RAdio:LORa:Ih", .callback = lora_ih,},
01588     {.pattern = "RAdio:LORa:Ih?", .callback = lora_ihQ,},        
01589     {.pattern = "RAdio:LORa:CRC", .callback = lora_crc,},
01590     {.pattern = "RAdio:LORa:CRC?", .callback = lora_crcQ,},  
01591     {.pattern = "RAdio:LORa:INVRx", .callback = lora_invrx,},
01592     {.pattern = "RAdio:LORa:INVRx?", .callback = lora_invrxQ,},  
01593     {.pattern = "RAdio:LORa:INVTx", .callback = lora_invtx,},
01594     {.pattern = "RAdio:LORa:INVTx?", .callback = lora_invtxQ,},            
01595     
01596 #ifdef TARGET_MOTE_L152RC
01597     {.pattern = "PD2", .callback = pd2_set,},
01598     {.pattern = "PD2?", .callback = pd2_get,},
01599     {.pattern = "RFSW?", .callback = rfswQ,},
01600     {.pattern = "VBAT?", .callback = vbatQ,},
01601     
01602     {.pattern = "GPS:ENable", .callback = gps_enable,},
01603     {.pattern = "GPS:ENable?", .callback = gps_enableQ,},
01604     {.pattern = "GPS:NUMCoords", .callback = gps_numCords,},
01605     {.pattern = "GPS:NUMCoords?", .callback = gps_numCordsQ,},   
01606     {.pattern = "GPS:LOngitude", .callback = gps_longitude,},
01607     {.pattern = "GPS:LOngitude?", .callback = gps_longitudeQ,},  
01608     {.pattern = "GPS:LAtitude", .callback = gps_latitude,},
01609     {.pattern = "GPS:LAtitude?", .callback = gps_latitudeQ,},  
01610     
01611     {.pattern = "MMA:ID?", .callback = mma_idQ,}, 
01612     
01613     {.pattern = "MPL:ID?", .callback = mpl_idQ,},
01614     
01615     {.pattern = "SX9500:RST", .callback = sx9500_reset,},
01616     {.pattern = "SX9500:REGister", .callback = sx9500_reg,},
01617     {.pattern = "SX9500:REGister?", .callback = sx9500_regQ,},
01618     
01619 #endif /* TARGET_MOTE_L152RC */
01620     
01621     SCPI_CMD_LIST_END
01622 };
01623 
01624 #ifdef TARGET_MOTE_L152RC
01625 void get_mote_version()
01626 {
01627     char first;
01628       
01629     pc_7 = 1;
01630     first = pc_1;
01631     pc_7 = 0;
01632     if (first && !pc_1) {
01633         mote_version = MOTE_V2;
01634         bat = new AnalogIn(PA_0);
01635     } else {
01636         mote_version = MOTE_V3;
01637         bat = new AnalogIn(PA_1);
01638     }
01639 }
01640 #endif
01641 
01642 static scpi_interface_t scpi_interface = {
01643     .error = SCPI_Error,
01644     .write = SCPI_Write,
01645     .control = SCPI_Control,
01646     .flush = SCPI_Flush,
01647     .reset = SCPI_Reset,
01648 };
01649 
01650 #define SCPI_INPUT_BUFFER_LENGTH 256
01651 static char scpi_input_buffer[SCPI_INPUT_BUFFER_LENGTH];
01652 static scpi_reg_val_t scpi_regs[SCPI_REG_COUNT];
01653 
01654 scpi_t scpi_context = {
01655     cmdlist : scpi_commands,
01656     buffer : {
01657         length : SCPI_INPUT_BUFFER_LENGTH,
01658         position : 0,
01659         data : scpi_input_buffer
01660     },
01661     param_list : { 0 }, 
01662     interface : &scpi_interface,
01663     output_count : 0,
01664     input_count : 0,
01665     cmd_error : false,
01666     error_queue : NULL,
01667     registers : scpi_regs,
01668     units : scpi_units_def,
01669     user_context : NULL,
01670     parser_state : {
01671         programHeader : { SCPI_TOKEN_UNKNOWN, NULL, 0 },
01672         programData : { SCPI_TOKEN_UNKNOWN, NULL, 0 },
01673         numberOfParameters : 0,
01674         termination : SCPI_MESSAGE_TERMINATION_NONE
01675     },
01676     idn : {"semtech", "na-mote", NULL, "01-02"}
01677 };
01678 
01679 void scpi_def_init()
01680 {
01681     radio.rf_switch = rfsw_callback;
01682     radio.get_frf_MHz();    // get HF bit
01683     
01684 #ifdef TARGET_MOTE_L152RC
01685 
01686     get_mote_version();
01687     if (mote_version == MOTE_V3) {
01688         gps.en_invert = false;
01689         scpi_context.idn[3] = "3";
01690     } else {
01691         gps.en_invert = true;
01692         scpi_context.idn[3] = "2";
01693     }
01694         
01695     gps.init();
01696 
01697 #endif /* TARGET_MOTE_L152RC */
01698 }