This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
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 }
Hi QJ,
I was too hasty in my test: Its still not working.
It should be something simple since the EPI uDMA read IS WORKING, and both EPI uDMA read and EPI uDMA write have very similar code.
Khaled.
Hi Amit
thanks for you reply, but the uDMA read is working just fine, its the uDMA write that I have trouble with.
If I use non uDMA read or non uDMA write function, all is OK: I can write data and read it back.
If I use the uDMA read all seems to be OK as well: I can use the non uDMA write followed by the uDMA read and its working.
Khaled.
Hi Amit,
I was testing with different configurations to see which one works. Tried both EPIDAMTxCount commented out and not commented and neither worked.
As for the DMA Done, I did not get that far. I'm still trying to get the data across to the destination devise. One I have that part working, I can worry about uDMA done.
Khaled.
Hello Khaled
I tried a SDRAM data transfer using the DMA and Write Request from the EPI and it works as expected. Attached is the reference code. The code is for a DK-TM4C129X (TM4C129XNCZAD) coupled with a SDRAM Board
//***************************************************************************** // // sdram.c - Example demonstrating how to configure the EPI bus in SDRAM // mode. // // Copyright (c) 2014 Texas Instruments Incorporated. All rights reserved. // Software License Agreement // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package. // //***************************************************************************** #include <stdbool.h> #include <stdint.h> #include "inc/hw_epi.h" #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_gpio.h" #include "driverlib/epi.h" #include "driverlib/gpio.h" #include "driverlib/pin_map.h" #include "driverlib/sysctl.h" #include "driverlib/systick.h" #include "driverlib/uart.h" #include "driverlib/udma.h" #include "utils/uartstdio.h" //***************************************************************************** // //! \addtogroup epi_examples_list //! <h1>EPI SDRAM Mode (sdram)</h1> //! //! This example shows how to configure the TM4C129 EPI bus in SDRAM mode. It //! assumes that a 64Mbit SDRAM is attached to EPI0. //! //! For the EPI SDRAM mode, the pinout is as follows: //! Address11:0 - EPI0S11:0 //! Bank1:0 - EPI0S14:13 //! Data15:0 - EPI0S15:0 //! DQML - EPI0S16 //! DQMH - EPI0S17 //! /CAS - EPI0S18 //! /RAS - EPI0S19 //! /WE - EPI0S28 //! /CS - EPI0S29 //! SDCKE - EPI0S30 //! SDCLK - EPI0S31 //! //! This example uses the following peripherals and I/O signals. You must //! review these and change as needed for your own board: //! - EPI0 peripheral //! - GPIO Port A peripheral (for EPI0 pins) //! - GPIO Port B peripheral (for EPI0 pins) //! - GPIO Port C peripheral (for EPI0 pins) //! - GPIO Port G peripheral (for EPI0 pins) //! - GPIO Port H peripheral (for EPI0 pins) //! - GPIO Port K peripheral (for EPI0 pins) //! - GPIO Port L peripheral (for EPI0 pins) //! - GPIO Port M peripheral (for EPI0 pins) //! - GPIO Port P peripheral (for EPI0 pins) //! - EPI0S0 - PH0 //! - EPI0S1 - PH1 //! - EPI0S2 - PH2 //! - EPI0S3 - PH3 //! - EPI0S4 - PC7 //! - EPI0S5 - PC6 //! - EPI0S6 - PC5 //! - EPI0S7 - PC4 //! - EPI0S8 - PA6 //! - EPI0S9 - PA7 //! - EPI0S10 - PG1 //! - EPI0S11 - PG0 //! - EPI0S12 - PM3 //! - EPI0S13 - PM2 //! - EPI0S14 - PM1 //! - EPI0S15 - PM0 //! - EPI0S16 - PL0 //! - EPI0S17 - PL1 //! - EPI0S18 - PL2 //! - EPI0S19 - PL3 //! - EPI0S28 - PB3 //! - EPI0S29 - PP2 //! - EPI0S30 - PP3 //! - EPI0S31 - PK5 //! //! The following UART signals are configured only for displaying console //! messages for this example. These are not required for operation of EPI0. //! - UART0 peripheral //! - GPIO Port A peripheral (for UART0 pins) //! - UART0RX - PA0 //! - UART0TX - PA1 //! //! This example uses the following interrupt handlers. To use this example //! in your own application you must add these interrupt handlers to your //! vector table. //! - None. // //***************************************************************************** //***************************************************************************** // // Use the following to specify the GPIO pins used by the SDRAM EPI bus. // //***************************************************************************** #define EPI_PORTA_PINS (GPIO_PIN_7 | GPIO_PIN_6) #define EPI_PORTB_PINS (GPIO_PIN_3) #define EPI_PORTC_PINS (GPIO_PIN_7 | GPIO_PIN_6 | GPIO_PIN_5 | GPIO_PIN_4) #define EPI_PORTG_PINS (GPIO_PIN_1 | GPIO_PIN_0) #define EPI_PORTH_PINS (GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1 | GPIO_PIN_0) #define EPI_PORTK_PINS (GPIO_PIN_5) #define EPI_PORTL_PINS (GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1 | GPIO_PIN_0) #define EPI_PORTM_PINS (GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1 | GPIO_PIN_0) #define EPI_PORTP_PINS (GPIO_PIN_3 | GPIO_PIN_2) //***************************************************************************** // // The starting and ending address for the 64MB SDRAM chip (32Meg x 16bits) on // the SDRAM daughter board. // //***************************************************************************** #define SDRAM_START_ADDRESS 0x00000000 #define SDRAM_END_ADDRESS 0x01FFFFFF #define NO_OF_RAM_LOC 256 //***************************************************************************** // // The Mapping address space for the EPI SDRAM. // //***************************************************************************** #define SDRAM_MAPPING_ADDRESS 0xA0000000 //***************************************************************************** // // The Max Count value for the SysTick Timer. // //***************************************************************************** #define SYSTICK_MAX_COUNT 16777216 //***************************************************************************** // // A pointer to the EPI memory aperture. Note that g_pui16EPISdram is declared // as volatile so the compiler should not optimize reads out of the image. // //***************************************************************************** static volatile uint16_t *g_pui16EPISdram; volatile uint32_t g_ui32InternalRamArray[NO_OF_RAM_LOC]; //***************************************************************************** // // The DMA control structure table. // //***************************************************************************** #ifdef ewarm #pragma data_alignment=1024 tDMAControlTable psDMAControlTable[64]; #elif defined(ccs) #pragma DATA_ALIGN(psDMAControlTable, 1024) tDMAControlTable psDMAControlTable[64]; #else tDMAControlTable psDMAControlTable[64] __attribute__ ((aligned(1024))); #endif //***************************************************************************** // // A table used to determine the EPI clock frequency band in use. // //***************************************************************************** typedef struct { uint32_t ui32SysClock; uint32_t ui32FreqFlag; } tSDRAMFreqMapping; static tSDRAMFreqMapping g_psSDRAMFreq[] = { // // SysClock >= 100MHz, EPI clock >= 50Mhz (divided by 2) // {100000000, EPI_SDRAM_CORE_FREQ_50_100}, // // SysClock >= 60MHz, EPI clock >= 30MHz (divided by 2) // {60000000, EPI_SDRAM_CORE_FREQ_50_100}, // // SysClock >= 50MHz, EPI clock >= 50MHz (no divider) // {50000000, EPI_SDRAM_CORE_FREQ_50_100}, // // SysClock >= 30MHz, EPI clock >= 30MHz (no divider) // {50000000, EPI_SDRAM_CORE_FREQ_30_50}, // // SysClock >= 15MHz, EPI clock >= 15MHz (no divider) // {15000000, EPI_SDRAM_CORE_FREQ_15_30}, // // SysClock < 15Mhz, EPI clock < 15Mhz (no divider) // {0, EPI_SDRAM_CORE_FREQ_0_15} }; #define NUM_SDRAM_FREQ (sizeof(g_psSDRAMFreq) / sizeof(tSDRAMFreqMapping)) //***************************************************************************** // // This function sets up UART0 to be used for a console to display information // as the example is running. // //***************************************************************************** void InitConsole(void) { // // Enable GPIO port A which is used for UART0 pins. // TODO: change this to whichever GPIO port you are using. // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // // Configure the pin muxing for UART0 functions on port A0 and A1. // This step is not necessary if your part does not support pin muxing. // TODO: change this to select the port/pin you are using. // GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); // // Enable UART0 so that we can configure the clock. // SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); // // Use the internal 16MHz oscillator as the UART clock source. // UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC); // // Select the alternate (UART) function for these pins. // TODO: change this to select the port/pin you are using. // GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); // // Initialize the UART for console I/O. // UARTStdioConfig(0, 115200, 16000000); } //***************************************************************************** // // Configure EPI0 in SDRAM mode. The EPI memory space is setup using an a // simple C array. This example shows how to read and write to an SDRAM card // using the EPI bus in SDRAM mode. // //***************************************************************************** int main(void) { uint32_t ui32Val, ui32Freq, ui32SysClock; uint32_t ui32Index; // // Set the clocking to run at 120MHz from the PLL. // TODO: Update this call to set the system clock frequency your // application requires. // ui32SysClock = SysCtlClockFreqSet((SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_XTAL_25MHZ | SYSCTL_CFG_VCO_480), 120000000); // // Set up the serial console to use for displaying messages. This is // just for this example program and is not needed for EPI operation. // InitConsole(); // // Display the setup on the console. // UARTprintf("EPI SDRAM Mode ->\n"); UARTprintf(" Type: SDRAM\n"); UARTprintf(" Starting Address: 0x%08x\n", SDRAM_MAPPING_ADDRESS); UARTprintf(" End Address: 0x%08x\n", (SDRAM_MAPPING_ADDRESS + SDRAM_END_ADDRESS)); UARTprintf(" Data: 16-bit\n"); UARTprintf(" Size: 64MB (32Meg x 16bits)\n\n"); // // The EPI0 peripheral must be enabled for use. // SysCtlPeripheralEnable(SYSCTL_PERIPH_EPI0); // // For this example EPI0 is used with multiple pins on PortA, B, C, G, H, // K, L, M and N. The actual port and pins used may be different on your // part, consult the data sheet for more information. // TODO: Update based upon the EPI pin assignment on your target part. // 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); // // This step configures the internal pin muxes to set the EPI pins for use // with EPI. Please refer to the datasheet for more information about pin // muxing. Note that EPI0S27:20 are not used for the EPI SDRAM // implementation. // GPIOPinConfigure(GPIO_PH0_EPI0S0); GPIOPinConfigure(GPIO_PH1_EPI0S1); GPIOPinConfigure(GPIO_PH2_EPI0S2); GPIOPinConfigure(GPIO_PH3_EPI0S3); GPIOPinConfigure(GPIO_PC7_EPI0S4); GPIOPinConfigure(GPIO_PC6_EPI0S5); GPIOPinConfigure(GPIO_PC5_EPI0S6); GPIOPinConfigure(GPIO_PC4_EPI0S7); GPIOPinConfigure(GPIO_PA6_EPI0S8); GPIOPinConfigure(GPIO_PA7_EPI0S9); GPIOPinConfigure(GPIO_PG1_EPI0S10); GPIOPinConfigure(GPIO_PG0_EPI0S11); GPIOPinConfigure(GPIO_PM3_EPI0S12); GPIOPinConfigure(GPIO_PM2_EPI0S13); GPIOPinConfigure(GPIO_PM1_EPI0S14); GPIOPinConfigure(GPIO_PM0_EPI0S15); GPIOPinConfigure(GPIO_PL0_EPI0S16); GPIOPinConfigure(GPIO_PL1_EPI0S17); GPIOPinConfigure(GPIO_PL2_EPI0S18); GPIOPinConfigure(GPIO_PL3_EPI0S19); GPIOPinConfigure(GPIO_PB3_EPI0S28); GPIOPinConfigure(GPIO_PP2_EPI0S29); GPIOPinConfigure(GPIO_PP3_EPI0S30); GPIOPinConfigure(GPIO_PK5_EPI0S31); // // Configure the GPIO pins for EPI mode. All the EPI pins require 8mA // drive strength in push-pull operation. This step also gives control of // pins to the EPI module. // GPIOPinTypeEPI(GPIO_PORTA_BASE, EPI_PORTA_PINS); GPIOPinTypeEPI(GPIO_PORTB_BASE, EPI_PORTB_PINS); GPIOPinTypeEPI(GPIO_PORTC_BASE, EPI_PORTC_PINS); GPIOPinTypeEPI(GPIO_PORTG_BASE, EPI_PORTG_PINS); GPIOPinTypeEPI(GPIO_PORTH_BASE, EPI_PORTH_PINS); GPIOPinTypeEPI(GPIO_PORTK_BASE, EPI_PORTK_PINS); GPIOPinTypeEPI(GPIO_PORTL_BASE, EPI_PORTL_PINS); GPIOPinTypeEPI(GPIO_PORTM_BASE, EPI_PORTM_PINS); GPIOPinTypeEPI(GPIO_PORTP_BASE, EPI_PORTP_PINS); // // Is our current system clock faster than we can drive the SDRAM clock? // if(ui32SysClock > 60000000) { // // Yes. Set the EPI clock to half the system clock. // EPIDividerSet(EPI0_BASE, 1); } else { // // With a system clock of 60MHz or lower, we can drive the SDRAM at // the same rate so set the divider to 0. // EPIDividerSet(EPI0_BASE, 0); } // // Sets the usage mode of the EPI module. For this example we will use // the SDRAM mode to talk to the external 64MB SDRAM daughter card. // EPIModeSet(EPI0_BASE, EPI_MODE_SDRAM); // // Keep the compiler happy by setting a default value for the frequency // flag. // ui32Freq = g_psSDRAMFreq[NUM_SDRAM_FREQ - 1].ui32FreqFlag; // // Examine the system clock frequency to determine how to set the SDRAM // controller's frequency flag. // for(ui32Val = 0; ui32Val < NUM_SDRAM_FREQ; ui32Val++) { // // Is the system clock frequency above the break point in the table? // if(ui32SysClock >= g_psSDRAMFreq[ui32Val].ui32SysClock) { // // Yes - remember the frequency flag to use and exit the loop. // ui32Freq = g_psSDRAMFreq[ui32Val].ui32FreqFlag; break; } } // // Configure the SDRAM mode. We configure the SDRAM according to our core // clock frequency. We will use the normal (or full power) operating // state which means we will not use the low power self-refresh state. // Set the SDRAM size to 64MB with a refresh interval of 1024 clock ticks. // EPIConfigSDRAMSet(EPI0_BASE, (ui32Freq | EPI_SDRAM_FULL_POWER | EPI_SDRAM_SIZE_256MBIT), 1024); // // Set the address map. The EPI0 is mapped from 0x60000000 to 0x01FFFFFF. // For this example, we will start from a base address of 0x60000000 with // a size of 256MB. Although our SDRAM is only 64MB, there is no 64MB // aperture option so we pick the next larger size. // EPIAddressMapSet(EPI0_BASE, EPI_ADDR_PER_SIZE_256MB | EPI_ADDR_PER_BASE_A); // // Wait for the SDRAM wake-up to complete by polling the SDRAM // initialization sequence bit. This bit is true when the SDRAM interface // is going through the initialization and false when the SDRAM interface // it is not in a wake-up period. // while(HWREG(EPI0_BASE + EPI_O_STAT) & EPI_STAT_INITSEQ) { } // // Set the EPI memory pointer to the base of EPI memory space. Note that // g_pui16EPISdram is declared as volatile so the compiler should not // optimize reads out of the memory. With this pointer, the memory space // is accessed like a simple array. // g_pui16EPISdram = (uint16_t *)SDRAM_MAPPING_ADDRESS; // // Read the initial data in SDRAM, and display it on the console. // UARTprintf(" SDRAM Initial Data:\n"); UARTprintf(" Mem[0x6000.0000] = 0x%4x\n", g_pui16EPISdram[SDRAM_START_ADDRESS]); UARTprintf(" Mem[0x6000.0001] = 0x%4x\n", g_pui16EPISdram[SDRAM_START_ADDRESS + 1]); UARTprintf(" Mem[0x603F.FFFE] = 0x%4x\n", g_pui16EPISdram[SDRAM_END_ADDRESS - 1]); UARTprintf(" Mem[0x603F.FFFF] = 0x%4x\n\n", g_pui16EPISdram[SDRAM_END_ADDRESS]); // // Display what writes we are doing on the console. // UARTprintf(" SDRAM Write:\n"); UARTprintf(" Mem[0x6000.0000] <- 0xabcd\n"); UARTprintf(" Mem[0x6000.0001] <- 0x1234\n"); UARTprintf(" Mem[0x603F.FFFE] <- 0xdcba\n"); UARTprintf(" Mem[0x603F.FFFF] <- 0x4321\n\n"); // // Write to the first 2 and last 2 address of the SDRAM card. Since the // SDRAM card is word addressable, we will write words. // g_pui16EPISdram[SDRAM_START_ADDRESS] = 0xabcd; g_pui16EPISdram[SDRAM_START_ADDRESS + 1] = 0x1234; g_pui16EPISdram[SDRAM_END_ADDRESS - 1] = 0xdcba; g_pui16EPISdram[SDRAM_END_ADDRESS] = 0x4321; // // Read back the data you wrote, and display it on the console. // UARTprintf(" SDRAM Read:\n"); UARTprintf(" Mem[0x6000.0000] = 0x%4x\n", g_pui16EPISdram[SDRAM_START_ADDRESS]); UARTprintf(" Mem[0x6000.0001] = 0x%4x\n", g_pui16EPISdram[SDRAM_START_ADDRESS + 1]); UARTprintf(" Mem[0x603F.FFFE] = 0x%4x\n", g_pui16EPISdram[SDRAM_END_ADDRESS - 1]); UARTprintf(" Mem[0x603F.FFFF] = 0x%4x\n\n", g_pui16EPISdram[SDRAM_END_ADDRESS]); // // Check the validity of the data. // if((g_pui16EPISdram[SDRAM_START_ADDRESS] == 0xabcd) && (g_pui16EPISdram[SDRAM_START_ADDRESS + 1] == 0x1234) && (g_pui16EPISdram[SDRAM_END_ADDRESS - 1] == 0xdcba) && (g_pui16EPISdram[SDRAM_END_ADDRESS] == 0x4321)) { // // Read and write operations were successful. Return with no errors. // UARTprintf("Read and write to external SDRAM was successful!\n"); UARTprintf("Begin Performance Test!\n"); } else { // // Display on the console that there was an error. // UARTprintf("Read and/or write failure!"); UARTprintf(" Check if your SDRAM card is plugged in."); return(0); } for(ui32Index=0; ui32Index < NO_OF_RAM_LOC; ui32Index++) { g_ui32InternalRamArray[ui32Index] = 0xABCD0000 + ui32Index; } // // Configure the uDMA // SysCtlPeripheralDisable(SYSCTL_PERIPH_UDMA); SysCtlPeripheralReset(SYSCTL_PERIPH_UDMA); SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA))); // // Enable the uDMA and set the control table address // uDMAEnable(); uDMAControlBaseSet(&psDMAControlTable[0]); // // Assign the channel 16 for ADC1 Sequencer 2 for Audio IN // uDMAChannelAssign(UDMA_CH21_EPI0TX); uDMAChannelAttributeDisable(UDMA_CH21_EPI0TX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_REQMASK | UDMA_ATTR_HIGH_PRIORITY); // // Configure the control parameters for the primary and alternate control // structure of channel for ADC1 Sequencer-2 // uDMAChannelControlSet(UDMA_CH21_EPI0TX | UDMA_PRI_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_4); uDMAChannelTransferSet(UDMA_CH21_EPI0TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *)&g_ui32InternalRamArray[0], (void *)0xA0001000, NO_OF_RAM_LOC); // // Now enable the channel for ADC1 Sequencer-2 // // // Now Transfer Data using DMA TX channel with EPI request. // EPIFIFOConfig(EPI0_BASE, EPI_FIFO_CONFIG_TX_1_4| EPI_FIFO_CONFIG_RX_1_8); EPIDMATxCount(EPI0_BASE, NO_OF_RAM_LOC); uDMAChannelEnable(UDMA_CH21_EPI0TX); // // Wait in while loop at the end... // while(1) { } }
Regards
Amit
Hi Amit,
Thanks for the effort that you are putting into this, but my problem is still un-resolved.
I tried to adapt you code to HB16 interface but nothing has changed: The uDMA write is still not working.
I'm not sure what will be the next step, but our customers are waiting for the new board and I can't give the go ahead until this interface is working!
Khaled.
I will probe it and get back to you. But most likely its not. As I mentioned before the following accesses are working fine: Non uDMA read, Non uDMA write, and uDMA read.
The only non working access is the uDMA write.
If it was the iRDY, I would have seen the problem with the Non uDMA write as well.
Both Non uDMA write and uDMA write functions shares the same code until the last few instruction.
In the non uDMA case I do a direct write
for(i = 0; i < count; i++) {
word = src_p[i];
*g_pusEPIFPGA = (word ) & 0xFFFF; g_pusEPIFPGA++;
*g_pusEPIFPGA = (word >> 16) & 0xFFFF; g_pusEPIFPGA++;
EPIWriteFIFOEmpty(TRUE); //wait write fifo to be empty
}
In the uDMA case write I program the uDMA to send the data
EPIDMATxCount( EPI0_BASE,count * 2);
uDMAChannelTransferSet( UDMA_CH21_EPI0TX, UDMA_MODE_BASIC, src_p, (void *)g_pusEPIFPGA, count * 2);
uDMAChannelEnable( UDMA_CH21_EPI0TX);
Hi Amit,
I fully agree with you: its a configuration problem. But what? that is what is driving me crazy. I checked every instruction and every register but I'm not able to find the error. I was hoping that you will be able to find it for me.
I don't have an SDRAM that is connected to the HB16 bus. This is a home made board that connect the Cortex M4 to Ti's TMS320C6472 HPI bus.
However, as per your instructions, I did asked our technician to solder probes to the HB16 control bus (including the iRDY). I should be able to have the modified board today.
Khaled.
Hello Amit
Did as you have suggested and I think I have the first clue: The address bus is not toggling when performing a uDMA write!
In my case, I"m using a single address bus A0 to act as a half word strobe to the TM320C6472: A0 is low for the 1th 16bits, and high for the second 16bits.
Now the question, is why?
Khaled.
Hello Amit,
I think I found the solution. I have to increment the destination address as follow:
uDMAChannelControlSet(UDMA_SEC_CHANNEL_EPI0TX, //WFIFO
UDMA_SIZE_16 | //data size
UDMA_SRC_INC_16 | //source address increment
UDMA_DST_INC_16 | //destination address increment
UDMA_ARB_1); //arbitration size
I will do some more tests to confirm.
Khaled
Hi Amit,
I'm confused. I thougth that the EPI WFIFOCNT == 4 means the the fifo IS empty.
Here is my Epi init and Epi uDMA write function. could you please take a look.
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 data
EPIDMATxCount(EPI0_BASE, count * 2);
uDMAChannelTransferSet(UDMA_CH21_EPI0TX, UDMA_MODE_BASIC, src_p, (void *)g_pusEPIFPGA, count*2);
uDMAChannelEnable(UDMA_CH21_EPI0TX);
}
void EPI_Init(void) {
g_pusEPIFPGA = (uint16_t *)0xC0000000;
EPIModeSet(EPI0_BASE,
EPI_MODE_DISABLE);
EPIDividerSet(EPI0_BASE,
EPI_DIV_FACTOR_DATA);
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 | //1 EPI clock write wait state reduction
EPI_HB16_RDWAIT_MINUS_ENABLE); //1 EPI clock read wait state reduction
EPIAddressMapSet(EPI0_BASE,
EPI_ADDR_PER_BASE_C |
EPI_ADDR_PER_SIZE_64KB);
EPIFIFOConfig(EPI0_BASE,
EPI_FIFO_CONFIG_TX_1_2 |
EPI_FIFO_CONFIG_RX_1_2);
EPINonBlockingReadConfigure(EPI0_BASE,
0,
EPI_NBCONFIG_SIZE_16,
0);
//-------------------------------------------------------------
// Setup the EPI interrupt to service the NBRFIFO and the WFIFO
//-------------------------------------------------------------
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 | //read FIFO above trigger level
// EPI_INT_TXREQ | //transmit FIFO below trigger level
EPI_INT_DMA_TX_DONE | //transmit DMA completes
EPI_INT_DMA_RX_DONE | //read DMA completes
EPI_INT_ERR); //error condition
IntEnable(INT_EPI0);
//-------------------------------------------------------------
// Configure the uDMA for the EPI read and write
//-------------------------------------------------------------
uDMAChannelAssign( UDMA_CH20_EPI0RX);
uDMAChannelAssign( UDMA_CH21_EPI0TX);
uDMAChannelAttributeDisable(UDMA_CH20_EPI0RX, UDMA_ATTR_ALL);
uDMAChannelAttributeDisable(UDMA_CH21_EPI0TX, UDMA_ATTR_ALL);
uDMAChannelSelectSecondary( UDMA_DEF_TMR1A_SEC_EPI0RX |
UDMA_DEF_TMR1B_SEC_EPI0TX);
uDMAChannelAttributeEnable( UDMA_CH20_EPI0RX, //NBRFIFO
UDMA_ATTR_USEBURST | //single request is not supported
UDMA_ATTR_HIGH_PRIORITY); //needed for ADC transfers
uDMAChannelAttributeEnable( UDMA_CH21_EPI0TX, //WFIFO
UDMA_ATTR_USEBURST); //single request is not supported
uDMAChannelControlSet( UDMA_CH20_EPI0RX, //NBRFIFO
UDMA_SIZE_16 | //data size
UDMA_SRC_INC_NONE | //no source address increment
UDMA_DST_INC_16 | //destination address increment
UDMA_ARB_4); //arbitration size
uDMAChannelControlSet( UDMA_CH21_EPI0TX, //WFIFO
UDMA_SIZE_16 | //data size
UDMA_SRC_INC_16 | //source address increment
UDMA_DST_INC_16 | //destination address increment
UDMA_ARB_2); //arbitration size
//-------------------------------------------------------------
//setup the uDMA interrupts
//-------------------------------------------------------------
IntEnable(INT_UDMA);
IntEnable(INT_UDMAERR);
}
Khaled