diff --git a/libscpi/inc/scpi/config.h b/libscpi/inc/scpi/config.h index b57d748c..8b97aecf 100644 --- a/libscpi/inc/scpi/config.h +++ b/libscpi/inc/scpi/config.h @@ -93,6 +93,10 @@ extern "C" { #define USE_COMMAND_TAGS 1 #endif +#ifndef USE_64K_PROGMEM_FOR_CMD_LIST +#define USE_64K_PROGMEM_FOR_CMD_LIST 0 +#endif + #ifndef USE_DEPRECATED_FUNCTIONS #define USE_DEPRECATED_FUNCTIONS 1 #endif diff --git a/libscpi/inc/scpi/types.h b/libscpi/inc/scpi/types.h index 38ee0184..ebeb4799 100644 --- a/libscpi/inc/scpi/types.h +++ b/libscpi/inc/scpi/types.h @@ -113,7 +113,11 @@ extern "C" { typedef struct _scpi_command_t scpi_command_t; +#if USE_COMMAND_TAGS #define SCPI_CMD_LIST_END {NULL, NULL, 0} +#else +#define SCPI_CMD_LIST_END {NULL, NULL} +#endif /* scpi interface */ typedef struct _scpi_t scpi_t; @@ -246,10 +250,22 @@ extern "C" { #define SCPI_CHOICE_LIST_END {NULL, -1} typedef struct _scpi_choice_def_t scpi_choice_def_t; + struct _scpi_command_t { + const char * pattern; + scpi_command_callback_t callback; +#if USE_COMMAND_TAGS + int32_t tag; +#endif /* USE_COMMAND_TAGS */ + }; + struct _scpi_param_list_t { const scpi_command_t * cmd; lex_state_t lex_state; scpi_const_buffer_t cmd_raw; +#if USE_64K_PROGMEM_FOR_CMD_LIST + scpi_command_t cmd_s; + char cmd_pattern_s[SCPI_MAX_CMD_PATTERN_SIZE + 1]; +#endif }; typedef struct _scpi_param_list_t scpi_param_list_t; @@ -273,14 +289,6 @@ extern "C" { typedef scpi_token_t scpi_parameter_t; - struct _scpi_command_t { - const char * pattern; - scpi_command_callback_t callback; -#if USE_COMMAND_TAGS - int32_t tag; -#endif /* USE_COMMAND_TAGS */ - }; - struct _scpi_interface_t { scpi_error_callback_t error; scpi_write_t write; @@ -289,6 +297,7 @@ extern "C" { scpi_command_callback_t reset; }; + struct _scpi_t { const scpi_command_t * cmdlist; scpi_buffer_t buffer; diff --git a/libscpi/src/parser.c b/libscpi/src/parser.c index 62dc1518..568ae47d 100644 --- a/libscpi/src/parser.c +++ b/libscpi/src/parser.c @@ -45,6 +45,10 @@ #include "scpi/constants.h" #include "scpi/utils.h" +#if USE_64K_PROGMEM_FOR_CMD_LIST +#include +#endif + /** * Write data to SCPI output * @param context @@ -160,12 +164,26 @@ static scpi_bool_t processCommand(scpi_t * context) { */ static scpi_bool_t findCommandHeader(scpi_t * context, const char * header, int len) { int32_t i; +#if USE_64K_PROGMEM_FOR_CMD_LIST + PGM_P pattern; + + for (i = 0; (pattern = (PGM_P)pgm_read_word(&context->cmdlist[i].pattern)) != 0; ++i) { + strncpy_P(context->param_list.cmd_pattern_s, pattern, SCPI_MAX_CMD_PATTERN_SIZE); + context->param_list.cmd_pattern_s[SCPI_MAX_CMD_PATTERN_SIZE] = '\0'; + + if (matchCommand(context->param_list.cmd_pattern_s, header, len, NULL, 0, 0)) { + context->param_list.cmd_s.callback = (scpi_command_callback_t)pgm_read_word(&context->cmdlist[i].callback); +#if USE_COMMAND_TAGS + context->param_list.cmd_s..tag = (int32_t)pgm_read_dword(&context->cmdlist[i].tag); +#endif +#else const scpi_command_t * cmd; for (i = 0; context->cmdlist[i].pattern != NULL; i++) { cmd = &context->cmdlist[i]; if (matchCommand(cmd->pattern, header, len, NULL, 0, 0)) { context->param_list.cmd = cmd; +#endif return TRUE; } } @@ -255,6 +273,11 @@ void SCPI_Init(scpi_t * context) { context->idn[3] = SCPI_DEFAULT_4_REVISION; } +#if USE_64K_PROGMEM_FOR_CMD_LIST + context->param_list.cmd_s.pattern = context->param_list.cmd_pattern_s; + context->param_list.cmd = &context->param_list.cmd_s; +#endif + context->buffer.position = 0; SCPI_ErrorInit(context); }