Because of the holidays, TI E2E™ design support forum responses will be delayed from Dec. 25 through Jan. 2. Thank you for your patience.

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.

Real-time SPI support with DMA, has it been done, is it feasible?

Other Parts Discussed in Thread: TLC5951

Hi and thanks for any information in advance,

I'm using a beaglebone to process video and flush pixel data to serial LED drivers through SPI (TLC5951). My plan is to use the virtual frame buffer "example" that is part of the linux kernel which will act as an interface between mplayer (or other video application) and my driver. My issue though, is that the lines need to update once every 200us worst-case with about 4k of data. I've done the math, and the high-level numbers suggest it 's possible, 48MHz gives me plenty of time, more if I can use both ports simultaneously. 

My first problem is that I have a 3.2.21 kernel with the Xenomai/iPipe patches working properly but this version of the kernel does not have DMA support with the McSPI driver, the spi subsytem becomes unresponsive when a transfer large enough to warrant DMA is requested. I modified the McSPI driver to always use PIO, but this will likely be a problem when I need to start decoding video on the same system. 

My second problem is that even when the spi subsystem is only using PIO mode, requesting transfers via a real-time task is very unstable, I've tried to guard it using spi_async (which is "guaranteed" not to sleep and safe to use in interrupt handlers) and a mutex that is unlocked by the complete callback, but I usually only get fewer than 10 transfers before the SPI subsystem becomes unresponsive and I need to reboot.

Both of these problems make me consider using portions of the starterware code to make a bare-bones application-specific driver to bang the dma and spi registers manually, but I don't have a lot of experience developing in the kernel and I don't know where to start with code that assumes there isn't already an operating system running. Is this approach feasible or should I go down a different road? Or if there's something like this already out there that would be fantastic too ;)

-Jon

  • I ran a test using a sending period of 1ms so I could get a better idea of how SPI reacted to load, and it looks really bad. Sitting idle, I get about 50us delay between the spi_async call and the data leaving the port, but it is extremely sensitive to cpu load. And it seems like the mutex isn't doing its job because if the callback doesn't occur before the next timer interrupt (where spi_async is called) the kernel crashes really hard. I've tried this five times and it three times it locked up, but twice it died with a really nasty stack trace from the scheduler, specifically in pick_next_task_fair().

    This just re-affirms my suspicion that the normal spi subsystem will be incompatible with my real-time needs.

    My original question still stands, what is my best option from here?!