{\r
//static DigitalIn pin(PTC0);\r
//static DigitalIn pin(PTC2);\r
- static int pin = 0;\r
+ //static int pin = 0;\r
\r
- printf("%lx - PTC0:%08lx GPCR:%08lx:%08lx - SC:%04lx CNT:%04lx MOD:%04lx STATUS:%04lx CONF:%08lx - CnSC:%02lx CnV:%04lx\r\n",\r
- (long)pin, PORTC->PCR[0], PORTC->GPCHR, PORTC->GPCLR,\r
+ printf("PTC0:%08lx GPCR:%08lx:%08lx - SC:%04lx CNT:%04lx MOD:%04lx STATUS:%04lx CONF:%08lx - CnSC:%02lx CnV:%04lx\r\n",\r
+ PORTC->PCR[0], PORTC->GPCHR, PORTC->GPCLR,\r
TPM1->SC, TPM1->CNT, TPM1->MOD, TPM1->STATUS, TPM1->CONF,\r
TPM1->CONTROLS[1].CnSC, TPM1->CONTROLS[1].CnV);\r
TPM1->SC |= TPM_STATUS_TOF_MASK;\r
char xmt[32] = "hello, world";\r
char rcv[32] = {};\r
\r
+ uint64_t tm1, tm2;\r
+\r
sdma_write(sdma1, xmt, strlen(xmt));\r
- sdma_flush(sdma1);\r
+ sdma_flush(sdma1, &tm1);\r
+\r
+ //sdma_read(sdma2, rcv, strlen(xmt));\r
+ sdma_wait(sdma2, &tm2);\r
\r
- for (int i = 0; xmt[i]; i++)\r
- rcv[i] = uart2.getc();\r
+ //printf("send: [%s] -> [%s] ", xmt, rcv);\r
+ //printf("time: %08lx / %08lx ", (uint32_t)tm1, (uint32_t)tm2);\r
+ //printf("tag: dir:%08lx in:%08lx\r\n",\r
+ // FPTD->PDDR, FPTD->PDIR);\r
\r
- printf("xmt: %s ", xmt);\r
- printf("rcv: %s ", rcv);\r
- printf("tag: dir:%08lx in:%08lx\r\n",\r
- FPTD->PDDR, FPTD->PDIR);\r
+ (void)xmt; (void)rcv;\r
+ (void)tm1; (void)tm2;\r
}\r
\r
void test_leds(void)\r
led1 = 0; led2 = 1; wait(0.1);\r
}\r
\r
+void test_irq(void)\r
+{\r
+ printf("\r\nirq");\r
+}\r
+\r
int main(int argc, char **argv)\r
{\r
uart0.baud(115200);\r
uart1.baud(115200);\r
uart2.baud(115200);\r
\r
- sdma1 = sdma_open(SDMA_UART1, SDMA_CHANNEL1);\r
- sdma2 = sdma_open(SDMA_UART2, SDMA_CHANNEL2);\r
+ //sdma0 = sdma_open(SDMA_UART0, SDMA_CHANNEL0, SDMA_CHANNEL1);\r
+ sdma1 = sdma_open(SDMA_UART1, SDMA_CHANNEL0, SDMA_CHANNEL1);\r
+ sdma2 = sdma_open(SDMA_UART2, SDMA_CHANNEL2, SDMA_CHANNEL3);\r
+\r
+ sdma_pinmap(sdma1, PTE0, PTE1);\r
+ sdma_pinmap(sdma2, PTD3, PTD2);\r
\r
- test_uart();\r
+ //test_uart();\r
//test_leds();\r
test_pit_init();\r
//test_tpm_init();\r
//test_leds();\r
//test_pit_run();\r
//test_tpm_run();\r
+ printf("\r\n");\r
}\r
}\r
#define SDMA_NUM 2\r
#define SDMA_LEN 1024\r
\r
+enum {\r
+ SDMA_REQ_U0RX = 2,\r
+ SDMA_REQ_U0TX = 3,\r
+ SDMA_REQ_U1RX = 4,\r
+ SDMA_REQ_U1TX = 5,\r
+ SDMA_REQ_U2RX = 6,\r
+ SDMA_REQ_U2TX = 7,\r
+ SDMA_REQ_PTA = 49,\r
+ SDMA_REQ_PTC = 51,\r
+ SDMA_REQ_PTD = 52,\r
+ SDMA_REQ_ON0 = 60,\r
+ SDMA_REQ_ON1 = 61,\r
+ SDMA_REQ_ON2 = 62,\r
+ SDMA_REQ_ON3 = 63,\r
+};\r
+\r
/* Port structure */\r
struct sdma_t {\r
/* DMA channel */\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
+ } *dma_xmt, *dma_rcv;\r
\r
/* DMA mux */\r
struct {\r
uint8_t cfg; // offset 0x00, Channel Configuration register\r
- } *mux;\r
+ } *mux_xmt, *mux_rcv;\r
+\r
+ /* Pin names */\r
+ struct {\r
+ uint32_t pcr; // offset 0x00, Pin Control register\r
+ } *pin_xmt, *pin_rcv;\r
+\r
+ /* UART */\r
+ struct {\r
+ uint8_t bdh; // offset 0x00, Baud Rate Register High\r
+ uint8_t bdl; // offset 0x01, Baud Rate Register Low\r
+ uint8_t c1; // offset 0x02, Control Register 1\r
+ uint8_t c2; // offset 0x03, Control Register 2\r
+ uint8_t s1; // offset 0x04, Status Register 1\r
+ uint8_t s2; // offset 0x05, Status Register 2\r
+ uint8_t c3; // offset 0x06, Control Register 3\r
+ uint8_t d; // offset 0x07, Data Register\r
+ } *uart;\r
\r
/* Data buffering */\r
- int index;\r
- int length[SDMA_NUM];\r
- uint8_t queue[SDMA_NUM][SDMA_LEN];\r
+ int index;\r
+ int length[SDMA_NUM];\r
+ uint8_t queue[SDMA_NUM][SDMA_LEN];\r
+\r
+ /* Timestamping */\r
+ uint32_t time_xmt[2];\r
+ uint32_t time_rcv[2];\r
\r
/* Error logging */\r
- int stuck;\r
- int full;\r
+ int stuck;\r
+ int full;\r
};\r
\r
/* DMA Request Sources */\r
static int sdma_req_rx[] = {\r
- [SDMA_UART0] 2,\r
- [SDMA_UART1] 4,\r
- [SDMA_UART2] 6,\r
+ [SDMA_UART0] SDMA_REQ_U0RX,\r
+ [SDMA_UART1] SDMA_REQ_U1RX,\r
+ [SDMA_UART2] SDMA_REQ_U2RX,\r
};\r
static int sdma_req_tx[] = {\r
- [SDMA_UART0] 3,\r
- [SDMA_UART1] 5,\r
- [SDMA_UART2] 7,\r
+ [SDMA_UART0] SDMA_REQ_U0TX,\r
+ [SDMA_UART1] SDMA_REQ_U1TX,\r
+ [SDMA_UART2] SDMA_REQ_U2TX,\r
+};\r
+static int sdma_uart[] = {\r
+ [SDMA_UART0] UART0_BASE,\r
+ [SDMA_UART1] UART1_BASE,\r
+ [SDMA_UART2] UART2_BASE,\r
};\r
\r
/* Port data */\r
static sdma_t sdma_ports[SDMA_NUM_UART];\r
\r
/* DMA Functions */\r
-sdma_t *sdma_open(sdma_uart_t uart, sdma_dma_t dma)\r
+sdma_t *sdma_open(sdma_uart_t uart, sdma_dma_t tx_chan, sdma_dma_t rx_chan)\r
{\r
int rxreq = sdma_req_rx[uart]; (void)rxreq;\r
int txreq = sdma_req_tx[uart]; (void)txreq;\r
// Setup port\r
sdma_t *port = &sdma_ports[uart];\r
\r
- port->dma = (void*)&DMA0->DMA[dma];\r
- port->mux = (void*)&DMAMUX0->CHCFG[dma];\r
+ port->uart = (void*)sdma_uart[uart];\r
+ port->dma_xmt = (void*)&DMA0->DMA[tx_chan];\r
+ port->dma_rcv = (void*)&DMA0->DMA[rx_chan];\r
+ port->mux_xmt = (void*)&DMAMUX0->CHCFG[tx_chan];\r
+ port->mux_rcv = (void*)&DMAMUX0->CHCFG[rx_chan];\r
\r
// Enable DMA Cock\r
- SIM->SCGC6 |= SIM_SCGC6_DMAMUX_MASK;\r
- SIM->SCGC7 |= SIM_SCGC7_DMA_MASK;\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
// Reset channel\r
- port->dma->dsr = DMA_DSR_BCR_DONE_MASK;\r
+ port->dma_xmt->dsr = DMA_DSR_BCR_DONE_MASK;\r
\r
// Configure DMA transfer\r
- port->dma->dar = (uint32_t)&UART1->D;\r
- port->dma->dcr = DMA_DCR_CS_MASK |\r
- DMA_DCR_SINC_MASK |\r
- DMA_DCR_SSIZE(1) |\r
- DMA_DCR_DSIZE(1) |\r
- DMA_DCR_D_REQ_MASK;\r
+ port->dma_xmt->dar = (uint32_t)&port->uart->d;\r
+ port->dma_xmt->dcr = DMA_DCR_CS_MASK\r
+ | DMA_DCR_SINC_MASK\r
+ | DMA_DCR_SSIZE(1)\r
+ | DMA_DCR_DSIZE(1)\r
+ | DMA_DCR_D_REQ_MASK;\r
\r
// Configure DMA Mux\r
- port->mux->cfg = DMAMUX_CHCFG_SOURCE(txreq) |\r
- DMAMUX_CHCFG_ENBL_MASK;\r
+ port->mux_xmt->cfg = DMAMUX_CHCFG_SOURCE(txreq)\r
+ | DMAMUX_CHCFG_ENBL_MASK;\r
\r
// Configure UART for DMA Channel 0\r
switch (uart) {\r
return port;\r
}\r
\r
+/* Map port to pins - for now, just save for timing */\r
+void sdma_pinmap(sdma_t *port, PinName tx, PinName rx)\r
+{\r
+ port->pin_xmt = (void*)(PORTA_BASE+tx);\r
+ port->pin_rcv = (void*)(PORTA_BASE+rx);\r
+}\r
+\r
/* Write binary data out the DMA output queue */\r
void sdma_write(sdma_t *port, void *data, int len)\r
{\r
}\r
}\r
\r
-/* Write ASCII data to the output queue */\r
-void sdma_vprintf(sdma_t *port, const char *fmt, va_list ap)\r
+/* Read binary data from the channel */\r
+void sdma_read(sdma_t *port, void *data, int len)\r
{\r
- int pos = port->length[port->index];\r
- void *dst = &port->queue[port->index][pos];\r
- port->length[port->index] +=\r
- vsnprintf((char*)dst, SDMA_LEN-pos, fmt, ap);\r
-}\r
+ for (int i = 0; i < len; i++) {\r
+ // wait for byte\r
+ while (!(port->uart->s1 & UART_S1_RDRF_MASK))\r
+ if (port->uart->s1 & UART_S1_OR_MASK)\r
+ port->uart->s1 |= UART_S1_OR_MASK;\r
\r
-void sdma_printf(sdma_t *port, const char *fmt, ...)\r
-{\r
- va_list ap;\r
- va_start(ap, fmt);\r
- sdma_vprintf(port, fmt, ap);\r
- va_end(ap);\r
+ // read the byte\r
+ ((uint8_t*)data)[i] = port->uart->d;\r
+ }\r
}\r
\r
/* Trigger DMA transmit of the current output queue\r
* and swap buffers so we can write into unused space */\r
-void sdma_flush(sdma_t *port)\r
+void sdma_flush(sdma_t *port, uint64_t *time)\r
{\r
if (port->length[port->index] == 0)\r
return;\r
\r
// Wait for transmit complete\r
- while (port->dma->dsr & DMA_DSR_BCR_BCR_MASK)\r
+ while (port->dma_xmt->dsr & DMA_DSR_BCR_BCR_MASK)\r
port->stuck++;\r
\r
// Reset channel\r
- port->dma->dsr = DMA_DSR_BCR_DONE_MASK;\r
+ port->dma_xmt->dsr = DMA_DSR_BCR_DONE_MASK;\r
\r
// Set source address and length\r
- port->dma->sar = (uint32_t)&port->queue[port->index];\r
- port->dma->dsr = DMA_DSR_BCR_BCR(port->length[port->index]);\r
+ port->dma_xmt->sar = (uint32_t)&port->queue[port->index];\r
+ port->dma_xmt->dsr = DMA_DSR_BCR_BCR(port->length[port->index]);\r
\r
// Enable DMA transmit\r
- port->dma->dcr |= DMA_DCR_ERQ_MASK;\r
+ port->dma_xmt->dcr |= DMA_DCR_ERQ_MASK;\r
\r
// Swap buffers\r
port->length[port->index] = 0;\r
port->index = (port->index + 1) % SDMA_NUM;\r
}\r
+\r
+/* Wait for DMA receive complete */\r
+void sdma_wait(sdma_t *port, uint64_t *time)\r
+{\r
+ int req = (void*)port->pin_rcv > (void*)PORTD ? SDMA_REQ_PTD :\r
+ (void*)port->pin_rcv > (void*)PORTC ? SDMA_REQ_PTC :\r
+ (void*)port->pin_rcv > (void*)PORTA ? SDMA_REQ_PTA : 0;\r
+\r
+ // Reset channel\r
+ port->dma_rcv->dsr = DMA_DSR_BCR_DONE_MASK;\r
+\r
+ // Configure channel\r
+ port->dma_rcv->dcr = DMA_DCR_SINC_MASK\r
+ | DMA_DCR_DINC_MASK\r
+ | DMA_DCR_SSIZE(0)\r
+ | DMA_DCR_DSIZE(0)\r
+ | DMA_DCR_D_REQ_MASK;\r
+\r
+ // Setup muxing\r
+ port->mux_rcv->cfg = DMAMUX_CHCFG_SOURCE(req)\r
+ | DMAMUX_CHCFG_ENBL_MASK;\r
+\r
+ // Set address and size\r
+ port->dma_rcv->sar = (uint32_t)&PIT->LTMR64H;\r
+ port->dma_rcv->dar = (uint32_t)&port->time_rcv;\r
+ port->dma_rcv->dsr = DMA_DSR_BCR_BCR(sizeof(uint64_t));\r
+\r
+ // Enable DMA transmit\r
+ port->dma_rcv->dcr |= DMA_DCR_ERQ_MASK;\r
+\r
+ // set pin to generate DMA req\r
+ port->pin_rcv->pcr = PORT_PCR_ISF_MASK\r
+ | PORT_PCR_IRQC(1)\r
+ | PORT_PCR_MUX(3)\r
+ | PORT_PCR_PE_MASK;\r
+\r
+ // Wait for transmit complete\r
+ while ((port->dma_rcv->dsr & DMA_DSR_BCR_BCR_MASK))\r
+ port->stuck++;\r
+\r
+ // Save recv time\r
+ *time = ((uint64_t)~port->time_rcv[0]) << 32\r
+ | ((uint64_t)~port->time_rcv[1]) << 0;\r
+\r
+ // pcr:00030302 dsr:41000008\r
+ printf(" - pcr:%08lx dsr:%08lx time:%08lx:%08lx",\r
+ port->pin_rcv->pcr, port->dma_rcv->dsr,\r
+ (uint32_t)(*time >> 32), (uint32_t)*time);\r
+}\r
+\r
+/* Write ASCII data to the output queue */\r
+void sdma_vprintf(sdma_t *port, const char *fmt, va_list ap)\r
+{\r
+ int pos = port->length[port->index];\r
+ void *dst = &port->queue[port->index][pos];\r
+ port->length[port->index] +=\r
+ vsnprintf((char*)dst, SDMA_LEN-pos, fmt, ap);\r
+}\r
+\r
+void sdma_printf(sdma_t *port, const char *fmt, ...)\r
+{\r
+ va_list ap;\r
+ va_start(ap, fmt);\r
+ sdma_vprintf(port, fmt, ap);\r
+ va_end(ap);\r
+}\r