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: DMA control packet Reconfiguration for variable length SCI Tx data

Part Number: TMS570LC4357

Hi Miroslav,

!! Thanks you for your support :-) !!

I'm using the DMA for data transmission over the SCI1. Buffer i'm sending on the SCI using DMA is of variable length.

Each time once i received the Block Transfer Complete interrupt (BTC) i will copy the new data in SharedRAM location and calling the below function by passing the length of buffer.  

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void Dma_modify_and_send (uint16 packet_size)
{
sciInit();

while (((sciREG1->FLR & SCI_TX_INT) == 0U) || ((sciREG1->FLR & 0x4) == 0x4))
{
} /* Wait */

dmaEnableInterrupt(DMA_CH0,BTC,DMA_INTA);

/*Assign DMA request SCI3 transmit to Channel 0*/
dmaReqAssign(DMA_CH0, DMA_SCI1_TX);

/*Assign DMA request SCI4 receive to Channel 1*/
sciTxData = SCI1_TX_ADDR;


/*Configure control packet for Channel 0*/
g_dmaCTRLPKT1.SADD = (uint32_t)TX_DATA; /* source address */
g_dmaCTRLPKT1.DADD = sciTxData; /* destination address */
g_dmaCTRLPKT1.CHCTRL = 0; /* channel control */
g_dmaCTRLPKT1.FRCNT = packet_size; /* frame count */
g_dmaCTRLPKT1.ELCNT = 1; /* element count */
g_dmaCTRLPKT1.ELDOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT1.ELSOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT1.FRDOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT1.FRSOFFSET = 0; /* frame destination offset */

g_dmaCTRLPKT1.PORTASGN = PORTA_READ_PORTB_WRITE;
g_dmaCTRLPKT1.RDSIZE = ACCESS_8_BIT; /* read size */
g_dmaCTRLPKT1.WRSIZE = ACCESS_8_BIT; /* write size */
g_dmaCTRLPKT1.TTYPE = FRAME_TRANSFER; /* transfer type */
g_dmaCTRLPKT1.ADDMODERD = ADDR_INC1; /* address mode read */
g_dmaCTRLPKT1.AUTOINIT = AUTOINIT_OFF; /* auto init */


/*Set control packet for channel 0 and 1*/
dmaSetCtrlPacket(DMA_CH0, g_dmaCTRLPKT1);

/*Set dma channel 0 and 1 to trigger on hardware request*/
dmaSetChEnable(DMA_CH0, DMA_HW);

/*Enable DMA*/
dmaEnable();

/*Enable SCI3 Transmit and SCI4 Receive DMA Request*/
sciREG1->SETINT |= SCI_SET_TX_DMA;


}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Now i have two question :

1) Do i need to call the sciInit(); each time ? if your answer is NO, DMA will not send the subsequent copied buffer and stops the working if did't called the sciInit(); function, is there any solution for that bcoz we should not re-init the sciInit(); 

2) Do i need to use below complete code each time to configure new control packets. what should be the bare minimum code that i should re-configure ?

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

dmaEnableInterrupt(DMA_CH0,BTC,DMA_INTA);

/*Assign DMA request SCI3 transmit to Channel 0*/
dmaReqAssign(DMA_CH0, DMA_SCI1_TX);

/*Assign DMA request SCI4 receive to Channel 1*/
sciTxData = SCI1_TX_ADDR;


/*Configure control packet for Channel 0*/
g_dmaCTRLPKT1.SADD = (uint32_t)TX_DATA; /* source address */
g_dmaCTRLPKT1.DADD = sciTxData; /* destination address */
g_dmaCTRLPKT1.CHCTRL = 0; /* channel control */
g_dmaCTRLPKT1.FRCNT = packet_size; /* frame count */
g_dmaCTRLPKT1.ELCNT = 1; /* element count */
g_dmaCTRLPKT1.ELDOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT1.ELSOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT1.FRDOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT1.FRSOFFSET = 0; /* frame destination offset */

g_dmaCTRLPKT1.PORTASGN = PORTA_READ_PORTB_WRITE;
g_dmaCTRLPKT1.RDSIZE = ACCESS_8_BIT; /* read size */
g_dmaCTRLPKT1.WRSIZE = ACCESS_8_BIT; /* write size */
g_dmaCTRLPKT1.TTYPE = FRAME_TRANSFER; /* transfer type */
g_dmaCTRLPKT1.ADDMODERD = ADDR_INC1; /* address mode read */ 
g_dmaCTRLPKT1.AUTOINIT = AUTOINIT_OFF; /* auto init */


/*Set control packet for channel 0 and 1*/
dmaSetCtrlPacket(DMA_CH0, g_dmaCTRLPKT1);

/*Set dma channel 0 and 1 to trigger on hardware request*/
dmaSetChEnable(DMA_CH0, DMA_HW);

/*Enable DMA*/
dmaEnable();

/*Enable SCI3 Transmit and SCI4 Receive DMA Request*/
sciREG1->SETINT |= SCI_SET_TX_DMA;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  • Hello Yogesh,

    I will take a look at your code, and come back to you.
  • Hello,

    I am sorry for late response. In the code you posted above, you don't define the address mode for RX which should be fixed. I don't see the reason to re-init the SCI module to start another DMA transmission.

    The first time a DMA channel is selected for a transaction, the following process occurs:
    1. The primary control packet is first read by the DMA state machine.
    2. Once the channel is arbitrated, the current source address, destination address and transfer count are then copied to their respective working images.
    3. When the channel is serviced again by the DMA, the state machine will read both the primary control packet and the working control packet to continue the DMA transaction until the end of an entire block transfer.

    When the same channel is requested again, the state machine will start again by reading only the primary control packet and then continue the same process described above.

    NOTE: Changing the contents of a channel control packet will clear the corresponding pending bit if the channel has a pending status. If the control packet of an active channel is changed, then the channel will stop immediately at an arbitration boundary. When the same channel is triggered again, it will begin with the new control packet information.