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

[sn32] Complete flashing support #401

Merged
merged 7 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 the controller has been flashed with QMK Firmware 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:

* [SonixQMKToolbox](https://github.com/SonixQMK/qmk_toolbox/releases) (recommended GUI)
* [sonixflasher](https://github.com/SonixQMK/SonixFlasherC/releases) / `:flash` target in QMK (recommended command line)
* [sonix-flasher](https://github.com/SonixQMK/sonix-flasher/releases) (old GUI - known to cause issues)
```
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 -j -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. Wait for the keyboard to become available
5 changes: 5 additions & 0 deletions lib/python/qmk/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,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 platforms/chibios/bootloader.mk
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,18 @@ endif
ifeq ($(strip $(BOOTLOADER)), sn32-dfu)
OPT_DEFS += -DBOOTLOADER_SN32_DFU
BOOTLOADER_TYPE = sn32_dfu

# Options to pass to sonixflasher when flashing
ifeq ($(strip $(MCU_SERIES)), SN32F240)
DFU_ARGS ?= -v 0c45/7900
endif
ifeq ($(strip $(MCU_SERIES)), SN32F240B)
DFU_ARGS ?= -v 0c45/7040
endif
ifeq ($(strip $(MCU_SERIES)), SN32F260)
DFU_ARGS ?= -v 0c45/7010 -o 0x200
endif

endif

ifeq ($(strip $(BOOTLOADER_TYPE)),)
Expand Down
8 changes: 8 additions & 0 deletions platforms/chibios/flash.mk
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ define EXEC_WB32_DFU_UPDATER
$(WB32_DFU_UPDATER) -D $(BUILD_DIR)/$(TARGET).bin && $(WB32_DFU_UPDATER) -R
endef

SONIX_FLASHER ?= sonixflasher

define EXEC_SONIX_FLASHER
$(SONIX_FLASHER) $(DFU_ARGS) -f $(BUILD_DIR)/$(TARGET).bin
endef

dfu-util: $(BUILD_DIR)/$(TARGET).bin cpfirmware sizeafter
$(call EXEC_DFU_UTIL)

Expand Down Expand Up @@ -115,6 +121,8 @@ else ifeq ($(strip $(MCU_FAMILY)),WB32)
$(UNSYNC_OUTPUT_CMD) && $(call EXEC_WB32_DFU_UPDATER)
else ifeq ($(strip $(MCU_FAMILY)),GD32V)
$(UNSYNC_OUTPUT_CMD) && $(call EXEC_DFU_UTIL)
else ifeq ($(strip $(MCU_FAMILY)),SN32)
$(UNSYNC_OUTPUT_CMD) && $(call EXEC_SONIX_FLASHER)
else
$(PRINT_OK); $(SILENT) || printf "$(MSG_FLASH_BOOTLOADER)"
endif
13 changes: 13 additions & 0 deletions util/install/linux_shared.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,16 @@ _qmk_install_bootloadhid() {
popd > /dev/null
fi
}

# No distros package sonixflasher yet
_qmk_install_sonixflasher() {
if ! command -v sonixflasher > /dev/null; then
latest_tag=$(curl -s https://api.github.com/repos/SonixQMK/SonixFlasherC/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
wget https://github.com/SonixQMK/SonixFlasherC/archive/refs/tags/${latest_tag}.tar.gz -O - | tar -xz -C /tmp
pushd /tmp/SonixFlasherC-${latest_tag}/ > /dev/null
if make; then
sudo cp sonixflasher /usr/local/bin
fi
popd > /dev/null
fi
}
6 changes: 6 additions & 0 deletions util/install/macos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,9 @@ _qmk_install() {

python3 -m pip install -r $QMK_FIRMWARE_DIR/requirements.txt
}

_qmk_install_sonixflasher() {
echo "Installing sonixflasher"

brew install sonixqmk/sonixqmk/sonixflasher
}
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"
Loading