|
@@ -6,6 +6,7 @@
|
|
|
#include <avr/io.h>
|
|
|
#include <avr/interrupt.h>
|
|
|
#include <avr/sleep.h>
|
|
|
+#include <util/delay.h>
|
|
|
#include <string.h>
|
|
|
#include "main.h"
|
|
|
#include "ff.h"
|
|
@@ -14,6 +15,10 @@
|
|
|
#include "uart1.h"
|
|
|
#include "xitoa.h"
|
|
|
#include "stime.h"
|
|
|
+#include "ds18b20.h"
|
|
|
+#include "I2C.h"
|
|
|
+#include "expander.h"
|
|
|
+#include "HD44780-I2C.h"
|
|
|
|
|
|
|
|
|
FUSES = {0xFF, 0x11, 0xFE}; /* ATmega644PA fuses: Low, High, Extended.
|
|
@@ -22,25 +27,27 @@ in the output hex file with program code. However some old flash programmers
|
|
|
cannot load the fuse bits from hex file. If it is the case, remove this line
|
|
|
and use these values to program the fuse bits. */
|
|
|
|
|
|
+volatile struct system_s System;
|
|
|
FATFS Fatfs; /* File system object for each logical drive */
|
|
|
FIL File1; /* File object */
|
|
|
char Line[100]; /* Line buffer */
|
|
|
|
|
|
-volatile BYTE Timer; /* 100Hz decrement timer */
|
|
|
-
|
|
|
/*---------------------------------------------------------*/
|
|
|
/* 100Hz timer interrupt generated by OC1A */
|
|
|
/*---------------------------------------------------------*/
|
|
|
|
|
|
ISR(TIMER1_COMPA_vect)
|
|
|
{
|
|
|
- BYTE n;
|
|
|
static WORD ivt_sync;
|
|
|
static BYTE led;
|
|
|
-
|
|
|
-
|
|
|
- n = Timer;
|
|
|
- if (n) Timer = --n;;
|
|
|
+ unsigned int *volatile ctimer;
|
|
|
+ unsigned char i;
|
|
|
+
|
|
|
+ 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;
|
|
|
+ if(*ctimer)
|
|
|
+ (*ctimer)--;
|
|
|
+ }
|
|
|
|
|
|
/* Sync interval */
|
|
|
if (IVT_SYNC && ++ivt_sync >= IVT_SYNC * 100) {
|
|
@@ -109,16 +116,24 @@ UINT get_line ( /* 0:Brownout, >0: Number of bytes received. */
|
|
|
char c;
|
|
|
UINT i = 0;
|
|
|
|
|
|
+ set_timer(recv_timeout, 1000);
|
|
|
|
|
|
for (;;) {
|
|
|
- if (FLAGS & F_LVD) return 0; /* A brownout is detected */
|
|
|
- if (!uart0_test()) continue;
|
|
|
+ if (FLAGS & F_LVD)
|
|
|
+ return 0; /* A brownout is detected */
|
|
|
+ if (timer_expired(recv_timeout))
|
|
|
+ return 0; /* timeout; continue the main loop */
|
|
|
+ if (!uart0_test())
|
|
|
+ continue;
|
|
|
c = (char)uart0_get();
|
|
|
xputc(c);
|
|
|
- if (i == 0 && c != '$') continue; /* Find start of line */
|
|
|
+ if (i == 0 && c != '$')
|
|
|
+ continue; /* Find start of line */
|
|
|
buff[i++] = c;
|
|
|
- if (c == '\n') break; /* EOL */
|
|
|
- if (i >= sz_buf) i = 0; /* Buffer overflow (abort this line) */
|
|
|
+ if (c == '\n')
|
|
|
+ break; /* EOL */
|
|
|
+ if (i >= sz_buf)
|
|
|
+ i = 0; /* Buffer overflow (abort this line) */
|
|
|
}
|
|
|
|
|
|
return i;
|
|
@@ -133,9 +148,11 @@ void beep (UINT len, BYTE cnt)
|
|
|
{
|
|
|
while (cnt--) {
|
|
|
BEEP_ON();
|
|
|
- DELAY_MS(len);
|
|
|
+ set_timer(beep, len);
|
|
|
+ while(!timer_expired(beep)) {};
|
|
|
BEEP_OFF();
|
|
|
- DELAY_MS(len);
|
|
|
+ set_timer(beep, len);
|
|
|
+ while(!timer_expired(beep)) {};
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -185,9 +202,11 @@ BYTE gp_val2 (
|
|
|
|
|
|
|
|
|
n = db[0] - '0';
|
|
|
- if (n >= 10) return 0;
|
|
|
+ if (n >= 10)
|
|
|
+ return 0;
|
|
|
m = db[1] - '0';
|
|
|
- if (m >= 10) return 0;
|
|
|
+ if (m >= 10)
|
|
|
+ return 0;
|
|
|
|
|
|
return n * 10 + m;
|
|
|
}
|
|
@@ -205,7 +224,8 @@ time_t gp_rmctime ( /* Get GPS status from RMC sentence */
|
|
|
time_t utc;
|
|
|
|
|
|
|
|
|
- if (gp_comp(str, PSTR("$GPRMC"))) return 0; /* Not the RMC */
|
|
|
+ if (gp_comp(str, PSTR("$GPRMC")))
|
|
|
+ return 0; /* Not the RMC */
|
|
|
|
|
|
p = gp_col(str, 2); /* Get status */
|
|
|
if (!p || *p != 'A') {
|
|
@@ -214,19 +234,22 @@ time_t gp_rmctime ( /* Get GPS status from RMC sentence */
|
|
|
}
|
|
|
|
|
|
p = gp_col(str, 1); /* Get h:m:s */
|
|
|
- if (!p) return 0;
|
|
|
+ if (!p)
|
|
|
+ return 0;
|
|
|
tmc.tm_hour = gp_val2(p);
|
|
|
tmc.tm_min = gp_val2(p+2);
|
|
|
tmc.tm_sec = gp_val2(p+4);
|
|
|
|
|
|
p = gp_col(str, 9); /* Get y:m:d */
|
|
|
- if (!p) return 0;
|
|
|
+ if (!p)
|
|
|
+ return 0;
|
|
|
tmc.tm_mday = gp_val2(p);
|
|
|
tmc.tm_mon = gp_val2(p+2) - 1;
|
|
|
tmc.tm_year = gp_val2(p+4) + 100;
|
|
|
|
|
|
utc = mktime(&tmc); /* Check time validity */
|
|
|
- if (utc == -1) return 0;
|
|
|
+ if (utc == -1)
|
|
|
+ return 0;
|
|
|
|
|
|
FLAGS |= F_GPSOK;
|
|
|
return utc;
|
|
@@ -238,14 +261,9 @@ time_t gp_rmctime ( /* Get GPS status from RMC sentence */
|
|
|
static
|
|
|
void ioinit (void)
|
|
|
{
|
|
|
- PORTB = 0b00000011; /* --zzzzHH */
|
|
|
- DDRB = 0b00000011;
|
|
|
-
|
|
|
- PORTC = 0b00111101; /* --uuuuLH */
|
|
|
- DDRC = 0b00000011;
|
|
|
-
|
|
|
- PORTD = 0b10111110; /* uLuuuuHz */
|
|
|
- DDRD = 0b01000010;
|
|
|
+ BUZZER_DDR |= BUZZER;
|
|
|
+ GPS_DIS_DDR |= GPS_DIS;
|
|
|
+ LEDR_DDR |= LEDR;
|
|
|
|
|
|
OCR1A = F_CPU/8/100-1; /* Timer1: 100Hz interval (OC1A) */
|
|
|
TCCR1B = _BV(WGM12) | _BV(CS11);
|
|
@@ -259,6 +277,11 @@ void ioinit (void)
|
|
|
|
|
|
/* uart1 (debug) */
|
|
|
uart1_init();
|
|
|
+
|
|
|
+ I2C_init();
|
|
|
+ expander_init(0, 0x00, 0x00); /* all as outputs */
|
|
|
+ LCD_Initialize();
|
|
|
+ LCD_Clear();
|
|
|
|
|
|
sei();
|
|
|
}
|
|
@@ -276,7 +299,6 @@ int main (void)
|
|
|
time_t utc;
|
|
|
FRESULT res;
|
|
|
|
|
|
-
|
|
|
ioinit();
|
|
|
xdev_out(uart1_put);
|
|
|
|
|
@@ -287,14 +309,17 @@ int main (void)
|
|
|
|
|
|
/* Wait for supply voltage stabled */
|
|
|
while (FLAGS & F_LVD) {};
|
|
|
- DELAY_MS(500);
|
|
|
- if (FLAGS & F_LVD) continue;
|
|
|
- if (disk_status(0) & STA_NODISK) continue;
|
|
|
+ _delay_ms(500);
|
|
|
+ if (FLAGS & F_LVD)
|
|
|
+ continue;
|
|
|
+ if (disk_status(0) & STA_NODISK)
|
|
|
+ continue;
|
|
|
|
|
|
res = f_mount(&Fatfs, "", 1);
|
|
|
if (res != FR_OK) {
|
|
|
xprintf(PSTR("FS error %u\r\n"), res);
|
|
|
- err = 2; continue;
|
|
|
+ err = 2;
|
|
|
+ continue;
|
|
|
}
|
|
|
xputs(PSTR("FS Ok\r\n"));
|
|
|
beep(50, 1); /* 1 beep */
|
|
@@ -302,14 +327,16 @@ int main (void)
|
|
|
/* Initialize GPS receiver */
|
|
|
GPS_ON(); /* GPS power on */
|
|
|
FLAGS |= F_POW;
|
|
|
- DELAY_MS(300); /* Delay */
|
|
|
+ _delay_ms(300); /* Delay */
|
|
|
uart0_init(); /* Enable UART */
|
|
|
// xfprintf(uart0_put, PSTR("$PSRF106,21*0F\r\n")); /* Send initialization command (depends on the receiver) */
|
|
|
|
|
|
utc = 0;
|
|
|
- for (;;) {
|
|
|
+ for (;;) { /* main loop */
|
|
|
+ gettemp();
|
|
|
len = get_line(Line, sizeof Line); /* Receive a line from GPS receiver */
|
|
|
- if (!len) break; /* Brownout? */
|
|
|
+ if (!len) continue;
|
|
|
+ if (FLAGS & F_LVD) break; /* brownout */
|
|
|
|
|
|
if (!utc) {
|
|
|
utc = gp_rmctime(Line); /* Get time in UTC from a valid RMC sentence */
|
|
@@ -322,7 +349,9 @@ int main (void)
|
|
|
|| f_lseek(&File1, f_size(&File1)) /* Append mode */
|
|
|
|| f_write(&File1, "\r\n", 2, &bw)) /* Put a blank line as start marker */
|
|
|
{
|
|
|
- utc = 0; err = 2; break; /* Failed to start logging */
|
|
|
+ utc = 0;
|
|
|
+ err = 2;
|
|
|
+ break; /* Failed to start logging */
|
|
|
}
|
|
|
beep(50, 2); /* Two beeps. Start logging. */
|
|
|
}
|
|
@@ -330,11 +359,13 @@ int main (void)
|
|
|
gp_rmctime(Line);
|
|
|
f_write(&File1, Line, len, &bw);
|
|
|
if (bw != len) {
|
|
|
- err = 3; break;
|
|
|
+ err = 3;
|
|
|
+ break;
|
|
|
}
|
|
|
if (FLAGS & F_SYNC) {
|
|
|
if (f_sync(&File1)) {
|
|
|
- err = 2; break;
|
|
|
+ err = 2;
|
|
|
+ break;
|
|
|
}
|
|
|
FLAGS &= ~F_SYNC;
|
|
|
}
|
|
@@ -347,9 +378,11 @@ int main (void)
|
|
|
FLAGS &= ~F_POW;
|
|
|
|
|
|
/* Close file */
|
|
|
- if (utc && f_close(&File1)) err = 2;
|
|
|
+ if (utc && f_close(&File1))
|
|
|
+ err = 2;
|
|
|
disk_ioctl(0, CTRL_POWER_OFF, 0);
|
|
|
- if (!err) beep(500, 1); /* Long beep on file close succeeded */
|
|
|
+ if (!err)
|
|
|
+ beep(500, 1); /* Long beep on file close succeeded */
|
|
|
}
|
|
|
|
|
|
}
|