SCPI interface to SX1272 and SX1276

Dependencies:   SX127x lib_gps lib_mma8451q lib_mpl3115a2 lib_sx9500 libscpi mbed

Description

This program implements a SCPI command parser. When connected via the debug virtual comm port, you can command the radio and peripherals to perform specific tasks or to set specific parameters. The serial port defaults to 9600bps N-8-1.

Example

The following exampling causes the NA Mote to transmit a continuous LoRa signal.

Example SCPI Commands

*IDN?
RA:MOD LORA
RA:FREQ 903
RA:PAS PA_BOOST
RA:OCP 170
RA:BGR 7
RA:POW 15
RA:LORA:TXContinuous ON
RA:FI "test"

Commands

SCPI is case-insensitive. Commands can be entered lower case.

  • RAdio
    • :FIfo "text" write to fifo, and transmit packet
    • :FIfo? read from fifo (last received packet)
    • :REGister { address }, {value} write radio register (SCPI takes #H for hex prefix)
    • :REGister? { address } read radio register (SCPI takes #H for hex prefix)
    • :MODulation { FSK | OOK | LORa } set modem type
    • :MODulation? get modem type
    • :OPmode { SLE | STB | FST | TX | FSR | RXC | RXS | CAD } set mode
    • :OPmode? get mode
    • :DIOMap { 0 - 5 }, { 0 - 3 } set DIO pin function {pin number}, {map value}
    • :DIOMap? { 0 - 5 } get DIO pin function {pin number}
    • :DIO? { 0 - 5 } read DIO pin level
    • :RSSI? read received signal strength (if in RXC mode)
    • :PASelect { RFO | PA_BOOST } set RF output pin
    • :PASelect? get RF output pin selected
    • :OCP {mA} set over current protection
    • :OCP? read current limit
    • :POWer {0 to 15} set OutputPower
    • :POWer? get OutputPower
    • :BGR { 0 - 7 } set PA ref current
    • :BGR? get PA ref current
    • :FREQuency {MHz} set FRF
    • :FREQuency? get FRF
    • :LNABoost { OFF | ON } set LNA boost
    • :LNABoost? get LNA boost
    • :LORa
      • :BW {KHz} set lora bandwidth
      • :BW? get lora bandwidth (in KHz)
      • :SF {7 to 12} set spreading factor
      • :SF? get spreading factor
      • :TXContinuous { OFF | ON } set continuous TX (end transmit by turning off)
      • :TXContinuous? get continuous TX
      • :PRELen {n-symbols} set preamble length
      • :PRELen? get preamble length
      • :CR {0-4} set coding rate
      • :CR? get coding rate
      • :LDRO { OFF | ON } set LowDataRateOptimize bit
      • :LDRO? get LowDataRateOptimize bit
      • :CRC { OFF | ON} enable CRC in transmitted packet
      • :CRC? read CRC enabled state
      • :INVRx { OFF | ON } enable receiver spectral invert
      • :INVRx? get receiver inversion state
      • :INVTx { OFF | ON } enable transmitter spectral invert
      • :INVTx? get transmitter inversion state
      • :FEI? get frequency error of last received packet
      • :PKTSnr? get S/N (dB) of last received packet
    • :FSK
      • :DATAMode { CONT | PKT } select continuous/packet mode
      • :DATAMode? get packet mode / continuous
      • :FDev {Hz} set TX frequency deviation
      • :FDev? get TX frequency deviation
      • :BITRate {bps} set bit rate
      • :BITRate? get bit rate
      • :BT { 1.0 | 0.5 | 0.3 | 0.0 } set transmit shaping
      • :BT? get transmit shaping
      • :PRELen {n} set preamble size
      • :PRELen? get preamble size
      • :RXBW {Hz} set receive bandwidth
      • :RXBW? set receive bandwidth
      • :AFCBW {Hz} set receive bandwidth (during preamble)
      • :AFCBW? set receive bandwidth (during preamble)
      • :DCFree { OFF | MAN | WHIT } set DC-free encoding
      • :DCFree? get DC-free encoding
      • :RXTrigger { OFF | RSSI | PRE | BOTH } set RX trigger mode
      • :RXTrigger? get RX trigger selection

radio events

Radio events are reported into the Questionable Data Status Event Register, which is summarized in Bit 3 (QSB) of Status Byte Register.

enabling event and reading event

RA:MOD?
"LORa"
RA:OP?
"RXC"
STAT:QUES:ENAB 512
*STB?
8
STAT:QUES:EVEN?
512
RA:FI?
"4747474747474747"
*STB?
0

Bit 9 of QUEStionable event register indicates DIO0 event occurred upon radio packet reception.

NA Mote-72 specific commands

  • PD2 { OFF | ON } set power amplifier voltage state
  • PD2? get power amplifier voltage state
  • VBAT? read battery voltage
  • GPS
    • :EN { OFF | ON } enable GPS
    • :EN? get GPS enabled state
    • :NUMCoords {n} set count of coordinates received (use to clear count)
    • :NUMCoords? get count of coordinates received
    • :LOngitude {n} set longitude
    • :LOngitude? get longitude
    • :LAtitude {n} set latitude
    • :LAtitude? get latitude
  • MMA MMA8451Q
    • :ID? read ID register (WHO_AM_I == 0x1a)
  • MPL MPL3115A2
    • :ID? read ID register (WHO_AM_I == 0xc4)
  • SX9500
    • :RST reset SX9500
    • :REGister {addr}, {value} write SX9500 register
    • :REGister? {addr} read SX9500 register
Committer:
dudmuck
Date:
Wed Nov 01 22:54:05 2017 +0000
Revision:
11:5e67cde3fc62
Parent:
9:73e03383fd21
LEDs in test_interactive.cpp only for TARGET_MOTE_L152RC

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dudmuck 0:8767be3c1b7f 1 /*-
dudmuck 0:8767be3c1b7f 2 * Copyright (c) 2012-2013 Jan Breuer,
dudmuck 0:8767be3c1b7f 3 *
dudmuck 0:8767be3c1b7f 4 * All Rights Reserved
dudmuck 0:8767be3c1b7f 5 *
dudmuck 0:8767be3c1b7f 6 * Redistribution and use in source and binary forms, with or without
dudmuck 0:8767be3c1b7f 7 * modification, are permitted provided that the following conditions are
dudmuck 0:8767be3c1b7f 8 * met:
dudmuck 0:8767be3c1b7f 9 * 1. Redistributions of source code must retain the above copyright notice,
dudmuck 0:8767be3c1b7f 10 * this list of conditions and the following disclaimer.
dudmuck 0:8767be3c1b7f 11 * 2. Redistributions in binary form must reproduce the above copyright
dudmuck 0:8767be3c1b7f 12 * notice, this list of conditions and the following disclaimer in the
dudmuck 0:8767be3c1b7f 13 * documentation and/or other materials provided with the distribution.
dudmuck 0:8767be3c1b7f 14 *
dudmuck 0:8767be3c1b7f 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
dudmuck 0:8767be3c1b7f 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
dudmuck 0:8767be3c1b7f 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
dudmuck 0:8767be3c1b7f 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
dudmuck 0:8767be3c1b7f 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
dudmuck 0:8767be3c1b7f 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
dudmuck 0:8767be3c1b7f 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
dudmuck 0:8767be3c1b7f 22 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
dudmuck 0:8767be3c1b7f 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
dudmuck 0:8767be3c1b7f 24 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
dudmuck 0:8767be3c1b7f 25 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dudmuck 0:8767be3c1b7f 26 */
dudmuck 0:8767be3c1b7f 27
dudmuck 0:8767be3c1b7f 28 /**
dudmuck 0:8767be3c1b7f 29 * @file main.c
dudmuck 0:8767be3c1b7f 30 * @date Thu Nov 15 10:58:45 UTC 2012
dudmuck 0:8767be3c1b7f 31 *
dudmuck 0:8767be3c1b7f 32 * @brief SCPI parser test
dudmuck 0:8767be3c1b7f 33 *
dudmuck 0:8767be3c1b7f 34 *
dudmuck 0:8767be3c1b7f 35 */
dudmuck 0:8767be3c1b7f 36
dudmuck 0:8767be3c1b7f 37 #include <stdio.h>
dudmuck 0:8767be3c1b7f 38 #include <stdlib.h>
dudmuck 0:8767be3c1b7f 39 #include <string.h>
dudmuck 0:8767be3c1b7f 40 #include "scpi/scpi.h"
dudmuck 0:8767be3c1b7f 41 #include "../common/scpi-def.h"
ubhat 9:73e03383fd21 42 #include "mbed.h"
ubhat 9:73e03383fd21 43 #include "timer.h"
dudmuck 0:8767be3c1b7f 44
dudmuck 11:5e67cde3fc62 45
ubhat 9:73e03383fd21 46
dudmuck 0:8767be3c1b7f 47 Serial pc(USBTX, USBRX);
dudmuck 0:8767be3c1b7f 48
dudmuck 11:5e67cde3fc62 49 #ifdef TARGET_MOTE_L152RC
dudmuck 11:5e67cde3fc62 50 #define LED_TIMEOUT 50000 // usec
dudmuck 11:5e67cde3fc62 51 DigitalOut RedLed( PB_1 ); // Active Low
dudmuck 11:5e67cde3fc62 52 DigitalOut YellowLed( PB_10 ); // Active Low
dudmuck 11:5e67cde3fc62 53 DigitalOut UsrLed( PA_5 ); // Active High
dudmuck 11:5e67cde3fc62 54 TimerEvent_t RedLedTimer;
dudmuck 11:5e67cde3fc62 55 static void OnInputEvent( void );
dudmuck 11:5e67cde3fc62 56 #endif /* TARGET_MOTE_L152RC */
ubhat 9:73e03383fd21 57
dudmuck 11:5e67cde3fc62 58 #ifdef TARGET_MOTE_L152RC
dudmuck 11:5e67cde3fc62 59 #endif /* TARGET_MOTE_L152RC */
ubhat 9:73e03383fd21 60
ubhat 9:73e03383fd21 61
dudmuck 2:547cc73f8887 62 char smbuffer[64];
dudmuck 2:547cc73f8887 63
dudmuck 0:8767be3c1b7f 64 size_t SCPI_Write(scpi_t * context, const char * data, size_t len) {
dudmuck 0:8767be3c1b7f 65 (void) context;
dudmuck 0:8767be3c1b7f 66 return fwrite(data, 1, len, stdout);
dudmuck 0:8767be3c1b7f 67 }
dudmuck 0:8767be3c1b7f 68
dudmuck 0:8767be3c1b7f 69 scpi_result_t SCPI_Flush(scpi_t * context) {
dudmuck 0:8767be3c1b7f 70 fflush(stdout);
dudmuck 0:8767be3c1b7f 71 return SCPI_RES_OK;
dudmuck 0:8767be3c1b7f 72 }
dudmuck 0:8767be3c1b7f 73
dudmuck 0:8767be3c1b7f 74 int SCPI_Error(scpi_t * context, int_fast16_t err) {
dudmuck 0:8767be3c1b7f 75 (void) context;
dudmuck 0:8767be3c1b7f 76
dudmuck 0:8767be3c1b7f 77 printf("**ERROR: %d, \"%s\"\r\n", (int32_t) err, SCPI_ErrorTranslate(err));
dudmuck 0:8767be3c1b7f 78 return 0;
dudmuck 0:8767be3c1b7f 79 }
dudmuck 0:8767be3c1b7f 80
dudmuck 0:8767be3c1b7f 81 scpi_result_t SCPI_Control(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val) {
dudmuck 0:8767be3c1b7f 82 if (SCPI_CTRL_SRQ == ctrl) {
dudmuck 0:8767be3c1b7f 83 printf("**SRQ: 0x%X (%d)\r\n", val, val);
dudmuck 0:8767be3c1b7f 84 } else {
dudmuck 0:8767be3c1b7f 85 printf("**CTRL %02x: 0x%X (%d)\r\n", ctrl, val, val);
dudmuck 0:8767be3c1b7f 86 }
dudmuck 0:8767be3c1b7f 87 return SCPI_RES_OK;
dudmuck 0:8767be3c1b7f 88 }
dudmuck 0:8767be3c1b7f 89
dudmuck 0:8767be3c1b7f 90 /**
dudmuck 0:8767be3c1b7f 91 * Return 0 as OK and other number as error
dudmuck 0:8767be3c1b7f 92 */
dudmuck 0:8767be3c1b7f 93 scpi_result_t SCPI_Test(scpi_t * context) {
dudmuck 0:8767be3c1b7f 94 printf("**Test\r\n");
dudmuck 0:8767be3c1b7f 95 return (scpi_result_t)0;
dudmuck 0:8767be3c1b7f 96 }
dudmuck 0:8767be3c1b7f 97
dudmuck 0:8767be3c1b7f 98
dudmuck 0:8767be3c1b7f 99
dudmuck 0:8767be3c1b7f 100 scpi_result_t SCPI_SystemCommTcpipControlQ(scpi_t * context) {
dudmuck 0:8767be3c1b7f 101 return SCPI_RES_ERR;
dudmuck 0:8767be3c1b7f 102 }
dudmuck 0:8767be3c1b7f 103 /*
dudmuck 0:8767be3c1b7f 104 *
dudmuck 0:8767be3c1b7f 105 */
dudmuck 0:8767be3c1b7f 106 int get_kbd_str(char* buf, int size)
dudmuck 0:8767be3c1b7f 107 {
dudmuck 0:8767be3c1b7f 108 char c;
dudmuck 0:8767be3c1b7f 109 int i;
dudmuck 0:8767be3c1b7f 110 static int prev_len;
dudmuck 0:8767be3c1b7f 111
dudmuck 0:8767be3c1b7f 112 for (i = 0;;) {
dudmuck 0:8767be3c1b7f 113 if (pc.readable()) {
dudmuck 0:8767be3c1b7f 114 c = pc.getc();
dudmuck 0:8767be3c1b7f 115 if (c == 8) { // backspace
dudmuck 0:8767be3c1b7f 116 if (i > 0) {
dudmuck 0:8767be3c1b7f 117 pc.putc(8);
dudmuck 0:8767be3c1b7f 118 pc.putc(' ');
dudmuck 0:8767be3c1b7f 119 pc.putc(8);
dudmuck 0:8767be3c1b7f 120 i--;
dudmuck 0:8767be3c1b7f 121 }
dudmuck 0:8767be3c1b7f 122 } else if (c == '\r') {
dudmuck 0:8767be3c1b7f 123 if (i == 0) {
dudmuck 0:8767be3c1b7f 124 return prev_len; // repeat previous
dudmuck 0:8767be3c1b7f 125 } else {
dudmuck 0:8767be3c1b7f 126 buf[i++] = c;
dudmuck 0:8767be3c1b7f 127 buf[i] = 0; // null terminate
dudmuck 0:8767be3c1b7f 128 prev_len = i;
dudmuck 0:8767be3c1b7f 129 pc.putc('\r');
dudmuck 0:8767be3c1b7f 130 pc.putc('\n');
dudmuck 0:8767be3c1b7f 131 return i;
dudmuck 0:8767be3c1b7f 132 }
dudmuck 0:8767be3c1b7f 133 } else if (c == 3) {
dudmuck 0:8767be3c1b7f 134 // ctrl-C abort
dudmuck 0:8767be3c1b7f 135 //abort_key = true;
dudmuck 0:8767be3c1b7f 136 return -1;
dudmuck 0:8767be3c1b7f 137 } else if (i < size) {
dudmuck 0:8767be3c1b7f 138 buf[i++] = c;
dudmuck 0:8767be3c1b7f 139 pc.putc(c);
dudmuck 0:8767be3c1b7f 140 }
dudmuck 0:8767be3c1b7f 141 } else {
dudmuck 0:8767be3c1b7f 142 /* service something */
dudmuck 0:8767be3c1b7f 143 service_radio();
dudmuck 0:8767be3c1b7f 144 }
dudmuck 0:8767be3c1b7f 145 } // ...for()
dudmuck 0:8767be3c1b7f 146 }
dudmuck 0:8767be3c1b7f 147
dudmuck 0:8767be3c1b7f 148 int main(int argc, char** argv) {
dudmuck 0:8767be3c1b7f 149 (void) argc;
dudmuck 0:8767be3c1b7f 150 (void) argv;
dudmuck 0:8767be3c1b7f 151 //int result;
dudmuck 0:8767be3c1b7f 152
dudmuck 0:8767be3c1b7f 153 scpi_def_init();
dudmuck 0:8767be3c1b7f 154
dudmuck 0:8767be3c1b7f 155 SCPI_Init(&scpi_context);
dudmuck 0:8767be3c1b7f 156
dudmuck 0:8767be3c1b7f 157 printf("\r\nreset\r\n");
dudmuck 2:547cc73f8887 158
dudmuck 11:5e67cde3fc62 159
dudmuck 11:5e67cde3fc62 160 #ifdef TARGET_MOTE_L152RC
ubhat 9:73e03383fd21 161 RedLed = 1;
ubhat 9:73e03383fd21 162 YellowLed = 1;
ubhat 9:73e03383fd21 163 UsrLed = 1;
dudmuck 11:5e67cde3fc62 164 TimerInit( &RedLedTimer, OnInputEvent);
dudmuck 11:5e67cde3fc62 165 #endif /* TARGET_MOTE_L152RC */
ubhat 9:73e03383fd21 166
dudmuck 11:5e67cde3fc62 167
ubhat 9:73e03383fd21 168
dudmuck 0:8767be3c1b7f 169 while (1) {
ubhat 9:73e03383fd21 170 //fgets(smbuffer, 10, stdin);
ubhat 9:73e03383fd21 171
dudmuck 0:8767be3c1b7f 172 int len = get_kbd_str(smbuffer, sizeof(smbuffer));
ubhat 9:73e03383fd21 173 if (len > 0) {
dudmuck 11:5e67cde3fc62 174 #ifdef TARGET_MOTE_L152RC
ubhat 9:73e03383fd21 175 /* Blink Red LED on keyboard entry */
ubhat 9:73e03383fd21 176 RedLed = 0;
ubhat 9:73e03383fd21 177 TimerSetValue( &RedLedTimer, LED_TIMEOUT ); // set blink LED to 750ms
ubhat 9:73e03383fd21 178 TimerStart( &RedLedTimer );
dudmuck 11:5e67cde3fc62 179 #endif /* TARGET_MOTE_L152RC */
dudmuck 0:8767be3c1b7f 180 /*result =*/ SCPI_Input(&scpi_context, smbuffer, len);
dudmuck 0:8767be3c1b7f 181 }
dudmuck 0:8767be3c1b7f 182 }
dudmuck 0:8767be3c1b7f 183
dudmuck 0:8767be3c1b7f 184 //return (EXIT_SUCCESS);
dudmuck 0:8767be3c1b7f 185 }
dudmuck 0:8767be3c1b7f 186
dudmuck 11:5e67cde3fc62 187 #ifdef TARGET_MOTE_L152RC
ubhat 9:73e03383fd21 188 static void OnInputEvent( void )
ubhat 9:73e03383fd21 189 {
ubhat 9:73e03383fd21 190 TimerStop( &RedLedTimer);
ubhat 9:73e03383fd21 191
ubhat 9:73e03383fd21 192 RedLed = 1;
ubhat 9:73e03383fd21 193 }
dudmuck 11:5e67cde3fc62 194 #endif /* TARGET_MOTE_L152RC */