* update serial.c and add OLED * update readme * keymap fix * keymap fix2pull/4786/head
@ -1,21 +1,30 @@ | |||||
# Build Options | # Build Options | ||||
# change to "no" to disable the options, or define them in the Makefile in | # change to "no" to disable the options, or define them in the Makefile in | ||||
# the appropriate keymap folder that will get included automatically | # the appropriate keymap folder that will get included automatically | ||||
# | # | ||||
RGBLIGHT_ENABLE = no | |||||
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) | BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) | ||||
MOUSEKEY_ENABLE = no # Mouse keys(+4700) | |||||
EXTRAKEY_ENABLE = no # Audio control and System control(+450) | |||||
MOUSEKEY_ENABLE = no # Mouse keys(+4700) | |||||
EXTRAKEY_ENABLE = no # Audio control and System control(+450) | |||||
CONSOLE_ENABLE = no # Console for debug(+400) | CONSOLE_ENABLE = no # Console for debug(+400) | ||||
COMMAND_ENABLE = no # Commands for debug and configuration | |||||
COMMAND_ENABLE = no # Commands for debug and configuration | |||||
NKRO_ENABLE = no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work | NKRO_ENABLE = no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work | ||||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality | |||||
MIDI_ENABLE = no # MIDI controls | MIDI_ENABLE = no # MIDI controls | ||||
AUDIO_ENABLE = no # Audio output on port C6 | AUDIO_ENABLE = no # Audio output on port C6 | ||||
UNICODE_ENABLE = no # Unicode | UNICODE_ENABLE = no # Unicode | ||||
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID | BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID | ||||
ONEHAND_ENABLE = no # Enable one-hand typing | |||||
RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight. | |||||
SWAP_HANDS_ENABLE = no # Enable one-hand typing | |||||
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE | # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE | ||||
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend | |||||
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend | |||||
# If you want to change the display of OLED, you need to change here | |||||
SRC += ./lib/glcdfont.c \ | |||||
./lib/rgb_state_reader.c \ | |||||
./lib/layer_state_reader.c \ | |||||
./lib/logo_reader.c \ | |||||
./lib/keylogger.c \ | |||||
# ./lib/mode_icon_reader.c \ | |||||
# ./lib/host_led_state_reader.c \ | |||||
# ./lib/timelogger.c \ |
@ -1,22 +1,30 @@ | |||||
# Build Options | # Build Options | ||||
# change to "no" to disable the options, or define them in the Makefile in | # change to "no" to disable the options, or define them in the Makefile in | ||||
# the appropriate keymap folder that will get included automatically | # the appropriate keymap folder that will get included automatically | ||||
# | # | ||||
OLED_ENABLE = no | |||||
RGBLIGHT_ENABLE = no | |||||
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) | BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) | ||||
MOUSEKEY_ENABLE = no # Mouse keys(+4700) | |||||
EXTRAKEY_ENABLE = no # Audio control and System control(+450) | |||||
MOUSEKEY_ENABLE = no # Mouse keys(+4700) | |||||
EXTRAKEY_ENABLE = no # Audio control and System control(+450) | |||||
CONSOLE_ENABLE = no # Console for debug(+400) | CONSOLE_ENABLE = no # Console for debug(+400) | ||||
COMMAND_ENABLE = no # Commands for debug and configuration | |||||
COMMAND_ENABLE = no # Commands for debug and configuration | |||||
NKRO_ENABLE = no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work | NKRO_ENABLE = no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work | ||||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality | |||||
MIDI_ENABLE = no # MIDI controls | MIDI_ENABLE = no # MIDI controls | ||||
AUDIO_ENABLE = no # Audio output on port C6 | AUDIO_ENABLE = no # Audio output on port C6 | ||||
UNICODE_ENABLE = no # Unicode | UNICODE_ENABLE = no # Unicode | ||||
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID | BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID | ||||
ONEHAND_ENABLE = no # Enable one-hand typing | |||||
RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight. | |||||
SWAP_HANDS_ENABLE = no # Enable one-hand typing | |||||
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE | # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE | ||||
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend | |||||
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend | |||||
# If you want to change the display of OLED, you need to change here | |||||
SRC += ./lib/glcdfont.c \ | |||||
./lib/rgb_state_reader.c \ | |||||
./lib/layer_state_reader.c \ | |||||
./lib/logo_reader.c \ | |||||
./lib/keylogger.c \ | |||||
# ./lib/mode_icon_reader.c \ | |||||
# ./lib/host_led_state_reader.c \ | |||||
# ./lib/timelogger.c \ |
@ -0,0 +1,243 @@ | |||||
// This is the 'classic' fixed-space bitmap font for Adafruit_GFX since 1.0. | |||||
// See gfxfont.h for newer custom bitmap font info. | |||||
#ifndef FONT5X7_H | |||||
#define FONT5X7_H | |||||
#ifdef __AVR__ | |||||
#include <avr/io.h> | |||||
#include <avr/pgmspace.h> | |||||
#elif defined(ESP8266) | |||||
#include <pgmspace.h> | |||||
#else | |||||
#define PROGMEM | |||||
#endif | |||||
// Standard ASCII 5x7 font | |||||
const unsigned char font[] PROGMEM = { | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00, | |||||
0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00, | |||||
0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00, | |||||
0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x00, | |||||
0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00, | |||||
0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00, | |||||
0x00, 0x18, 0x3C, 0x18, 0x00, 0x00, | |||||
0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00, | |||||
0x00, 0x18, 0x24, 0x18, 0x00, 0x00, | |||||
0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00, | |||||
0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00, | |||||
0x26, 0x29, 0x79, 0x29, 0x26, 0x00, | |||||
0x40, 0x7F, 0x05, 0x05, 0x07, 0x00, | |||||
0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00, | |||||
0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x00, | |||||
0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00, | |||||
0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00, | |||||
0x14, 0x22, 0x7F, 0x22, 0x14, 0x00, | |||||
0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00, | |||||
0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00, | |||||
0x00, 0x66, 0x89, 0x95, 0x6A, 0x00, | |||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x00, | |||||
0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00, | |||||
0x08, 0x04, 0x7E, 0x04, 0x08, 0x00, | |||||
0x10, 0x20, 0x7E, 0x20, 0x10, 0x00, | |||||
0x08, 0x08, 0x2A, 0x1C, 0x08, 0x00, | |||||
0x08, 0x1C, 0x2A, 0x08, 0x08, 0x00, | |||||
0x1E, 0x10, 0x10, 0x10, 0x10, 0x00, | |||||
0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x00, | |||||
0x30, 0x38, 0x3E, 0x38, 0x30, 0x00, | |||||
0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, | |||||
0x00, 0x07, 0x00, 0x07, 0x00, 0x00, | |||||
0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00, | |||||
0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00, | |||||
0x23, 0x13, 0x08, 0x64, 0x62, 0x00, | |||||
0x36, 0x49, 0x56, 0x20, 0x50, 0x00, | |||||
0x00, 0x08, 0x07, 0x03, 0x00, 0x00, | |||||
0x00, 0x1C, 0x22, 0x41, 0x00, 0x00, | |||||
0x00, 0x41, 0x22, 0x1C, 0x00, 0x00, | |||||
0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00, | |||||
0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, | |||||
0x00, 0x80, 0x70, 0x30, 0x00, 0x00, | |||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x00, | |||||
0x00, 0x00, 0x60, 0x60, 0x00, 0x00, | |||||
0x20, 0x10, 0x08, 0x04, 0x02, 0x00, | |||||
0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, | |||||
0x00, 0x42, 0x7F, 0x40, 0x00, 0x00, | |||||
0x72, 0x49, 0x49, 0x49, 0x46, 0x00, | |||||
0x21, 0x41, 0x49, 0x4D, 0x33, 0x00, | |||||
0x18, 0x14, 0x12, 0x7F, 0x10, 0x00, | |||||
0x27, 0x45, 0x45, 0x45, 0x39, 0x00, | |||||
0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00, | |||||
0x41, 0x21, 0x11, 0x09, 0x07, 0x00, | |||||
0x36, 0x49, 0x49, 0x49, 0x36, 0x00, | |||||
0x46, 0x49, 0x49, 0x29, 0x1E, 0x00, | |||||
0x00, 0x00, 0x14, 0x00, 0x00, 0x00, | |||||
0x00, 0x40, 0x34, 0x00, 0x00, 0x00, | |||||
0x00, 0x08, 0x14, 0x22, 0x41, 0x00, | |||||
0x14, 0x14, 0x14, 0x14, 0x14, 0x00, | |||||
0x00, 0x41, 0x22, 0x14, 0x08, 0x00, | |||||
0x02, 0x01, 0x59, 0x09, 0x06, 0x00, | |||||
0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00, | |||||
0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00, | |||||
0x7F, 0x49, 0x49, 0x49, 0x36, 0x00, | |||||
0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, | |||||
0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00, | |||||
0x7F, 0x49, 0x49, 0x49, 0x41, 0x00, | |||||
0x7F, 0x09, 0x09, 0x09, 0x01, 0x00, | |||||
0x3E, 0x41, 0x41, 0x51, 0x73, 0x00, | |||||
0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, | |||||
0x00, 0x41, 0x7F, 0x41, 0x00, 0x00, | |||||
0x20, 0x40, 0x41, 0x3F, 0x01, 0x00, | |||||
0x7F, 0x08, 0x14, 0x22, 0x41, 0x00, | |||||
0x7F, 0x40, 0x40, 0x40, 0x40, 0x00, | |||||
0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00, | |||||
0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00, | |||||
0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00, | |||||
0x7F, 0x09, 0x09, 0x09, 0x06, 0x00, | |||||
0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00, | |||||
0x7F, 0x09, 0x19, 0x29, 0x46, 0x00, | |||||
0x26, 0x49, 0x49, 0x49, 0x32, 0x00, | |||||
0x03, 0x01, 0x7F, 0x01, 0x03, 0x00, | |||||
0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00, | |||||
0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00, | |||||
0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00, | |||||
0x63, 0x14, 0x08, 0x14, 0x63, 0x00, | |||||
0x03, 0x04, 0x78, 0x04, 0x03, 0x00, | |||||
0x61, 0x59, 0x49, 0x4D, 0x43, 0x00, | |||||
0x00, 0x7F, 0x41, 0x41, 0x41, 0x00, | |||||
0x02, 0x04, 0x08, 0x10, 0x20, 0x00, | |||||
0x00, 0x41, 0x41, 0x41, 0x7F, 0x00, | |||||
0x04, 0x02, 0x01, 0x02, 0x04, 0x00, | |||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x00, | |||||
0x00, 0x03, 0x07, 0x08, 0x00, 0x00, | |||||
0x20, 0x54, 0x54, 0x78, 0x40, 0x00, | |||||
0x7F, 0x28, 0x44, 0x44, 0x38, 0x00, | |||||
0x38, 0x44, 0x44, 0x44, 0x28, 0x00, | |||||
0x38, 0x44, 0x44, 0x28, 0x7F, 0x00, | |||||
0x38, 0x54, 0x54, 0x54, 0x18, 0x00, | |||||
0x00, 0x08, 0x7E, 0x09, 0x02, 0x00, | |||||
0x18, 0x24, 0x24, 0x1C, 0x78, 0x00, | |||||
0x7F, 0x08, 0x04, 0x04, 0x78, 0x00, | |||||
0x00, 0x44, 0x7D, 0x40, 0x00, 0x00, | |||||
0x20, 0x40, 0x40, 0x3D, 0x00, 0x00, | |||||
0x7F, 0x10, 0x28, 0x44, 0x00, 0x00, | |||||
0x00, 0x41, 0x7F, 0x40, 0x00, 0x00, | |||||
0x7C, 0x04, 0x78, 0x04, 0x78, 0x00, | |||||
0x7C, 0x08, 0x04, 0x04, 0x78, 0x00, | |||||
0x38, 0x44, 0x44, 0x44, 0x38, 0x00, | |||||
0x7C, 0x18, 0x24, 0x24, 0x18, 0x00, | |||||
0x18, 0x24, 0x24, 0x18, 0x7C, 0x00, | |||||
0x7C, 0x08, 0x04, 0x04, 0x08, 0x00, | |||||
0x48, 0x54, 0x54, 0x54, 0x24, 0x00, | |||||
0x04, 0x04, 0x3F, 0x44, 0x24, 0x00, | |||||
0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00, | |||||
0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00, | |||||
0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00, | |||||
0x44, 0x28, 0x10, 0x28, 0x44, 0x00, | |||||
0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00, | |||||
0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, | |||||
0x00, 0x08, 0x36, 0x41, 0x00, 0x00, | |||||
0x00, 0x00, 0x77, 0x00, 0x00, 0x00, | |||||
0x00, 0x41, 0x36, 0x08, 0x00, 0x00, | |||||
0x02, 0x01, 0x02, 0x04, 0x02, 0x00, | |||||
0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, | |||||
0x80, 0x80, 0x80, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x80, 0xE0, 0x70, 0x18, | |||||
0x0C, 0x18, 0x30, 0xE0, 0x80, 0x00, | |||||
0x00, 0x10, 0xF8, 0x90, 0x10, 0x30, | |||||
0x78, 0x30, 0x10, 0xB8, 0xFC, 0x38, | |||||
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0xF8, 0xFC, 0xF8, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, | |||||
0x9C, 0x1C, 0x00, 0x00, 0x00, 0x00, | |||||
0xF8, 0xFC, 0xF8, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x1C, 0xFC, 0xF8, | |||||
0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x80, 0xE0, 0xF8, 0x7C, 0x1C, | |||||
0x00, 0x00, 0x00, 0xF0, 0xFC, 0xFC, | |||||
0xFC, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, | |||||
0x1C, 0x1C, 0x1C, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0xC0, 0xF0, 0xF8, | |||||
0x38, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, | |||||
0x1C, 0x3C, 0xF8, 0xF0, 0xE0, 0x00, | |||||
0xE0, 0xF0, 0xF0, 0xF0, 0xE0, 0xEC, | |||||
0xEE, 0xF7, 0xF3, 0x70, 0x20, 0x00, | |||||
0x7C, 0x7C, 0x7C, 0x7E, 0x00, 0x7E, | |||||
0x7E, 0x7E, 0x7F, 0x7F, 0x7F, 0x00, | |||||
0x00, 0x80, 0xC0, 0xE0, 0x7E, 0x5B, | |||||
0x4F, 0x5B, 0xFE, 0xC0, 0x00, 0x00, | |||||
0xC0, 0x00, 0xDC, 0xD7, 0xDE, 0xDE, | |||||
0xDE, 0xD7, 0xDC, 0x00, 0xC0, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, | |||||
0xBC, 0xE0, 0x81, 0x81, 0x81, 0x83, | |||||
0x83, 0x82, 0x87, 0x0C, 0x18, 0x30, | |||||
0x60, 0xC0, 0x00, 0x00, 0x1F, 0xFE, | |||||
0x90, 0xB9, 0xFF, 0xBB, 0x91, 0x98, | |||||
0x3C, 0x18, 0x11, 0x13, 0x3F, 0x11, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, | |||||
0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, | |||||
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, | |||||
0x0F, 0x7F, 0xF8, 0xE0, 0x80, 0xF0, | |||||
0xFC, 0x3F, 0x0F, 0x01, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, | |||||
0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x3C, | |||||
0x78, 0xF8, 0xF0, 0xE0, 0x80, 0x00, | |||||
0x00, 0x00, 0x00, 0xC3, 0xE7, 0xFF, | |||||
0x7E, 0x3C, 0x38, 0x78, 0x78, 0x70, | |||||
0x70, 0xF8, 0xFF, 0xDF, 0x87, 0x00, | |||||
0x0F, 0x1F, 0x3F, 0x7F, 0x7F, 0x7F, | |||||
0x7F, 0x7F, 0x3F, 0x1E, 0x0C, 0x00, | |||||
0x1F, 0x1F, 0x1F, 0x3F, 0x00, 0x3F, | |||||
0x3F, 0x3F, 0x7F, 0x7F, 0x7F, 0x00, | |||||
0x30, 0x7B, 0x7F, 0x78, 0x30, 0x20, | |||||
0x20, 0x30, 0x78, 0x7F, 0x3B, 0x00, | |||||
0x03, 0x00, 0x0F, 0x7F, 0x0F, 0x0F, | |||||
0x0F, 0x7F, 0x0F, 0x00, 0x03, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x18, 0x3C, 0x24, 0x66, 0x63, 0x41, | |||||
0xC1, 0x81, 0x80, 0x80, 0x80, 0x80, | |||||
0x80, 0x80, 0x81, 0xC1, 0x41, 0x62, | |||||
0x38, 0x6C, 0x4C, 0xC6, 0x81, 0x81, | |||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x81, | |||||
0xC1, 0x43, 0x62, 0x36, 0x1C, 0x18, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0xC0, | |||||
0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, | |||||
0xC0, 0x80, 0x00, 0x00, 0x00, 0x7F, | |||||
0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, | |||||
0x7F, 0xFF, 0xFF, 0xC0, 0x80, 0x00, | |||||
0x00, 0x00, 0xE0, 0xE0, 0xC0, 0xC0, | |||||
0xC0, 0xE0, 0xF9, 0x7F, 0x1F, 0x07, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x70, 0xF0, 0xE0, | |||||
0xE0, 0xC0, 0xC0, 0xC0, 0xC0, 0xE0, | |||||
0xF0, 0xF8, 0x7F, 0x3F, 0x0F, 0x00, | |||||
0x00, 0x00, 0x0F, 0x3F, 0x7F, 0xF9, | |||||
0xE0, 0xE0, 0xC0, 0xC0, 0xC0, 0xC0, | |||||
0xC0, 0xE0, 0xF9, 0x7F, 0x3F, 0x1F, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |||||
}; | |||||
#endif // FONT5X7_H |
@ -0,0 +1,15 @@ | |||||
#include <stdio.h> | |||||
#include "lily58.h" | |||||
char host_led_state_str[24]; | |||||
const char *read_host_led_state(void) | |||||
{ | |||||
uint8_t leds = host_keyboard_leds(); | |||||
snprintf(host_led_state_str, sizeof(host_led_state_str), "NL:%s CL:%s SL:%s", | |||||
(leds & (1 << USB_LED_NUM_LOCK)) ? "on" : "- ", | |||||
(leds & (1 << USB_LED_CAPS_LOCK)) ? "on" : "- ", | |||||
(leds & (1 << USB_LED_SCROLL_LOCK)) ? "on" : "- "); | |||||
return host_led_state_str; | |||||
} |
@ -0,0 +1,45 @@ | |||||
#include <stdio.h> | |||||
#include "lily58.h" | |||||
char keylog_str[24] = {}; | |||||
char keylogs_str[21] = {}; | |||||
int keylogs_str_idx = 0; | |||||
const char code_to_name[60] = { | |||||
' ', ' ', ' ', ' ', 'a', 'b', 'c', 'd', 'e', 'f', | |||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', | |||||
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', | |||||
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', | |||||
'R', 'E', 'B', 'T', ' ', ' ', ' ', ' ', ' ', ' ', | |||||
' ', ';', '\'', ' ', ',', '.', '/', ' ', ' ', ' '}; | |||||
void set_keylog(uint16_t keycode, keyrecord_t *record) { | |||||
char name = ' '; | |||||
if (keycode < 60) { | |||||
name = code_to_name[keycode]; | |||||
} | |||||
// update keylog | |||||
snprintf(keylog_str, sizeof(keylog_str), "%dx%d, k%2d : %c", | |||||
record->event.key.row, record->event.key.col, | |||||
keycode, name); | |||||
// update keylogs | |||||
if (keylogs_str_idx == sizeof(keylogs_str) - 1) { | |||||
keylogs_str_idx = 0; | |||||
for (int i = 0; i < sizeof(keylogs_str) - 1; i++) { | |||||
keylogs_str[i] = ' '; | |||||
} | |||||
} | |||||
keylogs_str[keylogs_str_idx] = name; | |||||
keylogs_str_idx++; | |||||
} | |||||
const char *read_keylog(void) { | |||||
return keylog_str; | |||||
} | |||||
const char *read_keylogs(void) { | |||||
return keylogs_str; | |||||
} |
@ -0,0 +1,35 @@ | |||||
#include QMK_KEYBOARD_H | |||||
#include <stdio.h> | |||||
#include "lily58.h" | |||||
#define L_BASE 0 | |||||
#define L_LOWER 2 | |||||
#define L_RAISE 4 | |||||
#define L_ADJUST 65536 | |||||
#define L_ADJUST_TRI 65542 | |||||
char layer_state_str[24]; | |||||
const char *read_layer_state(void) { | |||||
switch (layer_state) | |||||
{ | |||||
case L_BASE: | |||||
snprintf(layer_state_str, sizeof(layer_state_str), "Layer: Default"); | |||||
break; | |||||
case L_RAISE: | |||||
snprintf(layer_state_str, sizeof(layer_state_str), "Layer: Raise"); | |||||
break; | |||||
case L_LOWER: | |||||
snprintf(layer_state_str, sizeof(layer_state_str), "Layer: Lower"); | |||||
break; | |||||
case L_ADJUST: | |||||
case L_ADJUST_TRI: | |||||
snprintf(layer_state_str, sizeof(layer_state_str), "Layer: Adjust"); | |||||
break; | |||||
default: | |||||
snprintf(layer_state_str, sizeof(layer_state_str), "Layer: Undef-%ld", layer_state); | |||||
} | |||||
return layer_state_str; | |||||
} |
@ -0,0 +1,11 @@ | |||||
#include "lily58.h" | |||||
const char *read_logo(void) { | |||||
static char logo[] = { | |||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, | |||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, | |||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, | |||||
0}; | |||||
return logo; | |||||
} |
@ -0,0 +1,15 @@ | |||||
#include <stdio.h> | |||||
#include "lily58.h" | |||||
char mode_icon[24]; | |||||
const char *read_mode_icon(bool swap) { | |||||
static char logo[][2][3] = {{{0x95, 0x96, 0}, {0xb5, 0xb6, 0}}, {{0x97, 0x98, 0}, {0xb7, 0xb8, 0}}}; | |||||
if (swap == false) { | |||||
snprintf(mode_icon, sizeof(mode_icon), "%s\n%s", logo[0][0], logo[0][1]); | |||||
} else { | |||||
snprintf(mode_icon, sizeof(mode_icon), "%s\n%s", logo[1][0], logo[1][1]); | |||||
} | |||||
return mode_icon; | |||||
} |
@ -0,0 +1,15 @@ | |||||
#ifdef RGBLIGHT_ENABLE | |||||
#include QMK_KEYBOARD_H | |||||
#include <stdio.h> | |||||
extern rgblight_config_t rgblight_config; | |||||
char rbf_info_str[24]; | |||||
const char *read_rgb_info(void) { | |||||
snprintf(rbf_info_str, sizeof(rbf_info_str), "%s %2d h%3d s%3d v%3d", | |||||
rgblight_config.enable ? "on" : "- ", rgblight_config.mode, | |||||
rgblight_config.hue, rgblight_config.sat, rgblight_config.val); | |||||
return rbf_info_str; | |||||
} | |||||
#endif |
@ -0,0 +1,16 @@ | |||||
#include <stdio.h> | |||||
#include "lily58.h" | |||||
char timelog_str[24] = {}; | |||||
int last_time = 0; | |||||
int elapsed_time = 0; | |||||
void set_timelog(void) { | |||||
elapsed_time = timer_elapsed(last_time); | |||||
last_time = timer_read(); | |||||
snprintf(timelog_str, sizeof(timelog_str), "lt:%5d, et:%5d", last_time, elapsed_time); | |||||
} | |||||
const char *read_timelog(void) { | |||||
return timelog_str; | |||||
} |
@ -1 +1,10 @@ | |||||
#include "lily58.h" | |||||
#include "lily58.h" | |||||
#include "ssd1306.h" | |||||
bool process_record_kb(uint16_t keycode, keyrecord_t *record) { | |||||
#ifdef SSD1306OLED | |||||
return process_record_gfx(keycode,record) && process_record_user(keycode, record); | |||||
#else | |||||
return process_record_user(keycode, record); | |||||
#endif | |||||
} |
@ -1,28 +1,5 @@ | |||||
#ifndef LILY58_H | |||||
#define LILY58_H | |||||
#include "quantum.h" | |||||
#pragma once | |||||
#ifdef KEYBOARD_lily58_rev1 | #ifdef KEYBOARD_lily58_rev1 | ||||
#include "rev1.h" | #include "rev1.h" | ||||
#endif | #endif | ||||
// Used to create a keymap using only KC_ prefixed keys | |||||
#define LAYOUT_kc( \ | |||||
L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \ | |||||
L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \ | |||||
L20, L21, L22, L23, L24, L25, R20, R21, R22, R23, R24, R25, \ | |||||
L30, L31, L32, L33, L34, L35, L45, R40, R30, R31, R32, R33, R34, R35, \ | |||||
L41, L42, L43, L44, R41, R42, R43, R44 \ | |||||
) \ | |||||
LAYOUT( \ | |||||
KC_##L00, KC_##L01, KC_##L02, KC_##L03, KC_##L04, KC_##L05, KC_##R00, KC_##R01, KC_##R02, KC_##R03, KC_##R04, KC_##R05, \ | |||||
KC_##L10, KC_##L11, KC_##L12, KC_##L13, KC_##L14, KC_##L15, KC_##R10, KC_##R11, KC_##R12, KC_##R13, KC_##R14, KC_##R15, \ | |||||
KC_##L20, KC_##L21, KC_##L22, KC_##L23, KC_##L24, KC_##L25, KC_##R20, KC_##R21, KC_##R22, KC_##R23, KC_##R24, KC_##R25, \ | |||||
KC_##L30, KC_##L31, KC_##L32, KC_##L33, KC_##L34, KC_##L35, KC_##L45, KC_##R40, KC_##R30, KC_##R31, KC_##R32, KC_##R33, KC_##R34, KC_##R35, \ | |||||
KC_##L41, KC_##L42, KC_##L43, KC_##L44, KC_##R41, KC_##R42, KC_##R43, KC_##R44 \ | |||||
) | |||||
#endif |
@ -0,0 +1,357 @@ | |||||
/* | |||||
Copyright 2012 Jun Wako <wakojun@gmail.com> | |||||
This program is free software: you can redistribute it and/or modify | |||||
it under the terms of the GNU General Public License as published by | |||||
the Free Software Foundation, either version 2 of the License, or | |||||
(at your option) any later version. | |||||
This program is distributed in the hope that it will be useful, | |||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
GNU General Public License for more details. | |||||
You should have received a copy of the GNU General Public License | |||||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
/* | |||||
* scan matrix | |||||
*/ | |||||
#include <stdint.h> | |||||
#include <stdbool.h> | |||||
#include <string.h> | |||||
#include <avr/io.h> | |||||
#include <avr/wdt.h> | |||||
#include <avr/interrupt.h> | |||||
#include <util/delay.h> | |||||
#include "print.h" | |||||
#include "debug.h" | |||||
#include "util.h" | |||||
#include "matrix.h" | |||||
#include "split_util.h" | |||||
#include "pro_micro.h" | |||||
#ifdef USE_MATRIX_I2C | |||||
# include "i2c.h" | |||||
#else // USE_SERIAL | |||||
# include "split_scomm.h" | |||||
#endif | |||||
#ifndef DEBOUNCE | |||||
# define DEBOUNCE 5 | |||||
#endif | |||||
#define ERROR_DISCONNECT_COUNT 5 | |||||
static uint8_t debouncing = DEBOUNCE; | |||||
static const int ROWS_PER_HAND = MATRIX_ROWS/2; | |||||
static uint8_t error_count = 0; | |||||
uint8_t is_master = 0 ; | |||||
static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; | |||||
static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; | |||||
/* matrix state(1:on, 0:off) */ | |||||
static matrix_row_t matrix[MATRIX_ROWS]; | |||||
static matrix_row_t matrix_debouncing[MATRIX_ROWS]; | |||||
static matrix_row_t read_cols(void); | |||||
static void init_cols(void); | |||||
static void unselect_rows(void); | |||||
static void select_row(uint8_t row); | |||||
static uint8_t matrix_master_scan(void); | |||||
__attribute__ ((weak)) | |||||
void matrix_init_kb(void) { | |||||
matrix_init_user(); | |||||
} | |||||
__attribute__ ((weak)) | |||||
void matrix_scan_kb(void) { | |||||
matrix_scan_user(); | |||||
} | |||||
__attribute__ ((weak)) | |||||
void matrix_init_user(void) { | |||||
} | |||||
__attribute__ ((weak)) | |||||
void matrix_scan_user(void) { | |||||
} | |||||
inline | |||||
uint8_t matrix_rows(void) | |||||
{ | |||||
return MATRIX_ROWS; | |||||
} | |||||
inline | |||||
uint8_t matrix_cols(void) | |||||
{ | |||||
return MATRIX_COLS; | |||||
} | |||||
void matrix_init(void) | |||||
{ | |||||
debug_enable = true; | |||||
debug_matrix = true; | |||||
debug_mouse = true; | |||||
// initialize row and col | |||||
unselect_rows(); | |||||
init_cols(); | |||||
TX_RX_LED_INIT; | |||||
TXLED0; | |||||
RXLED0; | |||||
// initialize matrix state: all keys off | |||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) { | |||||
matrix[i] = 0; | |||||
matrix_debouncing[i] = 0; | |||||
} | |||||
is_master = has_usb(); | |||||
matrix_init_quantum(); | |||||
} | |||||
uint8_t _matrix_scan(void) | |||||
{ | |||||
// Right hand is stored after the left in the matirx so, we need to offset it | |||||
int offset = isLeftHand ? 0 : (ROWS_PER_HAND); | |||||
for (uint8_t i = 0; i < ROWS_PER_HAND; i++) { | |||||
select_row(i); | |||||
_delay_us(30); // without this wait read unstable value. | |||||
matrix_row_t cols = read_cols(); | |||||
if (matrix_debouncing[i+offset] != cols) { | |||||
matrix_debouncing[i+offset] = cols; | |||||
debouncing = DEBOUNCE; | |||||
} | |||||
unselect_rows(); | |||||
} | |||||
if (debouncing) { | |||||
if (--debouncing) { | |||||
_delay_ms(1); | |||||
} else { | |||||
for (uint8_t i = 0; i < ROWS_PER_HAND; i++) { | |||||
matrix[i+offset] = matrix_debouncing[i+offset]; | |||||
} | |||||
} | |||||
} | |||||
return 1; | |||||
} | |||||
#ifdef USE_MATRIX_I2C | |||||
// Get rows from other half over i2c | |||||
int i2c_transaction(void) { | |||||
int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; | |||||
int err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE); | |||||
if (err) goto i2c_error; | |||||
// start of matrix stored at 0x00 | |||||
err = i2c_master_write(0x00); | |||||
if (err) goto i2c_error; | |||||
// Start read | |||||
err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ); | |||||
if (err) goto i2c_error; | |||||
if (!err) { | |||||
int i; | |||||
for (i = 0; i < ROWS_PER_HAND-1; ++i) { | |||||
matrix[slaveOffset+i] = i2c_master_read(I2C_ACK); | |||||
} | |||||
matrix[slaveOffset+i] = i2c_master_read(I2C_NACK); | |||||
i2c_master_stop(); | |||||
} else { | |||||
i2c_error: // the cable is disconnceted, or something else went wrong | |||||
i2c_reset_state(); | |||||
return err; | |||||
} | |||||
return 0; | |||||
} | |||||
#else // USE_SERIAL | |||||
int serial_transaction(int master_changed) { | |||||
int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; | |||||
#ifdef SERIAL_USE_MULTI_TRANSACTION | |||||
int ret=serial_update_buffers(master_changed); | |||||
#else | |||||
int ret=serial_update_buffers(); | |||||
#endif | |||||
if (ret ) { | |||||
if(ret==2) RXLED1; | |||||
return 1; | |||||
} | |||||
RXLED0; | |||||
memcpy(&matrix[slaveOffset], | |||||
(void *)serial_slave_buffer, SERIAL_SLAVE_BUFFER_LENGTH); | |||||
return 0; | |||||
} | |||||
#endif | |||||
uint8_t matrix_scan(void) | |||||
{ | |||||
if (is_master) { | |||||
matrix_master_scan(); | |||||
}else{ | |||||
matrix_slave_scan(); | |||||
int offset = (isLeftHand) ? ROWS_PER_HAND : 0; | |||||
memcpy(&matrix[offset], | |||||
(void *)serial_master_buffer, SERIAL_MASTER_BUFFER_LENGTH); | |||||
matrix_scan_quantum(); | |||||
} | |||||
return 1; | |||||
} | |||||
uint8_t matrix_master_scan(void) { | |||||
int ret = _matrix_scan(); | |||||
int mchanged = 1; | |||||
int offset = (isLeftHand) ? 0 : ROWS_PER_HAND; | |||||
#ifdef USE_MATRIX_I2C | |||||
// for (int i = 0; i < ROWS_PER_HAND; ++i) { | |||||
/* i2c_slave_buffer[i] = matrix[offset+i]; */ | |||||
// i2c_slave_buffer[i] = matrix[offset+i]; | |||||
// } | |||||
#else // USE_SERIAL | |||||
#ifdef SERIAL_USE_MULTI_TRANSACTION | |||||
mchanged = memcmp((void *)serial_master_buffer, | |||||
&matrix[offset], SERIAL_MASTER_BUFFER_LENGTH); | |||||
#endif | |||||
memcpy((void *)serial_master_buffer, | |||||
&matrix[offset], SERIAL_MASTER_BUFFER_LENGTH); | |||||
#endif | |||||
#ifdef USE_MATRIX_I2C | |||||
if( i2c_transaction() ) { | |||||
#else // USE_SERIAL | |||||
if( serial_transaction(mchanged) ) { | |||||
#endif | |||||
// turn on the indicator led when halves are disconnected | |||||
TXLED1; | |||||
error_count++; | |||||
if (error_count > ERROR_DISCONNECT_COUNT) { | |||||
// reset other half if disconnected | |||||
int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; | |||||
for (int i = 0; i < ROWS_PER_HAND; ++i) { | |||||
matrix[slaveOffset+i] = 0; | |||||
} | |||||
} | |||||
} else { | |||||
// turn off the indicator led on no error | |||||
TXLED0; | |||||
error_count = 0; | |||||
} | |||||
matrix_scan_quantum(); | |||||
return ret; | |||||
} | |||||
void matrix_slave_scan(void) { | |||||
_matrix_scan(); | |||||
int offset = (isLeftHand) ? 0 : ROWS_PER_HAND; | |||||
#ifdef USE_MATRIX_I2C | |||||
for (int i = 0; i < ROWS_PER_HAND; ++i) { | |||||
/* i2c_slave_buffer[i] = matrix[offset+i]; */ | |||||
i2c_slave_buffer[i] = matrix[offset+i]; | |||||
} | |||||
#else // USE_SERIAL | |||||
#ifdef SERIAL_USE_MULTI_TRANSACTION | |||||
int change = 0; | |||||
#endif | |||||
for (int i = 0; i < ROWS_PER_HAND; ++i) { | |||||
#ifdef SERIAL_USE_MULTI_TRANSACTION | |||||
if( serial_slave_buffer[i] != matrix[offset+i] ) | |||||
change = 1; | |||||
#endif | |||||
serial_slave_buffer[i] = matrix[offset+i]; | |||||
} | |||||
#ifdef SERIAL_USE_MULTI_TRANSACTION | |||||
slave_buffer_change_count += change; | |||||
#endif | |||||
#endif | |||||
} | |||||
bool matrix_is_modified(void) | |||||
{ | |||||
if (debouncing) return false; | |||||
return true; | |||||
} | |||||
inline | |||||
bool matrix_is_on(uint8_t row, uint8_t col) | |||||
{ | |||||
return (matrix[row] & ((matrix_row_t)1<<col)); | |||||
} | |||||
inline | |||||
matrix_row_t matrix_get_row(uint8_t row) | |||||
{ | |||||
return matrix[row]; | |||||
} | |||||
void matrix_print(void) | |||||
{ | |||||
print("\nr/c 0123456789ABCDEF\n"); | |||||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | |||||
phex(row); print(": "); | |||||
pbin_reverse16(matrix_get_row(row)); | |||||
print("\n"); | |||||
} | |||||
} | |||||
uint8_t matrix_key_count(void) | |||||
{ | |||||
uint8_t count = 0; | |||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |||||
count += bitpop16(matrix[i]); | |||||
} | |||||
return count; | |||||
} | |||||
static void init_cols(void) | |||||
{ | |||||
for(int x = 0; x < MATRIX_COLS; x++) { | |||||
_SFR_IO8((col_pins[x] >> 4) + 1) &= ~_BV(col_pins[x] & 0xF); | |||||
_SFR_IO8((col_pins[x] >> 4) + 2) |= _BV(col_pins[x] & 0xF); | |||||
} | |||||
} | |||||
static matrix_row_t read_cols(void) | |||||
{ | |||||
matrix_row_t result = 0; | |||||
for(int x = 0; x < MATRIX_COLS; x++) { | |||||
result |= (_SFR_IO8(col_pins[x] >> 4) & _BV(col_pins[x] & 0xF)) ? 0 : (1 << x); | |||||
} | |||||
return result; | |||||
} | |||||
static void unselect_rows(void) | |||||
{ | |||||
for(int x = 0; x < ROWS_PER_HAND; x++) { | |||||
_SFR_IO8((row_pins[x] >> 4) + 1) &= ~_BV(row_pins[x] & 0xF); | |||||
_SFR_IO8((row_pins[x] >> 4) + 2) |= _BV(row_pins[x] & 0xF); | |||||
} | |||||
} | |||||
static void select_row(uint8_t row) | |||||
{ | |||||
_SFR_IO8((row_pins[row] >> 4) + 1) |= _BV(row_pins[row] & 0xF); | |||||
_SFR_IO8((row_pins[row] >> 4) + 2) &= ~_BV(row_pins[row] & 0xF); | |||||
} |
@ -1,14 +1,8 @@ | |||||
#include "lily58.h" | #include "lily58.h" | ||||
void matrix_init_kb(void) { | |||||
// // green led on | |||||
// DDRD |= (1<<5); | |||||
// PORTD &= ~(1<<5); | |||||
// // orange led on | |||||
// DDRB |= (1<<0); | |||||
// PORTB &= ~(1<<0); | |||||
matrix_init_user(); | |||||
}; | |||||
#ifdef SSD1306OLED | |||||
void led_set_kb(uint8_t usb_led) { | |||||
// put your keyboard LED indicator (ex: Caps Lock LED) toggling code here | |||||
//led_set_user(usb_led); | |||||
} | |||||
#endif |
@ -1 +1,3 @@ | |||||
BACKLIGHT_ENABLE = no | |||||
SRC += rev1/matrix.c | |||||
SRC += rev1/split_util.c | |||||
SRC += rev1/split_scomm.c |
@ -0,0 +1,4 @@ | |||||
#ifndef SOFT_SERIAL_PIN | |||||
#define SOFT_SERIAL_PIN D2 | |||||
#define SERIAL_USE_MULTI_TRANSACTION | |||||
#endif |
@ -0,0 +1,91 @@ | |||||
#ifdef USE_SERIAL | |||||
#ifdef SERIAL_USE_MULTI_TRANSACTION | |||||
/* --- USE flexible API (using multi-type transaction function) --- */ | |||||
#include <stdbool.h> | |||||
#include <stdint.h> | |||||
#include <stddef.h> | |||||
#include <split_scomm.h> | |||||
#include "serial.h" | |||||
#ifdef CONSOLE_ENABLE | |||||
#include <print.h> | |||||
#endif | |||||
uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0}; | |||||
uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0}; | |||||
uint8_t volatile status_com = 0; | |||||
uint8_t volatile status1 = 0; | |||||
uint8_t slave_buffer_change_count = 0; | |||||
uint8_t s_change_old = 0xff; | |||||
uint8_t s_change_new = 0xff; | |||||
SSTD_t transactions[] = { | |||||
#define GET_SLAVE_STATUS 0 | |||||
/* master buffer not changed, only recive slave_buffer_change_count */ | |||||
{ (uint8_t *)&status_com, | |||||
0, NULL, | |||||
sizeof(slave_buffer_change_count), &slave_buffer_change_count, | |||||
}, | |||||
#define PUT_MASTER_GET_SLAVE_STATUS 1 | |||||
/* master buffer changed need send, and recive slave_buffer_change_count */ | |||||
{ (uint8_t *)&status_com, | |||||
sizeof(serial_master_buffer), (uint8_t *)serial_master_buffer, | |||||
sizeof(slave_buffer_change_count), &slave_buffer_change_count, | |||||
}, | |||||
#define GET_SLAVE_BUFFER 2 | |||||
/* recive serial_slave_buffer */ | |||||
{ (uint8_t *)&status1, | |||||
0, NULL, | |||||
sizeof(serial_slave_buffer), (uint8_t *)serial_slave_buffer | |||||
} | |||||
}; | |||||
void serial_master_init(void) | |||||
{ | |||||
soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); | |||||
} | |||||
void serial_slave_init(void) | |||||
{ | |||||
soft_serial_target_init(transactions, TID_LIMIT(transactions)); | |||||
} | |||||
// 0 => no error | |||||
// 1 => slave did not respond | |||||
// 2 => checksum error | |||||
int serial_update_buffers(int master_update) | |||||
{ | |||||
int status, smatstatus; | |||||
static int need_retry = 0; | |||||
if( s_change_old != s_change_new ) { | |||||
smatstatus = soft_serial_transaction(GET_SLAVE_BUFFER); | |||||
if( smatstatus == TRANSACTION_END ) { | |||||
s_change_old = s_change_new; | |||||
#ifdef CONSOLE_ENABLE | |||||
uprintf("slave matrix = %b %b %b %b\n", | |||||
serial_slave_buffer[0], serial_slave_buffer[1], | |||||
serial_slave_buffer[2], serial_slave_buffer[3]); | |||||
#endif | |||||
} | |||||
} else { | |||||
// serial_slave_buffer dosen't change | |||||
smatstatus = TRANSACTION_END; // dummy status | |||||
} | |||||
if( !master_update && !need_retry) { | |||||
status = soft_serial_transaction(GET_SLAVE_STATUS); | |||||
} else { | |||||
status = soft_serial_transaction(PUT_MASTER_GET_SLAVE_STATUS); | |||||
} | |||||
if( status == TRANSACTION_END ) { | |||||
s_change_new = slave_buffer_change_count; | |||||
need_retry = 0; | |||||
} else { | |||||
need_retry = 1; | |||||
} | |||||
return smatstatus; | |||||
} | |||||
#endif // SERIAL_USE_MULTI_TRANSACTION | |||||
#endif /* USE_SERIAL */ |
@ -0,0 +1,24 @@ | |||||
#ifndef SPLIT_COMM_H | |||||
#define SPLIT_COMM_H | |||||
#ifndef SERIAL_USE_MULTI_TRANSACTION | |||||
/* --- USE Simple API (OLD API, compatible with let's split serial.c) --- */ | |||||
#include "serial.h" | |||||
#else | |||||
/* --- USE flexible API (using multi-type transaction function) --- */ | |||||
// Buffers for master - slave communication | |||||
#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 | |||||
#define SERIAL_MASTER_BUFFER_LENGTH MATRIX_ROWS/2 | |||||
extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH]; | |||||
extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH]; | |||||
extern uint8_t slave_buffer_change_count; | |||||
void serial_master_init(void); | |||||
void serial_slave_init(void); | |||||
int serial_update_buffers(int master_changed); | |||||
#endif | |||||
#endif /* SPLIT_COMM_H */ |
@ -0,0 +1,70 @@ | |||||
#include <avr/io.h> | |||||
#include <avr/wdt.h> | |||||
#include <avr/power.h> | |||||
#include <avr/interrupt.h> | |||||
#include <util/delay.h> | |||||
#include <avr/eeprom.h> | |||||
#include "split_util.h" | |||||
#include "matrix.h" | |||||
#include "keyboard.h" | |||||
#ifdef USE_MATRIX_I2C | |||||
# include "i2c.h" | |||||
#else | |||||
# include "split_scomm.h" | |||||
#endif | |||||
volatile bool isLeftHand = true; | |||||
static void setup_handedness(void) { | |||||
#ifdef EE_HANDS | |||||
isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS); | |||||
#else | |||||
// I2C_MASTER_RIGHT is deprecated, use MASTER_RIGHT instead, since this works for both serial and i2c | |||||
#if defined(I2C_MASTER_RIGHT) || defined(MASTER_RIGHT) | |||||
isLeftHand = !has_usb(); | |||||
#else | |||||
isLeftHand = has_usb(); | |||||
#endif | |||||
#endif | |||||
} | |||||
static void keyboard_master_setup(void) { | |||||
#ifdef USE_MATRIX_I2C | |||||
i2c_master_init(); | |||||
#else | |||||
serial_master_init(); | |||||
#endif | |||||
} | |||||
static void keyboard_slave_setup(void) { | |||||
#ifdef USE_MATRIX_I2C | |||||
i2c_slave_init(SLAVE_I2C_ADDRESS); | |||||
#else | |||||
serial_slave_init(); | |||||
#endif | |||||
} | |||||
bool has_usb(void) { | |||||
USBCON |= (1 << OTGPADE); //enables VBUS pad | |||||
_delay_us(5); | |||||
return (USBSTA & (1<<VBUS)); //checks state of VBUS | |||||
} | |||||
void split_keyboard_setup(void) { | |||||
setup_handedness(); | |||||
if (has_usb()) { | |||||
keyboard_master_setup(); | |||||
} else { | |||||
keyboard_slave_setup(); | |||||
} | |||||
sei(); | |||||
} | |||||
// this code runs before the usb and keyboard is initialized | |||||
void matrix_setup(void) { | |||||
split_keyboard_setup(); | |||||
} |
@ -0,0 +1,19 @@ | |||||
#ifndef SPLIT_KEYBOARD_UTIL_H | |||||
#define SPLIT_KEYBOARD_UTIL_H | |||||
#include <stdbool.h> | |||||
#include "eeconfig.h" | |||||
#define SLAVE_I2C_ADDRESS 0x32 | |||||
extern volatile bool isLeftHand; | |||||
// slave version of matix scan, defined in matrix.c | |||||
void matrix_slave_scan(void); | |||||
void split_keyboard_setup(void); | |||||
bool has_usb(void); | |||||
void matrix_master_OLED_init (void); | |||||
#endif |
@ -1,8 +1,4 @@ | |||||
#define SERIAL_PIN_DDR DDRD | |||||
#define SERIAL_PIN_PORT PORTD | |||||
#define SERIAL_PIN_INPUT PIND | |||||
#define SERIAL_PIN_MASK _BV(PD2) | |||||
#define SERIAL_PIN_INTERRUPT INT2_vect | |||||
#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 | |||||
#define SERIAL_MASTER_BUFFER_LENGTH 1 | |||||
#ifndef SOFT_SERIAL_PIN | |||||
#define SOFT_SERIAL_PIN D2 | |||||
#define SERIAL_USE_MULTI_TRANSACTION | |||||
#endif |
@ -0,0 +1,344 @@ | |||||
#ifdef SSD1306OLED | |||||
#include "ssd1306.h" | |||||
#include "i2c.h" | |||||
#include <string.h> | |||||
#include "print.h" | |||||
#ifdef ADAFRUIT_BLE_ENABLE | |||||
#include "adafruit_ble.h" | |||||
#endif | |||||
#ifdef PROTOCOL_LUFA | |||||
#include "lufa.h" | |||||
#endif | |||||
#include "sendchar.h" | |||||
#include "timer.h" | |||||
static const unsigned char font[] PROGMEM; | |||||
// Set this to 1 to help diagnose early startup problems | |||||
// when testing power-on with ble. Turn it off otherwise, | |||||
// as the latency of printing most of the debug info messes | |||||
// with the matrix scan, causing keys to drop. | |||||
#define DEBUG_TO_SCREEN 0 | |||||
//static uint16_t last_battery_update; | |||||
//static uint32_t vbat; | |||||
//#define BatteryUpdateInterval 10000 /* milliseconds */ | |||||
// 'last_flush' is declared as uint16_t, | |||||
// so this must be less than 65535 | |||||
#define ScreenOffInterval 60000 /* milliseconds */ | |||||
#if DEBUG_TO_SCREEN | |||||
static uint8_t displaying; | |||||
#endif | |||||
static uint16_t last_flush; | |||||
static bool force_dirty = true; | |||||
// Write command sequence. | |||||
// Returns true on success. | |||||
static inline bool _send_cmd1(uint8_t cmd) { | |||||
bool res = false; | |||||
if (i2c_start_write(SSD1306_ADDRESS)) { | |||||
xprintf("failed to start write to %d\n", SSD1306_ADDRESS); | |||||
goto done; | |||||
} | |||||
if (i2c_master_write(0x0 /* command byte follows */)) { | |||||
print("failed to write control byte\n"); | |||||
goto done; | |||||
} | |||||
if (i2c_master_write(cmd)) { | |||||
xprintf("failed to write command %d\n", cmd); | |||||
goto done; | |||||
} | |||||
res = true; | |||||
done: | |||||
i2c_master_stop(); | |||||
return res; | |||||
} | |||||
// Write 2-byte command sequence. | |||||
// Returns true on success | |||||
static inline bool _send_cmd2(uint8_t cmd, uint8_t opr) { | |||||
if (!_send_cmd1(cmd)) { | |||||
return false; | |||||
} | |||||
return _send_cmd1(opr); | |||||
} | |||||
// Write 3-byte command sequence. | |||||
// Returns true on success | |||||
static inline bool _send_cmd3(uint8_t cmd, uint8_t opr1, uint8_t opr2) { | |||||
if (!_send_cmd1(cmd)) { | |||||
return false; | |||||
} | |||||
if (!_send_cmd1(opr1)) { | |||||
return false; | |||||
} | |||||
return _send_cmd1(opr2); | |||||
} | |||||
#define send_cmd1(c) if (!_send_cmd1(c)) {goto done;} | |||||
#define send_cmd2(c,o) if (!_send_cmd2(c,o)) {goto done;} | |||||
#define send_cmd3(c,o1,o2) if (!_send_cmd3(c,o1,o2)) {goto done;} | |||||
static void clear_display(void) { | |||||
matrix_clear(&display); | |||||
// Clear all of the display bits (there can be random noise | |||||
// in the RAM on startup) | |||||
send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1); | |||||
send_cmd3(ColumnAddr, 0, DisplayWidth - 1); | |||||
if (i2c_start_write(SSD1306_ADDRESS)) { | |||||
goto done; | |||||
} | |||||
if (i2c_master_write(0x40)) { | |||||
// Data mode | |||||
goto done; | |||||
} | |||||
for (uint8_t row = 0; row < MatrixRows; ++row) { | |||||
for (uint8_t col = 0; col < DisplayWidth; ++col) { | |||||
i2c_master_write(0); | |||||
} | |||||
} | |||||
display.dirty = false; | |||||
done: | |||||
i2c_master_stop(); | |||||
} | |||||
#if DEBUG_TO_SCREEN | |||||
#undef sendchar | |||||
static int8_t capture_sendchar(uint8_t c) { | |||||
sendchar(c); | |||||
iota_gfx_write_char(c); | |||||
if (!displaying) { | |||||
iota_gfx_flush(); | |||||
} | |||||
return 0; | |||||
} | |||||
#endif | |||||
bool iota_gfx_init(bool rotate) { | |||||
bool success = false; | |||||
i2c_master_init(); | |||||
send_cmd1(DisplayOff); | |||||
send_cmd2(SetDisplayClockDiv, 0x80); | |||||
send_cmd2(SetMultiPlex, DisplayHeight - 1); | |||||
send_cmd2(SetDisplayOffset, 0); | |||||
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); | |||||
}else{ | |||||
// Flips the display orientation 0 degrees | |||||
send_cmd1(SegRemap | 0x1); | |||||
send_cmd1(ComScanDec); | |||||
} | |||||
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 | |||||
clear_display(); | |||||
success = true; | |||||
iota_gfx_flush(); | |||||
#if DEBUG_TO_SCREEN | |||||
print_set_sendchar(capture_sendchar); | |||||
#endif | |||||
done: | |||||
return success; | |||||
} | |||||
bool iota_gfx_off(void) { | |||||
bool success = false; | |||||
send_cmd1(DisplayOff); | |||||
success = true; | |||||
done: | |||||
return success; | |||||
} | |||||
bool iota_gfx_on(void) { | |||||
bool success = false; | |||||
send_cmd1(DisplayOn); | |||||
success = true; | |||||
done: | |||||
return success; | |||||
} | |||||
void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) { | |||||
*matrix->cursor = c; | |||||
++matrix->cursor; | |||||
if (matrix->cursor - &matrix->display[0][0] == sizeof(matrix->display)) { | |||||
// We went off the end; scroll the display upwards by one line | |||||
memmove(&matrix->display[0], &matrix->display[1], | |||||
MatrixCols * (MatrixRows - 1)); | |||||
matrix->cursor = &matrix->display[MatrixRows - 1][0]; | |||||
memset(matrix->cursor, ' ', MatrixCols); | |||||
} | |||||
} | |||||
void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) { | |||||
matrix->dirty = true; | |||||
if (c == '\n') { | |||||
// Clear to end of line from the cursor and then move to the | |||||
// start of the next line | |||||
uint8_t cursor_col = (matrix->cursor - &matrix->display[0][0]) % MatrixCols; | |||||
while (cursor_col++ < MatrixCols) { | |||||
matrix_write_char_inner(matrix, ' '); | |||||
} | |||||
return; | |||||
} | |||||
matrix_write_char_inner(matrix, c); | |||||
} | |||||
void iota_gfx_write_char(uint8_t c) { | |||||
matrix_write_char(&display, c); | |||||
} | |||||
void matrix_write(struct CharacterMatrix *matrix, const char *data) { | |||||
const char *end = data + strlen(data); | |||||
while (data < end) { | |||||
matrix_write_char(matrix, *data); | |||||
++data; | |||||
} | |||||
} | |||||
void matrix_write_ln(struct CharacterMatrix *matrix, const char *data) { | |||||
char data_ln[strlen(data)+2]; | |||||
snprintf(data_ln, sizeof(data_ln), "%s\n", data); | |||||
matrix_write(matrix, data_ln); | |||||
} | |||||
void iota_gfx_write(const char *data) { | |||||
matrix_write(&display, data); | |||||
} | |||||
void matrix_write_P(struct CharacterMatrix *matrix, const char *data) { | |||||
while (true) { | |||||
uint8_t c = pgm_read_byte(data); | |||||
if (c == 0) { | |||||
return; | |||||
} | |||||
matrix_write_char(matrix, c); | |||||
++data; | |||||
} | |||||
} | |||||
void iota_gfx_write_P(const char *data) { | |||||
matrix_write_P(&display, data); | |||||
} | |||||
void matrix_clear(struct CharacterMatrix *matrix) { | |||||
memset(matrix->display, ' ', sizeof(matrix->display)); | |||||
matrix->cursor = &matrix->display[0][0]; | |||||
matrix->dirty = true; | |||||
} | |||||
void iota_gfx_clear_screen(void) { | |||||
matrix_clear(&display); | |||||
} | |||||
void matrix_render(struct CharacterMatrix *matrix) { | |||||
last_flush = timer_read(); | |||||
iota_gfx_on(); | |||||
#if DEBUG_TO_SCREEN | |||||
++displaying; | |||||
#endif | |||||
// Move to the home position | |||||
send_cmd3(PageAddr, 0, MatrixRows - 1); | |||||
send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1); | |||||
if (i2c_start_write(SSD1306_ADDRESS)) { | |||||
goto done; | |||||
} | |||||
if (i2c_master_write(0x40)) { | |||||
// Data mode | |||||
goto done; | |||||
} | |||||
for (uint8_t row = 0; row < MatrixRows; ++row) { | |||||
for (uint8_t col = 0; col < MatrixCols; ++col) { | |||||
const uint8_t *glyph = font + (matrix->display[row][col] * FontWidth); | |||||
for (uint8_t glyphCol = 0; glyphCol < FontWidth; ++glyphCol) { | |||||
uint8_t colBits = pgm_read_byte(glyph + glyphCol); | |||||
i2c_master_write(colBits); | |||||
} | |||||
// 1 column of space between chars (it's not included in the glyph) | |||||
//i2c_master_write(0); | |||||
} | |||||
} | |||||
matrix->dirty = false; | |||||
done: | |||||
i2c_master_stop(); | |||||
#if DEBUG_TO_SCREEN | |||||
--displaying; | |||||
#endif | |||||
} | |||||
void iota_gfx_flush(void) { | |||||
matrix_render(&display); | |||||
} | |||||
__attribute__ ((weak)) | |||||
void iota_gfx_task_user(void) { | |||||
} | |||||
void iota_gfx_task(void) { | |||||
iota_gfx_task_user(); | |||||
if (display.dirty|| force_dirty) { | |||||
iota_gfx_flush(); | |||||
force_dirty = false; | |||||
} | |||||
if (timer_elapsed(last_flush) > ScreenOffInterval) { | |||||
iota_gfx_off(); | |||||
} | |||||
} | |||||
bool process_record_gfx(uint16_t keycode, keyrecord_t *record) { | |||||
force_dirty = true; | |||||
return true; | |||||
} | |||||
#endif |
@ -0,0 +1,91 @@ | |||||
#pragma once | |||||
#include <stdbool.h> | |||||
#include <stdio.h> | |||||
#include "pincontrol.h" | |||||
#include "action.h" | |||||
enum ssd1306_cmds { | |||||
DisplayOff = 0xAE, | |||||
DisplayOn = 0xAF, | |||||
SetContrast = 0x81, | |||||
DisplayAllOnResume = 0xA4, | |||||
DisplayAllOn = 0xA5, | |||||
NormalDisplay = 0xA6, | |||||
InvertDisplay = 0xA7, | |||||
SetDisplayOffset = 0xD3, | |||||
SetComPins = 0xda, | |||||
SetVComDetect = 0xdb, | |||||
SetDisplayClockDiv = 0xD5, | |||||
SetPreCharge = 0xd9, | |||||
SetMultiPlex = 0xa8, | |||||
SetLowColumn = 0x00, | |||||
SetHighColumn = 0x10, | |||||
SetStartLine = 0x40, | |||||
SetMemoryMode = 0x20, | |||||
ColumnAddr = 0x21, | |||||
PageAddr = 0x22, | |||||
ComScanInc = 0xc0, | |||||
ComScanDec = 0xc8, | |||||
SegRemap = 0xa0, | |||||
SetChargePump = 0x8d, | |||||
ExternalVcc = 0x01, | |||||
SwitchCapVcc = 0x02, | |||||
ActivateScroll = 0x2f, | |||||
DeActivateScroll = 0x2e, | |||||
SetVerticalScrollArea = 0xa3, | |||||
RightHorizontalScroll = 0x26, | |||||
LeftHorizontalScroll = 0x27, | |||||
VerticalAndRightHorizontalScroll = 0x29, | |||||
VerticalAndLeftHorizontalScroll = 0x2a, | |||||
}; | |||||
// Controls the SSD1306 128x32 OLED display via i2c | |||||
#ifndef SSD1306_ADDRESS | |||||
#define SSD1306_ADDRESS 0x3C | |||||
#endif | |||||
#define DisplayHeight 32 | |||||
#define DisplayWidth 128 | |||||
#define FontHeight 8 | |||||
#define FontWidth 6 | |||||
#define MatrixRows (DisplayHeight / FontHeight) | |||||
#define MatrixCols (DisplayWidth / FontWidth) | |||||
struct CharacterMatrix { | |||||
uint8_t display[MatrixRows][MatrixCols]; | |||||
uint8_t *cursor; | |||||
bool dirty; | |||||
}; | |||||
struct CharacterMatrix display; | |||||
bool iota_gfx_init(bool rotate); | |||||
void iota_gfx_task(void); | |||||
bool iota_gfx_off(void); | |||||
bool iota_gfx_on(void); | |||||
void iota_gfx_flush(void); | |||||
void iota_gfx_write_char(uint8_t c); | |||||
void iota_gfx_write(const char *data); | |||||
void iota_gfx_write_P(const char *data); | |||||
void iota_gfx_clear_screen(void); | |||||
void iota_gfx_task_user(void); | |||||
void matrix_clear(struct CharacterMatrix *matrix); | |||||
void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c); | |||||
void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c); | |||||
void matrix_write(struct CharacterMatrix *matrix, const char *data); | |||||
void matrix_write_ln(struct CharacterMatrix *matrix, const char *data); | |||||
void matrix_write_P(struct CharacterMatrix *matrix, const char *data); | |||||
void matrix_render(struct CharacterMatrix *matrix); | |||||
bool process_record_gfx(uint16_t keycode, keyrecord_t *record); |