STM32, Maple and Maple mini port to IDE 1.5.x

Ken

Re serial USB

What chipset of USB to serial are you using ?

This works fine for most people, however @mcnobby has very similar issues to you, and I strongly suspect its th USB to serial device at fault

If only 9600 works for you, look in tools/win/serial_upload.bat and find the line that has the stm32flash command with the baud rate set at 330000. ( I can't remember the precise value) and change it to 9600

However also check boot1 is low, often this floats and gives spurious results

Also don't rely on power cycling the board to reset before upload, use the reset button ( I assume you have one)

Turn on verbose in the prefs and you can see the path, or turn on the echo in serial upload.bat

Re stlink

Download STM s own stand alone program and try it.

I'm just using their exe, its just the command line one not the GUI, and I can't remember if the GUI version is in the repo (as you may have guessed I'm not in a position to access my computer to give you precise details)

With STM s. stlink GUI you could try upgrading your stlink firmware

I know it is frustrating but it can be made to work. And does work for most people
So it would be good to know if you figure out why it doesn't work for you

Quick question with the Maple mini libraries.

I checked the wiki linked in the first page and could not find anything about it.
Yesterday compiling for Maple Mini a very simple sketch I have used before in an UNO, it gave me an error with the function dtostrf.
It was telling me that was not define in that scope.
The sketch would compile fine for several Arduino boards I tested, even for the DUE, but fail for Maple mini or Generic Maple mini.

I ended adding an include line to /avr/dtostrf.h and compiled fine.

Was that the expected behaviour or something is missing in one of the libraries that should load by default?

@victor_pv

Looks like you found bug :wink:

The core code is not including that file by default.

I will investigate and fix

Ps if its your code not a library that uses that call, you may want to replace with sprintf as on arm that call works correctly

Dtostr is a AVR only to get around the problem with the cut down version of sprintf that is on AVR

It's part of the code. I didn't write the sketch, just modified a free one for my purposes to upload some values to thingspeak.

I guess I could change for the ARM, but so far I want to keep my code running in the AVRs too until I'm more confortable everything works in the maple mini. I need to use SPI for an LCD screen, that's the next part I need to test, if that works fine, I can have all the pieces of my code running in ARM.

Don't worry too much about finding why dtostrf doesn't work as we have workarounds: using sprintf, or including dtostrf.h

Thanks for the reply.

@victor_pv

I've fixed it

dtostrf.h is now included by default (in the core), like it always should have been :wink:

Download or checkout the latest copy of the repo

Cheers

Roger

@all

Following @turkoglucky's discovery that the serial consif e.g. word lenth, parity or stop bits, could not be set.

I've now updated the code so that a subset of the AVR modes are available

8 or 9 bits per word
1 or 2 stop bits
None, Even or Odd parity

I initially had some trouble getting this to work, as leaflabs had done some stuff in the uart enable code which overwrite my settings.

However I have now corrected their code, and changing the settings seems to change what I see on screen.

Note. Hopefully no one should even notice this change, as the default is Serial_8N1 as before

Cheers

Roger

Thanks, I'll pull it once I get home and try again.

May I ask where was it missing from?
I had a look yesterday and couldn't see. I am really new to C and libraries though.

Just an idea I had, would it be possible to wrap the CMSIS libraries on something to make them arduino compatible?
I understand those libraries are available for many ARM cpus providing a common interface to the different implementations of the peripherals. I may be totally wrong, as I said I am pretty new to all of this and trying to learn as much as I can.

@victor_pv

In theory yes.

In practice, we have something that mostly works, and it would be a lot of effort to attempt to re-create from scratch.

There is a repo on GitHub which has done basically what you suggest, but its for F3 only, and from what I've read is far from supporting the whole Arduino API.

See my wiki page on alternative ways to do STM32 for Arduino

of those in the list Koduino seemed to be the best, GitHub - avikde/koduino: Arduino code for STM32 microcontrollers but its only for F3 and only for the board which the author has made himself, i.e its not a board you can buy
e.g. Koduino would also not support Maple bootloader boards without some changes etc etc

It would be great to move away from this legacy Leaflabs code, but unless someone has a lot of spare time on their hands (I suspect it would take hundreds if not thousands of hours of work), I think we are better off building a user base using the code we already have !

BTW. Also CMSIS doesn't give dtostrf etc, its a hack on SAM and STM32 using wrapper functions around sprintf

rogerClark:
@ahull

I honestly couldn't remember who it was.

No offence intended.

If you could let me know what you did, including what scripts you used, I'd happily put them into the wiki

Details below.

Using the maple bootloader under Linux to allow access to the USB serial port on generic STM32 boards with the maple bootloader installed to them (should also work with genuine Maple boards).

Obviously the principle requirements are a Linux PC and a Maple board, or a generic board with the Maple bootloader installed, USB cable etc.

In addition to the requirements for installing the Arduino IDE and so forth as detailed here...

... you will need ...

dfu-util

Either install the packaged version for your particular Linux (sudo apt-get install dfu-util for Debian based versions including Ubuntu etc) or install from...

Some additional udev rules are needed to ensure that the maple 1eaf devices are correctly enumerated.

See your Linux documentation for details. The rules below will work for most Linux versions.

ATTRS{idProduct}=="1001", ATTRS{idVendor}=="0110", MODE="664", GROUP="plugdev"
ATTRS{idProduct}=="1002", ATTRS{idVendor}=="0110", MODE="664", GROUP="plugdev"
ATTRS{idProduct}=="0003", ATTRS{idVendor}=="1eaf", MODE="664", GROUP="plugdev" SYMLINK+="maple"
ATTRS{idProduct}=="0004", ATTRS{idVendor}=="1eaf", MODE="664", GROUP="plugdev" SYMLINK+="maple"

Save the rules locally as 45-maple.rules then do something like...

    sudo cp -v 45-maple.rules /etc/udev/rules.d/45-maple.rules
    sudo chown root:root /etc/udev/rules.d/45-maple.rules
    sudo chmod 644 /etc/udev/rules.d/45-maple.rules

.. and restart udev

sudo /etc/init.d/udev restart

(or whatever is appropriate for your Linux version)

Next you need to ensure that upload_router is functional. At the time of writing, there was no linux version of upload router in the git repo, so if this is the case, save the following to tools/linux/upload_router and symlink this to tools/win/upload_router (to ensure that the IDE calls the linux version).

#!/bin/bash
# Translates the windows Arduino IDE upload call - something like..
#
# upload_router ttyUSB0 1 1EAF:0003 /tmp/build9114565021046468906.tmp/STM32_Blink.cpp maple_dfu 0
#
# to the linux equivalent of the form...
#
# dfu-util -D ./STM32_Blink.cpp.bin -d 1eaf:0003 --intf 0 --alt 1
#
# Lowercase the 1eaf device name, since in Windows land everybody shouts.
#
DEVICE="$3"
DEVICE=${DEVICE,,}
BINFILE="$4.bin"
INTERFACE="$6"
ALT_INTERFACE="$2"
USBRESET=$(which usb-reset) || USBRESET="./usb-reset"
echo -e "\n\rPlease unplug and replug the USB cable to the STB device..."
sleep 2
while [[  $(lsusb |grep -i "1eaf") ]]
do
    echo -n "."
    sleep 1
done

until dfu-util -v -D "$BINFILE" -d "$DEVICE" --intf "$INTERFACE" --alt "$ALT_INTERFACE"
do
    echo -n "."
    sleep 1
done

echo -e "\n\rUnplug and replug the USB cable to the STM board again please...."
while [[  $(lsusb |grep -i "1eaf\:0003") ]]
do
    echo -n "."
    sleep 1
done

echo -e "\n\rReconnecting"
while [ -z "$(lsusb |grep -i "1eaf\:0003")" ]
do
    echo -n "."
    sleep 1
done

echo -e "\n\rWaiting for bootloader to exit."
for i in {1..6}
do
    echo -n "."
    sleep 1
done


"$USBRESET" "/dev/bus/usb/$(lsusb |grep "1eaf" |awk '{print $2,$4}'|sed 's/\://g'|sed 's/ /\//g')" >/dev/null 2>&1
for i in {1..4}
do
    echo -n "."
    sleep 1
done

echo -e "\n\rSerial port re-created... $(ls "/dev/ttyACM"*)\n\r"
for i in {1..4}
do
    echo -n "."
    sleep 1
done

Next we need a method to reset the device once we have programmed it. We use the code from here How do you reset a USB device from the command line? - Ask Ubuntu. Copy the code below and save as usb-reset.c

/* usb-reset -- send a USB port reset to a USB device
 
    Compile with ...  
    gcc usb-reset.c -o usb-reset
    ... then copy the resulting usb-reset binary to /usr/bin or some other suitable place in your PATH

*/

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>

#include <linux/usbdevice_fs.h>


int main(int argc, char **argv)
{
    const char *filename;
    int fd;
    int rc;

    if (argc != 2) {
        fprintf(stderr, "Usage: usbreset device-filename\n");
        return 1;
    }
    filename = argv[1];

    fd = open(filename, O_WRONLY);
    if (fd < 0) {
        perror("Error opening output file");
        return 1;
    }

    printf("Resetting USB device %s\n", filename);
    rc = ioctl(fd, USBDEVFS_RESET, 0);
    if (rc < 0) {
        perror("Error in ioctl");
        return 1;
    }
    printf("Reset successful\n");

    close(fd);
    return 0;
}

Compile with ...

gcc usb-reset.c -o usb-reset

... then copy the resulting usb-reset binary to /usr/bin or some other suitable place in your PATH

The work flow now is pretty much as described in the bash script.

Plug in your board with Maple Bootloader, select Maple Mini Generic as the board type and compile your sketch to prove it compiles, When you are happy that this all works, press the Upload button in the IDE. This should start upload_router if you have followed the above instructions without any problems.

  1. upload_router prompts you to unplug the board from the USB port, and re-plug it.
    upload_router then uses dfu-util to program the board.

  2. upload_router then prompts to unplug and replug the board again.
    usb-reset then identifies the leaf (1EAF) device and resets it using the usb-reset command (from the c code above).

  3. upload_router then waits while linux re-enumerated the device.
    /dev/ttyACM0 or /dev/ttyACM{whatever} automagically appears and if we look in lsusb, the device has changed from something like...

Bus 001 Device 114: ID 1eaf:0003

.. to ..

Bus 001 Device 115: ID 1eaf:0004

You should be able to use the USB serial port and the serial monitor in the IDE if you set serial.port=/dev/ttyACM1 (or serial.port=/dev/ttyACM2 or whatever the board enumerates as) in your IDE preferences.txt

If you are afraid of wearing out your laptop usb port with all that unplugging, use a USB extension lead.

Once in a while the IDE fails to connect the serial monitor after running the above upload_router. It almost invariably works on the 2nd (or worst case 3rd) attempt at clicking "Serial Monitor" in the IDE. Some sort of race condition I suspect. Other than that minor flaw, it works.

Roger,

Thanks for the useful suggestions. It's not often I get so bogged down in the fundamentals.

I have working designs based on STM32F103 '303, '373 and '407 - but these have generally been programmed using CooCox CoIDE using the ST Link section of a Discovery board to squirt the code in.

This is the first time I've tried the serial bootloader function, so I think it's just a minor problem.

My USB-Serial adaptors include FTDI, SiLabs CP2102 and the Arduino one based on the ATmega8U2. I'll work through these until I find one that works reliably.

I have a couple of Baite Maple mini clones coming to me from a friend (sourced from Chillitronix) - and I will go through the upload process with this known hardware, until I get it right.

Looking forwards, I have a friend in Shenzhen, who supplies me with customised SiLabs CP2102 serial adaptors. These are so cheap now, it makes the official FTDI cable look like a complete rip-off

Might it be an idea to bring out both the DTR and RTS outputs of the CP2102 to make a custom STM32 programming adaptor specifically for setting the BOOT0 whilst resetting the mcu?

I know you can get generic CP2102 adaptors already so cheaply which could be utilised, and it would be great if Arduino_STM32 hardware was as easy to program and get serial back, as the existing Arduino - which means automatic control of the BOOT0 and NRST lines from the PC.

I know that Jean Claude Wippler of JeeLabs has used this approach to modify a USB-serial for his work on the NXP ARM devices

Any feedback on this idea appreciated.

Ken

I have a couple of Baite Maple mini clones coming to me from a friend (sourced from Chillitronix) - and I will go through the upload process with this known hardware, until I get it right.

Looking forwards, I have a friend in Shenzhen, who supplies me with customised SiLabs CP2102 serial adaptors. These are so cheap now, it makes the official FTDI cable look like a complete rip-off

Might it be an idea to bring out both the DTR and RTS outputs of the CP2102 to make a custom STM32 programming adaptor specifically for setting the BOOT0 whilst resetting the mcu?

I know you can get generic CP2102 adaptors already so cheaply which could be utilised, and it would be great if Arduino_STM32 hardware was as easy to program and get serial back, as the existing Arduino - which means automatic control of the BOOT0 and NRST lines from the PC.

@ Ken,

This may be a great idea for those with Linux, OSx, but with Windows 8.1 on a PC using a 2.0 USB port, the Maple Mini works great using the USB serial connector. It is 100% with module in DFU (manually enabled) and I am finding 9 out of 10 times it works with the serial USB connection pulsing DTR which in turn brings the bootloader into DFU mode.

Why not 100% serial via DTR uploads...
I do not know for certain. I personally do not have an issue with pressing the Maple Mini reset button and reloading - the compile is very quick, little time is lost. Some however, have expressed outrage in not being able to ensure 100% consistency. So be it...

I have just completed a new project using hacked libraries (some by me, some by others) and I am very delighted in the results. I am using a BHP180 over I2C, a 2.2" ILI9341 320x240 in hardware SPI, a serial GPS running at 3.3V and the resulting clock is displaying the time and plotting the barometric pressure. All software compiles and functions including the faux SoftwareSerial I created from references made by Paul for the Teensy3.1

Great little product, this Maple Mini. Rock solid 3.3V performance and Roger's customizations to the core seem to be stable. At $4 per board (my Chinese price from AliExpress) this works out to be:

5 KB SRAM / $1 U.S.D
22.5 MIPS / $1
32K Flash / $1

Compile Stats under 1.6.1:

Sketch uses 45,816 bytes (42%) of program storage space. Maximum is 108,000 bytes.
Global variables use 5,752 bytes of dynamic memory.

I love it.

Ray

Ray

Thanks for your thoughts. I look forwards to using the Baite Maple mini clones at the weekend.

I'm kind of a windows luddite, having had very little exposure to Linux or MAC.

I have Raspberry Pi B+ but wouldn't know how to drive it if I powered it up. It's on my bucket list.

My STM32F407 board drives a 2.8" (Displaytech) ILI9341 display using SPI at 42MHz clock. It's a dual axis motion control board - that drives a couple of 24V dc motors up to 150W each. It can measure movement down to 1/6th micron - and move the motors at 3/8" per week using the '407 quadrature encoders.

The STM32F373 board interfaces to a 24bit ADC (AD7767) and streams analogue samples at 125kHz max to a multichannel graphing application on a PC. It's for high resolution measurement of signals down to the mV range - such as analogue pressure sensors, loadcells and thermocouples.

I think the Arduino_STM32 initiative is an excellent project and an great extension to Arduino, that can only help to get more people actively working with ARM processors.

Right now I am looking forwards to powering up the Baite Maple mini clone, and trying out all of Roger's and Bob Cousin's code.

Great to see you found a use for V-USB. I put V-USB on a ATmega328 board back in 2011, but failed to gain traction.

Best Wishes,

Ken

Quote from: rogerClark on Mar 04, 2015, 01:01 am

❝Hi Ray

Yes.

I may just see if I can code it, and not test it. And leave it to others to complain if it doesnt work

Testing will take far longer than coding !

I used to work with a Russian Java genius.... I think he actually owns the quote "Testing will take far longer than coding"

Both of these are obviously true. I find for myself, I probably spend 10X as much time testing as actually coding [although Ray was probably placing his usual "subtle" dig at the Java guy]. I also find that much of the code others have written has all the appearances of having been barely even tested at all, for which I coined my own phrase OPC = "Other People's Crap".

You guys are lucky this thread is running like a SourgeForge outing - a whole fraternity of interested parties all working together to one common purpose, :-).

Speaking of which, Roger, I noticed you had made a brief appearance a while back on that 33 page thread on getting the OV7670 camera to work. The one where only about 2% of the guys could get the OP's code to work, LOL. Did you ever have any success? I found this other website where the guy used the STM32, so maybe this is anti-OPC, but I'm not up on the STM32 enough to tell.

Would be nice to have an OV7670 library for the STM32.

guinnessimo:
....
My STM32F407 board drives a 2.8" (Displaytech) ILI9341 display using SPI at 42MHz clock.
....

quinnessimo, I don't know how fast your ILI9341 does updates, but the guys on the Teensy forum got that thing going at warp speed, using the SPI FIFO. The Teensy3.1 is another ARM, not the STM32, but code should be not too dissimilar.

Roger the dtostrf function compiles and work as expected now. Thanks.

EDIT:
I just found this: http://www.hackster.io/rayburne/arduino-stm32
I will try that and report back, so no one needs to waste his time looking at this, which may be resolved using what is in that page.


Now I am trying use SPI to control an ILI9341 display and I am not having much success.

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.

I am not sure if I am completely missing something but I suspect the SPI port is not even starting to communicate.

Did I understand correctly that now I dont need to instantiate it first with
HardwareSPI spi(1)

If I understood it right and I dont need that, how does the maple know what SPI port I am trying to use? any additional parameter in spi.begin (...)?
Is there any difference on the spi functions compared to the normal Arduino ones?

I am thinking on pulling a small section of code from the ILI library just to test reading some values, that way will be easier to troubleshoot for me than looking thru the whole library, and can set loads of serial.print lines to give me details how far it goes before going unresponsive.
If I manage to do that I will post the code here.

If anyone got an ILI9340 or 9341 working on the Maple mini, please share your sketch and library with me.

Thanks.

@victor

Some LCD libs have been ported and posted by various people, but I have not had time to go back through the forum, to find and test them

ray may have code for that one

@oric dan

Yes. Ov7670 is on my radar for stm32. At least we should be able to generate the pixel clock e.g. 8mhz using a timer or possibly even via PWM

But I have a stack of other updates queued up that I need to look at, pages need to be added to the wiki, library submissions need to be added to the repo etc etc

So I can't see myself having any time to look at that camera any time soon

Thanks Roger, I found one example posted by Ray in his page, so will test with that.

I will post results here.

Rays example probably won't work

Change the definitions of stm32f1xx to stm32f1

I rationalised the folder names

Also the pin macros are no longer needed as they are in the variants files

Roger, 8-MHz PWM generated by the Rduino works fine with the camera. MrArduino forgot to set it up in his 2 simple examples. With an STM32, you can probably go to a full 24-MHz PWM for XCLK, and get up to 30 fps.