XMC4500 VADC - DMA usage

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

cross mob
lock attach
Attachments are accessible only for community members.
User8734
Level 4
Level 4
Good day,

I plan to use DMA to transfer data from ADC.

ADC working, I see data in GLOBRES.
According xmc4500_rm_v1.4_2014_04, DLR_SRSEL, DLR_LNEN registers shall be programmed
such a way to DMA get, as example, VADC.C0SR0 Service Request.

No DAVE "DLR" Application found, so supposed these registers shall be programmed manually.

Question is, on what conditions such Service Requests generated?

In doc's (see attached) I see 20 possibilities:
VADC.C0SRx (where x=0..3) for ADC Common Block as well as
VADC.GySRx (where y=0..3 for ADC Groups; where x=0..3 for?)

I found nothing unfortunately in xmc4500_rm_v1.4_2014_04.pdf

My suspiction is, that SRGEN flags shall be activated,
but they exists in: GLOBRCR for GLOBRES (VADC common, I suspect)
and as well in VADC.GyRCRx (where y=0..3 for ADC Groups; where x=0..15 for 16 result registers),
so respectivly will be 1+16*4 = 65 possibilities.

Please clarify.

Thanks in advance,
Konstantin
0 Likes
17 Replies
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
Hi Konstantin,

After you have created a ADC result interrupt you can link this triggering signal to the DMA app.

Select hardware trigger and Peripheral-Memory for DMA002 app.

666.attach

Signal connection of ADC result interrupt signal to trigger DMA transfer.

667.attach


Best Regards
Travis
0 Likes
User8734
Level 4
Level 4
Good day Travis,

Thanks a lot, it is working now.

But, must I use NVIC002 IRQ each time i have a result in VADC GLOBRES?!?
I suppose VADC shall trigger DMA directly through DLR,
for transferring VADC result to memory,
and call IRQ only after DMA block transfer is completed.

But looks like I have no option to make "Signal Connection" from ADC002 to DMA002 directly:(

Best regards,
Konstantin
0 Likes
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
XmCfAn2014 wrote:
Good day Travis,

Thanks a lot, it is working now.

But, must I use NVIC002 IRQ each time i have a result in VADC GLOBRES?!?
I suppose VADC shall trigger DMA directly through DLR,
for transferring VADC result to memory,
and call IRQ only after DMA block transfer is completed.

But looks like I have no option to make "Signal Connection" from ADC002 to DMA002 directly:(

Best regards,
Konstantin


Hi Konstantin,

Yes, VADC interrupt signal will trigger DMA directly throught DLR. That is why the NVIC002 app (ADC ISR signal) is used to interlink to the DMA. Maybe there is no need to provide a ADC_ISR function.

DMA block transfer completed ISR can be created with a separate interrupt.

Best Regards
Travis
0 Likes
User8734
Level 4
Level 4
Good day Travis,

Thanks for clarification.
Really DMA still working, even when ISR not defined for NVIC002!
Somehow it is tricky for me,, but::!!

So now I get only ISR defined in NVIC_DMA001 after DMA transfer is finished,
as was planned.:):):)

BR
K
0 Likes
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
Hi Konstantin,

Can you share this example so that others will have the chance to know how to do a hardware trigger for DMA?

Best Regards
Travis
0 Likes
User8734
Level 4
Level 4
Good day Travis,

Yes, shure. My HW - Hexagon Application Kit XMC4500 series
(Shall be choosen in Debug Configurations).

675.attach 676.attach

I use standard ADC001_Example1, adding DMA003 & NVIC002 to it.
In this example VADC0 samples voltage on P14.1, which connected to on-board potentiometer.
Result stored in GLOBRES (0x40004300).
So my addition to example transfer it continiously into memory region
(0x30000000) using DMA.

Important settings shown on pictures attached.

677.attach 678.attach
674.attach

BR
K
0 Likes
User8734
Level 4
Level 4
Good day,

Below my ISR used after DMA block transfer finished.

