Add GPS time synchronisation

This commit is contained in:
eddyem 2015-08-03 17:36:47 +03:00
parent 5932bfe614
commit 589d00fd4e
6 changed files with 62 additions and 7 deletions

Binary file not shown.

View File

@ -163,7 +163,6 @@ uint8_t *nextpos(uint8_t **buf, int pos){
*/ */
void GPS_parse_answer(uint8_t *buf){ void GPS_parse_answer(uint8_t *buf){
uint8_t *ptr; uint8_t *ptr;
DBG(buf);
if(strncmp(buf+3, U("RMC"), 3)){ // not RMC message if(strncmp(buf+3, U("RMC"), 3)){ // not RMC message
GPS_send_start_seq(); GPS_send_start_seq();
return; return;

View File

@ -68,7 +68,7 @@ void GPIO_init(){
*/ */
void SysTick_init(){ void SysTick_init(){
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); // Systyck: 72/8=9MHz systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); // Systyck: 72/8=9MHz
STK_RVR = 8999; // 9000 pulses: 1kHz STK_RVR = STK_RVR_DEFAULT_VAL; // 9000 pulses: 1kHz
systick_interrupt_enable(); systick_interrupt_enable();
systick_counter_enable(); systick_counter_enable();
} }

View File

@ -31,6 +31,13 @@ volatile uint32_t systick_val = 0;
volatile uint32_t timer_val = 0; volatile uint32_t timer_val = 0;
volatile int clear_ST_on_connect = 1; volatile int clear_ST_on_connect = 1;
volatile int need_sync = 1;
volatile uint32_t last_corr_time = 0; // time of last PPS correction (seconds from midnight)
// STK_CVR values for all milliseconds (RVR0) and last millisecond (RVR1)
volatile uint32_t RVR0 = STK_RVR_DEFAULT_VAL, RVR1 = STK_RVR_DEFAULT_VAL;
curtime current_time = {25,61,61}; curtime current_time = {25,61,61};
void time_increment(){ void time_increment(){
@ -76,6 +83,7 @@ int main(){
usbdatalen = parce_incoming_buf(usbdatabuf, usbdatalen); usbdatalen = parce_incoming_buf(usbdatabuf, usbdatalen);
} }
if((string = check_UART2())){ if((string = check_UART2())){
P(string);
GPS_parse_answer(string); GPS_parse_answer(string);
} }
if(systick_val){ if(systick_val){
@ -84,6 +92,10 @@ int main(){
systick_val = 0; systick_val = 0;
P(", timer value: "); P(", timer value: ");
print_int(timer_val); print_int(timer_val);
P(", RVR0 = ");
print_int(RVR0);
P(", RVR1 = ");
print_int(RVR1);
P("\n"); P("\n");
} }
} }
@ -94,7 +106,11 @@ int main(){
* SysTick interrupt: increment global time & send data buffer through USB * SysTick interrupt: increment global time & send data buffer through USB
*/ */
void sys_tick_handler(){ void sys_tick_handler(){
if(++Timer == 1000){ ++Timer;
if(Timer == 999){
STK_RVR = RVR1;
}else if(Timer == 1000){
STK_RVR = RVR0;
time_increment(); time_increment();
} }
usb_send_buffer(); usb_send_buffer();
@ -102,17 +118,50 @@ void sys_tick_handler(){
// STK_CVR - current systick val // STK_CVR - current systick val
// STK_RVR - ticks till interrupt - 1 // STK_RVR - ticks till interrupt - 1
// PA4 interrupt // PA4 interrupt - PPS signal
void exti4_isr(){ void exti4_isr(){
uint32_t t = 0, ticks;
static uint32_t ticksavr = 0, N = 0;
if(EXTI_PR & EXTI4){ if(EXTI_PR & EXTI4){
// correct // correct
systick_val = STK_CVR; systick_val = STK_CVR;
STK_CVR = RVR0;
systick_val = RVR0 + 1 - systick_val; // Systick counts down!
timer_val = Timer; timer_val = Timer;
Timer = 0;
if(timer_val < 10) timer_val += 1000; // our closks go faster than real
else if(timer_val < 990){ // something wrong
RVR0 = RVR1 = STK_RVR_DEFAULT_VAL;
STK_RVR = RVR0;
need_sync = 1;
goto theend;
}else
time_increment(); // ms counter less than 1000 - we need to increment time
t = current_time.H * 3600 + current_time.M * 60 + current_time.S;
if(clear_ST_on_connect){ if(clear_ST_on_connect){
STK_CVR = 0;
clear_ST_on_connect = 0; clear_ST_on_connect = 0;
time_increment(); }else{
// || (last_corr_time == 86399 && t == 0)
if(t - last_corr_time == 1){ // PPS interval == 1s
ticks = systick_val + timer_val*(RVR0 + 1);
++N;
ticksavr += ticks;
if(N > 20){
ticks = ticksavr / N;
RVR0 = ticks / 1000 - 1; // main RVR value
STK_RVR = RVR0;
RVR1 = RVR0 + ticks % 1000 - 1; // last millisecond RVR value (with fine correction)
N = 0;
ticksavr = 0;
need_sync = 0;
}
}else{
N = 0;
ticksavr = 0;
}
} }
theend:
last_corr_time = t;
EXTI_PR = EXTI4; EXTI_PR = EXTI4;
} }
} }
@ -131,7 +180,7 @@ void set_time(uint8_t *buf){
inline uint8_t atou(uint8_t *b){ inline uint8_t atou(uint8_t *b){
return (b[0]-'0')*10 + b[1]-'0'; return (b[0]-'0')*10 + b[1]-'0';
} }
uint8_t H = atou(buf) + 3; uint8_t H = atou(buf) + TIMEZONE_GMT_PLUS;
if(H > 23) H -= 24; if(H > 23) H -= 24;
current_time.H = H; current_time.H = H;
current_time.M = atou(&buf[2]); current_time.M = atou(&buf[2]);
@ -156,6 +205,7 @@ void print_curtime(){
if(T < 10) usb_send('0'); if(T < 10) usb_send('0');
print_int(T); print_int(T);
if(GPS_status == GPS_NOT_VALID) P(" (not valid)"); if(GPS_status == GPS_NOT_VALID) P(" (not valid)");
if(need_sync) P(" need synchronisation");
newline(); newline();
}else }else
P("Waiting for satellites\n"); P("Waiting for satellites\n");

View File

@ -49,6 +49,9 @@ extern void *memcpy(void *dest, const void *src, int n);
#define U16(x) ((uint16_t) x) #define U16(x) ((uint16_t) x)
#define U32(x) ((uint32_t) x) #define U32(x) ((uint32_t) x)
#define STK_RVR_DEFAULT_VAL (8999)
#define TIMEZONE_GMT_PLUS (3)
typedef struct{ typedef struct{
uint8_t H; uint8_t H;
uint8_t M; uint8_t M;
@ -59,6 +62,8 @@ extern curtime current_time;
extern volatile uint32_t Timer; // global timer (milliseconds) extern volatile uint32_t Timer; // global timer (milliseconds)
extern volatile int clear_ST_on_connect; // flag for clearing Systick counter on next PPS extern volatile int clear_ST_on_connect; // flag for clearing Systick counter on next PPS
extern volatile int need_sync;
void Delay(uint16_t time); void Delay(uint16_t time);
void set_time(uint8_t *buf); void set_time(uint8_t *buf);

View File

@ -258,6 +258,7 @@ void fill_uart_RXbuff(uint32_t UART, uint8_t byte){
} }
curbuff = &RX_buffer[bufidx]; curbuff = &RX_buffer[bufidx];
if(curbuff->end == UART_BUF_DATA_SIZE){ // end of buffer - forget about data if(curbuff->end == UART_BUF_DATA_SIZE){ // end of buffer - forget about data
curbuff->end = 0;
return; return;
} }
curbuff->buf[curbuff->end++] = byte; // put byte into buffer curbuff->buf[curbuff->end++] = byte; // put byte into buffer