master
Ondřej Hruška 9 years ago
parent 7dab62b9aa
commit f62cd8df28
  1. 14
      main.c
  2. 2
      source/scpi_builtins.c
  3. 39
      source/scpi_parser.c
  4. 13
      source/scpi_parser.h

@ -29,6 +29,9 @@ int main(void)
send_cmd("USERERROR\n"); // string send_cmd("USERERROR\n"); // string
send_cmd("SYST:ERR:COUNT?\n"); send_cmd("SYST:ERR:COUNT?\n");
send_cmd("SYST:ERR:NEXT?\n"); send_cmd("SYST:ERR:NEXT?\n");
// test chardata
send_cmd("CHARD FOOBAR123_MOO_abcdef_HELLO, 12\n");
} }
@ -100,6 +103,12 @@ void cmd_USRERR_cb(const SCPI_argval_t *args)
} }
void cmd_CHARD_cb(const SCPI_argval_t *args)
{
printf("CHARData cb: %s, arg2 = %d", args[0].CHARDATA, args[1].INT);
}
// Command definition (mandatory commands are built-in) // Command definition (mandatory commands are built-in)
const SCPI_command_t scpi_commands[] = { const SCPI_command_t scpi_commands[] = {
{ {
@ -123,5 +132,10 @@ const SCPI_command_t scpi_commands[] = {
.levels = {"USeRERRor"}, .levels = {"USeRERRor"},
.callback = cmd_USRERR_cb .callback = cmd_USRERR_cb
}, },
{
.levels = {"CHARData"},
.params = {SCPI_DT_CHARDATA, SCPI_DT_INT},
.callback = cmd_CHARD_cb
},
{/*END*/} {/*END*/}
}; };

@ -9,7 +9,7 @@
#include "scpi_regs.h" #include "scpi_regs.h"
// response buffer // response buffer
static char sbuf[256]; static char sbuf[256]; // must be long enough to contain an error message
// ---------------- BUILTIN SCPI COMMANDS ------------------ // ---------------- BUILTIN SCPI COMMANDS ------------------

@ -21,11 +21,16 @@
#define IS_LCASE_CHAR(c) INRANGE((c), 'a', 'z') #define IS_LCASE_CHAR(c) INRANGE((c), 'a', 'z')
#define IS_UCASE_CHAR(c) INRANGE((c), 'A', 'Z') #define IS_UCASE_CHAR(c) INRANGE((c), 'A', 'Z')
#define IS_NUMBER_CHAR(c) INRANGE((c), '0', '9') #define IS_NUMBER_CHAR(c) INRANGE((c), '0', '9')
#define IS_MULTIPLIER_CHAR(c) ((c) == 'k' || (c) == 'M' || (c) == 'G' || (c) == 'm' || (c) == 'u' || (c) == 'n' || (c) == 'p') //#define IS_MULTIPLIER_CHAR(c) ((c) == 'k' || (c) == 'M' || (c) == 'G' || (c) == 'm' || (c) == 'u' || (c) == 'n' || (c) == 'p')
#define IS_IDENT_CHAR(c) (IS_LCASE_CHAR((c)) || IS_UCASE_CHAR((c)) || IS_NUMBER_CHAR((c)) || (c) == '_' || (c) == '*' || (c) == '?') // A-Z a-z 0-9 _
#define IS_INT_CHAR(c) (IS_NUMBER_CHAR((c)) || (c) == '-' || (c) == '+' || IS_MULTIPLIER_CHAR((c))) #define IS_CHARDATA_CHAR(c) (IS_LCASE_CHAR((c)) || IS_UCASE_CHAR((c)) || IS_NUMBER_CHAR((c)) || (c) == '_')
#define IS_FLOAT_CHAR(c) (IS_NUMBER_CHAR((c)) || (c) == '.' || (c) == 'e' || (c) == 'E' || (c) == '+' || (c) == '-' || IS_MULTIPLIER_CHAR((c))) // A-Z a-z 0-9 _ * ?
#define IS_IDENT_CHAR(c) (IS_CHARDATA_CHAR((c)) || (c) == '*' || (c) == '?')
// 0-9 - +
#define IS_INT_CHAR(c) (IS_NUMBER_CHAR((c)) || (c) == '-' || (c) == '+')
// 0-9 . + - eE
#define IS_FLOAT_CHAR(c) (IS_NUMBER_CHAR((c)) || (c) == '.' || (c) == 'e' || (c) == 'E' || (c) == '+' || (c) == '-')
#define CHAR_TO_LOWER(ucase) ((ucase) + 32) #define CHAR_TO_LOWER(ucase) ((ucase) + 32)
#define CHAR_TO_UPPER(lcase) ((lcase) - 32) #define CHAR_TO_UPPER(lcase) ((lcase) - 32)
@ -77,7 +82,7 @@ static struct {
// buffer for error messages // buffer for error messages
static char ebuf[256]; static char ebuf[100];
// ---------------- PRIVATE PROTOTYPES ------------------ // ---------------- PRIVATE PROTOTYPES ------------------
@ -718,6 +723,17 @@ static void pars_arg_char(char c)
} }
break; break;
case SCPI_DT_CHARDATA:
if (!IS_CHARDATA_CHAR(c)) {
sprintf(ebuf, "'%c' not allowed in CHARDATA.", c);
scpi_add_error(E_CMD_INVALID_CHARACTER_DATA, ebuf);
pst.state = PARS_DISCARD_LINE;
} else {
charbuf_append(c);
}
break;
case SCPI_DT_STRING: case SCPI_DT_STRING:
if (c == '\'' || c == '"') { if (c == '\'' || c == '"') {
pst.state = PARS_ARG_STRING; pst.state = PARS_ARG_STRING;
@ -857,7 +873,7 @@ static void arg_convert_value(void)
case SCPI_DT_STRING: case SCPI_DT_STRING:
if (strlen(pst.charbuf) > SCPI_MAX_STRING_LEN) { if (strlen(pst.charbuf) > SCPI_MAX_STRING_LEN) {
scpi_add_error(E_CMD_INVALID_STRING_DATA, "String too long."); scpi_add_error(E_CMD_STRING_DATA_ERROR, "String too long.");
pst.state = PARS_DISCARD_LINE; pst.state = PARS_DISCARD_LINE;
} else { } else {
@ -866,6 +882,17 @@ static void arg_convert_value(void)
break; break;
case SCPI_DT_CHARDATA:
if (strlen(pst.charbuf) > SCPI_MAX_STRING_LEN) { // using common buffer
scpi_add_error(E_CMD_CHARACTER_DATA_TOO_LONG, NULL);
pst.state = PARS_DISCARD_LINE;
} else {
strcpy(dest->CHARDATA, pst.charbuf); // copy the character data text
}
break;
default: default:
// impossible // impossible
scpi_add_error(E_DEV_SYSTEM_ERROR, "Unexpected argument data type."); scpi_add_error(E_DEV_SYSTEM_ERROR, "Unexpected argument data type.");

@ -6,8 +6,8 @@
#include "scpi_builtins.h" #include "scpi_builtins.h"
#include "scpi_regs.h" #include "scpi_regs.h"
#define SCPI_MAX_CMD_LEN 12 #define SCPI_MAX_CMD_LEN 16 // 12 according to spec
#define SCPI_MAX_STRING_LEN 12 #define SCPI_MAX_STRING_LEN 64 // 12 according to spec
#define SCPI_MAX_LEVEL_COUNT 4 #define SCPI_MAX_LEVEL_COUNT 4
#define SCPI_MAX_PARAM_COUNT 4 #define SCPI_MAX_PARAM_COUNT 4
@ -17,6 +17,7 @@ typedef enum {
SCPI_DT_FLOAT, // float with support for scientific notation SCPI_DT_FLOAT, // float with support for scientific notation
SCPI_DT_INT, // integer (may be signed) SCPI_DT_INT, // integer (may be signed)
SCPI_DT_BOOL, // 0, 1, ON, OFF SCPI_DT_BOOL, // 0, 1, ON, OFF
SCPI_DT_CHARDATA, // string without quotes - [A-Za-z0-9_]
SCPI_DT_STRING, // quoted string, max 12 chars; no escapes. SCPI_DT_STRING, // quoted string, max 12 chars; no escapes.
SCPI_DT_BLOB, // binary block, callback: uint32_t holding number of bytes SCPI_DT_BLOB, // binary block, callback: uint32_t holding number of bytes
} SCPI_datatype_t; } SCPI_datatype_t;
@ -25,10 +26,14 @@ typedef enum {
/** Arguemnt value (union) */ /** Arguemnt value (union) */
typedef union { typedef union {
float FLOAT; float FLOAT;
int32_t INT; int32_t INT;
bool BOOL;
char STRING[SCPI_MAX_STRING_LEN + 1]; // terminator
uint32_t BLOB_LEN; uint32_t BLOB_LEN;
bool BOOL;
char STRING[SCPI_MAX_STRING_LEN + 1];
char CHARDATA[SCPI_MAX_STRING_LEN + 1];
} SCPI_argval_t; } SCPI_argval_t;

Loading…
Cancel
Save