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.

uDMA not working with SSI0 in slave mode

1031.SOMspi.txtHi,

I am using the LM4F232H5QD microcontroller on a custom board with a Blackhawk debugger and AARDVARK SPI tool.  I cannot get uDMA working with SSI0.  I am attaching my initialization code1108.SOMspi.txt.  The functions:

ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);

ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);

are called in a different place in the code.  The SSI0 port works with the SPI tool when just configured for SSI and not including the uDMA so I know I have SSI0 working.  One thing I have noticed is when the lines: 

ROM_uDMAChannelEnable(UDMA_CHANNEL_SSI0RX);

ROM_uDMAChannelEnable(UDMA_CHANNEL_SSI0TX);

are executed in the initialization routine, both the UDMA_ENASET and UDMA_ENACLR are set not just the UDMA_ENASET as would be expected.  Can someone please take a look at it and see if there is a glaring mistake?

Regards,

Susie Johnson

  • Hi,

    I used the debugger to inspect the area of memory that the uDMA is using and I am getting the transfer but I am not getting the interrupt to let me know about the transfer.

    Regards,

    Susie Johnson

  • I finally got the interrupts going this morning.  I had the receive and transmit buffers sized at 512 bytes and was only sending 11 bytes from the Aardvark to the micro.  I was setting up the transfer:

         uDMAChannelTransferSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT,

                                    UDMA_MODE_BASIC,

                                    (void *)(SSI0_BASE + SSI_O_DR),

                                    SomRxBuf, sizeof(SomRxBuf));

     

    which has a size of 512 bytes.  This morning I changed the call to:

         uDMAChannelTransferSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT,

                                    UDMA_MODE_BASIC,

                                    (void *)(SSI0_BASE + SSI_O_DR),

                                    SomRxBuf, 11);

    And now I get the receive interrupt when the transfer is complete.  I am still getting some peculiar behavior on the transmit interrupts but am making progress.

  • I have gotten the receive side working perfectly but the transmit side is not working properly.  I have SSI0 connected to an Aardvark SPI tool running at 125kHz and using mode SSI_FRF_MOTO_MODE_1.  SSI0 is set up in slave mode with the Aardvark set to master mode.  I have loaded the transmit buffer on the LM4F232 micro with data to transmit to the Aardvark.  When I send data from the Aardvark to the micro, I do the data from the buffer on the micro but it is not transmitted in the correct order. 

     Data in buffer: 0x41, 0x42, 0x43,  0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50

     Data received on the Aardvark 1st transmission:  0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x41, 0x42, 0x41, 0x42, 0x43,  0x44, 0x45, 0x46, 0x47, 0x48

    Data received on the Aardvark 2nd transmission:  0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x41, 0x42, 0x43,  0x44, 0x45, 0x46, 0x47, 0x48, 0x49

    Data received on the Aardvark 3rd transmission:  0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x41, 0x42, 0x43,  0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A

    Data received on the Aardvark 4th transmission:  0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x41, 0x42, 0x43,  0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B

     The first transmission is always totally messed up and then it starts the shifting byte thing.  I have attached my latest code.

      4810.SOMspi.c

  • I did notice something interesting this morning.  I am getting two interrupts per transfer.  When I step through the interrupts, the following is what I notice:

     In the first Interrupt the following code gets executed in the ISR:

     ulStatus = ROM_SSIIntStatus(SSI0_BASE, 1);

     ROM_SSIIntClear(SSI0_BASE, ulStatus);

     ulMode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT);  (After this is executed ulMode is zero.)

         if(!ROM_uDMAChannelIsEnabled(UDMA_CHANNEL_SSI0RX))

       {

            uDMAChannelTransferSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT,

                                       UDMA_MODE_BASIC,

                                       (void *)(SSI0_BASE + SSI_O_DR),

                                       SomRxBuf, 16);

            ROM_uDMAChannelEnable(UDMA_CHANNEL_SSI0RX);

        }

        if(!ROM_uDMAChannelIsEnabled(UDMA_CHANNEL_SSI0TX))

        {

            TxBufCount++;

            uDMAChannelTransferSet(UDMA_CHANNEL_SSI0TX | UDMA_PRI_SELECT,

                                       UDMA_MODE_BASIC, SomTxBuf,

                                       (void *)(SSI0_BASE + SSI_O_DR),

                                       16);

            ROM_uDMAChannelEnable(UDMA_CHANNEL_SSI0TX);

        }

     

     In the second Interrupt the following code gets executed in the ISR:

     ulStatus = ROM_SSIIntStatus(SSI0_BASE, 1);

     ROM_SSIIntClear(SSI0_BASE, ulStatus);

     ulMode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT);  (After this is executed ulMode is one.)    

     if(ulMode == UDMA_MODE_BASIC)

         {

            RxBufCount++;

       }

     I thought there was supposed to be only one completion interrupt generated by the uDMA channel. 

  • First - must applaud your efforts - detail and care in your writings.  My "non-mastery" of uDMA prevents better response.

    I can offer the guidance that when an interrupt is cleared - too deep (or far down) w/in a service routine - re-entry to that service routine may occur.  You clear yours @ 2nd instruction - so that appears not to be your case.  (unless the code you presented here - is a small extract of the "real deal."

    Sometimes writing test code in the simplest form possible - lends greater light on such issues.  Perhaps you could increment a variable w/in the troublesome service - and see if indeed it agrees/confirms your +2 assertion. 

    Debuggers have been seen to sometimes cause - or erroneously report - such issues.  Would be beneficial to run the code and observe - w/ test variable as suggested...

    Wish I knew and/or could assist further - perhaps one w/greater uDMA "history" w/Stellaris can help...

  • Thanks cb1_mobile for the suggestion.  I put an interrupt counter variable in the code and incremented it each time the interrupt was called.  I sent 3 transactions with no breakpoints to interrupt the running  code and my variable reports that it was indeed called 6 times.  So I am getting two interrupts per transaction.

     

  • hi Susi,

    there is an unclear thing in your source code.

    To clear the interrupt you use the following statements:

    ulStatus = ROM_SSIIntStatus(SSI0_BASE, 1);

    ROM_SSIIntClear(SSI0_BASE, ulStatus);

    but while SSIIntStatus return a bit mask made by 4 bits, SSIIntClear take a bit mask made by only 2 bits as parameter.

    according to me there is something wrong

    best regards

    mastupristi