Преглед изворни кода

- temperature logging
- battery voltage logging
- battery voltage display
- ensure local time in filenames
- some display messages
- add CPU sleep
- add bootloader calling
- change xtal frequency
- change uart speed to 230400

k4be пре 3 година
родитељ
комит
85d8d83418
6 измењених фајлова са 180 додато и 37 уклоњено
  1. 1 1
      soft/Makefile
  2. 5 10
      soft/ds18b20.c
  3. 1 4
      soft/ds18b20.h
  4. 160 18
      soft/main.c
  5. 10 1
      soft/main.h
  6. 3 3
      soft/uart1.c

+ 1 - 1
soft/Makefile

@@ -19,7 +19,7 @@ OPTIMIZE = s
 LIBS	=
 LIBDIRS	=
 INCDIRS	=
-DEFS	= F_CPU=8000000
+DEFS	= F_CPU=7372800
 # DEFS	+= LEDR_UART
 ADEFS	=
 

+ 5 - 10
soft/ds18b20.c

@@ -18,14 +18,11 @@ union {
 
 #define MAX_ERRORS 5
 
-unsigned char temp_ok;
-signed int ds18b20_temp;
-
 void gettemp(void){
 	unsigned char i, crc=0, tmp;
 	static unsigned char error_cnt;
 	unsigned char temp_ok_out = 0;
-	signed int temp;
+	float temp;
 
 	if(System.timers.owire) return;
 
@@ -46,23 +43,21 @@ void gettemp(void){
 	}
 	if(!crc){
 		if(t.owbuffer[0] != 0x50 || t.owbuffer[1] != 0x05 || t.owbuffer[5] != 0xff || t.owbuffer[7] != 0x10){
-			temp = t.t;
-			temp *= (int)(0.625*16);
-			temp >>= 4;
-			ds18b20_temp = temp;
+			temp = (float)t.t*0.0625;
+			System.temperature = temp;
 			temp_ok_out = 1;
 		}
 	}
 
 	if(!temp_ok_out){
 		if(error_cnt > MAX_ERRORS){
-			temp_ok = 0;
+			System.temperature_ok = 0;
 		} else {
 			error_cnt++;
 		}
 	} else {
 		error_cnt = 0;
-		temp_ok = 1;
+		System.temperature_ok = 1;
 	}
 	
 	_1WireInit();

+ 1 - 4
soft/ds18b20.h

@@ -8,9 +8,6 @@
 #ifndef DS18B20_H_
 #define DS18B20_H_
 
-extern unsigned char temp_ok;
-extern float hs_temp;
-
 void gettemp(void);
 
-#endif /* DS18B20_H_ */
+#endif /* DS18B20_H_ */

+ 160 - 18
soft/main.c

@@ -8,6 +8,7 @@
 #include <avr/sleep.h>
 #include <util/delay.h>
 #include <avr/pgmspace.h>
+#include <avr/wdt.h>
 #include <string.h>
 #include "main.h"
 #include "ff.h"
@@ -37,6 +38,20 @@ char Line[100];				/* Line buffer */
 time_t utc;					/* current time */
 struct location_s location;
 
+void start_bootloader(void) {
+    typedef void (*do_reboot_t)(void);
+    const do_reboot_t do_reboot = (do_reboot_t)(0x7ffa >> 1);
+
+    cli();
+    LCD_Clear();
+    LCD_GoTo(0,0);
+    LCD_WriteTextP(PSTR("Aktualizacja"));
+    LCD_GoTo(8,1);
+    LCD_WriteTextP(PSTR("softu..."));
+    TCCR0A = TCCR1A = TCCR2A = 0; // make sure interrupts are off and timers are reset.
+    do_reboot();
+}
+
 /*---------------------------------------------------------*/
 /* 100Hz timer interrupt generated by OC1A                 */
 /*---------------------------------------------------------*/
@@ -84,24 +99,40 @@ ISR(TIMER1_COMPA_vect)
 	} else {
 		power_sw = 0;
 	}
+	
+	if (uart1_test() && uart1_get() == '0' && uart1_get() == ' '){
+	//if (!(PIND & _BV(PD5))) {
+		LEDB_ON();
+		start_bootloader();
+	}
 }
 
 
 /* Power supply monitor */
 ISR(ADC_vect)
 {
-	WORD ad;
+	float bat_volt;
+	static unsigned int adc_buf;
+	static unsigned char adc_cnt;
 	static BYTE lvt;
+	
+	adc_buf += ADC;
+	if(++adc_cnt < 15)
+		return;
 
-	ad = ADC * 16;
+	bat_volt = (float)adc_buf/(float)(adc_cnt)/VI_MULT;
+	adc_buf = 0;
+	adc_cnt = 0;
+	
+	System.bat_volt = bat_volt;
 	if (FLAGS & F_LVD) {
-		if (ad > (WORD)(VI_LVH * VI_MULT) * 16) {
+		if (bat_volt > VI_LVH) {
 			FLAGS &= ~F_LVD;
 			lvt = 0;
 		}
 	} else {
-		if (ad < (WORD)(VI_LVL * VI_MULT) * 16) {
-			if (++lvt >= 10)
+		if (bat_volt < VI_LVL) {
+			if (++lvt >= 3)
 				FLAGS |= F_LVD;
 		} else {
 			lvt = 0;
@@ -126,7 +157,12 @@ DWORD get_fattime (void)
            (DWORD)stm->tm_sec >> 1;
 }
 
-
+static void sleep(void) {
+	set_sleep_mode(SLEEP_MODE_IDLE);
+	sleep_enable();
+	sleep_cpu();
+	sleep_disable();
+}
 
 /*----------------------------------------------------*/
 /*  Get a line received from GPS module               */
@@ -147,8 +183,10 @@ UINT get_line (		/* 0:Brownout or timeout, >0: Number of bytes received. */
 			return 0;	/* A brownout is detected */
 		if (timer_expired(recv_timeout))
 			return 0; /* timeout; continue the main loop */
-		if (!uart0_test())
+		if (!uart0_test()) {
+			sleep();
 			continue;
+		}
 		c = (char)uart0_get();
 		uart1_put(c);
 		if (i == 0 && c != '$')
@@ -373,8 +411,6 @@ void ioinit (void)
 	TCCR1B = _BV(WGM12) | _BV(CS11);
 	TIMSK1 = _BV(OCIE1A);		/* Enable TC1.oca interrupt */
 
-	ACSR = _BV(ACD);		/* Disable analog comp */
-
 	/* ADC */
 //	ADMUX = 0;
 	ADMUX = 1; // FIXME only testing battery voltage
@@ -387,13 +423,78 @@ void ioinit (void)
 	expander_init(0, 0x00, 0x00); /* all as outputs */
 	LCD_Initialize();
 	LCD_Clear();
-	LCD_WriteTextP(PSTR("TEST"));
 
 	sei();
 	
 	ADCSRA |= _BV(ADSC);
+	
+	/* unused pins */
+	DDRA |= _BV(PA2) | _BV(PA4) | _BV(PA5);
+	PRR0 |= _BV(PRTIM2) | _BV(PRTIM0);
+	ACSR = _BV(ACD);		/* Disable analog comp */
 }
 
+__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,
+	},
+};
+
+void battery_state_display(void) {
+	unsigned char i;
+	unsigned char index;
+	if (System.bat_volt > 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;
+	
+	LCD_WriteCommand(0x40 + 0); // 0x00
+
+	for(i=0; i<8; i++){
+		LCD_WriteData(battery_states[index][i]);
+	};
+}
 
 __flash const char __open_msg[] = "Open %s\r\n";
 
@@ -404,19 +505,28 @@ __flash const char __open_msg[] = "Open %s\r\n";
 int main (void)
 {
 	UINT bw, len;
-	struct tm *ct;
+	static struct tm ct;
 	time_t tmp_utc, localtime;
 	FRESULT res;
 	unsigned char prev_status;
 
 	ioinit();
 	xdev_out(log_put);
-	
 	xputs_P(PSTR("STARTUP\r\n"));
+	LCD_GoTo(0,0);
+	LCD_WriteTextP(PSTR("Uruchamianie... "));
+	_delay_ms(3000);
 	
 	for (;;) {
-		if (FLAGS & F_POWEROFF) {
+		if (FLAGS & (F_POWEROFF | F_LVD)) {
 			xputs_P(PSTR("POWEROFF\r\n"));
+			LCD_GoTo(0,0);
+			LCD_WriteTextP(PSTR("Wylaczanie...   "));
+			if (FLAGS & F_LVD) {
+				LCD_GoTo(0,1);
+				LCD_WriteTextP(PSTR("Bateria slaba!  "));
+				_delay_ms(500);
+			}
 			POWEROFF();
 			while (POWER_SW_PRESSED());
 			_delay_ms(2000); /* wait for switch off */
@@ -425,6 +535,19 @@ int main (void)
 			xputs_P(PSTR("RESTART\r\n"));
 		}
 
+		LCD_GoTo(0,0);
+		LCD_WriteTextP(PSTR("Start           "));
+		LCD_GoTo(0,1);
+		switch(System.status){
+			case STATUS_NO_POWER: case STATUS_OK: case STATUS_NO_GPS: LCD_WriteTextP(PSTR("                ")); break;
+			case STATUS_NO_DISK:			LCD_WriteTextP(PSTR("Brak karty!     ")); break;
+			case STATUS_DISK_ERROR:			LCD_WriteTextP(PSTR("Blad karty!     ")); break;
+			case STATUS_FILE_WRITE_ERROR:	LCD_WriteTextP(PSTR("Blad zapisu!    ")); break;
+			case STATUS_FILE_SYNC_ERROR:	LCD_WriteTextP(PSTR("Blad zapisu FAT!")); break;
+			case STATUS_FILE_CLOSE_ERROR:	LCD_WriteTextP(PSTR("Blad zamk.pliku!")); break;
+			case STATUS_FILE_OPEN_ERROR:	LCD_WriteTextP(PSTR("Blad otw. pliku!")); break;
+		}
+
 		xprintf(PSTR("LOOP err=%u\r\n"), (unsigned int)System.status);
 		utc = 0;
 		localtime = 0;
@@ -434,7 +557,6 @@ int main (void)
 		beep(250, prev_status);	/* Error beep */
 
 		/* Wait for supply voltage stabled */
-		while (FLAGS & F_LVD) {};
 		_delay_ms(500);
 		if (FLAGS & F_LVD)
 			continue;
@@ -454,6 +576,11 @@ int main (void)
 		}
 		System.status = STATUS_NO_GPS;
 		xputs(PSTR("FS Ok\r\n"));
+		LCD_GoTo(0,0);
+		LCD_WriteTextP(PSTR("Karta OK!      "));
+		LCD_WriteData(0); /* battery symbol */
+		LCD_GoTo(0,1);
+		LCD_WriteTextP(PSTR("Czekam na GPS..."));
 		beep(50, 1);				/* 1 beep */
 
 		/* Initialize GPS receiver */
@@ -464,7 +591,9 @@ int main (void)
 //		xfprintf(uart0_put, PSTR("$PSRF106,21*0F\r\n"));	/* Send initialization command (depends on the receiver) */
 
 		for (;;) { /* main loop */
+			battery_state_display();
 			gettemp();
+
 			if (!(FLAGS & F_GPSOK))
 				xputs_P(PSTR("Waiting for GPS\r\n"));
 			len = get_line(Line, sizeof Line);	/* Receive a line from GPS receiver */
@@ -477,14 +606,23 @@ int main (void)
 			tmp_utc = gp_rmctime(Line);
 			if (tmp_utc) {
 				localtime = tmp_utc + LOCALDIFF * 3600L;	/* Local time */
+				ct = *gmtime(&localtime);
+				if (timer_expired(system_log)) {
+					set_timer(system_log, 5000);
+					xprintf(PSTR("Time: %u.%02u.%04u %u:%02u:%02u\r\n"), ct.tm_mday, ct.tm_mon + 1, ct.tm_year+1900, ct.tm_hour, ct.tm_min, ct.tm_sec);
+					xprintf(PSTR("Bat volt: %.3f\r\n"), System.bat_volt);
+					if (System.temperature_ok)
+						xprintf(PSTR("Temp: %.2f\r\n"), System.temperature);
+					else
+						xputs_P(PSTR("Temperature unknown\r\n"));
+				}
 				LEDG_ON();
 				_delay_ms(2);
 				LEDG_OFF();
 			}
 
 			if (localtime && !(FLAGS & F_FILEOPEN)) {
-				ct = gmtime(&localtime);
-				xsprintf(Line, PSTR("%04u-%02u-%02u_%02u-%02u.LOG"), ct->tm_year+1900, ct->tm_mon + 1, ct->tm_mday, ct->tm_hour, ct->tm_min);
+				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);
 				xprintf(__open_msg, Line);
 				if (f_open(&gps_log, Line, FA_WRITE | FA_OPEN_ALWAYS)		/* Open log file */
 					|| f_lseek(&gps_log, f_size(&gps_log)) 					/* Append mode */
@@ -494,7 +632,7 @@ int main (void)
 					break;	/* Failed to start logging */
 				}
 
-				xsprintf(Line, PSTR("%04u-%02u-%02u_%02u-%02u-%02u.GPX"), ct->tm_year+1900, ct->tm_mon + 1, ct->tm_mday, ct->tm_hour, ct->tm_min, ct->tm_sec);
+				xsprintf(Line, PSTR("%04u-%02u-%02u_%02u-%02u-%02u.GPX"), ct.tm_year+1900, ct.tm_mon + 1, ct.tm_mday, ct.tm_hour, ct.tm_min, ct.tm_sec);
 				xprintf(__open_msg, Line);
 				if (f_open(&gpx_file, Line, FA_WRITE | FA_OPEN_ALWAYS)		/* Open log file */
 					|| f_lseek(&gpx_file, f_size(&gpx_file)) 				/* Append mode */
@@ -505,7 +643,7 @@ int main (void)
 					break;	/* Failed to start logging */
 				}
 
-				xsprintf(Line, PSTR("%04u-%02u-%02u_%02u-%02u-SYSTEM.LOG"), ct->tm_year+1900, ct->tm_mon + 1, ct->tm_mday, ct->tm_hour, ct->tm_min);
+				xsprintf(Line, PSTR("%04u-%02u-%02u_%02u-%02u-%02u-SYSTEM.LOG"), ct.tm_year+1900, ct.tm_mon + 1, ct.tm_mday, ct.tm_hour, ct.tm_min, ct.tm_sec);
 				xprintf(__open_msg, Line);
 				if (f_open(&system_log, Line, FA_WRITE | FA_OPEN_ALWAYS)	/* Open log file */
 					|| f_lseek(&system_log, f_size(&system_log)) 			/* Append mode */
@@ -520,6 +658,8 @@ int main (void)
 				FLAGS |= F_FILEOPEN;
 				System.status = STATUS_OK;
 				beep(50, 2);		/* Two beeps. Start logging. */
+				LCD_GoTo(0,1);
+				LCD_WriteTextP(PSTR("Zapis aktywny   "));
 				continue;
 			}
 			if (FLAGS & F_FILEOPEN) {
@@ -557,6 +697,8 @@ int main (void)
 			if (f_close(&system_log))
 				System.status = STATUS_FILE_CLOSE_ERROR;
 			xputs_P(PSTR("File closed\r\n"));
+			LCD_GoTo(0,1);
+			LCD_WriteTextP(PSTR("Pliki zamkniete "));
 		}
 		FLAGS &= ~F_FILEOPEN;
 		disk_ioctl(0, CTRL_POWER, 0);

+ 10 - 1
soft/main.h

@@ -13,7 +13,7 @@
 
 //#define	VI_LVL		4.2			/* Blackout threshold [volt] */
 //#define	VI_LVH		4.8			/* Recharge threshold [volt] */
-#define	VI_LVL		2.9			/* Blackout threshold [volt] */
+#define	VI_LVL		3.1			/* Blackout threshold [volt] */
 #define	VI_LVH		3.4			/* Recharge threshold [volt] */
 #define	VI_MULT		(3.3 / 6.6 / 2.495 * 1024)
 
@@ -56,6 +56,9 @@
 #define LEDG_PORT		1 /* expander */
 #define LEDG			_BV(4)
 
+#define LEDB_PORT		1 /* expander */
+#define LEDB			_BV(5)
+
 /* on/off macros */
 
 #define	BEEP_ON()		{BUZZER_PORT |= BUZZER;}
@@ -64,6 +67,8 @@
 #define LEDR_OFF()		{LEDR_PORT &= ~LEDR;}
 #define	LEDG_ON()		expander_set_bit(LEDG_PORT, LEDG, 1)
 #define	LEDG_OFF()		expander_set_bit(LEDG_PORT, LEDG, 0)
+#define	LEDB_ON()		expander_set_bit(LEDB_PORT, LEDB, 1)
+#define	LEDB_OFF()		expander_set_bit(LEDB_PORT, LEDB, 0)
 #define GPS_ON()		{GPS_DIS_PORT &= ~GPS_DIS;}
 #define GPS_OFF()		{GPS_DIS_PORT |= GPS_DIS;}
 #define POWEROFF()		{POWER_ON_PORT &= ~POWER_ON;}
@@ -101,12 +106,16 @@ struct timers {
 	unsigned int owire;
 	unsigned int beep;
 	unsigned int recv_timeout;
+	unsigned int system_log;
 };
 
 struct system_s {
 	struct timers timers;
 	unsigned int global_error;
 	unsigned char status;
+	float bat_volt;
+	float temperature;
+	unsigned char temperature_ok;
 };
 
 

+ 3 - 3
soft/uart1.c

@@ -6,10 +6,10 @@
 #include <avr/interrupt.h>
 #include "uart1.h"
 
-#define	UART1_BAUD		38400
+#define	UART1_BAUD		230400
 #define	USE_TXINT		1
-#define	SZ_FIFO			128
-#define RECEIVE			0
+#define	SZ_FIFO			64
+#define RECEIVE			1
 
 #if SZ_FIFO >= 256
 typedef uint16_t	idx_t;