#include "globals.h" #include "lcd.h" #include "i2c.h" #include "error_utils.h" #include "string_utils.h" #include "device-functions.h" #include "version.h" #include /* define common strings */ #define Press_Change_Message "Push CHANGE to continue." /* keypad hardware definitions */ #define Move_Button 1 /* mask for MOVE button */ #define Change_Button 2 /* mask for CHANGE button */ #define Mult10_Button 4 /* mask for x10 button */ #define Div10_Button 8 /* mask for /10 button */ #define Plus_Minus_Button 16 /* mask for +/- button */ #define Extra_Fine_Button 32 /* mask for extra-fine button */ /* ----- HOW THE MENU SYSTEM WORKS -------------------------------------------------------------------------*/ /* To add a new menu: 1. add the menu name directly below */ /* 2. add the menu mode list choices directly below */ /* 3. if it is to be shown on the main menu, update Menu_Update_Display(void); */ /* 4. update Submenu_Display(void), which builds the submenu */ /* 5. update Submenu_Implement_Changes(void), to do the actual functions */ /* KEY SUBROUTINES: */ /* Menu_Update_Display(void); - displays the main menu */ /* Menu_Check_Buttons(void); - determines what to show based on button status */ /* (void); - clears any button presses */ /* Menu_Move_Pointer(int move_amount); - moves the pointer up and down the main menu */ /* Submenu_Display(void); - builds and displays submenus */ /* Submenu_Move_Pointer(void); - moves the pointer up and down submenu mode list */ /* Submenu_Implement_Changes(void); - once a mode in a submenu mode list has been chosen, */ /* this executes whatever is associated with that mode */ /* Submenu_Mult_Value(float mult_by); - this implements the x10, /10, +/- button functions */ /* Submenu_Service_Encoder(void); - this implements the adjust knob */ /* Nonstd_menu_RS232(void); - the RS232 menu is non-standard */ /* Nonstd_menu_default_rs232(void); - the default RS232 screen is non-standard */ /* Nonstd_menu_model_info(void); - the model info screen is non-standard */ /* MENU NAMES - these are menus with associated mode lists */ /* - Submenu1 are submenus linked from the main menu */ /* - Submenu2 are submenus linked from the other submenus */ /* MODE LIST CHOICES - if selected, these are fed into Submenu_Implement_Changes */ #define mode_freq_int 0 #define mode_freq_ext 100 #define mode_freq_man 200 #define mode_freq_hold 300 #define mode_delay_norm 400 #define mode_delay_dbl 500 #define mode_pw_norm 600 #define mode_pw_duty 700 #define mode_pw_inout 800 #define mode_pw_dc 900 #define mode_output_on 1000 #define mode_output_off 1100 #define mode_inv_no 1200 #define mode_inv_yes 1300 #define mode_gate_losync 1400 #define mode_gate_loasync 1500 #define mode_gpib_address 1600 #define mode_rs232_settings 1700 #define mode_model_info 1800 #define mode_exit_normal_submenu 1900 #define mode_zout_max 2000 #define mode_zout_min 2100 #define mode_save_0 2200 #define mode_save_1 2300 #define mode_save_2 2400 #define mode_save_3 2500 #define mode_load_0 2600 #define mode_load_1 2700 #define mode_load_2 2800 #define mode_load_3 2900 #define mode_load 3000 #define mode_save 3100 #define mode_change_rs232 3200 #define mode_default_rs232 3300 #define mode_1200 3400 #define mode_2400 3500 #define mode_4800 3600 #define mode_9600 3700 #define mode_7bits 3800 #define mode_8bits 3900 #define mode_par_none 4000 #define mode_par_even 4100 #define mode_par_odd 4200 #define mode_1bit 4300 #define mode_2bits 4400 #define mode_hand_hard 4500 #define mode_hand_off 4600 #define mode_echo_on 4700 #define mode_echo_off 4800 #define mode_amp_normal 4900 #define mode_amp_ea 5000 #define mode_gate_hisync 5100 #define mode_gate_hiasync 5200 #define mode_go_to_local 5500 #define mode_exit_rs232 5600 #define mode_logic_ttl 5700 #define mode_logic_ecl 5800 #define mode_amp_min 5900 #define mode_amp_max 6000 #define mode_os_normal 6300 #define mode_os_eo 6400 #define mode_amp_amplify 6500 #define mode_func_sin 6700 #define mode_func_tri 6800 #define mode_func_squ 6900 #define mode_func_pulse 7000 #define mode_func_amp 7100 #define mode_network 7200 #define mode_password 7300 #define mode_selfcal 7400 #define Submenu_maximum_entries 8 /* used to be 4, before scrolling lists were added */ /* what parameter to adjust */ #define Show_frequency 0 #define Show_delay 100 #define Show_pw 200 #define Show_amplitude 300 #define Show_offset 400 #define Show_duty_cycle 500 #define Show_zout 600 #define Show_No_Number 700 #define Show_monitor 800 #define Show_Burst_Count 900 #define Show_Burst_Time 1000 #define Show_rise_time 1100 #define Show_gpib_address 1200 #define Show_soft_current_limit 1300 #define Show_route_primary 1500 #define Show_route_secondary 1600 #define Show_load_type 1700 #define Show_slew 1800 #define Show_avrq_ampl 1900 /* KEY MENU-JUGGLING VARIABLES - controlling what is actually shown on the display */ char temp[LCD_col_width+1]; int menu_cursor_pos; int last_button_state; /* keeping track of button presses (software flip-flop) */ int last_encoder_adjust_error; unsigned long long encoder_last_adjust; unsigned long long encoder_timer_change[3]; int encoder_mult; int base_entry; /* for scrolling submenu mode lists */ /* KEY MAIN-MENU-RELATED VARIABLES */ /* - the main menu choices are indexed [0]-[Main_Menu_max_entry] */ /* - the actual item at each choice is stored in Main_Menu_Structure[] */ int Main_Menu_Structure[LCD_max_entries+1]; int Main_Menu_max_entry; /* KEY SUBMENU VARIABLES */ int Submenu_Structure[Submenu_maximum_entries]; /* this keeps track of the submenu mode-list */ int Submenu_Selected_Item; /* current submenu mode-list item selected */ int Submenu_Numeric_Parameter; /* when the adjust knob is varied, this is what gets changed */ /* for example, Show_No_Number */ /* Show_frequency */ /* Show_delay */ /* Show_pw */ /* Show_amplitude */ /* Show_offset */ /* Show_duty_cycle */ int Submenu_max_entry; /* highest mode-list menu item number */ float Submenu_Value; /* actual value of the shown parameter (like frequency) */ int Submenu_extra_fine; /* is the extra-fine mode on? */ static int Menu_Is_Item_Visible(int LCD_entry); static void Menu_Move_Pointer(int move_amount); static void Display_Number_on_LCD(int Is_Item_Visible,int LCD_row,int LCD_col,char *start_string,int Show_What, int significant_digits, int width_of_column,char *LCD_string); static void Submenu_Display(int redraw); static void Submenu_Move_Pointer(void); static int Submenu_Mult_Value(float mult_by); static void Submenu_Service_Encoder(int encoder_change); static void Nonstd_menu_default_rs232(void); static void Nonstd_menu_model_info(void); static void Menu_Check_Buttons(void); static int Submenu_Implement_Changes(void); static void Nonstd_menu_network(void); void Menu_Refresh() { globals.Changes.update_whole_main_menu = YES; LCD_clear(); Menu_Update_Display(); } static int Menu_Is_Item_Visible(int LCD_entry) { return ((LCD_entry/LCD_max_entries_per_page)==(menu_cursor_pos/LCD_max_entries_per_page)); } void Menu_Update_Display(void) { char units[2*LCD_col_width]; char a_string[2*LCD_col_width]; char b_string[2*LCD_col_width]; int LCD_entry, LCD_row, LCD_col; int sig_dig; /* number of significant digits to display */ int i; int chan; int show_item; int old_cursor_pos; char LCD_string[LCD_cols+1]; LCD_entry=-1; sig_dig = 4; globals.MenuStatus.Type_Of_Menu=Main_Menu_On; Submenu_extra_fine=NO; globals.MenuStatus.Error_Screen=NO; globals.MenuStatus.Nonstd_Display=NO; /* fill in unused cursor columns */ for (i=0; i<(menu_cursor_pos % LCD_max_entries_per_page); ++i) { LCD_row=i % LCD_rows; LCD_col=(i / LCD_rows) * LCD_col_width; LCD_write(LCD_row,LCD_col," "); } /* Don't overwrite the cursor. This would generate needless LCD accesses */ for (i=((menu_cursor_pos % LCD_max_entries_per_page)+1); i<15; ++i) { LCD_row=i % LCD_rows; LCD_col=(i / LCD_rows) * LCD_col_width; LCD_write(LCD_row,LCD_col," "); } old_cursor_pos=menu_cursor_pos; /*----- display freq, always (except func gen amplify mode) -----*/ for (chan=0; chan<(globals.Flash.ChanKey_frequency?globals.Flash.channels:1); ++chan) { if (globals.ChannelState[chan].func_mode!=amp_mode_on) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_freq+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_freq+chan; /* keep track of what is displayed */ LCD_row=LCD_entry % LCD_rows; /* find next available row */ LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; /* find next available column */ show_item=Show_No_Number; if (globals.ChannelState[chan].trigger_source==source_internal) { strcpy(a_string,"INT"); show_item=Show_frequency+chan; } else if (globals.ChannelState[chan].trigger_source==source_external) { strcpy(a_string,"EXT TRIG"); } else if (globals.ChannelState[chan].trigger_source==source_manual) { strcpy(a_string,"MAN TRIG"); } else if (globals.ChannelState[chan].trigger_source==source_hold) { strcpy(a_string,"HOLD TRIG"); } else if (globals.ChannelState[chan].trigger_source==source_immediate) { strcpy(a_string,"IMMED TRIG"); } if (globals.Flash.ChanKey_frequency) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } if (globals.ChannelState[chan].trigger_source==source_internal) { strcat(a_string,":"); } Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_freq) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig,LCD_col_width-1,LCD_string); } } /*----- display shape, if appropriate -----*/ for (chan=0; chan<(globals.Flash.ChanKey_func_mode?globals.Flash.channels:1); ++chan) { if (globals.Flash.is_func_gen[chan]) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_func+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_func+chan; /* keep track of what is displayed */ LCD_row=LCD_entry % LCD_rows; /* find next available row */ LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; /* find next available column */ show_item=Show_No_Number; if (globals.ChannelState[chan].func_mode==pulse_mode_on) { strcpy(a_string,"SHAPE:PULSE"); } else if (globals.ChannelState[chan].func_mode==sin_mode_on) { strcpy(a_string,"SHAPE:SINE"); } else if (globals.ChannelState[chan].func_mode==tri_mode_on) { strcpy(a_string,"SHAPE:TRI"); } else if (globals.ChannelState[chan].func_mode==squ_mode_on) { strcpy(a_string,"SHAPE:SQU"); } else if (globals.ChannelState[chan].func_mode==amp_mode_on) { strcpy(a_string,"SHAPE:AMP"); } if (globals.Flash.ChanKey_func_mode) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_func) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig,LCD_col_width-1,LCD_string); } } /*----- display delay, except for pwin=pwout and ext amplify modes -----*/ for (chan=0; chan<(globals.Flash.ChanKey_delay?globals.Flash.channels:1); ++chan) if ( (globals.ChannelState[chan].amp_mode!=amp_mode_amplify) && (globals.ChannelState[chan].ab_mode!=pw_in_out) && ((globals.ChannelState[chan].func_mode==pulse_mode_on) || (globals.ChannelState[chan].func_mode==dc_mode_on)) ) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_delay+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_delay+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; if (globals.ChannelState[chan].double_pulse==double_off) { strcpy(a_string,"DLY"); } else { strcpy(a_string,"DBL"); } if (globals.Flash.ChanKey_delay) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_delay) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,Show_delay+chan,sig_dig-globals.Flash.ChanKey_delay,LCD_col_width-1,LCD_string); } /*----- display pw, as appropriate -----*/ for (chan=0; chan<(globals.Flash.ChanKey_pw?globals.Flash.channels:1); ++chan) { if ( !globals.Flash.fixed_pw[chan] && (globals.ChannelState[chan].amp_mode!=amp_mode_amplify) && ((globals.ChannelState[chan].func_mode==pulse_mode_on) || (globals.ChannelState[chan].func_mode==dc_mode_on)) ) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_pw+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_pw+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_No_Number; if (globals.ChannelState[chan].func_mode==pulse_mode_on) { if (globals.ChannelState[chan].ab_mode==pw_normal) { if (globals.ChannelState[chan].hold_setting==hold_width) { show_item=Show_pw+chan; strcpy(a_string,"PW"); if (globals.Flash.ChanKey_pw) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); } else { show_item=Show_duty_cycle+chan; strcpy(a_string,"DUTY"); if (globals.Flash.ChanKey_pw) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); } } else { strcpy(a_string,"PW"); if (globals.Flash.ChanKey_pw) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string," IN=OUT"); } } else { strcpy(a_string,"PW"); if (globals.Flash.ChanKey_pw) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,": DC"); } Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_pw) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig-globals.Flash.ChanKey_pw,LCD_col_width-1,LCD_string); } } /*----- display rise_time, as appropriate -----*/ for (chan=0; chan<(globals.Flash.ChanKey_rise_time?globals.Flash.channels:1); ++chan) { if ( !globals.Flash.fixed_rise_time[chan] && (globals.ChannelState[chan].amp_mode!=amp_mode_amplify) && ((globals.ChannelState[chan].func_mode==pulse_mode_on) || (globals.ChannelState[chan].func_mode==dc_mode_on)) ) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_rise_time+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_rise_time+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_rise_time+chan; strcpy(a_string,"TR"); if (globals.Flash.ChanKey_rise_time) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_rise_time) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig-globals.Flash.ChanKey_rise_time,LCD_col_width-1,LCD_string); } } /*----- display amplitude, as appropriate -----*/ for (chan=0; chan<(globals.Flash.ChanKey_amplitude?globals.Flash.channels:1); ++chan) { if ((globals.Flash.voltage_enabled[chan] || globals.Flash.current_enabled[chan]) ) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_amp+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_amp+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_No_Number; if (globals.ChannelState[chan].amp_mode==amp_mode_normal) { show_item=Show_amplitude+chan; strcpy(a_string,"AMP"); if (globals.Flash.ChanKey_amplitude) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); } else if (globals.ChannelState[chan].amp_mode==amp_mode_ea) { strcpy(a_string,"AMP"); if (globals.Flash.ChanKey_amplitude) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":EXT"); } else if (globals.ChannelState[chan].amp_mode==amp_mode_amplify) { strcpy(a_string,"AMP"); if (globals.Flash.ChanKey_amplitude) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":AMPLFY"); } Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_amp) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig-globals.Flash.ChanKey_amplitude,LCD_col_width-1,LCD_string); } } /*----- display AVRQ extra amplitudes -----*/ if (globals.Flash.enable_avrq_extra_ampls) { for (chan=2; chan<5; ++chan) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_avrq+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_avrq+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_avrq_ampl+chan; strcpy(a_string,"AMP"); sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); strcat(a_string,":"); Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_amp) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig-1,LCD_col_width-1,LCD_string); } } /*----- display soft_current_limit, as appropriate -----*/ for (chan=0; chan<(globals.Flash.ChanKey_current_limit?globals.Flash.channels:1); ++chan) { if (globals.Flash.soft_current_limit_enabled[chan]) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_soft_current_limit+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_soft_current_limit+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_soft_current_limit+chan; strcpy(a_string,"LIM"); if (globals.Flash.ChanKey_current_limit) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_soft_current_limit) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig-globals.Flash.ChanKey_current_limit,LCD_col_width-1,LCD_string); } } /*----- display current slew, as appropriate -----*/ for (chan=0; chan<(globals.Flash.ChanKey_slew?globals.Flash.channels:1); ++chan) { if ( globals.Flash.curr_slew[chan] ) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_slew+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_slew+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_slew+chan; strcpy(a_string,"SL"); if (globals.Flash.ChanKey_slew) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_slew) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig-globals.Flash.ChanKey_slew,LCD_col_width-1,LCD_string); } } /*----- display burst count, as appropriate -----*/ for (chan=0; chan<(globals.Flash.ChanKey_Burst_Count?globals.Flash.channels:1); ++chan) { if (globals.Flash.max_burst_count[chan]>1) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_burst_count+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_burst_count+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_Burst_Count+chan; strcpy(a_string,"N"); if (globals.Flash.ChanKey_Burst_Count) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_burst_count) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,0,LCD_col_width-1,LCD_string); } } /*----- display burst timing, as appropriate -----*/ for (chan=0; chan<(globals.Flash.ChanKey_Burst_Time?globals.Flash.channels:1); ++chan) { if ((globals.Flash.max_burst_count[chan]>1) && !globals.Flash.burst_func[chan]) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_burst_time+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_burst_time+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_Burst_Time+chan; strcpy(a_string,"BUR"); if (globals.Flash.ChanKey_Burst_Time) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_burst_time) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig-globals.Flash.ChanKey_Burst_Time,LCD_col_width-1,LCD_string); } } /*----- display offset, as appropriate -----*/ for (chan=0; chan<(globals.Flash.ChanKey_offset?globals.Flash.channels:1); ++chan) { if ((globals.Flash.voltage_offset_enabled[chan] || globals.Flash.current_offset_enabled[chan]) && (globals.ChannelState[chan].amp_mode!=amp_mode_amplify)) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_offset+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_offset+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_No_Number; if (globals.ChannelState[chan].os_mode==os_mode_normal) { show_item=Show_offset+chan; strcpy(a_string,"OS"); if (globals.Flash.ChanKey_offset) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); } else { strcpy(a_string,"OS"); if (globals.Flash.ChanKey_offset) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":EXT"); } Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_os) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig-globals.Flash.ChanKey_offset,LCD_col_width-1,LCD_string); } } /*----- displayed monitor, as appropriate -----*/ for (chan=0; chan<(globals.Flash.ChanKey_Curr_Mon_value?globals.Flash.channels:1); ++chan) { if (globals.Flash.monitor_enabled[chan]) { ++LCD_entry; Main_Menu_Structure[LCD_entry]=Submenu1_mon+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; strcpy(a_string,"Mon"); if (globals.Flash.ChanKey_Curr_Mon_value) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry),LCD_row,LCD_col,a_string,Show_monitor+chan,sig_dig-globals.Flash.ChanKey_Curr_Mon_value,LCD_col_width-1,LCD_string); globals.ChannelState[chan].displayed_mon_val=globals.ChannelState[chan].Curr_Mon_value; } } /*----- display Zout, as appropriate -----*/ /* The Zout hardware and software is controlled by PW commands in the AVPP */ for (chan=0; chan<(globals.Flash.ChanKey_zout?globals.Flash.channels:1); ++chan) { if (globals.Flash.switchable_zout[chan] && !globals.Flash.volt_ctrl_pw[chan]) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_zout+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_zout+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; strcpy(a_string,"Zout"); if (globals.Flash.ChanKey_zout) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); if (globals.ChannelState[chan].zout==globals.Flash.zout_max[chan]) { sprintf(temp, "%d", globals.Flash.zout_max[chan]); strcat(a_string,temp); strcat(a_string,"\xf4 "); } else { sprintf(temp, "%d", globals.Flash.zout_min[chan]); strcat(a_string,temp); strcat(a_string,"\xf4 "); } Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_zout) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,Show_No_Number,sig_dig-globals.Flash.ChanKey_zout,LCD_col_width-1,LCD_string); } } /*----- display load type, as appropriate -----*/ for (chan=0; chan<(globals.Flash.ChanKey_load_type?globals.Flash.channels:1); ++chan) { if (globals.Flash.switchable_load[chan]) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_loadtype+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_loadtype+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_load_type+chan; strcpy(a_string,"Load"); if (globals.Flash.ChanKey_load_type) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_load) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig-globals.Flash.ChanKey_load_type,LCD_col_width-1,LCD_string); } } /*----- display output state, if used -----*/ if (globals.Flash.on_off_used) for (chan=0; chan<(globals.Flash.ChanKey_output_state?globals.Flash.channels:1); ++chan) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_output_state+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_output_state+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; strcpy(a_string,"Output"); if (globals.Flash.ChanKey_output_state) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); if (globals.ChannelState[chan].output_state==output_on) { strcat(a_string,"ON"); } else { strcat(a_string,"OFF"); } Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_output) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,Show_No_Number,sig_dig-globals.Flash.ChanKey_output_state,LCD_col_width-1,LCD_string); } /*----- display primary routing, as appropriate -----*/ for (chan=0; chan<(globals.Flash.ChanKey_route?globals.Flash.channels:1); ++chan) { if (globals.Flash.routing_required[chan] > 0) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_route_primary+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_route_primary+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_route_primary+chan; if (globals.Flash.routing_required[chan] == 1) { strcpy(a_string,"Route"); } else { strcpy(a_string,"ANOD"); } if (globals.Flash.ChanKey_route) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_routes) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,0,LCD_col_width-1,LCD_string); } } /*----- display secondary routing, as appropriate -----*/ for (chan=0; chan<(globals.Flash.ChanKey_route?globals.Flash.channels:1); ++chan) { if (globals.Flash.routing_required[chan] == 2) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_route_secondary+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_route_secondary+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_route_secondary+chan; strcpy(a_string,"CATH"); if (globals.Flash.ChanKey_route) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_routes) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,0,LCD_col_width-1,LCD_string); } } /*----- display inverted state, if allowed -----*/ for (chan=0; chan<(globals.Flash.ChanKey_polarity?globals.Flash.channels:1); ++chan) { if (globals.Flash.invert_allowed[chan]) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_invert+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_invert+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; strcpy(a_string,"INVERT"); if (globals.Flash.ChanKey_polarity) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); if (globals.ChannelState[chan].polarity==pol_norm) { strcat(a_string,"NO"); } else { strcat(a_string,"YES"); } Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_inv) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,Show_No_Number,sig_dig-globals.Flash.ChanKey_polarity,LCD_col_width-1,LCD_string); } } /*----- display logic level type, as appropriate -----*/ if (globals.Flash.logic_level_enabled) { for (chan=0; chan<(globals.Flash.ChanKey_logic_level?globals.Flash.channels:1); ++chan) { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_logic_level+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_logic_level+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; strcpy(a_string,"Logic"); if (globals.Flash.ChanKey_logic_level) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); if (globals.ChannelState[chan].logic_level==logic_ttl) { strcat(a_string,"TTL"); } else { strcat(a_string,"ECL"); } Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_logic_level) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,Show_No_Number,sig_dig-globals.Flash.ChanKey_logic_level,LCD_col_width-1,LCD_string); } } /*----- display gate type, except on func gens -----*/ for (chan=0; chan<((globals.Flash.ChanKey_gate_level|globals.Flash.ChanKey_gate_type)?globals.Flash.channels:1); ++chan) if (!globals.Flash.is_func_gen[chan]) { { ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_gate+chan) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_gate+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; strcpy(a_string,"GAT"); if (globals.Flash.ChanKey_gate_type || globals.Flash.ChanKey_gate_level) { sprintf(b_string, "%d", chan+1); strcat(a_string,b_string); } strcat(a_string,":"); if (globals.ChannelState[chan].gate_type==gate_sync && globals.ChannelState[chan].gate_level==gate_low) { strcat(a_string,"SYN,LO"); } else if (globals.ChannelState[chan].gate_type==gate_sync && globals.ChannelState[chan].gate_level==gate_high) { strcat(a_string,"SYN,HI"); } else if (globals.ChannelState[chan].gate_type==gate_async && globals.ChannelState[chan].gate_level==gate_low) { strcat(a_string,"ASY,LO"); } else { strcat(a_string,"ASY,HI"); } Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_gate) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,Show_No_Number, sig_dig-(globals.Flash.ChanKey_gate_level | globals.Flash.ChanKey_gate_type),LCD_col_width-1,LCD_string); } } /*----- display remote/local, always -----*/ ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_rem_loc) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_rem_loc; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; switch (globals.control_mode) { case LOCS_ctrl: strcpy(LCD_string,"LOCAL CTRL "); break; case LWLS_ctrl: strcpy(LCD_string,"LOCAL LOCK "); break; case REMS_ctrl: strcpy(LCD_string,"GPIB CTRL "); break; case RWLS_ctrl: strcpy(LCD_string,"GPIB LOCK "); break; case RS232_ctrl: strcpy(LCD_string,"RS232 CTRL "); break; case WEB_ctrl: strcpy(LCD_string,"WEB CTRL "); break; case TELNET_ctrl: strcpy(LCD_string,"TELNET CTRL "); break; } if (globals.Changes.update_whole_main_menu && Menu_Is_Item_Visible(LCD_entry)) { LCD_write(LCD_row,LCD_col,LCD_string); } /*----- display memory, always -----*/ ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_memory) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_memory; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; strcpy(LCD_string,"Memory menu "); if (globals.Changes.update_whole_main_menu && Menu_Is_Item_Visible(LCD_entry)) { LCD_write(LCD_row,LCD_col,LCD_string); } /*----- display setup, always -----*/ ++LCD_entry; if (Main_Menu_Structure[LCD_entry]!=Submenu1_setup) { globals.Changes.update_whole_main_menu=YES; } Main_Menu_Structure[LCD_entry]=Submenu1_setup; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; strcpy(LCD_string,"Setup menu "); if (globals.Changes.update_whole_main_menu && Menu_Is_Item_Visible(LCD_entry)) { LCD_write(LCD_row,LCD_col,LCD_string); } /*----- display the pointer -----*/ Menu_Move_Pointer(0); /* display pointer, but don't move it */ if (old_cursor_pos!=menu_cursor_pos) { LCD_row=(old_cursor_pos % LCD_max_entries_per_page) % LCD_rows; LCD_col=((old_cursor_pos % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width; LCD_write(LCD_row,LCD_col," "); } /*----- finish up -----*/ Main_Menu_max_entry=LCD_entry; /* record number of menu items */ if (Main_Menu_max_entry>=LCD_max_entries_per_page) { LCD_write(3,39,">"); } else { LCD_write(3,39," "); } if ((Main_Menu_max_entry/LCD_max_entries_per_page)==(menu_cursor_pos/LCD_max_entries_per_page)) for (i=(Main_Menu_max_entry%LCD_max_entries_per_page)+ 1; i<12; ++i) { LCD_row=i % LCD_rows; LCD_col=(i / LCD_rows) * LCD_col_width + 1; /*1234567890123*/ LCD_write(LCD_row,LCD_col," "); } globals.Changes.update_whole_main_menu=NO; } static void Menu_Move_Pointer(int move_amount) { int LCD_row,LCD_col; int old_page,new_page; /* find the menu index where the selected item is */ for (menu_cursor_pos=0; ((globals.MenuStatus.Selected_Submenu!=Main_Menu_Structure[menu_cursor_pos]) && (menu_cursor_pos < LCD_max_entries)); ++menu_cursor_pos) { ; } if (menu_cursor_pos==LCD_max_entries) { menu_cursor_pos=0; } /* this occurs when submenus not listed on the main menu are selected, like load/save */ old_page=menu_cursor_pos / LCD_max_entries_per_page; /* use the menu index to find where the cursor is currently pointing, and erase it */ if (move_amount) { LCD_row=menu_cursor_pos % LCD_rows; LCD_col=((menu_cursor_pos % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width; LCD_write(LCD_row,LCD_col," "); /* erase pointer */ /* move the pointer, with wrap-around to zero */ menu_cursor_pos += move_amount; if (menu_cursor_pos > Main_Menu_max_entry) { menu_cursor_pos=0; } if (menu_cursor_pos < 0) { menu_cursor_pos=Main_Menu_max_entry; } } /* update the selected menu item */ globals.MenuStatus.Selected_Submenu=Main_Menu_Structure[menu_cursor_pos]; /* draw the pointer at the new location */ LCD_row=menu_cursor_pos % LCD_rows; LCD_col=((menu_cursor_pos % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width; LCD_write(LCD_row,LCD_col,"~"); /* "~" equals "->" on LCD */ new_page=menu_cursor_pos / LCD_max_entries_per_page; if (new_page!=old_page) { globals.Changes.update_whole_main_menu=YES; LCD_clear(); Menu_Update_Display(); } } static void Display_Number_on_LCD(int Is_Item_Visible,int LCD_row,int LCD_col,char *start_string,int Show_What, int significant_digits, int width_of_column,char *LCD_string) { char units[10]; int show_plus_sign; int i; int channel; LCD_string[0]=0; channel=Show_What%100; if (Show_What!=Show_No_Number) { switch (Show_What-channel) { case Show_frequency: Submenu_Value=globals.ChannelState[channel].frequency; strcpy(units,"Hz"); show_plus_sign=NO; break; case Show_delay: Submenu_Value=globals.ChannelState[channel].delay; strcpy(units,"s"); show_plus_sign=YES; break; case Show_pw: Submenu_Value=globals.ChannelState[channel].pw; strcpy(units,"s"); show_plus_sign=NO; break; case Show_amplitude: Submenu_Value=globals.ChannelState[channel].amplitude; show_plus_sign=YES; if (globals.Flash.voltage_enabled[channel]) { strcpy(units,"V"); } else { strcpy(units,"A"); } break; case Show_avrq_ampl: switch (channel) { case 2: Submenu_Value=globals.ChannelState[0].vcc1; break; case 3: Submenu_Value=globals.ChannelState[0].vcc2; break; case 4: Submenu_Value=globals.ChannelState[0].vlogic; break; } show_plus_sign=YES; strcpy(units,"V"); break; case Show_offset: Submenu_Value=globals.ChannelState[channel].offset; show_plus_sign=YES; if (globals.Flash.voltage_offset_enabled[channel]) { strcpy(units,"V"); } else { strcpy(units,"A"); } break; case Show_monitor: Submenu_Value=globals.ChannelState[channel].Curr_Mon_value; show_plus_sign=YES; if (globals.ChannelState[channel].pw0) { LCD_write(0,19,"Mode:"); for (i=0; i<=Submenu_max_entry; ++i) { switch (Submenu_Structure[i]-channel) { case mode_freq_int: strcpy(mode_name[i],"Internal"); if (globals.ChannelState[channel].trigger_source==source_internal) { current_operating_mode=i; } break; case mode_freq_ext: strcpy(mode_name[i],"External"); if (globals.ChannelState[channel].trigger_source==source_external) { current_operating_mode=i; } break; case mode_freq_man: strcpy(mode_name[i],"Manual"); if (globals.ChannelState[channel].trigger_source==source_manual) { current_operating_mode=i; } break; case mode_freq_hold: strcpy(mode_name[i],"Hold"); if (globals.ChannelState[channel].trigger_source==source_hold) { current_operating_mode=i; } break; case mode_func_sin: strcpy(mode_name[i],"Sine"); if (globals.ChannelState[channel].func_mode==sin_mode_on) { current_operating_mode=i; } break; case mode_func_tri: strcpy(mode_name[i],"Triangle"); if (globals.ChannelState[channel].func_mode==tri_mode_on) { current_operating_mode=i; } break; case mode_func_squ: strcpy(mode_name[i],"Square"); if (globals.ChannelState[channel].func_mode==squ_mode_on) { current_operating_mode=i; } break; case mode_func_pulse: strcpy(mode_name[i],"Pulse"); if (globals.ChannelState[channel].func_mode==pulse_mode_on) { current_operating_mode=i; } break; case mode_func_amp: strcpy(mode_name[i],"Amplify"); if (globals.ChannelState[channel].func_mode==amp_mode_on) { current_operating_mode=i; } break; case mode_delay_norm: strcpy(mode_name[i],"Normal"); if (globals.ChannelState[channel].double_pulse==double_off) { current_operating_mode=i; } break; case mode_delay_dbl: strcpy(mode_name[i],"Double Pulse"); if (globals.ChannelState[channel].double_pulse==double_on) { current_operating_mode=i; } break; case mode_pw_norm: strcpy(mode_name[i],"Normal"); if (globals.ChannelState[channel].func_mode==pulse_mode_on && globals.ChannelState[channel].hold_setting==hold_width && globals.ChannelState[channel].ab_mode==pw_normal) { current_operating_mode=i; } break; case mode_pw_duty: strcpy(mode_name[i],"Duty Cycle"); if (globals.ChannelState[channel].func_mode==pulse_mode_on && globals.ChannelState[channel].hold_setting==hold_duty && globals.ChannelState[channel].ab_mode==pw_normal) { current_operating_mode=i; } break; case mode_pw_inout: strcpy(mode_name[i],"PWin=PWout"); if (globals.ChannelState[channel].func_mode==pulse_mode_on && globals.ChannelState[channel].ab_mode==pw_in_out) { current_operating_mode=i; } break; case mode_pw_dc: strcpy(mode_name[i],"DC output"); if (globals.ChannelState[channel].func_mode==dc_mode_on) { current_operating_mode=i; } break; case mode_output_on: strcpy(mode_name[i],"Output On"); if (globals.ChannelState[channel].output_state==output_on) { current_operating_mode=i; } break; case mode_output_off: strcpy(mode_name[i],"Output Off"); if (globals.ChannelState[channel].output_state==output_off) { current_operating_mode=i; } break; case mode_go_to_local: strcpy(mode_name[i],"Go To Local"); break; case mode_inv_no: strcpy(mode_name[i],"NO (normal)"); if (globals.ChannelState[channel].polarity==pol_norm) { current_operating_mode=i; } break; case mode_inv_yes: strcpy(mode_name[i],"YES (inverted)"); if (globals.ChannelState[channel].polarity==pol_complement) { current_operating_mode=i; } break; case mode_gate_losync: strcpy(mode_name[i],"Sync,TTL-low"); if (globals.ChannelState[channel].gate_type==gate_sync && globals.ChannelState[channel].gate_level==gate_low) { current_operating_mode=i; } break; case mode_gate_hisync: strcpy(mode_name[i],"Sync,TTL-hi"); if (globals.ChannelState[channel].gate_type==gate_sync && globals.ChannelState[channel].gate_level==gate_high) { current_operating_mode=i; } break; case mode_gate_loasync: strcpy(mode_name[i],"Async,TTL-low"); if (globals.ChannelState[channel].gate_type==gate_async && globals.ChannelState[channel].gate_level==gate_low) { current_operating_mode=i; } break; case mode_gate_hiasync: strcpy(mode_name[i],"Async,TTL-hi"); if (globals.ChannelState[channel].gate_type==gate_async && globals.ChannelState[channel].gate_level==gate_high) { current_operating_mode=i; } break; case mode_gpib_address: strcpy(mode_name[i],"GPIB address"); break; case mode_rs232_settings: strcpy(mode_name[i],"RS232 setup"); break; case mode_model_info: strcpy(mode_name[i],"Model info"); break; case mode_network: strcpy(mode_name[i],"Network info"); break; case mode_password: strcpy(mode_name[i],"Pwd~default"); break; case mode_selfcal: strcpy(mode_name[i],"Self Cal"); break; case mode_exit_normal_submenu: strcpy(mode_name[i],"Exit"); break; case mode_load: strcpy(mode_name[i],"Load Settings"); break; case mode_save: strcpy(mode_name[i],"Save Settings"); break; case mode_load_0: strcpy(mode_name[i],"Storage 0"); break; case mode_load_1: strcpy(mode_name[i],"Storage 1"); break; case mode_load_2: strcpy(mode_name[i],"Storage 2"); break; case mode_load_3: strcpy(mode_name[i],"Storage 3"); break; case mode_save_0: strcpy(mode_name[i],"Storage 0"); break; case mode_save_1: strcpy(mode_name[i],"Storage 1"); break; case mode_save_2: strcpy(mode_name[i],"Storage 2"); break; case mode_save_3: strcpy(mode_name[i],"Storage 3"); break; case mode_change_rs232: strcpy(mode_name[i],"Change values"); break; case mode_default_rs232: strcpy(mode_name[i],"Default"); break; case mode_exit_rs232: strcpy(mode_name[i],"Exit"); break; case mode_zout_max: strcpy(mode_name[i],"Zout = "); sprintf(temp, "%d", globals.Flash.zout_max[channel]); strcat(mode_name[i],temp); strcat(mode_name[i],"\xf4"); if (globals.ChannelState[channel].zout==globals.Flash.zout_max[channel]) { current_operating_mode=i; } break; case mode_zout_min: strcpy(mode_name[i],"Zout = "); sprintf(temp, "%d", globals.Flash.zout_min[channel]); strcat(mode_name[i],temp); strcat(mode_name[i],"\xf4"); if (globals.ChannelState[channel].zout==globals.Flash.zout_min[channel]) { current_operating_mode=i; } break; case mode_logic_ttl: strcpy(mode_name[i],"TTL levels"); if (globals.ChannelState[channel].logic_level==logic_ttl) { current_operating_mode=i; } break; case mode_logic_ecl: strcpy(mode_name[i],"ECL levels"); if (globals.ChannelState[channel].logic_level==logic_ecl) { current_operating_mode=i; } break; case mode_amp_normal: strcpy(mode_name[i],"Normal"); if (globals.ChannelState[channel].amp_mode==amp_mode_normal) { current_operating_mode=i; } break; case mode_amp_ea: strcpy(mode_name[i],"Ext Control"); if (globals.ChannelState[channel].amp_mode==amp_mode_ea) { current_operating_mode=i; } break; case mode_amp_amplify: strcpy(mode_name[i],"Ext Amplify"); if (globals.ChannelState[channel].amp_mode==amp_mode_amplify) { current_operating_mode=i; } break; case mode_os_normal: strcpy(mode_name[i],"Normal"); if (globals.ChannelState[channel].os_mode==os_mode_normal) { current_operating_mode=i; } break; case mode_os_eo: strcpy(mode_name[i],"Ext Control"); if (globals.ChannelState[channel].os_mode==os_mode_eo) { current_operating_mode=i; } break; case mode_amp_min: if (globals.Flash.voltage_enabled[channel]) { String_Parameter_To_Text(globals.Flash.min_ampl[channel],0,2,"","V",mode_name[i],YES); } else { String_Parameter_To_Text(globals.Flash.min_ampl[channel],0,2,"","A",mode_name[i],YES); } if (fabs(globals.ChannelState[channel].amplitude-globals.Flash.min_ampl[channel])=4) { base_entry=Submenu_Selected_Item-3; } for (i=base_entry; ( (i<=Submenu_max_entry) && (i< (base_entry+4)) ); ++i) { add_spaces=LCD_col_width-strlen(mode_name[i]); for (j=0; j0) { LCD_write(Submenu_Selected_Item-base_entry,25," "); ++Submenu_Selected_Item; if (Submenu_Selected_Item>Submenu_max_entry) { Submenu_Selected_Item=0; } Submenu_Display(YES); } } static int Submenu_Mult_Value(float mult_by) { int error_num; int channel; char LCD_string[LCD_cols+1]; float new_value; error_num=OK; /* return if the encoder is not useful for the displayed parameter */ if (Submenu_Numeric_Parameter==Show_No_Number) { return OK; } channel=Submenu_Numeric_Parameter%100; new_value = Submenu_Value * mult_by; switch (Submenu_Numeric_Parameter-channel) { case Show_frequency: if (error_num=Set_frequency(0,0,0,channel,new_value)) { Submenu_Value=new_value; } break; case Show_delay: if (fabs(new_value)1.0) { if (new_value<0.0) { new_value=-zero_equiv_timing; } else { new_value=zero_equiv_timing; } } if (fabs(new_value) < zero_equiv_timing) if (new_value<0.0) { new_value=-smallest_allowed_number; } else { new_value=smallest_allowed_number; } if (error_num=Set_Delay(0,0,0,channel,new_value)) { Submenu_Value=new_value; } break; case Show_pw: if (fabs(new_value)1.0) { if (new_value<0.0) { new_value=-zero_equiv_timing; } else { new_value=zero_equiv_timing; } } if (fabs(new_value) < zero_equiv_timing) if (new_value<0.0) { new_value=-smallest_allowed_number; } else { new_value=smallest_allowed_number; } if (error_num=Set_Pw(0,0,0,channel,new_value,0)) { Submenu_Value=new_value; } break; case Show_amplitude: if (fabs(new_value)1.0) { if (new_value<0.0 || globals.Flash.max_ampl[channel]1.0) { new_value=AVRQ_ZERO_EQUIV; } else if (fabs(new_value) < AVRQ_ZERO_EQUIV) { new_value=smallest_allowed_number; } if (channel == 4) { /* vlogic */ if (mult_by > 1.0) { new_value = globals.ChannelState[0].vcc1; } else { new_value = 0.0; } } if (error_num=Set_Amplitude(0,0,0,0,0,0,channel,new_value,0)) { Submenu_Value=new_value; } break; case Show_Burst_Time: if (error_num=Set_Burst_Time(0,0,0,channel,new_value)) { Submenu_Value=new_value; } break; case Show_rise_time: if (error_num=Set_rise_time(0,0,0,channel,new_value)) { Submenu_Value=new_value; } break; case Show_slew: if (error_num=Set_slew(0,0,0,channel,new_value)) { Submenu_Value=new_value; } break; case Show_load_type: if (error_num=Set_Load(channel,new_value)) { Submenu_Value=new_value; } break; case Show_soft_current_limit: if (error_num=Set_current_limit(0,channel,new_value)) { Submenu_Value=new_value; } break; case Show_offset: if (fabs(new_value)1.0) { if (new_value<0.0 || globals.Flash.max_offset[channel]1) { Menu_Move_Pointer(1); } else if (encoder_change<-1) { Menu_Move_Pointer(-1); } g_usleep(2e5); return; } /* increase increments for rapid rotation */ encoder_timer_change[2] = encoder_timer_change[1]; encoder_timer_change[1] = encoder_timer_change[0]; encoder_timer_change[0] = ms_timer() - encoder_last_adjust; encoder_last_adjust = ms_timer(); if (encoder_timer_change[0]<0) { encoder_timer_change[0]=1000; } if ( (encoder_timer_change[0] < 50) && (encoder_timer_change[1] < 50) && (encoder_timer_change[2] < 50) && (Submenu_extra_fine==NO) ) { ++encoder_mult; if (encoder_mult>8) { encoder_mult=8; } encoder_change *= encoder_mult; } else { encoder_mult=1; } /* make changes minimal if last adjustment caused an error */ if (last_encoder_adjust_error != OK) { if (encoder_change>0) { encoder_change=1; } else { encoder_change=-1; } } channel=Submenu_Numeric_Parameter%100; /* return if the encoder is not useful for the displayed parameter */ if ((Submenu_Numeric_Parameter-channel)==Show_No_Number || (Submenu_Numeric_Parameter-channel)==Show_monitor) { return; } if (Submenu_Value<0) { abs_Submenu_Value=-Submenu_Value; } else { abs_Submenu_Value=Submenu_Value; } /* deal with special integer parameters first */ if ((Submenu_Numeric_Parameter-channel) == Show_gpib_address) { g_usleep (2e5); reset_encoder=YES; /* to avoid extra unwanted increments */ if (encoder_change>0) { new_int_value=(int) (Submenu_Value + 1.0); if (new_int_value>30) { new_int_value=0; } } else { new_int_value=(int) (Submenu_Value - 1.0); if (new_int_value<0) { new_int_value=30; } } } if ((Submenu_Numeric_Parameter-channel) == Show_Burst_Count) { g_usleep (2e5); reset_encoder=YES; /* to avoid extra unwanted increments */ new_int_value=(int) (Submenu_Value); if (encoder_change>0) { ++new_int_value; } else { --new_int_value; } if (new_int_value>globals.Constraints.err_max_burst_count[channel]) { if (globals.Flash.burst_func[channel]) { new_int_value=0; } else { new_int_value=1; } } else if ( (new_int_value<1 && !globals.Flash.burst_func[channel]) || (new_int_value<0 && globals.Flash.burst_func[channel])) { new_int_value=globals.Constraints.err_max_burst_count[channel]; } } else if ( ((Submenu_Numeric_Parameter-channel) == Show_route_primary) || ((Submenu_Numeric_Parameter-channel) == Show_route_secondary) ) { g_usleep (2e5); reset_encoder=YES; /* to avoid extra unwanted increments */ new_int_value=(int) (Submenu_Value); if (encoder_change>0) { ++new_int_value; } else { --new_int_value; } if (new_int_value>globals.Flash.routing_max_pins[channel]) { new_int_value=1; } if (new_int_value<1) { new_int_value=globals.Flash.routing_max_pins[channel]; } } else { /* deal with normal floating point parameters */ /* if the value is zero, substitute small value */ if (abs_Submenu_Value 0) { Submenu_Value = abs_Submenu_Value = globals.ChannelState[0].vcc1; encoder_change = 0; } else { Submenu_Value = abs_Submenu_Value = 0.0; encoder_change = 0; } } } else if ((channel10000) { equivalent_integer=10100; } /* get first digit of new number */ new_string[0]=' '; sprintf(new_string+1, "%d", equivalent_integer); /* put in sign if required */ if (Submenu_Value<0) { new_string[0]='-'; } sprintf(new_string+2, "%d", equivalent_integer); new_string[2]='.'; /* finish by adding exponent*/ strcat(new_string,expon); new_value=atof(new_string); if (equivalent_integer>9999) { new_value*=10; } if (equivalent_integer<1000) { new_value/=10; } } /* update display - correct later if required */ Display_Number_on_LCD(YES,1,2,"",Submenu_Numeric_Parameter,4,LCD_col_width,LCD_string); switch ((Submenu_Numeric_Parameter-channel)) { case Show_frequency: if (globals.Flash.min_freq[channel]==globals.Flash.max_freq[channel]) { return; } if (error_num=Set_frequency(0,0,0,channel,new_value)) { Submenu_Value=new_value; } break; case Show_delay: /* If the new value is less than the zero_equiv_value, but the original was not, set the new value to the smallest allowed number with the same polarity (zero, basically) */ if ( (fabs(new_value) < zero_equiv_timing) && (abs_Submenu_Value > zero_equiv_timing)) { if (Submenu_Value<0.0) { new_value=-smallest_allowed_number; } else { new_value=smallest_allowed_number; } } /* If the new value is less than the zero_equiv_value, and so was the original, flip the polarity (i.e., cross zero) */ if ( (fabs(new_value) < zero_equiv_timing) && (abs_Submenu_Value = zero_equiv_timing)) { if (Submenu_Value<0.0) { new_value=zero_equiv_timing; } else { new_value=-zero_equiv_timing; } } if (error_num=Set_Delay(0,0,0,channel,new_value)) { Submenu_Value=new_value; } break; case Show_pw: if (globals.Flash.min_pw[channel]==globals.Flash.max_pw[channel]) { return; } /* If the new value is less than the zero_equiv_value, but the original was not, set the new value to the smallest allowed number with the same polarity (zero, basically) */ if ( (fabs(new_value) < zero_equiv_timing) && (abs_Submenu_Value > zero_equiv_timing)) { if (Submenu_Value<0.0) { new_value=-smallest_allowed_number; } else { new_value=smallest_allowed_number; } } /* If the new value is less than the zero_equiv_value, and so was the original, flip the polarity (i.e., cross zero) */ if ( (fabs(new_value) < zero_equiv_timing) && (abs_Submenu_Value = zero_equiv_timing)) { if (Submenu_Value<0.0) { new_value=zero_equiv_timing; } else { new_value=-zero_equiv_timing; } } if (error_num=Set_Pw(0,0,0,channel,new_value,0)) { Submenu_Value=new_value; } break; case Show_Burst_Time: if (error_num=Set_Burst_Time(0,0,0,channel,new_value)) { Submenu_Value=new_value; } break; case Show_rise_time: if (error_num=Set_rise_time(0,0,0,channel,new_value)) { Submenu_Value=new_value; } break; case Show_slew: if (error_num=Set_slew(0,0,0,channel,new_value)) { Submenu_Value=new_value; } break; case Show_load_type: if (error_num=Set_Load(channel,new_value)) { Submenu_Value=new_value; } break; case Show_soft_current_limit: if (error_num=Set_current_limit(0,channel,new_value)) { Submenu_Value=new_value; } break; case Show_amplitude: if (globals.Flash.min_ampl[channel]==globals.Flash.max_ampl[channel]) { return; } if (fabs(new_value) < globals.Flash.ampl_zero_equiv[channel]) if (Submenu_Value<0.0) { new_value=-smallest_allowed_number; } else { new_value=smallest_allowed_number; } if (globals.Flash.ampl_min_max_only[channel]) { /* not used for two-state amplitudes */ return; } /* For units with large amplitude step sizes (AVRQ-2-B-PN-EVE) */ if (globals.Flash.ampl_step_size[channel] > 0.0) { if (new_value < globals.ChannelState[channel].amplitude) { new_value = globals.ChannelState[channel].amplitude - globals.Flash.ampl_step_size[channel]; } else { new_value = globals.ChannelState[channel].amplitude + globals.Flash.ampl_step_size[channel]; } } if (error_num=Set_Amplitude(0,0,0,0,0,0,channel,new_value,0)) { Submenu_Value=new_value; } break; case Show_avrq_ampl: if (new_value < AVRQ_ZERO_EQUIV) { new_value=0.0; } if (error_num=Set_Amplitude(0,0,0,0,0,0,channel,new_value,0)) { Submenu_Value=new_value; } break; case Show_offset: if (globals.Flash.min_offset[channel]==globals.Flash.max_offset[channel]) { return; } if (fabs(new_value) < globals.Flash.ampl_zero_equiv[channel]) if (Submenu_Value<0.0) { new_value=-smallest_allowed_number; } else { new_value=smallest_allowed_number; } if (error_num=Set_Offset(0,0,0,0,channel,new_value)) { Submenu_Value=new_value; } break; case Show_duty_cycle: if (error_num=Set_Pw(0,0,0,channel,new_value/(100*globals.ChannelState[channel].frequency),0)) { Submenu_Value=new_value; } break; case Show_gpib_address: GPIB_change_address(new_int_value); error_num=OK; break; case Show_Burst_Count: if (error_num=Set_Burst_Count(channel,new_int_value,globals.ChannelState[channel].burst_time)) { Submenu_Value=new_value; } break; case Show_route_primary: if (error_num=Set_Route(channel,ROUTE_PRIMARY,new_int_value)) { Submenu_Value=new_value; } break; case Show_route_secondary: if (error_num=Set_Route(channel,ROUTE_SECONDARY,new_int_value)) { Submenu_Value=new_value; } break; } Main_update_shift_registers(); Display_Number_on_LCD(YES,1,2,"",Submenu_Numeric_Parameter,4,LCD_col_width,LCD_string); queue_error_and_display_on_LCD(error_num); last_encoder_adjust_error=error_num; if (reset_encoder) { Menu_Clear_Buttons(); } return; } static void Nonstd_menu_default_rs232(void) { Menu_Clear_Buttons(); LCD_clear(); /*0123456789012345678901234567890123456789*/ LCD_write(0,0,"The RS232 settings are now: 1200 baud, "); LCD_write(1,0,"8 data bits, no parity, 1 stop bit,"); LCD_write(2,0,"hardware handshaking on, and echo on."); LCD_write(3,0,Press_Change_Message); globals.RS232.baud = rs232_1200_baud; globals.RS232.parity = rs232_parity_none; globals.RS232.stopbits = rs232_1stop_bit; globals.RS232.databits = rs232_8data_bits; globals.RS232.hardhand = rs232_hard_on; globals.RS232.echo = rs232_echo_on; IO_Setup_RS232(); Menu_Clear_Buttons(); globals.MenuStatus.Nonstd_Display=YES; } static void Nonstd_menu_model_info(void) { // FIXME - better string handling char response[LCD_cols+1]; int i; char model[32]; char serial_num[16]; LCD_clear(); i=-1; do { ++i; model[i] = toupper(globals.Flash.model_num[i]); } while (model[i]); i=-1; do { ++i; serial_num[i] = toupper(globals.Flash.serial_num[i]); } while (serial_num[i]); /*0123456789012345678901234567890123456789*/ LCD_write(0,0,"Avtech Electrosystems Ltd. - since 1975"); LCD_write(1,0,"Visit us at www.avtechpulse.com!"); LCD_write(2,0,"Model: "); LCD_write(2,7,model); strcpy(response,"SN:"); strcat(response,serial_num); strcat(response,","); strcat(response,FW_VERSION); LCD_write(3,0,response); LCD_write(3,27,"Press CHANGE."); globals.MenuStatus.Nonstd_Display=YES; } void Menu_Clear_Buttons(void) { int dummy1,dummy2,dummy3; /* enable interrupt lines */ Read_Keypad(&dummy1,&dummy2,&dummy3); } /*** BeginHeader Read_Keypad */ int Read_Keypad(int *button_port_val, int *upper_encoder_val, int *lower_encoder_val); /*** EndHeader */ /*----------------------------------------------------------------------------------------------------------*/ int Read_Keypad(int *button_port_val, int *upper_encoder_val, int *lower_encoder_val) { #define Overload_Input 64 /* mask for main overload input */ #define Over_Temp 0x10 /* over-temperature */ #define Over_Volt 0x20 /* over-voltage */ #define Over_Other 0x40 /* over-other */ int new_button_state; int chan; int outputs_turned_off; /* read the button data */ new_button_state = I2C_Read(PCF8574A+Button_Press_Port); /* invert bit 6 (of 0-7) = overload */ if ( (new_button_state & 0x40) == 0x40) { /* if high, set low */ new_button_state = new_button_state & (0xff - 0x40); } else { /* if low, set high */ new_button_state = new_button_state | 0x40; } /* ignore bit 7 (of 0-7) */ new_button_state = new_button_state & 0x7f; /* a button_port_val bit goes low if: The corresponding last_button_state was low (inactive) and The corresponding new_button_state is high (pressed) */ *button_port_val = ~ ((~last_button_state) & (new_button_state)); last_button_state = new_button_state; /* read the encoder data */ *upper_encoder_val = I2C_Read(PCF8574A+Upper_Encoder_Port); /* lowering the button clear line disables encoder counting */ I2C_Write(PCF8574A+Button_Press_Port,127); *lower_encoder_val = I2C_Read(PCF8574A+Lower_Encoder_Port); /* reenable encoder */ I2C_Write(PCF8574A+Button_Press_Port,255); /* reset encoder-monitoring by presetting counters to mid range */ I2C_Write(PCF8574A+Upper_Encoder_Port,127); I2C_Write(PCF8574A+Upper_Encoder_Port,255); /* alarm condition */ /* valid for both local and remote modes */ if ( !(*upper_encoder_val & Over_Temp) || !(*upper_encoder_val & Over_Volt) || !(*upper_encoder_val & Over_Other) || !(*button_port_val & Overload_Input) ) { /* disable all outputs immediately */ outputs_turned_off = 0; if (globals.Flash.on_off_used) { for (chan=0; chan<(globals.Flash.ChanKey_output_state?globals.Flash.channels:1); ++chan) { if (globals.ChannelState[chan].output_state == output_on) { ++outputs_turned_off; Set_Output_State(chan,output_off); } } } /* Report the problem if outputs had to be turned off. */ if ((outputs_turned_off > 0) || globals.Flash.warn_even_if_output_off) { /* flag the problem */ if (!(*upper_encoder_val & Over_Temp)) { queue_and_broadcast_sensor_alarm(Overtemp_Detected); } else if (!(*upper_encoder_val & Over_Volt)) { queue_and_broadcast_sensor_alarm(Overvolt_Detected); } else if (!(*upper_encoder_val & Over_Other)) { queue_and_broadcast_sensor_alarm(Device_Specific_Aux_Error_Detected); } else if (!(*button_port_val & Overload_Input)) { queue_and_broadcast_sensor_alarm(Overload_Detected); } } } } static void Menu_Check_Buttons(void) { int error_num; int button_port_val; int upper_encoder_val; int lower_encoder_val; int encoder_change; int chan; /* get keypad state */ Read_Keypad(&button_port_val,&upper_encoder_val,&lower_encoder_val); encoder_change=lower_encoder_val; /* handle negative changes */ if (encoder_change & 0x80) { encoder_change = encoder_change - 0x100; } if (!(button_port_val & Change_Button)) { /* ----- CHANGE BUTTON --------- */ if ( globals.control_mode==LOCS_ctrl || globals.control_mode==LWLS_ctrl || ( ( globals.control_mode==REMS_ctrl || globals.control_mode==RS232_ctrl || globals.control_mode==WEB_ctrl || globals.control_mode==TELNET_ctrl) && globals.MenuStatus.Selected_Submenu==Submenu1_rem_loc ) ) { if ((globals.MenuStatus.Type_Of_Menu==Main_Menu_On && globals.MenuStatus.Error_Screen==YES) || globals.MenuStatus.Nonstd_Display==YES) { Menu_Update_Display(); } else if (globals.MenuStatus.Type_Of_Menu==Submenu_On && globals.MenuStatus.Error_Screen==YES) { Submenu_Display(NO); } else if (globals.MenuStatus.Type_Of_Menu==Main_Menu_On && globals.MenuStatus.Error_Screen==NO) { Submenu_Display(NO); } else if (globals.MenuStatus.Type_Of_Menu==Submenu_On && globals.MenuStatus.Error_Screen==NO) { if (error_num=Submenu_Implement_Changes()) { queue_error_and_display_on_LCD(error_num); } } } } else if (!(button_port_val & Move_Button)) { /* ----- MOVE BUTTON ----------- */ /* MOVE button hit, move pointer */ if (globals.MenuStatus.Type_Of_Menu==Main_Menu_On && globals.MenuStatus.Nonstd_Display==NO && globals.MenuStatus.Error_Screen==NO) { Menu_Move_Pointer(1); } else if (globals.MenuStatus.Type_Of_Menu==Submenu_On && globals.MenuStatus.Nonstd_Display==NO && globals.MenuStatus.Error_Screen==NO) { Submenu_Move_Pointer(); } } else if (!(button_port_val & Mult10_Button)) { /* ----- X10 BUTTON ------------ */ if (globals.MenuStatus.Type_Of_Menu==Submenu_On && (globals.control_mode==LOCS_ctrl || globals.control_mode==LWLS_ctrl)) { if (globals.MenuStatus.Error_Screen==YES) { Submenu_Display(NO); } queue_error_and_display_on_LCD(Submenu_Mult_Value(10.0)); } } else if (!(button_port_val & Div10_Button)) { /* ----- /10 BUTTON ------------ */ if (globals.MenuStatus.Type_Of_Menu==Submenu_On && (globals.control_mode==LOCS_ctrl || globals.control_mode==LWLS_ctrl)) { if (globals.MenuStatus.Error_Screen==YES) { Submenu_Display(NO); } queue_error_and_display_on_LCD(Submenu_Mult_Value(0.1)); } } else if (!(button_port_val & Plus_Minus_Button)) { /* ----- +/- BUTTON ------------ */ if (globals.MenuStatus.Type_Of_Menu==Submenu_On && (globals.control_mode==LOCS_ctrl || globals.control_mode==LWLS_ctrl)) { if (globals.MenuStatus.Error_Screen==YES) { Submenu_Display(NO); } queue_error_and_display_on_LCD(Submenu_Mult_Value(-1.0)); } } else if (!(button_port_val & Extra_Fine_Button)) { /* ----- EXTRA FINE BUTTON ----- */ if (globals.MenuStatus.Type_Of_Menu==Submenu_On && globals.MenuStatus.Nonstd_Display==NO && globals.MenuStatus.Error_Screen==NO && (globals.control_mode==LOCS_ctrl || globals.control_mode==LWLS_ctrl)) { if (Submenu_extra_fine==YES) { g_usleep (250e3); Submenu_extra_fine=NO; LCD_write(2,2," "); } else { g_usleep (250e3); Submenu_extra_fine=YES; LCD_write(2,2,"(extra fine adjust)"); } } } /* if none of the buttons are pressed, it must be the encoder */ else if (encoder_change) { /* ----- ENCODER --------------- */ /* ignore if the overload error screen is displayed */ if (!(globals.MenuStatus.Error_Screen==YES && globals.MenuStatus.Type_Of_Menu==Main_Menu_On)) { if (globals.MenuStatus.Error_Screen==YES && globals.MenuStatus.Type_Of_Menu==Submenu_On) { Submenu_Display(NO); } Submenu_Service_Encoder(encoder_change); } } } static int Submenu_Implement_Changes(void) { int error_num; int call_new_submenu; int check_valid; int channel,eprom_loc; call_new_submenu=NO; /* this routine changes the pulse generator parameters, as chosen by the submenu settings */ if (Submenu_max_entry==0) { Menu_Update_Display(); return OK; } /* Cases that involve third-level and greater menu must indicate what menu to return to, e.g */ /* globals.MenuStatus.Selected_Submenu=Submenu1_setup after finishing the default RS232 case. */ channel=Submenu_Structure[Submenu_Selected_Item]%100; switch (Submenu_Structure[Submenu_Selected_Item]-channel) { case mode_freq_int: if (globals.ChannelState[channel].trigger_source!=source_internal) { if (error_num=Set_Trig_Source(channel,source_internal)) { return error_num; } } break; case mode_freq_ext: if (error_num=Set_Trig_Source(channel,source_external)) { return error_num; } break; case mode_freq_man: if (error_num=Set_Trig_Source(channel,source_manual)) { return error_num; } break; case mode_freq_hold: if (error_num=Set_Trig_Source(channel,source_hold)) { return error_num; } break; case mode_func_sin: if (error_num=Set_Func(channel,sin_mode_on)) { return error_num; } break; case mode_func_tri: if (error_num=Set_Func(channel,tri_mode_on)) { return error_num; } break; case mode_func_squ: if (error_num=Set_Func(channel,squ_mode_on)) { return error_num; } break; case mode_func_pulse: if (error_num=Set_Func(channel,pulse_mode_on)) { return error_num; } break; case mode_func_amp: if (error_num=Set_Func(channel,amp_mode_on)) { return error_num; } break; case mode_delay_norm: if (error_num=Set_Double(channel,double_off)) { return error_num; } break; case mode_delay_dbl: if (error_num=Set_Double(channel,double_on)) { return error_num; } break; case mode_pw_norm: globals.ChannelState[channel].hold_setting=hold_width; if ( (globals.ChannelState[channel].ab_mode!=pw_normal) || (globals.ChannelState[channel].func_mode!=pulse_mode_on)) { if (error_num=Set_Func(channel,pulse_mode_on)) { return error_num; } if (error_num=Set_Pwmode(channel,pw_normal)) { return error_num; } if (Set_Pw(0,0,0,channel,globals.ChannelState[channel].pw,0)!=OK) { Set_Pw(0,0,0,channel,globals.Flash.min_pw[channel],0); } } break; case mode_pw_duty: globals.ChannelState[channel].hold_setting=hold_duty; if ( (globals.ChannelState[channel].ab_mode!=pw_normal) || (globals.ChannelState[channel].func_mode!=pulse_mode_on)) { if (error_num=Set_Func(channel,pulse_mode_on)) { return error_num; } if (error_num=Set_Pwmode(channel,pw_normal)) { return error_num; } if (Set_Pw(0,0,0,channel,globals.ChannelState[channel].pw,0)!=OK) { Set_Pw(0,0,0,channel,globals.Flash.min_pw[channel],0); } } break; case mode_pw_inout: if (error_num=Set_Func(channel,pulse_mode_on)) { return error_num; } if (error_num=Set_Pwmode(channel,pw_in_out)) { return error_num; } break; case mode_pw_dc: if (error_num=Set_Func(channel,dc_mode_on)) { return error_num; } break; case mode_output_on: if (error_num=Set_Output_State(channel,output_on)) { return error_num; } break; case mode_output_off: if (error_num=Set_Output_State(channel,output_off)) { return error_num; } break; case mode_go_to_local: Main_return_to_local(); break; case mode_inv_no: if (error_num=Set_Pol(channel,pol_norm)) { return error_num; } break; case mode_inv_yes: if (error_num=Set_Pol(channel,pol_complement)) { return error_num; } break; case mode_gate_losync: Set_Gate_Sync(channel,gate_sync); Set_Gate_Level(channel,gate_low); break; case mode_gate_hisync: Set_Gate_Sync(channel,gate_sync); Set_Gate_Level(channel,gate_high); break; case mode_gate_loasync: Set_Gate_Sync(channel,gate_async); Set_Gate_Level(channel,gate_low); break; case mode_gate_hiasync: Set_Gate_Sync(channel,gate_async); Set_Gate_Level(channel,gate_high); break; case mode_gpib_address: globals.MenuStatus.Selected_Submenu=Submenu2_gpib_address; call_new_submenu=YES; Submenu_Display(NO); /* return cursor to setup submenu afterwards */ globals.MenuStatus.Selected_Submenu=Submenu1_setup; break; case mode_zout_max: if (error_num=Set_zout(channel,globals.Flash.zout_max[channel],1)) { return error_num; } break; case mode_zout_min: if (error_num=Set_zout(channel,globals.Flash.zout_min[channel],1)) { return error_num; } break; case mode_logic_ttl: if (error_num=Set_Logic_Level(channel,logic_ttl)) { return error_num; } break; case mode_logic_ecl: if (error_num=Set_Logic_Level(channel,logic_ecl)) { return error_num; } break; case mode_amp_min: if (error_num=Set_Amplitude(0,0,0,0,0,0,channel,globals.Flash.min_ampl[channel],0)) { return error_num; } break; case mode_amp_max: if (error_num=Set_Amplitude(0,0,0,0,0,0,channel,globals.Flash.max_ampl[channel],0)) { return error_num; } break; case mode_amp_normal: if (error_num=Set_EA(channel,amp_mode_normal)) { return error_num; } break; case mode_amp_ea: if (error_num=Set_EA(channel,amp_mode_ea)) { return error_num; } break; case mode_amp_amplify: if (error_num=Set_EA(channel,amp_mode_amplify)) { return error_num; } break; case mode_os_normal: if (error_num=Set_EO(channel,os_mode_normal)) { return error_num; } break; case mode_os_eo: if (error_num=Set_EO(channel,os_mode_eo)) { return error_num; } break; case mode_load: globals.MenuStatus.Selected_Submenu=Submenu2_load; call_new_submenu=YES; Submenu_Display(NO); break; case mode_load_0: Set_Rcl(0); globals.MenuStatus.Selected_Submenu=Submenu1_memory; break; case mode_load_1: Set_Rcl(1); globals.MenuStatus.Selected_Submenu=Submenu1_memory; break; case mode_load_2: Set_Rcl(2); globals.MenuStatus.Selected_Submenu=Submenu1_memory; break; case mode_load_3: Set_Rcl(3); globals.MenuStatus.Selected_Submenu=Submenu1_memory; break; case mode_save: globals.MenuStatus.Selected_Submenu=Submenu2_save; call_new_submenu=YES; Submenu_Display(NO); break; case mode_save_0: Set_Sav(0); globals.MenuStatus.Selected_Submenu=Submenu1_memory; break; case mode_save_1: Set_Sav(1); globals.MenuStatus.Selected_Submenu=Submenu1_memory; break; case mode_save_2: Set_Sav(2); globals.MenuStatus.Selected_Submenu=Submenu1_memory; break; case mode_save_3: Set_Sav(3); globals.MenuStatus.Selected_Submenu=Submenu1_memory; break; case mode_rs232_settings: globals.MenuStatus.Selected_Submenu=Submenu2_rs232; call_new_submenu=YES; Submenu_Display(NO); break; case mode_default_rs232: Nonstd_menu_default_rs232(); globals.MenuStatus.Selected_Submenu=Submenu1_setup; break; case mode_model_info: call_new_submenu=YES; Nonstd_menu_model_info(); break; case mode_network: call_new_submenu=YES; Nonstd_menu_network(); break; case mode_password: strcpy(globals.Flash.password,"default"); // FIXME - save password to /etc/shadow here eprom_loc = (char *) &(globals.Flash.password) - (char *) &(globals.Flash.flash_start); writeUserBlock(&globals.Flash, eprom_loc, strlen(globals.Flash.password)+1); break; case mode_selfcal: if (error_num=self_cal()) { return error_num; } break; case mode_change_rs232: globals.MenuStatus.Selected_Submenu=Submenu2_rs232_baud; call_new_submenu=YES; Submenu_Display(NO); break; case mode_exit_rs232: globals.MenuStatus.Selected_Submenu=Submenu1_setup; break; case mode_1200: globals.RS232.baud = rs232_1200_baud; globals.MenuStatus.Selected_Submenu=Submenu2_rs232_databits; call_new_submenu=YES; Submenu_Display(NO); break; case mode_2400: globals.RS232.baud = rs232_2400_baud; globals.MenuStatus.Selected_Submenu=Submenu2_rs232_databits; call_new_submenu=YES; Submenu_Display(NO); break; case mode_4800: globals.RS232.baud = rs232_4800_baud; globals.MenuStatus.Selected_Submenu=Submenu2_rs232_databits; call_new_submenu=YES; Submenu_Display(NO); break; case mode_9600: globals.RS232.baud = rs232_9600_baud; globals.MenuStatus.Selected_Submenu=Submenu2_rs232_databits; call_new_submenu=YES; Submenu_Display(NO); break; case mode_7bits: globals.RS232.databits = rs232_7data_bits; globals.MenuStatus.Selected_Submenu=Submenu2_rs232_parity; call_new_submenu=YES; Submenu_Display(NO); break; case mode_8bits: globals.RS232.databits = rs232_8data_bits; globals.MenuStatus.Selected_Submenu=Submenu2_rs232_parity; call_new_submenu=YES; Submenu_Display(NO); break; case mode_par_none: globals.RS232.parity = rs232_parity_none; globals.MenuStatus.Selected_Submenu=Submenu2_rs232_stopbits; call_new_submenu=YES; Submenu_Display(NO); break; case mode_par_odd: globals.RS232.parity = rs232_parity_odd; globals.MenuStatus.Selected_Submenu=Submenu2_rs232_stopbits; call_new_submenu=YES; Submenu_Display(NO); break; case mode_par_even: globals.RS232.parity = rs232_parity_even; globals.MenuStatus.Selected_Submenu=Submenu2_rs232_stopbits; call_new_submenu=YES; Submenu_Display(NO); break; case mode_1bit: globals.RS232.stopbits = rs232_1stop_bit; globals.MenuStatus.Selected_Submenu=Submenu2_rs232_hardhand; call_new_submenu=YES; Submenu_Display(NO); break; case mode_2bits: globals.RS232.stopbits = rs232_2stop_bits; globals.MenuStatus.Selected_Submenu=Submenu2_rs232_hardhand; call_new_submenu=YES; Submenu_Display(NO); break; case mode_hand_hard: globals.RS232.hardhand = rs232_hard_on; globals.MenuStatus.Selected_Submenu=Submenu2_rs232_echo; call_new_submenu=YES; Submenu_Display(NO); break; case mode_hand_off: globals.RS232.hardhand = rs232_hard_off; globals.MenuStatus.Selected_Submenu=Submenu2_rs232_echo; call_new_submenu=YES; Submenu_Display(NO); break; case mode_echo_on: globals.RS232.echo = rs232_echo_on; globals.MenuStatus.Selected_Submenu=Submenu1_setup; break; case mode_echo_off: globals.RS232.echo = rs232_echo_off; globals.MenuStatus.Selected_Submenu=Submenu1_setup; break; } Main_update_shift_registers(); /* update values in pulse generator circuit */ if (call_new_submenu==NO) { globals.Changes.update_whole_main_menu=YES; Menu_Update_Display(); } /* re-run error_check to update min/max values based on actual settings, not proposed settings */ Error_check(globals.ChannelState); return OK; } static void Nonstd_menu_network(void) { char ip_buf[LCD_cols+1]; char mac_buf[6]; char response[LCD_cols+1]; int i; char model[32]; char serial_num[16]; LCD_clear(); /* FIXME - network info if (globals.Flash.network_enabled==0) { LCD_write(0,0,"This instrument does not have the"); LCD_write(1,0,"TCP/IP telnet access networking option"); LCD_write(2,0,"installed."); } else { pd_getaddress(0,mac_buf); sprintf(response,"MAC address: %02x:%02x:%02x:%02x:%02x:%02x", mac_buf[0], mac_buf[1], mac_buf[2], mac_buf[3], mac_buf[4], mac_buf[5]); LCD_write(0,0,response); sprintf(response,"IP address: %s",inet_ntoa(ip_buf,gethostid())); LCD_write(1,0,response); } LCD_write(3,0,response); */ LCD_write(3,0,"Press CHANGE to continue."); globals.MenuStatus.Nonstd_Display=YES; }