]> Pileus Git - ~andy/csm213a-hw/blobdiff - hw2/timer_dma.c
Work on second mbed
[~andy/csm213a-hw] / hw2 / timer_dma.c
index 23f11e226a23d83d8585bf2eacbd3c918423ba3a..2e197186cec8b507d902b75b660dfd141aaf4cf5 100644 (file)
@@ -71,7 +71,7 @@ void tdma_init(void)
 }\r
 \r
 /* DMA Functions */\r
-tdma_t *tdma_open(tdma_chan_t chan, PinName pin, PinMode mode)\r
+tdma_t *tdma_open(tdma_chan_t chan, int alt, PinName pin, PinMode mode)\r
 {\r
        int req  = pin >= PTD0 ? TDMA_REQ_PTD :\r
                   pin >= PTC0 ? TDMA_REQ_PTC :\r
@@ -95,7 +95,7 @@ tdma_t *tdma_open(tdma_chan_t chan, PinName pin, PinMode mode)
                        | DMA_DCR_DINC_MASK         // Dest increment\r
                        | DMA_DCR_SSIZE(0)          // 32-bit access\r
                        | DMA_DCR_DSIZE(0)          // 32-bit access\r
-                       | DMA_DCR_ERQ_MASK;         // Enable port request\r
+                       | DMA_DCR_D_REQ_MASK;       // Only run once\r
 \r
        // Setup and enable DMA MUX\r
        port->mux->cfg  = DMAMUX_CHCFG_SOURCE(req)  // Request source\r
@@ -103,42 +103,101 @@ tdma_t *tdma_open(tdma_chan_t chan, PinName pin, PinMode mode)
 \r
        // Set pin to generate DMA req\r
        port->pin->pcr  = PORT_PCR_ISF_MASK         // Clear ISR flag\r
-                       | PORT_PCR_MUX(3)           // Pin mapping\r
+                       | PORT_PCR_MUX(alt)         // Pin mapping\r
                        | PORT_PCR_IRQC(ircq)       // DMA on falling edge\r
                        | mode;                     // Pin pull up/down\r
 \r
+       // Initial reset\r
+       tdma_reset(port);\r
+\r
        return port;\r
 }\r
 \r
 void tdma_reset(tdma_t *port)\r
 {\r
+       if (!port)\r
+               return;\r
+\r
        // Clear previous time\r
        port->time[0] = 0;\r
        port->time[1] = 0;\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
+       port->dma->dsr  =  DMA_DSR_BCR_DONE_MASK;\r
 \r
        // Set addresses and size\r
-       port->dma->sar  = (uint32_t)&PIT->LTMR64H;  // Global timer\r
-       port->dma->dar  = (uint32_t)&port->time;    // Temp timer buffer\r
-       port->dma->dsr  = DMA_DSR_BCR_BCR(8);       // 64-bit timer\r
+       port->dma->sar  =  (uint32_t)&PIT->LTMR64H;  // Global timer\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
+       // Enable port request\r
+       port->dma->dcr |=  DMA_DCR_ERQ_MASK;\r
 }\r
 \r
 int tdma_stamp(tdma_t *port, uint64_t *time)\r
 {\r
+       uint64_t clocks;\r
+\r
+       if (!port)\r
+               return 0;\r
+\r
        if (port->dma->dsr & DMA_DSR_BCR_BCR_MASK)\r
                return 0;\r
 \r
        // Read the timestamp\r
-       *time = ((uint64_t)~port->time[0]) << 32\r
-             | ((uint64_t)~port->time[1]) << 0;\r
+       clocks = ((uint64_t)~port->time[0]) << 32\r
+              | ((uint64_t)~port->time[1]) << 0;\r
 \r
-       // Debug output..\r
-       //printf(" - sar:%08lx dar:%08lx pcr:%08lx dsr:%08lx time:%08lx:%08lx",\r
-       //      port->dma->sar, port->dma->dar,\r
-       //      port->pin->pcr, port->dma->dsr,\r
-       //      (uint32_t)(*time >> 32), (uint32_t)*time);\r
+       // Convert to nanoseconds\r
+       *time  = clocks * 1000 / 24;\r
 \r
        return 1;\r
 }\r
+\r
+uint64_t tdma_time(void)\r
+{\r
+       uint32_t tmh = PIT->LTMR64H;\r
+       uint32_t tml = PIT->LTMR64L;\r
+\r
+       // Read the timestamp\r
+       uint64_t clocks = ((uint64_t)~tmh) << 32\r
+                       | ((uint64_t)~tml) << 0;\r
+\r
+       // Convert to nanoseconds\r
+       return clocks * 1000 / 24;\r
+}\r
+\r
+void tdma_debug(tdma_t *port)\r
+{\r
+       int dsr = port->dma->dsr;\r
+       int dcr = port->dma->dcr;\r
+\r
+       printf("dsr: %s %s %s %s %s %s %d\r\n",\r
+                        dsr & DMA_DSR_BCR_CE_MASK   ? "CE"      : "ce",\r
+                        dsr & DMA_DSR_BCR_BES_MASK  ? "BSE"     : "bse",\r
+                        dsr & DMA_DSR_BCR_BED_MASK  ? "BED"     : "bed",\r
+                        dsr & DMA_DSR_BCR_REQ_MASK  ? "REQ"     : "req",\r
+                        dsr & DMA_DSR_BCR_BSY_MASK  ? "BSY"     : "bsy",\r
+                        dsr & DMA_DSR_BCR_DONE_MASK ? "DONE"    : "done",\r
+                        dsr & DMA_DSR_BCR_BCR_MASK);\r
+\r
+       printf("dcr: %s %s %s %s %s %s %s %s ssize=%d:%d mod=%d:%d link=%d:%d:%d\r\n",\r
+                        dcr & DMA_DCR_EINT_MASK     ? "EINT"    : "eint",\r
+                        dcr & DMA_DCR_ERQ_MASK      ? "ERQ"     : "erq",\r
+                        dcr & DMA_DCR_CS_MASK       ? "CS"      : "cs",\r
+                        dcr & DMA_DCR_AA_MASK       ? "AA"      : "aa",\r
+                        dcr & DMA_DCR_EADREQ_MASK   ? "EADRREQ" : "eadrreq",\r
+                        dcr & DMA_DCR_SINC_MASK     ? "SINC"    : "sinc",\r
+                        dcr & DMA_DCR_DINC_MASK     ? "DINC"    : "dinc",\r
+                        dcr & DMA_DCR_D_REQ_MASK    ? "DREQ"    : "dreq",\r
+                       (dcr & DMA_DCR_SSIZE_MASK ) >> DMA_DCR_SSIZE_SHIFT,\r
+                       (dcr & DMA_DCR_DSIZE_MASK ) >> DMA_DCR_DSIZE_SHIFT,\r
+                       (dcr & DMA_DCR_SMOD_MASK  ) >> DMA_DCR_SMOD_SHIFT,\r
+                       (dcr & DMA_DCR_DMOD_MASK  ) >> DMA_DCR_DMOD_SHIFT,\r
+                       (dcr & DMA_DCR_LINKCC_MASK) >> DMA_DCR_LINKCC_SHIFT,\r
+                       (dcr & DMA_DCR_LCH1_MASK  ) >> DMA_DCR_LCH1_SHIFT,\r
+                       (dcr & DMA_DCR_LCH2_MASK  ) >> DMA_DCR_LCH2_SHIFT);\r
+}\r