diff options
Diffstat (limited to 'util')
| -rwxr-xr-x | util/new_keyboard.sh | 12 | ||||
| -rw-r--r-- | util/nix/poetry.lock | 467 | ||||
| -rw-r--r-- | util/nix/pyproject.toml | 32 | ||||
| -rw-r--r-- | util/nix/sources.json | 38 | ||||
| -rw-r--r-- | util/nix/sources.nix | 174 | ||||
| -rw-r--r-- | util/reset.eep | 9 | ||||
| -rwxr-xr-x | util/stm32eeprom_parser.py | 317 | ||||
| -rw-r--r-- | util/udev/50-qmk.rules | 6 | ||||
| -rwxr-xr-x | util/update_chibios_mirror.sh | 83 | 
9 files changed, 1135 insertions, 3 deletions
diff --git a/util/new_keyboard.sh b/util/new_keyboard.sh index d0db23bb42..62e8cb9e13 100755 --- a/util/new_keyboard.sh +++ b/util/new_keyboard.sh @@ -1,7 +1,7 @@  #!/usr/bin/env bash  # This script generates a new keyboard directory under keyboards/, -# and copies the template files from quantum/template/ into it. +# and copies the template files from data/templates/ into it.  # Print an error message with the word "ERROR" in red.  echo_error() { @@ -35,11 +35,11 @@ copy_templates() {      mkdir -p "$keyboard_dir"      echo -n "Copying base template files..." -    cp -r "quantum/template/base/." "${keyboard_dir}" +    cp -r "data/templates/base/." "${keyboard_dir}"      echo " done"      echo -n "Copying $keyboard_type template files..." -    cp -r "quantum/template/${keyboard_type}/." "${keyboard_dir}" +    cp -r "data/templates/${keyboard_type}/." "${keyboard_dir}"      echo " done"      echo -n "Renaming keyboard files..." @@ -129,6 +129,12 @@ if [ ! -d "quantum" ]; then      exit 1  fi +echo_bold "########################################" +echo_bold "#                NOTICE                #" +echo_bold "#   This script has been deprecated.   #" +echo_bold "# Please use qmk new-keyboard instead. #" +echo_bold "########################################" +echo  echo_bold "Generating a new QMK keyboard directory"  echo diff --git a/util/nix/poetry.lock b/util/nix/poetry.lock new file mode 100644 index 0000000000..1a1aefe21a --- /dev/null +++ b/util/nix/poetry.lock @@ -0,0 +1,467 @@ +[[package]] +name = "appdirs" +version = "1.4.4" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "argcomplete" +version = "1.12.3" +description = "Bash tab completion for argparse" +category = "main" +optional = false +python-versions = "*" + +[package.extras] +test = ["coverage", "flake8", "pexpect", "wheel"] + +[[package]] +name = "attrs" +version = "21.2.0" +description = "Classes Without Boilerplate" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.extras] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"] +docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"] + +[[package]] +name = "colorama" +version = "0.4.4" +description = "Cross-platform colored terminal text." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "coverage" +version = "5.5" +description = "Code coverage measurement for Python" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" + +[package.extras] +toml = ["toml"] + +[[package]] +name = "dotty-dict" +version = "1.3.0" +description = "Dictionary wrapper for quick access to deeply nested keys." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +setuptools_scm = "*" + +[[package]] +name = "flake8" +version = "3.9.2" +description = "the modular source code checker: pep8 pyflakes and co" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[package.dependencies] +mccabe = ">=0.6.0,<0.7.0" +pycodestyle = ">=2.7.0,<2.8.0" +pyflakes = ">=2.3.0,<2.4.0" + +[[package]] +name = "flake8-polyfill" +version = "1.0.2" +description = "Polyfill package for Flake8 plugins" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +flake8 = "*" + +[[package]] +name = "halo" +version = "0.0.31" +description = "Beautiful terminal spinners in Python" +category = "main" +optional = false +python-versions = ">=3.4" + +[package.dependencies] +colorama = ">=0.3.9" +log-symbols = ">=0.0.14" +six = ">=1.12.0" +spinners = ">=0.0.24" +termcolor = ">=1.1.0" + +[package.extras] +ipython = ["IPython (==5.7.0)", "ipywidgets (==7.1.0)"] + +[[package]] +name = "hid" +version = "1.0.4" +description = "ctypes bindings for hidapi" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "hjson" +version = "3.0.2" +description = "Hjson, a user interface for JSON." +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "jsonschema" +version = "3.2.0" +description = "An implementation of JSON Schema validation for Python" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +attrs = ">=17.4.0" +pyrsistent = ">=0.14.0" +six = ">=1.11.0" + +[package.extras] +format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] +format_nongpl = ["idna", "jsonpointer (>1.13)", "webcolors", "rfc3986-validator (>0.1.0)", "rfc3339-validator"] + +[[package]] +name = "log-symbols" +version = "0.0.14" +description = "Colored symbols for various log levels for Python" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +colorama = ">=0.3.9" + +[[package]] +name = "mccabe" +version = "0.6.1" +description = "McCabe checker, plugin for flake8" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "milc" +version = "1.4.2" +description = "Opinionated Batteries-Included Python 3 CLI Framework." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +appdirs = "*" +argcomplete = "*" +colorama = "*" +halo = "*" +spinners = "*" + +[[package]] +name = "nose2" +version = "0.10.0" +description = "unittest2 with plugins, the succesor to nose" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +coverage = ">=4.4.1" +six = ">=1.7" + +[package.extras] +coverage_plugin = ["coverage (>=4.4.1)"] +dev = ["Sphinx (>=1.6.5)", "sphinx-rtd-theme", "mock", "coverage"] + +[[package]] +name = "pep8-naming" +version = "0.11.1" +description = "Check PEP-8 naming conventions, plugin for flake8" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +flake8-polyfill = ">=1.0.2,<2" + +[[package]] +name = "pycodestyle" +version = "2.7.0" +description = "Python style guide checker" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pyflakes" +version = "2.3.1" +description = "passive checker of Python programs" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pygments" +version = "2.9.0" +description = "Pygments is a syntax highlighting package written in Python." +category = "main" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "pyrsistent" +version = "0.17.3" +description = "Persistent/Functional/Immutable data structures" +category = "main" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "pyusb" +version = "1.1.1" +description = "Python USB access module" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "qmk" +version = "0.0.51" +description = "A program to help users work with QMK Firmware." +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +dotty-dict = "*" +flake8 = "*" +hid = "*" +hjson = "*" +jsonschema = ">=3" +milc = ">=1.4.0" +nose2 = "*" +pygments = "*" +pyusb = "*" +yapf = "*" + +[[package]] +name = "setuptools-scm" +version = "6.0.1" +description = "the blessed package to manage your versions by scm tags" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.extras] +toml = ["toml"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "spinners" +version = "0.0.24" +description = "Spinners for terminals" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "termcolor" +version = "1.1.0" +description = "ANSII Color formatting for output in terminal." +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "yapf" +version = "0.30.0" +description = "A formatter for Python code." +category = "main" +optional = false +python-versions = "*" + +[metadata] +lock-version = "1.1" +python-versions = "^3.8" +content-hash = "5e181d51536240d08c74ba6a46bd0988ee4ca72ac3d5b388965ca8023e9b9a99" + +[metadata.files] +appdirs = [ +    {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, +    {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, +] +argcomplete = [ +    {file = "argcomplete-1.12.3-py2.py3-none-any.whl", hash = "sha256:291f0beca7fd49ce285d2f10e4c1c77e9460cf823eef2de54df0c0fec88b0d81"}, +    {file = "argcomplete-1.12.3.tar.gz", hash = "sha256:2c7dbffd8c045ea534921e63b0be6fe65e88599990d8dc408ac8c542b72a5445"}, +] +attrs = [ +    {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, +    {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, +] +colorama = [ +    {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, +    {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, +] +coverage = [ +    {file = "coverage-5.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf"}, +    {file = "coverage-5.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b"}, +    {file = "coverage-5.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669"}, +    {file = "coverage-5.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90"}, +    {file = "coverage-5.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c"}, +    {file = "coverage-5.5-cp27-cp27m-win32.whl", hash = "sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a"}, +    {file = "coverage-5.5-cp27-cp27m-win_amd64.whl", hash = "sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82"}, +    {file = "coverage-5.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905"}, +    {file = "coverage-5.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083"}, +    {file = "coverage-5.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5"}, +    {file = "coverage-5.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81"}, +    {file = "coverage-5.5-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6"}, +    {file = "coverage-5.5-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0"}, +    {file = "coverage-5.5-cp310-cp310-win_amd64.whl", hash = "sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae"}, +    {file = "coverage-5.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb"}, +    {file = "coverage-5.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160"}, +    {file = "coverage-5.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6"}, +    {file = "coverage-5.5-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701"}, +    {file = "coverage-5.5-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793"}, +    {file = "coverage-5.5-cp35-cp35m-win32.whl", hash = "sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e"}, +    {file = "coverage-5.5-cp35-cp35m-win_amd64.whl", hash = "sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3"}, +    {file = "coverage-5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066"}, +    {file = "coverage-5.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a"}, +    {file = "coverage-5.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465"}, +    {file = "coverage-5.5-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb"}, +    {file = "coverage-5.5-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821"}, +    {file = "coverage-5.5-cp36-cp36m-win32.whl", hash = "sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45"}, +    {file = "coverage-5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184"}, +    {file = "coverage-5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a"}, +    {file = "coverage-5.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53"}, +    {file = "coverage-5.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d"}, +    {file = "coverage-5.5-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638"}, +    {file = "coverage-5.5-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3"}, +    {file = "coverage-5.5-cp37-cp37m-win32.whl", hash = "sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a"}, +    {file = "coverage-5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a"}, +    {file = "coverage-5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6"}, +    {file = "coverage-5.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2"}, +    {file = "coverage-5.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759"}, +    {file = "coverage-5.5-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873"}, +    {file = "coverage-5.5-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a"}, +    {file = "coverage-5.5-cp38-cp38-win32.whl", hash = "sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6"}, +    {file = "coverage-5.5-cp38-cp38-win_amd64.whl", hash = "sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502"}, +    {file = "coverage-5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b"}, +    {file = "coverage-5.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529"}, +    {file = "coverage-5.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b"}, +    {file = "coverage-5.5-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff"}, +    {file = "coverage-5.5-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b"}, +    {file = "coverage-5.5-cp39-cp39-win32.whl", hash = "sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6"}, +    {file = "coverage-5.5-cp39-cp39-win_amd64.whl", hash = "sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03"}, +    {file = "coverage-5.5-pp36-none-any.whl", hash = "sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079"}, +    {file = "coverage-5.5-pp37-none-any.whl", hash = "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4"}, +    {file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"}, +] +dotty-dict = [ +    {file = "dotty_dict-1.3.0.tar.gz", hash = "sha256:eb0035a3629ecd84397a68f1f42f1e94abd1c34577a19cd3eacad331ee7cbaf0"}, +] +flake8 = [ +    {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, +    {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, +] +flake8-polyfill = [ +    {file = "flake8-polyfill-1.0.2.tar.gz", hash = "sha256:e44b087597f6da52ec6393a709e7108b2905317d0c0b744cdca6208e670d8eda"}, +    {file = "flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9"}, +] +halo = [ +    {file = "halo-0.0.31-py2-none-any.whl", hash = "sha256:5350488fb7d2aa7c31a1344120cee67a872901ce8858f60da7946cef96c208ab"}, +    {file = "halo-0.0.31.tar.gz", hash = "sha256:7b67a3521ee91d53b7152d4ee3452811e1d2a6321975137762eb3d70063cc9d6"}, +] +hid = [ +    {file = "hid-1.0.4-py2-none-any.whl", hash = "sha256:fba9913f07030b01059b822b24c83b370ca3f444e9e6443bd662f9f1aa3f0780"}, +    {file = "hid-1.0.4.tar.gz", hash = "sha256:f61b0382f37a334bc8ba8604bc84b94875ee4f594fbbaf82b2c3b3e827883fc1"}, +] +hjson = [ +    {file = "hjson-3.0.2-py3-none-any.whl", hash = "sha256:5546438bf4e1b52bc964c6a47c4ed10fa5fba8a1b264e22efa893e333baad2db"}, +    {file = "hjson-3.0.2.tar.gz", hash = "sha256:2838fd7200e5839ea4516ece953f3a19892c41089f0d933ba3f68e596aacfcd5"}, +] +jsonschema = [ +    {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, +    {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, +] +log-symbols = [ +    {file = "log_symbols-0.0.14-py3-none-any.whl", hash = "sha256:4952106ff8b605ab7d5081dd2c7e6ca7374584eff7086f499c06edd1ce56dcca"}, +    {file = "log_symbols-0.0.14.tar.gz", hash = "sha256:cf0bbc6fe1a8e53f0d174a716bc625c4f87043cc21eb55dd8a740cfe22680556"}, +] +mccabe = [ +    {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, +    {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] +milc = [ +    {file = "milc-1.4.2-py2.py3-none-any.whl", hash = "sha256:65ee004caa769b1ee144b15be7908d1f623920ab6f356e5c5c95be9457aa15d8"}, +    {file = "milc-1.4.2.tar.gz", hash = "sha256:c6b2f19e3196b00a0060f8c883533e356f2054a9f81692b7b97ccee0d01626fd"}, +] +nose2 = [ +    {file = "nose2-0.10.0-py2.py3-none-any.whl", hash = "sha256:aa620e759f2c5018d9ba041340391913e282ecebd3c392027f1575847b093ec6"}, +    {file = "nose2-0.10.0.tar.gz", hash = "sha256:886ba617a96de0130c54b24479bd5c2d74d5c940d40f3809c3a275511a0c4a60"}, +] +pep8-naming = [ +    {file = "pep8-naming-0.11.1.tar.gz", hash = "sha256:a1dd47dd243adfe8a83616e27cf03164960b507530f155db94e10b36a6cd6724"}, +    {file = "pep8_naming-0.11.1-py2.py3-none-any.whl", hash = "sha256:f43bfe3eea7e0d73e8b5d07d6407ab47f2476ccaeff6937c84275cd30b016738"}, +] +pycodestyle = [ +    {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, +    {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, +] +pyflakes = [ +    {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, +    {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, +] +pygments = [ +    {file = "Pygments-2.9.0-py3-none-any.whl", hash = "sha256:d66e804411278594d764fc69ec36ec13d9ae9147193a1740cd34d272ca383b8e"}, +    {file = "Pygments-2.9.0.tar.gz", hash = "sha256:a18f47b506a429f6f4b9df81bb02beab9ca21d0a5fee38ed15aef65f0545519f"}, +] +pyrsistent = [ +    {file = "pyrsistent-0.17.3.tar.gz", hash = "sha256:2e636185d9eb976a18a8a8e96efce62f2905fea90041958d8cc2a189756ebf3e"}, +] +pyusb = [ +    {file = "pyusb-1.1.1-py3-none-any.whl", hash = "sha256:f18eb813d3a1439918071234589162c2f209a19adbeffeb1377ce078a4aebc70"}, +    {file = "pyusb-1.1.1.tar.gz", hash = "sha256:7d449ad916ce58aff60b89aae0b65ac130f289c24d6a5b7b317742eccffafc38"}, +] +qmk = [ +    {file = "qmk-0.0.51-py2.py3-none-any.whl", hash = "sha256:5f676f389b2450b0956d7eb8e7e378d2e6690d5859a887c91876da0a5faf75ed"}, +    {file = "qmk-0.0.51.tar.gz", hash = "sha256:efeef209cde1df92b9823db686d9684962cd00aae9f45ba5e3d494aa5b3c6b9a"}, +] +setuptools-scm = [ +    {file = "setuptools_scm-6.0.1-py3-none-any.whl", hash = "sha256:c3bd5f701c8def44a5c0bfe8d407bef3f80342217ef3492b951f3777bd2d915c"}, +    {file = "setuptools_scm-6.0.1.tar.gz", hash = "sha256:d1925a69cb07e9b29416a275b9fadb009a23c148ace905b2fb220649a6c18e92"}, +] +six = [ +    {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, +    {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] +spinners = [ +    {file = "spinners-0.0.24-py3-none-any.whl", hash = "sha256:2fa30d0b72c9650ad12bbe031c9943b8d441e41b4f5602b0ec977a19f3290e98"}, +    {file = "spinners-0.0.24.tar.gz", hash = "sha256:1eb6aeb4781d72ab42ed8a01dcf20f3002bf50740d7154d12fb8c9769bf9e27f"}, +] +termcolor = [ +    {file = "termcolor-1.1.0.tar.gz", hash = "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b"}, +] +yapf = [ +    {file = "yapf-0.30.0-py2.py3-none-any.whl", hash = "sha256:3abf61ba67cf603069710d30acbc88cfe565d907e16ad81429ae90ce9651e0c9"}, +    {file = "yapf-0.30.0.tar.gz", hash = "sha256:3000abee4c28daebad55da6c85f3cd07b8062ce48e2e9943c8da1b9667d48427"}, +] diff --git a/util/nix/pyproject.toml b/util/nix/pyproject.toml new file mode 100644 index 0000000000..a813361893 --- /dev/null +++ b/util/nix/pyproject.toml @@ -0,0 +1,32 @@ +# This file should be kept in sync with requirements.txt and requirements-dev.txt +# It is particularly required by the Nix environment (see shell.nix). To update versions, +# normally one would run "poetry update --lock" +[tool.poetry] +name = "qmk_firmware" +version = "0.1.0" +description = "" +authors = [] + +[tool.poetry.dependencies] +python = "^3.8" +appdirs = "^1.4.4" +argcomplete = "^1.12.2" +colorama = "^0.4.4" +dotty-dict = "^1.3.0" +hjson = "^3.0.2" +jsonschema = "^3.2.0" +milc = "^1.3.0" +Pygments = "^2.8.0" +qmk = "*" + +[tool.poetry.dev-dependencies] +nose2 = "^0.10.0" +flake8 = "^3.8.4" +hid = "^1.0.4" +pep8-naming = "^0.11.1" +pyusb = "^1.1.1" +yapf = "^0.30.0" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/util/nix/sources.json b/util/nix/sources.json new file mode 100644 index 0000000000..caf5cb7d29 --- /dev/null +++ b/util/nix/sources.json @@ -0,0 +1,38 @@ +{ +    "niv": { +        "branch": "master", +        "description": "Easy dependency management for Nix projects", +        "homepage": "https://github.com/nmattia/niv", +        "owner": "nmattia", +        "repo": "niv", +        "rev": "af958e8057f345ee1aca714c1247ef3ba1c15f5e", +        "sha256": "1qjavxabbrsh73yck5dcq8jggvh3r2jkbr6b5nlz5d9yrqm9255n", +        "type": "tarball", +        "url": "https://github.com/nmattia/niv/archive/af958e8057f345ee1aca714c1247ef3ba1c15f5e.tar.gz", +        "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" +    }, +    "nixpkgs": { +        "branch": "nixpkgs-unstable", +        "description": "Nix Packages collection", +        "homepage": "", +        "owner": "NixOS", +        "repo": "nixpkgs", +        "rev": "c0e881852006b132236cbf0301bd1939bb50867e", +        "sha256": "0fy7z7yxk5n7yslsvx5cyc6h21qwi4bhxf3awhirniszlbvaazy2", +        "type": "tarball", +        "url": "https://github.com/NixOS/nixpkgs/archive/c0e881852006b132236cbf0301bd1939bb50867e.tar.gz", +        "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" +    }, +    "poetry2nix": { +        "branch": "master", +        "description": "Convert poetry projects to nix automagically [maintainer=@adisbladis] ", +        "homepage": "", +        "owner": "nix-community", +        "repo": "poetry2nix", +        "rev": "2d27d44397242b28c3f0081e0432e4f6c951f3a1", +        "sha256": "06syfg150r59m4kksj5547b5kwxjxjaif5hiljcq966kb9hxsvmv", +        "type": "tarball", +        "url": "https://github.com/nix-community/poetry2nix/archive/2d27d44397242b28c3f0081e0432e4f6c951f3a1.tar.gz", +        "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" +    } +} diff --git a/util/nix/sources.nix b/util/nix/sources.nix new file mode 100644 index 0000000000..1938409ddd --- /dev/null +++ b/util/nix/sources.nix @@ -0,0 +1,174 @@ +# This file has been generated by Niv. + +let + +  # +  # The fetchers. fetch_<type> fetches specs of type <type>. +  # + +  fetch_file = pkgs: name: spec: +    let +      name' = sanitizeName name + "-src"; +    in +      if spec.builtin or true then +        builtins_fetchurl { inherit (spec) url sha256; name = name'; } +      else +        pkgs.fetchurl { inherit (spec) url sha256; name = name'; }; + +  fetch_tarball = pkgs: name: spec: +    let +      name' = sanitizeName name + "-src"; +    in +      if spec.builtin or true then +        builtins_fetchTarball { name = name'; inherit (spec) url sha256; } +      else +        pkgs.fetchzip { name = name'; inherit (spec) url sha256; }; + +  fetch_git = name: spec: +    let +      ref = +        if spec ? ref then spec.ref else +          if spec ? branch then "refs/heads/${spec.branch}" else +            if spec ? tag then "refs/tags/${spec.tag}" else +              abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!"; +    in +      builtins.fetchGit { url = spec.repo; inherit (spec) rev; inherit ref; }; + +  fetch_local = spec: spec.path; + +  fetch_builtin-tarball = name: throw +    ''[${name}] The niv type "builtin-tarball" is deprecated. You should instead use `builtin = true`. +        $ niv modify ${name} -a type=tarball -a builtin=true''; + +  fetch_builtin-url = name: throw +    ''[${name}] The niv type "builtin-url" will soon be deprecated. You should instead use `builtin = true`. +        $ niv modify ${name} -a type=file -a builtin=true''; + +  # +  # Various helpers +  # + +  # https://github.com/NixOS/nixpkgs/pull/83241/files#diff-c6f540a4f3bfa4b0e8b6bafd4cd54e8bR695 +  sanitizeName = name: +    ( +      concatMapStrings (s: if builtins.isList s then "-" else s) +        ( +          builtins.split "[^[:alnum:]+._?=-]+" +            ((x: builtins.elemAt (builtins.match "\\.*(.*)" x) 0) name) +        ) +    ); + +  # The set of packages used when specs are fetched using non-builtins. +  mkPkgs = sources: system: +    let +      sourcesNixpkgs = +        import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) { inherit system; }; +      hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath; +      hasThisAsNixpkgsPath = <nixpkgs> == ./.; +    in +      if builtins.hasAttr "nixpkgs" sources +      then sourcesNixpkgs +      else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then +        import <nixpkgs> {} +      else +        abort +          '' +            Please specify either <nixpkgs> (through -I or NIX_PATH=nixpkgs=...) or +            add a package called "nixpkgs" to your sources.json. +          ''; + +  # The actual fetching function. +  fetch = pkgs: name: spec: + +    if ! builtins.hasAttr "type" spec then +      abort "ERROR: niv spec ${name} does not have a 'type' attribute" +    else if spec.type == "file" then fetch_file pkgs name spec +    else if spec.type == "tarball" then fetch_tarball pkgs name spec +    else if spec.type == "git" then fetch_git name spec +    else if spec.type == "local" then fetch_local spec +    else if spec.type == "builtin-tarball" then fetch_builtin-tarball name +    else if spec.type == "builtin-url" then fetch_builtin-url name +    else +      abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}"; + +  # If the environment variable NIV_OVERRIDE_${name} is set, then use +  # the path directly as opposed to the fetched source. +  replace = name: drv: +    let +      saneName = stringAsChars (c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c) name; +      ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}"; +    in +      if ersatz == "" then drv else +        # this turns the string into an actual Nix path (for both absolute and +        # relative paths) +        if builtins.substring 0 1 ersatz == "/" then /. + ersatz else /. + builtins.getEnv "PWD" + "/${ersatz}"; + +  # Ports of functions for older nix versions + +  # a Nix version of mapAttrs if the built-in doesn't exist +  mapAttrs = builtins.mapAttrs or ( +    f: set: with builtins; +    listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set)) +  ); + +  # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295 +  range = first: last: if first > last then [] else builtins.genList (n: first + n) (last - first + 1); + +  # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257 +  stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1)); + +  # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269 +  stringAsChars = f: s: concatStrings (map f (stringToCharacters s)); +  concatMapStrings = f: list: concatStrings (map f list); +  concatStrings = builtins.concatStringsSep ""; + +  # https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d118/lib/attrsets.nix#L331 +  optionalAttrs = cond: as: if cond then as else {}; + +  # fetchTarball version that is compatible between all the versions of Nix +  builtins_fetchTarball = { url, name ? null, sha256 }@attrs: +    let +      inherit (builtins) lessThan nixVersion fetchTarball; +    in +      if lessThan nixVersion "1.12" then +        fetchTarball ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; })) +      else +        fetchTarball attrs; + +  # fetchurl version that is compatible between all the versions of Nix +  builtins_fetchurl = { url, name ? null, sha256 }@attrs: +    let +      inherit (builtins) lessThan nixVersion fetchurl; +    in +      if lessThan nixVersion "1.12" then +        fetchurl ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; })) +      else +        fetchurl attrs; + +  # Create the final "sources" from the config +  mkSources = config: +    mapAttrs ( +      name: spec: +        if builtins.hasAttr "outPath" spec +        then abort +          "The values in sources.json should not have an 'outPath' attribute" +        else +          spec // { outPath = replace name (fetch config.pkgs name spec); } +    ) config.sources; + +  # The "config" used by the fetchers +  mkConfig = +    { sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null +    , sources ? if isNull sourcesFile then {} else builtins.fromJSON (builtins.readFile sourcesFile) +    , system ? builtins.currentSystem +    , pkgs ? mkPkgs sources system +    }: rec { +      # The sources, i.e. the attribute set of spec name to spec +      inherit sources; + +      # The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers +      inherit pkgs; +    }; + +in +mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); } diff --git a/util/reset.eep b/util/reset.eep new file mode 100644 index 0000000000..a8a75389fe --- /dev/null +++ b/util/reset.eep @@ -0,0 +1,9 @@ +:10000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:10001000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:10002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:10004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:10005000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:10006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:10007000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:00000001FF diff --git a/util/stm32eeprom_parser.py b/util/stm32eeprom_parser.py new file mode 100755 index 0000000000..b124f713d5 --- /dev/null +++ b/util/stm32eeprom_parser.py @@ -0,0 +1,317 @@ +#!/usr/bin/env python +# +# Copyright 2021 Don Kjer +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program.  If not, see <http://www.gnu.org/licenses/>. +# + +from __future__ import print_function + +import argparse +from struct import pack, unpack +import os, sys + +MAGIC_FEEA     = '\xea\xff\xfe\xff' + +MAGIC_FEE9     = '\x16\x01' +EMPTY_WORD     = '\xff\xff' +WORD_ENCODING  = 0x8000 +VALUE_NEXT     = 0x6000 +VALUE_RESERVED = 0x4000 +VALUE_ENCODED  = 0x2000 +BYTE_RANGE     = 0x80 + +CHUNK_SIZE = 1024 + +STRUCT_FMTS = { +    1: 'B', +    2: 'H', +    4: 'I' +} +PRINTABLE='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ ' + +EECONFIG_V1 = [ +    ("MAGIC",                0, 2), +    ("DEBUG",                2, 1), +    ("DEFAULT_LAYER",        3, 1), +    ("KEYMAP",               4, 1), +    ("MOUSEKEY_ACCEL",       5, 1), +    ("BACKLIGHT",            6, 1), +    ("AUDIO",                7, 1), +    ("RGBLIGHT",             8, 4), +    ("UNICODEMODE",         12, 1), +    ("STENOMODE",           13, 1), +    ("HANDEDNESS",          14, 1), +    ("KEYBOARD",            15, 4), +    ("USER",                19, 4), +    ("VELOCIKEY",           23, 1), +    ("HAPTIC",              24, 4), +    ("MATRIX",              28, 4), +    ("MATRIX_EXTENDED",     32, 2), +    ("KEYMAP_UPPER_BYTE",   34, 1), +] +VIABASE_V1 = 35 + +VERBOSE = False + +def parseArgs(): +    parser = argparse.ArgumentParser(description='Decode an STM32 emulated eeprom dump') +    parser.add_argument('-s', '--size', type=int, +                        help='Size of the emulated eeprom (default: input_size / 2)') +    parser.add_argument('-o', '--output', help='File to write decoded eeprom to') +    parser.add_argument('-y', '--layout-options-size', type=int, +                        help='VIA layout options size (default: 1)', default=1) +    parser.add_argument('-t', '--custom-config-size', type=int, +                        help='VIA custom config size (default: 0)', default=0) +    parser.add_argument('-l', '--layers', type=int, +                        help='VIA keyboard layers (default: 4)', default=4) +    parser.add_argument('-r', '--rows', type=int, help='VIA matrix rows') +    parser.add_argument('-c', '--cols', type=int, help='VIA matrix columns') +    parser.add_argument('-m', '--macros', type=int, +                        help='VIA macro count (default: 16)', default=16) +    parser.add_argument('-C', '--canonical', action='store_true', +                        help='Canonical hex+ASCII display.') +    parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output') +    parser.add_argument('input', help='Raw contents of the STM32 flash area used to emulate eeprom') +    return parser.parse_args() + + +def decodeEepromFEEA(in_file, size): +    decoded=size*[None] +    pos = 0 +    while True: +        chunk = in_file.read(CHUNK_SIZE) +        for i in range(0, len(chunk), 2): +            decoded[pos] = unpack('B', chunk[i])[0] +            pos += 1 +            if pos >= size: +                break + +        if len(chunk) < CHUNK_SIZE or pos >= size: +            break +    return decoded + +def decodeEepromFEE9(in_file, size): +    decoded=size*[None] +    pos = 0 +    # Read compacted flash  +    while True: +        read_size = min(size - pos, CHUNK_SIZE) +        chunk = in_file.read(read_size) +        for i in range(len(chunk)): +            decoded[pos] = unpack('B', chunk[i])[0] ^ 0xFF +            pos += 1 +            if pos >= size: +                break + +        if len(chunk) < read_size or pos >= size: +            break +    if VERBOSE: +        print("COMPACTED EEPROM:") +        dumpBinary(decoded, True) +        print("WRITE LOG:") +    # Read write log +    while True: +        entry = in_file.read(2) +        if len(entry) < 2: +            print("Partial log address at position 0x%04x" % pos, file=sys.stderr) +            break +        pos += 2 + +        if entry == EMPTY_WORD: +            break + +        be_entry = unpack('>H', entry)[0] +        entry = unpack('H', entry)[0] +        if not (entry & WORD_ENCODING): +            address = entry >> 8 +            decoded[address] = entry & 0xFF +            if VERBOSE: +                print("[0x%04x]: BYTE 0x%02x = 0x%02x" % (be_entry, address, decoded[address])) +        else: +            if (entry & VALUE_NEXT) == VALUE_NEXT: +                # Read next word as value +                value = in_file.read(2) +                if len(value) < 2: +                    print("Partial log value at position 0x%04x" % pos, file=sys.stderr) +                    break +                pos += 2 +                address = entry & 0x1FFF +                address <<= 1 +                address += BYTE_RANGE +                decoded[address]   = unpack('B', value[0])[0] ^ 0xFF +                decoded[address+1] = unpack('B', value[1])[0] ^ 0xFF +                be_value = unpack('>H', value)[0] +                if VERBOSE: +                    print("[0x%04x 0x%04x]: WORD 0x%04x = 0x%02x%02x" % (be_entry, be_value, address, decoded[address+1], decoded[address])) +            else: +                # Reserved for future use +                if entry & VALUE_RESERVED: +                    if VERBOSE: +                        print("[0x%04x]: RESERVED 0x%04x" % (be_entry, address)) +                    continue +                address = entry & 0x1FFF +                address <<= 1 +                decoded[address]   = (entry & VALUE_ENCODED) >> 13 +                decoded[address+1] = 0 +                if VERBOSE: +                    print("[0x%04x]: ENCODED 0x%04x = 0x%02x%02x" % (be_entry, address, decoded[address+1], decoded[address])) + +    return decoded + +def dumpBinary(data, canonical): +    def display(pos, row): +        print("%04x" % pos, end='') +        for i in range(len(row)): +            if i % 8 == 0: +                print(" ", end='') +            char = row[i] +            if char is None: +                print("   ", end='') +            else: +                print(" %02x" % row[i], end='') +        if canonical: +            print("  |", end='') +            for i in range(len(row)): +                char = row[i] +                if char is None: +                    char = " " +                else: +                    char = chr(char) +                if char not in PRINTABLE: +                    char = "." +                print(char, end='') +            print("|", end='') + +        print("") + +    size = len(data) +    empty_rows = 0 +    prev_row = '' +    first_repeat = True +    for pos in range(0, size, 16): +        row=data[pos:pos+16] +        row[len(row):16] = (16-len(row))*[None] +        if row == prev_row: +            if first_repeat: +                print("*") +                first_repeat = False +        else: +            first_repeat = True +            display(pos, row) +        prev_row = row +    print("%04x" % (pos+16)) + +def dumpEeconfig(data, eeconfig): +    print("EECONFIG:") +    for (name, pos, length) in eeconfig: +        fmt = STRUCT_FMTS[length] +        value = unpack(fmt, ''.join([chr(x) for x in data[pos:pos+length]]))[0] +        print(("%%04x %%s = 0x%%0%dx" % (length * 2)) % (pos, name, value)) + +def dumpVia(data, base, layers, cols, rows, macros, +            layout_options_size, custom_config_size): +    magicYear  = data[base + 0] +    magicMonth = data[base + 1] +    magicDay   = data[base + 2] +    # Sanity check +    if not 10 <= magicYear <= 0x99 or \ +       not 0 <= magicMonth <= 0x12 or \ +       not 0 <= magicDay <= 0x31: +        print("ERROR: VIA Signature is not valid; Year:%x, Month:%x, Day:%x" % (magicYear, magicMonth, magicDay)) +        return +    if cols is None or rows is None: +        print("ERROR: VIA dump requires specifying --rows and --cols", file=sys.stderr) +        return 2 +    print("VIA:") +    # Decode magic +    print("%04x MAGIC = 20%02x-%02x-%02x" % (base, magicYear, magicMonth, magicDay)) +    # Decode layout options +    options = 0 +    pos = base + 3 +    for i in range(base+3, base+3+layout_options_size): +        options = options << 8 +        options |= data[i] +    print(("%%04x LAYOUT_OPTIONS = 0x%%0%dx" % (layout_options_size * 2)) % (pos, options)) +    pos += layout_options_size + custom_config_size +    # Decode keycodes +    keymap_size = layers * rows * cols * 2 +    if (pos + keymap_size) >= (len(data) - 1): +        print("ERROR: VIA keymap requires %d bytes, but only %d available" % (keymap_size, len(data) - pos)) +        return 3 +    for layer in range(layers): +        print("%s LAYER %d %s" % ('-'*int(cols*2.5), layer, '-'*int(cols*2.5))) +        for row in range(rows): +            print("%04x  | " % pos, end='') +            for col in range(cols): +                keycode = (data[pos] << 8) | (data[pos+1]) +                print(" %04x" % keycode, end='') +                pos += 2 +            print("") +    # Decode macros +    for macro_num in range(macros): +        macro = "" +        macro_pos = pos +        while pos < len(data): +            char = chr(data[pos]) +            pos += 1 +            if char == '\x00': +                print("%04x MACRO[%d] = '%s'" % (macro_pos, macro_num, macro)) +                break +            else: +                macro += char +    return 0 + + +def decodeSTM32Eeprom(input, canonical, size=None, output=None, **kwargs): +    input_size = os.path.getsize(input) +    if size is None: +        size = input_size >> 1 + +    # Read the first few bytes to check magic signature +    with open(input, 'rb') as in_file: +        magic=in_file.read(4) +        in_file.seek(0) + +        if magic == MAGIC_FEEA: +            decoded = decodeEepromFEEA(in_file, size) +            eeconfig = EECONFIG_V1 +            via_base = VIABASE_V1 +        elif magic[:2] == MAGIC_FEE9: +            decoded = decodeEepromFEE9(in_file, size) +            eeconfig = EECONFIG_V1 +            via_base = VIABASE_V1 +        else: +            print("Unknown magic signature: %s" % " ".join(["0x%02x" % ord(x) for x in magic]), file=sys.stderr) +            return 1 + +    if output is not None: +        with open(output, 'wb') as out_file: +            out_file.write(pack('%dB' % len(decoded), *decoded)) +    print("DECODED EEPROM:") +    dumpBinary(decoded, canonical) +    dumpEeconfig(decoded, eeconfig) +    if kwargs['rows'] is not None and kwargs['cols'] is not None: +        return dumpVia(decoded, via_base, **kwargs) + +    return 0 + +def main(): +    global VERBOSE +    kwargs = vars(parseArgs()) +    VERBOSE = kwargs.pop('verbose') +    return decodeSTM32Eeprom(**kwargs) + +if __name__ == '__main__': +    sys.exit(main()) diff --git a/util/udev/50-qmk.rules b/util/udev/50-qmk.rules index 679fe4ced3..db27d4dc81 100644 --- a/util/udev/50-qmk.rules +++ b/util/udev/50-qmk.rules @@ -63,3 +63,9 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="2a03", ATTRS{idProduct}=="0037", TAG+="uacc  # hid_listen  KERNEL=="hidraw*", MODE="0660", GROUP="plugdev", TAG+="uaccess", TAG+="udev-acl" + +# hid bootloaders +## QMK HID +SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2067", TAG+="uaccess" +## PJRC's HalfKay +SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="0478", TAG+="uaccess" diff --git a/util/update_chibios_mirror.sh b/util/update_chibios_mirror.sh new file mode 100755 index 0000000000..d4593a8432 --- /dev/null +++ b/util/update_chibios_mirror.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +################################ +# Configuration + +# The ChibiOS branches to mirror +chibios_branches="trunk stable_20.3.x stable_21.6.x" + +# The ChibiOS tags to mirror +chibios_tags="ver20.3.1 ver20.3.2 ver20.3.3 ver21.6.0" + +# The ChibiOS-Contrib branches to mirror +contrib_branches="master chibios-20.3.x" + +################################ +# Actions + +set -eEuo pipefail +umask 022 + +this_script="$(realpath "${BASH_SOURCE[0]}")" +script_dir="$(realpath "$(dirname "$this_script")")" +qmk_firmware_dir="$(realpath "$script_dir/../")" +chibios_dir="$qmk_firmware_dir/lib/chibios" +contrib_dir="$qmk_firmware_dir/lib/chibios-contrib" + +chibios_git_location=$(realpath "$chibios_dir/$(cat "$chibios_dir/.git" | awk '/gitdir:/ {print $2}')") +chibios_git_config=$(realpath "$chibios_git_location/config") +contrib_git_location=$(realpath "$contrib_dir/$(cat "$contrib_dir/.git" | awk '/gitdir:/ {print $2}')") +contrib_git_config=$(realpath "$contrib_git_location/config") + +cd "$chibios_dir" + +if [[ -z "$(cat "$chibios_git_config" | grep '\[svn-remote "svn"\]')" ]] ; then +    git svn init --stdlayout --prefix='svn/' http://svn.osdn.net/svnroot/chibios/ +fi + +if [[ -z "$(cat "$chibios_git_config" | grep '\[remote "qmk"\]')" ]] ; then +    git remote add qmk git@github.com:qmk/ChibiOS.git +    git remote set-url qmk git@github.com:qmk/ChibiOS.git --push +fi + +echo "Updating remotes..." +git fetch --all --tags --prune + +echo "Fetching latest from subversion..." +git svn fetch + +echo "Updating ChibiOS branches..." +for branch in $chibios_branches ; do +    echo "Creating branch 'svn-mirror/$branch' from 'svn/$branch'..." +    git branch -f svn-mirror/$branch svn/$branch \ +        && git push qmk svn-mirror/$branch +done + +echo "Updating ChibiOS tags..." +for tagname in $chibios_tags ; do +    echo "Creating tag 'svn-mirror/$tagname' from 'svn/tags/$tagname'..." +    GIT_COMMITTER_DATE="$(git log -n1 --pretty=format:'%ad' svn/tags/$tagname)" git tag -f -a -m "Tagging $tagname" svn-mirror/$tagname svn/tags/$tagname +    git push qmk svn-mirror/$tagname +done + +cd "$contrib_dir" + +if [[ -z "$(cat "$contrib_git_config" | grep '\[remote "qmk"\]')" ]] ; then +    git remote add qmk git@github.com:qmk/ChibiOS-Contrib.git +    git remote set-url qmk git@github.com:qmk/ChibiOS-Contrib.git --push +fi + +if [[ -z "$(cat "$contrib_git_config" | grep '\[remote "upstream"\]')" ]] ; then +    git remote add upstream git@github.com:ChibiOS/ChibiOS-Contrib.git +    git remote set-url upstream git@github.com:ChibiOS/ChibiOS-Contrib.git --push +fi + +echo "Updating remotes..." +git fetch --all --tags --prune + +echo "Updating ChibiOS-Contrib branches..." +for branch in $contrib_branches ; do +    echo "Creating branch 'mirror/$branch' from 'upstream/$branch'..." +    git branch -f mirror/$branch upstream/$branch \ +        && git push qmk mirror/$branch +done  | 
