zmkfirmware / zmk

ZMK Firmware Repository
https://zmk.dev/
MIT License
2.83k stars 2.85k forks source link

Documentation: How to flash BlackPill, BluePill and other STM32 based boards with zmk #1711

Open infused-kim opened 1 year ago

infused-kim commented 1 year ago

After being spoiled by how easy it is to flash nice!nanos, I was a little shocked by how hard it is for my new blackpill controller.

Even though these boards are not used much with zmk keyboards I think it would be good to improve the documentation.

In the meantime, hopefully this issue will start ranking on google.

How to flash a BlackPill, BluePill and other STM32 based boards

To flash them you need to install dfu-utils and then use these commands:

❯ dfu-util --list
dfu-util 0.11

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2021 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

Found DFU: [0483:df11] ver=2200, devnum=1, cfg=1, intf=0, path="1-1", alt=3, name="@Device Feature/0xFFFF0000/01*004 e", serial="3377337E3539"
Found DFU: [0483:df11] ver=2200, devnum=1, cfg=1, intf=0, path="1-1", alt=2, name="@OTP Memory /0x1FFF7800/01*512 e,01*016 e", serial="3377337E3539"
Found DFU: [0483:df11] ver=2200, devnum=1, cfg=1, intf=0, path="1-1", alt=1, name="@Option Bytes  /0x1FFFC000/01*016 e", serial="3377337E3539"
Found DFU: [0483:df11] ver=2200, devnum=1, cfg=1, intf=0, path="1-1", alt=0, name="@Internal Flash  /0x08000000/04*016Kg,01*064Kg,03*128Kg", serial="3377337E3539"

Here you should take note of the alt=0 parameter of the Internal Flash line. You will then use it in the next command to actually flash it with the -a 0 parameter.

❯ dfu-util -a 0 -i 0 -s 0x08000000:leave -D [path to zmk .bin file]
dfu-util 0.11

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2021 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

dfu-util: Warning: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release
Opening DFU capable USB device...
Device ID 0483:df11
Device DFU version 011a
Claiming USB DFU Interface...
Setting Alternate Interface #0 ...
Determining device status...
DFU state(10) = dfuERROR, status(10) = Device's firmware is corrupt. It cannot return to run-time (non-DFU) operations
Clearing status
Determining device status...
DFU state(2) = dfuIDLE, status(0) = No error condition is present
DFU mode device DFU version 011a
Device returned transfer size 2048
DfuSe interface name: "Internal Flash  "
Downloading element to address = 0x08000000, size = 50228
Erase       [=========================] 100%        50228 bytes
Erase    done.
Download    [=========================] 100%        50228 bytes
Download done.
File downloaded successfully
Submitting leave request...
Transitioning to dfuMANIFEST state

This is working for me on a BlackPill STM32F411CEU6 board.

If the STM32 doesn't show up in DFU mode on macOS

MacOS had trouble finding my blackpill in DFU mode. What helped was using the USB Probe app from the Apple Dev center to reset USB on macOS.

You can find more info about that here. And instructions on how and where to get the USB Probe app here.

Apparently you can also use this open source, command line renumerate utility to reset usb, but it requieres you to compile it yourself and I havent tried it.

urob commented 1 year ago

You could use https://github.com/qmk/qmk_toolbox to simplify things a bit. You'll have to use the hardware reset buttons to start the bootloader mode on STM32 boards though (cf, #1086).

ReFil commented 1 year ago

There is also a port of the uf2 bootloader to STM32F3 and F4 boards you can flash through DFU anf then access using the normal double tap reset sequence https://github.com/adafruit/tinyuf2

lesshonor commented 3 months ago

Flashing instructions for boards supported in upstream Zephyr can be found in the Zephyr docs: see WeAct BlackPill F401, F411).

It strikes me as a bad idea for ZMK to replicate this information, though some mention of upstream tooling and documentation would be appropriate.

dhruvinsh commented 1 month ago

There is also a port of the uf2 bootloader to STM32F3 and F4 boards you can flash through DFU anf then access using the normal double tap reset sequence https://github.com/adafruit/tinyuf2

@ReFil if you can shade some light here,

ReFil commented 1 month ago

Yes, just short reset to gnd twice in rapid succession

Uf2 files

dhruvinsh commented 1 month ago

Thank you for the update,

I just found old thread on discord and Pete mentioned that CONIFG_USE_DT_CODE_PARTITION=y and CONFIG_BUILD_OUTPUT_UF2=y need to be set. Which I understand, but he also mentioned that code partition also need to change.

Current Blackpill (STM32f4x1) code partition is upstream, Here. Any idea what kind of change I am looking for?

&flash0 {

    partitions {
        compatible = "fixed-partitions";
        #address-cells = <1>;
        #size-cells = <1>;

        boot_partition: partition@0 {
            label = "mcuboot";
            reg = <0x00000000 DT_SIZE_K(32)>;
            read-only;
        };

        /*
         * The flash starting at offset 0x00008000 and ending at
         * offset 0x0001ffff (sectors 2 through 4) is reserved for
         * use by the application.
         */

        slot0_partition: partition@20000 {
            label = "image-0";
            reg = <0x00020000 DT_SIZE_K(128)>;
        };
        slot1_partition: partition@40000 {
            label = "image-1";
            reg = <0x00040000 DT_SIZE_K(128)>;
        };
        scratch_partition: partition@60000 {
            label = "image-scratch";
            reg = <0x00060000 DT_SIZE_K(128)>;
        };
    };
};