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.

RM48 MIBSPI RX DMA trigger

Other Parts Discussed in Thread: HALCOGEN

Hello,

I am trying to use MIBSPI3 as a master to TX and RX. I can currently get it to transfer, but I am not sure how to get the data from MIBSPI RX RAM to DMA to system RAM. I can get the data and see it in the RX RAM using loopback. How to I get the DMA on the RX RAM to trigger? Is it by chaining?

I have been playing with the demo code and looking through the forum, but I haven't been able to make any progress. 

Thank you,

Alex

mibspiEnableLoopback(mibspiREG3, Analog_Lbk);

dmaReqAssign(0,15);

g_dmaCTRLPKT.SADD      = (uint32)&txData;			  /* source address             */
g_dmaCTRLPKT.DADD      = (uint32)(&(mibspiRAM3->tx[0].data));			  /* 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 source offset */
g_dmaCTRLPKT.FRDOFFSET = 0;		          /* frame destination offset   */
g_dmaCTRLPKT.FRSOFFSET = 0;                 /* frame source 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_OFFSET;       /* address mode write         */
g_dmaCTRLPKT.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */

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

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

dmaReqAssign(1,14);

g_dmaCTRLPKT.SADD      = (uint32)(&(mibspiRAM3->rx[0].data));			  /* source address             */
g_dmaCTRLPKT.DADD      = (uint32)&rxData;			  /* destination  address       */
g_dmaCTRLPKT.CHCTRL    = 0;                 /* channel control            */
g_dmaCTRLPKT.FRCNT	 = 1;                 /* frame count                */
g_dmaCTRLPKT.ELCNT     = dsize;             /* element count              */
g_dmaCTRLPKT.ELDOFFSET = 0;                 /* element destination offset */
g_dmaCTRLPKT.ELSOFFSET = 4;		          /* element source offset */
g_dmaCTRLPKT.FRDOFFSET = 0;		          /* frame destination offset   */
g_dmaCTRLPKT.FRSOFFSET = 0;                 /* frame source 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_OFFSET;         /* address mode read          */
g_dmaCTRLPKT.ADDMODEWR = ADDR_INC1;       /* address mode write         */
g_dmaCTRLPKT.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */

/* - setting dma control packets */
dmaSetCtrlPacket(DMA_CH1,g_dmaCTRLPKT);

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

/* - configuring the mibspi dma , channel 0 , tx line -0 , rxline -1     */
/* - refer to the device data sheet dma request source for mibspi tx/rx  */
mibspiDmaConfig(mibspiREG3,0,14,15);


dmaEnableInterrupt(0, FTC);

/* - enabling dma module */
dmaEnable();
/* - start the mibspi transfer tg 0 */
mibspiTransfer(mibspiREG3,0 );

/* ... wait until transfer complete  */
while(!(mibspiIsTransferComplete(mibspiREG3,0)))
{
};

/* copy from mibspi ram to sys ram */

