Go Down

Topic: STM32, Maple and Maple mini port to IDE 1.5.x (Read 690417 times) previous topic - next topic



Try this one.

Its my hacked version of Rays code and it works for me

Note. see my pins for CS and RESET etc , you may want to change these but at least they are in real STM32 ports / pins, not the Maple mini pin numbers (which I generally avoid)
Freelance developer and IT consultant



Thanks for the info on how to use the Maple bootloader on a non-maple board, if you are running linux

I have pasted all the text into a wiki page


I will need to go back and fix the formatting and link the page from the Linux page and the maple bootloader page, but at least its in the wiki ;-)
Freelance developer and IT consultant


I am trying to use the Adafruit libraries for ILI9340 and 9341, and besides the display not showing anything, I have seen that the sketch first reads and set some parameters in the display, and while those show up when using a Mega, they show either as FF or 00 when using the maple.
Victor, if you're seeing Serial output, but not any LCD display, when using the Mega, it may be because you need to have the Reset pin connected, as well as 3.3V to the Led pin. Neither appears to be necessary with the Adafruit ILI9341 "shield", but are with the [ebay] modules.

The Adafruit ILI9341 library h.w. constructor and example both default the Reset pin to -1, but you have to add it in in your sketches, eg.

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, 8 );
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

This is just to get the Rduino to work.



Try this one.

Its my hacked version of Rays code and it works for me

Note. see my pins for CS and RESET etc , you may want to change these but at least they are in real STM32 ports / pins, not the Maple mini pin numbers (which I generally avoid)
Roger, et al:

I did not make the major hacks to ILI9341, see here:

Thanks to madias



Hi Ray,

I was saying that  I   hacked your version, not that your version was a hack :-)

Looking at what Matthias changed, its just in the ILI9341 lib and not in the Adafruit_GFX, and as far as I can tell, by taking a quick look at the code

Matthias has just duplicated the code used by the TEENSYDUINO  sections

I think he could have just changed it so that it read

defined(TEENSYDUINO) || defined (__STM32F1XX__)

I wonder if doing #TEENSYDUINO in the top of the sketch would work even with the stock Adafruit library (If I get chance I'll give that a go !)

Re: Oric Dan's posting about speed.

We could almost certainly speed things up, especially if this device can handle a fast SPI clock rate

I've just checked the STM32F103 reference manual and SPI doesn't have a hardware FIFO, it would be possible write code to implement something similar using a DMA transfer,

But its hard to know quite how much time the code is sitting and waiting for the SPI transfer to finish, and how much time is being spent just building the data to send to the display

I have feeling if we have to implement a software solution to some sort of hardware SPI fifo that may be on the Teensy, that the performance gains may not be that good, as the code to write to the FIFO would need to keep track of the circular buffer pointer and test to loop around etc etc
Freelance developer and IT consultant


Mar 06, 2015, 03:53 am Last Edit: Mar 06, 2015, 04:11 am by oric_dan
It looks to me that everyone is using the same ILI9341 module, so it should handle the speeds. Here is the original Teensy thread.
More here,

So far, I tried the LCD on my 16-Mhz 1284 board, and got the same speeds as shown in post #17. You see his T3.1 at 96-Mhz gave about 10X speedup.

This page shows what the SPI xfers look like on a scope, with the FIFO and SPI clock running 24 or 32 Mhz,

Don't know if this will help anything, but attached is the SPI library that comes with Teensyduino for IDE v1.0.6, for some bizarre reason I couldn't find this version of it on github.



It would be interesting to know how long the Teensy takes to run the whole adafruit graphics test without delays.

I took the delays out and it was 13 secs with Matthia's code

Anyway, cutting to the chase. Firstly we're running the SPI at DIV2 which is 36Mhz. I checked the spec for the ILI9341 and as far as I can tell, thats far faster than the spec allows
Perhaps someone else can read the spec http://www.newhavendisplay.com/app_notes/ILI9341.pdf but as far as I can tell, on page 242 it shows max clock rate cycle time for SPI is 100 nS = 10Mhz

Anyway, It seems to work OK at 36Mhz, which is great, but assuming we are indeed clocking data to it 3 x faster than the spec, this will impact on any optimizations that are done elsewhere in the code, as the bottleneck would become the time to transfer the data not to set it up

Anyway.... Assuming we can use DIV_2 i.e 72Mhz / 2 = 36 Mhz (which is what my oscilloscope is showing)

I setup a timing test to see how long it takes to go the whole Adafruit graphics test, after having removed the delays, and its 13.27 seconds

Looking at where the code is possibly wasting time, I looked at how the data is sent from spiWrite() in the library which calls SPI transfer, however SPI transfer both writes and reads, hence is doing something we don't need in this case.

