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.

TMS570LS3137 DMA

Other Parts Discussed in Thread: HALCOGEN

I've never used DMA before and I'm struggling to get it going. What I'm trying to do, initially, is to get 4 bytes of software real time clock out of the SCI port. I can do this by calling a sciSend function that was generated by HalCoGen. So I know the SCI port is working.

I understand that the SCI requires the use of request line 31, but what channel do I need to use? Is it just the next one available or do I have to use a specific one? It's not very well explained in the TRM.

I watched the tutorial video on mibSPI and DMA and it said to use the dma.c/h files in the HalCoGen example directory. I've had a look there and I don't have those files. Could someone post them here for me please?

Thanks

Andy

  • Hi Andy,

    If you are looking for the MIBSPI DMA example, then please install the latest halcogen and generate the code with MIBSPI driver selected, you can see sys_dma.c as well as sys_dma.h generated as well which will be later used.

    Post that copy the contents from . ....\HALCoGen\vxx.xx.xx\examples\TMS570LS31x\example_mibspiDma.c in to your sys_main.c which effectively uses the DMA functions from sys_dma.c, this will help you understand the usage of DMA.

    You can use any of the channel in DMA module, for ex say channel-0, and then assign the required hardware request(SCI in your case) to that channel. You can map SCI TX Request 31 to Channel '0'. 

    Post this set the channel'0' control packet with SCI TX buffer as well as the data address from where you intend to transfer with transfer sizes set accordingly.

    You can follow the mibspi example with these details in mind. Hope this helps.

  • I've followed what was in the example code you mentioned, but I'm still getting nowhere.

    What actually kicks off a DMA transfer? Is it just a data send (over SCI in this case) or do I have to set a flag somewhere?


    My initialisation code looks like this:

        dmaReqAssign( DMA_CH0, DMA_CH31 );      // assigns a channel to a request line (0 to 31)
        dmaConfigCtrlPacket( (U32)sw_rtc, (U32)(&(sciREG->TD)), 4, &rtc_CTRLPKT);
        dmaSetCtrlPacket( DMA_HW, &rtc_CTRLPKT);
        dmaSetChEnable( DMA_CH0, DMA_HW );
        dmaEnable();
        sci_enable_dma();
        
        LastCount = sw_rtc[3];

    and the code in the do-forever loop looks like this:

                if( sciIsTxReady( sciREG ) )
                {
                    sci_enable_dma();
                    dmaSetChEnable( DMA_CH0, DMA_HW );
                    dmaReqAssign( DMA_CH0, DMA_CH31 );      // assigns a channel to a request line (0 to 31)
                    dmaEnableInterrupt( DMA_CH0, FTC );     // I don't know if this is needed or not
                    sciSendByte( sciREG, sw_rtc[0]);        // I think this kicks off the DMA transfer
                }
                
            }
            LastCount = sw_rtc[3];

    The function definition of dmaConfigCtrlPacket looks like this:

    void dmaConfigCtrlPacket(U32 sadd, U32 dadd, U32 dsize, g_dmaCTRL* g_dmaCTRLPKT )
    {
        g_dmaCTRLPKT->SADD      = sadd;                /* source address             */
        g_dmaCTRLPKT->DADD      = dadd;                /* destination  address       */
        g_dmaCTRLPKT->CHCTRL    = 0;                 /* channel control            */
        g_dmaCTRLPKT->FRCNT     = 1;                   /* frame count                */
        g_dmaCTRLPKT->ELCNT     = dsize;             /* element count              */
        g_dmaCTRLPKT->ELDOFFSET = 4;                 /* element destination offset */
        g_dmaCTRLPKT->ELSOFFSET = 0;                    /* element destination offset */
        g_dmaCTRLPKT->FRDOFFSET = 0;                    /* frame destination offset   */
        g_dmaCTRLPKT->FRSOFFSET = 0;                 /* frame destination offset   */
        g_dmaCTRLPKT->PORTASGN  = 4;                 /* port b                     */
        g_dmaCTRLPKT->RDSIZE    = ACCESS_8_BIT;        /* read size                  */
        g_dmaCTRLPKT->WRSIZE    = ACCESS_8_BIT;         /* write size                 */
        g_dmaCTRLPKT->TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
        g_dmaCTRLPKT->ADDMODERD = ADDR_INC1;         /* address mode read          */
        g_dmaCTRLPKT->ADDMODEWR = ADDR_FIXED;        /* address mode write         */
        g_dmaCTRLPKT->AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */
    }

    I'm expecting to see 4 bytes of data coming across the RS232 per second that have the real time clock data, but I only see the first byte (the one that's polled).

    What have I missed?

    Regards

    Andy

  • Andy,

    I am attaching some code snip for you to see how to set SCI with DMA. I will send you a CCS project later once I verify it on EVM. In the mean time, I would suggest you to read the SCI and DMA section of TRM one more time to understand their operation.

    2022.sci_dma.zip

    Thanks and regards,

    Zhaohong

  • Zhaohong,

    the code you've sent me is for a LIN implementation. I am not using LIN, and as I have never used it, I don't understand how it works.

    I am trying to do something much more simple: basic RS232 comms (out of pins 38 & 39 of a 3137PGE). It's hard for me to see what is relevant and what is not because you're accessing a different module.

    Regards

    Andy

  • Andy,

    By default, LIN module on Hercules devices are in SCI mode. The code I posted is for SCI. You will be able to see it if you double check the TRM.

    Thanks and regards,

    Zhaohong

  • Zhaohong

    The TRM has two sections referring to SCI: Section 26 LIN/SCI and section 27 SCI. Section 26 (DMA section) makes references to multi-buffer mode, which section 27 doesn't. I assume that means these two modules are different.

    Do you have anything that runs a simple 4 byte send using DMA out of SCI (not LIN)? I have come to a complete stop on this, I can't see why it isn't working. So any help you can give me here would be appreciated.

    Thanks.

    Andy

  • I've compared my code with several sample versions that can be found on this forum and can't see a significant difference. I've read and reread the TRM and it's not helping. I'm going round and round in circles.

  • Zhaohong,

    I have put the code you sent me (in 2022.sci_dma.zip) into my project and run it and I'm getting an error returned.

    I presume the only functions I need to call are LIN1_TestInit() and LIN1_TestVerify() or have I missed something?

    Regards

    Andy

  • Andy,

    A SCI/TX DMA example is attached. It continuously outputs a data string from LIN0 (configured as SCI). On TI HDK, LIN0 is hooked to the same FT chip for XDS100 emulator. You can use a hyper terminal type of software to view the data on PC screen. The parameter for the USB serial port is 9600 8N1.

    1200.SCI_DMA_CCS5.zip

    Thanks and regards,

    Zhaohong.

  • I use the example you offered, it's works. But I have a doubt why the destination address add 3 ?

    the line :dmaConfigCtrlPacket0((uint32)(&TEXT3),(uint32)(&scilinREG->TD)+ 3,TSIZE3);

  • TMS570 is a big endian device. For a byte write or read  to the lowest byte of a 32 bit register, the address has to be the base address of the register plus 3.

    Thanks,

    Zhaohong