From 6092bdc4b163977bb5f31df50e6b2a6def28aac5 Mon Sep 17 00:00:00 2001
From: Chernov Dmitriy <cd_work@mail.ru>
Date: 摹曛, 25 2月 2016 21:53:34 +0800
Subject: [PATCH] start #73

---
 libscpi/inc/scpi/error.h   |    4 +
 libscpi/inc/scpi/types.h   |   16 +++++
 libscpi/src/fifo_private.h |    8 +-
 libscpi/src/minimal.c      |   19 +++++-
 libscpi/src/parser.c       |   11 +++
 libscpi/inc/scpi/config.h  |   22 +++++++
 libscpi/src/error.c        |   49 ++++++++++++++--
 libscpi/inc/scpi/parser.h  |    3 
 libscpi/src/fifo.c         |   14 ++--
 9 files changed, 122 insertions(+), 24 deletions(-)

diff --git a/libscpi/inc/scpi/config.h b/libscpi/inc/scpi/config.h
index 1824ab2..c2c95d4 100644
--- a/libscpi/inc/scpi/config.h
+++ b/libscpi/inc/scpi/config.h
@@ -89,6 +89,14 @@
 #define USE_USER_ERROR_LIST 0
 #endif
 
+#ifndef USE_DEVICE_DEPENDENT_ERROR_INFORMATION
+#define USE_DEVICE_DEPENDENT_ERROR_INFORMATION 1
+#endif
+
+#ifndef USE_MEMORY_ALLOCATION_FREE
+#define USE_MEMORY_ALLOCATION_FREE 1
+#endif
+
 #ifndef USE_COMMAND_TAGS
 #define USE_COMMAND_TAGS 1
 #endif
@@ -249,6 +257,20 @@
 #define SCPIDEFINE_doubleToStr(v, s, l) snprintf((s), (l), "%.15lg", (v))
 #endif
 
+#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION
+	#if USE_MEMORY_ALLOCATION_FREE
+		#include <string.h>
+		#include <malloc.h>
+		#define SCPIDEFINE_strdup(s)		strdup((s))
+		#define SCPIDEFINE_free(s)			free((s))
+	#else
+		#define SCPIDEFINE_strdup(s)		NULL
+		#define SCPIDEFINE_free(s)			NULL
+	#endif
+#else
+	#define SCPIDEFINE_strdup(s)			NULL
+	#define SCPIDEFINE_free(s)				NULL
+#endif
 
 #ifdef	__cplusplus
 }
diff --git a/libscpi/inc/scpi/error.h b/libscpi/inc/scpi/error.h
index 916ca25..36c8986 100644
--- a/libscpi/inc/scpi/error.h
+++ b/libscpi/inc/scpi/error.h
@@ -44,9 +44,11 @@
 extern "C" {
 #endif
 
-    void SCPI_ErrorInit(scpi_t * context, int16_t * data, int16_t size);
+    void SCPI_ErrorInit(scpi_t * context, scpi_error_t * data, int16_t size);
     void SCPI_ErrorClear(scpi_t * context);
+	scpi_bool_t SCPI_ErrorPopEx(scpi_t * context, scpi_error_t * error);
     int16_t SCPI_ErrorPop(scpi_t * context);
+	void SCPI_ErrorPushEx(scpi_t * context, int16_t err, char * info);
     void SCPI_ErrorPush(scpi_t * context, int16_t err);
     int32_t SCPI_ErrorCount(scpi_t * context);
     const char * SCPI_ErrorTranslate(int16_t err);
diff --git a/libscpi/inc/scpi/parser.h b/libscpi/inc/scpi/parser.h
index 84a433d..f89310a 100644
--- a/libscpi/inc/scpi/parser.h
+++ b/libscpi/inc/scpi/parser.h
@@ -49,7 +49,8 @@
             const scpi_unit_def_t * units,
             const char * idn1, const char * idn2, const char * idn3, const char * idn4,
             char * input_buffer, size_t input_buffer_length, 
-            int16_t * error_queue_data, int16_t error_queue_size);
+            scpi_error_t * error_queue_data, int16_t error_queue_size,
+			char * error_info_heap, size_t error_info_heap_length);
 
     scpi_bool_t SCPI_Input(scpi_t * context, const char * data, int len);
     scpi_bool_t SCPI_Parse(scpi_t * context, char * data, int len);
