#include #include "main.h" #include "display.h" #include "xprintf.h" #include "working_modes.h" #include "timec.h" #ifndef LCD_GRAPHIC __flash const unsigned char battery_states[][8] = { { 0b01110, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, }, { 0b01110, 0b11111, 0b10001, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, }, { 0b01110, 0b11111, 0b10001, 0b10001, 0b10001, 0b11111, 0b11111, 0b11111, }, { 0b01110, 0b11111, 0b10001, 0b10001, 0b10001, 0b10001, 0b10001, 0b11111, }, }; __flash const unsigned char custom_chars[] = { 0b00000, /* 0x01 down arrow */ 0b00100, 0b00100, 0b00100, 0b10101, 0b01110, 0b00100, 0b00000, 0b00000, /* 0x02 up arrow */ 0b00100, 0b01110, 0b10101, 0b00100, 0b00100, 0b00100, 0b00000, }; #endif /* LCD_GRAPHIC */ struct disp_s disp; void disp_init(void) { /* send custom characters starting with 0x01 */ #ifndef LCD_GRAPHIC unsigned char i; LCD_WriteCommand(0x40 + 8); // 0x01 for(i=0; i 4.0) index = 0; else if (System.bat_volt > 3.7) index = 1; else if (System.bat_volt > 3.4) index = 2; else index = 3; #ifdef LCD_GRAPHIC LCD_GoTo(15,0); LCD_WriteChar(0x82 + index); #else unsigned char i; LCD_WriteCommand(0x40 + 0); // 0x00 for(i=0; i<8; i++){ LCD_WriteData(battery_states[index][i]); }; #endif /* LCD_GRAPHIC */ } static inline void disp_line(unsigned char i, __flash const char *text) { switch(i) { case 2: strcpy_P(disp.line2, text); break; case 1: strcpy_P(disp.line1, text); break; } } void disp_line1(__flash const char *text) { disp_line(1, text); } void disp_line2(__flash const char *text) { disp_line(2, text); } __flash const char _gps_wait[] = "Czekam na GPS..."; __flash const char _gps_ok[] = "GPS OK!"; __flash const char _card_ok[] = "Karta OK!"; __flash const char _logging_active[] = "Zapis aktywny"; __flash const char _logging_paused[] = "Zapis wstrzymany"; __flash const char _starting[] = "Uruchamianie..."; __flash const char _battery_low[] = "Bateria slaba!"; __flash const char _shutting_down[] = "Wylaczanie..."; __flash const char _no_card[] = "Brak karty!"; __flash const char _card_error[] = "Blad karty!"; __flash const char _write_error[] = "Blad zapisu!"; __flash const char _fat_write_error[] = "Blad zapisu FAT!"; __flash const char _file_close_error[] = "Blad zamk.pliku!"; __flash const char _file_open_error[] = "Blad otw. pliku!"; __flash const char _files_closed[] = "Pliki zamkniete"; __flash const char _files_open[] = "Pliki otwarte"; __flash const char _tracking_paused[] = "Wstrzymano!"; __flash const char _tracking_resumed[] = "Wznowiono!"; __flash const char _point_saved[] = "Zapisano!"; __flash const char _point_not_saved[] = "Nie zapisano!"; __flash const char _logging_auto_paused[] = "Autom. wstrzym."; __flash const char _sat_count_low[] = "Za malo satelit"; void display_event(unsigned char event) { /* overrides display with current messages */ switch (event) { case DISPLAY_EVENT_STARTUP: disp_line1(_starting); break; case DISPLAY_EVENT_LOW_BATTERY: disp_line2(_battery_low); /* fall through */ case DISPLAY_EVENT_POWEROFF: disp_line1(_shutting_down); break; case DISPLAY_EVENT_INITIALIZED: disp_line1(PSTR("Start")); switch(System.status){ case STATUS_NO_POWER: case STATUS_OK: case STATUS_NO_GPS: disp.line2[0] = '\0'; break; case STATUS_NO_DISK: disp_line2(_no_card); break; case STATUS_DISK_ERROR: disp_line2(_card_error); break; case STATUS_FILE_WRITE_ERROR: disp_line2(_write_error); break; case STATUS_FILE_SYNC_ERROR: disp_line2(_fat_write_error); break; case STATUS_FILE_CLOSE_ERROR: disp_line2(_file_close_error); break; case STATUS_FILE_OPEN_ERROR: disp_line2(_file_open_error); break; } break; case DISPLAY_EVENT_CARD_INITIALIZED: disp_line1(_card_ok); disp_line2(_gps_wait); break; case DISPLAY_EVENT_FILE_CLOSED: disp_line2(_files_closed); break; case DISPLAY_EVENT_FILE_OPEN: disp_line2(_files_open); break; case DISPLAY_EVENT_TRACKING_PAUSED: disp_line2(_tracking_paused); break; case DISPLAY_EVENT_TRACKING_RESUMED: disp_line2(_tracking_resumed); break; case DISPLAY_EVENT_POINT_SAVED: disp_line2(_point_saved); break; case DISPLAY_EVENT_POINT_NOT_SAVED: disp_line2(_point_not_saved); break; } display_refresh(1); } void disp_func_main_default(void) { if (FLAGS & F_FILEOPEN) { if (System.tracking_paused) { disp_line1(_logging_paused); } else if (System.tracking_auto_paused) { disp_line1(_logging_auto_paused); } else { disp_line1(_logging_active); } } else disp_line1(_card_ok); if (FLAGS & F_GPSOK) { if (System.sat_count_low) disp_line2(_sat_count_low); else disp_line2(_gps_ok); } else { disp_line2(_gps_wait); } } void disp_func_coord(void) { if (System.location_valid == LOC_INVALID) { disp_line1(PSTR("??? N/S")); disp_line2(PSTR("??? E/W")); return; } xsprintf(disp.line1, PSTR("%2.6f%c"), (location.lat < 0)?(-location.lat):location.lat, (location.lat < 0)?'S':'N'); xsprintf(disp.line2, PSTR("%3.6f%c"), (location.lon < 0)?(-location.lon):location.lon, (location.lon < 0)?'W':'E'); } void disp_func_ele_sat(void) { if (System.location_valid == LOC_INVALID) { disp_line1(PSTR("ele = ???")); } else { xsprintf(disp.line1, PSTR("ele = %.1fm"), location.alt); } xsprintf(disp.line2, PSTR("%2d satelit"), System.satellites_used); if (System.sbas) strcat_P(disp.line2, PSTR(", DGPS")); } static void format_time(char *buf, unsigned int seconds) { unsigned int hours; unsigned char mins, secs; hours = seconds / 3600; mins = (seconds % 3600) / 60; secs = seconds % 60; if (seconds < 60) { /* Under 1 minute: show seconds only */ xsprintf(buf, PSTR("%us"), secs); } else if (seconds < 3600) { /* Under 1 hour: show minutes and seconds */ xsprintf(buf, PSTR("%um%02us"), mins, secs); } else if (hours < 10) { /* Under 10 hours: show full format */ xsprintf(buf, PSTR("%uh%02um%02us"), hours, mins, secs); } else { /* 10 hours or more: drop seconds to save space */ xsprintf(buf, PSTR("%uh%02um"), hours, mins); } } void disp_distance_and_time(void) { unsigned int time = get_logging_time(); xsprintf(disp.line1, PSTR("%.2f km"), (float)System.distance / 100000.0); if (time) { strcpy(disp.line2, "t="); format_time(disp.line2 + 2, time); } else { disp_line2(PSTR("Czas nieznany")); } } void disp_pause_time(void) { strcpy_P(disp.line1, PSTR("Pauza: ")); format_time(disp.line1 + 7, get_pause_time()); disp.line2[0] = '\0'; } void disp_speed(void) { unsigned int time = get_logging_time(); disp_line1(PSTR("Predkosc:")); if (time) { xsprintf(disp.line2, PSTR("%.2f km/h"), (float)System.distance / (float)(time) * 0.036); /* convert seconds to hours */ } else { disp_line2(PSTR("nieznana")); } } void disp_time(void) { if (utc == 0) { disp_line1(PSTR("?")); disp_line2(PSTR("?")); return; } time_t time = utc; time += local_time_diff(time) * (signed int)3600; struct tm *ct = gmtime(&time); xsprintf(disp.line1, PSTR("%d.%02d.%4d"), ct->tm_mday, ct->tm_mon+1, ct->tm_year+1900); xsprintf(disp.line2, PSTR("%d:%02d:%02d"), ct->tm_hour, ct->tm_min, ct->tm_sec); } void disp_func_temperature(void) { disp_line1(PSTR("Temperatura")); if (System.temperature_ok) { xsprintf(disp.line2, PSTR("%.1f stC"), System.temperature); } else { disp_line2(PSTR("Blad!")); } } static struct { unsigned char index; unsigned char count; } error_browser; static __flash const struct { unsigned int flag; __flash const char *name; } error_list[] = { {ERROR_TEMPERATURE, PSTR("Czujnik temp.")}, {ERROR_I2C, PSTR("I2C")}, {ERROR_I2C_TIMEOUT, PSTR("I2C timeout")}, {ERROR_DISK, PSTR("Blad karty")}, {ERROR_FILE_WRITE, PSTR("Blad zapisu")}, {ERROR_FILE_SYNC, PSTR("Blad zapisu FAT")}, {ERROR_FILE_CLOSE, PSTR("Blad zamk.pliku")}, {ERROR_FILE_OPEN, PSTR("Blad otw. pliku")}, }; void disp_func_global_error(void) { unsigned char i, found_index = 0; disp_line1(PSTR("*** BLAD ***")); if (System.global_error == ERROR_NO) { disp_line2(PSTR("Brak")); error_browser.count = 0; error_browser.index = 0; return; } /* Count errors and find current one */ error_browser.count = 0; for (i = 0; i < sizeof(error_list)/sizeof(error_list[0]); i++) { if (System.global_error & error_list[i].flag) { if (error_browser.count == error_browser.index) { found_index = i; } error_browser.count++; } } /* Wrap index if needed */ if (error_browser.index >= error_browser.count) { error_browser.index = 0; found_index = 0; for (i = 0; i < sizeof(error_list)/sizeof(error_list[0]); i++) { if (System.global_error & error_list[i].flag) { found_index = i; break; } } } /* Display current error */ if (error_browser.count > 1) { xsprintf(disp.line2, PSTR("<%u/%u> "), error_browser.index + 1, error_browser.count); } else { disp.line2[0] = '\0'; } strcat_P(disp.line2, error_list[found_index].name); } unsigned char error_browser_func(unsigned char k) { if (k == K_LEFT && error_browser.count > 0) { if (error_browser.index > 0) error_browser.index--; else error_browser.index = error_browser.count - 1; return 1; } if (k == K_RIGHT && error_browser.count > 0) { error_browser.index++; if (error_browser.index >= error_browser.count) error_browser.index = 0; return 1; } /* Long press on UP to reset errors */ if (k == (K_UP | K_DOWN)) { /* both up and down pressed together as "confirm" */ System.global_error = ERROR_NO; error_browser.index = 0; error_browser.count = 0; return 1; } return 0; } void display_refresh(unsigned char changed) { if (timer_expired(lcd)) { changed = 1; } /* write to LCD */ if (changed) { set_timer(lcd, 1000); battery_state_display(); unsigned char len; LCD_GoTo(0,0); len = strlen(disp.line1); LCD_WriteText(disp.line1); while (len<15) { len++; LCD_WriteData(' '); } #ifndef LCD_GRAPHIC LCD_WriteData(0); /* battery symbol */ #endif LCD_GoTo(0,1); len = strlen(disp.line2); LCD_WriteText(disp.line2); while (len<16) { len++; LCD_WriteData(' '); } } }