]> Pileus Git - ~andy/csm213a-hw/commitdiff
Fix bug in irq code
authorAndy Spencer <andy753421@gmail.com>
Mon, 10 Mar 2014 22:14:37 +0000 (22:14 +0000)
committerAndy Spencer <andy753421@gmail.com>
Mon, 10 Mar 2014 22:17:45 +0000 (22:17 +0000)
hw2/main.cpp
hw2/serial_irq.c

index aafb879c15a3bafff45921359745cc9a7a59d078..9292124da454b95e442519ba975843df35c051d1 100644 (file)
  *   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 *
  *******************/
@@ -112,7 +101,7 @@ void time_ext_sync(uint64_t local, uint64_t world)
        world = time_last_world;
 
 //#ifdef VERBOSE
-#if 0
+#if 1
        uint64_t error = world > guess ? world - guess :
                         guess > world ? guess - world : 0;
        int      ahead = guess > world;
@@ -150,7 +139,7 @@ static uint64_t  emit_start  = 0; // transmit start time (world time)
 static uint64_t  emit_period = 0; // transmit period
 static uint64_t  emit_due    = 0; // next transmit (world time)
 
-static uint32_t  emit_slack  = 0; // how far ahead we need to schedule
+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
 
 void emit_init(int alt, PinName pin, PinMode mode)
@@ -190,11 +179,13 @@ void emit_init(int alt, PinName pin, PinMode mode)
 
 void emit_enable(uint64_t start, uint64_t period)
 {
+       const int slack_tick = 0xC000; // tune based on emit_worst
+
        emit_start  = start;
        emit_period = period;
        emit_due    = start + period;
 
-       emit_slack  = 10000; // tune based on emit_worst
+       emit_slack  = slack_tick * 1000 / 24;
 
        time_printf("emit scheduled", emit_due);
 }
@@ -219,19 +210,17 @@ void emit_schedule(uint64_t when)
                               | TPM_SC_CMOD(1);
 
        // Debug
-       //sirq_printf("emitting event\r\n");
+       sirq_printf("emitting event\r\n");
 }
 
-void emit_transmit(void)
+void emit_transmit(uint64_t local, uint64_t world)
 {
-       static uint64_t prev;
-
-       // Get a fresh timestamp
-       uint64_t world = time_to_world(tdma_time());
+       static uint64_t prev = 0;
 
        // Record how how much time we have to reschedule
-       if (prev && world - prev > emit_worst)
-               emit_worst = prev;
+       if (prev && (local-prev) > emit_worst)
+               emit_worst = (local-prev);
+       prev = local;
 
        // Schedule task if needed
        if (emit_due && emit_period &&
@@ -319,25 +308,17 @@ void serial_send_sync(sirq_t *port, uint64_t now)
 
        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));
        tdma_stop(serial_tdma_xmt);
 
        // save transmit time
-       //local = test_xmt_time1;
        int valid = tdma_stamp(serial_tdma_xmt, &local);
-       if (!valid) {
+       if (!valid)
                sirq_printf("sync transmit time -- missed\r\n");
-       } else {
+       else
                //time_printf("sync transmit time ", local);
-               //time_printf("sync transmit test0", test_xmt_time0);
-               //time_printf("sync transmit test1", test_xmt_time1);
-       }
 
        tdma_start(serial_tdma_rcv);
 
@@ -380,10 +361,6 @@ void serial_send_event(uint16_t event, uint64_t local)
 
        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));
@@ -612,7 +589,7 @@ void task_leds(uint64_t local, uint64_t world)
 
 void task_emit(uint64_t local, uint64_t world)
 {
-       emit_transmit();
+       emit_transmit(local, world);
 }
 
 void task_debug(uint64_t local, uint64_t world)
@@ -730,10 +707,36 @@ int main(int argc, char **argv)
        //sirq_printf("MGC - C10   %02hx\r\n", MCG->C10);    // 00
 
        // Run background loop
-       printf("hello");
        while (true)
                background();
 
+       // Performance testing
+       //uint64_t prev = 0, due = 0;
+       //uint64_t worst[10] = {};
+       //int      count = 0;
+       //while (true) {
+       //      uint64_t local = tdma_time();
+       //      if (prev && (local-prev) > worst[count])
+       //              worst[count] = (local-prev);
+       //      prev = local;
+       //      if (local > due) {
+       //              if (count == 5) {
+       //                      static char str[] = "background background background\r\n";
+       //                      sirq_write(sirq_dbg, str, sizeof(str));
+       //              }
+       //              if (count == 9) {
+       //                      sirq_printf("background\r\n");
+       //                      for (int i = 0; i < 10; i++) {
+       //                              sirq_printf("  worst[%d] = 0.%09u\r\n",
+       //                                              i, worst[i]);
+       //                              worst[i] = 0;
+       //                      }
+       //              }
+       //              due += NSEC_PER_SEC;
+       //              count = (count + 1) % 10;
+       //      }
+       //}
+
        // Run tests
        //test_main();
 
index 68945cfcbb759e8e46361046f7c40c7ce7734e0f..e002ce94f49a07c96d7436612ab4cbaa014bc214 100644 (file)
@@ -20,16 +20,9 @@ struct sirq_t {
        serial_t uart;\r
        queue_t  xmt;\r
        queue_t  rcv;\r
+       int      irq;\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
@@ -41,20 +34,11 @@ 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
-\r
-               uint64_t time0 = tdma_time();\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->irq = 0;\r
        }\r
 \r
        // Handle receive\r
@@ -87,7 +71,10 @@ void sirq_putc(sirq_t *port, int byte)
 {\r
        port->xmt.buf[port->xmt.wix] = byte;\r
        port->xmt.wix = (port->xmt.wix+1) % SIRQ_LEN;\r
-       serial_irq_set(&port->uart, TxIrq, 1);\r
+       if (!port->irq) {\r
+               port->irq = 1;\r
+               serial_irq_set(&port->uart, TxIrq, 1);\r
+       }\r
 }\r
 \r
 /* Read byte from the port */\r