]> Pileus Git - ~andy/csm213a-hw/commitdiff
Split start and period set functions
authorAndy Spencer <andy753421@gmail.com>
Sat, 15 Mar 2014 09:31:40 +0000 (09:31 +0000)
committerAndy Spencer <andy753421@gmail.com>
Sat, 15 Mar 2014 09:31:40 +0000 (09:31 +0000)
hw2/main_comm.c
hw2/main_emit.c
hw2/main_emit.h

index a9dbf7757baf97eb27d12629ec2003ab8d445ff5..54cdffcf23d18b9025359e8836f36d6a1d6d56c1 100644 (file)
@@ -227,18 +227,14 @@ void comm_handle_init(header_t *head, init_msg_t *body)
        if (body->control & MSG_CTL_VALID_DEVICE)
                comm_device_id = body->device;
 
-       if (body->control & MSG_CTL_VALID_START ||
-           body->control & MSG_CTL_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_START)
+               emit_set_start(comm_read_time(body->start));
 
-       if (body->control & MSG_CTL_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_VALID_PERIOD)
+               emit_set_period(comm_read_time(body->period));
+
+       if (body->control & MSG_CTL_VALID_WORLD)
+               time_ext_init(tdma_time(), comm_read_time(body->world));
 
        if (body->control & MSG_CTL_RELAY_MODE)
                comm_relay_mode = 1;
index ffec2967265f3dbf33ae0c6a5cc0d9174e3ce6e0..6588e1fc35079709d72bc6d44b69555bd3759d94 100644 (file)
@@ -1,6 +1,7 @@
 #include <stdint.h>
 
 #include "serial_irq.h"
+#include "timer_dma.h"
 #include "main_time.h"
 #include "main_emit.h"
 
@@ -39,6 +40,8 @@
 #define EMIT_NSEC(clocks) ((uint32_t)((clocks) * 1000 / 3))
 #endif
 
+#define EMIT_SLACK_CLOCKS 0x4000  // tune based on emit_worst
+
 static uint32_t *emit_pcr    = 0; // transmit pin name
 
 static uint64_t  emit_start  = 0; // transmit start time (world time)
@@ -48,8 +51,28 @@ static uint64_t  emit_due    = 0; // next transmit (world time)
 static uint32_t  emit_slack  = 0; // how far ahead we need to schedule, in us
 static uint32_t  emit_worst  = 0; // worst-case latency in task table
 
+static void emit_setup(void)
+{
+       //        start-.  .-phase-.--period--.
+       //      |       @  |       @  |       @  |
+       //  utc-^                last-^ now-^
+       if (emit_period) {
+               uint64_t now   = tdma_time();
+               uint64_t phase = emit_start % emit_period;
+               uint64_t last  = (now / emit_period) * emit_period;
+               emit_due = last + phase;
+       } else {
+               emit_due = 0;
+       }
+
+       time_printf("emit scheduled", emit_due);
+}
+
 void emit_init(int alt, PinName pin, PinMode mode)
 {
+       // Calculate slack time
+       emit_slack  = EMIT_NSEC(EMIT_SLACK_CLOCKS);
+
        // Find pin
        emit_pcr = (uint32_t*)(PORTA_BASE + pin);
 
@@ -92,17 +115,16 @@ void emit_init(int alt, PinName pin, PinMode mode)
        TPM1->CONF             = TPM_CONF_CSOO_MASK;
 }
 
-void emit_enable(uint64_t start, uint64_t period)
+void emit_set_start(uint64_t start)
 {
-       const int slack_clocks = 0x4000; // tune based on emit_worst
-
        emit_start  = start;
-       emit_period = period;
-       emit_due    = start + period;
-
-       emit_slack  = EMIT_NSEC(slack_clocks);
+       emit_setup();
+}
 
-       time_printf("emit scheduled", emit_due);
+void emit_set_period(uint64_t period)
+{
+       emit_period = period;
+       emit_setup();
 }
 
 void emit_schedule(uint64_t when)
@@ -174,6 +196,8 @@ void emit_transmit(uint64_t local, uint64_t world)
            world+emit_slack > emit_due) {
                emit_schedule(emit_due);
                emit_due += emit_period;
+               if (emit_due < local)
+                       sirq_printf("missed emit deadline\r\n");
        }
 }
 
index 577174ad41424904beb3c6a945dffabf86c3d4cc..355aa40b64a7183f74f1075699914e1b01a78e54 100644 (file)
@@ -8,8 +8,11 @@ extern "C" {
 /* Signal generation init */
 void emit_init(int alt, PinName pin, PinMode mode);
 
-/* Configure GPIO output */
-void emit_enable(uint64_t start, uint64_t period);
+/* Configure signal generation phase */
+void emit_set_start(uint64_t start);
+
+/* Configure signal generation frequency */
+void emit_set_period(uint64_t period);
 
 /* Queue GPIO signal if due */
 void emit_transmit(uint64_t local, uint64_t world);