Skip to content

Commit

Permalink
remove hacky macros, some C linting, break zig into modules, override…
Browse files Browse the repository at this point in the history
…s instrospection, WIP asset fetching from `build.zig`
  • Loading branch information
elpekenin committed Aug 13, 2024
1 parent dcb2027 commit 38229ee
Show file tree
Hide file tree
Showing 18 changed files with 270 additions and 226 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,10 @@ __pycache__/

TODO.md

# zig artifacts
.zig-cache
zig-out

# linting
lint
Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,15 @@ static uint32_t read_touch_callback(uint32_t trigger_time, void *cb_arg) {
void keyboard_post_init_keymap(void) {
#if defined(QUANTUM_PAINTER_ENABLE)
# if IS_LEFT_HAND
load_display(il91874, "il91874");
qp_set_device_by_name("il91874", il91874);
# endif

# if IS_RIGHT_HAND
load_display(ili9163, "ili9163");
load_display(ili9341, "ili9341");
qp_set_device_by_name("ili9163", ili9163);
qp_set_device_by_name("ili9341", ili9341);

// set_uptime_device(ili9341);
// set_logging_device(ili9341);
set_logging_device(ili9341);
// set_heap_stats_device(ili9341);
set_layer_device(ili9341);
# if defined(KEYLOG_ENABLE)
Expand Down
41 changes: 41 additions & 0 deletions firmware/users/elpekenin/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ const KnownMcus = [_]MCU{
.abi = .eabi,
},
},
.{ // to run tests on computer
.name = "native",
.target = .{}, // default to native
}
};

