#include "mbed.h" #include "serial_dma.h" #include "timer_dma.h" /** * * Only port A, C, and D can do aysnc DMA (p. 67) * * DMA Channel Allocation: * Ch Trigger Description * 0 gpio timestamp (async event) * 1 uart1 transmit * 2 uart2 tx timestamp (time sync xmt) * 3 uart2 rx timestamp (time sync rcv) * * Uart Sources: * UART 0 UART 1 UART 2 * xmt rcv xmt rcv xmt rcv * --- --- --- --- --- --- * A2 A1 --A19 A18-- - - * A14 A15 - - - - * B17 B16 - - - - * - - **C4 C3-- - - * D7 D6 - - **D3/3 D2/3** <<< * - - - - **D5/3 D4/3** * E20 E21 E0 E1 E16 E17 * - - - - E22 E23 * * Pinout * A1 B18 E30 C1 * A2 B19 B20 C2 * D3 C0 E23 B3 * A12 C4 E22 B2 * A4 C6 E21 B1 * A5 C7 E20 B0 * C8 C10 * C9 C11 E2 P5-9V * E3 GND * A13 C13 E6 GND * D2 C16 E16 P5V-USB * D4 A7 E17 P3V3 * D6 A6 E18 RST * D7 A14 E19 P3V3 * D5 A15 E31 SDA/D5 * GND A15 * VREFH A17 * E0 B9 * E1 -- */ /* Trigger select options */ #define TMP_CONF_TRGSEL_EXTRG 0x0 // 0b0000 External trigger pin input (EXTRG_IN) #define TMP_CONF_TRGSEL_CMP0 0x1 // 0b0001 CMP0 output #define TMP_CONF_TRGSEL_PIT0 0x4 // 0b0100 PIT trigger 0 #define TMP_CONF_TRGSEL_PIT1 0x5 // 0b0101 PIT trigger 1 #define TMP_CONF_TRGSEL_TPM0 0x8 // 0b1000 TPM0 overflow #define TMP_CONF_TRGSEL_TPM1 0x9 // 0b1001 TPM1 overflow #define TMP_CONF_TRGSEL_TPM2 0xA // 0b1010 TPM2 overflow #define TMP_CONF_TRGSEL_RTCA 0xC // 0b1100 RTC alarm #define TMP_CONF_TRGSEL_RTCS 0xD // 0b1101 RTC seconds #define TMP_CONF_TRGSEL_LPTMR 0xE // 0b1110 LPTMR trigger /******************** * Data definitions * ********************/ // LEDs extern DigitalOut led1; extern DigitalOut led2; // UARTs extern Serial uart0; extern Serial uart1; extern Serial uart2; // Serial DMA extern sdma_t *sdma0; extern sdma_t *sdma1; extern sdma_t *sdma2; // Timer DMA extern tdma_t *tdma0; extern tdma_t *tdma1; extern tdma_t *tdma2; extern tdma_t *tdma3; /******** * Main * ********/ void test_tpm_init(void) { // EXTRG_IN - PTB8 - alt 3 // PTC0 - alt 3 // PTC6 - alt 3 // Setup System Integration Module SIM_Type *sim = SIM; sim->SCGC5 |= SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK | SIM_SCGC5_LPTMR_MASK; sim->SCGC6 |= SIM_SCGC6_TPM0_MASK | SIM_SCGC6_TPM1_MASK | SIM_SCGC6_TPM2_MASK | SIM_SCGC6_DAC0_MASK | SIM_SCGC6_ADC0_MASK | SIM_SCGC6_PIT_MASK | SIM_SCGC6_DMAMUX_MASK | SIM_SCGC6_RTC_MASK; sim->SOPT2 |= SIM_SOPT2_TPMSRC(1); sim->SOPT4 = SIM_SOPT4_TPM1CLKSEL_MASK | SIM_SOPT4_TPM1CH0SRC(3); printf("SOPT2:%08lx SCGC5:%08lx SCGC6:%08lx\r\n", sim->SOPT2, sim->SCGC5, sim->SCGC6); //SOPT2:05010000 SCGC5:00003f83 SCGC6:07800001 //sim->SOPT7 |= SIM_SOPT7_ADC0TRGSEL(TMP_CONF_TRGSEL_EXTRG); // Setup Port Control PORT_Type *port = PORTC; PORTE->PCR[25] = PORT_PCR_ISF_MASK | PORT_PCR_IRQC(0x1) | PORT_PCR_MUX(3) ; port->PCR[0] = PORT_PCR_ISF_MASK | PORT_PCR_IRQC(0x1) | PORT_PCR_MUX(3) | PORT_PCR_PE_MASK; // Setup Timer/PWM Module volatile TPM_Type *tpm = TPM1; tpm->SC = TPM_SC_PS(0x7) | TPM_SC_TOF_MASK; tpm->CNT = TPM_CNT_COUNT(0); tpm->MOD = TPM_CNT_COUNT(0xFFFF); tpm->CONTROLS[1].CnV = 0x1234; tpm->CONTROLS[1].CnSC = TPM_CnSC_CHF_MASK | TPM_CnSC_CHIE_MASK | TPM_CnSC_ELSA_MASK; //tpm->CONTROLS[0].CnSC = TPM_CnSC_CHF_MASK // | TPM_CnSC_CHIE_MASK // | TPM_CnSC_MSB_MASK // | TPM_CnSC_MSA_MASK // | TPM_CnSC_ELSB_MASK // | TPM_CnSC_ELSA_MASK; tpm->STATUS = TPM_STATUS_CH0F_MASK | TPM_STATUS_CH1F_MASK | TPM_STATUS_CH2F_MASK | TPM_STATUS_CH3F_MASK | TPM_STATUS_CH4F_MASK | TPM_STATUS_CH5F_MASK | TPM_STATUS_TOF_MASK; tpm->CONF = TPM_CONF_TRGSEL(TMP_CONF_TRGSEL_EXTRG) | TPM_CONF_CSOO_MASK | TPM_CONF_CSOT_MASK | TPM_CONF_GTBEEN_MASK | TPM_CONF_DBGMODE_MASK; tpm->SC = TPM_SC_CMOD(1) | TPM_SC_PS(0x7) | TPM_SC_TOF_MASK; printf("test - %02lx %08lx\r\n", tpm->CONTROLS[1].CnSC, tpm->CONTROLS[1].CnV); wait(0.1); } void test_tpm_run(void) { //static DigitalIn pin(PTC0); //static DigitalIn pin(PTC2); //static int pin = 0; printf("PTC0:%08lx GPCR:%08lx:%08lx - SC:%04lx CNT:%04lx MOD:%04lx STATUS:%04lx CONF:%08lx - CnSC:%02lx CnV:%04lx\r\n", PORTC->PCR[0], PORTC->GPCHR, PORTC->GPCLR, TPM1->SC, TPM1->CNT, TPM1->MOD, TPM1->STATUS, TPM1->CONF, TPM1->CONTROLS[1].CnSC, TPM1->CONTROLS[1].CnV); TPM1->SC |= TPM_STATUS_TOF_MASK; TPM1->STATUS |= TPM_STATUS_TOF_MASK; } void test_pit_init(void) { //printf("test_pit_init\r\n"); // Enable SIM->SCGC6 |= SIM_SCGC6_PIT_MASK; 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; } void test_pit_run(void) { register volatile uint32_t *tmh asm("r4") = &PIT->LTMR64H; register volatile uint32_t *tml asm("r5") = &PIT->LTMR64L; register uint32_t hi0 asm("r0"), lo0 asm("r1"); register uint32_t hi1 asm("r2"), lo1 asm("r3"); asm("ldr %0, [%4]\n\t" // Two clocks per load "ldr %1, [%5]\n\t" "ldr %2, [%4]\n\t" "ldr %3, [%5]\n\t" : "=r"(hi0), "=r"(lo0), "=r"(hi1), "=r"(lo1) : "r"(tmh), "r"(tml)); uint64_t tm0 = ~((uint64_t)hi0 << 32 | lo0); uint64_t tm1 = ~((uint64_t)hi1 << 32 | lo1); double bus = 24E6; // 24 MHz bus clock printf(" - pit"); printf(" %08lx:%08lx", (uint32_t)(tm0>>32), (uint32_t)tm0); printf(" %08lx:%08lx", (uint32_t)(tm1>>32), (uint32_t)tm1); printf(" %08lx", (uint32_t)(tm1-tm0)); printf(" %f", (double)tm0 / bus); } void test_sdma_init(void) { sdma0 = sdma_open(SDMA_UART0, SDMA_CHANNEL0, SDMA_CHANNEL1); sdma1 = sdma_open(SDMA_UART1, SDMA_CHANNEL0, SDMA_CHANNEL1); sdma2 = sdma_open(SDMA_UART2, SDMA_CHANNEL2, SDMA_CHANNEL3); sdma_pinmap(sdma1, PTE0, PTE1); sdma_pinmap(sdma2, PTD3, PTD2); } void test_sdma_run(void) { char xmt[32] = "hello, world"; char rcv[32] = {}; uint64_t tm1, tm2; sdma_write(sdma1, xmt, strlen(xmt)); sdma_flush(sdma1, &tm1); sdma_read(sdma2, rcv, strlen(xmt)); sdma_wait(sdma2, &tm2); printf("send: [%s] -> [%s] ", xmt, rcv); printf("time: %08lx / %08lx ", (uint32_t)tm1, (uint32_t)tm2); printf("tag: dir:%08lx in:%08lx\r\n", FPTD->PDDR, FPTD->PDIR); (void)xmt; (void)rcv; (void)tm1; (void)tm2; } void test_tdma_init(void) { tdma_init(); tdma0 = tdma_open(TDMA_CHAN0, 3, PTA1, PullNone); tdma1 = tdma_open(TDMA_CHAN1, 3, PTC1, PullNone); tdma2 = tdma_open(TDMA_CHAN2, 3, PTD3, PullUp); tdma3 = tdma_open(TDMA_CHAN3, 3, PTD2, PullUp); } void test_tdma_run(void) { static uint32_t time0[2]; static uint32_t time1[2]; static uint32_t time2[2]; static uint32_t time3[2]; tdma_stamp(tdma0, (uint64_t*)&time0); tdma_stamp(tdma1, (uint64_t*)&time1); tdma_stamp(tdma2, (uint64_t*)&time2); tdma_stamp(tdma3, (uint64_t*)&time3); tdma_start(tdma0); tdma_start(tdma1); tdma_start(tdma2); tdma_start(tdma3); printf(" - timer:"); printf(" %08lx:%08lx", time0[1], time0[0]); printf(" %08lx:%08lx", time1[1], time1[0]); printf(" %08lx:%08lx", time2[1], time2[0]); printf(" %08lx:%08lx", time3[1], time3[0]); //printf(" do:%08lx", FPTD->PDOR); //printf(" di:%08lx", FPTD->PDIR); //printf(" dd:%08lx", FPTD->PDDR); } void test_leds(void) { led1 = 1; led2 = 0; wait(0.1); led1 = 0; led2 = 1; wait(0.1); } void test_main(void) { printf("init\r\n"); //test_tpm_init(); //test_pit_init(); //test_sdma_init(); //test_tdma_init(); printf("run\r\n"); for (int i = 0; true; i++) { printf("%8d", i); test_leds(); //test_tpm_run(); //test_pit_run(); //test_sdma_run(); //test_tdma_run(); printf("\r\n"); } }