diff --git a/libscpi/inc/scpi/types.h b/libscpi/inc/scpi/types.h
index 01611be..97f5592 100644
--- a/libscpi/inc/scpi/types.h
+++ b/libscpi/inc/scpi/types.h
@@ -201,12 +201,25 @@
 
     typedef scpi_result_t(*scpi_command_callback_t)(scpi_t *);
 
+	struct _scpi_error_info_heap_t {
+        size_t length;
+        size_t position;
+        char * data;
+	};
+	typedef struct _scpi_error_info_heap_t scpi_error_info_heap_t;
+	
+	struct _scpi_error_t {
+		int16_t error_code;
+		const char * device_dependent_info;
+	};
+	typedef struct _scpi_error_t scpi_error_t;
+	
     struct _scpi_fifo_t {
         int16_t wr;
         int16_t rd;
         int16_t count;
         int16_t size;
-        int16_t * data;
+        scpi_error_t * data;
     };
     typedef struct _scpi_fifo_t scpi_fifo_t;
 
@@ -350,6 +363,7 @@
         int_fast16_t input_count;
         scpi_bool_t cmd_error;
         scpi_fifo_t error_queue;
+		scpi_error_info_heap_t error_info_heap;
         scpi_reg_val_t registers[SCPI_REG_COUNT];
         const scpi_unit_def_t * units;
         void * user_context;
diff --git a/libscpi/src/error.c b/libscpi/src/error.c
index 9d8e756..d69b005 100644
--- a/libscpi/src/error.c
+++ b/libscpi/src/error.c
@@ -45,7 +45,7 @@
  * Initialize error queue
  * @param context - scpi context
  */
-void SCPI_ErrorInit(scpi_t * context, int16_t * data, int16_t size) {
+void SCPI_ErrorInit(scpi_t * context, scpi_error_t * data, int16_t size) {
     fifo_init(&context->error_queue, data, size);
 }
 
@@ -86,6 +86,16 @@
     SCPI_ErrorEmitEmpty(context);
 }
 
+
+scpi_bool_t SCPI_ErrorPopEx(scpi_t * context, scpi_error_t * error) {
+	if(error == NULL) return FALSE;
+
+	fifo_remove(&context->error_queue, error);
+
+	SCPI_ErrorEmitEmpty(context);
+
+	return TRUE;
+}
 /**
  * Pop error from queue
  * @param context - scpi context
@@ -114,10 +124,10 @@
     return result;
 }
 
-static scpi_bool_t SCPI_ErrorAddInternal(scpi_t * context, int16_t err) {
-    if (!fifo_add(&context->error_queue, err)) {
+static scpi_bool_t SCPI_ErrorAddInternal(scpi_t * context, int16_t err, char * info) {
+    if (!fifo_add(&context->error_queue, err, info)) {
         fifo_remove_last(&context->error_queue, NULL);
-        fifo_add(&context->error_queue, SCPI_ERROR_QUEUE_OVERFLOW);
+        fifo_add(&context->error_queue, SCPI_ERROR_QUEUE_OVERFLOW, NULL);
         return FALSE;
     }
     return TRUE;
@@ -148,11 +158,38 @@
  * @param context - scpi context
  * @param err - error number
  */
