Go Down

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


Roger - I am not criticizing  - I am full of gratitude to you and the other code gods here!

I have put up a first draft of my progress so far here -


If I can run I2C I can do most of what I want by linking to a router running OpenWrt



No worries.  I think people have miss understood your first posting

I will read your web page and see how if the file structure looks similar to my OSX ;-)

Freelance developer and IT consultant


Hi Victor

I've had a quick look at the DMA code in both the STM32 dma and the Due dma libs that you added via the pull request

It looks like both of those implementations have a while() loop, which waits for the DMA transfer to complete.

Can you confirm whether this is your understanding of how they both work.

If this is true, there is a faster way to operate the display, by using 2 buffers instead of one.

(not sure if a callback is needed, we can probably just put a while loop in the start of SPIDMATransfer() which waits for the current transfer to complete before starting the new one.)

Freelance developer and IT consultant


Mar 22, 2015, 11:05 pm Last Edit: Mar 22, 2015, 11:07 pm by victor_pv
Roger, that is right. The way it works right now is waiting until a DMA transfer completes.
That is the way the library worked before for the DUE, so I kept the same way, but I definitely agree that using a double buffer could be better.
Now, for the graphic library, for normal functions, it really could do away with the buffer altogether.
The fact is that the library only draws in one color at a time, so the buffer is just a sequence of a pair 8bit numbers repeated up to 320 times, or how many pixels wide is the line being drawn in the screen. It is a waste of memory, plus a waste of time filling that memory in a for loop.
The DMA controller can be set to transfer from a 16bit memory position, to an 8 bit peripheral, and can be set to NOT increment the memory position. It is actually used in one of the functions that is sending FF while receiving data.
I have to test it, because we may need to invert the bytes making up the 16bit int, but if we store the color data in the right order in 1 single 16bit integer, we can set the DMA controller to send that as many times as we want without incrementing the memory.

For uploading any kind of bitmap, yes, the doublebuffer would definitely help a lot. I think we commented on that before, instead of checking until the DMA transfer is over in a while loop, we perfectly can return right way. Once the transfer is over it calls an ISR that set a Boolean value to false, indicating no transfer is happening.
Now, that would require more modifications in the library, as before any other SPI operation or DC or CS change, we have to confirm there isn't any DMA going on. There are many places in the library where the DMA transfer is called, and right next DC is changed to write a new address to the screen controller, and then another DMA transfer is called. If those functions do not wait for the previous DMA to finish, they would mess up with the DC line.


Hi Victor,

Thanks for the detailed explanation.

Re: 16 bit transfer

I did briefly look at that, but didn't have time to get it to work even for normal transfers

One thing that I noted about switching to 16 bit, (or back to 8 bit) is that the SPI device has to be disabled when you make that change - which will take several clock cycles, so 16 bit transfers will only be useful for some operations like writing a whole buffer of data.

Doing it for individual setPixel commands would probably not yield any speed advantage

BTW. Did you look at the Teensy implementation of the ILI9341 library.  Paul achieves the very high speeds using by combining parts of the graphic lib (the line drawing in particular) inside the ILI9341 lib. But I guess its similar to what the Due version does

The Teensy has a hardware FIFO, so they can just keep writing bytes to the FIFO and it handles the DMA transfer, without needing any additional code.

We could use a circular buffer to act as a FIFO, because the DMA had that option, but of course we'd need handle the code side of writing to the circular buffer, so that it wraps around at the end. However using "if" statements in ARM can often be a bigger code overhear than lots of other operations. Hence using a circular buffer could end up taking longer than other methods ;-(

Re: Checking whether DMA is complete in other SPI methods

It think this is OK within a library, but my concern about adding tests for DMA into the main SPI library, is that it will lower the speed of the library for the 99% of the time when its not being used for DMA

I still think that perhaps we should add a SPIDMATransfer to the main SPI library, e.g. a bit like the Due ILI9341 lib has. So that each library doesn't need to have their own implementation of this e.g. it seems wasteful having to add the same code to the SD library as well  (I know the Due lib is both SD and ILI9341)
so it doesnt apply in that case

We could write 2 functions a SPIDMATransfer() into which you pass 2 buffers (write and read), - we could test to see if either buffer was null and configure the DMA transfer accordingly e.g. if only write was needed.

We probably also need a function to check if the DMA is still transferring, and we'd also need to "block" i.e have a while() loop at the start of the SPIDMATransfer function, so that if DMA was already in progress it would just wait (and "block" the main flow)

