MCF52259 SPI driver very slow

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MCF52259 SPI driver very slow

1,460 Views
dmarks_ls
Senior Contributor I

I'm currently writing a device driver for a SPI peripheral, utilizing the MQX-provided QSPI driver (currently running in polled mode).  I've noticed that while running the CPU at 40MHz and the QSPI clock at 1MHz, there's always a ~270us delay between the conclusion of an operation (_io_read, _io_write, fflush) and the next operation or raising of chip select.  Looking on my scope, if I perform the following actions on an open fd handle:

 

_io_write(spi_fp, &cmd, 1);

_io_read(spi_fp, &recv_data, 1);

fflush(spi_fp);

 

there is zero delay from assertion of chip select to the start of the SPI write, but 270 us from the end of the write to the start of the read, and another 270us from the end of the read to the deassertion of chip select.  If I do a two-byte write, the two bytes go out very quickly, but there's still a 270us delay from the end of the write to chip deselect.  Given that my SPI peripheral is a UART, this is seriously killing performance.

 

What could possibly be taking so long?

 

(CW 7.2, MQX 3.6.1, running on M52259EVB w/ SPI device daughterboard)

0 Kudos
3 Replies

474 Views
PetrM
Senior Contributor I

Hello,

 

there are some overheads I can think of: ram target is generally slower than flash target, debug target is slower than release target, the POSIX api (read/write/flush) also consumes some time and there's also overhead of setting up the QSPI queue for 1 byte each time.

Sorry, I can only recommend you to use interrupt mode.

 

PetrM

 

0 Kudos

473 Views
dmarks_ls
Senior Contributor I

Well, I experimented with interrupt mode by running the MQX-provided SPI/ISPI example, and running the CPU at the stock 80MHz instead of the ~40MHz that more closely matches my target hardware.  But the inter-character gap only came down to about 190us instead of 270us.  Your explanation of where all the overhead is coming from makes sense; I'm just disappointed that the resulting performance of the QSPI peripheral is so poor.  I've had to modify and optimize my UART driver to merge written bytes together whenever possible (I had to clone/rename the serl_mcf522x driver framework and perform significant modifications).  It's a good thing I don't have to support a baud rate above 19200.

 

If I had this design to do over again, I would abandon the SPI port entirely and use a CPLD to allow the UART to share the MiniBus with the other chip we have on the board... or maybe select a ColdFire that has more than one memory chip select.  I just can't rely on the SPI port to do anything involving high bandwidth.  Thanks for the insight.

0 Kudos

473 Views
tkavan01
Contributor I

I wrote my own qspi driver because I too found the mqx dismally slow, after digging stupidly deep with hours of staring at an oscope I found the largest issue was the check to see if a transfer has completed.

My line of code looked like this

   while((MCF_QSPI_QDLYR & MCF_QSPI_QDLYR_SPE) == MCF_QSPI_QDLYR_SPE)
      {;}
In my case I am transmitting 192,000 bytes, at ~8.9 MHz, I found that just the action of looking at that register cost me on the order of 3.24 us, when the entire byte transmit time was about 0.92 us, So i experimented with using nop's in it's place and found I could shave that time down to 0.84 us and still have the comms work correctly. I suspect this might be part of the issue as well.

 

Trevor

0 Kudos