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.

Problem using FTCA interrupt

Other Parts Discussed in Thread: HALCOGEN

The enclosed example file illustrates two separate issues that I am experiencing using the TMS570LS31USB development kit.

The code configures the HET1 PWM0 to drive a 1kHz 5% duty cycle pulse on HET1_10.  This in turn drives TG1 for a mibspi1 TX burst.  DMA Ch0 is automatically triggered to move the RX buffer data into system RAM.  The DMA FTCA interrupt is enabled and triggers VIM Ch 33 which runs T0_Cisr when this data transfer is complete. 

Issue #1: The T0_Cisr routine is run successfully once.  It then triggers a resetEntry() function.  With a similar architecture, I have observed this T0_Cisr routine getting triggered three sequential times from a single mibspi1 TX event before triggering the resentEntry() function and locking up the processor.  It appears that I am not properly servicing the VIM Ch3 interrupt, but I have been unable to identify what I am missing.

Issue #2 (unrelated to issue #1): When T0_Cisr runs, it triggers DMA Ch3 to load the SPI2 DAT1 TX register.  The resulting loopback RX does not match the TX.  It is as if I have not properly configured the DMA controller to coordinate with the SPI2 TX_DMA_REQ.  I have reviewed and emulated the existing examples and postings but I have not been able to get the DMA TX/RX to work reliably using SPI2 (which is a traditional SPI, not a mibspi).

Please advise. Thank you for your time.

