From 9fcab705a99729526e8d013d3c2181c8931b557a Mon Sep 17 00:00:00 2001 From: zvecr Date: Sun, 16 Oct 2022 20:24:37 +0100 Subject: [PATCH] Align client/docs gen with recent changes --- .../xap/client/python/constants.py.j2 | 7 +- data/templates/xap/client/python/routes.py.j2 | 3 +- data/templates/xap/client/python/types.py.j2 | 2 + data/templates/xap/docs/docs.md.j2 | 2 + data/templates/xap/docs/route_request.md.j2 | 8 -- data/templates/xap/docs/route_response.md.j2 | 8 -- data/templates/xap/docs/routes.md.j2 | 27 ++++- data/templates/xap/docs/versions.md.j2 | 6 + .../templates/xap/firmware/xap_generated.h.j2 | 4 +- .../xap/firmware/xap_generated.inl.j2 | 4 +- docs/xap_0.0.1.md | 28 ++++- docs/xap_0.1.0.md | 58 +++++++--- docs/xap_0.2.0.md | 76 ++++++++----- docs/xap_0.3.0.md | 106 +++++++++++------- docs/xap_protocol.md | 27 ++++- lib/python/qmk/cli/xap/generate_docs.py | 17 ++- lib/python/qmk/cli/xap/generate_python.py | 13 +-- lib/python/qmk/constants.py | 31 +++++ lib/python/qmk/xap/common.py | 12 +- lib/python/qmk/xap/jinja2_filters.py | 5 + lib/python/xap_client/constants.py | 1 + lib/python/xap_client/routes.py | 1 - 22 files changed, 309 insertions(+), 137 deletions(-) delete mode 100644 data/templates/xap/docs/route_request.md.j2 delete mode 100644 data/templates/xap/docs/route_response.md.j2 create mode 100644 data/templates/xap/docs/versions.md.j2 diff --git a/data/templates/xap/client/python/constants.py.j2 b/data/templates/xap/client/python/constants.py.j2 index 61c9767d970..a972890dae6 100644 --- a/data/templates/xap/client/python/constants.py.j2 +++ b/data/templates/xap/client/python/constants.py.j2 @@ -1,14 +1,17 @@ +{{ constants.GPL2_HEADER_SH_LIKE }} +{{ constants.GENERATED_HEADER_SH_LIKE }} from enum import IntEnum # version: 0.0.1 class RgblightModes(IntEnum): -{%- for id, effect in constants.rgblight.effects | dictsort %} +{%- for id, effect in specs.rgblight.effects | dictsort %} {{ effect.key }} = {{ id }} {%- endfor %} +# version: 0.0.1 class RgbMatrixModes(IntEnum): -{%- for id, effect in constants.rgb_matrix.effects | dictsort %} +{%- for id, effect in specs.rgb_matrix.effects | dictsort %} {{ effect.key }} = {{ id }} {%- endfor %} diff --git a/data/templates/xap/client/python/routes.py.j2 b/data/templates/xap/client/python/routes.py.j2 index 3cd65912e76..475ee23137d 100644 --- a/data/templates/xap/client/python/routes.py.j2 +++ b/data/templates/xap/client/python/routes.py.j2 @@ -1,4 +1,5 @@ - +{{ constants.GPL2_HEADER_SH_LIKE }} +{{ constants.GENERATED_HEADER_SH_LIKE }} class XAPRouteError(Exception): pass diff --git a/data/templates/xap/client/python/types.py.j2 b/data/templates/xap/client/python/types.py.j2 index ca9b90cdae5..0c49de3e133 100644 --- a/data/templates/xap/client/python/types.py.j2 +++ b/data/templates/xap/client/python/types.py.j2 @@ -1,3 +1,5 @@ +{{ constants.GPL2_HEADER_SH_LIKE }} +{{ constants.GENERATED_HEADER_SH_LIKE }} from collections import namedtuple from enum import IntFlag, IntEnum from struct import Struct diff --git a/data/templates/xap/docs/docs.md.j2 b/data/templates/xap/docs/docs.md.j2 index 7d6225ff7b0..a43b50b8ce6 100644 --- a/data/templates/xap/docs/docs.md.j2 +++ b/data/templates/xap/docs/docs.md.j2 @@ -1,3 +1,5 @@ +{{ constants.GPL2_HEADER_XML_LIKE }} +{{ constants.GENERATED_HEADER_XML_LIKE }} {%- for item in xap.documentation.order -%} {%- if not item[0:1] == '!' -%} {{ xap.documentation.get(item) }} diff --git a/data/templates/xap/docs/route_request.md.j2 b/data/templates/xap/docs/route_request.md.j2 deleted file mode 100644 index 8d9c1fd37db..00000000000 --- a/data/templates/xap/docs/route_request.md.j2 +++ /dev/null @@ -1,8 +0,0 @@ -{%- if route.request_type == 'struct' -%} -__Request:__ -{%- for member in route.request_struct_members -%} -
{{ " "|safe*4 }}* {{ member.name }}: `{{ member.type }}` -{%- endfor -%} -{%- elif route.request_type -%} -__Request:__ `{{ route.request_type }}` -{%- endif -%} \ No newline at end of file diff --git a/data/templates/xap/docs/route_response.md.j2 b/data/templates/xap/docs/route_response.md.j2 deleted file mode 100644 index 64f4e065e08..00000000000 --- a/data/templates/xap/docs/route_response.md.j2 +++ /dev/null @@ -1,8 +0,0 @@ -{%- if route.return_type == 'struct' -%} -__Response:__ -{%- for member in route.return_struct_members -%} -
{{ " "|safe*4 }}* {{ member.name }}: `{{ member.type }}` -{%- endfor -%} -{%- elif route.return_type -%} -__Response:__ `{{ route.return_type }}` -{%- endif -%} \ No newline at end of file diff --git a/data/templates/xap/docs/routes.md.j2 b/data/templates/xap/docs/routes.md.j2 index 4c6edee210f..92afcad20ba 100644 --- a/data/templates/xap/docs/routes.md.j2 +++ b/data/templates/xap/docs/routes.md.j2 @@ -1,3 +1,22 @@ +{%- macro gen_payload(name, type, members) -%} +{%- if type == 'struct' -%} +__{{ name }}:__ +{%- for member in members -%} +
{{ " "|safe*4 }}* {{ member.name }}: `{{ member.type }}` +{%- endfor -%} +{%- elif type -%} +__{{ name }}:__ `{{ type }}` +{%- endif -%} +{%- endmacro -%} + +{%- macro gen_payloads(route) -%} +{{ gen_payload('Request', route.request_type, route.request_struct_members) }}{%- if route.return_type and route.request_type -%}