So I tried calling SPI write() But the total time goes up to about 23 secs :-( - so this spi.write() is not at all effecient :-(

However if I copy the code from SPI.transfer() into SPI.write() and remove the stuff that does the read !
I can get this time down to 11.6 seconds (i.e about 12% faster)

And one more trick, if I don't wait for the SPI busy flag before existing the function, but instead check and wait when the function is called i can get the time of the whole test down to 10.4 seconds

Which is 21.6% faster

As a further optimisation of the write() function, I tried to move the "wait for TX empty" wait loop to the start of the write function, but although data continued to be sent, the display stopped working.

But if I put a small delay at the end of the write() function, simply by calling the function which checks the TX buffer (but didn't do anything with the result), it does work.

and total time for the test is now down to 9.18 seconds, i.e just over 30% faster than before !

Like I initially said. It would be interesting to see how long it take the Teensy to run the same test, as it looks like we are in a lot of places just being limited by the amount of throughput that the display can possibly handle

If I've got this correct... In our case i.e using 36Mhz clock, the best option appears to be to create data and send it immediately, rather than building a buffer. Which is what the lib generally appears to do.

If anyone wants to have a go themselves, here is the replacement spi.write

Code: [Select]
void SPIClass::write(uint8 byte) {
  //  this->write(&byte, 1);
while (spi_is_tx_empty(this->spi_d) == 0); // "5. Wait until TXE=1 ..."
while (spi_is_busy(this->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
spi_tx_reg(this->spi_d, byte); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."

Freelance developer and IT consultant


Thinking a bit more about my optimisation, I think its boy working because the clock rate is so high and all the data is getting clocked out in around 16 cycles.

If it was going slower, the code that controls the Chip Select line will disable CS before all the data was clocked out, which is probably why I had to add a small delay.

It would work however if we were using hardware chip select.

But just copying the write parts of transfer() into write(byte) gives around 10% and I think should be stable

I.e but we can't exit from write() until the transfer has finished.
Freelance developer and IT consultant



Try this one.

Its my hacked version of Rays code and it works for me

Note. see my pins for CS and RESET etc , you may want to change these but at least they are in real STM32 ports / pins, not the Maple mini pin numbers (which I generally avoid)
It works fine for my display too, a 2.2 or 2.4" from ebay.

Now I have all the parts I wanted to use working separately, I should be able to put it all together.

I would suggest that you add the library to the repo, as it seems to work fine.



Mar 06, 2015, 09:16 pm Last Edit: Mar 06, 2015, 09:20 pm by madias
goodies, goodies, I've some goodies for you :)
How about a big 12864 LED-Graphic-Display (ST7920 chipset) for about 7 USD (free shipping?)

Best of all: It can be driven in serial mode, and you need only 2 pins! (Data and Clock, no slave select pin!)).
And uncle Matthias did the bored stuff for you: adapting a driver library
I didn't rewrote the u8glib library, because it's MUCH to huge, because it supports many displays. I found the arduino library from D. Crocker, Escher Technologies Ltd. (well known in the forum) and played around with it.
I added STM32-Arduino support, using any pin you want. There is no low level pin toggling stuff inside, just plain "digitalWrite". Reason: I tried out some direct commands, but they are much too fast for the display. Also SPI mode isn't implemented (no benefit for myself). I also added some new features like : new fonts, box, filledbox, ...
If somebody feel bored, he can eliminate all the PROGMEM code out of the lib. (The progmem macros of STM32-arduino are doing their job well, so I didn't have done it myself)
Drawback: The display MUST be driven with +5V (only for VCC not the signal lines, 3.3V is ok for them), so maple mini users have to tinker. 



Thanks, I will order some of those to test with.


I will add the ILI9431 lib to the repo


Not sure what is useful on that Elektor page, free hardware if they accept a development proposal, but then lots of hard work for a board worth less than $50. Better just to buy a board, unless you are an unemployed firmware developer who really wants one of those boards.


I think I will modify SPI write(byte)  as discussed above, as I think I can get around 10% more speed than th current implementation, with no side effects, it may also be possible to speed up SPI write ( *byte , length) as well. But as write byte seems the most commonly used command in these libs I will update that

I will also change the ILI9341 lib to call write instead of transfer as appropriate

Although it would be possible to use an interrupt driven FIFO style SPI input buffer, I have a feeling that it would not work on most libraries, especially for the ILI9341, because of the other control lines and also because of chip select being toggled in the library rather than by the SPI library.

Hence the SPI write command would return before the data was sent, and the library would most likely drive chip select high to deselect and the pending transfer would fail.

Even if chip select was being controlled by the SPI lib; if there are other control lines, these could be toggled at the wrong time by the library.

So to support asynchronous SPI transfers would require additional SPI lib API functions for the library to determine if he Tx FIFO was empty or still transferring, I.e or perhaps have a isBusy() function.

Ray. Do you have you Teensy yet ? I wonder how they make the FIFO SPI work, perhaps heavily modified libraries.

Freelance developer and IT consultant


A quick message for all owners of the ILI9341 TFT with touchscreen (2.4 or 2.6 inch, they are sold for about 1 year on ebay and aliexpress).
As in the last threads wrote, the best driver is the modified adafruit ili9341.
But for the touch panel the "utouch" library of Henning Karlsen is doing the job, because the display is using a special touch panel chip, which is (only) supported by the utouch library. the utouch lib should be compatible without changes for STM32. So mix both libraries together.


I gave the links for the Teensy in #1745.


Mar 07, 2015, 12:06 am Last Edit: Mar 07, 2015, 01:09 am by rogerClark

I've taken the work done by Matthias and have put it into the repo, with some minor modifications

I've tested the code with the latest version of the Adafruit_GFX lib and it works fine.

I did one minor speed improvment, calling spi.write instead of spi.transfer

But to get this speed improvement, rather than it going slower, you need to get the updated spi.c as well

Or just the whole repo !

Freelance developer and IT consultant

Go Up