- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm trying to dma from ADC DelSig into memory, chained. I used the DMA tool to generate the code.
Bringing the ADC EOC out to a pin shows it is bouncing, but I never get an ISR notification of DMA complete.
I think I'm doing something wrong. Here is the code and a picture of the schematic.
Any suggestions as to what I'm doing wrong and how to fix?
Pic of the schematic under question is attached
#include <project.h>
/* Variable declarations for DMA_1 */
/* Move these variable declarations to the top of the function */
uint8 DMA_1_Chan;// the handle for this DMA unit
int finishedDMA_1; // set to 1 when the DMA is irq is triggered
uint8 DMA_1_State; // current state of the DMA unit
uint8 DMA_1_TD_InUse; // which TD is in use currently (filled in at DMA Complete interrupt)
uint8 DMA_1_TD[4];
int16 WaveForm1a[3750];
int16 WaveForm1b[3750];
int16 WaveForm2a[3750];
int16 WaveForm2b[3750];
/* DMA Configuration for DMA_1 */
#define DMA_1_BYTES_PER_BURST 2
#define DMA_1_REQUEST_PER_BURST 1
#define DMA_1_SRC_BASE (CYDEV_PERIPH_BASE)
#define DMA_1_DST_BASE (CYDEV_SRAM_BASE)
void configDMA_1() {
// init channel
DMA_1_Chan = DMA_1_DmaInitialize(DMA_1_BYTES_PER_BURST, DMA_1_REQUEST_PER_BURST,
HI16(DMA_1_SRC_BASE), HI16(DMA_1_DST_BASE));
// set up transfer descriptors
DMA_1_TD[0] = CyDmaTdAllocate();
DMA_1_TD[1] = CyDmaTdAllocate();
DMA_1_TD[2] = CyDmaTdAllocate();
DMA_1_TD[3] = CyDmaTdAllocate();
// configure td
CyDmaTdSetConfiguration(DMA_1_TD[0], 3750, DMA_1_TD[1], TD_INC_DST_ADR | TD_AUTO_EXEC_NEXT);
CyDmaTdSetConfiguration(DMA_1_TD[1], 3750, DMA_1_TD[2], TD_INC_DST_ADR | TD_AUTO_EXEC_NEXT);
CyDmaTdSetConfiguration(DMA_1_TD[2], 3750, DMA_1_TD[3], TD_INC_DST_ADR | TD_AUTO_EXEC_NEXT);
CyDmaTdSetConfiguration(DMA_1_TD[3], 3750, DMA_1_TD[0], TD_INC_DST_ADR | TD_AUTO_EXEC_NEXT);
// set addresses
CyDmaTdSetAddress(DMA_1_TD[0], LO16((uint32)ADC_DelSig_DEC_SAMP_PTR), LO16((uint32)WaveForm1a));
CyDmaTdSetAddress(DMA_1_TD[1], LO16((uint32)ADC_DelSig_DEC_SAMP_PTR), LO16((uint32)WaveForm1b));
CyDmaTdSetAddress(DMA_1_TD[2], LO16((uint32)ADC_DelSig_DEC_SAMP_PTR), LO16((uint32)WaveForm2a));
CyDmaTdSetAddress(DMA_1_TD[3], LO16((uint32)ADC_DelSig_DEC_SAMP_PTR), LO16((uint32)WaveForm2b));
// set initial td
CyDmaChSetInitialTd(DMA_1_Chan, DMA_1_TD[0]);
// enable
CyDmaChEnable(DMA_1_Chan, 1);
}
/******************************************************************************
* Function Name: DmaDone
*******************************************************************************
*
* Summary:
* Handle Interrupt Service Routine. Source - DMA.
*
******************************************************************************/
CY_ISR(DmaDone)
{
finishedDMA_1 = 1u;
// pick up current operational prameters
CyDmaChStatus( DMA_1_Chan,&DMA_1_TD_InUse, &DMA_1_State);
}
int main()
{
/* Place your initialization/startup code here (e.g. MyInst_Start()) */
ADC_DelSig_Start();
configDMA_1();
/* Setup the Interrupt connected to the nrq terminal. */
isr_DMA_1_StartEx(DmaDone);// this call takes the address of our ISR. isr_DMA_1_Start() assigns default address
ADC_DelSig_StartConvert();
CyGlobalIntEnable; /* Uncomment this line to enable global interrupts. */
for(;;)
{
/* Place your application code here. */
}
}
- Labels:
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This should be in main() and part of startup right after main( ) {
CyGlobalIntEnable; /* Uncomment this line to enable global interrupts. */
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the reply, but that did not change anything. I saw that the png file did not get included as I thought it would. Here it is:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The EOC line is transitioning, (yellow trace), but the NRQ line from the DMA unit is never transitioning (blue trace). Any suggestions?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You did not specify DMA__TD_TERMOUT_EN in Td initialization.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your DMA TDs form a loop (the last one sets the first one as next TD). So there is no condition that will end the DMA transfer, the just execute one after each other.
So each TD will transfer 3750 bytes, then the next one, and the the first one starts again. Look at AN52705 - Ping-Pong-DMA, thats exactly what you did.
For a solution to your problem: look in this thread: http://www.cypress.com/?app=forum&id=2492&rID=104670 (though it uses the SAR ADC)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That was it. I did not pick up on that meaning that nrq was enabled until I played around with the DMA Tool in PSoC creator again. I thought, from the text of the #define that it killed the transfer. DOH!
thanks! It is working now, I'm getting my ISR.
worst case,it appears to take about 6 microseconds to generate the NRQ into the ISR unit. It varies, sometimes it is less than 1 microsecond.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@hli, thanks.
Yes, I understood that. However, my problem was that NRQ was not being driven through because I did not have DMA_1__TD_TERMOUT_EN in my configuration of the DMA unit. I misunderstood what it was for. Mea culpa!
Each time I get the ISR, I grab the current TD being used, and gives my non-isr code the information it needs to determine which data set is complete. A data set is 7,500 bytes. The DMA unit can only transfer a maximum of 4096 bytes, so I split it into two parts of 3750 bytes.
I essentially have a ping-pong buffer setup to allow the code to work on one completed unit while the other unit is being filled. Hopefully that allows me to gather data without dropping any samples.
thanks again!