5 #include "serial_irq.h"
11 /***************************
12 * Communication functions *
13 ***************************/
15 static uint32_t comm_device_id = 0;
17 const uint64_t comm_sync_delay = NSEC_PER_SEC / 100;
18 static uint64_t comm_sync_due = 0;
20 static sirq_t *comm_sirq_dbg = 0;
21 static sirq_t *comm_sirq_bbb = 0;
22 static sirq_t *comm_sirq_mbed = 0;
24 static tdma_t *comm_tdma_rcv = 0;
25 static tdma_t *comm_tdma_xmt = 0;
30 void comm_init(sirq_t *dbg, sirq_t *bbb, sirq_t *mbed,
31 tdma_t *rcv, tdma_t *xmt)
35 comm_sirq_mbed = mbed;
42 * Convert world to local time
44 uint64_t comm_read_time(ntime_t time)
46 return ((uint64_t)time.seconds) * NSEC_PER_SEC
47 + ((uint64_t)time.nanosec);
50 ntime_t comm_write_time(uint64_t time)
53 buf.seconds = time / NSEC_PER_SEC;
54 buf.nanosec = time % NSEC_PER_SEC;
58 int comm_time_stamp(tdma_t *port, uint64_t *local, uint64_t *world,
61 int valid = tdma_stamp(port, local);
62 *world = time_to_world(*local);
65 sirq_printf("%s -- missing\r\n", msg);
67 // time_printf(msg, current);
73 * Output initialization message init message
75 void comm_send_init(uint16_t device, uint64_t local)
80 * Output time sync message
82 void comm_send_sync(sirq_t *port, uint64_t now)
84 if (comm_sync_due == 0 || now < comm_sync_due)
92 head.header = MSG_HEADER;
93 head.msgid = MSG_ID_SYNC;
94 head.length = sizeof(body);
95 head.cksum = 0; // todo
97 tdma_stop(comm_tdma_rcv, 0);
98 tdma_start(comm_tdma_xmt);
100 sirq_write(port, &head, sizeof(head));
102 tdma_stop(comm_tdma_xmt, 100);
103 tdma_start(comm_tdma_rcv);
105 // Save transmit time
106 uint64_t local = 0, world = 0;
107 comm_time_stamp(comm_tdma_xmt, &local, &world,
108 "sync time transmit");
111 //sirq_printf("sync time transmit\r\n");
112 //time_printf(" local", local);
113 //time_printf(" world", world);
115 // Write body with updated time and send
116 body.time = comm_write_time(world);
118 sirq_write(port, &body, sizeof(body));
120 // Queue next transmit time
125 * Output external event received message
126 * event: id of the received event
127 * time: compensated timestamp of the event
129 void comm_send_event(sirq_t *port, uint16_t event, uint64_t local)
131 //time_printf("event received", local);
134 uint64_t world = time_to_world(local);
135 ntime_t ltime = comm_write_time(local);
136 ntime_t wtime = comm_write_time(world);
140 event_msg_t body = {};
142 // Transmit sync message
143 head.header = MSG_HEADER;
144 head.msgid = MSG_ID_EVENT;
145 head.length = sizeof(body);
146 head.cksum = 0; // todo
148 body.device = comm_device_id;
153 // Transmit message to BBB
154 sirq_write(port, &head, sizeof(head));
155 sirq_write(port, &body, sizeof(body));
159 * Handle init message
161 void comm_handle_init(int msgid, init_msg_t *body)
163 sirq_printf("initialize: %s %s %s %s %s\r\n",
164 body->valid & MSG_VALID_DEVICE ? "DEV" : "dev",
165 body->valid & MSG_VALID_START ? "START" : "start",
166 body->valid & MSG_VALID_PERIOD ? "PERIOD" : "period",
167 body->valid & MSG_VALID_WORLD ? "WORLD" : "world",
168 body->valid & MSG_VALID_SYNC ? "SYNC" : "sync");
169 sirq_printf(" dev -- %d\r\n", body->device);
170 time_printf(" start ", comm_read_time(body->start));
171 time_printf(" period", comm_read_time(body->period));
172 time_printf(" world ", comm_read_time(body->world));
174 if (body->valid & MSG_VALID_DEVICE)
175 comm_device_id = body->device;
177 if (body->valid & MSG_VALID_START ||
178 body->valid & MSG_VALID_PERIOD) {
179 uint64_t start = comm_read_time(body->start);
180 uint64_t period = comm_read_time(body->period);
181 emit_enable(start, period);
184 if (body->valid & MSG_VALID_WORLD) {
185 uint64_t world = comm_read_time(body->world);
186 uint64_t local = tdma_time();
187 time_ext_init(local, world);
190 if (body->valid & MSG_VALID_SYNC)
191 comm_sync_due = tdma_time() + comm_sync_delay;
195 * Handle sync message
197 void comm_handle_sync(int msgid, sync_msg_t *body)
199 // Read receive timestamp
200 uint64_t local = 0, world = 0;
201 comm_time_stamp(comm_tdma_rcv, &local, &world,
202 "sync time receive ");
203 tdma_stop(comm_tdma_rcv, 0);
205 // Lookup reference time from message
206 uint64_t reference = comm_read_time(body->time);
209 //sirq_printf("sync time receive\r\n");
210 //time_printf(" local", local);
211 //time_printf(" world", world);
212 //time_printf(" ref ", reference);
214 // Synchronize the clocks
215 time_ext_sync(local, reference);
217 // Queue transmit to other board
218 comm_sync_due = tdma_time() + comm_sync_delay;
222 * Handle event message
224 void comm_handle_event(header_t *head, event_msg_t *body)
226 // Relay event from mbed to bbb
227 if (comm_device_id == 1) {
228 sirq_write(comm_sirq_bbb, &head, sizeof(head));
229 sirq_write(comm_sirq_bbb, &body, sizeof(body));