Parcourir la source

Add SBAS switch and GNSS source selector

k4be il y a 2 ans
Parent
commit
1a761fa781
8 fichiers modifiés avec 254 ajouts et 58 suppressions
  1. 7 6
      soft/main.c
  2. 2 0
      soft/main.h
  3. 79 5
      soft/nmea.c
  4. 2 0
      soft/nmea.h
  5. 110 9
      soft/settings.c
  6. 45 6
      soft/settings.h
  7. 9 23
      soft/working_modes.c
  8. 0 9
      soft/working_modes.h

+ 7 - 6
soft/main.c

@@ -219,6 +219,7 @@ void ioinit (void)
 	PORTA |= POWER_ON;
 	
 	BUZZER_DDR |= BUZZER;
+	GPS_OFF();
 	GPS_DIS_DDR |= GPS_DIS;
 	LEDR_DDR |= LEDR;
 
@@ -268,10 +269,6 @@ void close_files(unsigned char flush_logs) {
 	disk_ioctl(0, CTRL_POWER, 0);
 }
 
-void uart0_put_wrap(int c) {
-	uart0_put((char)c);
-}
-
 __flash const char __open_msg[] = "Open %s\r\n";
 
 /*-----------------------------------------------------------------------*/
@@ -345,9 +342,10 @@ int main (void)
 		/* Initialize GPS receiver */
 		GPS_ON();		/* GPS power on */
 		FLAGS |= F_POW;
-		_delay_ms(300);	/* Delay */
+		_delay_ms(1);
 		uart0_init();	/* Enable UART */
-		xfprintf(uart0_put_wrap, PSTR("$PMTK353,1,1,1,0,0*2A\r\n$PMTK313,1*2E\r\n"));	/* Send initialization command (depends on the receiver) */
+		_delay_ms(300);	/* Delay */
+		System.gps_initialized = 0;
 
 		for (;;) { /* main loop */
 			wdt_reset();
@@ -384,6 +382,9 @@ int main (void)
 						xputs_P(PSTR("SBAS (DGPS) active\r\n"));
 					else
 						xputs_P(PSTR("SBAS inactive\r\n"));
+					xputs_P(PSTR("Using GNSS: "));
+					xputs_P(gnss_names[System.conf.gnss_mode]);
+					xputs_P(PSTR("\r\n"));
 				}
 				LEDG_ON();
 				_delay_ms(2);

+ 2 - 0
soft/main.h

