firstTest
Dependencies: mbed lib_sx9500 SX127x lib_mpl3115a2 lib_mma8451q lib_gps libscpi
Diff: scpi-def.cpp
- Revision:
- 0:1aa6d4a96bf1
- Child:
- 1:96123698b488
diff -r 000000000000 -r 1aa6d4a96bf1 scpi-def.cpp --- /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, ©_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, ¶m1, 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, ¶m1, 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, ¶m1, 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, ¶m1, 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, ¶m1, 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, ¶m1, 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, ¶m1, 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, ¶m1, 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, ¶m1, 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 */ +}