void DMA_End_Transfer(DMA_IRQType DMA_IRQ_TFR, uint32_t cb_arg)
{

// DMA003_Init(); //May be used instead of all below,,, but it is excessive...

const DMA003_ChannelHandleType* Handle;
Handle = &DMA003_Handle0;
GPDMA0_GLOBAL_TypeDef* DMARegs = Handle->DMARegs;
GPDMA0_CH_TypeDef* DMAChRegs = Handle->DMAChRegs;
uint8_t Channel = Handle->ChannelID;
uint32_t DMA = (uint32_t)(1UL << Channel);

/* Reload Src. & Dest. & LLP registers */
DMAChRegs->SAR = (uint32_t) Handle->ChConfig.SrcAddress; //Not changed by DMA
DMAChRegs->DAR = (uint32_t) Handle->ChConfig.DstAddress; //Changed after DMA block transfer
DMAChRegs->LLP = (uint32_t) 0x00000000; //for multi-block chaining

/* Clear DMA flags */
DMARegs->CLEARTFR = DMA;
DMARegs->CLEARBLOCK = DMA; //Not changed in my config
DMARegs->CLEARSRCTRAN = DMA; //Not changed in my config
DMARegs->CLEARDSTTRAN = DMA; //Not changed in my config
DMARegs->CLEARERR = DMA; //Not changed in my config

/* Finally Enable CHENREG */
DMARegs->CHENREG = DMA_CH_NUM(Channel);

}

On picture - values in memory and DLR configuration. By red shown changed values,
as VADC LSB affected by noise. 12-bit result take 2 bytes in reverse notation.
Other words, 50 09 means actually 0950(hex) = 2384 (dec)
and may be easily changed by rotating potentiometer!

DLR settings for GPDMA1 CH2. Interesting to note that registers
may be reconfigured "on fly" in debugging mode,
right-mouse click -> change value.


BR
K
0 Likes
User8734
Level 4
Level 4
Good day,

As well interesting compare GPDMA1 registers before and after DMA transfer:

Seen that after DMA transfer RAWxx flags set, and STATUSINT, which trigger ISR as well.
But, CHENREG expected to be 0x004 before DMA transfer, but it is don't, on some reason.
Accoring DOC's it shall be cleared by HW only after DMA transfer is finished.

I try set breaking point just after line
DMARegs->CHENREG = DMA_CH_NUM(Channel);

in DMA ISR, where it shall be set - no result.
But looks like in reality it is set meanwhile, overwise DMA will not working.

I am only able get 0x4 there by chance, when no SignalConnection between NVIC002 and DMA003
was established (Before Travis advice) and DMA was not operational.

BR
K
0 Likes
User8734
Level 4
Level 4
Comparing GPDMA1_CH2 registers before and after transfer shows
that DAR (Destination Address) changed from beginning (0x30000000)
to next byte from end (0x30000800) of used memory area.
(I suppose it is done for multi-block chaining transfer.)
So what is why it must be reloaded after DMA block transmission complete.
0 Likes
Not applicable
Where do you place the function void DMA_End_Transfer(DMA_IRQType DMA_IRQ_TFR, uint32_t cb_arg) ? What did you do in your main program to let it work?

When I try to build the project I get the following error:

