ソースを参照

Update display procedures
Keyboard support
Display some location info

k4be 2 年 前
コミット
e6f0b47084
7 ファイル変更203 行追加68 行削除
  1. 1 1
      soft/Makefile
  2. 96 61
      soft/display.c
  3. 3 0
      soft/display.h
  4. 33 5
      soft/main.c
  5. 15 1
      soft/main.h
  6. 48 0
      soft/working_modes.c
  7. 7 0
      soft/working_modes.h

+ 1 - 1
soft/Makefile

@@ -2,7 +2,7 @@
 PROJECT	= glg
 
 ### Source files and search directory
-CSRC    = main.c uart0.c uart1.c ff.c mmc.c 1wire.c ds18b20.c expander.c HD44780-I2C.c I2C.c xprintf.c gpx.c ffunicode.c display.c
+CSRC    = main.c uart0.c uart1.c ff.c mmc.c 1wire.c ds18b20.c expander.c HD44780-I2C.c I2C.c xprintf.c gpx.c ffunicode.c display.c working_modes.o
 ASRC    = stime.S
 VPATH   =
 

+ 96 - 61
soft/display.c

@@ -47,6 +47,11 @@ __flash const unsigned char battery_states[][8] = {
 	},
 };
 
+struct disp_s {
+	char line1[16];
+	char line2[17];
+} disp;
+
 void battery_state_display(void) {
 	unsigned char i;
 	unsigned char index;
@@ -66,46 +71,90 @@ void battery_state_display(void) {
 	};
 }
 
