diff options
author | root <root@ka-ata-killa.ourano.james.local> | 2021-03-20 16:20:42 +0000 |
---|---|---|
committer | root <root@ka-ata-killa.ourano.james.local> | 2021-03-20 16:20:42 +0000 |
commit | 5b8f47a70a57765ba04a4d75dfa31a2f55f75029 (patch) | |
tree | 7f74f74344d9e8fdca1a6e0cfee2f957e1135540 | |
parent | 4342064ee35d4facf1ad4cbde8f6f84460df02a0 (diff) | |
download | clock-5b8f47a70a57765ba04a4d75dfa31a2f55f75029.tar.gz clock-5b8f47a70a57765ba04a4d75dfa31a2f55f75029.tar.bz2 clock-5b8f47a70a57765ba04a4d75dfa31a2f55f75029.zip |
add alarm support
-rw-r--r-- | app/Makefile | 2 | ||||
-rw-r--r-- | app/fs.c | 69 | ||||
-rw-r--r-- | app/httpd.c | 297 | ||||
-rw-r--r-- | app/lwip/lwipopts.h | 1 | ||||
-rw-r--r-- | app/lwip_glue.c | 1 | ||||
-rw-r--r-- | app/prototypes.h | 11 | ||||
-rw-r--r-- | app/ptb.h | 5 | ||||
-rw-r--r-- | app/time_fn.c | 133 | ||||
-rw-r--r-- | app/util.c | 10 |
9 files changed, 452 insertions, 77 deletions
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 ("<pre>\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 ("</pre>\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 ("<html>\n"); + PTB_ADD ("<body>\n"); + PTB_ADD ("<form method='get' action='/index.html'><input type='submit' value='back' /></form>\n"); + + PTB_ADD ("<h2>Alarm</h2>\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 ("<pre>\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 ("</pre>\n"); + + PTB_ADD ("<table>\n"); + PTB_ADD ("<tr><td><form method='get' action='/alarm_set.cgi'><td>LRA:</td><td><input type='text' name='lra' value='%.9f' size='32' maxlength='32' /></td><td><input type='submit' value='set' /></td></form></tr>\n", lra); + PTB_ADD ("<tr><td><form method='get' action='/alarm_set.cgi'><td>LST:</td><td><input type='text' name='lst' value='%02d:%02d:%02d.%06d' size='32' maxlength='32' /></td><td><input type='submit' value='set' /></td></form></tr>\n", l.hour, l.minute, l.second, l.nanosecond / 1000); + PTB_ADD ("</table>\n"); + + PTB_ADD ("</body>\n"); + PTB_ADD ("</html>\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 ("<html>\n"); + PTB_ADD ("<head><meta http-equiv='refresh' content='5; url=/'></head>\n"); + PTB_ADD ("<body>\n"); + PTB_ADD ("<form method='get' action='/index.html'><input type='submit' value='refresh' /></form>\n"); + PTB_ADD ("<h2>Now</h2>\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 ("<pre>\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 ("</pre>\n"); + PTB_ADD ("\n"); + PTB_ADD ("<h2>Alarm</h2>\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 ("<pre>\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 ("</pre>\n"); + + PTB_ADD ("<form method='get' action='/alarm.html'><input type='submit' value='set' /></form>\n"); + + PTB_ADD ("<h2>GPS</h2>\n"); + PTB_ADD ("<pre>\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 ("</pre>\n"); + PTB_ADD ("</body>\n"); + PTB_ADD ("</html>\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; +} @@ -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; +} |