Serial USB and Bootloader on generic boards

RogerClark
Mon May 04, 2015 12:56 am
Guys,

Just thought I’d post about some experiments I’ve been doing with onboard Serial USB on generic boards and the Bootloader on generic boards

What a lot of people don’t realise is that the Maple Serial USB is not part of the Bootloader.

The Serial USB, is compiled into the sketch.
So, Assuming you have the Windows drivers installed – see the bat file in the drivers folder….

This means is you compile for Maple mini but upload to a generic board, the remove the usb plug and put it back in again, the board will appear as Maple Serial
(Assuming you have Boot0 low so that the code runs directly after its powered up)

And you sketch will run and anything you output via Serial.println() will appear though the virtual serial port

Also, its possible to upload the Maple bootloader to a generic board, and it will appear as a Maple DFU device, and you can upload using the maple uploader (DFU Util)

However there are a few problems with both of these methods

If you upload using Serial, you’d need to constantly change the boot settings after the upload is complete, and you’d also need to unplug and plug back in again after each upload.

If you are using STLink you’d not need to change the Boot0 setting, but you would need to unplug/ plug in again :-(

On Linux @hull has written a simple utility that resets a USB device, so that after his STLink uploads, he can reset the usb device which means he doesnt have to remove and reconnect.

I’ve now found there is a way to do this on Windows, albeit at the moment, I am doing this manually.
There is a microsoft utility called devcon.exe that has commands to reset a usb device

So what I can do is upload using STLink, then immedatly after completion I manually run

devcon.exe restart *1EAF*


victor_pv
Mon May 04, 2015 3:41 am
Can we make the bootloader to disable or reset the STM32 usb peripheral before calling the sketch?
If so, that may cause the usb device to disappear, causing a reenumeration when the sketch enables the USB peripheral again.

RogerClark
Mon May 04, 2015 4:05 am
I think the Sketch may be resetting the USB, it certainly needs to have the DISC pin defined in the code

I don’t think its defined in the bootloader but it would be easy to add


mrburnette
Mon May 04, 2015 3:49 pm
Windows-centric enumeration of USB:

A dated, but still relevant discussion by a MS developer on enumeration.
http://blogs.msdn.com/b/usbcoreblog/arc … evice.aspx

Ray


victor_pv
Mon May 04, 2015 6:41 pm
Roger I didn’t mean resetting thru the discovery pin, but rather resetting the STM32 USB peripheral. From reading the stm32 manual, I understand there are ways to disable the peripheral that will completely shutdown the differential signals, so Windows would think the device has been disconnected.
Now, I don’t know if they sketch contains all the code to re-enable the USB peripheral, but I would guess so as the USB Serial can be used on a board without bootloader, so the code in the sketch must contain all the initialization needed.

RogerClark
Mon May 04, 2015 10:19 pm
Victor,

Sounds technically feasible but I’m not sure why LeafLabs would have added all that extra circuitry e.g. 2 transistors and about 6 resistors, if it could have been done in code

Rick noticed that on the small Generic STM32F103C8 boards that one of the USB pins (PA12 I think) is pulled up to 3.3V via 1.5k.
This means that initially the pin is pull high by the resistor so the USB is held in reset, until the code runs in the sketch or bootloader hwich initialises the USB pins.

So the best board to try it on is possibly that board.

We could of course switch the pin from USB to GPIO and either turn on the internal pullup or drive it high,

But I still don’t know why LeafLabs would not have done this if it was possible


RogerClark
Mon May 04, 2015 10:33 pm
Guys

I made some progress with this on Windows.

Firstly this will only work if you have an STlink adapter to upload.
You also need to run the IDE as adminstrator, and you need an extra file, devcon.exe (32 or 64 bit version)

I have added some lines at the end of my local copy of stlink_upload.bat to wait 1 second then call devconX64.exe to reset the usb device for board.

rem: Using the open source texane-stlink instead of the proprietary STM stlink exe
texane-stlink\st-flash.exe write %str% 0x8000000
sleep 1
devconX64.exe restart *1eaf*


mrbwa1
Tue May 05, 2015 2:25 pm
Roger,

If that is the solution for running things, I could write a small standalone wrapper that can call things with appropriate privileges. Of course, you still have to run that program with elevated privileges.

Anyhow, if you get to a point in the windows world where you need to call some commandline utilities or things have to be run as an Admin, I know how to write some small programs that can handle all of that (including detecting and executing the appropriate 32 or 64 bit version of something).

I’m actually working on some updates to small software I wrote for our support folks at work this week.


RogerClark
Tue May 05, 2015 9:07 pm
That’s a good point about a helper task

I recall writing a windows service (years ago) because I needed some ASP on a IIS server to make a call into the Active Director user authentication functions, and I needed to reliably run this in the elevated privileges

So this thing could be written as a Windows service, I’ve not looked for the source code, but I think the source for devcon.exe is publicly available and I have seen other C# code snippets that do the individual tasks that are needed

I don’t think this is every going to be an ideal or foolproof solution, but some people would probably be ok using it. E.g I know @ahull already does something similar on Linux, where he uploads by stlink but uses USB serial for Serial.print etc

This may also end up being another option


victor_pv
Tue May 05, 2015 9:12 pm
Roger, can’t we set the bootloader to disable or Reset the USB device, until the sketch goes and start it up again?

According to RM00008 we have this two bits in the USB control register to play with:
Bit 1 PDWN: Power down
This bit is used to completely switch off all USB-related analog parts if it is required to
completely disable the USB peripheral for any reason. When this bit is set, the USB
peripheral is disconnected from the transceivers and it cannot be used.
0: Exit Power Down.
1: Enter Power down mode.

Bit 0 FRES: Force USB Reset
0: Clear USB reset.
1: Force a reset of the USB peripheral, exactly like a RESET signalling on the USB. The
USB peripheral is held in RESET state until software clears this bit. A “USB-RESET”
interrupt is generated, if enabled.

I would think that if the bootloader sets the PDWN to 1, that would make the board appear electrically disconnected from the USB.
According to RM00008 the software application must set that bit to 0 as part of initializing the device, so the default reset state must be 1. Given that the sketches successfully use the Serial USB, the code must already be there to enable the USB, we only need to do either of these two:
1-Disable the device in the DFU before calling the sketch
or 2.- In the sketches serial code, make them set the USB to powerdown before initializing, in case the sketch was called from DFU or from a device reset with no power down.

Option 2 may solve two problems at once: re-enumeration when using the bootloader in a different board, and re-enumerating when you reset one of those board without power down, so the device appears to disconnect and reconnect.


RogerClark
Tue May 05, 2015 10:00 pm
@ahull

We could give it a try

The bootloader code is relatively simple really.

To build it, you just need to put ARM compiler location in your $PATH

Then do make maple-mini

You will need to pull the button pin high (I forget which one it is) and also attach a Led to the LED pin (I think its PB1)

I did try recompiling the bootloader for the generic stm32f103c8 board you (and I, and Rick etc) have.

to move the LED pin to PC13, but I can’t get it to work at the moment, so the easiest thing to test this usb stuff is just to put a LED onto PB1 electrically

But feel free to try changing the code, its setup in config.h, there is a Port, pin, mask and also a Bit for the RCC clock for the GPIO port that need to be changed (which didn’t work for me ;-( )

On that generic stm32f103C8, Rick has noticed that PA12 is pulled high via a 1.5k resistor, which is located under the board , we think its R3

If you can get the code to disable the USB, that resistor will pull the D- line high and tell the host system that the USB has been reset

BTW. I tried the bootloader on another generic stm32f103c8 board, but it didnt work. This could be because the board has a defective USB connector, or perhaps it needs that resistor

I know people don’t like soldering etc.

But the easy solution may not be software, but just a tiny board with 4 wires on it, that people attach to the board

it seems to just need 1 NPN transistor and 2 resistors (see the Nucleo schematic)

We could easily gets some PCB’s made

Or perhaps some sort of daughter / mother board, that the generic board plugs into (though that sounds a bit of overkill)

Anyway, let me know if you need help modifying the bootloader

BTW. you can probably test the same thing with a sketch if you just want to test simulating USB reset

i.e write a sketch that flashes a LED for 5 secs then resets the USB bus and see if your host machine notices ;-)


victor_pv
Wed May 06, 2015 4:08 am
Roger, I actually already tried that today, disabling the port in software.
It kills the serial connection, but Windows did not notice any usb disconnection and there was no re-enumeration.
I tried both Reset and PowerDown, neither caused a re-enumeration.

I think another software solution may be to manipulate the USB pins alternate function setting and force them to be GPIO, set the level to whatever is needed, and then jump to the sketch. I will try to give that a shot tomorrow if I have time.

But really, the easiest may be to just use st-link or a usb to serial for programming given the super low price of either, and that you only need one or a couple, no need to add extra hardware to a board.


RogerClark
Wed May 06, 2015 4:21 am
Victor

I agree, this is not the easiest solution.

The devcon.exe method does work, but only when uploading via STLink because I coudlnt get the timing quite right stating devcon manually just after an upload, and it could be that it will never work to switch between DFU and Serial

I did build the “Serial” bootloader version of the Maple bootloader and it did compile and enumerate in Windows as the Maple serial device.

https://github.com/jonatanolofsson/mapl … erial-boot

However LeafLabs implemented an AVR protocol for uploads (stk500 ), but I’m not sure which uploader supports that protocol, it could be a standard AVR uploader but I’m not sure

I looked at the Esperino firmware, and loaded that onto my STM32F103ZET and it appears on USB as a STM virtual serial port. (luckily I already had STM’s drivers installed for another board).
Esperino has the code which accepts the same commands as the one built into the hardware of the chip, i.e which can be uploaded via stm32flash

The code doesnt look that complex, so I think the best approach for a generic bootloader is to just have the board constantly appear as the Maple Serial device, and have a method to switch it into upload mode. I think that what happens at the moment on the Maple mini, is that the maple_loader.jar file does something like set DTR and then send a special sequence of characters e.g. 1EAD1AB5 or something like that

When the code in the sketch sees this sequence it reboots

But we’d need to do something a whole lot more complex

What we’d need to do is move all the USB serial into the bootloader and have the ability for the sketch to call back into the bootloader to do an upload, because rebooting the chip, will cause the USB stuff to get re-inited in the bootloader and we don’t want to do that as the connection will get screwed up to the PC

I think its do-able, but not easy, so perhaps we should park this for now and come back when everyone has more time

I think looking at PIN_MAP in __FLASH__ is probably more important at the moment


Leave a Reply

Your email address will not be published. Required fields are marked *