From 53052228df2e0cbf1154878679f7f06f93ea37c7 Mon Sep 17 00:00:00 2001 From: zvecr Date: Thu, 31 Mar 2022 22:34:01 +0100 Subject: [PATCH] Add types codegen --- data/xap/xap_0.0.1.hjson | 68 +++++++++++++++---- .../qmk/xap/gen_firmware/header_generator.py | 54 ++++++++++----- 2 files changed, 94 insertions(+), 28 deletions(-) diff --git a/data/xap/xap_0.0.1.hjson b/data/xap/xap_0.0.1.hjson index 328207768e..31aa5fdafc 100755 --- a/data/xap/xap_0.0.1.hjson +++ b/data/xap/xap_0.0.1.hjson @@ -101,10 +101,6 @@ ''' A high-level area of functionality within XAP. ''' - ID: - ''' - A single octet / 8-bit byte. - ''' Route: ''' A sequence of _IDs_ describing the route to invoke a _handler_. @@ -113,24 +109,72 @@ ''' A piece of code that is executed when a specific _route_ is received. ''' - Token: - ''' - A `u16` associated with a specific request as well as its corresponding response. - ''' Response: ''' The data sent back to the host during execution of a _handler_. ''' - "Response Flags": - ''' - An `u8` containing the status of the request. - ''' Payload: ''' Any received data appended to the _route_, which gets delivered to the _handler_ when received. ''' } + types: { + identifier: { + name: ID + description: Subsystem/Route ID + type: u8 + } + + response_flags: { + name: Response Flags + description: Contains the status of the request + type: u8 + } + + token: { + name: Token + description: ID associated with a specific request as well as its corresponding response + type: u16 + } + + request_header: { + name: Request Header + description: asdf + type: struct + struct_members: [ + { + type: token + name: token + }, + { + type: u8 + name: length + } + ] + } + + response_header: { + name: Response Header + description: asdf + type: struct + struct_members: [ + { + type: token + name: token + }, + { + type: response_flags + name: flags + }, + { + type: u8 + name: length + } + ] + } + } + response_flags: { define_prefix: XAP_RESPONSE_FLAG bits: { diff --git a/lib/python/qmk/xap/gen_firmware/header_generator.py b/lib/python/qmk/xap/gen_firmware/header_generator.py index 6cc9ff8816..e8e2465e4d 100755 --- a/lib/python/qmk/xap/gen_firmware/header_generator.py +++ b/lib/python/qmk/xap/gen_firmware/header_generator.py @@ -9,6 +9,24 @@ from qmk.constants import GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE from qmk.xap.common import latest_xap_defs, route_conditions +def _get_c_type(xap_type): + if xap_type == 'bool': + return 'bool' + elif xap_type == 'u8': + return 'uint8_t' + elif xap_type == 'u16': + return 'uint16_t' + elif xap_type == 'u32': + return 'uint32_t' + elif xap_type == 'u64': + return 'uint64_t' + elif xap_type == 'struct': + return 'struct' + elif xap_type == 'string': + return 'const char *' + return 'unknown' + + def _append_route_defines(lines, container, container_id=None, route_stack=None): """Handles building the list of the XAP routes, combining parent and child names together, as well as the route number. """ @@ -105,25 +123,29 @@ def _append_types(lines, container): # Add special lines.append(f'#define {prefix}_FAILED 0x00') + lines.append('') - # TODO: define this in xap_*.hjson - lines.append( - ''' -typedef uint8_t xap_identifier_t; -typedef uint8_t xap_response_flags_t; -typedef uint16_t xap_token_t; + additional_types = {} + types = container.get('types', {}) + for key, value in types.items(): + data_type = _get_c_type(value['type']) + additional_types[key] = f'xap_{key}_t' -typedef struct { - xap_token_t token; - uint8_t length; -} xap_request_header_t; + for key, value in types.items(): + data_type = _get_c_type(value['type']) + if data_type == 'struct': + members = value['struct_members'] -typedef struct { - xap_token_t token; - xap_response_flags_t flags; - uint8_t length; -} xap_response_header_t;''' - ) + lines.append(f'typedef {data_type} {{') + for member in members: + member_name = member["name"] + member_type = _get_c_type(member["type"]) + if member_type == 'unknown': + member_type = additional_types[member["type"]] + lines.append(f' {member_type} {member_name};') + lines.append(f'}} xap_{key}_t;') + else: + lines.append(f'typedef {data_type} xap_{key}_t;') def generate_header(output_file, keyboard):