|
@@ -8,6 +8,7 @@
|
|
#include <avr/sleep.h>
|
|
#include <avr/sleep.h>
|
|
#include <util/delay.h>
|
|
#include <util/delay.h>
|
|
#include <avr/pgmspace.h>
|
|
#include <avr/pgmspace.h>
|
|
|
|
+#include <avr/wdt.h>
|
|
#include <string.h>
|
|
#include <string.h>
|
|
#include "main.h"
|
|
#include "main.h"
|
|
#include "ff.h"
|
|
#include "ff.h"
|
|
@@ -37,6 +38,20 @@ char Line[100]; /* Line buffer */
|
|
time_t utc; /* current time */
|
|
time_t utc; /* current time */
|
|
struct location_s location;
|
|
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 */
|
|
/* 100Hz timer interrupt generated by OC1A */
|
|
/*---------------------------------------------------------*/
|
|
/*---------------------------------------------------------*/
|
|
@@ -84,24 +99,40 @@ ISR(TIMER1_COMPA_vect)
|
|
} else {
|
|
} else {
|
|
power_sw = 0;
|
|
power_sw = 0;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (uart1_test() && uart1_get() == '0' && uart1_get() == ' '){
|
|
|
|
+ //if (!(PIND & _BV(PD5))) {
|
|
|
|
+ LEDB_ON();
|
|
|
|
+ start_bootloader();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Power supply monitor */
|
|
/* Power supply monitor */
|
|
ISR(ADC_vect)
|
|
ISR(ADC_vect)
|
|
{
|
|
{
|
|
- WORD ad;
|
|
|
|
|
|
+ float bat_volt;
|
|
|
|
+ static unsigned int adc_buf;
|
|
|
|
+ static unsigned char adc_cnt;
|
|
static BYTE lvt;
|
|
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 (FLAGS & F_LVD) {
|
|
- if (ad > (WORD)(VI_LVH * VI_MULT) * 16) {
|
|
|
|
|
|
+ if (bat_volt > VI_LVH) {
|
|
FLAGS &= ~F_LVD;
|
|
FLAGS &= ~F_LVD;
|
|
lvt = 0;
|
|
lvt = 0;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- if (ad < (WORD)(VI_LVL * VI_MULT) * 16) {
|
|
|
|
- if (++lvt >= 10)
|
|
|
|
|
|
+ if (bat_volt < VI_LVL) {
|
|
|
|
+ if (++lvt >= 3)
|
|
FLAGS |= F_LVD;
|
|
FLAGS |= F_LVD;
|
|
} else {
|
|
} else {
|
|
lvt = 0;
|
|
lvt = 0;
|
|
@@ -126,7 +157,12 @@ DWORD get_fattime (void)
|
|
(DWORD)stm->tm_sec >> 1;
|
|
(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 */
|
|
/* 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 */
|
|
return 0; /* A brownout is detected */
|
|
if (timer_expired(recv_timeout))
|
|
if (timer_expired(recv_timeout))
|
|
return 0; /* timeout; continue the main loop */
|
|
return 0; /* timeout; continue the main loop */
|
|
- if (!uart0_test())
|
|
|
|
|
|
+ if (!uart0_test()) {
|
|
|
|
+ sleep();
|
|
continue;
|
|
continue;
|
|
|
|
+ }
|
|
c = (char)uart0_get();
|
|
c = (char)uart0_get();
|
|
uart1_put(c);
|
|
uart1_put(c);
|
|
if (i == 0 && c != '$')
|
|
if (i == 0 && c != '$')
|
|
@@ -373,8 +411,6 @@ void ioinit (void)
|
|
TCCR1B = _BV(WGM12) | _BV(CS11);
|
|
TCCR1B = _BV(WGM12) | _BV(CS11);
|
|
TIMSK1 = _BV(OCIE1A); /* Enable TC1.oca interrupt */
|
|
TIMSK1 = _BV(OCIE1A); /* Enable TC1.oca interrupt */
|
|
|
|
|
|
- ACSR = _BV(ACD); /* Disable analog comp */
|
|
|
|
-
|
|
|
|
/* ADC */
|
|
/* ADC */
|
|
// ADMUX = 0;
|
|
// ADMUX = 0;
|
|
ADMUX = 1; // FIXME only testing battery voltage
|
|
ADMUX = 1; // FIXME only testing battery voltage
|
|
@@ -387,13 +423,78 @@ void ioinit (void)
|
|
expander_init(0, 0x00, 0x00); /* all as outputs */
|
|
expander_init(0, 0x00, 0x00); /* all as outputs */
|
|
LCD_Initialize();
|
|
LCD_Initialize();
|
|
LCD_Clear();
|
|
LCD_Clear();
|
|
- LCD_WriteTextP(PSTR("TEST"));
|
|
|
|
|
|
|
|
sei();
|
|
sei();
|
|
|
|
|
|
ADCSRA |= _BV(ADSC);
|
|
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";
|
|
__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)
|
|
int main (void)
|
|
{
|
|
{
|
|
UINT bw, len;
|
|
UINT bw, len;
|
|
- struct tm *ct;
|
|
|
|
|
|
+ static struct tm ct;
|
|
time_t tmp_utc, localtime;
|
|
time_t tmp_utc, localtime;
|
|
FRESULT res;
|
|
FRESULT res;
|
|
unsigned char prev_status;
|
|
unsigned char prev_status;
|
|
|
|
|
|
ioinit();
|
|
ioinit();
|
|
xdev_out(log_put);
|
|
xdev_out(log_put);
|
|
-
|
|
|
|
xputs_P(PSTR("STARTUP\r\n"));
|
|
xputs_P(PSTR("STARTUP\r\n"));
|
|
|
|
+ LCD_GoTo(0,0);
|
|
|
|
+ LCD_WriteTextP(PSTR("Uruchamianie... "));
|
|
|
|
+ _delay_ms(3000);
|
|
|
|
|
|
for (;;) {
|
|
for (;;) {
|
|
- if (FLAGS & F_POWEROFF) {
|
|
|
|
|
|
+ if (FLAGS & (F_POWEROFF | F_LVD)) {
|
|
xputs_P(PSTR("POWEROFF\r\n"));
|
|
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();
|
|
POWEROFF();
|
|
while (POWER_SW_PRESSED());
|
|
while (POWER_SW_PRESSED());
|
|
_delay_ms(2000); /* wait for switch off */
|
|
_delay_ms(2000); /* wait for switch off */
|
|
@@ -425,6 +535,19 @@ int main (void)
|
|
xputs_P(PSTR("RESTART\r\n"));
|
|
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);
|
|
xprintf(PSTR("LOOP err=%u\r\n"), (unsigned int)System.status);
|
|
utc = 0;
|
|
utc = 0;
|
|
localtime = 0;
|
|
localtime = 0;
|
|
@@ -434,7 +557,6 @@ int main (void)
|
|
beep(250, prev_status); /* Error beep */
|
|
beep(250, prev_status); /* Error beep */
|
|
|
|
|
|
/* Wait for supply voltage stabled */
|
|
/* Wait for supply voltage stabled */
|
|
- while (FLAGS & F_LVD) {};
|
|
|
|
_delay_ms(500);
|
|
_delay_ms(500);
|
|
if (FLAGS & F_LVD)
|
|
if (FLAGS & F_LVD)
|
|
continue;
|
|
continue;
|
|
@@ -454,6 +576,11 @@ int main (void)
|
|
}
|
|
}
|
|
System.status = STATUS_NO_GPS;
|
|
System.status = STATUS_NO_GPS;
|
|
xputs(PSTR("FS Ok\r\n"));
|
|
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 */
|
|
beep(50, 1); /* 1 beep */
|
|
|
|
|
|
/* Initialize GPS receiver */
|
|
/* 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) */
|
|
// xfprintf(uart0_put, PSTR("$PSRF106,21*0F\r\n")); /* Send initialization command (depends on the receiver) */
|
|
|
|
|
|
for (;;) { /* main loop */
|
|
for (;;) { /* main loop */
|
|
|
|
+ battery_state_display();
|
|
gettemp();
|
|
gettemp();
|
|
|
|
+
|
|
if (!(FLAGS & F_GPSOK))
|
|
if (!(FLAGS & F_GPSOK))
|
|
xputs_P(PSTR("Waiting for GPS\r\n"));
|
|
xputs_P(PSTR("Waiting for GPS\r\n"));
|
|
len = get_line(Line, sizeof Line); /* Receive a line from GPS receiver */
|
|
len = get_line(Line, sizeof Line); /* Receive a line from GPS receiver */
|
|
@@ -477,14 +606,23 @@ int main (void)
|
|
tmp_utc = gp_rmctime(Line);
|
|
tmp_utc = gp_rmctime(Line);
|
|
if (tmp_utc) {
|
|
if (tmp_utc) {
|
|
localtime = tmp_utc + LOCALDIFF * 3600L; /* Local time */
|
|
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();
|
|
LEDG_ON();
|
|
_delay_ms(2);
|
|
_delay_ms(2);
|
|
LEDG_OFF();
|
|
LEDG_OFF();
|
|
}
|
|
}
|
|
|
|
|
|
if (localtime && !(FLAGS & F_FILEOPEN)) {
|
|
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);
|
|
xprintf(__open_msg, Line);
|
|
if (f_open(&gps_log, Line, FA_WRITE | FA_OPEN_ALWAYS) /* Open log file */
|
|
if (f_open(&gps_log, Line, FA_WRITE | FA_OPEN_ALWAYS) /* Open log file */
|
|
|| f_lseek(&gps_log, f_size(&gps_log)) /* Append mode */
|
|
|| f_lseek(&gps_log, f_size(&gps_log)) /* Append mode */
|
|
@@ -494,7 +632,7 @@ int main (void)
|
|
break; /* Failed to start logging */
|
|
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);
|
|
xprintf(__open_msg, Line);
|
|
if (f_open(&gpx_file, Line, FA_WRITE | FA_OPEN_ALWAYS) /* Open log file */
|
|
if (f_open(&gpx_file, Line, FA_WRITE | FA_OPEN_ALWAYS) /* Open log file */
|
|
|| f_lseek(&gpx_file, f_size(&gpx_file)) /* Append mode */
|
|
|| f_lseek(&gpx_file, f_size(&gpx_file)) /* Append mode */
|
|
@@ -505,7 +643,7 @@ int main (void)
|
|
break; /* Failed to start logging */
|
|
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);
|
|
xprintf(__open_msg, Line);
|
|
if (f_open(&system_log, Line, FA_WRITE | FA_OPEN_ALWAYS) /* Open log file */
|
|
if (f_open(&system_log, Line, FA_WRITE | FA_OPEN_ALWAYS) /* Open log file */
|
|
|| f_lseek(&system_log, f_size(&system_log)) /* Append mode */
|
|
|| f_lseek(&system_log, f_size(&system_log)) /* Append mode */
|
|
@@ -520,6 +658,8 @@ int main (void)
|
|
FLAGS |= F_FILEOPEN;
|
|
FLAGS |= F_FILEOPEN;
|
|
System.status = STATUS_OK;
|
|
System.status = STATUS_OK;
|
|
beep(50, 2); /* Two beeps. Start logging. */
|
|
beep(50, 2); /* Two beeps. Start logging. */
|
|
|
|
+ LCD_GoTo(0,1);
|
|
|
|
+ LCD_WriteTextP(PSTR("Zapis aktywny "));
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
if (FLAGS & F_FILEOPEN) {
|
|
if (FLAGS & F_FILEOPEN) {
|
|
@@ -557,6 +697,8 @@ int main (void)
|
|
if (f_close(&system_log))
|
|
if (f_close(&system_log))
|
|
System.status = STATUS_FILE_CLOSE_ERROR;
|
|
System.status = STATUS_FILE_CLOSE_ERROR;
|
|
xputs_P(PSTR("File closed\r\n"));
|
|
xputs_P(PSTR("File closed\r\n"));
|
|
|
|
+ LCD_GoTo(0,1);
|
|
|
|
+ LCD_WriteTextP(PSTR("Pliki zamkniete "));
|
|
}
|
|
}
|
|
FLAGS &= ~F_FILEOPEN;
|
|
FLAGS &= ~F_FILEOPEN;
|
|
disk_ioctl(0, CTRL_POWER, 0);
|
|
disk_ioctl(0, CTRL_POWER, 0);
|