summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorroot <root@ka-ata-killa.ourano.james.local>2021-03-20 16:20:42 +0000
committerroot <root@ka-ata-killa.ourano.james.local>2021-03-20 16:20:42 +0000
commit5b8f47a70a57765ba04a4d75dfa31a2f55f75029 (patch)
tree7f74f74344d9e8fdca1a6e0cfee2f957e1135540
parent4342064ee35d4facf1ad4cbde8f6f84460df02a0 (diff)
downloadclock-5b8f47a70a57765ba04a4d75dfa31a2f55f75029.tar.gz
clock-5b8f47a70a57765ba04a4d75dfa31a2f55f75029.tar.bz2
clock-5b8f47a70a57765ba04a4d75dfa31a2f55f75029.zip
add alarm support
-rw-r--r--app/Makefile2
-rw-r--r--app/fs.c69
-rw-r--r--app/httpd.c297
-rw-r--r--app/lwip/lwipopts.h1
-rw-r--r--app/lwip_glue.c1
-rw-r--r--app/prototypes.h11
-rw-r--r--app/ptb.h5
-rw-r--r--app/time_fn.c133
-rw-r--r--app/util.c10
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;
+}
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;
+}