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.

CCS/TMS570LC4357: How to get the DMA data Count?

Part Number: TMS570LC4357

Tool/software: Code Composer Studio

Hi,

I am Using the Hercules TMS570LC4357 Development Kit, 

for the SCI Transmission and Reception using the DMA.

I wanted to know is there any way i can get the DMA count for the number of bytes that are been received at a particular instant.

if in my program i am configuring the dma channel 1 for the reception, then using the CDADDR, and CSADDR i could get the number of bytes that has been received.

But still i could not able to read that value. even i tried with the CTCOUNT, but enable to read it.

So, can anyone please provide the way to read the data count that has been received over dma, without using interrupt?

Regards,

Shivam Kakad

  • Hi Team,

    To add to the above statements, below is what we are doing:
    1. Configure SCI 1 module to use DMA channel 1 for reception without interrupts.
    Destination address configured in DMA is 0x0800F100.

    In S/W, we are checking current desitnation address register in DMA to determine if there are any packets DMA has completed its transaction or not.
    But, its value is not getting updated with the configured, instead it holds the 0x0800F103 (where it mostly depends on what previous value it holds prior to restart).

    Do we need to do anything for this, as current Desitation address register is only read only one.

  • Hi Team,

    We would like to try the below thing:

    1. Configure SCI1 DMA channel for packet reception (SCi RD to TCRAM)
    2. Configure another DMA channel to read DMA channel (used for SCI)->CDADDR value to TCRAM
    3. Configure above both channels in chaining mode.
    But, still we are not able to read CDADDR register when second DMA channel is triggered.

    We tried with the below sample code provided in one of previous case (DMA chaining mode example):

    uint32 src1[transfer_size] = {0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555, 0x66666666, 0x77777777, 0x88888888};
    uint32 src2[transfer_size] = {0x99999999, 0xaaaaaaaa, 0xbbbbbbbb, 0xcccccccc, 0xdddddddd, 0xeeeeeeee, 0xffffffff, 0x12345678};
    uint32 src3[transfer_size] = {0x11223344, 0x55667788, 0x99aabbcc, 0xddeeff00, 0x12345678, 0x13579bdf, 0x2468ace0, 0x87654321};

    uint32 dest1[transfer_size] = {0};
    uint32 dest2[transfer_size] = {0};
    uint32 dest3[transfer_size] = {0};


    dmaEnable();

    // dma config for receive
    dma_config.SADD = (uint32_t)src1;
    dma_config.DADD = (uint32_t)dest1;
    dma_config.CHCTRL = 2; // chain to next channel
    dma_config.FRCNT = 1;
    dma_config.ELCNT = transfer_size;
    dma_config.ELDOFFSET = 0;
    dma_config.ELSOFFSET = 0;
    dma_config.FRDOFFSET = 0;
    dma_config.FRSOFFSET = 0;
    dma_config.PORTASGN = 4;
    dma_config.RDSIZE = ACCESS_32_BIT;
    dma_config.WRSIZE = ACCESS_32_BIT;
    dma_config.TTYPE = FRAME_TRANSFER;
    dma_config.ADDMODERD = ADDR_INC1;
    dma_config.ADDMODEWR = ADDR_INC1;
    dma_config.AUTOINIT = AUTOINIT_OFF;

    // setting dma control packets for receive
    dmaSetCtrlPacket(DMA_CH0, dma_config);

    // dma config for receive
    dma_config.SADD = (uint32_t)dmaRAMREG->WCP[0].CDADDR ;
    dma_config.DADD = (uint32_t)dest2;
    dma_config.CHCTRL = 3;
    dma_config.FRCNT = 1;
    dma_config.ELCNT = 1;
    dma_config.ELDOFFSET = 0;
    dma_config.ELSOFFSET = 0;
    dma_config.FRDOFFSET = 0;
    dma_config.FRSOFFSET = 0;
    dma_config.PORTASGN = 3;
    dma_config.RDSIZE = ACCESS_32_BIT;
    dma_config.WRSIZE = ACCESS_32_BIT;
    dma_config.TTYPE = FRAME_TRANSFER;
    dma_config.ADDMODERD = ADDR_INC1;
    dma_config.ADDMODEWR = ADDR_INC1;
    dma_config.AUTOINIT = AUTOINIT_ON;

    // setting dma control packets for receive
    dmaSetCtrlPacket(DMA_CH1, dma_config);

    // dma config for receive
    dma_config.SADD = (uint32_t)src3;
    dma_config.DADD = (uint32_t)dest3;
    dma_config.CHCTRL = 0; // chain to next channel
    dma_config.FRCNT = 1;
    dma_config.ELCNT = transfer_size;
    dma_config.ELDOFFSET = 0;
    dma_config.ELSOFFSET = 0;
    dma_config.FRDOFFSET = 0;
    dma_config.FRSOFFSET = 0;
    dma_config.PORTASGN = 4;
    dma_config.RDSIZE = ACCESS_32_BIT;
    dma_config.WRSIZE = ACCESS_32_BIT;
    dma_config.TTYPE = FRAME_TRANSFER;
    dma_config.ADDMODERD = ADDR_INC1;
    dma_config.ADDMODEWR = ADDR_INC1;
    dma_config.AUTOINIT = AUTOINIT_OFF;

    // setting dma control packets for receive
    dmaSetCtrlPacket(DMA_CH2, dma_config);

    dmaReqAssign(0,12); // RTI_DMAREQ[0] is connected to reqline 12. Map Reqline 12 to channel 0

    dmaSetChEnable(0,DMA_HW); // Enable channel 0
    dmaSetChEnable(1,DMA_HW); // Enable channel 1
    dmaSetChEnable(2,DMA_HW); // Enable channel 2


    rtiInit();

    rtiREG1->SETINTENA |= (1U << 8);

    rtiStartCounter(rtiCOUNTER_BLOCK0); // When a compare match is reached it will generate a DMA
    // Request on reqline 12 which is mapped to channel 0

    while ((dmaREG->HWCHENAS & 0x07) != 0x0);

    while (1);

    Can you please check and let me know your inputs on this?

  • Anyone has comment on this?

  • Hello Sreenivasan,

    The primary control packet is used to store the channel information of each channel. When the DMA works on several channels, it needs to save the current context of each channel in the working control packet.

    The working control packets are stored in the local DMA memory. They are memory mapped. The working control packet for channel 0 starts at 0xFFF80800 and the working control packet for channel 1 will start at 0xFFF80810. The working control packet is only updated when a channel is arbitrated out. If you have two channels and configure them in round-robin arbitration then the DMA will make some transfers for channel 0 and arbitrates to channel 1 in a round robin fashion. Each time the channel is arbitrated out, its context is saved in the working control packet. Let's say each channel has 16 elements per frame and you are using 8-bit transfer size. After 4 elements for channel 0 is transferred, the DMA will switch to channel 1. It will save 12 as the transfer count in the WCP for channel 0 so that later when it switches back to channel 0 it knows that there are still 12 elements left to transfer.

    The CDADDR is only updated after a channel is arbitrated out of the priority queue.

  • Hi Wang,

    Can we use chaining mode to read the CSADDR value as mentioned above? We tried to doing that, but its not working.

  • Hello Sreenivasan,

    Yes, you can read this register directly or through channel chain, but the value may not be the current source address. AS I mentioned that the current source address, destination address and transfer count are copied to their respective working images only when the channel is arbitrated.