]> Pileus Git - ~andy/csm213a-hw/commitdiff
Improve time sync accuracy
authorAndy Spencer <andy753421@gmail.com>
Mon, 10 Mar 2014 09:14:40 +0000 (09:14 +0000)
committerAndy Spencer <andy753421@gmail.com>
Mon, 10 Mar 2014 09:14:40 +0000 (09:14 +0000)
This code is kind of messy, but it is more accurate.

Noise between time syncs seems to be around 50 nanoseconds. Noise on
external event readings seems to be around 500 nanoseconds. External
events were tested by manually inserting pins.

The mbeds seems to be consistency apart on external events, so some of
the noise could be caused by differing thresholds on the wires. Rising
edge mode on mbed seems to be ahead, and in falling edge the other is
ahead.

A large portion of the measurement errors was caused by not properly
learning pending DMA requests before enabling the DMA channels. The
pending requests seem to need to be disabled in the DMAMUX as well as
the DMA controller, and on the pins as well. It's not clearly what the
idea reset method is.

hw2/main.cpp
hw2/serial_irq.c
hw2/serial_irq.h
hw2/test.cpp
hw2/timer_dma.c
hw2/timer_dma.h

index 108000ee6dfbf42a81bf5bb47f2181498d9f7f6d..87bca115891bdbb3132dcbe0c42211b4a25714ae 100644 (file)
  *   Time synchronization is performed in both directions.
  */
 
  *   Time synchronization is performed in both directions.
  */
 
+/****************
+ * Testing vars *
+ ****************/
+
+uint32_t test_xmt_enab  = 0;
+uint64_t test_xmt_time0 = 0;
+uint64_t test_xmt_time1 = 0;
+
+uint32_t test_rcv_enab  = 0;
+uint64_t test_rcv_time  = 0;
+
 /*******************
  * Timer functions *
  *******************/
 /*******************
  * Timer functions *
  *******************/
@@ -92,19 +103,51 @@ void time_ext_sync(uint64_t local, uint64_t world)
        int      ahead = guess > world;
 
        time_last_local = local;
        int      ahead = guess > world;
 
        time_last_local = local;
-       time_last_world = guess/2 + world/2;
+       time_last_world = (guess/2) + (world/2);
+       //time_last_world = (guess * 3 / 4) + (world * 1 / 4);
+       //time_last_world =
+       //      (guess - (        guess / 2)) +
+       //      (world - (world - world / 2));
+       //time_last_world =
+       //      (guess - (guess - guess / 4)) +
+       //      (world - (        world / 4));
 
        world = time_last_world;
 
 
        world = time_last_world;
 
-       sirq_printf("syncing clocks: %d=%d.%04u -> %d.%04u (err: %s%ld.%09lu)\r\n",
+//#ifdef VERBOSE
+#if 0
+       sirq_printf("syncing clocks: %6d=%d.%04u -> %d.%04u (err: %s%ld.%09lu)\r\n",
                        (int)((local / NSEC_PER_SEC)),
                        (int)((guess / NSEC_PER_SEC)),
                        (int)((guess % NSEC_PER_SEC)/(NSEC_PER_SEC/10000)),
                        (int)((world / NSEC_PER_SEC)),
                        (int)((world % NSEC_PER_SEC)/(NSEC_PER_SEC/10000)),
                        (int)((local / NSEC_PER_SEC)),
                        (int)((guess / NSEC_PER_SEC)),
                        (int)((guess % NSEC_PER_SEC)/(NSEC_PER_SEC/10000)),
                        (int)((world / NSEC_PER_SEC)),
                        (int)((world % NSEC_PER_SEC)/(NSEC_PER_SEC/10000)),
-                       ahead ? "-" : "",
+                       ahead ? "-" : " ",
                        (int32_t )(error / (int64_t)NSEC_PER_SEC),
                        (uint32_t)(error % (int64_t)NSEC_PER_SEC));
                        (int32_t )(error / (int64_t)NSEC_PER_SEC),
                        (uint32_t)(error % (int64_t)NSEC_PER_SEC));
