#define MARGIN_NOSE 6 /*mm*/
#define MARGIN_TAIL 6 /*mm*/
#define MARGIN_SPEED 1.2 /*ratio*/
-#define MARGIN_STOPTIME 50 /*ms*/
#define MARGIN_AUTOPOINTTIME 500 /*ms*/
-#define MARGIN_POLARISETIME 50 /*ms*/
#define UNMARGIN_ROUNDING 1e-4 /* mm/ms; for 1s, leads to max err of 100um */
+#define MARGIN_STOPTIME 60 /*ms*/
+#define MARGIN_POLARISETIME 60 /*ms*/
+
+#define UNMARGIN_WATCHDOG_16 3 /* 16ms units */ /* should be < MARGIN_*TIME */
+#define UNMARGIN_WATCHDOG (UNMARGIN_WATCHDOG_16*16) /*ms*/
+#define MARGIN_WATCHDOG 20
+
#endif /*SAFETY_H*/
StartupState sta_state;
static TimeoutEvent sta_toev= { .pclass="startup", .pinst="sta" };
-static TimeoutEvent ping_toev= { .pclass="startup", .pinst="ping" };
-static int ping_seq;
static PicInsn piob;
static void sta_goto(StartupState new_state);
-static void timedout_onward(TimeoutEvent *toev) {
- assert(sta_state != Sta_Run);
- if (sta_state == Sta_Settling) {
- enco_pic_off(&piob);
- serial_transmit(&piob);
- }
- sta_goto(sta_state == Sta_Flush ? Sta_Ping : sta_state + 1);
-}
+/*---------- ping ----------*/
+
+static int ping_seq;
+static TimeoutEvent ping_toev= { .pclass="startup", .pinst="ping" };
static void timedout_ping(TimeoutEvent *toev) {
assert(sta_state >= Sta_Ping);
struct timeval now;
mgettimeofday(&now);
-oprintf(DUPO("ip") " %ld.%06ld\n", now.tv_sec, now.tv_usec);
ping_seq= (now.tv_sec & 0x1fU) << 5; /* bottom 5bi of secs: period 32s */
ping_seq |= (now.tv_usec >> 15); /* top 5bi of 20bi us: res.~2^15us */
ping_toev.duration= 300;
timefor_ping(0);
}
+/*---------- watchdog ----------*/
+
+static TimeoutEvent watchdog_toev= { .pclass="startup", .pinst="watchdog" };
+static PicInsn watchdog_piob;
+
+static void watchdog_transmit(TimeoutEvent *toev) {
+ toev_start(&watchdog_toev);
+ serial_transmit(&watchdog_piob);
+}
+
+static void watchdog_start(void) {
+ watchdog_toev.duration= UNMARGIN_WATCHDOG - MARGIN_WATCHDOG;
+ watchdog_toev.callback= watchdog_transmit;
+ enco_pic_watchdog(&watchdog_piob, UNMARGIN_WATCHDOG_16);
+ watchdog_transmit(0);
+}
+
+static void watchdog_stop(void) {
+ if (!watchdog_toev.running) return;
+ toev_stop(&watchdog_toev);
+ enco_pic_watchdog(&watchdog_piob, 0);
+ serial_transmit(&watchdog_piob);
+}
+
+/*---------- main startup algorithm ----------*/
+
+static void timedout_onward(TimeoutEvent *toev) {
+ assert(sta_state != Sta_Run);
+ if (sta_state == Sta_Settling) {
+ enco_pic_off(&piob);
+ serial_transmit(&piob);
+ }
+ sta_goto(sta_state == Sta_Flush ? Sta_Ping : sta_state + 1);
+}
+
static void sta_startup_manual(void) {
waggle_startup_manual();
retransmit_start();
}
if (piob.l) serial_transmit(&piob);
+ if (new_state >= Sta_Run) watchdog_start();
+ else watchdog_stop();
+
toev_start(&sta_toev);
sta_state= new_state;
void on_pic_wtimeout(const PicInsnInfo *pii, const PicInsn *pi, int objnum) {
if (sta_state <= Sta_Settling) return;
- if (sta_state == Sta_Resolving || sta_state == Sta_Finalising)
- die("PIC sent WTIMEOUT in Resolving or Finalising");
- oprintf(UPO, "warning watchdog : PIC watchdog timer triggered\n");
+ die("microcontrollers' watchdog timer triggered\n");
}
void on_pic_hello(const PicInsnInfo *pii, const PicInsn *pi, int objnum)