Platformio STM32F103C8 maple bootloader dfu

O ficheiro platformio.ini deve conter o seguinte:

[env:genericSTM32F103C8]

platform = ststm32
board = genericSTM32F103C8
framework = arduino

board_build.core = maple

# send by usb
upload_protocol = dfu
upload_port = anything

Consideremos a posição dos dois jumpers do lado da entrada USB, ou seja boot0 e boot1 para o lado do 1 (a melhor solução está mais abaixo quando temos o boot1 para o lado do 1)

No entanto quando se envia o programa existe um erro que impede o upload do programa para o mcu. O log exibido nesse caso é o seguinte:

AVAILABLE: blackmagic, cmsis-dap, dfu, jlink, serial, stlink
CURRENT: upload_protocol = dfu
Looking for upload port...
Using manually specified: anything
Uploading .pio/build/genericSTM32F103C8/firmware.bin
Failed to open serial device.

dfu-util 0.7

Copyright 2005-2008 Weston Schmidt, Harald Welte and OpenMoko Inc.
No DFU capable USB device found
Copyright 2010-2012 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to dfu-util@lists.gnumonks.org

Filter on vendor = 0x1eaf product = 0x0003
Waiting for /dev/anything serial...Done

O problema reside na identificação do dispositivo (device) que não é igual ao esperado, 1eaf:0003, mas sim 1eaf:0004. Deste modo, a porta não é correctamente identificada e por isso o upload falha.

Reparem abaixo nas mensagens do lsusb, e depois o filtro que é exibido acima:

Bus 001 Device 012: ID 1eaf:0004 LeafLabs Maple
Filter on vendor = 0x1eaf product = 0x0003

Isto é o resultado de uma troca de device ID durante o boot. Que passa do 0x0003, para 0x0004 em 6 segundos. Isto significa que o dfu apenas fica disponível nos primeiros 6 segundos após o reset. Se falharmos o momento exacto dá a mensagem: No DFU capable USB device found e falha o envio.

Deste modo, termos que sincronizar o levantamento da pressão do botão do reset para o dfu estar activo exactamente durante o período em que o platformio tenta fazer o upload do firmware. Isto é um processo complicado.

Podemos instalar o pacote dft-util ( sudo apt install dfu-util )para termos maior controlo sobre o assunto. Correr o seguinte comando para saber o que se pode fazer: dfu-util -h

Mas a melhor opção é colocar o jumper boot1 para o lado do 1. Deste modo após um reset, o dfu fica em modo perpetuo e pode ser enviado um programa com mais facilidade. No final do envio, o mcu faz um reset especial e fica com o programa a correr. Mas se for desligado, ou fizermos um reset volta ao modo dfu (ou seja de programação) por isso quando terminarmos a programação devermos colocar o boot1 para o lado do 0.

Também existe um reparo a fazer sobre os pinos. Alguns funcionam de forma diferente, pelo menos os pinos pwm, caso se use no ficheiro platformio.ini a linha que refere a board como:

board = bluepill_f103c8

Neste caso passa a usar STM32duino core (o core da ST), se for indicado como inicialmente usa o Arduino_STM32 Core do Roger Clark.

PWM com o Roger Clark / maple arduino_stm32 core

Configurar, no setup, o pino para ser usado com PWM

pinMode(PB6, PWM);

Atribuir o ciclo de trabalho (duty cycle) o pino previamente configurado.

pwmWrite(PB6, 32000);

O valor pode variar entre 0 e 65535.

PWM com o STM32duino core (o core da ST)

Configurar, no setup, o pino para ser usado com PWM

pinMode(PB6, OUTPUT);

Atribuir o ciclo de trabalho (duty cycle) o pino previamente configurado.

pwmWrite(PB6, 32000);
analogWrite(PB6, 50);

O valor pode variar entre 0 e 4095.

Ver também o seguinte artigo: STM32F bluepill, Platformio, Roger Clark arduino stm32 core