#include "main_time.h"
#include "main_emit.h"
+/**
+ * Communcation overview:
+ *
+ * Initialization:
+ * bbb --init1--> mbed1
+ * bbb --init2--> mbed1 --init2---> mbed2
+ *
+ * Time sync:
+ * bbb mbed1 ---sync---> mbed2
+ * bbb mbed1 <--sync---- mbed2
+ *
+ * Event Receive:
+ * bbb <--event1-- mbed1 mbed2
+ * bbb <--event2-- mbed1 <--event2-- mbed2
+ *
+ * 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
+ * does not match the configured Device ID, the messages is relayed to the
+ * second mbed.
+ *
+ * Event receive:
+ * When receiving events, an event message is sent from the mbed to the
+ * bbb. If the mbed receiving the event is not Device 1, the message is
+ * sent to mbed1 instead of the bbb.
+ *
+ * Debug ports:
+ * 1. Init messages may be received from the host instead of the bbb
+ * 2. Event messages may be sent to the host in addition to the bbb
+ */
+
/***************************
* Communication functions *
***************************/
static tdma_t *comm_tdma_rcv = 0;
static tdma_t *comm_tdma_xmt = 0;
-/**
- * Initialization
- */
-void comm_init(sirq_t *dbg, sirq_t *bbb, sirq_t *mbed,
- tdma_t *rcv, tdma_t *xmt)
-{
- comm_sirq_dbg = dbg;
- comm_sirq_bbb = bbb;
- comm_sirq_mbed = mbed;
-
- comm_tdma_rcv = rcv;
- comm_tdma_xmt = xmt;
-}
-
/**
* Convert world to local time
*/
-uint64_t comm_read_time(ntime_t time)
+static uint64_t comm_read_time(ntime_t time)
{
return ((uint64_t)time.seconds) * NSEC_PER_SEC
+ ((uint64_t)time.nanosec);
}
-ntime_t comm_write_time(uint64_t time)
+static ntime_t comm_write_time(uint64_t time)
{
ntime_t buf = {};
buf.seconds = time / NSEC_PER_SEC;
return buf;
}
-int comm_time_stamp(tdma_t *port, uint64_t *local, uint64_t *world,
+static int comm_time_stamp(tdma_t *port, uint64_t *local, uint64_t *world,
const char *msg)
{
int valid = tdma_stamp(port, local);
}
/**
- * Output initialization message init message
+ * Initialization
*/
-void comm_send_init(uint16_t device, uint64_t local)
+void comm_init(sirq_t *dbg, sirq_t *bbb, sirq_t *mbed,
+ tdma_t *rcv, tdma_t *xmt)
{
+ comm_sirq_dbg = dbg;
+ comm_sirq_bbb = bbb;
+ comm_sirq_mbed = mbed;
+
+ comm_tdma_rcv = rcv;
+ comm_tdma_xmt = xmt;
}
+
/**
* Output time sync message
*/
-void comm_send_sync(sirq_t *port, uint64_t now)
+void comm_send_sync(uint64_t local)
{
- if (comm_sync_due == 0 || now < comm_sync_due)
+ if (comm_sync_due == 0 || local < comm_sync_due)
return; // not ready
// Message data
tdma_stop(comm_tdma_rcv, 0);
tdma_start(comm_tdma_xmt);
- sirq_write(port, &head, sizeof(head));
+ sirq_write(comm_sirq_mbed, &head, sizeof(head));
tdma_stop(comm_tdma_xmt, 100);
tdma_start(comm_tdma_rcv);
// Save transmit time
- uint64_t local = 0, world = 0;
- comm_time_stamp(comm_tdma_xmt, &local, &world,
+ uint64_t xmt_local = 0, xmt_world = 0;
+ comm_time_stamp(comm_tdma_xmt, &xmt_local, &xmt_world,
"sync time transmit");
// Debug output
//sirq_printf("sync time transmit\r\n");
- //time_printf(" local", local);
- //time_printf(" world", world);
+ //time_printf(" local", xmt_local);
+ //time_printf(" world", xmt_world);
// Write body with updated time and send
- body.time = comm_write_time(world);
+ body.time = comm_write_time(xmt_world);
- sirq_write(port, &body, sizeof(body));
+ sirq_write(comm_sirq_mbed, &body, sizeof(body));
// Queue next transmit time
comm_sync_due = 0;
* event: id of the received event
* time: compensated timestamp of the event
*/
-void comm_send_event(sirq_t *port, uint16_t event, uint64_t local)
+void comm_send_event(uint16_t event, uint64_t local)
{
//time_printf("event received", local);
body.local = ltime;
// Transmit message to BBB
- sirq_write(port, &head, sizeof(head));
- sirq_write(port, &body, sizeof(body));
+ if (comm_device_id == 1) {
+ sirq_write(comm_sirq_bbb, &head, sizeof(head));
+ sirq_write(comm_sirq_bbb, &body, sizeof(body));
+ } else {
+ sirq_write(comm_sirq_mbed, &head, sizeof(head));
+ sirq_write(comm_sirq_mbed, &body, sizeof(body));
+ }
}
/**
* Handle init message
*/
-void comm_handle_init(int msgid, init_msg_t *body)
+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));
+ 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",
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)
comm_device_id = body->device;
/**
* Handle sync message
*/
-void comm_handle_sync(int msgid, sync_msg_t *body)
+void comm_handle_sync(header_t *head, sync_msg_t *body)
{
// Read receive timestamp
uint64_t local = 0, world = 0;