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.

TMS570 DMA and DCAN Hardware Request

Other Parts Discussed in Thread: HALCOGEN, RM48L950

Hello,

I'm trying to configure DCAN and DMA to move incoming messages from the IF3-Registers to an address in RAM. Therefore I connected DCAN1 (with MessageBox1 as TxD) and DCAN2 (with MessageBox1 as RxD) and set the Update Enable Bit for the DCAN2-MsgBox1. To enable DMA Request for DCAN2IF3 I set DE3 in the DCAN2 CTL Register. The DMA funktions I used are based on the 3146.MIBSPI_DMA_Demo from this forum. For DCAN DMA Connection the DMA Request Line 4 ist used (DCAN2 IF3).

When I start the program, a message is sent from DCAN1 (MsgBox1) to DCAN2 (MsgBox1), where DataA and DataB is moved from IF2 to IF3 Register. It's working fine so far. But although the DMA Interrupts are enabled with HALCoGen, no Flags are set in the DMA Registers when the CAN message is coming in and the DMA Transfer with Hardware Request isn't working. When I use DMA Software Request the DMA Transfer works fine. What do I have to do to get the DMA Hardware Request working with the DCAN2 IF3 Registers?

Regards,

Joris

  • I am not sure how you configure your DCAN memory interface. IF3 can not be set to a certain message ID as IF1/IF2 does, so, usually, it is used together with IF1 or IF2.

    Assume:

    DCAN1, IF2 -> DCAN2, IF2. And you want to use DCAN2 IF3 checks for the newData flags in message RAM to trigger DMA request, what you can something like:

     // USE IF3 observation
     DCAN2_Ptr->IF3OBS_UN.IF3OBS_UL = 0x00000012;//dataB and ARB has to be read

     //Enable automatic update
     DCAN2_Ptr->IF3UPDATE_ENA1_UL = 0xFF;

    Regards,

    Haixiao

  • Hello Haixiao,

     

    thank you very much for your reply. Now that DataB and Arb Bits are set in the Observation Register, the DMA transfer works as expected.

     

    Best regards,

     

    Joris

  • Hi, Haixiao

    My processor is RM48L950.

    I am trying to move data from DCAN2 IF3 to a memory location using DMA ( via channel 0, request line 1). I use "dma.c/.h" provided by TI for RM48 chips.

    here is what I did:

    DCAN2 IE0 (rx interrupt) disabled, IE1 (tx interrupt) enabled.

    DCAN2 DE3 enabled.

        /* move data A and B to DMA from mailbox 1-48 which are receive mailboxes*/

        canREG2->IF3OBS = 0x00000018U;
        canREG2->IF3UEy[0] = 0xFFFFFFFFU;
        canREG2->IF3UEy[1] = 0x0000FFFFU;

    and here is how I setup DMA

        /* - enabling dma module : this brings dma out of reset     */
        dmaEnable();                                     

        /* - assigning dma request: channel-0 with request line - 1 */
        dmaReqAssign( DMA_CH0,1 );                               

        cp.SADD      = (uint32)(&(canREG2->IF3DATx[0]));              /* source address             */
        cp.DADD      = CANQUEUE_fnGetRxQueueAddr(CAN_eMODULE2);              /* destination  address       */
        cp.CHCTRL    = 0;                 /* channel control            */
        cp.FRCNT     = 1;                 /* frame count                */
        cp.ELCNT     = 1;                 /* element count              */
        cp.ELDOFFSET = 0;                 /* element destination offset */
        cp.ELSOFFSET = 0;                  /* element destination offset */
        cp.FRDOFFSET = 8;                  /* frame destination offset   */
        cp.FRSOFFSET = 0;                 /* frame destination offset   */
        cp.PORTASGN  = 4;                 /* port b                     */
        cp.RDSIZE    = ACCESS_64_BIT;      /* read size                  */    
        cp.WRSIZE    = ACCESS_64_BIT;       /* write size                 */
        cp.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
        cp.ADDMODERD = ADDR_FIXED;         /* address mode read          */
        cp.ADDMODEWR = ADDR_OFFSET;       /* address mode write         */
        cp.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */

        /* - setting dma control packets */
        dmaSetCtrlPacket(DMA_CH0, &cp);

        /* - setting the dma channel to trigger on h/w request */
        dmaSetChEnable(DMA_CH0, DMA_HW); 

    I can see IF3 data A/B registers have been updated with the incoming, but nothing moved into the memory location I specified. Could you please point out what I have missed here?

    Thanks,

    Clio

    P.S. I attach the DCAN2 and DMA register values just in case:

  • One more question:

    Where can I find out which dma request line is for which peripheral?

    Thanks,

    Clio

  • Lets assume that I have 2 ram buffers to store 10-10 can messages (IF3 copy). DMA is running and alternating between the ram buffers but I can only have or afford an interrupt when the DMA completes the 10 transfers (ergo: message/frame based interrupt is not an option).

    I would also like to read the ram buffers from time to time and check if the DMA has written anything to it.

    What I do not know is how to do this poll mechanism correctly.
    Here is what I would like to do:

    • check if DMA frame tx count is greater than 0 (or there was a DMA interrupt indicating that 10 frames were stored) -> (dma.ITCOUNT - dma.CTCOUNT) > 0
    • halt the DMA -> dma.HWCHENAS &= ~(1<<dma_ch)
    • wait for current frame transfer (if there is a pending copy) -> while( dma.PEND & dma_ch );
    • restart the DMA with the other buffer
    • (copy the "prev" buffer to a ram location)

    So is the above register usage correct to handle the described stop/wait/change scenario?
    Is there anything that should be considered?