Hi, I've been having a hard time configuring the EDMA on my DSP! I have created a simple code just to see how the EDMA works. The problem I am having is that the EDMA is not transfering my buffer from the initial location to the location I desired. I am using the CSL (Chip Library Support) and DSP/BIOS OS to run my code on the C6711 DSK. After running the code, I check in the memory by means of a time/frequency graph and I do not get the results I want (the desired buffer has not been filled). I am using the EDMA_setChannel() function to create the event. The stopEDMA() function is triggered by PRD_swi every 5 seconds just to make sure I have closed the EDMA channel before halting the DSP. Here is my main Code. Any help will be greatly appreciated. Att., Juan A. Torres-Rosario Code: ----------------------------- /* DSP/BIOS Files */ #include"edma_basicocfg.h" #include <std.h> #include <swi.h> #include <log.h> #include <clk.h /* CSL Support Files */ #include <csl.h> #include <csl_cache.h> #include <csl_edma.h> #include <csl_timer.h> #include <csl_irq.h> /* define some constants */ #define BUFF_SZ 10 /* ping-pong buffer sizes in # of ints */ /* define variables */ short ad_buffer[BUFF_SZ]={10,20,30,40,50,60,70,80,90,100}; short nx_buffer[BUFF_SZ]={0,0,0,0,0,0,0,0,0,0}; /* function prototypes */ void transferData (void); void stopEdma (void); EDMA_Handle hEdma; EDMA_Config gEdmaConfig = { EDMA_OPT_RMK( EDMA_OPT_PRI_LOW, // Priority EDMA_OPT_ESIZE_16BIT,// Element size EDMA_OPT_2DS_NO, // 2 dimensional source EDMA_OPT_SUM_INC, // Src update mode EDMA_OPT_2DD_NO, // 2 dimensional dest EDMA_OPT_DUM_INC, // Dest update mode EDMA_OPT_TCINT_NO, // Cause EDMA interrupt EDMA_OPT_TCC_OF(0), // Transfer Complete Code EDMA_OPT_LINK_NO, // Enable link parameters EDMA_OPT_FS_YES // Use frame sync ), EDMA_SRC_OF(ad_buffer), // src address EDMA_CNT_OF(BUFF_SZ), // Count = buffer size EDMA_DST_OF(nx_buffer), // dest address EDMA_IDX_OF(0), // frame/element index value EDMA_RLD_OF(0) // reload }; void main (void) { hEdma = EDMA_open(EDMA_CHA_ANY,EDMA_OPEN_RESET); EDMA_config(hEdma,&gEdmaConfig); EDMA_enableChannel(hEdma); LOG_printf(&trace,"DSP/BIOS takes control\n"); SWI_post(&SWItransferData); } // Software Interrupt Function void transferData (void) { LOG_printf(&trace,"SWItransferData_post\n"); EDMA_setChannel(hEdma); } // Periodic Function - runs every 5 seconds void stopEdma() { LOG_printf(&trace,"EDMA_close Channel\n"); EDMA_disableChannel(hEdma); EDMA_close(hEdma); } |
|
EDMA Problem in Simple Code on C6711DSK
Started by ●March 2, 2004
Reply by ●March 2, 20042004-03-02
Hello Juan: You need to program the EDMA using the EDMMA Options parameter - EDMA_OPT_TCC_OF macro, to set a transfer complete bit in the CIPR when the transfer is complete, and then use the EDMA_intTest() function to check that bit in CIPR to see if the transfer is completed. Also, I dont see why you need to use EDMA_enableChannel and EDMA_disableChannel, since these are for event-synchronized EDMAs. You just need to use EDMA_setChannel, and that kicks off the EDMA. You only have to be careful not to use any of the event-enabled channels for your asynchronous (i.e. CPU-initiated) EDMAs. Also be sure to clear the relevant CIPR-bit once you have checked it, so that you can use the same EDMA_config again if needed. Hope this helps, Regards ka > Code: > ----------------------------- > > /* DSP/BIOS Files */ > #include"edma_basicocfg.h" > #include <std.h> > #include <swi.h> > #include <log.h> > #include <clk.h > /* CSL Support Files */ > #include <csl.h> > #include <csl_cache.h> > #include <csl_edma.h> > #include <csl_timer.h> > #include <csl_irq.h> > > /* define some constants */ > #define BUFF_SZ 10 /* ping-pong buffer sizes in # of > ints */ > > /* define variables */ > short ad_buffer[BUFF_SZ]={10,20,30,40,50,60,70,80,90,100}; > short nx_buffer[BUFF_SZ]={0,0,0,0,0,0,0,0,0,0}; > > /* function prototypes */ > void transferData (void); > void stopEdma (void); > > EDMA_Handle hEdma; > > EDMA_Config gEdmaConfig = { > EDMA_OPT_RMK( > EDMA_OPT_PRI_LOW, // > Priority > EDMA_OPT_ESIZE_16BIT,// Element > size > EDMA_OPT_2DS_NO, // 2 dimensional > source > EDMA_OPT_SUM_INC, // Src update > mode > EDMA_OPT_2DD_NO, // 2 dimensional > dest > EDMA_OPT_DUM_INC, // Dest update > mode > EDMA_OPT_TCINT_NO, // Cause EDMA > interrupt > EDMA_OPT_TCC_OF(0), // Transfer Complete > Code > EDMA_OPT_LINK_NO, // Enable link > parameters > EDMA_OPT_FS_YES // Use frame > sync > ), > > EDMA_SRC_OF(ad_buffer), // src > address > EDMA_CNT_OF(BUFF_SZ), // Count = buffer > size > EDMA_DST_OF(nx_buffer), // dest > address > EDMA_IDX_OF(0), // frame/element index > value > EDMA_RLD_OF(0) // > reload > }; > void main (void) > { > hEdma = EDMA_open(EDMA_CHA_ANY,EDMA_OPEN_RESET); > > EDMA_config(hEdma,&gEdmaConfig); > > EDMA_enableChannel(hEdma); > > LOG_printf(&trace,"DSP/BIOS takes control\n"); > > SWI_post(&SWItransferData); > > } > // Software Interrupt Function > void transferData (void) > { > > LOG_printf(&trace,"SWItransferData_post\n"); > > EDMA_setChannel(hEdma); > > } > // Periodic Function - runs every 5 seconds > void stopEdma() > { > > LOG_printf(&trace,"EDMA_close Channel\n"); > > EDMA_disableChannel(hEdma); > > EDMA_close(hEdma); > > } __________________________________ |
|
Reply by ●March 3, 20042004-03-03
Hi KAnand: I am not interested in sending any interrupt to the CPU after the transfer is completed (at least not for know). Do I still need to fill the Transfer Complete Code Parameter on the EDMA_config? If the TCC must be used, does this means that I need to set the appropiate channel bit on the CIER, set the nmi and global interrupt, and configure the EDMA interrupt? Also, what do you mean "not to use event-enabled channels for asynchronous transmision"? Last, but not least, can I use any channel, i.e. a timer 1 EDMA channel, eventhough it will not be driven by the peripheral associated with the channel (timer 1)? Sorry for asking a lot of questions and thanks for your help. -Juan --- KAnand <> wrote: > > Hello Juan: > > You need to program the EDMA using the EDMMA Options > parameter - EDMA_OPT_TCC_OF macro, to set a transfer > complete bit in the CIPR when the transfer is > complete, and then use the EDMA_intTest() function > to > check that bit in CIPR to see if the transfer is > completed. > > Also, I dont see why you need to use > EDMA_enableChannel and EDMA_disableChannel, since > these are for event-synchronized EDMAs. You just > need > to use EDMA_setChannel, and that kicks off the EDMA. > You only have to be careful not to use any of the > event-enabled channels for your asynchronous (i.e. > CPU-initiated) EDMAs. > > Also be sure to clear the relevant CIPR-bit once you > have checked it, so that you can use the same > EDMA_config again if needed. > > Hope this helps, > > Regards > ka > > Code: > > > ----------------------------- > > > > /* DSP/BIOS Files */ > > #include"edma_basicocfg.h" > > #include <std.h> > > #include <swi.h> > > #include <log.h> > > #include <clk.h> > > > > > > /* CSL Support Files */ > > #include <csl.h> > > #include <csl_cache.h> > > #include <csl_edma.h> > > #include <csl_timer.h> > > #include <csl_irq.h> > > > > /* define some constants */ > > #define BUFF_SZ 10 /* ping-pong > buffer > sizes in # of > > ints */ > > > > /* define variables */ > > short > ad_buffer[BUFF_SZ]={10,20,30,40,50,60,70,80,90,100}; > > short nx_buffer[BUFF_SZ]={0,0,0,0,0,0,0,0,0,0}; > > > > /* function prototypes */ > > void transferData (void); > > void stopEdma (void); > > > > EDMA_Handle hEdma; > > > > EDMA_Config gEdmaConfig = { > > EDMA_OPT_RMK( > > EDMA_OPT_PRI_LOW, // > > Priority > > EDMA_OPT_ESIZE_16BIT,// Element > > size > > EDMA_OPT_2DS_NO, // 2 dimensional > > source > > EDMA_OPT_SUM_INC, // Src update > > mode > > EDMA_OPT_2DD_NO, // 2 dimensional > > dest > > EDMA_OPT_DUM_INC, // Dest update > > mode > > EDMA_OPT_TCINT_NO, // Cause EDMA > > interrupt > > EDMA_OPT_TCC_OF(0), // Transfer Complete > > Code > > EDMA_OPT_LINK_NO, // Enable link > > parameters > > EDMA_OPT_FS_YES // Use frame > > sync > > ), > > > > EDMA_SRC_OF(ad_buffer), // src > > address > > EDMA_CNT_OF(BUFF_SZ), // Count = buffer > > size > > EDMA_DST_OF(nx_buffer), // dest > > address > > EDMA_IDX_OF(0), // frame/element index > > value > > EDMA_RLD_OF(0) // > > reload > > }; > > > > > > void main (void) > > { > > > > > > hEdma = EDMA_open(EDMA_CHA_ANY,EDMA_OPEN_RESET); > > > > EDMA_config(hEdma,&gEdmaConfig); > > > > EDMA_enableChannel(hEdma); > > > > LOG_printf(&trace,"DSP/BIOS takes control\n"); > > > > SWI_post(&SWItransferData); > > > > } > > > > > > // Software Interrupt Function > > void transferData (void) > > { > > > > LOG_printf(&trace,"SWItransferData_post\n"); > > > > EDMA_setChannel(hEdma); > > > > } > > > > > > // Periodic Function - runs every 5 seconds > > void stopEdma() > > { > > > > LOG_printf(&trace,"EDMA_close Channel\n"); > > > > EDMA_disableChannel(hEdma); > > > > EDMA_close(hEdma); > > > > } > > __________________________________ > __________________________________ |
|
Reply by ●March 3, 20042004-03-03
--- Juan Torres <> wrote: > Hi KAnand: > > I am not interested in sending any interrupt to the > CPU after the transfer is completed (at least not > for > know). Do I still need to fill the Transfer Complete > Code Parameter on the EDMA_config? If the TCC must > be > used, does this means that I need to set the > appropiate channel bit on the CIER, set the nmi and > global interrupt, and configure the EDMA interrupt? You are mixing up two different things here. I. CIPR: ======== Using the TCC-parameter is the only way to tell if an EDMA completed or not. So the steps to follow are: 1. Clear the bit 'n' of CIPR if you havent already 2. Set the EdmaConfig's TCC parameter to bit 'n' 3. After starting the EDMA, poll the 'n'-th bit of CIPR to see if the EDMA is finished. 4. Clear it after EDMA is complete. II. CIER: ========= Setting the corresponding bits in CIER causes the software interrupt handler to fire, when the EDMA completes, IF, that interrupt is enabled in the IER. (which is Interrupt 8) - this is IN ADDITION to setting the corresponding CIPR bits. > Also, what do you mean "not to use event-enabled > channels for asynchronous transmision"? Event synchronized EDMAs are started by events that happen - like McBSP Receive event for e.g. Since you are starting the EDMA yourself by setting the correspondinb bit in ESR ("Event Set Register"), it is called CPU-initiated or "Asynchronous" EDMA transfer. > Last, but not least, can I use any channel, i.e. a > timer 1 EDMA channel, eventhough it will not be > driven > by the peripheral associated with the channel (timer > 1)? Sure you can (at least I did that way :) ) ! As long as the event is not enabled in EER, thats OK. > Sorry for asking a lot of questions and thanks for > your help. > > -Juan > No problem, but I assumed you would read up on this stuff in my previous email - I strongly suggest you read the section titled "EDMA Interrupt Generation" and the one titled "Initiating an EDMA Transfer" in the Peripherals Reference Guide. This document, I think, has been replaced with smaller modules - then find the module on EDMA and you will find these topics there. Corrections to my understanding are welcome and requested. Regards Anand __________________________________ |
|
Reply by ●March 3, 20042004-03-03
Hi KAnand, Thanks for your help :). I have modified my code so that the EDMA Channel's opt TCC has a particular channel (2), cleared the CIPR before configuring the channel, and testing the channel after I perform the transfer. When I test the channel, the CIPR bit has been set, meaning that the EDMA Transfer was completed. The problem is that when I check the memory location of the destination buffer, it does not have the content of the source buffer as if no transfer was made. My variables (source and destination buffers) are been stored in the SDRAM. I have read the EDMA part on "spru190d" file, which deals with the peripherals, and quite understand how the EDMA works. Is there any other parameter I am supposed to set for asynchronous transfer? Is asynchronous transfer reliable? Code: ------------------ /* DSP/BIOS Files */ #include"edma_basicocfg.h" #include <std.h> #include <swi.h> #include <log.h> #include <clk.h /* CSL Support Files */ #include <csl.h> #include <csl_cache.h> #include <csl_edma.h> #include <csl_timer.h> #include <csl_irq.h> /* define some constants */ #define BUFF_SZ 10 /* ping-pong buffer sizes in # of ints */ /* define variables */ short ad_buffer[BUFF_SZ]={10,20,30,40,50,60,70,80,90,100}; short nx_buffer[BUFF_SZ]={0,0,0,0,0,0,0,0,0,0}; /* function prototypes */ void transferData (void); void stopEdma (void); EDMA_Handle hEdma; EDMA_Config gEdmaConfig = { EDMA_OPT_RMK( EDMA_OPT_PRI_LOW, // Priority EDMA_OPT_ESIZE_16BIT,// Element size EDMA_OPT_2DS_NO, // 2 dimensional source EDMA_OPT_SUM_INC, // Src update mode EDMA_OPT_2DD_NO, // 2 dimensional dest EDMA_OPT_DUM_INC, // Dest update mode EDMA_OPT_TCINT_YES, // Cause EDMA interrupt EDMA_OPT_TCC_OF(2), // Transfer Complete Code EDMA_OPT_LINK_NO, // Enable link parameters EDMA_OPT_FS_YES // Use frame sync ), EDMA_SRC_OF(ad_buffer), // src address EDMA_CNT_OF(BUFF_SZ), // Count = buffer size EDMA_DST_OF(nx_buffer), // dest address EDMA_IDX_OF(0), // frame/element index value EDMA_RLD_OF(0) // reload }; void main (void) { EDMA_resetAll(); hEdma = EDMA_open(EDMA_CHA_TINT1,EDMA_OPEN_RESET); EDMA_intClear(2); EDMA_config(hEdma,&gEdmaConfig); //EDMA_enableChannel(hEdma); LOG_printf(&trace,"DSP/BIOS takes control\n"); SWI_post(&SWItransferData); } // Software Interrupt Function void transferData (void) { LOG_printf(&trace,"SWItransferData_post\n"); EDMA_setChannel(hEdma); } // Periodic Function - runs every 5 seconds void stopEdma() { if (EDMA_intTest(2)) LOG_printf(&trace,"EDMA Transfer Completed\n"); else LOG_printf(&trace,"No EDMA Transfer\n"); EDMA_intClear(2); //EDMA_disableChannel(hEdma); EDMA_close(hEdma); } __________________________________ |
Reply by ●March 4, 20042004-03-04
In a message dated 3/3/2004 11:35:07 AM Eastern Standard Time,
t...@yahoo.com writes:
Hi KAnand, Hi!
I bet that this is a caching problem!
You nead to do a cache Flush and/or Clean on the SDRAM location to which
you are trying to do this transfer.
I also bet that if you changed your buffer location to On Chip memory (I
assume you have at least one bank available) or, even better, disable caching,
just for testing, and rerun your test, then you should find the correct data in
the buffer.
Hope this helps.
Regards,
/Khalid
|
|
Reply by ●March 4, 20042004-03-04
Hi khalida1: You hitted right on the spot!!! When I changed my variables to the INTERNAL Memory (L2 CACHE), the transfer was really made. As of your solutions for SDRAM, What do you mean by Cache Flush. How can I do a Cache Flush and/or clean the SDRAM location? If I am using DSP/BIOS OS, how can I disable caching? Thanks for your help. Att., Juan A. Torres-Rosario --- wrote: > In a message dated 3/3/2004 11:35:07 AM Eastern > Standard Time, > writes: > Hi KAnand, > > Thanks for your help :). I have modified my code so > that the EDMA Channel's opt TCC has a particular > channel (2), cleared the CIPR before configuring the > channel, and testing the channel after I perform the > transfer. When I test the channel, the CIPR bit has > been set, meaning that the EDMA Transfer was > completed. The problem is that when I check the > memory > location of the destination buffer, it does not have > the content of the source buffer as if no transfer > was > made. My variables (source and destination buffers) > are been stored in the SDRAM. I have read the EDMA > part on "spru190d" file, which deals with the > peripherals, and quite understand how the EDMA > works. > Is there any other parameter I am supposed to set > for > asynchronous transfer? Is asynchronous transfer > reliable? > > Code: > Hi! > I bet that this is a caching problem! > You nead to do a cache Flush and/or Clean on the > SDRAM location to which you > are trying to do this transfer. > I also bet that if you changed your buffer location > to On Chip memory (I > assume you have at least one bank available) or, > even better, disable caching, > just for testing, and rerun your test, then you > should find the correct data in > the buffer. > > Hope this helps. > Regards, > /Khalid > __________________________________ |
Reply by ●March 6, 20042004-03-06
In a message dated 3/4/2004 10:26:26 AM Eastern Standard Time, writes: Hi khalida1: You hitted right on the spot!!! When I changed my variables to the INTERNAL Memory (L2 CACHE), the transfer was really made. As of your solutions for SDRAM, What do you mean by Cache Flush. How can I do a Cache Flush and/or clean the SDRAM location? If I am using DSP/BIOS OS, how can I disable caching? Thanks for your help. Att., Juan A. Torres-Rosario --- wrote: > In a message dated 3/3/2004 11:35:07 AM Eastern > Standard Time, > writes: > Hi KAnand, > > Thanks for your help :). I have modified my code so > that the EDMA Channel's opt TCC has a particular > channel (2), cleared the CIPR before configuring the > channel, and testing the channel after I perform the > transfer. When I test the channel, the CIPR bit has > been set, meaning that the EDMA Transfer was > completed. The problem is that when I check the > memory > location of the destination buffer, it does not have > the content of the source buffer as if no transfer > was > made. My variables (source and destination buffers) > are been stored in the SDRAM. I have read the EDMA > part on "spru190d" file, which deals with the > peripherals, and quite understand how the EDMA > works. > Is there any other parameter I am supposed to set > for > asynchronous transfer? Is asynchronous transfer > reliable? > > Code: > Hi! > I bet that this is a caching problem! > You nead to do a cache Flush and/or Clean on the > SDRAM location to which you > are trying to do this transfer. > I also bet that if you changed your buffer location > to On Chip memory (I > assume you have at least one bank available) or, > even better, disable caching, > just for testing, and rerun your test, then you > should find the correct data in > the buffer. > > Hope this helps. > Regards, > /Khalid > Hi Juan, There are TI Chip Support Library (CSL) functions that you can call to Clean the cache memory. Just search the help from Code Composer for cache clean and you should be able to find the exact call. You basically pass the SDRAM buffer address and the buffer size as the parameters for this function call. You'll have to do so before every transfer, therefore it is probably best that you set your receive buffer in INTERNAL memory and after each transfer is completed you then copy the data from INTERNAL to SDRAM memory. Glad that I can help. Regards, /Khalid |