Adding Retro_Refit Keyboard Retro_Refit is an example of using a Teensy to replace a keyboard controller on an older keyboard. The original 6x15 keyboard had a non-standard 11x8 matrix.
6 files changed, 400 insertions(+), 0 deletions(-) A keyboard/retro_refit/Makefile A keyboard/retro_refit/README.md A keyboard/retro_refit/config.h A keyboard/retro_refit/keymaps/default.c A keyboard/retro_refit/retro_refit.c A keyboard/retro_refit/retro_refit.h
A keyboard/retro_refit/Makefile => keyboard/retro_refit/Makefile +139 -0
@@ 0,0 1,139 @@ #---------------------------------------------------------------------------- # On command line: # # make all = Make software. # # make clean = Clean out built project files. # # make coff = Convert ELF to AVR COFF. # # make extcoff = Convert ELF to AVR Extended COFF. # # make program = Download the hex file to the device. # Please customize your programmer settings(PROGRAM_CMD) # # make teensy = Download the hex file to the device, using teensy_loader_cli. # (must have teensy_loader_cli installed). # # make dfu = Download the hex file to the device, using dfu-programmer (must # have dfu-programmer installed). # # make flip = Download the hex file to the device, using Atmel FLIP (must # have Atmel FLIP installed). # # make dfu-ee = Download the eeprom file to the device, using dfu-programmer # (must have dfu-programmer installed). # # make flip-ee = Download the eeprom file to the device, using Atmel FLIP # (must have Atmel FLIP installed). # # make debug = Start either simulavr or avarice as specified for debugging, # with avr-gdb or avr-insight as the front end for debugging. # # make filename.s = Just compile filename.c into the assembler code only. # # make filename.i = Create a preprocessed source file for use in submitting # bug reports to the GCC project. # # To rebuild project do "make clean" then "make all". #---------------------------------------------------------------------------- # Target file name (without extension). TARGET = retro_refit # Directory common source filess exist TOP_DIR = ../.. TMK_DIR = ../../tmk_core # Directory keyboard dependent files exist TARGET_DIR = . # # project specific files SRC = retro_refit.c ifdef KEYMAP SRC := keymaps/$(KEYMAP).c $(SRC) else SRC := keymaps/default.c $(SRC) endif CONFIG_H = config.h # MCU name #MCU = at90usb1287 MCU = atmega32u4 # Processor frequency. # This will define a symbol, F_CPU, in all source code files equal to the # processor frequency in Hz. You can then use this symbol in your source code to # calculate timings. Do NOT tack on a 'UL' at the end, this will be done # automatically to create a 32-bit value in your source code. # # This will be an integer division of F_USB below, as it is sourced by # F_USB after it has run through any CPU prescalers. Note that this value # does not *change* the processor frequency - it should merely be updated to # reflect the processor speed set externally so that the code can use accurate # software delays. F_CPU = 16000000 # # LUFA specific # # Target architecture (see library "Board Types" documentation). ARCH = AVR8 # Input clock frequency. # This will define a symbol, F_USB, in all source code files equal to the # input clock frequency (before any prescaling is performed) in Hz. This value may # differ from F_CPU if prescaling is used on the latter, and is required as the # raw input clock is fed directly to the PLL sections of the AVR for high speed # clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' # at the end, this will be done automatically to create a 32-bit value in your # source code. # # If no clock division is performed on the input clock inside the AVR (via the # CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. F_USB = $(F_CPU) # Interrupt driven control endpoint task(+60) OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT # Boot Section Size in *bytes* # Teensy halfKay 512 # Teensy++ halfKay 1024 # Atmel DFU loader 4096 # LUFA bootloader 4096 # USBaspLoader 2048 OPT_DEFS += -DBOOTLOADER_SIZE=512 # Build Options # comment out to disable the options. # BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) MOUSEKEY_ENABLE = yes # Mouse keys(+4700) EXTRAKEY_ENABLE = yes # Audio control and System control(+450) CONSOLE_ENABLE = yes # Console for debug(+400) COMMAND_ENABLE = yes # Commands for debug and configuration # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE # SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend # NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work # BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality # MIDI_ENABLE = YES # MIDI controls # UNICODE_ENABLE = YES # Unicode # BLUETOOTH_ENABLE = yes # Enable Bluetooth with the Adafruit EZ-Key HID # Optimize size but this may cause error "relocation truncated to fit" #EXTRALDFLAGS = -Wl,--relax # Search Path VPATH += $(TARGET_DIR) VPATH += $(TOP_DIR) VPATH += $(TMK_DIR) include $(TOP_DIR)/quantum/quantum.mk
A keyboard/retro_refit/README.md => keyboard/retro_refit/README.md +24 -0
@@ 0,0 1,24 @@ retro_refit keyboard firmware ====================== ## Quantum MK Firmware For the full Quantum feature list, see [the parent README.md](/README.md). ## Building Download or clone the whole firmware and navigate to the keyboard/retro_refit folder. Once your dev env is setup, you'll be able to type `make` to generate your .hex - you can then use the Teensy Loader to program your .hex file. Depending on which keymap you would like to use, you will have to compile slightly differently. ### Default To build with the default keymap, simply run `make`. ### Other Keymaps Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create file named `<name>.c` and see keymap document (you can find in top README.md) and existent keymap files. To build the firmware binary hex file with a keymap just do `make` with `KEYMAP` option like: ``` $ make KEYMAP=[default|jack|<name>] ``` Keymaps follow the format **__\<name\>.c__** and are stored in the `keymaps` folder. \ No newline at end of file
A keyboard/retro_refit/config.h => keyboard/retro_refit/config.h +79 -0
@@ 0,0 1,79 @@ /* 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/>. */ #ifndef CONFIG_H #define CONFIG_H #include "config_common.h" /* USB Device descriptor parameter */ #define VENDOR_ID 0xFEED #define PRODUCT_ID 0x6060 #define DEVICE_VER 0x0001 #define MANUFACTURER Nobody #define PRODUCT retro_refit #define DESCRIPTION Retro Refit /* key matrix size */ #define MATRIX_ROWS 11 #define MATRIX_COLS 8 // See note in retro_refit.h for an explanation of how this matrix is wired up #define COLS (int []){ B0, B1, B2, B3, D2, D3, C7, D5 } #define ROWS (int []){ D4, D7, B4, B5, B6, F7, F6, F5, F4, F1, F0 } /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW /* define if matrix has ghost */ //#define MATRIX_HAS_GHOST /* number of backlight levels */ #define BACKLIGHT_LEVELS 0 /* Set 0 if debouncing isn't needed */ #define DEBOUNCE 5 /* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ #define LOCKING_SUPPORT_ENABLE /* Locking resynchronize hack */ #define LOCKING_RESYNC_ENABLE /* key combination for command */ #define IS_COMMAND() ( \ keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ ) /* * Feature disable options * These options are also useful to firmware size reduction. */ /* disable debug print */ //#define NO_DEBUG /* disable print */ //#define NO_PRINT /* disable action features */ //#define NO_ACTION_LAYER //#define NO_ACTION_TAPPING //#define NO_ACTION_ONESHOT //#define NO_ACTION_MACRO //#define NO_ACTION_FUNCTION #endif
A keyboard/retro_refit/keymaps/default.c => keyboard/retro_refit/keymaps/default.c +33 -0
@@ 0,0 1,33 @@ // This is the canonical layout file for the Quantum project. If you want to add another keyboard, // this is the style you want to emulate. #include "retro_refit.h" const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = KEYMAP( ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, NLCK, SLCK, PSCR, PAUS, \ GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS, EQL, BSPC, HOME, \ TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC, RBRC, PGUP, \ BSLS, A, S, D, F, G, H, J, K, L, SCLN, QUOT, ENT, PGDN, \ LSFT, Z, X, C, V, B, N, M, COMM, DOT, SLSH, RSFT, UP, END, \ LCTL, LGUI, LALT, SPC, INS, DEL, LEFT, DOWN, RGHT), }; const uint16_t PROGMEM fn_actions[] = { }; const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { // MACRODOWN only works in this function switch(id) { case 0: if (record->event.pressed) { register_code(KC_RSFT); } else { unregister_code(KC_RSFT); } break; } return MACRO_NONE; };
A keyboard/retro_refit/retro_refit.c => keyboard/retro_refit/retro_refit.c +80 -0
@@ 0,0 1,80 @@ #include "retro_refit.h" __attribute__ ((weak)) void * matrix_init_user(void) { // leave this function blank - it can be defined in a keymap file return NULL; }; __attribute__ ((weak)) void * matrix_scan_user(void) { // leave this function blank - it can be defined in a keymap file return NULL; }; __attribute__ ((weak)) void * led_set_user(uint8_t usb_led) { // leave this function blank - it can be defined in a keymap file return NULL; }; void * matrix_init_kb(void) { // put your keyboard start-up code here // runs once when the firmware starts up // Disable status LED on KB, enable status LED on Teensy (KB_STATUS = !TEENSY_STATUS) DDRD |= (1<<6); PORTD |= (1<<6); if (matrix_init_user) { (*matrix_init_user)(); } return NULL; }; void * matrix_scan_kb(void) { // put your looping keyboard code here // runs every cycle (a lot) if (matrix_scan_user) { (*matrix_scan_user)(); } return NULL; }; void * led_set_kb(uint8_t usb_led) { // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here if (usb_led & (1<<USB_LED_CAPS_LOCK)) { // output low DDRD |= (1<<0); PORTD &= ~(1<<0); } else { // Hi-Z DDRD &= ~(1<<0); PORTD &= ~(1<<0); } if (usb_led & (1<<USB_LED_NUM_LOCK)) { // output low DDRD |= (1<<1); PORTD &= ~(1<<1); } else { // Hi-Z DDRD &= ~(1<<1); PORTD &= ~(1<<1); } if (usb_led & (1<<USB_LED_SCROLL_LOCK)) { // output low DDRC |= (1<<6); PORTC &= ~(1<<6); } else { // Hi-Z DDRC &= ~(1<<6); PORTC &= ~(1<<6); } if (led_set_user) { (*led_set_user)(usb_led); } return NULL; }; \ No newline at end of file
A keyboard/retro_refit/retro_refit.h => keyboard/retro_refit/retro_refit.h +45 -0
@@ 0,0 1,45 @@ #ifndef RETRO_REFIT_H #define RETRO_REFIT_H #include "matrix.h" #include "keymap_common.h" #include "led.h" #include <stddef.h> // This macro is an example of using a non-standard row-column matrix. The // keyboard in question had 11 rows and 8 columns, but the rows were not all // horizontal, and the columns were not all vertical. For example, row 2 // contained "Print Screen", "N", "M", ",", ".", "/", "Right Shift", and // "Left Alt". Column 0 contained "F6", "7", "O", "'", "Q", "D", "B", // "Left Alt", "Up Arrow", and "Down Arrow". // // The macro makes programming the keys easier and in a more straight-forward // manner because it realigns the keys into a 6x15 sensible keyboard layout // instead of the obtuse 11x8 matrix. #define KEYMAP( \ K77, K05, K04, K03, K02, K01, K00, KA7, KA6, KA5, KA4, KA3, KA2, K11, K94, \ K27, K76, K75, K74, K73, K72, K71, K70, K67, K66, K65, K64, K63, K62, KA1, \ K61, K60, K57, K56, K55, K54, K53, K52, K51, K50, K47, K46, K45, K97, \ K43, K42, K41, K40, K37, K36, K35, K34, K33, K32, K31, K30, K44, K87, \ K26, K24, K23, K22, K21, K20, K17, K16, K15, K14, K13, K12, KA0, K91, \ K10, K06, K25, K07, K86, K85, K95, K90, K93 \ ) { \ { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07, }, \ { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17, }, \ { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27, }, \ { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37, }, \ { KC_##K40, KC_##K41, KC_##K42, KC_##K43, KC_##K44, KC_##K45, KC_##K46, KC_##K47, }, \ { KC_##K50, KC_##K51, KC_##K52, KC_##K53, KC_##K54, KC_##K55, KC_##K56, KC_##K57, }, \ { KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_##K66, KC_##K67, }, \ { KC_##K70, KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76, KC_##K77, }, \ { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_##K85, KC_##K86, KC_##K87, }, \ { KC_##K90, KC_##K91, KC_NO, KC_##K93, KC_##K94, KC_##K95, KC_NO, KC_##K97, }, \ { KC_##KA0, KC_##KA1, KC_##KA2, KC_##KA3, KC_##KA4, KC_##KA5, KC_##KA6, KC_##KA7, } \ } void * matrix_init_user(void); void * matrix_scan_user(void); void * led_set_user(uint8_t usb_led); #endif \ No newline at end of file