problem about sama5d3 dma mode

Discussion around products based on ARM Cortex-A5 core.

Moderator: nferre

leo.ni
Posts: 52
Joined: Mon Jun 06, 2016 4:20 am

problem about sama5d3 dma mode

Mon Jun 27, 2016 12:03 pm

Hi,all! i have a problem: when i config sama5d3 dma controller work under link chain mode(datasheet 522 table31-4 row 6),can i extra set "DMAC_CTRLB_AUTO_ENABLE" bit? Thanks!
blue_z
Location: USA
Posts: 2131
Joined: Thu Apr 19, 2007 10:15 pm

Re: problem about sama5d3 dma mode

Tue Jun 28, 2016 2:02 am

leo.ni wrote:i have a problem: ...
Which you do not state.
leo.ni wrote:when i config sama5d3 dma controller work under link chain mode(datasheet 522 table31-4 row 6),can i extra set "DMAC_CTRLB_AUTO_ENABLE" bit?
You refer to a datasheet, yet mention an identifier that does not exist in the datasheet.
Presumably you are referring to DMAC_CTRLBx.AUTO?

The answer presumably would be "no".
On line 6 of that table, the first column specifies that AUTO is zero.

Presumably you are attempting to replay a linked list of buffers?
Besides the table that you referenced, there are other hints in the datasheet that such a multi-buffer setup is not possible (e.g. "Replay Mode ... registers are reloaded from their initial value at the start of a buffer transfer" and "Ending Multi-buffer Transfers ... For rows 2, 3, 4, 5, and 6 (DMAC_CRTLBx.AUTO cleared), the user must set up the last buffer descriptor in memory so that LLI.DMAC_DSCRx is set to 0)".

Regards
leo.ni
Posts: 52
Joined: Mon Jun 06, 2016 4:20 am

Re: problem about sama5d3 dma mode

Tue Jun 28, 2016 5:08 am

Thanks for your reply first! i use pingpong buffer used dma link chain mode as follow:
void recordingSSC1( Device *pInstance )
{
sDmaTransferDescriptor *pTds = Ssc1_rxLLI;

pTds[0].dwSrcAddr = ( uint32_t )&SSC1->SSC_RHR;
pTds[0].dwDstAddr = ( uint32_t )ssc1_I2SBuffersIn[ 0 ];
pTds[0].dwCtrlA = DMAC_CTRLA_BTSIZE(I2S_IN_BUFFER_SIZE)
| DMAC_CTRLA_SRC_WIDTH_BYTE
| DMAC_CTRLA_DST_WIDTH_BYTE;
pTds[0].dwCtrlB = DMAC_CTRLB_FC_PER2MEM_DMA_FC
| DMAC_CTRLB_SRC_INCR_FIXED
| DMAC_CTRLB_DST_INCR_INCREMENTING
| DMAC_CTRLB_SIF_AHB_IF2
| DMAC_CTRLB_DIF_AHB_IF0
;
pTds[0].dwDscAddr = (uint32_t) &pTds[1];

pTds[1].dwSrcAddr = ( uint32_t )&SSC1->SSC_RHR;
pTds[1].dwDstAddr = ( uint32_t )ssc1_I2SBuffersIn[ 1 ];
pTds[1].dwCtrlA = DMAC_CTRLA_BTSIZE(I2S_IN_BUFFER_SIZE)
| DMAC_CTRLA_SRC_WIDTH_BYTE
| DMAC_CTRLA_DST_WIDTH_BYTE;
pTds[1].dwCtrlB = DMAC_CTRLB_FC_PER2MEM_DMA_FC
| DMAC_CTRLB_SRC_INCR_FIXED
| DMAC_CTRLB_DST_INCR_INCREMENTING
| DMAC_CTRLB_SIF_AHB_IF2
| DMAC_CTRLB_DIF_AHB_IF0
;
pTds[1].dwDscAddr = (uint32_t) &pTds[0];

/* Enable recording(SSC RX) */
DMAD_PrepareMultiTransfer(&g_dmad, sscDmaRxChannel1, Ssc1_rxLLI);
DMAD_StartTransfer(&g_dmad, sscDmaRxChannel1);
SSC_EnableReceiver(SSC1);
}

my problem is :(1)when two buffers transfer completely, can it auto restart from first buffer?if can ,how to config it? if can't,can i reconfig the dma in interrupt serive function?
(2)which time generate a dma interrupt ?when the first buffer transfer completely or all of buffer linked transfer completely?
Thanks again!
blue_z
Location: USA
Posts: 2131
Joined: Thu Apr 19, 2007 10:15 pm

Re: problem about sama5d3 dma mode

Wed Jun 29, 2016 12:06 am

leo.ni wrote:i use pingpong buffer used dma link chain mode as follow:!
Please learn to use the code style tag so that indentation is preserved and a fixed (instead of proportional) font is used. There's a tool bar just above the text area where you edit your post.
leo.ni wrote:my problem is :(1)when two buffers transfer completely, can it auto restart from first buffer?if can ,how to config it? if can't,can i reconfig the dma in interrupt serive function?
(2)which time generate a dma interrupt ?when the first buffer transfer completely or all of buffer linked transfer completely?
A round-robin dual buffer scheme is normally easy to do with a traditional DMA controller that employs current and backup register sets for DMA operations.
But this DMAC is far more complicated and poorly documented.

The datasheet contradicts itself.
On page 544, 31.7 DMAC Software Requirements
There must not be any write operation to channel registers in an active channel after the channel enable is
made HIGH. If any channel parameters must be reprogrammed, this can only be done after disabling the
DMAC channel.
But in various places that directive is contradicted. For instance on page 523, 31.6.4.3 Ending Multi-buffer Transfers
For rows 9, 10 and 11 of Table 31-4 on page 522, (DMAC_DSCRx = 0 and DMAC_CTRLBx.AUTO is set), multi-
buffer DMAC transfers continue until the automatic mode is disabled by clearing the DMAC_CTRLBx.AUTO bit.
This bit should be programmed to zero in the end of buffer interrupt service routine that services the next-to-last
buffer transfer.
So I'm not sure what really works with this DMAC, as I haven't done any programming of this DMAC.
I can offer two schemes to try out, but no guarantee as to what will happen.

There is no explanation for rows 7 and 8 of Table 31-4. But perhaps row 8 is what you want, a replay of a linked list with interrupts after each buffer transfer.

A more promising scheme might be a linked list that links back to itself. The last link, instead of being zero, would point to the first descriptor. Note that the Descriptor Integrity Check has to be disabled, and after every buffer transfer, the DMAC_CTRLA entry of the descriptor that just finished has to be rewritten (because it was updated by the DMAC).

Regards
leo.ni
Posts: 52
Joined: Mon Jun 06, 2016 4:20 am

Re: problem about sama5d3 dma mode

Wed Jun 29, 2016 12:48 pm

Thanks again! i used row-4(table31-4) but can't switch buffer auto,i'll try row-8 acorrding to what you said,Thanks!
blue_z
Location: USA
Posts: 2131
Joined: Thu Apr 19, 2007 10:15 pm

Re: problem about sama5d3 dma mode

Wed Jun 29, 2016 9:39 pm

leo.ni wrote:Thanks again! i used row-4(table31-4) but can't switch buffer auto,i'll try row-8 acorrding to what you said,Thanks!
That might be a waste of time.
Your best chance of success is to use a linked list that links back (i.e. a ring list).
That is what is used in the SoftPack. From /Atmel/sama5d3x-ek/examples/ssc_dma_audio/main.c:

Code: Select all

    rxLLI[i-1].dwDscAddr = ((unsigned int)&rxLLI[0]);
    txLLI[i-1].dwDscAddr = ((unsigned int)&txLLI[0]);
Regards
leo.ni
Posts: 52
Joined: Mon Jun 06, 2016 4:20 am

Re: problem about sama5d3 dma mode

Thu Jun 30, 2016 3:20 am

Thanks a lot! i configured dmac as what you said:

Code: Select all

void PlayingSSC0( Device *pInstance )
{        
        sDmaTransferDescriptor *pTds = Ssc0_txLLI;
        
//        memset( ssc0_I2SBuffersOut, 0x5555, sizeof( ssc0_I2SBuffersOut ));
        memset( ( void * )ssc0_I2SBuffersOut[ 0 ], 0xffff,I2S_OUT_BUFFER_SIZE );
        memset( ( void * )ssc0_I2SBuffersOut[ 1 ], 0x00,I2S_OUT_BUFFER_SIZE );
        
		/* Setup TD list for TX */
                pTds[0].dwSrcAddr = (uint32_t) ssc0_I2SBuffersOut[ 0 ];

                
		pTds[0].dwDstAddr = (uint32_t)	&SSC0->SSC_THR;

                pTds[0].dwCtrlA  = DMAC_CTRLA_BTSIZE( I2S_OUT_BUFFER_SIZE )

						  | DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_BYTE;
		pTds[0].dwCtrlB   = 0
						  | DMAC_CTRLB_SIF_AHB_IF0
						  | DMAC_CTRLB_DIF_AHB_IF2
						  | DMAC_CTRLB_FC_MEM2PER_DMA_FC
						  | DMAC_CTRLB_SRC_INCR_INCREMENTING
						  | DMAC_CTRLB_DST_INCR_FIXED
                                                  | DMAC_CTRLB_SRC_DSCR
                                                  | DMAC_CTRLB_AUTO_ENABLE
                                                  ;
		pTds[0].dwDscAddr = (uint32_t) &pTds[1];

                pTds[0].dwSrcAddr = (uint32_t) ssc0_I2SBuffersOut[ 1 ];

		pTds[1].dwDstAddr = (uint32_t)	&SSC0->SSC_THR;

                pTds[1].dwCtrlA   = DMAC_CTRLA_BTSIZE( I2S_OUT_BUFFER_SIZE )

						  | DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_BYTE;
		pTds[1].dwCtrlB   = 0
						  | DMAC_CTRLB_SIF_AHB_IF0
						  | DMAC_CTRLB_DIF_AHB_IF2
						  | DMAC_CTRLB_FC_MEM2PER_DMA_FC
						  | DMAC_CTRLB_SRC_INCR_INCREMENTING
						  | DMAC_CTRLB_DST_INCR_FIXED
                                                  | DMAC_CTRLB_SRC_DSCR
                                                  | DMAC_CTRLB_AUTO_ENABLE
                                                  ;
		pTds[1].dwDscAddr = (uint32_t) &pTds[0];
		CP15_coherent_dcache_for_dma ((uint32_t)pTds, ((uint32_t)pTds) + sizeof(pTds));

                CP15_coherent_dcache_for_dma ((uint32_t)&ssc0_I2SBuffersOut[0], ((uint32_t)(&ssc0_I2SBuffersOut[0]) + I2S_OUT_BUFFER_SIZE ));
                CP15_coherent_dcache_for_dma ((uint32_t)&ssc0_I2SBuffersOut[1], ((uint32_t)(&ssc0_I2SBuffersOut[1]) + I2S_OUT_BUFFER_SIZE ));
               
                DMAD_PrepareMultiTransfer(&g_dmad,sscDmaTxChannel, Ssc0_txLLI);
                DMAD_StartTransfer(&g_dmad, sscDmaTxChannel);

                SSC_EnableTransmitter( SSC0 );
}
now,but dma can't work.Can you give me some advise again? Thanks!
blue_z
Location: USA
Posts: 2131
Joined: Thu Apr 19, 2007 10:15 pm

Re: problem about sama5d3 dma mode

Fri Jul 01, 2016 1:41 am

leo.ni wrote:now,but dma can't work.
That's not a helpful description or failure analysis of what is wrong.
Did you check the DMA and SSC registers (e.g. status) for clues?

A quick glance at your code indicates that you're enabling the AUTO bit in CtrlB, which is incorrect for row 6 operation.
The SRC_DSCR bit is also enabled. That will inhibit the fetch of the source buffer address from the linked list, which nullifies its use.
Look at the DMA code example in the SoftPack for guidance.

Regards
leo.ni
Posts: 52
Joined: Mon Jun 06, 2016 4:20 am

Re: problem about sama5d3 dma mode

Fri Jul 01, 2016 3:04 am

Thanks a lot! i removed those bits and ssc0 transmit data appear,but it was NOT a continuous stream of data.i set ssc0 to loop mode,and enable receive and transmit,it can entry transmit dma callback function but can't entry receive dma callback function.Can you help me ? by the way,if i want to change the data in the dma buffer in dma callback function,some special proccess needed as follow?Thanks!

Code: Select all

                CP15_coherent_dcache_for_dma ((uint32_t)&ssc0_I2SBuffersOut[0], ((uint32_t)(&ssc0_I2SBuffersOut[0]) + I2S_OUT_BUFFER_SIZE ));
                CP15_coherent_dcache_for_dma ((uint32_t)&ssc0_I2SBuffersOut[1], ((uint32_t)(&ssc0_I2SBuffersOut[1]) + I2S_OUT_BUFFER_SIZE ));
leo.ni
Posts: 52
Joined: Mon Jun 06, 2016 4:20 am

Re: problem about sama5d3 dma mode

Fri Jul 01, 2016 9:12 am

The problem that my program can't entry receive dma channel callback function,my code as follow:

Code: Select all

void recordingSSC0( Device *pInstance )
{ 
        sDmaTransferDescriptor *pTds = Ssc0_rxLLI;
        
        Ssc0_rxLLI[0].dwSrcAddr = ( uint32_t )&SSC0->SSC_RHR;
        Ssc0_rxLLI[0].dwDstAddr = ( uint32_t )ssc0_I2SBuffersIn[ 0 ]; 
        Ssc0_rxLLI[0].dwCtrlA   = DMAC_CTRLA_BTSIZE(I2S_IN_BUFFER_SIZE)
                             | DMAC_CTRLA_SRC_WIDTH_BYTE
                             | DMAC_CTRLA_DST_WIDTH_BYTE;
        Ssc0_rxLLI[0].dwCtrlB   = DMAC_CTRLB_FC_PER2MEM_DMA_FC
                             | DMAC_CTRLB_SRC_INCR_FIXED
                             | DMAC_CTRLB_DST_INCR_INCREMENTING
                             | DMAC_CTRLB_SIF_AHB_IF2
                             | DMAC_CTRLB_DIF_AHB_IF0
                             ;      
        Ssc0_rxLLI[0].dwDscAddr = (uint32_t) &Ssc0_rxLLI[1];
        
        Ssc0_rxLLI[1].dwSrcAddr = ( uint32_t )&SSC0->SSC_RHR;
        Ssc0_rxLLI[1].dwDstAddr = ( uint32_t )ssc0_I2SBuffersIn[ 1 ]; 
        Ssc0_rxLLI[1].dwCtrlA   = DMAC_CTRLA_BTSIZE(I2S_IN_BUFFER_SIZE)
                             | DMAC_CTRLA_SRC_WIDTH_BYTE
                             | DMAC_CTRLA_DST_WIDTH_BYTE;
        Ssc0_rxLLI[1].dwCtrlB   = DMAC_CTRLB_FC_PER2MEM_DMA_FC
                             | DMAC_CTRLB_SRC_INCR_FIXED
                             | DMAC_CTRLB_DST_INCR_INCREMENTING
                             | DMAC_CTRLB_SIF_AHB_IF2
                             | DMAC_CTRLB_DIF_AHB_IF0
                             ;      
        Ssc0_rxLLI[1].dwDscAddr = (uint32_t) &Ssc0_rxLLI[0];
               
        /* Enable recording(SSC RX) */
        DMAD_PrepareMultiTransfer(&g_dmad, sscDmaRxChannel, Ssc0_rxLLI);
        DMAD_StartTransfer(&g_dmad, sscDmaRxChannel);
        SSC_EnableReceiver(SSC0);          
}
when i debug step by step,at line "DMAD_StartTransfer(&g_dmad, sscDmaRxChannel);",DMAC0_CHSR has no change(my received dma channel is 1,but bit ENA1 of DMAC0_CHSR is 0 ),Please help me,Thanks!
blue_z
Location: USA
Posts: 2131
Joined: Thu Apr 19, 2007 10:15 pm

Re: problem about sama5d3 dma mode

Sat Jul 02, 2016 1:27 am

Be sure to also check the DMA destination, i.e. the SSC device.
If it isn't accepting any data, then the DMAC will not try to transfer any data.

One technique of developing device handlers is to first use programmed I/O to ensure that the device interface is functional (and/or understood).
Only after that PIO version is working, is the DMA version tested.
IOW develop/test only one device at a time.

I know practically nothing about the library in the SoftPack.

Regards
leo.ni
Posts: 52
Joined: Mon Jun 06, 2016 4:20 am

Re: problem about sama5d3 dma mode

Sat Jul 02, 2016 3:03 pm

Thanks again! i'll debug it continue.
leo.ni
Posts: 52
Joined: Mon Jun 06, 2016 4:20 am

Re: problem about sama5d3 dma mode

Mon Jul 04, 2016 4:02 am

I debuged the problem of dma, that i found that if i diabled D/I cache,it can work normally.but I worry, it will not have any bad effect to my application,because DDR ram is used on my board.Can you give me some advise again?Thanks a lot!
blue_z
Location: USA
Posts: 2131
Joined: Thu Apr 19, 2007 10:15 pm

Re: problem about sama5d3 dma mode

Tue Jul 05, 2016 9:15 pm

leo.ni wrote:I debuged the problem of dma, that i found that if i diabled D/I cache,it can work normally.but I worry, it will not have any bad effect to my application,because DDR ram is used on my board.
DMA and processor cache don't work well together because of potential coherency issues. This affects any memory that both CPU and DMAC are using, so the DDR DRAM just happens to be your main memory.

If you're only using DMA for data transfers, then you can safely enable the instruction cache.
Either don't enable the data cache when also using the DMAC, or
define a memory region that is cache coherent, and allocate your buffers in that region, or
define a memory region that is not cached, and allocate your buffers in that region.
The latter two schemes require the MMU and virtual memory.

A quick look at the SoftPack documention indicates that its library does have a function named CP15_invalidate_dcache_for_dma(), which will "Invalidate the data cache within the specified region; we will be performing a DMA operation in this region and we want to purge old data in the cache. ".
See the usart_spi for an example of its use as well as a DMA callback.

Regards
leo.ni
Posts: 52
Joined: Mon Jun 06, 2016 4:20 am

Re: problem about sama5d3 dma mode

Wed Jul 06, 2016 3:36 am

Thank you very much!and you said:

Code: Select all

define a memory region that is not cached, and allocate your buffers in that region. 
How to do this?Pls give me some advise.Thanks again!

Return to “SAMA5D Cortex-A5 MPU”

Who is online

Users browsing this forum: No registered users and 2 guests