summaryrefslogtreecommitdiff
path: root/menus.c
diff options
context:
space:
mode:
Diffstat (limited to 'menus.c')
-rw-r--r--menus.c3464
1 files changed, 3464 insertions, 0 deletions
diff --git a/menus.c b/menus.c
new file mode 100644
index 0000000..ac10eb1
--- /dev/null
+++ b/menus.c
@@ -0,0 +1,3464 @@
+#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 <glib.h>
+
+
+/* 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].pw<globals.Flash.mon_pw_threshold[channel]) {
+ strcpy(units,"A*");
+ --significant_digits;
+ } else {
+ strcpy(units,"A");
+ }
+ break;
+
+ case Show_duty_cycle:
+ Submenu_Value=100*globals.ChannelState[channel].pw*globals.ChannelState[channel].frequency;
+ show_plus_sign=NO;
+ strcpy(units,"%");
+ break;
+
+ case Show_route_primary:
+ Submenu_Value=(float) globals.ChannelState[channel].route_primary;
+ significant_digits=0;
+ show_plus_sign=NO;
+ strcpy(units,"");
+ break;
+
+ case Show_route_secondary:
+ Submenu_Value=(float) globals.ChannelState[channel].route_secondary;
+ significant_digits=0;
+ show_plus_sign=NO;
+ strcpy(units,"");
+ break;
+
+ case Show_Burst_Count:
+ Submenu_Value=(float) globals.ChannelState[channel].burst_count;
+ significant_digits=0;
+ show_plus_sign=NO;
+ strcpy(units,"");
+ break;
+
+ case Show_Burst_Time:
+ Submenu_Value=globals.ChannelState[channel].burst_time;
+ strcpy(units,"s");
+ show_plus_sign=NO;
+ break;
+
+ case Show_rise_time:
+ Submenu_Value=globals.ChannelState[channel].rise_time;
+ strcpy(units,"s");
+ show_plus_sign=NO;
+ break;
+
+ case Show_slew:
+ Submenu_Value=globals.ChannelState[channel].slew;
+ strcpy(units,"A/s");
+ show_plus_sign=NO;
+ break;
+
+ case Show_load_type:
+ Submenu_Value=globals.ChannelState[channel].load_type;
+ strcpy(units,"\xf4");
+ show_plus_sign=NO;
+ break;
+
+ case Show_soft_current_limit:
+ Submenu_Value=globals.ChannelState[channel].soft_current_limit;
+ strcpy(units,"A");
+ show_plus_sign=YES;
+ break;
+
+ case Show_gpib_address:
+ Submenu_Value=(float) globals.GPIB.PRIMARY_ADDRESS;
+ significant_digits=0;
+ strcpy(units,"");
+ show_plus_sign=NO;
+ break;
+ }
+
+ String_Parameter_To_Text(Submenu_Value,(int) Submenu_Value,significant_digits,start_string,units,LCD_string,show_plus_sign);
+ } else {
+ strcpy(LCD_string,start_string);
+ }
+
+ /* tack on spaces on end of string, but no wider than column */
+ for (i=strlen(LCD_string); i<width_of_column; ++i) {
+ LCD_string[i]=' ';
+ }
+ LCD_string[width_of_column]=0;
+
+ if (Is_Item_Visible) {
+ LCD_write(LCD_row,LCD_col,LCD_string);
+ }
+}
+
+
+static void Submenu_Display(int redraw)
+{
+ char title[LCD_chars_total+1];
+ char mode_name[Submenu_maximum_entries][LCD_col_width+1];
+ int i;
+ int j;
+ int channel;
+ int current_operating_mode;
+ int add_spaces;
+ int error_num;
+ char LCD_string[LCD_cols+1];
+
+ current_operating_mode=0;
+
+ globals.MenuStatus.Type_Of_Menu=Submenu_On;
+ globals.MenuStatus.Error_Screen=NO;
+ globals.MenuStatus.Nonstd_Display=NO;
+
+ if (!redraw) {
+ LCD_clear();
+ }
+
+ Submenu_Numeric_Parameter=Show_No_Number;
+ Submenu_max_entry=0;
+
+
+ channel=globals.MenuStatus.Selected_Submenu%100;
+
+ switch (globals.MenuStatus.Selected_Submenu-channel) {
+ case Submenu1_freq:
+
+ if (globals.ChannelState[channel].trigger_source==source_internal) {
+ strcpy(title,"Internal Clock:");
+ Submenu_Numeric_Parameter=Show_frequency+channel;
+ } else {
+ strcpy(title,"Trigger Menu");
+ }
+
+ if (globals.Flash.is_func_gen[channel]) {
+ Submenu_max_entry=0;
+ } else {
+ Submenu_max_entry=3;
+ Submenu_Structure[0]=mode_freq_int;
+ Submenu_Structure[1]=mode_freq_ext;
+ Submenu_Structure[2]=mode_freq_man;
+ Submenu_Structure[3]=mode_freq_hold;
+ }
+
+ break;
+
+ case Submenu1_func:
+
+ strcpy(title,"Shape Menu");
+ Submenu_max_entry=4;
+ Submenu_Structure[0]=mode_func_sin;
+ Submenu_Structure[1]=mode_func_tri;
+ Submenu_Structure[2]=mode_func_squ;
+ Submenu_Structure[3]=mode_func_pulse;
+ Submenu_Structure[4]=mode_func_amp;
+
+ break;
+
+ case Submenu1_delay:
+
+ if (globals.ChannelState[channel].double_pulse==double_off) {
+ strcpy(title,"Delay:");
+ } else {
+ strcpy(title,"Pulse Spacing:");
+ }
+ Submenu_Numeric_Parameter=Show_delay+channel;
+
+ if (globals.Flash.double_pulse_allowed[channel]) {
+ Submenu_max_entry=1;
+ Submenu_Structure[0]=mode_delay_norm;
+ Submenu_Structure[1]=mode_delay_dbl;
+ } else {
+ Submenu_max_entry=0;
+ }
+
+
+ break;
+
+ case Submenu1_pw:
+ if (globals.ChannelState[channel].ab_mode==pw_normal) {
+ if (globals.ChannelState[channel].hold_setting==hold_width) {
+ strcpy(title,"Pulse Width:");
+ Submenu_Numeric_Parameter=Show_pw+channel;
+ } else {
+ strcpy(title,"Duty Cycle:");
+ Submenu_Numeric_Parameter=Show_duty_cycle+channel;
+ }
+ } else {
+ strcpy(title,"Pulse Width:");
+ }
+
+ Submenu_max_entry=0;
+ Submenu_Structure[0]=mode_pw_norm;
+
+ if (globals.ChannelState[channel].trigger_source==source_external && (globals.Flash.ab_mode_allowed[channel])) {
+ Submenu_max_entry=1;
+ Submenu_Structure[1]=mode_pw_inout;
+ } else if (globals.ChannelState[channel].trigger_source==source_internal && (globals.Flash.dc_mode_allowed[channel])) {
+ Submenu_max_entry=2;
+ Submenu_Structure[1]=mode_pw_duty;
+ Submenu_Structure[2]=mode_pw_dc;
+ } else if (globals.ChannelState[channel].trigger_source==source_internal) {
+ Submenu_max_entry=1;
+ Submenu_Structure[1]=mode_pw_duty;
+ }
+ break;
+
+ case Submenu1_amp:
+ strcpy(title,"Amplitude");
+
+ if (globals.Flash.enable_avrq_extra_ampls) {
+ if (channel==0) {
+ strcat(title,"1 (HV):");
+ } else {
+ strcat(title,"2 (IBIAS):");
+ }
+ } else {
+ strcat(title,":");
+ }
+
+
+ if (globals.ChannelState[channel].amp_mode==amp_mode_normal && !globals.Flash.ampl_min_max_only[channel]) {
+ Submenu_Numeric_Parameter=Show_amplitude+channel;
+ }
+
+ if (globals.Flash.ampl_min_max_only[channel]) {
+ Submenu_max_entry=1;
+ Submenu_Structure[0]=mode_amp_min;
+ Submenu_Structure[1]=mode_amp_max;
+ }
+ if (globals.Flash.ea_enabled[channel]) {
+ ++Submenu_max_entry;
+ Submenu_Structure[0]=mode_amp_normal;
+ Submenu_Structure[Submenu_max_entry]=mode_amp_ea;
+ }
+ if (globals.Flash.ext_amplify_enabled[channel]) {
+ ++Submenu_max_entry;
+ Submenu_Structure[0]=mode_amp_normal;
+ Submenu_Structure[Submenu_max_entry]=mode_amp_amplify;
+ }
+
+ break;
+
+ case Submenu1_avrq:
+
+ switch (channel) {
+ case 2:
+ strcpy(title,"Amplitude3 (Vcc1):");
+ break;
+ case 3:
+ strcpy(title,"Amplitude4 (Vcc2):");
+ break;
+ case 4:
+ strcpy(title,"Amplitude5 (Vlogic):");
+ break;
+ }
+
+ Submenu_Numeric_Parameter=Show_avrq_ampl+channel;
+ break;
+
+ case Submenu1_burst_count:
+ strcpy(title,"Pulses per burst:");
+ Submenu_Numeric_Parameter=Show_Burst_Count+channel;
+ Submenu_max_entry=0;
+ break;
+
+ case Submenu1_burst_time:
+ strcpy(title,"Burst Spacing (i.e., low interval):");
+ Submenu_Numeric_Parameter=Show_Burst_Time+channel;
+ Submenu_max_entry=0;
+ break;
+
+ case Submenu1_rise_time:
+ strcpy(title,"Rise time (10%-90%):");
+ Submenu_Numeric_Parameter=Show_rise_time+channel;
+ Submenu_max_entry=0;
+ break;
+
+ case Submenu1_slew:
+ strcpy(title,"Slew rate:");
+ Submenu_Numeric_Parameter=Show_slew+channel;
+ Submenu_max_entry=0;
+ break;
+
+ case Submenu1_soft_current_limit:
+ strcpy(title,"Current limit:");
+ Submenu_Numeric_Parameter=Show_soft_current_limit+channel;
+ Submenu_max_entry=0;
+ break;
+
+ case Submenu1_zout:
+ strcpy(title,"Output Impedance");
+ Submenu_max_entry=1;
+ Submenu_Structure[0]=mode_zout_min;
+ Submenu_Structure[1]=mode_zout_max;
+ break;
+
+ case Submenu1_loadtype:
+ strcpy(title,"Load Impedance");
+ Submenu_Numeric_Parameter=Show_load_type+channel;
+ Submenu_max_entry=0;
+ break;
+
+ case Submenu1_offset:
+ strcpy(title,"Offset:");
+
+ if (globals.ChannelState[channel].os_mode==os_mode_normal) {
+ Submenu_Numeric_Parameter=Show_offset+channel;
+ }
+
+ if (globals.Flash.eo_enabled[channel]) {
+ Submenu_max_entry=1;
+ Submenu_Structure[0]=mode_os_normal;
+ Submenu_Structure[1]=mode_os_eo;
+ } else {
+ Submenu_max_entry=0;
+ }
+
+ break;
+
+ case Submenu1_mon:
+ Submenu_max_entry=0;
+ strcpy(title,"Monitor:");
+ if (globals.ChannelState[channel].pw<globals.Flash.mon_pw_threshold[channel]) {
+ LCD_write(2,2,"*PW too narrow for accurate reading.");
+ }
+ Submenu_Numeric_Parameter=Show_monitor+channel;
+ break;
+
+ case Submenu1_output_state:
+ strcpy(title,"Output State:");
+
+ Submenu_max_entry=1;
+ Submenu_Structure[0]=mode_output_on;
+ Submenu_Structure[1]=mode_output_off;
+
+ break;
+
+ case Submenu1_invert:
+ strcpy(title,"Inverted Output?:");
+
+ Submenu_max_entry=1;
+ Submenu_Structure[0]=mode_inv_no;
+ Submenu_Structure[1]=mode_inv_yes;
+
+ break;
+
+ case Submenu1_logic_level:
+ strcpy(title,"Logic Outputs:");
+ Submenu_max_entry=1;
+ Submenu_Structure[0]=mode_logic_ttl;
+ Submenu_Structure[1]=mode_logic_ecl;
+ break;
+
+ case Submenu1_gate:
+ strcpy(title,"Gate (trigger off) ");
+
+ Submenu_max_entry=1;
+ Submenu_Structure[0]=mode_gate_losync;
+ Submenu_Structure[1]=mode_gate_hisync;
+
+ /* async mode doesn't work properly in dual-channel units */
+ if ((globals.Flash.channels<=1) && !globals.Flash.sync_only) {
+ Submenu_max_entry=3;
+ Submenu_Structure[2]=mode_gate_loasync;
+ Submenu_Structure[3]=mode_gate_hiasync;
+ }
+
+ break;
+
+ case Submenu1_rem_loc:
+ strcpy(title,"Control Mode:");
+ Submenu_max_entry=1;
+
+ Submenu_Structure[0]=mode_go_to_local;
+ Submenu_Structure[1]=mode_exit_normal_submenu;
+ break;
+
+ case Submenu1_setup:
+ strcpy(title,"Setup Menu:");
+
+ Submenu_max_entry=5;
+ if (globals.Flash.self_cal) {
+ Submenu_max_entry=6;
+ Submenu_Structure[5]=mode_selfcal;
+ }
+
+ Submenu_Structure[0]=mode_gpib_address;
+ Submenu_Structure[1]=mode_rs232_settings;
+ Submenu_Structure[2]=mode_model_info;
+ Submenu_Structure[3]=mode_network;
+ Submenu_Structure[4]=mode_password;
+ Submenu_Structure[Submenu_max_entry]=mode_exit_normal_submenu;
+ break;
+
+ case Submenu2_save:
+ strcpy(title,"Save Settings:");
+ Submenu_max_entry=3;
+
+ Submenu_Structure[0]=mode_save_0;
+ Submenu_Structure[1]=mode_save_1;
+ Submenu_Structure[2]=mode_save_2;
+ Submenu_Structure[3]=mode_save_3;
+ break;
+
+ case Submenu2_load:
+ strcpy(title,"Load Settings:");
+ Submenu_max_entry=3;
+
+ Submenu_Structure[0]=mode_load_0;
+ Submenu_Structure[1]=mode_load_1;
+ Submenu_Structure[2]=mode_load_2;
+ Submenu_Structure[3]=mode_load_3;
+ break;
+
+ case Submenu1_memory:
+ strcpy(title,"Memory:");
+ Submenu_max_entry=2;
+
+ Submenu_Structure[0]=mode_load;
+ Submenu_Structure[1]=mode_save;
+ Submenu_Structure[2]=mode_exit_normal_submenu;
+ break;
+
+ case Submenu2_rs232:
+ strcpy(title,"Serial Port:");
+ Submenu_max_entry=2;
+
+ Submenu_Structure[0]=mode_change_rs232;
+ Submenu_Structure[1]=mode_default_rs232;
+ Submenu_Structure[2]=mode_exit_rs232;
+ break;
+
+ case Submenu2_rs232_baud:
+ strcpy(title,"Baud Rate:");
+ Submenu_max_entry=3;
+
+ Submenu_Structure[0]=mode_1200;
+ Submenu_Structure[1]=mode_2400;
+ Submenu_Structure[2]=mode_4800;
+ Submenu_Structure[3]=mode_9600;
+ break;
+
+ case Submenu2_rs232_databits:
+ strcpy(title,"Data Bits:");
+ Submenu_max_entry=1;
+
+ Submenu_Structure[0]=mode_7bits;
+ Submenu_Structure[1]=mode_8bits;
+ break;
+
+ case Submenu2_rs232_parity:
+ strcpy(title,"Parity:");
+ Submenu_max_entry=2;
+
+ Submenu_Structure[0]=mode_par_none;
+ Submenu_Structure[1]=mode_par_even;
+ Submenu_Structure[2]=mode_par_odd;
+ break;
+
+ case Submenu2_rs232_stopbits:
+ strcpy(title,"Stop Bits:");
+ Submenu_max_entry=1;
+
+ Submenu_Structure[0]=mode_1bit;
+ Submenu_Structure[1]=mode_2bits;
+ break;
+
+ case Submenu2_rs232_hardhand:
+ strcpy(title,"Handshaking:");
+ Submenu_max_entry=1;
+
+ Submenu_Structure[0]=mode_hand_hard;
+ Submenu_Structure[1]=mode_hand_off;
+ break;
+
+ case Submenu2_rs232_echo:
+ strcpy(title,"Echo:");
+ Submenu_max_entry=1;
+
+ Submenu_Structure[0]=mode_echo_on;
+ Submenu_Structure[1]=mode_echo_off;
+ break;
+
+ case Submenu2_gpib_address:
+ strcpy(title,"GPIB Address:");
+ Submenu_Numeric_Parameter=Show_gpib_address+channel;
+ break;
+
+ case Submenu1_route_primary:
+ if (globals.Flash.routing_required[channel] == 1) {
+ strcpy(title,"Output route:");
+ } else {
+ strcpy(title,"Anode pin:");
+ }
+ Submenu_Numeric_Parameter=Show_route_primary+channel;
+ Submenu_max_entry=0;
+ break;
+
+ case Submenu1_route_secondary:
+ strcpy(title,"Cathode pin:");
+ Submenu_Numeric_Parameter=Show_route_secondary+channel;
+ Submenu_max_entry=0;
+ break;
+
+
+ default:
+ strcpy(title,"error - not implemented");
+ }
+
+ for (i=0; i<=Submenu_max_entry; ++i) {
+ Submenu_Structure[i]+=channel;
+ }
+
+ LCD_write(0,0,title);
+ Display_Number_on_LCD(YES,1,2,"",Submenu_Numeric_Parameter,4,LCD_col_width,LCD_string);
+ LCD_write(3,0,Press_Change_Message);
+
+ if (Submenu_max_entry>0) {
+ 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])<globals.Flash.ampl_zero_equiv[channel]) {
+ current_operating_mode=i;
+ }
+ break;
+ case mode_amp_max:
+ if (globals.Flash.voltage_enabled[channel]) {
+ String_Parameter_To_Text(globals.Flash.max_ampl[channel],0,2,"","V",mode_name[i],YES);
+ } else {
+ String_Parameter_To_Text(globals.Flash.max_ampl[channel],0,2,"","A",mode_name[i],YES);
+ }
+
+ if (fabs(globals.ChannelState[channel].amplitude-globals.Flash.max_ampl[channel])<globals.Flash.ampl_zero_equiv[channel]) {
+ current_operating_mode=i;
+ }
+ break;
+ case mode_1200:
+ strcpy(mode_name[i],"1200 baud");
+ if (globals.RS232.baud==rs232_1200_baud) {
+ current_operating_mode=i;
+ }
+ break;
+ case mode_2400:
+ strcpy(mode_name[i],"2400 baud");
+ if (globals.RS232.baud==rs232_2400_baud) {
+ current_operating_mode=i;
+ }
+ break;
+ case mode_4800:
+ strcpy(mode_name[i],"4800 baud");
+ if (globals.RS232.baud==rs232_4800_baud) {
+ current_operating_mode=i;
+ }
+ break;
+ case mode_9600:
+ strcpy(mode_name[i],"9600 baud");
+ if (globals.RS232.baud==rs232_9600_baud) {
+ current_operating_mode=i;
+ }
+ break;
+ case mode_7bits:
+ strcpy(mode_name[i],"7 bits");
+ if (globals.RS232.databits==rs232_7data_bits) {
+ current_operating_mode=i;
+ }
+ break;
+ case mode_8bits:
+ strcpy(mode_name[i],"8 bits");
+ if (globals.RS232.databits==rs232_8data_bits) {
+ current_operating_mode=i;
+ }
+ break;
+ case mode_par_none:
+ strcpy(mode_name[i],"None");
+ if (globals.RS232.parity==rs232_parity_none) {
+ current_operating_mode=i;
+ }
+ break;
+ case mode_par_even:
+ strcpy(mode_name[i],"Even");
+ if (globals.RS232.parity==rs232_parity_even) {
+ current_operating_mode=i;
+ }
+ break;
+ case mode_par_odd:
+ strcpy(mode_name[i],"Odd");
+ if (globals.RS232.parity==rs232_parity_odd) {
+ current_operating_mode=i;
+ }
+ break;
+ case mode_1bit:
+ strcpy(mode_name[i],"1 bit");
+ if (globals.RS232.stopbits==rs232_1stop_bit) {
+ current_operating_mode=i;
+ }
+ break;
+ case mode_2bits:
+ strcpy(mode_name[i],"2 bits");
+ if (globals.RS232.stopbits==rs232_2stop_bits) {
+ current_operating_mode=i;
+ }
+ break;
+ case mode_hand_hard:
+ strcpy(mode_name[i],"Hardware");
+ if (globals.RS232.hardhand==rs232_hard_on) {
+ current_operating_mode=i;
+ }
+ break;
+ case mode_hand_off:
+ strcpy(mode_name[i],"None");
+ if (globals.RS232.hardhand==rs232_hard_off) {
+ current_operating_mode=i;
+ }
+ break;
+ case mode_echo_on:
+ strcpy(mode_name[i],"On");
+ if (globals.RS232.echo==rs232_echo_on) {
+ current_operating_mode=i;
+ }
+ break;
+ case mode_echo_off:
+ strcpy(mode_name[i],"Off");
+ if (globals.RS232.echo==rs232_echo_off) {
+ current_operating_mode=i;
+ }
+ break;
+ }
+ }
+
+ /* If redraw==NO, the submenu is being drawn from scratch. In this case, the arrow pointer points at the
+ current operating mode. If redraw=YES, the submenu is being redrawn to scroll the mode list. In this case,
+ the arrow pointer points at the current selection. */
+
+ if (redraw==NO && current_operating_mode<4) {
+ base_entry=0;
+ Submenu_Selected_Item=current_operating_mode;
+ } else if (redraw==NO) {
+ base_entry=current_operating_mode-3;
+ Submenu_Selected_Item=current_operating_mode;
+ } else if (redraw=YES && Submenu_Selected_Item<4) {
+ base_entry=0;
+ } else if (redraw=YES && Submenu_Selected_Item>=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; j<add_spaces; j++) {
+ strcat(mode_name[i]," ");
+ }
+ LCD_write(i-base_entry,26,mode_name[i]);
+ }
+ LCD_write(Submenu_Selected_Item-base_entry,25,"~");
+
+ /* add scrolling indicators, if required */
+ LCD_write(0,39," ");
+ LCD_write(3,39," ");
+ if (base_entry) {
+ LCD_write(0,39,"\x2");
+ }
+ if ((base_entry+3) < Submenu_max_entry) {
+ LCD_write(3,39,"\x3");
+ }
+
+ }
+
+ return OK;
+}
+
+
+static void Submenu_Move_Pointer(void)
+{
+ if (Submenu_max_entry>0) {
+
+ 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)<zero_equiv_timing && mult_by>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)<zero_equiv_timing && mult_by>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)<globals.Flash.ampl_zero_equiv[channel] && mult_by>1.0) {
+ if (new_value<0.0 || globals.Flash.max_ampl[channel]<globals.Flash.ampl_zero_equiv[channel]) {
+ new_value=-globals.Flash.ampl_zero_equiv[channel];
+ } else {
+ new_value=globals.Flash.ampl_zero_equiv[channel];
+ }
+ }
+ if (fabs(new_value) < globals.Flash.ampl_zero_equiv[channel])
+ if (new_value<0.0) {
+ new_value=-smallest_allowed_number;
+ } else {
+ new_value=smallest_allowed_number;
+ }
+ 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 (fabs(new_value)<AVRQ_ZERO_EQUIV && mult_by>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)<globals.Flash.ampl_zero_equiv[channel] && mult_by>1.0) {
+ if (new_value<0.0 || globals.Flash.max_offset[channel]<globals.Flash.ampl_zero_equiv[channel]) {
+ new_value=-globals.Flash.ampl_zero_equiv[channel];
+ } else {
+ new_value=globals.Flash.ampl_zero_equiv[channel];
+ }
+ }
+ if (fabs(new_value) < globals.Flash.ampl_zero_equiv[channel])
+ if (new_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;
+ }
+
+ Main_update_shift_registers();
+
+ Display_Number_on_LCD(YES,1,2,"",Submenu_Numeric_Parameter,4,LCD_col_width,LCD_string);
+
+ return error_num;
+}
+
+
+static void Submenu_Service_Encoder(int encoder_change)
+{
+
+ int error_num;
+ int new_encoder_change;
+ char num_string[32]; /* submenu_value in string form */
+ char expon[32]; /* exponent portion of string */
+ int equivalent_integer; /* non-exponent part stripped of its decimal point */
+ char new_string[32]; /* new parameter value to be loaded, string format */
+ float new_value; /* new parameter value to be loaded */
+ float abs_Submenu_Value; /* absolute value of Submenu_Value */
+ int increment_size;
+ int new_int_value;
+ int reset_encoder;
+ int channel;
+ char LCD_string[LCD_cols+1];
+
+ reset_encoder=YES;
+
+ /* quit if RWLS mode */
+ if (globals.control_mode==RWLS_ctrl) {
+ return;
+ }
+
+ if (globals.MenuStatus.Type_Of_Menu==Main_Menu_On) {
+ if (encoder_change>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<zero_equiv_timing
+ &&
+ ( ((Submenu_Numeric_Parameter-channel)==Show_delay)
+ || ((Submenu_Numeric_Parameter-channel)==Show_pw)
+ || ((Submenu_Numeric_Parameter-channel)==Show_Burst_Time) )
+ ) {
+ abs_Submenu_Value=zero_equiv_timing;
+ }
+
+ /* reverse direction for negative values if they are supposed
+ to smoothly transition through zero */
+ if ( (Submenu_Value < 0.0)
+ && (((Submenu_Numeric_Parameter-channel)==Show_delay)
+ || ((Submenu_Numeric_Parameter-channel)==Show_pw)) ) {
+ encoder_change = -encoder_change;
+ }
+
+ else if ((channel<max_channels) && abs_Submenu_Value<globals.Flash.ampl_zero_equiv[channel] && (Submenu_Numeric_Parameter-channel)==Show_amplitude) {
+ abs_Submenu_Value=globals.Flash.ampl_zero_equiv[channel];
+ if (globals.Flash.max_ampl[channel]<globals.Flash.ampl_zero_equiv[channel]) {
+ Submenu_Value=-abs_Submenu_Value;
+ }
+ }
+
+ else if (abs_Submenu_Value < AVRQ_ZERO_EQUIV && (Submenu_Numeric_Parameter-channel)==Show_avrq_ampl) {
+ abs_Submenu_Value=AVRQ_ZERO_EQUIV;
+
+ if (channel == 4) { /* vlogic */
+ if (encoder_change > 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 ((channel<max_channels) && abs_Submenu_Value<globals.Flash.ampl_zero_equiv[channel] && (Submenu_Numeric_Parameter-channel)==Show_offset) {
+ abs_Submenu_Value=globals.Flash.ampl_zero_equiv[channel];
+ if (globals.Flash.max_offset[channel]<globals.Flash.ampl_zero_equiv[channel]) {
+ Submenu_Value=-abs_Submenu_Value;
+ }
+ }
+
+
+ /* get a string version of the floating value to be modified */
+ Float_To_Text(3,abs_Submenu_Value,num_string);
+
+ /* isolate the exponent and non-exponent parts */
+ strcpy(expon,num_string+5);
+ num_string[5]=0;
+
+ /* remove the decimal */
+ strcpy(num_string+1,num_string+2);
+ num_string[4]=0;
+
+ /* convert the non-exponent significant digits to an integer */
+ if (Submenu_extra_fine==NO) {
+ num_string[3]='0'; /* go in steps of 10 */
+
+ /* now select encoder step size */
+ if (num_string[0]=='1') {
+ increment_size=10;
+ } else if (num_string[0]<'5') {
+ /* now make sure that we go in steps of 20 - odd numbers can arise after switching out */
+ /* of the extra fine mode */
+ if (num_string[2]=='1' || num_string[2]=='3' || num_string[2]=='5' || num_string[2]=='7' || num_string[2]=='9' ) {
+ num_string[2]-=1;
+ }
+ increment_size=20;
+ } else {
+ /* now make sure that we go in steps of 50 */
+ if (num_string[2]<'5') {
+ num_string[2]='0';
+ } else {
+ num_string[2]='5';
+ }
+ increment_size=50;
+ }
+
+ equivalent_integer=atoi(num_string);
+
+ /* new number is ... */
+ equivalent_integer+=increment_size*encoder_change;
+ } else {
+ equivalent_integer=atoi(num_string);
+ equivalent_integer+=encoder_change;
+ }
+
+ /* don't let it change too much */
+ if (equivalent_integer<1000) {
+ equivalent_integer=995;
+ }
+ if (equivalent_integer>10000) {
+ 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;
+}
+