From 1de5a34e0c1a32bb0c4c2872ad7c2a2c9e950a01 Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Sat, 15 Mar 2014 09:31:40 +0000 Subject: [PATCH] Split start and period set functions --- hw2/main_comm.c | 18 +++++++----------- hw2/main_emit.c | 40 ++++++++++++++++++++++++++++++++-------- hw2/main_emit.h | 7 +++++-- 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/hw2/main_comm.c b/hw2/main_comm.c index a9dbf77..54cdffc 100644 --- a/hw2/main_comm.c +++ b/hw2/main_comm.c @@ -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; diff --git a/hw2/main_emit.c b/hw2/main_emit.c index ffec296..6588e1f 100644 --- a/hw2/main_emit.c +++ b/hw2/main_emit.c @@ -1,6 +1,7 @@ #include #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"); } } diff --git a/hw2/main_emit.h b/hw2/main_emit.h index 577174a..355aa40 100644 --- a/hw2/main_emit.h +++ b/hw2/main_emit.h @@ -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); -- 2.43.2