MPC5634M eDMA to eQADC to RAM

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

MPC5634M eDMA to eQADC to RAM

跳至解决方案
2,070 次查看
AndreiC
Contributor III

This shouldn't be difficult, but I've spent a few weeks on it, am getting nowhere and the next step isn't pretty.

I'm trying to use DMA to take a list of ADC commands, DMA them into CFIFO, and DMA the results from RFIFO into RAM.

It should work, but it doesn't. I get the end of queue interrupt, but the results have never managed to make it out of the RFIFO into RAM.

From this, I can assume that the ADC is being fed, but not emptied.

Many things could be wrong, I could be missing a command, the S32DS may have a bug, there could be a silicon bug. At this point I have no idea at all.

I'm using the latest S32DS and a TRK-MPC5634M, all NXP off the shelf, nothing custom.

Attached is a minimal project that shows the problem.

标签 (1)
0 项奖励
回复
1 解答
1,984 次查看
davidtosenovjan
NXP TechSupport
NXP TechSupport

Founded.

I have redefined result as 32-bit words and your example is working fine.

pastedImage_1.png

What you have wrong is that you are reading MSB half of result register, that’s the reason of zeros. I have never used 16-bit result reads but according to documentation it should be possible.

 

Changed to following:

 
uint32_t triggeredADCResults[4];                                                                                                                                                                                                                                                                                                
 
            /*
             * Set up the DMA transfer to push ADC results into the results array
             */
            EDMA.TCD[1].SADDR = (vuint32_t) &(EQADC.RFPR[0].R);                                 /* Source address, the ADC results FIFO */
            EDMA.TCD[1].SSIZE = EDMA_SIZE_32_BIT;                                                                  /* Each command is 16-bits wide */
            EDMA.TCD[1].SOFF = 0;                                                                                                              /* After a result is transfered, don't increment the source address */
            EDMA.TCD[1].SLAST = 0;                                                                                                            /* Once the result queue has been transfered, don't back up to the source pointer */
            EDMA.TCD[1].SMOD = 0;                                                                                                             /* We aren't going to use the modulo ability, since we can't really place the command array at a 2**n address easily */

            EDMA.TCD[1].DADDR = (vuint32_t) triggeredADCResults;            /* Transfer into the results array */
            EDMA.TCD[1].DSIZE = EDMA_SIZE_32_BIT;
            EDMA.TCD[1].DOFF = 4;                                                                                                              /* Don't increment the destination pointer */
            EDMA.TCD[1].DLAST_SGA = (vint32_t) -16;                                                                     /* When all results are transfered, back up the destination pointer to the top of the array */
            EDMA.TCD[1].DMOD = 0;

            EDMA.TCD[1].NBYTES = 4;                                                                                                         /* Transfer 2 bytes at a time. */
            EDMA.TCD[1].BITER = 4;                                                                                                             /* The number of transfers to do in a full transaction */
            EDMA.TCD[1].CITER = 4;                                                                                                             /* P.174 says this must be the same as biter */

            EDMA.TCD[1].BITERE_LINK = 0;                                                                                      /* no interchannel linking needed */
            EDMA.TCD[1].CITERE_LINK = 0;
            EDMA.TCD[1].MAJORE_LINK = 0;
            EDMA.TCD[1].MAJORLINKCH = 0;

            EDMA.TCD[1].D_REQ = 0;                                                                                                           /* Keep the DMA channel open once all commands have been transfered. */
            EDMA.TCD[1].INT_HALF = 0;                                                                                                       /* Don't Give me an interrupt when half of the commands were sent */
            EDMA.TCD[1].INT_MAJ = 0;                                                                                              /* Don't Give me an interrupt when all of the commands are finished being sent */
            EDMA.TCD[1].E_SG = 0;                                                                                                              /* Don't use scatter/gather */
            EDMA.TCD[1].BWC = 0;                                                                                                               /* No bandwith control */

            EDMA.TCD[1].START = 0;                                                                                                            /* Don't start quite yet */
            EDMA.TCD[1].DONE = 0;                                                                                                             /* Not finshed yet */
            EDMA.TCD[1].ACTIVE = 0;                                                                                                          /* Not active yet either */

