summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--device-functions.c78
-rw-r--r--error_utils.c1004
-rw-r--r--lcd.c616
-rw-r--r--lcd.h14
-rw-r--r--parser.c2022
-rw-r--r--string_utils.c96
6 files changed, 1915 insertions, 1915 deletions
diff --git a/device-functions.c b/device-functions.c
index 9422b40..ac2acfb 100644
--- a/device-functions.c
+++ b/device-functions.c
@@ -1,39 +1,39 @@
-#include "device-functions.h"
-
-/* START FUNCTION DESCRIPTION ********************************************
-Set_frequency <DEVFUNC.LIB>
-
-SYNTAX: Set_frequency(int check_possible_only,int word_override,int range_override,int channel,float set_freq)
-
-KEYWORDS:
-
-DESCRIPTION: sets the offset DAC.
-
-RETURN VALUE: error code (zero = OK).
-END DESCRIPTION **********************************************************/
-
-/*----------------------------------------------------------------------------------------------------------*/
-int Set_frequency(int check_possible_only,int word_override,int range_override,int channel,float set_freq)
-{
- // keep, but ignore, the first 3 parameters for now
-
- // all this does right now is check the frequency range,
- // and store the set value.
-
- /* abandon if high channel selected by user but not enabled by firmware */
- if (channel && !globals.Flash.ChanKey_frequency) {
- return InvalidChannel;
- }
-
- if (set_freq < 1.0) {
- return freq_lower_limit;
- }
- if (set_freq > 1.0e6) {
- return freq_upper_limit;
- }
-
- globals.ChannelState[channel].frequency=set_freq;
-
- return OK;
-}
-
+#include "device-functions.h"
+
+/* START FUNCTION DESCRIPTION ********************************************
+Set_frequency <DEVFUNC.LIB>
+
+SYNTAX: Set_frequency(int check_possible_only,int word_override,int range_override,int channel,float set_freq)
+
+KEYWORDS:
+
+DESCRIPTION: sets the offset DAC.
+
+RETURN VALUE: error code (zero = OK).
+END DESCRIPTION **********************************************************/
+
+/*----------------------------------------------------------------------------------------------------------*/
+int Set_frequency(int check_possible_only,int word_override,int range_override,int channel,float set_freq)
+{
+ // keep, but ignore, the first 3 parameters for now
+
+ // all this does right now is check the frequency range,
+ // and store the set value.
+
+ /* abandon if high channel selected by user but not enabled by firmware */
+ if (channel && !globals.Flash.ChanKey_frequency) {
+ return InvalidChannel;
+ }
+
+ if (set_freq < 1.0) {
+ return freq_lower_limit;
+ }
+ if (set_freq > 1.0e6) {
+ return freq_upper_limit;
+ }
+
+ globals.ChannelState[channel].frequency=set_freq;
+
+ return OK;
+}
+
diff --git a/error_utils.c b/error_utils.c
index 73d2999..c4eae61 100644
--- a/error_utils.c
+++ b/error_utils.c
@@ -1,502 +1,502 @@
-/* START LIBRARY DESCRIPTION *********************************************
-ERRCHK.LIB
- Copyright (c) 2006, Avtech Electrosystems Ltd.
-
-DESCRIPTION:
- Error-checking and reporting functions.
-
-SUPPORT LIB'S:
-END DESCRIPTION **********************************************************/
-
-
-/*** BeginHeader Error_check */
-
-#include <string.h>
-#include <glib/gprintf.h>
-#include "globals.h"
-#include "dummy_functions.h"
-#include "lcd.h"
-
-/*** EndHeader */
-
-/* FIXME */
-int Error_Screen=NO;
-
-void set_gpib_error_flags (int error_num);
-
-void set_gpib_error_flags (int error_num)
-{
-
- if (error_num == OK) {
- return;
- }
-
- /* set the error flags in the GPIB ESR register right away */
- switch (error_num) {
- case AsyncModeDisabled:
- case Unrecognized:
- case SyntaxError:
- case UnknownUnits:
- case InvalidChannel:
- GPIB_Set_Command_Error();
- break;
- case query_error_interrupted:
- case query_error_unterminated:
- GPIB_Set_Query_Error();
- break;
- case Overload_Detected:
- case Overtemp_Detected:
- case Overvolt_Detected:
- case Device_Specific_Aux_Error_Detected:
- case queue_overflow:
- case CalibrationPercentError:
- case CalibrationZeroError:
- case CalibrationMinMaxError:
- case CalibrationClosenessError:
- case CalibrationRangeError:
- case CalibrationPolarityError:
- case Soft_Limit_Exceeded:
- case SelfCalError:
- GPIB_Set_Device_Dependent_Error();
- break;
- default:
- GPIB_Set_Execution_Error();
- break;
- }
-
- return;
-}
-
-void queue_error(int error_num);
-
-void queue_error(int error_num)
-{
- if (error_num == OK) {
- return;
- }
-
- set_gpib_error_flags (error_num);
- if (globals.number_of_errors<error_queue_length) {
- ++globals.number_of_errors;
- globals.error_queue[globals.number_of_errors]=error_num;
- } else {
- globals.error_queue[globals.number_of_errors]=queue_overflow;
- }
-
- return;
-}
-
-
-
-/*----------------------------------------------------------------------------------------------------------*/
-void queue_error_and_get_text(gchar** response, int error_num)
-{
- g_assert (*response == NULL);
-
- if (error_num == OK) {
- return;
- }
- queue_error (error_num);
- get_error_text (response, error_num);
- return;
-}
-
-/*----------------------------------------------------------------------------------------------------------*/
-void queue_error_from_parser(gchar** response, int error_num)
-{
- g_assert (*response == NULL);
-
- if (error_num == OK) {
- return;
- }
- queue_error_and_get_text(response, error_num);
- Menu_Refresh();
- return;
-}
-
-
-void queue_error_for_gpib_only(int error_num);
-
-void queue_error_for_gpib_only(int error_num)
-{
-// not part of this project, but left in for coder's reference. Can be deleted for now
- if (error_num == OK) {
- return;
- }
- queue_error(error_num);
- return;
-}
-
-
-void queue_error_and_display_on_LCD(int error_num);
-
-void queue_error_and_display_on_LCD(int error_num)
-{
- gchar* response = NULL;
- queue_error_and_get_text(&response, error_num);
- LCD_display_error_message (response);
-}
-
-
-void queue_and_broadcast_sensor_alarm(int error_num);
-
-void queue_and_broadcast_sensor_alarm(int error_num)
-{
-// not part of this project, but left in for coder's reference. Can be deleted for now
-}
-
-/*----------------------------------------------------------------------------------------------------------*/
-void Error_Remove_From_Queue(void)
-{
- int i;
- for (i=1; i<globals.number_of_errors; ++i) {
- globals.error_queue[i]=globals.error_queue[i+1];
- }
- --globals.number_of_errors; /* error reported, so remove it from the error queue */
-}
-
-
-void format_error_text (gchar **response, int error_type, char *in);
-
-void format_error_text (gchar **response, int error_type, char *in)
-{
- char* prefix = NULL;
-
- switch (error_type) {
- case 0:
- prefix = g_strdup("No error");
- break;
- case -100:
- prefix=g_strdup("Command error");
- break;
- case -102:
- prefix=g_strdup("Syntax error");
- break;
- case -114:
- prefix=g_strdup("Command error");
- break;
- case -131:
- prefix=g_strdup("Invalid suffix");
- break;
- case -200:
- prefix=g_strdup("Execution error");
- break;
- case -221:
- prefix=g_strdup("Settings conflict");
- break;
- case -222:
- prefix=g_strdup("Data out of range");
- break;
- case -224:
- prefix=g_strdup("Illegal parameter value");
- break;
- case -240:
- prefix=g_strdup("Hardware error");
- break;
- case -300:
- prefix=g_strdup("Device-specific error");
- break;
- case -340:
- prefix=g_strdup("Calibration failed");
- break;
- case -350:
- prefix=g_strdup("Queue overflow");
- break;
- case -400:
- prefix=g_strdup("Query error");
- break;
- default:
- prefix=g_strdup("System error");
- break;
- }
-
-
- *response = g_strdup_printf("%d, \"%s; %s\"", error_type, prefix, in);
- g_free(prefix);
-}
-
-
-void get_error_text(gchar **response, int error_num)
-{
- switch (error_num) {
-
- case OK:
- format_error_text(response,0,"");
- break;
-
- case Unrecognized:
- format_error_text(response,-102,"Unrecognized command.");
- break;
-
- case AsyncModeDisabled:
- format_error_text(response,-102,"Async gating not available.");
- break;
-
- case SyntaxError:
- format_error_text(response,-100,"Recognized command, but improper syntax.");
- break;
-
- case InvalidChannel:
- format_error_text(response,-114,"Invalid channel suffix.");
- break;
-
- case OutOfRange:
- format_error_text(response,-222,"Too high or too low.");
- break;
-
- case Negative_Not_Allowed:
- format_error_text(response,-222,"Negative value not allowed.");
- break;
-
- case IllegalParameter:
- case amplitude_confined_values:
- format_error_text(response,-224,"Not in list of allowed values.");
- break;
-
- case UnknownUnits:
- format_error_text(response,-131,"Unrecognized units.");
- break;
-
- case Route_Range_Error:
- format_error_text(response,-224,"Ranges are not supported.");
- break;
-
- case AB_Mode_Error:
- format_error_text(response,-221,"This PW mode is not valid for the current trigger mode.");
- break;
-
- case Valid_For_RS232_TELNET_Only:
- format_error_text(response,-221,"Command valid in RS232 or TELNET modes only.");
- break;
-
- case PW_Exceeds_Period:
- format_error_text(response,-221,"PW can not exceed period.");
- break;
-
- case Delay_Exceeds_95Period:
- format_error_text(response,-221,"Delay can not exceed 95% of period.");
- break;
-
- case NeedNonZeroAmpl:
- format_error_text(response,-222,"Amplitude must be non-zero.");
- break;
-
- case freq_lower_limit:
- format_error_text(response,-222,"PRF too low.");
- break;
-
- case freq_upper_limit:
- format_error_text(response,-222,"PRF too high.");
- break;
-
- case pw_lower_limit:
- format_error_text(response,-222,"PW too low.");
- break;
-
- case pw_upper_limit:
- format_error_text(response,-222,"PW too high.");
- break;
-
- case max_rise_time_error:
- format_error_text(response,-222,"Rise time too high.");
- break;
-
- case min_rise_time_error:
- format_error_text(response,-222,"Rise time too low.");
- break;
-
- case max_slew_error:
- format_error_text(response,-222,"Slew rate too high.");
- break;
-
- case min_slew_error:
- format_error_text(response,-222,"Slew rate too low.");
- break;
-
- case max_load_type_error:
- format_error_text(response,-222,"Resistance too high.");
- break;
-
- case min_load_type_error:
- format_error_text(response,-222,"Duty cycle too high or load resistance too low.");
- break;
-
- case max_soft_current_limit_error:
- format_error_text(response,-222,"Current limit too high.");
- break;
-
- case min_soft_current_limit_error:
- format_error_text(response,-222,"Current limit too low.");
- break;
-
- case duty_cycle_upper_limit:
- format_error_text(response,-222,"Duty cycle too high.");
- break;
-
- case Average_Amplitude_Too_High:
- format_error_text(response,-222,"Average amplitude too high.");
- break;
-
- case delay_lower_limit:
- format_error_text(response,-222,"Delay too low.");
- break;
-
- case delay_upper_limit:
- format_error_text(response,-222,"Delay too high.");
- break;
-
- case amplitude_lower_limit:
- format_error_text(response,-222,"Amplitude too low.");
- break;
-
- case amplitude_upper_limit:
- format_error_text(response,-222,"Amplitude too high.");
- break;
-
- case peak_power_limit:
- format_error_text(response,-222,"Peak power too high.");
- break;
-
- case average_power_limit:
- format_error_text(response,-222,"Average power too high.");
- break;
-
- case offset_lower_limit:
- format_error_text(response,-222,"Offset too low.");
- break;
-
- case offset_upper_limit:
- format_error_text(response,-222,"Offset too high.");
- break;
-
- case ampl_plus_os_lower_limit:
- format_error_text(response,-222,"AMPL+OS too low.");
- break;
-
- case ampl_plus_os_upper_limit:
- format_error_text(response,-222,"AMPL+OS too high.");
- break;
-
- case DutyTriggerError:
- format_error_text(response,-221,"Duty cycle can not be set. Set PW instead.");
- break;
-
- case PW_Exceeds_Double_Separation:
- format_error_text(response,-221,"PW can not exceed double pulse separation.");
- break;
-
- case Double_Separation_Too_Large:
- format_error_text(response,-221,"Double pulse separation is too high. It must be < 95% of the period.");
- break;
-
- case queue_overflow:
- format_error_text(response,-350,"Clear with *cls or syst:err.");
- break;
-
- case query_error_interrupted:
- format_error_text(response,-400,"Data lost in output buffer.");
- break;
-
- case query_error_unterminated:
- format_error_text(response,-400,"No data to send.");
- break;
-
- case Overload_Detected:
- format_error_text(response,-300,"Power supply overload detected. The output has been turned off.");
- break;
-
- case Overtemp_Detected:
- format_error_text(response,-300,"Overheating problem. The output has been turned off.");
- break;
-
- case Overvolt_Detected:
- format_error_text(response,-300,"Over-voltage or over-current! The output has been turned off.");
- break;
-
- case Soft_Limit_Exceeded:
- format_error_text(response,-300,"Monitor current limit exceeded! The output has been turned off.");
- break;
-
- case Device_Specific_Aux_Error_Detected:
- // replace with "FIXME" if Flash not implemented yet
- format_error_text(response,-300,globals.Flash.aux_error_message);
- break;
-
- case CalibrationPercentError:
- format_error_text(response,-340,"Percent change is too large.");
- break;
-
- case CalibrationPolarityError:
- format_error_text(response,-340,"Old and new polarities disagree.");
- break;
-
- case CalibrationZeroError:
- format_error_text(response,-340,"Zero point can not be changed.");
- break;
-
- case CalibrationMinMaxError:
- format_error_text(response,-340,"Would prevent operation at the minimum or maximum settings.");
- break;
-
- case CalibrationClosenessError:
- format_error_text(response,-340,"Too few calibration points, or they are too closely spaced.");
- break;
-
- case CalibrationRangeError:
- format_error_text(response,-340,"Top or bottom of range. Can not be deleted.");
- break;
-
- case SelfCalError:
- format_error_text(response,-340,"Calibration problem.");
- break;
-
- case HardwareError:
- format_error_text(response,-240,"Not possible with the current calibration settings.");
- break;
-
- case CalibrationTimingProblem:
- format_error_text(response,-221,"Set timing to allow operation at minimum and maximum amplitudes.");
- break;
-
- case Coupled_OS_Ampl_Error:
- format_error_text(response,-221,"If ampl > 0, ampl+offset must be > 0, if ampl < 0, ampl+offset must be < 0.");
- break;
-
- case PW_Distort_Error:
- format_error_text(response,-240,"Not possible with the current PW distortion settings.");
- break;
-
- case burst_duty_error:
- format_error_text(response,-222,"Duty cycle inside burst is too high.");
- break;
-
- case min_burst_period_error:
- format_error_text(response,-222,"Time between consecutive rising edges inside burst is too low.");
- break;
-
- case max_burst_count_error:
- format_error_text(response,-222,"Too many pulses per burst.");
- break;
-
- case min_burst_gap_error:
- format_error_text(response,-222,"Pulse separation too low.");
- break;
-
- case max_burst_gap_error:
- format_error_text(response,-222,"Pulse separation too high.");
- break;
-
- case Burst_Exceeds_Period:
- format_error_text(response,-222,"Burst width can not exceed period.");
- break;
-
- case password_change_error:
- format_error_text(response,-222,"Incorrect old password, or new password is too long or short. ");
- break;
-
- default:
- format_error_text(response,-200,"Specific problem unknown.");
- }
-
-}
-
+/* START LIBRARY DESCRIPTION *********************************************
+ERRCHK.LIB
+ Copyright (c) 2006, Avtech Electrosystems Ltd.
+
+DESCRIPTION:
+ Error-checking and reporting functions.
+
+SUPPORT LIB'S:
+END DESCRIPTION **********************************************************/
+
+
+/*** BeginHeader Error_check */
+
+#include <string.h>
+#include <glib/gprintf.h>
+#include "globals.h"
+#include "dummy_functions.h"
+#include "lcd.h"
+
+/*** EndHeader */
+
+/* FIXME */
+int Error_Screen=NO;
+
+void set_gpib_error_flags (int error_num);
+
+void set_gpib_error_flags (int error_num)
+{
+
+ if (error_num == OK) {
+ return;
+ }
+
+ /* set the error flags in the GPIB ESR register right away */
+ switch (error_num) {
+ case AsyncModeDisabled:
+ case Unrecognized:
+ case SyntaxError:
+ case UnknownUnits:
+ case InvalidChannel:
+ GPIB_Set_Command_Error();
+ break;
+ case query_error_interrupted:
+ case query_error_unterminated:
+ GPIB_Set_Query_Error();
+ break;
+ case Overload_Detected:
+ case Overtemp_Detected:
+ case Overvolt_Detected:
+ case Device_Specific_Aux_Error_Detected:
+ case queue_overflow:
+ case CalibrationPercentError:
+ case CalibrationZeroError:
+ case CalibrationMinMaxError:
+ case CalibrationClosenessError:
+ case CalibrationRangeError:
+ case CalibrationPolarityError:
+ case Soft_Limit_Exceeded:
+ case SelfCalError:
+ GPIB_Set_Device_Dependent_Error();
+ break;
+ default:
+ GPIB_Set_Execution_Error();
+ break;
+ }
+
+ return;
+}
+
+void queue_error(int error_num);
+
+void queue_error(int error_num)
+{
+ if (error_num == OK) {
+ return;
+ }
+
+ set_gpib_error_flags (error_num);
+ if (globals.number_of_errors<error_queue_length) {
+ ++globals.number_of_errors;
+ globals.error_queue[globals.number_of_errors]=error_num;
+ } else {
+ globals.error_queue[globals.number_of_errors]=queue_overflow;
+ }
+
+ return;
+}
+
+
+
+/*----------------------------------------------------------------------------------------------------------*/
+void queue_error_and_get_text(gchar** response, int error_num)
+{
+ g_assert (*response == NULL);
+
+ if (error_num == OK) {
+ return;
+ }
+ queue_error (error_num);
+ get_error_text (response, error_num);
+ return;
+}
+
+/*----------------------------------------------------------------------------------------------------------*/
+void queue_error_from_parser(gchar** response, int error_num)
+{
+ g_assert (*response == NULL);
+
+ if (error_num == OK) {
+ return;
+ }
+ queue_error_and_get_text(response, error_num);
+ Menu_Refresh();
+ return;
+}
+
+
+void queue_error_for_gpib_only(int error_num);
+
+void queue_error_for_gpib_only(int error_num)
+{
+// not part of this project, but left in for coder's reference. Can be deleted for now
+ if (error_num == OK) {
+ return;
+ }
+ queue_error(error_num);
+ return;
+}
+
+
+void queue_error_and_display_on_LCD(int error_num);
+
+void queue_error_and_display_on_LCD(int error_num)
+{
+ gchar* response = NULL;
+ queue_error_and_get_text(&response, error_num);
+ LCD_display_error_message (response);
+}
+
+
+void queue_and_broadcast_sensor_alarm(int error_num);
+
+void queue_and_broadcast_sensor_alarm(int error_num)
+{
+// not part of this project, but left in for coder's reference. Can be deleted for now
+}
+
+/*----------------------------------------------------------------------------------------------------------*/
+void Error_Remove_From_Queue(void)
+{
+ int i;
+ for (i=1; i<globals.number_of_errors; ++i) {
+ globals.error_queue[i]=globals.error_queue[i+1];
+ }
+ --globals.number_of_errors; /* error reported, so remove it from the error queue */
+}
+
+
+void format_error_text (gchar **response, int error_type, char *in);
+
+void format_error_text (gchar **response, int error_type, char *in)
+{
+ char* prefix = NULL;
+
+ switch (error_type) {
+ case 0:
+ prefix = g_strdup("No error");
+ break;
+ case -100:
+ prefix=g_strdup("Command error");
+ break;
+ case -102:
+ prefix=g_strdup("Syntax error");
+ break;
+ case -114:
+ prefix=g_strdup("Command error");
+ break;
+ case -131:
+ prefix=g_strdup("Invalid suffix");
+ break;
+ case -200:
+ prefix=g_strdup("Execution error");
+ break;
+ case -221:
+ prefix=g_strdup("Settings conflict");
+ break;
+ case -222:
+ prefix=g_strdup("Data out of range");
+ break;
+ case -224:
+ prefix=g_strdup("Illegal parameter value");
+ break;
+ case -240:
+ prefix=g_strdup("Hardware error");
+ break;
+ case -300:
+ prefix=g_strdup("Device-specific error");
+ break;
+ case -340:
+ prefix=g_strdup("Calibration failed");
+ break;
+ case -350:
+ prefix=g_strdup("Queue overflow");
+ break;
+ case -400:
+ prefix=g_strdup("Query error");
+ break;
+ default:
+ prefix=g_strdup("System error");
+ break;
+ }
+
+
+ *response = g_strdup_printf("%d, \"%s; %s\"", error_type, prefix, in);
+ g_free(prefix);
+}
+
+
+void get_error_text(gchar **response, int error_num)
+{
+ switch (error_num) {
+
+ case OK:
+ format_error_text(response,0,"");
+ break;
+
+ case Unrecognized:
+ format_error_text(response,-102,"Unrecognized command.");
+ break;
+
+ case AsyncModeDisabled:
+ format_error_text(response,-102,"Async gating not available.");
+ break;
+
+ case SyntaxError:
+ format_error_text(response,-100,"Recognized command, but improper syntax.");
+ break;
+
+ case InvalidChannel:
+ format_error_text(response,-114,"Invalid channel suffix.");
+ break;
+
+ case OutOfRange:
+ format_error_text(response,-222,"Too high or too low.");
+ break;
+
+ case Negative_Not_Allowed:
+ format_error_text(response,-222,"Negative value not allowed.");
+ break;
+
+ case IllegalParameter:
+ case amplitude_confined_values:
+ format_error_text(response,-224,"Not in list of allowed values.");
+ break;
+
+ case UnknownUnits:
+ format_error_text(response,-131,"Unrecognized units.");
+ break;
+
+ case Route_Range_Error:
+ format_error_text(response,-224,"Ranges are not supported.");
+ break;
+
+ case AB_Mode_Error:
+ format_error_text(response,-221,"This PW mode is not valid for the current trigger mode.");
+ break;
+
+ case Valid_For_RS232_TELNET_Only:
+ format_error_text(response,-221,"Command valid in RS232 or TELNET modes only.");
+ break;
+
+ case PW_Exceeds_Period:
+ format_error_text(response,-221,"PW can not exceed period.");
+ break;
+
+ case Delay_Exceeds_95Period:
+ format_error_text(response,-221,"Delay can not exceed 95% of period.");
+ break;
+
+ case NeedNonZeroAmpl:
+ format_error_text(response,-222,"Amplitude must be non-zero.");
+ break;
+
+ case freq_lower_limit:
+ format_error_text(response,-222,"PRF too low.");
+ break;
+
+ case freq_upper_limit:
+ format_error_text(response,-222,"PRF too high.");
+ break;
+
+ case pw_lower_limit:
+ format_error_text(response,-222,"PW too low.");
+ break;
+
+ case pw_upper_limit:
+ format_error_text(response,-222,"PW too high.");
+ break;
+
+ case max_rise_time_error:
+ format_error_text(response,-222,"Rise time too high.");
+ break;
+
+ case min_rise_time_error:
+ format_error_text(response,-222,"Rise time too low.");
+ break;
+
+ case max_slew_error:
+ format_error_text(response,-222,"Slew rate too high.");
+ break;
+
+ case min_slew_error:
+ format_error_text(response,-222,"Slew rate too low.");
+ break;
+
+ case max_load_type_error:
+ format_error_text(response,-222,"Resistance too high.");
+ break;
+
+ case min_load_type_error:
+ format_error_text(response,-222,"Duty cycle too high or load resistance too low.");
+ break;
+
+ case max_soft_current_limit_error:
+ format_error_text(response,-222,"Current limit too high.");
+ break;
+
+ case min_soft_current_limit_error:
+ format_error_text(response,-222,"Current limit too low.");
+ break;
+
+ case duty_cycle_upper_limit:
+ format_error_text(response,-222,"Duty cycle too high.");
+ break;
+
+ case Average_Amplitude_Too_High:
+ format_error_text(response,-222,"Average amplitude too high.");
+ break;
+
+ case delay_lower_limit:
+ format_error_text(response,-222,"Delay too low.");
+ break;
+
+ case delay_upper_limit:
+ format_error_text(response,-222,"Delay too high.");
+ break;
+
+ case amplitude_lower_limit:
+ format_error_text(response,-222,"Amplitude too low.");
+ break;
+
+ case amplitude_upper_limit:
+ format_error_text(response,-222,"Amplitude too high.");
+ break;
+
+ case peak_power_limit:
+ format_error_text(response,-222,"Peak power too high.");
+ break;
+
+ case average_power_limit:
+ format_error_text(response,-222,"Average power too high.");
+ break;
+
+ case offset_lower_limit:
+ format_error_text(response,-222,"Offset too low.");
+ break;
+
+ case offset_upper_limit:
+ format_error_text(response,-222,"Offset too high.");
+ break;
+
+ case ampl_plus_os_lower_limit:
+ format_error_text(response,-222,"AMPL+OS too low.");
+ break;
+
+ case ampl_plus_os_upper_limit:
+ format_error_text(response,-222,"AMPL+OS too high.");
+ break;
+
+ case DutyTriggerError:
+ format_error_text(response,-221,"Duty cycle can not be set. Set PW instead.");
+ break;
+
+ case PW_Exceeds_Double_Separation:
+ format_error_text(response,-221,"PW can not exceed double pulse separation.");
+ break;
+
+ case Double_Separation_Too_Large:
+ format_error_text(response,-221,"Double pulse separation is too high. It must be < 95% of the period.");
+ break;
+
+ case queue_overflow:
+ format_error_text(response,-350,"Clear with *cls or syst:err.");
+ break;
+
+ case query_error_interrupted:
+ format_error_text(response,-400,"Data lost in output buffer.");
+ break;
+
+ case query_error_unterminated:
+ format_error_text(response,-400,"No data to send.");
+ break;
+
+ case Overload_Detected:
+ format_error_text(response,-300,"Power supply overload detected. The output has been turned off.");
+ break;
+
+ case Overtemp_Detected:
+ format_error_text(response,-300,"Overheating problem. The output has been turned off.");
+ break;
+
+ case Overvolt_Detected:
+ format_error_text(response,-300,"Over-voltage or over-current! The output has been turned off.");
+ break;
+
+ case Soft_Limit_Exceeded:
+ format_error_text(response,-300,"Monitor current limit exceeded! The output has been turned off.");
+ break;
+
+ case Device_Specific_Aux_Error_Detected:
+ // replace with "FIXME" if Flash not implemented yet
+ format_error_text(response,-300,globals.Flash.aux_error_message);
+ break;
+
+ case CalibrationPercentError:
+ format_error_text(response,-340,"Percent change is too large.");
+ break;
+
+ case CalibrationPolarityError:
+ format_error_text(response,-340,"Old and new polarities disagree.");
+ break;
+
+ case CalibrationZeroError:
+ format_error_text(response,-340,"Zero point can not be changed.");
+ break;
+
+ case CalibrationMinMaxError:
+ format_error_text(response,-340,"Would prevent operation at the minimum or maximum settings.");
+ break;
+
+ case CalibrationClosenessError:
+ format_error_text(response,-340,"Too few calibration points, or they are too closely spaced.");
+ break;
+
+ case CalibrationRangeError:
+ format_error_text(response,-340,"Top or bottom of range. Can not be deleted.");
+ break;
+
+ case SelfCalError:
+ format_error_text(response,-340,"Calibration problem.");
+ break;
+
+ case HardwareError:
+ format_error_text(response,-240,"Not possible with the current calibration settings.");
+ break;
+
+ case CalibrationTimingProblem:
+ format_error_text(response,-221,"Set timing to allow operation at minimum and maximum amplitudes.");
+ break;
+
+ case Coupled_OS_Ampl_Error:
+ format_error_text(response,-221,"If ampl > 0, ampl+offset must be > 0, if ampl < 0, ampl+offset must be < 0.");
+ break;
+
+ case PW_Distort_Error:
+ format_error_text(response,-240,"Not possible with the current PW distortion settings.");
+ break;
+
+ case burst_duty_error:
+ format_error_text(response,-222,"Duty cycle inside burst is too high.");
+ break;
+
+ case min_burst_period_error:
+ format_error_text(response,-222,"Time between consecutive rising edges inside burst is too low.");
+ break;
+
+ case max_burst_count_error:
+ format_error_text(response,-222,"Too many pulses per burst.");
+ break;
+
+ case min_burst_gap_error:
+ format_error_text(response,-222,"Pulse separation too low.");
+ break;
+
+ case max_burst_gap_error:
+ format_error_text(response,-222,"Pulse separation too high.");
+ break;
+
+ case Burst_Exceeds_Period:
+ format_error_text(response,-222,"Burst width can not exceed period.");
+ break;
+
+ case password_change_error:
+ format_error_text(response,-222,"Incorrect old password, or new password is too long or short. ");
+ break;
+
+ default:
+ format_error_text(response,-200,"Specific problem unknown.");
+ }
+
+}
+
diff --git a/lcd.c b/lcd.c
index 508f1a0..076cd8e 100644
--- a/lcd.c
+++ b/lcd.c
@@ -1,308 +1,308 @@
-#include "i2c.h"
-#include "lcd.h"
-#include <glib.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define LCD_ENABLE 0x03 /* the 4x40 LCDs have two enable lines - 0x03 enables both at the same time */
-#define LCD_DATA_RAM 128 /* display RAM, in the LCD ICs */
-#define LCD_CG_RAM 64 /* custom character RAM, in the LCD ICs */
-
-#define LCD_chars_total 160
-#define LCD_cols 40
-#define LCD_rows 4 /* 4x40 LCD */
-
-char LCD_Data[LCD_rows][LCD_cols]; /* shadow copy of LCD display in local RAM, to minimize slow I2C writes */
-
-/*** EndHeader */
-
-
-static void break_up_string (char *in_string, int N, char **str1, char **str2, char **str3)
-{
-
-#define SUBSTRING_CNT 3
-
- int input_length;
- int j, k, copypos;
- int n;
-
- char *copy_input;
- char *p;
-
- j=k=copypos=0;
- input_length=strlen(in_string);
- copy_input = g_strdup(in_string);
-
- for (j=0; j<SUBSTRING_CNT; j++) {
-
- gchar *interm_str = g_strnfill (N, 0);
-
- for (k=0; k<N; k++) {
- copypos++; // next symbol
- if (copypos>input_length) {
- break;
- }
- if ((*(copy_input+k)==' ')&&(copypos<input_length)) { // space found
- //find next space
- p=strchr(copy_input+k+1,' ');
- if (p!=NULL) {
- // next space is beyond N char limit for one line
- if((p-copy_input)/sizeof(char)>=N) {
- break;
- }
- } else {
- // No more spaces. Does the last chunk of text fit?
- if (strlen(copy_input+k+1)>N-k) {
- break;
- }
- }
- }
- // valid character, copy to output string
- *(interm_str+k)=*(copy_input+k);
-
- }
- // remove processed part from the input
- if (copypos<=input_length) {
- strcpy(copy_input, in_string+copypos);
- }
- n = strlen(interm_str);
- for ((k=n-1); (k=0); k--) { //trim space
- if (*(interm_str+k)==' ') {
- *(interm_str+k)=0;
- } else {
- break;
- }
- }
- switch (j) {
- case 0:
- *str1 = g_strdup(interm_str);
- break;
- case 1:
- *str2 = g_strdup(interm_str);
- break;
- case 2:
- *str3 = g_strdup(interm_str);
- break;
- }
- g_free(interm_str);
-
- }
-
- g_free(copy_input);
-}
-
-
-
-
-void LCD_clear()
-{
- int i;
- int j;
-
- I2C_Write(PCF8574A+LCD_Port, 0x00 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x00);
- I2C_Write(PCF8574A+LCD_Port, 0x10 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x10);
-
- /* wait 1.64ms */
- g_usleep(1640);
-
- for (i=0; i<4; ++i)
- for (j=0; j<40; ++j) {
- LCD_Data[i][j]=0;
- }
-
- return;
-}
-
-
-static void LCD_RAM_write(int RAM_start,int row, int col, char *LCD_string)
-{
- /* rows: 0-3, cols: 0-39 */
-
-#define data_level 0x04
-
- int i;
- int cur_row, cur_col;
- int String_length;
- char char_out, enable_one_lcd;
- int ram_location;
- char last_op_a_write;
-
- if (!LCD_string) {
- return;
- }
-
- String_length=strlen(LCD_string);
- enable_one_lcd=0x02;
-
- last_op_a_write=0;
- cur_row=row;
- cur_col=col;
-
- if (cur_row<2) {
- enable_one_lcd=0x02;
- } else {
- enable_one_lcd=0x01;
- }
-
- /* write out the string */
- for (i=0; i<String_length; ++i) {
- if (cur_row<2) {
- enable_one_lcd=0x02;
- } else {
- enable_one_lcd=0x01;
- }
-
- if (LCD_string[i]!=LCD_Data[cur_row][cur_col]) {
- if (!last_op_a_write) {
- /* move to new position */
- ram_location = (cur_row & 1) * 64 + cur_col + RAM_start;
- char_out=ram_location & 0xf0;
- I2C_Write(PCF8574A+LCD_Port, char_out | enable_one_lcd);
- I2C_Write(PCF8574A+LCD_Port, char_out);
- char_out=ram_location << 4;
- I2C_Write(PCF8574A+LCD_Port, char_out | enable_one_lcd);
- I2C_Write(PCF8574A+LCD_Port, char_out);
- }
- LCD_Data[cur_row][cur_col]=LCD_string[i];
- char_out=LCD_string[i] & 0xf0;
- I2C_Write(PCF8574A+LCD_Port, char_out | enable_one_lcd | data_level);
- I2C_Write(PCF8574A+LCD_Port, char_out | data_level);
- char_out=LCD_string[i] << 4;
- I2C_Write(PCF8574A+LCD_Port, char_out | enable_one_lcd | data_level);
- I2C_Write(PCF8574A+LCD_Port, char_out | data_level);
- last_op_a_write=1;
- } else {
- last_op_a_write=0;
- }
-
- ++cur_col;
- if (cur_col==40) {
- cur_col=0;
- ++cur_row;
- }
- }
- return;
-}
-
-
-void LCD_write(int row, int col, char *LCD_string)
-{
- LCD_RAM_write(LCD_DATA_RAM, row, col, LCD_string);
- return;
-}
-
-
-static void LCD_make_custom_chars()
-{
- /* define custom LCD characters 2 and 3 (up arrow and down arrow).*/
- /* The up arrow is stored in one LCD controller (for rows 0 and 1) */
- /* The down arrow is stored in the other LCD controller (for rows 2 and 3) */
- LCD_RAM_write(LCD_CG_RAM,0,16,"\x4");
- LCD_RAM_write(LCD_CG_RAM,0,17,"\xe");
- LCD_RAM_write(LCD_CG_RAM,0,18,"\x15");
- LCD_RAM_write(LCD_CG_RAM,0,19,"\x4");
- LCD_RAM_write(LCD_CG_RAM,0,20,"\x4");
- LCD_RAM_write(LCD_CG_RAM,0,21,"\x4");
- LCD_RAM_write(LCD_CG_RAM,0,22,"\x4");
- LCD_RAM_write(LCD_CG_RAM,0,23,"\x4");
- LCD_RAM_write(LCD_CG_RAM,2,24,"\x4");
- LCD_RAM_write(LCD_CG_RAM,2,25,"\x4");
- LCD_RAM_write(LCD_CG_RAM,2,26,"\x4");
- LCD_RAM_write(LCD_CG_RAM,2,27,"\x4");
- LCD_RAM_write(LCD_CG_RAM,2,28,"\x4");
- LCD_RAM_write(LCD_CG_RAM,2,29,"\x15");
- LCD_RAM_write(LCD_CG_RAM,2,30,"\xe");
- LCD_RAM_write(LCD_CG_RAM,2,31,"\x4");
-// prove that it works - debug only
-// LCD_RAM_write(LCD_DATA_RAM,0,39,"\x2");
-// LCD_RAM_write(LCD_DATA_RAM,3,39,"\x3");
-
- return;
-}
-
-
-void LCD_initialize(void)
-{
- /* Wait 15ms */
- g_usleep(15000);
-
- I2C_Write(PCF8574A+LCD_Port, 0x30 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x30);
-
- /* wait 4.1ms */
- g_usleep(4100);
-
- I2C_Write(PCF8574A+LCD_Port, 0x30 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x30);
-
- /* wait 100us */
- g_usleep(100);
-
- I2C_Write(PCF8574A+LCD_Port, 0x30 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x30);
-
- /* wait 4.1ms */
- g_usleep(4100);
-
- I2C_Write(PCF8574A+LCD_Port, 0x20 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x20);
-
- /*wait 40us */
- g_usleep(40);
-
- I2C_Write(PCF8574A+LCD_Port, 0x20 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x20);
- I2C_Write(PCF8574A+LCD_Port, 0x80 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x80);
-
- /* wait 40us */
- g_usleep(40);
-
- LCD_clear();
-
- I2C_Write(PCF8574A+LCD_Port, 0x00 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x00);
- I2C_Write(PCF8574A+LCD_Port, 0x60 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x60);
-
- /* wait 40us */
- g_usleep(40);
-
- I2C_Write(PCF8574A+LCD_Port, 0x00 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0x00);
- I2C_Write(PCF8574A+LCD_Port, 0xc0 | LCD_ENABLE);
- I2C_Write(PCF8574A+LCD_Port, 0xc0);
-
- LCD_make_custom_chars();
-
- return;
-}
-
-
-void LCD_display_error_message(char *response)
-{
- char *row0 = NULL;
- char *row1 = NULL;
- char *row2 = NULL;
-
-// Error_Screen=1; //FIXME
-
- break_up_string (response, LCD_cols, &row0, &row1, &row2);
-
- LCD_clear();
- LCD_write(0,0,row0);
- LCD_write(1,0,row1);
- LCD_write(2,0,row2);
- LCD_write(3,0,Press_Change_Message);
-
- g_free (row0);
- g_free (row1);
- g_free (row2);
-
- return;
-}
-
-
-
+#include "i2c.h"
+#include "lcd.h"
+#include <glib.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define LCD_ENABLE 0x03 /* the 4x40 LCDs have two enable lines - 0x03 enables both at the same time */
+#define LCD_DATA_RAM 128 /* display RAM, in the LCD ICs */
+#define LCD_CG_RAM 64 /* custom character RAM, in the LCD ICs */
+
+#define LCD_chars_total 160
+#define LCD_cols 40
+#define LCD_rows 4 /* 4x40 LCD */
+
+char LCD_Data[LCD_rows][LCD_cols]; /* shadow copy of LCD display in local RAM, to minimize slow I2C writes */
+
+/*** EndHeader */
+
+
+static void break_up_string (char *in_string, int N, char **str1, char **str2, char **str3)
+{
+
+#define SUBSTRING_CNT 3
+
+ int input_length;
+ int j, k, copypos;
+ int n;
+
+ char *copy_input;
+ char *p;
+
+ j=k=copypos=0;
+ input_length=strlen(in_string);
+ copy_input = g_strdup(in_string);
+
+ for (j=0; j<SUBSTRING_CNT; j++) {
+
+ gchar *interm_str = g_strnfill (N, 0);
+
+ for (k=0; k<N; k++) {
+ copypos++; // next symbol
+ if (copypos>input_length) {
+ break;
+ }
+ if ((*(copy_input+k)==' ')&&(copypos<input_length)) { // space found
+ //find next space
+ p=strchr(copy_input+k+1,' ');
+ if (p!=NULL) {
+ // next space is beyond N char limit for one line
+ if((p-copy_input)/sizeof(char)>=N) {
+ break;
+ }
+ } else {
+ // No more spaces. Does the last chunk of text fit?
+ if (strlen(copy_input+k+1)>N-k) {
+ break;
+ }
+ }
+ }
+ // valid character, copy to output string
+ *(interm_str+k)=*(copy_input+k);
+
+ }
+ // remove processed part from the input
+ if (copypos<=input_length) {
+ strcpy(copy_input, in_string+copypos);
+ }
+ n = strlen(interm_str);
+ for ((k=n-1); (k=0); k--) { //trim space
+ if (*(interm_str+k)==' ') {
+ *(interm_str+k)=0;
+ } else {
+ break;
+ }
+ }
+ switch (j) {
+ case 0:
+ *str1 = g_strdup(interm_str);
+ break;
+ case 1:
+ *str2 = g_strdup(interm_str);
+ break;
+ case 2:
+ *str3 = g_strdup(interm_str);
+ break;
+ }
+ g_free(interm_str);
+
+ }
+
+ g_free(copy_input);
+}
+
+
+
+
+void LCD_clear()
+{
+ int i;
+ int j;
+
+ I2C_Write(PCF8574A+LCD_Port, 0x00 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x00);
+ I2C_Write(PCF8574A+LCD_Port, 0x10 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x10);
+
+ /* wait 1.64ms */
+ g_usleep(1640);
+
+ for (i=0; i<4; ++i)
+ for (j=0; j<40; ++j) {
+ LCD_Data[i][j]=0;
+ }
+
+ return;
+}
+
+
+static void LCD_RAM_write(int RAM_start,int row, int col, char *LCD_string)
+{
+ /* rows: 0-3, cols: 0-39 */
+
+#define data_level 0x04
+
+ int i;
+ int cur_row, cur_col;
+ int String_length;
+ char char_out, enable_one_lcd;
+ int ram_location;
+ char last_op_a_write;
+
+ if (!LCD_string) {
+ return;
+ }
+
+ String_length=strlen(LCD_string);
+ enable_one_lcd=0x02;
+
+ last_op_a_write=0;
+ cur_row=row;
+ cur_col=col;
+
+ if (cur_row<2) {
+ enable_one_lcd=0x02;
+ } else {
+ enable_one_lcd=0x01;
+ }
+
+ /* write out the string */
+ for (i=0; i<String_length; ++i) {
+ if (cur_row<2) {
+ enable_one_lcd=0x02;
+ } else {
+ enable_one_lcd=0x01;
+ }
+
+ if (LCD_string[i]!=LCD_Data[cur_row][cur_col]) {
+ if (!last_op_a_write) {
+ /* move to new position */
+ ram_location = (cur_row & 1) * 64 + cur_col + RAM_start;
+ char_out=ram_location & 0xf0;
+ I2C_Write(PCF8574A+LCD_Port, char_out | enable_one_lcd);
+ I2C_Write(PCF8574A+LCD_Port, char_out);
+ char_out=ram_location << 4;
+ I2C_Write(PCF8574A+LCD_Port, char_out | enable_one_lcd);
+ I2C_Write(PCF8574A+LCD_Port, char_out);
+ }
+ LCD_Data[cur_row][cur_col]=LCD_string[i];
+ char_out=LCD_string[i] & 0xf0;
+ I2C_Write(PCF8574A+LCD_Port, char_out | enable_one_lcd | data_level);
+ I2C_Write(PCF8574A+LCD_Port, char_out | data_level);
+ char_out=LCD_string[i] << 4;
+ I2C_Write(PCF8574A+LCD_Port, char_out | enable_one_lcd | data_level);
+ I2C_Write(PCF8574A+LCD_Port, char_out | data_level);
+ last_op_a_write=1;
+ } else {
+ last_op_a_write=0;
+ }
+
+ ++cur_col;
+ if (cur_col==40) {
+ cur_col=0;
+ ++cur_row;
+ }
+ }
+ return;
+}
+
+
+void LCD_write(int row, int col, char *LCD_string)
+{
+ LCD_RAM_write(LCD_DATA_RAM, row, col, LCD_string);
+ return;
+}
+
+
+static void LCD_make_custom_chars()
+{
+ /* define custom LCD characters 2 and 3 (up arrow and down arrow).*/
+ /* The up arrow is stored in one LCD controller (for rows 0 and 1) */
+ /* The down arrow is stored in the other LCD controller (for rows 2 and 3) */
+ LCD_RAM_write(LCD_CG_RAM,0,16,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,0,17,"\xe");
+ LCD_RAM_write(LCD_CG_RAM,0,18,"\x15");
+ LCD_RAM_write(LCD_CG_RAM,0,19,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,0,20,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,0,21,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,0,22,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,0,23,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,2,24,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,2,25,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,2,26,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,2,27,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,2,28,"\x4");
+ LCD_RAM_write(LCD_CG_RAM,2,29,"\x15");
+ LCD_RAM_write(LCD_CG_RAM,2,30,"\xe");
+ LCD_RAM_write(LCD_CG_RAM,2,31,"\x4");
+// prove that it works - debug only
+// LCD_RAM_write(LCD_DATA_RAM,0,39,"\x2");
+// LCD_RAM_write(LCD_DATA_RAM,3,39,"\x3");
+
+ return;
+}
+
+
+void LCD_initialize(void)
+{
+ /* Wait 15ms */
+ g_usleep(15000);
+
+ I2C_Write(PCF8574A+LCD_Port, 0x30 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x30);
+
+ /* wait 4.1ms */
+ g_usleep(4100);
+
+ I2C_Write(PCF8574A+LCD_Port, 0x30 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x30);
+
+ /* wait 100us */
+ g_usleep(100);
+
+ I2C_Write(PCF8574A+LCD_Port, 0x30 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x30);
+
+ /* wait 4.1ms */
+ g_usleep(4100);
+
+ I2C_Write(PCF8574A+LCD_Port, 0x20 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x20);
+
+ /*wait 40us */
+ g_usleep(40);
+
+ I2C_Write(PCF8574A+LCD_Port, 0x20 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x20);
+ I2C_Write(PCF8574A+LCD_Port, 0x80 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x80);
+
+ /* wait 40us */
+ g_usleep(40);
+
+ LCD_clear();
+
+ I2C_Write(PCF8574A+LCD_Port, 0x00 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x00);
+ I2C_Write(PCF8574A+LCD_Port, 0x60 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x60);
+
+ /* wait 40us */
+ g_usleep(40);
+
+ I2C_Write(PCF8574A+LCD_Port, 0x00 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0x00);
+ I2C_Write(PCF8574A+LCD_Port, 0xc0 | LCD_ENABLE);
+ I2C_Write(PCF8574A+LCD_Port, 0xc0);
+
+ LCD_make_custom_chars();
+
+ return;
+}
+
+
+void LCD_display_error_message(char *response)
+{
+ char *row0 = NULL;
+ char *row1 = NULL;
+ char *row2 = NULL;
+
+// Error_Screen=1; //FIXME
+
+ break_up_string (response, LCD_cols, &row0, &row1, &row2);
+
+ LCD_clear();
+ LCD_write(0,0,row0);
+ LCD_write(1,0,row1);
+ LCD_write(2,0,row2);
+ LCD_write(3,0,Press_Change_Message);
+
+ g_free (row0);
+ g_free (row1);
+ g_free (row2);
+
+ return;
+}
+
+
+
diff --git a/lcd.h b/lcd.h
index c369017..0626237 100644
--- a/lcd.h
+++ b/lcd.h
@@ -1,7 +1,7 @@
-#define Press_Change_Message "Push CHANGE to continue."
-
-
-void LCD_display_error_message(char *response);
-void LCD_clear();
-void LCD_write(int row, int col, char *LCD_string);
-void LCD_initialize(void);
+#define Press_Change_Message "Push CHANGE to continue."
+
+
+void LCD_display_error_message(char *response);
+void LCD_clear();
+void LCD_write(int row, int col, char *LCD_string);
+void LCD_initialize(void);
diff --git a/parser.c b/parser.c
index d62d1f9..ea716be 100644
--- a/parser.c
+++ b/parser.c
@@ -1,1011 +1,1011 @@
-/* START LIBRARY DESCRIPTION *********************************************
-PARSER.LIB
- Copyright (c) 1997, Avtech Electrosystems Ltd.
-
-DESCRIPTION:
- Parser functions.
-
-SUPPORT LIB'S:
-END DESCRIPTION **********************************************************/
-
-
-#include "parser.h"
-#include <glib/gprintf.h>
-
-//STATICS
-static int query_int (gchar** response, int n);
-static int query_min_max_float (gchar** response, char *parameter, float min_val, float max_val);
-static int query_float (gchar** response, float value);
-static int process_float_param (char *parameter, float *value, float min_val, float max_val, int zero_mode);
-static int check_channel_ok (int channel, int enabled_channels, char chankey);
-static int Parser_id_word(char *id_me, int *channel, int *with_id_code);
-static int Parser_find_commands(int commands[], int command_depth);
-static int Parser_get_unit(char **parameter, char **units);
-static int Parser_channel (int *channel,int with_id_code,int routine_num);
-static int Go_freq_32_33(gchar** response, int channel, char *parameter,char *units,int command_type);
-static int Handle_Units(float *mult,char *units, char *base);
-static int Is_Min_Command(char *text);
-static int Is_Max_Command(char *text);
-static int Go_syst_err_11(gchar** response, int channel, char *parameter,char *units,int command_type);
-static int Go_syst_errcnt66(gchar** response, int channel, char *parameter,char *units,int command_type);
-
-static int Parser_id_word(char *id_me, int *channel, int *with_id_code)
-{
- int id_code;
- int set_new_channel;
-
- set_new_channel=0;
-
- /* detect channel suffixes in the range of 0-99 */
- if (isdigit((int) id_me[strlen(id_me)-1])) {
- set_new_channel=1;
- *channel=atoi(id_me+strlen(id_me)-1);
- if (isdigit((int) id_me[strlen(id_me)-2])) {
- *channel=atoi(id_me+strlen(id_me)-2);
- id_me[strlen(id_me)-2]=0;
- } else {
- id_me[strlen(id_me)-1]=0;
- }
- }
-
-
- if (!strcmp(id_me,"*cls") ) {
- id_code = 1;
- } else if (!strcmp(id_me,"*ese") ) {
- id_code = 2;
- } else if (!strcmp(id_me,"*esr") ) {
- id_code = 4;
- } else if (!strcmp(id_me,"*idn") ) {
- id_code = 5;
- } else if (!strcmp(id_me,"*opc") ) {
- id_code = 6;
- } else if (!strcmp(id_me,"*rst") ) {
- id_code = 8;
- } else if (!strcmp(id_me,"*sre") ) {
- id_code = 9;
- } else if (!strcmp(id_me,"*stb") ) {
- id_code = 10;
- } else if (!strcmp(id_me,"*tst") ) {
- id_code = 11;
- } else if (!strcmp(id_me,"*wai") ) {
- id_code = 12;
- } else if (!strcmp(id_me,"system") || !strcmp(id_me,"syst")) {
- id_code = 13;
- } else if (!strcmp(id_me,"error") || !strcmp(id_me,"err")) {
- id_code = 14;
- } else if (!strcmp(id_me,"version") || !strcmp(id_me,"vers")) {
- id_code = 15;
- } else if (!strcmp(id_me,"status") || !strcmp(id_me,"stat") || !strcmp(id_me,"state")) {
- id_code = 16;
- } else if (!strcmp(id_me,"operation") || !strcmp(id_me,"oper")) {
- id_code = 17;
- } else if (!strcmp(id_me,"event") || !strcmp(id_me,"even")) {
- id_code = 18;
- } else if (!strcmp(id_me,"condition") || !strcmp(id_me,"cond")) {
- id_code = 19;
- } else if (!strcmp(id_me,"enable") || !strcmp(id_me,"enab")) {
- id_code = 20;
- } else if (!strcmp(id_me,"questionable") || !strcmp(id_me,"ques")) {
- id_code = 21;
- } else if (!strcmp(id_me,"preset") || !strcmp(id_me,"pres")) {
- id_code = 22;
- } else if (!strcmp(id_me,"diagnostic") || !strcmp(id_me,"diag")) {
- id_code = 23;
- } else if (!strcmp(id_me,"output") || !strcmp(id_me,"outp")) {
- id_code = 24;
- } else if (!strcmp(id_me,"impedance") || !strcmp(id_me,"imp")) {
- id_code = 25;
- } else if (!strcmp(id_me,"protection") || !strcmp(id_me,"prot")) {
- id_code = 26;
- } else if (!strcmp(id_me,"tripped") || !strcmp(id_me,"trip")) {
- id_code = 27;
- } else if (!strcmp(id_me,"source") || !strcmp(id_me,"sour")) {
- id_code = 28;
- } else if (!strcmp(id_me,"current") || !strcmp(id_me,"curr")) {
- id_code = 29;
- } else if (!strcmp(id_me,"level") || !strcmp(id_me,"lev")) {
- id_code = 30;
- } else if (!strcmp(id_me,"immediate") || !strcmp(id_me,"imm")) {
- id_code = 31;
- } else if (!strcmp(id_me,"amplitude") || !strcmp(id_me,"ampl")) {
- id_code = 32;
- } else if (!strcmp(id_me,"offset") || !strcmp(id_me,"offs")) {
- id_code = 33;
- } else if (!strcmp(id_me,"high") ) {
- id_code = 34;
- } else if (!strcmp(id_me,"low") ) {
- id_code = 35;
- } else if (!strcmp(id_me,"voltage") || !strcmp(id_me,"volt")) {
- id_code = 36;
- } else if (!strcmp(id_me,"frequency") || !strcmp(id_me,"freq")) {
- id_code = 37;
- } else if (!strcmp(id_me,"function") || !strcmp(id_me,"func")) {
- id_code = 38;
- } else if (!strcmp(id_me,"shape") || !strcmp(id_me,"shap")) {
- id_code = 39;
- } else if (!strcmp(id_me,"pulse") || !strcmp(id_me,"puls")) {
- id_code = 40;
- } else if (!strcmp(id_me,"period") || !strcmp(id_me,"per")) {
- id_code = 41;
- } else if (!strcmp(id_me,"width") || !strcmp(id_me,"widt")) {
- id_code = 42;
- } else if (!strcmp(id_me,"dcycle") || !strcmp(id_me,"dcyc")) {
- id_code = 43;
- } else if (!strcmp(id_me,"hold") ) {
- id_code = 44;
- } else if (!strcmp(id_me,"delay") || !strcmp(id_me,"del")) {
- id_code = 45;
- } else if (!strcmp(id_me,"double") || !strcmp(id_me,"doub")) {
- id_code = 46;
- } else if (!strcmp(id_me,"polarity") || !strcmp(id_me,"pol")) {
- id_code = 47;
- } else if (!strcmp(id_me,"beeper") || !strcmp(id_me,"beep")) {
- id_code = 48;
- } else if (!strcmp(id_me,"cw") ) {
- id_code = 49;
- } else if (!strcmp(id_me,"fixed") || !strcmp(id_me,"fix")) {
- id_code = 50;
- } else if (!strcmp(id_me,"abort") || !strcmp(id_me,"abor")) {
- id_code = 51;
- } else if (!strcmp(id_me,"initiate") || !strcmp(id_me,"init")) {
- id_code = 52;
- } else if (!strcmp(id_me,"continuous")) {
- id_code = 53;
- } else if (!strcmp(id_me,"trigger") || !strcmp(id_me,"trig")) {
- id_code = 54;
- } else if (!strcmp(id_me,"integer") || !strcmp(id_me,"int")) {
- id_code = 55;
- } else if (!strcmp(id_me,"float") ) {
- id_code = 56;
- } else if (!strcmp(id_me,"eprom") ) {
- id_code = 57;
- } else if (!strcmp(id_me,"string") ) {
- id_code = 58;
- } else if (!strcmp(id_me,"bit") ) {
- id_code = 59;
- } else if (!strcmp(id_me,"set") ) {
- id_code = 60;
- } else if (!strcmp(id_me,"clear") ) {
- id_code = 61;
- } else if (!strcmp(id_me,"shiftreg") ) {
- id_code = 62;
- } else if (!strcmp(id_me,"*rcl") ) {
- id_code = 63;
- } else if (!strcmp(id_me,"*sav") ) {
- id_code = 64;
- } else if (!strcmp(id_me,"gate") ) {
- id_code = 65;
- } else if (!strcmp(id_me,"local") || !strcmp(id_me,"logout") || !strcmp(id_me,"exit") || !strcmp(id_me,"quit") ) {
- id_code = 66;
- } else if (!strcmp(id_me,"test") ) {
- id_code = 67;
- } else if (!strcmp(id_me,"communicate") || !strcmp(id_me,"comm")) {
- id_code = 68;
- } else if (!strcmp(id_me,"address") || !strcmp(id_me,"addr")) {
- id_code = 69;
- } else if (!strcmp(id_me,"gpib") ) {
- id_code = 70;
- } else if (!strcmp(id_me,"serial") || !strcmp(id_me,"ser")) {
- id_code = 71;
- } else if (!strcmp(id_me,"receive") || !strcmp(id_me,"rec")) {
- id_code = 72;
- } else if (!strcmp(id_me,"baud") ) {
- id_code = 73;
- } else if (!strcmp(id_me,"parity") || !strcmp(id_me,"par")) {
- id_code = 74;
- } else if (!strcmp(id_me,"type") ) {
- id_code = 75;
- } else if (!strcmp(id_me,"bits") ) {
- id_code = 76;
- } else if (!strcmp(id_me,"sbits") || !strcmp(id_me,"sbit")) {
- id_code = 77;
- } else if (!strcmp(id_me,"echo") ) {
- id_code = 78;
- } else if (!strcmp(id_me,"rts") ) {
- id_code = 79;
- } else if (!strcmp(id_me,"control") || !strcmp(id_me,"cont")) {
- id_code = 80;
- } else if (!strcmp(id_me,"next") ) {
- id_code = 81;
- } else if (!strcmp(id_me,"count") || !strcmp(id_me,"coun")) {
- id_code = 82;
- } else if (!strcmp(id_me,"display") || !strcmp(id_me,"disp")) {
- id_code = 83;
- } else if (!strcmp(id_me,"brightness") || !strcmp(id_me,"brig")) {
- id_code = 84;
- } else if (!strcmp(id_me,"load") ) {
- id_code = 85;
- } else if (!strcmp(id_me,"measure") || !strcmp(id_me,"meas")) {
- id_code = 86;
- } else if (!strcmp(id_me,"char") ) {
- id_code = 87;
- } else if (!strcmp(id_me,"calibration") || !strcmp(id_me,"cal")) {
- id_code = 88;
- } else if (!strcmp(id_me,"monitor") || !strcmp(id_me,"mon")) {
- id_code = 89;
- } else if (!strcmp(id_me,"step") ) {
- id_code = 90;
- } else if (!strcmp(id_me,"route") || !strcmp(id_me,"rout")) {
- id_code = 91;
- } else if (!strcmp(id_me,"close") || !strcmp(id_me,"clos")) {
- id_code = 92;
- } else if (!strcmp(id_me,"point") ) {
- id_code = 93;
- } else if (!strcmp(id_me,"shift") ) {
- id_code = 94;
- } else if (!strcmp(id_me,"scale") ) {
- id_code = 95;
- } else if (!strcmp(id_me,"null") ) {
- id_code = 96;
- } else if (!strcmp(id_me,"size") ) {
- id_code = 97;
- } else if (!strcmp(id_me,"separation") || !strcmp(id_me,"sep")) {
- id_code = 98;
- } else if (!strcmp(id_me,"network") || !strcmp(id_me,"net")) {
- id_code = 99;
- } else if (!strcmp(id_me,"password") || !strcmp(id_me,"pass")) {
- id_code = 100;
- } else if (!strcmp(id_me,"new") ) {
- id_code = 101;
- } else if (!strcmp(id_me,"suspend") ) {
- id_code = 102;
- } else if (!strcmp(id_me,"transition") || !strcmp(id_me,"tran")) {
- id_code = 103;
- } else if (!strcmp(id_me,"leading") || !strcmp(id_me,"lead")) {
- id_code = 104;
- } else if (!strcmp(id_me,"limit") || !strcmp(id_me,"lim")) {
- id_code = 105;
- } else if (!strcmp(id_me,"slew") ) {
- id_code = 106;
- } else if (!strcmp(id_me,"all") ) {
- id_code = 107;
- }
-
- else {
- id_code = 9999;
- }
-
- if (set_new_channel) {
- *with_id_code=id_code;
- }
-
- return id_code;
-
-}
-
-static int Parser_find_commands(int commands[], int command_depth)
-{
-#define optional 16384 /* set bit high if optional */
-#define opt_mask 16383 /* default bit mask */
-#define max_tokens_in_sentence 7
-#define max_no_of_sentences 110
-
- /* Valid command -sequences-. The -individual- commands are defined in id_word. */
-
- static const int sentences[max_no_of_sentences][max_tokens_in_sentence] = {
- {0}, /* null - error */
- {1}, /* cls - sentence 1 */
- {2}, /* ese - sentence 2 */
- {4}, /* esr - sentence 3 */
- {5}, /* idn - sentence 4 */
- {6}, /* opc - sentence 5 */
- {8}, /* rst - sentence 6 */
- {9}, /* sre - sentence 7 */
- {10}, /* stb - sentence 8 */
- {11}, /* tst - sentence 9 */
- {12}, /* wai - sentence 10 */
- {13,14,81|optional}, /* syst:err:next - 11 */
- {13,15}, /* syst:vers - 12 */
- {16,17,18|optional}, /* stat:oper:event - 13 */
- {16,17,19}, /* stat:oper:cond - 14 */
- {16,17,20}, /* stat:oper:enable - 15 */
- {16,21,18|optional}, /* stat:ques:event - 16 */
- {16,21,19}, /* stat:ques:cond - 17 */
- {16,21,20}, /* stat:ques:enable - 18 */
- {16,22}, /* stat:preset - 19 */
- {24,25}, /* output:impedance - 20 */
- {24,26,27}, /* output:prot:tripped - 21 */
- {28|optional,29,30|optional,31|optional,32|optional}, /* sour:curr:lev:imm:ampl - 22 */
- {28|optional,29,30|optional,31|optional,33}, /* sour:curr:lev:imm:offset - 23 - not used */
- {28|optional,29,30|optional,31|optional,34}, /* sour:curr:lev:imm:high - 24 - not used */
- {28|optional,29,30|optional,31|optional,35}, /* sour:curr:lev:imm:low - 25 */
- {28|optional,36,30|optional,31|optional,32|optional}, /* sour:volt:lev:imm:ampl - 26 */
- {28|optional,36,30|optional,31|optional,33}, /* sour:volt:lev:imm:offset - 27 - not used */
- {28|optional,36,30|optional,31|optional,34}, /* sour:volt:lev:imm:high - 28 - not used */
- {28|optional,36,30|optional,31|optional,35}, /* sour:volt:lev:imm:low - 29 */
- {28|optional,29,26,27}, /* sour:curr:prot:tripped? - 30 */
- {28|optional,36,26,27}, /* sour:volt:prot:tripped? - 31 */
- {28|optional,37,49|optional}, /* sour:freq:cw - 32 */
- {28|optional,37,50|optional}, /* sour:freq:fixed - 33 */
- {28|optional,38,39|optional}, /* sour:func:shape - 34 */
- {28|optional,40,41}, /* sour:puls:per - 35 */
- {28|optional,40,42}, /* sour:puls:width - 36 */
- {28|optional,40,43}, /* sour:puls:dcyc - 37 */
- {28|optional,40,44}, /* sour:puls:hold - 38 */
- {28|optional,40,45}, /* sour:puls:delay - 39 */
- {28|optional,40,46,16|optional}, /* sour:puls:doub:state - 40 */
- {28|optional,40,46,45}, /* sour:puls:doub:delay - 41 */
- {28|optional,40,47}, /* sour:puls:pol - 42 */
- {13,48,31|optional}, /* syst:beep:imm - 43 - not used */
- {52,31|optional,53}, /* init:imm:cont - 44 - not used */
- {51}, /* abort - 45 - not used */
- {54,31|optional,28}, /* trig:imm:sour - 46 */
- {23,57,58}, /* diag:eprom:string - 47 */
- {23,57,55}, /* diag:eprom:int - 48 */
- {23,57,59,60}, /* diag:eprom:bit:set - 49 - not used */
- {23,57,59,61}, /* diag:eprom:bit:clear - 50 - not used */
- {23,57,56}, /* diag:eprom:float - 51 */
- {23,62}, /* diag:shiftreg - 52 */
- {63}, /* *rcl - 53 */
- {64}, /* *sav - 54 */
- {24,16|optional}, /* output:state - 55 */
- {28|optional,40,65,75}, /* sour:puls:gate:type - 56 */
- {66}, /* local (RS232 mode only) - 57 */
- {23,67,45}, /* diag:test:delay - 58 */
- {13,68,70,69}, /* syst:comm:gpib:addr - 59 */
- {13,68,71,72|optional,73}, /* syst:comm:ser:rec:baud - 60 */
- {13,68,71,72|optional,74,75|optional}, /* syst:comm:ser:rec:parity - 61 */
- {13,68,71,72|optional,76}, /* syst:comm:ser:rec:bits - 62 */
- {13,68,71,72|optional,77}, /* syst:comm:ser:rec:sbits - 63 */
- {13,68,71,80,79}, /* syst:comm:ser:control:rts - 64 */
- {13,68,71,72|optional,78}, /* syst:comm:ser:rec:echo - 65 */
- {13,14,82}, /* syst:err:count - 66 */
- {28|optional,40,65,30}, /* sour:puls:gate:level - 67 */
- {24,85}, /* output:load - 68 */
- {86,32}, /* meas:ampl? - 69 */
- {23,57,87}, /* diag:eprom:char - 70 */
- {23,88}, /* diag:calib - 71 */
- {23,32,88,95|optional}, /* diag:ampl:calib:scale - 72 */
- {23,89,88,95|optional}, /* diag:mon:calib:scale - 73 */
- {23,89,90}, /* diag:mon:step - 74 */
- {24,75}, /* output:type - 75 */
- {23,33,88,95|optional}, /* diag:offset:calib:scale - 76 */
- {23,40,42,88,94}, /* diag:pulse:width:calib:shift - 77 */
- {91,92}, /* route:close - 78 */
- {23,40,42,88,93}, /* diag:pulse:width:calib:point - 79 */
- {23,40,45,88,93}, /* diag:pulse:delay:calib:point - 80 */
- {23,40,41,88,93}, /* diag:pulse:period:calib:point - 81 */
- {23,40,45,88,94}, /* diag:pulse:delay:calib:shift - 82 */
- {23,32,88,93}, /* diag:ampl:calib:point - 83 */
- {23,33,88,93}, /* diag:offset:calib:point - 84 */
- {23,33,96,93}, /* diag:offset:null:point - 85 */
- {23,57,97}, /* diag:eprom:size - 86 */
- {83,84}, /* display:brightness - 87 */
- {28|optional,40,82}, /* sour:puls:count - 88 */
- {28|optional,40,98}, /* sour:puls:separation - 89 */
- {23,40,98,88,93}, /* diag:pulse:separation:calib:point - 90 */
- {13,68,99}, /* system:comm:network - 91 */
- {13,100,101}, /* system:password:new - 92 */
- {23,57,102}, /* diag:eprom:suspend - 93 */
- {28|optional,40,103,104|optional}, /* sour:puls:transition:leading - 94 */
- {23,40,103,88,93}, /* diag:pulse:transition:calib:point - 95 */
- {28|optional,29,105,32|optional}, /* sour:curr:limit:ampl - 96 */
- {23,24,85,88,93}, /* diag:output:load:calib:point - 97 */
- {28|optional,29,106}, /* sour:curr:slew - 98 */
- {23,106,88,93}, /* diag:slew:calib:point - 99 */
- {88,107|optional}, /* calibration:all - 100 */
- {88,37} /* calibration:frequency - 101 */
-
- };
-
-
- int token_num; /* which token in the command[] list is being considered */
- int sentence_num; /* which sentence is being considered as a match */
- int sentence_found; /* matching sentence found yet? */
- int sent_pos; /* position in current sentence */
- int invalid_match; /* flag if definitely the wrong match */
- int local_match_pos; /* position (or pos+1, depends) of most-recently-matched token in sentence */
- int local_match; /* match for current token found yet? */
- int prev_match; /* were there previous local matches? */
- int i; /* a counter */
-
- sentence_num = 1;
- sent_pos = 0;
-
- /* check each "sentence" (corresponding to a different routine or function)
- until a match is found, or until their are no possible sentences left */
- for (sentence_found = 0; (!sentence_found && sentence_num < max_no_of_sentences); ++sentence_num) {
- local_match_pos=0;
- invalid_match=0;
- prev_match=0;
- /* start with the first input token, until all have been matched, or one
- is unmatchable */
- for (token_num = 0; (token_num < command_depth) && !invalid_match; ++token_num) {
- /* start after most recent matching token */
- sent_pos=local_match_pos;
-
- /* compare current token to the sentence components until a matching component
- is found, or until there are none left */
- for (local_match=0; (!local_match) && (sent_pos<max_tokens_in_sentence); ++sent_pos) {
-
- /* compare here */
- if (commands[token_num]==((sentences[sentence_num][sent_pos]) & opt_mask)) {
- /* flag a local token match (not a whole sentence match) */
- local_match=1;
- }
- }
- if (local_match) {
- /* if any of the components in the sentence were skipped between the last two
- matches, make sure that they were optional ones */
- if (!prev_match) {
- local_match_pos=-1;
- }
- /* if there was no local match previously, then the initial value
- of local_match_pos is misleading - there was no match at 0. */
- for (i=(local_match_pos+1); i<(sent_pos-1); ++i) {
- /* if they weren't optional, the match is not valid */
- if (!(sentences[sentence_num][i] & optional)) {
- invalid_match=1;
- }
- }
- /* counteract the last "++i" due to the for loop */
- local_match_pos = sent_pos - 1;
- if (local_match && !invalid_match) {
- prev_match=1;
- }
- }
-
- /* if no match for this one token existed in this sentence, mark this sentence as invalid */
- if (!local_match) {
- invalid_match = 1;
- }
- }
- /* if no invalid token match was found for any of the tokens in this sentence,
- then it's an overall sentence match! */
- if (!invalid_match) {
- sentence_found=1;
- }
- }
- --sentence_num;
-
- if (!sentence_found) {
- sentence_num = 0;
- }
- /* 0 is the no-match value */
-
- return sentence_num;
-}
-
-
-static int Parser_get_unit(char **parameter, char **units)
-{
- /* this function takes a parameter like "1e+6 ms" and breaks it into parameter="1e+6" and
- units="ms" */
-
- if (*parameter == NULL) {
- *parameter = g_strdup ("");
- }
-
- g_assert (*units == NULL);
-
- gchar *end_ptr;
- g_strtod (*parameter, &end_ptr);
-
- if (end_ptr == *parameter) {
- *units = g_strdup ("");
- } else {
- *units = g_strdup (end_ptr);
- end_ptr[0] = 0; // truncates parameter
- }
-
- g_strstrip (*units);
- g_strstrip (*parameter);
-
- int units_present = (*units[0] != 0);
- return units_present;
-}
-
-void Parser_main (char *raw_in, int interactive_terminal, void(*cbfunc)(gpointer, gchar *), gpointer user_data)
-{
- int in_pos; /* this identifies the single character of in being processed */
- int command_depth; /* how many command words have been parsed */
- int old_command_depth; /* save this if in case of a compound message */
- char current_command[max_input_word_length]; /* current command word being processed */
- int current_command_length; /* length of current command so far */
- int commands[max_commands_in_input]; /* list of identified command tokens */
- int old_commands[max_commands_in_input]; /* list of identified command tokens from */
- /* last non-common, non-colon-started command*/
- int space_found; /* if true, a space was found. parameter may follow */
- int parameter_found; /* if true, there is a parameter at the end of the command string */
- int semicolon_found; /* to break up lines */
- int units_found; /* text found after parameter must be units */
- int i; /* counter */
- int routine_num; /* routine to execute, based on command */
- int dont_use_this_header; /* the old head is saved in case of compound message, unless this is set */
- int compound_message; /* this indicates that at least one semicolon has been found, so */
- /* the message is a compound one */
-
-
- int is_query;
- int command_type; /* combination of is_query, parameter_found, and units_found */
-
- int channel;
- int with_id_code;
-
- g_strstrip (raw_in);
-
- // add white space to the end of the input string - FIXME?
- gchar *in = g_strdup_printf ("%s ", raw_in);
-
- in_pos = 0; /* start at the beginning of the input string */
- semicolon_found = 0;
- compound_message = 0;
- command_depth=0;
- old_command_depth=0;
- dont_use_this_header=NO;
-
- while (isspace(in[in_pos]) || in[in_pos]==':' || in[in_pos]==';') {
- /* ignore leading spaces */
- ++in_pos;
- }
-
-
- /* examine each letter in the string until EOS */
- while (in[in_pos] != 0) {
-
- gchar *units = NULL;
- gchar *response = NULL;
- gchar *error_response = NULL;
- gchar *parameter = NULL;
-
- channel=-1;
- with_id_code=0;
- space_found = 0;
- parameter_found = 0; /* no numeric parameters yet */
- units_found = 0;
- is_query = 0;
- current_command_length = 0;
-
- if (semicolon_found && !dont_use_this_header) {
- old_command_depth=command_depth-2;
- for (i=0; i<old_command_depth; ++i) {
- old_commands[i]=commands[i];
- }
- }
-
- command_depth=old_command_depth;
- for (i=0; i<command_depth; ++i) {
- commands[i]=old_commands[i];
- }
-
- semicolon_found=0;
- dont_use_this_header=NO;
-
- /* break it up if semicolons are present */
- while (!semicolon_found && in[in_pos] != 0) {
-
- in[in_pos]=tolower(in[in_pos]);
- /* everything to lowercase */
-
- /* words are separated by white space or colons or semicolons */
- if ( isspace(in[in_pos]) || in[in_pos] == ':' || in[in_pos] == ';')
-
- {
-
- if (in[in_pos] == ';') {
- ++semicolon_found;
- }
- ++compound_message;
-
- /* if it is a separator, ignore it if it is duplicated */
- if ( !isspace(in[in_pos-1]) && (in[in_pos-1] != ':') && (in[in_pos-1] != ';')) {
- /* valid separator, so terminate current command word string */
- current_command[current_command_length] = '\0';
-
- if (space_found) {
- /* Just end things if it is a semicolon */
- if (in[in_pos]!=';') {
- current_command[current_command_length] = in[in_pos];
- ++current_command_length;
- }
-
- current_command[current_command_length] = '\0';
- ++parameter_found;
- parameter = g_strdup (current_command);
- } else if (!space_found) {
- /* just a regular command word */
-
- /* terminate the current command string */
- current_command_length = 0; /* make room for a new command string */
- commands[command_depth]=Parser_id_word(current_command,&channel,&with_id_code);
-
- if ( commands[command_depth]<13
- || commands[command_depth]==63
- || commands[command_depth]==64) {
- dont_use_this_header=YES;
- commands[0]=commands[command_depth];
- command_depth=0;
- }
-
- ++command_depth; /* indicate that a new command word is ready */
-
- /* indicate if the separator was a space - next bit parameter then */
- if (in[in_pos]==' ') {
- ++space_found;
- }
- }
- } /* non-repeated separator */
- else if (compound_message && in[in_pos-1]==';' && in[in_pos]==':') {
- dont_use_this_header=YES;
- command_depth=0;
- }
-
- } /* a separator */
- else if (in[in_pos]!='?') {
- /* if not white space or separator, add character to current command word */
- current_command[current_command_length] = in[in_pos];
- ++current_command_length;
- } /* not a separator */
- else {
- ++is_query;
- /* question mark found */
- }
-
-
- ++in_pos; /* move pointer to next letter */
-
- } /* not a semi-colon */
-
- commands[command_depth]=0;
- ++command_depth;
- /* add end of tokens marker (0) */
-
- int error_num=OK;
-
- units_found = Parser_get_unit(&parameter,&units);
-
- if (!error_num) {
- command_type=(is_query<<2) | (parameter_found?2:0) | units_found;
-
- if (commands[0]!=0) {
- routine_num = Parser_find_commands(commands,command_depth);
-
- /* check for valid channel number, based on position in command */
- if ( (error_num=Parser_channel(&channel,with_id_code,routine_num)) )
- /* not a valid command due to improper channel suffix */
- {
- routine_num=9999;
- }
- } else {
- routine_num=9999;
- /* ignore empty commands lists, generated by a white space string */
- }
-
- switch (routine_num) {
- case 0:
- response = g_strdup_printf("routine_num: %d, channel: %d, parameter: %s, units: %s, command type: %d",routine_num,channel,parameter,units,command_type);
- error_num=Unrecognized;
- break;
- case 11:
- error_num=Go_syst_err_11(&response,channel,parameter,units,command_type);
- break;
- case 32:
- case 33:
- error_num=Go_freq_32_33(&response,channel,parameter,units,command_type);
- break;
- case 66:
- error_num=Go_syst_errcnt66(&response,channel,parameter,units,command_type);
- break;
-
- case 9999:
- // was only whitespace, ignore
- break;
-
- default:
- /* valid but not implemented yet */
- response = g_strdup_printf("routine_num: %d, channel: %d, parameter: %s, units: %s, command type: %d",routine_num,channel,parameter,units,command_type);
- break;
-
- }
- }
-
- if (error_num) {
- queue_error_from_parser(&error_response, error_num);
- if (interactive_terminal) {
- (*cbfunc)(user_data, error_response);
- }
- } else {
- (*cbfunc)(user_data, response);
- }
-
- g_free (units);
- g_free (response);
- g_free (error_response);
- g_free (parameter);
-
- if (!is_query) {
- Main_update_shift_registers(); /* update values in pulse generator circuit */
- }
-
- } /* not EOS */
-
- /* update display if it wasn't a query, and if the control menu isn't on (this gives the user
- a chance to press "Go To Local" to override control */
-
- int Selected_Submenu=0, Submenu1_rem_loc=0, Type_Of_Menu=0, Submenu_On=0;
-
- if (!is_query && !(Selected_Submenu==Submenu1_rem_loc && Type_Of_Menu==Submenu_On)) {
- Menu_Update_Display();
- }
-
- /* re-run error_check to update min/max values based on actual settings, not proposed settings */
- Error_check(globals.ChannelState);
-
- // trigger a prompt
- if (interactive_terminal) {
- (*cbfunc)(user_data, "");
- }
-
- g_free (in);
-}
-
-
-static int Parser_channel (int *channel,int with_id_code,int routine_num)
-{
- /* return if no channel suffixes appeared */
- if (*channel==-1) {
- *channel=0;
- return OK;
- }
-
-
- /* compare to maximum number of channels allowed */
- if (*channel>1 && *channel>globals.Flash.channels && !globals.Flash.enable_avrq_extra_ampls) {
- return InvalidChannel;
- }
- if (*channel>5 && globals.Flash.enable_avrq_extra_ampls) {
- return InvalidChannel;
- }
-
-
- /* SCPI uses 1-N counting, change to 0 - (N-1) */
- if (*channel > 0) {
- --(*channel);
- } else {
- return InvalidChannel;
- }
-
- return OK;
-}
-
-
-static int Go_freq_32_33(gchar** response, int channel, char *parameter,char *units,int command_type)
-{
- // this is a typical parser function - there will be many more added later
-
- float new_freq;
- int status;
-
- if ( (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_frequency))) {
- return status;
- }
-
- new_freq=1.0;
-
- switch (command_type) {
- case command_param_units:
- if ( (status=Handle_Units(&new_freq,units,"hz")) ) {
- return status;
- }
- /* no break */
-
- case command_withparam:
- if ( (status = process_float_param (parameter, &new_freq, 1.0, 1.0e6, NORMAL_ZERO)) ) {
- return status;
- }
- return Set_frequency(0,0,0,channel,new_freq);
- break;
-
- case query_simple:
- return query_float(response, globals.ChannelState[channel].frequency);
- break;
-
- case query_param:
- return query_min_max_float (response, parameter, 1.0, 1.0e6);
- break;
-
- default:
- return SyntaxError;
- break;
- }
-}
-
-
-static int Handle_Units(float *mult,char *units, char *in_base)
-{
- int len_base, len_all, pos;
- char prefix[max_input_word_length];
- char base[max_input_word_length];
-
- strcpy (base, in_base);
-
- *mult=1.0;
- if (!strcmp(units,base)) {
- return OK;
- }
-
- // match base
- len_all = strlen (units);
- if (len_all == 0) {
- return OK;
- }
-
- len_base = strlen (base);
- pos = len_all - len_base;
-
- strcpy (prefix, units);
-
- if (!strcmp(base,"%") && (len_all >= 3) && !strcmp(prefix + len_all - 3,"pct")) {
- strcpy(base, "pct");
- prefix[len_all - 3] = 0;
- } else if (!strcmp(base,"pct") && !strcmp(prefix + len_all - 1,"%")) {
- strcpy(base, "%");
- prefix[len_all - 1] = 0;
- } else if (strcmp(prefix+pos,base)) {
- return UnknownUnits;
- } else {
- prefix[pos]=0;
- }
-
- if (strlen(prefix) == 0) {
- return OK;
- }
-
- // special exceptions
- if (!strcmp(prefix,"m") && !strcmp(base,"ohm")) {
- *mult=1.0e6;
- } else if (!strcmp(prefix,"m") && !strcmp(base,"hz")) {
- *mult=1.0e6;
- }
- // normal rules
- else if (!strcmp(prefix,"ex")) {
- *mult=1.0e18;
- } else if (!strcmp(prefix,"pe")) {
- *mult=1.0e15;
- } else if (!strcmp(prefix,"t")) {
- *mult=1.0e12;
- } else if (!strcmp(prefix,"g")) {
- *mult=1.0e9;
- } else if (!strcmp(prefix,"ma")) {
- *mult=1.0e6;
- } else if (!strcmp(prefix,"k")) {
- *mult=1.0e3;
- } else if (!strcmp(prefix,"m")) {
- *mult=1.0e-3;
- } else if (!strcmp(prefix,"u")) {
- *mult=1.0e-6;
- } else if (!strcmp(prefix,"n")) {
- *mult=1.0e-9;
- } else if (!strcmp(prefix,"p")) {
- *mult=1.0e-12;
- } else if (!strcmp(prefix,"f")) {
- *mult=1.0e-15;
- } else if (!strcmp(prefix,"a")) {
- *mult=1.0e-18;
- } else {
- return UnknownUnits;
- }
-
- return OK;
-}
-
-
-static int Is_Min_Command(gchar *text)
-{
- return (!strcmp(text,"min") || !strcmp(text,"minimum"));
-}
-
-
-static int Is_Max_Command(char *text)
-{
- return (!strcmp(text,"max") || !strcmp(text,"maximum"));
-}
-
-static int query_int (gchar** response, int n)
-{
- *response = g_strdup_printf ("%d", n);
- return OK;
-}
-
-static int query_min_max_float (gchar** response, char *parameter, float min_val, float max_val)
-{
- float report_val;
-
- if (Is_Min_Command(parameter)) {
- report_val=min_val;
- } else if (Is_Max_Command(parameter)) {
- report_val=max_val;
- } else {
- return SyntaxError;
- }
-
- Float_To_Text(remote_digits_after_decimal,report_val,response);
- return OK;
-}
-
-static int query_float (gchar** response, float value)
-{
- Float_To_Text(remote_digits_after_decimal,value,response);
- return OK;
-}
-
-static int process_float_param (char *parameter, float *value, float min_val, float max_val, int zero_mode)
-{
- int status;
- status = OK;
-
- if (String_is_it_numeric(parameter)) {
- *value *= atof(parameter);
-
- if (zero_mode == ALLOW_NEG_ZERO) {
- /* allow a value of "-0" */
- if (fabs(*value) < smallest_allowed_number)
- if (parameter[0] == '-') {
- *value = -0.1*smallest_allowed_number;
- }
- }
- }
-
- else if (!strcmp(parameter,"+") && (zero_mode == ALLOW_NEG_ZERO)) {
- *value = smallest_allowed_number;
- } else if (!strcmp(parameter,"-") && (zero_mode == ALLOW_NEG_ZERO)) {
- *value = -smallest_allowed_number;
- } else if (Is_Min_Command(parameter)) {
- *value = min_val;
- } else if (Is_Max_Command(parameter)) {
- *value = max_val;
- } else {
- status=SyntaxError;
- }
-
- return status;
-}
-
-static int check_channel_ok (int channel, int enabled_channels, char chankey)
-{
- /* how many channels overall */
- if (channel >= enabled_channels) {
- return InvalidChannel;
- }
-
- /* abandon if high channel selected by user but not enabled by firmware for that parameter*/
- if (channel && !chankey) {
- return InvalidChannel;
- }
-
- return OK;
-}
-
-
-static int Go_syst_err_11(gchar** response, int channel, char *parameter,char *units,int command_type)
-{
- switch (command_type) {
- case query_simple:
- if (globals.number_of_errors==0) {
- get_error_text(response, OK);
- } else {
- get_error_text(response,globals.error_queue[1]);
- Error_Remove_From_Queue();
- }
- return OK;
- break;
-
- default:
- return SyntaxError;
- break;
- }
-}
-
-static int Go_syst_errcnt66(gchar** response, int channel, char *parameter,char *units,int command_type)
-{
- switch (command_type) {
- case query_simple:
- return query_int (response, globals.number_of_errors);
- break;
-
- default:
- return SyntaxError;
- break;
- }
-}
-
+/* START LIBRARY DESCRIPTION *********************************************
+PARSER.LIB
+ Copyright (c) 1997, Avtech Electrosystems Ltd.
+
+DESCRIPTION:
+ Parser functions.
+
+SUPPORT LIB'S:
+END DESCRIPTION **********************************************************/
+
+
+#include "parser.h"
+#include <glib/gprintf.h>
+
+//STATICS
+static int query_int (gchar** response, int n);
+static int query_min_max_float (gchar** response, char *parameter, float min_val, float max_val);
+static int query_float (gchar** response, float value);
+static int process_float_param (char *parameter, float *value, float min_val, float max_val, int zero_mode);
+static int check_channel_ok (int channel, int enabled_channels, char chankey);
+static int Parser_id_word(char *id_me, int *channel, int *with_id_code);
+static int Parser_find_commands(int commands[], int command_depth);
+static int Parser_get_unit(char **parameter, char **units);
+static int Parser_channel (int *channel,int with_id_code,int routine_num);
+static int Go_freq_32_33(gchar** response, int channel, char *parameter,char *units,int command_type);
+static int Handle_Units(float *mult,char *units, char *base);
+static int Is_Min_Command(char *text);
+static int Is_Max_Command(char *text);
+static int Go_syst_err_11(gchar** response, int channel, char *parameter,char *units,int command_type);
+static int Go_syst_errcnt66(gchar** response, int channel, char *parameter,char *units,int command_type);
+
+static int Parser_id_word(char *id_me, int *channel, int *with_id_code)
+{
+ int id_code;
+ int set_new_channel;
+
+ set_new_channel=0;
+
+ /* detect channel suffixes in the range of 0-99 */
+ if (isdigit((int) id_me[strlen(id_me)-1])) {
+ set_new_channel=1;
+ *channel=atoi(id_me+strlen(id_me)-1);
+ if (isdigit((int) id_me[strlen(id_me)-2])) {
+ *channel=atoi(id_me+strlen(id_me)-2);
+ id_me[strlen(id_me)-2]=0;
+ } else {
+ id_me[strlen(id_me)-1]=0;
+ }
+ }
+
+
+ if (!strcmp(id_me,"*cls") ) {
+ id_code = 1;
+ } else if (!strcmp(id_me,"*ese") ) {
+ id_code = 2;
+ } else if (!strcmp(id_me,"*esr") ) {
+ id_code = 4;
+ } else if (!strcmp(id_me,"*idn") ) {
+ id_code = 5;
+ } else if (!strcmp(id_me,"*opc") ) {
+ id_code = 6;
+ } else if (!strcmp(id_me,"*rst") ) {
+ id_code = 8;
+ } else if (!strcmp(id_me,"*sre") ) {
+ id_code = 9;
+ } else if (!strcmp(id_me,"*stb") ) {
+ id_code = 10;
+ } else if (!strcmp(id_me,"*tst") ) {
+ id_code = 11;
+ } else if (!strcmp(id_me,"*wai") ) {
+ id_code = 12;
+ } else if (!strcmp(id_me,"system") || !strcmp(id_me,"syst")) {
+ id_code = 13;
+ } else if (!strcmp(id_me,"error") || !strcmp(id_me,"err")) {
+ id_code = 14;
+ } else if (!strcmp(id_me,"version") || !strcmp(id_me,"vers")) {
+ id_code = 15;
+ } else if (!strcmp(id_me,"status") || !strcmp(id_me,"stat") || !strcmp(id_me,"state")) {
+ id_code = 16;
+ } else if (!strcmp(id_me,"operation") || !strcmp(id_me,"oper")) {
+ id_code = 17;
+ } else if (!strcmp(id_me,"event") || !strcmp(id_me,"even")) {
+ id_code = 18;
+ } else if (!strcmp(id_me,"condition") || !strcmp(id_me,"cond")) {
+ id_code = 19;
+ } else if (!strcmp(id_me,"enable") || !strcmp(id_me,"enab")) {
+ id_code = 20;
+ } else if (!strcmp(id_me,"questionable") || !strcmp(id_me,"ques")) {
+ id_code = 21;
+ } else if (!strcmp(id_me,"preset") || !strcmp(id_me,"pres")) {
+ id_code = 22;
+ } else if (!strcmp(id_me,"diagnostic") || !strcmp(id_me,"diag")) {
+ id_code = 23;
+ } else if (!strcmp(id_me,"output") || !strcmp(id_me,"outp")) {
+ id_code = 24;
+ } else if (!strcmp(id_me,"impedance") || !strcmp(id_me,"imp")) {
+ id_code = 25;
+ } else if (!strcmp(id_me,"protection") || !strcmp(id_me,"prot")) {
+ id_code = 26;
+ } else if (!strcmp(id_me,"tripped") || !strcmp(id_me,"trip")) {
+ id_code = 27;
+ } else if (!strcmp(id_me,"source") || !strcmp(id_me,"sour")) {
+ id_code = 28;
+ } else if (!strcmp(id_me,"current") || !strcmp(id_me,"curr")) {
+ id_code = 29;
+ } else if (!strcmp(id_me,"level") || !strcmp(id_me,"lev")) {
+ id_code = 30;
+ } else if (!strcmp(id_me,"immediate") || !strcmp(id_me,"imm")) {
+ id_code = 31;
+ } else if (!strcmp(id_me,"amplitude") || !strcmp(id_me,"ampl")) {
+ id_code = 32;
+ } else if (!strcmp(id_me,"offset") || !strcmp(id_me,"offs")) {
+ id_code = 33;
+ } else if (!strcmp(id_me,"high") ) {
+ id_code = 34;
+ } else if (!strcmp(id_me,"low") ) {
+ id_code = 35;
+ } else if (!strcmp(id_me,"voltage") || !strcmp(id_me,"volt")) {
+ id_code = 36;
+ } else if (!strcmp(id_me,"frequency") || !strcmp(id_me,"freq")) {
+ id_code = 37;
+ } else if (!strcmp(id_me,"function") || !strcmp(id_me,"func")) {
+ id_code = 38;
+ } else if (!strcmp(id_me,"shape") || !strcmp(id_me,"shap")) {
+ id_code = 39;
+ } else if (!strcmp(id_me,"pulse") || !strcmp(id_me,"puls")) {
+ id_code = 40;
+ } else if (!strcmp(id_me,"period") || !strcmp(id_me,"per")) {
+ id_code = 41;
+ } else if (!strcmp(id_me,"width") || !strcmp(id_me,"widt")) {
+ id_code = 42;
+ } else if (!strcmp(id_me,"dcycle") || !strcmp(id_me,"dcyc")) {
+ id_code = 43;
+ } else if (!strcmp(id_me,"hold") ) {
+ id_code = 44;
+ } else if (!strcmp(id_me,"delay") || !strcmp(id_me,"del")) {
+ id_code = 45;
+ } else if (!strcmp(id_me,"double") || !strcmp(id_me,"doub")) {
+ id_code = 46;
+ } else if (!strcmp(id_me,"polarity") || !strcmp(id_me,"pol")) {
+ id_code = 47;
+ } else if (!strcmp(id_me,"beeper") || !strcmp(id_me,"beep")) {
+ id_code = 48;
+ } else if (!strcmp(id_me,"cw") ) {
+ id_code = 49;
+ } else if (!strcmp(id_me,"fixed") || !strcmp(id_me,"fix")) {
+ id_code = 50;
+ } else if (!strcmp(id_me,"abort") || !strcmp(id_me,"abor")) {
+ id_code = 51;
+ } else if (!strcmp(id_me,"initiate") || !strcmp(id_me,"init")) {
+ id_code = 52;
+ } else if (!strcmp(id_me,"continuous")) {
+ id_code = 53;
+ } else if (!strcmp(id_me,"trigger") || !strcmp(id_me,"trig")) {
+ id_code = 54;
+ } else if (!strcmp(id_me,"integer") || !strcmp(id_me,"int")) {
+ id_code = 55;
+ } else if (!strcmp(id_me,"float") ) {
+ id_code = 56;
+ } else if (!strcmp(id_me,"eprom") ) {
+ id_code = 57;
+ } else if (!strcmp(id_me,"string") ) {
+ id_code = 58;
+ } else if (!strcmp(id_me,"bit") ) {
+ id_code = 59;
+ } else if (!strcmp(id_me,"set") ) {
+ id_code = 60;
+ } else if (!strcmp(id_me,"clear") ) {
+ id_code = 61;
+ } else if (!strcmp(id_me,"shiftreg") ) {
+ id_code = 62;
+ } else if (!strcmp(id_me,"*rcl") ) {
+ id_code = 63;
+ } else if (!strcmp(id_me,"*sav") ) {
+ id_code = 64;
+ } else if (!strcmp(id_me,"gate") ) {
+ id_code = 65;
+ } else if (!strcmp(id_me,"local") || !strcmp(id_me,"logout") || !strcmp(id_me,"exit") || !strcmp(id_me,"quit") ) {
+ id_code = 66;
+ } else if (!strcmp(id_me,"test") ) {
+ id_code = 67;
+ } else if (!strcmp(id_me,"communicate") || !strcmp(id_me,"comm")) {
+ id_code = 68;
+ } else if (!strcmp(id_me,"address") || !strcmp(id_me,"addr")) {
+ id_code = 69;
+ } else if (!strcmp(id_me,"gpib") ) {
+ id_code = 70;
+ } else if (!strcmp(id_me,"serial") || !strcmp(id_me,"ser")) {
+ id_code = 71;
+ } else if (!strcmp(id_me,"receive") || !strcmp(id_me,"rec")) {
+ id_code = 72;
+ } else if (!strcmp(id_me,"baud") ) {
+ id_code = 73;
+ } else if (!strcmp(id_me,"parity") || !strcmp(id_me,"par")) {
+ id_code = 74;
+ } else if (!strcmp(id_me,"type") ) {
+ id_code = 75;
+ } else if (!strcmp(id_me,"bits") ) {
+ id_code = 76;
+ } else if (!strcmp(id_me,"sbits") || !strcmp(id_me,"sbit")) {
+ id_code = 77;
+ } else if (!strcmp(id_me,"echo") ) {
+ id_code = 78;
+ } else if (!strcmp(id_me,"rts") ) {
+ id_code = 79;
+ } else if (!strcmp(id_me,"control") || !strcmp(id_me,"cont")) {
+ id_code = 80;
+ } else if (!strcmp(id_me,"next") ) {
+ id_code = 81;
+ } else if (!strcmp(id_me,"count") || !strcmp(id_me,"coun")) {
+ id_code = 82;
+ } else if (!strcmp(id_me,"display") || !strcmp(id_me,"disp")) {
+ id_code = 83;
+ } else if (!strcmp(id_me,"brightness") || !strcmp(id_me,"brig")) {
+ id_code = 84;
+ } else if (!strcmp(id_me,"load") ) {
+ id_code = 85;
+ } else if (!strcmp(id_me,"measure") || !strcmp(id_me,"meas")) {
+ id_code = 86;
+ } else if (!strcmp(id_me,"char") ) {
+ id_code = 87;
+ } else if (!strcmp(id_me,"calibration") || !strcmp(id_me,"cal")) {
+ id_code = 88;
+ } else if (!strcmp(id_me,"monitor") || !strcmp(id_me,"mon")) {
+ id_code = 89;
+ } else if (!strcmp(id_me,"step") ) {
+ id_code = 90;
+ } else if (!strcmp(id_me,"route") || !strcmp(id_me,"rout")) {
+ id_code = 91;
+ } else if (!strcmp(id_me,"close") || !strcmp(id_me,"clos")) {
+ id_code = 92;
+ } else if (!strcmp(id_me,"point") ) {
+ id_code = 93;
+ } else if (!strcmp(id_me,"shift") ) {
+ id_code = 94;
+ } else if (!strcmp(id_me,"scale") ) {
+ id_code = 95;
+ } else if (!strcmp(id_me,"null") ) {
+ id_code = 96;
+ } else if (!strcmp(id_me,"size") ) {
+ id_code = 97;
+ } else if (!strcmp(id_me,"separation") || !strcmp(id_me,"sep")) {
+ id_code = 98;
+ } else if (!strcmp(id_me,"network") || !strcmp(id_me,"net")) {
+ id_code = 99;
+ } else if (!strcmp(id_me,"password") || !strcmp(id_me,"pass")) {
+ id_code = 100;
+ } else if (!strcmp(id_me,"new") ) {
+ id_code = 101;
+ } else if (!strcmp(id_me,"suspend") ) {
+ id_code = 102;
+ } else if (!strcmp(id_me,"transition") || !strcmp(id_me,"tran")) {
+ id_code = 103;
+ } else if (!strcmp(id_me,"leading") || !strcmp(id_me,"lead")) {
+ id_code = 104;
+ } else if (!strcmp(id_me,"limit") || !strcmp(id_me,"lim")) {
+ id_code = 105;
+ } else if (!strcmp(id_me,"slew") ) {
+ id_code = 106;
+ } else if (!strcmp(id_me,"all") ) {
+ id_code = 107;
+ }
+
+ else {
+ id_code = 9999;
+ }
+
+ if (set_new_channel) {
+ *with_id_code=id_code;
+ }
+
+ return id_code;
+
+}
+
+static int Parser_find_commands(int commands[], int command_depth)
+{
+#define optional 16384 /* set bit high if optional */
+#define opt_mask 16383 /* default bit mask */
+#define max_tokens_in_sentence 7
+#define max_no_of_sentences 110
+
+ /* Valid command -sequences-. The -individual- commands are defined in id_word. */
+
+ static const int sentences[max_no_of_sentences][max_tokens_in_sentence] = {
+ {0}, /* null - error */
+ {1}, /* cls - sentence 1 */
+ {2}, /* ese - sentence 2 */
+ {4}, /* esr - sentence 3 */
+ {5}, /* idn - sentence 4 */
+ {6}, /* opc - sentence 5 */
+ {8}, /* rst - sentence 6 */
+ {9}, /* sre - sentence 7 */
+ {10}, /* stb - sentence 8 */
+ {11}, /* tst - sentence 9 */
+ {12}, /* wai - sentence 10 */
+ {13,14,81|optional}, /* syst:err:next - 11 */
+ {13,15}, /* syst:vers - 12 */
+ {16,17,18|optional}, /* stat:oper:event - 13 */
+ {16,17,19}, /* stat:oper:cond - 14 */
+ {16,17,20}, /* stat:oper:enable - 15 */
+ {16,21,18|optional}, /* stat:ques:event - 16 */
+ {16,21,19}, /* stat:ques:cond - 17 */
+ {16,21,20}, /* stat:ques:enable - 18 */
+ {16,22}, /* stat:preset - 19 */
+ {24,25}, /* output:impedance - 20 */
+ {24,26,27}, /* output:prot:tripped - 21 */
+ {28|optional,29,30|optional,31|optional,32|optional}, /* sour:curr:lev:imm:ampl - 22 */
+ {28|optional,29,30|optional,31|optional,33}, /* sour:curr:lev:imm:offset - 23 - not used */
+ {28|optional,29,30|optional,31|optional,34}, /* sour:curr:lev:imm:high - 24 - not used */
+ {28|optional,29,30|optional,31|optional,35}, /* sour:curr:lev:imm:low - 25 */
+ {28|optional,36,30|optional,31|optional,32|optional}, /* sour:volt:lev:imm:ampl - 26 */
+ {28|optional,36,30|optional,31|optional,33}, /* sour:volt:lev:imm:offset - 27 - not used */
+ {28|optional,36,30|optional,31|optional,34}, /* sour:volt:lev:imm:high - 28 - not used */
+ {28|optional,36,30|optional,31|optional,35}, /* sour:volt:lev:imm:low - 29 */
+ {28|optional,29,26,27}, /* sour:curr:prot:tripped? - 30 */
+ {28|optional,36,26,27}, /* sour:volt:prot:tripped? - 31 */
+ {28|optional,37,49|optional}, /* sour:freq:cw - 32 */
+ {28|optional,37,50|optional}, /* sour:freq:fixed - 33 */
+ {28|optional,38,39|optional}, /* sour:func:shape - 34 */
+ {28|optional,40,41}, /* sour:puls:per - 35 */
+ {28|optional,40,42}, /* sour:puls:width - 36 */
+ {28|optional,40,43}, /* sour:puls:dcyc - 37 */
+ {28|optional,40,44}, /* sour:puls:hold - 38 */
+ {28|optional,40,45}, /* sour:puls:delay - 39 */
+ {28|optional,40,46,16|optional}, /* sour:puls:doub:state - 40 */
+ {28|optional,40,46,45}, /* sour:puls:doub:delay - 41 */
+ {28|optional,40,47}, /* sour:puls:pol - 42 */
+ {13,48,31|optional}, /* syst:beep:imm - 43 - not used */
+ {52,31|optional,53}, /* init:imm:cont - 44 - not used */
+ {51}, /* abort - 45 - not used */
+ {54,31|optional,28}, /* trig:imm:sour - 46 */
+ {23,57,58}, /* diag:eprom:string - 47 */
+ {23,57,55}, /* diag:eprom:int - 48 */
+ {23,57,59,60}, /* diag:eprom:bit:set - 49 - not used */
+ {23,57,59,61}, /* diag:eprom:bit:clear - 50 - not used */
+ {23,57,56}, /* diag:eprom:float - 51 */
+ {23,62}, /* diag:shiftreg - 52 */
+ {63}, /* *rcl - 53 */
+ {64}, /* *sav - 54 */
+ {24,16|optional}, /* output:state - 55 */
+ {28|optional,40,65,75}, /* sour:puls:gate:type - 56 */
+ {66}, /* local (RS232 mode only) - 57 */
+ {23,67,45}, /* diag:test:delay - 58 */
+ {13,68,70,69}, /* syst:comm:gpib:addr - 59 */
+ {13,68,71,72|optional,73}, /* syst:comm:ser:rec:baud - 60 */
+ {13,68,71,72|optional,74,75|optional}, /* syst:comm:ser:rec:parity - 61 */
+ {13,68,71,72|optional,76}, /* syst:comm:ser:rec:bits - 62 */
+ {13,68,71,72|optional,77}, /* syst:comm:ser:rec:sbits - 63 */
+ {13,68,71,80,79}, /* syst:comm:ser:control:rts - 64 */
+ {13,68,71,72|optional,78}, /* syst:comm:ser:rec:echo - 65 */
+ {13,14,82}, /* syst:err:count - 66 */
+ {28|optional,40,65,30}, /* sour:puls:gate:level - 67 */
+ {24,85}, /* output:load - 68 */
+ {86,32}, /* meas:ampl? - 69 */
+ {23,57,87}, /* diag:eprom:char - 70 */
+ {23,88}, /* diag:calib - 71 */
+ {23,32,88,95|optional}, /* diag:ampl:calib:scale - 72 */
+ {23,89,88,95|optional}, /* diag:mon:calib:scale - 73 */
+ {23,89,90}, /* diag:mon:step - 74 */
+ {24,75}, /* output:type - 75 */
+ {23,33,88,95|optional}, /* diag:offset:calib:scale - 76 */
+ {23,40,42,88,94}, /* diag:pulse:width:calib:shift - 77 */
+ {91,92}, /* route:close - 78 */
+ {23,40,42,88,93}, /* diag:pulse:width:calib:point - 79 */
+ {23,40,45,88,93}, /* diag:pulse:delay:calib:point - 80 */
+ {23,40,41,88,93}, /* diag:pulse:period:calib:point - 81 */
+ {23,40,45,88,94}, /* diag:pulse:delay:calib:shift - 82 */
+ {23,32,88,93}, /* diag:ampl:calib:point - 83 */
+ {23,33,88,93}, /* diag:offset:calib:point - 84 */
+ {23,33,96,93}, /* diag:offset:null:point - 85 */
+ {23,57,97}, /* diag:eprom:size - 86 */
+ {83,84}, /* display:brightness - 87 */
+ {28|optional,40,82}, /* sour:puls:count - 88 */
+ {28|optional,40,98}, /* sour:puls:separation - 89 */
+ {23,40,98,88,93}, /* diag:pulse:separation:calib:point - 90 */
+ {13,68,99}, /* system:comm:network - 91 */
+ {13,100,101}, /* system:password:new - 92 */
+ {23,57,102}, /* diag:eprom:suspend - 93 */
+ {28|optional,40,103,104|optional}, /* sour:puls:transition:leading - 94 */
+ {23,40,103,88,93}, /* diag:pulse:transition:calib:point - 95 */
+ {28|optional,29,105,32|optional}, /* sour:curr:limit:ampl - 96 */
+ {23,24,85,88,93}, /* diag:output:load:calib:point - 97 */
+ {28|optional,29,106}, /* sour:curr:slew - 98 */
+ {23,106,88,93}, /* diag:slew:calib:point - 99 */
+ {88,107|optional}, /* calibration:all - 100 */
+ {88,37} /* calibration:frequency - 101 */
+
+ };
+
+
+ int token_num; /* which token in the command[] list is being considered */
+ int sentence_num; /* which sentence is being considered as a match */
+ int sentence_found; /* matching sentence found yet? */
+ int sent_pos; /* position in current sentence */
+ int invalid_match; /* flag if definitely the wrong match */
+ int local_match_pos; /* position (or pos+1, depends) of most-recently-matched token in sentence */
+ int local_match; /* match for current token found yet? */
+ int prev_match; /* were there previous local matches? */
+ int i; /* a counter */
+
+ sentence_num = 1;
+ sent_pos = 0;
+
+ /* check each "sentence" (corresponding to a different routine or function)
+ until a match is found, or until their are no possible sentences left */
+ for (sentence_found = 0; (!sentence_found && sentence_num < max_no_of_sentences); ++sentence_num) {
+ local_match_pos=0;
+ invalid_match=0;
+ prev_match=0;
+ /* start with the first input token, until all have been matched, or one
+ is unmatchable */
+ for (token_num = 0; (token_num < command_depth) && !invalid_match; ++token_num) {
+ /* start after most recent matching token */
+ sent_pos=local_match_pos;
+
+ /* compare current token to the sentence components until a matching component
+ is found, or until there are none left */
+ for (local_match=0; (!local_match) && (sent_pos<max_tokens_in_sentence); ++sent_pos) {
+
+ /* compare here */
+ if (commands[token_num]==((sentences[sentence_num][sent_pos]) & opt_mask)) {
+ /* flag a local token match (not a whole sentence match) */
+ local_match=1;
+ }
+ }
+ if (local_match) {
+ /* if any of the components in the sentence were skipped between the last two
+ matches, make sure that they were optional ones */
+ if (!prev_match) {
+ local_match_pos=-1;
+ }
+ /* if there was no local match previously, then the initial value
+ of local_match_pos is misleading - there was no match at 0. */
+ for (i=(local_match_pos+1); i<(sent_pos-1); ++i) {
+ /* if they weren't optional, the match is not valid */
+ if (!(sentences[sentence_num][i] & optional)) {
+ invalid_match=1;
+ }
+ }
+ /* counteract the last "++i" due to the for loop */
+ local_match_pos = sent_pos - 1;
+ if (local_match && !invalid_match) {
+ prev_match=1;
+ }
+ }
+
+ /* if no match for this one token existed in this sentence, mark this sentence as invalid */
+ if (!local_match) {
+ invalid_match = 1;
+ }
+ }
+ /* if no invalid token match was found for any of the tokens in this sentence,
+ then it's an overall sentence match! */
+ if (!invalid_match) {
+ sentence_found=1;
+ }
+ }
+ --sentence_num;
+
+ if (!sentence_found) {
+ sentence_num = 0;
+ }
+ /* 0 is the no-match value */
+
+ return sentence_num;
+}
+
+
+static int Parser_get_unit(char **parameter, char **units)
+{
+ /* this function takes a parameter like "1e+6 ms" and breaks it into parameter="1e+6" and
+ units="ms" */
+
+ if (*parameter == NULL) {
+ *parameter = g_strdup ("");
+ }
+
+ g_assert (*units == NULL);
+
+ gchar *end_ptr;
+ g_strtod (*parameter, &end_ptr);
+
+ if (end_ptr == *parameter) {
+ *units = g_strdup ("");
+ } else {
+ *units = g_strdup (end_ptr);
+ end_ptr[0] = 0; // truncates parameter
+ }
+
+ g_strstrip (*units);
+ g_strstrip (*parameter);
+
+ int units_present = (*units[0] != 0);
+ return units_present;
+}
+
+void Parser_main (char *raw_in, int interactive_terminal, void(*cbfunc)(gpointer, gchar *), gpointer user_data)
+{
+ int in_pos; /* this identifies the single character of in being processed */
+ int command_depth; /* how many command words have been parsed */
+ int old_command_depth; /* save this if in case of a compound message */
+ char current_command[max_input_word_length]; /* current command word being processed */
+ int current_command_length; /* length of current command so far */
+ int commands[max_commands_in_input]; /* list of identified command tokens */
+ int old_commands[max_commands_in_input]; /* list of identified command tokens from */
+ /* last non-common, non-colon-started command*/
+ int space_found; /* if true, a space was found. parameter may follow */
+ int parameter_found; /* if true, there is a parameter at the end of the command string */
+ int semicolon_found; /* to break up lines */
+ int units_found; /* text found after parameter must be units */
+ int i; /* counter */
+ int routine_num; /* routine to execute, based on command */
+ int dont_use_this_header; /* the old head is saved in case of compound message, unless this is set */
+ int compound_message; /* this indicates that at least one semicolon has been found, so */
+ /* the message is a compound one */
+
+
+ int is_query;
+ int command_type; /* combination of is_query, parameter_found, and units_found */
+
+ int channel;
+ int with_id_code;
+
+ g_strstrip (raw_in);
+
+ // add white space to the end of the input string - FIXME?
+ gchar *in = g_strdup_printf ("%s ", raw_in);
+
+ in_pos = 0; /* start at the beginning of the input string */
+ semicolon_found = 0;
+ compound_message = 0;
+ command_depth=0;
+ old_command_depth=0;
+ dont_use_this_header=NO;
+
+ while (isspace(in[in_pos]) || in[in_pos]==':' || in[in_pos]==';') {
+ /* ignore leading spaces */
+ ++in_pos;
+ }
+
+
+ /* examine each letter in the string until EOS */
+ while (in[in_pos] != 0) {
+
+ gchar *units = NULL;
+ gchar *response = NULL;
+ gchar *error_response = NULL;
+ gchar *parameter = NULL;
+
+ channel=-1;
+ with_id_code=0;
+ space_found = 0;
+ parameter_found = 0; /* no numeric parameters yet */
+ units_found = 0;
+ is_query = 0;
+ current_command_length = 0;
+
+ if (semicolon_found && !dont_use_this_header) {
+ old_command_depth=command_depth-2;
+ for (i=0; i<old_command_depth; ++i) {
+ old_commands[i]=commands[i];
+ }
+ }
+
+ command_depth=old_command_depth;
+ for (i=0; i<command_depth; ++i) {
+ commands[i]=old_commands[i];
+ }
+
+ semicolon_found=0;
+ dont_use_this_header=NO;
+
+ /* break it up if semicolons are present */
+ while (!semicolon_found && in[in_pos] != 0) {
+
+ in[in_pos]=tolower(in[in_pos]);
+ /* everything to lowercase */
+
+ /* words are separated by white space or colons or semicolons */
+ if ( isspace(in[in_pos]) || in[in_pos] == ':' || in[in_pos] == ';')
+
+ {
+
+ if (in[in_pos] == ';') {
+ ++semicolon_found;
+ }
+ ++compound_message;
+
+ /* if it is a separator, ignore it if it is duplicated */
+ if ( !isspace(in[in_pos-1]) && (in[in_pos-1] != ':') && (in[in_pos-1] != ';')) {
+ /* valid separator, so terminate current command word string */
+ current_command[current_command_length] = '\0';
+
+ if (space_found) {
+ /* Just end things if it is a semicolon */
+ if (in[in_pos]!=';') {
+ current_command[current_command_length] = in[in_pos];
+ ++current_command_length;
+ }
+
+ current_command[current_command_length] = '\0';
+ ++parameter_found;
+ parameter = g_strdup (current_command);
+ } else if (!space_found) {
+ /* just a regular command word */
+
+ /* terminate the current command string */
+ current_command_length = 0; /* make room for a new command string */
+ commands[command_depth]=Parser_id_word(current_command,&channel,&with_id_code);
+
+ if ( commands[command_depth]<13
+ || commands[command_depth]==63
+ || commands[command_depth]==64) {
+ dont_use_this_header=YES;
+ commands[0]=commands[command_depth];
+ command_depth=0;
+ }
+
+ ++command_depth; /* indicate that a new command word is ready */
+
+ /* indicate if the separator was a space - next bit parameter then */
+ if (in[in_pos]==' ') {
+ ++space_found;
+ }
+ }
+ } /* non-repeated separator */
+ else if (compound_message && in[in_pos-1]==';' && in[in_pos]==':') {
+ dont_use_this_header=YES;
+ command_depth=0;
+ }
+
+ } /* a separator */
+ else if (in[in_pos]!='?') {
+ /* if not white space or separator, add character to current command word */
+ current_command[current_command_length] = in[in_pos];
+ ++current_command_length;
+ } /* not a separator */
+ else {
+ ++is_query;
+ /* question mark found */
+ }
+
+
+ ++in_pos; /* move pointer to next letter */
+
+ } /* not a semi-colon */
+
+ commands[command_depth]=0;
+ ++command_depth;
+ /* add end of tokens marker (0) */
+
+ int error_num=OK;
+
+ units_found = Parser_get_unit(&parameter,&units);
+
+ if (!error_num) {
+ command_type=(is_query<<2) | (parameter_found?2:0) | units_found;
+
+ if (commands[0]!=0) {
+ routine_num = Parser_find_commands(commands,command_depth);
+
+ /* check for valid channel number, based on position in command */
+ if ( (error_num=Parser_channel(&channel,with_id_code,routine_num)) )
+ /* not a valid command due to improper channel suffix */
+ {
+ routine_num=9999;
+ }
+ } else {
+ routine_num=9999;
+ /* ignore empty commands lists, generated by a white space string */
+ }
+
+ switch (routine_num) {
+ case 0:
+ response = g_strdup_printf("routine_num: %d, channel: %d, parameter: %s, units: %s, command type: %d",routine_num,channel,parameter,units,command_type);
+ error_num=Unrecognized;
+ break;
+ case 11:
+ error_num=Go_syst_err_11(&response,channel,parameter,units,command_type);
+ break;
+ case 32:
+ case 33:
+ error_num=Go_freq_32_33(&response,channel,parameter,units,command_type);
+ break;
+ case 66:
+ error_num=Go_syst_errcnt66(&response,channel,parameter,units,command_type);
+ break;
+
+ case 9999:
+ // was only whitespace, ignore
+ break;
+
+ default:
+ /* valid but not implemented yet */
+ response = g_strdup_printf("routine_num: %d, channel: %d, parameter: %s, units: %s, command type: %d",routine_num,channel,parameter,units,command_type);
+ break;
+
+ }
+ }
+
+ if (error_num) {
+ queue_error_from_parser(&error_response, error_num);
+ if (interactive_terminal) {
+ (*cbfunc)(user_data, error_response);
+ }
+ } else {
+ (*cbfunc)(user_data, response);
+ }
+
+ g_free (units);
+ g_free (response);
+ g_free (error_response);
+ g_free (parameter);
+
+ if (!is_query) {
+ Main_update_shift_registers(); /* update values in pulse generator circuit */
+ }
+
+ } /* not EOS */
+
+ /* update display if it wasn't a query, and if the control menu isn't on (this gives the user
+ a chance to press "Go To Local" to override control */
+
+ int Selected_Submenu=0, Submenu1_rem_loc=0, Type_Of_Menu=0, Submenu_On=0;
+
+ if (!is_query && !(Selected_Submenu==Submenu1_rem_loc && Type_Of_Menu==Submenu_On)) {
+ Menu_Update_Display();
+ }
+
+ /* re-run error_check to update min/max values based on actual settings, not proposed settings */
+ Error_check(globals.ChannelState);
+
+ // trigger a prompt
+ if (interactive_terminal) {
+ (*cbfunc)(user_data, "");
+ }
+
+ g_free (in);
+}
+
+
+static int Parser_channel (int *channel,int with_id_code,int routine_num)
+{
+ /* return if no channel suffixes appeared */
+ if (*channel==-1) {
+ *channel=0;
+ return OK;
+ }
+
+
+ /* compare to maximum number of channels allowed */
+ if (*channel>1 && *channel>globals.Flash.channels && !globals.Flash.enable_avrq_extra_ampls) {
+ return InvalidChannel;
+ }
+ if (*channel>5 && globals.Flash.enable_avrq_extra_ampls) {
+ return InvalidChannel;
+ }
+
+
+ /* SCPI uses 1-N counting, change to 0 - (N-1) */
+ if (*channel > 0) {
+ --(*channel);
+ } else {
+ return InvalidChannel;
+ }
+
+ return OK;
+}
+
+
+static int Go_freq_32_33(gchar** response, int channel, char *parameter,char *units,int command_type)
+{
+ // this is a typical parser function - there will be many more added later
+
+ float new_freq;
+ int status;
+
+ if ( (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_frequency))) {
+ return status;
+ }
+
+ new_freq=1.0;
+
+ switch (command_type) {
+ case command_param_units:
+ if ( (status=Handle_Units(&new_freq,units,"hz")) ) {
+ return status;
+ }
+ /* no break */
+
+ case command_withparam:
+ if ( (status = process_float_param (parameter, &new_freq, 1.0, 1.0e6, NORMAL_ZERO)) ) {
+ return status;
+ }
+ return Set_frequency(0,0,0,channel,new_freq);
+ break;
+
+ case query_simple:
+ return query_float(response, globals.ChannelState[channel].frequency);
+ break;
+
+ case query_param:
+ return query_min_max_float (response, parameter, 1.0, 1.0e6);
+ break;
+
+ default:
+ return SyntaxError;
+ break;
+ }
+}
+
+
+static int Handle_Units(float *mult,char *units, char *in_base)
+{
+ int len_base, len_all, pos;
+ char prefix[max_input_word_length];
+ char base[max_input_word_length];
+
+ strcpy (base, in_base);
+
+ *mult=1.0;
+ if (!strcmp(units,base)) {
+ return OK;
+ }
+
+ // match base
+ len_all = strlen (units);
+ if (len_all == 0) {
+ return OK;
+ }
+
+ len_base = strlen (base);
+ pos = len_all - len_base;
+
+ strcpy (prefix, units);
+
+ if (!strcmp(base,"%") && (len_all >= 3) && !strcmp(prefix + len_all - 3,"pct")) {
+ strcpy(base, "pct");
+ prefix[len_all - 3] = 0;
+ } else if (!strcmp(base,"pct") && !strcmp(prefix + len_all - 1,"%")) {
+ strcpy(base, "%");
+ prefix[len_all - 1] = 0;
+ } else if (strcmp(prefix+pos,base)) {
+ return UnknownUnits;
+ } else {
+ prefix[pos]=0;
+ }
+
+ if (strlen(prefix) == 0) {
+ return OK;
+ }
+
+ // special exceptions
+ if (!strcmp(prefix,"m") && !strcmp(base,"ohm")) {
+ *mult=1.0e6;
+ } else if (!strcmp(prefix,"m") && !strcmp(base,"hz")) {
+ *mult=1.0e6;
+ }
+ // normal rules
+ else if (!strcmp(prefix,"ex")) {
+ *mult=1.0e18;
+ } else if (!strcmp(prefix,"pe")) {
+ *mult=1.0e15;
+ } else if (!strcmp(prefix,"t")) {
+ *mult=1.0e12;
+ } else if (!strcmp(prefix,"g")) {
+ *mult=1.0e9;
+ } else if (!strcmp(prefix,"ma")) {
+ *mult=1.0e6;
+ } else if (!strcmp(prefix,"k")) {
+ *mult=1.0e3;
+ } else if (!strcmp(prefix,"m")) {
+ *mult=1.0e-3;
+ } else if (!strcmp(prefix,"u")) {
+ *mult=1.0e-6;
+ } else if (!strcmp(prefix,"n")) {
+ *mult=1.0e-9;
+ } else if (!strcmp(prefix,"p")) {
+ *mult=1.0e-12;
+ } else if (!strcmp(prefix,"f")) {
+ *mult=1.0e-15;
+ } else if (!strcmp(prefix,"a")) {
+ *mult=1.0e-18;
+ } else {
+ return UnknownUnits;
+ }
+
+ return OK;
+}
+
+
+static int Is_Min_Command(gchar *text)
+{
+ return (!strcmp(text,"min") || !strcmp(text,"minimum"));
+}
+
+
+static int Is_Max_Command(char *text)
+{
+ return (!strcmp(text,"max") || !strcmp(text,"maximum"));
+}
+
+static int query_int (gchar** response, int n)
+{
+ *response = g_strdup_printf ("%d", n);
+ return OK;
+}
+
+static int query_min_max_float (gchar** response, char *parameter, float min_val, float max_val)
+{
+ float report_val;
+
+ if (Is_Min_Command(parameter)) {
+ report_val=min_val;
+ } else if (Is_Max_Command(parameter)) {
+ report_val=max_val;
+ } else {
+ return SyntaxError;
+ }
+
+ Float_To_Text(remote_digits_after_decimal,report_val,response);
+ return OK;
+}
+
+static int query_float (gchar** response, float value)
+{
+ Float_To_Text(remote_digits_after_decimal,value,response);
+ return OK;
+}
+
+static int process_float_param (char *parameter, float *value, float min_val, float max_val, int zero_mode)
+{
+ int status;
+ status = OK;
+
+ if (String_is_it_numeric(parameter)) {
+ *value *= atof(parameter);
+
+ if (zero_mode == ALLOW_NEG_ZERO) {
+ /* allow a value of "-0" */
+ if (fabs(*value) < smallest_allowed_number)
+ if (parameter[0] == '-') {
+ *value = -0.1*smallest_allowed_number;
+ }
+ }
+ }
+
+ else if (!strcmp(parameter,"+") && (zero_mode == ALLOW_NEG_ZERO)) {
+ *value = smallest_allowed_number;
+ } else if (!strcmp(parameter,"-") && (zero_mode == ALLOW_NEG_ZERO)) {
+ *value = -smallest_allowed_number;
+ } else if (Is_Min_Command(parameter)) {
+ *value = min_val;
+ } else if (Is_Max_Command(parameter)) {
+ *value = max_val;
+ } else {
+ status=SyntaxError;
+ }
+
+ return status;
+}
+
+static int check_channel_ok (int channel, int enabled_channels, char chankey)
+{
+ /* how many channels overall */
+ if (channel >= enabled_channels) {
+ return InvalidChannel;
+ }
+
+ /* abandon if high channel selected by user but not enabled by firmware for that parameter*/
+ if (channel && !chankey) {
+ return InvalidChannel;
+ }
+
+ return OK;
+}
+
+
+static int Go_syst_err_11(gchar** response, int channel, char *parameter,char *units,int command_type)
+{
+ switch (command_type) {
+ case query_simple:
+ if (globals.number_of_errors==0) {
+ get_error_text(response, OK);
+ } else {
+ get_error_text(response,globals.error_queue[1]);
+ Error_Remove_From_Queue();
+ }
+ return OK;
+ break;
+
+ default:
+ return SyntaxError;
+ break;
+ }
+}
+
+static int Go_syst_errcnt66(gchar** response, int channel, char *parameter,char *units,int command_type)
+{
+ switch (command_type) {
+ case query_simple:
+ return query_int (response, globals.number_of_errors);
+ break;
+
+ default:
+ return SyntaxError;
+ break;
+ }
+}
+
diff --git a/string_utils.c b/string_utils.c
index e28ccfc..db077a7 100644
--- a/string_utils.c
+++ b/string_utils.c
@@ -1,48 +1,48 @@
-/* START LIBRARY DESCRIPTION *********************************************
-FLOAT.LIB
- Copyright (c) 2006, Avtech Electrosystems Ltd.
-
-DESCRIPTION:
- Functions that deal with strings and floating point numbers.
-
-SUPPORT LIB'S:
-END DESCRIPTION **********************************************************/
-
-
-#include <string.h>
-#include <ctype.h>
-#include <math.h>
-#include <glib/gprintf.h>
-#include "globals.h"
-#include "string_utils.h"
-
-void Float_To_Text(int decimal_digits,float number_in, gchar ** text_out)
-{
- g_assert (*text_out == NULL);
-
- if (fabs(number_in)<1.1*smallest_allowed_number) {
- if (number_in<0.0) {
- *text_out = g_strdup_printf("-0.%0*d",decimal_digits,0);
- } else {
- *text_out = g_strdup_printf("0.%0*d",decimal_digits,0);
- }
- return;
- }
-
- *text_out = g_strdup_printf("%.*e", decimal_digits, number_in);
-}
-
-
-/*----------------------------------------------------------------------------------------------------------*/
-gboolean String_is_it_numeric(char *parameter)
-{
-
- GRegex *numeric_regex = g_regex_new ( "\\s*[+-]?(\\d*\\.\\d+|\\d+(\\.\\d*)?)\\s*(e\\s*[+-]?\\d+)?\\s*",
- G_REGEX_CASELESS,
- 0,
- NULL);
-
- gboolean match = g_regex_match (numeric_regex, parameter, 0, NULL);
- g_regex_unref (numeric_regex);
- return match;
-}
+/* START LIBRARY DESCRIPTION *********************************************
+FLOAT.LIB
+ Copyright (c) 2006, Avtech Electrosystems Ltd.
+
+DESCRIPTION:
+ Functions that deal with strings and floating point numbers.
+
+SUPPORT LIB'S:
+END DESCRIPTION **********************************************************/
+
+
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#include <glib/gprintf.h>
+#include "globals.h"
+#include "string_utils.h"
+
+void Float_To_Text(int decimal_digits,float number_in, gchar ** text_out)
+{
+ g_assert (*text_out == NULL);
+
+ if (fabs(number_in)<1.1*smallest_allowed_number) {
+ if (number_in<0.0) {
+ *text_out = g_strdup_printf("-0.%0*d",decimal_digits,0);
+ } else {
+ *text_out = g_strdup_printf("0.%0*d",decimal_digits,0);
+ }
+ return;
+ }
+
+ *text_out = g_strdup_printf("%.*e", decimal_digits, number_in);
+}
+
+
+/*----------------------------------------------------------------------------------------------------------*/
+gboolean String_is_it_numeric(char *parameter)
+{
+
+ GRegex *numeric_regex = g_regex_new ( "\\s*[+-]?(\\d*\\.\\d+|\\d+(\\.\\d*)?)\\s*(e\\s*[+-]?\\d+)?\\s*",
+ G_REGEX_CASELESS,
+ 0,
+ NULL);
+
+ gboolean match = g_regex_match (numeric_regex, parameter, 0, NULL);
+ g_regex_unref (numeric_regex);
+ return match;
+}