Commit d3260912 authored by Robey Pointer's avatar Robey Pointer
Browse files

there's only one OLED, so just make it static vars, not a struct

parent 68ebc839
......@@ -51,8 +51,6 @@
/** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */
static uint8_t PrevKeyboardHIDReportBuffer[sizeof(USB_KeyboardReport_Data_t)];
text_display_t display;
/** LUFA HID Class driver interface configuration and state information. This structure is
* passed to all HID Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another.
......@@ -166,7 +164,10 @@ static void remote_check_for_low_battery(void) {
if (info.total_percent > 0 && info.total_percent < 10) {
low_battery_alert = 1;
}
if (was_low && !low_battery_alert) text_display_clear(&display);
if (was_low && !low_battery_alert) {
text_display_clear();
text_display_flush();
}
}
int oledbrt=0;
......@@ -391,16 +392,19 @@ int execute_meta_function(int keycode) {
remote_turn_off_aux();
}*/
else if (keycode == KEY_B) {
ux_show_battery(&display);
ux_show_battery();
return 0;
}
else if (keycode == KEY_S) {
ux_show_status(&display);
ux_show_status();
return 0;
}
else if (keycode == KEY_Z) {
low_battery_alert = !low_battery_alert;
if (!low_battery_alert) text_display_clear(&display);
if (!low_battery_alert) {
text_display_clear();
text_display_flush();
}
return 0;
}
else if (keycode == KEY_F1) {
......@@ -557,7 +561,7 @@ int blink = 0;
void process_alerts(void) {
if (low_battery_alert) {
ux_blink_low_battery(&display, blink);
ux_blink_low_battery(blink);
}
blink = 1-blink;
}
......@@ -625,7 +629,7 @@ void SetupHardware()
kbd_brightness_init();
oled_init();
text_display_init(&display, &font_oranj);
text_display_init(&font_oranj);
gfx_clear();
gfx_flush();
hid_report_init();
......
......@@ -12,13 +12,15 @@
#include "text_display.h"
#include "ux.h"
extern text_display_t display;
// hid commands are all 4-letter
#define cmd(_s) (*(uint32_t *)(_s))
#define CMD_TEXT_FRAME cmd("OLED") // fill the screen with a single wall of text
#define CMD_TEXT_WRITE cmd("WRIT") // write to the oled as if it's a console
#define CMD_REPORT_POWER cmd("RPRT") // ask for power stats
#define CMD_UX_POWER cmd("UXPW") // display detailed power screen as if user hit circle-B
#define CMD_UX_STATUS cmd("UXST") // display status screen as if user hit circle-S
#define CMD_TEST cmd("test")
void hid_report_init(void) {
// pass
......@@ -45,16 +47,25 @@ void CALLBACK_HID_Device_ProcessHIDReport(
const uint32_t command = *(uint32_t *)data;
if (command == CMD_TEXT_FRAME) {
text_display_clear(&display);
for (int i = 4; i < report_size; i++) text_display_putc(&display, data[i]);
text_display_flush(&display);
text_display_init(&font_oranj);
text_display_clear();
for (int i = 4; i < report_size; i++) text_display_putc(data[i]);
text_display_flush();
} else if (command == CMD_TEXT_WRITE) {
text_display_write_len((const char *)&data[4], report_size - 4);
text_display_flush();
} else if (command == CMD_REPORT_POWER) {
const char *report = controller_request("0c");
if (report) text_display_write(&display, report);
text_display_putc(&display, '@');
text_display_flush(&display);
if (report) text_display_write(report);
text_display_flush();
} else if (command == CMD_UX_POWER) {
ux_show_battery(&display);
ux_show_battery();
} else if (command == CMD_UX_STATUS) {
ux_show_status();
} else if (command == CMD_TEST) {
text_display_init(&font_bizcat);
text_display_write("This is a test.");
text_display_flush();
}
#if 0
......
......@@ -16,106 +16,120 @@
const monospace_font_t font_oranj = { oranj_reform_font_data, 8, 6 };
const monospace_font_t font_bizcat = { bizcat_reform_font_data, 16, 8 };
void text_display_init(text_display_t *display, const monospace_font_t *font) {
display->font = font;
display->height = DisplayHeight / display->font->height;
display->width = DisplayWidth / display->font->width;
text_display_clear(display);
static uint8_t framebuffer[DisplayHeight * DisplayWidth / 8] = { 0, };
// text grid
static uint8_t text_cells[MAX_HEIGHT * MAX_WIDTH];
static uint8_t text_invert[(MAX_HEIGHT * MAX_WIDTH + 7) / 8];
static const monospace_font_t *text_font = &font_oranj;
static uint8_t text_height = 0;
static uint8_t text_width = 0;
static uint8_t text_cursor = 0;
static bool text_dirty = false;
static bool text_inverting = false;
static uint8_t text_roll = 0; // FIXME hack
void text_display_init(const monospace_font_t *font) {
text_font = font;
text_height = DisplayHeight / text_font->height;
text_width = DisplayWidth / text_font->width;
text_display_clear();
}
void text_display_clear(text_display_t *display) {
memset(display->cells, ' ', sizeof(display->cells));
memset(display->invert, 0, sizeof(display->invert));
display->cursor = 0;
display->dirty = true;
display->inverting = false;
display->roll = 0;
void text_display_clear(void) {
memset(framebuffer, 0, sizeof(framebuffer));
memset(text_cells, ' ', sizeof(text_cells));
memset(text_invert, 0, sizeof(text_invert));
text_cursor = 0;
text_dirty = true;
text_inverting = false;
text_roll = 0;
}
void text_display_clear_line(text_display_t *display, uint8_t line) {
memset(display->cells + line * display->width, ' ', display->width);
for (int i = line * display->width; i < (line + 1) * display->width; i++) {
display->invert[i >> 3] &= ~(1 << (i & 7));
void text_display_clear_line(uint8_t line) {
memset(text_cells + line * text_width, ' ', text_width);
for (int i = line * text_width; i < (line + 1) * text_width; i++) {
text_invert[i >> 3] &= ~(1 << (i & 7));
}
}
// scroll up one line.
void text_display_scroll(text_display_t *display) {
memmove(display->cells, display->cells + display->width, (display->height - 1) * display->width);
void text_display_scroll(void) {
memmove(text_cells, text_cells + text_width, (text_height - 1) * text_width);
// this is a pain: scroll the invert bits too.
uint8_t bytes = display->width >> 3;
uint8_t bits = display->width & 7;
for (int i = 0; i < (display->width * (display->height - 1) + 7) >> 3; i++) {
display->invert[i] = (display->invert[i + bytes] >> bits) + (display->invert[i + bytes + 1] << (8 - bits));
uint8_t bytes = text_width >> 3;
uint8_t bits = text_width & 7;
for (int i = 0; i < (text_width * (text_height - 1) + 7) >> 3; i++) {
text_invert[i] = (text_invert[i + bytes] >> bits) + (text_invert[i + bytes + 1] << (8 - bits));
}
text_display_clear_line(display, display->height - 1);
display->dirty = true;
text_display_clear_line(text_height - 1);
text_dirty = true;
}
void text_display_putc(text_display_t *display, uint8_t c) {
while (display->cursor >= display->width * display->height) {
display->cursor -= display->width;
text_display_scroll(display);
void text_display_putc(uint8_t c) {
while (text_cursor >= text_width * text_height) {
text_cursor -= text_width;
text_display_scroll();
}
display->cells[display->cursor] = c;
uint8_t invert_bit = 1 << (display->cursor & 7);
display->invert[display->cursor >> 3] &= ~invert_bit;
display->invert[display->cursor >> 3] |= display->inverting ? invert_bit : 0;
display->cursor++;
display->dirty = true;
text_cells[text_cursor] = c;
uint8_t invert_bit = 1 << (text_cursor & 7);
text_invert[text_cursor >> 3] &= ~invert_bit;
text_invert[text_cursor >> 3] |= text_inverting ? invert_bit : 0;
text_cursor++;
text_dirty = true;
}
void text_display_write_len(text_display_t *display, const char *text, int len) {
void text_display_write_len(const char *text, int len) {
for (int i = 0; i < len; i++) {
switch (text[i]) {
case '\n':
display->cursor = ((display->cursor / display->width) + 1) * display->width;
text_cursor = ((text_cursor / text_width) + 1) * text_width;
break;
case 0x0c:
// clear
text_display_clear(display);
text_display_clear();
break;
case 0x0e:
// "shift out": invert
display->inverting = true;
text_inverting = true;
break;
case 0x0f:
// "shift in": normal
display->inverting = false;
text_inverting = false;
break;
default:
text_display_putc(display, text[i]);
text_display_putc(text[i]);
}
}
}
void text_display_write(text_display_t *display, const char *text) {
text_display_write_len(display, text, strlen(text));
void text_display_write(const char *text) {
text_display_write_len(text, strlen(text));
}
void text_display_move(text_display_t *display, uint8_t x, uint8_t y) {
display->cursor = display->width * y + x;
if (display->cursor >= display->width * display->height) display->cursor = 0;
void text_display_move(uint8_t x, uint8_t y) {
text_cursor = text_width * y + x;
if (text_cursor >= text_width * text_height) text_cursor = 0;
}
void text_display_invert(text_display_t *display, bool invert) {
display->inverting = invert;
void text_display_invert(bool invert) {
text_inverting = invert;
}
void text_display_flush(text_display_t *display) {
if (!display->dirty) return;
uint8_t x_offset = (DisplayWidth - display->width * display->font->width) / 2;
int stride = (display->font->height + 7) / 8;
void text_display_flush(void) {
if (!text_dirty) return;
uint8_t x_offset = (DisplayWidth - text_width * text_font->width) / 2;
int stride = (text_font->height + 7) / 8;
oled_on();
oled_home();
oled_start_render();
uint8_t cursor = 0;
for (uint8_t y = 0; y < display->height; y++) {
if (y < display->roll) {
for (uint8_t y = 0; y < text_height; y++) {
if (y < text_roll) {
// skip row
for (uint8_t x = 0; x < DisplayWidth; x++) oled_render(0);
continue;
......@@ -123,14 +137,14 @@ void text_display_flush(text_display_t *display) {
for (uint8_t row = 0; row < stride; row++) {
// back up if we're drawing the later row of a tall font
if (row > 0) cursor -= display->width;
if (row > 0) cursor -= text_width;
for (uint8_t pad = 0; pad < x_offset; pad++) oled_render(0);
for (uint8_t x = 0; x < display->width; x++) {
int offset = (display->cells[cursor] & 0x7f) * display->font->width * stride;
for (uint8_t column = 0; column < display->font->width; column++) {
uint8_t pixels = pgm_read_byte((uint8_t *)display->font->glyphs + offset + column * stride + row);
if (display->invert[cursor >> 3] & (1 << (cursor & 7))) pixels = ~pixels;
for (uint8_t x = 0; x < text_width; x++) {
int offset = (text_cells[cursor] & 0x7f) * text_font->width * stride;
for (uint8_t column = 0; column < text_font->width; column++) {
uint8_t pixels = pgm_read_byte((uint8_t *)text_font->glyphs + offset + column * stride + row);
if (text_invert[cursor >> 3] & (1 << (cursor & 7))) pixels = ~pixels;
oled_render(pixels);
}
cursor++;
......@@ -138,11 +152,15 @@ void text_display_flush(text_display_t *display) {
}
for (uint8_t pad = 0; pad < x_offset; pad++) oled_render(0);
}
if (display->roll == 1 && display->font->height > 8) {
if (text_roll == 1 && text_font->height > 8) {
// skip row
for (uint8_t x = 0; x < DisplayWidth; x++) oled_render(0);
}
oled_finish_render();
display->dirty = false;
text_dirty = false;
}
void text_display_render(void) {
}
......@@ -25,28 +25,16 @@ typedef struct {
uint8_t width;
} monospace_font_t;
typedef struct {
uint8_t cells[MAX_HEIGHT * MAX_WIDTH];
uint8_t invert[(MAX_HEIGHT * MAX_WIDTH + 7) / 8];
uint8_t width;
uint8_t height;
uint8_t cursor;
uint8_t dirty;
uint8_t inverting;
uint8_t roll; // special mode for centering one line in large-font mode
const monospace_font_t *font;
} text_display_t;
extern const monospace_font_t font_oranj;
extern const monospace_font_t font_bizcat;
void text_display_init(text_display_t *display, const monospace_font_t *font);
void text_display_clear(text_display_t *display);
void text_display_clear_line(text_display_t *display, uint8_t line);
void text_display_scroll(text_display_t *display);
void text_display_putc(text_display_t *display, uint8_t c);
void text_display_write_len(text_display_t *display, const char *text, int len);
void text_display_write(text_display_t *display, const char *text);
void text_display_move(text_display_t *display, uint8_t x, uint8_t y);
void text_display_invert(text_display_t *display, bool invert);
void text_display_flush(text_display_t *display);
void text_display_init(const monospace_font_t *font);
void text_display_clear(void);
void text_display_clear_line(uint8_t line);
void text_display_scroll(void);
void text_display_putc(uint8_t c);
void text_display_write_len(const char *text, int len);
void text_display_write(const char *text);
void text_display_move(uint8_t x, uint8_t y);
void text_display_invert(bool invert);
void text_display_flush(void);
......@@ -38,60 +38,60 @@ static const char *show_one_battery(uint8_t decivolts) {
return buffer;
}
void ux_show_battery(text_display_t *display) {
void ux_show_battery(void) {
battery_info_t info;
controller_probe_batteries(&info);
// plot, using oranj (6x8) so all the info will fit
text_display_init(display, &font_oranj);
text_display_init(&font_oranj);
char str[32];
sprintf(str, "%s %s %3d%%",
show_one_battery(info.decivolts[0]), show_one_battery(info.decivolts[4]), info.total_percent);
text_display_write(display, str);
text_display_write(str);
sprintf(str, "%s %s ",
show_one_battery(info.decivolts[1]), show_one_battery(info.decivolts[5]));
text_display_write(display, str);
text_display_write(str);
sprintf(str, "%s %s %5.2fA",
show_one_battery(info.decivolts[2]), show_one_battery(info.decivolts[6]), info.total_amps);
text_display_write(display, str);
text_display_write(str);
sprintf(str, "%s %s %5.2fV",
show_one_battery(info.decivolts[3]), show_one_battery(info.decivolts[7]), info.total_volts);
text_display_write(display, str);
text_display_flush(display);
text_display_write(str);
text_display_flush();
}
void ux_show_status(text_display_t *display) {
text_display_init(display, &font_oranj);
void ux_show_status(void) {
text_display_init(&font_oranj);
#ifndef KBD_VARIANT_STANDALONE
const char *response = controller_request("s");
text_display_write(display, response);
text_display_write(response);
#endif
text_display_move(display, 0, 2);
text_display_write(display, "MNT Reform Keyboard");
text_display_move(display, 0, 3);
text_display_write(display, KBD_FW_REV);
text_display_flush(display);
text_display_move(0, 2);
text_display_write("MNT Reform Keyboard");
text_display_move(0, 3);
text_display_write(KBD_FW_REV);
text_display_flush();
}
#define BATTERY_EMPTY_LEFT 0
#define BATTERY_EMPTY_RIGHT 6
#define BATTERY_ALERT_LEFT 12
#define BATTERY_ALERT_RIGHT 13
void ux_blink_low_battery(text_display_t *display, bool blink) {
void ux_blink_low_battery(bool blink) {
// switch to the large font, and sneakily drop down one half-row
text_display_init(display, &font_bizcat);
display->roll = 1;
text_display_move(display, 7, 0);
text_display_init(&font_bizcat);
// display->roll = 1;
text_display_move(7, 0);
if (blink) {
text_display_putc(display, BATTERY_ALERT_LEFT);
text_display_putc(display, BATTERY_ALERT_RIGHT);
text_display_putc(BATTERY_ALERT_LEFT);
text_display_putc(BATTERY_ALERT_RIGHT);
} else {
text_display_putc(display, BATTERY_EMPTY_LEFT);
text_display_putc(display, BATTERY_EMPTY_RIGHT);
text_display_putc(BATTERY_EMPTY_LEFT);
text_display_putc(BATTERY_EMPTY_RIGHT);
}
text_display_flush(display);
display->roll = 0;
text_display_flush();
// display->roll = 0;
}
......@@ -9,6 +9,6 @@
#include "text_display.h"
void ux_show_battery(text_display_t *display);
void ux_show_status(text_display_t *display);
void ux_blink_low_battery(text_display_t *display, bool blink);
void ux_show_battery(void);
void ux_show_status(void);
void ux_blink_low_battery(bool blink);
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment