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
|
void exti1_isr(){ // PPS - PA1
|
||||||
DBG("exti1");
|
|
||||||
systick_correction();
|
systick_correction();
|
||||||
|
DBG("exti1");
|
||||||
EXTI->PR = EXTI_PR_PR1;
|
EXTI->PR = EXTI_PR_PR1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,17 +26,6 @@
|
|||||||
|
|
||||||
#include "stm32f1.h"
|
#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
|
// onboard LEDs - PB8/PB9
|
||||||
#define LED0_port GPIOB
|
#define LED0_port GPIOB
|
||||||
#define LED0_pin (1<<8)
|
#define LED0_pin (1<<8)
|
||||||
|
|||||||
@ -39,8 +39,10 @@ volatile uint32_t Tms = 0;
|
|||||||
|
|
||||||
/* Called when systick fires */
|
/* Called when systick fires */
|
||||||
void sys_tick_handler(void){
|
void sys_tick_handler(void){
|
||||||
++Tms;
|
++Tms; // increment pseudo-milliseconds counter
|
||||||
increment_timer();
|
if(++Timer == 1000){ // increment milliseconds counter
|
||||||
|
time_increment();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void iwdg_setup(){
|
void iwdg_setup(){
|
||||||
@ -171,57 +173,6 @@ static char *get_USB(){
|
|||||||
return NULL;
|
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){
|
int main(void){
|
||||||
uint32_t lastT = 0;
|
uint32_t lastT = 0;
|
||||||
sysreset();
|
sysreset();
|
||||||
@ -230,7 +181,7 @@ int main(void){
|
|||||||
LED1_off();
|
LED1_off();
|
||||||
USBPU_OFF();
|
USBPU_OFF();
|
||||||
usarts_setup();
|
usarts_setup();
|
||||||
SysTick_Config(SYSTICK_DEFLOAD);
|
SysTick_Config(SYSTICK_DEFCONF); // function SysTick_Config decrements argument!
|
||||||
SEND("Chronometer version " VERSION ".\n");
|
SEND("Chronometer version " VERSION ".\n");
|
||||||
if(RCC->CSR & RCC_CSR_IWDGRSTF){ // watchdog reset occured
|
if(RCC->CSR & RCC_CSR_IWDGRSTF){ // watchdog reset occured
|
||||||
SEND("WDGRESET=1\n");
|
SEND("WDGRESET=1\n");
|
||||||
@ -280,10 +231,10 @@ int main(void){
|
|||||||
int r = 0;
|
int r = 0;
|
||||||
char *txt;
|
char *txt;
|
||||||
if((txt = get_USB())){
|
if((txt = get_USB())){
|
||||||
parse_USBCMD(txt);
|
|
||||||
DBG("Received data over USB:");
|
DBG("Received data over USB:");
|
||||||
DBG(txt);
|
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 defined EBUG || defined USART1PROXY
|
||||||
if(usartrx(1)){ // usart1 received data, store in in buffer
|
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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "flash.h"
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
|
#include "time.h"
|
||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
|
#include "usb.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief cmpstr - the same as strncmp
|
* @brief cmpstr - the same as strncmp
|
||||||
* @param s1,s2 - strings to compare
|
* @param s1,s2 - strings to compare
|
||||||
@ -44,3 +48,60 @@ char *getchr(const char *str, char symbol){
|
|||||||
}while(*(++str));
|
}while(*(++str));
|
||||||
return NULL;
|
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__
|
#ifndef STR_H__
|
||||||
#define 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);
|
int cmpstr(const char *s1, const char *s2, int n);
|
||||||
char *getchr(const char *str, char symbol);
|
char *getchr(const char *str, char symbol);
|
||||||
|
int parse_USBCMD(char *cmd);
|
||||||
#endif // STR_H__
|
#endif // STR_H__
|
||||||
|
|||||||
@ -18,20 +18,26 @@
|
|||||||
|
|
||||||
#include "GPS.h"
|
#include "GPS.h"
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
|
#ifdef EBUG
|
||||||
|
#include "usart.h"
|
||||||
|
#endif
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
volatile uint32_t Timer; // milliseconds counter
|
volatile uint32_t Timer; // milliseconds counter
|
||||||
curtime current_time = TMNOTINI;
|
curtime current_time = TMNOTINI;
|
||||||
volatile int need_sync = 1;
|
|
||||||
|
|
||||||
// SysTick->LOAD values for all milliseconds (RVR0) and last millisecond (RVR1)
|
// ms counter in last correction by PPS
|
||||||
static uint32_t RVR0 = SYSTICK_DEFLOAD, RVR1 = SYSTICK_DEFLOAD;
|
static uint32_t last_corr_time = 0;
|
||||||
|
|
||||||
static inline uint8_t atou(const char *b){
|
static inline uint8_t atou(const char *b){
|
||||||
return (b[0]-'0')*10 + b[1]-'0';
|
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){
|
void set_time(const char *buf){
|
||||||
uint8_t H = atou(buf) + TIMEZONE_GMT_PLUS;
|
uint8_t H = atou(buf) + TIMEZONE_GMT_PLUS;
|
||||||
if(H > 23) H -= 24;
|
if(H > 23) H -= 24;
|
||||||
@ -54,6 +60,10 @@ void time_increment(){
|
|||||||
current_time.H = 0;
|
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)");
|
strcpy(bptr, " (not valid)");
|
||||||
bptr += 12;
|
bptr += 12;
|
||||||
}
|
}
|
||||||
if(need_sync){
|
if(Tms - last_corr_time > 1000){
|
||||||
strcpy(bptr, " need synchronisation");
|
strcpy(bptr, " need PPS sync");
|
||||||
bptr += 21;
|
bptr += 14;
|
||||||
}
|
}
|
||||||
*bptr++ = '\n';
|
*bptr++ = '\n';
|
||||||
*bptr = 0;
|
*bptr = 0;
|
||||||
@ -103,15 +113,39 @@ char *get_time(curtime *Tm, uint32_t T){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief get_millis - calculate milliseconds due to global fix parameter
|
* @brief systick_correction
|
||||||
* @return milliseconds value
|
* 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(){
|
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;
|
uint32_t t = 0, ticks;
|
||||||
static uint32_t ticksavr = 0, N = 0, last_corr_time = 0;
|
static uint32_t ticksavr = 0, N = 0, last_corr_time = 0;
|
||||||
// correct
|
// correct
|
||||||
@ -150,14 +184,6 @@ void systick_correction(){
|
|||||||
}
|
}
|
||||||
theend:
|
theend:
|
||||||
last_corr_time = t;
|
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}
|
#define TMNOTINI {25,61,61}
|
||||||
|
|
||||||
|
// current milliseconds
|
||||||
|
#define get_millis() (Timer)
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
uint8_t H;
|
uint8_t H;
|
||||||
uint8_t M;
|
uint8_t M;
|
||||||
@ -51,9 +54,7 @@ extern volatile int need_sync;
|
|||||||
|
|
||||||
char *get_time(curtime *T, uint32_t m);
|
char *get_time(curtime *T, uint32_t m);
|
||||||
void set_time(const char *buf);
|
void set_time(const char *buf);
|
||||||
uint32_t get_millis(); // current milliseconds
|
|
||||||
void time_increment();
|
void time_increment();
|
||||||
void systick_correction();
|
void systick_correction();
|
||||||
void increment_timer();
|
|
||||||
|
|
||||||
#endif // TIME_H__
|
#endif // TIME_H__
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user