diff --git a/F1-nolib/chronometer/chrono.bin b/F1-nolib/chronometer/chrono.bin
index 2f8e1f6..8577c2e 100755
Binary files a/F1-nolib/chronometer/chrono.bin and b/F1-nolib/chronometer/chrono.bin differ
diff --git a/F1-nolib/chronometer/hardware.c b/F1-nolib/chronometer/hardware.c
index 22b4f60..61f6630 100644
--- a/F1-nolib/chronometer/hardware.c
+++ b/F1-nolib/chronometer/hardware.c
@@ -89,8 +89,8 @@ void hw_setup(){
}
void exti1_isr(){ // PPS - PA1
- DBG("exti1");
systick_correction();
+ DBG("exti1");
EXTI->PR = EXTI_PR_PR1;
}
diff --git a/F1-nolib/chronometer/hardware.h b/F1-nolib/chronometer/hardware.h
index cb2d123..00a3842 100644
--- a/F1-nolib/chronometer/hardware.h
+++ b/F1-nolib/chronometer/hardware.h
@@ -26,17 +26,6 @@
#include "stm32f1.h"
-// usb commands
-// lower and upper limits to capture
-#define CMD_DISTMIN "distmin"
-#define CMD_DISTMAX "distmax"
-#define CMD_ADC1MIN "adc1min"
-#define CMD_ADC2MIN "adc2min"
-#define CMD_ADC1MAX "adc1max"
-#define CMD_ADC2MAX "adc2max"
-#define CMD_PRINTTIME "time"
-#define CMD_STORECONF "store"
-
// onboard LEDs - PB8/PB9
#define LED0_port GPIOB
#define LED0_pin (1<<8)
diff --git a/F1-nolib/chronometer/main.c b/F1-nolib/chronometer/main.c
index 164e02b..cd68b43 100644
--- a/F1-nolib/chronometer/main.c
+++ b/F1-nolib/chronometer/main.c
@@ -39,8 +39,10 @@ volatile uint32_t Tms = 0;
/* Called when systick fires */
void sys_tick_handler(void){
- ++Tms;
- increment_timer();
+ ++Tms; // increment pseudo-milliseconds counter
+ if(++Timer == 1000){ // increment milliseconds counter
+ time_increment();
+ }
}
void iwdg_setup(){
@@ -171,57 +173,6 @@ static char *get_USB(){
return NULL;
}
-static void parse_USBCMD(char *cmd){
-#define CMP(a,b) cmpstr(a, b, sizeof(b)-1)
-#define GETNUM(x) if(getnum(cmd+sizeof(x)-1, &N)) goto bad_number;
- static uint8_t conf_modified = 0;
- uint8_t succeed = 0;
- int32_t N;
- if(!cmd || !*cmd) return;
- if(*cmd == '?'){ // help
- USB_send("Commands:\n"
- CMD_DISTMIN " - min distance threshold (cm)\n"
- CMD_DISTMAX " - max distance threshold (cm)\n"
- CMD_PRINTTIME " - print time\n"
- CMD_STORECONF " - store new configuration in flash\n"
- );
- }else if(CMP(cmd, CMD_PRINTTIME) == 0){
- USB_send(get_time(¤t_time, get_millis()));
- }else if(CMP(cmd, CMD_DISTMIN) == 0){ // set low limit
- DBG("CMD_DISTMIN");
- GETNUM(CMD_DISTMIN);
- if(N < 0 || N > 0xffff) goto bad_number;
- if(the_conf.dist_min != (uint16_t)N){
- conf_modified = 1;
- the_conf.dist_min = (uint16_t) N;
- succeed = 1;
- }
- }else if(CMP(cmd, CMD_DISTMAX) == 0){ // set low limit
- DBG("CMD_DISTMAX");
- GETNUM(CMD_DISTMAX);
- if(N < 0 || N > 0xffff) goto bad_number;
- if(the_conf.dist_max != (uint16_t)N){
- conf_modified = 1;
- the_conf.dist_max = (uint16_t) N;
- succeed = 1;
- }
- }else if(CMP(cmd, CMD_STORECONF) == 0){ // store everything
- DBG("Store");
- if(conf_modified){
- if(store_userconf()){
- USB_send("Error: can't save data!\n");
- }else{
- conf_modified = 0;
- succeed = 1;
- }
- }
- }
- if(succeed) USB_send("Success!\n");
- return;
- bad_number:
- USB_send("Error: bad number!\n");
-}
-
int main(void){
uint32_t lastT = 0;
sysreset();
@@ -230,7 +181,7 @@ int main(void){
LED1_off();
USBPU_OFF();
usarts_setup();
- SysTick_Config(SYSTICK_DEFLOAD);
+ SysTick_Config(SYSTICK_DEFCONF); // function SysTick_Config decrements argument!
SEND("Chronometer version " VERSION ".\n");
if(RCC->CSR & RCC_CSR_IWDGRSTF){ // watchdog reset occured
SEND("WDGRESET=1\n");
@@ -280,10 +231,10 @@ int main(void){
int r = 0;
char *txt;
if((txt = get_USB())){
- parse_USBCMD(txt);
DBG("Received data over USB:");
DBG(txt);
- USB_send(txt); // echo all back
+ if(parse_USBCMD(txt))
+ USB_send(txt); // echo back non-commands data
}
#if defined EBUG || defined USART1PROXY
if(usartrx(1)){ // usart1 received data, store in in buffer
diff --git a/F1-nolib/chronometer/str.c b/F1-nolib/chronometer/str.c
index 1929765..f22cc17 100644
--- a/F1-nolib/chronometer/str.c
+++ b/F1-nolib/chronometer/str.c
@@ -16,8 +16,12 @@
* along with this program. If not, see .
*/
+#include "flash.h"
#include "str.h"
+#include "time.h"
#include "usart.h"
+#include "usb.h"
+
/**
* @brief cmpstr - the same as strncmp
* @param s1,s2 - strings to compare
@@ -44,3 +48,60 @@ char *getchr(const char *str, char symbol){
}while(*(++str));
return NULL;
}
+
+/**
+ * @brief parse_USBCMD - parsing of string buffer got by USB
+ * @param cmd - buffer with commands
+ * @return 0 if got command, 1 if command not recognized
+ */
+int parse_USBCMD(char *cmd){
+#define CMP(a,b) cmpstr(a, b, sizeof(b)-1)
+#define GETNUM(x) if(getnum(cmd+sizeof(x)-1, &N)) goto bad_number;
+ static uint8_t conf_modified = 0;
+ uint8_t succeed = 0;
+ int32_t N;
+ if(!cmd || !*cmd) return 0;
+ if(*cmd == '?'){ // help
+ USB_send("Commands:\n"
+ CMD_DISTMIN " - min distance threshold (cm)\n"
+ CMD_DISTMAX " - max distance threshold (cm)\n"
+ CMD_PRINTTIME " - print time\n"
+ CMD_STORECONF " - store new configuration in flash\n"
+ );
+ }else if(CMP(cmd, CMD_PRINTTIME) == 0){
+ USB_send(get_time(¤t_time, get_millis()));
+ }else if(CMP(cmd, CMD_DISTMIN) == 0){ // set low limit
+ DBG("CMD_DISTMIN");
+ GETNUM(CMD_DISTMIN);
+ if(N < 0 || N > 0xffff) goto bad_number;
+ if(the_conf.dist_min != (uint16_t)N){
+ conf_modified = 1;
+ the_conf.dist_min = (uint16_t) N;
+ succeed = 1;
+ }
+ }else if(CMP(cmd, CMD_DISTMAX) == 0){ // set low limit
+ DBG("CMD_DISTMAX");
+ GETNUM(CMD_DISTMAX);
+ if(N < 0 || N > 0xffff) goto bad_number;
+ if(the_conf.dist_max != (uint16_t)N){
+ conf_modified = 1;
+ the_conf.dist_max = (uint16_t) N;
+ succeed = 1;
+ }
+ }else if(CMP(cmd, CMD_STORECONF) == 0){ // store everything
+ DBG("Store");
+ if(conf_modified){
+ if(store_userconf()){
+ USB_send("Error: can't save data!\n");
+ }else{
+ conf_modified = 0;
+ succeed = 1;
+ }
+ }
+ }else return 1;
+ if(succeed) USB_send("Success!\n");
+ return 0;
+ bad_number:
+ USB_send("Error: bad number!\n");
+ return 0;
+}
diff --git a/F1-nolib/chronometer/str.h b/F1-nolib/chronometer/str.h
index 4b2e50d..95d86ea 100644
--- a/F1-nolib/chronometer/str.h
+++ b/F1-nolib/chronometer/str.h
@@ -19,7 +19,18 @@
#ifndef STR_H__
#define STR_H__
+// usb commands
+// lower and upper limits to capture
+#define CMD_DISTMIN "distmin"
+#define CMD_DISTMAX "distmax"
+#define CMD_ADC1MIN "adc1min"
+#define CMD_ADC2MIN "adc2min"
+#define CMD_ADC1MAX "adc1max"
+#define CMD_ADC2MAX "adc2max"
+#define CMD_PRINTTIME "time"
+#define CMD_STORECONF "store"
+
int cmpstr(const char *s1, const char *s2, int n);
char *getchr(const char *str, char symbol);
-
+int parse_USBCMD(char *cmd);
#endif // STR_H__
diff --git a/F1-nolib/chronometer/time.c b/F1-nolib/chronometer/time.c
index 6f8f0c3..64908ba 100644
--- a/F1-nolib/chronometer/time.c
+++ b/F1-nolib/chronometer/time.c
@@ -18,20 +18,26 @@
#include "GPS.h"
#include "time.h"
+#ifdef EBUG
+#include "usart.h"
+#endif
#include "usb.h"
#include
volatile uint32_t Timer; // milliseconds counter
curtime current_time = TMNOTINI;
-volatile int need_sync = 1;
-// SysTick->LOAD values for all milliseconds (RVR0) and last millisecond (RVR1)
-static uint32_t RVR0 = SYSTICK_DEFLOAD, RVR1 = SYSTICK_DEFLOAD;
+// ms counter in last correction by PPS
+static uint32_t last_corr_time = 0;
static inline uint8_t atou(const char *b){
return (b[0]-'0')*10 + b[1]-'0';
}
+/**
+ * @brief set_time - set current time from GPS data
+ * @param buf - buffer with time data (HHMMSS)
+ */
void set_time(const char *buf){
uint8_t H = atou(buf) + TIMEZONE_GMT_PLUS;
if(H > 23) H -= 24;
@@ -54,6 +60,10 @@ void time_increment(){
current_time.H = 0;
}
}
+#ifdef EBUG
+ SEND("time_increment(): ");
+ SEND(get_time(¤t_time, 0));
+#endif
}
/**
@@ -93,9 +103,9 @@ char *get_time(curtime *Tm, uint32_t T){
strcpy(bptr, " (not valid)");
bptr += 12;
}
- if(need_sync){
- strcpy(bptr, " need synchronisation");
- bptr += 21;
+ if(Tms - last_corr_time > 1000){
+ strcpy(bptr, " need PPS sync");
+ bptr += 14;
}
*bptr++ = '\n';
*bptr = 0;
@@ -103,15 +113,39 @@ char *get_time(curtime *Tm, uint32_t T){
}
/**
- * @brief get_millis - calculate milliseconds due to global fix parameter
- * @return milliseconds value
+ * @brief systick_correction
+ * Makes correction of system timer
+ * The default frequency of timer is 1kHz - 72000 clocks per interrupt
+ * So we check how much ticks there was for last one second - between PPS interrupts
+ * Their amount equal to M = `Timer` value x (SysTick->LOAD+1) + (SysTick->LOAD+1 - SysTick->VAL)
+ * if `Timer` is very small, add 1000 to its value.
+ * We need 1000xN ticks instead of M
+ * if L = LOAD+1, then
+ * M = Timer*L + L - VAL; newL = L + D = M/1000
+ * 1000*D = M - 1000*L = L(Timer+1-1000) - VAL ->
+ * D = [L*(Timer-999) - VAL]/1000
+ * So correction equal to
+ * [ (SysTick->LOAD + 1) * (Timer - 999) - SysTick->VAL ] / 1000
*/
-uint32_t get_millis(){
- // TODO: calculate right millis
- return Tms % 1000; // temporary gag
-}
-
void systick_correction(){
+ SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // stop systick for a while
+ int32_t systick_val = SysTick->VAL, L = SysTick->LOAD + 1, timer_val = Timer;
+ SysTick->VAL = SysTick->LOAD;
+ SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // start it again
+ Timer = 0;
+ if(Tms - last_corr_time < 2000){ // calculate corrections only if Timer was zeroed last time
+ if(timer_val < 500) timer_val += 1000; // timer already incremented in SysTick interrupt
+ else time_increment(); // counter less than 1000 -> need to increment time
+ int32_t D = L * (timer_val - 999) - systick_val;
+ D /= 1000;
+#ifdef EBUG
+ SEND("Delta: "); if(D < 0){usart_putchar(1, '-'); printu(1, -D);} else printu(1, D); newline();
+ SEND(get_time(¤t_time, 0));
+#endif
+ SysTick->LOAD += D;
+ }
+ last_corr_time = Tms;
+#if 0
uint32_t t = 0, ticks;
static uint32_t ticksavr = 0, N = 0, last_corr_time = 0;
// correct
@@ -150,14 +184,6 @@ void systick_correction(){
}
theend:
last_corr_time = t;
+#endif
}
-void increment_timer(){
- ++Timer;
- if(Timer == 999){
- SysTick->LOAD = RVR1;
- }else if(Timer == 1000){
- SysTick->LOAD = RVR0;
- time_increment();
- }
-}
diff --git a/F1-nolib/chronometer/time.h b/F1-nolib/chronometer/time.h
index d4f8f6c..569524d 100644
--- a/F1-nolib/chronometer/time.h
+++ b/F1-nolib/chronometer/time.h
@@ -34,6 +34,9 @@
#define TMNOTINI {25,61,61}
+// current milliseconds
+#define get_millis() (Timer)
+
typedef struct{
uint8_t H;
uint8_t M;
@@ -51,9 +54,7 @@ extern volatile int need_sync;
char *get_time(curtime *T, uint32_t m);
void set_time(const char *buf);
-uint32_t get_millis(); // current milliseconds
void time_increment();
void systick_correction();
-void increment_timer();
#endif // TIME_H__