/* Setup of the operating parameters with LCD menu */ /* $Id: setup.c,v 1.2 2001/08/31 16:13:48 leon Exp leon $ */ #pragma SYMBOLS #include <reg515.h> #include "setup.h" #include "display.h" #include "ds1307.h" #include "serial.h" #define TEST_MESSAGE_TIME 1000 /* Setup parameters */ unsigned long burner_seconds; unsigned int idata solar_pump_minutes; int idata boiler_min_temp; int idata boiler_max_temp; int idata hot_water_min_temp; int idata hot_water_max_temp; int idata underfloor_temp[4]; int idata temperature_slope; /* underfloor temperature slope correction neg. */ int idata night_temp_offset; /* negative temperature offset at night times */ unsigned char idata night_begin; /* minutes/6 for the start of night regime */ unsigned char idata night_end; /* minutes/6 for the end */ sbit SECONDS_SOURCE = 0xB2; /* P3.2 DS1307 1Hz clock */ unsigned char bdata operating_flags; sbit burner_enabled = operating_flags ^ 0; sbit display_solar_temperatures = operating_flags ^ 1; sbit display_blanking_enabled = operating_flags ^ 2; sbit vacation = operating_flags ^ 3; unsigned char bdata pump_enabled; sbit hot_water_pump_enabled = pump_enabled ^ 0; sbit underfloor_pump0_enabled = pump_enabled ^ 1; sbit underfloor_pump1_enabled = pump_enabled ^ 2; sbit underfloor_pump2_enabled = pump_enabled ^ 3; sbit underfloor_pump3_enabled = pump_enabled ^ 4; sbit circulator_pump_enabled = pump_enabled ^ 5; sbit solar_pump_enabled = pump_enabled ^ 6; sbit inter_tank_pump_enabled = pump_enabled ^ 7; unsigned char idata circulator_start_time[8]; /* (minutes from midnigth)/6 */ unsigned char idata circulator_duration; /* in minutes */ int idata max_solar_temperature; /* in solar DHW */ int idata collector_temp_difference; /* between collector and heat exchanger */ int idata inter_tank_temp_difference; /* min difference + 3K hysteresis */ void set_defaults() { boiler_min_temp = 4500; boiler_max_temp = 7500; hot_water_min_temp = 5000; hot_water_max_temp = 6000; underfloor_temp[0] = 2200; underfloor_temp[1] = 2400; underfloor_temp[2] = 2400; underfloor_temp[3] = 2300; temperature_slope = 25; pump_enabled = 0xff; /* all pumps enabled */ circulator_start_time[0] = 60; /* 6:00 get up */ circulator_start_time[1] = 65; /* 6:30 brush teeth me */ circulator_start_time[2] = 71; /* 7:06 brush teeth kids */ circulator_start_time[3] = 110; /* 11:00 start cooking */ circulator_start_time[4] = 145; /* 14:30 dish cleaner */ circulator_start_time[5] = 189; /* 18:54 kids bath */ circulator_start_time[6] = 195; /* 19:30 wash face */ circulator_start_time[7] = 240; /* off (spare) */ circulator_duration = 3; night_temp_offset = 200; night_begin = 215; /* 21:30 */ night_end = 50; /* 5:00 */ max_solar_temperature = 9800; collector_temp_difference = 700; inter_tank_temp_difference = 600; burner_enabled = 0; display_solar_temperatures = 1; display_blanking_enabled = 1; vacation = 0; /* Nightly cooling of solar tank */ } static bit parameters_range_check(void) { #define RANGE_CHECK(pmin, pmax, lo, hi) \ (pmin >= pmax || pmin < lo || pmax > hi) if ( RANGE_CHECK(boiler_min_temp, boiler_max_temp, 4000, 9500) || RANGE_CHECK(hot_water_min_temp, hot_water_max_temp, 3000, 7000) || underfloor_temp[0] < 0 || underfloor_temp[0] > 4500 || underfloor_temp[1] < 0 || underfloor_temp[1] > 4500 || underfloor_temp[2] < 0 || underfloor_temp[2] > 4500 || underfloor_temp[3] < 0 || underfloor_temp[3] > 4500 || temperature_slope < 0 || temperature_slope > 200 || circulator_duration == 0 || circulator_duration > 30 || night_temp_offset < 0 || night_temp_offset > 1000 || night_end > night_begin || max_solar_temperature < 4000 || collector_temp_difference > 1500 || inter_tank_temp_difference < 100 || inter_tank_temp_difference > 3000) return 1; return 0; } /* CCIT 16-bit */ static unsigned int idata crc; static void crc16(unsigned char ser_data) { WDT = 1; /* reset the watch dog timer. CRC is overkill*/ SWDT = 1; crc = (unsigned char) (crc >> 8) | (crc << 8); crc ^= ser_data; crc ^= (unsigned char) (crc & 0xff) >> 4; crc ^= (crc << 8) << 4; crc ^= ((crc & 0xff) << 4) << 1; } #define CRC16I(x) crc16(*((unsigned char *)&x)); \ crc16(*(((unsigned char *)&x)+1)) #define PARAMETERS_START_ADDRESS 0x0e static void save_parameters() /* into NVRAM */ { unsigned char address = PARAMETERS_START_ADDRESS; unsigned char i; crc = 0xdead; #define SAVE_INT_PARAM(x) ds1307_set_int(address, x); CRC16I(x); address += 2 #define SAVE_BYTE_PARAM(x) ds1307_set_byte(address++, x); crc16(x) SAVE_INT_PARAM(boiler_min_temp); SAVE_INT_PARAM(boiler_max_temp); SAVE_INT_PARAM(hot_water_min_temp); SAVE_INT_PARAM(hot_water_max_temp); SAVE_INT_PARAM(underfloor_temp[0]); SAVE_INT_PARAM(underfloor_temp[1]); SAVE_INT_PARAM(underfloor_temp[2]); SAVE_INT_PARAM(underfloor_temp[3]); SAVE_INT_PARAM(temperature_slope); SAVE_INT_PARAM(night_temp_offset); SAVE_INT_PARAM(max_solar_temperature); SAVE_INT_PARAM(collector_temp_difference); SAVE_INT_PARAM(inter_tank_temp_difference); SAVE_BYTE_PARAM(night_begin); SAVE_BYTE_PARAM(night_end); for (i = 0; i < 8; i++) SAVE_BYTE_PARAM(circulator_start_time[i]); SAVE_BYTE_PARAM(circulator_duration); SAVE_BYTE_PARAM(operating_flags); SAVE_BYTE_PARAM(pump_enabled); ds1307_set_int(address, crc); } /* Memory Map of the 56 bytes in the DS1307 TODO 0x08, 0x09, 0x0A, 0x0B : (ulong) burner_seconds burner working time counter 0x0C, 0x0D : (int) boiler minimal temp 0x0E, 0x0F : (int) boiler maximal temp 0x10, 0x11 : (int) hot water container min temp 0x12, 0x13 : (int) hot water container max temp 0x14 : (unsigned char) operating flags 0x15, 0x16 : (int) circuit 0 temperature 0x17, 0x18 : (int) circuit 1 temperature 0x19, 0x1A : (int) circuit 2 temperature 0x1B, 0x1C : (int) circuit 3 temperature 0x1D, 0x1E : (unsigned int) CRC 16 bit from 0x0C 0x1F .. 0x3F : spare circuit night temperature offset solar container max temperature solar pump delta temperature container circulator delta temperature DHW circulator times */ void load_parameters() { unsigned int last_crc; unsigned char address = PARAMETERS_START_ADDRESS; unsigned char i; crc = 0xdead; #define LOAD_BYTE_PARAM(x) x = ds1307_get_byte(address++); crc16(x); #define LOAD_INT_PARAM(x) x = ds1307_get_int(address); CRC16I(x); address += 2 LOAD_INT_PARAM(boiler_min_temp); LOAD_INT_PARAM(boiler_max_temp); LOAD_INT_PARAM(hot_water_min_temp); LOAD_INT_PARAM(hot_water_max_temp); LOAD_INT_PARAM(underfloor_temp[0]); LOAD_INT_PARAM(underfloor_temp[1]); LOAD_INT_PARAM(underfloor_temp[2]); LOAD_INT_PARAM(underfloor_temp[3]); LOAD_INT_PARAM(temperature_slope); LOAD_INT_PARAM(night_temp_offset); LOAD_INT_PARAM(max_solar_temperature); LOAD_INT_PARAM(collector_temp_difference); LOAD_INT_PARAM(inter_tank_temp_difference); LOAD_BYTE_PARAM(night_begin); LOAD_BYTE_PARAM(night_end); for (i = 0; i < 8; i++) LOAD_BYTE_PARAM(circulator_start_time[i]); LOAD_BYTE_PARAM(circulator_duration); LOAD_BYTE_PARAM(operating_flags); LOAD_BYTE_PARAM(pump_enabled); last_crc = ds1307_get_int(address); if (last_crc != crc || parameters_range_check()) /* CRC16 match test */ { icm_error(29); if (confirm_dialog("Nalo\03im za\01etne \nnastavitve? ")) { set_defaults(); save_parameters(); } } } void delay(unsigned int n) { while(n--) { WDT = 1; SWDT = 1; } } static void debounce_keys(void) { int i = 0; while (i++ < 3000) /* release the key before answer with debounce*/ { if (!KEY_UP || !KEY_DOWN || !KEY_YES || !KEY_NO) i = 0; WDT = 1; /* reset the watch dog timer */ SWDT = 1; } } /* Dialog message shifts display left for 16 chars and prints the question. Previous display is then restored! */ bit confirm_dialog(const char code *question) { unsigned char i; lcd_send(0, 0x90); /* move cursor to first line (shifted) */ for (i = 0; i < 16; i++) lcd_send(0, 0x18); /* shift display left */ i = 0; while(question[i]) { if (question[i] == '\n') { lcd_send(0, 0x80+0x50); /* new line */ i++; continue; } lcd_send(1, question[i++]); } debounce_keys(); while (1) { WDT = 1; /* reset the watch dog timer */ SWDT = 1; if (!KEY_YES) { lcd_send(0, 0x02); /* cursor home and shift restore */ debounce_keys(); return 1; } if (!KEY_NO) { lcd_send(0, 0x02); /* cursor home and shift restore */ debounce_keys(); return 0; } } return 0; } static void timed_message(char code *message, unsigned int time) { unsigned char i; lcd_send(0, 0x90); /* move cursor to first line (shifted) */ for (i = 0; i < 16; i++) lcd_send(0, 0x18); /* shift display left */ i = 0; while(message[i]) { if (message[i] == '\n') { lcd_send(0, 0x80+0x50); /* new line */ i++; continue; } lcd_send(1, message[i++]); } while(time--) { for (i = 0; i < 200; i++) { WDT = 1; /* reset the watch dog timer */ SWDT = 1; } } lcd_send(0, 0x02); /* cursor home and shift restore */ } static void test_processor_clock(void) { unsigned int i; i = 0; EAL = 0; do { WDT = 1; /* reset the watch dog timer */ SWDT = 1; } while(!SECONDS_SOURCE); /* wait HI */ ; do { WDT = 1; /* reset the watch dog timer */ SWDT = 1; } while(SECONDS_SOURCE); /* wait LO */ ; do { WDT = 1; /* 1T */ SWDT = 1; /* 1T */ i++; /* 1T+1T+ 2T + (1T) */ } while(!SECONDS_SOURCE); /* 2 T */ EAL = 1; lcd_print("Processor clock \n "); lcd_print_ulong(0x4A, ((unsigned long)i*8UL + (unsigned long)i/256UL) * 24UL); } static void test_ram(void) { unsigned char xdata *p = 0; lcd_print("Testing RAM ... \n "); while (p < 0x8000) { *p = 0x00; p++; /* Ouch this was optimized! */ p--; if ((unsigned int)p % 16 == 0) /* printout is slow ! */ lcd_print_ulong(0x4A, (unsigned long)p); if (*p != 0x00) { lcd_print_ulong(0x4A, (unsigned long)p); halt(70, "RAM fault x00 at"); } *p = 0xFF; p++; p--; if (*p != 0xFF) { lcd_print_ulong(0x4A, (unsigned long)p); halt(71, "RAM fault xFF at"); } p++; WDT = 1; /* reset the watch dog timer */ SWDT = 1; } timed_message("32 kilobytes of\nSTATIC RAM OK! ", TEST_MESSAGE_TIME); } static void clock_setup(void) { char i; char day_of_week, hours, minutes, year, month, date, state; char code *day_names = " Error DayOfWeek" " ponedeljek >" " torek >" " sreda >" " \01etrtek >" " petek >" " sobota >" " nedelja >"; hours = ds1307_get_bcd_hours(); BCD_TO_DECIMAL(hours); minutes = ds1307_get_bcd_minutes(); BCD_TO_DECIMAL(minutes); day_of_week = ds1307_get_byte(3) & 0x07; date = ds1307_get_byte(4) & 0x3f; BCD_TO_DECIMAL(date); month = ds1307_get_byte(5) & 0x3f; BCD_TO_DECIMAL(month); year = ds1307_get_byte(6); BCD_TO_DECIMAL(year); lcd_send(0, 0x90); /* move cursor to first line (shifted) */ for (i = 0; i < 16; i++) lcd_send(0, 0x18); /* shift display left */ for(i = 0; i < 16; i++) lcd_send(1, day_names[day_of_week * 16 + i]); # define LCD_SEND_2(x) lcd_send(1,((x)/10) + '0'); lcd_send(1,((x)%10) + '0') lcd_send(0, 0x80 + 0x50); LCD_SEND_2(year); lcd_send(1, '-'); LCD_SEND_2(month); lcd_send(1, '-'); LCD_SEND_2(date); lcd_send(1, ' '); LCD_SEND_2(hours); lcd_send(1, ':'); LCD_SEND_2(minutes); lcd_send(1, ' '); lcd_send(1, ' '); lcd_send(0, 0x90); /* move cursor to the first line (shifted) */ #if 0 lcd_send(0, 0x0f); /* blink the cursor */ #endif debounce_keys(); state = 0; #define CHANGE_VARIABLE(var, lo, hi) if (!KEY_UP) var++; else var--;\ if (var > hi) var = lo; if (var < lo) var = hi while (1) { if (!KEY_UP|| !KEY_DOWN) { switch (state) { case 0: CHANGE_VARIABLE(day_of_week, 1, 7); for(i = 0; i < 16; i++) lcd_send(1, day_names[day_of_week * 16 + i]); lcd_send(0, 0x90); /* move cursor to the first line (shifted) */ break; case 1: CHANGE_VARIABLE(year, 0, 99); LCD_SEND_2(year); lcd_send(0, 0x80 + 0x50); break; case 2: CHANGE_VARIABLE(month, 1, 12); LCD_SEND_2(month); lcd_send(0, 0x80 + 0x53); break; case 3: CHANGE_VARIABLE(date, 1, 31); LCD_SEND_2(date); lcd_send(0, 0x80 + 0x56); break; case 4: CHANGE_VARIABLE(hours, 0, 23); LCD_SEND_2(hours); lcd_send(0, 0x80 + 0x59); break; case 5: CHANGE_VARIABLE(minutes, 0, 59); LCD_SEND_2(minutes); lcd_send(0, 0x80 + 0x5c); break; } debounce_keys(); } if (!KEY_YES) break; if (!KEY_NO) { state++; if (state > 5) state = 0; debounce_keys(); if (state) lcd_send(0, (0x80 | 0x50) + (state - 1)*3); else lcd_send(0, 0x90); } WDT = 1; /* reset the watch dog timer */ SWDT = 1; } ds1307_set_date_time(year, month, date, hours, minutes, day_of_week); #if 0 ds1307_set_date_time(year, month, date, hours, minutes, day_of_week); lcd_send(0, 0x0c); /* disable cursor */ #endif lcd_send(0, 0x02); /* cursor home and shift restore */ } static void show_main_menu_icons(void) { lcd_cgram_symbols_init(); lcd_print("\001 \005 \002 \003 \004 \006 i"); lcd_send(0, 0x0d); /* blink on */ } static void show_main_menu(char menu_number) { unsigned char i; char code *main_menu_text = { "1.Kotel " "2.Hranilnik TV " "3.Cirkulacija TV" "4.Talno gretje " "5.Solarni sklop " "6.Nastavitve " "7.Informacije " }; main_menu_text += 16 * menu_number; lcd_send(0,0x80|0x40); /* second row */ for (i = 0; i < 16 ; i++) lcd_send(1, *(main_menu_text++)); lcd_send(0, 0x80 + menu_number * 2); } #define KEY_DELAY_TIME 20000 /* With negative selected no radio buttons are shown */ static void show_option(char code *text, char start_line, char selected, bit cursor_at_home, bit show_options) { char i; text += 16 * start_line; lcd_send(0, 0x80); for (i = 0; i < 16; i++) lcd_send(1, *(text++)); lcd_send(0, 0xc0); if (*text) for (i = 0; i < 16; i++) lcd_send(1, *(text++)); else for (i = 0; i < 16; i++) lcd_send(1, '-'); if (show_options) { lcd_send(0, 0x8f); /* move to 15th char pos. */ if (start_line == selected) lcd_send(1, '\x07'); else lcd_send(1, '\x08'); lcd_send(0, 0xcf); if (start_line + 1 == selected) lcd_send(1, '\x07'); else lcd_send(1, '\x08'); } if (cursor_at_home) lcd_send(0, 0x80); else lcd_send(0, 0xc0); } static bit select_option(char code *text, char *start_line, char *selected, bit cursor_at_home, bit show_options) { char options; char code *p = text; unsigned int key_delay; while(*p) p++; options = (p - text)/16; show_option(text, *start_line, *selected, cursor_at_home, show_options); debounce_keys(); while(1) { WDT = 1; /* reset the watch dog timer */ SWDT = 1; if (key_delay) { key_delay --; continue; } if (!KEY_DOWN) { if (!cursor_at_home && *start_line < options - 2) { (*start_line) ++; show_option(text, *start_line, *selected, cursor_at_home, show_options); } else cursor_at_home = 0; lcd_send(0, 0xc0); key_delay = KEY_DELAY_TIME; } if (!KEY_UP) { if (cursor_at_home && *start_line > 0) { (*start_line) --; show_option(text, *start_line, *selected, cursor_at_home, show_options); } else cursor_at_home = 1; lcd_send(0, 0x80); key_delay = KEY_DELAY_TIME; } if(!KEY_YES) { *selected = cursor_at_home ? *start_line : *start_line + 1; if (show_options) { show_option(text, *start_line, *selected, cursor_at_home, show_options); delay(0xffff); } break; } if(!KEY_NO) { *selected = -1; break; } } return cursor_at_home; } static char option_on_off(char selected) { char start_line = 0; if (selected) selected = 0; else selected = 1; select_option("1. Vklju\x1i 2. Izklju\x1i ", &start_line, &selected, selected ? 0 : 1, 1); if (selected == 0) return 1; else if (selected == 1) return 0; return -1; /* nothing selected */ } /* up/down and confirm/cancel dialog */ static void set_temperature(char code *title, int idata *temperature, char step, int minT, int maxT) { unsigned int key_delay = 0; int value = *temperature; lcd_print(title); if (value > maxT) value = maxT; if (value < minT) value = minT; lcd_print_temp(0xca, value); debounce_keys(); while(1) { WDT = 1; /* reset the watch dog timer */ SWDT = 1; if (key_delay) { key_delay --; continue; } if(!KEY_DOWN && value - step >= minT) { value -= step; lcd_print_temp(0xca, value); key_delay = KEY_DELAY_TIME; } if(!KEY_UP && value + step <= maxT) { value += step; lcd_print_temp(0xca, value); key_delay = KEY_DELAY_TIME; } if(!KEY_YES) { *temperature = value; return; } if(!KEY_NO) return; } } static void set_time_of_day(char code *title, unsigned char *time_of_day) { unsigned int key_delay = 0; unsigned char value = *time_of_day; lcd_print(title); lcd_print_time_of_day(value); debounce_keys(); while(1) { WDT = 1; /* reset the watch dog timer */ SWDT = 1; if (key_delay) { key_delay --; continue; } if(!KEY_DOWN && value != 0) { value --; lcd_print_time_of_day(value); key_delay = KEY_DELAY_TIME; } if(!KEY_UP && value < 240) { value ++; lcd_print_time_of_day(value); key_delay = KEY_DELAY_TIME; } if(!KEY_YES) { *time_of_day = value; return; } if(!KEY_NO) return; } } static void set_minutes(char code *title, unsigned char low, unsigned char high, unsigned char *minutes) { unsigned int key_delay = 0; unsigned char value = *minutes; lcd_print(title); lcd_print_uchar(0x47, value); lcd_princ(0x49, "minut"); debounce_keys(); while(1) { WDT = 1; /* reset the watch dog timer */ SWDT = 1; if (key_delay) { key_delay --; continue; } if(!KEY_DOWN && value > low) { value --; lcd_print_uchar(0x47, value); key_delay = KEY_DELAY_TIME; } if(!KEY_UP && value < high) { value ++; lcd_print_uchar(0x47, value); key_delay = KEY_DELAY_TIME; } if(!KEY_YES) { *minutes = value; return; } if(!KEY_NO) return; } } #define ON_OFF(value) option = option_on_off(value); \ if (option >= 0) value = option static void display_hours(char code *title, unsigned int minutes) { lcd_print(title); lcd_print_uchar(0x47, minutes/60); lcd_princ(0x49, "ur"); debounce_keys(); while(1) { WDT = 1; /* reset the watch dog timer */ SWDT = 1; if(!KEY_YES || !KEY_NO) break; } } static void submenu(char main_menu_number) { char selected = 0; char start_line = 0; bit cursor_at_home = 1; char option; lcd_cgram_caron_init(); while (1) { switch (main_menu_number) { case 0: /* Boiler */ cursor_at_home = select_option("1. Gorilec " "2. Min. temp. " "3. Maks. temp. ", &start_line, &selected, cursor_at_home, 0); switch(selected) { case 0: ON_OFF(burner_enabled); break; case 1: set_temperature("Min. temp kotla", &boiler_min_temp, 100, 1000, boiler_max_temp - 1000); break; case 2: set_temperature("Maks.temp kotla", &boiler_max_temp, 100, boiler_min_temp + 1000, 9000); break; } break; case 1: /* DHW tank connected to boiler */ cursor_at_home = select_option("0. Hranilnik " "1. Min. temp. " "2. Maks. temp. ", &start_line, &selected, cursor_at_home, 0); switch (selected) { case 0: ON_OFF(hot_water_pump_enabled); break; case 1: set_temperature("Min.T hranilnika", &hot_water_min_temp, 100, 500, hot_water_max_temp - 500); break; case 2: set_temperature("Max.T hranilnika", &hot_water_max_temp, 100, hot_water_min_temp + 500, boiler_max_temp - 500); break; } break; case 2: /* Hot water circulation setup */ cursor_at_home = select_option("1. Kro\003enje vode" "2. Trajanje " "3. Za\001etek 1 " "4. Za\001etek 2 " "5. Za\001etek 3 " "6. Za\001etek 4 " "7. Za\001etek 5 " "8. Za\001etek 6 " "9. Za\001etek 7 " "10.Za\001etek 8 ", &start_line, &selected, cursor_at_home, 0); switch (selected) { case 0: ON_OFF(circulator_pump_enabled); break; case 1: set_minutes("Trajanje kro\03en.", 1, 30, &circulator_duration); break; default: if (selected > 0) set_time_of_day("Za\01etek", &circulator_start_time[selected - 2]); break; } break; case 3: /* Underfloor heating */ cursor_at_home = select_option("0. Mansarda " "1. Spalnice " "2. Pritli\001je " "3. Gara\003a " "4. Temp.mansarde" "5. Temp. spalnic" "6. T. pritli\001ja " "7. Temp. gara\003e " "8.Nagib krivulje" "9. No\001na korekc." "10.Za\01etek no\01i " "11.Konec no\01i ", &start_line, &selected, cursor_at_home, 0); switch (selected) { case 0: ON_OFF(underfloor_pump0_enabled); break; case 1: ON_OFF(underfloor_pump1_enabled); break; case 2: ON_OFF(underfloor_pump2_enabled); break; case 3: ON_OFF(underfloor_pump3_enabled); break; case 4: case 5: case 6: case 7: set_temperature("Izhodi\02\01na temp.", &underfloor_temp[selected - 4], 100, 1000, 4000); break; case 8: set_temperature("Nagib -\xdf/K", &temperature_slope, 1, 0, 100); break; case 9: set_temperature("No\001na korekcija ", &night_temp_offset, 10, 0, 1000); break; case 10: set_time_of_day("Za\01etek no\01i", &night_begin); break; case 11: set_time_of_day("Konec no\01i", &night_end); break; } break; case 4: /* Solar */ cursor_at_home = select_option("0. Solarni sklop" "1. Maks. temp. " "2. Razlika Tc-Th" "3. Pretakanje " "4. Razlika Th-Tb" "5. No\01no hlajen.", &start_line, &selected, cursor_at_home, 0); switch (selected) { case 0: ON_OFF(solar_pump_enabled); break; case 1: set_temperature("Maks. solar temp", &max_solar_temperature, 100, 4000, 10000); break; case 2: set_temperature("kolektor-izmenj.", &collector_temp_difference, 100, 200, 2000); break; case 3: ON_OFF(inter_tank_pump_enabled); break; case 4: set_temperature("sol.hran.-bud.hr", &inter_tank_temp_difference, 100, 100, 3000); break; case 5: ON_OFF(vacation); break; } break; case 5: /* general system setup */ cursor_at_home = select_option("0. Nastavi uro " "1. Bri\02i \02tevce " "2. Privzete nast", &start_line, &selected, cursor_at_home, 0); switch (selected) { case 0: clock_setup(); break; case 1: if (confirm_dialog("Ali naj izbri\02em\n\02tevce ur? ")) { burner_seconds = 0; solar_pump_minutes = 0; ds1307_set_ulong(BURNER_SECONDS_NVRAM_ADDR, burner_seconds); ds1307_set_int(BURNER_SECONDS_NVRAM_ADDR+4, solar_pump_minutes); } break; case 2: if (confirm_dialog("Ali naj nastavim\nprivzete param.?")) { timed_message("Za\01etni parametr\nso nastavljeni!", 400); set_defaults(); } break; } break; case 6: /* info */ cursor_at_home = select_option("0. Prikaz temp. " "1. Temnjenje pr." "2. Ure sol. \01rp." "3. Zgodovina " "4. Test sistema ", &start_line, &selected, cursor_at_home, 0); switch (selected) { case 0: option = 0; selected = display_solar_temperatures; select_option("0.Talno gretje " "1.Solarne temp. ", &option , &selected, selected ? 0 : 1, 1); if (selected >= 0) display_solar_temperatures = selected; selected = 0; break; case 1: ON_OFF(display_blanking_enabled); break; case 2: display_hours("Obratovalne ure", solar_pump_minutes); break; case 3: option = 0; /* start line */ selected = 0; select_option("0. Informacije " "1. Izpi\02i zgod. " "2. Izpi\02i 57600b" "3. Bri\02i zgodov.", &option, &selected, 1, 0); switch (selected) { case 0: push_char('@'); push_char('I'); break; case 1: push_char('@'); push_char('P'); break; case 2: push_char('@'); push_char('F'); break; case 3: if (confirm_dialog("Ali naj izbri\02em\nzgodov.dogodkov?")) { push_char('@'); push_char('E'); } break; } selected = 3; break; case 4: /* System test */ option = 0; /* start line */ selected = 0; select_option("0. Static RAM " "1. Test ICM7218A" "2. RS232 9600bps" "3. \01rpalke " "4. Processor CLK", &option, &selected, 1, 0); switch (selected) { case 0: test_ram(); break; case 1: icm_test(0); timed_message("Blanking ICM7128\n... ", TEST_MESSAGE_TIME); icm_test(1); timed_message("Lighting all ICM\nsegments & LEDs ", TEST_MESSAGE_TIME); icm_test(2); timed_message("Writting error \nmessage #2 ", TEST_MESSAGE_TIME); break; case 2: syslog(LOG_INFO, "A. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "B. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "C. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "D. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "E. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "F. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "G. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "H. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "I. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "J. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "K. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "L. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "M. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "N. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "O. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "P. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "Q. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "R. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "S. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "T. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "U. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "V. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "W. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "X. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "Y. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; syslog(LOG_INFO, "Z. The quick brown fox jumped over lazy dog"); SWDT=WDT=1; break; case 3: break; case 4: test_processor_clock(); delay(60000); delay(60000); delay(60000); delay(60000); break; } selected = 4; break; } break; } /* info */ if (selected < 0) return; } } void setup() { #define TOTAL_MENUS 7 char main_menu_number = 0; unsigned int key_delay = 0; WDT = 1; /* reset the watch dog timer */ SWDT = 1; show_main_menu_icons(); show_main_menu(main_menu_number); /* set_defaults(); */ debounce_keys(); while (1) { WDT = 1; /* reset the watch dog timer */ SWDT = 1; if (key_delay) { key_delay --; continue; } if (!KEY_UP) { if (++main_menu_number >= TOTAL_MENUS) main_menu_number = 0; show_main_menu(main_menu_number); key_delay = KEY_DELAY_TIME; continue; } if (!KEY_DOWN) { if (--main_menu_number < 0) main_menu_number = TOTAL_MENUS - 1; show_main_menu(main_menu_number); key_delay = KEY_DELAY_TIME; continue; } if (!KEY_YES) { submenu(main_menu_number); show_main_menu_icons(); show_main_menu(main_menu_number); debounce_keys(); continue; } if (!KEY_NO) break; } save_parameters(); lcd_send(0, 0x0c); /* disable cursor */ lcd_send(0, 0x01); /* clear display at exit of the setup*/ }