]> Pileus Git - ~andy/csm213a-hw/blobdiff - hw2/main_comm.c
Fix event scheduling bug
[~andy/csm213a-hw] / hw2 / main_comm.c
index 6afe80d27c1550dfffa208b78ea51355ee127161..118f6b3cd42f2499528829e5568fd7c1f00a490e 100644 (file)
@@ -9,7 +9,7 @@
 #include "main_emit.h"
 
 /**
- * Communcation overview:
+ * Communication overview:
  *
  *     Initialization:
  *        bbb --init1-->  mbed1
@@ -26,7 +26,7 @@
  * Initialization:
  *     Each mbed is initialized by the BBB by receiving an initialization
  *     message.  The Device ID must be non-zero, and is saved for future
- *     messages. If the device is already initialized and a recevied Device ID
+ *     messages. If the device is already initialized and a received Device ID
  *     does not match the configured Device ID, the messages is relayed to the
  *     second mbed.
  *
@@ -44,7 +44,8 @@
  * Communication functions *
  ***************************/
 
-static uint32_t comm_device_id   = 0;
+static int      comm_device_id   = 0;
+static int      comm_relay_mode  = 0;
 
 const  uint64_t comm_sync_delay  = NSEC_PER_SEC / 100;
 static uint64_t comm_sync_due    = 0;
@@ -101,7 +102,6 @@ void comm_init(sirq_t *dbg, sirq_t *bbb, sirq_t *mbed,
        comm_tdma_xmt  = xmt;
 }
 
-
 /**
  * Output time sync message
  */
@@ -120,10 +120,13 @@ void comm_send_sync(uint64_t local)
        head.length = sizeof(body);
        head.cksum  = 0; // todo
 
+       sirq_write(comm_sirq_mbed, &head, sizeof(head));
+
+       // Capture transmit time
        tdma_stop(comm_tdma_rcv, 0);
        tdma_start(comm_tdma_xmt);
 
-       sirq_write(comm_sirq_mbed, &head, sizeof(head));
+       sirq_transmit(comm_sirq_mbed);
 
        tdma_stop(comm_tdma_xmt, 100);
        tdma_start(comm_tdma_rcv);
@@ -143,6 +146,8 @@ void comm_send_sync(uint64_t local)
 
        sirq_write(comm_sirq_mbed, &body, sizeof(body));
 
+       sirq_transmit(comm_sirq_mbed);
+
        // Queue next transmit time
        comm_sync_due  = 0;
 }
@@ -154,7 +159,7 @@ void comm_send_sync(uint64_t local)
  */
 void comm_send_event(uint16_t event, uint64_t local)
 {
-       //time_printf("event received", local);
+       time_printf("event received", local);
 
        // Convert timestamp
        uint64_t world = time_to_world(local);
@@ -177,12 +182,12 @@ void comm_send_event(uint16_t event, uint64_t local)
        body.local  = ltime;
 
        // Transmit message to BBB
-       if (comm_device_id == 1) {
-               sirq_write(comm_sirq_bbb,  &head, sizeof(head));
-               sirq_write(comm_sirq_bbb,  &body, sizeof(body));
-       } else {
+       if (comm_relay_mode) {
                sirq_write(comm_sirq_mbed, &head, sizeof(head));
                sirq_write(comm_sirq_mbed, &body, sizeof(body));
+       } else {
+               sirq_write(comm_sirq_bbb,  &head, sizeof(head));
+               sirq_write(comm_sirq_bbb,  &body, sizeof(body));
        }
 }
 
@@ -193,42 +198,53 @@ void comm_handle_init(header_t *head, init_msg_t *body)
 {
        // Relay initialization from bbb to mbed
        if (comm_device_id && body->device != comm_device_id) {
-               sirq_write(comm_sirq_bbb, &head, sizeof(head));
-               sirq_write(comm_sirq_bbb, &body, sizeof(body));
+               //sirq_printf("relaying init\r\n");
+
+               sirq_write(comm_sirq_mbed, head, sizeof(*head));
+               sirq_write(comm_sirq_mbed, body, sizeof(*body));
+
+               // Normally we transmit during the time sync but
+               // if we haven't started syncing yet, we need to
+               // push out the message now.
+               if (!comm_sync_due)
+                       sirq_transmit(comm_sirq_mbed);
                return;
        }
 
        // Debug output
        sirq_printf("initialize: %s %s %s %s %s\r\n",
-               body->valid & MSG_VALID_DEVICE ? "DEV"    : "dev",
-               body->valid & MSG_VALID_START  ? "START"  : "start",
-               body->valid & MSG_VALID_PERIOD ? "PERIOD" : "period",
-               body->valid & MSG_VALID_WORLD  ? "WORLD"  : "world",
-               body->valid & MSG_VALID_SYNC   ? "SYNC"   : "sync");
+               body->control & MSG_CTL_VALID_DEVICE ? "DEV"    : "dev",
+               body->control & MSG_CTL_VALID_START  ? "START"  : "start",
+               body->control & MSG_CTL_VALID_PERIOD ? "PERIOD" : "period",
+               body->control & MSG_CTL_VALID_WORLD  ? "WORLD"  : "world",
+               body->control & MSG_CTL_RELAY_MODE   ? "RELAY"  : "relay",
+               body->control & MSG_CTL_BEGIN_SYNC   ? "SYNC"   : "sync");
        sirq_printf("  dev    -- %d\r\n", body->device);
        time_printf("  start ", comm_read_time(body->start));
        time_printf("  period", comm_read_time(body->period));
        time_printf("  world ", comm_read_time(body->world));
 
        // Validate message parts and initialize
-       if (body->valid & MSG_VALID_DEVICE)
+       if (body->control & MSG_CTL_VALID_DEVICE)
                comm_device_id = body->device;
 
-       if (body->valid & MSG_VALID_START ||
-           body->valid & MSG_VALID_PERIOD) {
-               uint64_t start  = comm_read_time(body->start);
-               uint64_t period = comm_read_time(body->period);
-               emit_enable(start, period);
-       }
+       if (body->control & MSG_CTL_VALID_WORLD)
+               time_ext_init(tdma_time(), comm_read_time(body->world));
 
-       if (body->valid & MSG_VALID_WORLD) {
-               uint64_t world = comm_read_time(body->world);
-               uint64_t local = tdma_time();
-               time_ext_init(local, world);
-       }
+       if (body->control & MSG_CTL_RELAY_MODE)
+               comm_relay_mode = 1;
+       else
+               comm_relay_mode = 0;
 
-       if (body->valid & MSG_VALID_SYNC)
+       if (body->control & MSG_CTL_BEGIN_SYNC)
                comm_sync_due = tdma_time() + comm_sync_delay;
+
+       // Run these after world time is valid
+       if (body->control & MSG_CTL_VALID_START)
+               emit_set_start(comm_read_time(body->start));
+
+       if (body->control & MSG_CTL_VALID_PERIOD)
+               emit_set_period(comm_read_time(body->period));
 }
 
 /**
@@ -263,9 +279,7 @@ void comm_handle_sync(header_t *head, sync_msg_t *body)
  */
 void comm_handle_event(header_t *head, event_msg_t *body)
 {
-       // Relay event from mbed to bbb
-       if (comm_device_id == 1) {
-               sirq_write(comm_sirq_bbb, &head, sizeof(head));
-               sirq_write(comm_sirq_bbb, &body, sizeof(body));
-       }
+       // Relay events from other mbeds
+       sirq_write(comm_sirq_bbb, head, sizeof(*head));
+       sirq_write(comm_sirq_bbb, body, sizeof(*body));
 }