+#endif
+//#endif
+
+       // .000000284
+       // .000000253
+       // .000000264
+       // .000000451
+       // .000000284
+       // .000000267
+       // .000000223
+       // .000000326
+
+}
+
+void time_printf(const char *label, uint64_t local)
+{
+       uint64_t world = time_to_world(local);
+       sirq_printf("%s -- %d.%09u -> %d.%09u\r\n",
+                       label,
+                       (int)(local / NSEC_PER_SEC),
+                       (int)(local % NSEC_PER_SEC),
+                       (int)(world / NSEC_PER_SEC),
+                       (int)(world % NSEC_PER_SEC));
 }
 
 /************************
 }
 
 /************************
@@ -117,7 +160,7 @@ typedef struct {
        uint8_t  buffer[256];
 } parser_t;
 
        uint8_t  buffer[256];
 } parser_t;
 
-const  uint64_t serial_sync_delay = NSEC_PER_SEC / 10; // 1hz
+const  uint64_t serial_sync_delay = NSEC_PER_SEC / 100; // 1hz
 static uint64_t serial_sync_due   = 0;
 
 static tdma_t  *serial_tdma_rcv   = NULL;
 static uint64_t serial_sync_due   = 0;
 
 static tdma_t  *serial_tdma_rcv   = NULL;
@@ -137,7 +180,10 @@ void serial_send_sync(sirq_t *port, uint64_t now)
        if (serial_sync_due == 0 || now < serial_sync_due)
                return; // not ready
 
        if (serial_sync_due == 0 || now < serial_sync_due)
                return; // not ready
 
+       //sirq_printf("sending sync\r\n");
+
        // Calculate world time
        // Calculate world time
+       uint64_t local = 0;
        uint64_t world = time_to_world(serial_xmt_local);
 
        // Message data
        uint64_t world = time_to_world(serial_xmt_local);
 
        // Message data
@@ -154,23 +200,33 @@ void serial_send_sync(sirq_t *port, uint64_t now)
        body.time.seconds = world / NSEC_PER_SEC;
        body.time.nanosec = world % NSEC_PER_SEC;
 
        body.time.seconds = world / NSEC_PER_SEC;
        body.time.nanosec = world % NSEC_PER_SEC;
 
+       tdma_stop(serial_tdma_rcv);
+
+       test_xmt_enab  = 1;
+       test_xmt_time0 = 0;
+       test_xmt_time1 = 0;
+
+       tdma_start(serial_tdma_xmt);
        sirq_write(port, &head, sizeof(head));
        sirq_write(port, &body, sizeof(body));
        sirq_write(port, &head, sizeof(head));
        sirq_write(port, &body, sizeof(body));
+       tdma_stop(serial_tdma_xmt);
 
 
-       serial_xmt_seq  += 1;
-       serial_sync_due  = 0;
+       // save transmit time
+       //local = test_xmt_time1;
+       int valid = tdma_stamp(serial_tdma_xmt, &local);
+       if (!valid) {
+               sirq_printf("sync transmit time -- missed\r\n");
+       } else {
+               //time_printf("sync transmit time ", local);
+               //time_printf("sync transmit test0", test_xmt_time0);
+               //time_printf("sync transmit test1", test_xmt_time1);
+       }
 
 
-       // Debug
-       //sirq_printf("sync msg transmit\r\n");
+       tdma_start(serial_tdma_rcv);
 
 
-       // save transmit time
-       for (int i = 0; i < 1000; i++)
-               asm("nop");
-       int valid = tdma_stamp(serial_tdma_xmt, &serial_xmt_local);
-       if (!valid)
-               sirq_printf("missing sync transmit time\r\n");
-       tdma_reset(serial_tdma_rcv);
-       tdma_reset(serial_tdma_xmt);
+       serial_xmt_seq  += 1;
+       serial_sync_due  = 0;
+       serial_xmt_local = local;
 }
 
 /**
 }
 
 /**
@@ -201,9 +257,10 @@ void serial_handle_sync(sync_msg_t *msg)
        uint64_t current = 0;
        int valid = tdma_stamp(serial_tdma_rcv, &current);
        if (!valid)
        uint64_t current = 0;
        int valid = tdma_stamp(serial_tdma_rcv, &current);
        if (!valid)
-               sirq_printf("missing sync receive time\r\n");
-       tdma_reset(serial_tdma_rcv);
-       tdma_reset(serial_tdma_xmt);
+               sirq_printf("sync receive time  -- missing\r\n");
+       //else
+       //      time_printf("sync receive time ", current);
+       tdma_stop(serial_tdma_rcv);
 
        // Lookup times
        uint64_t world = ((uint64_t)msg->time.seconds) * NSEC_PER_SEC
 
        // Lookup times
        uint64_t world = ((uint64_t)msg->time.seconds) * NSEC_PER_SEC
@@ -359,7 +416,8 @@ void task_events(uint64_t local, uint64_t world)
 
        if (tdma_stamp(tdma_evt, &event))
                serial_send_event(0, event);
 
        if (tdma_stamp(tdma_evt, &event))
                serial_send_event(0, event);
-       tdma_reset(tdma_evt);
+       tdma_stop(tdma_evt);
+       tdma_start(tdma_evt);
 }
 
 void task_sync(uint64_t local, uint64_t world)
 }
 
 void task_sync(uint64_t local, uint64_t world)
@@ -378,6 +436,10 @@ void task_leds(uint64_t local, uint64_t world)
 void task_debug(uint64_t local, uint64_t world)
 {
        //tdma_debug(tdma_rcv);
 void task_debug(uint64_t local, uint64_t world)
 {
        //tdma_debug(tdma_rcv);
+       //tdma_debug(tdma_xmt);
+
+       //sirq_debug(sirq_mbed);
+
 #ifdef VERBOSE
        sirq_printf("background - %6u.%02u -> %u.%02u\r\n",
                        (uint32_t)(local / NSEC_PER_SEC),
 #ifdef VERBOSE
        sirq_printf("background - %6u.%02u -> %u.%02u\r\n",
                        (uint32_t)(local / NSEC_PER_SEC),
@@ -432,9 +494,8 @@ int main(int argc, char **argv)
        sirq_bbb   = sirq_open(SIRQ_UART1, PTE0,  PTE1,  115200); // to bbb
        sirq_mbed  = sirq_open(SIRQ_UART2, PTD3,  PTD2,  115200); // to mbed
 
        sirq_bbb   = sirq_open(SIRQ_UART1, PTE0,  PTE1,  115200); // to bbb
        sirq_mbed  = sirq_open(SIRQ_UART2, PTD3,  PTD2,  115200); // to mbed
 
-
        // Setup timers
        // Setup timers
-       tdma_evt   = tdma_open(TDMA_CHAN0, 3, PTC9,  PullDown); // async event
+       tdma_evt   = tdma_open(TDMA_CHAN0, 3, PTC9,  PullUp); // async event
 
        // mbed time sync
        tdma_rcv   = tdma_open(TDMA_CHAN2, 3, PTD2,  PullUp);   // time sync rcv
 
        // mbed time sync
        tdma_rcv   = tdma_open(TDMA_CHAN2, 3, PTD2,  PullUp);   // time sync rcv
@@ -444,10 +505,46 @@ int main(int argc, char **argv)
        //tdma_rcv   = tdma_open(TDMA_CHAN2, 2, USBRX, PullUp); // time sync rcv
        //tdma_xmt   = tdma_open(TDMA_CHAN3, 2, USBTX, PullUp); // time sync xmt
 
        //tdma_rcv   = tdma_open(TDMA_CHAN2, 2, USBRX, PullUp); // time sync rcv
        //tdma_xmt   = tdma_open(TDMA_CHAN3, 2, USBTX, PullUp); // time sync xmt
 
+       // start timers
+       tdma_start(tdma_evt);
+       tdma_start(tdma_rcv);
+       tdma_start(tdma_xmt);
+
        // Serial timestamping
        serial_tdma_rcv = tdma_rcv;
        serial_tdma_xmt = tdma_xmt;
 
        // Serial timestamping
        serial_tdma_rcv = tdma_rcv;
        serial_tdma_xmt = tdma_xmt;
 
+       // Test clocks
+       //MCG->C1    = 0x05; // was 0x1A
+       //MCG->C2    = 0x2C; // was 0x24
+       //MCG->C3    = 0x91; // was 0x91
+       //MCG->C4    = 0x10; // was 0x10
+       //MCG->C5    = 0x01; // was 0x01
+       //MCG->C6    = 0x40; // was 0x40
+       //MCG->S     = 0x6E; // was 0x6E
+       //MCG->SC    = 0x02; // was 0x02
+       //MCG->ATCVH = 0x00; // was 0x00
+       //MCG->ATCVL = 0x00; // was 0x00
+       //MCG->C7    = 0x00; // was 0x00
+       //MCG->C8    = 0x80; // was 0x80
+       //MCG->C9    = 0x00; // was 0x00
+       //MCG->C10   = 0x00; // was 0x00
+
+       //sirq_printf("MGC - C1    %02hx\r\n", MCG->C1);     // 1A
+       //sirq_printf("MGC - C2    %02hx\r\n", MCG->C2);     // 24
+       //sirq_printf("MGC - C3    %02hx\r\n", MCG->C3);     // 91
+       //sirq_printf("MGC - C4    %02hx\r\n", MCG->C4);     // 10
+       //sirq_printf("MGC - C5    %02hx\r\n", MCG->C5);     // 01
+       //sirq_printf("MGC - C6    %02hx\r\n", MCG->C6);     // 40
+       //sirq_printf("MGC - S     %02hx\r\n", MCG->S);      // 6E
+       //sirq_printf("MGC - SC    %02hx\r\n", MCG->SC);     // 02
+       //sirq_printf("MGC - ATCVH %02hx\r\n", MCG->ATCVH);  // 00
+       //sirq_printf("MGC - ATCVL %02hx\r\n", MCG->ATCVL);  // 00
+       //sirq_printf("MGC - C7    %02hx\r\n", MCG->C7);     // 00
+       //sirq_printf("MGC - C8    %02hx\r\n", MCG->C8);     // 80
+       //sirq_printf("MGC - C9    %02hx\r\n", MCG->C9);     // 00
+       //sirq_printf("MGC - C10   %02hx\r\n", MCG->C10);    // 00
+
        // Run background loop
        printf("hello");
        while (true)
        // Run background loop
        printf("hello");
        while (true)
index 67beeab353ff9ac707eb13696a678925f41443e9..68945cfcbb759e8e46361046f7c40c7ce7734e0f 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdio.h>\r
 #include "serial_api.h"\r
 #include "serial_irq.h"\r
 #include <stdio.h>\r
 #include "serial_api.h"\r
 #include "serial_irq.h"\r
+#include "timer_dma.h"\r
 \r
 /* Defines */\r
 #define SIRQ_LEN  1024\r
 \r
 /* Defines */\r
 #define SIRQ_LEN  1024\r