@@ -143,6 +143,8 @@ struct system_s {
 	unsigned satellites_used:5;
 	unsigned location_valid:2;
 	unsigned sbas:1;
+	unsigned gps_initialized:1;
+	unsigned gps_only:1;
 };
 
 struct location_s {

+ 79 - 5
soft/nmea.c

@@ -137,6 +137,9 @@ static void gp_gga_parse(const char *str) {
 	const char *p;
 	double tmp;
 
+	p = gp_col(str, 7); /* satellites used */
+	System.satellites_used = atoi(p);
+
 	/* check validity */
 	p = gp_col(str, 6);
 	if (*p == '0') {
@@ -174,9 +177,6 @@ static void gp_gga_parse(const char *str) {
 		System.sbas = 1;
 	else
 		System.sbas = 0;
-
-	p = gp_col(str, 7); /* satellites used */
-	System.satellites_used = atoi(p);
 	
 	p = gp_col(str, 9); /* MSL altitude */
 	xatof(&p, &tmp);
@@ -184,15 +184,89 @@ static void gp_gga_parse(const char *str) {
 
 	location.time = utc; /* parsed from RMC */
 }
+/*$PMTK355*31<CR><LF>
+Return $PMTK001,355,3,1,0,0*2E “$PMTK001,355,3,GLON_Enable,BEIDOU_Enable,GALILEO_Enable”
+The GLONASS search mode is enabled. */
+static void pmtk001_parse(const char *str) {
+	const char *p;
+
+	/* check validity */
+	p = gp_col(str, 1);
+	if (strcmp_P(p, PSTR("355"))) /* not the PMTK355 reply */
+		return;
+	p = gp_col(str, 2);
+	if (*p == '0' || *p == '1') { /* invalid / unsupported */
+		System.gps_only = 1;
+		xputs_P(PSTR("GPS only\r\n"));
+	} else {
+		System.gps_only = 0;
+		xputs_P(PSTR("Multi GNSS\r\n"));
+	}
+
+	gps_initialize();
+}
 
 time_t gps_parse(const char *str) {	/* Get all required data from NMEA sentences */
-	if (!gp_comp(str, PSTR("$GPRMC")) || !gp_comp(str, PSTR("$GNRMC"))) {
+	if (!gp_comp(str, PSTR("$GPRMC")) || !gp_comp(str, PSTR("$GNRMC")) || !gp_comp(str, PSTR("$BDRMC")) || !gp_comp(str, PSTR("$GARMC"))) {
 		return gp_rmc_parse(str);
 	}
-	if (!gp_comp(str, PSTR("$GPGGA")) || !gp_comp(str, PSTR("$GNGGA"))) {
+	if (!gp_comp(str, PSTR("$GPGGA")) || !gp_comp(str, PSTR("$GNGGA")) || !gp_comp(str, PSTR("$BDGGA")) || !gp_comp(str, PSTR("$GAGGA"))) {
 		gp_gga_parse(str);
 		return 0;
 	}
+	if (!System.gps_initialized && !gp_comp(str, PSTR("$PMTK011"))) {
+		gps_initialize();
+		return 0;
+	}
+	if (!gp_comp(str, PSTR("$PMTK001"))) {
+		pmtk001_parse(str);
+		return 0;
+	}
 	return 0;
 }
 
+void uart0_put_wrap(int c) {
+	uart0_put((char)c);
+}
+
+void gps_initialize(void) {
+	/*
+	 * PMTK355: query gnss search mode (will fail if only GPS is supported)
+	 * PMTK353: set gnss search mode (GPS/Galileo/Glonass/Beidou)
+	 * PMTK313: enable SBAS
+	 */
+	if (!System.gps_initialized)
+		xfprintf(uart0_put_wrap, PSTR("$PMTK355*31\r\n"));
+	if (get_flag(CONFFLAG_ENABLE_SBAS))
+		xfprintf(uart0_put_wrap, PSTR("$PMTK313,1*2E\r\n"));
+	else
+		xfprintf(uart0_put_wrap, PSTR("$PMTK313,0*2F\r\n"));
+	if (!System.gps_only) {
+		switch (System.conf.gnss_mode) {
+			default:
+			case GNSS_MODE_GPS_GLONASS_GALILEO:
+				xfprintf(uart0_put_wrap, PSTR("$PMTK353,1,1,1,0,0*2A\r\n"));
+				break;
+			case GNSS_MODE_GPS:
+				xfprintf(uart0_put_wrap, PSTR("$PMTK353,1,0,0,0,0*2A\r\n"));
+				break;
+			case GNSS_MODE_GPS_GALILEO:
+				xfprintf(uart0_put_wrap, PSTR("$PMTK353,1,0,1,0,0*2B\r\n"));
+				break;
+			case GNSS_MODE_GALILEO:
+				xfprintf(uart0_put_wrap, PSTR("$PMTK353,0,0,1,0,0*2A\r\n"));
+				break;
+			case GNSS_MODE_GPS_BEIDOU:
+				xfprintf(uart0_put_wrap, PSTR("$PMTK353,1,0,0,0,1*2B\r\n"));
+				break;
+			case GNSS_MODE_BEIDOU:
+				xfprintf(uart0_put_wrap, PSTR("$PMTK353,0,0,0,0,1*2A\r\n"));
+				break;
+		}
+	} else {
+		System.conf.gnss_mode = GNSS_MODE_GPS;
+	}
+	xputs_P(PSTR("GPS init sent\r\n"));
+	System.gps_initialized = 1;
+}
+

+ 2 - 0
soft/nmea.h

@@ -4,3 +4,5 @@
 
 time_t gps_parse(const char *str);
 UINT get_line(char *buff, UINT sz_buf);
+void gps_initialize(void);
+

+ 110 - 9
soft/settings.c

@@ -3,10 +3,16 @@
 #include "settings.h"
 #include "display.h"
 #include "xprintf.h"
+#include "working_modes.h"
+#include "nmea.h"
 
 EEMEM struct config_s config_eep;
 EEMEM unsigned char config_crc;
 
+const __flash unsigned char limits_max_u8[] = {
+	[CONF_U8_GNSS_MODE] = 5,
+};
+
 unsigned char settings_load(void) { /* 0 - ok, 1 - error */
 	unsigned char crc=0, rcrc, i;
 	unsigned char *cptr = (unsigned char *)&System.conf;
@@ -30,7 +36,14 @@ unsigned char settings_load(void) { /* 0 - ok, 1 - error */
 }
 
 unsigned char check_config_data(void) { /* 0 - ok, 1 - error */
-	return 0;
+	unsigned char i, ret=0;
+	for (i=0; i<=CONF_U8_LAST; i++) {
+		if (System.conf.conf_u8[i] > limits_max_u8[i]) {
+			ret = 1;
+			System.conf.conf_u8[i] = 0;
+		}
+	}
+	return ret;
 }
 
 void settings_store(void) {
@@ -44,20 +57,45 @@ void settings_store(void) {
 	xputs_P(PSTR("EEPROM write done\r\n"));
 }
 
-void settings_display_and_modify_bool(unsigned char index, __flash const char *name, unsigned char k, unsigned char have_prev, unsigned char have_next) {
+void settings_display_and_modify_bool(unsigned char mindex, unsigned char k) {
+	unsigned char index = settings_menu[mindex].index;
 	unsigned char val = get_flag(index);
+	const __flash char *name = settings_menu[mindex].name;
 
 	if (k ==  K_LEFT || k ==  K_RIGHT) { /* change value */
-		set_flag(index, !val);
+		val = !val;
+		set_flag(index, val);
+		if (settings_menu[mindex].changed != NULL)
+			settings_menu[mindex].changed();
 	}
 
 	strcpy_P(disp.line1, name);
-	if (val)
-		strcpy_P(disp.line2, PSTR("< Tak > "));
-	else
-		strcpy_P(disp.line2, PSTR("< Nie > "));
-	strcat_P(disp.line2, have_next?PSTR(" \x01"):PSTR("  ")); /* down arrow */
-	strcat_P(disp.line2, have_prev?PSTR(" \x02"):PSTR("  ")); /* up arrow */
+	settings_menu[mindex].display(val);
+}
+
+void settings_display_and_modify_u8(unsigned char mindex, unsigned char k) {
+	unsigned char index = settings_menu[mindex].index;
+	unsigned char val = System.conf.conf_u8[index];
+	const __flash char *name = settings_menu[mindex].name;
+
+	if (k == K_LEFT) {
+		if (val)
+			val--;
+	}
+
+	if (k == K_RIGHT) {
+		if (val < limits_max_u8[index])
+			val++;
+	}
+
+	if (k ==  K_LEFT || k ==  K_RIGHT) {
+		System.conf.conf_u8[index] = val;
+		if (settings_menu[mindex].changed != NULL)
+			settings_menu[mindex].changed();
+	}
+
+	strcpy_P(disp.line1, name);
+	settings_menu[mindex].display(val);
 }
 
 unsigned char get_flag(unsigned char index) {
@@ -76,3 +114,66 @@ void set_flag(unsigned char index, unsigned char val) {
 		*sptr &= ~_BV(index);
 }
 
+void settings_bool_disp_default(unsigned char val) {
+	if (val)
+		strcpy_P(disp.line2, PSTR("< Tak > "));
+	else
+		strcpy_P(disp.line2, PSTR("< Nie > "));
+	strcat_P(disp.line2, HAVE_NEXT_SETTING_POSITION?PSTR(" \x01"):PSTR("  ")); /* down arrow */
+	strcat_P(disp.line2, HAVE_PREV_SETTING_POSITION?PSTR(" \x02"):PSTR("  ")); /* up arrow */
+}
+
+void display_gnss_mode(unsigned char val) {
+	strcpy_P(disp.line2, gnss_names[val]);
+}
+
+/* SETTINGS ITEMS */
+
+__flash const char _msg_disable_filters[] = "Nie filtruj";
+__flash const char _msg_enable_sbas[] = "Szukaj SBAS";
+__flash const char _msg_gnss_type[] = "Rodzaj GNSS";
+__flash const char _msg_back[] = "< Powrot";
+
+__flash const struct settings_menu_pos_s settings_menu[SETTINGS_MENU_MAXPOS+1] = {
+	{
+		.type = SETTINGS_TYPE_BACK,
+		.name = _msg_back,
+	},
+	{
+		.type = SETTINGS_TYPE_BOOL,
+		.name = _msg_disable_filters,
+		.index = CONFFLAG_DISABLE_FILTERS,
+		.display = settings_bool_disp_default,
+	},
+	{
+		.type = SETTINGS_TYPE_BOOL,
+		.name = _msg_enable_sbas,
+		.index = CONFFLAG_ENABLE_SBAS,
+		.display = settings_bool_disp_default,
+		.changed = gps_initialize,
+	},
+	{
+		.type = SETTINGS_TYPE_U8,
+		.name = _msg_gnss_type,
+		.index = CONF_U8_GNSS_MODE,
+		.display = display_gnss_mode,
+		.changed = gps_initialize,
+	},
+};
+
+__flash const char gnss_gps_glonass_galileo[] = "GPS+GL.NS+GAL.EO";
+__flash const char gnss_gps[] = "GPS";
+__flash const char gnss_gps_galileo[] = "GPS+GALILEO";
+__flash const char gnss_galileo[] = "GALILEO";
+__flash const char gnss_gps_beidou[] = "GPS+BEIDOU";
+__flash const char gnss_beidou[] = "BEIDOU";
+
+__flash const char *gnss_names[] = {
+	gnss_gps_glonass_galileo,
+	gnss_gps,
+	gnss_gps_galileo,
+	gnss_galileo,
+	gnss_gps_beidou,
+	gnss_beidou,
+};
+

+ 45 - 6
soft/settings.h

@@ -1,24 +1,63 @@
 #pragma once
 #include <avr/eeprom.h>
+#include "working_modes.h"
+
+/* u8 list - max 15 */
+#define CONF_U8_GNSS_MODE	0
+
+#define CONF_U8_LAST		0
+
+/* flags list - max 31 */
+#define CONFFLAG_DISABLE_FILTERS	0
+#define CONFFLAG_ENABLE_SBAS		1
+
+#define CONFFLAG_LAST				1
+
+/* GNSS modes */
+#define GNSS_MODE_GPS_GLONASS_GALILEO	0
+#define GNSS_MODE_GPS					1
+#define GNSS_MODE_GPS_GALILEO			2
+#define GNSS_MODE_GALILEO				3
+#define GNSS_MODE_GPS_BEIDOU			4
+#define GNSS_MODE_BEIDOU				5
+
+#define SETTINGS_TYPE_BACK	0
+#define SETTINGS_TYPE_BOOL	1
+#define SETTINGS_TYPE_U8	2
+
+#define HAVE_NEXT_SETTING_POSITION (mp.settings_menu_pos < SETTINGS_MENU_MAXPOS)
+#define HAVE_PREV_SETTING_POSITION (mp.settings_menu_pos > 0)
+
+#define SETTINGS_MENU_MAXPOS	3
 
 struct config_s {
 	union {
 		unsigned char conf_u8[16];
 		struct {
-			unsigned char __empty1;
-			unsigned char __empty2;
-		} u8;
+			unsigned char gnss_mode; // 0
+		};
 	};
 	unsigned char flags[4];
 };
 
-/* flags list */
-#define CONFFLAG_DISABLE_FILTERS	0
+struct settings_menu_pos_s {
+	unsigned char type;
+	__flash const char *name;
+	unsigned char index;
+	void (* changed)(void);
+	void (* display)(unsigned char);
+};
+
+extern const __flash unsigned char limits_max_u8[];
+extern __flash const struct settings_menu_pos_s settings_menu[SETTINGS_MENU_MAXPOS+1];
+extern __flash const char *gnss_names[];
 
 unsigned char settings_load(void); /* 0 - ok, 1 - error */
 void settings_store(void);
 unsigned char check_config_data(void); /* 0 - ok, 1 - error */
-void settings_display_and_modify_bool(unsigned char index, __flash const char *name, unsigned char k, unsigned char have_prev, unsigned char have_next);
+void settings_display_and_modify_bool(unsigned char mindex, unsigned char k);
+void settings_display_and_modify_u8(unsigned char mindex, unsigned char k);
 unsigned char get_flag(unsigned char index);
 void set_flag(unsigned char index, unsigned char val);
+void settings_bool_disp_default(unsigned char val);
 

+ 9 - 23
soft/working_modes.c

@@ -4,6 +4,7 @@
 #include "HD44780-I2C.h"
 #include "xprintf.h"
 #include "settings.h"
+#include "nmea.h"
 
 static signed char display_mode_index;
 
@@ -19,23 +20,6 @@ __flash const struct main_menu_pos_s main_menu[] = {
 	},
 };
 
-__flash const char _msg_disable_filters[] = "Nie filtruj";
-__flash const char _msg_back[] = "< Powrot";
-
-__flash const struct settings_menu_pos_s settings_menu[] = {
-	{
-		.type = SETTINGS_TYPE_BACK,
-		.name = _msg_back,
-	},
-	{
-		.type = SETTINGS_TYPE_BOOL,
-		.name = _msg_disable_filters,
-		.index = CONFFLAG_DISABLE_FILTERS,
-	},
-};
-
-#define SETTINGS_MENU_MAXPOS	((sizeof(settings_menu) / sizeof(settings_menu[0])) - 1)
-
 struct menu_params_s mp;
 
 void change_display_mode(signed char dir) {
@@ -74,9 +58,6 @@ unsigned char working_mode_main_menu(unsigned char k) {
 	return MODE_NO_CHANGE;
 }
 
-#define HAVE_NEXT_SETTING_POSITION (mp.settings_menu_pos < SETTINGS_MENU_MAXPOS)
-#define HAVE_PREV_SETTING_POSITION (mp.settings_menu_pos > 0)
-
 unsigned char working_mode_settings_menu(unsigned char k) {
 	switch (k) {
 		case K_LEFT:
@@ -84,8 +65,10 @@ unsigned char working_mode_settings_menu(unsigned char k) {
 				return MODE_MAIN_MENU;
 			/* fall through */
 		case K_RIGHT:
-			if (settings_menu[mp.settings_menu_pos].type == SETTINGS_TYPE_BOOL)
-				settings_display_and_modify_bool(settings_menu[mp.settings_menu_pos].index, settings_menu[mp.settings_menu_pos].name, k, HAVE_PREV_SETTING_POSITION, HAVE_NEXT_SETTING_POSITION);
+			switch (settings_menu[mp.settings_menu_pos].type) {
+				case SETTINGS_TYPE_BOOL: settings_display_and_modify_bool(mp.settings_menu_pos, k); break;
+				case SETTINGS_TYPE_U8: settings_display_and_modify_u8(mp.settings_menu_pos, k); break;
+			}
 			break;
 		case K_DOWN:
 			if (mp.settings_menu_pos < SETTINGS_MENU_MAXPOS)
@@ -102,7 +85,10 @@ unsigned char working_mode_settings_menu(unsigned char k) {
 void display_settings_menu_item(void) {
 	switch (settings_menu[mp.settings_menu_pos].type) {
 		case SETTINGS_TYPE_BOOL:
-			settings_display_and_modify_bool(settings_menu[mp.settings_menu_pos].index, settings_menu[mp.settings_menu_pos].name, 0, HAVE_PREV_SETTING_POSITION, HAVE_NEXT_SETTING_POSITION);
+			settings_display_and_modify_bool(mp.settings_menu_pos, 0);
+			break;
+		case SETTINGS_TYPE_U8:
+			settings_display_and_modify_u8(mp.settings_menu_pos, 0);
 			break;
 		case SETTINGS_TYPE_BACK:
 			strcpy_P(disp.line1, PSTR("* Ustawienia *"));

+ 0 - 9
soft/working_modes.h

@@ -5,19 +5,10 @@
 #define MODE_MAIN_MENU	1
 #define MODE_SETTINGS_MENU	2
 
-#define SETTINGS_TYPE_BACK	0
-#define SETTINGS_TYPE_BOOL	1
-
 struct main_menu_pos_s {
 	unsigned char (* func)(void);
 };
 
-struct settings_menu_pos_s {
-	unsigned char type;
-	__flash const char *name;
-	unsigned char index;
-};
-
 struct menu_params_s {
 	unsigned char main_menu_pos;
 	unsigned char settings_menu_pos;