fn getTarget(mcu: []const u8) std.Target.Query {
Expand All @@ -27,6 +31,37 @@ fn getTarget(mcu: []const u8) std.Target.Query {
std.debug.panic("Unknown MCU: {s}", .{mcu});
}

fn getFiles(b: *std.Build, options: *std.Build.Step.Options, path: []const u8, needle: []const u8) !void {
var dir = try std.fs.openDirAbsolute(path, .{ .iterate = true });
defer dir.close();

var walker = try dir.walk(b.allocator);
while (try walker.next()) |file| {
if (file.kind == .file) {
if (std.mem.endsWith(u8, file.basename, needle)) {
const fd = try dir.openFile(file.path, .{});
defer fd.close();

const stat = try fd.stat();

const buff = try b.allocator.alloc(u8, stat.size);
defer b.allocator.free(buff);

_ = try fd.read(buff);

options.addOption([]const u8, file.basename, buff);
}
}
}
}

fn getAssets(b: *std.Build) !*std.Build.Step.Options {
const options = b.addOptions();
try getFiles(b, options, b.pathJoin(&.{b.build_root.path orelse @panic("No root"), "painter", "images"}), "qgf.c");
try getFiles(b, options, b.pathJoin(&.{b.build_root.path orelse @panic("No root"), "painter", "fonts"}), "qff");
return options;
}

pub fn build(b: *std.Build) !void {
const mcu = b.option([]const u8, "mcu", "MCU to compile for") orelse @panic("Select a MCU");
const target = b.resolveTargetQuery(getTarget(mcu));
Expand All @@ -49,6 +84,9 @@ pub fn build(b: *std.Build) !void {

elpekenin_lib.is_linking_libc = true;

// needed on native, not on MCU (?)
elpekenin_lib.bundle_compiler_rt = target.result.os.tag == .linux;

// // ideally, we would only need these two paths
// elpekenin_lib.addSystemIncludePath(.{.cwd_relative = qmk});
// elpekenin_lib.addSystemIncludePath(.{.cwd_relative = elpekenin ++ "/include"});
Expand All @@ -70,6 +108,9 @@ pub fn build(b: *std.Build) !void {
// // hack newlib include path too...
// elpekenin_lib.addSystemIncludePath(.{.cwd_relative = "/usr/include/newlib/"});

const assets = try getAssets(b);
elpekenin_lib.root_module.addImport("assets", assets.createModule());

// generate the .a file
b.installArtifact(elpekenin_lib);
}
12 changes: 6 additions & 6 deletions firmware/users/elpekenin/include/elpekenin/qp/graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
#endif // QUANTUM_PAINTER_NUM_DISPLAYS

// *** Asset handling ***
NON_NULL(2) READ_ONLY(1) void load_display(painter_device_t display, const char *name);
NON_NULL(2) READ_ONLY(1) void load_font(const uint8_t *font, const char *name);
NON_NULL(2) READ_ONLY(1) void load_image(const uint8_t *img, const char *name);
NON_NULL(2) READ_ONLY(1) void qp_set_device_by_name(const char *name, painter_device_t display);
NON_NULL(2) READ_ONLY(1) void qp_set_font_by_name(const char *name, const uint8_t *font);
NON_NULL(2) READ_ONLY(1) void qp_set_image_by_name(const char *name, const uint8_t *img);

NON_NULL(1) PURE READ_ONLY(1) painter_device_t qp_get_device_by_name(const char *name);
NON_NULL(1) PURE READ_ONLY(1) painter_font_handle_t qp_get_font_by_name(const char *name);
NON_NULL(1) PURE READ_ONLY(1) painter_image_handle_t qp_get_img_by_name(const char *name);
NON_NULL(1) READ_ONLY(1) painter_device_t qp_get_device_by_name(const char *name);
NON_NULL(1) READ_ONLY(1) painter_font_handle_t qp_get_font_by_name(const char *name);
NON_NULL(1) READ_ONLY(1) painter_image_handle_t qp_get_image_by_name(const char *name);


// *** Show build info ***
Expand Down
8 changes: 5 additions & 3 deletions firmware/users/elpekenin/include/elpekenin/utils/sections.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@
#define INIT_QP_LOG 1020
#define INIT_SENDCHAR 1021 /* after QP logging has been init */
#define INIT_LOG_FORMAT 1022
#define INIT_ZIG 1023 /* early on, but with logging available */

#define INIT_CRASH 1030
#define INIT_BUILD 1030 /* before split, so that we send the right thing over wire */

#define INIT_QP_MAPS_AND_TASKS 1040
#define INIT_KEYLOG_MAP 1040
#define INIT_INDICATORS_MAP 1040
#define INIT_QP_TASKS_ARGS 1040
#define INIT_KEYLOG_MAP 1040
#define INIT_INDICATORS_MAP 1040

#define INIT_SPLIT 1050
#define INIT_TRI_LAYER 1050
Expand All @@ -56,6 +57,7 @@
#define DEINIT_XAP 1010

#define DEINIT_QP 1020
#define DEINIT_ZIG 1020
#define DEINIT_RGB 1020


Expand Down
68 changes: 33 additions & 35 deletions firmware/users/elpekenin/scripts/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,27 @@
BACKGROUND_COLOR = "HSV_WHITE"

# Capitalization here doesnt matter, code will format it
FEATURES = sorted({
"AUDIO",
"AUTOCORRECT",
"BOOTMAGIC",
"COMBO",
"EXTRAKEY",
"KEY_OVERRIDE",
"MOUSEKEY",
"NKRO",
"RGB_MATRIX",
"SIPO_PINS",
"TAP_DANCE",
"TOUCH_SCREEN",
"QP_XAP",
"QUANTUM_PAINTER",
"UNICODE_COMMON",
"WPM",
"XAP",
})
FEATURES = sorted(
{
"AUDIO",
"AUTOCORRECT",
"BOOTMAGIC",
"COMBO",
"EXTRAKEY",
"KEY_OVERRIDE",
"MOUSEKEY",
"NKRO",
"RGB_MATRIX",
"SIPO_PINS",
"TAP_DANCE",
"TOUCH_SCREEN",
"QP_XAP",
"QUANTUM_PAINTER",
"UNICODE_COMMON",
"WPM",
"XAP",
}
)
SHORT_NAMES = {
"QUANTUM_PAINTER": "PAINTER",
"UNICODE_COMMON": "UNICODE",
Expand All @@ -58,12 +60,12 @@
"typedef union {{",
" {type} raw;",
" struct {{",
"{generated_code}",
"{generated_code}",
" }};",
"}} enabled_features_t;",
"",
"enabled_features_t get_enabled_features(void);",
""
"",
)

C_FILE = lines(
Expand All @@ -76,16 +78,16 @@
"",
" features.raw = 0;",
"",
"{generated_code}",
"{generated_code}",
" return features;",
"}}",
""
"",
)

DRAW_FILE = lines(
C_HEADER,
"",
'#include <quantum/color.h>',
"#include <quantum/color.h>",
"",
f'#include "{OUTPUT_NAME}.h"',
'#include "elpekenin/qp/graphics.h"',
Expand All @@ -97,7 +99,7 @@
" if (font == NULL) {{",
' _ = logging(QP, LOG_ERROR, "Font was NULL");',
" return;",
" }}"
" }}",
"",
" enabled_features_t features = get_build_info().features;",
" uint8_t font_height = font->line_height;",
Expand All @@ -109,8 +111,8 @@
"",
" bool shifted = false;",
"",
"{generated_code}" # no comma here intentionally
"}}"
"{generated_code}" # no comma here intentionally
"}}",
)


Expand All @@ -124,10 +126,7 @@ def _get_type() -> str:


def _for_all_features(func: Callable) -> str:
return "\n".join(
func(feature)
for feature in FEATURES
)
return "\n".join(func(feature) for feature in FEATURES)


def _h_generator(feature: str) -> str:
Expand All @@ -138,8 +137,8 @@ def _c_generator(feature: str) -> str:
return lines(
f" #if defined({feature.upper()}_ENABLE)",
f" features.{feature.lower()} = true;",
f" #endif",
""
" #endif",
"",
)


Expand Down Expand Up @@ -185,7 +184,6 @@ def _draw_generator(feature: str) -> str:
with open(output_dir / f"{OUTPUT_NAME}.h", "w") as f:
f.write(H_FILE.format(type=type_, generated_code=gen_h))


gen_c = _for_all_features(_c_generator)
with open(output_dir / f"{OUTPUT_NAME}.c", "w") as f:
f.write(C_FILE.format(generated_code=gen_c))
Expand All @@ -196,4 +194,4 @@ def _draw_generator(feature: str) -> str:

else:
print("Dont try to import this")
exit(1)
exit(1)
31 changes: 13 additions & 18 deletions firmware/users/elpekenin/scripts/keycode_str.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

sys.path.append(str(QMK / "users" / "elpekenin" / "scripts"))
from scripts import *

sys.path.append(str(QMK / "lib" / "python"))
from qmk import keycodes

Expand All @@ -37,23 +38,18 @@

OUTPUT_NAME = "keycode_str"

H_FILE = lines(
H_HEADER,
"",
"const char *get_keycode_name(uint16_t keycode);",
""
)
H_FILE = lines(H_HEADER, "", "const char *get_keycode_name(uint16_t keycode);", "")

C_FILE = lines(
C_HEADER,
"",
'#include <quantum/quantum.h>',
"#include <quantum/quantum.h>",
"",
'#include "elpekenin.h" // keycodes and layers',
"",
"static const char *keycode_names[] = {{",
"{qmk_data}" # intentional lack of comma
"{keymap_data}"
"{qmk_data}" # intentional lack of comma
"{keymap_data}"
"}};",
"",
"const char *get_keycode_name(uint16_t keycode) {{",
Expand All @@ -71,15 +67,12 @@
# out of bounds -> nothing
" return NULL;",
"}}",
""
"",
)


def _read_file(keymap_path: Path) -> str:
with open(
keymap_path,
"r"
) as f:
with open(keymap_path, "r") as f:
return f.read()


Expand Down Expand Up @@ -116,11 +109,13 @@ def _extract_keycodes(clean_file: str) -> list[str]:
accumulated += char

if parens == 0: # outsize of layout macro
if char == "}": # keymap array end
if char == "}": # keymap array end
break

if accumulated: # if gathered a layer of keycodes, store it
accumulated = ", ".join([i.strip() for i in accumulated.replace("\n", "").split(", ")])
accumulated = ", ".join(
[i.strip() for i in accumulated.replace("\n", "").split(", ")]
)
layers.append(accumulated)
accumulated = ""

Expand All @@ -142,7 +137,7 @@ def _keymap_data(layers: list[str]) -> str:

if __name__ == "__main__":
# -- Handle args
if len(sys.argv) < 3: # executable, output path, keymap path
if len(sys.argv) < 3: # executable, output path, keymap path
print(f"{CLI_ERROR} {current_filename(__file__)} <output_path> <keymap_path>")
exit(1)

Expand Down Expand Up @@ -183,4 +178,4 @@ def _keymap_data(layers: list[str]) -> str:

else:
print("Dont try to import this")
exit(1)
exit(1)
Loading

0 comments on commit 38229ee

Please sign in to comment.