firstTest

Dependencies:   mbed lib_sx9500 SX127x lib_mpl3115a2 lib_mma8451q lib_gps libscpi

Revision:
0:1aa6d4a96bf1
Child:
1:96123698b488
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scpi-def.cpp	Tue Apr 14 02:53:27 2020 +0000
@@ -0,0 +1,1698 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "scpi/scpi.h"
+#include "scpi-def.h"
+
+//#include "sx12xx.h"
+#include "sx127x_lora.h"
+#include "sx127x_fsk.h"
+
+/******************************************************************************/
+#ifdef TARGET_MOTE_L152RC
+#include "gps.h"
+#include "mma8451q.h"
+#include "mpl3115a2.h"
+#include "sx9500.h"
+
+#define RFSW1                    PC_4 //NorAm_Mote RFSwitch_CNTR_1
+#define RFSW2                    PC_13 //NorAm_Mote RFSwitch_CNTR_2
+#define RADIO_RESET              PC_2 //NorAm_Mote Reset_sx
+#define RADIO_MOSI               PB_15 //NorAm_Mote SPI2 Mosi
+#define RADIO_MISO               PB_14 //NorAm_Mote SPI2 Miso
+#define RADIO_SCLK               PB_13 //NorAm_Mote  SPI2 Clk
+#define RADIO_NSS                PB_12 //NorAm_Mote SPI2 Nss
+#define RADIO_DIO_0              PC_6 //NorAm_Mote DIO0 
+#define RADIO_DIO_1              PC_10 //NorAm_Mote DIO1
+#define RADIO_DIO_2              PC_8 //NorAm_Mote DIO2 
+#define RADIO_DIO_3              PB_4 //NorAm_Mote DIO3 
+#define RADIO_DIO_4              PB_5 //NorAm_Mote DIO4 
+#define RADIO_DIO_5              PB_6 //NorAm_Mote DIO5
+
+SPI spi(RADIO_MOSI, RADIO_MISO, RADIO_SCLK);
+//             dio0, dio1, nss, spi, rst
+SX127x radio(RADIO_DIO_0, RADIO_DIO_1, RADIO_NSS, spi, RADIO_RESET);
+
+DigitalOut rfsw1(RFSW1);
+DigitalOut rfsw2(RFSW2);
+
+void rfsw_callback()
+{
+    if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER) {  // start of transmission
+        //if (radio.HF)
+        if (radio.RegPaConfig.bits.PaSelect) { // if PA_BOOST
+            rfsw2 = 0;
+            rfsw1 = 1;
+        } else { // RFO to power amp
+            rfsw2 = 1;
+            rfsw1 = 0;            
+        }
+        //hdr_fem_csd = 1;    //debug
+    } else if (radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER || radio.RegOpMode.bits.Mode == RF_OPMODE_CAD) { // start of reception
+        //if (radio.HF)
+        rfsw2 = 1;
+        rfsw1 = 1;
+        //hdr_fem_csd = 0;    //debug
+    } else { // RF switch shutdown
+        rfsw2 = 0;
+        rfsw1 = 0;     
+        //hdr_fem_csd = 0;    //debug         
+    }
+}
+
+DigitalOut pd2(PD_2);
+
+DigitalIn dio2_pin(RADIO_DIO_2);
+DigitalIn dio3_pin(RADIO_DIO_3);
+DigitalIn dio4_pin(RADIO_DIO_4);
+DigitalIn dio5_pin(RADIO_DIO_5);
+
+AnalogIn *bat;
+#define AIN_VREF        3.3     // stm32 internal refernce
+#define AIN_VBAT_DIV    2       // resistor divider
+
+/*  gps(tx, rx, en); */
+DigitalOut gps_en(PB_11);
+GPS gps(PB_6, PB_7, PB_11);
+uint32_t gps_coord_cnt;
+
+DigitalIn i2c_int_pin(PB_4);
+I2C i2c(I2C_SDA, I2C_SCL);
+MMA8451Q mma8451q(i2c, i2c_int_pin);
+MPL3115A2 mpl3115a2(i2c, i2c_int_pin);
+SX9500 sx9500(i2c, PA_9, PA_10);
+
+typedef enum {
+    MOTE_NONE = 0,
+    MOTE_V2,
+    MOTE_V3
+} mote_version_e;
+mote_version_e mote_version = MOTE_NONE;
+
+DigitalOut pc_7(PC_7);
+DigitalIn pc_1(PC_1);
+#else // sx1276 shield...
+
+SPI spi(D11, D12, D13); // mosi, miso, sclk
+//           dio0, dio1, nss, spi, rst
+SX127x radio(  D2,   D3, D10, spi, A0); // sx1276 arduino shield
+
+#ifdef TARGET_LPC11U6X
+DigitalOut rfsw(P0_23);
+#else
+DigitalOut rfsw(A4);    // for SX1276 arduino shield
+#endif
+
+void rfsw_callback()
+{
+    if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER)
+        rfsw = 1;
+    else
+        rfsw = 0;
+}
+
+DigitalIn dio2_pin(D4);
+DigitalIn dio3_pin(D5);
+DigitalIn dio4_pin(A3);
+DigitalIn dio5_pin(D9);
+
+#endif /* !TARGET_MOTE_L152RC */
+
+SX127x_fsk fsk(radio);
+SX127x_lora lora(radio);
+
+volatile bool tx_busy = false;
+
+bool is_lora()
+{
+    radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
+    return radio.RegOpMode.bits.LongRangeMode;
+}
+
+void
+service_radio()
+{
+    service_action_e act;
+    
+    if (radio.RegOpMode.bits.LongRangeMode) {
+        act = lora.service();
+        switch (act) {
+            case SERVICE_READ_FIFO:
+                //printf("lora SERVICE_READ_FIFO\r\n");
+                SCPI_RegSetBits(&scpi_context, SCPI_REG_QUES, 0x200);    // bit 9 for packet received
+                break;
+            case SERVICE_TX_DONE:
+                tx_busy = false;
+                break;
+            case SERVICE_ERROR:
+            case SERVICE_NONE:
+                break;
+        } // ...switch (act)
+    } else {
+        /* FSK: */
+        act = fsk.service();     
+        switch (act) {
+            case SERVICE_READ_FIFO:
+                SCPI_RegSetBits(&scpi_context, SCPI_REG_QUES, 0x200);    // bit 9 for packet received
+                break;            
+            case SERVICE_TX_DONE:
+                tx_busy = false;
+                break;
+            case SERVICE_ERROR:
+            case SERVICE_NONE:
+                break;
+        } // ...switch (act)           
+    }
+    
+#ifdef TARGET_MOTE_L152RC
+    gps.service();
+    if (gps.LatitudeBinary != 0) {
+        gps.LatitudeBinary = 0;
+        //printf("gps long:%f, lat:%f  Vbat:%.2fV\r\n", gps.Longitude, gps.Latitude, ain_bat->read()*AIN_VREF*AIN_VBAT_DIV);
+        gps_coord_cnt++;
+    }    
+#endif /* TARGET_MOTE_L152RC */
+}
+
+scpi_result_t tx_busyQ(scpi_t * context)
+{
+    SCPI_ResultBool(context, tx_busy);
+    return SCPI_RES_OK;
+}
+
+scpi_result_t SCPI_Reset(scpi_t * context)
+{
+    radio.hw_reset();
+    printf("**Reset\r\n");
+    tx_busy = false;
+    return SCPI_RES_OK;
+}
+
+const scpi_choice_def_t pa_selects[] = {
+    { "RFO", 0 },
+    { "PA_BOOST", 1 },       
+    SCPI_CHOICE_LIST_END
+};
+
+scpi_result_t radio_PASelect(scpi_t* context)
+{
+    int32_t value;
+    
+    if (!SCPI_ParamChoice(context, pa_selects, &value, TRUE))
+        return SCPI_RES_ERR;  
+        
+    radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
+    radio.RegPaConfig.bits.PaSelect = value;
+    radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);
+    
+    if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER)
+        rfsw_callback();    
+    
+    return SCPI_RES_OK;
+}
+    
+scpi_result_t radio_PASelectQ(scpi_t* context)
+{
+    int idx;
+    
+    radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
+    idx = radio.RegPaConfig.bits.PaSelect;
+        
+    SCPI_ResultText(context, pa_selects[idx].name);
+    return SCPI_RES_OK;    
+}
+
+const scpi_choice_def_t modulations[] = {
+    { "FSK", 1 },
+    { "OOK", 2 },
+    { "LORa", 3 },        
+    SCPI_CHOICE_LIST_END
+};
+
+scpi_result_t radio_modulation(scpi_t* context)
+{
+    int32_t value;
+    
+    /* scpi_bool_t SCPI_ParamChoice(scpi_t * context, const scpi_choice_def_t * options, int32_t * value, scpi_bool_t mandatory); */
+    if (!SCPI_ParamChoice(context, modulations, &value, TRUE))
+        return SCPI_RES_ERR;
+
+    radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
+    if (value == 3) {
+        if (!radio.RegOpMode.bits.LongRangeMode)
+            lora.enable();
+    } else {
+        if (radio.RegOpMode.bits.LongRangeMode)
+            fsk.enable(false);
+        if (radio.RegOpMode.bits.ModulationType) { // radio is OOK
+            if (value == 1) {   // change to FSK
+                radio.RegOpMode.bits.ModulationType = 0;
+                radio.write_reg(REG_OPMODE, radio.RegOpMode.octet);
+            }
+        } else { // radio is FSK
+            if (value == 2) {   // change to OOK
+                radio.RegOpMode.bits.ModulationType = 1;
+                radio.write_reg(REG_OPMODE, radio.RegOpMode.octet);
+            }
+        }
+    }
+ 
+   return SCPI_RES_OK;
+}
+
+scpi_result_t radio_modulationQ(scpi_t* context)
+{
+    int idx;
+    
+    if (is_lora()) {
+        idx = 2;    // lora
+    } else {
+        if (radio.RegOpMode.bits.ModulationType)
+            idx = 1;    // ook
+        else
+            idx = 0;    // fsk
+    }
+    
+    SCPI_ResultText(context, modulations[idx].name);
+    return SCPI_RES_OK;
+}
+
+scpi_result_t fsk_fdev(scpi_t* context)
+{
+    int32_t i;
+    
+    if (!SCPI_ParamInt(context, &i, TRUE))
+        return SCPI_RES_ERR;
+            
+    if (is_lora())
+        return SCPI_RES_ERR;
+        
+    fsk.set_tx_fdev_hz(i);
+    return SCPI_RES_OK;
+}
+
+scpi_result_t fsk_fdevQ(scpi_t* context)
+{
+    if (is_lora())
+        return SCPI_RES_ERR;
+        
+    SCPI_ResultInt(context, fsk.get_tx_fdev_hz());    
+    return SCPI_RES_OK;      
+}
+
+const scpi_choice_def_t rxtrigs[] = {
+    { "OFF", 0 },
+    { "RSSI", 1 },
+    { "PRE", 6 },        
+    { "BOTH", 7 },          
+    SCPI_CHOICE_LIST_END
+};
+
+scpi_result_t fsk_rxtrig(scpi_t* context)
+{
+    int32_t value;
+    
+    if (is_lora())
+        return SCPI_RES_ERR;
+        
+    if (!SCPI_ParamChoice(context, rxtrigs, &value, TRUE))
+        return SCPI_RES_ERR;           
+        
+    fsk.RegRxConfig.octet = radio.read_reg(REG_FSK_RXCONFIG);       
+    fsk.RegRxConfig.bits.RxTrigger = value;
+    radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet);
+    return SCPI_RES_OK;
+}
+
+scpi_result_t fsk_rxtrigQ(scpi_t* context)
+{
+    int idx;
+    
+    if (is_lora())
+        return SCPI_RES_ERR;    
+        
+    fsk.RegRxConfig.octet = radio.read_reg(REG_FSK_RXCONFIG);
+    idx = fsk.RegRxConfig.bits.RxTrigger;
+    SCPI_ResultText(context, rxtrigs[idx].name);
+    return SCPI_RES_OK;             
+}
+
+scpi_result_t fsk_bt(scpi_t* context)
+{
+    double bt;    
+    
+    if (is_lora())
+        return SCPI_RES_ERR;        
+    
+    if (!SCPI_ParamDouble(context, &bt, TRUE))
+        return SCPI_RES_ERR; 
+                
+    if (bt < 0.2)                
+        radio.RegOpMode.bits.ModulationShaping = 0; // no shaping
+    else if (bt < 0.4)
+        radio.RegOpMode.bits.ModulationShaping = 3; // BT0.3  (most shaping)
+    else if (bt < 0.9)
+        radio.RegOpMode.bits.ModulationShaping = 2; // BT0.5
+    else
+        radio.RegOpMode.bits.ModulationShaping = 1; // BT1.0
+        
+    radio.write_reg(REG_OPMODE, radio.RegOpMode.octet);       
+    return SCPI_RES_OK;    
+}
+
+scpi_result_t fsk_btQ(scpi_t* context)
+{
+    double bt;
+    
+    if (is_lora())
+        return SCPI_RES_ERR;        
+        
+    switch (radio.RegOpMode.bits.ModulationShaping) {
+        case 0: bt = 0.0; break;
+        case 1: bt = 1.0; break;
+        case 2: bt = 0.5; break;
+        case 3: bt = 0.3; break;
+    }
+    
+    SCPI_ResultDouble(context, bt);
+    return SCPI_RES_OK;    
+}
+
+const scpi_choice_def_t datamodes[] = {
+    { "CONT", 0 },
+    { "PKT", 1 },       
+    SCPI_CHOICE_LIST_END
+};
+
+scpi_result_t fsk_datamode(scpi_t* context)
+{
+    int32_t value;
+    
+    if (!SCPI_ParamChoice(context, datamodes, &value, TRUE))
+        return SCPI_RES_ERR;
+            
+    if (is_lora())
+        return SCPI_RES_ERR;  
+        
+    fsk.RegPktConfig2.word = radio.read_u16(REG_FSK_PACKETCONFIG2);
+    fsk.RegPktConfig2.bits.DataModePacket = value;
+    radio.write_u16(REG_FSK_PACKETCONFIG2, fsk.RegPktConfig2.word);
+    return SCPI_RES_OK;
+}
+
+scpi_result_t fsk_datamodeQ(scpi_t* context)
+{
+    int idx;
+    
+    if (is_lora())
+        return SCPI_RES_ERR;       
+    
+    fsk.RegPktConfig2.word = radio.read_u16(REG_FSK_PACKETCONFIG2);
+    idx = fsk.RegPktConfig2.bits.DataModePacket;    
+    SCPI_ResultText(context, datamodes[idx].name);
+    return SCPI_RES_OK;
+}
+  
+const scpi_choice_def_t dcfrees[] = {
+    { "OFF", 0 },
+    { "MAN", 1 },
+    { "WHIT", 2 },        
+    SCPI_CHOICE_LIST_END
+};
+
+scpi_result_t fsk_dcfree(scpi_t* context)
+{
+    int32_t value;
+        
+    if (is_lora())
+        return SCPI_RES_ERR;    
+   
+    if (!SCPI_ParamChoice(context, dcfrees, &value, TRUE))
+        return SCPI_RES_ERR;        
+        
+    fsk.RegPktConfig1.octet = radio.read_reg(REG_FSK_PACKETCONFIG1);        
+    fsk.RegPktConfig1.bits.DcFree = value;
+    radio.write_reg(REG_FSK_PACKETCONFIG1, fsk.RegPktConfig1.octet);
+    return SCPI_RES_OK;    
+}
+
+scpi_result_t fsk_dcfreeQ(scpi_t* context)
+{
+    int idx;
+    
+    if (is_lora())
+        return SCPI_RES_ERR;
+        
+    fsk.RegPktConfig1.octet = radio.read_reg(REG_FSK_PACKETCONFIG1);        
+    idx = fsk.RegPktConfig1.bits.DcFree ;
+    SCPI_ResultText(context, dcfrees[idx].name);
+    return SCPI_RES_OK;
+}
+
+scpi_result_t fsk_rxbw(scpi_t* context)
+{
+    int32_t i;
+    
+    if (!SCPI_ParamInt(context, &i, TRUE))
+        return SCPI_RES_ERR; 
+        
+    if (is_lora())
+        return SCPI_RES_ERR;
+        
+    fsk.set_rx_dcc_bw_hz(i, 0);
+    return SCPI_RES_OK;
+}
+
+scpi_result_t fsk_rxbwQ(scpi_t* context)
+{
+    if (is_lora())
+        return SCPI_RES_ERR;    
+        
+    SCPI_ResultInt(context, fsk.get_rx_bw_hz(REG_FSK_RXBW));    
+    return SCPI_RES_OK;          
+}
+
+scpi_result_t fsk_afcbw(scpi_t* context)
+{
+    int32_t i;
+    
+    if (!SCPI_ParamInt(context, &i, TRUE))
+        return SCPI_RES_ERR; 
+        
+    if (is_lora())        
+        return SCPI_RES_ERR;
+        
+    fsk.set_rx_dcc_bw_hz(i, 1);
+    return SCPI_RES_OK;
+}
+
+scpi_result_t fsk_afcbwQ(scpi_t* context)
+{
+    if (is_lora())    
+        return SCPI_RES_ERR;    
+        
+    SCPI_ResultInt(context, fsk.get_rx_bw_hz(REG_FSK_AFCBW));    
+    return SCPI_RES_OK;          
+} 
+
+scpi_result_t fsk_bitrate(scpi_t* context)
+{
+    int32_t i;
+    
+    if (!SCPI_ParamInt(context, &i, TRUE))
+        return SCPI_RES_ERR;
+            
+    if (is_lora())            
+        return SCPI_RES_ERR;    
+        
+    fsk.set_bitrate(i);
+    return SCPI_RES_OK;     
+}
+
+scpi_result_t fsk_bitrateQ(scpi_t* context)
+{
+    if (is_lora())    
+        return SCPI_RES_ERR;    
+    
+    SCPI_ResultInt(context, fsk.get_bitrate());    
+    return SCPI_RES_OK;    
+}
+
+scpi_result_t fsk_prelen(scpi_t* context)
+{
+    int32_t i;
+    
+    if (!SCPI_ParamInt(context, &i, TRUE))
+        return SCPI_RES_ERR;
+        
+    if (is_lora())        
+        return SCPI_RES_ERR;     
+        
+    radio.write_u16(REG_FSK_PREAMBLEMSB, i); 
+    return SCPI_RES_OK;          
+}
+
+scpi_result_t fsk_prelenQ(scpi_t* context)
+{
+    if (is_lora())    
+        return SCPI_RES_ERR;     
+        
+    SCPI_ResultInt(context, radio.read_u16(REG_FSK_PREAMBLEMSB) );    
+    return SCPI_RES_OK;      
+} 
+
+scpi_result_t fsk_sync(scpi_t* context)
+{
+    char buffer[100];
+    size_t _copy_len, _len, i;
+    uint8_t addr;
+    uint8_t sync_size;
+        
+    if (is_lora())        
+        return SCPI_RES_ERR;
+        
+    memset(buffer, 0, sizeof(buffer));    
+    SCPI_ParamCopyText(context, buffer, 100, &_copy_len, false);
+    for (_len = 0; buffer[_len] != 0; _len++)
+        ;  
+   
+    fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
+    sync_size = 0;
+    addr = REG_FSK_SYNCVALUE1;
+    for (i = 0; i < _len; i+=2) {
+        int o;
+        sscanf(buffer+i, "%02x", &o);
+        radio.write_reg(addr++, o);
+        sync_size++;
+    }    
+    if (sync_size > 0)
+        fsk.RegSyncConfig.bits.SyncSize = sync_size - 1;
+        
+    radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet);
+    
+    return SCPI_RES_OK;
+}
+
+scpi_result_t fsk_syncQ(scpi_t* context)
+{
+    int i;
+    char txt[64];
+    char *ptr = txt;
+    
+    if (is_lora())    
+        return SCPI_RES_ERR;
+        
+    fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
+    for (i = 0; i <= fsk.RegSyncConfig.bits.SyncSize; i++) {
+        uint8_t o = radio.read_reg(i + REG_FSK_SYNCVALUE1);
+        sprintf(ptr, "%02x", o);
+        ptr += 2;
+    }
+    
+    SCPI_ResultText(context, txt);
+    return SCPI_RES_OK;
+}
+
+scpi_result_t radio_rssiQ(scpi_t* context)
+{
+    int reg_val;
+    
+    radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
+    if (radio.RegOpMode.bits.Mode != RF_OPMODE_RECEIVER)
+        return SCPI_RES_ERR;
+
+    if (is_lora()) {
+        reg_val = radio.read_reg(REG_LR_RSSIVALUE);    // 0x1b: dbm = -125 + regvalue
+        SCPI_ResultDouble(context, -125 + reg_val);
+    } else {
+        reg_val = radio.read_reg(REG_FSK_RSSIVALUE);   // 0x11: dBm = -regvalue/2
+        SCPI_ResultDouble(context, -reg_val/2.0);
+    }
+    
+    return SCPI_RES_OK;
+}
+
+scpi_result_t radio_binFifo(scpi_t* context)
+{
+    size_t len;
+    const char* buf = (const char *)radio.tx_buf;
+             
+     /*scpi_bool_t SCPI_ParamArbitraryBlock(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory);*/
+     if (!SCPI_ParamArbitraryBlock(context, &buf, &len, TRUE))
+        return SCPI_RES_ERR; 
+
+    radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG); // pull PaSelect
+    if (is_lora()) {
+        lora.RegPayloadLength = len;
+        radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
+        lora.start_tx(lora.RegPayloadLength);        
+    } else {
+        fsk.start_tx(len);
+    }    
+    
+    tx_busy = true;
+    
+    return SCPI_RES_OK;            
+}
+
+scpi_result_t radio_binFifoQ(scpi_t* context)
+{
+    size_t len;
+    const char* buf = (const char *)radio.rx_buf;
+
+    if (is_lora()) {
+        len = lora.RegRxNbBytes;  
+    } else {
+        len = fsk.rx_buf_length;
+    }
+    
+    //size_t SCPI_ResultArbitraryBlock(scpi_t * context, const char * data, size_t len);
+    if (SCPI_ResultArbitraryBlock(context, buf, len) == len)
+        return SCPI_RES_OK;    
+    else
+        return SCPI_RES_ERR; 
+}
+
+scpi_result_t radio_fifoQ(scpi_t* context)
+{
+    int i;
+    char txt[520];
+    char *ptr = txt;
+        
+    if (is_lora()) {
+        for (i = 0; i < lora.RegRxNbBytes; i++) {
+            sprintf(ptr, "%02x", radio.rx_buf[i]);
+            ptr += 2;
+        }        
+    } else {
+        for (i = 0; i < fsk.rx_buf_length; i++) {
+            sprintf(ptr, "%02x", radio.rx_buf[i]);
+            ptr += 2;
+        }   
+    }
+    
+    SCPI_ResultText(context, txt);
+    return SCPI_RES_OK;
+}
+
+scpi_result_t radio_fifo(scpi_t* context)
+{
+    char buffer[100];
+    size_t copy_len, i, len;
+    
+    if (tx_busy)
+        return SCPI_RES_ERR;
+                
+    memset(buffer, 0, sizeof(buffer));
+    SCPI_ParamCopyText(context, buffer, 100, &copy_len, false);
+
+    for (len = 0; buffer[len] != 0; len++)
+        ;
+
+    for (i = 0; i < len; i++)
+        radio.tx_buf[i] = buffer[i];
+    
+    radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);    
+    if (is_lora()) {
+        lora.RegPayloadLength = len;
+        radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
+        lora.start_tx(lora.RegPayloadLength);        
+    } else {
+        /* fsk todo */
+        fsk.start_tx(len);
+    }    
+    
+    tx_busy = true;
+    
+    return SCPI_RES_OK;    
+}
+
+const scpi_choice_def_t opmodes[] = {
+    { "SLE", 0 },
+    { "STB", 1 },
+    { "FST", 2 },        
+    { "TX", 3 },
+    { "FSR", 4 },
+    { "RXC", 5 },       
+    { "RXS", 6 },         
+    { "CAD", 7 },         
+    SCPI_CHOICE_LIST_END
+};
+
+scpi_result_t radio_opmode(scpi_t* context)
+{
+    int32_t value;
+    
+    if (!SCPI_ParamChoice(context, opmodes, &value, TRUE))
+        return SCPI_RES_ERR;    
+ 
+    if (value == RF_OPMODE_TRANSMITTER)
+        radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);     // pull PaSelect
+    else
+        tx_busy = false;        
+               
+    radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);   
+    radio.set_opmode((chip_mode_e)value);
+
+    return SCPI_RES_OK;        
+}
+
+scpi_result_t radio_opmodeQ(scpi_t* context)
+{
+    int idx;
+    
+    radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
+    idx = radio.RegOpMode.bits.Mode;
+    SCPI_ResultText(context, opmodes[idx].name);
+    
+    return SCPI_RES_OK;
+}
+
+
+/*scpi_result_t wbr_set_bit9(scpi_t* context)
+{
+    SCPI_RegSetBits(context, SCPI_REG_QUES, 0x200);
+    printf("set bit9\r\n");
+    return SCPI_RES_OK;
+}*/
+scpi_result_t radio_ocp(scpi_t* context)
+{
+    int32_t i;
+    
+    if (!SCPI_ParamInt(context, &i, TRUE))
+        return SCPI_RES_ERR;     
+        
+    radio.RegOcp.octet = radio.read_reg(REG_OCP);
+    if (i < 130)
+        radio.RegOcp.bits.OcpTrim = (i - 45) / 5;
+    else
+        radio.RegOcp.bits.OcpTrim = (i + 30) / 10;
+    radio.write_reg(REG_OCP, radio.RegOcp.octet);   
+    return SCPI_RES_OK; 
+}
+
+scpi_result_t radio_ocpQ(scpi_t* context)
+{
+    int32_t i;
+    
+    radio.RegOcp.octet = radio.read_reg(REG_OCP);
+    
+    if (radio.RegOcp.bits.OcpTrim < 16)
+        i = 45 + (5 * radio.RegOcp.bits.OcpTrim);
+    else if (radio.RegOcp.bits.OcpTrim < 28)
+        i = (10 * radio.RegOcp.bits.OcpTrim) - 30;
+    else
+        i = 240;    
+        
+    SCPI_ResultInt(context, i);    
+    return SCPI_RES_OK;         
+}
+
+scpi_result_t radio_bgr(scpi_t* context)
+{
+    RegPdsTrim1_t pds_trim;
+    int32_t i;
+    
+    if (!SCPI_ParamInt(context, &i, TRUE))
+        return SCPI_RES_ERR;  
+            
+    if (radio.type == SX1276) {
+        pds_trim.octet = radio.read_reg(REG_PDSTRIM1_SX1276);
+        pds_trim.bits.prog_txdac = i;
+        radio.write_reg(REG_PDSTRIM1_SX1276, pds_trim.octet);
+    } else if (radio.type == SX1272) { 
+        pds_trim.octet = radio.read_reg(REG_PDSTRIM1_SX1272);       
+        pds_trim.bits.prog_txdac = i;
+        radio.write_reg(REG_PDSTRIM1_SX1272, pds_trim.octet);
+    } else
+        return SCPI_RES_ERR; 
+    
+    return SCPI_RES_OK;
+}
+
+scpi_result_t radio_bgrQ(scpi_t* context)
+{
+    RegPdsTrim1_t pds_trim;
+      
+    if (radio.type == SX1276)
+        pds_trim.octet = radio.read_reg(REG_PDSTRIM1_SX1276);    
+    else if (radio.type == SX1272)
+        pds_trim.octet = radio.read_reg(REG_PDSTRIM1_SX1272);
+    else
+        return SCPI_RES_ERR;
+        
+    SCPI_ResultInt(context, pds_trim.bits.prog_txdac);  
+    return SCPI_RES_OK;        
+}
+
+scpi_result_t radio_lnaBoost(scpi_t* context)
+{
+    scpi_bool_t param1;
+    
+    if (!SCPI_ParamBool(context, &param1, TRUE))
+        return SCPI_RES_ERR;
+            
+    radio.RegLna.octet = radio.read_reg(REG_LNA);  
+    if (param1)
+        radio.RegLna.bits.LnaBoostHF = 3;
+    else
+        radio.RegLna.bits.LnaBoostHF = 0;
+        
+    radio.write_reg(REG_LNA, radio.RegLna.octet);
+    return SCPI_RES_OK;
+}
+
+scpi_result_t radio_lnaBoostQ(scpi_t* context)
+{
+    radio.RegLna.octet = radio.read_reg(REG_LNA);
+    if (radio.RegLna.bits.LnaBoostHF)
+        SCPI_ResultBool(context, 1);
+    else
+        SCPI_ResultBool(context, 0);
+    
+    return SCPI_RES_OK;     
+}
+
+scpi_result_t radio_power(scpi_t* context)
+{
+    int32_t i;
+    
+    if (!SCPI_ParamInt(context, &i, TRUE))
+        return SCPI_RES_ERR;  
+            
+    radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
+    radio.RegPaConfig.bits.OutputPower = i;
+    radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);
+
+    return SCPI_RES_OK;    
+}
+
+scpi_result_t radio_powerQ(scpi_t* context)
+{
+    radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
+    SCPI_ResultInt(context, radio.RegPaConfig.bits.OutputPower);  
+    return SCPI_RES_OK;
+}
+
+scpi_result_t radio_diomap(scpi_t* context)
+{
+    int32_t dioN, map_value;
+    
+    if (!SCPI_ParamInt(context, &dioN, TRUE))
+        return SCPI_RES_ERR;  
+        
+    if (!SCPI_ParamInt(context, &map_value, TRUE))
+        return SCPI_RES_ERR;    
+      
+    if (dioN < 4) {
+        radio.RegDioMapping1.octet = radio.read_reg(REG_DIOMAPPING1);
+        switch (dioN) {
+            case 0: radio.RegDioMapping1.bits.Dio0Mapping = map_value; break;
+            case 1: radio.RegDioMapping1.bits.Dio1Mapping = map_value; break;
+            case 2: radio.RegDioMapping1.bits.Dio2Mapping = map_value; break;
+            case 3: radio.RegDioMapping1.bits.Dio3Mapping = map_value; break;
+        } // ...switch (dioN)
+        radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
+    } else {
+        radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
+        switch (dioN) {
+            case 4: radio.RegDioMapping2.bits.Dio4Mapping = map_value; break;
+            case 5: radio.RegDioMapping2.bits.Dio5Mapping = map_value; break;
+        } // ...switch (dioN)        
+        radio.write_reg(REG_DIOMAPPING2, radio.RegDioMapping2.octet);
+    }
+    
+    return SCPI_RES_OK;
+}
+
+scpi_result_t radio_diomapQ(scpi_t* context)
+{
+    int32_t dioN, map_value = -1;
+    
+    if (!SCPI_ParamInt(context, &dioN, TRUE))
+        return SCPI_RES_ERR; 
+        
+    if (dioN < 4) {
+        radio.RegDioMapping1.octet = radio.read_reg(REG_DIOMAPPING1);
+        switch (dioN) {
+            case 0: map_value = radio.RegDioMapping1.bits.Dio0Mapping; break;
+            case 1: map_value = radio.RegDioMapping1.bits.Dio1Mapping; break;
+            case 2: map_value = radio.RegDioMapping1.bits.Dio2Mapping; break;
+            case 3: map_value = radio.RegDioMapping1.bits.Dio3Mapping; break;
+        } // ...switch (dioN)        
+    } else {
+        radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
+        switch (dioN) {
+            case 4: map_value = radio.RegDioMapping2.bits.Dio4Mapping; break;
+            case 5: map_value = radio.RegDioMapping2.bits.Dio5Mapping; break;
+        } // ...switch (dioN)          
+    }
+    
+    SCPI_ResultInt(context, map_value);
+    return SCPI_RES_OK;    
+}
+
+scpi_result_t radio_reg(scpi_t* context)
+{
+    int32_t addr, data;
+
+    if (!SCPI_ParamInt(context, &addr, TRUE))
+        return SCPI_RES_ERR;  
+        
+    if (!SCPI_ParamInt(context, &data, TRUE))
+        return SCPI_RES_ERR;  
+
+    radio.write_reg(addr, data);
+        
+    return SCPI_RES_OK;
+}
+
+scpi_result_t radio_regQ(scpi_t* context)
+{
+    int32_t addr;
+    
+    if (!SCPI_ParamInt(context, &addr, TRUE))
+        return SCPI_RES_ERR; 
+     
+    SCPI_ResultIntBase(context, radio.read_reg(addr), 16);
+    return SCPI_RES_OK;     
+}
+
+
+scpi_result_t radio_dioQ(scpi_t* context)
+{
+    int32_t dioN, value = -1;
+    
+    if (!SCPI_ParamInt(context, &dioN, TRUE))
+        return SCPI_RES_ERR;     
+        
+    switch (dioN) {
+        case 0: value = radio.dio0.read(); break;
+        case 1: value = radio.dio1.read(); break;
+        case 2: value = dio2_pin.read(); break;
+        case 3: value = dio3_pin.read(); break;
+        case 4: value = dio4_pin.read(); break;
+        case 5: value = dio5_pin.read(); break;
+        default:      
+            return SCPI_RES_ERR;          
+    } // ..switch (dioN)      
+    
+    SCPI_ResultInt(context, value);
+    return SCPI_RES_OK;    
+}
+
+scpi_result_t radio_freq(scpi_t* context)
+{
+    double MHz;
+    
+    if (!SCPI_ParamDouble(context, &MHz, TRUE))
+        return SCPI_RES_ERR; 
+    
+    radio.set_frf_MHz(MHz);
+    
+    return SCPI_RES_OK;
+}
+
+scpi_result_t radio_freqQ(scpi_t* context)
+{
+    SCPI_ResultDouble(context, radio.get_frf_MHz());
+    return SCPI_RES_OK;
+}
+
+scpi_result_t lora_cr(scpi_t* context)
+{
+    int32_t i;
+    
+    if (!SCPI_ParamInt(context, &i, TRUE))
+        return SCPI_RES_ERR;
+
+    if (!is_lora())            
+        return SCPI_RES_ERR;    
+        
+    lora.setCodingRate(i);
+    return SCPI_RES_OK;    
+}
+
+scpi_result_t lora_crQ(scpi_t* context)
+{
+    if (!is_lora())     
+        return SCPI_RES_ERR;    
+
+     SCPI_ResultInt(context, lora.getCodingRate(false));
+     return SCPI_RES_OK;   
+}  
+
+scpi_result_t lora_invrx(scpi_t* context)
+{
+    scpi_bool_t param1;
+    
+    if (!SCPI_ParamBool(context, &param1, TRUE))
+        return SCPI_RES_ERR;
+            
+    if (!is_lora())     
+        return SCPI_RES_ERR;   
+        
+    lora.invert_rx(param1);
+    return SCPI_RES_OK; 
+}
+
+scpi_result_t lora_invrxQ(scpi_t* context)
+{
+    if (!is_lora())     
+        return SCPI_RES_ERR;   
+        
+    lora.RegTest33.octet = radio.read_reg(REG_LR_TEST33);
+    SCPI_ResultBool(context, lora.RegTest33.bits.invert_i_q );
+    return SCPI_RES_OK;                
+}
+
+scpi_result_t lora_invtx(scpi_t* context)
+{
+    scpi_bool_t param1;
+    
+    if (!SCPI_ParamBool(context, &param1, TRUE))
+        return SCPI_RES_ERR;
+            
+    if (!is_lora())     
+        return SCPI_RES_ERR;  
+        
+    lora.invert_tx(param1);
+    return SCPI_RES_OK;           
+}
+
+scpi_result_t lora_invtxQ(scpi_t* context)
+{
+    if (!is_lora())     
+        return SCPI_RES_ERR;  
+        
+    lora.RegTest33.octet = radio.read_reg(REG_LR_TEST33);
+    SCPI_ResultBool(context, !lora.RegTest33.bits.chirp_invert_tx);        
+    return SCPI_RES_OK;    
+}
+
+scpi_result_t lora_crc(scpi_t* context)
+{
+    scpi_bool_t param1;
+    
+    if (!SCPI_ParamBool(context, &param1, TRUE))
+        return SCPI_RES_ERR;
+            
+    if (!is_lora())             
+        return SCPI_RES_ERR;       
+
+    lora.setRxPayloadCrcOn(param1);
+    return SCPI_RES_OK;    
+}
+
+scpi_result_t lora_crcQ(scpi_t* context)
+{
+    if (!is_lora())     
+        return SCPI_RES_ERR;   
+        
+    SCPI_ResultBool(context, lora.getRxPayloadCrcOn());
+    return SCPI_RES_OK;         
+}
+ 
+scpi_result_t lora_ih(scpi_t* context)
+{
+    scpi_bool_t param1;
+    
+    if (!SCPI_ParamBool(context, &param1, TRUE))
+        return SCPI_RES_ERR;
+            
+    if (!is_lora())             
+        return SCPI_RES_ERR;    
+
+    lora.setHeaderMode(param1);   
+    return SCPI_RES_OK;    
+}
+
+scpi_result_t lora_ihQ(scpi_t* context)
+{
+    if (!is_lora())     
+        return SCPI_RES_ERR;     
+        
+    SCPI_ResultBool(context, lora.getHeaderMode());
+    return SCPI_RES_OK;
+}
+
+scpi_result_t lora_ldro(scpi_t* context)
+{
+    scpi_bool_t param1;
+    
+    if (!SCPI_ParamBool(context, &param1, TRUE))
+        return SCPI_RES_ERR;
+
+    if (!is_lora())             
+        return SCPI_RES_ERR; 
+        
+    if (radio.type == SX1272) {
+        lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
+        lora.RegModemConfig.sx1272bits.LowDataRateOptimize = param1;
+        radio.write_reg(REG_LR_MODEMCONFIG, lora.RegModemConfig.octet);
+    } else if (radio.type == SX1276) {
+        lora.RegModemConfig3.octet = radio.read_reg(REG_LR_MODEMCONFIG3);
+        lora.RegModemConfig3.sx1276bits.LowDataRateOptimize = param1;
+        radio.write_reg(REG_LR_MODEMCONFIG3, lora.RegModemConfig3.octet);
+    } else
+        return SCPI_RES_ERR; 
+    
+    return SCPI_RES_OK;                
+}
+
+scpi_result_t lora_ldroQ(scpi_t* context)
+{
+    scpi_bool_t param1;
+    
+    if (!is_lora())     
+        return SCPI_RES_ERR;   
+        
+    if (radio.type == SX1272) {
+        lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
+        param1 = lora.RegModemConfig.sx1272bits.LowDataRateOptimize;
+    } else if (radio.type == SX1276) {
+        lora.RegModemConfig3.octet = radio.read_reg(REG_LR_MODEMCONFIG3);
+        param1 = lora.RegModemConfig3.sx1276bits.LowDataRateOptimize;
+    } else
+        return SCPI_RES_ERR;         
+        
+    SCPI_ResultBool(context, param1);
+    return SCPI_RES_OK;    
+}
+
+scpi_result_t lora_bw(scpi_t* context)
+{
+    double KHz;
+        
+    if (!is_lora())         
+        return SCPI_RES_ERR;
+        
+    if (!SCPI_ParamDouble(context, &KHz, TRUE))
+        return SCPI_RES_ERR;         
+            
+    lora.setBw_KHz(KHz);
+    return SCPI_RES_OK;
+}
+
+scpi_result_t lora_bwQ(scpi_t* context)
+{
+    int bw;
+    double khz;
+    
+    if (!is_lora()) 
+        return SCPI_RES_ERR;
+        
+    bw = lora.getBw();
+    
+    if (radio.type == SX1272) {
+        switch (bw) {
+            case 0: khz = 125; break;
+            case 1: khz = 250; break;
+            case 2: khz = 500; break;                
+            default: return SCPI_RES_ERR;
+        }
+    } else if (radio.type == SX1276) {
+        switch (bw) {
+            case 0: khz = 7.8; break;
+            case 1: khz = 10.4; break;
+            case 2: khz = 15.6; break;
+            case 3: khz = 20.8; break;
+            case 4: khz = 31.25; break;
+            case 5: khz = 41.7; break;
+            case 6: khz = 62.5; break;
+            case 7: khz = 125; break;
+            case 8: khz = 250; break;
+            case 9: khz = 500; break;            
+            default: return SCPI_RES_ERR;
+        }
+    } else
+        return SCPI_RES_ERR;
+    
+    SCPI_ResultDouble(context, khz);
+    return SCPI_RES_OK;    
+}
+
+scpi_result_t lora_sf(scpi_t* context)
+{
+    int32_t i;
+        
+    if (!is_lora())         
+        return SCPI_RES_ERR;      
+    
+    if (!SCPI_ParamInt(context, &i, TRUE))
+        return SCPI_RES_ERR;          
+        
+    lora.setSf(i);
+    return SCPI_RES_OK; 
+}
+
+scpi_result_t lora_sfQ(scpi_t* context)
+{
+    if (!is_lora())     
+        return SCPI_RES_ERR;    
+        
+     SCPI_ResultInt(context, lora.getSf());
+     return SCPI_RES_OK; 
+}
+
+scpi_result_t lora_feiQ(scpi_t* context)
+{
+    if (!is_lora())     
+        return SCPI_RES_ERR;     
+        
+    SCPI_ResultInt(context, lora.get_freq_error_Hz());    
+    return SCPI_RES_OK;                
+}
+
+scpi_result_t lora_pktsnrQ(scpi_t* context)
+{
+    if (!is_lora())     
+        return SCPI_RES_ERR;     
+        
+    SCPI_ResultDouble(context, lora.RegPktSnrValue / 4.0);
+    return SCPI_RES_OK;                
+}
+
+scpi_result_t lora_pktrssiQ(scpi_t* context)
+{
+    if (!is_lora())     
+        return SCPI_RES_ERR;
+        
+    SCPI_ResultDouble(context, lora.get_pkt_rssi());
+    return SCPI_RES_OK;
+}
+
+
+scpi_result_t lora_prelen(scpi_t* context)
+{
+    int32_t i;
+        
+    if (!is_lora())         
+        return SCPI_RES_ERR;
+    
+    if (!SCPI_ParamInt(context, &i, TRUE))
+        return SCPI_RES_ERR;    
+        
+    lora.RegPreamble = i;
+    radio.write_u16(REG_LR_PREAMBLEMSB, lora.RegPreamble);  
+    return SCPI_RES_OK;       
+}
+
+scpi_result_t lora_prelenQ(scpi_t* context)
+{
+    if (!is_lora())     
+        return SCPI_RES_ERR;
+        
+    lora.RegPreamble = radio.read_u16(REG_LR_PREAMBLEMSB);
+    SCPI_ResultInt(context, lora.RegPreamble);    
+    return SCPI_RES_OK;      
+}
+
+scpi_result_t lora_txc(scpi_t* context)
+{
+    scpi_bool_t param1;
+    
+    if (!is_lora())     
+        return SCPI_RES_ERR;         
+    
+    if (!SCPI_ParamBool(context, &param1, TRUE))
+        return SCPI_RES_ERR;
+        
+    lora.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);        
+    lora.RegModemConfig2.sx1276bits.TxContinuousMode = param1;
+    radio.write_reg(REG_LR_MODEMCONFIG2, lora.RegModemConfig2.octet);    
+    
+    return SCPI_RES_OK;
+}
+
+scpi_result_t lora_txcQ(scpi_t* context)
+{
+    if (!is_lora())     
+        return SCPI_RES_ERR;        
+        
+    lora.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);        
+    SCPI_ResultBool(context, lora.RegModemConfig2.sx1276bits.TxContinuousMode);
+    
+    return SCPI_RES_OK;    
+}
+
+
+#ifdef TARGET_MOTE_L152RC
+scpi_result_t pd2_set(scpi_t* context)
+{
+    scpi_bool_t param1;
+    
+    if (!SCPI_ParamBool(context, &param1, TRUE))
+        return SCPI_RES_ERR;
+
+    pd2 = param1;
+    return SCPI_RES_OK;
+}
+
+scpi_result_t pd2_get(scpi_t* context)
+{
+    SCPI_ResultBool(context, pd2.read());
+    return SCPI_RES_OK;
+}
+
+scpi_result_t rfswQ(scpi_t* context)
+{
+    SCPI_ResultBool(context, rfsw1.read());
+    SCPI_ResultBool(context, rfsw2.read());
+    return SCPI_RES_OK;
+}
+
+scpi_result_t vbatQ(scpi_t* context)
+{
+    bool bat_flag = false;
+    bool BatOffState;
+    
+    if(gps.en_invert == true)
+        BatOffState = true;
+    else
+        BatOffState = false;
+    
+    if(gps_en == BatOffState)
+    {
+        bat_flag = true;
+        gps.enable(1);
+    }
+        
+    SCPI_ResultDouble(context, bat->read()*AIN_VREF*AIN_VBAT_DIV);
+    
+    if(bat_flag)
+        gps.enable(0);
+        
+    return SCPI_RES_OK;      
+}
+
+scpi_result_t gps_enable(scpi_t* context)
+{
+    scpi_bool_t param1;
+    
+    if (!SCPI_ParamBool(context, &param1, TRUE))
+        return SCPI_RES_ERR;    
+        
+    gps.enable(param1);
+    return SCPI_RES_OK;
+}
+
+scpi_result_t gps_enableQ(scpi_t* context)
+{
+    SCPI_ResultBool(context, gps.enabled());
+    
+    return SCPI_RES_OK;      
+}
+
+scpi_result_t gps_numCords(scpi_t* context)
+{
+    int32_t i;
+    
+    if (!SCPI_ParamInt(context, &i, TRUE))
+        return SCPI_RES_ERR;   
+        
+    gps_coord_cnt = i; 
+    return SCPI_RES_OK;
+}
+
+scpi_result_t gps_numCordsQ(scpi_t* context)
+{
+    SCPI_ResultInt(context, gps_coord_cnt);    
+    return SCPI_RES_OK;    
+}
+
+scpi_result_t gps_longitude(scpi_t* context)
+{
+    if (!SCPI_ParamDouble(context, &gps.Longitude, TRUE))
+        return SCPI_RES_ERR;   
+        
+    return SCPI_RES_OK;         
+}
+
+scpi_result_t gps_longitudeQ(scpi_t* context)
+{
+    SCPI_ResultDouble(context, gps.Longitude);
+    return SCPI_RES_OK;     
+}
+
+scpi_result_t gps_latitude(scpi_t* context)
+{
+    if (!SCPI_ParamDouble(context, &gps.Latitude, TRUE))
+        return SCPI_RES_ERR;   
+        
+    return SCPI_RES_OK;           
+}
+
+scpi_result_t gps_latitudeQ(scpi_t* context)
+{
+    SCPI_ResultDouble(context, gps.Latitude);
+    return SCPI_RES_OK; 
+} 
+
+scpi_result_t mma_idQ(scpi_t* context)
+{
+    SCPI_ResultIntBase(context, mma8451q.read_single(MMA8451_ID), 16);
+    return SCPI_RES_OK;      
+}
+
+scpi_result_t mpl_idQ(scpi_t* context)
+{
+    SCPI_ResultIntBase(context, mpl3115a2.read(MPL3115_ID), 16);
+    return SCPI_RES_OK;       
+}
+
+scpi_result_t sx9500_reset(scpi_t* context)
+{
+    sx9500.reset();
+    return SCPI_RES_OK;
+}
+
+scpi_result_t sx9500_reg(scpi_t* context)
+{
+    int32_t addr, data;
+
+    if (!SCPI_ParamInt(context, &addr, TRUE))
+        return SCPI_RES_ERR;  
+        
+    if (!SCPI_ParamInt(context, &data, TRUE))
+        return SCPI_RES_ERR;  
+
+    sx9500.write(addr, data);
+        
+    return SCPI_RES_OK;
+}
+
+scpi_result_t sx9500_regQ(scpi_t* context)
+{
+    int32_t addr;
+    
+    if (!SCPI_ParamInt(context, &addr, TRUE))
+        return SCPI_RES_ERR; 
+     
+    SCPI_ResultIntBase(context, sx9500.read_single(addr), 16);
+    return SCPI_RES_OK;     
+}
+
+#endif /* TARGET_MOTE_L152RC */
+
+static const scpi_command_t scpi_commands[] = {
+    // http://na.support.keysight.com/pna/help/latest/Programming/GP-IB_Command_Finder/Common_Commands.htm
+    /* IEEE Mandated Commands (SCPI std V1999.0 4.1.1) */
+    { .pattern = "*CLS", .callback = SCPI_CoreCls,},    // clear status
+    { .pattern = "*ESE", .callback = SCPI_CoreEse,},    // standard event status enable
+    { .pattern = "*ESE?", .callback = SCPI_CoreEseQ,},
+    { .pattern = "*ESR?", .callback = SCPI_CoreEsrQ,},  // event status query
+    { .pattern = "*IDN?", .callback = SCPI_CoreIdnQ,},  // identification query
+    { .pattern = "*OPC", .callback = SCPI_CoreOpc,},    // operation complete command
+    { .pattern = "*OPC?", .callback = SCPI_CoreOpcQ,},  // operation complete query
+    { .pattern = "*RST", .callback = SCPI_CoreRst,},    // reset command
+    { .pattern = "*SRE", .callback = SCPI_CoreSre,},    // service request enable command
+    { .pattern = "*SRE?", .callback = SCPI_CoreSreQ,},  // service request enable query
+    { .pattern = "*STB?", .callback = SCPI_CoreStbQ,},  // status byte register query
+    { .pattern = "*TST?", .callback = SCPI_CoreTstQ,},  // self-test query
+    { .pattern = "*WAI", .callback = SCPI_CoreWai,},    // wait to continue
+
+    /* Required SCPI commands (SCPI std V1999.0 4.2.1) */
+    {.pattern = "SYSTem:ERRor[:NEXT]?", .callback = SCPI_SystemErrorNextQ,},
+    {.pattern = "SYSTem:ERRor:COUNt?", .callback = SCPI_SystemErrorCountQ,},
+    {.pattern = "SYSTem:VERSion?", .callback = SCPI_SystemVersionQ,},
+
+    //{.pattern = "STATus:OPERation?", .callback = scpi_stub_callback,},
+    //{.pattern = "STATus:OPERation:EVENt?", .callback = scpi_stub_callback,},
+    //{.pattern = "STATus:OPERation:CONDition?", .callback = scpi_stub_callback,},
+    //{.pattern = "STATus:OPERation:ENABle", .callback = scpi_stub_callback,},
+    //{.pattern = "STATus:OPERation:ENABle?", .callback = scpi_stub_callback,},
+
+    {.pattern = "STATus:QUEStionable[:EVENt]?", .callback = SCPI_StatusQuestionableEventQ,},
+    //{.pattern = "STATus:QUEStionable:CONDition?", .callback = scpi_stub_callback,},
+    {.pattern = "STATus:QUEStionable:ENABle", .callback = SCPI_StatusQuestionableEnable,},
+    {.pattern = "STATus:QUEStionable:ENABle?", .callback = SCPI_StatusQuestionableEnableQ,},
+
+    {.pattern = "STATus:PRESet", .callback = SCPI_StatusPreset,},
+
+    /* DMM */
+    /*   
+    {.pattern = "SYSTem:COMMunication:TCPIP:CONTROL?", .callback = SCPI_SystemCommTcpipControlQ,},
+
+    {.pattern = "TEST:BOOL", .callback = TEST_Bool,},
+    {.pattern = "TEST#:NUMbers#", .callback = TEST_Numbers,},*/
+    
+    /*{.pattern = "TEST:CHOice?", .callback = TEST_ChoiceQ,},*/
+    
+    {.pattern = "BUSY?", .callback = tx_busyQ,},
+
+    {.pattern = "RAdio:FIfo", .callback = radio_fifo,},
+    {.pattern = "RAdio:FIfo?", .callback = radio_fifoQ,},
+    {.pattern = "RAdio:BINFIfo", .callback = radio_binFifo,},
+    {.pattern = "RAdio:BINFIfo?", .callback = radio_binFifoQ,},
+    {.pattern = "RAdio:MODulation", .callback = radio_modulation,},
+    {.pattern = "RAdio:MODulation?", .callback = radio_modulationQ,},
+    {.pattern = "RAdio:RSSI?", .callback = radio_rssiQ,},
+    {.pattern = "RAdio:OPmode", .callback = radio_opmode,},
+    {.pattern = "RAdio:OPmode?", .callback = radio_opmodeQ,},
+    {.pattern = "RAdio:PASelect", .callback = radio_PASelect,},
+    {.pattern = "RAdio:PASelect?", .callback = radio_PASelectQ,},
+    {.pattern = "RAdio:OCP", .callback = radio_ocp,},
+    {.pattern = "RAdio:OCP?", .callback = radio_ocpQ,},
+    {.pattern = "RAdio:POWer", .callback = radio_power,},
+    {.pattern = "RAdio:POWer?", .callback = radio_powerQ,},
+    {.pattern = "RAdio:BGR", .callback = radio_bgr,},
+    {.pattern = "RAdio:BGR?", .callback = radio_bgrQ,},
+    {.pattern = "RAdio:LNABoost", .callback = radio_lnaBoost,},
+    {.pattern = "RAdio:LNABoost?", .callback = radio_lnaBoostQ,},    
+    {.pattern = "RAdio:FREQuency", .callback = radio_freq,},
+    {.pattern = "RAdio:FREQuency?", .callback = radio_freqQ,},
+    {.pattern = "RAdio:DIOMap", .callback = radio_diomap,},
+    {.pattern = "RAdio:DIOMap?", .callback = radio_diomapQ,},
+    {.pattern = "RAdio:DIO?", .callback = radio_dioQ,},
+    {.pattern = "RAdio:REGister", .callback = radio_reg,},
+    {.pattern = "RAdio:REGister?", .callback = radio_regQ,},
+       
+    {.pattern = "RAdio:FSK:SYNC", .callback = fsk_sync,},
+    {.pattern = "RAdio:FSK:SYNC?", .callback = fsk_syncQ,}, 
+    {.pattern = "RAdio:FSK:FDev", .callback = fsk_fdev,},
+    {.pattern = "RAdio:FSK:FDev?", .callback = fsk_fdevQ,}, 
+    {.pattern = "RAdio:FSK:BITRate", .callback = fsk_bitrate,},
+    {.pattern = "RAdio:FSK:BITRate?", .callback = fsk_bitrateQ,},     
+    {.pattern = "RAdio:FSK:PRELen", .callback = fsk_prelen,},
+    {.pattern = "RAdio:FSK:PRELen?", .callback = fsk_prelenQ,},  
+    {.pattern = "RAdio:FSK:RXBW", .callback = fsk_rxbw,},
+    {.pattern = "RAdio:FSK:RXBW?", .callback = fsk_rxbwQ,},        
+    {.pattern = "RAdio:FSK:AFCBW", .callback = fsk_afcbw,},
+    {.pattern = "RAdio:FSK:AFCBW?", .callback = fsk_afcbwQ,}, 
+    {.pattern = "RAdio:FSK:DCFree", .callback = fsk_dcfree,},
+    {.pattern = "RAdio:FSK:DCFree?", .callback = fsk_dcfreeQ,},       
+    {.pattern = "RAdio:FSK:RXTrigger", .callback = fsk_rxtrig,},
+    {.pattern = "RAdio:FSK:RXTrigger?", .callback = fsk_rxtrigQ,},     
+    {.pattern = "RAdio:FSK:DATAMode", .callback = fsk_datamode,},
+    {.pattern = "RAdio:FSK:DATAMode?", .callback = fsk_datamodeQ,}, 
+    {.pattern = "RAdio:FSK:BT", .callback = fsk_bt,},
+    {.pattern = "RAdio:FSK:BT?", .callback = fsk_btQ,},     
+    
+    {.pattern = "RAdio:LORa:BW", .callback = lora_bw,},
+    {.pattern = "RAdio:LORa:BW?", .callback = lora_bwQ,},    
+    {.pattern = "RAdio:LORa:SF", .callback = lora_sf,},
+    {.pattern = "RAdio:LORa:SF?", .callback = lora_sfQ,},     
+    {.pattern = "RAdio:LORa:TXContinuous", .callback = lora_txc,},
+    {.pattern = "RAdio:LORa:TXContinuous?", .callback = lora_txcQ,},         
+    {.pattern = "RAdio:LORa:PRELen", .callback = lora_prelen,},
+    {.pattern = "RAdio:LORa:PRELen?", .callback = lora_prelenQ,},    
+    {.pattern = "RAdio:LORa:CR", .callback = lora_cr,},
+    {.pattern = "RAdio:LORa:CR?", .callback = lora_crQ,},      
+    {.pattern = "RAdio:LORa:LDRO", .callback = lora_ldro,},
+    {.pattern = "RAdio:LORa:LDRO?", .callback = lora_ldroQ,},
+    {.pattern = "RAdio:LORa:FEI?", .callback = lora_feiQ,},         
+    {.pattern = "RAdio:LORa:PKTSnr?", .callback = lora_pktsnrQ,},   
+    {.pattern = "RAdio:LORa:PKTRssi?", .callback = lora_pktrssiQ,},     
+    {.pattern = "RAdio:LORa:Ih", .callback = lora_ih,},
+    {.pattern = "RAdio:LORa:Ih?", .callback = lora_ihQ,},        
+    {.pattern = "RAdio:LORa:CRC", .callback = lora_crc,},
+    {.pattern = "RAdio:LORa:CRC?", .callback = lora_crcQ,},  
+    {.pattern = "RAdio:LORa:INVRx", .callback = lora_invrx,},
+    {.pattern = "RAdio:LORa:INVRx?", .callback = lora_invrxQ,},  
+    {.pattern = "RAdio:LORa:INVTx", .callback = lora_invtx,},
+    {.pattern = "RAdio:LORa:INVTx?", .callback = lora_invtxQ,},            
+    
+#ifdef TARGET_MOTE_L152RC
+    {.pattern = "PD2", .callback = pd2_set,},
+    {.pattern = "PD2?", .callback = pd2_get,},
+    {.pattern = "RFSW?", .callback = rfswQ,},
+    {.pattern = "VBAT?", .callback = vbatQ,},
+    
+    {.pattern = "GPS:ENable", .callback = gps_enable,},
+    {.pattern = "GPS:ENable?", .callback = gps_enableQ,},
+    {.pattern = "GPS:NUMCoords", .callback = gps_numCords,},
+    {.pattern = "GPS:NUMCoords?", .callback = gps_numCordsQ,},   
+    {.pattern = "GPS:LOngitude", .callback = gps_longitude,},
+    {.pattern = "GPS:LOngitude?", .callback = gps_longitudeQ,},  
+    {.pattern = "GPS:LAtitude", .callback = gps_latitude,},
+    {.pattern = "GPS:LAtitude?", .callback = gps_latitudeQ,},  
+    
+    {.pattern = "MMA:ID?", .callback = mma_idQ,}, 
+    
+    {.pattern = "MPL:ID?", .callback = mpl_idQ,},
+    
+    {.pattern = "SX9500:RST", .callback = sx9500_reset,},
+    {.pattern = "SX9500:REGister", .callback = sx9500_reg,},
+    {.pattern = "SX9500:REGister?", .callback = sx9500_regQ,},
+    
+#endif /* TARGET_MOTE_L152RC */
+    
+    SCPI_CMD_LIST_END
+};
+
+#ifdef TARGET_MOTE_L152RC
+void get_mote_version()
+{
+    char first;
+      
+    pc_7 = 1;
+    first = pc_1;
+    pc_7 = 0;
+    if (first && !pc_1) {
+        mote_version = MOTE_V2;
+        bat = new AnalogIn(PA_0);
+    } else {
+        mote_version = MOTE_V3;
+        bat = new AnalogIn(PA_1);
+    }
+}
+#endif
+
+static scpi_interface_t scpi_interface = {
+    .error = SCPI_Error,
+    .write = SCPI_Write,
+    .control = SCPI_Control,
+    .flush = SCPI_Flush,
+    .reset = SCPI_Reset,
+};
+
+#define SCPI_INPUT_BUFFER_LENGTH 256
+static char scpi_input_buffer[SCPI_INPUT_BUFFER_LENGTH];
+static scpi_reg_val_t scpi_regs[SCPI_REG_COUNT];
+
+scpi_t scpi_context = {
+    cmdlist : scpi_commands,
+    buffer : {
+        length : SCPI_INPUT_BUFFER_LENGTH,
+        position : 0,
+        data : scpi_input_buffer
+    },
+    param_list : { 0 }, 
+    interface : &scpi_interface,
+    output_count : 0,
+    input_count : 0,
+    cmd_error : false,
+    error_queue : NULL,
+    registers : scpi_regs,
+    units : scpi_units_def,
+    user_context : NULL,
+    parser_state : {
+        programHeader : { SCPI_TOKEN_UNKNOWN, NULL, 0 },
+        programData : { SCPI_TOKEN_UNKNOWN, NULL, 0 },
+        numberOfParameters : 0,
+        termination : SCPI_MESSAGE_TERMINATION_NONE
+    },
+    idn : {"semtech", "na-mote", NULL, "01-02"}
+};
+
+void scpi_def_init()
+{
+    radio.rf_switch = rfsw_callback;
+    radio.get_frf_MHz();    // get HF bit
+    
+#ifdef TARGET_MOTE_L152RC
+
+    get_mote_version();
+    if (mote_version == MOTE_V3) {
+        gps.en_invert = false;
+        scpi_context.idn[3] = "3";
+    } else {
+        gps.en_invert = true;
+        scpi_context.idn[3] = "2";
+    }
+        
+    gps.init();
+
+#endif /* TARGET_MOTE_L152RC */
+}