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.

Continous SPI Communication via EDMA controlled by Spix_ENA line

Other Parts Discussed in Thread: ADS1274, OMAPL138

I am using a C6748 processor an I am interfacing an ADC to an SPI bus with the DSP being the master. I would like to set up a continuous ping-pong edma transfer that is gated by the SPIx_ENA line.

Is it possible to set this up with the existing psp drivers, or will I have to manualy set up the EDMA parameters? Are their any documents, example programs, or forum threads that show how to do this?

I having been bashing my head against this for several days trying to modify the dma_ping_pong_test example to work with the SPI but to no avail.

Thank you for any assistance that can be given.

  • Hi,

        There is an example showing how to use SPI driver in EDMA mode to access SPI flash. You can find the example in PSP_PACKAGE\packages\ti\pspiom\examples\evm6748\spi\edma\. There is no example showing how to interface/access ADC via SPI, but the SPI flash example along with the SPI driver should be good enough to help you get started.

        Note that the SPI driver is in PSP_PACKAGE\packages\ti\pspiom\spi. If you are familiar with EDMA, the function in spi_edma.c should be straightforward to see how the EDMA was configured.

        Basically the aCnt is set to either 1 or 2 (around line 164), depending on whether it is 8 bit or 16 bit for each element. The bCnt is set to the buffer length (around line 214) which is specified by application. The opt is set to A sync (around line 231) which means the EDMA will sync with SPI for element transfer.

       The synchronization between EDMA and SPI happens "automatically", meaning that if ENA is not active, then the EDMA will not transfer the next element until it becomes valid again.

  • Thank you for responding.

    The spi_edma.c file is fantastic for showing how to configure a "single shot" transfer. What I am needing is a continuous ping/pong transfer with the ADC. Here is some additional information.

    The ADC I am interfacing to is the ADS1274, connected to SPI1 of the C6748. I want to retrieve data from this ADC continuously, so I am planning on setting up a Ping-Pong configuration that will fire an interrupt after 128 samples are collected as it proceeds to alternate between the ping and pong buffers.

    Since the ADS1274 de-asserts the DRRDY line one clock cycle after the C6748 starts clocking data in over SPI, it can not be used as the SPI_nENA input. Each conversion results in 12 bytes of data that need to be clocked in. When the SPI hardware sees SPI_nENA go high, it will finish clocking in the current byte, and then wait until SPI_nENA is asserted again before clocking in the remaining bytes.

    So, this leads me down the path where I need to create a chained EDMA for the SPI transmit. The DRRDY line will go into a GPIO line which is configured as a falling edge interrupt. When this interrupt occurs, this triggers the gpio event EDMA transfer (Acnt = 1, Bcnt = 128, Ccnt = 1) that for every A event, then triggers an SPI transmit EDMA transfer for 12 bytes (Acnt = 1, Bcnt = 12, Ccnt = 1). After the GPIO EDMA event completes (all 128 samples), the SPI receive EDMA transfer (ping/pong configuration with Acnt=1, Bcnt=12, Ccnt=128) completes and issues a callback function call to process the ping buffer while the pong is being filled.

    I have questions about setting up the chained events for the SPI transmit since the examples in the user guide are not very helpful on explaining how to configure the EDMA. I need the GPIO event to chain to the SPI TX event, but I also need the EDMA parameter sets to reload so they can continuously be used. I have attempted this, but failed. I can get it to transmit the 12 bytes as needed, but an EDMA miss error consistently happens on the SPI TX event before a successfull completion happens (disables the channel and then reloads the param set).

    Do you have any suggestions?

  • Hi,

        It looks your HW setup justifies the way you are doing. Why don't you copy/paste your edma paramset so that I can take a look. Please let me know which paramset (address) and gpio pin that you are using. Also please let me know how fast is your ADC?

  • Here is my current configuration. Note, instead of doing 128 samples, I am only doing 8 for testing purposes:

    Paramset

    [7] = {GPIO Event Bank1} 0x01C040E0

                OPT = 0x81007000

                SRC = 0x1181FF80

                A_B_CNT = 0x00010001

                DST = 0x01F0E03C

                SRC_DST_BIDX = 0x00000000

                LINK_BCNTRLD = 0x000140E0

                SRC_DST_CIDX = 0x00000000

                CCNT = 0x00000008

    [19] = {SPI1 TX Event} 0x01C04260

                OPT = 0x81113000

                SRC = 0x1181FF80

                A_B_CNT = 0x000B0001

                DST = 0x01F0E03C

                SRC_DST_BIDX = 0x00000000

                LINK_BCNTRLD = 0x0000FFFF

                SRC_DST_CIDX = 0x00000000

                CCNT = 0x00000001

    [18] = {SPI1 RX Event } 0x01C04240

                OPT = 0x81112000

                SRC = 0x01F0E040

                A_B_CNT = 0x000C0001

                DST = 0x1181FE80

                SRC_DST_BIDX = 0x00010000

                LINK_BCNTRLD = 0x000C4420

                SRC_DST_CIDX = 0x00010000

                CCNT = 0x00000008

    [32] = {...} 0x01C04400

                OPT = 0x81112000

                SRC = 0x01F0E040

                A_B_CNT = 0x000C0001

                DST = 0x1181FE80

                SRC_DST_BIDX = 0x00010000

                LINK_BCNTRLD = 0x000C4420

                SRC_DST_CIDX = 0x00010000

                CCNT = 0x00000008

    [33] = {...} 0x01C04420

                OPT = 0x81112000

                SRC = 0x01F0E040

                A_B_CNT = 0x000C0001

                DST = 0x1181FF00

                SRC_DST_BIDX = 0x00010000

                LINK_BCNTRLD = 0x000C4400

                SRC_DST_CIDX = 0x00010000

                CCNT = 0x00000008

    This configuration produces the 12 byte transmit all in one continuous chunk, but then has an EDMA miss on TX followed by an EDMA success on TX. The TX event on success will reload the TX paramset. I believe this is non-ideal since it is "expecting" TX to have been terminated by the miss. If the TX paramset is linked to itself for auto-reload, once the first byte is transmitted, the SPI will "forever" continue, irregardless of being triggered by the GPIO event.

    EDIT: I forgot to answer that the ADC is operating at 51200samples/sec. This results in a GPIO event every 19.53usec.

  • Hi,

        I am still not able to completely understand your setting but I think I have found some problems.

     

        First of all, if you need GPIO bank1 interrupt to trigger GPIO EDMA transfer, than you should use paramset[41] (see table 6-5 in OMAPL138 or C6748 datasheet). Right now you are using paramset[7].

        Secondly, if you want GPIO transfer to chain to SPI1 TX transfer, than you should do 2 things: 1) The TCC code should be [19] since your SPI1 TX transfer is using paramset[19]; 2) you should enable either bit 22 or 23 in OPT (depending on whether you want to do transfer complete chaining or inter-mediate transfer complete chaining). Please see table 17 of EDMA user guild. Right now I don't see how paramset[19] can be triggered.

        Thirdly, your  paramset[7] is linking to itself which is usually not a good idea. You should allocate another paramset and link to it.

        Your SPI1 TX transfer may also need another paramset to link to. I am not sure since I cannot figure out what exactly you are trying to do.

        Paramset[18], [32] and [33] look good.

        One question: for each GPIO interrupt, do you need to transfer 12 x 128 bytes for SPI TX, or you only need to transfer 12 bytes for SPI TX? If it is the former case, then probably you have to let DSP receive SPI TX completion interrupt (for every 12 bytes) and re-trigger the next SPI1 TX transfer because GPIO is only synced once with the interrupt.

  • According to the C6748 datasheet table 6-12 for EDMA Synchronization events, event seven is mapped to GPIO Bank 1 interrupt. I can verify that every time a Bank 1 interrupt fires, it executes paramset[7]. Besides, table 6-5 refers to clock frequencies at a voltage operating point. I believe you meant table 6-6 which refers to DSP interrupts through the ECM which is different that the event controller for the EDMA.

    For your second point, I currently am not chaining. Since the GPIO event loads the SPIDAT1 register for a transfer, once this byte transfers, it triggers a TX event automatically switching over to paramset[19] which is configured to only transmit 11 (0xb) bytes..

    Each GPIO transfer triggers the transmission of 12 bytes. I need 12 and only 12 bytes transmitted every GPIO event. 128 events is the full size of the receive ping/pong buffers. Every GPIO event from here till potentially the end of time needs to trigger a transmission of 12 bytes on the SPI. The data being transmitted is in-material, it is the SPI CLK output to clockin new data that is important.

    The problem I have is this. Gpio event triggers transmission of 12 bytes. After the last byte is transmitted by paramset[19], EDMA posts EVT 19 to the controller since this event is still enabled. Since paramset[19] is now a NULL paramset, and EDMA miss event happens. I can not have paramset[19] auto reload, since if EVT 19 happens while paramset[19] is valid, it will continue to xmit regardless of input from the GPIO event.

    I will change and have paramset[7] link to a reload paramset.

  • Sorry for the confusion. I was looking at the interrupt table.

    Now I have a better understanding of what you are doing. I am not sure why another SPI TX EVT will arrive after the last last byte is transferred. Anyway, if the event will come, maybe you should link paramset[19] to a dummy paramset which transfer a byte from/to the same memory location, i.e. SRC=DST. In that way, at least you can avoid the edma event miss error.

  • Due to priorities at work, I have not been able to try this suggestion yet. I will let you know by Monday how it has turned out.

  • Finally got it working. Linking to the dummy set was key in the final solution. Here is what I finally ended up doing.

     

    [19] = {SPI1 TX Event} 0x01C04260    Dummy Set

                    OPT = 0x81113000

                    SRC = 0x1182DF40

                    A_B_CNT = 0x000B0000

                    DST = 0x01F0E03C

                    SRC_DST_BIDX = 0x00000000

                    LINK_BCNTRLD = 0x000B4480

                    SRC_DST_CIDX = 0x00000000

                    CCNT = 0x00000001

     

    [35] = {...} 0x01C04460     Dummy Set

                    OPT = 0x81113000

                    SRC = 0x1182DF40

                    A_B_CNT = 0x000B0000

                    DST = 0x01F0E03C

                    SRC_DST_BIDX = 0x00000000

                    LINK_BCNTRLD = 0x000B4480

                    SRC_DST_CIDX = 0x00000000

                    CCNT = 0x00000001

     

    [36] = {...} 0x01C04480    Real TX set

                    OPT = 0x81113000

                    SRC = 0x1182DF40

                    A_B_CNT = 0x000B0001

                    DST = 0x01F0E03C

                    SRC_DST_BIDX = 0x00000000

                    LINK_BCNTRLD = 0x000B4460

                    SRC_DST_CIDX = 0x00000000

                    CCNT = 0x00000001

     

     

    I set the dummy paramset initially to param[19]. This allows the Spi to be enabled without any transfers happening until the GPIO event happens. Param[19] links to param[35] (which has the actual tx parameters), param[35] then links param[36] and Param[36] to param[35].

    Do you have any suggestions on how to ensure that TX and RX stay in sync with each other or a way to flag an error if they get out of sync? If a glitch happens on RX, I could end up with data coherency issues. Thanks.