Creating a Bootloader for generic boards

Bootloader for boards that don't have the addition hardware found on the Maple mini, which resets the USB
User avatar
RogerClark
Posts: 5470
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: Creating a Bootloader for generic boards

Postby RogerClark » Mon May 11, 2015 3:17 am

Ray

Very interesting. I wonder why leaflabs chose to use an external circuit for this... Shame we can't ask them, but they are busy doing new stuff ;-(

User avatar
mrburnette
Posts: 1774
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: Creating a Bootloader for generic boards

Postby mrburnette » Mon May 11, 2015 12:57 pm

RogerClark wrote:Ray

Very interesting. I wonder why leaflabs chose to use an external circuit for this... Shame we can't ask them, but they are busy doing new stuff ;-(


My guess is timing across the then available 1.1 and 2.0 USB specs... that is, they force enumeration but the host port defaults to 1.1 most likely.
http://www.beyondlogic.org/usbnutshell/usb2.shtml

This quote is of interest:
High speed devices will start by connecting as a full speed device (1.5k to 3.3V). Once it has been attached, it will do a high speed chirp during reset and establish a high speed connection if the hub supports it. If the device operates in high speed mode, then the pull up resistor is removed to balance the line.

A USB 2.0 compliant device is not required to support high-speed mode. This allows cheaper devices to be produced if the speed isn’t critical. This is also the case for a low speed USB 1.1 devices which is not required to support full speed.

However a high speed device must not support low speed mode. It should only support full speed mode needed to connect first, then high speed mode if successfully negotiated later. A USB 2.0 compliant downstream facing device (Hub or Host) must support all three modes, high speed, full speed and low speed.


I worked with V-USB extensively for a few months, for the most part it works flawlessly on 1.1 USB. On 2.0 and 3.0 USB ports, it is problematic. I suspect that is why it is not seen more out in the wild.

User avatar
RogerClark
Posts: 5470
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: Creating a Bootloader for generic boards

Postby RogerClark » Mon May 11, 2015 10:33 pm

Ray

That's interesting.

I think Rick noticed that the GenericSTM32F103C8 boards have a 1.5k resistor between one of the USB lines and 3.3v ( I think it was the D- line but I can't be sure)

So on those boards, it sounds like the host system must presume its a USB 3.0 device, because on cold boot the GPIO pin to which D- is attached will be floating, so the resistor will pull D- high.

Then when the USB setup code runs in the uP it will override the 1.5k resistor.

So it could be that these boards can re enumerate simply by putting the D- pin on the uP back into input mode.


Or have I got it wrong and 1.5k to 3.3 is for USB 1.1 ???

User avatar
mrburnette
Posts: 1774
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: Creating a Bootloader for generic boards

Postby mrburnette » Tue May 12, 2015 2:52 am

RogerClark wrote:Ray

That's interesting.

I think Rick noticed that the GenericSTM32F103C8 boards have a 1.5k resistor between one of the USB lines and 3.3v ( I think it was the D- line but I can't be sure)

So on those boards, it sounds like the host system must presume its a USB 3.0 device, because on cold boot the GPIO pin to which D- is attached will be floating, so the resistor will pull D- high.

Then when the USB setup code runs in the uP it will override the 1.5k resistor.

So it could be that these boards can re enumerate simply by putting the D- pin on the uP back into input mode.


Or have I got it wrong and 1.5k to 3.3 is for USB 1.1 ???


As we have discussed, USB uses a differential transmission pair for data. This is encoded using NRZI and is bit stuffed to ensure adequate transitions in the data stream. On low and full speed devices, a differential ‘1’ is transmitted by pulling D+ over 2.8V with a 15K ohm resistor pulled to ground and D- under 0.3V with a 1.5K ohm resistor pulled to 3.6V. A differential ‘0’ on the other hand is a D- greater than 2.8V and a D+ less than 0.3V with the same appropriate pull down/up resistors.

The receiver defines a differential ‘1’ as D+ 200mV greater than D- and a differential ‘0’ as D+ 200mV less than D-. The polarity of the signal is inverted depending on the speed of the bus. Therefore the terms ‘J’ and ‘K’ states are used in signifying the logic levels. In low speed a ‘J’ state is a differential 0. In high speed a ‘J’ state is a differential 1.

USB transceivers will have both differential and single ended outputs. Certain bus states are indicated by single ended signals on D+, D- or both. For example a single ended zero or SE0 can be used to signify a device reset if held for more than 10mS. A SE0 is generated by holding both D- and D+ low (< 0.3V). Single ended and differential outputs are important to note if you are using a transceiver and FPGA as your USB device. You cannot get away with sampling just the differential output.

The low speed/full speed bus has a characteristic impedance of 90 ohms +/- 15%. It is therefore important to observe the datasheet when selecting impedance matching series resistors for D+ and D-. Any good datasheet should specify these values and tolerances.


The above from the earlier reference.

Ray

victor_pv
Posts: 1059
Joined: Mon Apr 27, 2015 12:12 pm

Re: Creating a Bootloader for generic boards

Postby victor_pv » Tue May 12, 2015 6:18 pm

Just verified with my VET board, which has a 1.5K pull up and no control circuit, I can cause a reenumeration by setting PA12 as output, setting it LOW, waiting a bit, and setting it floating again:

Code: Select all

        pinMode (PA12, OUTPUT);
        digitalWrite (PA12, LOW);
        delay (100);
        Serial.println ("Setting PA12 Floating");
        pinMode (PA12, INPUT_FLOATING);


Serial in this case is the USART1 thru CH340. I have not been able to use my serial USB. The device gets detected with the wrong Hardware ID, so I don't think the peripheral is initializing right, but every time I run the code above, the device disappears and reappears.
I think this should be enough to cause a re-enumeration pretty much in any similarly connected board (1k5 pull up, no pin control).

EDIT: I have also tested pulling PA11 down, that does not cause anything.
EDIT2: I wonder if this working has anything to do with the USB not initializing properly in the sketches I upload to this board. I did however load the maple mini bootloader to this board, and it was detected fine as DFU device and I could upload to it, so I know the USB port works in that board.

User avatar
RogerClark
Posts: 5470
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: Creating a Bootloader for generic boards

Postby RogerClark » Tue May 12, 2015 9:44 pm

Victor

Can you zip up your VET variant files and boards.txt and post it to the forum, or email it to me

I have a ZET board which is a superset of the VET so I can give your files a go on my board.

I suspect serial USB is not being compiled into the sketch, but without seeing your setup its hard to know what is wrong

User avatar
Rick Kimball
Posts: 754
Joined: Tue Apr 28, 2015 1:26 am
Location: Eastern NC, US
Contact:

Re: Creating a Bootloader for generic boards

Postby Rick Kimball » Wed May 13, 2015 12:23 am

victor_pv wrote:Just verified with my VET board, which has a 1.5K pull up and no control circuit, I can cause a reenumeration by setting PA12 as output, setting it LOW, waiting a bit, and setting it floating again:


So I used that idea but not that code. I added this technique to the libopencm3-examples cdcacm. It worked great. I push reset and it re-enumerates. Their code is a serial echo example. But it drops my putty session like I'd expect when you reenumerate. BTW: I'm using one of those jc66 stm32f103c8t6 coreboards

Here is the cdcacm.c code I changed:

Code: Select all

int main(void)
{
        usbd_device *usbd_dev;

        rcc_clock_setup_in_hsi_out_48mhz();

        rcc_periph_clock_enable(RCC_GPIOA);
        rcc_periph_clock_enable(RCC_AFIO);

        AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON;

        gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15);

        /* toggle pin PA0 so i can measure how long the delay takes */
        gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO0);
        gpio_set(GPIOA,GPIO0);

        /* toggle USB_DP */
        gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO12);
        gpio_clear(GPIOA,GPIO12);
        volatile unsigned x = 48000000/4/100; do { ; }while(--x);

        gpio_clear(GPIOA,GPIO0);

        usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer));
        usbd_register_set_config_callback(usbd_dev, cdcacm_set_config);

        gpio_set(GPIOA, GPIO15);
        gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
                      GPIO_CNF_OUTPUT_PUSHPULL, GPIO15);

        while (1)
                usbd_poll(usbd_dev);

