support for custom errors & properly set SESR error type flags

master
Ondřej Hruška 9 years ago
parent d1ed1ba31c
commit 1118d51b7c
  1. 2
      README.md
  2. 24
      main.c
  3. 2
      scpi.pro.user
  4. 53
      source/scpi_errors.c
  5. 18
      source/scpi_errors.h
  6. 2
      source/scpi_regs.c
  7. 4
      source/scpi_regs.h

@ -22,7 +22,7 @@ See main.c for example of how to use the library.
## What is missing ## What is missing
- Setting error type flags in the ESR when error is added to queue - <s>Setting error type flags in the ESR when error is added to queue</s>
- There may be some bugs in the status registers (not tested much) - There may be some bugs in the status registers (not tested much)
- Character data argument ("string without quotes", enum-like) - Character data argument ("string without quotes", enum-like)
- Number units and metric suffixes (k,M,G,m,u,n) - Number units and metric suffixes (k,M,G,m,u,n)

@ -23,11 +23,24 @@ int main()
send_cmd("APPLY:SINE 50, 1.0, 2.17\n"); // floats send_cmd("APPLY:SINE 50, 1.0, 2.17\n"); // floats
send_cmd("DISP:TEXT \"Hello world\"\n"); // string 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 ---- // ---- Test device impl ----
const SCPI_error_desc scpi_user_errors[] = {
{10, "Custom error"},
{0} // terminator
};
void scpi_send_byte_impl(uint8_t b) void scpi_send_byte_impl(uint8_t b)
{ {
putchar(b); // device sends a byte 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) // Command definition (mandatory commands are built-in)
const SCPI_command_t scpi_commands[] = { const SCPI_command_t scpi_commands[] = {
{ {
@ -97,5 +117,9 @@ const SCPI_command_t scpi_commands[] = {
.blob_chunk = 4, .blob_chunk = 4,
.blob_callback = cmd_DATA_BLOB_data .blob_callback = cmd_DATA_BLOB_data
}, },
{
.levels = {"USeRERRor"},
.callback = cmd_USRERR_cb
},
{0} // end marker {0} // end marker
}; };

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.5.1, 2015-12-05T18:39:54. --> <!-- Written by QtCreator 3.5.1, 2015-12-05T19:13:04. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>

@ -21,7 +21,7 @@ static struct {
} erq; } 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; bool added = true;
if (erq.count >= ERR_QUEUE_LEN) { 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; 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(); scpi_status_update();
} }
@ -96,15 +108,7 @@ uint8_t scpi_error_count(void)
// ---- table ---- // ---- table ----
typedef struct {
const int16_t errno;
const char *msg;
} SCPI_error_desc;
static const SCPI_error_desc error_table[] = { static const SCPI_error_desc error_table[] = {
{ 0, "No error"},
{ -100, "Command error"}, { -100, "Command error"},
{ -101, "Invalid character"}, { -101, "Invalid character"},
{ -102, "Syntax error"}, { -102, "Syntax error"},
@ -226,23 +230,38 @@ static const SCPI_error_desc error_table[] = {
{ -600, "User request"}, { -600, "User request"},
{ -700, "Request control"}, { -700, "Request control"},
{ -800, "Operation complete"}, { -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 (errno == 0) {
if (error_table[i].errno == errno) { // ok state
return error_table[i].msg; 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); 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); // <code>," len = offs = sprintf(buffer, "%d,\"", errno); // <code>,"
buffer += offs; buffer += offs;
if (msg == NULL) msg = "Unknown error";
offs = sprintf(buffer, "%s", msg); // Error message offs = sprintf(buffer, "%s", msg); // Error message
len += offs; len += offs;
buffer += offs; buffer += offs;

@ -2,8 +2,16 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
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 // SCPI error constants
typedef enum { enum {
E_NO_ERROR = 0, E_NO_ERROR = 0,
E_COMMAND_ERROR = -100, E_COMMAND_ERROR = -100,
E_CMD_INVALID_CHARACTER = -101, E_CMD_INVALID_CHARACTER = -101,
@ -126,11 +134,11 @@ typedef enum {
E_USER_REQUEST = -600, E_USER_REQUEST = -600,
E_REQUEST_CONTROL = -700, E_REQUEST_CONTROL = -700,
E_OPERATION_COMPLETE = -800, E_OPERATION_COMPLETE = -800,
} SCPI_error_t; };
/** Get SCPI error message (alone) */ /** 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. * 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 */ /** 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 */ /** Get number of errors in the error queue */

@ -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;
SCPI_REG_OPER_t SCPI_REG_OPER_EN = {.u16 = 0xFFFF}; 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_SESR_t SCPI_REG_SESR_EN;
SCPI_REG_STB_t SCPI_REG_STB; SCPI_REG_STB_t SCPI_REG_STB;

@ -52,8 +52,8 @@ typedef union {
typedef union { typedef union {
struct __attribute__((packed)) { struct __attribute__((packed)) {
bool OPC: 1; bool OPC: 1; // operation complete - only for instruments with overlapping commands
bool REQ_CONTROL: 1; bool REQ_CONTROL: 1; // GPIB-only
bool QUERY_ERROR: 1; bool QUERY_ERROR: 1;
bool DEV_ERROR: 1; bool DEV_ERROR: 1;
bool EXE_ERROR: 1; bool EXE_ERROR: 1;

Loading…
Cancel
Save