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

draw the splash (and unsplash) logo as an animated image file

parent ff14b43e
......@@ -111,43 +111,6 @@ void empty_serial(void) {
int term_x = 0;
int term_y = 0;
void anim_hello(void) {
gfx_clear();
gfx_on();
for (int y=0; y<3; y++) {
for (int x=0; x<12; x++) {
gfx_poke(x+4,y+1,(5+y)*32+x);
gfx_flush();
}
}
for (int y=0; y<0xff; y++) {
gfx_contrast(y);
Delay_MS(2);
}
for (int y=0; y<0xff; y++) {
gfx_contrast(0xff-y);
Delay_MS(2);
}
}
void anim_goodbye(void) {
gfx_clear();
gfx_on();
for (int y=0; y<3; y++) {
for (int x=0; x<12; x++) {
gfx_poke(x+4,y+1,(5+y)*32+x);
}
}
for (int y=0; y<3; y++) {
for (int x=0; x<12; x++) {
gfx_poke(x+4,y+1,' ');
gfx_flush();
}
}
gfx_off();
}
int low_battery_alert = 0;
static void remote_check_for_low_battery(void) {
......@@ -226,12 +189,12 @@ void remote_turn_on_som(void) {
Serial_SendByte('\r');
Delay_MS(1);
empty_serial();
anim_hello();
ux_splash();
kbd_brightness_init();
}
void remote_turn_off_som(void) {
anim_goodbye();
ux_unsplash();
empty_serial();
term_x = 0;
......@@ -634,7 +597,7 @@ void SetupHardware()
gfx_flush();
hid_report_init();
anim_hello();
ux_splash();
controller_init();
USB_Init();
......
......@@ -18,7 +18,7 @@ F_CPU = 16000000
F_USB = $(F_CPU)
OPTIMIZATION = s
TARGET = Keyboard
SRC = $(TARGET).c controller.c Descriptors.c hid_report.c i2c.c ssd1306.c text_display.c ux.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
SRC = $(TARGET).c controller.c Descriptors.c hid_report.c i2c.c ssd1306.c display.c ux.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
LUFA_PATH = ./lufa-master/LUFA
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER $(REFORM_KBD_OPTIONS) -IConfig/
LD_FLAGS = -Wl,-u,vfprintf -lprintf_flt
......
......@@ -171,19 +171,30 @@ void display_bitmap(const uint8_t *data) {
render();
}
void display_packed_bitmap(const uint8_t *data) {
static void check_effect(int i) {
if ((i & 7) != 0 || i >= sizeof(framebuffer)) return;
// draw a cursor, then render
memset(framebuffer + i, 255, 8);
render();
}
void display_packed_bitmap(const uint8_t *data, bool cursor_effect) {
int i = 0;
while (*data) {
uint8_t n = (*data) & 0x7f;
bool rle = ((*data) & 0x80) != 0;
data++;
if (rle) {
for (int j = 0; j < n; j++) framebuffer[i++] = *data;
data++;
while (true) {
uint8_t header = pgm_read_byte(data++);
if (header == 0) break;
uint8_t n = header & 0x7f;
if (header & 0x80) {
uint8_t repeat = pgm_read_byte(data++);
for (int j = 0; j < n; j++) {
framebuffer[i++] = repeat;
if (cursor_effect) check_effect(i);
}
} else {
memmove(&framebuffer[i], data, n);
data += n;
i += n;
for (int j = 0; j < n; j++) {
framebuffer[i++] = pgm_read_byte(data++);
if (cursor_effect) check_effect(i);
}
}
}
render();
......
......@@ -38,4 +38,4 @@ void display_write(const char *text);
void display_move(uint8_t x, uint8_t y);
void display_invert(bool invert);
void display_flush(void);
void display_packed_bitmap(const uint8_t *data);
void display_packed_bitmap(const uint8_t *data, bool cursor_effect);
#include <stdint.h>
#include <avr/pgmspace.h>
// in packed (simple RLE) format
const uint8_t logo_bitmap[] PROGMEM = {
0x9c, 0x00, 0x04, 0xf0, 0xe0, 0xc0, 0x80, 0x85, 0x00, 0x04, 0xf0, 0xe0,
0xc0, 0x80, 0x85, 0x00, 0x04, 0xf0, 0xe0, 0xc0, 0x80, 0xea, 0x00, 0x84,
0xff, 0x05, 0x7f, 0xfe, 0xfc, 0xf8, 0xf0, 0x84, 0xff, 0x05, 0x7f, 0xfe,
0xfc, 0xf8, 0xf0, 0x84, 0xff, 0x05, 0x7f, 0xfe, 0xfc, 0xf8, 0xf0, 0x84,
0xff, 0x87, 0x0f, 0xda, 0x00, 0x84, 0x03, 0x43, 0x00, 0x00, 0x01, 0x03,
0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f,
0x3f, 0x7f, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0x00,
0x00, 0x00, 0xff, 0xff, 0x03, 0xdb, 0xdb, 0x27, 0xff, 0x03, 0xdb, 0xdb,
0xdb, 0xff, 0x07, 0xdb, 0xdb, 0xfb, 0xff, 0x07, 0xfb, 0xfb, 0xfb, 0x07,
0xff, 0x03, 0xdb, 0xdb, 0x27, 0xff, 0x03, 0xf7, 0xef, 0xdf, 0xef, 0xf7,
0x03, 0xff, 0xff, 0xdb, 0x00, 0x07, 0x07, 0x07, 0x06, 0x07, 0x07, 0x06,
0x07, 0x84, 0x06, 0x02, 0x07, 0x06, 0x85, 0x07, 0x0b, 0x06, 0x06, 0x06,
0x07, 0x07, 0x06, 0x07, 0x07, 0x06, 0x07, 0x06, 0x85, 0x07, 0x03, 0x06,
0x07, 0x07, 0x9d, 0x00, 0x00
};
const uint8_t empty_bitmap[] PROGMEM = {
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x84, 0x00, 0x00
};
......@@ -9,97 +9,101 @@
// Write command sequence.
static inline void send_cmd1(uint8_t cmd) {
i2c_start_write(SSD1306_ADDRESS);
i2c_master_write(0x0); // Command byte
i2c_master_write(cmd);
i2c_master_stop();
i2c_start_write(SSD1306_ADDRESS);
i2c_master_write(0x0); // Command byte
i2c_master_write(cmd);
i2c_master_stop();
}
// Write 2-byte command sequence.
static inline void send_cmd2(uint8_t cmd, uint8_t opr) {
send_cmd1(cmd);
send_cmd1(opr);
send_cmd1(cmd);
send_cmd1(opr);
}
// Write 3-byte command sequence.
static inline void send_cmd3(uint8_t cmd, uint8_t opr1, uint8_t opr2) {
send_cmd1(cmd);
send_cmd1(opr1);
send_cmd1(opr2);
send_cmd1(cmd);
send_cmd1(opr1);
send_cmd1(opr2);
}
void oled_init(void) {
i2c_master_init();
send_cmd1(DisplayOff);
send_cmd2(SetDisplayClockDiv, 0x80);
send_cmd2(SetMultiPlex, DisplayHeight - 1);
i2c_master_init();
send_cmd1(DisplayOff);
send_cmd2(SetDisplayClockDiv, 0x80);
send_cmd2(SetMultiPlex, DisplayHeight - 1);
send_cmd2(SetDisplayOffset, 0);
send_cmd2(SetDisplayOffset, 0);
send_cmd1(SetStartLine | 0x0);
send_cmd2(SetChargePump, 0x14 /* Enable */);
send_cmd2(SetMemoryMode, 0 /* horizontal addressing */);
send_cmd1(SetStartLine | 0x0);
send_cmd2(SetChargePump, 0x14 /* Enable */);
send_cmd2(SetMemoryMode, 0 /* horizontal addressing */);
#if ROTATE
// the following Flip the display orientation 180 degrees
send_cmd1(SegRemap);
send_cmd1(ComScanInc);
// the following Flip the display orientation 180 degrees
send_cmd1(SegRemap);
send_cmd1(ComScanInc);
#else
// Flips the display orientation 0 degrees
send_cmd1(SegRemap | 0x1);
send_cmd1(ComScanDec);
// Flips the display orientation 0 degrees
send_cmd1(SegRemap | 0x1);
send_cmd1(ComScanDec);
#endif
send_cmd2(SetComPins, 0x2);
send_cmd2(SetContrast, 0x8f);
send_cmd2(SetPreCharge, 0xf1);
send_cmd2(SetVComDetect, 0x40);
send_cmd1(DisplayAllOnResume);
send_cmd1(NormalDisplay);
send_cmd1(DeActivateScroll);
send_cmd1(DisplayOn);
send_cmd2(SetComPins, 0x2);
send_cmd2(SetContrast, 0x8f);
send_cmd2(SetPreCharge, 0xf1);
send_cmd2(SetVComDetect, 0x40);
send_cmd1(DisplayAllOnResume);
send_cmd1(NormalDisplay);
send_cmd1(DeActivateScroll);
send_cmd1(DisplayOn);
send_cmd2(SetContrast, 0); // Dim
send_cmd2(SetContrast, 0); // Dim
// Clear all of the display bits (there can be random noise
// in the RAM on startup)
oled_clear();
// Clear all of the display bits (there can be random noise
// in the RAM on startup)
oled_clear();
}
void oled_clear(void) {
send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1);
send_cmd3(ColumnAddr, 0, DisplayWidth - 1);
send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1);
send_cmd3(ColumnAddr, 0, DisplayWidth - 1);
i2c_start_write(SSD1306_ADDRESS);
i2c_master_write(0x40);
for (int i = 0; i < DisplayHeight * DisplayWidth / 8; i++) {
i2c_master_write(0);
}
i2c_master_stop();
i2c_start_write(SSD1306_ADDRESS);
i2c_master_write(0x40);
for (int i = 0; i < DisplayHeight * DisplayWidth / 8; i++) {
i2c_master_write(0);
}
i2c_master_stop();
}
void oled_off(void) {
send_cmd1(DisplayOff);
send_cmd1(DisplayOff);
}
void oled_on(void) {
send_cmd1(NormalDisplay);
send_cmd1(DisplayOn);
send_cmd1(NormalDisplay);
send_cmd1(DisplayOn);
}
void oled_contrast(int c) {
send_cmd2(SetContrast, c);
}
void oled_home(void) {
// Move to the home position
send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1);
send_cmd3(ColumnAddr, 0, DisplayWidth - 1);
// Move to the home position
send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1);
send_cmd3(ColumnAddr, 0, DisplayWidth - 1);
}
void oled_start_render(void) {
i2c_start_write(SSD1306_ADDRESS);
i2c_master_write(0x40);
i2c_start_write(SSD1306_ADDRESS);
i2c_master_write(0x40);
}
void oled_finish_render(void) {
i2c_master_stop();
i2c_master_stop();
}
......
......@@ -77,6 +77,7 @@ void oled_init(void);
void oled_clear(void);
void oled_off(void);
void oled_on(void);
void oled_contrast(int c);
void oled_home(void);
void oled_start_render(void);
#define oled_render(_x) i2c_master_write(_x)
......
......@@ -8,8 +8,10 @@
#include <stdio.h>
#include <stdlib.h>
#include "controller.h"
#include "display.h"
#include "Keyboard.h"
#include "text_display.h"
#include "logo.h"
#include "ssd1306.h"
#include "ux.h"
// battery fullness icons: 0-5 are left, 6-11 are right
......@@ -95,3 +97,23 @@ void ux_blink_low_battery(bool blink) {
display_flush();
// display->roll = 0;
}
// display the boot logo
void ux_splash(void) {
display_clear();
display_packed_bitmap(logo_bitmap, true);
for (int i = 0; i < 0xff; i++) {
oled_contrast(i);
Delay_MS(2);
}
for (int i = 0; i < 0xff; i++) {
oled_contrast(0xff - i);
Delay_MS(2);
}
}
// wipe away the boot logo
void ux_unsplash(void) {
display_packed_bitmap(logo_bitmap, false);
display_packed_bitmap(empty_bitmap, true);
}
......@@ -7,8 +7,10 @@
#pragma once
#include "text_display.h"
#include "display.h"
void ux_show_battery(void);
void ux_show_status(void);
void ux_blink_low_battery(bool blink);
void ux_splash(void);
void ux_unsplash(void);
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