Thanks!
-rick
-rick

User avatar
mrburnette
Posts: 1774
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: Creating a Bootloader for generic boards

Postby mrburnette » Wed May 13, 2015 12:55 am

:D
Last edited by mrburnette on Wed May 13, 2015 11:56 am, edited 1 time in total.

victor_pv
Posts: 1059
Joined: Mon Apr 27, 2015 12:12 pm

Re: Creating a Bootloader for generic boards

Postby victor_pv » Wed May 13, 2015 4:19 am

Roger, I uploaded the modified files to my "modified" repo:
https://github.com/victorpv/STM32F1_Modified/

Thanks for checking it.
You will notice I tried to make pin_map to flash conditional, but that is not working as I wanted, so I think it is going to ram as it is right now in those files even if I select the option in the board menu. Not sure what I did wrong, but don't worry much about that.

Rick thanks for testing, I am glad to know in another board. Hopefully it will be consistent.
If it seems to work properly I think we could try to include it either in the normal sketch init() routine, or in the bootloader right before calling the sketch.

EDIT: Rick I see you set the port low, but don't see you change the PA12 after that, is it brought back floating by the USD dev setup?

User avatar
RogerClark
Posts: 5470
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: Creating a Bootloader for generic boards

Postby RogerClark » Wed May 13, 2015 4:30 am

Victor

I had a quick go with my F103ZET and also F103C8 boards but couldn't get USB Serial to work on either

I'm sure it was working the other day, so I don't know what I changed :-(

I'll stay on my main branch and add your VET files

BTW. My VET board arrived in the post this morning, and it looks really good.

Is smaller than the one you have, and is approx 2/3 the size of a Uno. I really like the size, its a good compromise as the ZET chip is massive (unnecessarily large for most jobs I suspect)

It has a ATMEL 24C08 (I2C EEPROM 8K) on the back as well as micro SD card slot

Actually my ZET board has Micro SD as well, but I've been too busy to try it.


I'll add you V series stuff into the repo if I get time this evening

Thanks

Roger

Edit

I just noticed I was on a branch of code where the whole archive flag had been removed, perhaps this breaks Serial USB as well ;-)


Return to “Generic bootloader”

Who is online

Users browsing this forum: No registered users and 1 guest