{% endif %}{{ gen_payload('Response', route.return_type, route.return_struct_members) }} +{%- endmacro -%} + +{%- macro gen_tags(route) -%} +{% if 'secure' == route.permissions %}__Secure__{% endif %} +{%- endmacro -%} + {%- for id, route in xap.routes | dictsort %} ### {{ route.name }} - `{{ id }}` {{ route.description }} @@ -7,9 +26,7 @@ | -- | -- | -- | -- | -- | {%- for subid, subroute in route.routes | dictsort %} {%- if not subroute.routes %} -{%- with route=subroute %} -| {{ subroute.name }} | `{{ id }} {{ subid }}` | {% if 'secure' == subroute.permissions %}__Secure__{% endif %} | {%- include 'route_request.md.j2' -%}{%- if subroute.return_type and subroute.request_type -%}

{% endif %}{%- include 'route_response.md.j2' -%} | {{ subroute.description.replace('\n', '
') }}| -{%- endwith %} +| {{ subroute.name }} | `{{ id }} {{ subid }}` | {{ gen_tags(subroute) }} | {{ gen_payloads(subroute) }} | {{ subroute.description | newline_to_br }}| {%- endif %} {%- endfor %} @@ -23,9 +40,7 @@ | -- | -- | -- | -- | -- | {%- for subsubid, subsubroute in subroute.routes | dictsort %} {%- if not subsubroute.routes %} -{%- with route=subsubroute %} -| {{ subsubroute.name }} | `{{ id }} {{ subid }} {{ subsubid }}` | {% if 'secure' == subsubroute.permissions %}__Secure__{% endif %} | {%- include 'route_request.md.j2' -%}{%- if subsubroute.return_type and subsubroute.request_type -%}

{% endif %}{%- include 'route_response.md.j2' -%} | {{ subsubroute.description.replace('\n', '
') }}| -{%- endwith %} +| {{ subsubroute.name }} | `{{ id }} {{ subid }} {{ subsubid }}` | {{ gen_tags(subsubroute) }} | {{ gen_payloads(subsubroute) }} | {{ subsubroute.description | newline_to_br }}| {%- endif %} {%- endfor %} {%- endif %} diff --git a/data/templates/xap/docs/versions.md.j2 b/data/templates/xap/docs/versions.md.j2 new file mode 100644 index 00000000000..4d91913abe3 --- /dev/null +++ b/data/templates/xap/docs/versions.md.j2 @@ -0,0 +1,6 @@ +{{ constants.GPL2_HEADER_XML_LIKE }} +{{ constants.GENERATED_HEADER_XML_LIKE }} + +{%- for ver in versions | reverse -%} +* [XAP Version {{ ver }}](xap_{{ ver }}.md) +{% endfor %} diff --git a/data/templates/xap/firmware/xap_generated.h.j2 b/data/templates/xap/firmware/xap_generated.h.j2 index ef35bfacaa9..efb238bae3d 100755 --- a/data/templates/xap/firmware/xap_generated.h.j2 +++ b/data/templates/xap/firmware/xap_generated.h.j2 @@ -1,5 +1,5 @@ -{{ GPL2_HEADER_C_LIKE }} -{{ GENERATED_HEADER_C_LIKE }} +{{ constants.GPL2_HEADER_C_LIKE }} +{{ constants.GENERATED_HEADER_C_LIKE }} #pragma once #include diff --git a/data/templates/xap/firmware/xap_generated.inl.j2 b/data/templates/xap/firmware/xap_generated.inl.j2 index 00da36fa5dd..2f30ffcac72 100755 --- a/data/templates/xap/firmware/xap_generated.inl.j2 +++ b/data/templates/xap/firmware/xap_generated.inl.j2 @@ -1,5 +1,5 @@ -{{ GPL2_HEADER_C_LIKE }} -{{ GENERATED_HEADER_C_LIKE }} +{{ constants.GPL2_HEADER_C_LIKE }} +{{ constants.GENERATED_HEADER_C_LIKE }} //////////////////////////////////////////////////////////////////////////////// // Full XAP {{ xap.version }} definitions diff --git a/docs/xap_0.0.1.md b/docs/xap_0.0.1.md index 410a2d9d32d..d94ada81d67 100644 --- a/docs/xap_0.0.1.md +++ b/docs/xap_0.0.1.md @@ -1,3 +1,29 @@ + + + + # QMK Firmware XAP Specs This document describes the requirements of the QMK XAP ("extensible application protocol") API. @@ -80,6 +106,6 @@ This subsystem is always present, and provides the ability to query information | Name | Route | Tags | Payloads | Description | | -- | -- | -- | -- | -- | -| Version Query | `0x00 0x00` | |__Response:__ `u32`| XAP protocol version query.

* Returns the BCD-encoded version in the format of XX.YY.ZZZZ => `0xXXYYZZZZ`
* e.g. 3.2.115 will match `0x03020115`, or bytes {0x15,0x01,0x02,0x03}.| +| Version Query | `0x00 0x00` | | __Response:__ `u32` | XAP protocol version query.

* Returns the BCD-encoded version in the format of XX.YY.ZZZZ => `0xXXYYZZZZ`
* e.g. 3.2.115 will match `0x03020115`, or bytes {0x15,0x01,0x02,0x03}.| diff --git a/docs/xap_0.1.0.md b/docs/xap_0.1.0.md index de34463df2f..59bdd878d22 100644 --- a/docs/xap_0.1.0.md +++ b/docs/xap_0.1.0.md @@ -1,3 +1,29 @@ + + + + # QMK Firmware XAP Specs This document describes the requirements of the QMK XAP ("extensible application protocol") API. @@ -91,12 +117,12 @@ This subsystem is always present, and provides the ability to query information | Name | Route | Tags | Payloads | Description | | -- | -- | -- | -- | -- | -| Version Query | `0x00 0x00` | |__Response:__ `u32`| XAP protocol version query.

* Returns the BCD-encoded version in the format of XX.YY.ZZZZ => `0xXXYYZZZZ`
* e.g. 3.2.115 will match `0x03020115`, or bytes {0x15,0x01,0x02,0x03}.| -| Capabilities Query | `0x00 0x01` | |__Response:__ `u32`| XAP subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| -| Enabled subsystem query | `0x00 0x02` | |__Response:__ `u32`| XAP protocol subsystem query. Each bit should be considered as a "usable" subsystem. For example, checking `(value & (1 << XAP_ROUTE_QMK) != 0)` means the QMK subsystem is enabled and available for querying.| -| Secure Status | `0x00 0x03` | |__Response:__ `u8`| Query secure route status

* 0 means secure routes are disabled
* 1 means unlock sequence initiated but incomplete
* 2 means secure routes are allowed
* any other value should be interpreted as disabled| -| Secure Unlock | `0x00 0x04` | || Initiate secure route unlock sequence| -| Secure Lock | `0x00 0x05` | || Disable secure routes| +| Version Query | `0x00 0x00` | | __Response:__ `u32` | XAP protocol version query.

* Returns the BCD-encoded version in the format of XX.YY.ZZZZ => `0xXXYYZZZZ`
* e.g. 3.2.115 will match `0x03020115`, or bytes {0x15,0x01,0x02,0x03}.| +| Capabilities Query | `0x00 0x01` | | __Response:__ `u32` | XAP subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| +| Enabled subsystem query | `0x00 0x02` | | __Response:__ `u32` | XAP protocol subsystem query. Each bit should be considered as a "usable" subsystem. For example, checking `(value & (1 << XAP_ROUTE_QMK) != 0)` means the QMK subsystem is enabled and available for querying.| +| Secure Status | `0x00 0x03` | | __Response:__ `u8` | Query secure route status

* 0 means secure routes are disabled
* 1 means unlock sequence initiated but incomplete
* 2 means secure routes are allowed
* any other value should be interpreted as disabled| +| Secure Unlock | `0x00 0x04` | | | Initiate secure route unlock sequence| +| Secure Lock | `0x00 0x05` | | | Disable secure routes| ### QMK - `0x01` This subsystem is always present, and provides the ability to address QMK-specific functionality. @@ -104,16 +130,16 @@ This subsystem is always present, and provides the ability to address QMK-specif | Name | Route | Tags | Payloads | Description | | -- | -- | -- | -- | -- | -| Version Query | `0x01 0x00` | |__Response:__ `u32`| QMK protocol version query.

* Returns the BCD-encoded version in the format of XX.YY.ZZZZ => `0xXXYYZZZZ`
* e.g. 3.2.115 will match `0x03020115`, or bytes {0x15,0x01,0x02,0x03}.| -| Capabilities Query | `0x01 0x01` | |__Response:__ `u32`| QMK subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| -| Board identifiers | `0x01 0x02` | |__Response:__
    * Vendor ID: `u16`
    * Product ID: `u16`
    * Product Version: `u16`
    * QMK Unique Identifier: `u32`| Retrieves the set of identifying information for the board.| -| Board Manufacturer | `0x01 0x03` | |__Response:__ `string`| Retrieves the name of the manufacturer| -| Product Name | `0x01 0x04` | |__Response:__ `string`| Retrieves the product name| -| Config Blob Length | `0x01 0x05` | |__Response:__ `u16`| Retrieves the length of the configuration data bundled within the firmware| -| Config Blob Chunk | `0x01 0x06` | |__Request:__ `u16`

__Response:__ `u8[32]`| Retrieves a chunk of the configuration data bundled within the firmware| -| Jump to bootloader | `0x01 0x07` | __Secure__ |__Response:__ `u8`| Jump to bootloader

May not be present - if QMK capabilities query returns “true”, then jump to bootloader is supported

* 0 means secure routes are disabled, and should be considered as a failure
* 1 means successful, board will jump to bootloader| -| Hardware Identifier | `0x01 0x08` | |__Response:__ `u32[4]`| Retrieves a unique identifier for the board.| -| Reinitialize EEPROM | `0x01 0x09` | __Secure__ |__Response:__ `u8`| Reinitializes the keyboard's EEPROM (persistent memory)

May not be present - if QMK capabilities query returns “true”, then reinitialize is supported

* 0 means secure routes are disabled, and should be considered as a failure
* 1 means successful, board will reinitialize and then reboot| +| Version Query | `0x01 0x00` | | __Response:__ `u32` | QMK protocol version query.

* Returns the BCD-encoded version in the format of XX.YY.ZZZZ => `0xXXYYZZZZ`
* e.g. 3.2.115 will match `0x03020115`, or bytes {0x15,0x01,0x02,0x03}.| +| Capabilities Query | `0x01 0x01` | | __Response:__ `u32` | QMK subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| +| Board identifiers | `0x01 0x02` | | __Response:__
    * Vendor ID: `u16`
    * Product ID: `u16`
    * Product Version: `u16`
    * QMK Unique Identifier: `u32` | Retrieves the set of identifying information for the board.| +| Board Manufacturer | `0x01 0x03` | | __Response:__ `string` | Retrieves the name of the manufacturer| +| Product Name | `0x01 0x04` | | __Response:__ `string` | Retrieves the product name| +| Config Blob Length | `0x01 0x05` | | __Response:__ `u16` | Retrieves the length of the configuration data bundled within the firmware| +| Config Blob Chunk | `0x01 0x06` | | __Request:__ `u16`

__Response:__ `u8[32]` | Retrieves a chunk of the configuration data bundled within the firmware| +| Jump to bootloader | `0x01 0x07` | __Secure__ | __Response:__ `u8` | Jump to bootloader

May not be present - if QMK capabilities query returns “true”, then jump to bootloader is supported

* 0 means secure routes are disabled, and should be considered as a failure
* 1 means successful, board will jump to bootloader| +| Hardware Identifier | `0x01 0x08` | | __Response:__ `u32[4]` | Retrieves a unique identifier for the board.| +| Reinitialize EEPROM | `0x01 0x09` | __Secure__ | __Response:__ `u8` | Reinitializes the keyboard's EEPROM (persistent memory)

May not be present - if QMK capabilities query returns “true”, then reinitialize is supported

* 0 means secure routes are disabled, and should be considered as a failure
* 1 means successful, board will reinitialize and then reboot| ### Keyboard - `0x02` This subsystem is always present, and reserved for vendor-specific functionality. No routes are defined by XAP. diff --git a/docs/xap_0.2.0.md b/docs/xap_0.2.0.md index cfdece98917..4e640c68a66 100644 --- a/docs/xap_0.2.0.md +++ b/docs/xap_0.2.0.md @@ -1,3 +1,29 @@ + + + + # QMK Firmware XAP Specs This document describes the requirements of the QMK XAP ("extensible application protocol") API. @@ -91,12 +117,12 @@ This subsystem is always present, and provides the ability to query information | Name | Route | Tags | Payloads | Description | | -- | -- | -- | -- | -- | -| Version Query | `0x00 0x00` | |__Response:__ `u32`| XAP protocol version query.

* Returns the BCD-encoded version in the format of XX.YY.ZZZZ => `0xXXYYZZZZ`
* e.g. 3.2.115 will match `0x03020115`, or bytes {0x15,0x01,0x02,0x03}.| -| Capabilities Query | `0x00 0x01` | |__Response:__ `u32`| XAP subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| -| Enabled subsystem query | `0x00 0x02` | |__Response:__ `u32`| XAP protocol subsystem query. Each bit should be considered as a "usable" subsystem. For example, checking `(value & (1 << XAP_ROUTE_QMK) != 0)` means the QMK subsystem is enabled and available for querying.| -| Secure Status | `0x00 0x03` | |__Response:__ `u8`| Query secure route status

* 0 means secure routes are disabled
* 1 means unlock sequence initiated but incomplete
* 2 means secure routes are allowed
* any other value should be interpreted as disabled| -| Secure Unlock | `0x00 0x04` | || Initiate secure route unlock sequence| -| Secure Lock | `0x00 0x05` | || Disable secure routes| +| Version Query | `0x00 0x00` | | __Response:__ `u32` | XAP protocol version query.

* Returns the BCD-encoded version in the format of XX.YY.ZZZZ => `0xXXYYZZZZ`
* e.g. 3.2.115 will match `0x03020115`, or bytes {0x15,0x01,0x02,0x03}.| +| Capabilities Query | `0x00 0x01` | | __Response:__ `u32` | XAP subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| +| Enabled subsystem query | `0x00 0x02` | | __Response:__ `u32` | XAP protocol subsystem query. Each bit should be considered as a "usable" subsystem. For example, checking `(value & (1 << XAP_ROUTE_QMK) != 0)` means the QMK subsystem is enabled and available for querying.| +| Secure Status | `0x00 0x03` | | __Response:__ `u8` | Query secure route status

* 0 means secure routes are disabled
* 1 means unlock sequence initiated but incomplete
* 2 means secure routes are allowed
* any other value should be interpreted as disabled| +| Secure Unlock | `0x00 0x04` | | | Initiate secure route unlock sequence| +| Secure Lock | `0x00 0x05` | | | Disable secure routes| ### QMK - `0x01` This subsystem is always present, and provides the ability to address QMK-specific functionality. @@ -104,16 +130,16 @@ This subsystem is always present, and provides the ability to address QMK-specif | Name | Route | Tags | Payloads | Description | | -- | -- | -- | -- | -- | -| Version Query | `0x01 0x00` | |__Response:__ `u32`| QMK protocol version query.

* Returns the BCD-encoded version in the format of XX.YY.ZZZZ => `0xXXYYZZZZ`
* e.g. 3.2.115 will match `0x03020115`, or bytes {0x15,0x01,0x02,0x03}.| -| Capabilities Query | `0x01 0x01` | |__Response:__ `u32`| QMK subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| -| Board identifiers | `0x01 0x02` | |__Response:__
    * Vendor ID: `u16`
    * Product ID: `u16`
    * Product Version: `u16`
    * QMK Unique Identifier: `u32`| Retrieves the set of identifying information for the board.| -| Board Manufacturer | `0x01 0x03` | |__Response:__ `string`| Retrieves the name of the manufacturer| -| Product Name | `0x01 0x04` | |__Response:__ `string`| Retrieves the product name| -| Config Blob Length | `0x01 0x05` | |__Response:__ `u16`| Retrieves the length of the configuration data bundled within the firmware| -| Config Blob Chunk | `0x01 0x06` | |__Request:__ `u16`

__Response:__ `u8[32]`| Retrieves a chunk of the configuration data bundled within the firmware| -| Jump to bootloader | `0x01 0x07` | __Secure__ |__Response:__ `u8`| Jump to bootloader

May not be present - if QMK capabilities query returns “true”, then jump to bootloader is supported

* 0 means secure routes are disabled, and should be considered as a failure
* 1 means successful, board will jump to bootloader| -| Hardware Identifier | `0x01 0x08` | |__Response:__ `u32[4]`| Retrieves a unique identifier for the board.| -| Reinitialize EEPROM | `0x01 0x09` | __Secure__ |__Response:__ `u8`| Reinitializes the keyboard's EEPROM (persistent memory)

May not be present - if QMK capabilities query returns “true”, then reinitialize is supported

* 0 means secure routes are disabled, and should be considered as a failure
* 1 means successful, board will reinitialize and then reboot| +| Version Query | `0x01 0x00` | | __Response:__ `u32` | QMK protocol version query.

* Returns the BCD-encoded version in the format of XX.YY.ZZZZ => `0xXXYYZZZZ`
* e.g. 3.2.115 will match `0x03020115`, or bytes {0x15,0x01,0x02,0x03}.| +| Capabilities Query | `0x01 0x01` | | __Response:__ `u32` | QMK subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| +| Board identifiers | `0x01 0x02` | | __Response:__
    * Vendor ID: `u16`
    * Product ID: `u16`
    * Product Version: `u16`
    * QMK Unique Identifier: `u32` | Retrieves the set of identifying information for the board.| +| Board Manufacturer | `0x01 0x03` | | __Response:__ `string` | Retrieves the name of the manufacturer| +| Product Name | `0x01 0x04` | | __Response:__ `string` | Retrieves the product name| +| Config Blob Length | `0x01 0x05` | | __Response:__ `u16` | Retrieves the length of the configuration data bundled within the firmware| +| Config Blob Chunk | `0x01 0x06` | | __Request:__ `u16`

__Response:__ `u8[32]` | Retrieves a chunk of the configuration data bundled within the firmware| +| Jump to bootloader | `0x01 0x07` | __Secure__ | __Response:__ `u8` | Jump to bootloader

May not be present - if QMK capabilities query returns “true”, then jump to bootloader is supported

* 0 means secure routes are disabled, and should be considered as a failure
* 1 means successful, board will jump to bootloader| +| Hardware Identifier | `0x01 0x08` | | __Response:__ `u32[4]` | Retrieves a unique identifier for the board.| +| Reinitialize EEPROM | `0x01 0x09` | __Secure__ | __Response:__ `u8` | Reinitializes the keyboard's EEPROM (persistent memory)

May not be present - if QMK capabilities query returns “true”, then reinitialize is supported

* 0 means secure routes are disabled, and should be considered as a failure
* 1 means successful, board will reinitialize and then reboot| ### Keyboard - `0x02` This subsystem is always present, and reserved for vendor-specific functionality. No routes are defined by XAP. @@ -129,10 +155,10 @@ This subsystem allows for query of currently configured keycodes. | Name | Route | Tags | Payloads | Description | | -- | -- | -- | -- | -- | -| Capabilities Query | `0x04 0x01` | |__Response:__ `u32`| Keymap subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| -| Get Layer Count | `0x04 0x02` | |__Response:__ `u8`| Query maximum number of layers that can be addressed within the keymap.| -| Get Keycode | `0x04 0x03` | |__Request:__
    * Layer: `u8`
    * Row: `u8`
    * Column: `u8`

__Response:__ `u16`| Query the Keycode at the requested location.| -| Get Encoder Keycode | `0x04 0x04` | |__Request:__
    * Layer: `u8`
    * Encoder: `u8`
    * Clockwise: `u8`

__Response:__ `u16`| Query the Keycode at the requested location.| +| Capabilities Query | `0x04 0x01` | | __Response:__ `u32` | Keymap subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| +| Get Layer Count | `0x04 0x02` | | __Response:__ `u8` | Query maximum number of layers that can be addressed within the keymap.| +| Get Keycode | `0x04 0x03` | | __Request:__
    * Layer: `u8`
    * Row: `u8`
    * Column: `u8`

__Response:__ `u16` | Query the Keycode at the requested location.| +| Get Encoder Keycode | `0x04 0x04` | | __Request:__
    * Layer: `u8`
    * Encoder: `u8`
    * Clockwise: `u8`

__Response:__ `u16` | Query the Keycode at the requested location.| ### Remapping - `0x05` This subsystem allows for live reassignment of keycodes without rebuilding the firmware. @@ -140,10 +166,10 @@ This subsystem allows for live reassignment of keycodes without rebuilding the f | Name | Route | Tags | Payloads | Description | | -- | -- | -- | -- | -- | -| Capabilities Query | `0x05 0x01` | |__Response:__ `u32`| Remapping subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| -| Get Layer Count | `0x05 0x02` | |__Response:__ `u8`| Query maximum number of layers that can be addressed within the keymap.| -| Set Keycode | `0x05 0x03` | __Secure__ |__Request:__
    * Layer: `u8`
    * Row: `u8`
    * Column: `u8`
    * Keycode: `u16`| Modify the Keycode at the requested location.| -| Set Encoder Keycode | `0x05 0x04` | __Secure__ |__Request:__
    * Layer: `u8`
    * Encoder: `u8`
    * Clockwise: `u8`
    * Keycode: `u16`| Modify the Keycode at the requested location.| +| Capabilities Query | `0x05 0x01` | | __Response:__ `u32` | Remapping subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| +| Get Layer Count | `0x05 0x02` | | __Response:__ `u8` | Query maximum number of layers that can be addressed within the keymap.| +| Set Keycode | `0x05 0x03` | __Secure__ | __Request:__
    * Layer: `u8`
    * Row: `u8`
    * Column: `u8`
    * Keycode: `u16` | Modify the Keycode at the requested location.| +| Set Encoder Keycode | `0x05 0x04` | __Secure__ | __Request:__
    * Layer: `u8`
    * Encoder: `u8`
    * Clockwise: `u8`
    * Keycode: `u16` | Modify the Keycode at the requested location.| ### Lighting - `0x06` This subsystem allows for control over the lighting subsystem. @@ -151,7 +177,7 @@ This subsystem allows for control over the lighting subsystem. | Name | Route | Tags | Payloads | Description | | -- | -- | -- | -- | -- | -| Capabilities Query | `0x06 0x01` | |__Response:__ `u32`| Lighting subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| +| Capabilities Query | `0x06 0x01` | | __Response:__ `u32` | Lighting subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| ## Broadcast messages diff --git a/docs/xap_0.3.0.md b/docs/xap_0.3.0.md index 8cc05485916..75dbf0e1767 100644 --- a/docs/xap_0.3.0.md +++ b/docs/xap_0.3.0.md @@ -1,3 +1,29 @@ + + + + # QMK Firmware XAP Specs This document describes the requirements of the QMK XAP ("extensible application protocol") API. @@ -91,12 +117,12 @@ This subsystem is always present, and provides the ability to query information | Name | Route | Tags | Payloads | Description | | -- | -- | -- | -- | -- | -| Version Query | `0x00 0x00` | |__Response:__ `u32`| XAP protocol version query.

* Returns the BCD-encoded version in the format of XX.YY.ZZZZ => `0xXXYYZZZZ`
* e.g. 3.2.115 will match `0x03020115`, or bytes {0x15,0x01,0x02,0x03}.| -| Capabilities Query | `0x00 0x01` | |__Response:__ `u32`| XAP subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| -| Enabled subsystem query | `0x00 0x02` | |__Response:__ `u32`| XAP protocol subsystem query. Each bit should be considered as a "usable" subsystem. For example, checking `(value & (1 << XAP_ROUTE_QMK) != 0)` means the QMK subsystem is enabled and available for querying.| -| Secure Status | `0x00 0x03` | |__Response:__ `u8`| Query secure route status

* 0 means secure routes are disabled
* 1 means unlock sequence initiated but incomplete
* 2 means secure routes are allowed
* any other value should be interpreted as disabled| -| Secure Unlock | `0x00 0x04` | || Initiate secure route unlock sequence| -| Secure Lock | `0x00 0x05` | || Disable secure routes| +| Version Query | `0x00 0x00` | | __Response:__ `u32` | XAP protocol version query.

* Returns the BCD-encoded version in the format of XX.YY.ZZZZ => `0xXXYYZZZZ`
* e.g. 3.2.115 will match `0x03020115`, or bytes {0x15,0x01,0x02,0x03}.| +| Capabilities Query | `0x00 0x01` | | __Response:__ `u32` | XAP subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| +| Enabled subsystem query | `0x00 0x02` | | __Response:__ `u32` | XAP protocol subsystem query. Each bit should be considered as a "usable" subsystem. For example, checking `(value & (1 << XAP_ROUTE_QMK) != 0)` means the QMK subsystem is enabled and available for querying.| +| Secure Status | `0x00 0x03` | | __Response:__ `u8` | Query secure route status

* 0 means secure routes are disabled
* 1 means unlock sequence initiated but incomplete
* 2 means secure routes are allowed
* any other value should be interpreted as disabled| +| Secure Unlock | `0x00 0x04` | | | Initiate secure route unlock sequence| +| Secure Lock | `0x00 0x05` | | | Disable secure routes| ### QMK - `0x01` This subsystem is always present, and provides the ability to address QMK-specific functionality. @@ -104,16 +130,16 @@ This subsystem is always present, and provides the ability to address QMK-specif | Name | Route | Tags | Payloads | Description | | -- | -- | -- | -- | -- | -| Version Query | `0x01 0x00` | |__Response:__ `u32`| QMK protocol version query.

* Returns the BCD-encoded version in the format of XX.YY.ZZZZ => `0xXXYYZZZZ`
* e.g. 3.2.115 will match `0x03020115`, or bytes {0x15,0x01,0x02,0x03}.| -| Capabilities Query | `0x01 0x01` | |__Response:__ `u32`| QMK subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| -| Board identifiers | `0x01 0x02` | |__Response:__
    * Vendor ID: `u16`
    * Product ID: `u16`
    * Product Version: `u16`
    * QMK Unique Identifier: `u32`| Retrieves the set of identifying information for the board.| -| Board Manufacturer | `0x01 0x03` | |__Response:__ `string`| Retrieves the name of the manufacturer| -| Product Name | `0x01 0x04` | |__Response:__ `string`| Retrieves the product name| -| Config Blob Length | `0x01 0x05` | |__Response:__ `u16`| Retrieves the length of the configuration data bundled within the firmware| -| Config Blob Chunk | `0x01 0x06` | |__Request:__ `u16`

__Response:__ `u8[32]`| Retrieves a chunk of the configuration data bundled within the firmware| -| Jump to bootloader | `0x01 0x07` | __Secure__ |__Response:__ `u8`| Jump to bootloader

May not be present - if QMK capabilities query returns “true”, then jump to bootloader is supported

* 0 means secure routes are disabled, and should be considered as a failure
* 1 means successful, board will jump to bootloader| -| Hardware Identifier | `0x01 0x08` | |__Response:__ `u32[4]`| Retrieves a unique identifier for the board.| -| Reinitialize EEPROM | `0x01 0x09` | __Secure__ |__Response:__ `u8`| Reinitializes the keyboard's EEPROM (persistent memory)

May not be present - if QMK capabilities query returns “true”, then reinitialize is supported

* 0 means secure routes are disabled, and should be considered as a failure
* 1 means successful, board will reinitialize and then reboot| +| Version Query | `0x01 0x00` | | __Response:__ `u32` | QMK protocol version query.

* Returns the BCD-encoded version in the format of XX.YY.ZZZZ => `0xXXYYZZZZ`
* e.g. 3.2.115 will match `0x03020115`, or bytes {0x15,0x01,0x02,0x03}.| +| Capabilities Query | `0x01 0x01` | | __Response:__ `u32` | QMK subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| +| Board identifiers | `0x01 0x02` | | __Response:__
    * Vendor ID: `u16`
    * Product ID: `u16`
    * Product Version: `u16`
    * QMK Unique Identifier: `u32` | Retrieves the set of identifying information for the board.| +| Board Manufacturer | `0x01 0x03` | | __Response:__ `string` | Retrieves the name of the manufacturer| +| Product Name | `0x01 0x04` | | __Response:__ `string` | Retrieves the product name| +| Config Blob Length | `0x01 0x05` | | __Response:__ `u16` | Retrieves the length of the configuration data bundled within the firmware| +| Config Blob Chunk | `0x01 0x06` | | __Request:__ `u16`

__Response:__ `u8[32]` | Retrieves a chunk of the configuration data bundled within the firmware| +| Jump to bootloader | `0x01 0x07` | __Secure__ | __Response:__ `u8` | Jump to bootloader

May not be present - if QMK capabilities query returns “true”, then jump to bootloader is supported

* 0 means secure routes are disabled, and should be considered as a failure
* 1 means successful, board will jump to bootloader| +| Hardware Identifier | `0x01 0x08` | | __Response:__ `u32[4]` | Retrieves a unique identifier for the board.| +| Reinitialize EEPROM | `0x01 0x09` | __Secure__ | __Response:__ `u8` | Reinitializes the keyboard's EEPROM (persistent memory)

May not be present - if QMK capabilities query returns “true”, then reinitialize is supported

* 0 means secure routes are disabled, and should be considered as a failure
* 1 means successful, board will reinitialize and then reboot| ### Keyboard - `0x02` This subsystem is always present, and reserved for vendor-specific functionality. No routes are defined by XAP. @@ -129,10 +155,10 @@ This subsystem allows for query of currently configured keycodes. | Name | Route | Tags | Payloads | Description | | -- | -- | -- | -- | -- | -| Capabilities Query | `0x04 0x01` | |__Response:__ `u32`| Keymap subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| -| Get Layer Count | `0x04 0x02` | |__Response:__ `u8`| Query maximum number of layers that can be addressed within the keymap.| -| Get Keycode | `0x04 0x03` | |__Request:__
    * Layer: `u8`
    * Row: `u8`
    * Column: `u8`

__Response:__ `u16`| Query the Keycode at the requested location.| -| Get Encoder Keycode | `0x04 0x04` | |__Request:__
    * Layer: `u8`
    * Encoder: `u8`
    * Clockwise: `u8`

__Response:__ `u16`| Query the Keycode at the requested location.| +| Capabilities Query | `0x04 0x01` | | __Response:__ `u32` | Keymap subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| +| Get Layer Count | `0x04 0x02` | | __Response:__ `u8` | Query maximum number of layers that can be addressed within the keymap.| +| Get Keycode | `0x04 0x03` | | __Request:__
    * Layer: `u8`
    * Row: `u8`
    * Column: `u8`

__Response:__ `u16` | Query the Keycode at the requested location.| +| Get Encoder Keycode | `0x04 0x04` | | __Request:__
    * Layer: `u8`
    * Encoder: `u8`
    * Clockwise: `u8`

__Response:__ `u16` | Query the Keycode at the requested location.| ### Remapping - `0x05` This subsystem allows for live reassignment of keycodes without rebuilding the firmware. @@ -140,10 +166,10 @@ This subsystem allows for live reassignment of keycodes without rebuilding the f | Name | Route | Tags | Payloads | Description | | -- | -- | -- | -- | -- | -| Capabilities Query | `0x05 0x01` | |__Response:__ `u32`| Remapping subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| -| Get Layer Count | `0x05 0x02` | |__Response:__ `u8`| Query maximum number of layers that can be addressed within the keymap.| -| Set Keycode | `0x05 0x03` | __Secure__ |__Request:__
    * Layer: `u8`
    * Row: `u8`
    * Column: `u8`
    * Keycode: `u16`| Modify the Keycode at the requested location.| -| Set Encoder Keycode | `0x05 0x04` | __Secure__ |__Request:__
    * Layer: `u8`
    * Encoder: `u8`
    * Clockwise: `u8`
    * Keycode: `u16`| Modify the Keycode at the requested location.| +| Capabilities Query | `0x05 0x01` | | __Response:__ `u32` | Remapping subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| +| Get Layer Count | `0x05 0x02` | | __Response:__ `u8` | Query maximum number of layers that can be addressed within the keymap.| +| Set Keycode | `0x05 0x03` | __Secure__ | __Request:__
    * Layer: `u8`
    * Row: `u8`
    * Column: `u8`
    * Keycode: `u16` | Modify the Keycode at the requested location.| +| Set Encoder Keycode | `0x05 0x04` | __Secure__ | __Request:__
    * Layer: `u8`
    * Encoder: `u8`
    * Clockwise: `u8`
    * Keycode: `u16` | Modify the Keycode at the requested location.| ### Lighting - `0x06` This subsystem allows for control over the lighting subsystem. @@ -151,40 +177,40 @@ This subsystem allows for control over the lighting subsystem. | Name | Route | Tags | Payloads | Description | | -- | -- | -- | -- | -- | -| Capabilities Query | `0x06 0x01` | |__Response:__ `u32`| Lighting subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| +| Capabilities Query | `0x06 0x01` | | __Response:__ `u32` | Lighting subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| #### backlight - `0x06 0x02` This subsystem allows for control over the backlight subsystem. | Name | Route | Tags | Payloads | Description | | -- | -- | -- | -- | -- | -| Capabilities Query | `0x06 0x02 0x01` | |__Response:__ `u32`| backlight subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| -| Get Enabled Effects | `0x06 0x02 0x02` | |__Response:__ `u8`| Each bit should be considered as a "usable" effect id| -| Get Config | `0x06 0x02 0x03` | |__Response:__
    * enable: `u8`
    * mode: `u8`
    * val: `u8`| Query the current config.| -| Set Config | `0x06 0x02 0x04` | |__Request:__
    * enable: `u8`
    * mode: `u8`
    * val: `u8`| Set the current config.| -| Save Config | `0x06 0x02 0x05` | || Save the current config.| +| Capabilities Query | `0x06 0x02 0x01` | | __Response:__ `u32` | backlight subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| +| Get Enabled Effects | `0x06 0x02 0x02` | | __Response:__ `u8` | Each bit should be considered as a "usable" effect id| +| Get Config | `0x06 0x02 0x03` | | __Response:__
    * enable: `u8`
    * mode: `u8`
    * val: `u8` | Query the current config.| +| Set Config | `0x06 0x02 0x04` | | __Request:__
    * enable: `u8`
    * mode: `u8`
    * val: `u8` | Set the current config.| +| Save Config | `0x06 0x02 0x05` | | | Save the current config.| #### rgblight - `0x06 0x03` This subsystem allows for control over the rgblight subsystem. | Name | Route | Tags | Payloads | Description | | -- | -- | -- | -- | -- | -| Capabilities Query | `0x06 0x03 0x01` | |__Response:__ `u32`| rgblight subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| -| Get Enabled Effects | `0x06 0x03 0x02` | |__Response:__ `u64`| Each bit should be considered as a "usable" effect id| -| Get Config | `0x06 0x03 0x03` | |__Response:__
    * enable: `u8`
    * mode: `u8`
    * hue: `u8`
    * sat: `u8`
    * val: `u8`
    * speed: `u8`| Query the current config.| -| Set Config | `0x06 0x03 0x04` | |__Request:__
    * enable: `u8`
    * mode: `u8`
    * hue: `u8`
    * sat: `u8`
    * val: `u8`
    * speed: `u8`| Set the current config.| -| Save Config | `0x06 0x03 0x05` | || Save the current config.| +| Capabilities Query | `0x06 0x03 0x01` | | __Response:__ `u32` | rgblight subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| +| Get Enabled Effects | `0x06 0x03 0x02` | | __Response:__ `u64` | Each bit should be considered as a "usable" effect id| +| Get Config | `0x06 0x03 0x03` | | __Response:__
    * enable: `u8`
    * mode: `u8`
    * hue: `u8`
    * sat: `u8`
    * val: `u8`
    * speed: `u8` | Query the current config.| +| Set Config | `0x06 0x03 0x04` | | __Request:__
    * enable: `u8`
    * mode: `u8`
    * hue: `u8`
    * sat: `u8`
    * val: `u8`
    * speed: `u8` | Set the current config.| +| Save Config | `0x06 0x03 0x05` | | | Save the current config.| #### rgbmatrix - `0x06 0x04` This subsystem allows for control over the rgb matrix subsystem. | Name | Route | Tags | Payloads | Description | | -- | -- | -- | -- | -- | -| Capabilities Query | `0x06 0x04 0x01` | |__Response:__ `u32`| rgb matrix subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| -| Get Enabled Effects | `0x06 0x04 0x02` | |__Response:__ `u64`| Each bit should be considered as a "usable" effect id| -| Get Config | `0x06 0x04 0x03` | |__Response:__
    * enable: `u8`
    * mode: `u8`
    * hue: `u8`
    * sat: `u8`
    * val: `u8`
    * speed: `u8`
    * flags: `u8`| Query the current config.| -| Set Config | `0x06 0x04 0x04` | |__Request:__
    * enable: `u8`
    * mode: `u8`
    * hue: `u8`
    * sat: `u8`
    * val: `u8`
    * speed: `u8`
    * flags: `u8`| Set the current config.| -| Save Config | `0x06 0x04 0x05` | || Save the current config.| +| Capabilities Query | `0x06 0x04 0x01` | | __Response:__ `u32` | rgb matrix subsystem capabilities query. Each bit should be considered as a "usable" route within this subsystem.| +| Get Enabled Effects | `0x06 0x04 0x02` | | __Response:__ `u64` | Each bit should be considered as a "usable" effect id| +| Get Config | `0x06 0x04 0x03` | | __Response:__
    * enable: `u8`
    * mode: `u8`
    * hue: `u8`
    * sat: `u8`
    * val: `u8`
    * speed: `u8`
    * flags: `u8` | Query the current config.| +| Set Config | `0x06 0x04 0x04` | | __Request:__
    * enable: `u8`
    * mode: `u8`
    * hue: `u8`
    * sat: `u8`
    * val: `u8`
    * speed: `u8`
    * flags: `u8` | Set the current config.| +| Save Config | `0x06 0x04 0x05` | | | Save the current config.| ## Broadcast messages diff --git a/docs/xap_protocol.md b/docs/xap_protocol.md index f70f605bb5b..17638ff01cd 100644 --- a/docs/xap_protocol.md +++ b/docs/xap_protocol.md @@ -1,4 +1,29 @@ - + + + + * [XAP Version 0.3.0](xap_0.3.0.md) * [XAP Version 0.2.0](xap_0.2.0.md) * [XAP Version 0.1.0](xap_0.1.0.md) diff --git a/lib/python/qmk/cli/xap/generate_docs.py b/lib/python/qmk/cli/xap/generate_docs.py index ae1c9907b4a..38fb9d2c270 100755 --- a/lib/python/qmk/cli/xap/generate_docs.py +++ b/lib/python/qmk/cli/xap/generate_docs.py @@ -1,16 +1,18 @@ """This script generates the XAP protocol documentation. """ import hjson + +from milc import cli + from qmk.constants import QMK_FIRMWARE from qmk.xap.common import get_xap_definition_files, update_xap_definitions, render_xap_output -from milc import cli @cli.subcommand('Generates the XAP protocol documentation.', hidden=False if cli.config.user.developer else True) def xap_generate_docs(cli): """Generates the XAP protocol documentation by merging the definitions files, and producing the corresponding Markdown document under `/docs/`. """ - docs_list = [] + versions = [] overall = None for file in get_xap_definition_files(): @@ -22,17 +24,12 @@ def xap_generate_docs(cli): overall['response_flags']['bits'][str(n)] = {'name': '', 'description': '', 'define': '-'} output_doc = QMK_FIRMWARE / "docs" / f"{file.stem}.md" - docs_list.append(output_doc) + versions.append(overall['version']) output = render_xap_output('docs', 'docs.md.j2', overall) with open(output_doc, "w", encoding='utf-8') as out_file: out_file.write(output) output_doc = QMK_FIRMWARE / "docs" / "xap_protocol.md" + output = render_xap_output('docs', 'versions.md.j2', overall, versions=versions) with open(output_doc, "w", encoding='utf-8') as out_file: - out_file.write('''\ - -''') - - for file in reversed(sorted(docs_list)): - ver = file.stem[4:] - out_file.write(f'* [XAP Version {ver}]({file.name})\n') + out_file.write(output) diff --git a/lib/python/qmk/cli/xap/generate_python.py b/lib/python/qmk/cli/xap/generate_python.py index cd7573cca10..23fb7a81046 100644 --- a/lib/python/qmk/cli/xap/generate_python.py +++ b/lib/python/qmk/cli/xap/generate_python.py @@ -1,12 +1,11 @@ """This script generates the python XAP client. """ -from qmk.constants import QMK_FIRMWARE, GPL2_HEADER_SH_LIKE, GENERATED_HEADER_SH_LIKE - -from qmk.xap.common import latest_xap_defs, render_xap_output -from qmk.commands import dump_lines - from milc import cli +from qmk.commands import dump_lines +from qmk.constants import QMK_FIRMWARE +from qmk.xap.common import latest_xap_defs, render_xap_output + @cli.subcommand('Generates the python XAP client.', hidden=False if cli.config.user.developer else True) def xap_generate_python(cli): @@ -14,9 +13,7 @@ def xap_generate_python(cli): parent = QMK_FIRMWARE / 'lib' / 'python' / 'xap_client' for name in ['types.py', 'routes.py', 'constants.py']: - lines = [GPL2_HEADER_SH_LIKE, GENERATED_HEADER_SH_LIKE] - output = render_xap_output('client/python', f'{name}.j2', defs) - lines += output.split('\n') + lines = output.split('\n') dump_lines(parent / name, lines) diff --git a/lib/python/qmk/constants.py b/lib/python/qmk/constants.py index 8a13029a8a8..191e6906f33 100644 --- a/lib/python/qmk/constants.py +++ b/lib/python/qmk/constants.py @@ -136,6 +136,11 @@ GPL2_HEADER_SH_LIKE = f'''\ # SPDX-License-Identifier: GPL-2.0-or-later ''' +GPL2_HEADER_XML_LIKE = f'''\ + + +''' + GENERATED_HEADER_C_LIKE = '''\ /******************************************************************************* 88888888888 888 d8b .d888 d8b 888 d8b @@ -186,3 +191,29 @@ GENERATED_HEADER_SH_LIKE = '''\ # ################################################################################ ''' + +GENERATED_HEADER_XML_LIKE = '''\ + +''' diff --git a/lib/python/qmk/xap/common.py b/lib/python/qmk/xap/common.py index b964685e29c..fcbb4be4300 100755 --- a/lib/python/qmk/xap/common.py +++ b/lib/python/qmk/xap/common.py @@ -8,7 +8,7 @@ from pathlib import Path from typing import OrderedDict from jinja2 import Environment, FileSystemLoader, select_autoescape -from qmk.constants import QMK_FIRMWARE, GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE +import qmk.constants from qmk.git import git_get_version from qmk.json_schema import json_load, validate from qmk.decorators import lru_cache @@ -53,7 +53,7 @@ def load_lighting_spec(feature, version='latest'): def _get_jinja2_env(data_templates_xap_subdir: str): - templates_dir = os.path.join(QMK_FIRMWARE, 'data', 'templates', 'xap', data_templates_xap_subdir) + templates_dir = os.path.join(qmk.constants.QMK_FIRMWARE, 'data', 'templates', 'xap', data_templates_xap_subdir) j2 = Environment(loader=FileSystemLoader(templates_dir), autoescape=select_autoescape()) return j2 @@ -65,11 +65,11 @@ def render_xap_output(data_templates_xap_subdir, file_to_render, defs=None, **kw attach_filters(j2) - constants = {} + specs = {} for feature in ['rgblight', 'rgb_matrix', 'led_matrix']: - constants[feature] = load_lighting_spec(feature) + specs[feature] = load_lighting_spec(feature) - return j2.get_template(file_to_render).render(xap=defs, qmk_version=git_get_version(), xap_str=hjson.dumps(defs), constants=constants, GPL2_HEADER_C_LIKE=GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE=GENERATED_HEADER_C_LIKE, **kwargs) + return j2.get_template(file_to_render).render(xap=defs, qmk_version=git_get_version(), xap_str=hjson.dumps(defs), specs=specs, constants=qmk.constants, **kwargs) def _find_kb_spec(kb): @@ -130,7 +130,7 @@ def _merge_ordered_dicts(dicts): def get_xap_definition_files(): """Get the sorted list of XAP definition files, from /data/xap. """ - xap_defs = QMK_FIRMWARE / "data" / "xap" + xap_defs = qmk.constants.QMK_FIRMWARE / "data" / "xap" return list(sorted(xap_defs.glob('**/xap_*.hjson'))) diff --git a/lib/python/qmk/xap/jinja2_filters.py b/lib/python/qmk/xap/jinja2_filters.py index 625747dd481..c5b2aba55fd 100644 --- a/lib/python/qmk/xap/jinja2_filters.py +++ b/lib/python/qmk/xap/jinja2_filters.py @@ -61,8 +61,13 @@ def _triplet_to_bcd(value: str): return f'0x{int(m.group(1)):02d}{int(m.group(2)):02d}{int(m.group(3)):04d}' +def _newline_to_br(value: str): + return value.replace('\n', '
') + + def attach_filters(j2: Environment): j2.filters['to_snake'] = to_snake + j2.filters['newline_to_br'] = _newline_to_br j2.filters['triplet_to_bcd'] = _triplet_to_bcd j2.filters['fnv1a_32'] = _fnv1a_32 j2.filters['type_to_c'] = _xap_type_to_c diff --git a/lib/python/xap_client/constants.py b/lib/python/xap_client/constants.py index 09d69e69861..f78b1356964 100644 --- a/lib/python/xap_client/constants.py +++ b/lib/python/xap_client/constants.py @@ -75,6 +75,7 @@ class RgblightModes(IntEnum): TWINKLE_6 = 0x29 +# version: 0.0.1 class RgbMatrixModes(IntEnum): SOLID_COLOR = 0x00 ALPHAS_MODS = 0x01 diff --git a/lib/python/xap_client/routes.py b/lib/python/xap_client/routes.py index cace9b1591a..658c486d041 100644 --- a/lib/python/xap_client/routes.py +++ b/lib/python/xap_client/routes.py @@ -26,7 +26,6 @@ # ################################################################################ - class XAPRouteError(Exception): pass