@@ -21,6 +22,14 @@ struct sirq_t {
        queue_t  rcv;\r
 };\r
 \r
        queue_t  rcv;\r
 };\r
 \r
+/* Test data */\r
+extern uint32_t test_xmt_enab;\r
+extern uint64_t test_xmt_time0;\r
+extern uint64_t test_xmt_time1;\r
+\r
+extern uint32_t test_rcv_enab;\r
+extern uint64_t test_rcv_time;\r
+\r
 /* Port data */\r
 static sirq_t sirq_ports[SIRQ_NUM_UART];\r
 \r
 /* Port data */\r
 static sirq_t sirq_ports[SIRQ_NUM_UART];\r
 \r
@@ -32,7 +41,17 @@ void sirq_handler(uint32_t _port, SerialIrq event)
        // Handle transmit\r
        if (event == TxIrq && port->xmt.rix != port->xmt.wix) {\r
                int byte = port->xmt.buf[port->xmt.rix];\r
        // Handle transmit\r
        if (event == TxIrq && port->xmt.rix != port->xmt.wix) {\r
                int byte = port->xmt.buf[port->xmt.rix];\r
+\r
+               uint64_t time0 = tdma_time();\r
                serial_putc(&port->uart, byte);\r
                serial_putc(&port->uart, byte);\r
+               uint64_t time1 = tdma_time();\r
+\r
+               if (test_xmt_enab) {\r
+                       test_xmt_time0 = time0;\r
+                       test_xmt_time1 = time1;\r
+                       test_xmt_enab  = 0;\r
+               }\r
+\r
                port->xmt.rix = (port->xmt.rix+1) % SIRQ_LEN;\r
        } else {\r
                serial_irq_set(&port->uart, TxIrq, 0);\r
                port->xmt.rix = (port->xmt.rix+1) % SIRQ_LEN;\r
        } else {\r
                serial_irq_set(&port->uart, TxIrq, 0);\r
@@ -75,7 +94,7 @@ void sirq_putc(sirq_t *port, int byte)
 int sirq_getc(sirq_t *port)\r
 {\r
        int byte = 0;\r
 int sirq_getc(sirq_t *port)\r
 {\r
        int byte = 0;\r
-       if (port->rcv.rix < port->rcv.wix) {\r
+       if (port->rcv.rix != port->rcv.wix) {\r
                byte = port->rcv.buf[port->rcv.rix];\r
                port->rcv.rix = (port->rcv.rix+1) % SIRQ_LEN;\r
        }\r
                byte = port->rcv.buf[port->rcv.rix];\r
                port->rcv.rix = (port->rcv.rix+1) % SIRQ_LEN;\r
        }\r
@@ -93,7 +112,29 @@ void sirq_write(sirq_t *port, void *data, int len)
 /* Check if port is writable */\r
 int sirq_ready(sirq_t *port)\r
 {\r
 /* Check if port is writable */\r
 int sirq_ready(sirq_t *port)\r
 {\r
-       return port->rcv.rix < port->rcv.wix;\r
+       return port->rcv.rix != port->rcv.wix;\r
+}\r
+\r
+/* Debug print */\r
+void sirq_debug(sirq_t *port)\r
+{\r
+       sirq_printf("xmt  - wix:%03x rix:%03x\r\n", port->xmt.wix, port->xmt.rix);\r
+       sirq_printf("rcv  - wix:%03x rix:%03x\r\n", port->rcv.wix, port->rcv.rix);\r
+       sirq_printf("irq  - ??\r\n");\r
+       sirq_printf("uart - ??\r\n");\r
+\r
+       // __IO uint8_t BDH;     \r
+       // __IO uint8_t BDL;     \r
+       // __IO uint8_t C1;      \r
+       // __IO uint8_t C2;      \r
+       // __IO uint8_t S1;      \r
+       // __IO uint8_t S2;      \r
+       // __IO uint8_t C3;      \r
+       // __IO uint8_t D;       \r
+       // __IO uint8_t MA1;     \r
+       // __IO uint8_t MA2;     \r
+       // __IO uint8_t C4;      \r
+       // __IO uint8_t C5;      \r
 }\r
 \r
 /* Write ASCII data to the output queue */\r
 }\r
 \r
 /* Write ASCII data to the output queue */\r
index 5595d14518778cd1c77e5523eaf37e0841404438..e640a9e5a9d2f738190c48c3bfbd3d2b073f3fbd 100644 (file)
@@ -33,6 +33,9 @@ void sirq_write(sirq_t *port, void *data, int len);
 /* Read In */
 int  sirq_ready(sirq_t *port);
 
 /* Read In */
 int  sirq_ready(sirq_t *port);
 
+/* Debug print */
+void sirq_debug(sirq_t *port);
+
 /* Print */
 void sirq_vprintf(const char *fmt, va_list ap);
 void sirq_printf(const char *fmt, ...);
 /* Print */
 void sirq_vprintf(const char *fmt, va_list ap);
 void sirq_printf(const char *fmt, ...);
index 3cfb70194367ae050d7414f574875cc871f0ece0..5f95a858603eca0d96025bf870042809f6d2e578 100644 (file)
@@ -296,10 +296,10 @@ void test_tdma_run(void)
        tdma_stamp(tdma2, (uint64_t*)&time2);\r
        tdma_stamp(tdma3, (uint64_t*)&time3);\r
 \r
        tdma_stamp(tdma2, (uint64_t*)&time2);\r
        tdma_stamp(tdma3, (uint64_t*)&time3);\r
 \r
-       tdma_reset(tdma0);\r
-       tdma_reset(tdma1);\r
-       tdma_reset(tdma2);\r
-       tdma_reset(tdma3);\r
+       tdma_start(tdma0);\r
+       tdma_start(tdma1);\r
+       tdma_start(tdma2);\r
+       tdma_start(tdma3);\r
 \r
        printf(" - timer:");\r
        printf(" %08lx:%08lx", time0[1], time0[0]);\r
 \r
        printf(" - timer:");\r
        printf(" %08lx:%08lx", time0[1], time0[0]);\r
index 2e197186cec8b507d902b75b660dfd141aaf4cf5..529fd7e2a59d2873563995cf5d5800f698df91ba 100644 (file)
@@ -6,6 +6,7 @@
 #include <string.h>\r
 \r
 #include "timer_dma.h"\r
 #include <string.h>\r
 \r
 #include "timer_dma.h"\r
+#include "serial_irq.h"\r
 \r
 /* Defines */\r
 enum {\r
 \r
 /* Defines */\r
 enum {\r
@@ -36,6 +37,10 @@ struct tdma_t {
 \r
        /* Time stamping */\r
        uint32_t time[2];\r
 \r
        /* Time stamping */\r
        uint32_t time[2];\r
+\r
+       /* Save state */\r
+       int      req;\r
+       int      irqc;\r
 };\r
 \r
 /* Port data */\r
 };\r
 \r
 /* Port data */\r
@@ -77,7 +82,7 @@ tdma_t *tdma_open(tdma_chan_t chan, int alt, PinName pin, PinMode mode)
                   pin >= PTC0 ? TDMA_REQ_PTC :\r
                   pin >= PTA0 ? TDMA_REQ_PTA : 0;\r
 \r
                   pin >= PTC0 ? TDMA_REQ_PTC :\r
                   pin >= PTA0 ? TDMA_REQ_PTA : 0;\r
 \r
-       int ircq = mode == PullUp ? 2 : 1;\r
+       int irqc = mode == PullUp ? 1 : 2;\r
 \r
        // Allocate port\r
        tdma_t *port    = &tdma_ports[chan];\r
 \r
        // Allocate port\r
        tdma_t *port    = &tdma_ports[chan];\r
@@ -104,24 +109,30 @@ tdma_t *tdma_open(tdma_chan_t chan, int alt, PinName pin, PinMode mode)
        // Set pin to generate DMA req\r
        port->pin->pcr  = PORT_PCR_ISF_MASK         // Clear ISR flag\r
                        | PORT_PCR_MUX(alt)         // Pin mapping\r
        // Set pin to generate DMA req\r
        port->pin->pcr  = PORT_PCR_ISF_MASK         // Clear ISR flag\r
                        | PORT_PCR_MUX(alt)         // Pin mapping\r
-                       | PORT_PCR_IRQC(ircq)       // DMA on falling edge\r
+                       | PORT_PCR_IRQC(irqc)       // DMA on falling edge\r
                        | mode;                     // Pin pull up/down\r
 \r
                        | mode;                     // Pin pull up/down\r
 \r
-       // Initial reset\r
-       tdma_reset(port);\r
+       // Save IRC for later\r
+       port->req       = req;\r
+       port->irqc      = irqc;\r
 \r
        return port;\r
 }\r
 \r
 \r
        return port;\r
 }\r
 \r
-void tdma_reset(tdma_t *port)\r
+void tdma_start(tdma_t *port)\r
 {\r
        if (!port)\r
                return;\r
 \r
 {\r
        if (!port)\r
                return;\r
 \r
+       //sirq_printf("isfr2: %08x\r\n", PORTD->ISFR);\r
+\r
        // Clear previous time\r
        port->time[0] = 0;\r
        port->time[1] = 0;\r
 \r
        // Clear previous time\r
        port->time[0] = 0;\r
        port->time[1] = 0;\r
 \r
+       // Reset DMA Mux\r
+       port->mux->cfg &= DMAMUX_CHCFG_ENBL_MASK;\r
+\r
        // Freeze DMA channel\r
        port->dma->dcr &= ~DMA_DCR_ERQ_MASK;\r
 \r
        // Freeze DMA channel\r
        port->dma->dcr &= ~DMA_DCR_ERQ_MASK;\r
 \r
@@ -133,8 +144,41 @@ void tdma_reset(tdma_t *port)
        port->dma->dar  =  (uint32_t)&port->time;    // Temp timer buffer\r
        port->dma->dsr  =  DMA_DSR_BCR_BCR(8);       // 64-bit timer\r
 \r
        port->dma->dar  =  (uint32_t)&port->time;    // Temp timer buffer\r
        port->dma->dsr  =  DMA_DSR_BCR_BCR(8);       // 64-bit timer\r
 \r
+       // Set pin to generate DMA req\r
+       port->pin->pcr |=  PORT_PCR_ISF_MASK;\r
+       port->pin->pcr |=  PORT_PCR_IRQC(port->irqc);\r
+\r
        // Enable port request\r
        port->dma->dcr |=  DMA_DCR_ERQ_MASK;\r
        // Enable port request\r
        port->dma->dcr |=  DMA_DCR_ERQ_MASK;\r
+\r
+       // Enable DMA Mux\r
+       port->mux->cfg  = DMAMUX_CHCFG_SOURCE(port->req)\r
+                       | DMAMUX_CHCFG_ENBL_MASK;\r
+\r
+       //sirq_printf("isfr3: %08x\r\n", PORTD->ISFR);\r
+}\r
+\r
+void tdma_stop(tdma_t *port)\r
+{\r
+       if (!port)\r
+               return;\r
+\r
+       //sirq_printf("isfr0: %08x\r\n", PORTD->ISFR);\r
+\r
+       // Disable DMA Mux\r
+       port->mux->cfg &= DMAMUX_CHCFG_ENBL_MASK;\r
+\r
+       // Freeze DMA channel\r
+       port->dma->dcr &= ~DMA_DCR_ERQ_MASK;\r
+\r
+       // Reset DMA channel\r
+       port->dma->dsr  =  DMA_DSR_BCR_DONE_MASK;\r
+\r
+       // Disable pin DMA request\r
+       port->pin->pcr &= ~PORT_PCR_IRQC_MASK;\r
+       port->pin->pcr |=  PORT_PCR_ISF_MASK;\r
+\r
+       //sirq_printf("isfr1: %08x\r\n", PORTD->ISFR);\r
 }\r
 \r
 int tdma_stamp(tdma_t *port, uint64_t *time)\r
 }\r
 \r
 int tdma_stamp(tdma_t *port, uint64_t *time)\r
index c6d276307581c77a473137cb63527e2dce42aa8d..e35af7368d07672962ecff01626362596d1c55bf 100644 (file)
@@ -30,7 +30,8 @@ void tdma_init(void);
 tdma_t *tdma_open(tdma_chan_t chan, int alt, PinName pin, PinMode mode);
 
 /* Flush/Wait */
 tdma_t *tdma_open(tdma_chan_t chan, int alt, PinName pin, PinMode mode);
 
 /* Flush/Wait */
-void tdma_reset(tdma_t *port);
+void tdma_start(tdma_t *port);
+void tdma_stop(tdma_t *port);
 int  tdma_stamp(tdma_t *port, uint64_t *time);
 
 /* Time */
 int  tdma_stamp(tdma_t *port, uint64_t *time);
 
 /* Time */