Does that sound like it would be worth doing ? (or be generally useful)?
Freelance developer and IT consultant


Mar 23, 2015, 02:04 am Last Edit: Mar 23, 2015, 02:12 am by victor_pv
I agree having to check if DMA is finished before each other transfer is a big waste of time, I started rewriting the library that way. I made so many small changes to try to improve speed even a bit more, that I don't remember if I finished that one, or was something else, but resulted in losing a big of speed in the screen test.

About the Fifo, I thought on it, then I checked the specifications for the chip to see if we can read where the DMA transfer pointer is at any given time. Not possible :( so even though we could enable circular mode, and keep a pointer on where are we writing, we wouldn't be able to know if we passed ahead of the DMA controller. According to the specs, you can write the start address and fire the transfer, but the pointer is only writable and not readable. I didn't check thought to see if there is any pointer that tells you how many bytes has transferred so far, so you can write a routine to see within a circular buffer what position would that be.

Having the SPIDMA transfer is possibly the best solution, so it can be used for anything.
That way you can use the library to initialize the display and draw lines and text, but for dumping a whole bitmap you could call the library function to set the tft coordinates, fire a DMA, while the DMA is going prepare the next scan line, when it is finished set new tft coordinates and fire another DMA.
In all reality, that's fairly easy to do as of right now. We can copy the functions I wrote in that library, and take the While out.
Currently I think it passes only 2 parameters, the buffer pointer, and the byte count.
EDIT: Just re-read what you wrote, I said basically the same again.
I only have 1 concern. I don't think the DMA transfer function should wait with a while inside, again wasted time, I would rather make it return an error code. The main program can check the return and know, well this didn't fire, I'll do something else and try again in X time. Or if there is nothing to do, keep retrying, but if it doesn't finish in certain period, for whatever reason, can call an abort function. That would be better than unexpectedly sitting in a while loop, don't you think?

Re. the SDcard. I forked the new sdcard library and added the code for DMA to it, but I couldn't get it to work. I only have 2 sd cards around so I'm not sure if it is the code (most likely not, as it is almost to the letter the one I used in the ili due library), or the new library that doesn't work fine in the maple, or rather my sdcards.

What sdcard library and sketch have you used successfully in the Maple so far? I just want to make sure my SDcard get detected so I can use them for troubleshooting.


Mar 23, 2015, 02:15 am Last Edit: Mar 23, 2015, 03:30 am by rogerClark

Just a quick reply to part of your post

Re: SD

I just use the CardInfo demo that comes with the IDE

Last time I checked it worked OK for me, but I've not tried the one in 1.6.1 or 1.6.0 and its possible they change something ;-(

All I needed to do was change the CS line to match the one I was using for the SD card

PS. You may want to unplug your display if it doesn't work

I will try to take a quick look during lunchtime, to see if cardinfo from 1.6.1 works (i.e in about 1/2 hour) !



My test rig isnt working on the SD Card any more :-(

I suspect its a wiring issue

Unfortunately I don't have time to investigate whats broken, until this evening

Freelance developer and IT consultant


Mar 23, 2015, 04:03 am Last Edit: Mar 23, 2015, 12:14 pm by mrburnette

I caught Andy Brown's recent YouTube vid of a STM32 graphic co-processor board for UNO.  Thd video is a bit boring until he demonstrates the performance.


The article is here:

As he is using DMA in the STM code to access external RAM, I thought it may make for some interesting browsing.  He has also implemented command buffer queuing but i have not looked into how the AVR code is implemented (blocking?).

I do not know if any of his techniques for DMA is useful in Maple STM but i wanted to post for inquisitive minds.

My Projects


Roger, I managed to get some sdcard sketches running first with the library from the 1.6.0 ide for the AVRs, it compiles and work in the STM without a problem.

Then I tried the new library, and I get the same issues no matter if I use standard SPI, or my new DMA, so I believe the issue is with the library.
Just 2 days ago there was a commit to update the FAT driver part, I suspect that has something to do with my issues, because I can detect the card and read properties from it, but I can not format or use it, only erase and see other details.

I'll try to test the version before the latest changes later to see if that works fine. That should still be compatible with the DMA code I added.

Ray thanks for sharing, I wonder though why wouldn't the author just use the STM32 for the main program, and not only as an accessory for a much more limited CPU, given the STM he uses has more RAM and flash than the UNO. Anyway, pretty impressive speed. Looks like the display uses a parallel bus rather than SPI, that surely helps too.


I wonder though why wouldn't the author just use the STM32 for the main program, and not only as an accessory for a much more limited CPU
That was my first thought also!

Interesting news (for a few people...):
I've managed to get USB_MIDI to work with STM32-Arduino. Now my maple mini appears as "USB generic MIDI device" (no additional driver (OSX;linux;win) is needed for that). Sending and receiving notes, controller, clock... is tested and work like a charm.
original github
Drawback: the whole conversation is so  branched and inscrutable, so I decided to me, to make a complete clone of the STM-32-Arduino folder into hardware and serial.usb is gone for this (this is no problem for me).



Thanks for posting about the display

I looked the then schematic and its got 18 data/address lines, plus a load of other control lines, which explains why its blindingly fast.

I have a smaller display that is parallel, but I don't have time to the moment to wire it up, and test the existing AVR libs.

I thought someone else also investigated parallel access displays, possibly Matthias?


Thanks for the link.

I have seem a USB mass storage library for libmaple as well, though I can't remember who posted it.

Again, I did take a brief look but didn't have time to investigate how to make it work with our updated version of libmaple
Though from what I recall, it worked by being called constantly from loop() rather than needing changes to the core of libmaple, but I'm not sure how it could be enumerated as an additional device after the serial device was already enumerated.

USB is a "hero" feature of the STM32 and we should be making more use of it ;-)
Freelance developer and IT consultant



On that page that you posted with the graphic accelerator, there is a pretty detailed post on using an STM32 to make a reflow oven, what a coincidence, I think I will apply a few of the things described there, although he used a type of oven I haven't seen before, the rest like the PID algorithm is very usable for any case.

@Roger, I got the SDcard working with the previous to last version of the sdfat library. I found a bug in my code for the STM32 for that library, so I'll see if I can test later with the latest version of the library.
I get about 370kB write and 900kB reads with a class 4 card. My other SDCard may not be compatible.
I have a few class10 cards that I can't find :(


Mar 23, 2015, 11:01 pm Last Edit: Mar 23, 2015, 11:02 pm by bigplik

I have a problem with Maple Rev5 board, coudn't upload any sketch into it through linux and windows8, I managed by xp,
but only once, now It is all the time connecting and disconnecting from usb port with this annoying windows sound when doing it. Board is flashing fast, then after while much faster and again same, all the way around. It was impossible to me to put this device into perpetual mode.
I mean about this board maple r5

what is strange, that I bought another board, mini maple
which started working on the beginning without any issue. I just connected it into usb, computer recognised it,
before I installed drivers form maple (dfu and serial), for board above (R5) it isn't enough to work on it but for this another mini maple board is no problem, I can upload another sketch one by one.
And procedure to put this mini board into perpetual bootloader mode is also easy and working

do you have any idea what might be wrong with this R5 board? or how to fix it?
it could be bootloader problem? or it is something else?


Mar 23, 2015, 11:01 pm Last Edit: Mar 23, 2015, 11:09 pm by madias
@roger: yes, I've done some work with an 8-bit parallel LCD (ST7781) controller, but I found about 11-13 display wires  not really useful for any project with the maple mini / nucleo;) I think, the adapted due version of the ILI9341 is so incredible fast, that everything further is only limited by  the MCU itself (and the lack of a FPU).
about USB stuff: It's a hack  doing other things like serial.usb. midi_usb is more or less much the same as serial (MIDI is a serial protocol) and it's complicated and branched enough, so USB mass storage would be the overkill. I was thinking about an adaption for the STM32-Arduino main project, but I think, the best would be, that I'll make a side project out of it. I think there are only a handful people interesting in USB-MIDI here


Mar 23, 2015, 11:16 pm Last Edit: Mar 23, 2015, 11:23 pm by madias
@bigplik: The behavior sounds a little bit "faulty" to me. Sadly, there are almost no people in this thread with an "original maple" (but I guess this device is not original). I use the STM32F103RB only on my nucleo board, with ST-Link V2.1 as upload management. If you wont get a ultimate hint here or you trash the board, maybe invest into a cheapo ST-Link v2 adapter from ali or ebay  --3 EUR-- and try to upload it with that (or even re- up the bootloader with the ST-link).
Ok, one question: Which board do you choose for the "big maple" - "leaflabs Maple rev 3+ to flash"?

Go Up