mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 10:45:11 +03:00
time sync (not tested)
This commit is contained in:
parent
7ac9d908fa
commit
20728db47f
Binary file not shown.
@ -89,8 +89,8 @@ void hw_setup(){
|
||||
}
|
||||
|
||||
void exti1_isr(){ // PPS - PA1
|
||||
DBG("exti1");
|
||||
systick_correction();
|
||||
DBG("exti1");
|
||||
EXTI->PR = EXTI_PR_PR1;
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -16,8 +16,12 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@ -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__
|
||||
|
||||
@ -18,20 +18,26 @@
|
||||
|
||||
#include "GPS.h"
|
||||
#include "time.h"
|
||||
#ifdef EBUG
|
||||
#include "usart.h"
|
||||
#endif
|
||||
#include "usb.h"
|
||||
#include <string.h>
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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__
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user