reform

MNT Reform: Open Source Portable Computer
Log (Feed) | Files | Refs (Tags) | README

commit db1afb84ce837bd34bd410c26422ee9a0b8c5a4c
parent 650412076baf5c2024375044de12a56db911df5c
Author: Lukas F. Hartmann <lukas@mntre.com>
Date:   Mon, 21 Feb 2022 18:48:21 +0100

Merge branch 'kbd-bitmaps' of source.mnt.re:reform/reform into kbd-bitmaps

Diffstat:
Areform2-keyboard-fw/kbdgfx-demo/build.sh | 4++++
Areform2-keyboard-fw/kbdgfx-demo/kbdgfx.c | 140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Areform2-keyboard-fw/kbdgfx-demo/picture-floyd.sh | 9+++++++++
Areform2-keyboard-fw/kbdgfx-demo/picture.sh | 7+++++++
Areform2-keyboard-fw/kbdgfx-demo/text.sh | 7+++++++
Mreform2-keyboard-fw/matrix.h | 2+-
Mreform2-keyboard-fw/menu.c | 13+++++++++++--
7 files changed, 179 insertions(+), 3 deletions(-)

diff --git a/reform2-keyboard-fw/kbdgfx-demo/build.sh b/reform2-keyboard-fw/kbdgfx-demo/build.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +gcc -O2 -o kbdgfx ./kbdgfx.c -lm + diff --git a/reform2-keyboard-fw/kbdgfx-demo/kbdgfx.c b/reform2-keyboard-fw/kbdgfx-demo/kbdgfx.c @@ -0,0 +1,140 @@ +/* + kbdgfx.c -- Demo for drawing realtime graphics to the MNT Reform Keyboard + Copyright 2022 MNT Research GmbH (https://mntre.com) + License: MIT +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <math.h> +#include <unistd.h> + +#define ROWS 4 +#define COLS 126 +#define BUFSZ (5+COLS*ROWS) +#define FBUFSZ COLS*ROWS*8 + +// our unpacked, wasteful framebuffer (one byte per pixel, 126x32) +uint8_t fb[FBUFSZ]; + +// the buffer we're sending to the keyboard (bit packed and column byte order) +uint8_t buf[BUFSZ]; + +void oled_blit(uint8_t* src, uint8_t* dst) { + for (int y = 0; y < ROWS; y++) { + // right-to-left + for (int x = 0; x < COLS; x++) { + uint8_t column = 0; + + for (int z = 0; z < 8; z++) { + // look up the pixel and threshold it to black and white at 127 + uint8_t bit = src[((y * 8 + 7 - z)*COLS + x)] > 127; + + // bitshift the column byte to the left to make room for new pixel + column <<= 1; + // OR the bit (the pixel) to the column byte + column |= bit; + } + + // store in the destination buffer + dst[y*COLS + x] = column; + } + } +} + +// unused +void fill_pattern(uint8_t bitpattern, uint8_t* dst) { + int i = 0; + for (int y = 0; y < 32; y++) { + for (int x = 0; x < COLS; x++) { + uint8_t pos = x % 8; + uint8_t b = bitpattern & (1<<pos); + + dst[i++] = b ? 1 : 0; + } + } +} + +void draw_sine(float t, uint8_t* dst) { + for (int x=0; x<126; x++) { + int y = 16 + sin(t + ((float)x/126.0 * 3.141))*12; + if (y < 0) y = 0; + if (y > 31) y = 31; + + dst[y*COLS + x] = 0xff; + } +} + +int main(int argc, char** argv) { + // just a counter + uint32_t t = 0; + + if (argc < 2) { + printf("Usage: sudo kbdgfx /dev/hidraw0 [bitmap.raw]\n"); + exit(1); + } + + // loop forever + while (1) { + FILE* f = fopen(argv[1],"w"); + + if (!f) { + printf("Couldn't open %s. Try sudo.\n", argv[1]); + exit(1); + } + + // start with the command + buf[0] = 'x'; + buf[1] = 'W'; + buf[2] = 'B'; + buf[3] = 'I'; + buf[4] = 'T'; + + // clear + memset(fb, 0, FBUFSZ); + + if (argc == 3) { + // read bitmap from file + FILE* bmf = fopen(argv[2],"r"); + if (!bmf) { + printf("Couldn't open bitmap %s!\n", argv[2]); + fclose(f); + exit(2); + } + + int res = fread(fb, FBUFSZ, 1, bmf); + fclose(bmf); + + if (res<1) { + printf("Couldn't read bitmap or wrong size.\n", argv[2]); + fclose(f); + exit(3); + } + } else { + // graphics demo + + // paint + draw_sine((float)t*0.03, fb); + draw_sine((float)t*0.05, fb); + } + + // convert to weird OLED buffer format + oled_blit(fb, buf+5); + + // send our buffer to the keyboard + fwrite(buf, BUFSZ, 1, f); + + fclose(f); + + // if we're in bitmap file mode, exit now + if (argc == 3) exit(0); + + // ~50 FPS + usleep(1000*20); + // ~2 FPS + //usleep(1000*500); + t++; + } +} diff --git a/reform2-keyboard-fw/kbdgfx-demo/picture-floyd.sh b/reform2-keyboard-fw/kbdgfx-demo/picture-floyd.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# Usage: ./picture-floyd.sh /dev/hidraw3 picture.jpg + +#convert $2 -resize 126 -crop 126x32+0+0 -depth 8 -dither FloydSteinberg -remap pattern:gray50 gray:temp.bin + +convert $2 -resize 126 -gravity center -extent 126x32 -depth 8 -dither FloydSteinberg -remap pattern:gray50 gray:temp.bin +sudo ./kbdgfx $1 ./temp.bin + diff --git a/reform2-keyboard-fw/kbdgfx-demo/picture.sh b/reform2-keyboard-fw/kbdgfx-demo/picture.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Usage: ./picture.sh /dev/hidraw3 picture.png + +convert $2 -resize 126 -gravity center -extent 126x32 -depth 8 gray:temp.bin +sudo ./kbdgfx $1 ./temp.bin + diff --git a/reform2-keyboard-fw/kbdgfx-demo/text.sh b/reform2-keyboard-fw/kbdgfx-demo/text.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Usage: ./text.sh /dev/hidraw3 18 "hello world" + +convert -size 126x32 -background black -font Inter-Bold.ttf -pointsize $2 -fill white -gravity center caption:"$3" -depth 8 -flatten gray:temp.bin +sudo ./kbdgfx $1 ./temp.bin + diff --git a/reform2-keyboard-fw/matrix.h b/reform2-keyboard-fw/matrix.h @@ -22,7 +22,7 @@ uint8_t matrix[KBD_MATRIX_SZ] = { // When holding down HYPER uint8_t matrix_fn[KBD_MATRIX_SZ] = { - // Media keys (not working, FIXME) + // Media keys on Hyper + F7-F12 KEY_ESCAPE, KEY_F1, KEY_F2, diff --git a/reform2-keyboard-fw/menu.c b/reform2-keyboard-fw/menu.c @@ -17,12 +17,13 @@ int current_menu_y = 0; int current_scroll_y = 0; #ifdef KBD_VARIANT_STANDALONE -#define MENU_NUM_ITEMS 4 +#define MENU_NUM_ITEMS 5 const MenuItem menu_items[] = { { "Exit Menu ESC", KEY_ESCAPE }, { "Key Backlight- F1", KEY_F1 }, { "Key Backlight+ F2", KEY_F2 }, - { "System Status s", KEY_S } + { "System Status s", KEY_S }, + { "USB Flashing Mode x", KEY_X }, }; #else #define MENU_NUM_ITEMS 9 @@ -67,6 +68,11 @@ int execute_menu_function(int y) { return execute_meta_function(KEY_ESCAPE); } +#define BOOTLOADER_START_ADDRESS ((0x8000-0x1000) >> 1) +void jump_to_bootloader(void) { + ((void (*)(void))BOOTLOADER_START_ADDRESS)(); +} + // returns 1 for navigation function (stay in meta mode), 0 for terminal function int execute_meta_function(int keycode) { if (keycode == KEY_0) { @@ -133,6 +139,9 @@ int execute_meta_function(int keycode) { gfx_clear(); gfx_flush(); } + else if (keycode == KEY_X) { + jump_to_bootloader(); + } gfx_clear(); gfx_flush();