-void SCPI_ErrorPush(scpi_t * context, int16_t err) {
+void SCPI_ErrorPushEx(scpi_t * context, int16_t err, char * info) {
+	int i;
+	char * info_ptr=SCPIDEFINE_strdup(info);
+	scpi_bool_t queue_overflow = !SCPI_ErrorAddInternal(context, err, info_ptr);
 
+	for (i = 0; i < ERROR_DEFS_N; i++) {
+		if ((err <= errs[i].from) && (err >= errs[i].to)) {
+			SCPI_RegSetBits(context, SCPI_REG_ESR, errs[i].bit);
+		}
+	}
+
+	SCPI_ErrorEmit(context, err);
+	if (queue_overflow) {
+		SCPI_ErrorEmit(context, SCPI_ERROR_QUEUE_OVERFLOW);
+	}
+
+	if (context) {
+		context->cmd_error = TRUE;
+	}
+}
+
+/**
+ * Push error to queue
+ * @param context - scpi context
+ * @param err - error number
+ */
+void SCPI_ErrorPush(scpi_t * context, int16_t err) {
+	SCPI_ErrorPushEx(context, err, NULL);
+	return;
     int i;
 
-    scpi_bool_t queue_overflow = !SCPI_ErrorAddInternal(context, err);
+    scpi_bool_t queue_overflow = !SCPI_ErrorAddInternal(context, err, NULL);
 
     for (i = 0; i < ERROR_DEFS_N; i++) {
         if ((err <= errs[i].from) && (err >= errs[i].to)) {
diff --git a/libscpi/src/fifo.c b/libscpi/src/fifo.c
index e81f55e..6c125ff 100644
--- a/libscpi/src/fifo.c
+++ b/libscpi/src/fifo.c
@@ -5,7 +5,7 @@
  * Initialize fifo
  * @param fifo
  */
-void fifo_init(scpi_fifo_t * fifo, int16_t * data, int16_t size) {
+void fifo_init(scpi_fifo_t * fifo, scpi_error_t * data, int16_t size) {
     fifo->wr = 0;
     fifo->rd = 0;
     fifo->count = 0;
@@ -44,16 +44,18 @@
 /**
  * Add element to fifo. If fifo is full, return FALSE.
  * @param fifo
- * @param value
+ * @param err
+ * @param info
  * @return
  */
-scpi_bool_t fifo_add(scpi_fifo_t * fifo, int16_t value) {
+scpi_bool_t fifo_add(scpi_fifo_t * fifo, int16_t err, char * info) {
     /* FIFO full? */
     if (fifo_is_full(fifo)) {
         return FALSE;
     }
 
-    fifo->data[fifo->wr] = value;
+    fifo->data[fifo->wr].error_code = err;
+	fifo->data[fifo->wr].device_dependent_info = info;
     fifo->wr = (fifo->wr + 1) % (fifo->size);
     fifo->count += 1;
     return TRUE;
@@ -65,7 +67,7 @@
  * @param value
  * @return FALSE - fifo is empty
  */
-scpi_bool_t fifo_remove(scpi_fifo_t * fifo, int16_t * value) {
+scpi_bool_t fifo_remove(scpi_fifo_t * fifo, scpi_error_t * value) {
     /* FIFO empty? */
     if (fifo_is_empty(fifo)) {
         return FALSE;
@@ -87,7 +89,7 @@
  * @param value
  * @return FALSE - fifo is empty
  */
-scpi_bool_t fifo_remove_last(scpi_fifo_t * fifo, int16_t * value) {
+scpi_bool_t fifo_remove_last(scpi_fifo_t * fifo, scpi_error_t * value) {
     /* FIFO empty? */
     if (fifo_is_empty(fifo)) {
         return FALSE;
diff --git a/libscpi/src/fifo_private.h b/libscpi/src/fifo_private.h
index f1a1d12..7440bc2 100644
--- a/libscpi/src/fifo_private.h
+++ b/libscpi/src/fifo_private.h
@@ -44,13 +44,13 @@
 extern "C" {
 #endif
 
-    void fifo_init(scpi_fifo_t * fifo, int16_t * data, int16_t size) LOCAL;
+    void fifo_init(scpi_fifo_t * fifo, scpi_error_t * data, int16_t size) LOCAL;
     void fifo_clear(scpi_fifo_t * fifo) LOCAL;
     scpi_bool_t fifo_is_empty(scpi_fifo_t * fifo) LOCAL;
     scpi_bool_t fifo_is_full(scpi_fifo_t * fifo) LOCAL;
-    scpi_bool_t fifo_add(scpi_fifo_t * fifo, int16_t value) LOCAL;
-    scpi_bool_t fifo_remove(scpi_fifo_t * fifo, int16_t * value) LOCAL;
-    scpi_bool_t fifo_remove_last(scpi_fifo_t * fifo, int16_t * value) LOCAL;
+    scpi_bool_t fifo_add(scpi_fifo_t * fifo, int16_t err, char * info) LOCAL;
+    scpi_bool_t fifo_remove(scpi_fifo_t * fifo, scpi_error_t * value) LOCAL;
+    scpi_bool_t fifo_remove_last(scpi_fifo_t * fifo, scpi_error_t * value) LOCAL;
     scpi_bool_t fifo_count(scpi_fifo_t * fifo, int16_t * value) LOCAL;
 
 #ifdef	__cplusplus
diff --git a/libscpi/src/minimal.c b/libscpi/src/minimal.c
index 7641311..ecfcaf2 100644
--- a/libscpi/src/minimal.c
+++ b/libscpi/src/minimal.c
@@ -77,11 +77,24 @@
  * @return 
  */
 scpi_result_t SCPI_SystemErrorNextQ(scpi_t * context) {
-    int16_t err = SCPI_ErrorPop(context);
+	scpi_error_t error;
+	if(!SCPI_ErrorPopEx(context, &error))return SCPI_RES_ERR;
+	
+    //int16_t err = SCPI_ErrorPop(context);
 
-    SCPI_ResultInt32(context, err);
-    SCPI_ResultText(context, SCPI_ErrorTranslate(err));
+    SCPI_ResultInt32(context, error.error_code);
+    SCPI_ResultText(context, SCPI_ErrorTranslate(error.error_code));
+	
+	size_t info_len=0;
+	if(error.device_dependent_info){
+		info_len=SCPIDEFINE_strnlen(error.device_dependent_info,255);
+		SCPI_ResultCharacters(context, ";", 1);
+		SCPI_ResultText(context, error.device_dependent_info);
+		SCPIDEFINE_free(error.device_dependent_info);		
+	}
+	
 
+	
     return SCPI_RES_OK;
 }
 
diff --git a/libscpi/src/parser.c b/libscpi/src/parser.c
index 7849e2a..7720c09 100644
--- a/libscpi/src/parser.c
+++ b/libscpi/src/parser.c
@@ -219,7 +219,10 @@
                 result &= processCommand(context);
                 cmd_prev = state->programHeader;
             } else {
-                SCPI_ErrorPush(context, SCPI_ERROR_UNDEFINED_HEADER);
+                //SCPI_ErrorPush(context, SCPI_ERROR_UNDEFINED_HEADER);
+				/* test */
+				data[r-1]=0;
+				SCPI_ErrorPushEx(context, SCPI_ERROR_UNDEFINED_HEADER, data);
                 result = FALSE;
             }
         }
@@ -252,7 +255,8 @@
         const scpi_unit_def_t * units,
         const char * idn1, const char * idn2, const char * idn3, const char * idn4,
         char * input_buffer, size_t input_buffer_length, 
-        int16_t * error_queue_data, int16_t error_queue_size) {
+        scpi_error_t * error_queue_data, int16_t error_queue_size,
+		char * error_info_heap, size_t error_info_heap_length) {
     memset(context, 0, sizeof(*context));
     context->cmdlist = commands;
     context->interface = interface;
@@ -264,6 +268,9 @@
     context->buffer.data = input_buffer;
     context->buffer.length = input_buffer_length;
     context->buffer.position = 0;
+	context->error_info_heap.data = error_info_heap;
+	context->error_info_heap.position = 0;
+	context->error_info_heap.length = error_info_heap_length;
     SCPI_ErrorInit(context, error_queue_data, error_queue_size);
 }
 

--
Gitblit v1.9.1