flash.sh (4581B)
1 #!/bin/sh 2 3 set -eu 4 5 if [ ! -e ./keyboard.hex ]; then 6 echo "keyboard.hex doesn't exist. build it or use ./download-fw.sh to download it." >&2 7 exit 1 8 fi 9 10 if [ "$(id -u)" -ne 0 ]; then 11 echo "you need to run this as root (for example by using sudo)" >&2 12 exit 1 13 fi 14 15 get_property() { 16 path="$1" 17 property="$2" 18 if [ "$(udevadm --version)" -lt 250 ]; then 19 # no udevadm --property before version 250 20 udevadm info --query=property "$path" | sed -ne "s/^$property=//p" 21 else 22 udevadm info --query=property --property="$property" --value "$path" 23 fi 24 } 25 26 find_usb_device() { 27 result= 28 for p in /sys/bus/usb/devices/*; do 29 [ -e "$p/idVendor" ] || continue 30 [ "$(cat "$p/idVendor")" = "$1" ] || continue 31 [ -e "$p/idProduct" ] || continue 32 [ "$(cat "$p/idProduct")" = "$2" ] || continue 33 [ "$(get_property "$p" "ID_MODEL")" = "$3" ] || continue 34 if [ -n "$result" ]; then 35 echo "found more than one device matching $1 $2 $3" >&2 36 exit 1 37 fi 38 result="$(realpath -e "$p")" 39 done 40 echo "$result" 41 } 42 43 remove_prefix_char() { 44 result="$1" 45 char="$2" 46 while :; do 47 case $result in 48 "$char"*) result=${result#"$char"};; 49 *) break;; 50 esac 51 done 52 echo "$result" 53 } 54 55 path_keyboard=$(find_usb_device 03eb 2042 Reform_Keyboard) 56 57 busnum_keyboard= 58 devnum_keyboard= 59 if [ -n "$path_keyboard" ] && [ -e "$path_keyboard" ]; then 60 busnum_keyboard="$(get_property "$path_keyboard" "BUSNUM")" 61 devnum_keyboard="$(get_property "$path_keyboard" "DEVNUM")" 62 echo " 1. Find out your keyboard firmware version in the 'System Status' by pressing" >&2 63 echo " the circle key followed by the S key. The keyboard firmware version is on" >&2 64 echo " on the last line in a date-based format YYYYMMDD. Then either:" 65 echo >&2 66 echo " 2.A. If you are on keyboard firmware version 20231124 or newer:" >&2 67 echo >&2 68 echo " 2.A.1. Press the circle key followed by the X key to enter firmware update mode." >&2 69 echo >&2 70 echo " 2.B. If you are on keyboard firmware version older than 20231124:" >&2 71 echo >&2 72 echo " 2.B.1. Toggle the programming DIP switch SW84 on the keyboard to “ON”." >&2 73 echo " 2.B.2. Press the reset button SW83." >&2 74 echo >&2 75 echo " ATTENTION: Do not remove the keyboard bezel without having disconnected" >&2 76 echo " both battery boards first. If you don't want to remove the" >&2 77 echo " bezel you can reach both the programming DIP switch as well" >&2 78 echo " as the reset button with a non-conductive thin stick (like" >&2 79 echo " a wooden toothpick) behind the F4 key." >&2 80 echo >&2 81 if [ "$(udevadm --version)" -lt 251 ]; then 82 # no udevadm wait before version 251 83 echo " 3. Press the Enter key once you are ready" >&2 84 # shellcheck disable=SC2034 85 read -r enter 86 else 87 echo " 3. Waiting for the keyboard to disappear..." >&2 88 udevadm wait --removed "$path_keyboard" 89 echo " 4. Waiting for the Atmel DFU bootloader USB device to appear..." >&2 90 udevadm wait --settle "$path_keyboard" 91 fi 92 fi 93 94 path=$(find_usb_device 03eb 2ff4 ATm32U4DFU) 95 if [ -z "$path" ] || [ ! -e "$path" ]; then 96 echo "cannot find Atmel DFU bootloader USB device" >&2 97 exit 1 98 fi 99 100 busnum="$(get_property "$path" "BUSNUM")" 101 devnum="$(get_property "$path" "DEVNUM")" 102 103 # do some extra checks if we saw the usb device as a keyboard before 104 if [ -n "$path_keyboard" ] && [ -e "$path_keyboard" ]; then 105 if [ "$path_keyboard" != "$path" ]; then 106 echo "path of Atmel DFU bootloader USB device is different from the keyboard" >&2 107 exit 1 108 fi 109 if [ "$busnum_keyboard" != "$busnum" ]; then 110 echo "busnum of Atmel DFU bootloader USB device is different from the keyboard" >&2 111 exit 1 112 fi 113 # the devnum of the atmel increments by 1 on every press of the reset 114 # button (why?), so no sense comparing those 115 #if [ "$((devnum_keyboard+1))" != "$devnum" ]; then 116 # echo "devnum of Atmel DFU bootloader USB device is different from the keyboard" >&2 117 # exit 1 118 #fi 119 fi 120 121 device="atmega32u4:$(remove_prefix_char "$busnum" 0),$(remove_prefix_char "$devnum" 0)" 122 123 dfu-programmer "$device" erase --suppress-bootloader-mem 124 125 dfu-programmer "$device" flash ./keyboard.hex --suppress-bootloader-mem 126 127 dfu-programmer "$device" start 128 129 if [ "$(udevadm --version)" -ge 251 ]; then 130 echo "Waiting for the Atmel DFU bootloader USB device to disappear..." >&2 131 udevadm wait --removed "$path" 132 echo "Waiting for the keyboard to re-appear..." >&2 133 udevadm wait --settle "$path" 134 fi 135 136 echo "All done!" >&2 137 echo >&2 138 echo "If you were on an old firmware, don't forget to toggle the programming DIP switch SW84 on the keyboard to “OFF” again" >&2