Dave/Generated/src/DMA003/DMA003_Conf.o:(.data+0x2c): undefined reference to `DMA_End_Transfer'
collect2.exe: error: ld returned 1 exit status
make: *** [ADC_DMA_TRY.elf] Error 1


Thanks in advice
0 Likes
lock attach
Attachments are accessible only for community members.
Not applicable
Nevermind about this error. I managed to solve this error. But now it seems that I have a problem in my program when I'm debugging.

It seems like I don't get an interrupt from the ADC001.

This is my main program:
#include //Declarations from DAVE3 Code Generation (includes SFR declaration)

ADC001_ResultHandleType Result;

void DMA_End_Transfer(DMA_IRQType DMA_IRQ_TFR, uint32_t cb_arg)
{

// DMA003_Init();

const DMA003_ChannelHandleType* Handle;
Handle = &DMA003_Handle0;
GPDMA0_GLOBAL_TypeDef* DMARegs = Handle->DMARegs;
GPDMA0_CH_TypeDef* DMAChRegs = Handle->DMAChRegs;
uint8_t Channel = Handle->ChannelID;
uint32_t DMA = (uint32_t)(1UL << Channel);

/* Reload Src. & Dest. & LLP registers */
DMAChRegs->SAR = (uint32_t) Handle->ChConfig.SrcAddress; //Not changed by DMA
DMAChRegs->DAR = (uint32_t) Handle->ChConfig.DstAddress; //Changed after DMA block transfer
DMAChRegs->LLP = (uint32_t) 0x00000000; //for multi-block chaining

/* Clear DMA flags */
DMARegs->CLEARTFR = DMA;
DMARegs->CLEARBLOCK = DMA; //Not changed in my config
DMARegs->CLEARSRCTRAN = DMA; //Not changed in my config
DMARegs->CLEARDSTTRAN = DMA; //Not changed in my config
DMARegs->CLEARERR = DMA; //Not changed in my config

/* Finally Enable CHENREG */
DMARegs->CHENREG = DMA_CH_NUM(Channel);

}


int main(void)
{
// status_t status; // Declaration of return variable for DAVE3 APIs (toggle comment if required)


DAVE_Init(); // Initialization of DAVE Apps

//DMA003_StartTransfer(&DMA003_Handle0);

/* Generate Load Event*/
ADC001_GenerateLoadEvent(&ADC001_Handle0);
DMA003_StartTransfer(&DMA003_Handle0);

while(1)
{

}

return 0;
}

void GlobalResultEvent(void)
{
/* Read the Result Register*/
ADC001_GetResult(&ADC001_Handle0,&Result);

}


Any help is welcome. My goal is trying to get an ADC working who reads in 16 different values (for multiple times), sends the result to the DMA and than calculate the average of every value that was read in multiple times
0 Likes
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
I just make a quick review of your software. I think your did not declare the interrupt handler in the NVIC app.


1276.attach
0 Likes
Not applicable
Hi Travis,

I'm developing a handheld instrument with DAVE3 based on the XMC4500 relax board. This instrument has an USB, SDCard, and Seggar-driven GUI display and interfaces with an analog board using the Relax pin headers. The most important part is a high-speed analog input that collects 2us samples from P14.0 using ADC002, DMA002 and 2us analog triggering using PWMSP001 and NVIC002 apps.

I recently downloaded the "xmc4500_DMA002.zip" example from this forum and got it working to prove the technique works. But when I attempted to implement this technique from scratch in a small firmware application using the current versions for each of the Dave3 Apps, everything appears to work, except that only zeros come across in the raw and processed ADC result arrays.

Do you have any advice in getting the DMA002 data coming in from ADC002?

Thanks,

Dan Griffing
0 Likes
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
Dan Griffing wrote:

But when I attempted to implement this technique from scratch in a small firmware application using the current versions for each of the Dave3 Apps, everything appears to work, except that only zeros come across in the raw and processed ADC result arrays.

Do you have any advice in getting the DMA002 data coming in from ADC002?

Thanks,

Dan Griffing


Do you mean that you are reading zeros? If that is the case you have to check your assigned result register for the ADC and be sure that you had DMA from the correct Source address.

However DMA is meant for mass data transfer and it might not make sense for you just to transfer only a word (32bit) data to the destination. It would be better that you make use of the ADC result interrupt.
0 Likes
Not applicable
Hi Travis,
I will also use the DMA to transfer very fast ADC-Channel-Results. Therefore I used the example xmc4500_DMA002.zip. from this forum:

http://www.infineonforums.com/threads/653-Changing-configuration-of-DMA002


I had the same problem which Dan Griffing wrote above.

“I recently downloaded the "xmc4500_DMA002.zip" example from this forum and got it working to prove the technique works. But when I attempted to implement this technique from scratch in a small firmware application using the current versions for each of the Dave3 Apps, everything appears to work, except that only zeros come across in the raw and processed ADC result arrays.”

I checked the ADC result register. The ADC result register is not zero but the DMA-Buffer-Value is zero?
@ Travis: Can you update the xmc4500_DMA002.zip example with the current versions of the Dave3-Apps?

Thanks,

Johannes
0 Likes
Not applicable
Hi Travis,
I will also use the DMA to transfer very fast ADC-Channel-Results. Therefore I used the example xmc4500_DMA002.zip. from this forum:
http://www.infineonforums.com/threads/653-Changing-configuration-of-DMA002
I had the same problem which Dan Griffing wrote above.
“I recently downloaded the "xmc4500_DMA002.zip" example from this forum and got it working to prove the technique works. But when I attempted to implement this technique from scratch in a small firmware application using the current versions for each of the Dave3 Apps, everything appears to work, except that only zeros come across in the raw and processed ADC result arrays.”

I checked the ADC-Result-Register. The ADC-Value is not zero but the DMA-Buffer-Value is zero?
@ Travis: Can you update the xmc4500_DMA002.zip example with the current versions of the Dave3-Apps?

Thanks,
Johannes
0 Likes
Not applicable
Hi Travis,
I will also use the DMA to transfer very fast ADC-Channel-Results. Therefore I used the example xmc4500_DMA002.zip. from this forum:
http://www.infineonforums.com/threads/653-Changing-configuration-of-DMA002

I had the same problem which Dan Griffing wrote above.
“I recently downloaded the "xmc4500_DMA002.zip" example from this forum and got it working to prove the technique works. But when I attempted to implement this technique from scratch in a small firmware application using the current versions for each of the Dave3 Apps, everything appears to work, except that only zeros come across in the raw and processed ADC result arrays.”

I checked the ADC-Result-Register. The ADC-Value is not zero but the DMA-Buffer-Value is zero?
@ Travis: Can you please update the xmc4500_DMA002.zip example with the current versions of the Dave3-Apps?

Thanks,

Johannes
0 Likes