//----------------------------SD
while(1); /* loop forever */

  • Alex,

    Which version of HalCoGen are you using?

    I'm looking at the code you pasted above, but it doesn't match the example in the HalCoGen folder.
    C:\ti\Hercules\HALCoGen\v04.02.00\examples\RM48x\example_mibspiDma.c.

    Are you using the instructions in the HalCoGen "Help" to configure the part through the GUI and then pasting in the
    code from the file example_mibspiDma.c to sys_main.c? This should work.
  • Anthony,

    I am using 04.02.00. I started off with the demo code in the help, got it to work with MIBSPI3 in loopback. I am trying to add DMA to the RX side so that I can copy the data without using the mibspiGetData(). I have been fiddling around with it trying to get it to work, so it does look a bit different. Thanks.
  • Ales,

    Ok, that's fine.   As long as you're starting from a good place.

    So what's lacking in this example, is that it shows DMA only being used for transmit,  and you're trying to make it use DMA for both transmit and receive, correct?

    I think maybe these are reversed:

    g_dmaCTRLPKT.SADD      = (uint32)&txData;             /* source address             */

    g_dmaCTRLPKT.DADD      = (uint32)(&(mibspiRAM3->tx[0].data));              /* destination  address       */

    Since you want to copy data from (source) system RAM to (dest) the mibSPI transmit data ram.

  • I have two control packets. I them set to ch0, req line 15 and ch1, req line 14.
    transmit -> sys ram to mibSPI ram:
    g_dmaCTRLPKT.SADD = (uint32)&txData; /* source address */
    g_dmaCTRLPKT.DADD = (uint32)(&(mibspiRAM3->tx[0].data)); /* destination address */

    receive -> mibSPI ram to sysram
    g_dmaCTRLPKT.SADD = (uint32)(&(mibspiRAM3->rx[0].data)); /* source address */
    g_dmaCTRLPKT.DADD = (uint32)&rxData; /* destination address */
  • Sorry Alex, you are right. My eyes must be failing me as I could swear I read them as reversed.

    In any case it looks ok. Looks like you have the right idea swapping the source and dest parameters for the receive direction.

    So, what I would look at next is how you have configured the DMA request generation in the MibSPI.
    That would mean inspecting the values that are being programmed into the MibSPI DMAxCTRL registers.

    After that you could try disabling the DMA channel for receive in the DMA's HWCHENAS and then run your code.
    You should see the transfers occur on a scope if you haven't done something to disturb the transmit side DMA... or at least the first byte should be transferred (depends on how BUFMOD is set... but it doesn't matter...)

    When you see the first transmit occur, you should have also receive data ready. At that point if the MibSPI is configured correctly, then if you look in the DMA's channel pending register, you should see a status bit set indicating that the MibSPI has made a DMA request for receive.
    If you don't see the bit set, then you should go back and check things inside the MibSPI for the setting(s) preventing the DMA request.

    If you do see the pend bit set for the receive DMA request, then you could try enabling the receive DMA channel again (HWCHENAS) and even try triggering it manually (SWCHENAS) to see what it's doing.

    For all of these tests on the DMA side - it may be beneficial to try transmitting and receiving just one element through one MibSPI buffer ram entry first. Because that way the DMA channel will complete after one trigger. Otherwise the DMA may keep the current channel state 'internally' in registers that are not visible, and not set any completion bits. That can make it hard to figure out exactly what the DMA is doing.
  • I will work with just one element per your recommendation.

    Before calling the transfer, the MibSPI DMAxCTRL is 0x80FEC001. I am not seeing the anything in the DMA pending register, but I am seeing the frame transfer complete interrupt trigger for both channels. I feel like I am missing something there.

    When I try using Buffer mode 7 using HW request (wait until TX full and RX empty) it gets stuck at mibspiIsTransferComplete(), and I dont see data in the MibRAM buffer. When I use mode 7 and SW request, I do see the data waiting in the MibRAM buffer. When I try to use SW request and set the SWCHENAS, it clears right away. I don't see the channel pending for either case. Should I be using one over the other?
  • If I trigger it by SWCHENAS, it does go to my system RAM.
  • Hi Alex,

    Ok, I think you're on the right track. It sounds like the MibSPI isn't generating the DMA requests.

    How do you have the MibSPI's DMAxCTRL register configured again? In MIB mode there's more than one request line available,
    so the MIBSPI might be requesting on some other channels instead of DMAREQ[14] and DMAREQ[15].
  • DMACTRL[0] is set to 0x80FEC001
    Oneshot =0
    bufid= 0
    RxDMAMAP= 15
    TXDMAMAP =14
    RX DMA en= 1
    TX DMA en =1
    NOBRK= 0
    icount= 0
    count bit17 =0
    countx =1

    When I configure the DMA ctrl packet, I have the first one set to DMA ch 0 for transfer and second one set to DMA ch 1 for rx. Is this correct?
  • Alex,

    I'm thinking the problem is here:
    RxDMAMAP= 15
    TXDMAMAP =14

    Because if these are the fields in the MibSPI DMAxCTRL register then they are MIBSPI requests #14 and #15.

    You have to look at the map in the datasheet to see which DMA request they are wired up to.
    There should be a table called "DMA Request Line Connection"

    I'm looking at the RM46 which should be the same (but double check RM48) and I see that MIBSPI[15] goes to DMAREQ[31]
    and MIBSPI[14] goes to DMAREQ[30].

    So I think you'd want these to be:
    dmaReqAssign(0,30);
    dmaReqAssign(1,31);

    Also I should point out that the table DMA Request Line Connection should have a statement above it saying
    "Some DMA requests have multiple sources, as shown in Table 4-33. The application must ensure that
    only one of these DMA request sources is enabled at any time"
    (table # might be different in the RM48 datasheet)

    So be sure that you are not planning to use any of the other DMA requests that share these lines into the DMA controller. I believe they are basically or'd together. So that would be something like MIBSPI1[14], MIBSPI5[1], and SCI receive (again please confirm in RM48 datasheet).
    If you have a conflict or forsee one you can change RxDMAMAP / TXDMAMAP to use a different request out of MibSPI3 as long as you then also change the mapping in dmaReqAssign to match...
  • Yup, that fixed it. I have seen that table before, but I had misunderstood it.

    Another question, how do I use the chaining to trigger another dma transfer (for example, last transfer of ch1 trigger ch2)? I am having trouble getting that to work.
  • I changed it DMA ch trigger to SW and it worked. Thanks for all the help!