]> Pileus Git - ~andy/csm213a-hw/blobdiff - hw2/timer_dma.c
Fix newlines
[~andy/csm213a-hw] / hw2 / timer_dma.c
index 36fdc979e567527600268f1c27360c187460041b..77dc6899da804216930652ae27aa15f2273c90b7 100644 (file)
-#include <MKL46Z4.h>\r
-\r
-#include <stdint.h>\r
-#include <stdarg.h>\r
-#include <stdio.h>\r
-#include <string.h>\r
-\r
-#include "timer_dma.h"\r
-#include "serial_irq.h"\r
-\r
-/* Defines */\r
-enum {\r
-       TDMA_REQ_PTA  = 49,\r
-       TDMA_REQ_PTC  = 51,\r
-       TDMA_REQ_PTD  = 52,\r
-};\r
-\r
-/* Port structure */\r
-struct tdma_t {\r
-       /* DMA channel */\r
-       struct {\r
-               uint32_t sar; // offset 0x00, Source Address Register\r
-               uint32_t dar; // offset 0x04, Destination Address Register\r
-               uint32_t dsr; // offset 0x08, DMA Status Register / Byte Count Register\r
-               uint32_t dcr; // offset 0x0C, DMA Control Register\r
-       } *dma;\r
-\r
-       /* DMA mux */\r
-       struct {\r
-               uint8_t  cfg; // offset 0x00, Channel Configuration register\r
-       } *mux;\r
-\r
-       /* Pin names */\r
-       struct {\r
-               uint32_t pcr; // offset 0x00, Pin Control register\r
-       } *pin;\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
-static tdma_t tdma_ports[TDMA_NUM_CHAN];\r
-\r
-/* Global timer initialization */\r
-void tdma_init(void)\r
-{\r
-       static int tdma_init_done = 0;\r
-       if (tdma_init_done)\r
-               return;\r
-\r
-       // Enable DMA Cock\r
-       SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK;\r
-       SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK;\r
-       SIM->SCGC5 |= SIM_SCGC5_PORTD_MASK;\r
-       SIM->SCGC6 |= SIM_SCGC6_DMAMUX_MASK;\r
-       SIM->SCGC7 |= SIM_SCGC7_DMA_MASK;\r
-\r
-       // Enable timer Clock\r
-       SIM->SCGC6 |= SIM_SCGC6_PIT_MASK;\r
-\r
-       // Enable PIT\r
-       PIT->MCR               = 0;\r
-\r
-       // Channel 0\r
-       PIT->CHANNEL[0].LDVAL  = 0xFFFFFFFF;\r
-       PIT->CHANNEL[0].TCTRL  = 0;\r
-\r
-       // Channel 1\r
-       PIT->CHANNEL[1].LDVAL  = 0xFFFFFFFF;\r
-       PIT->CHANNEL[1].TCTRL  = PIT_TCTRL_CHN_MASK;\r
-\r
-       // Start timers\r
-       PIT->CHANNEL[0].TCTRL |= PIT_TCTRL_TEN_MASK;\r
-       PIT->CHANNEL[1].TCTRL |= PIT_TCTRL_TEN_MASK;\r
-\r
-       // Done\r
-       tdma_init_done = 1;\r
-}\r
-\r
-/* DMA Functions */\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
-                  pin >= PTA0 ? TDMA_REQ_PTA : 0;\r
-\r
-       int irqc = mode == PullDown ? 1 : 2;\r
-\r
-       // Initialize global registers\r
-       tdma_init();\r
-\r
-       // Allocate port\r
-       tdma_t *port    = &tdma_ports[chan];\r
-\r
-       // Setup port pointers\r
-       port->dma       = (void*)&DMA0->DMA[chan];\r
-       port->mux       = (void*)&DMAMUX0->CHCFG[chan];\r
-       port->pin       = (void*)(PORTA_BASE + pin);\r
-\r
-       // Reset DMA channel\r
-       port->dma->dsr  = DMA_DSR_BCR_DONE_MASK;\r
-\r
-       // Configure DMA channel\r
-       port->dma->dcr  = DMA_DCR_SINC_MASK         // Source increment\r
-                       | 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_D_REQ_MASK;       // Only run once\r
-\r
-       // Setup and enable DMA MUX\r
-       port->mux->cfg  = DMAMUX_CHCFG_SOURCE(req)  // Request source\r
-                       | DMAMUX_CHCFG_ENBL_MASK;   // Enable DMA mux\r
-\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(irqc)       // DMA on falling edge\r
-                       | mode;                     // Pin pull up/down\r
-\r
-       // Save IRC for later\r
-       port->req       = req;\r
-       port->irqc      = irqc;\r
-\r
-       return port;\r
-}\r
-\r
-void tdma_start(tdma_t *port)\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
-       // 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
-       // Reset DMA channel\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
-\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
-\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, int wait)\r
-{\r
-       if (!port)\r
-               return;\r
-\r
-       //sirq_printf("isfr0: %08x\r\n", PORTD->ISFR);\r
-\r
-       for (int i = 0; port->dma->dsr & DMA_DSR_BCR_BCR_MASK; i++)\r
-               if (i > wait)\r
-                       return;\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
-       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
-       clocks = ((uint64_t)~port->time[0]) << 32\r
-              | ((uint64_t)~port->time[1]) << 0;\r
-\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 * 125 / 3;\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
+#include <MKL46Z4.h>
+
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "timer_dma.h"
+#include "serial_irq.h"
+
+/* Defines */
+enum {
+       TDMA_REQ_PTA  = 49,
+       TDMA_REQ_PTC  = 51,
+       TDMA_REQ_PTD  = 52,
+};
+
+/* Port structure */
+struct tdma_t {
+       /* DMA channel */
+       struct {
+               uint32_t sar; // offset 0x00, Source Address Register
+               uint32_t dar; // offset 0x04, Destination Address Register
+               uint32_t dsr; // offset 0x08, DMA Status Register / Byte Count Register
+               uint32_t dcr; // offset 0x0C, DMA Control Register
+       } *dma;
+
+       /* DMA mux */
+       struct {
+               uint8_t  cfg; // offset 0x00, Channel Configuration register
+       } *mux;
+
+       /* Pin names */
+       struct {
+               uint32_t pcr; // offset 0x00, Pin Control register
+       } *pin;
+
+       /* Time stamping */
+       uint32_t time[2];
+
+       /* Save state */
+       int      req;
+       int      irqc;
+};
+
+/* Port data */
+static tdma_t tdma_ports[TDMA_NUM_CHAN];
+
+/* Global timer initialization */
+void tdma_init(void)
+{
+       static int tdma_init_done = 0;
+       if (tdma_init_done)
+               return;
+
+       // Enable DMA Cock
+       SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK;
+       SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK;
+       SIM->SCGC5 |= SIM_SCGC5_PORTD_MASK;
+       SIM->SCGC6 |= SIM_SCGC6_DMAMUX_MASK;
+       SIM->SCGC7 |= SIM_SCGC7_DMA_MASK;
+
+       // Enable timer Clock
+       SIM->SCGC6 |= SIM_SCGC6_PIT_MASK;
+
+       // Enable PIT
+       PIT->MCR               = 0;
+
+       // Channel 0
+       PIT->CHANNEL[0].LDVAL  = 0xFFFFFFFF;
+       PIT->CHANNEL[0].TCTRL  = 0;
+
+       // Channel 1
+       PIT->CHANNEL[1].LDVAL  = 0xFFFFFFFF;
+       PIT->CHANNEL[1].TCTRL  = PIT_TCTRL_CHN_MASK;
+
+       // Start timers
+       PIT->CHANNEL[0].TCTRL |= PIT_TCTRL_TEN_MASK;
+       PIT->CHANNEL[1].TCTRL |= PIT_TCTRL_TEN_MASK;
+
+       // Done
+       tdma_init_done = 1;
+}
+
+/* DMA Functions */
+tdma_t *tdma_open(tdma_chan_t chan, int alt, PinName pin, PinMode mode)
+{
+       int req  = pin >= PTD0 ? TDMA_REQ_PTD :
+                  pin >= PTC0 ? TDMA_REQ_PTC :
+                  pin >= PTA0 ? TDMA_REQ_PTA : 0;
+
+       int irqc = mode == PullDown ? 1 : 2;
+
+       // Initialize global registers
+       tdma_init();
+
+       // Allocate port
+       tdma_t *port    = &tdma_ports[chan];
+
+       // Setup port pointers
+       port->dma       = (void*)&DMA0->DMA[chan];
+       port->mux       = (void*)&DMAMUX0->CHCFG[chan];
+       port->pin       = (void*)(PORTA_BASE + pin);
+
+       // Reset DMA channel
+       port->dma->dsr  = DMA_DSR_BCR_DONE_MASK;
+
+       // Configure DMA channel
+       port->dma->dcr  = DMA_DCR_SINC_MASK         // Source increment
+                       | DMA_DCR_DINC_MASK         // Dest increment
+                       | DMA_DCR_SSIZE(0)          // 32-bit access
+                       | DMA_DCR_DSIZE(0)          // 32-bit access
+                       | DMA_DCR_D_REQ_MASK;       // Only run once
+
+       // Setup and enable DMA MUX
+       port->mux->cfg  = DMAMUX_CHCFG_SOURCE(req)  // Request source
+                       | DMAMUX_CHCFG_ENBL_MASK;   // Enable DMA mux
+
+       // Set pin to generate DMA req
+       port->pin->pcr  = PORT_PCR_ISF_MASK         // Clear ISR flag
+                       | PORT_PCR_MUX(alt)         // Pin mapping
+                       | PORT_PCR_IRQC(irqc)       // DMA on falling edge
+                       | mode;                     // Pin pull up/down
+
+       // Save IRC for later
+       port->req       = req;
+       port->irqc      = irqc;
+
+       return port;
+}
+
+void tdma_start(tdma_t *port)
+{
+       if (!port)
+               return;
+
+       //sirq_printf("isfr2: %08x\r\n", PORTD->ISFR);
+
+       // Clear previous time
+       port->time[0] = 0;
+       port->time[1] = 0;
+
+       // Reset DMA Mux
+       port->mux->cfg &= DMAMUX_CHCFG_ENBL_MASK;
+
+       // Freeze DMA channel
+       port->dma->dcr &= ~DMA_DCR_ERQ_MASK;
+
+       // Reset DMA channel
+       port->dma->dsr  =  DMA_DSR_BCR_DONE_MASK;
+
+       // Set addresses and size
+       port->dma->sar  =  (uint32_t)&PIT->LTMR64H;  // Global timer
+       port->dma->dar  =  (uint32_t)&port->time;    // Temp timer buffer
+       port->dma->dsr  =  DMA_DSR_BCR_BCR(8);       // 64-bit timer
+
+       // Set pin to generate DMA req
+       port->pin->pcr |=  PORT_PCR_ISF_MASK;
+       port->pin->pcr |=  PORT_PCR_IRQC(port->irqc);
+
+       // Enable port request
+       port->dma->dcr |=  DMA_DCR_ERQ_MASK;
+
+       // Enable DMA Mux
+       port->mux->cfg  = DMAMUX_CHCFG_SOURCE(port->req)
+                       | DMAMUX_CHCFG_ENBL_MASK;
+
+       //sirq_printf("isfr3: %08x\r\n", PORTD->ISFR);
+}
+
+void tdma_stop(tdma_t *port, int wait)
+{
+       if (!port)
+               return;
+
+       //sirq_printf("isfr0: %08x\r\n", PORTD->ISFR);
+
+       for (int i = 0; port->dma->dsr & DMA_DSR_BCR_BCR_MASK; i++)
+               if (i > wait)
+                       return;
+
+       // Disable DMA Mux
+       port->mux->cfg &= DMAMUX_CHCFG_ENBL_MASK;
+
+       // Freeze DMA channel
+       port->dma->dcr &= ~DMA_DCR_ERQ_MASK;
+
+       // Reset DMA channel
+       port->dma->dsr  =  DMA_DSR_BCR_DONE_MASK;
+
+       // Disable pin DMA request
+       port->pin->pcr &= ~PORT_PCR_IRQC_MASK;
+       port->pin->pcr |=  PORT_PCR_ISF_MASK;
+
+       //sirq_printf("isfr1: %08x\r\n", PORTD->ISFR);
+}
+
+int tdma_stamp(tdma_t *port, uint64_t *time)
+{
+       uint64_t clocks;
+
+       if (!port)
+               return 0;
+
+       if (port->dma->dsr & DMA_DSR_BCR_BCR_MASK)
+               return 0;
+
+       // Read the timestamp
+       clocks = ((uint64_t)~port->time[0]) << 32
+              | ((uint64_t)~port->time[1]) << 0;
+
+       // Convert to nanoseconds
+       *time  = clocks * 1000 / 24;
+
+       return 1;
+}
+
+uint64_t tdma_time(void)
+{
+       uint32_t tmh = PIT->LTMR64H;
+       uint32_t tml = PIT->LTMR64L;
+
+       // Read the timestamp
+       uint64_t clocks = ((uint64_t)~tmh) << 32
+                       | ((uint64_t)~tml) << 0;
+
+       // Convert to nanoseconds
+       return clocks * 125 / 3;
+}
+
+void tdma_debug(tdma_t *port)
+{
+       int dsr = port->dma->dsr;
+       int dcr = port->dma->dcr;
+
+       printf("dsr: %s %s %s %s %s %s %d\r\n",
+                        dsr & DMA_DSR_BCR_CE_MASK   ? "CE"      : "ce",
+                        dsr & DMA_DSR_BCR_BES_MASK  ? "BSE"     : "bse",
+                        dsr & DMA_DSR_BCR_BED_MASK  ? "BED"     : "bed",
+                        dsr & DMA_DSR_BCR_REQ_MASK  ? "REQ"     : "req",
+                        dsr & DMA_DSR_BCR_BSY_MASK  ? "BSY"     : "bsy",
+                        dsr & DMA_DSR_BCR_DONE_MASK ? "DONE"    : "done",
+                        dsr & DMA_DSR_BCR_BCR_MASK);
+
+       printf("dcr: %s %s %s %s %s %s %s %s ssize=%d:%d mod=%d:%d link=%d:%d:%d\r\n",
+                        dcr & DMA_DCR_EINT_MASK     ? "EINT"    : "eint",
+                        dcr & DMA_DCR_ERQ_MASK      ? "ERQ"     : "erq",
+                        dcr & DMA_DCR_CS_MASK       ? "CS"      : "cs",
+                        dcr & DMA_DCR_AA_MASK       ? "AA"      : "aa",
+                        dcr & DMA_DCR_EADREQ_MASK   ? "EADRREQ" : "eadrreq",
+                        dcr & DMA_DCR_SINC_MASK     ? "SINC"    : "sinc",
+                        dcr & DMA_DCR_DINC_MASK     ? "DINC"    : "dinc",
+                        dcr & DMA_DCR_D_REQ_MASK    ? "DREQ"    : "dreq",
+                       (dcr & DMA_DCR_SSIZE_MASK ) >> DMA_DCR_SSIZE_SHIFT,
+                       (dcr & DMA_DCR_DSIZE_MASK ) >> DMA_DCR_DSIZE_SHIFT,
+                       (dcr & DMA_DCR_SMOD_MASK  ) >> DMA_DCR_SMOD_SHIFT,
+                       (dcr & DMA_DCR_DMOD_MASK  ) >> DMA_DCR_DMOD_SHIFT,
+                       (dcr & DMA_DCR_LINKCC_MASK) >> DMA_DCR_LINKCC_SHIFT,
+                       (dcr & DMA_DCR_LCH1_MASK  ) >> DMA_DCR_LCH1_SHIFT,
+                       (dcr & DMA_DCR_LCH2_MASK  ) >> DMA_DCR_LCH2_SHIFT);
+}