AnsweredAssumed Answered

DMA Scatter/Gather loads wrong adress in TCD

Question asked by AnEngineer on Jun 30, 2015
Latest reply on Jul 2, 2015 by jeremyzhou

Hi together,

 

I have a problem implementing the scatter/gather mechnism for the eDMA. My Processor is a MK61FN1M0VMJ15.

 

When finished the major loop, the field DLAST_SGA is added to the current DADDR.

But because of the fact, that the E_SG Bit (Enable Scatter/Gather) is set, this address should NOT be added, but the new TCD should be copied from this adress.

 

I found an errata for such a case, but I am not sure, if it is for this processor. (4N86B, e4626)

 

Following the code:

volatile uint32_t TCD_SG[] = {
      (uint32_t)&testArray, 0x02020004,
      0x00000004, 0xFFFFFFEC,
      0x80000020, 0x00050004,
      0xFFFFFFEC, 0x00050001,
   };

static int32_t testArray[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};


void InitDMA(void)
{
#ifdef __arm__
  
   // DMA Request for rising edge; Port as GPIO;
   PORTB->PCR[2] &= ~PORT_PCR_IRQC_MASK &~PORT_PCR_MUX_MASK;
   PORTB->PCR[2] = PORT_PCR_IRQC(1) | PORT_PCR_MUX(1);
   
   // Enable clock for DMAMUX and DMA
    SIM->SCGC6 |= SIM_SCGC6_DMAMUX0_MASK;
    SIM->SCGC7 |= SIM_SCGC7_DMA_MASK;
            
    // Enable Channel 0 and set PORTF (FPGA_INT#2) as DMA request source 
    DMAMUX0->CHCFG[0] |= DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(50);
   
    // Enable request signal for channel 0 
    DMA0->ERQ |= DMA_ERQ_ERQ0_MASK;// | DMA_ERQ_ERQ1_MASK;
        
    // Set memory address for source and destination 
    DMA0->TCD[0].SADDR = (uint32_t)&testArray;
    DMA0->TCD[0].DADDR = DDR_ADRESS_START;

    // Set an offset for source and destination address
    DMA0->TCD[0].SOFF = 0x04; // Source address offset per transaction
    DMA0->TCD[0].DOFF = 0x04; // Destination address offset per transaction
        
    // Set source and destination data transfer size 32bit
    DMA0->TCD[0].ATTR = DMA_ATTR_SSIZE(2) | DMA_ATTR_DSIZE(2);
        
    // Number of bytes to be transfered in each service request of the channel
    DMA0->TCD[0].NBYTES_MLNO = 0x04; // 4 Bytes pro Minor Loop
        
    // Current major iteration count (a single iteration of 5 bytes)
    DMA0->TCD[0].CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(5);
    DMA0->TCD[0].BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(5);
    
    // Adjustment value used to restore the source and destiny address to the initial value
    DMA0->TCD[0].SLAST = -0x14;           // Source address adjustment
    DMA0->TCD[0].DLAST_SGA = (uint32_t)&TCD_SG[0];    // Destination address adjustment
   
    // Setup control and status register
    DMA0->TCD[0].CSR = 0;
    DMA0->TCD[0].CSR |= DMA_CSR_ESG_MASK;

#else
#endif
}
K_MASK | DMA_CSR_MAJORLINKCH(1);

Outcomes