diff --git a/GPS/GPS.bin b/GPS/GPS.bin index e2a9967..f688aec 100755 Binary files a/GPS/GPS.bin and b/GPS/GPS.bin differ diff --git a/GPS/GPS.c b/GPS/GPS.c index cecc433..e5991e8 100644 --- a/GPS/GPS.c +++ b/GPS/GPS.c @@ -26,6 +26,7 @@ #define GPS_endline() do{GPS_send_string((uint8_t*)"\r\n");}while(0) #define U(arg) ((uint8_t*)arg) +gps_status GPS_status = GPS_WAIT; void GPS_send_string(uint8_t *str){ while(*str) @@ -48,35 +49,43 @@ uint8_t *ustrchr(uint8_t *str, uint8_t symbol){ return NULL; } -/* -// Check checksum -int checksum(uint8_t *buf){ +uint8_t hex(uint8_t n){ + return ((n < 10) ? (n+'0') : (n+'A'-10)); +} + +/** + * Check checksum + */ +int checksum_true(uint8_t *buf){ uint8_t *eol; - char chs[3]; - uint8_t checksum = 0; - if(*buf != '$' || !(eol = (uint8_t*)ustrchr((char*)buf, '*'))){ - DBG("Wrong data: %s\n", buf); + uint8_t checksum = 0, cs[3]; + if(*buf != '$' || !(eol = ustrchr(buf, '*'))){ + DBG("Wrong data: "); + DBG(buf); + DBG("\n"); return 0; } while(++buf != eol) checksum ^= *buf; - snprintf(chs, 3, "%02X", checksum); - if(strncmp(chs, (char*)++buf, 2)){ - DBG("Wrong checksum: %s", chs); - return 0; - } - return 1; -}*/ + ++buf; + cs[0] = hex(checksum >> 4); + cs[1] = hex(checksum & 0x0f); + if(buf[0] == cs[0] && buf[1] == cs[1]) + return 1; +#ifdef EBUG + cs[2] = 0; + P("CHS, get "); + P(buf); + P(" need "); + P(cs); + usb_send('\n'); +#endif + return 0; +} void send_chksum(uint8_t chs){ - void puts(uint8_t c){ - if(c < 10) - fill_uart_buff(USART2, c + '0'); - else - fill_uart_buff(USART2, c + 'A' - 10); - } - puts(chs >> 4); - puts(chs & 0x0f); + fill_uart_buff(USART2, hex(chs >> 4)); + fill_uart_buff(USART2, hex(chs & 0x0f)); } /** * Calculate checksum & write message to port @@ -135,23 +144,51 @@ uint8_t *nextpos(uint8_t **buf, int pos){ */ /** * Parse answer from GPS module + * + * Recommended minimum specific GPS/Transit data + * $GPRMC,hhmmss,status,latitude,N,longitude,E,spd,cog,ddmmyy,mv,mvE,mode*cs + * 1 = UTC of position fix + * 2 = Data status (V=navigation receiver warning) + * 3 = Latitude of fix + * 4 = N or S + * 5 = Longitude of fix + * 6 = E or W + * 7 = Speed over ground in knots + * 8 = Cource over ground in degrees + * 9 = UT date + * 10 = Magnetic variation degrees (Easterly var. subtracts from true course) + * 11 = E or W + * 12 = Mode: N(bad), E(approx), A(auto), D(diff) + * 213457.00,A,4340.59415,N,04127.47560,E,2.494,,290615,,,A*7B */ void GPS_parse_answer(uint8_t *buf){ uint8_t *ptr; DBG(buf); - if(strncmp(buf+3, U("RMC"), 3)) return; // not RMC message - buf += 7; // skip header - P("time: "); - if(*buf != ','){ - ptr = ustrchr(buf, ','); - *ptr++ = 0; - P(buf); - buf = ptr; - P(" "); - }else{ - P("undefined "); - ++buf; + if(strncmp(buf+3, U("RMC"), 3)){ // not RMC message + GPS_send_start_seq(); + return; } + if(!checksum_true(buf)){ + DBG("Wrong chs\n"); + return; // wrong checksum + } + buf += 7; // skip header + if(*buf == ','){ // time unknown + GPS_status = GPS_WAIT; + return; + } + //P("time: "); + ptr = ustrchr(buf, ','); + *ptr++ = 0; + //P(buf); + if(*ptr == 'A') + GPS_status = GPS_VALID; + else + GPS_status = GPS_NOT_VALID; + print_curtime(); + set_time(buf); +// buf = ustrchr(ptr, ','); +// P(" "); P("\n"); } diff --git a/GPS/GPS.geany b/GPS/GPS.geany index d6ec8a5..6f2dce9 100644 --- a/GPS/GPS.geany +++ b/GPS/GPS.geany @@ -21,16 +21,17 @@ long_line_behaviour=1 long_line_column=80 [files] -current_page=1 -FILE_NAME_0=4732;C;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FELECTRONICS%2FSTM32%2Fc8t6%2FGPS%2Fuser_proto.c;0;4 -FILE_NAME_1=0;C;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FELECTRONICS%2FSTM32%2Fc8t6%2FGPS%2Fuser_proto.h;0;4 -FILE_NAME_2=6683;C;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FELECTRONICS%2FSTM32%2Fc8t6%2FGPS%2Fuart.c;0;4 -FILE_NAME_3=1297;C;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FELECTRONICS%2FSTM32%2Fc8t6%2FGPS%2Fuart.h;0;4 -FILE_NAME_4=2072;C;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FELECTRONICS%2FSTM32%2Fc8t6%2FGPS%2Fmain.c;0;4 -FILE_NAME_5=1364;C;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FELECTRONICS%2FSTM32%2Fc8t6%2FGPS%2Fmain.h;0;4 -FILE_NAME_6=949;C;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FELECTRONICS%2FSTM32%2Fc8t6%2FGPS%2FGPS.c;0;4 -FILE_NAME_7=903;C;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FELECTRONICS%2FSTM32%2Fc8t6%2FGPS%2FGPS.h;0;4 +current_page=0 +FILE_NAME_0=2419;C;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FELECTRONICS%2FSTM32%2Fc8t6%2FGPS%2Fuser_proto.c;0;4 +FILE_NAME_1=1153;C;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FELECTRONICS%2FSTM32%2Fc8t6%2FGPS%2Fuser_proto.h;0;4 +FILE_NAME_2=5725;C;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FELECTRONICS%2FSTM32%2Fc8t6%2FGPS%2Fuart.c;0;4 +FILE_NAME_3=1269;C;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FELECTRONICS%2FSTM32%2Fc8t6%2FGPS%2Fuart.h;0;4 +FILE_NAME_4=925;C;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FELECTRONICS%2FSTM32%2Fc8t6%2FGPS%2Fmain.c;0;4 +FILE_NAME_5=1384;C;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FELECTRONICS%2FSTM32%2Fc8t6%2FGPS%2Fmain.h;0;4 +FILE_NAME_6=1188;C;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FELECTRONICS%2FSTM32%2Fc8t6%2FGPS%2FGPS.c;0;4 +FILE_NAME_7=875;C;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FELECTRONICS%2FSTM32%2Fc8t6%2FGPS%2FGPS.h;0;4 FILE_NAME_8=2128;C;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FELECTRONICS%2FSTM32%2Fc8t6%2FGPS%2Fhardware_ini.c;0;4 +FILE_NAME_9=2589;C;0;EUTF-8;1;1;0;%2Fhome%2Feddy%2FDocs%2FSAO%2FELECTRONICS%2FGPS%2Fsrc%2Fmain.c;0;4 [VTE] last_dir=/home/eddy/Docs/SAO/Cameras/FLI_camera/my/Mytakepic diff --git a/GPS/GPS.h b/GPS/GPS.h index 6ce2330..d400864 100644 --- a/GPS/GPS.h +++ b/GPS/GPS.h @@ -23,6 +23,14 @@ #ifndef __GPS_H__ #define __GPS_H__ +typedef enum{ + GPS_WAIT // wait for satellites + ,GPS_NOT_VALID // time known, but not valid + ,GPS_VALID +} gps_status; + +extern gps_status GPS_status; + void GPS_parse_answer(uint8_t *string); void GPS_send_start_seq(); diff --git a/GPS/hardware_ini.c b/GPS/hardware_ini.c index 887faab..2ca2dd3 100644 --- a/GPS/hardware_ini.c +++ b/GPS/hardware_ini.c @@ -32,9 +32,17 @@ * GPIO initialisaion: clocking + pins setup */ void GPIO_init(){ -/* rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN | + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_IOPEEN); + // Setup EXTI on PA4 (PPS input from GPS) - pull down + gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO4); + //AFIO_EXTICR2 = 0; + exti_enable_request(EXTI4); + // trigger on rising edge + exti_set_trigger(EXTI4, EXTI_TRIGGER_RISING); + nvic_enable_irq(NVIC_EXTI4_IRQ); +/* // Buttons: pull-up input gpio_set_mode(BTNS_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, BTN_S2_PIN | BTN_S3_PIN); @@ -60,7 +68,7 @@ void GPIO_init(){ */ void SysTick_init(){ systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); // Systyck: 72/8=9MHz - systick_set_reload(899); // 900 pulses: 10kHz + STK_RVR = 8999; // 9000 pulses: 1kHz systick_interrupt_enable(); systick_counter_enable(); } diff --git a/GPS/main.c b/GPS/main.c index c1c2804..49d3fc4 100644 --- a/GPS/main.c +++ b/GPS/main.c @@ -25,12 +25,28 @@ #include "uart.h" #include "GPS.h" -volatile uint32_t Ticks = 0; // global ticks (10kHz) -volatile uint32_t Timer = 0; // global timer (milliseconds) +volatile uint32_t Timer = 0; // milliseconds usbd_device *usbd_dev; +volatile uint32_t systick_val = 0; +volatile uint32_t timer_val = 0; +volatile int clear_ST_on_connect = 1; + +curtime current_time = {25,61,61}; + +void time_increment(){ + Timer = 0; + if(current_time.H == 25) return; // Time not initialized + if(++current_time.S == 60){ + current_time.S = 0; + if(++current_time.M == 60){ + current_time.M = 0; + if(++current_time.H == 24) + current_time.H = 0; + } + } +} int main(){ - uint32_t usb_timer = 0; uint8_t *string; // RCC clocking: 8MHz oscillator -> 72MHz system rcc_clock_setup_in_hse_8mhz_out_72mhz(); @@ -59,13 +75,16 @@ int main(){ if(usbdatalen){ // there's something in USB buffer usbdatalen = parce_incoming_buf(usbdatabuf, usbdatalen); } - if((string = check_UART2())) + if((string = check_UART2())){ GPS_parse_answer(string); - if(Ticks - usb_timer > 9){ // 1ms cycle - usb_timer += 10; - //usb_send_buffer(); - }else if(Ticks < usb_timer){ // Timer overflow - usb_timer = 0; + } + if(systick_val){ + P("Systick differs by "); + print_int(systick_val); + systick_val = 0; + P(", timer value: "); + print_int(timer_val); + P("\n"); } } } @@ -75,15 +94,30 @@ int main(){ * SysTick interrupt: increment global time & send data buffer through USB */ void sys_tick_handler(){ - static int T = 0; // 0..10 - for millisecond timer - ++Ticks; - if(++T == 10){ - usb_send_buffer(); - ++Timer; - T = 0; + if(++Timer == 1000){ + time_increment(); + } + usb_send_buffer(); +} +// STK_CVR - current systick val +// STK_RVR - ticks till interrupt - 1 + +// PA4 interrupt +void exti4_isr(){ + if(EXTI_PR & EXTI4){ + // correct + systick_val = STK_CVR; + timer_val = Timer; + if(clear_ST_on_connect){ + STK_CVR = 0; + clear_ST_on_connect = 0; + time_increment(); + } + EXTI_PR = EXTI4; } } + // pause function, delay in ms void Delay(uint16_t _U_ time){ uint32_t waitto = Timer + time; @@ -91,8 +125,38 @@ void Delay(uint16_t _U_ time){ } /** - * print current time in milliseconds + * set current time by buffer hhmmss */ -void print_time(){ - print_int(Timer); +void set_time(uint8_t *buf){ + inline uint8_t atou(uint8_t *b){ + return (b[0]-'0')*10 + b[1]-'0'; + } + uint8_t H = atou(buf) + 3; + if(H > 23) H -= 24; + current_time.H = H; + current_time.M = atou(&buf[2]); + current_time.S = atou(&buf[4]); +} + + +void print_curtime(){ + int T = Timer; + newline(); + if(current_time.H < 25 && GPS_status != GPS_WAIT){ + P("Current time: "); + if(current_time.H < 10) usb_send('0'); + print_int(current_time.H); usb_send(':'); + if(current_time.M < 10) usb_send('0'); + print_int(current_time.M); usb_send(':'); + if(current_time.S < 10) usb_send('0'); + print_int(current_time.S); usb_send('.'); + /* uint32_t millis = STK_CVR * 1000; + millis /= STK_RVR;*/ + if(T < 100) usb_send('0'); + if(T < 10) usb_send('0'); + print_int(T); + if(GPS_status == GPS_NOT_VALID) P(" (not valid)"); + newline(); + }else + P("Waiting for satellites\n"); } diff --git a/GPS/main.h b/GPS/main.h index 54c68ba..eda190b 100644 --- a/GPS/main.h +++ b/GPS/main.h @@ -25,6 +25,7 @@ #define __MAIN_H__ #include +#include #include #include #include @@ -48,8 +49,20 @@ extern void *memcpy(void *dest, const void *src, int n); #define U16(x) ((uint16_t) x) #define U32(x) ((uint32_t) x) +typedef struct{ + uint8_t H; + uint8_t M; + uint8_t S; +} curtime; + +extern curtime current_time; extern volatile uint32_t Timer; // global timer (milliseconds) +extern volatile int clear_ST_on_connect; // flag for clearing Systick counter on next PPS + void Delay(uint16_t time); +void set_time(uint8_t *buf); + +void print_curtime(); #endif // __MAIN_H__ diff --git a/GPS/uart.c b/GPS/uart.c index 7e83fbe..0a528d7 100644 --- a/GPS/uart.c +++ b/GPS/uart.c @@ -23,7 +23,6 @@ #include "uart.h" #include "cdcacm.h" #include "hardware_ini.h" -#include // for memcpy // Buffers for Tx static UART_buff TX_buffer[2]; // Tx buffers for all three ports diff --git a/GPS/user_proto.c b/GPS/user_proto.c index aa904ba..c9cfa99 100644 --- a/GPS/user_proto.c +++ b/GPS/user_proto.c @@ -40,8 +40,10 @@ intfun I = NULL; // function to process entered integer #define READINT() do{i += read_int(&buf[i+1], len-i-1);}while(0) void help(){ + P("C\tclear SysTick on PPS\n"); P("H\tshow this help\n"); // P("I\ttest entering integer value\n"); + P("S\tSend GPS starting sequence\n"); P("T\tshow current approx. time\n"); } @@ -76,6 +78,9 @@ int parce_incoming_buf(char *buf, int len){ command = buf[i]; if(!command) continue; // omit zero switch (command){ + case 'C': + clear_ST_on_connect = 1; + break; case 'H': // show help help(); break; @@ -83,10 +88,11 @@ int parce_incoming_buf(char *buf, int len){ I = show_int; READINT(); break;*/ + case 'S': + GPS_send_start_seq(); + break; case 'T': - newline(); - print_int(Timer); // be careful for Time >= 2^{31}!!! - newline(); + print_curtime(); break; case '\n': // show newline, space and tab as is case '\r':