+void disp_func_startup(__attribute__ ((unused)) unsigned char changed) {
+	strcpy_P(disp.line1, PSTR("Uruchamianie..."));
+}
+
+void disp_func_poweroff(__attribute__ ((unused)) unsigned char changed) {
+	strcpy_P(disp.line1, PSTR("Wylaczanie..."));
+}
+
+void disp_func_poweroff_lowbat(unsigned char changed) {
+	disp_func_poweroff(changed);
+	strcpy_P(disp.line2, PSTR("Bateria slaba!"));
+}
+
+void disp_func_start_message(__attribute__ ((unused)) unsigned char changed) {
+	strcpy_P(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:			strcpy_P(disp.line2, PSTR("Brak karty!")); break;
+		case STATUS_DISK_ERROR:			strcpy_P(disp.line2, PSTR("Blad karty!")); break;
+		case STATUS_FILE_WRITE_ERROR:	strcpy_P(disp.line2, PSTR("Blad zapisu!")); break;
+		case STATUS_FILE_SYNC_ERROR:	strcpy_P(disp.line2, PSTR("Blad zapisu FAT!")); break;
+		case STATUS_FILE_CLOSE_ERROR:	strcpy_P(disp.line2, PSTR("Blad zamk.pliku!")); break;
+		case STATUS_FILE_OPEN_ERROR:	strcpy_P(disp.line2, PSTR("Blad otw. pliku!")); break;
+	}
+}
+
+void disp_func_card_ok(__attribute__ ((unused)) unsigned char changed) {
+	strcpy_P(disp.line1, PSTR("Karta OK!"));
+	strcpy_P(disp.line2, PSTR("Czekam na GPS..."));
+}
+
+void disp_func_file_open(__attribute__ ((unused)) unsigned char changed) {
+	strcpy_P(disp.line2, PSTR("Zapis aktywny"));
+}
+
+void disp_func_file_closed(__attribute__ ((unused)) unsigned char changed) {
+	strcpy_P(disp.line2, PSTR("Pliki zamkniete"));
+}
+
+void disp_func_main_default(unsigned char changed) {
+	disp.line1[0] = '\0';
+	disp_func_file_open(changed);
+}
+
+void disp_func_coord(__attribute__ ((unused)) unsigned char changed) {
+	if (System.location_valid == LOC_INVALID) {
+		strcpy_P(disp.line1, PSTR("??? N/S"));
+		strcpy_P(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(__attribute__ ((unused)) unsigned char changed) {
+	if (System.location_valid == LOC_INVALID) {
+		strcpy_P(disp.line1, PSTR("ele = ???"));
+	} else {
+		xsprintf(disp.line1, PSTR("ele = %.1fm"), location.alt);
+	}
+	xsprintf(disp.line2, PSTR("%d satelit"), System.satellites_used);
+}
+
+void (*__flash const disp_funcs[])(unsigned char) = {
+	[DISPLAY_STATE_STARTUP] = disp_func_startup,
+	[DISPLAY_STATE_POWEROFF] = disp_func_poweroff,
+	[DISPLAY_STATE_POWEROFF_LOWBAT] = disp_func_poweroff_lowbat,
+	[DISPLAY_STATE_START_MESSAGE] = disp_func_start_message,
+	[DISPLAY_STATE_CARD_OK] = disp_func_card_ok,
+	[DISPLAY_STATE_FILE_OPEN] = disp_func_file_open,
+	[DISPLAY_STATE_FILE_CLOSED] = disp_func_file_closed,
+	[DISPLAY_STATE_MAIN_DEFAULT] = disp_func_main_default,
+	[DISPLAY_STATE_COORD] = disp_func_coord,
+	[DISPLAY_STATE_ELE_SAT] = disp_func_ele_sat,
+};
 
 void display_refresh(unsigned char newstate) {
-	static const char *line1, *line2;
 	unsigned char changed = 0;
-	
-	switch (System.display_state) {
-		case DISPLAY_STATE_STARTUP:
-			line1 = PSTR("Uruchamianie...");
-			break;
-		case DISPLAY_STATE_POWEROFF_LOWBAT:
-			line2 = PSTR("Bateria slaba!");
-			/* fall through */
-		case DISPLAY_STATE_POWEROFF:
-			line1 = PSTR("Wylaczanie...");
-			break;
-		case DISPLAY_STATE_START_MESSAGE:
-			line1 = PSTR("Start");
-			switch(System.status){
-				case STATUS_NO_POWER: case STATUS_OK: case STATUS_NO_GPS: line2 = NULL; break;
-				case STATUS_NO_DISK:			line2 = PSTR("Brak karty!"); break;
-				case STATUS_DISK_ERROR:			line2 = PSTR("Blad karty!"); break;
-				case STATUS_FILE_WRITE_ERROR:	line2 = PSTR("Blad zapisu!"); break;
-				case STATUS_FILE_SYNC_ERROR:	line2 = PSTR("Blad zapisu FAT!"); break;
-				case STATUS_FILE_CLOSE_ERROR:	line2 = PSTR("Blad zamk.pliku!"); break;
-				case STATUS_FILE_OPEN_ERROR:	line2 = PSTR("Blad otw. pliku!"); break;
-			}
-			break;
-		case DISPLAY_STATE_CARD_OK:
-			line1 = PSTR("Karta OK!");
-			line2 = PSTR("Czekam na GPS...");
-			break;
-		case DISPLAY_STATE_FILE_OPEN:
-			line2 = PSTR("Zapis aktywny");
-			break;
-		case DISPLAY_STATE_FILE_CLOSED:
-			line2 = PSTR("Pliki zamkniete");
-			break;
-	}
+
 	if (newstate)
 		changed = 1;
+	
+	disp_funcs[System.display_state](changed);
+	
 	if (timer_expired(lcd)) {
 		changed = 1;
 		set_timer(lcd, 1000);
@@ -116,35 +165,20 @@ void display_refresh(unsigned char newstate) {
 		battery_state_display();
 		unsigned char len;
 		LCD_GoTo(0,0);
-		if (line1) {
-			len = strlen_P(line1);
-			if (len > 15)
-				xprintf(PSTR("Warning: too long line1=%d, mem addr %4x\r\n"), (int)len, (unsigned int)line1);
-			LCD_WriteTextP(line1);
-			while (len<15) {
-				len++;
-				LCD_WriteData(' ');
-			}
-		} else {
-			for (len=0; len<15; len++)
-				LCD_WriteData(' ');
+		len = strlen(disp.line1);
+		LCD_WriteText(disp.line1);
+		while (len<15) {
+			len++;
+			LCD_WriteData(' ');
 		}
+		LCD_WriteData(0); /* battery symbol */
 		LCD_GoTo(0,1);
-		if (line2) {
-			len = strlen_P(line2);
-			if (len > 16)
-				xprintf(PSTR("Warning: too long line2=%d, mem addr %4x\r\n"), (int)len, (unsigned int)line1);
-			LCD_WriteTextP(line2);
-			while (len<16) {
-				len++;
-				LCD_WriteData(' ');
-			}
-		} else {
-			for (len=0; len<16; len++)
-				LCD_WriteData(' ');
+		len = strlen(disp.line2);
+		LCD_WriteText(disp.line2);
+		while (len<16) {
+			len++;
+			LCD_WriteData(' ');
 		}
-		LCD_GoTo(15, 0);
-		LCD_WriteData(0); /* battery symbol */
 	}
 }
 
@@ -152,3 +186,4 @@ void display_state(unsigned char newstate) {
 	System.display_state = newstate;
 	display_refresh(newstate);
 }
+

+ 3 - 0
soft/display.h

@@ -8,6 +8,9 @@
 #define DISPLAY_STATE_CARD_OK	5
 #define DISPLAY_STATE_FILE_OPEN	6
 #define DISPLAY_STATE_FILE_CLOSED	7
+#define DISPLAY_STATE_MAIN_DEFAULT	8
+#define DISPLAY_STATE_COORD	9
+#define DISPLAY_STATE_ELE_SAT	10
 
 void display_refresh(unsigned char newstate);
 void display_state(unsigned char newstate);

+ 33 - 5
soft/main.c

@@ -24,6 +24,7 @@
 #include "HD44780-I2C.h"
 #include "gpx.h"
 #include "display.h"
+#include "working_modes.h"
 
 
 /*FUSES = {0xFF, 0x11, 0xFE};*/		/* ATmega644PA fuses: Low, High, Extended.
@@ -44,7 +45,9 @@ void start_bootloader(void) {
 	typedef void (*do_reboot_t)(void);
 	const do_reboot_t do_reboot = (do_reboot_t)((FLASHEND - 1023) >> 1);
 	cli();
-//	close_files(0); // FIXME not working
+	uart1_deinit();
+/*	close_files(0); // FIXME not working
+	display_state(DISPLAY_STATE_BOOTLOADER);*/
 	LCD_Clear(); /* Do not call display.c here! */
 	LCD_GoTo(0,0);
 	LCD_WriteTextP(PSTR("Aktualizacja"));
@@ -67,6 +70,8 @@ ISR(TIMER1_COMPA_vect)
 	static unsigned int power_sw;
 	unsigned int *volatile ctimer;
 	unsigned char i;
+	unsigned char k;
+	static unsigned char oldk;
 	
 	for(i=0; i<sizeof(System.timers)/sizeof(unsigned int); i++){ // decrement every variable from timers struct unless it's already zero
 		ctimer = ((unsigned int *)&System.timers) + i;
@@ -109,6 +114,23 @@ ISR(TIMER1_COMPA_vect)
 		start_bootloader();
 		LEDR_ON();
 	}
+	
+	/* keyboard */
+	k = ((~PIND) >> 4) & 0x0f;
+	if (POWER_SW_PRESSED())
+		k |= K_POWER;
+	if (k && k != oldk) {
+		System.keypress = k;
+		oldk = k;
+	}
+	if (!k)
+		oldk = 0;
+}
+
+unsigned char getkey(void) {
+	unsigned char key = System.keypress;
+	System.keypress = 0;
+	return key;
 }
 
 
@@ -337,6 +359,7 @@ static time_t gp_rmc_parse(const char *str) {
 
 	p = gp_col(str, 2);		/* Get status */
 	if (!p || *p != 'A') {
+		System.location_valid = LOC_INVALID;
 		FLAGS &= ~F_GPSOK;
 		return 0;			/* Return 0 even is time is valid (comes from module's internal RTC) */
 	}
@@ -352,10 +375,12 @@ static void gp_gga_parse(const char *str) {
 
 	/* check validity */
 	p = gp_col(str, 6);
-	if (*p == '0')
+	if (*p == '0') {
+		System.location_valid = LOC_INVALID;
 		return;
+	}
 	
-	System.location_valid = 1;
+	System.location_valid = LOC_VALID_NEW;
 
 	/* parse location */
 	p = gp_col(str, 2);		/* latitude */
@@ -559,6 +584,7 @@ int main (void)
 			wdt_reset();
 			display_refresh(DISPLAY_STATE_NO_CHANGE);
 			gettemp();
+			key_process();
 
 			if (!(FLAGS & F_GPSOK))
 				xputs_P(PSTR("Waiting for GPS\r\n"));
@@ -593,7 +619,7 @@ int main (void)
 					System.status = STATUS_FILE_WRITE_ERROR;
 					break;
 				}
-				if (System.location_valid) /* a new point */
+				if (System.location_valid == LOC_VALID_NEW) /* a new point */
 					gpx_process_point(&location, &gpx_file);
 				wdt_reset();
 				if (FLAGS & F_SYNC) {
@@ -604,7 +630,9 @@ int main (void)
 					FLAGS &= ~F_SYNC;
 				}
 			}
-			System.location_valid = 0;
+			if (System.location_valid == LOC_VALID_NEW) {
+				System.location_valid = LOC_VALID;
+			}
 
 			if (localtime && !(FLAGS & F_FILEOPEN)) {
 				xsprintf(Line, PSTR("%04u-%02u-%02u_%02u-%02u-%02u.LOG"), ct.tm_year+1900, ct.tm_mon + 1, ct.tm_mday, ct.tm_hour, ct.tm_min, ct.tm_sec);

+ 15 - 1
soft/main.h

@@ -100,6 +100,18 @@
 #define STATUS_FILE_CLOSE_ERROR	7
 #define STATUS_FILE_OPEN_ERROR	8
 
+/* Keyboard */
+#define K_UP	_BV(1)
+#define K_DOWN	_BV(3)
+#define K_LEFT	_BV(2)
+#define K_RIGHT	_BV(0)
+#define K_POWER	_BV(4)
+
+/* System.location_valid values */
+#define LOC_INVALID	0
+#define LOC_VALID	1
+#define LOC_VALID_NEW	2
+
 #define ms(x) (x/10)
 
 struct timers {
@@ -120,6 +132,8 @@ struct system_s {
 	unsigned char satellites_used;
 	unsigned char display_state;
 	unsigned char location_valid;
+	unsigned char keypress;
+	unsigned char working_mode;
 };
 
 struct location_s {
@@ -156,5 +170,5 @@ static inline unsigned int atomic_get_uint(volatile unsigned int *volatile data)
 void disk_timerproc (void); /* mmc.h */
 const char *get_iso_time(time_t time);
 void close_files(unsigned char flush_logs);
-
+unsigned char getkey(void);
 

+ 48 - 0
soft/working_modes.c

@@ -0,0 +1,48 @@
+#include "main.h"
+#include "working_modes.h"
+#include "display.h"
+#include "HD44780-I2C.h"
+#include "xprintf.h"
+
+__flash const unsigned char main_display_modes[] = {
+	DISPLAY_STATE_MAIN_DEFAULT,
+	DISPLAY_STATE_COORD,
+	DISPLAY_STATE_ELE_SAT,
+};
+
+void change_display_mode(signed char dir) {
+	static signed char display_mode_index;
+	display_mode_index += dir;
+	if (display_mode_index < 0)
+		display_mode_index = sizeof(main_display_modes) - 1;
+	if (display_mode_index >= (signed char)sizeof(main_display_modes))
+		display_mode_index = 0;
+	display_state(main_display_modes[display_mode_index]);
+}
+
+unsigned char working_mode_default(unsigned char k) {
+	switch (k) {
+		case K_UP:
+			change_display_mode(-1);
+			break;
+		case K_DOWN:
+			change_display_mode(1);
+			break;
+	}
+	return MODE_NO_CHANGE;
+}
+
+unsigned char (*__flash const working_modes[])(unsigned char) = {
+	working_mode_default,
+};
+
+void key_process(void) {
+//	static unsigned char mode_changed;
+	unsigned char k = getkey();
+	unsigned char newmode = working_modes[System.working_mode](k);
+	if (newmode != MODE_NO_CHANGE && newmode != System.working_mode) {
+		LCD_Clear();
+		System.working_mode = newmode;
+	}
+}
+

+ 7 - 0
soft/working_modes.h

@@ -0,0 +1,7 @@
+#pragma once
+
+#define MODE_NO_CHANGE	0xff
+
+
+void key_process(void);
+