diff --git a/README.md b/README.md index 7e382f2..f2e1ed3 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ See main.c for example of how to use the library. ## What is missing -- Setting error type flags in the ESR when error is added to queue +- Setting error type flags in the ESR when error is added to queue - There may be some bugs in the status registers (not tested much) - Character data argument ("string without quotes", enum-like) - Number units and metric suffixes (k,M,G,m,u,n) diff --git a/main.c b/main.c index 551f4eb..58e2890 100644 --- a/main.c +++ b/main.c @@ -23,11 +23,24 @@ int main() send_cmd("APPLY:SINE 50, 1.0, 2.17\n"); // floats send_cmd("DISP:TEXT \"Hello world\"\n"); // string + + // test user error + send_cmd("*CLS\n"); // string + send_cmd("USERERROR\n"); // string + send_cmd("SYST:ERR:COUNT?\n"); + send_cmd("SYST:ERR:NEXT?\n"); } // ---- Test device impl ---- + +const SCPI_error_desc scpi_user_errors[] = { + {10, "Custom error"}, + {0} // terminator +}; + + void scpi_send_byte_impl(uint8_t b) { putchar(b); // device sends a byte @@ -78,6 +91,13 @@ void cmd_DATA_BLOB_data(const uint8_t *bytes) } +void cmd_USRERR_cb(const SCPI_argval_t *args) +{ + printf("cb USRERR - raising user error 10.\n"); + scpi_add_error(10, "Custom error message..."); +} + + // Command definition (mandatory commands are built-in) const SCPI_command_t scpi_commands[] = { { @@ -97,5 +117,9 @@ const SCPI_command_t scpi_commands[] = { .blob_chunk = 4, .blob_callback = cmd_DATA_BLOB_data }, + { + .levels = {"USeRERRor"}, + .callback = cmd_USRERR_cb + }, {0} // end marker }; diff --git a/scpi.pro.user b/scpi.pro.user index c49305f..f2d5683 100644 --- a/scpi.pro.user +++ b/scpi.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/source/scpi_errors.c b/source/scpi_errors.c index 980e98e..7ce33bb 100644 --- a/source/scpi_errors.c +++ b/source/scpi_errors.c @@ -21,7 +21,7 @@ static struct { } erq; -void scpi_add_error(SCPI_error_t errno, const char *extra) +void scpi_add_error(int16_t errno, const char *extra) { bool added = true; if (erq.count >= ERR_QUEUE_LEN) { @@ -45,6 +45,18 @@ void scpi_add_error(SCPI_error_t errno, const char *extra) erq.w_pos = 0; } + // error type status flags + if (errno >= -499 && errno <= -400) { + SCPI_REG_SESR.QUERY_ERROR = true; + } else if ((errno >= -399 && errno <= -300) || errno > 0) { + SCPI_REG_SESR.DEV_ERROR = true; + } else if (errno >= -299 && errno <= -200) { + SCPI_REG_SESR.EXE_ERROR = true; + } else if (errno >= -199 && errno <= -100) { + SCPI_REG_SESR.CMD_ERROR = true; + } + + // update the error queue bit and propagate the above flags scpi_status_update(); } @@ -96,15 +108,7 @@ uint8_t scpi_error_count(void) // ---- table ---- - -typedef struct { - const int16_t errno; - const char *msg; -} SCPI_error_desc; - - static const SCPI_error_desc error_table[] = { - { 0, "No error"}, { -100, "Command error"}, { -101, "Invalid character"}, { -102, "Syntax error"}, @@ -226,23 +230,38 @@ static const SCPI_error_desc error_table[] = { { -600, "User request"}, { -700, "Request control"}, { -800, "Operation complete"}, - { -9999} // end mark + {0} // end mark }; -const char * scpi_error_message(SCPI_error_t errno) +const char * scpi_error_message(int16_t errno) { - for (int i = 0; error_table[i].errno != -9999; i++) { - if (error_table[i].errno == errno) { - return error_table[i].msg; + if (errno == 0) { + // ok state + return "No error"; + + } else if (errno < 0) { + // standard errors + for (int i = 0; (i == 0 || error_table[i].errno != 0); i++) { + if (error_table[i].errno == errno) { + return error_table[i].msg; + } + } + + } else { + // user error + for (int i = 0; scpi_user_errors[i].errno != 0; i++) { + if (scpi_user_errors[i].errno == errno) { + return scpi_user_errors[i].msg; + } } } - return NULL; + return "Unknown error"; } -void scpi_error_string(char *buffer, SCPI_error_t errno, const char *extra) +void scpi_error_string(char *buffer, int16_t errno, const char *extra) { const char *msg = scpi_error_message(errno); @@ -252,8 +271,6 @@ void scpi_error_string(char *buffer, SCPI_error_t errno, const char *extra) len = offs = sprintf(buffer, "%d,\"", errno); // ," buffer += offs; - if (msg == NULL) msg = "Unknown error"; - offs = sprintf(buffer, "%s", msg); // Error message len += offs; buffer += offs; diff --git a/source/scpi_errors.h b/source/scpi_errors.h index 2b30fa5..c2914f9 100644 --- a/source/scpi_errors.h +++ b/source/scpi_errors.h @@ -2,8 +2,16 @@ #include #include +typedef struct { + const int16_t errno; + const char *msg; +} SCPI_error_desc; + +/** User error definitions */ +extern const SCPI_error_desc scpi_user_errors[]; + // SCPI error constants -typedef enum { +enum { E_NO_ERROR = 0, E_COMMAND_ERROR = -100, E_CMD_INVALID_CHARACTER = -101, @@ -126,11 +134,11 @@ typedef enum { E_USER_REQUEST = -600, E_REQUEST_CONTROL = -700, E_OPERATION_COMPLETE = -800, -} SCPI_error_t; +}; /** Get SCPI error message (alone) */ -const char *scpi_error_message(SCPI_error_t errno); +const char *scpi_error_message(int16_t errno); /** @@ -139,11 +147,11 @@ const char *scpi_error_message(SCPI_error_t errno); * * extra can be NULL to skip the optional part. */ -void scpi_error_string(char *buffer, SCPI_error_t errno, const char *extra); +void scpi_error_string(char *buffer, int16_t errno, const char *extra); /** Add error to the error queue */ -void scpi_add_error(SCPI_error_t errno, const char *extra); +void scpi_add_error(int16_t errno, const char *extra); /** Get number of errors in the error queue */ diff --git a/source/scpi_regs.c b/source/scpi_regs.c index 9322fb3..e4cc456 100644 --- a/source/scpi_regs.c +++ b/source/scpi_regs.c @@ -13,7 +13,7 @@ SCPI_REG_QUES_t SCPI_REG_QUES_EN = {.u16 = 0xFFFF}; SCPI_REG_OPER_t SCPI_REG_OPER; SCPI_REG_OPER_t SCPI_REG_OPER_EN = {.u16 = 0xFFFF}; -SCPI_REG_SESR_t SCPI_REG_SESR; +SCPI_REG_SESR_t SCPI_REG_SESR = {.POWER_ON = 1}; // indicates the startup condition SCPI_REG_SESR_t SCPI_REG_SESR_EN; SCPI_REG_STB_t SCPI_REG_STB; diff --git a/source/scpi_regs.h b/source/scpi_regs.h index 7fff32e..65657e1 100644 --- a/source/scpi_regs.h +++ b/source/scpi_regs.h @@ -52,8 +52,8 @@ typedef union { typedef union { struct __attribute__((packed)) { - bool OPC: 1; - bool REQ_CONTROL: 1; + bool OPC: 1; // operation complete - only for instruments with overlapping commands + bool REQ_CONTROL: 1; // GPIB-only bool QUERY_ERROR: 1; bool DEV_ERROR: 1; bool EXE_ERROR: 1;