Problems setting SPI Speed

I have been trying to eek the most out of my SPI display. I can’t figure out how to increase the speed of the SPI port. I have tried to change the clock divisor using SPI.setClockDivider(SPI_CLOCK_DIV2); but I don’t see any difference. I have tried SPI_CLOCK_DIV2, SPI_CLOCK_DIV4 and some others and can’t see any difference in the timing on my code. - I have not yet looked at a scope of the signal. Reading the web on what this function call does it very confusing. Can someone explain how the SPI.setClockDivider() affects the speed at which we can clock data out on the SPI port?

Also there was some discussion over using the builtin DMA on the SPI port, does the Spark use the DMA or is it using software SPI?

I need to get faster updates on my LCD display. Unfortunately there are not enough I/O ports to use I2C, 8-bit I/O to a display and also read the Touch Screen - otherwise I would use an 8-bit interface on the display. So I was hoping to push up the speed on the SPI to see if I can get acceptable refresh rates.

1 Like

@mtnscott the issue may be with the library and not with the SPI speed. Which display are you using?

1 Like

@peekay123 I’m using the Adafruit_ILI9341 library. If you look at line 115 in Adafruit_ILI9341::begin() I call SPI.setClock Divider(SPI_CLOCK_DIV2), but as I stated earlier any value does not seem to make a difference.

Now - I noticed that in the write function there are four calls to digitalWrite and I was starting to wonder if that may be limiting the speed of transfer.

I will take a look at the library tomorrow to see what could be optimized. Do you have any other SPI devices?

Not handy. I do have a scope so I can look at SCLK. That will tell me if the clock is being adjusted with my calls to SPI.setClockDivider() I’m off to the slopes tomorrow so I will take a look tomorrow evening and report back!

@mtnscott, from what I see, the library is riddled with code that can be optimized or removed. For example, before some SPI read commands, the SCLK line is written LOW. I cannot think of any reason to do this since the hardware SPI returns the line to the correct state after each operation. Also, the digitalWrite() commands can be changed to direct bit set commands. If all control lines are on a single port, a port set command could be used. :smile:

2 Likes

A lot of Adafruit libraries that have been ported to Spark Core implement SPI with digitalWrite and digitalRead calls, rather than just using the SPI hardware supplied on the Core. I don’t know if this is how the original Adafruit libraries are written or if this is only how the Spark adaptations are done.

I was using an Adafruit MAX31855 thermocouple amplifier library and I wound up stripping the library entirely and reimplemented it. Either the original Adafruit library was written to be ported to very basic processors, or the person who ported that library to the Spark didn’t know what they were doing. There was a lot of code that implemented 2’s compliment handling on unsigned ints when all they needed to do was use a signed int, for example. I took that library down from about 400 lines of code to maybe 15 lines, and I wasn’t even being clever in my implementation.

The takeaway I’m trying to give here is that one should probably look over the libraries they’re using, if they can. There’s a lot of foolishness going on in some of them.

1 Like

@peekay123 Thanks a huge bunch, the display is much faster now. If you are comfortable with this version I’m happy to update the library published on the IDE to use this optimized version.

@naikrovek You make a good point. I just looked at the libraries I am using for the display, there is potential for me to improve the performance by eliminating some extra functionality that I don’t need. I will take a look and see what more I can squeeze out of this.

My overall goal is to be able to have an effective LCD display for my project. Since the Spark does not have enough I/O pins to use an 8-bit interface to an LCD (11 pins are actually needed) and if you add a touch screen (4 pins) then you can’t do anything else with the Spark. I am wondering is SPI can be fast enough to draw graphics efficiently.

Or there might be other reasons, too. e.g. a quick and dirty port for someone else, who was just happy with that, or …

Please, don’t jump to conclusions without knowing all the individual cases.

@mtnscott SPI can be incredibly fast. I2C is limited to a few hundred kHz; SPI on the Core with SPI_CLOCK_DIV2 set would be 36MHz. Not too shabby.

