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;