TIsupport_DMA.zip
  • Scott,

    It take CPU 12VCLK cycles to read a peripheral register. If the interrupts happens too often, you will run into problems caused interrupt overrun. The advantage of using DMA to move a block of data without CPU intervention. We would be able to help you better if you can tell us what you would like to achieve at system level. From your post, mibSPI1 transfer is triggered every 1 ms by HET1. How many data are in the transfer? How about SPI2? You also need to remember that the transmit and receive happens simultaneously on SPI. 

    Thanks and regards,

    Zhaohong

  • Zhaohong,

    Thanks for the quick response (and all of the expert points).  I used HalCoGen to generate the drivers and it set VCLK=100MHz.  That means a peripheral access will take 120ns.

    The system-level concept is to use the TMS570 to receive 1kHz data from a sensor connected to mibspi1, buffer that data into a larger block, and then, at a lower rate, output the block data to a storage device connected to SPI2.  I created this example to illustrate the issues I am seeing when I attempt to construct that architecture.  The USB dev kit only has SPI1 and SPI2 on the output headers, so I am using those.  This architecture is intended to fully utilize the DMA to offload the processor from data handling.

    The example uses mibspi1 bursting 8 elements, 16 bits/element, 20MHz buadrate, Buff Mode=7.  That comes out to 8*16/20e6=6.4usec for the TX/RX and 8*0.12usec=0.96usec for the peripheral access.  The mibspi1 TX/RX is working successfully and the Ch0 DMA triggers the FTCA interrupt and the associated T0_Cisr successfully.  However, after completing the first pass through the T0_Cisr routine, the processor calls resetEntry() and then locks up.  The T0_Cisr code successfully clears the DMA GINTFLAG by clearing FTCFLAG, LFSFLAG, HBCFLAG, and BTCFLAG.  I measure 12.5usec from the rising edge of the HET1 trigger to the completion of the T0_Cisr, which is well within the 1000usec real-time allocation for the process. 

    Question 1: Is there something else required from the interrupt service routine to prevent the resetEntry()? 
    Question 2: What causes the resetEntry() routine to be triggered?

    For the SPI2, the T0_Cisr triggers a software request of the DMA to shift out 64 words, 8bits/word, 25MHz buadrate (total of 20.5 usec). This is within the 1000us real-time allocation.  Monitoring the SPI2 CLK and MOSI channels, I see only three of the 8-bit words come out (~1usec) ... the first, third, and seventh.  The spi2_RX array in system memory, where the DMA is writing the SPIBUF data, receives 16 words ... the first word followed by 15 repeats of the 11th word.  To me it appears there is a timing coordination issue between the DMA and the SPI2.  The example code shows how I am configuring the DMA and SPI2. I offset the SPI2 DAT1 address by 3bytes so that the 8-bit DMA transfer is correctly placed into the DAT1 register.  When I watch the DMA primary/working control packet registers they appear to be sequencing properly, but the SPI2 output values are not correct.  Section 25.7 of the TRM states:

    "When a character is being transmitted or received, the SPI will signal the DMA via the DMA request signals, TX_DMA_REQ and RX_DMA_REQ. The DMA controller will then perform the required data transfer."

    Question 3:  How do I verify that the DMA is waiting for the TX_DMA_REQ signal from SPI2 before loading the next byte?  Stated another way, how do I control the timing of the DMA loading the SPI2 DAT1?  Since the DMA is working as I expect on the mibspi1, I am assuming this second issue is unique to the SPI2.

    Thank you again for your time.

  • Scott,

    First of all, I would suggest you to test SPI1 and SPI2 separately to make the debugging easier.

    (1) For SPI2, you can run a test repeatedly in the mainloop to see if it works. I am attaching a SPI_DMA example. It is not a complete CCS project, but it would provide you enough information about how to set it up.

    5417.spi_dma.zip

    (2) Reset is normally caused by software error. You need to declare T0_Cisr() as an IRQ interrupt service routine. You can can see how to do it in the attached example. Since you set it as a normal fuinction, the stack is not handled properly. I believe that it is the reason for reset. If you compile the code in 16 bit Thumb2 mode, you need also the set the ISR functions as a 32 bit function. You can also see it from the attached example.

    Thanks and regards,

    Zhaohong

  • Zhaohong,

    I noticed the latest release of HalCoGen 03.05.01 fixed my first issue by now automatically generating the ISR and associated pragma calls so that the FTCA interrupt works correctly.  Thank you.

    Regarding the use of DMA with SPI2, I reviewed the SPI_DMA example that you provided and distilled it into the enclosed example that runs on the TMS570 USB dev kit to illustrate the issue that I am observing.  With FLAG_POLLED=1 and NUM_TX=64, the code successfully executes a polled TX/RX of 64 bytes on SPI2. 

    However, when FLAG_POLLED=0, the code illustrates that a DMA TX/RX of the same 64bytes on SPI2 is erratic.  Only 17 bytes are seen on the MOSI line, and they occur in 6 bursts of 2-3 bytes each.  If the RX DMA is disabled, then the SPI2 MOSI line shows a 5.4usec burst outputting 11 bytes, but not the full 64bytes.  The DMA is writing 64bytes to the SPI2 DAT1 register, but the SPI2 is not reliably transferring the data out the MOSI line. 

    When NUM_TX=1, the DMA TX/RX with SPI2 works.  This indicates that the code setup is correct, but it only works for a single byte transfer which is better done directly to the registers rather than using DMA.  When NUM_TX=2, the SPI2 MOSI line shows that both bytes are transmitted, but the received data is just the last byte repeated twice.

    My interpretation of these results is that SPI2 works in a polled mode, but has a memory access conflict when using DMA.  Does anyone have a work-around or an example that enables the use of DMA on SPI2?

    Thank you for your time.

    Scott

    SPI2_DMA_Ex.zip
  • Scott,

    Your DMA setup is wrong. You need to have the following.

    (1) Enable RX and TX DMA requests in the SPI2 module.

    (2) Enable Two DMA channels with hardware requests. One DMA channel is triggered by SPI2 TX DMA request and the other one triggered by TX DMA request.

    When there is data in SPI rx register, SPI sends the rx DMA request. It triggers DMA to perform a frame transfer moving data from SPI rx register to a buffer you defined in system RAM. Please take another look at the example I sent. It has everything you need.

    I can assure you that there is no hardware issue with SPI2/DMA operation.

    Thanks and regards,

    Zhaohong

  • Zhaohong,

    Got it.  Thanks. Everything is now working.

    For anyone else struggling with this issue, the TRM states:

    The DMA controller also supports a mix of hardware and software requests on the same channel. Note
    that such interchangeable usage may result into an out of sync for DMA channel and peripheral. The
    application needs to be careful as the DMA does not have a built-in mechansim to protect against this loss
    of synchronization.

    When I post a SW channel enable to trigger a DMA block transfer to the SPI2 DAT1 or DAT0, the DMA gets out of sync with the peripheral and some of the data does not get transmitted.

    When I follow the example and use a HW channel enable to trigger a DMA transfer to the SPI2 DAT1 or DAT0, the DMA and peripheral remain synchronized and the data is transmitted without loss.

    I was focused on using the SW channel enable architecture and missed the cautions in the TRM and the illustration in the example.  Thank you for your help.  All of my questions have been answered.

    Regards,

    Scott