Multiple DMA problem

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
RuPi_283656
Level 4
Level 4
10 sign-ins First solution authored 25 replies posted

Hello. I'm having a problem with a very simple pair of DMA channels.  Call them DMA1 and DMA2.  DMA1 was created first to write the output of an ADC channel to memory, and works fine.  Later I added DMA2 and set it up exactly the same.  However DMA2 would not work, no errors but the destination memory location always contained zero.

I checked the setups carefully.  The channel number for DMA1 was 0 and 1 for DMA1.  The TD handle for DMA1 is 127 and 126 for DMA2.  There are no errors returned from any of the setup steps.  I eventually used the wizard to create code for the second DMA and it was identical to what I already had.  I had thought maybe the second channel needed some different values somewhere in the setup, but it appears not.  Both ADC's and DMA;s  and TD's have different names and memory locations.

Finally in desperation I commented out all of the code for DMA1, and DMA2 started working.  Experimenting a bit I found that as long as I did not make the ADCStartConvert call for DMA1, then DMA2 works.  I tried reversing the order so that the ADCStartConvert for DMA1 is done second, but still DMA2 is the one that fails.

So I am very unclear as to what I could be doing wrong.  I am using creator version 4.2 with a PSOC5.  Below is the setup code for both DMA's.

Thanks for any help.

Russ

// Defines for TempDma
#define TempDma_BYTES_PER_BURST 2
#define TempDma_REQUEST_PER_BURST 1
#define TempDma_SRC_BASE (CYDEV_PERIPH_BASE)
#define TempDma_DST_BASE (CYDEV_SRAM_BASE)

// Variable declarations for TempDma - These are defined globally elsewhere
// uint8 TempDma_Chan;
// uint8 TempDma_TD[1];

// DMA Configuration for TempDma
TempDma_Chan = TempDma_DmaInitialize (TempDma_BYTES_PER_BURST, TempDma_REQUEST_PER_BURST,
  HI16 (TempDma_SRC_BASE), HI16 (TempDma_DST_BASE));
TempDma_TD [0] = CyDmaTdAllocate ();
CyDmaTdSetConfiguration (TempDma_TD [0], 2, TempDma_TD [0], TD_AUTO_EXEC_NEXT);
CyDmaTdSetAddress (TempDma_TD [0], LO16 ((uint32) TempAdc_SAR_WRK0_PTR), LO16 ((uint32) &Td.TempResult));
CyDmaChSetInitialTd (TempDma_Chan, TempDma_TD [0]);
CyDmaChEnable (TempDma_Chan, 1);

TempAdc_Start ();
TempAdc_StartConvert ();


// Defines for UserAttnDma
#define UserAttnDma_BYTES_PER_BURST 2
#define UserAttnDma_REQUEST_PER_BURST 1
#define UserAttnDma_SRC_BASE (CYDEV_PERIPH_BASE)
#define UserAttnDma_DST_BASE (CYDEV_SRAM_BASE)

// Variable declarations for UserAttnDma - These are defined globally elsewhere
// uint8 UserAttnDma_Chan;
// uint8 UserAttnDma_TD[1];

// DMA Configuration for TempDma
UserAttnDma_Chan = UserAttnDma_DmaInitialize (UserAttnDma_BYTES_PER_BURST, UserAttnDma_REQUEST_PER_BURST,
  HI16 (UserAttnDma_SRC_BASE), HI16 (UserAttnDma_DST_BASE));
UserAttnDma_TD [0] = CyDmaTdAllocate ();
CyDmaTdSetConfiguration (UserAttnDma_TD [0], 2, UserAttnDma_TD [0], TD_AUTO_EXEC_NEXT);
CyDmaTdSetAddress (UserAttnDma_TD [0], LO16 ((uint32) UaAdc_SAR_WRK0_PTR), LO16 ((uint32) &Td.UserAttnResult));
CyDmaChSetInitialTd (UserAttnDma_Chan, UserAttnDma_TD [0]);
CyDmaChEnable (UserAttnDma_Chan, 1);

UaAdc_Start ();
UaAdc_StartConvert ();

0 Likes
1 Solution
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

What you can do for debugging:

- connect a pin to the DMA output pins

- connect a pin to the DMA trigger pins (which should be the the ADC EOC pins)

then use a scope or a logic analyzer to see whether they actually get triggered.

You also should test whether the second ADC really creates non-null results (e.g. sample it once per second in a loop and print it to the LCD or the serial port).

View solution in original post

0 Likes
5 Replies
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

please attach project 1. Build->Clean 2. File->Create Archive bundle->Minimal. 3. Delete Generated Source inside created zip file to save space.

0 Likes

Thanks, but I really cannot do that.  I was hoping someone had some suggestions.  Maybe someone can say if my code should work or if there is something wrong with my setup.  Just knowing if it should work would be helpful.  Otherwise I am going to have to try to create a minimal project to demo this.  I will start doing that but probably cannot get to it until Monday.

0 Likes

It would be reasonable to ask for a minimal demo if you want assistance. Will save time for communication and re-creation of the issue.

/odissey1

0 Likes
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

What you can do for debugging:

- connect a pin to the DMA output pins

- connect a pin to the DMA trigger pins (which should be the the ADC EOC pins)

then use a scope or a logic analyzer to see whether they actually get triggered.

You also should test whether the second ADC really creates non-null results (e.g. sample it once per second in a loop and print it to the LCD or the serial port).

0 Likes

Thank  you for those suggestions.  I will apply the debugging techniques and report back here.  It is likely to be middle of next week before that is completed though.

Regards, Russ

0 Likes