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.

F28377S SPI DMA



I am trying to get the DMA working with a SPI device on a 28377S processor.

I am using the example code example_2837xS_spi_dma as a starting point.

Note however I am running a SYS BIOS application.

The issue I am having is that the DMA TX ISR only gets called on the first DMA transfer. The DMA RX ISR gets called each time a DMA transfer occurs.

The calls to configure the spi fifo and the DMA are identical each iteration.

I have compared the DMA registers and fifo registers and they are set the same in all cases.

Is there some other register that needs to be set to get multiple TX DMA IRQ or can you advise on what else I might look for?

Thanks

Maury

  • Maury,

    Are you doing acknowledging the PIE group in your TX ISR?

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP7;

    -Mark

  • I have the ISR set up in the app.cfg file to do an automatic ack of PIE interrupts. Setup is the same for both RX and TX DMA IRQ.
  • Maury,

    The Dma example only does one transfer. If you have not done any modification to the code, you will get the same results. The DMA ISR in the example code halts each DMA channel. You need to restart the channel for the DMA to trigger again. There are two ways to adjust the example code to do this. 1) If you set DmaRegs.CHx.CONTROL.bit.HALT to 1 in the ISR, you will want to set the RUN bit to 1 to start the next transmission. 2) If you Set the DMA to Continuous mode and never set the HALT bit, the DMA will reinitialize and wait for the next trigger to start the next transmission.

    Am I understanding your issue properly?

    -Mark
  • Mark,
    Thanks for the response. I was setting the DMA run but for the channels used but this did not fix the issue.
    I tracked it down to the fact that the SPIFF RX and TX were not getting reset and so the status and INT flags were set and could not get another IRQ.
    SpiaRegs.SPIFFRX.bit.RXFIFORESET = 0x0; // reset the RX FIFO
    SpiaRegs.SPIFFTX.bit.SPIRST =0x0; // reset the TX FIFO
    I have another question or two regarding DMA operation
    #1) Is it half duplex in the sense all the TX data is sent first and then RX data.
    That is can I setup the DMA RX and TX burst and transfer registers at the same time then start transfer and know that TX will happen then RX?
    #2) I want to know when the SPI operation is completed (TX/RX)and it appears the DMA TX and RX IRQ occur when the DMA transfer completes not the SPI transfer. I was going to use the SPI IRQ to keep track of the number of interrupts RX + TX so I can signal the application when transfer is done.
    Is that the correct way to do this or is there a better approach?
    thanks
    Maury
  • Glad to hear that you figured out the tx not restarting.

    For your additional questions:
    1) The SPI is a essentially a programmable shift register. When you write data to SPITXBUF, the data is copied to SPIDAT and the transfer begins. As each each bit is shifted out of SPIDAT, the recieve line is shifted in. once the full word is complete, the contents of SPIDAT are copied into the SPIRXBUF to be handled as necessary. the timings of each bit shifting in/out is dependent on active edges as determined by the Clock Phase and Polarity settings.
    2) The DMA Interrupts are triggered at the beginning or end of a transfer (configuration dependent). If you wish to send/receive 1024 words, you would configure the DMA channels to interrupt at the end of the transfers. So once, the TX DMA completes shifting the full 1024 words to the SPI, it will trigger the interrupt. once the 1024th word is shifted from RXBUF to the memory location, the RX DMA will trigger an interrupt. If you enable the SPI interrupt to count the number of SPI FIFO interrupts, you are essentially recreating the DMA transfer completion interrupt and placing an undue burden on the CPU by interrupting every (TXFFIL/RXFFIL) words. unless you want some intermediate info, this might not be ideal. It all depends on your application requirements, of course.

    -Mark
  • Mark,
    The operation I think I am seeing is the TX and RX IRQ are happening when data is transferred to the SPI. I am using a scope to toggle I/O when these IRQ occur. In addition I have the SPI clock and MISO MOSI outputs.
    What I am seeing is that the RX or TX DMA IRQ are happening but the SPI has not yet shifted the data out/and or in.
    How do I determine when the SPI is done sending/receiving data?
    Thanks
    Maury
  • This makes sense for the TX operation, as the DMA will interrupt when the data is shifted from the memory buffer to the TX FIFO. The channel configured for RX, will only interrupt once the last word in the transfer has been copied from the RX FIFO, meaning when SPI is done receiving. Since the TX and RX are interlinked (SPIDAT is a shift register) you can treat the RX DMA channel as the indication that the SPI is done sending and receiving data.

    First verify that you are configuring the DMA interrupt properly. Have you accidentally configured it to generate the interrupt at the beginning of the transfer?
    Another option would be to do a single complete transfer (like the spi dma example) and provide the scope capture so show the behavior.

    -Mark
  • Mark,

    I am using channel 5 for tx and 6 for RX like the example

    I have the mode bits set on transfer to 0x8305 and 0x8306

    CHINTE = 1                                                               8

    CHINTMODE = 1 // IRQ end of transfer        3

    PERINTE = 1

    PERINTSEL either 5 TX or 6 RX

    I am using an external chip select as there are two devices on the SPI.

    I am trying to send 4 bytes of data and receive 4.

    So I have the DMA burst set to 3 and transfer to 0 for both RX and TX

    If look at scope capture below CS which is being activated before DMA transfer is started and then is deactivated when DMA RX ISR fires is happening before the data is clocked in or out. I seems to be getting the correct number of clocks and the output data looks correct.

    I know that SPI gets data shifted in when ever shift out - have SPI set up to TX on rising edge and RX on falling edge.

    Does the number of DMA RX event need to total the sum of the TX data and RX data?

  • Mark,
    The DMA transfer is only 16 or 32 bits. Does this mean the SPI needs to be setup for 16 bit operation or can it be set to 8 and each DMA transfer to SPI FIFO will generate two 8 bit outputs on SPI.
  • Maury,

    Your scope capture did not import. Can you try that again?

    The DMA should be configured to 16-bit transfers. The DMA will essentially replace the CPU operation of copying data from a memory buffer to the SPITXBUF. This means that the data (if less than 16-bits per word) should be left justified in the memory buffer. i.e. if you are transmitting 4x 8bit words, the DMA will make 4 16-bit moves.

    The 4 register settings you shared are correct for what you are trying to accomplish. Have you verified that the DMACHSRCSEL is configured properly for the SPI RX channel?

    The DMA channels are separate from each other. You are not required to use DMA for both TX and RX operations if you don't want to. What this means is that your RX should be configured to the number of words you are receiving, not the sum of TX and RX. As you have mentioned (but I have yet to see), the correct data seems to appear on the TX line, so we can safely ignore the TX Channel for now as it is working correctly. Focus on the RX register settings, you can share your DMA configuration code for RX only if you wish. It might eliminate some back and forth.

    -Mark
  • Mark,
    I appreciate you responses as they have helped me move ahead
    I think I have not been as clear in the operation as I should have.
    The device in question requires that I send a command to read registers/data.
    After that I need to then read the response (half duplex)
    Do I need to setup a transmit that will then recv the same number of words in response. I'll throw that data away as it is just spi clocking in data and is not meaningful. Then do I set another DMA TX and RX to receive the data expected from the command sent?
    This operation is typical of what I do when using the SPI ISR.
    Thanks
    Maury
  • Glad to help Maury. If there is anything that has been especially painful, such as lack of documentation in the TRM, let us know so we can prevent others from struggling with the same issue.

    I understand now what you are trying to do.

    Assuming you are the master, then yes, you need to initiate the clocks. I think that you will want to do what you had suggested. You want to transmit your command (4 words) and then your "response" clocks (4 dummy words). As you said earlier, you will set the both TX and RX DMA to the full length of the sequence. the RX DMA would transfer 4 don't care words while the SPI transmit command is happening, then the second 4 words would be the valid received response.

    Does that make sense?
    -Mark