From 5b8f47a70a57765ba04a4d75dfa31a2f55f75029 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 20 Mar 2021 16:20:42 +0000 Subject: add alarm support --- app/Makefile | 2 +- app/fs.c | 69 ------------ app/httpd.c | 297 ++++++++++++++++++++++++++++++++++++++++++++++++++++ app/lwip/lwipopts.h | 1 + app/lwip_glue.c | 1 + app/prototypes.h | 11 +- app/ptb.h | 5 + app/time_fn.c | 133 +++++++++++++++++++++-- app/util.c | 10 ++ 9 files changed, 452 insertions(+), 77 deletions(-) delete mode 100644 app/fs.c create mode 100644 app/httpd.c create mode 100644 app/ptb.h diff --git a/app/Makefile b/app/Makefile index 126baa1..e11bbfc 100644 --- a/app/Makefile +++ b/app/Makefile @@ -29,7 +29,7 @@ default: ${PROG}.elf CSRCS=led.c ticker.c ring.c usart.c stdio.c lwip_glue.c steth.c msf.c abs.c \ pll.c main.c time_fn.c ntp.c dcf77.c util.c stats.c gps.c hexdump.c bits.c \ max7219.c report.c sysclk.c cdcacm.c usb.c dfu.c adc.c dummy_kb.c ref.c \ - ptp.c display.c fs.c + ptp.c display.c httpd.c HSRCS= events.h gps.h project.h ring.h steth.h time_fn.h ubx.h diff --git a/app/fs.c b/app/fs.c deleted file mode 100644 index 7b041fb..0000000 --- a/app/fs.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "project.h" - -#if 0 -#define FS_FILE_FLAGS_HEADER_INCLUDED 0x01 -#define FS_FILE_FLAGS_HEADER_PERSISTENT 0x02 -#define FS_FILE_FLAGS_HEADER_HTTPVER_1_1 0x04 -#define FS_FILE_FLAGS_SSI 0x08 -#endif - - -static char index_html[8192]; - -static uint32_t make_index (void) -{ - uint64_t abs = ref_get(); - EPOCH e; - UTC u; - ST l; - char buf[128]; - - PTB_INIT (index_html); - - e = ref_decompose (abs); - u = time_epoch_to_utc (e); - l = time_utc_to_lst (u, gps_lon); - - utc_to_str (buf, &u); - - PTB_ADD ("
\n");
-  PTB_ADD ("UTC: %s\n", buf);
-  PTB_ADD ("LST:                 %02d:%02d:%02d.%09d\n", l.hour, l.minute, l.second, l.nanosecond);
-  PTB_ADD("\n");
-
-  PTB_ADD ("GPS:\n");
-  PTB_ADD ("%s\n", gps_info);
-  PTB_ADD (" %s\n", gps_pos);
-  PTB_ADD (" %s\n", gps_svin_info);
-  PTB_ADD("\n");
-
-  PTB_ADD ("%s", gps_svinfo);
-  PTB_ADD ("
\n"); - - return PTB_LEN; -} - -int fs_open_custom (struct fs_file *file, const char *name) -{ - int len; - - if (strcmp (name, "/index.html")) return 0; - - len = make_index(); - - file->data = (const char *)index_html; - file->len = len; - file->index = file->len; - file->pextension = NULL; - file->flags = 0; - - - return 1; -} - - - - -void fs_close_custom (struct fs_file *file) -{ -} diff --git a/app/httpd.c b/app/httpd.c new file mode 100644 index 0000000..5c96c44 --- /dev/null +++ b/app/httpd.c @@ -0,0 +1,297 @@ +#include "project.h" + +#if 0 +#define FS_FILE_FLAGS_HEADER_INCLUDED 0x01 +#define FS_FILE_FLAGS_HEADER_PERSISTENT 0x02 +#define FS_FILE_FLAGS_HEADER_HTTPVER_1_1 0x04 +#define FS_FILE_FLAGS_SSI 0x08 +#endif + + +static char html_buf[8192]; + +EPOCH alarm; + +static uint32_t make_alarm (void) +{ + uint64_t abs = ref_get(); + EPOCH e, ad; + double ra, lra; + UTC u; + ST l; + char buf[128]; + + PTB_INIT (html_buf); + PTB_ADD ("\n"); + PTB_ADD ("\n"); + PTB_ADD ("
\n"); + + PTB_ADD ("

Alarm

\n"); + + u = time_epoch_to_utc (alarm); + utc_to_str (buf, &u); + ra = time_utc_to_ra (u); + lra = ra_normalize (ra + gps_lon); + l = time_ra_to_st (lra); + + PTB_ADD ("
\n");
+
+  e = ref_decompose (abs);
+  ad = time_epoch_sub (alarm, e);
+
+  if (ad.s >= 0) {
+    unsigned d, h, m, s;
+    s = ad.s;
+    m = s / 60;
+    s -= m * 60;
+    h = m / 60;
+    m -= h * 60;
+    d = h / 24;
+    h -= d * 24;
+
+    PTB_ADD (" in %d days, %02d:%02d:%02d\n", d, h, m, s);
+  }
+
+  PTB_ADD (" UTC: %s\n", buf);
+  PTB_ADD (" RA:                  %.9f\n", ra);
+  PTB_ADD ("
\n"); + + PTB_ADD ("\n"); + PTB_ADD ("\n", lra); + PTB_ADD ("\n", l.hour, l.minute, l.second, l.nanosecond / 1000); + PTB_ADD ("
LRA:
LST:
\n"); + + PTB_ADD ("\n"); + PTB_ADD ("\n"); + return PTB_LEN; +} + + + +static uint32_t make_index (void) +{ + uint64_t abs = ref_get(); + EPOCH e, ad; + double ra, lra; + UTC u; + ST l; + char buf[128]; + + PTB_INIT (html_buf); + PTB_ADD ("\n"); + PTB_ADD ("\n"); + PTB_ADD ("\n"); + PTB_ADD ("
\n"); + PTB_ADD ("

Now

\n"); + + e = ref_decompose (abs); + u = time_epoch_to_utc (e); + utc_to_str (buf, &u); + ra = time_utc_to_ra (u); + lra = ra + gps_lon; + l = time_ra_to_st (lra); + + + + PTB_ADD ("
\n");
+  PTB_ADD (" UTC: %s\n", buf);
+  PTB_ADD (" RA:                  %.9f\n", ra);
+  PTB_ADD (" LRA:                 %.9f\n", lra);
+  PTB_ADD (" LST:                 %02d:%02d:%02d.%06d\n", l.hour, l.minute, l.second, l.nanosecond / 1000);
+  PTB_ADD ("
\n"); + PTB_ADD ("\n"); + PTB_ADD ("

Alarm

\n"); + + u = time_epoch_to_utc (alarm); + utc_to_str (buf, &u); + ra = time_utc_to_ra (u); + lra = ra_normalize (ra + gps_lon); + l = time_ra_to_st (lra); + + PTB_ADD ("
\n");
+
+  ad = time_epoch_sub (alarm, e);
+
+  if (ad.s >= 0) {
+    unsigned d, h, m, s;
+    s = ad.s;
+    m = s / 60;
+    s -= m * 60;
+    h = m / 60;
+    m -= h * 60;
+    d = h / 24;
+    h -= d * 24;
+
+    PTB_ADD (" in %d days, %02d:%02d:%02d\n", d, h, m, s);
+  }
+
+  PTB_ADD (" UTC: %s\n", buf);
+  PTB_ADD (" RA:                  %.9f\n", ra);
+  PTB_ADD (" LRA:                 %.9f\n", lra);
+  PTB_ADD (" LST:                 %02d:%02d:%02d.%06d\n", l.hour, l.minute, l.second, l.nanosecond / 1000);
+  PTB_ADD ("
\n"); + + PTB_ADD ("
\n"); + + PTB_ADD ("

GPS

\n"); + PTB_ADD ("
\n");
+  PTB_ADD ("%s\n", gps_info);
+  PTB_ADD (" %s\n", gps_pos);
+  PTB_ADD (" %s\n", gps_svin_info);
+  PTB_ADD ("\n");
+
+  PTB_ADD ("%s", gps_svinfo);
+  PTB_ADD ("
\n"); + PTB_ADD ("\n"); + PTB_ADD ("\n"); + + return PTB_LEN; +} + + +static int cgi_set_lra (double lra) +{ + uint64_t abs = ref_get(); + EPOCH e = ref_decompose (abs); + double ra = ra_normalize (lra - gps_lon); + alarm = time_ra_to_next_epoch (e, ra); + + return 0; +} + + + +static int cgi_set_lst (char *lst_str) +{ + double ra = 0; + char *a2, *a3; + char *s = NULL, *m = NULL, *h = NULL; + unsigned i = 0; + + printf ("set lst = %s\n", lst_str); + + a2 = index (lst_str, ':'); + + if (!a2) { + h = NULL; + m = NULL; + s = lst_str; + } else { + a2++; + a3 = index (a2, ':'); + + if (!a3) { + m = lst_str; + s = a2; + } else { + a3++; + h = lst_str; + m = a2; + s = a3; + } + } + + ra = atof (s); + + + if (h) + i += atoi (h); + + i *= 60; + + if (m) i += atoi (m); + + i *= 60; + + ra += (double) i; + + ra /= 240.; + + return cgi_set_lra (ra); +} + +static char *uri_unescape (char *c) +{ + char *ret = c, *ptr; + + for (ptr = c; *c; ++c, ++ptr) { + + if (*c != '%') { + *ptr = *c; + continue; + } + + if (!c[1] || !c[2]) break; + + *ptr = (xtoi (c[1]) << 4) | xtoi (c[2]); + + c += 2; + } + + * ptr = 0; + + return ret; +} + + +static const char *cgi_set_handler (int idx, int num_params, char *params[], char *values[]) +{ + do { + if (num_params != 1)break; + + if (!strcmp (params[0], "lra")) { + if (cgi_set_lra (atof (values[0]))) + break; + } else if (!strcmp (params[0], "lst")) { + if (cgi_set_lst (uri_unescape (values[0]))) + break; + } else + break; + + return "/index.html"; + + } while (0); + + return "/error.html"; +} + + +int fs_open_custom (struct fs_file *file, const char *name) +{ + int len; + + if (!strcmp (name, "/index.html")) + len = make_index(); + else if (!strcmp (name, "/alarm.html")) + len = make_alarm(); + else { + printf ("looking for url=%s, found nothing\n", name); + return 0; + } + + file->data = (const char *)html_buf; + file->len = len; + file->index = file->len; + file->pextension = NULL; + file->flags = 0; + + + return 1; +} + + + + +void fs_close_custom (struct fs_file *file) +{ +} + + + +static tCGI cgi_handlers[] = {{"/alarm_set.cgi", cgi_set_handler}}; +void cgi_init (void) +{ + http_set_cgi_handlers (cgi_handlers, sizeof (cgi_handlers) / sizeof (cgi_handlers[0])); +} + + diff --git a/app/lwip/lwipopts.h b/app/lwip/lwipopts.h index ee49f7c..7adba9c 100644 --- a/app/lwip/lwipopts.h +++ b/app/lwip/lwipopts.h @@ -213,6 +213,7 @@ The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums #define LWIP_HTTPD_CUSTOM_FILES 1 #define LWIP_HTTPD_FILE_STATE 0 +#define LWIP_HTTPD_CGI 1 diff --git a/app/lwip_glue.c b/app/lwip_glue.c index 72428ba..b4370a2 100644 --- a/app/lwip_glue.c +++ b/app/lwip_glue.c @@ -32,6 +32,7 @@ void start_lwip (void) httpd_init(); + cgi_init(); } static sys_prot_t ethernet_irq_enabled = 1; diff --git a/app/prototypes.h b/app/prototypes.h index e763d3d..66f6586 100644 --- a/app/prototypes.h +++ b/app/prototypes.h @@ -72,6 +72,8 @@ extern int time_known; extern const struct rcc_clock_scale hse_10mhz_3v3_168; extern int main(void); /* time_fn.c */ +extern EPOCH time_epoch_sub(EPOCH a, EPOCH b); +extern EPOCH time_epoch_add(EPOCH a, EPOCH b); extern UTC time_epoch_to_utc(EPOCH epoch); extern EPOCH time_utc_to_epoch(UTC u); extern void utc_to_str(char *dst, UTC *u); @@ -79,8 +81,12 @@ extern void time_print_utc(const char *p, UTC *u, const char *t); extern void time_print_epoch(const char *p, EPOCH e, const char *t); extern double time_utc_to_tjd(UTC u); extern double time_utc_to_ra(UTC u); +extern double time_st_to_ra(ST st); +extern double ra_normalize(double ra); extern ST time_ra_to_st(double ra); extern ST time_utc_to_lst(UTC u, double lon); +extern int time_ra_cmp(double a, double b); +extern EPOCH time_ra_to_next_epoch(EPOCH l, double tra); /* ntp.c */ extern void ntp_init(void); /* dcf77.c */ @@ -92,6 +98,7 @@ extern void dcf77_init(void); extern int check_parity(uint8_t *d, unsigned s, unsigned e, uint8_t p); extern unsigned bcd(uint8_t *d, unsigned s, unsigned e); extern unsigned le_bcd(uint8_t *d, unsigned s, unsigned e); +extern unsigned xtoi(char c); /* stats.c */ /* gps.c */ extern unsigned gps_sats_searching; @@ -191,6 +198,8 @@ extern void ptp_slow_tick(void); extern void display_report_fix(char fix, char fix2); extern void display_report_svin(int valid, int active); extern void display_dispatch(void); -/* fs.c */ +/* httpd.c */ +extern EPOCH alarm; extern int fs_open_custom(struct fs_file *file, const char *name); extern void fs_close_custom(struct fs_file *file); +extern void cgi_init(void); diff --git a/app/ptb.h b/app/ptb.h new file mode 100644 index 0000000..865cacf --- /dev/null +++ b/app/ptb.h @@ -0,0 +1,5 @@ + +#define PTB_INIT(b) int _ptb_len=0,_ptb_left=sizeof(b)-1; char * _ptb_ptr=b; +#define PTB_ADD(a...) do { int _ptb_writ=snprintf(_ptb_ptr,_ptb_left,a ); if (_ptb_writ >=0 ) { _ptb_left-=_ptb_writ; _ptb_len+=_ptb_writ; _ptb_ptr+=_ptb_writ; } } while (0) +#define PTB_LEN _ptb_len + diff --git a/app/time_fn.c b/app/time_fn.c index fc3f829..64a92ff 100644 --- a/app/time_fn.c +++ b/app/time_fn.c @@ -15,6 +15,39 @@ static int is_leap (unsigned year) return 1; } +EPOCH time_epoch_sub (EPOCH a, EPOCH b) +{ + EPOCH ret; + + ret.ns = a.ns - b.ns; + ret.s = a.s - b.s; + + if (!ret.s) return ret; + + if (ret.ns < 0) { + ret.s--; + ret.ns += 1000000000; + } + + return ret; +} + + +EPOCH time_epoch_add (EPOCH a, EPOCH b) +{ + EPOCH ret; + + ret.ns = a.ns + b.ns; + ret.s = a.s + b.s; + + while (ret.ns > 1000000000) { + ret.s++; + ret.ns -= 1000000000; + } + + return ret; +} + UTC time_epoch_to_utc (EPOCH epoch) { @@ -293,6 +326,20 @@ time_utc_to_tjd (UTC u) return ret; } + +double ra_normalize (double ra) +{ + + while (ra < 0.) + ra += 360.; + + if (ra >= 360.0) + ra = remainder (ra, 360.); + + return ra; +} + + double time_utc_to_ra (UTC u) { @@ -302,9 +349,31 @@ time_utc_to_ra (UTC u) 280.46061837 + (360.98564736629 * tjd) + (0.000387933 * T * T) - (T * T * T / 38710000.0); - return remainder (theta0, 360.); + + return ra_normalize (remainder (theta0, 360.)); } +double time_st_to_ra (ST st) +{ + double ra; + unsigned i; + + i = st.hour; + i *= 60; + i += st.minute; + i *= 60; + i += st.second; + + ra = (double) st.nanosecond; + ra /= 1000000000.; + ra += (double) i; + + ra /= 240.; + + return ra; +} + + ST time_ra_to_st (double ra) @@ -312,11 +381,7 @@ time_ra_to_st (double ra) ST ret; unsigned i; - while (ra < 0.) - ra += 360.; - - if (ra >= 360.0) - ra = remainder (ra, 360.); + ra = ra_normalize (ra); ra *= 240.0; @@ -344,4 +409,60 @@ ST time_utc_to_lst (UTC u, double lon) return time_ra_to_st (ra + lon); } +int time_ra_cmp (double a, double b) +{ + return (ra_normalize (a - b) < 180.) ? -1 : 1;; +} + + +/*Find the next occuring time for RA tra */ + +EPOCH time_ra_to_next_epoch (EPOCH l, double tra) +{ + EPOCH r, m; + unsigned n; + UTC u; + double ra; + + printf ("time_ra_to_next_epoch %.9f\n", tra); + + /* XXX: we should use newton raphson, but */ + /* 1) we're on team hooke */ + /* 2) we want to limit the domain of solutions */ + /* So IB works better */ + + + r = l; + r.s += 86400.; + + for (n = 0; n < 64; ++n) { + + m = time_epoch_sub (r, l); + + if (m.s < 0) { + m.s = 0; + m.ns = 0; + break; + } + + if (m.s & 1) + m.ns += 1000000000; + + m.s /= 2; + m.ns /= 2; + + m = time_epoch_add (l, m); + + u = time_epoch_to_utc (m); + ra = time_utc_to_ra (u); + + if (time_ra_cmp (ra, tra) < 0) + r = m; + + else + l = m; + } + + return m; +} diff --git a/app/util.c b/app/util.c index 7f05a60..b0ffe53 100644 --- a/app/util.c +++ b/app/util.c @@ -55,3 +55,13 @@ unsigned le_bcd (uint8_t *d, unsigned s, unsigned e) } +unsigned xtoi (char c) +{ + if ((c >= '0') && (c <= '9')) return c - '0'; + + if ((c >= 'a') && (c <= 'f')) return 0xa + (c - 'a'); + + if ((c >= 'A') && (c <= 'F')) return 0xA + (c - 'A'); + + return 0; +} -- cgit v1.2.3