在原帖中查看解决方案

0 项奖励
回复
2 回复数
1,985 次查看
davidtosenovjan
NXP TechSupport
NXP TechSupport

Founded.

I have redefined result as 32-bit words and your example is working fine.

pastedImage_1.png

What you have wrong is that you are reading MSB half of result register, that’s the reason of zeros. I have never used 16-bit result reads but according to documentation it should be possible.

 

Changed to following:

 
uint32_t triggeredADCResults[4];                                                                                                                                                                                                                                                                                                
 
            /*
             * Set up the DMA transfer to push ADC results into the results array
             */
            EDMA.TCD[1].SADDR = (vuint32_t) &(EQADC.RFPR[0].R);                                 /* Source address, the ADC results FIFO */
            EDMA.TCD[1].SSIZE = EDMA_SIZE_32_BIT;                                                                  /* Each command is 16-bits wide */
            EDMA.TCD[1].SOFF = 0;                                                                                                              /* After a result is transfered, don't increment the source address */
            EDMA.TCD[1].SLAST = 0;                                                                                                            /* Once the result queue has been transfered, don't back up to the source pointer */
            EDMA.TCD[1].SMOD = 0;                                                                                                             /* We aren't going to use the modulo ability, since we can't really place the command array at a 2**n address easily */

            EDMA.TCD[1].DADDR = (vuint32_t) triggeredADCResults;            /* Transfer into the results array */
            EDMA.TCD[1].DSIZE = EDMA_SIZE_32_BIT;
            EDMA.TCD[1].DOFF = 4;                                                                                                              /* Don't increment the destination pointer */
            EDMA.TCD[1].DLAST_SGA = (vint32_t) -16;                                                                     /* When all results are transfered, back up the destination pointer to the top of the array */
            EDMA.TCD[1].DMOD = 0;

            EDMA.TCD[1].NBYTES = 4;                                                                                                         /* Transfer 2 bytes at a time. */
            EDMA.TCD[1].BITER = 4;                                                                                                             /* The number of transfers to do in a full transaction */
            EDMA.TCD[1].CITER = 4;                                                                                                             /* P.174 says this must be the same as biter */

            EDMA.TCD[1].BITERE_LINK = 0;                                                                                      /* no interchannel linking needed */
            EDMA.TCD[1].CITERE_LINK = 0;
            EDMA.TCD[1].MAJORE_LINK = 0;
            EDMA.TCD[1].MAJORLINKCH = 0;

            EDMA.TCD[1].D_REQ = 0;                                                                                                           /* Keep the DMA channel open once all commands have been transfered. */
            EDMA.TCD[1].INT_HALF = 0;                                                                                                       /* Don't Give me an interrupt when half of the commands were sent */
            EDMA.TCD[1].INT_MAJ = 0;                                                                                              /* Don't Give me an interrupt when all of the commands are finished being sent */
            EDMA.TCD[1].E_SG = 0;                                                                                                              /* Don't use scatter/gather */
            EDMA.TCD[1].BWC = 0;                                                                                                               /* No bandwith control */

            EDMA.TCD[1].START = 0;                                                                                                            /* Don't start quite yet */
            EDMA.TCD[1].DONE = 0;                                                                                                             /* Not finshed yet */
            EDMA.TCD[1].ACTIVE = 0;                                                                                                          /* Not active yet either */
0 项奖励
回复
1,984 次查看
AndreiC
Contributor III

Yes, this worked.

In one of the other app notes, they mention sending 32-bit commands and pulling 16-bit results if you don't turn on time stamping.

I'm wondering if there is an endian thing that I'm stumbling over. The time stamps were being picked up rather than the data.

Oh well, I'm getting progress.

Thanks for your help on this.

A

0 项奖励
回复