This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS570LC4357: TMS570LC4357: simultaneous dma transfers form mibspi 2 and 3 to RAM

Part Number: TMS570LC4357

I am trying to transfer ~1KB  form MibSpi2 and 3 to two locations the RAM, when ever these to transfers happen at the same time one fails to write data in the RAM.

Both transfers a consisting of several frames and I hoped to be able have both transfers running at the same time.

If both transfers are not overlapping in time everything works fine, however if they are overlapping the one with the higher destination address fails to write.

The RAM regions are not overlapping. 

Is it possible to have both transfers running at the same time, in an interleaved manner, or do I have to make sure that they are executed non overlapping?

  • Hello Georg,

    The DMA supports two priority scheme: fixed and rotating. 

    Fixed: the lower the DMA channel number, the higher its priority. This is the default scheme used by DMA.

    Rotating: use round-robin scheme

    So the DMA transfer with lower priority channel is arbitrated, and starts transfer after the channel with higher priority is complete. 

  • Thanks for the quick reply, 

    I will try to change the priority scheme but I do not understand why the destination address is in my case the deciding factor whether the transfer fails or not.

    I changed the channels and the mibspi that is starting first, it was allways the higher address in ram that failed.

  • Is the whole higher addresses in valid memory range (<0x08080000)? Is the higher address in a dedicated MPU region which has restricted write permission?

  • To both questions yes, the DMAs are working for both addresses if they are not overlapping in time

  • Hi Georg,

    Ok, how do you make the transfer of two DMA channels overlap? Are MibSPI2 and MibSPI3 triggered by the same trigger source?  

    "higher destination address fails to write." -- no data is written to the higher address, right? did you get data abort? 

    Can you share your code with us, so we can test it on our bench?

  • There are two GIO interrupts, one for each MibSpi, in these interrupts I decide how many frames need to be read and than trigger a DMA transfer for the right amount of frames. If these two interrupts are close enough the dma transfer overlaps. For debugging I trigger these interrupts manually to force the overlapping.

    Yes, there is no data witten to the higher address. I do not get data aborts.

    I will check how to share the code.

  • two configuration structs    
        dmaConfig0.mibspiDmaLine = 1;
        dmaConfig0.rxChannel = DMA_CH4;
        dmaConfig0.rxRequest = DMA_REQ34;
        dmaConfig0.txChannel = DMA_CH5;
        dmaConfig0.txRequest = DMA_REQ35;
    
        dmaConfig1.mibspiDmaLine = 0;
        dmaConfig1.rxChannel = DMA_CH6;
        dmaConfig1.rxRequest = DMA_REQ12;
        dmaConfig1.txChannel = DMA_CH7;
        dmaConfig1.txRequest = DMA_REQ13;

    DMA control packet initialization:

           this->txDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].SADD = (uintptr_t) DummyBuffer; 
           this->txDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].DADD = (uintptr_t) &(this->mibspiRam->tx[this->tgBufferStart[0]].data); 
           this->txDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].ADDMODERD = ADDR_FIXED; 
           this->rxDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].SADD = (uintptr_t) &(this->mibspiRam->rx[this->tgBufferStart[0]].data); 
           this->rxDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].DADD = (uintptr_t) rxBuffer; 
           this->rxDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].ADDMODEWR = ADDR_INC1; 
    
           this->txDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].CHCTRL = 0; 
           this->txDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].FRCNT = segmentCount; 
           this->txDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].ELCNT = this->tgBufferLength[0]; 
           this->txDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].ELDOFFSET = 4; 
           this->txDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].ELSOFFSET = 0; 
           this->txDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].FRDOFFSET = 0; 
           this->txDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].FRSOFFSET = 0 ; 
           this->txDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].PORTASGN = PORTA_READ_PORTB_WRITE;
           this->txDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].RDSIZE = ACCESS_16_BIT; 
           this->txDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].WRSIZE = ACCESS_16_BIT; 
           this->txDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].TTYPE = FRAME_TRANSFER; 
           this->txDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].ADDMODEWR = ADDR_OFFSET; 
           this->txDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].AUTOINIT = AUTOINIT_ON; 
          
           
           dmaSetCtrlPacket(this->dmaConfig->txChannel, this->txDmaCtrlPacket[this->dmaConfig->mibspiDmaLine]);
           dmaReqAssign(this->dmaConfig->txChannel, this->dmaConfig->txRequest);
           dmaSetChEnable(this->dmaConfig->txChannel, DMA_HW);
    
           this->rxDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].CHCTRL = 0; 
           this->rxDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].FRCNT = segmentCount; 
           this->rxDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].ELCNT = this->tgBufferLength[0]; 
           this->rxDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].ELDOFFSET = 0; 
           this->rxDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].ELSOFFSET = 4; 
           this->rxDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].FRDOFFSET = 0; 
           this->rxDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].FRSOFFSET = 0 ;
           this->rxDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].PORTASGN = PORTB_READ_PORTA_WRITE;
           this->rxDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].RDSIZE = ACCESS_16_BIT; 
           this->rxDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].WRSIZE = ACCESS_16_BIT; 
           this->rxDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].TTYPE = FRAME_TRANSFER; 
           this->rxDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].ADDMODERD = ADDR_OFFSET; 
           this->rxDmaCtrlPacket[this->dmaConfig->mibspiDmaLine].AUTOINIT = AUTOINIT_ON; 
    
           dmaSetCtrlPacket(this->dmaConfig->rxChannel, this->rxDmaCtrlPacket[this->dmaConfig->mibspiDmaLine]);
           dmaReqAssign(this->dmaConfig->rxChannel, this->dmaConfig->rxRequest);
           dmaSetChEnable(this->dmaConfig->rxChannel, DMA_HW);

    tiggering the DMA transfer from the interrupts:

        uint32 bufid = this->tgBufferEnd[0]; 
        uint32 icount = 0;
        this->mibspiInterface->DMACTRL[this->dmaConfig->mibspiDmaLine] = 0;
        
        this->mibspiInterface->DMACTRL[this->dmaConfig->mibspiDmaLine] |= ((this->dmaConfig->rxChannel & DMACTRL_RXDMAMAP_MASK) << DMACTRL_RXDMAMAP_OFFSET );
        this->mibspiInterface->DMACTRL[this->dmaConfig->mibspiDmaLine] |= ((this->dmaConfig->txChannel & DMACTRL_TXDMAMAP_MASK) << DMACTRL_TXDMAMAP_OFFSET);
    
        
        this->mibspiInterface->DMACTRL[this->dmaConfig->mibspiDmaLine] |= DMACTRL_RXDMAENA;
        this->mibspiInterface->DMACTRL[this->dmaConfig->mibspiDmaLine] |= DMACTRL_TXDMAENA;
    
        
        this->mibspiInterface->DMACTRL[this->dmaConfig->mibspiDmaLine] |= DMACTRL_ONESHOT;
        
       
        this->mibspiInterface->DMACTRL[this->dmaConfig->mibspiDmaLine] |= ((icount & DMACTRL_ICOUNT_MASK) << DMACTRL_ICOUNT_OFFSET) ;
        this->mibspiInterface->DMACTRL[this->dmaConfig->mibspiDmaLine] |= ((bufid & DMACTRL_BUFID_MASK) << DMACTRL_BUFID_OFFSET );
    
       
        this->mibspiInterface->DMACNTLEN = 1;
        this->mibspiInterface->DMACOUNT[this->dmaConfig->mibspiDmaLine] = ((segmentsNeeded-1) << 16); 

  • Thanks Georg, I will take a look at your code. 

  • I found my mistake, the data structures I write to were missing some padding byte, therefore the higher one was overwritten by the transfer to the lower address.

    thanks for you support. 

  • Good to know the issue has been solved. Thanks