Hi,
I'm having trouble getting the EPI uDMA write to function properly.
I have EPI write (no uDMA) working, EPI read (no uDMA) working and EPI uDMA read working.
From my tests it seems that the EPI uDMA is not even starting!
Please help.
Khaled.
//define the uDMA control table #if defined(ewarm) #pragma data_alignment=1024 unsigned char ucControlTable[1024]; #elif defined(ccs) #pragma DATA_ALIGN(ucControlTable, 1024) tDMAControlTable ucControlTable[1024]; #else unsigned char ucControlTable[1024] __attribute__ ((aligned(1024))); #endif volatile uint16_t *g_pusEPIFPGA; // Pointer for EPI memory window. uint32_t u32DataIn[100]; uint32_t u32DataOut[100]; uint32_t numSuccess; uint32_t numFail; /********************************************************************** **********************************************************************/ int main(void) { uint16_t i; uint32_t status; uint16_t errorIndex; SystemInit(); //system setup GPIO_Init(); //setup GPIO uDMA_Init(); //setup the uDMA EPI_Init(); //setup EPI HPI interface //test the access to the DSP/HPI interface numFail = 0; numSuccess = 0; while(1) { //fill with dummy data for(i = 0; i < 100; i++) { u32DataIn[i] = i; u32DataOut[i] = 0x0BAD0BAD; } EPI_HPI_write ( u32DataIn, 100, (uint32_t *) HPI_MEM_DAC_TX_START); while((!EPIdone())) { } //wait until uDMA is done EPI_HPI_read ((uint32_t *) HPI_MEM_DAC_TX_START, 100, u32DataOut); while((!EPIdone())) { } //wait until uDMA is done //compare for(i = 0, errorIndex = 0xFFFF; i < 100; i++) { if(u32DataIn[i] != u32DataOut[i]) numFail++; else numSuccess++; }//for all // status = EPI_HPI_uDMA_write( u32DataIn, 100, (uint32_t *) HPI_MEM_DAC_TX_START); // while((!EPIdone())) { } //wait until uDMA is done status &= EPI_HPI_uDMA_read ((uint32_t *) HPI_MEM_DAC_TX_START, 100, u32DataOut); // SysCtlDelay(gSysCtlClock * 1e-3); // wait for uDMA interrupt // wait for uDMA to finish while((!EPIdone())) { } //wait until uDMA is done //compare for(i = 0, errorIndex = 0xFFFF; i < 100; i++) { if(u32DataIn[i] != u32DataOut[i]) numFail++; else numSuccess++; }//for all }//while(1) }//main /********************************************************************** **********************************************************************/ void EPI_Init(void) { // Set pointer to EPI memory mapped window. g_pusEPIFPGA = (uint16_t *)0xC0000000; //reset the EPI interface EPIModeSet( EPI0_BASE, EPI_MODE_DISABLE); // Set the EPI divider. EPIDividerSet( EPI0_BASE, 1); //enable the EPI interface, and use general purpose mode EPIModeSet( EPI0_BASE, EPI_MODE_HB16); EPIConfigHB16Set( EPI0_BASE, // EPI_HB16_USE_TXEMPTY | //Tx fifo empty enable // EPI_HB16_USE_RXFULL | //Rx fifo full enable // EPI_HB16_BURST_TRAFFIC | //burst mode enabled EPI_HB16_IN_READY_EN | //IRDY enabled EPI_HB16_IN_READY_EN_INVERTED | //IRDY polarity inverted EPI_HB16_MODE_ADDEMUX | //sets up data and address as separate EPI_HB16_CSCFG_ALE | //EPIS030 to operate as an address latch (ALE) EPI_HB16_ALE_HIGH | //sets the address latch active high EPI_HB16_WRWAIT_0 | //sets write wait state to 2 EPI clocks. EPI_HB16_RDWAIT_0 , //sets read wait state to 2 EPI clocks. 0xF0); //FIFO mode maximum number of clocks EPIConfigHB16TimingSet(EPI0_BASE, 0 , //specifies the chip select to configure[0-3] EPI_HB16_IN_READY_DELAY_1 | //sets the stall on input ready (EPIS032) //to start 1 EPI clock after signaled EPI_HB16_WRWAIT_MINUS_ENABLE | //enables a 1 EPI clock write wait state reduction EPI_HB16_RDWAIT_MINUS_ENABLE); //enables a 1 EPI clock read wait state reduction //setup the address mapping for low level driver EPIAddressMapSet( EPI0_BASE, EPI_ADDR_PER_BASE_C | EPI_ADDR_PER_SIZE_64KB); EPIFIFOConfig( EPI0_BASE, EPI_FIFO_CONFIG_TX_1_4 | EPI_FIFO_CONFIG_RX_1_8); //configure the EPI Non blocking read EPINonBlockingReadConfigure(EPI0_BASE, 0, EPI_NBCONFIG_SIZE_16, 0); //------------------------------------------------------------- // Setup the EPI interrupt to service the NBRFIFO and the WFIFO // When the NBRFIFO is full, or the WFIFO is empty generate an // interrupt or trigger a uDMA transfer to service the buffer //------------------------------------------------------------- //clear the FIFO interrupt triggers 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); // 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); //------------------------------------------------------------- // Configure the uDMA for the EPI read and write //------------------------------------------------------------- // Put the attributes in a known state for the uDMA EPI channel. uDMAChannelAssign(UDMA_CH20_EPI0RX); uDMAChannelAssign(UDMA_CH21_EPI0TX); uDMAChannelAttributeDisable(UDMA_SEC_CHANNEL_EPI0RX, UDMA_ATTR_ALL); //NBRFIFO uDMAChannelAttributeDisable(UDMA_SEC_CHANNEL_EPI0TX, UDMA_ATTR_ALL); //WFIFO // Set the USEBURST attribute for the uDMA EPI RX/TX channel. // and allow the peripheral to generate software request for uDMA channel uDMAChannelSelectSecondary( UDMA_DEF_TMR1A_SEC_EPI0RX | UDMA_DEF_TMR1B_SEC_EPI0TX); uDMAChannelAttributeEnable( UDMA_SEC_CHANNEL_EPI0RX, //NBRFIFO UDMA_ATTR_USEBURST | //single request is not supported UDMA_ATTR_HIGH_PRIORITY); //needed for ADC transfers uDMAChannelAttributeEnable( UDMA_SEC_CHANNEL_EPI0TX, //WFIFO UDMA_ATTR_USEBURST); //single request is not supported // Configure the control parameters for the EPI RX/TX. The uDMA EPI RX/TX uDMAChannelControlSet( UDMA_SEC_CHANNEL_EPI0RX, //NBRFIFO UDMA_SIZE_16 | //data size UDMA_SRC_INC_NONE | //no source address increment UDMA_DST_INC_16 | //destination address increment UDMA_ARB_1); //arbitration size uDMAChannelControlSet( UDMA_SEC_CHANNEL_EPI0TX, //WFIFO UDMA_SIZE_16 | //data size UDMA_SRC_INC_16 | //source address increment UDMA_DST_INC_NONE | //no destination address increment UDMA_ARB_1); //arbitration size //------------------------------------------------------------- //setup the uDMA interrupts //we don't want the uDMA to generate an interrupt on conclusion //------------------------------------------------------------- IntDisable(INT_UDMA); IntDisable(INT_UDMAERR); } /********************************************************************** **********************************************************************/ void EPI0_Handler(void) { uint32_t intStatus; intStatus = EPIIntStatus(EPI0_BASE, true); if(intStatus & EPI_INT_ERR) { if(EPIIntErrorStatus(EPI0_BASE)){ // __breakpoint(0); EPIIntErrorClear(EPI0_BASE, intStatus); } } //if its the end of a Tx EPI/HPI uDMA transfer // signal that the packet transfer is done if(uDMAChannelModeGet(UDMA_SEC_CHANNEL_EPI0TX) == UDMA_MODE_STOP) { } //if its the end of an Rx EPI/HPI uDMA transfer // process the data if(uDMAChannelModeGet(UDMA_SEC_CHANNEL_EPI0RX) == UDMA_MODE_STOP) { } } #endif /********************************************************************** **********************************************************************/ void EPI_HPI_uDMA_write(uint32_t *src_p, uint32_t count, uint32_t *dst_p) { // Set pointer to EPI memory mapped window. g_pusEPIFPGA = (uint16_t *)0xC0000000; //write the HPID with the data // EPIDMATxCount( EPI0_BASE, // count * 2); uDMAChannelTransferSet( UDMA_SEC_CHANNEL_EPI0TX, UDMA_MODE_BASIC, src_p, //transfer payload (void *)g_pusEPIFPGA, //to EPI WFIFO count * 2); //convert from uint32 to uint16 uDMAChannelEnable( UDMA_SEC_CHANNEL_EPI0TX); } /********************************************************************** **********************************************************************/ uint16_t EPI_HPI_uDMA_read(uint32_t *src_p, uint32_t count, uint32_t *dst_p) { //read data from the HPID //configure the EPI interface to read into the NBRFIFO //configure the uDMA to service the NBRFIFO EPINonBlockingReadStart(EPI0_BASE, 0, count * 2); uDMAChannelTransferSet( UDMA_SEC_CHANNEL_EPI0RX, UDMA_MODE_BASIC, (void *)(EPI0_BASE + EPI_O_READFIFO0),//from EPI NBRFIFO dst_p, //transfer payload count * 2); //convert from uint32 to uint16 uDMAChannelEnable( UDMA_SEC_CHANNEL_EPI0RX); } /********************************************************************** **********************************************************************/ void EPI_HPI_read( uint32_t *src_p, uint32_t count, uint32_t *dst_p) { uint32_t i; uint32_t word; //HPI data // Set pointer to EPI memory mapped window. g_pusEPIFPGA = (uint16_t *)0xC0000000; //read the data for(i = 0; i < count; i++) { word = ((uint32_t) *g_pusEPIFPGA);//read the HPID lower 16bits g_pusEPIFPGA++; word |= ((uint32_t) *g_pusEPIFPGA) << 16; g_pusEPIFPGA++; *dst_p = word; *dst_p++; } } /********************************************************************** **********************************************************************/ void EPI_HPI_write( uint32_t *src_p, uint32_t count, uint32_t *dst_p) { uint32_t i; uint32_t word; //HPI data // Set pointer to EPI memory mapped window. g_pusEPIFPGA = (uint16_t *)0xC0000000; //write the data for(i = 0; i < count; i++) { word = src_p[i]; *g_pusEPIFPGA = word & 0xFFFF; //write the HPID lower 16bits g_pusEPIFPGA++; *g_pusEPIFPGA = (word >> 16) & 0xFFFF; g_pusEPIFPGA++; } } /********************************************************************** **********************************************************************/ uint16_t EPIdone(void) { //check if there is a EPI RX uDMA transfer is in progress. if(UDMA_MODE_STOP != uDMAChannelModeGet(UDMA_SEC_CHANNEL_EPI0RX)) return FALSE; if(EPINonBlockingReadCount(EPI0_BASE, 0) != 0) return FALSE; //check if there is EPI TX uDMA transfer is in progress. if(UDMA_MODE_STOP != uDMAChannelModeGet(UDMA_SEC_CHANNEL_EPI0TX)) return FALSE; if(EPIWriteFIFOCountGet(EPI0_BASE) < 4) return FALSE; return TRUE; } /********************************************************************** **********************************************************************/ void uDMA_Init(void) { uDMAControlBaseSet(ucControlTable); uDMAEnable(); IntEnable(INT_UDMAERR); } /********************************************************************** **********************************************************************/ void GPIO_Init(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); SysCtlPeripheralReset(SYSCTL_PERIPH_UDMA); SysCtlPeripheralEnable(SYSCTL_PERIPH_EPI0); SysCtlPeripheralReset(SYSCTL_PERIPH_EPI0); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOA); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOB); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOC); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOD); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOE); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOF); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG); SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOG); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH); SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOH); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ); SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOJ); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK); SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOK); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL); SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOL); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM); SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOM); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION); SysCtlPeripheralReset(SYSCTL_PERIPH_GPION); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP); SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOP); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ); SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOQ); //--------------------------------------------------------------- //configure EPI pins //--------------------------------------------------------------- GPIOPinConfigure(GPIO_PK5_EPI0S31); //EPI CLK GPIOPinConfigure(GPIO_PP3_EPI0S30); //EPI ALE/HAS GPIOPinConfigure(GPIO_PP2_EPI0S29); //EPI WR GPIOPinConfigure(GPIO_PB3_EPI0S28); //EPI RD GPIOPinConfigure(GPIO_PK4_EPI0S32); //EPI RDY GPIOPinConfigure(GPIO_PL0_EPI0S16); //EPI A0/HHWIL GPIOPinConfigure(GPIO_PH0_EPI0S0); //EPI D0 GPIOPinConfigure(GPIO_PH1_EPI0S1); //EPI D1 GPIOPinConfigure(GPIO_PH2_EPI0S2); //EPI D2 GPIOPinConfigure(GPIO_PH3_EPI0S3); //EPI D3 GPIOPinConfigure(GPIO_PC7_EPI0S4); //EPI D4 GPIOPinConfigure(GPIO_PC6_EPI0S5); //EPI D5 GPIOPinConfigure(GPIO_PC5_EPI0S6); //EPI D6 GPIOPinConfigure(GPIO_PC4_EPI0S7); //EPI D7 GPIOPinConfigure(GPIO_PA6_EPI0S8); //EPI D8 GPIOPinConfigure(GPIO_PA7_EPI0S9); //EPI D9 GPIOPinConfigure(GPIO_PG1_EPI0S10); //EPI D10 GPIOPinConfigure(GPIO_PG0_EPI0S11); //EPI D11 GPIOPinConfigure(GPIO_PM3_EPI0S12); //EPI D12 GPIOPinConfigure(GPIO_PM2_EPI0S13); //EPI D13 GPIOPinConfigure(GPIO_PM1_EPI0S14); //EPI D14 GPIOPinConfigure(GPIO_PM0_EPI0S15); //EPI D15 //--------------------------------------------------------------- //for each function pin, select the type //--------------------------------------------------------------- GPIOPinTypeEPI(GPIO_PORTH_BASE, GPIO_PIN_0 | //EPI D0 GPIO_PIN_1 | //EPI D1 GPIO_PIN_2 | //EPI D2 GPIO_PIN_3); //EPI D3 GPIOPinTypeEPI(GPIO_PORTC_BASE, GPIO_PIN_7 | //EPI D4 GPIO_PIN_6 | //EPI D5 GPIO_PIN_5 | //EPI D6 GPIO_PIN_4); //EPI D7 GPIOPinTypeEPI(GPIO_PORTA_BASE, GPIO_PIN_6 | //EPI D8 GPIO_PIN_7); //EPI D9 GPIOPinTypeEPI(GPIO_PORTG_BASE, GPIO_PIN_1 | //EPI D10 GPIO_PIN_0); //EPI D11 GPIOPinTypeEPI(GPIO_PORTM_BASE, GPIO_PIN_3 | //EPI D12 GPIO_PIN_2 | //EPI D13 GPIO_PIN_1 | //EPI D14 GPIO_PIN_0); //EPI D15 GPIOPinTypeEPI(GPIO_PORTB_BASE, GPIO_PIN_3); //EPI RD GPIOPinTypeEPI(GPIO_PORTP_BASE, GPIO_PIN_2 | //EPI WR GPIO_PIN_3); //EPI ALE GPIOPinTypeEPI(GPIO_PORTK_BASE, GPIO_PIN_4); //EPI IRDY GPIOPinTypeEPI(GPIO_PORTK_BASE, GPIO_PIN_5); //EPI CLOCK GPIOPinTypeEPI(GPIO_PORTL_BASE, GPIO_PIN_0); //EPI A0/HHWIL } /********************************************************************** **********************************************************************/ void SystemInit (void) { SysCtlMOSCConfigSet(SYSCTL_MOSC_HIGHFREQ); SysCtlDelay(5242880); gSysCtlClock = SysCtlClockFreqSet( SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_25MHZ | SYSCTL_CFG_VCO_480, 120000000); //desired system frequency }