unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
* [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages
@ 2023-09-26 18:59 Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 01/22] gnu: make-avr-toolchain: Add a #:xgcc argument Maxim Cournoyer
                   ` (21 more replies)
  0 siblings, 22 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 18:59 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer

This series add various ErgoDox keyboards (AVR-based)
firmware packages.  I've tested them with a newly built ErgoDox keyboard (from
a 2014 kit!).  The make-qmk-firmware procedure should be easy to extend to
support more keyboards, if someone is interested in doing so.


Maxim Cournoyer (22):
  gnu: make-avr-toolchain: Add a #:xgcc argument.
  gnu: qmk: Style.
  gnu: qmk: Avoid propagating inputs.
  gnu: qmk: Use GCC 8 for the AVR toolchain.
  gnu: qmk: Add many missing inputs and add more commands to PATH.
  gnu: Add lufa.
  gnu: embedded: Do not use a prefix on the (gnu packages base) module.
  gnu: Add qmk-firmware-ergodox-ez-default.
  gnu: Add qmk-firmware-ergodox-ez-dvorak-42-key.
  gnu: Add qmk-udev-rules.
  gnu: Add qmk-firmware-ergodox-ez-hacker-dvorak.
  gnu: Add qmk-firmware-ergodox-ez-dvorak.
  gnu: Add qmk-firmware-ergodox-ez-dvorak-emacs.
  gnu: Add qmk-firmware-ergodox-ez-dvorak-emacs-software.
  gnu: Add ergodox-firmware-colemak-jc-mod.
  gnu: Add ergodox-firmware-colemak-symbol-mod.
  gnu: Add ergodox-firmware-dvorak-kinesis-mod.
  gnu: Add ergodox-firmware-qwerty-kinesis-mod.
  gnu: Add ergodox-firmware-workman-p-kinesis-mod.
  gnu: teensy-loader-cli: Use gexps.
  gnu: teensy-loader-cli: Fix license.
  gnu: Add teensy-udev-rules.

 gnu/local.mk                                  |    3 +
 gnu/packages/avr-xyz.scm                      |   83 +
 gnu/packages/avr.scm                          |  212 +--
 gnu/packages/embedded.scm                     |    8 +-
 gnu/packages/firmware.scm                     |  378 ++++-
 gnu/packages/flashing-tools.scm               |   64 +-
 .../ergodox-firmware-fix-json-target.patch    | 1405 +++++++++++++++++
 .../patches/ergodox-firmware-fix-numpad.patch |   18 +
 .../qmk-firmware-fix-hacker-dvorak.patch      |   15 +
 9 files changed, 2061 insertions(+), 125 deletions(-)
 create mode 100644 gnu/packages/patches/ergodox-firmware-fix-json-target.patch
 create mode 100644 gnu/packages/patches/ergodox-firmware-fix-numpad.patch
 create mode 100644 gnu/packages/patches/qmk-firmware-fix-hacker-dvorak.patch


base-commit: 06dc36ffb7cde821a4762b299d1c95b3788ba110
-- 
2.41.0





^ permalink raw reply	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 01/22] gnu: make-avr-toolchain: Add a #:xgcc argument.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 02/22] gnu: qmk: Style Maxim Cournoyer
                   ` (20 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer

This allows generating an AVR toolchain for any version of GCC.

* gnu/packages/avr.scm (make-avr-gcc): Add a #:xgcc argument; use memoize
instead of mlambda.
(make-avr-libc): Likewise.  Provide it to the 'make-avr-gcc' call.
(make-avr-toolchain): Add a #:xgcc argument; use memoize instead of mlambda.
Provide the xgcc argument to the 'make-avr-libc' and 'make-avr-gcc'
procedures.
---

 gnu/packages/avr.scm | 212 ++++++++++++++++++++++---------------------
 1 file changed, 110 insertions(+), 102 deletions(-)

diff --git a/gnu/packages/avr.scm b/gnu/packages/avr.scm
index bc583ddff3b..a66abbbd3ad 100644
--- a/gnu/packages/avr.scm
+++ b/gnu/packages/avr.scm
@@ -6,6 +6,7 @@
 ;;; Copyright © 2018 Tobias Geerinckx-Rice <me@tobias.gr>
 ;;; Copyright © 2020 Marius Bakke <mbakke@fastmail.com>
 ;;; Copyright © 2020 Arun Isaac <arunisaac@systemreboot.net>
+;;; Copyright © 2023 Maxim Cournoyer <maxim.cournoyer@gmail.com>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -58,115 +59,122 @@ (define make-avr-binutils
       (inherit (cross-binutils "avr"))
       (name "avr-binutils"))))
 
