Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

minimal hooks for SN32 flashing support #21228

Closed
wants to merge 11 commits into from
5 changes: 4 additions & 1 deletion docs/driver_installation_zadig.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

QMK presents itself to the host as a regular HID keyboard device, and as such requires no special drivers. However, in order to flash your keyboard on Windows, the bootloader device that appears when you reset the board often *does*.

There are two notable exceptions: the Caterina bootloader, usually seen on Pro Micros, and the HalfKay bootloader shipped with PJRC Teensys, appear as a serial port and a generic HID device respectively, and so do not require a driver.
There are three notable exceptions: the Caterina bootloader, usually seen on Pro Micros, the HalfKay bootloader shipped with PJRC Teensys, and the SN32 DFU bootloader shipped with Sonix SN32F2xx, appear as a serial port and a generic HID device respectively, and so do not require a driver.

We recommend the use of the [Zadig](https://zadig.akeo.ie/) utility. If you have set up the development environment with MSYS2, the `qmk_install.sh` script will have already installed the drivers for you.

Expand Down Expand Up @@ -96,4 +96,7 @@ The device name here is the name that appears in Zadig, and may not be what the
|`gd32v-dfu` |GD32V BOOTLOADER |`28E9:0189` |WinUSB |
|`kiibohd` |Kiibohd DFU Bootloader |`1C11:B007` |WinUSB |
|`stm32duino` |Maple 003 |`1EAF:0003` |WinUSB |
|`sn32-dfu` |*none* |`0c45:7010` |HidUsb |
|`sn32-dfu` |*none* |`0c45:7040` |HidUsb |
|`sn32-dfu` |*none* |`0c45:7900` |HidUsb |
|`qmk-hid` |(keyboard name) Bootloader |`03EB:2067` |HidUsb |
42 changes: 42 additions & 0 deletions docs/flashing.md
Original file line number Diff line number Diff line change
Expand Up @@ -465,3 +465,45 @@ CLI Flashing sequence:
4. Wait for the keyboard to become available

<sup>1</sup>: This works only if QMK was compiled with `RP2040_BOOTLOADER_DOUBLE_TAP_RESET` defined.

## SN32 DFU

All SN32 MCUs, except for 260<sup>1</sup> come preloaded with a factory bootloader that cannot be modified nor deleted.

To ensure compatibility with the SN32-DFU bootloader, make sure this block is present in your `rules.mk` :

```make
# Bootloader selection
BOOTLOADER = sn32-dfu
```

Compatible flashers:

* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI)
* [Sonix-Flasher](https://github.com/SonixQMK/sonix-flasher/releases) (advanced GUI with MCU specific functionalities)
* [SonixFlasherC](https://github.com/SonixQMK/SonixFlasherC/releases) (recommended command line)
```
sonixflasher --vidpid 0c45:7040 -f <filename>
```
<sup>1</sup>: 260 series of chips have part of the SN32-DFU bootloader in userspace and therefore must be guarded to avoid bricking. Install the [sonix-bootloader](https://github.com/SonixQMK/sonix-keyboard-bootloader) before flashing the firmware
```
sonixflasher --vidpid 0c45:7010 --jumploader -f <bootloader_filename>

```
as a one-shot operation, then flash the firmware with an offset `0x200`
```
sonixflasher --vidpid 0c45:7010 -o 0x200 -f <filename>

```

If using `$ qmk flash` to flash a firmware, the offset is automatically applied if needed.

Flashing sequence:

1. Enter the bootloader using any of the following methods:
* Tap the `QK_BOOT` keycode
* If a reset circuit is present, tap the `RESET` button on the PCB; some boards may also have a toggle switch that must be flipped
* Otherwise, you need to bridge `BOOT` to GND (via `BOOT` button or jumper), short `RESET` to GND (via `RESET` button, jumper or by unplugging and replugging USB), and then let go of the `BOOT` bridge
2. Wait for the OS to detect the device
3. Flash a .bin file
4. Reset the device into application mode (may be done automatically)
7 changes: 6 additions & 1 deletion lib/python/qmk/cli/doctor/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ def _check_arm_gcc_version():
version_number = ESSENTIAL_BINARIES['arm-none-eabi-gcc']['output'].strip()
cli.log.info('Found arm-none-eabi-gcc version %s', version_number)

return CheckStatus.OK # Right now all known arm versions are ok
parsed_version = _parse_gcc_version(version_number)
if (parsed_version['major'], parsed_version['minor']) < (10, 3):
cli.log.warning('{fg_yellow}We do not recommend arm-none-eabi-gcc older than 10.3.x. Upgrading to 10.3.x or higher is recommended.')
return CheckStatus.WARNING

return CheckStatus.OK # arm versions less than 10.3.x cause issues on sn32
Comment on lines +47 to +52
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the reason for this is occasional and random hardfaults when built against those versions in arm m0. The toolchain version that first fixed it was arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10-2020-q4-major). Bumping the version one up makes sure the right one is selected ( up until q2 it was buggy). No known issues exist with current latest version, tested extensively with every major release from 10.3 onwards.

while my original notes are lost on this, I believe this to be the bug



def _check_avr_gcc_version():
Expand Down
5 changes: 5 additions & 0 deletions lib/python/qmk/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@
'hid-bootloader': {
("03eb", "2067"), # QMK HID
("16c0", "0478") # PJRC halfkay
},
'sn32-dfu': {
("0c45", "7010"), # SN32F260
("0c45", "7040"), # SN32F240B
("0c45", "7900") # SN32F240
}
}

Expand Down
12 changes: 11 additions & 1 deletion lib/python/qmk/flashers.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def _find_bootloader():
details = 'halfkay'
else:
details = 'qmk-hid'
elif bl in {'apm32-dfu', 'gd32v-dfu', 'kiibohd', 'stm32-dfu'}:
elif bl in {'apm32-dfu', 'gd32v-dfu', 'kiibohd', 'stm32-dfu', 'sn32-dfu'}:
details = (vid, pid)
else:
details = None
Expand Down Expand Up @@ -205,6 +205,14 @@ def _flash_uf2(file):
cli.run(['util/uf2conv.py', '--deploy', file], capture_output=False)


def _flash_sonixflasher(details, file):
# SN32F260
if details[0] == '0c45' and details[1] == '7010':
cli.run(['sonixflasher', '--vidpid', f'{details[0]}:{details[1]}', '--offset', '0x200', '--file', file], capture_output=False)
else:
cli.run(['sonixflasher', '--vidpid', f'{details[0]}:{details[1]}', '--file', file], capture_output=False)


def flasher(mcu, file):
bl, details = _find_bootloader()
# Add a small sleep to avoid race conditions
Expand Down Expand Up @@ -234,6 +242,8 @@ def flasher(mcu, file):
_flash_mdloader(file)
elif bl == '_uf2_compatible_':
_flash_uf2(file)
elif bl == 'sn32-dfu':
_flash_sonixflasher(details, file)
else:
return (True, "Known bootloader found but flashing not currently supported!")

Expand Down
12 changes: 12 additions & 0 deletions util/install/linux_shared.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,15 @@ _qmk_install_bootloadhid() {
popd > /dev/null
fi
}

# No distros package sonixflasher yet
_qmk_install_sonixflasher() {
if ! command -v sonixflasher > /dev/null; then
wget https://github.com/SonixQMK/SonixFlasherC/archive/refs/tags/1.1.0.tar.gz -O - | tar -xz -C /tmp
pushd /tmp/SonixFlasherC-1.1.0/ > /dev/null
if make; then
sudo cp sonixflasher /usr/local/bin
fi
popd > /dev/null
fi
}
3 changes: 2 additions & 1 deletion util/install/msys2.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ _qmk_install() {
base-devel: toolchain:x clang:x python-qmk:x hidapi:x \
avr-binutils:x avr-gcc:x avr-libc:x \
arm-none-eabi-binutils:x arm-none-eabi-gcc:x arm-none-eabi-newlib:x \
avrdude:x bootloadhid:x dfu-programmer:x dfu-util:x hid-bootloader-cli:x mdloader:x teensy-loader-cli:x wb32-dfu-updater:x
avrdude:x bootloadhid:x dfu-programmer:x dfu-util:x hid-bootloader-cli:x mdloader:x \
teensy-loader-cli:x wb32-dfu-updater:x sonixflasher:x

_qmk_install_drivers
}
Expand Down
4 changes: 4 additions & 0 deletions util/qmk_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,7 @@ _qmk_install
if type _qmk_install_bootloadhid &>/dev/null; then
_qmk_install_bootloadhid
fi

if type _qmk_install_sonixflasher &>/dev/null; then
_qmk_install_sonixflasher
fi
5 changes: 5 additions & 0 deletions util/udev/50-qmk.rules
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,8 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="28e9", ATTRS{idProduct}=="0189", TAG+="uacc

# WB32 DFU
SUBSYSTEMS=="usb", ATTRS{idVendor}=="342d", ATTRS{idProduct}=="dfa0", TAG+="uaccess"

# SN32 DFU
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0c45", ATTRS{idProduct}=="7010", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0c45", ATTRS{idProduct}=="7040", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0c45", ATTRS{idProduct}=="7900", TAG+="uaccess"