Other Parts Discussed in Thread: EK-TM4C1294XL
Hello,
I'm trying to transmit multiple large buffers using uDMA Ping Pong Mode, after transmitting for example buffer 1, 2, I swap buffer 1, with buffer 3.
My question is where the triple buffering needed to be swapped, in which area exactly in the interrupts ?
/* Private Typedefs ----------------------------------------------------------*/ #pragma DATA_ALIGN(psDMAControlTable, 1024) tDMAControlTable psDMAControlTable[64]; #define EPI_DATA_SIZE 1024 #define SYSTEM_CLOCK_120M 120000000 #define EPI_PORT 0xA0000000 uint8_t testttttttttttttt = 0; int PingCount; uint16_t send_data[EPI_DATA_SIZE] = { }; uint16_t send_data2[EPI_DATA_SIZE] = { }; uint16_t send_data3[EPI_DATA_SIZE] = { }; uint32_t ui32SysClock, g_ui32EPIErrors = 0; volatile uint32_t *g_pusEPIFPGA; // Pointer for EPI memory window. uint16_t *pa; uint16_t *pb; void initEPI(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG); // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH); // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK); // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL); // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM); // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP); // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ); // SysCtlPeripheralEnable(SYSCTL_PERIPH_EPI0); while (!SysCtlPeripheralReady(SYSCTL_PERIPH_EPI0)) //wait for it to be ready { } MAP_GPIOPinConfigure(GPIO_PK0_EPI0S0); GPIOPinTypeEPI(GPIO_PORTK_BASE, GPIO_PIN_0); //D0 MAP_GPIOPinConfigure(GPIO_PK1_EPI0S1); GPIOPinTypeEPI(GPIO_PORTK_BASE, GPIO_PIN_1); //D1 MAP_GPIOPinConfigure(GPIO_PK2_EPI0S2); GPIOPinTypeEPI(GPIO_PORTK_BASE, GPIO_PIN_2); //D2 MAP_GPIOPinConfigure(GPIO_PK3_EPI0S3); GPIOPinTypeEPI(GPIO_PORTK_BASE, GPIO_PIN_3); //D3 MAP_GPIOPinConfigure(GPIO_PC7_EPI0S4); GPIOPinTypeEPI(GPIO_PORTC_BASE, GPIO_PIN_7); //D4 MAP_GPIOPinConfigure(GPIO_PC6_EPI0S5); GPIOPinTypeEPI(GPIO_PORTC_BASE, GPIO_PIN_6); //D5 MAP_GPIOPinConfigure(GPIO_PC5_EPI0S6); GPIOPinTypeEPI(GPIO_PORTC_BASE, GPIO_PIN_5); //D6 MAP_GPIOPinConfigure(GPIO_PC4_EPI0S7); GPIOPinTypeEPI(GPIO_PORTC_BASE, GPIO_PIN_4); //D7 MAP_GPIOPinConfigure(GPIO_PA6_EPI0S8); GPIOPinTypeEPI(GPIO_PORTA_BASE, GPIO_PIN_6); //D8 MAP_GPIOPinConfigure(GPIO_PA7_EPI0S9); GPIOPinTypeEPI(GPIO_PORTA_BASE, GPIO_PIN_7); //D9 MAP_GPIOPinConfigure(GPIO_PG1_EPI0S10); GPIOPinTypeEPI(GPIO_PORTG_BASE, GPIO_PIN_1); //D10 MAP_GPIOPinConfigure(GPIO_PG0_EPI0S11); GPIOPinTypeEPI(GPIO_PORTG_BASE, GPIO_PIN_0); //D11 MAP_GPIOPinConfigure(GPIO_PM3_EPI0S12); GPIOPinTypeEPI(GPIO_PORTM_BASE, GPIO_PIN_3); //D12 MAP_GPIOPinConfigure(GPIO_PM2_EPI0S13); GPIOPinTypeEPI(GPIO_PORTM_BASE, GPIO_PIN_2); //D13 MAP_GPIOPinConfigure(GPIO_PM1_EPI0S14); GPIOPinTypeEPI(GPIO_PORTM_BASE, GPIO_PIN_1); //D14 MAP_GPIOPinConfigure(GPIO_PM0_EPI0S15); GPIOPinTypeEPI(GPIO_PORTM_BASE, GPIO_PIN_0); //D15 MAP_GPIOPinConfigure(GPIO_PL0_EPI0S16); GPIOPinTypeEPI(GPIO_PORTL_BASE, GPIO_PIN_0); //A0 MAP_GPIOPinConfigure(GPIO_PL1_EPI0S17); GPIOPinTypeEPI(GPIO_PORTL_BASE, GPIO_PIN_1); //A1 MAP_GPIOPinConfigure(GPIO_PL2_EPI0S18); GPIOPinTypeEPI(GPIO_PORTL_BASE, GPIO_PIN_2); //A2 MAP_GPIOPinConfigure(GPIO_PL3_EPI0S19); GPIOPinTypeEPI(GPIO_PORTL_BASE, GPIO_PIN_3); //A3 MAP_GPIOPinConfigure(GPIO_PQ0_EPI0S20); GPIOPinTypeEPI(GPIO_PORTQ_BASE, GPIO_PIN_0); //A4 MAP_GPIOPinConfigure(GPIO_PQ1_EPI0S21); GPIOPinTypeEPI(GPIO_PORTQ_BASE, GPIO_PIN_1); //A5 MAP_GPIOPinConfigure(GPIO_PQ2_EPI0S22); GPIOPinTypeEPI(GPIO_PORTQ_BASE, GPIO_PIN_2); //A6 MAP_GPIOPinConfigure(GPIO_PQ3_EPI0S23); GPIOPinTypeEPI(GPIO_PORTQ_BASE, GPIO_PIN_3); //A7 MAP_GPIOPinConfigure(GPIO_PK7_EPI0S24); GPIOPinTypeEPI(GPIO_PORTK_BASE, GPIO_PIN_7); //A8 MAP_GPIOPinConfigure(GPIO_PK6_EPI0S25); GPIOPinTypeEPI(GPIO_PORTK_BASE, GPIO_PIN_6); //A9 MAP_GPIOPinConfigure(GPIO_PL4_EPI0S26); GPIOPinTypeEPI(GPIO_PORTL_BASE, GPIO_PIN_4); //A10 MAP_GPIOPinConfigure(GPIO_PB2_EPI0S27); GPIOPinTypeEPI(GPIO_PORTB_BASE, GPIO_PIN_2); //A11 MAP_GPIOPinConfigure(GPIO_PB3_EPI0S28); GPIOPinTypeEPI(GPIO_PORTB_BASE, GPIO_PIN_3); //WR MAP_GPIOPinConfigure(GPIO_PP2_EPI0S29); GPIOPinTypeEPI(GPIO_PORTP_BASE, GPIO_PIN_2); //RD MAP_GPIOPinConfigure(GPIO_PP3_EPI0S30); GPIOPinTypeEPI(GPIO_PORTP_BASE, GPIO_PIN_3); //FRAME MAP_GPIOPinConfigure(GPIO_PK5_EPI0S31); GPIOPinTypeEPI(GPIO_PORTK_BASE, GPIO_PIN_5); //CLK EPIModeSet(EPI0_BASE, EPI_MODE_GENERAL); //general mode EPIDividerSet(EPI0_BASE, 5); //1=60MHz, 10=10MHz, 119=1MHz EPIConfigGPModeSet(EPI0_BASE, EPI_GPMODE_CLKPIN | //interface clock is output on a pin // EPI_GPMODE_CLKGATE | //clock is stopped when there is no transaction // EPI_GPMODE_FRAME50 | //frame 50:50 - not using frame signal // EPI_GPMODE_WRITE2CYCLE | //two cycle write - single cycle write EPI_GPMODE_ASIZE_NONE | //address bus size of 4 bits EPI_GPMODE_DSIZE_16, //data bus size of 16 bits 0, //frame 0 0); //parameter not used EPIAddressMapSet(EPI0_BASE, EPI_ADDR_PER_SIZE_256B | //only 16 needed EPI_ADDR_PER_BASE_C); //EPI0 is mapped from 0xC0000000 to 0xC00000FF. EPIFIFOConfig(EPI0_BASE, (EPI_FIFO_CONFIG_TX_1_2)); /* EPIIntDisable( EPI0_BASE, EPI_INT_RXREQ | EPI_INT_TXREQ | EPI_INT_ERR); EPIIntErrorClear(EPI0_BASE, EPI_INT_ERR_WTFULL | EPI_INT_ERR_RSTALL | EPI_INT_ERR_TIMEOUT); //setup the interrupt mask for the EPI. //Note: interrupt masking has no effect on uDMA, which // operates off the raw source of the read/write // interrupts //Note: we dont want to enable the EPI Rx and Tx interrupt, // the EPI fifos will be serviced by the uDMA EPIIntEnable( EPI0_BASE, // EPI_INT_RXREQ | // EPI_INT_TXREQ | // EPI_INT_DMA_TX_DONE | // EPI_INT_DMA_RX_DONE | EPI_INT_ERR);*/ EPIIntDisable( EPI0_BASE, EPI_INT_RXREQ | EPI_INT_TXREQ | EPI_INT_ERR); EPIIntErrorClear(EPI0_BASE, EPI_INT_ERR_WTFULL | EPI_INT_ERR_RSTALL | EPI_INT_ERR_TIMEOUT); //EPIIntEnable( EPI0_BASE // EPI_INT_RXREQ | // EPI_INT_TXREQ | //EPI_INT_DMA_TX_DONE // EPI_INT_DMA_RX_DONE | // ); EPIIntEnable( EPI0_BASE, // EPI_INT_RXREQ | //EPI_INT_TXREQ EPI_INT_DMA_TX_DONE //EPI_INT_DMA_RX_DONE // EPI_INT_ERR ); // Enable the EPI interrupt on the processor (NVIC). // Note: even if no EPI interrupt were enabled, the uDMA // controller will generate an interrupt on the EPI // interrupt signal when a uDMA transfer is complete. IntEnable(INT_EPI0); EPIIntEnable(EPI0_BASE, EPI_INT_DMA_TX_DONE); while (HWREG(EPI0_BASE + EPI_O_STAT) & EPI_STAT_INITSEQ) { } } //initEPI() void DMA_Init() { SysCtlPeripheralDisable(SYSCTL_PERIPH_UDMA); SysCtlPeripheralReset(SYSCTL_PERIPH_UDMA); SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); uDMAEnable(); while (!(SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA))) ; uDMAControlBaseSet(psDMAControlTable); //uDMAChannelAttributeDisable(UDMA_CH20_EPI0RX, UDMA_ATTR_ALL); uDMAChannelAttributeDisable(UDMA_CH21_EPI0TX, UDMA_ATTR_ALL); uDMAChannelAttributeEnable(UDMA_CH21_EPI0TX, UDMA_ATTR_USEBURST); //single request is not supported //uDMAChannelAssign(UDMA_CH20_EPI0RX); uDMAChannelAssign(UDMA_CH21_EPI0TX); uDMAChannelControlSet(UDMA_CH21_EPI0TX | UDMA_PRI_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE | UDMA_ARB_1024); // UDMA_ARB_2 uDMAChannelControlSet(UDMA_CH21_EPI0TX | UDMA_ALT_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE | UDMA_ARB_1024); // UDMA_ARB_2 uDMAChannelSelectSecondary(UDMA_DEF_TMR1B_SEC_EPI0TX); } void EPI_HPI_uDMA_write(uint16_t * s2,uint16_t * s1,uint32_t count) { g_pusEPIFPGA = (uint32_t*) 0xC0000000; // EPIIntEnable(EPI0_BASE, EPI_INT_DMA_TX_DONE); uDMAChannelTransferSet(UDMA_CH21_EPI0TX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void*) s1, (void*) g_pusEPIFPGA, count); //UDMA_MODE_AUTO, UDMA_MODE_BASIC uDMAChannelTransferSet(UDMA_CH21_EPI0TX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void*) s2, (void*) g_pusEPIFPGA, count); uDMAChannelEnable(UDMA_CH21_EPI0TX); EPIDMATxCount(EPI0_BASE, count*2); } void SwapBuffers(uint16_t ** a, uint16_t **b) { uint16_t *tmp = *a; *a = *b; *b = tmp; } int main(void) { ui32SysClock = SysCtlClockFreqSet( (SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), SYSTEM_CLOCK_120M); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION); while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPION)) { } GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0); GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_1); DMA_Init(); initEPI(); pa = send_data; pb = send_data3; //uint16_t i =0; EPI_HPI_uDMA_write(pa,send_data2,1024); SwapBuffers(&pa, &pb); /* uint16_t data1[16] = { 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0xFFFF , 0xAAAA , 0x5555 , 0x0000 , 0x0000 , 0x5555 , 0xAAAA , 0xFFFF , 0xFFFF , 0xFFFF , 0xFFFF , 0xFFFF}; //initEPI(); //uint16_t sr; //to read an fpga register... sr = EPIfpga[2]; //to write an fpga register... */ while (1) { /*while(uDMAChannelModeGet(UDMA_CH21_EPI0TX)!=UDMA_MODE_STOP); uDMAChannelTransferSet(UDMA_CH21_EPI0TX |UDMA_PRI_SELECT, UDMA_MODE_BASIC,(void*)send_data2, (void*) g_pusEPIFPGA, 1024); //UDMA_MODE_AUTO, UDMA_MODE_BASIC uDMAChannelEnable(UDMA_CH21_EPI0TX); EPIDMATxCount(EPI0_BASE, 1024); while(uDMAChannelModeGet(UDMA_CH21_EPI0TX)!=UDMA_MODE_STOP); uDMAChannelTransferSet(UDMA_CH21_EPI0TX | UDMA_ALT_SELECT, UDMA_MODE_BASIC,(void*)send_data, (void*) g_pusEPIFPGA, 1024); //UDMA_MODE_AUTO, UDMA_MODE_BASIC uDMAChannelEnable(UDMA_CH21_EPI0TX); EPIDMATxCount(EPI0_BASE, 1024);*/ if (uDMAChannelModeGet(UDMA_CH21_EPI0TX) == UDMA_MODE_STOP) { GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, 2); GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0); EPI_HPI_uDMA_write(pa,send_data2,1024); } else if (uDMAChannelModeGet(UDMA_CH21_EPI0TX) == UDMA_MODE_PINGPONG) { GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, 0); GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 1); } } } void EPIIntHandler(void) { //IntDisable(INT_EPI0); uint32_t state = EPIIntStatus(EPI0_BASE, true); if(state & EPI_INT_ERR) EPIIntErrorClear(EPI0_BASE, EPIIntErrorStatus(EPI0_BASE)); uint32_t ui32Mode; ui32Mode = uDMAChannelModeGet(UDMA_CH21_EPI0TX | UDMA_PRI_SELECT); if(ui32Mode == UDMA_MODE_STOP) { PingCount++; } ui32Mode = uDMAChannelModeGet(UDMA_CH21_EPI0TX | UDMA_ALT_SELECT); if(ui32Mode == UDMA_MODE_STOP) { PingCount++; } if(PingCount >=2) { PingCount = 0; SwapBuffers(&pa, &pb); } switch (state) { case EPI_INT_DMA_TX_DONE: // EPIIntErrorClear(EPI0_BASE, EPI_INT_ERR_DMAWRIC); //* if(!testttttttttttttt) // { // testttttttttttttt = 1; EPI_HPI_uDMA_write(pa,send_data2,1024); // } // else // { // testttttttttttttt = 0; // EPI_HPI_uDMA_write(send_data3,send_data,1024); // } break; case EPI_INT_ERR: // EPIIntErrorClear(EPI0_BASE, EPIIntErrorStatus(EPI0_BASE)); break; default: break; } // switch () // { // case 4: // EPIIntDisable(EPI0_BASE, EPI_INT_TXREQ); // // break; // } uDMAIntClear(UDMA_CH21_EPI0TX); uDMAIntClear(UDMA_SEC_CHANNEL_EPI0TX); }