how to determine "BTSIZE" filed of DMAC control A register?

Discussion around products based on ARM Cortex-A5 core.

Moderator: nferre

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

how to determine "BTSIZE" filed of DMAC control A register?

Wed Oct 26, 2016 11:51 am

Hi,all.i face a problem. when i declare buffer as "uint16_t dmabuffer[1024]",how to set DMAC control A register‘s BTSIZE filed? i set as follow:

Code: Select all

sizeof( dmabuffer )
am i correct?Thanks for your reply!
blue_z
Location: USA
Posts: 1509
Joined: Thu Apr 19, 2007 10:15 pm

Re: how to determine "BTSIZE" filed of DMAC control A regist

Thu Oct 27, 2016 2:04 am

leo.ni wrote:Hi,all.i face a problem. when i declare buffer as "uint16_t dmabuffer[1024]",how to set DMAC control A register‘s BTSIZE filed? i set as follow:

Code: Select all

sizeof( dmabuffer )
am i correct?!
No, you are not correct (and are ambiguous and have bad spelling).
This size is in the units of the transfer, and is not a byte count.

Additionally, you only present a snippet of code with no context whatsoever.
In the worst-case scenario (which is highly probable), this expression will always evaluate to the value 4.

So is the "problem" related to getting too much or too little data?

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

Re: how to determine "BTSIZE" filed of DMAC control A regist

Thu Oct 27, 2016 2:37 am

Thanks!my dma operate function as follow:

Code: Select all

uint8_t ssc0_buffer_read( void *pInstance,const uint8_t *buf,uint32_t len )
{ 
        assert( NULL != pInstance );
		
	DataSource *pSource = (DataSource *)pInstance;
	sDmaTransferDescriptor *pTds = dmaTdSSC0Rx;
        
        Ssc* pSsc = _get_ssc_instance( pSource->dev.identify );
        
        pTds[0].dwSrcAddr = ( uint32_t )&SSC0->SSC_RHR;
        pTds[0].dwDstAddr = ( uint32_t )buf; 
        pTds[0].dwCtrlA   = DMAC_CTRLA_BTSIZE( len >> 1 )
                               | DMAC_CTRLA_SRC_WIDTH_HALF_WORD 
                               | DMAC_CTRLA_DST_WIDTH_HALF_WORD;          
        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 )&SSC0->SSC_RHR;
        pTds[1].dwDstAddr = ( uint32_t )( buf + ( sizeof( ssc0_PingPongIn ) >> 1 ) ); 
        pTds[1].dwCtrlA   = DMAC_CTRLA_BTSIZE( len >> 1 )
                               | DMAC_CTRLA_SRC_WIDTH_HALF_WORD 
                               | DMAC_CTRLA_DST_WIDTH_HALF_WORD;          
        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, pSource->dev.rxDMAChannel, dmaTdSSC0Rx );
        DMAD_StartTransfer(&g_dmad, pSource->dev.rxDMAChannel);
        
        SSC_EnableReceiver(pSsc); 
        
        return 0;
}

and i declare buffer :

Code: Select all

uint16_t ssc0_PingPongIn[2][ 4096 ] ;
in app layer, i call ssc0_buffer_read as follow:

Code: Select all

source_ssc0.buffer_read( &source_ssc0,( uint8_t * )ssc0_PingPongIn,
                                    sizeof( ssc0_PingPongIn ) >> 1);
Please give me some advise,blue_z.Thank again!
blue_z
Location: USA
Posts: 1509
Joined: Thu Apr 19, 2007 10:15 pm

Re: how to determine "BTSIZE" filed of DMAC control A regist

Fri Oct 28, 2016 2:21 am

leo.ni wrote:Please give me some advise,
You didn't answer my simple question, and you haven't stated what the problem is.
So I will only comment on how poorly the code is structured.

There's no reason to declare the buffer as uint16_t, and then confusingly use it as uint8_t.
You use a magic number for the array size.

Code: Select all

        pTds[1].dwDstAddr = ( uint32_t )( buf + ( sizeof( ssc0_PingPongIn ) >> 1 ) );
This is a horrible blend of an argument and the attribute of a global(?) array.
The function has been passed a "length", but you don't bother to use it here.

You overuse sizeof() and right shifts to obscure what's going on.

If I had to write this code the first thing is to declare a macro for the number of elements.

Code: Select all

#define NELEMENTS  4096
 ...
uint16_t ssc0_PingPongIn[2 * NELEMENTS];    /* double buffer */
The function prototype becomes

Code: Select all

uint8_t ssc0_buffer_read(void *pInstance, const uint16_t *dbuf, uint32_t halfcount);
So an example of a call would be

Code: Select all

source_ssc0.buffer_read(&source_ssc0, ssc0_PingPongIn, NELEMENTS);
Salient statements in the function become:

Code: Select all

 ...
       pTds[0].dwDstAddr = (uint32_t)dbuf;   /* 1st half of double buffer */
       pTds[0].dwCtrlA   = DMAC_CTRLA_BTSIZE(halfcount)
                               | DMAC_CTRLA_SRC_WIDTH_HALF_WORD 
                               | DMAC_CTRLA_DST_WIDTH_HALF_WORD;          
 ...        
        pTds[1].dwDstAddr = (uint32_t)(dbuf + halfcount);   /* latter half of double buffer */
        pTds[1].dwCtrlA   = DMAC_CTRLA_BTSIZE(halfcount)
                               | DMAC_CTRLA_SRC_WIDTH_HALF_WORD 
                               | DMAC_CTRLA_DST_WIDTH_HALF_WORD;          
 ... 
leo.ni
Posts: 52
Joined: Mon Jun 06, 2016 4:20 am

Re: how to determine "BTSIZE" filed of DMAC control A regist

Fri Oct 28, 2016 2:42 am

Thanks! i'm sorry i didn't tell you about my problem clear. i played sound via ssc,but sound isn't correct.and i found it relate about follow code:

Code: Select all

        pTds[0].dwDstAddr = ( uint32_t )buf; 
        pTds[0].dwCtrlA   = DMAC_CTRLA_BTSIZE( len >> 1 )
my dma callback function as this:

Code: Select all

void _SSC0_DmaRxCallback( uint8_t status, void *pArg)
{    
    assert( NULL != pArg );
    
    uint32_t temp;
    INT8U error;
    
    DataSource *pSource = ( DataSource *)pArg;
      
     /*step 1:calculate buffer space */ 
     temp = kfifo_get_free_space( pSource->pRingBulkIn );

     /*step 2:merge buffer according condition */  
     if(  temp >= pSource->warmWaterLevel * 2 )
     {      
              kfifo_put( pSource->pRingBulkIn,
                  ( uint8_t * )&pSource->pBufferIn[ pSource-> rx_index ],  //here, push data from double buffer to ring buffer 
                  pSource->rxSize );                                                         //rx_index is the double buffer index 0 or 1
                                                                                                      //rxSize is half part of double buffer.

       pSource->rx_index = 1 - pSource->rx_index;
     }    
     
}
i'll edit my code as you said and feedback.Thanks again,blue_z!
leo.ni
Posts: 52
Joined: Mon Jun 06, 2016 4:20 am

Re: how to determine "BTSIZE" filed of DMAC control A regist

Fri Nov 25, 2016 5:21 am

Thanks, blue_z! i see now.This is changed according byte,half-word or word .Thanks again!

Return to “SAMA5D Cortex-A5 MPU”

Who is online

Users browsing this forum: No registered users and 1 guest