-(define make-avr-gcc
-  (mlambda ()
-    (let ((xgcc (cross-gcc "avr" #:xbinutils (make-avr-binutils))))
-      (package
-        (inherit xgcc)
-        (name "avr-gcc")
-        (arguments
-         (substitute-keyword-arguments (package-arguments xgcc)
-           ((#:phases phases)
-            #~(modify-phases #$phases
-                (add-after 'set-paths 'augment-CPLUS_INCLUDE_PATH
-                  (lambda* (#:key inputs #:allow-other-keys)
-                    (let ((gcc (assoc-ref inputs  "gcc")))
-                      ;; Remove the default compiler from CPLUS_INCLUDE_PATH
-                      ;; to prevent header conflict with the GCC from
-                      ;; native-inputs.
-                      (setenv "CPLUS_INCLUDE_PATH"
-                              (string-join
-                               (delete (string-append gcc "/include/c++")
-                                       (string-split (getenv "CPLUS_INCLUDE_PATH")
-                                                     #\:))
-                               ":"))
-                      (format #t
-                              "environment variable `CPLUS_INCLUDE_PATH' \
+(define* (make-avr-gcc/implementation #:key (xgcc gcc))
+  "Return a XGCC-base cross-compiler for the AVR target."
+  (let ((xgcc (cross-gcc "avr" #:xgcc xgcc #:xbinutils (make-avr-binutils))))
+    (package
+      (inherit xgcc)
+      (name "avr-gcc")
+      (arguments
+       (substitute-keyword-arguments (package-arguments xgcc)
+         ((#:phases phases)
+          #~(modify-phases #$phases
+              (add-after 'set-paths 'augment-CPLUS_INCLUDE_PATH
+                (lambda* (#:key inputs #:allow-other-keys)
+                  (let ((gcc (assoc-ref inputs  "gcc")))
+                    ;; Remove the default compiler from CPLUS_INCLUDE_PATH
+                    ;; to prevent header conflict with the GCC from
+                    ;; native-inputs.
+                    (setenv "CPLUS_INCLUDE_PATH"
+                            (string-join
+                             (delete (string-append gcc "/include/c++")
+                                     (string-split (getenv "CPLUS_INCLUDE_PATH")
+                                                   #\:))
+                             ":"))
+                    (format #t
+                            "environment variable `CPLUS_INCLUDE_PATH' \
 changed to ~a~%"
-                              (getenv "CPLUS_INCLUDE_PATH")))))
-                ;; Without a working multilib build, the resulting GCC lacks
-                ;; support for nearly every AVR chip.
-                (add-after 'unpack 'fix-genmultilib
-                  (lambda _
-                    ;; patch-shebang doesn't work here because there are
-                    ;; actually several scripts inside this script, each with
-                    ;; a #!/bin/sh that needs patching.
-                    (substitute* "gcc/genmultilib"
-                      (("#!/bin/sh") (string-append "#!" (which "sh"))))))))
-           ((#:configure-flags flags)
-            #~(delete "--disable-multilib" #$flags))))
-        (native-search-paths
-         (list (search-path-specification
-                (variable "CROSS_C_INCLUDE_PATH")
-                (files '("avr/include")))
-               (search-path-specification
-                (variable "CROSS_CPLUS_INCLUDE_PATH")
-                (files '("avr/include")))
-               (search-path-specification
-                (variable "CROSS_OBJC_INCLUDE_PATH")
-                (files '("avr/include")))
-               (search-path-specification
-                (variable "CROSS_OBJCPLUS_INCLUDE_PATH")
-                (files '("avr/include")))
-               (search-path-specification
-                (variable "CROSS_LIBRARY_PATH")
-                (files '("avr/lib")))))
-        (native-inputs
-         `(("gcc" ,gcc)
-           ,@(package-native-inputs xgcc)))))))
+                            (getenv "CPLUS_INCLUDE_PATH")))))
+              ;; Without a working multilib build, the resulting GCC lacks
+              ;; support for nearly every AVR chip.
+              (add-after 'unpack 'fix-genmultilib
+                (lambda _
+                  ;; patch-shebang doesn't work here because there are
+                  ;; actually several scripts inside this script, each with
+                  ;; a #!/bin/sh that needs patching.
+                  (substitute* "gcc/genmultilib"
+                    (("#!/bin/sh") (string-append "#!" (which "sh"))))))))
+         ((#:configure-flags flags)
+          #~(delete "--disable-multilib" #$flags))))
+      (native-search-paths
+       (list (search-path-specification
+              (variable "CROSS_C_INCLUDE_PATH")
+              (files '("avr/include")))
+             (search-path-specification
+              (variable "CROSS_CPLUS_INCLUDE_PATH")
+              (files '("avr/include")))
+             (search-path-specification
+              (variable "CROSS_OBJC_INCLUDE_PATH")
+              (files '("avr/include")))
+             (search-path-specification
+              (variable "CROSS_OBJCPLUS_INCLUDE_PATH")
+              (files '("avr/include")))
+             (search-path-specification
+              (variable "CROSS_LIBRARY_PATH")
+              (files '("avr/lib")))))
+      (native-inputs
+       `(("gcc" ,gcc)
+         ,@(package-native-inputs xgcc))))))
+
+(define make-avr-gcc
+  (memoize make-avr-gcc/implementation))
+
+(define* (make-avr-libc/implementation #:key (xgcc gcc))
+  (package
+    (name "avr-libc")
+    (version "2.0.0")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "mirror://savannah//avr-libc/avr-libc-"
+                                  version ".tar.bz2"))
+              (sha256
+               (base32
+                "15svr2fx8j6prql2il2fc0ppwlv50rpmyckaxx38d3gxxv97zpdj"))))
+    (build-system gnu-build-system)
+    (arguments
+     '(#:out-of-source? #t
+       #:configure-flags '("--host=avr")))
+    (native-inputs `(("avr-binutils" ,(make-avr-binutils))
+                     ("avr-gcc" ,(make-avr-gcc #:xgcc xgcc))))
+    (home-page "https://www.nongnu.org/avr-libc/")
+    (synopsis "The AVR C Library")
+    (description
+     "AVR Libc is a project whose goal is to provide a high quality C library
+for use with GCC on Atmel AVR microcontrollers.")
+    (license
+     (license:non-copyleft "http://www.nongnu.org/avr-libc/LICENSE.txt"))))
 
 (define make-avr-libc
-  (mlambda ()
-    (package
-      (name "avr-libc")
-      (version "2.0.0")
-      (source (origin
-                (method url-fetch)
-                (uri (string-append "mirror://savannah//avr-libc/avr-libc-"
-                                    version ".tar.bz2"))
-                (sha256
-                 (base32
-                  "15svr2fx8j6prql2il2fc0ppwlv50rpmyckaxx38d3gxxv97zpdj"))))
-      (build-system gnu-build-system)
-      (arguments
-       '(#:out-of-source? #t
-         #:configure-flags '("--host=avr")))
-      (native-inputs `(("avr-binutils" ,(make-avr-binutils))
-                       ("avr-gcc" ,(make-avr-gcc))))
-      (home-page "https://www.nongnu.org/avr-libc/")
-      (synopsis "The AVR C Library")
-      (description
-       "AVR Libc is a project whose goal is to provide a high quality C
-library for use with GCC on Atmel AVR microcontrollers.")
-      (license
-       (license:non-copyleft "http://www.nongnu.org/avr-libc/LICENSE.txt")))))
+  (memoize make-avr-libc/implementation))
 
-(define make-avr-toolchain
-  (mlambda ()
-    (let ((avr-binutils (make-avr-binutils))
-          (avr-libc (make-avr-libc))
-          (avr-gcc (make-avr-gcc)))
-      ;; avr-libc checks the compiler version and passes "--enable-device-lib"
-      ;; for avr-gcc > 5.1.0.  It wouldn't install the library for atmega32u4
-      ;; etc if we didn't use the corret avr-gcc.
-      (package
-        (name "avr-toolchain")
-        (version (package-version avr-gcc))
-        (source #f)
-        (build-system trivial-build-system)
-        (arguments '(#:builder (begin (mkdir %output) #t)))
-        (propagated-inputs
-         `(("avrdude" ,avrdude)
-           ("binutils" ,avr-binutils)
-           ("gcc" ,avr-gcc)
-           ("libc" ,avr-libc)))
-        (synopsis "Complete GCC tool chain for AVR microcontroller development")
-        (description "This package provides a complete GCC tool chain for AVR
+(define* (make-avr-toolchain/implementation #:key (xgcc gcc))
+  (let ((avr-binutils (make-avr-binutils))
+        (avr-libc (make-avr-libc #:xgcc xgcc))
+        (avr-gcc (make-avr-gcc #:xgcc xgcc)))
+    ;; avr-libc checks the compiler version and passes "--enable-device-lib"
+    ;; for avr-gcc > 5.1.0.  It wouldn't install the library for atmega32u4
+    ;; etc if we didn't use the corret avr-gcc.
+    (package
+      (name "avr-toolchain")
+      (version (package-version avr-gcc))
+      (source #f)
+      (build-system trivial-build-system)
+      (arguments '(#:builder (begin (mkdir %output) #t)))
+      (propagated-inputs
+       `(("avrdude" ,avrdude)
+         ("binutils" ,avr-binutils)
+         ("gcc" ,avr-gcc)
+         ("libc" ,avr-libc)))
+      (synopsis "Complete GCC tool chain for AVR microcontroller development")
+      (description "This package provides a complete GCC tool chain for AVR
 microcontroller development.  This includes the GCC AVR cross compiler and
 avrdude for firmware flashing.  The supported programming languages are C and
 C++.")
-        (home-page (package-home-page avr-libc))
-        (license (package-license avr-gcc))))))
+      (home-page (package-home-page avr-libc))
+      (license (package-license avr-gcc)))))
+
+(define make-avr-toolchain
+  (memoize make-avr-toolchain/implementation))
 
 (define-public microscheme
   (package
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 02/22] gnu: qmk: Style.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 01/22] gnu: make-avr-toolchain: Add a #:xgcc argument Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 03/22] gnu: qmk: Avoid propagating inputs Maxim Cournoyer
                   ` (19 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer, Efraim Flashner, Vagrant Cascadian

* gnu/packages/firmware.scm (qmk): Apply 'guix style' changes.
---

 gnu/packages/firmware.scm | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/gnu/packages/firmware.scm b/gnu/packages/firmware.scm
index 08fe8311dce..dcae0d510b5 100644
--- a/gnu/packages/firmware.scm
+++ b/gnu/packages/firmware.scm
@@ -1223,10 +1223,17 @@ (define-public qmk
                (base32
                 "1619q9v90740dbg8xpzqlhwcasz42xj737803aiip8qc3a7zhwgq"))))
     (build-system pyproject-build-system)
-    (arguments (list #:tests? #f)) ;; No tests.
-    (propagated-inputs (list python-dotty-dict python-hid python-hjson
-                             python-jsonschema python-milc python-pillow
-                             python-pygments python-pyserial python-pyusb))
+    (arguments
+     (list #:tests? #f)) ;No tests.
+    (propagated-inputs (list python-dotty-dict
+                             python-hid
+                             python-hjson
+                             python-jsonschema
+                             python-milc
+                             python-pillow
+                             python-pygments
+                             python-pyserial
+                             python-pyusb))
     (home-page "https://qmk.fm")
     (synopsis "Command line utility to manage QMK keyboard firmwares")
     (description "This package provides a program to help users work with
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 03/22] gnu: qmk: Avoid propagating inputs.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 01/22] gnu: make-avr-toolchain: Add a #:xgcc argument Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 02/22] gnu: qmk: Style Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 04/22] gnu: qmk: Use GCC 8 for the AVR toolchain Maxim Cournoyer
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer, Efraim Flashner, Vagrant Cascadian

* gnu/packages/firmware.scm (qmk):
[arguments]: New modules and phases arguments.
[propagated-inputs]: Turn into...
[inputs]: ... this.  Add coreutils-minimal, sed and util-linux.
[description]: Expound.
---

 gnu/packages/firmware.scm | 71 ++++++++++++++++++++++++++++++++-------
 1 file changed, 59 insertions(+), 12 deletions(-)

diff --git a/gnu/packages/firmware.scm b/gnu/packages/firmware.scm
index dcae0d510b5..499920160a8 100644
--- a/gnu/packages/firmware.scm
+++ b/gnu/packages/firmware.scm
@@ -33,6 +33,7 @@ (define-module (gnu packages firmware)
   #:use-module (guix gexp)
   #:use-module (guix utils)
   #:use-module (guix git-download)
+  #:use-module (guix build-system copy)
   #:use-module (guix build-system gnu)
   #:use-module (guix build-system meson)
   #:use-module (guix build-system python)
@@ -40,6 +41,8 @@ (define-module (gnu packages firmware)
   #:use-module (guix build-system trivial)
   #:use-module (gnu packages)
   #:use-module (gnu packages admin)
+  #:use-module (gnu packages autotools)
+  #:use-module (gnu packages avr)
   #:use-module (gnu packages assembly)
   #:use-module (gnu packages backup)
   #:use-module (gnu packages base)
@@ -52,6 +55,7 @@ (define-module (gnu packages firmware)
   #:use-module (gnu packages curl)
   #:use-module (gnu packages efi)
   #:use-module (gnu packages elf)
+  #:use-module (gnu packages flashing-tools)
   #:use-module (gnu packages flex)
   #:use-module (gnu packages gcc)
   #:use-module (gnu packages gettext)
@@ -1212,6 +1216,11 @@ (define-public crust-pinebook
 (define-public crust-pine64-plus
   (make-crust-package "pine64_plus"))
 
+\f
+;;;
+;;; QMK Firmware.
+;;;
+
 (define-public qmk
   (package
     (name "qmk")
@@ -1224,18 +1233,56 @@ (define-public qmk
                 "1619q9v90740dbg8xpzqlhwcasz42xj737803aiip8qc3a7zhwgq"))))
     (build-system pyproject-build-system)
     (arguments
-     (list #:tests? #f)) ;No tests.
-    (propagated-inputs (list python-dotty-dict
-                             python-hid
-                             python-hjson
-                             python-jsonschema
-                             python-milc
-                             python-pillow
-                             python-pygments
-                             python-pyserial
-                             python-pyusb))
+     (list
+      #:tests? #f                       ;no tests
+      #:modules '((guix build pyproject-build-system)
+                  (guix build utils)
+                  (srfi srfi-26))
+      #:phases
+      #~(modify-phases %standard-phases
+          (add-after 'wrap 'wrap-path
+            (lambda* (#:key inputs outputs #:allow-other-keys)
+              (wrap-program (search-input-file outputs "bin/qmk")
+                `("PATH" prefix
+                  ,(map (compose dirname
+                                 (cut search-input-file inputs <>))
+                        '("bin/avr-gcc"
+                          "bin/avrdude"
+                          "bin/dfu-programmer"
+                          "bin/git"
+                          ;; TODO: Remove after git is wrapped with these.
+                          "bin/basename"
+                          "bin/sed"
+                          "bin/uname")))))))))
+    ;; The inputs are not propagated since qmk is to be used strictly as a
+    ;; command.
+    (inputs
+     (list (make-avr-toolchain)
+           avrdude
+           dfu-programmer
+           git-minimal                  ;for the clone action
+           python-dotty-dict
+           python-hid
+           python-hjson
+           python-jsonschema
+           python-milc
+           python-pillow
+           python-pygments
+           python-pyserial
+           python-pyusb
+           ;; These are added to workaround faults in our git package (see
+           ;; bug#65924).
+           coreutils-minimal
+           sed
+           util-linux))
     (home-page "https://qmk.fm")
     (synopsis "Command line utility to manage QMK keyboard firmwares")
-    (description "This package provides a program to help users work with
-@acronym{QMK, Quantum Mechanical Keyboard} firmwares.")
+    (description "The QMK CLI provides a @acronym{CLI, command line interface}
+based program to help users work with the QMK firmware, which can be used for
+multiple custom keyboards such as Planck, ErgoDox, Corne and others.
+
+This @acronym{CLI} program is mainly used for building the QMK firmware, but
+also has some other convenience utilities.  It is highly recommended to
+install the udev rules provided by the @code{qmk-udev-rules} package to avoid
+having to run @command{qmk} as root when flashing the firmware.")
     (license license:expat)))
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 04/22] gnu: qmk: Use GCC 8 for the AVR toolchain.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (2 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 03/22] gnu: qmk: Avoid propagating inputs Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 05/22] gnu: qmk: Add many missing inputs and add more commands to PATH Maxim Cournoyer
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer, Efraim Flashner, Vagrant Cascadian

* gnu/packages/firmware.scm (qmk) [inputs]: Specify 'gcc-8' as the #:xgcc
argument to the 'make-avr-toolchain' procedure.
---

 gnu/packages/firmware.scm | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/firmware.scm b/gnu/packages/firmware.scm
index 499920160a8..c1f6c8ea5e2 100644
--- a/gnu/packages/firmware.scm
+++ b/gnu/packages/firmware.scm
@@ -1257,7 +1257,9 @@ (define-public qmk
     ;; The inputs are not propagated since qmk is to be used strictly as a
     ;; command.
     (inputs
-     (list (make-avr-toolchain)
+     ;; The 'qmk setup' command advises to use GCC at version 8, and there are
+     ;; compilation errors in some firmware otherwise.
+     (list (make-avr-toolchain #:xgcc gcc-8)
            avrdude
            dfu-programmer
            git-minimal                  ;for the clone action
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 05/22] gnu: qmk: Add many missing inputs and add more commands to PATH.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (3 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 04/22] gnu: qmk: Use GCC 8 for the AVR toolchain Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 06/22] gnu: Add lufa Maxim Cournoyer
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer, Efraim Flashner, Vagrant Cascadian

* gnu/packages/firmware.scm (qmk) [inputs]: Add bash-minimal, dfu-util,
diffutils, gawk, gnu-make, grep and python.
[arguments]: Add them to PATH in the wrapper in the wrap-path phase.  Also
capture avr-ar in the PATH.  Add CROSS_C_INCLUDE_PATH and
CROSS_LIBRARY_PATH to the wrapper.
---

 gnu/packages/firmware.scm | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/gnu/packages/firmware.scm b/gnu/packages/firmware.scm
index c1f6c8ea5e2..1957fb8aac4 100644
--- a/gnu/packages/firmware.scm
+++ b/gnu/packages/firmware.scm
@@ -57,6 +57,7 @@ (define-module (gnu packages firmware)
   #:use-module (gnu packages elf)
   #:use-module (gnu packages flashing-tools)
   #:use-module (gnu packages flex)
+  #:use-module (gnu packages gawk)
   #:use-module (gnu packages gcc)
   #:use-module (gnu packages gettext)
   #:use-module (gnu packages glib)
@@ -1241,19 +1242,31 @@ (define-public qmk
       #:phases
       #~(modify-phases %standard-phases
           (add-after 'wrap 'wrap-path
+            ;; Wrap all the tools needed for the 'setup' and 'compile' actions
+            ;; (tested with the 'ergodox_ez' keyboard).
             (lambda* (#:key inputs outputs #:allow-other-keys)
               (wrap-program (search-input-file outputs "bin/qmk")
                 `("PATH" prefix
                   ,(map (compose dirname
                                  (cut search-input-file inputs <>))
-                        '("bin/avr-gcc"
+                        '("bin/avr-ar"
+                          "bin/avr-gcc"
                           "bin/avrdude"
+                          "bin/awk"
+                          "bin/cmp"
                           "bin/dfu-programmer"
+                          "bin/dfu-util"
                           "bin/git"
+                          "bin/grep"
+                          "bin/make"
+                          "bin/python3"
+                          "bin/sh"
                           ;; TODO: Remove after git is wrapped with these.
                           "bin/basename"
                           "bin/sed"
-                          "bin/uname")))))))))
+                          "bin/uname")))
+                `("CROSS_C_INCLUDE_PATH" = (,(getenv "CROSS_C_INCLUDE_PATH")))
+                `("CROSS_LIBRARY_PATH" = (,(getenv "CROSS_LIBRARY_PATH")))))))))
     ;; The inputs are not propagated since qmk is to be used strictly as a
     ;; command.
     (inputs
@@ -1261,8 +1274,15 @@ (define-public qmk
      ;; compilation errors in some firmware otherwise.
      (list (make-avr-toolchain #:xgcc gcc-8)
            avrdude
+           bash-minimal
            dfu-programmer
+           dfu-util
+           diffutils
            git-minimal                  ;for the clone action
+           gawk
+           gnu-make
+           grep
+           python
            python-dotty-dict
            python-hid
            python-hjson
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 06/22] gnu: Add lufa.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (4 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 05/22] gnu: qmk: Add many missing inputs and add more commands to PATH Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 07/22] gnu: embedded: Do not use a prefix on the (gnu packages base) module Maxim Cournoyer
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer

* gnu/packages/avr-xyz.scm (lufa): New variable.
---

 gnu/packages/avr-xyz.scm | 83 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/gnu/packages/avr-xyz.scm b/gnu/packages/avr-xyz.scm
index e8844b8d438..e0db2e3a0c7 100644
--- a/gnu/packages/avr-xyz.scm
+++ b/gnu/packages/avr-xyz.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2022 Artyom V. Poptsov <poptsov.artyom@gmail.com>
+;;; Copyright © 2023 Maxim Cournoyer <maxim.cournoyer@gmail.com>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -29,6 +30,7 @@ (define-module (gnu packages avr-xyz)
   #:use-module (gnu packages base)
   #:use-module (gnu packages bash)
   #:use-module (gnu packages avr)
+  #:use-module (gnu packages documentation)
   #:use-module (gnu packages elf)
   #:use-module (gnu packages gl)
   #:use-module (gnu packages pkg-config)
@@ -95,3 +97,84 @@ (define-public simavr
 in the emulated code using an @code{.elf} section.  You can also load
 multipart HEX files.")
     (license license:gpl3)))
+
+(define-public lufa
+  (package
+    (name "lufa")
+    (version "210130")
+    (source (origin
+              (method git-fetch)
+              (uri (git-reference
+                    (url "https://github.com/abcminiuser/lufa")
+                    (commit (string-append "LUFA-" version))))
+              (file-name (git-file-name name version))
+              (sha256
+               (base32
+                "0ylr7qsiikcy827k18zj1vdzf0kb8hb0gjmifd75y8krkhhar49g"))))
+    (outputs '("bootloaders" "demos" "projects" "doc"))
+    (build-system gnu-build-system)
+    (arguments
+     ;; There are tests, but even LUFA's own CI doesn't run them (they are
+     ;; only built).
+     (list
+      #:tests? #f
+      #:modules '((guix build gnu-build-system)
+                  (guix build utils)
+                  (ice-9 match)
+                  (srfi srfi-26))
+      #:make-flags
+      #~(list (string-append "SHELL="(search-input-file %build-inputs
+                                                        "bin/sh")))
+      #:phases #~(modify-phases %standard-phases
+                   (delete 'configure)
+                   (add-before 'build 'build-documentation
+                     (lambda* (#:key make-flags #:allow-other-keys)
+                       (apply invoke "make" "-j" (number->string
+                                                  (or (parallel-job-count)
+                                                      1))
+                              "doxygen"
+                              ;; Ignore errors (see:
+                              ;; https://github.com/abcminiuser/lufa/issues/90).
+                              "-i"
+                              make-flags)))
+                   (replace 'install
+                     ;; There is no default install target as the library is
+                     ;; intended to be integrated in source form in a
+                     ;; project.  Install the example projects and demos
+                     ;; binaries as well as the documentation.
+                     (lambda _
+                       (let ((doc (string-append #$output:doc
+                                                 "/share/doc/lufa/"))
+                             (html-dirs (find-files "."  "^html$"
+                                                    #:directories? #t)))
+                         (for-each (cut install-file <> #$output:bootloaders)
+                                   (find-files "Bootloaders" "\\.hex$"))
+                         (for-each (cut install-file <> #$output:demos)
+                                   (find-files "Demos" "\\.hex$"))
+                         (for-each (cut install-file <> #$output:projects)
+                                   (find-files "Projects" "\\.hex$"))
+                         ;; Install Doxygen generated HTML documentation.
+                         (for-each
+                          (lambda (html)
+                            (let* ((suffix "Documentation/html")
+                                   (l (string-length suffix))
+                                   (dest (string-append
+                                          doc
+                                          (string-drop
+                                           (if (string-suffix? suffix html)
+                                               (string-drop-right html l)
+                                               (error "unexpected path" html))
+                                           1)))) ;drop leading "."
+                              (mkdir-p dest)
+                              (copy-recursively html dest)))
+                          html-dirs)))))))
+    (native-inputs (list doxygen (make-avr-toolchain)))
+    (home-page "https://www.lufa-lib.org/")
+    (synopsis "Lightweight USB Framework for AVRs")
+    (description "UFA is a simple to use, lightweight framework which sits
+atop the hardware USB controller in specific AVR microcontroller models, and
+allows for the quick and easy creation of complex USB devices and hosts.  This
+package contains the user-submitted projects and bootloaders for use with
+compatible microcontroller models, as well as the demos and the
+documentation.")
+    (license license:expat)))           ;see LUFA/License.txt
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 07/22] gnu: embedded: Do not use a prefix on the (gnu packages base) module.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (5 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 06/22] gnu: Add lufa Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 08/22] gnu: Add qmk-firmware-ergodox-ez-default Maxim Cournoyer
                   ` (14 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer

This can in some cases hide the real error with errors such as:

  error: base:which: unbound variable

* gnu/packages/embedded.scm (openocd) [native-inputs]: Replace base:which with
which.
(binutils-vc4): Likewise.
(python-libmpsse): Likewise.
---

 gnu/packages/embedded.scm | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/gnu/packages/embedded.scm b/gnu/packages/embedded.scm
index 46a9a3a70a8..aca3cbade87 100644
--- a/gnu/packages/embedded.scm
+++ b/gnu/packages/embedded.scm
@@ -46,7 +46,7 @@ (define-module (gnu packages embedded)
   #:use-module (gnu packages)
   #:use-module (gnu packages admin)
   #:use-module (gnu packages autotools)
-  #:use-module ((gnu packages base) #:prefix base:)
+  #:use-module (gnu packages base)
   #:use-module (gnu packages bison)
   #:use-module (gnu packages boost)
   #:use-module (gnu packages check)
@@ -672,7 +672,7 @@ (define-public openocd
      (list autoconf
            automake
            libtool
-           base:which
+           which
            pkg-config
            texinfo))
     (inputs
@@ -1152,7 +1152,7 @@ (define-public binutils-vc4
          ("flex" ,flex)
          ("bison" ,bison)
          ("guile-1.8" ,guile-1.8)
-         ("which" ,base:which)))
+         ("which" ,which)))
       (synopsis "Binutils for VC4")
       (description "This package provides @code{binutils} for VideoCore IV,
 the Raspberry Pi chip.")
@@ -1241,7 +1241,7 @@ (define-public python-libmpsse
     (inputs
      (list libftdi python))
     (native-inputs
-     (list pkg-config swig base:which))
+     (list pkg-config swig which))
     (arguments
      `(#:tests? #f ; No tests exist.
        #:parallel-build? #f  ; Would be buggy.
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 08/22] gnu: Add qmk-firmware-ergodox-ez-default.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (6 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 07/22] gnu: embedded: Do not use a prefix on the (gnu packages base) module Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 09/22] gnu: Add qmk-firmware-ergodox-ez-dvorak-42-key Maxim Cournoyer
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer, Efraim Flashner, Vagrant Cascadian

* gnu/packages/firmware.scm (make-qmk-firmware/implementation)
(make-qmk-firmware): New procedures.
(qmk-firmware-ergodox-ez-default): New variable.
---

 gnu/packages/firmware.scm | 126 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 125 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/firmware.scm b/gnu/packages/firmware.scm
index 1957fb8aac4..7220177eadb 100644
--- a/gnu/packages/firmware.scm
+++ b/gnu/packages/firmware.scm
@@ -28,6 +28,7 @@
 
 (define-module (gnu packages firmware)
   #:use-module ((guix licenses) #:prefix license:)
+  #:use-module (guix memoization)
   #:use-module (guix packages)
   #:use-module (guix download)
   #:use-module (guix gexp)
@@ -43,6 +44,7 @@ (define-module (gnu packages firmware)
   #:use-module (gnu packages admin)
   #:use-module (gnu packages autotools)
   #:use-module (gnu packages avr)
+  #:use-module (gnu packages avr-xyz)
   #:use-module (gnu packages assembly)
   #:use-module (gnu packages backup)
   #:use-module (gnu packages base)
@@ -80,7 +82,10 @@ (define-module (gnu packages firmware)
   #:use-module (gnu packages tls)
   #:use-module (gnu packages version-control)
   #:use-module (gnu packages xml)
-  #:use-module (ice-9 match))
+  #:use-module (ice-9 format)
+  #:use-module (ice-9 match)
+
+  #:export (make-qmk-firmware))
 
 (define-public ath9k-htc-firmware
   (package
@@ -1308,3 +1313,122 @@ (define-public qmk
 install the udev rules provided by the @code{qmk-udev-rules} package to avoid
 having to run @command{qmk} as root when flashing the firmware.")
     (license license:expat)))
+
+(define* (make-qmk-firmware/implementation keyboard keymap
+                                           #:key (description "")
+                                           keymap-json
+                                           keymap-source-directory)
+  "Return a package to build the QMK firmware for KEYBOARD with KEYMAP.
+Keyboard should be the name of a sub-directory under the @file{keyboards}
+directory.  For custom keymaps, KEYMAP-JSON, a file-like object of a JSON
+representation of KEYMAP as generated by the @url{https://config.qmk.fm/, QMK
+Configurator} tool or KEYMAP-SOURCE-DIRECTORY, a file-like object directory
+containing the keymap source files files such as @file{keymap.c}, can be
+provided."
+  (package
+    (name (string-append "qmk-firmware-"
+                         (string-replace-substring keyboard "_" "-") "-"
+                         (string-replace-substring keymap "_" "-")))
+    ;; Note: When updating this package, make sure to also update the commit
+    ;; used for the LUFA submodule in the 'copy-lufa-source' phase below.
+    (version "0.22.3")
+    (source (origin
+              (method git-fetch)
+              (uri (git-reference
+                    (url "https://github.com/qmk/qmk_firmware")
+                    (commit version)))
+              (file-name (git-file-name "qmk-firmware" version))
+              (sha256
+               (base32
+                "0s1lcnv7cddpn768p7mrc5bkxhx0ba5p77ya007dnkbk36c33d0w"))))
+    (build-system gnu-build-system)
+    (arguments
+     (list
+      #:modules '((guix build gnu-build-system)
+                  (guix build utils)
+                  (ice-9 match)
+                  (srfi srfi-26))
+      ;; XXX: Running a test target like "test:$keyboard" doesn't seem to run
+      ;; anything and causes the .hex file to be regenerated; leave the tests
+      ;; out for now.
+      #:tests? #f
+      #:make-flags
+      #~(list #$(format #f "~a:~a" keyboard keymap)
+              (string-append "SHELL=" (search-input-file
+                                       %build-inputs "bin/sh")))
+      #:phases
+      #~(modify-phases %standard-phases
+          (replace 'configure
+            (lambda _
+              ;; Do not attempt to retrieve information from git during the
+              ;; build.
+              (setenv "SKIP_GIT" "1")))
+          (add-after 'unpack 'copy-lufa-source
+            ;; QMK carries a custom fork of LUFA as a git submodule; make sure
+            ;; the same commit is used (see:
+            ;; https://github.com/qmk/qmk_firmware/tree/master/lib).
+            (lambda _
+              (copy-recursively
+               #$(let ((commit "549b97320d515bfca2f95c145a67bd13be968faa"))
+                   (origin
+                     (inherit (package-source lufa))
+                     (uri (git-reference
+                           (url "https://github.com/qmk/lufa")
+                           (commit commit)))
+                     (file-name (git-file-name "lufa" commit))
+                     (sha256
+                      (base32
+                       "1rmhm4rxvq8skxqn6vc4n4ly1ak6whj7c386zbsci4pxx548n9h4"))))
+               "lib/lufa")))
+          #$@(if keymap-source-directory
+                 #~((add-after 'unpack 'copy-keymap-source-directory
+                      (lambda _
+                        (let ((keymap-dir #$(string-append "keyboards/" keyboard
+                                                           "/keymaps/" keymap)))
+                          (false-if-exception (delete-file-recursively
+                                               keymap-dir))
+                          (copy-recursively #$keymap-source-directory
+                                            keymap-dir)))))
+                 #~())
+          #$@(if keymap-json
+                 #~((replace 'build
+                      (lambda _
+                        (invoke "qmk" "compile" #$keymap-json))))
+                 #~())
+          (replace 'install
+            (lambda _
+              (match (find-files ".build" "\\.hex$")
+                (()
+                 (error "no built binary file found"))
+                ((hex ..1)
+                 (for-each (cut install-file <> #$output) hex))))))))
+    ;; Some of the build tools are required to be on the PATH, as the make
+    ;; files do not always operate through 'qmk'; all of qmk's inputs must
+    ;; thus be made available.
+    (native-inputs (modify-inputs (package-inputs qmk)
+                     (append qmk)))
+    (home-page "https://qmk.fm/")
+    (synopsis "Keyboard firmware for Atmel AVR and Arm USB families")
+    (description
+     (format #f "QMK (Quantum Mechanical Keyboard Firmware) is a keyboard
+firmware based on the @url{https://github.com/tmk/tmk_keyboard, tmk_keyboard
+firmware} with some useful features for Atmel AVR and ARM controllers, and
+more specifically, the @url{https://olkb.com/, OLKB product line}, the
+@url{https://ergodox-ez.com/, ErgoDox EZ keyboard}, and the
+@url{https://clueboard.co/, Clueboard product line}.~@[~%~%~a~]" description))
+    (license license:gpl2+)))
+
+(define make-qmk-firmware (memoize make-qmk-firmware/implementation))
+
+(define-public qmk-firmware-ergodox-ez-default
+  (make-qmk-firmware
+   "ergodox_ez" "default" #:description
+   "This is the default keymap used on the ErgoDox EZ keyboard.  It includes
+the novel MEH and Hyper keys pioneered by the ErgoDox EZ, easy to reach
+Control/Shift modifiers keys, and two-functions hold keys to access layer 1.
+Layer 1 contains function keys, symbols, a numpad as well as brightness keys.
+Layer 2 contains multimedia and mouse keys.  See the
+@file{keyboards/ergodox_ez/keymaps/default/keymap.c} source file for the
+keymap definition, or the
+@url{https://configure.ergodox-ez.com/ergodox-ez/layouts/JwwW/latest/0,
+ErgoDox EZ Configurator} page."))
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 09/22] gnu: Add qmk-firmware-ergodox-ez-dvorak-42-key.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (7 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 08/22] gnu: Add qmk-firmware-ergodox-ez-default Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 10/22] gnu: Add qmk-udev-rules Maxim Cournoyer
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer, Efraim Flashner, Vagrant Cascadian

* gnu/packages/firmware.scm (qmk-firmware-ergodox-ez-dvorak-42-key): New variable.
---

 gnu/packages/firmware.scm | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/gnu/packages/firmware.scm b/gnu/packages/firmware.scm
index 7220177eadb..79ef0416b3d 100644
--- a/gnu/packages/firmware.scm
+++ b/gnu/packages/firmware.scm
@@ -1432,3 +1432,14 @@ (define-public qmk-firmware-ergodox-ez-default
 keymap definition, or the
 @url{https://configure.ergodox-ez.com/ergodox-ez/layouts/JwwW/latest/0,
 ErgoDox EZ Configurator} page."))
+
+(define-public qmk-firmware-ergodox-ez-dvorak-42-key
+  (make-qmk-firmware "ergodox_ez" "dvorak_42_key" #:description "\
+This is a Dvorak-based layout for the ErgoDox EZ.  Its basic key layout is
+similar to the Atreus @samp{dvorak_42_key} layout; in fact this layout was
+created for seamless switching between the ErgoDox EZ and Atreus keyboards.
+On the base layer, the keys that don't exist on the Atreus are mapped to MEH
+shortcuts and can be interpreted by your window managher.  This layout only
+makes use of the 42 keys that the Atreus also has for the main functionality.
+See the @file{keyboards/atreus/keymaps/dvorak_42_key/keymap.c} source file for
+the keymap definition."))
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 10/22] gnu: Add qmk-udev-rules.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (8 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 09/22] gnu: Add qmk-firmware-ergodox-ez-dvorak-42-key Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 11/22] gnu: Add qmk-firmware-ergodox-ez-hacker-dvorak Maxim Cournoyer
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer, Efraim Flashner, Vagrant Cascadian

* gnu/packages/firmware.scm (qmk-udev-rules): New variable.
---

 gnu/packages/firmware.scm | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/gnu/packages/firmware.scm b/gnu/packages/firmware.scm
index 79ef0416b3d..22be7ee62dd 100644
--- a/gnu/packages/firmware.scm
+++ b/gnu/packages/firmware.scm
@@ -1443,3 +1443,21 @@ (define-public qmk-firmware-ergodox-ez-dvorak-42-key
 makes use of the 42 keys that the Atreus also has for the main functionality.
 See the @file{keyboards/atreus/keymaps/dvorak_42_key/keymap.c} source file for
 the keymap definition."))
+
+(define-public qmk-udev-rules
+  (package
+    (inherit qmk-firmware-ergodox-ez-default)
+    (name "qmk-udev-rules")
+    (build-system copy-build-system)
+    (arguments
+     '(#:install-plan '(("./util/udev" "lib/udev/rules.d"
+                         #:include-regexp ("rules$")))))
+    (native-inputs '())
+    (inputs '())
+    (propagated-inputs '())
+    (synopsis "Udev rules for QMK Firmware")
+    (description
+     "This package provides a set of udev rules to specify the proper
+privileges for flashing QMK compatible devices without needing root.  The
+rules require the group @code{plugdev} to be added to each user that needs
+this.")))
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 11/22] gnu: Add qmk-firmware-ergodox-ez-hacker-dvorak.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (9 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 10/22] gnu: Add qmk-udev-rules Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 12/22] gnu: Add qmk-firmware-ergodox-ez-dvorak Maxim Cournoyer
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer, Efraim Flashner, Vagrant Cascadian

* gnu/packages/firmware.scm (qmk-firmware-ergodox-ez-hacker-dvorak): New
variable.
* gnu/packages/patches/qmk-firmware-fix-hacker-dvorak.patch: New file.
* gnu/local.mk (dist_patch_DATA): Register it.
---

 gnu/local.mk                                  |  1 +
 gnu/packages/firmware.scm                     | 25 ++++++++++++++++++-
 .../qmk-firmware-fix-hacker-dvorak.patch      | 15 +++++++++++
 3 files changed, 40 insertions(+), 1 deletion(-)
 create mode 100644 gnu/packages/patches/qmk-firmware-fix-hacker-dvorak.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index bfa816d717c..c04c4196cdf 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1893,6 +1893,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/quagga-reproducible-build.patch          \
   %D%/packages/patches/quickswitch-fix-dmenu-check.patch	\
   %D%/packages/patches/quilt-grep-compat.patch 			\
+  %D%/packages/patches/qmk-firmware-fix-hacker-dvorak.patch 	\
   %D%/packages/patches/qtwayland-dont-recreate-callbacks.patch	\
   %D%/packages/patches/qtwayland-cleanup-callbacks.patch	\
   %D%/packages/patches/ragel-char-signedness.patch		\
diff --git a/gnu/packages/firmware.scm b/gnu/packages/firmware.scm
index 22be7ee62dd..6a488d672ff 100644
--- a/gnu/packages/firmware.scm
+++ b/gnu/packages/firmware.scm
@@ -1340,7 +1340,9 @@ (define* (make-qmk-firmware/implementation keyboard keymap
               (file-name (git-file-name "qmk-firmware" version))
               (sha256
                (base32
-                "0s1lcnv7cddpn768p7mrc5bkxhx0ba5p77ya007dnkbk36c33d0w"))))
+                "0s1lcnv7cddpn768p7mrc5bkxhx0ba5p77ya007dnkbk36c33d0w"))
+              (patches
+               (search-patches "qmk-firmware-fix-hacker-dvorak.patch"))))
     (build-system gnu-build-system)
     (arguments
      (list
@@ -1444,6 +1446,27 @@ (define-public qmk-firmware-ergodox-ez-dvorak-42-key
 See the @file{keyboards/atreus/keymaps/dvorak_42_key/keymap.c} source file for
 the keymap definition."))
 
+(define-public qmk-firmware-ergodox-ez-hacker-dvorak
+  (make-qmk-firmware "ergodox_ez" "hacker_dvorak" #:description "\
+This is a Dvorak layout for the ErgoDox EZ.  It is inspired by the
+@url{https://www.kaufmann.no/roland/dvorak, Programmer Dvorak}.  The operating
+system keyboard layout should be set to US for this keymap to function
+normally.  It defines 10 layers:
+@enumerate
+@item Dvorak
+@item Querty
+@item Gaming
+@item Arrows
+@item Mouse
+@item Numpad
+@item Hyper Fn
+@item Media Fn
+@item Meh Fn
+@item Meh Fn +
+@end enumerate
+The complete keymap can be inspected at the ErgoDox EZ Configurator web site:
+@url{https://configure.ergodox-ez.com/ergodox-ez/layouts/Wadz/latest/0}."))
+
 (define-public qmk-udev-rules
   (package
     (inherit qmk-firmware-ergodox-ez-default)
diff --git a/gnu/packages/patches/qmk-firmware-fix-hacker-dvorak.patch b/gnu/packages/patches/qmk-firmware-fix-hacker-dvorak.patch
new file mode 100644
index 00000000000..69e68cc8e12
--- /dev/null
+++ b/gnu/packages/patches/qmk-firmware-fix-hacker-dvorak.patch
@@ -0,0 +1,15 @@
+Submitted upstream: https://github.com/qmk/qmk_firmware/pull/22102
+
+diff --git a/keyboards/ergodox_ez/keymaps/hacker_dvorak/user/layer_set_state_user.c b/keyboards/ergodox_ez/keymaps/hacker_dvorak/user/layer_set_state_user.c
+index bd4fd10ad1..5ce5f5298f 100644
+--- a/keyboards/ergodox_ez/keymaps/hacker_dvorak/user/layer_set_state_user.c
++++ b/keyboards/ergodox_ez/keymaps/hacker_dvorak/user/layer_set_state_user.c
+@@ -4,7 +4,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
+ 
+     switch (layer) {
+         case DVORAK:
+-            rgblight_sethsv_noeeprom(GREEN);
++            rgblight_sethsv_noeeprom(HSV_GREEN);
+             rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
+ 
+             if (PLOVER_MODE) {
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 12/22] gnu: Add qmk-firmware-ergodox-ez-dvorak.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (10 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 11/22] gnu: Add qmk-firmware-ergodox-ez-hacker-dvorak Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 13/22] gnu: Add qmk-firmware-ergodox-ez-dvorak-emacs Maxim Cournoyer
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer, Efraim Flashner, Vagrant Cascadian

* gnu/packages/firmware.scm (qmk-firmware-ergodox-ez-dvorak): New variable.
---

 gnu/packages/firmware.scm | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/gnu/packages/firmware.scm b/gnu/packages/firmware.scm
index 6a488d672ff..ecbab94eda5 100644
--- a/gnu/packages/firmware.scm
+++ b/gnu/packages/firmware.scm
@@ -1467,6 +1467,14 @@ (define-public qmk-firmware-ergodox-ez-hacker-dvorak
 The complete keymap can be inspected at the ErgoDox EZ Configurator web site:
 @url{https://configure.ergodox-ez.com/ergodox-ez/layouts/Wadz/latest/0}."))
 
+(define-public qmk-firmware-ergodox-ez-dvorak
+  (make-qmk-firmware
+   "ergodox_ez" "dvorak" #:description
+   "This is a rather plain Dvorak layout for the ErgoDox EZ, containing
+function and symbols on layer 1 and media and and mouse keys on layer 2.  See
+the @file{layouts/community/ergodox/dvorak/keymap.c} source file for the
+keymap definition."))
+
 (define-public qmk-udev-rules
   (package
     (inherit qmk-firmware-ergodox-ez-default)
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 13/22] gnu: Add qmk-firmware-ergodox-ez-dvorak-emacs.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (11 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 12/22] gnu: Add qmk-firmware-ergodox-ez-dvorak Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 14/22] gnu: Add qmk-firmware-ergodox-ez-dvorak-emacs-software Maxim Cournoyer
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer, Efraim Flashner, Vagrant Cascadian

* gnu/packages/firmware.scm (qmk-firmware-ergodox-ez-dvorak-emacs): New variable.
---

 gnu/packages/firmware.scm | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/gnu/packages/firmware.scm b/gnu/packages/firmware.scm
index ecbab94eda5..19dc12a8fce 100644
--- a/gnu/packages/firmware.scm
+++ b/gnu/packages/firmware.scm
@@ -1475,6 +1475,15 @@ (define-public qmk-firmware-ergodox-ez-dvorak
 the @file{layouts/community/ergodox/dvorak/keymap.c} source file for the
 keymap definition."))
 
+(define-public qmk-firmware-ergodox-ez-dvorak-emacs
+  (make-qmk-firmware
+   "ergodox_ez" "dvorak_emacs" #:description
+   "This is a Dvorak-based keymap optimized for Emacs usage, with the
+frequently used Control and Meta (Alt) keys mapped to the thumb buttons.  It
+contains a single extra layer that includes function and multimedia keys.  A
+graphical representation of the keymap is available in the
+@file{layouts/community/ergodox/dvorak_emacs/readme.md} source file."))
+
 (define-public qmk-udev-rules
   (package
     (inherit qmk-firmware-ergodox-ez-default)
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 14/22] gnu: Add qmk-firmware-ergodox-ez-dvorak-emacs-software.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (12 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 13/22] gnu: Add qmk-firmware-ergodox-ez-dvorak-emacs Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 15/22] gnu: Add ergodox-firmware-colemak-jc-mod Maxim Cournoyer
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer, Efraim Flashner, Vagrant Cascadian

* gnu/packages/firmware.scm
(qmk-firmware-ergodox-ez-dvorak-emacs-software): New variable.
---

 gnu/packages/firmware.scm | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/gnu/packages/firmware.scm b/gnu/packages/firmware.scm
index 19dc12a8fce..a7428df8129 100644
--- a/gnu/packages/firmware.scm
+++ b/gnu/packages/firmware.scm
@@ -1484,6 +1484,14 @@ (define-public qmk-firmware-ergodox-ez-dvorak-emacs
 graphical representation of the keymap is available in the
 @file{layouts/community/ergodox/dvorak_emacs/readme.md} source file."))
 
+(define-public qmk-firmware-ergodox-ez-dvorak-emacs-software
+  (make-qmk-firmware
+   "ergodox_ez" "dvorak_emacs_software" #:description
+   "This is the same layout as that of the
+@code{qmk-firmware-ergodox-ez-dvorak-emacs}, but designed to be used with a
+Dvorak-configured operating system (instead of a US QWERTY one, which is the
+default assumption for QMK firmware keymaps)."))
+
 (define-public qmk-udev-rules
   (package
     (inherit qmk-firmware-ergodox-ez-default)
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 15/22] gnu: Add ergodox-firmware-colemak-jc-mod.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (13 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 14/22] gnu: Add qmk-firmware-ergodox-ez-dvorak-emacs-software Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 16/22] gnu: Add ergodox-firmware-colemak-symbol-mod Maxim Cournoyer
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer, Efraim Flashner, Vagrant Cascadian

* gnu/packages/firmware.scm (make-ergodox-firmware): New procedure
(ergodox-firmware-colemak-jc-mod): New variable.
* gnu/packages/patches/ergodox-firmware-fix-json-target.patch: New file.
* gnu/packages/patches/ergodox-firmware-fix-numpad.patch: Likewise.
* gnu/local.mk (dist_patch_DATA): Register them.
---

 gnu/local.mk                                  |    2 +
 gnu/packages/firmware.scm                     |   77 +-
 .../ergodox-firmware-fix-json-target.patch    | 1405 +++++++++++++++++
 .../patches/ergodox-firmware-fix-numpad.patch |   18 +
 4 files changed, 1501 insertions(+), 1 deletion(-)
 create mode 100644 gnu/packages/patches/ergodox-firmware-fix-json-target.patch
 create mode 100644 gnu/packages/patches/ergodox-firmware-fix-numpad.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index c04c4196cdf..052e6f2013c 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1120,6 +1120,8 @@ dist_patch_DATA =						\
   %D%/packages/patches/enblend-enfuse-reproducible.patch	\
   %D%/packages/patches/enjarify-setup-py.patch			\
   %D%/packages/patches/enlightenment-fix-setuid-path.patch	\
+  %D%/packages/patches/ergodox-firmware-fix-json-target.patch	\
+  %D%/packages/patches/ergodox-firmware-fix-numpad.patch	\
   %D%/packages/patches/erlang-man-path.patch			\
   %D%/packages/patches/esmini-no-clutter-log.patch		\
   %D%/packages/patches/esmini-use-pkgconfig.patch		\
diff --git a/gnu/packages/firmware.scm b/gnu/packages/firmware.scm
index a7428df8129..a901ae46944 100644
--- a/gnu/packages/firmware.scm
+++ b/gnu/packages/firmware.scm
@@ -85,7 +85,8 @@ (define-module (gnu packages firmware)
   #:use-module (ice-9 format)
   #:use-module (ice-9 match)
 
-  #:export (make-qmk-firmware))
+  #:export (make-ergodox-firmware
+            make-qmk-firmware))
 
 (define-public ath9k-htc-firmware
   (package
@@ -1222,6 +1223,80 @@ (define-public crust-pinebook
 (define-public crust-pine64-plus
   (make-crust-package "pine64_plus"))
 
+\f
+;;;
+;;; ErgoDox firmware.
+;;;
+
+(define* (make-ergodox-firmware/implementation layout #:key override.c
+                                               override.h)
+  "Return an ergodox-firmware package for LAYOUT, optionally using OVERRIDE.C,
+a C source file-like object to override LAYOUT which may be accompanied by
+OVERRIDE.H, to also override the corresponding layout include file."
+  (let ((revision "0")
+        (commit "89b7e2bfdafb2a87e0248846d5c95cc5e9a27858"))
+    (package
+      (name (string-append "ergodox-firmware-" layout))
+      (version (git-version "1" revision commit))
+      (source (origin
+                (method git-fetch)
+                (uri (git-reference
+                      (url "https://github.com/benblazak/ergodox-firmware")
+                      (commit commit)))
+                (file-name (git-file-name name version))
+                (sha256
+                 (base32
+                  "1z28frxyb21nz90frycrpsbxjp09374wawayvjphnwc8njlvkkpy"))
+                (patches
+                 (search-patches "ergodox-firmware-fix-json-target.patch"
+                                 "ergodox-firmware-fix-numpad.patch"))))
+      (build-system gnu-build-system)
+      (arguments
+       (list
+        #:tests? #f                   ;no test suite
+        #:make-flags
+        #~(list (string-append "LAYOUT=" #$layout)
+                ;; Simplify the output directory name.
+                "ROOT=output")
+        #:phases
+        #~(modify-phases %standard-phases
+            (add-after 'unpack 'copy-override-files
+              (lambda _
+                (when #$override.c
+                  (copy-file #$override.c
+                             (format #f "src/keyboard/ergodox/layout/~a.c"
+                                     #$layout)))
+                (when #$override.h
+                  (copy-file #$override.h
+                             (format #f "src/keyboard/ergodox/layout/~a.h"
+                                     #$layout)))))
+            ;; The Makefile-based build system lacks configure
+            ;; and install targets.
+            (delete 'configure)
+            (replace 'install
+              (lambda _
+                (with-directory-excursion "output"
+                  (install-file "firmware.hex" #$output)
+                  (install-file "firmware.eep" #$output)
+                  (install-file "firmware--layout.html" #$output)))))))
+      (native-inputs (list (make-avr-toolchain) python))
+      (home-page "https://www.ergodox.io")
+      (synopsis "Firmware for the ErgoDox keyboard")
+      (description (format #f "This package contains the original firmware for
+the ErgoDox keyboard, built using the ~a layout (as defined in the
+@file{src/keyboard/ergodox/layout/~@*~a.c} source file).  It contains the
+@file{firmware.hex} and the @file{firmware.eep} files, which can be loaded to
+a target using the @code{teensy-loader-cli} package as well as a
+@file{firmware--layout.html} file, useful to easily visualize the
+corresponding layout." layout))
+      (license license:expat))))
+
+(define make-ergodox-firmware
+  (memoize make-ergodox-firmware/implementation))
+
+(define-public ergodox-firmware-colemak-jc-mod
+  (make-ergodox-firmware "colemak-jc-mod"))
+
 \f
 ;;;
 ;;; QMK Firmware.
diff --git a/gnu/packages/patches/ergodox-firmware-fix-json-target.patch b/gnu/packages/patches/ergodox-firmware-fix-json-target.patch
new file mode 100644
index 00000000000..52da4e2497d
--- /dev/null
+++ b/gnu/packages/patches/ergodox-firmware-fix-json-target.patch
@@ -0,0 +1,1405 @@
+Submitted upstream:
+<https://github.com/benblazak/ergodox-firmware/pull/99>
+<https://github.com/benblazak/ergodox-firmware/pull/98>
+
+diff --git a/build-scripts/gen-layout.py b/build-scripts/gen-layout.py
+index fd5e54c..251a463 100755
+--- a/build-scripts/gen-layout.py
++++ b/build-scripts/gen-layout.py
+@@ -22,8 +22,10 @@ import sys
+ 
+ # -----------------------------------------------------------------------------
+ 
+-class Namespace():
+-	pass
++
++class Namespace:
++    pass
++
+ 
+ template = Namespace()
+ doc = Namespace()
+@@ -31,45 +33,45 @@ info = Namespace()
+ 
+ # -----------------------------------------------------------------------------
+ 
++
+ def main():
+-	arg_parser = argparse.ArgumentParser(
+-			description = "Generate a picture of the firmware's "
+-			            + "keyboard layout" )
++    arg_parser = argparse.ArgumentParser(
++        description="Generate a picture of the firmware's " + "keyboard layout"
++    )
+ 
+-	arg_parser.add_argument(
+-			'--ui-info-file',
+-			required = True )
++    arg_parser.add_argument("--ui-info-file", required=True)
+ 
+-	args = arg_parser.parse_args(sys.argv[1:])
++    args = arg_parser.parse_args(sys.argv[1:])
+ 
+-	# constant file paths
+-	args.template_svg_file = './build-scripts/gen_layout/template.svg'
+-	args.template_js_file = './build-scripts/gen_layout/template.js'
++    # constant file paths
++    args.template_svg_file = "./build-scripts/gen_layout/template.svg"
++    args.template_js_file = "./build-scripts/gen_layout/template.js"
+ 
+-	# normalize paths
+-	args.ui_info_file = os.path.abspath(args.ui_info_file)
+-	args.template_svg_file = os.path.abspath(args.template_svg_file)
+-	args.template_js_file = os.path.abspath(args.template_js_file)
++    # normalize paths
++    args.ui_info_file = os.path.abspath(args.ui_info_file)
++    args.template_svg_file = os.path.abspath(args.template_svg_file)
++    args.template_js_file = os.path.abspath(args.template_js_file)
+ 
+-	# set vars
+-	doc.main = ''  # to store the html document we're generating
+-	template.svg = open(args.template_svg_file).read()
+-	template.js = open(args.template_js_file).read()
+-	info.all = json.loads(open(args.ui_info_file).read())
++    # set vars
++    doc.main = ""  # to store the html document we're generating
++    template.svg = open(args.template_svg_file).read()
++    template.js = open(args.template_js_file).read()
++    info.all = json.loads(open(args.ui_info_file).read())
+ 
+-	info.matrix_positions = info.all['mappings']['matrix-positions']
+-	info.matrix_layout = info.all['mappings']['matrix-layout']
++    info.matrix_positions = info.all["mappings"]["matrix-positions"]
++    info.matrix_layout = info.all["mappings"]["matrix-layout"]
+ 
+-	# prefix
+-	doc.prefix = ("""
++    # prefix
++    doc.prefix = (
++        """
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
+ <html>
+ 
+ <head>
+   <script>
+ """
+-+ template.js +
+-""" </script>
++        + template.js
++        + """ </script>
+ </head>
+ 
+ <body>
+@@ -78,9 +80,13 @@ def main():
+ 
+ <ul>
+   <li>git commit date:
+-  <code>""" + info.all['miscellaneous']['git-commit-date'] + """</code></li>
++  <code>"""
++        + info.all["miscellaneous"]["git-commit-date"]
++        + """</code></li>
+   <li>git commit id:
+-  <code>""" + info.all['miscellaneous']['git-commit-id'] + """</code></li>
++  <code>"""
++        + info.all["miscellaneous"]["git-commit-id"]
++        + """</code></li>
+ </ul>
+ 
+ <h2>Notes</h2>
+@@ -123,301 +129,293 @@ def main():
+ 
+ <br>
+ 
+-""")[1:-1]
++"""
++    )[1:-1]
+ 
+-	# suffix
+-	doc.suffix = ("""
++    # suffix
++    doc.suffix = (
++        """
+ </body>
+ </html>
+ 
+-""")[1:-1]
+-
+-	# substitute into template
+-	# -------
+-	# note: this is not general enough to handle any possible layout well, at
+-	# the moment.  but it should handle more standard ones well.  (hopefully
+-	# minor) modifications may be necessary on a case by case basis
+-	# -------
+-	layer_number = -1
+-	for (layout, layer) in zip( info.matrix_layout,
+-								range(len(info.matrix_layout))):
+-		layer_number += 1
+-		svg = template.svg
+-		for (name, (code, press, release)) \
+-				in zip(info.matrix_positions, layout):
+-			replace = ''
+-			if press == 'kbfun_transparent':
+-				replace = ''
+-			elif press == 'kbfun_shift_press_release':
+-				replace = 'sh ' + keycode_to_string.get(code, '[n/a]')
+-			elif press == 'kbfun_jump_to_bootloader':
+-				replace = '[btldr]'
+-			elif press == 'NULL' and release == 'NULL':
+-				replace = '(null)'
+-			elif re.search(r'numpad', press+release):
+-				replace = '[num]'
+-			elif re.search(r'layer', press+release):
+-				replace = 'la ' + re.findall(r'\d+', press+release)[0] + ' '
+-				if re.search(r'push', press+release):
+-					replace += '+'
+-				if re.search(r'pop', press+release):
+-					replace += '-'
+-				replace += ' ' + str(code)
+-			else:
+-				replace = keycode_to_string.get(code, '[n/a]')
+-
+-			svg = re.sub(
+-					'>'+name+'<', '>'+replace+'<', svg )
+-			svg = re.sub(
+-					r"\('(" + name + r".*)'\)",
+-					r"('\1', " + str(layer) + r")",
+-					svg )
+-
+-		doc.main += '<h2>Layer ' + str(layer_number) + '</h2>\n' + svg
+-
+-	# change the font size
+-	doc.main = re.sub(r'22.5px', '15px', doc.main)
+-
+-	print(doc.prefix + doc.main + doc.suffix)
++"""
++    )[1:-1]
++
++    # substitute into template
++    # -------
++    # note: this is not general enough to handle any possible layout well, at
++    # the moment.  but it should handle more standard ones well.  (hopefully
++    # minor) modifications may be necessary on a case by case basis
++    # -------
++    layer_number = -1
++    for (layout, layer) in zip(
++        info.matrix_layout, range(len(info.matrix_layout))
++    ):
++        layer_number += 1
++        svg = template.svg
++        for (name, (code, press, release)) in zip(
++            info.matrix_positions, layout
++        ):
++            replace = ""
++            if press == "kbfun_transparent":
++                replace = ""
++            elif press == "kbfun_shift_press_release":
++                replace = "sh " + keycode_to_string.get(code, "[n/a]")
++            elif press == "kbfun_jump_to_bootloader":
++                replace = "[btldr]"
++            elif press == "NULL" and release == "NULL":
++                replace = "(null)"
++            elif re.search(r"numpad", press + release):
++                replace = "[num]"
++            elif re.search(r"layer", press + release):
++                replace = "la " + re.findall(r"\d+", press + release)[0] + " "
++                if re.search(r"push", press + release):
++                    replace += "+"
++                if re.search(r"pop", press + release):
++                    replace += "-"
++                replace += " " + str(code)
++            else:
++                replace = keycode_to_string.get(code, "[n/a]")
++
++            svg = re.sub(">" + name + "<", ">" + replace + "<", svg)
++            svg = re.sub(
++                r"\('(" + name + r".*)'\)", r"('\1', " + str(layer) + r")", svg
++            )
++
++        doc.main += "<h2>Layer " + str(layer_number) + "</h2>\n" + svg
++
++    # change the font size
++    doc.main = re.sub(r"22.5px", "15px", doc.main)
++
++    print(doc.prefix + doc.main + doc.suffix)
++
+ 
+ # -----------------------------------------------------------------------------
+ # -----------------------------------------------------------------------------
+ 
+ keycode_to_string = {
+-		0x01: "Error",  # ErrorRollOver
+-		0x02: "POSTFail",
+-		0x03: "Error",  # ErrorUndefined
+-		0x04: "a A",
+-		0x05: "b B",
+-		0x06: "c C",
+-		0x07: "d D",
+-		0x08: "e E",
+-		0x09: "f F",
+-		0x0A: "g G",
+-		0x0B: "h H",
+-		0x0C: "i I",
+-		0x0D: "j J",
+-		0x0E: "k K",
+-		0x0F: "l L",
+-		0x10: "m M",
+-		0x11: "n N",
+-		0x12: "o O",
+-		0x13: "p P",
+-		0x14: "q Q",
+-		0x15: "r R",
+-		0x16: "s S",
+-		0x17: "t T",
+-		0x18: "u U",
+-		0x19: "v V",
+-		0x1A: "w W",
+-		0x1B: "x X",
+-		0x1C: "y Y",
+-		0x1D: "z Z",
+-		0x1E: "1 !",
+-		0x1F: "2 @",
+-		0x20: "3 #",
+-		0x21: "4 $",
+-		0x22: "5 %",
+-		0x23: "6 ^",
+-		0x24: "7 &",
+-		0x25: "8 *",
+-		0x26: "9 (",
+-		0x27: "0 )",
+-		0x28: "Return",
+-		0x29: "Esc",
+-		0x2A: "Backspace",
+-		0x2B: "Tab",
+-		0x2C: "Space",
+-		0x2D: "- _",
+-		0x2E: "= +",
+-		0x2F: "[ {",
+-		0x30: "] }",
+-		0x31: "\ |",
+-		0x32: "# ~",
+-		0x33: "; :",
+-		0x34: "\' \"",
+-		0x35: "` ~",
+-		0x36: ", <",
+-		0x37: ". >",
+-		0x38: "/ ?",
+-		0x39: "Caps",
+-		0x3A: "F1",
+-		0x3B: "F2",
+-		0x3C: "F3",
+-		0x3D: "F4",
+-		0x3E: "F5",
+-		0x3F: "F6",
+-		0x40: "F7",
+-		0x41: "F8",
+-		0x42: "F9",
+-		0x43: "F10",
+-		0x44: "F11",
+-		0x45: "F12",
+-		0x46: "PrintScreen",
+-		0x47: "ScrollLock",
+-		0x48: "Pause",
+-		0x49: "Ins",  # Insert
+-		0x4A: "Hm",  # Home
+-		0x4B: "Pg\u2191",  # up arrow
+-		0x4C: "Delete",
+-		0x4D: "End",
+-		0x4E: "Pg\u2193",  # down arrow
+-		0x4F: "\u2192",  # right arrow
+-		0x50: "\u2190",  # left arrow
+-		0x51: "\u2193",  # down arrow
+-		0x52: "\u2191",  # up arrow
+-
+-		0x53: "Num",
+-		0x54: "/",
+-		0x55: "*",
+-		0x56: "-",
+-		0x57: "+",
+-		0x58: "Enter",
+-		0x59: "1 End",
+-		0x5A: "2 \u2193",  # down arrow
+-		0x5B: "3 Pg\u2193",  # down arrow
+-		0x5C: "4 \u2190",  # left arrow
+-		0x5D: "5",
+-		0x5E: "6 \u2192",  # right arrow
+-		0x5F: "7 Hm",  # Home
+-		0x60: "8 \u2191",  # up arrow
+-		0x61: "9 Pg\u2191",  # up arrow
+-		0x62: "0 Ins",  # Insert
+-		0x63: ". Del",
+-
+-		0x64: "\ |",
+-		0x65: "App",
+-		0x66: "Power",
+-
+-		0x67: "=",
+-
+-		0x68: "F13",
+-		0x69: "F14",
+-		0x6A: "F15",
+-		0x6B: "F16",
+-		0x6C: "F17",
+-		0x6D: "F18",
+-		0x6E: "F19",
+-		0x6F: "F20",
+-		0x70: "F21",
+-		0x71: "F22",
+-		0x72: "F23",
+-		0x73: "F24",
+-		0x74: "Exec",
+-		0x75: "Help",
+-		0x76: "Menu",
+-		0x77: "Select",
+-		0x78: "Stop",
+-		0x79: "Again",
+-		0x7A: "Undo",
+-		0x7B: "Cut",
+-		0x7C: "Copy",
+-		0x7D: "Paste",
+-		0x7E: "Find",
+-		0x7F: "Mute",
+-		0x80: "VolUp",
+-		0x81: "VolDown",
+-		0x82: "LockingCapsLock",
+-		0x83: "LockingNumLock",
+-		0x84: "LockingScrollLock",
+-
+-		0x85: ",",
+-		0x86: "=",
+-
+-		0x87: "Int1",
+-		0x88: "Int2",
+-		0x89: "Int3",
+-		0x8A: "Int4",
+-		0x8B: "Int5",
+-		0x8C: "Int6",
+-		0x8D: "Int7",
+-		0x8E: "Int8",
+-		0x8F: "Int9",
+-		0x90: "LANG1",
+-		0x91: "LANG2",
+-		0x92: "LANG3",
+-		0x93: "LANG4",
+-		0x94: "LANG5",
+-		0x95: "LANG6",
+-		0x96: "LANG7",
+-		0x97: "LANG8",
+-		0x98: "LANG9",
+-		0x99: "AlternateErase",
+-		0x9A: "SysReq_Attention",
+-		0x9B: "Cancel",
+-		0x9C: "Clear",
+-		0x9D: "Prior",
+-		0x9E: "Return",
+-		0x9F: "Separator",
+-		0xA0: "Out",
+-		0xA1: "Oper",
+-		0xA2: "Clear_Again",
+-		0xA3: "CrSel_Props",
+-		0xA4: "ExSel",
+-
+-		0xB0: "00",
+-		0xB1: "000",
+-
+-		0xB2: "Thousands_Sep",
+-		0xB3: "Decimal_Sep",
+-		0xB4: "$",
+-		0xB5: "Currency_Subunit",
+-
+-		0xB6: "(",
+-		0xB7: ")",
+-		0xB8: "{",
+-		0xB9: "}",
+-
+-		0xBA: "Tab",
+-		0xBB: "Backspace",
+-		0xBC: "A",
+-		0xBD: "B",
+-		0xBE: "C",
+-		0xBF: "D",
+-		0xC0: "E",
+-		0xC1: "F",
+-		0xC2: "XOR",
+-		0xC3: "^",
+-		0xC4: "%",
+-		0xC5: "<",
+-		0xC6: ">",
+-		0xC7: "&",
+-		0xC8: "&&",
+-		0xC9: "|",
+-		0xCA: "||",
+-		0xCB: ":",
+-		0xCC: "#",
+-		0xCD: "Space",
+-		0xCE: "@",
+-		0xCF: "!",
+-		0xD0: "Mem_Store",
+-		0xD1: "Mem_Recall",
+-		0xD2: "Mem_Clear",
+-		0xD3: "Mem_+",
+-		0xD4: "Mem_-",
+-		0xD5: "Mem_*",
+-		0xD6: "Mem_/",
+-		0xD7: "+-",
+-		0xD8: "Clear",
+-		0xD9: "ClearEntry",
+-		0xDA: "Binary",
+-		0xDB: "Octal",
+-		0xDC: ".",
+-		0xDD: "Hexadecimal",
+-
+-		0xE0: "L-Ctrl",
+-		0xE1: "L-Shift",
+-		0xE2: "L-Alt",
+-		0xE3: "L-GUI",
+-		0xE4: "R-Ctrl",
+-		0xE5: "R-Shift",
+-		0xE6: "R-Alt",
+-		0xE7: "R-GUI",
+-		}
++    0x01: "Error",  # ErrorRollOver
++    0x02: "POSTFail",
++    0x03: "Error",  # ErrorUndefined
++    0x04: "a A",
++    0x05: "b B",
++    0x06: "c C",
++    0x07: "d D",
++    0x08: "e E",
++    0x09: "f F",
++    0x0A: "g G",
++    0x0B: "h H",
++    0x0C: "i I",
++    0x0D: "j J",
++    0x0E: "k K",
++    0x0F: "l L",
++    0x10: "m M",
++    0x11: "n N",
++    0x12: "o O",
++    0x13: "p P",
++    0x14: "q Q",
++    0x15: "r R",
++    0x16: "s S",
++    0x17: "t T",
++    0x18: "u U",
++    0x19: "v V",
++    0x1A: "w W",
++    0x1B: "x X",
++    0x1C: "y Y",
++    0x1D: "z Z",
++    0x1E: "1 !",
++    0x1F: "2 @",
++    0x20: "3 #",
++    0x21: "4 $",
++    0x22: "5 %",
++    0x23: "6 ^",
++    0x24: "7 &",
++    0x25: "8 *",
++    0x26: "9 (",
++    0x27: "0 )",
++    0x28: "Return",
++    0x29: "Esc",
++    0x2A: "Backspace",
++    0x2B: "Tab",
++    0x2C: "Space",
++    0x2D: "- _",
++    0x2E: "= +",
++    0x2F: "[ {",
++    0x30: "] }",
++    0x31: "\ |",
++    0x32: "# ~",
++    0x33: "; :",
++    0x34: "' \"",
++    0x35: "` ~",
++    0x36: ", <",
++    0x37: ". >",
++    0x38: "/ ?",
++    0x39: "Caps",
++    0x3A: "F1",
++    0x3B: "F2",
++    0x3C: "F3",
++    0x3D: "F4",
++    0x3E: "F5",
++    0x3F: "F6",
++    0x40: "F7",
++    0x41: "F8",
++    0x42: "F9",
++    0x43: "F10",
++    0x44: "F11",
++    0x45: "F12",
++    0x46: "PrintScreen",
++    0x47: "ScrollLock",
++    0x48: "Pause",
++    0x49: "Ins",  # Insert
++    0x4A: "Hm",  # Home
++    0x4B: "Pg\u2191",  # up arrow
++    0x4C: "Delete",
++    0x4D: "End",
++    0x4E: "Pg\u2193",  # down arrow
++    0x4F: "\u2192",  # right arrow
++    0x50: "\u2190",  # left arrow
++    0x51: "\u2193",  # down arrow
++    0x52: "\u2191",  # up arrow
++    0x53: "Num",
++    0x54: "/",
++    0x55: "*",
++    0x56: "-",
++    0x57: "+",
++    0x58: "Enter",
++    0x59: "1 End",
++    0x5A: "2 \u2193",  # down arrow
++    0x5B: "3 Pg\u2193",  # down arrow
++    0x5C: "4 \u2190",  # left arrow
++    0x5D: "5",
++    0x5E: "6 \u2192",  # right arrow
++    0x5F: "7 Hm",  # Home
++    0x60: "8 \u2191",  # up arrow
++    0x61: "9 Pg\u2191",  # up arrow
++    0x62: "0 Ins",  # Insert
++    0x63: ". Del",
++    0x64: "\ |",
++    0x65: "App",
++    0x66: "Power",
++    0x67: "=",
++    0x68: "F13",
++    0x69: "F14",
++    0x6A: "F15",
++    0x6B: "F16",
++    0x6C: "F17",
++    0x6D: "F18",
++    0x6E: "F19",
++    0x6F: "F20",
++    0x70: "F21",
++    0x71: "F22",
++    0x72: "F23",
++    0x73: "F24",
++    0x74: "Exec",
++    0x75: "Help",
++    0x76: "Menu",
++    0x77: "Select",
++    0x78: "Stop",
++    0x79: "Again",
++    0x7A: "Undo",
++    0x7B: "Cut",
++    0x7C: "Copy",
++    0x7D: "Paste",
++    0x7E: "Find",
++    0x7F: "Mute",
++    0x80: "VolUp",
++    0x81: "VolDown",
++    0x82: "LockingCapsLock",
++    0x83: "LockingNumLock",
++    0x84: "LockingScrollLock",
++    0x85: ",",
++    0x86: "=",
++    0x87: "Int1",
++    0x88: "Int2",
++    0x89: "Int3",
++    0x8A: "Int4",
++    0x8B: "Int5",
++    0x8C: "Int6",
++    0x8D: "Int7",
++    0x8E: "Int8",
++    0x8F: "Int9",
++    0x90: "LANG1",
++    0x91: "LANG2",
++    0x92: "LANG3",
++    0x93: "LANG4",
++    0x94: "LANG5",
++    0x95: "LANG6",
++    0x96: "LANG7",
++    0x97: "LANG8",
++    0x98: "LANG9",
++    0x99: "AlternateErase",
++    0x9A: "SysReq_Attention",
++    0x9B: "Cancel",
++    0x9C: "Clear",
++    0x9D: "Prior",
++    0x9E: "Return",
++    0x9F: "Separator",
++    0xA0: "Out",
++    0xA1: "Oper",
++    0xA2: "Clear_Again",
++    0xA3: "CrSel_Props",
++    0xA4: "ExSel",
++    0xB0: "00",
++    0xB1: "000",
++    0xB2: "Thousands_Sep",
++    0xB3: "Decimal_Sep",
++    0xB4: "$",
++    0xB5: "Currency_Subunit",
++    0xB6: "(",
++    0xB7: ")",
++    0xB8: "{",
++    0xB9: "}",
++    0xBA: "Tab",
++    0xBB: "Backspace",
++    0xBC: "A",
++    0xBD: "B",
++    0xBE: "C",
++    0xBF: "D",
++    0xC0: "E",
++    0xC1: "F",
++    0xC2: "XOR",
++    0xC3: "^",
++    0xC4: "%",
++    0xC5: "<",
++    0xC6: ">",
++    0xC7: "&",
++    0xC8: "&&",
++    0xC9: "|",
++    0xCA: "||",
++    0xCB: ":",
++    0xCC: "#",
++    0xCD: "Space",
++    0xCE: "@",
++    0xCF: "!",
++    0xD0: "Mem_Store",
++    0xD1: "Mem_Recall",
++    0xD2: "Mem_Clear",
++    0xD3: "Mem_+",
++    0xD4: "Mem_-",
++    0xD5: "Mem_*",
++    0xD6: "Mem_/",
++    0xD7: "+-",
++    0xD8: "Clear",
++    0xD9: "ClearEntry",
++    0xDA: "Binary",
++    0xDB: "Octal",
++    0xDC: ".",
++    0xDD: "Hexadecimal",
++    0xE0: "L-Ctrl",
++    0xE1: "L-Shift",
++    0xE2: "L-Alt",
++    0xE3: "L-GUI",
++    0xE4: "R-Ctrl",
++    0xE5: "R-Shift",
++    0xE6: "R-Alt",
++    0xE7: "R-GUI",
++}
+ 
+ # -----------------------------------------------------------------------------
+ # -----------------------------------------------------------------------------
+ 
+-if __name__ == '__main__':
+-	main()
+-
++if __name__ == "__main__":
++    main()
+diff --git a/build-scripts/gen-ui-info.py b/build-scripts/gen-ui-info.py
+index 1c93d32..0fa52e3 100755
+--- a/build-scripts/gen-ui-info.py
++++ b/build-scripts/gen-ui-info.py
+@@ -13,7 +13,16 @@ Depends on:
+ - the project '.map' file (generated by the compiler)
+ """
+ 
+-_FORMAT_DESCRIPTION = ("""
++import argparse
++import json
++import os
++import pathlib
++import re
++import subprocess
++import sys
++
++_FORMAT_DESCRIPTION = (
++    """
+ /* ----------------------------------------------------------------------------
+  * Version 0
+  * ----------------------------------------------------------------------------
+@@ -31,7 +40,7 @@ var ui_info = {
+     ".meta-data": {                    // for the JSON file
+         "version": "<number>",
+         "date-generated": "<string>",  // format: RFC 3339
+-		"description": "<string>",
++                "description": "<string>",
+     },
+     "keyboard-functions": {
+         "<(function name)>": {
+@@ -57,7 +66,7 @@ var ui_info = {
+         "..."
+     },
+     "mappings": {
+-        /* 
++        /*
+          * The mappings prefixed with 'matrix' have their elements in the same
+          * order as the .hex file (whatever order that is).  The mappings
+          * prefixed with 'physical' will have their elements in an order
+@@ -113,365 +122,304 @@ var ui_info = {
+         "number-of-layers": "<number>"
+     }
+ }
+-""")[1:-1]
++"""
++)[1:-1]
+ 
+ # -----------------------------------------------------------------------------
+ 
+-import argparse
+-import json
+-import os
+-import re
+-import subprocess
+-import sys
+-
+-# -----------------------------------------------------------------------------
+ 
+ def gen_static(current_date=None, git_commit_date=None, git_commit_id=None):
+-	"""Generate static information"""
+-
+-	return {
+-		'.meta-data': {
+-			'version': 0,  # the format version number
+-			'date-generated': current_date,
+-			'description': _FORMAT_DESCRIPTION,
+-		},
+-		'miscellaneous': {
+-			'git-commit-date': git_commit_date, # should be passed by makefile
+-			'git-commit-id': git_commit_id, # should be passed by makefile
+-		},
+-	}
+-
+-def gen_derived(data):
+-    return {}  # don't really need this info anymore
+-# 	"""
+-# 	Generate derived information
+-# 	Should be called last
+-# 	"""
+-# 	return {
+-# 		'miscellaneous': {
+-# 			'number-of-layers':
+-# 				int( data['layout-matrices']['_kb_layout']['length']/(6*14) ),
+-# 				# because 6*14 is the number of bytes/layer for '_kb_layout'
+-# 				# (which is a uint8_t matrix)
+-# 		},
+-# 	}
+-
+-# -----------------------------------------------------------------------------
++    """Generate static information"""
+ 
+-def parse_mapfile(map_file_path):
+-    return {}  # don't really need this info anymore
+-# 	"""Parse the '.map' file"""
+-# 
+-# 	def parse_keyboard_function(f, line):
+-# 		"""Parse keyboard-functions in the '.map' file"""
+-# 
+-# 		search = re.search(r'(0x\S+)\s+(0x\S+)', next(f))
+-# 		position = int( search.group(1), 16 )
+-# 		length = int( search.group(2), 16 )
+-# 
+-# 		search = re.search(r'0x\S+\s+(\S+)', next(f))
+-# 		name = search.group(1)
+-# 
+-# 		return {
+-# 			'keyboard-functions': {
+-# 				name: {
+-# 					'position': position,
+-# 					'length': length,
+-# 				},
+-# 			},
+-# 		}
+-# 
+-# 	def parse_layout_matrices(f, line):
+-# 		"""Parse layout matrix information in the '.map' file"""
+-# 
+-# 		name = re.search(r'.progmem.data.(_kb_layout\S*)', line).group(1)
+-# 
+-# 		search = re.search(r'(0x\S+)\s+(0x\S+)', next(f))
+-# 		position = int( search.group(1), 16 )
+-# 		length = int( search.group(2), 16 )
+-# 
+-# 		return {
+-# 			'layout-matrices': {
+-# 				name: {
+-# 					'position': position,
+-# 					'length': length,
+-# 				},
+-# 			},
+-# 		}
+-# 
+-# 	# --- parse_mapfile() ---
+-# 
+-# 	# normalize paths
+-# 	map_file_path = os.path.abspath(map_file_path)
+-# 	# check paths
+-# 	if not os.path.exists(map_file_path):
+-# 		raise ValueError("invalid 'map_file_path' given")
+-# 
+-# 	output = {}
+-# 
+-# 	f = open(map_file_path)
+-# 
+-# 	for line in f:
+-# 		if re.search(r'^\s*\.text\.kbfun_', line):
+-# 			dict_merge(output, parse_keyboard_function(f, line))
+-# 		elif re.search(r'^\s*\.progmem\.data.*layout', line):
+-# 			dict_merge(output, parse_layout_matrices(f, line))
+-# 
+-# 	return output
++    return {
++        ".meta-data": {
++            "version": 0,  # the format version number
++            "date-generated": current_date,
++            "description": _FORMAT_DESCRIPTION,
++        },
++        "miscellaneous": {
++            "git-commit-date": git_commit_date,  # should be passed by makefile
++            "git-commit-id": git_commit_id,  # should be passed by makefile
++        },
++    }
+ 
+ 
+ def find_keyboard_functions(source_code_path):
+-	"""Parse all files in the source directory"""
+-
+-	def read_comments(f, line):
+-		"""
+-		Read in properly formatted multi-line comments
+-		- Comments must start with '/*' and end with '*/', each on their own
+-		  line
+-		"""
+-		comments = ''
+-		while(line.strip() != r'*/'):
+-			comments += line[2:].strip()+'\n'
+-			line = next(f)
+-		return comments
+-
+-	def parse_comments(comments):
+-		"""
+-		Parse an INI style comment string
+-		- Fields begin with '[field-name]', and continue until the next field,
+-		  or the end of the comment
+-		- Fields '[name]', '[description]', and '[note]' are treated specially
+-		"""
+-
+-		def add_field(output, field, value):
+-			"""Put a field+value pair in 'output', the way we want it, if the
+-			pair is valid"""
+-
+-			value = value.strip()
+-
+-			if field is not None:
+-				if field in ('name', 'description'):
+-					if field not in output:
+-						output[field] = value
+-				else:
+-					if field == 'note':
+-						field = 'notes'
+-
+-					if field not in output:
+-						output[field] = []
+-
+-					output[field] += [value]
+-
+-		# --- parse_comments() ---
+-
+-		output = {}
+-
+-		field = None
+-		value = None
+-		for line in comments.split('\n'):
+-			line = line.strip()
+-
+-			if re.search(r'^\[.*\]$', line):
+-				add_field(output, field, value)
+-				field = line[1:-1]
+-				value = None
+-
+-			else:
+-				if value is None:
+-					value = ''
+-				if len(value) > 0 and value[-1] == '.':
+-					line = ' '+line
+-				value += ' '+line
+-
+-		add_field(output, field, value)
+-
+-		return output
+-
+-	def parse_keyboard_function(f, line, comments):
+-		"""Parse keyboard-functions in the source code"""
+-
+-		search = re.search(r'void\s+(kbfun_\S+)\s*\(void\)', line)
+-		name = search.group(1)
+-
+-		return {
+-			'keyboard-functions': {
+-				name: {
+-					'comments': parse_comments(comments),
+-				},
+-			},
+-		}
+-
+-	# --- find_keyboard_functions() ---
+-
+-	# normalize paths
+-	source_code_path = os.path.abspath(source_code_path)
+-	# check paths
+-	if not os.path.exists(source_code_path):
+-		raise ValueError("invalid 'source_code_path' given")
+-
+-	output = {}
+-
+-	for tup in os.walk(source_code_path):
+-		for file_name in tup[2]:
+-			# normalize paths
+-			file_name = os.path.abspath( os.path.join( tup[0], file_name ) )
+-
+-			# ignore non '.c' files
+-			if file_name[-2:] != '.c':
+-				continue
+-
+-			f = open(file_name)
+-
+-			comments = ''
+-			for line in f:
+-				if line.strip() == r'/*':
+-					comments = read_comments(f, line)
+-				elif re.search(r'void\s+kbfun_\S+\s*\(void\)', line):
+-					dict_merge(
+-							output,
+-							parse_keyboard_function(f, line, comments) )
+-
+-	return output
++    """Parse all files in the source directory"""
++
++    def read_comments(f, line):
++        """
++        Read in properly formatted multi-line comments
++        - Comments must start with '/*' and end with '*/', each on their own
++          line
++        """
++        comments = ""
++        while line.strip() != r"*/":
++            comments += line[2:].strip() + "\n"
++            line = next(f)
++        return comments
++
++    def parse_comments(comments):
++        """
++        Parse an INI style comment string
++        - Fields begin with '[field-name]', and continue until the next field,
++          or the end of the comment
++        - Fields '[name]', '[description]', and '[note]' are treated specially
++        """
++
++        def add_field(output, field, value):
++            """Put a field+value pair in 'output', the way we want it, if the
++            pair is valid"""
++
++            value = value.strip()
++
++            if field is not None:
++                if field in ("name", "description"):
++                    if field not in output:
++                        output[field] = value
++                else:
++                    if field == "note":
++                        field = "notes"
++
++                    if field not in output:
++                        output[field] = []
++
++                    output[field] += [value]
++
++        # --- parse_comments() ---
++
++        output = {}
++
++        field = None
++        value = None
++        for line in comments.split("\n"):
++            line = line.strip()
++
++            if re.search(r"^\[.*\]$", line):
++                add_field(output, field, value)
++                field = line[1:-1]
++                value = None
++            else:
++                if value is None:
++                    value = ""
++                if len(value) > 0 and value[-1] == ".":
++                    line = " " + line
++                value += " " + line
++
++        add_field(output, field, value)
++
++        return output
++
++    def parse_keyboard_function(f, line, comments):
++        """Parse keyboard-functions in the source code"""
++
++        search = re.search(r"void\s+(kbfun_\S+)\s*\(void\)", line)
++        name = search.group(1)
++
++        return {
++            "keyboard-functions": {
++                name: {
++                    "comments": parse_comments(comments),
++                },
++            },
++        }
++
++    # --- find_keyboard_functions() ---
++
++    # normalize paths
++    source_code_path = os.path.abspath(source_code_path)
++    # check paths
++    if not os.path.exists(source_code_path):
++        raise ValueError("invalid 'source_code_path' given")
++
++    output = {}
++
++    for tup in os.walk(source_code_path):
++        for file_name in tup[2]:
++            # normalize paths
++            file_name = os.path.abspath(os.path.join(tup[0], file_name))
++
++            # ignore non '.c' files
++            if file_name[-2:] != ".c":
++                continue
++
++            f = open(file_name)
++
++            comments = ""
++            for line in f:
++                if line.strip() == r"/*":
++                    comments = read_comments(f, line)
++                elif re.search(r"void\s+kbfun_\S+\s*\(void\)", line):
++                    dict_merge(
++                        output, parse_keyboard_function(f, line, comments)
++                    )
++
++    return output
+ 
+ 
+ def gen_mappings(matrix_file_path, layout_file_path):
+-	# normalize paths
+-	matrix_file_path = os.path.abspath(matrix_file_path)
+-	layout_file_path = os.path.abspath(layout_file_path)
+-
+-	def parse_matrix_file(matrix_file_path):
+-		match = re.search(  # find the whole 'KB_MATRIX_LAYER' macro
+-				r'#define\s+KB_MATRIX_LAYER\s*\(([^)]+)\)[^{]*\{\{([^#]+)\}\}',
+-				open(matrix_file_path).read() )
+-
+-		return {
+-			"mappings": {
+-				"physical-positions": re.findall(r'k..', match.group(1)),
+-				"matrix-positions": re.findall(r'k..|na', match.group(2)),
+-			},
+-		}
+-
+-	def parse_layout_file(layout_file_path):
+-		match = re.findall(  # find each whole '_kb_layout*' matrix definition
+-				r'(_kb_layout\w*)[^=]*=((?:[^{}]*\{){3}[^=]*(?:[^{}]*\}){3})',
+-				subprocess.getoutput("gcc -E '"+layout_file_path+"'") )
+-
+-		layout = {}
+-		# collect all the values
+-		for (name, matrix) in match:
+-			layout[name] = [
+-					re.findall(  # find all numbers and function pointers
+-						r'[x0-9A-F]+|&\w+|NULL',
+-						re.sub(  # replace '((void *) 0)' with 'NULL'
+-							r'\(\s*\(\s*void\s*\*\s*\)\s*0\s*\)',
+-							'NULL',
+-							el ) )
+-					for el in
+-						re.findall(  # find each whole layer
+-							r'(?:[^{}]*\{){2}((?:[^}]|\}\s*,)+)(?:[^{}]*\}){2}',
+-							matrix ) ]
+-
+-		# make the numbers into actual numbers
+-		layout['_kb_layout'] = \
+-				[[eval(el) for el in layer] for layer in layout['_kb_layout']]
+-		# remove the preceeding '&' from function pointers
+-		for matrix in ('_kb_layout_press', '_kb_layout_release'):
+-			layout[matrix] = \
+-					[ [re.sub(r'&', '', el) for el in layer]
+-					  for layer in layout[matrix] ]
+-
+-		return {
+-			"mappings": {
+-				"matrix-layout":
+-					# group them all properly
+-					[ [[c, p, r] for (c, p, r) in zip(code, press, release)]
+-					  for (code, press, release) in
+-						  zip( layout['_kb_layout'],
+-							   layout['_kb_layout_press'],
+-							   layout['_kb_layout_release'] ) ]
+-			},
+-		}
+-
+-	return dict_merge(
+-			parse_matrix_file(matrix_file_path),
+-			parse_layout_file(layout_file_path) )
++    # normalize paths
++    matrix_file_path = os.path.abspath(matrix_file_path)
++    layout_file_path = os.path.abspath(layout_file_path)
++    layout_name = pathlib.Path(layout_file_path).with_suffix('').name
++
++    def parse_matrix_file(matrix_file_path):
++        match = re.search(  # find the whole 'KB_MATRIX_LAYER' macro
++            r"#define\s+KB_MATRIX_LAYER\s*\(([^)]+)\)[^{]*\{\{([^#]+)\}\}",
++            open(matrix_file_path).read(),
++        )
++
++        return {
++            "mappings": {
++                "physical-positions": re.findall(r"k..", match.group(1)),
++                "matrix-positions": re.findall(r"k..|na", match.group(2)),
++            },
++        }
++
++    def parse_layout_file(layout_file_path):
++        output = subprocess.check_output(
++            ['avr-gcc', f'-DMAKEFILE_KEYBOARD_LAYOUT={layout_name}',
++             '-E', layout_file_path], encoding='UTF-8')
++        match = re.findall(  # find each whole '_kb_layout*' matrix definition
++            r"(_kb_layout\w*)[^=]*=((?:[^{}]*\{){3}[^=]*(?:[^{}]*\}){3})",
++            output,
++        )
++
++        layout = {}
++        # collect all the values
++        for (name, matrix) in match:
++            layout[name] = [
++                re.findall(  # find all numbers and function pointers
++                    r"[x0-9A-F]+|&\w+|NULL",
++                    re.sub(  # replace '((void *) 0)' with 'NULL'
++                        r"\(\s*\(\s*void\s*\*\s*\)\s*0\s*\)", "NULL", el
++                    ),
++                )
++                for el in re.findall(  # find each whole layer
++                    r"(?:[^{}]*\{){2}((?:[^}]|\}\s*,)+)(?:[^{}]*\}){2}", matrix
++                )
++            ]
++
++        # make the numbers into actual numbers
++        layout["_kb_layout"] = [
++            [eval(el) for el in layer] for layer in layout["_kb_layout"]
++        ]
++        # remove the preceeding '&' from function pointers
++        for matrix in ("_kb_layout_press", "_kb_layout_release"):
++            layout[matrix] = [
++                [re.sub(r"&", "", el) for el in layer]
++                for layer in layout[matrix]
++            ]
++
++        return {
++            "mappings": {
++                "matrix-layout":
++                # group them all properly
++                [
++                    [[c, p, r] for (c, p, r) in zip(code, press, release)]
++                    for (code, press, release) in zip(
++                        layout["_kb_layout"],
++                        layout["_kb_layout_press"],
++                        layout["_kb_layout_release"],
++                    )
++                ]
++            },
++        }
++
++    return dict_merge(
++        parse_matrix_file(matrix_file_path),
++        parse_layout_file(layout_file_path),
++    )
+ 
+ 
+ # -----------------------------------------------------------------------------
+ 
++
+ def dict_merge(a, b):
+-	"""
+-	Recursively merge two dictionaries
+-	- I was looking around for an easy way to do this, and found something
+-	  [here]
+-	  (http://www.xormedia.com/recursively-merge-dictionaries-in-python.html).
+-	  This is pretty close, but i didn't copy it exactly.
+-	"""
++    """
++    Recursively merge two dictionaries
++    - I was looking around for an easy way to do this, and found something
++      [here]
++      (http://www.xormedia.com/recursively-merge-dictionaries-in-python.html).
++      This is pretty close, but i didn't copy it exactly.
++    """
++
++    if not isinstance(a, dict) or not isinstance(b, dict):
++        return b
+ 
+-	if not isinstance(a, dict) or not isinstance(b, dict):
+-		return b
++    for (key, value) in b.items():
++        if key in a:
++            a[key] = dict_merge(a[key], value)
++        else:
++            a[key] = value
+ 
+-	for (key, value) in b.items():
+-		if key in a:
+-			a[key] = dict_merge(a[key], value)
+-		else:
+-			a[key] = value
++    return a
+ 
+-	return a
+ 
+ # -----------------------------------------------------------------------------
+ 
++
+ def main():
+-	arg_parser = argparse.ArgumentParser(
+-			description = 'Generate project data for use with the UI' )
+-
+-	arg_parser.add_argument(
+-			'--current-date',
+-			help = ( "should be in the format rfc-3339 "
+-				   + "(e.g. 2006-08-07 12:34:56-06:00)" ),
+-			required = True )
+-	arg_parser.add_argument(
+-			'--git-commit-date',
+-			help = ( "should be in the format rfc-3339 "
+-				   + "(e.g. 2006-08-07 12:34:56-06:00)" ),
+-			required = True )
+-	arg_parser.add_argument(
+-			'--git-commit-id',
+-			help = "the git commit ID",
+-			required = True )
+-	arg_parser.add_argument(
+-			'--map-file-path',
+-			help = "the path to the '.map' file",
+-			required = True )
+-	arg_parser.add_argument(
+-			'--source-code-path',
+-			help = "the path to the source code directory",
+-			required = True )
+-	arg_parser.add_argument(
+-			'--matrix-file-path',
+-			help = "the path to the matrix file we're using",
+-			required = True )
+-	arg_parser.add_argument(
+-			'--layout-file-path',
+-			help = "the path to the layout file we're using",
+-			required = True )
+-
+-	args = arg_parser.parse_args(sys.argv[1:])
+-
+-	output = {}
+-	dict_merge( output, gen_static( args.current_date,
+-									args.git_commit_date,
+-									args.git_commit_id ) )
+-	dict_merge(output, parse_mapfile(args.map_file_path))
+-	dict_merge(output, find_keyboard_functions(args.source_code_path))
+-	dict_merge(output, gen_mappings( args.matrix_file_path,
+-									  args.layout_file_path ))
+-	dict_merge(output, gen_derived(output))
+-
+-	print(json.dumps(output, sort_keys=True, indent=4))
++    arg_parser = argparse.ArgumentParser(
++        description="Generate project data for use with the UI"
++    )
++
++    arg_parser.add_argument(
++        "--current-date",
++        help=(
++            "should be in the format rfc-3339 "
++            "(e.g. 2006-08-07 12:34:56-06:00)"
++        ),
++        required=True,
++    )
++    arg_parser.add_argument(
++        "--git-commit-date",
++        help=(
++            "should be in the format rfc-3339 "
++            "(e.g. 2006-08-07 12:34:56-06:00)"
++        ),
++        required=True,
++    )
++    arg_parser.add_argument(
++        "--git-commit-id", help="the git commit ID", required=True
++    )
++    arg_parser.add_argument(
++        "--map-file-path", help="the path to the '.map' file", required=True
++    )
++    arg_parser.add_argument(
++        "--source-code-path",
++        help="the path to the source code directory",
++        required=True,
++    )
++    arg_parser.add_argument(
++        "--matrix-file-path",
++        help="the path to the matrix file we're using",
++        required=True,
++    )
++    arg_parser.add_argument(
++        "--layout-file-path",
++        help="the path to the layout file we're using",
++        required=True,
++    )
++
++    args = arg_parser.parse_args(sys.argv[1:])
++
++    output = {}
++    dict_merge(
++        output,
++        gen_static(
++            args.current_date, args.git_commit_date, args.git_commit_id
++        )
++    )
++    dict_merge(output, find_keyboard_functions(args.source_code_path))
++    dict_merge(
++        output, gen_mappings(args.matrix_file_path, args.layout_file_path)
++    )
++
++    print(json.dumps(output, sort_keys=True, indent=4))
+ 
+-# -----------------------------------------------------------------------------
+ 
+-if __name__ == '__main__':
+-	main()
++# -----------------------------------------------------------------------------
+ 
++if __name__ == "__main__":
++    main()
+diff --git a/makefile b/makefile
+index d9fe10c..971ee0e 100644
+--- a/makefile
++++ b/makefile
+@@ -58,24 +58,27 @@ SCRIPTS := build-scripts
+ all: dist
+ 
+ clean:
+-	git clean -dX  # remove ignored files and directories
+-	-rm -r '$(BUILD)'
++	git clean -fdX  # remove ignored files and directories
++	rm -rf '$(BUILD)'
+ 
+ checkin:
+ 	-git commit -a
+ 
+ build-dir:
+-	-rm -r '$(BUILD)/$(TARGET)'*
+-	-mkdir -p '$(BUILD)/$(TARGET)'
++	rm -rf '$(BUILD)/$(TARGET)'*
++	mkdir -p '$(BUILD)/$(TARGET)'
+ 
+ firmware:
+ 	cd src; $(MAKE) LAYOUT=$(LAYOUT) all
+ 
+-$(ROOT)/firmware.%: firmware
++$(ROOT):
++	mkdir -p '$@'
++
++$(ROOT)/firmware.%: firmware $(ROOT)
+ 	cp 'src/firmware.$*' '$@'
+ 
+ 
+-$(ROOT)/firmware--ui-info.json: $(SCRIPTS)/gen-ui-info.py checkin
++$(ROOT)/firmware--ui-info.json: $(SCRIPTS)/gen-ui-info.py checkin firmware
+ 	( ./'$<' \
+ 		--current-date '$(shell $(DATE_PROG) --rfc-3339 s)' \
+ 		--git-commit-date '$(GIT_COMMIT_DATE)' \
diff --git a/gnu/packages/patches/ergodox-firmware-fix-numpad.patch b/gnu/packages/patches/ergodox-firmware-fix-numpad.patch
new file mode 100644
index 00000000000..47af9f8398d
--- /dev/null
+++ b/gnu/packages/patches/ergodox-firmware-fix-numpad.patch
@@ -0,0 +1,18 @@
+Submitted upstream: https://github.com/benblazak/ergodox-firmware/pull/100
+
+diff --git a/src/lib/key-functions/public/special.c b/src/lib/key-functions/public/special.c
+index 42aba45..6488137 100644
+--- a/src/lib/key-functions/public/special.c
++++ b/src/lib/key-functions/public/special.c
+@@ -102,9 +102,9 @@ void kbfun_2_keys_capslock_press_release(void) {
+ static uint8_t numpad_layer_id;
+ 
+ static inline void numpad_toggle_numlock(void) {
+-	_kbfun_press_release(true, KEY_LockingNumLock);
++	_kbfun_press_release(true, KEYPAD_NumLock_Clear);
+ 	usb_keyboard_send();
+-	_kbfun_press_release(false, KEY_LockingNumLock);
++	_kbfun_press_release(false, KEYPAD_NumLock_Clear);
+ 	usb_keyboard_send();
+ }
+ 
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 16/22] gnu: Add ergodox-firmware-colemak-symbol-mod.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (14 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 15/22] gnu: Add ergodox-firmware-colemak-jc-mod Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 17/22] gnu: Add ergodox-firmware-dvorak-kinesis-mod Maxim Cournoyer
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer, Efraim Flashner, Vagrant Cascadian

* gnu/packages/firmware.scm (ergodox-firmware-colemak-symbol-mod): New variable.
---

 gnu/packages/firmware.scm | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gnu/packages/firmware.scm b/gnu/packages/firmware.scm
index a901ae46944..213f2002403 100644
--- a/gnu/packages/firmware.scm
+++ b/gnu/packages/firmware.scm
@@ -1297,6 +1297,9 @@ (define make-ergodox-firmware
 (define-public ergodox-firmware-colemak-jc-mod
   (make-ergodox-firmware "colemak-jc-mod"))
 
+(define-public ergodox-firmware-colemak-symbol-mod
+  (make-ergodox-firmware "colemak-symbol-mod"))
+
 \f
 ;;;
 ;;; QMK Firmware.
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 17/22] gnu: Add ergodox-firmware-dvorak-kinesis-mod.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (15 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 16/22] gnu: Add ergodox-firmware-colemak-symbol-mod Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 18/22] gnu: Add ergodox-firmware-qwerty-kinesis-mod Maxim Cournoyer
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer, Efraim Flashner, Vagrant Cascadian

* gnu/packages/firmware.scm (ergodox-firmware-dvorak-kinesis-mod): New variable.
---

 gnu/packages/firmware.scm | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gnu/packages/firmware.scm b/gnu/packages/firmware.scm
index 213f2002403..9bab352f704 100644
--- a/gnu/packages/firmware.scm
+++ b/gnu/packages/firmware.scm
@@ -1300,6 +1300,9 @@ (define-public ergodox-firmware-colemak-jc-mod
 (define-public ergodox-firmware-colemak-symbol-mod
   (make-ergodox-firmware "colemak-symbol-mod"))
 
+(define-public ergodox-firmware-dvorak-kinesis-mod
+  (make-ergodox-firmware "dvorak-kinesis-mod"))
+
 \f
 ;;;
 ;;; QMK Firmware.
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 18/22] gnu: Add ergodox-firmware-qwerty-kinesis-mod.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (16 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 17/22] gnu: Add ergodox-firmware-dvorak-kinesis-mod Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 19/22] gnu: Add ergodox-firmware-workman-p-kinesis-mod Maxim Cournoyer
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer, Efraim Flashner, Vagrant Cascadian

* gnu/packages/firmware.scm (ergodox-firmware-qwerty-kinesis-mod): New variable.
---

 gnu/packages/firmware.scm | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gnu/packages/firmware.scm b/gnu/packages/firmware.scm
index 9bab352f704..4f928ec8bce 100644
--- a/gnu/packages/firmware.scm
+++ b/gnu/packages/firmware.scm
@@ -1303,6 +1303,9 @@ (define-public ergodox-firmware-colemak-symbol-mod
 (define-public ergodox-firmware-dvorak-kinesis-mod
   (make-ergodox-firmware "dvorak-kinesis-mod"))
 
+(define-public ergodox-firmware-qwerty-kinesis-mod
+  (make-ergodox-firmware "qwerty-kinesis-mod"))
+
 \f
 ;;;
 ;;; QMK Firmware.
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 19/22] gnu: Add ergodox-firmware-workman-p-kinesis-mod.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (17 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 18/22] gnu: Add ergodox-firmware-qwerty-kinesis-mod Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 20/22] gnu: teensy-loader-cli: Use gexps Maxim Cournoyer
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer, Efraim Flashner, Vagrant Cascadian

* gnu/packages/firmware.scm (ergodox-firmware-workman-p-kinesis-mod): New variable.
---

 gnu/packages/firmware.scm | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gnu/packages/firmware.scm b/gnu/packages/firmware.scm
index 4f928ec8bce..5eb4292ec7d 100644
--- a/gnu/packages/firmware.scm
+++ b/gnu/packages/firmware.scm
@@ -1306,6 +1306,9 @@ (define-public ergodox-firmware-dvorak-kinesis-mod
 (define-public ergodox-firmware-qwerty-kinesis-mod
   (make-ergodox-firmware "qwerty-kinesis-mod"))
 
+(define-public ergodox-firmware-workman-p-kinesis-mod
+  (make-ergodox-firmware "workman-p-kinesis-mod"))
+
 \f
 ;;;
 ;;; QMK Firmware.
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 20/22] gnu: teensy-loader-cli: Use gexps.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (18 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 19/22] gnu: Add ergodox-firmware-workman-p-kinesis-mod Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 21/22] gnu: teensy-loader-cli: Fix license Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 22/22] gnu: Add teensy-udev-rules Maxim Cournoyer
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer

* gnu/packages/flashing-tools.scm (teensy-loader-cli) [arguments]: Use gexps.
---

 gnu/packages/flashing-tools.scm | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/gnu/packages/flashing-tools.scm b/gnu/packages/flashing-tools.scm
index d9f59cd0b7c..a17547cbcd7 100644
--- a/gnu/packages/flashing-tools.scm
+++ b/gnu/packages/flashing-tools.scm
@@ -234,16 +234,15 @@ (define-public teensy-loader-cli
        (patches (search-patches "teensy-loader-cli-help.patch"))))
     (build-system gnu-build-system)
     (arguments
-     '(#:tests? #f ;; Makefile has no test target
-       #:make-flags (list "CC=gcc" (string-append "PREFIX=" %output))
-       #:phases
-       (modify-phases %standard-phases
-         (delete 'configure)
-         (replace 'install
-           (lambda* (#:key outputs #:allow-other-keys)
-             (let* ((out (assoc-ref outputs "out"))
-                    (bin (string-append out "/bin")))
-               (install-file "teensy_loader_cli" bin)))))))
+     (list
+      #:tests? #f ;; Makefile has no test target
+      #:make-flags #~(list "CC=gcc" (string-append "PREFIX=" #$output))
+      #:phases #~(modify-phases %standard-phases
+                   (delete 'configure)
+                   (replace 'install
+                     (lambda _
+                       (install-file "teensy_loader_cli"
+                                     (string-append #$output "/bin")))))))
     (inputs (list libusb-compat))       ;only compatible with libusb 0.1
     (synopsis "Command line firmware uploader for Teensy development boards")
     (description
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 21/22] gnu: teensy-loader-cli: Fix license.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (19 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 20/22] gnu: teensy-loader-cli: Use gexps Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  2023-09-26 19:04 ` [bug#66217] [PATCH 22/22] gnu: Add teensy-udev-rules Maxim Cournoyer
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer

* gnu/packages/flashing-tools.scm (teensy-loader-cli) [license]: Adjust to
license:gpl3+.
---

 gnu/packages/flashing-tools.scm | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gnu/packages/flashing-tools.scm b/gnu/packages/flashing-tools.scm
index a17547cbcd7..5142a993cf9 100644
--- a/gnu/packages/flashing-tools.scm
+++ b/gnu/packages/flashing-tools.scm
@@ -252,7 +252,7 @@ (define-public teensy-loader-cli
 You need to add the udev rules to make the Teensy update available for
 non-root users.")
     (home-page "https://www.pjrc.com/teensy/loader_cli.html")
-    (license license:gpl3)))
+    (license license:gpl3+)))
 
 (define-public rkflashtool
   (let ((commit "8966c4e277de8148290554aaaa4146a3a84a3c53")
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [bug#66217] [PATCH 22/22] gnu: Add teensy-udev-rules.
  2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
                   ` (20 preceding siblings ...)
  2023-09-26 19:04 ` [bug#66217] [PATCH 21/22] gnu: teensy-loader-cli: Fix license Maxim Cournoyer
@ 2023-09-26 19:04 ` Maxim Cournoyer
  21 siblings, 0 replies; 23+ messages in thread
From: Maxim Cournoyer @ 2023-09-26 19:04 UTC (permalink / raw)
  To: 66217; +Cc: Maxim Cournoyer

* gnu/packages/flashing-tools.scm (teensy-udev-rules): New variable.

---

 gnu/packages/flashing-tools.scm | 43 ++++++++++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/flashing-tools.scm b/gnu/packages/flashing-tools.scm
index 5142a993cf9..fb48b2a366c 100644
--- a/gnu/packages/flashing-tools.scm
+++ b/gnu/packages/flashing-tools.scm
@@ -10,6 +10,7 @@
 ;;; Copyright © 2021 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2021 Mathieu Othacehe <othacehe@gnu.org>
 ;;; Copyright © 2022 Peter Polidoro <peter@polidoro.io>
+;;; Copyright © 2023 Maxim Cournoyer <maxim.cournoyer@gmail.com>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -35,6 +36,7 @@ (define-module (gnu packages flashing-tools)
   #:use-module (guix utils)
   #:use-module (gnu packages)
   #:use-module (guix build-system cmake)
+  #:use-module (guix build-system copy)
   #:use-module (guix build-system gnu)
   #:use-module (guix build-system meson)
   #:use-module (guix build-system python)
@@ -61,7 +63,8 @@ (define-module (gnu packages flashing-tools)
   #:use-module (gnu packages libftdi)
   #:use-module (gnu packages pciutils)
   #:use-module (gnu packages qt)
-  #:use-module (gnu packages tls))
+  #:use-module (gnu packages tls)
+  #:use-module (srfi srfi-26))
 
 (define-public flashrom
   (package
@@ -254,6 +257,44 @@ (define-public teensy-loader-cli
     (home-page "https://www.pjrc.com/teensy/loader_cli.html")
     (license license:gpl3+)))
 
+(define-public teensy-udev-rules
+  (package
+    (name "teensy-udev-rules")
+    (version "2023-09-13")      ;no version whatsoever -- use the current date
+    (source (origin
+              (method url-fetch)
+              (uri "https://www.pjrc.com/teensy/00-teensy.rules")
+              (sha256
+               (base32
+                "1yxczxvwi0s31g7lfa4v13yvvpv6gcsfs7r9mv6y4w9jc1inpx8p"))))
+    (build-system copy-build-system)
+    (arguments
+     (let ((rules-file "lib/udev/rules.d/70-teensy.rules"))
+       (list
+        #:install-plan
+        #~(list `(,#$source #$rules-file))
+        #:phases
+        #~(modify-phases %standard-phases
+            (add-after 'install 'patch-paths
+              (lambda* (#:key inputs #:allow-other-keys)
+                (substitute* (string-append #$output "/" #$rules-file)
+                  (("/bin/stty")
+                   (search-input-file inputs "bin/stty")))))))))
+    (inputs (list coreutils-minimal))
+    (home-page "https://www.pjrc.com/teensy/loader_cli.html")
+    (synopsis "udev rules for the Teensy family of micro-controllers")
+    (description "This package provides a udev rules file that allows
+unprivileged users communication with the Teensy family of micro-controllers.
+ModemManager (part of NetworkManager) can interfere with USB Serial devices,
+which includes the Teensy.  In case of problems, see the @file{.rules} file
+for possible workarounds.")
+    ;; FIXME: The file lacks an explicit license, so the license of
+    ;; teensy-cli-loader is *assumed* to hold (see:
+    ;; https://github.com/PaulStoffregen/teensy_loader_cli/issues/84).
+    (license license:gpl3+)
+    (supported-systems (filter (cut string-suffix? "-linux" <>)
+                               %supported-systems))))
+
 (define-public rkflashtool
   (let ((commit "8966c4e277de8148290554aaaa4146a3a84a3c53")
         (revision "1"))
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2023-09-26 20:31 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-26 18:59 [bug#66217] [PATCH 00/22] Add ErgoDox firmware packages Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 01/22] gnu: make-avr-toolchain: Add a #:xgcc argument Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 02/22] gnu: qmk: Style Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 03/22] gnu: qmk: Avoid propagating inputs Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 04/22] gnu: qmk: Use GCC 8 for the AVR toolchain Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 05/22] gnu: qmk: Add many missing inputs and add more commands to PATH Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 06/22] gnu: Add lufa Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 07/22] gnu: embedded: Do not use a prefix on the (gnu packages base) module Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 08/22] gnu: Add qmk-firmware-ergodox-ez-default Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 09/22] gnu: Add qmk-firmware-ergodox-ez-dvorak-42-key Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 10/22] gnu: Add qmk-udev-rules Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 11/22] gnu: Add qmk-firmware-ergodox-ez-hacker-dvorak Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 12/22] gnu: Add qmk-firmware-ergodox-ez-dvorak Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 13/22] gnu: Add qmk-firmware-ergodox-ez-dvorak-emacs Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 14/22] gnu: Add qmk-firmware-ergodox-ez-dvorak-emacs-software Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 15/22] gnu: Add ergodox-firmware-colemak-jc-mod Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 16/22] gnu: Add ergodox-firmware-colemak-symbol-mod Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 17/22] gnu: Add ergodox-firmware-dvorak-kinesis-mod Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 18/22] gnu: Add ergodox-firmware-qwerty-kinesis-mod Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 19/22] gnu: Add ergodox-firmware-workman-p-kinesis-mod Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 20/22] gnu: teensy-loader-cli: Use gexps Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 21/22] gnu: teensy-loader-cli: Fix license Maxim Cournoyer
2023-09-26 19:04 ` [bug#66217] [PATCH 22/22] gnu: Add teensy-udev-rules Maxim Cournoyer

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).