@scruffR I just looked and the original Adafruit library was written to bitbang SPI. Presumably so you weren’t limited to the actual SPI pins on whatever Arduino chip you are using. I wasn’t jumping to conclusions; it’s clear that the Adafruit is lacking in lots of ways.

One point that is sometimes forgotten is that you can also use the RX/TX pins as digital IOs, so you actually could still use SPI or I2C parallel to your above needs.

@mtnscott, yes! Go ahead and update the published library :smile: To create a fast display using SPI, you would ideally have a two page display buffer and updating the display one-screen at a time, allowing a very fast (possibly DMA) dump to the screen. For the ILI9341 and a 320x240 colour display, that is beyond what the Core or even the Photon can handle as RAM goes. For that size display and assuming 16-bit color, that requires 153KB or RAM! So you essentially are drawing directly to the display instead of RAM and that is what is limiting your display speed. Ultimately, the display speed will be limited by how fast you can draw your pixels, less by SPI speed. Optimizing your code is a good strategy.

Another approach is to use a “smart” display which does all the work like the Digole LCD and OLED displays. Unfortunately, they don’t have touch screens as of yet. There are other display/touch options(eg. www.buydisplay.com) you can explore but you get the idea. :smile:

Please watch your tone here.

We are all here to help using our free time trying to help people in the community. If you feel that something is wrong, send in the PR and get it fixed since you sound like you know things better than the experienced people here.

@naikrovek, the SPI clock in the STM32F103 clock tree is system clock (72MHz) divided by 2 or 36MHz. So the fastest SPI clock you can get (DIV2) is 18MHz. I have to look in the firmware and the processor specs if DIV1 is possible. However, I don’t believe the ILI9341 can handle more than 20MHz. :smile:

I completely agree that often, Arduino libraries are not optimized for the Core. That’s why we are all here! :stuck_out_tongue:

@kennethlimcp, I believe @naikrovek was referring to Arduino libraries that are not written optimally but work nonetheless. He is just trying to say that when we port a library, it is worth looking carefully at the code since there is often “a lot of foolishness” that can be cleaned up. No harm intended I believe. :smile:

1 Like

Let’s leave negative comments out of the community irregardless of Spark, Arduino or other platforms.

That’s what makes our community so active and popular afterall.

I am a beginner and writing libraries is not my strength but sharing the library was to help people in their limited knowledge and capacity. Don’t see why we should even criticise them. :wink:

2 Likes

For instance this was a superfluous comment, since it fails to leave room for other reasons and sounds somehow judgemental

2 Likes

@kennethlimcp, I agree. If you have nothing good to say, then don’t say it (Thumper’s mom in Disney’s Bambie). It is true that often libraries are written for specific (older) platforms under specific circumstances. Heck, if everything was perfect, there would be nothing for us to do! I augmented the GFX library to create the mfGFX library but I am sure someone else could optimize it better than I did. I wanted something quick and easy for others to use. The spirit of Open Source is to share, improve and build on each other’s work. :sunny:

3 Likes

@ScruffR, @kennethlimcp, @peekay123, @naikrovek

  1. I’ve been guilty of publishing a terrible library. Many times I am just trying to get stuff to work, so I search the internet, locate a library, hack it to get it working and move on. Lots of times I don’t fully understand the code, and not until later when I can invest the time do I discover the how bad it is - and that’s assuming I continue with that project. :smile:

The Spark target audience is typically novice, arduino type people - gosh I have even seen some really surprising comments around hardware - but heck - we are all here to have fun!!

Yes, i’ve been frustrated when I discover that something i picked up off the internet was not as good as I had thought - but it did save me time initially when I was starting my project.

So - it’s a pot luck of contributions - lots of times there are ‘updated & optimized’ versions of software that never make it to public status.

I just try and keep a realistic expectation of what’s out there and then I try not to get (too) frustrated when I find something ugly after banging my head against the wall for hours :wink:

BIG THANKS TO THIS COMMUNITY - IT’S BEEN ONE OF THE BEST I HAVE BEEN EXPOSED TO!!!

3 Likes

SPI_CLOCK_DIV1 is undefined :frowning: - oh well.