/* START LIBRARY DESCRIPTION ********************************************* PARSER.LIB Copyright (c) 1997, Avtech Electrosystems Ltd. DESCRIPTION: Parser functions. SUPPORT LIB'S: END DESCRIPTION **********************************************************/ #include "error_utils.h" #include "parser.h" #include "flash.h" #include "nicutils.h" #include "version.h" #include "i2c.h" #include "lcd.h" #include "menus.h" #include "gpib.h" #include extern void send_message(gchar* message); //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_min_max_int (gchar** response, char *parameter, int min_val, int max_val); static int query_string (gchar** response, char *in); 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 process_int_param (char *parameter, int *value, int item_count, int *valid_nums, int allow_on_off); static int process_int_range (char *parameter, int *value, int min_val, int max_val); static int process_on_off (char *parameter, int *value); static int process_two_ints (char *parameter, int *value, int min, int max); 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 gchar* filter_input (gchar *raw_in); static int Parser_get_unit(char **parameter, char **units); static int Parser_channel (int *channel,int with_id_code,int routine_num); 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 Go_Str_eprom_47(gchar** response, int channel, char *loc_string,char *store_string,int command_type); static int Go_int_eprom_48(gchar** response, int channel, char *loc_string,char *store_string,int command_type); static int Go_Float_eprom51(gchar** response, int channel, char *loc_string,char *store_string,int command_type); static int Go_char_eprom_70(gchar** response, int channel, char *loc_string,char *store_string,int command_type); static int Go_eprom_siz_86(gchar** response, int channel, int command_type); static int Go_sys_net_91(gchar** response, int channel, char *loc_string,char *store_string,int command_type); static int Go_ampl_26(gchar** response, int channel, char *parameter,char *units,int command_type,char *mode); static int Go_pw_36(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_duty_37(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_offset_29(gchar** response, int channel, char *parameter,char *units,int command_type,char *mode); static int Go_idn_5(gchar** response, int channel, char *loc_string,char *store_string,int command_type); static int Go_freq_32_33(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_period_35(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_delay_39(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_dbl_pulse_40(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_func_34(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_polarity_42(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_hold_38(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_output_55(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_trig_source46(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_gate_type_56(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_gate_level_67(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_delay_test58(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_wai_10(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_opc_5(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_ese_2(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_esr_3(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_cls_1(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_sre_7(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_stb_8(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_tst_9(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_syst_ver_12(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_event_13(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_oper_enable15(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_ques_enable18(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_preset_19(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_zout_20(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_prot_trip_21(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_gpib_addr_59(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_ser_baud_60(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_ser_rts_64(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_load_68(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_meas_ampl_69(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_rst_6(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_calib_amp_72(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_calib_mon_73(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_mon_step_74(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_outputtype_75(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_calib_os_76(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_calib_pw_77(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_routeclose_78(gchar** response, int channel, char *parameter,char *units,int command_type); static int Parse_chan_list(int channel,char *parameter,int *primary_selected, int *secondary_selected,gchar** response); static int Go_dly_shift_82(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_amp_pnt_83(gchar** response, int channel, char *parameter,char *units,int command_type,int cal_type); static int Go_puls_count_88(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_puls_sep_89(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_sys_pwd_92(gchar** response, int channel, char *parameter,int command_type); static int Go_eprom_sus_93(gchar** response, int channel, char *parameter,int command_type); static int Go_rise_time_94(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_rcl_53(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_sav_54(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_soft_current_limit_96(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_curr_slew_98(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_cal_100(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_cal_interval_101(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_eprom_reset_102(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_atten_103(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,"") ) { id_code = 0; } else 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 if (!strcmp(id_me,"reset") || !strcmp(id_me,"res")) { id_code = 108; } else if (!strcmp(id_me,"attenuator") || !strcmp(id_me,"att")) { id_code = 109; } 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 - not used */ {13,68,71,72|optional,76}, /* syst:comm:ser:rec:bits - 62 - not used */ {13,68,71,72|optional,77}, /* syst:comm:ser:rec:sbits - 63 - not used */ {13,68,71,80,79}, /* syst:comm:ser:control:rts - 64 */ {13,68,71,72|optional,78}, /* syst:comm:ser:rec:echo - 65 - not used */ {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 */ {23,57,108}, /* diag:eprom:reset - 102 */ {23,109,16|optional}, /* diag:attenuator:state - 103 */ }; 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_posstr); } else if (!space_found) { /* end of a regular command word - use it */ commands[command_depth]=Parser_id_word( current_word->str, &channel, &with_id_code); /* get ready for the next token */ g_string_free (current_word, 1); current_word = g_string_new (""); 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 */ g_string_append_c (current_word, in[in_pos]); } /* 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(¶meter,&units); if (!globals.Sys.startup_complete) { error_num=Startup_Not_Finished; } 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: error_num=Unrecognized; break; case 1: error_num=Go_cls_1(&response,channel,parameter,units,command_type); break; case 2: error_num=Go_ese_2(&response,channel,parameter,units,command_type); break; case 3: error_num=Go_esr_3(&response,channel,parameter,units,command_type); break; case 4: error_num=Go_idn_5(&response,channel,parameter,units,command_type); break; case 5: error_num=Go_opc_5(&response,channel,parameter,units,command_type); break; case 6: error_num=Go_rst_6(&response,channel,parameter,units,command_type); break; case 7: error_num=Go_sre_7(&response,channel,parameter,units,command_type); break; case 8: error_num=Go_stb_8(&response,channel,parameter,units,command_type); break; case 9: error_num=Go_tst_9(&response,channel,parameter,units,command_type); break; case 10: error_num=Go_wai_10(&response,channel,parameter,units,command_type); break; case 11: error_num=Go_syst_err_11(&response,channel,parameter,units,command_type); break; case 12: error_num=Go_syst_ver_12(&response,channel,parameter,units,command_type); break; case 13: case 14: case 16: case 17: error_num=Go_event_13(&response,channel,parameter,units,command_type); break; case 15: error_num=Go_oper_enable15(&response,channel,parameter,units,command_type); break; case 18: error_num=Go_ques_enable18(&response,channel,parameter,units,command_type); break; case 19: error_num=Go_preset_19(&response,channel,parameter,units,command_type); break; case 20: error_num=Go_zout_20(&response,channel,parameter,units,command_type); break; case 21: case 30: case 31: error_num=Go_prot_trip_21(&response,channel,parameter,units,command_type); break; case 22: error_num=Go_ampl_26(&response,channel,parameter,units,command_type,"a"); break; case 25: error_num=Go_offset_29(&response,channel,parameter,units,command_type,"a"); break; case 26: error_num=Go_ampl_26(&response,channel,parameter,units,command_type,"v"); break; case 29: error_num=Go_offset_29(&response,channel,parameter,units,command_type,"v"); break; case 32: case 33: error_num=Go_freq_32_33(&response,channel,parameter,units,command_type); break; case 34: error_num=Go_func_34(&response,channel,parameter,units,command_type); break; case 35: error_num=Go_period_35(&response,channel,parameter,units,command_type); break; case 36: error_num=Go_pw_36(&response,channel,parameter,units,command_type); break; case 37: error_num=Go_duty_37(&response,channel,parameter,units,command_type); break; case 38: error_num=Go_hold_38(&response,channel,parameter,units,command_type); break; case 39: case 41: error_num=Go_delay_39(&response,channel,parameter,units,command_type); break; case 40: error_num=Go_dbl_pulse_40(&response,channel,parameter,units,command_type); break; case 42: error_num=Go_polarity_42(&response,channel,parameter,units,command_type); break; case 46: error_num=Go_trig_source46(&response,channel,parameter,units,command_type); break; case 47: error_num=Go_Str_eprom_47(&response,channel,parameter,units,command_type); break; case 48: error_num=Go_int_eprom_48(&response,channel,parameter,units,command_type); break; case 51: error_num=Go_Float_eprom51(&response,channel,parameter,units,command_type); break; case 53: error_num=Go_rcl_53(&response,channel,parameter,units,command_type); break; case 54: error_num=Go_sav_54(&response,channel,parameter,units,command_type); break; case 55: error_num=Go_output_55(&response,channel,parameter,units,command_type); break; case 56: error_num=Go_gate_type_56(&response,channel,parameter,units,command_type); break; case 58: error_num=Go_delay_test58(&response,channel,parameter,units,command_type); break; case 59: error_num=Go_gpib_addr_59(&response,channel,parameter,units,command_type); break; case 60: error_num=Go_ser_baud_60(&response,channel,parameter,units,command_type); break; case 64: error_num=Go_ser_rts_64(&response,channel,parameter,units,command_type); break; case 66: error_num=Go_syst_errcnt66(&response,channel,parameter,units,command_type); break; case 67: error_num=Go_gate_level_67(&response,channel,parameter,units,command_type); break; case 68: error_num=Go_load_68(&response,channel,parameter,units,command_type); break; case 69: error_num=Go_meas_ampl_69(&response,channel,parameter,units,command_type); break; case 70: error_num=Go_char_eprom_70(&response,channel,parameter,units,command_type); break; case 72: error_num=Go_calib_amp_72(&response,channel,parameter,units,command_type); break; case 73: error_num=Go_calib_mon_73(&response,channel,parameter,units,command_type); break; case 74: error_num=Go_mon_step_74(&response,channel,parameter,units,command_type); break; case 75: error_num=Go_outputtype_75(&response,channel,parameter,units,command_type); break; case 76: error_num=Go_calib_os_76(&response,channel,parameter,units,command_type); break; case 77: error_num=Go_calib_pw_77(&response,channel,parameter,units,command_type); break; case 78: error_num=Go_routeclose_78(&response,channel,parameter,units,command_type); break; case 79: error_num=Go_amp_pnt_83(&response,channel,parameter,units,command_type,pwl_pw_values); break; case 80: error_num=Go_amp_pnt_83(&response,channel,parameter,units,command_type,pwl_delay_values); break; case 81: error_num=Go_amp_pnt_83(&response,channel,parameter,units,command_type,pwl_period_values); break; case 82: error_num=Go_dly_shift_82(&response,channel,parameter,units,command_type); break; case 83: error_num=Go_amp_pnt_83(&response,channel,parameter,units,command_type,pwl_ampl_values); break; case 84: error_num=Go_amp_pnt_83(&response,channel,parameter,units,command_type,pwl_os_values); break; case 86: error_num=Go_eprom_siz_86(&response,channel,command_type); break; case 88: error_num=Go_puls_count_88(&response,channel,parameter,units,command_type); break; case 89: error_num=Go_puls_sep_89(&response,channel,parameter,units,command_type); break; case 90: error_num=Go_amp_pnt_83(&response,channel,parameter,units,command_type,pwl_burst_values); break; case 91: error_num=Go_sys_net_91(&response,channel,parameter,units,command_type); break; case 92: error_num=Go_sys_pwd_92(&response,channel,parameter,command_type); break; case 93: error_num=Go_eprom_sus_93(&response,channel,parameter,command_type); break; case 94: error_num=Go_rise_time_94(&response,channel,parameter,units,command_type); break; case 95: error_num=Go_amp_pnt_83(&response,channel,parameter,units,command_type,pwl_rise_time_values); break; case 96: error_num=Go_soft_current_limit_96(&response,channel,parameter,units,command_type); break; case 98: error_num=Go_curr_slew_98(&response,channel,parameter,units,command_type); break; case 99: error_num=Go_amp_pnt_83(&response,channel,parameter,units,command_type,pwl_slew_values); break; case 100: error_num=Go_cal_100(&response,channel,parameter,units,command_type); break; case 101: error_num=Go_cal_interval_101(&response,channel,parameter,units,command_type); break; case 102: error_num=Go_eprom_reset_102(&response,channel,parameter,units,command_type); break; case 103: error_num=Go_atten_103(&response,channel,parameter,units,command_type); break; case 9999: // was only whitespace, ignore break; default: error_num=Unrecognized; break; } } if (error_num) { queue_error_from_parser(&error_response, error_num); if (interactive_terminal) { (*cbfunc)(user_data, error_response); } } else if (response != NULL) { (*cbfunc)(user_data, response); } g_free (units); g_free (response); g_free (error_response); g_free (parameter); g_string_free (current_word, 1); 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 */ if (!is_query && !(globals.MenuStatus.Selected_Submenu==Submenu1_rem_loc && globals.MenuStatus.Type_Of_Menu==Submenu_On)) { Show_Main_Menu(); } /* 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); g_static_mutex_unlock (&mutex); } 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) { 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) { 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, globals.Constraints.err_min_freq[channel], globals.Constraints.err_max_freq[channel], 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, globals.Constraints.err_min_freq[channel], globals.Constraints.err_max_freq[channel]); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_Str_eprom_47(gchar** response, int channel, char *loc_string,char *store_string,int command_type) { /* diag:eprom:string - 47 */ int eprom_loc; eprom_loc = atoi(loc_string); /* convert location string to a number */ if ((eprom_loc < 0) || (eprom_loc>sizeof(globals.Flash))) { return OutOfRange; } switch (command_type) { case command_param_units: if ( (strlen(store_string) < LCD_cols) && (eprom_loc >= 0)) { int i; for (i=0; isizeof(globals.Flash))) { return OutOfRange; } switch (command_type) { case command_param_units: the_number=(short) atoi(store_string); *(short *)(&globals.Flash.flash_start + eprom_loc) = the_number; writeUserBlock(&globals.Flash, eprom_loc, sizeof (the_number)); return OK; break; case query_param: return query_int (response, (int) *(short *)(&globals.Flash.flash_start + eprom_loc)); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_Float_eprom51(gchar** response, int channel, char *loc_string,char *store_string,int command_type) { /* diag:eprom:float - 51 */ int eprom_loc; float the_number; eprom_loc = atoi(loc_string); /* convert location string to a number */ if ((eprom_loc < 0) || (eprom_loc>sizeof(globals.Flash))) { return OutOfRange; } switch (command_type) { case command_param_units: the_number=atof(store_string); *(float *)(&globals.Flash.flash_start + eprom_loc)=the_number; writeUserBlock(&globals.Flash, eprom_loc, sizeof(the_number)); return OK; break; case query_param:{ // The basic issue here is that this pointer isn't aligned. Which // should actually be a problem as ARMv7 has unaligned access support // and it's hardcoded to be on.. the issue is that not all instructions // can do unaliged accesses and the previous code generated one of those // instructions. The kernel traps the access and kills the process. // You should see something like this in dmesg: // [494223.471575] Alignment trap: not handling instruction edd37a00 at [<00011d12>] // [494223.479380] Unhandled fault: alignment exception (0x001) at 0x00050d66 // // I use memcpy here to copy the variable out into a temp // variable on the stack which is aligned. // There are probably other bits of code that will trigger this because of // the use of offsets into the struct.. It might be an idea to write some macros // for pushing and pulling bits from the struct. float temp; memcpy(&temp, (float *)(&globals.Flash.flash_start + eprom_loc),sizeof(float)); return query_float(response, temp); } break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_char_eprom_70(gchar** response, int channel, char *loc_string,char *store_string,int command_type) { /* diag:eprom:char - 70 */ int eprom_loc; char the_number; eprom_loc = atoi(loc_string); /* convert location string to a number */ if ((eprom_loc < 0) || (eprom_loc>sizeof(globals.Flash))) { return OutOfRange; } switch (command_type) { case command_param_units: the_number=(char) atoi(store_string); *(char *)(&globals.Flash.flash_start + eprom_loc)=the_number; writeUserBlock(&globals.Flash, eprom_loc, sizeof(the_number)); return OK; break; case query_param: return query_int (response, (int) *(char *)(&globals.Flash.flash_start + eprom_loc)); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_eprom_siz_86(gchar** response, int channel, int command_type) { switch (command_type) { case query_simple: return query_int (response, sizeof(globals.Flash)); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_sys_net_91(gchar **response, int channel, char *loc_string,char *store_string,int command_type) { nicinfo info; switch (command_type) { case query_simple: if (nicutils_infofordefaultroute(&info)) { *response = g_strdup_printf ("MAC address: %s, IP address: %s", info.mac, info.ip); return OK; } else { return NetworkNotFound; } break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Handle_Units(float *mult,char *units, char *in_base) { int len_base, len_all, pos; int errornum = OK; *mult=1.0; if (!strcmp(units,in_base)) { return OK; } len_all = strlen (units); if (len_all == 0) { return OK; } gchar *prefix = g_strdup (units); gchar *base = g_strdup (in_base); len_base = strlen (base); pos = len_all - len_base; if (!strcmp(base,"%") && (len_all >= 3) && !strcmp(prefix + len_all - 3,"pct")) { g_free (base); base = g_strdup ("pct"); prefix[len_all - 3] = 0; } else if (!strcmp(base,"pct") && !strcmp(prefix + len_all - 1,"%")) { g_free (base); base = g_strdup ("%"); prefix[len_all - 1] = 0; } else if (strcmp(prefix+pos,base)) { errornum = UnknownUnits; } else { prefix[pos]=0; } if (strlen(prefix) && !errornum) { // 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 { errornum = UnknownUnits; } } g_free (base); g_free (prefix); return errornum; } 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_int (gchar** response, char *parameter, int min_val, int max_val) { int report_val; if (Is_Min_Command(parameter)) { report_val=min_val; } else if (Is_Max_Command(parameter)) { report_val=max_val; } else { return SyntaxError; } *response = g_strdup_printf ("%d", report_val); 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 query_string (gchar** response, char *in) { *response = g_strdup (in); 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; } #define USE_ON_OFF 0 #define NO_ON_OFF 1 static int process_int_param (char *parameter, int *value, int item_count, int *valid_nums, int allow_on_off) { int status, min_val, max_val, is_valid; status = OK; is_valid = 0; min_val = valid_nums[0]; max_val = valid_nums[item_count - 1]; if (String_is_it_numeric(parameter)) { *value = atoi(parameter); int i; for (i = 0; (i < item_count) && (is_valid == 0); i++) { if (*value == valid_nums[i]) { is_valid = 1; } } if (is_valid == 0) { status = IllegalParameter; } } else if (!strcmp(parameter,"off") && (allow_on_off == USE_ON_OFF)) { *value = 0; } else if (!strcmp(parameter,"on") && (allow_on_off == USE_ON_OFF)) { *value = 1; } else if (Is_Min_Command(parameter) && (allow_on_off == NO_ON_OFF)) { *value = min_val; } else if (Is_Max_Command(parameter) && (allow_on_off == NO_ON_OFF)) { *value = max_val; } else { status=SyntaxError; } return status; } static int process_int_range (char *parameter, int *value, int min_val, int max_val) { int status; status = OK; if (String_is_it_numeric(parameter)) { *value = atoi(parameter); if ((*valuemax_val)) { status = OutOfRange; } } 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 process_on_off (char *parameter, int *value) { int valid_choices[2] = {0, 1}; return process_int_param (parameter, value, 2, valid_choices, USE_ON_OFF); } static int process_two_ints (char *parameter, int *value, int min, int max) { int valid_choices[2] = {min, max}; return process_int_param (parameter, value, 2, valid_choices, NO_ON_OFF); } 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.Errors.number_of_errors==0) { get_error_text(response, OK); } else { get_error_text(response,globals.Errors.error_queue[1]); Error_Remove_From_Queue(); } return OK; break; default: return SyntaxError; break; } return ThisShouldntHappen; } 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.Errors.number_of_errors); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_ampl_26(gchar** response, int channel, char *parameter,char *units,int command_type,char *mode) { float new_ampl; int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_amplitude)) { return status; } if (!strcmp(mode,"v")) { if (!globals.Flash.voltage_enabled[channel]) { return Unrecognized; } } if (!strcmp(mode,"a") && !globals.Flash.current_enabled[channel]) { return Unrecognized; } new_ampl=1.0; switch (command_type) { case command_param_units: if (status=Handle_Units(&new_ampl,units,mode)) { return status; } /* no break */ case command_withparam: if (!strcmp(parameter,"ext") || !strcmp(parameter,"external")) { return Set_EA(channel,amp_mode_ea); } else if (!strcmp(parameter,"amp") || !strcmp(parameter,"amplify")) { return Set_EA(channel,amp_mode_amplify); } else if (status = process_float_param (parameter, &new_ampl, globals.Constraints.err_min_ampl[channel], globals.Constraints.err_max_ampl[channel], ALLOW_NEG_ZERO)) { return status; } Set_EA(channel,amp_mode_normal); return Set_Amplitude(0,0,0,0,0,0,channel,new_ampl,0); break; case query_simple: if (globals.ChannelState[channel].amp_mode==amp_mode_ea) { return query_string(response, "EXT"); } else if (globals.ChannelState[channel].amp_mode==amp_mode_amplify) { return query_string(response, "AMP"); } else { return query_float(response, globals.ChannelState[channel].amplitude); } break; case query_param: return query_min_max_float (response, parameter, globals.Constraints.err_min_ampl[channel], globals.Constraints.err_max_ampl[channel]); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_pw_36(gchar** response, int channel, char *parameter,char *units,int command_type) { float new_pw; int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_pw)) { return status; } if (globals.Flash.fixed_pw[channel]) { return Unrecognized; } new_pw=1.0; switch (command_type) { case command_param_units: if (status=Handle_Units(&new_pw,units,"s")) { return status; } /* no break */ case command_withparam: if (!strcmp(parameter,"in")) { return Set_Pwmode(channel,pw_in_out); } else if (!strcmp(parameter,"ext")) { return Set_Pwmode(channel,pw_ew_ext); } else if (status = process_float_param (parameter, &new_pw, globals.Constraints.err_min_pw[channel], globals.Constraints.err_max_pw[channel], NORMAL_ZERO)) { return status; } if (status = Set_Pwmode(channel,pw_normal)) { return status; } return Set_Pw(0,0,0,channel,new_pw,0); break; case query_simple: switch (globals.ChannelState[channel].pw_ctrl_mode) { case pw_in_out: return query_string(response, "IN"); break; case pw_ew_ext: return query_string(response, "EXT"); break; default: case pw_normal: return query_float(response, globals.ChannelState[channel].pw); break; } break; case query_param: return query_min_max_float (response, parameter, globals.Constraints.err_min_pw[channel], globals.Constraints.err_max_pw[channel]); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_duty_37(gchar** response, int channel, char *parameter,char *units,int command_type) { float new_duty; int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_pw)) { return status; } if (globals.ChannelState[channel].trigger_source!=source_internal) { return DutyTriggerError; } new_duty=1.0; switch (command_type) { case command_param_units: if (status=Handle_Units(&new_duty,units,"%")) { return status; } /* no break */ case command_withparam: if (status = process_float_param (parameter, &new_duty, globals.Constraints.err_min_pw[channel]*globals.ChannelState[channel].frequency*100, globals.Constraints.err_max_pw[channel]*globals.ChannelState[channel].frequency*100, NORMAL_ZERO)) { return status; } return Set_Pw(0,0,0,channel,new_duty/(100*globals.ChannelState[channel].frequency),0); break; case query_simple: return query_float(response, 100*globals.ChannelState[channel].pw*globals.ChannelState[channel].frequency); break; case query_param: return query_min_max_float (response, parameter, globals.Constraints.err_min_pw[channel]*globals.ChannelState[channel].frequency*100, globals.Constraints.err_max_pw[channel]*globals.ChannelState[channel].frequency*100); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_offset_29(gchar** response, int channel, char *parameter,char *units,int command_type,char *mode) { float new_offset; int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_offset)) { return status; } if (!strcmp(mode,"v") && !globals.Flash.voltage_offset_enabled[channel]) { return Unrecognized; } if (!strcmp(mode,"a") && !globals.Flash.current_offset_enabled[channel]) { return Unrecognized; } new_offset=1.0; switch (command_type) { case command_param_units: if (status=Handle_Units(&new_offset,units,mode)) { return status; } /* no break */ case command_withparam: if (!strcmp(parameter,"ext") || !strcmp(parameter,"external")) { return Set_EO(channel,os_mode_eo); } else if (status = process_float_param (parameter, &new_offset, globals.Constraints.err_min_offset[channel], globals.Constraints.err_max_offset[channel], NORMAL_ZERO)) { return status; } Set_EO(channel,os_mode_normal); return Set_Offset(0,0,0,0,channel,new_offset); break; case query_simple: if (globals.ChannelState[channel].os_mode) { return query_string(response, "EXT"); } else { return query_float(response, globals.ChannelState[channel].offset); } break; case query_param: return query_min_max_float (response, parameter, globals.Constraints.err_min_offset[channel], globals.Constraints.err_max_offset[channel]); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_idn_5(gchar** response, int channel, char *loc_string,char *store_string,int command_type) { /* *idn? - 5 */ switch (command_type) { case query_simple: idn_string(response); return OK; break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_period_35(gchar** response, int channel, char *parameter,char *units,int command_type) { float new_period; float min_period; float max_period; int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_frequency)) { return status; } new_period=1.0; switch (command_type) { case command_param_units: if (status=Handle_Units(&new_period,units,"s")) { return status; } /* no break */ case command_withparam: min_period = 1.0/globals.Constraints.err_max_freq[channel]; max_period = globals.Constraints.err_min_freq[channel]; if (max_period==0.0) { return OutOfRange; } else { max_period = 1.0/max_period; } if (status = process_float_param (parameter, &new_period, min_period, max_period, NORMAL_ZERO)) { return status; } return Set_frequency(0,0,0,channel,1.0/new_period); break; case query_simple: return query_float(response, 1/globals.ChannelState[channel].frequency); break; case query_param: return query_min_max_float (response, parameter, 1.0/globals.Constraints.err_max_freq[channel], 1.0/globals.Constraints.err_min_freq[channel]); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_delay_39(gchar** response, int channel, char *parameter,char *units,int command_type) { float new_delay; int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_delay)) { return status; } new_delay=1.0; switch (command_type) { case command_param_units: if (status=Handle_Units(&new_delay,units,"s")) { return status; } /* no break */ case command_withparam: if (status = process_float_param (parameter, &new_delay, globals.Constraints.err_min_delay[channel], globals.Constraints.err_max_delay[channel], NORMAL_ZERO)) { return status; } return Set_Delay(0,0,0,channel,new_delay); break; case query_simple: return query_float(response, globals.ChannelState[channel].delay); break; case query_param: return query_min_max_float (response, parameter, globals.Constraints.err_min_delay[channel], globals.Constraints.err_max_delay[channel]); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_dbl_pulse_40(gchar** response, int channel, char *parameter,char *units,int command_type) { int on_off, status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_double_pulse)) { return status; } if (!(globals.Flash.double_pulse_allowed[channel])) { return Unrecognized; } switch (command_type) { case command_withparam: if (status=process_on_off (parameter, &on_off)) { return status; } return Set_Double(channel,on_off); break; case query_simple: return query_int (response, globals.ChannelState[channel].double_pulse); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_func_34(gchar** response, int channel, char *parameter,char *units,int command_type) { int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_func_mode)) { return status; } switch (command_type) { case command_withparam: if (!strcmp(parameter,"dc")) { return Set_Func(channel,dc_mode_on); } else if (!strcmp(parameter,"pulse") || !strcmp(parameter,"puls")) { return Set_Func(channel,pulse_mode_on); } else if (!strcmp(parameter,"sinusoid") || !strcmp(parameter,"sin") || !strcmp(parameter,"sine")) { return Set_Func(channel,sin_mode_on); } else if (!strcmp(parameter,"triangle") || !strcmp(parameter,"tri")) { return Set_Func(channel,tri_mode_on); } else if (!strcmp(parameter,"square") || !strcmp(parameter,"squ")) { return Set_Func(channel,squ_mode_on); } else if (!strcmp(parameter,"amplify") || !strcmp(parameter,"amp")) { return Set_Func(channel,amp_mode_on); } else { return SyntaxError; } break; case query_simple: if (globals.ChannelState[channel].func_mode==dc_mode_on) { return query_string(response, "DC"); } else if (globals.ChannelState[channel].func_mode==pulse_mode_on) { return query_string(response, "PULSE"); } else if (globals.ChannelState[channel].func_mode==sin_mode_on) { return query_string(response, "SIN"); } else if (globals.ChannelState[channel].func_mode==tri_mode_on) { return query_string(response, "TRI"); } else if (globals.ChannelState[channel].func_mode==squ_mode_on) { return query_string(response, "SQU"); } else if (globals.ChannelState[channel].func_mode==amp_mode_on) { return query_string(response, "AMP"); } return OK; break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_polarity_42(gchar** response, int channel, char *parameter,char *units,int command_type) { int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_polarity)) { return status; } if (!(globals.Flash.invert_allowed[channel])) { return Unrecognized; } switch (command_type) { case command_withparam: if (!strcmp(parameter,"norm") || !strcmp(parameter,"normal")) { return Set_Pol(channel,pol_norm); } else if (!strcmp(parameter,"comp") || !strcmp(parameter,"complement") || !strcmp(parameter,"inv") || !strcmp(parameter,"inverted") ) { return Set_Pol(channel,pol_complement); } else { return SyntaxError; } break; case query_simple: if (globals.ChannelState[channel].polarity==pol_norm) { return query_string(response, "NORM"); } else { return query_string(response, "COMP"); } break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_hold_38(gchar** response, int channel, char *parameter,char *units,int command_type) { int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_hold_setting)) { return status; } switch (command_type) { case command_withparam: if (!strcmp(parameter,"widt") || !strcmp(parameter,"width")) { Set_Hold(channel,hold_width); return OK; } else if (!strcmp(parameter,"dcyc") || !strcmp(parameter,"dcycle")) { Set_Hold(channel,hold_duty); return OK; } else { return SyntaxError; } break; case query_simple: if (globals.ChannelState[channel].hold_setting==hold_width) { return query_string(response, "WIDT"); } else { return query_string(response, "DCYC"); } break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_output_55(gchar** response, int channel, char *parameter,char *units,int command_type) { int on_off, status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_output_state)) { return status; } if(!globals.Flash.on_off_used) { return Unrecognized; } switch (command_type) { case command_withparam: if (status=process_on_off (parameter, &on_off)) { return status; } return Set_Output_State(channel,on_off); break; case query_simple: return query_int (response, globals.ChannelState[channel].output_state); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_trig_source46(gchar** response, int channel, char *parameter,char *units,int command_type) { int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_trigger_source)) { return status; } if (globals.Flash.is_func_gen[channel]) { return Unrecognized; } switch (command_type) { case command_withparam: if (!strcmp(parameter,"int") || !strcmp(parameter,"internal")) { Set_Trig_Source(channel,source_internal); } else if (!strcmp(parameter,"ext") || !strcmp(parameter,"external")) { Set_Trig_Source(channel,source_external); } else if (!strcmp(parameter,"man") || !strcmp(parameter,"manual")) { Set_Trig_Source(channel,source_manual); } else if (!strcmp(parameter,"hold")) { Set_Trig_Source(channel,source_hold); } else if (!strcmp(parameter,"imm") || !strcmp(parameter,"immediate")) { Set_Trig_Source(channel,source_immediate); } else { return SyntaxError; } return OK; break; case query_simple: if (globals.ChannelState[channel].trigger_source==source_internal) { return query_string(response, "INT"); } else if (globals.ChannelState[channel].trigger_source==source_external) { return query_string(response, "EXT"); } else if (globals.ChannelState[channel].trigger_source==source_manual) { return query_string(response, "MAN"); } else if (globals.ChannelState[channel].trigger_source==source_hold) { return query_string(response, "HOLD"); } else if (globals.ChannelState[channel].trigger_source==source_immediate) { return query_string(response, "IMM"); } return OK; break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_gate_type_56(gchar** response, int channel, char *parameter,char *units,int command_type) { int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_gate_type)) { return status; } if (globals.Flash.is_func_gen[channel]) { return Unrecognized; } switch (command_type) { case command_withparam: if (!strcmp(parameter,"sync")) { return Set_Gate_Sync(channel,gate_sync); } else if (!strcmp(parameter,"async")) { /* async mode doesn't work properly in dual-channel units */ if ( (globals.Flash.channels>1) || globals.Flash.sync_only) { return AsyncModeDisabled; } return Set_Gate_Sync(channel,gate_async); } else { return SyntaxError; } break; case query_simple: if (globals.ChannelState[channel].gate_type==gate_sync) { return query_string(response, "SYNC"); } else { return query_string(response, "ASYNC"); } break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_gate_level_67(gchar** response, int channel, char *parameter,char *units,int command_type) { int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_gate_level)) { return status; } if (globals.Flash.is_func_gen[channel]) { return Unrecognized; } switch (command_type) { case command_withparam: if (!strcmp(parameter,"hi") || !strcmp(parameter,"high")) { return Set_Gate_Level(channel,gate_high); } else if (!strcmp(parameter,"low") || !strcmp(parameter,"lo")) { return Set_Gate_Level(channel,gate_low); } else { return SyntaxError; } break; case query_simple: if (globals.ChannelState[channel].gate_level==gate_high) { return query_string(response, "HI"); } else { return query_string(response, "LO"); } break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_delay_test58(gchar** response, int channel, char *parameter,char *units,int command_type) { int on_off, status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_delay)) { return status; } switch (command_type) { case command_withparam: if (status=process_on_off (parameter, &on_off)) { return status; } globals.ChannelState[channel].test_delay_mode=on_off; Set_Mux(channel); return OK; break; default: return IllegalParameter; break; } return ThisShouldntHappen; } static int Go_wai_10(gchar** response, int channel, char *parameter,char *units,int command_type) { /* the *WAI command has no effect since all OP1B commands are non-overlapping */ switch (command_type) { case command_simple: return OK; break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_opc_5(gchar** response, int channel, char *parameter,char *units,int command_type) { /* the OPC commands automatically signal "operation complete" */ /* since all OP1B commands are non-overlapping */ switch (command_type) { case command_simple: GPIB_set_ESR(0x01,1); return OK; break; case query_simple: return query_int (response, 1); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_ese_2(gchar** response, int channel, char *parameter,char *units,int command_type) { int value, status; switch (command_type) { case command_withparam: if (status = process_int_range (parameter, &value, 0, 255)) { return status; } GPIB_set_ESE(0xff,0); GPIB_set_ESE(value,1); return OK; break; case query_simple: return query_int (response, GPIB_get_ESE()); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_esr_3(gchar** response, int channel, char *parameter,char *units,int command_type) { int orig_esr; switch (command_type) { case query_simple: orig_esr = GPIB_get_ESR(); GPIB_clear_events(); return query_int (response, orig_esr); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_cls_1(gchar** response, int channel, char *parameter,char *units,int command_type) { switch (command_type) { case command_simple: GPIB_clear_events(); globals.Errors.number_of_errors=0; return OK; break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_sre_7(gchar** response, int channel, char *parameter,char *units,int command_type) { int value, status; switch (command_type) { case command_withparam: if (status = process_int_range (parameter, &value, 0, 255)) { return status; } GPIB_set_SRE(0xbf,0); GPIB_set_SRE(value,1); return OK; break; case query_simple: return query_int (response, GPIB_get_SRE()); break; default: return SyntaxError; break; } } static int Go_stb_8(gchar** response, int channel, char *parameter,char *units,int command_type) { switch (command_type) { case query_simple: return query_int (response, GPIB_and_VXI_get_STB()); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_tst_9(gchar** response, int channel, char *parameter,char *units,int command_type) { switch (command_type) { case query_simple: return query_int (response, 0); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_syst_ver_12(gchar** response, int channel, char *parameter,char *units,int command_type) { switch (command_type) { case query_simple: return query_string(response, SCPI_version); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_event_13(gchar** response, int channel, char *parameter,char *units,int command_type) { switch (command_type) { case query_simple: return query_int (response, 0); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_oper_enable15(gchar** response, int channel, char *parameter,char *units,int command_type) { int value, status; switch (command_type) { case command_withparam: if (status = process_int_range (parameter, &value, 0, 255)) { return status; } globals.Registers.oper_enable_register=value; return OK; break; case query_simple: return query_int (response, globals.Registers.oper_enable_register); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_ques_enable18(gchar** response, int channel, char *parameter,char *units,int command_type) { int value, status; switch (command_type) { case command_withparam: if (status = process_int_range (parameter, &value, 0, 255)) { return status; } globals.Registers.ques_enable_register=value; return OK; break; case query_simple: return query_int (response, globals.Registers.ques_enable_register); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_preset_19(gchar** response, int channel, char *parameter,char *units,int command_type) { switch (command_type) { case command_simple: globals.Registers.oper_enable_register=0; globals.Registers.ques_enable_register=0; return OK; break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_zout_20(gchar** response, int channel, char *parameter,char *units,int command_type) { int value, status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_zout)) { return status; } if (!globals.Flash.switchable_zout[channel] || globals.Flash.volt_ctrl_pw[channel]) { return Unrecognized; } switch (command_type) { case command_param_units: // non-std unit handling, because zout is an integer, not a float if (strcmp(units,"ohm")) { return UnknownUnits; } /* no break */ case command_withparam: if (status=process_two_ints (parameter, &value, globals.Flash.zout_min[channel], globals.Flash.zout_max[channel])) { return status; } return Set_zout(channel,value,1); break; case query_simple: return query_int (response, globals.ChannelState[channel].zout); break; case query_param: return query_min_max_int(response, parameter, globals.Flash.zout_min[channel], globals.Flash.zout_max[channel]); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_prot_trip_21(gchar** response, int channel, char *parameter,char *units,int command_type) { switch (command_type) { case query_simple: if (I2C_Read(PCF8574A+Button_Press_Port) & Overload_Input) { return query_int (response, 0); /* overload not tripped */ } else { return query_int (response, 1); /* overload tripped */ } break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_gpib_addr_59(gchar** response, int channel, char *parameter,char *units,int command_type) { int value, status; switch (command_type) { case command_withparam: if (status = process_int_range (parameter, &value, 0, 30)) { return status; } GPIB_change_address(value); return OK; break; case query_simple: return query_int (response, globals.Flash.gpib_address); break; case query_param: return query_min_max_int (response, parameter, 0, 30); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_ser_baud_60(gchar** response, int channel, char *parameter,char *units,int command_type) { int new_baud, status; int valid_choices[] = {1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200}; switch (command_type) { case command_withparam: if (status = process_int_param (parameter, &new_baud, 8, valid_choices, NO_ON_OFF)) { return status; } return IO_Setup_RS232(new_baud, globals.Flash.hardhand, TRUE); break; case query_simple: return query_int (response, globals.Flash.baud); break; case query_param: return query_min_max_int (response, parameter, 1200, 115200); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_ser_rts_64(gchar** response, int channel, char *parameter,char *units,int command_type) { char new_hardhand; switch (command_type) { case command_withparam: if (!strcmp(parameter,"rfr") || !strcmp(parameter,"ibf") || !strcmp(parameter,"ibfull")) { // these are valid hardware handshake modes new_hardhand = 1; } else if (!strcmp(parameter,"on")) { new_hardhand = 0; } else { return IllegalParameter; } return IO_Setup_RS232(globals.Flash.baud, new_hardhand, TRUE); break; case query_simple: if (globals.Flash.hardhand) { return query_string(response, "IBF"); } else { return query_string(response, "ON"); } return OK; break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_load_68(gchar** response, int channel, char *parameter,char *units,int command_type) { float new_load_type; int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_load_type)) { return status; } if (!globals.Flash.switchable_load[channel]) { return Unrecognized; } new_load_type=1.0; switch (command_type) { case command_param_units: if (status=Handle_Units(&new_load_type,units,"ohm")) { return status; } /* no break */ case command_withparam: if (status = process_float_param (parameter, &new_load_type, globals.Constraints.err_min_load_type[channel], globals.Constraints.err_max_load_type[channel], NORMAL_ZERO)) { return status; } return Set_Load(channel,new_load_type); break; case query_simple: return query_float(response, globals.ChannelState[channel].load_type); break; case query_param: return query_min_max_float (response, parameter, globals.Constraints.err_min_load_type[channel], globals.Constraints.err_max_load_type[channel]); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_meas_ampl_69(gchar** response, int channel, char *parameter,char *units,int command_type) { int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_amplitude)) { return status; } if (!globals.Flash.monitor_enabled[channel]) { return Unrecognized; } switch (command_type) { case query_simple: return query_float(response, globals.ChannelState[channel].Curr_Mon_value); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_rst_6(gchar** response, int channel, char *parameter,char *units,int command_type) { switch (command_type) { case command_simple: Main_Rst(); return OK; break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_calib_amp_72(gchar** response, int channel, char *parameter,char *units,int command_type) { float cal_val; int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_amplitude)) { return status; } if (!globals.Flash.voltage_enabled[channel] && !globals.Flash.current_enabled[channel]) { return Unrecognized; } cal_val=1.0; switch (command_type) { case command_param_units: if (globals.Flash.current_enabled[channel]) { if (status=Handle_Units(&cal_val,units,"a")) { return status; } } else if (globals.Flash.voltage_enabled[channel]) { if (status=Handle_Units(&cal_val,units,"v")) { return status; } /* no break */ } case command_withparam: if (!String_is_it_numeric(parameter)) { return SyntaxError; } return Set_Amp_Calib(channel,atof(parameter)*cal_val); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_calib_mon_73(gchar** response, int channel, char *parameter,char *units,int command_type) { float mon_val; int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_amplitude)) { return status; } if (!globals.Flash.monitor_enabled[channel]) { return Unrecognized; } mon_val=1.0; switch (command_type) { case command_param_units: if (status=Handle_Units(&mon_val,units,"a")) { return status; } case command_withparam: if (!String_is_it_numeric(parameter)) { return SyntaxError; } return Set_Mon_Calib(channel,atof(parameter)*mon_val); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_mon_step_74(gchar** response, int channel, char *parameter,char *units,int command_type) { float mon_val; float span , step_min, step_max; int status; int eprom_loc; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_amplitude)) { return status; } if (!globals.Flash.monitor_enabled[channel]) { return Unrecognized; } mon_val=1.0; span = fabs(globals.Flash.max_ampl[channel]-globals.Flash.min_ampl[channel]); if (globals.Flash.voltage_enabled[channel] || globals.Flash.current_enabled[channel]) { step_min = span / 5000.0; step_max = span / 5.0; } else { step_min = 0.0001; step_max = 10.0; } switch (command_type) { case command_param_units: if (status=Handle_Units(&mon_val,units,"a")) { return status; } case command_withparam: if (status = process_float_param (parameter, &mon_val, step_min, step_max, NORMAL_ZERO)) { return status; } mon_val=fabs(mon_val); if ((mon_val < step_min) || (mon_val > step_max)) { return OutOfRange; } globals.Flash.monitor_step[channel]=mon_val; eprom_loc = (char *) &(globals.Flash.monitor_step) - (char *) &(globals.Flash.flash_start); writeUserBlock(&globals.Flash, eprom_loc, sizeof(globals.Flash.monitor_step)); break; case query_simple: return query_float(response, globals.Flash.monitor_step[channel]); break; case query_param: return query_min_max_float (response, parameter, step_min, step_max); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_outputtype_75(gchar** response, int channel, char *parameter,char *units,int command_type) { int new_logic_level, status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_logic_level)) { return status; } if (!globals.Flash.logic_level_enabled) { return Unrecognized; } switch (command_type) { case command_withparam: if (!strcmp(parameter,"ttl")) { new_logic_level=logic_ttl; } else if (!strcmp(parameter,"ecl")) { new_logic_level=logic_ecl; } else { return SyntaxError; } return Set_Logic_Level(channel,new_logic_level); break; case query_simple: if (globals.ChannelState[channel].logic_level==logic_ttl) { return query_string(response, "TTL"); } else { return query_string(response, "ECL"); } break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_calib_os_76(gchar** response, int channel, char *parameter,char *units,int command_type) { float mon_val; int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_offset)) { return status; } if ( !globals.Flash.current_offset_enabled[channel] && !globals.Flash.voltage_offset_enabled[channel]) { return Unrecognized; } mon_val=1.0; switch (command_type) { case command_param_units: if (globals.Flash.current_offset_enabled[channel]) { if (status=Handle_Units(&mon_val,units,"a")) { return status; } } else { if (status=Handle_Units(&mon_val,units,"v")) { return status; } } case command_withparam: if (!String_is_it_numeric(parameter)) { return SyntaxError; } return Set_OS_Calib(channel,atof(parameter)*mon_val); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_calib_pw_77(gchar** response, int channel, char *parameter,char *units,int command_type) { float pw_adjust; int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_pw)) { return status; } pw_adjust=1.0; switch (command_type) { case command_param_units: if (status=Handle_Units(&pw_adjust,units,"s")) { return status; } /* no break */ case command_withparam: if (status = process_float_param (parameter, &pw_adjust, -1.0e-6, 1.0e-6, NORMAL_ZERO)) { return status; } return Set_PW_shift(channel,pw_adjust); break; case query_simple: return query_float(response, Get_PW_shift(channel)); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_routeclose_78(gchar** response, int channel, char *parameter,char *units,int command_type) { int error_num; int temp1, temp2, status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_route)) { return status; } if (!globals.Flash.routing_required[channel]) { return Unrecognized; } temp1 = globals.ChannelState[channel].route_primary; temp2 = globals.ChannelState[channel].route_secondary; switch (command_type) { case command_withparam: if (error_num=Parse_chan_list(channel, parameter, &temp1, &temp2, NULL)) { return error_num; } else { Set_Route(channel,ROUTE_PRIMARY,temp1); Set_Route(channel,ROUTE_SECONDARY,temp2); return OK; } break; case query_param: if (error_num=Parse_chan_list(channel, parameter, &temp1, &temp2, response)) { return error_num; } else { return OK; } break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Parse_chan_list(int channel,char *parameter,int *primary_selected, int *secondary_selected, gchar** response) { int i; int n; int pointer; int has_module_name; int *value_pointer; #define PARSE_MAX_STRING 20 if ( !(parameter[0]=='(' && parameter[1]=='@')) { return SyntaxError; } if (strchr (parameter, ':')) { return Route_Range_Error; } if (strchr (parameter, '!')) { return Route_Range_Error; } pointer=1; do { int error_num = OK; pointer++; has_module_name = FALSE; /* get module name, if any */ GString *name = g_string_new (""); for (i=0; isalpha(parameter[pointer]) && (i0) { has_module_name = TRUE; if (!strcmp (name->str, "anod")) { value_pointer = primary_selected; } else if (!strcmp (name->str, "cath")) { if (globals.Flash.routing_required[channel]<2) { error_num = IllegalParameter; } value_pointer = secondary_selected; } else { error_num = IllegalParameter; } if (!error_num && (parameter[pointer] == '(' )) { pointer++; } else { error_num =SyntaxError; } } g_string_free (name, TRUE); if (error_num) { return error_num; } GString *digits = g_string_new (""); /* get digits */ for (i=0; isdigit(parameter[pointer]) && (istr); g_string_free (digits, TRUE); if (error_num) { return error_num; } if ((n < 1) || (n > globals.Flash.routing_max_pins[channel])) { return OutOfRange; } if (has_module_name) { if (parameter[pointer] == ')' ) { pointer++; } else { return SyntaxError; } } /* query or command? */ if (response) { if (*value_pointer == n) { *response = g_strdup ("1 "); } else { *response = g_strdup ("0 "); } } else { if (value_pointer) { *value_pointer=n; } } } while (parameter[pointer]==','); if ( parameter[pointer]==')') { pointer++; for(; parameter[pointer]; pointer++) if (!isspace(parameter[pointer])) { return SyntaxError; } } else { return SyntaxError; } return OK; } static int Go_dly_shift_82(gchar** response, int channel, char *parameter,char *units,int command_type) { #define num_of_dly_shift_points 2 int value, status; float cal_point; float min_one_shot_delay; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_delay)) { return status; } switch (command_type) { case command_param_units: /* if param=point number, and units=measurement, then update calibration */ if (String_is_it_numeric(parameter) && String_is_it_numeric(units)) { value=atoi(parameter); if (value>num_of_dly_shift_points || value<1) { return IllegalParameter; } cal_point=atof(units); return Set_Dly_Shr_Cal(channel,value,cal_point); } else if (String_is_it_numeric(parameter) && !strcmp(units,"go")) { value=atoi(parameter); if (value>num_of_dly_shift_points || value<1) { return IllegalParameter; } return Set_Dly_Shr_Nom(channel,value); } else { return SyntaxError; } return OK; break; case query_param: return query_min_max_int(response, parameter, 1, num_of_dly_shift_points); break; case query_simple: min_one_shot_delay = globals.Flash.delay_pwl_time[channel][0][0][0]; *response = g_strdup_printf ( "Fixed delay: %f ns, PG-SYNC propagation delay: %f ns, narrowest variable delay: %f ns, all delays valid: %s, delay monotonic in external trigger mode: %s", globals.Flash.delay_shrink[channel]*1e9, globals.Flash.propagation_delay[channel]*1e9, globals.Flash.delay_pwl_time[channel][0][0][0]*1e9, (globals.Flash.delay_shrink[channel] >= min_one_shot_delay) ? "TRUE" : "FALSE", (( globals.Flash.delay_shrink[channel] - globals.Flash.propagation_delay[channel] ) >= min_one_shot_delay) ? "TRUE" : "FALSE"); return OK; break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_amp_pnt_83(gchar** response, int channel, char *parameter,char *units,int command_type,int cal_type) { int value,status; float cal_point; switch (cal_type) { case pwl_burst_values: if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_Burst_Time)) { return status; } if (globals.Flash.max_burst_count[channel]<2) { return Unrecognized; } break; case pwl_ampl_values: if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_amplitude)) { return status; } if (!globals.Flash.voltage_enabled[channel] && !globals.Flash.current_enabled[channel]) { return Unrecognized; } break; case pwl_rise_time_values: if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_rise_time)) { return status; } if (globals.Flash.fixed_rise_time[channel]) { return Unrecognized; } break; case pwl_slew_values: if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_slew)) { return status; } if (!globals.Flash.curr_slew[channel]) { return Unrecognized; } break; case pwl_os_values: if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_offset)) { return status; } if (!globals.Flash.voltage_offset_enabled[channel] && !globals.Flash.current_offset_enabled[channel]) { return Unrecognized; } break; case pwl_pw_values: if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_pw)) { return status; } break; case pwl_delay_values: if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_delay)) { return status; } break; case pwl_period_values: if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_frequency)) { return status; } break; } switch (command_type) { case command_param_units: /* if param=point number, and units=measurement, then update calibration */ if (String_is_it_numeric(parameter) && String_is_it_numeric(units)) { value=atoi(parameter); if (value>Get_VI_Num_Pnts(cal_type,channel) || value<1) { return IllegalParameter; } cal_point=atof(units); return Set_VI_Cal_Pnt(cal_type,channel,value,cal_point); } else if (String_is_it_numeric(parameter) && !strcmp(units,"go")) { value=atoi(parameter); if (value>Get_VI_Num_Pnts(cal_type,channel) || value<1) { return IllegalParameter; } if (status=Set_Cal_Nom(channel,value,cal_type,NULL)) { return status; } } else if (String_is_it_numeric(parameter) && !strcmp(units,"delete")) { value=atoi(parameter); if (value>Get_VI_Num_Pnts(cal_type,channel) || value<1) { return IllegalParameter; } if (status=Set_VI_Del_Cal(cal_type,channel,value)) { return status; } } else if (String_is_it_numeric(parameter) && !strcmp(units,"add")) { cal_point=atof(parameter); if (status=Set_VI_Add_Cal(cal_type,channel,cal_point)) { return status; } } else { return SyntaxError; } return OK; break; case query_param: return query_min_max_int(response, parameter, 1, Get_VI_Num_Pnts(cal_type,channel)); break; default: return SyntaxError; break; } return ThisShouldntHappen; } int Handle_Curr_Slew_Unit(float *new_val,char *units); int Handle_Curr_Slew_Unit(float *new_val,char *units) { char *slash; float tmp1, tmp2; *new_val = 1.0; slash = strstr (units,"/"); if (slash == NULL) { return UnknownUnits; } slash[0]=0; if (Handle_Units (&tmp1, units, "a") != OK) { return UnknownUnits; } if (Handle_Units (&tmp2, slash+1, "s") != OK) { return UnknownUnits; } *new_val = tmp1 / tmp2; return OK; } static int Go_puls_count_88(gchar** response, int channel, char *parameter,char *units,int command_type) { int value, status; int min_val; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_Burst_Count)) { return status; } /* if the maximum burst count is 0 or 1, disable this command */ if (globals.Flash.max_burst_count[channel]<2) { return Unrecognized; } min_val = 1; // -BR if (globals.Flash.burst_func[channel]) { min_val = 0; // -PANB } switch (command_type) { case command_withparam: if (status = process_int_range (parameter, &value, min_val, globals.Constraints.err_max_burst_count[channel])) { return status; } return Set_Burst_Count(channel,value,globals.ChannelState[channel].burst_time); break; case query_simple: return query_int (response, globals.ChannelState[channel].burst_count); break; case query_param: return query_min_max_int(response, parameter, min_val, globals.Constraints.err_max_burst_count[channel]); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_puls_sep_89(gchar** response, int channel, char *parameter,char *units,int command_type) { float new_pw; int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_Burst_Time)) { return status; } /* if the maximum burst count is 0 or 1, disable this command */ if ((globals.Flash.max_burst_count[channel]<2) || (globals.Flash.burst_func[channel])) { return Unrecognized; } new_pw=1.0; switch (command_type) { case command_param_units: if (status=Handle_Units(&new_pw,units,"s")) { return status; } /* no break */ case command_withparam: globals.ChannelState[channel].pw_ctrl_mode=pw_normal; if (status = process_float_param (parameter, &new_pw, globals.Constraints.err_min_burst_time[channel], globals.Constraints.err_max_burst_time[channel], NORMAL_ZERO)) { return status; } return Set_Burst_Time(0,0,0,channel,new_pw); break; case query_simple: return query_float(response, globals.ChannelState[channel].burst_time); break; case query_param: return query_min_max_float (response, parameter, globals.Constraints.err_min_burst_time[channel], globals.Constraints.err_max_burst_time[channel]); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_sys_pwd_92(gchar** response, int channel, char *parameter,int command_type) { gchar *old_password = NULL; gchar *new_password = NULL; char *new_loc; int error_num; switch (command_type) { case command_withparam: /* new password follows comma */ new_loc = strchr(parameter,','); if (new_loc == NULL) { return password_change_error; } new_password = g_strdup_printf ("%s", new_loc + 1); new_loc[0]=0; old_password = g_strdup (parameter); error_num = OK; if ((strlen(new_password)< 6) || (strlen(new_password)>32)) { error_num = password_change_error; } if (!error_num) { error_num = change_password (old_password, new_password); } g_free (new_password); g_free (old_password); return error_num; default: return SyntaxError; break; } } static int Go_eprom_sus_93(gchar** response, int channel, char *parameter,int command_type) { if (channel) { return InvalidChannel; } switch (command_type) { case command_withparam: if (!strcmp(parameter,"1")) { globals.Flags.flash_writes_suspended=1; } else if (!strcmp(parameter,"0")) { globals.Flags.flash_writes_suspended=0; writeUserBlock(&globals.Flash,0,sizeof(globals.Flash)); } else { return SyntaxError; } Menu_Clear_Buttons(); return OK; break; case query_simple: return query_int (response, globals.Flags.flash_writes_suspended); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_eprom_reset_102(gchar** response, int channel, char *parameter,char *units,int command_type) { int status, value; if (channel) { return InvalidChannel; } switch (command_type) { case command_withparam: if (status = process_int_range (parameter, &value, 0, sizeof(globals.Flash)-1)) { return status; } initFlash(&globals.Flash, TRUE, value); Main_Rst(); return OK; break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_rise_time_94(gchar** response, int channel, char *parameter,char *units,int command_type) { float new_rise_time; int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_rise_time)) { return status; } if (globals.Flash.fixed_rise_time[channel]) { return Unrecognized; } new_rise_time=1.0; switch (command_type) { case command_param_units: if (status=Handle_Units(&new_rise_time,units,"s")) { return status; } /* no break */ case command_withparam: if (status = process_float_param (parameter, &new_rise_time, globals.Constraints.err_min_rise_time[channel], globals.Constraints.err_max_rise_time[channel], NORMAL_ZERO)) { return status; } return Set_rise_time(0,0,0,channel,new_rise_time); break; case query_simple: return query_float(response, globals.ChannelState[channel].rise_time); break; case query_param: return query_min_max_float (response, parameter, globals.Constraints.err_min_rise_time[channel], globals.Constraints.err_max_rise_time[channel]); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_rcl_53(gchar** response, int channel, char *parameter,char *units,int command_type) { int value, status; switch (command_type) { case command_withparam: if (status = process_int_range (parameter, &value, 0, 3)) { return status; } Set_Rcl(value); return OK; break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_sav_54(gchar** response, int channel, char *parameter,char *units,int command_type) { int value, status; switch (command_type) { case command_withparam: if (status = process_int_range (parameter, &value, 0, 3)) { return status; } Set_Sav(value); return OK; break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_soft_current_limit_96(gchar** response, int channel, char *parameter,char *units,int command_type) { float new_soft_current_limit; int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_current_limit)) { return status; } if (!globals.Flash.soft_current_limit_enabled[channel]) { return Unrecognized; } new_soft_current_limit=1.0; switch (command_type) { case command_param_units: if (status=Handle_Units(&new_soft_current_limit,units,"a")) { return status; } /* no break */ case command_withparam: if (status = process_float_param (parameter, &new_soft_current_limit, globals.Constraints.err_min_soft_current_limit[channel], globals.Constraints.err_max_soft_current_limit[channel], NORMAL_ZERO)) { return status; } return Set_current_limit(0,channel,new_soft_current_limit); break; case query_simple: return query_float(response, globals.ChannelState[channel].soft_current_limit); break; case query_param: return query_min_max_float (response, parameter, globals.Constraints.err_min_soft_current_limit[channel], globals.Constraints.err_max_soft_current_limit[channel]); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_curr_slew_98(gchar** response, int channel, char *parameter,char *units,int command_type) { float new_slew; int status; if (status = check_channel_ok (channel, globals.Flash.channels, globals.Flash.ChanKey_slew)) { return status; } if (!globals.Flash.curr_slew[channel]) { return Unrecognized; } new_slew=1.0; switch (command_type) { case command_param_units: if (status=Handle_Curr_Slew_Unit(&new_slew,units)) { return status; } /* no break */ case command_withparam: if (status = process_float_param (parameter, &new_slew, globals.Constraints.err_min_slew[channel], globals.Constraints.err_max_slew[channel], NORMAL_ZERO)) { return status; } return Set_slew(0,0,0,channel,new_slew); break; case query_simple: return query_float(response, globals.ChannelState[channel].slew); break; case query_param: return query_min_max_float (response, parameter, globals.Constraints.err_min_slew[channel], globals.Constraints.err_max_slew[channel]); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_cal_100(gchar** response, int channel, char *parameter,char *units,int command_type) { int no_report, status; CalStruct caldata; if (!globals.Flash.self_cal) { return Unrecognized; } no_report = 0; switch (command_type) { case command_simple: no_report = 1; // continue below case query_simple: status = do_full_self_cal(&caldata); if (!no_report) { query_string(response, caldata.response->str); g_string_free (caldata.response, TRUE); } return status; break; default: return SyntaxError; break; } } static int Go_cal_interval_101(gchar** response, int channel, char *parameter,char *units,int command_type) { int eprom_loc, status, the_number; if (!globals.Flash.self_cal) { return Unrecognized; } switch (command_type) { case command_withparam: if (status = process_int_range (parameter, &the_number, 0, 365)) { return status; } globals.Flash.self_cal_interval = the_number; eprom_loc = (char *) &(globals.Flash.self_cal_interval) - (char *) &(globals.Flash.flash_start); writeUserBlock(&globals.Flash, eprom_loc, sizeof(globals.Flash.self_cal_interval)); return OK; break; case query_simple: return query_int (response, globals.Flash.self_cal_interval); break; case query_param: return query_min_max_int(response, parameter, 0, 365); break; default: return SyntaxError; break; } return ThisShouldntHappen; } static int Go_atten_103(gchar** response, int channel, char *parameter,char *units,int command_type) { int on_off, status; switch (command_type) { case command_withparam: if (status=process_on_off (parameter, &on_off)) { return status; } globals.Flags.attenuators_enabled = on_off; return OK; break; case query_simple: return query_int (response, globals.Flags.attenuators_enabled); break; default: return SyntaxError; break; } return ThisShouldntHappen; }