diff options
| author | Jack Humbert <[email protected]> | 2017-06-27 14:21:42 -0400 | 
|---|---|---|
| committer | Jack Humbert <[email protected]> | 2017-06-27 14:21:42 -0400 | 
| commit | 9f5b4e1d7a37f873acbc19b8385964121566653e (patch) | |
| tree | 78a51918d16a84148af5276170d2c30525dee661 | |
| parent | b82604dadad81872abdb9fdde18086ee69e66671 (diff) | |
| parent | 4ba9438c3f71e6ea3433be4f9e1a28d36471d247 (diff) | |
| download | qmk_firmware-9f5b4e1d7a37f873acbc19b8385964121566653e.tar.gz qmk_firmware-9f5b4e1d7a37f873acbc19b8385964121566653e.zip | |
Merge branch 'master' of https://github.com/qmk/qmk_firmware into dual_audio
56 files changed, 4466 insertions, 40 deletions
| diff --git a/docs/_summary.md b/docs/_summary.md index 8e0a6f51ca..c5e29cb520 100644 --- a/docs/_summary.md +++ b/docs/_summary.md @@ -29,3 +29,4 @@  ### Other topics  * [General FAQ](faq.md)  * [Differences from TMK](differences_from_tmk.md) +* [Using Eclipse with QMK](eclipse.md) diff --git a/keyboards/ergodox/infinity/config.h b/keyboards/ergodox/infinity/config.h index 95f713819e..25cc8af0fc 100644 --- a/keyboards/ergodox/infinity/config.h +++ b/keyboards/ergodox/infinity/config.h @@ -56,6 +56,11 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #define VISUALIZER_USER_DATA_SIZE 16 +#define LCD_DISPLAY_NUMBER 0 +#define LED_DISPLAY_NUMBER 1 + +#define LED_NUM_ROWS 7 +#define LED_NUM_COLS 7  /*   * Feature disable options   *  These options are also useful to firmware size reduction. diff --git a/keyboards/ergodox/keymaps/swedish/keymap.c b/keyboards/ergodox/keymaps/swedish/keymap.c new file mode 100644 index 0000000000..c110538e6f --- /dev/null +++ b/keyboards/ergodox/keymaps/swedish/keymap.c @@ -0,0 +1,247 @@ +/* Copyright 2017 Andreas Lindhé + * + * 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/>. + */ + +#include "ergodox.h" +#include "debug.h" +#include "action_layer.h" +#include "version.h" +#include "keymap_swedish.h" + +#define BASE 0 // default layer +#define SYMB 1 // symbols +#define MDIA 2 // media keys + +enum custom_keycodes { +  PLACEHOLDER = SAFE_RANGE, // can always be here +  EPRM, +  VRSN, +  RGB_SLD +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { +/* Keymap 0: Basic layer + * + * ,--------------------------------------------------.           ,--------------------------------------------------. + * |   ½    |   !  |  "   |  #   |  #   |  %   | LEFT |           | RIGHT|   &  |  /   |  (   |  )   |  =   |  ?     | + * |   §    |   1  |  2 @ |  3 £ |  4 $ |  5   |      |           |      |   6  |  7 { |  8 [ |  9 ] |  0 } |  + \   | + * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------| + * | Delete |   Q  |   W  |   E  |   R  |   T  |  L1  |           |  L1  |   Y  |   U  |   I  |   O  |   P  |   Å    | + * |        |      |      |      |      |      |      |           |      |      |      |      |      |      |        | + * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------| + * | Caps   |   A  |   S  |   D  |   F  |   G  |------|           |------|   H  |   J  |   K  |   L  |Ö / L2|Ä / Cmd | + * | Lock   |      |      |      |      |      | Hyper|           | Meh  |      |      |      |      |      |        | + * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------| + * | Left   |Z/Ctrl|   X  |   C  |   V  |   B  |      |           |      |   N  |   M  |   ;  |   :  |_/Ctrl| RShift | + * | Shift  |      |      |      |      |      |      |           |      |      |      |   ,  |   .  |-     |        | + * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------' + *   | '/L1 |  `   |AltShf| Left | Right|                                       |  Up  | Down |  ^   |  *   | ~L1  | + *   |      |  '   |      |      |      |                                       |      |      |      |      |      | + *   `----------------------------------'                                       `----------------------------------' + *                                        ,-------------.       ,---------------. + *                                        | App  | LGui |       | AltGr|Ctrl/Esc| + *                                 ,------|------|------|       |------+--------+------. + *                                 |      |      | Home |       | PgUp |        |      | + *                                 | Space|Back- |------|       |------|  Tab   |Enter | + *                                 |      |space | End  |       | PgDn |        |      | + *                                 `--------------------'       `----------------------' + */ +// If it accepts an argument (i.e, is a function), it doesn't need KC_. +// Otherwise, it needs KC_* +[BASE] = KEYMAP(  // layer 0 : default +    // left hand +    NO_HALF,          KC_1,           KC_2,          KC_3,    KC_4,    KC_5,   KC_LEFT, +    KC_DELT,          KC_Q,           KC_W,          KC_E,    KC_R,    KC_T,   TG(SYMB), +    KC_BSPC,          KC_A,           KC_S,          KC_D,    KC_F,    KC_G, +    KC_LSFT,          CTL_T(KC_Z),    KC_X,          KC_C,    KC_V,    KC_B,   ALL_T(KC_NO), +    LT(SYMB,NO_APOS), NO_ACUT,        LALT(KC_LSFT), KC_LEFT, KC_RGHT, +                                          ALT_T(KC_APP),  KC_LGUI, +                                                          KC_HOME, +                                           KC_SPC,KC_BSPC,KC_END, +    // right hand +         KC_RGHT,      KC_6,   KC_7,   KC_8,    KC_9,    KC_0,              NO_PLUS, +         TG(SYMB),     KC_Y,   KC_U,   KC_I,    KC_O,    KC_P,              NO_AA, +                       KC_H,   KC_J,   KC_K,    KC_L,    LT(MDIA, NO_OSLH), GUI_T(NO_AE), +         MEH_T(KC_NO), KC_N,   KC_M,   KC_COMM, KC_DOT,  CTL_T(NO_MINS),    KC_RSFT, +                               KC_UP,  KC_DOWN, NO_CIRC, NO_ASTR,           KC_FN1, +         NO_ALGR,        CTL_T(KC_ESC), +         KC_PGUP, +         KC_PGDN,KC_TAB, KC_ENT +), + +/* Keymap 1: Symbol Layer + * + * ,--------------------------------------------------.           ,--------------------------------------------------. + * |Version |  F1  |  F2  |  F3  |  F4  |  F5  |      |           |      |  F6  |  F7  |  F8  |  F9  |  F10 |   F11  | + * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------| + * |        |   !  |   @  |   {  |   }  |   |  |      |           |      |   Up |   7  |   8  |   9  |   *  |   F12  | + * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------| + * |        |   #  |   $  |   (  |   )  |   `  |------|           |------| Down |   4  |   5  |   6  |   +  |        | + * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------| + * |        |   %  |   ^  |   [  |   ]  |   ~  |      |           |      |   &  |   1  |   2  |   3  |   \  |        | + * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------' + *   |      |      |      |      |      |                                       |      |    . |   0  |   =  |      | + *   `----------------------------------'                                       `----------------------------------' + *                                        ,-------------.       ,-------------. + *                                        |Animat|      |       |Toggle|Solid | + *                                 ,------|------|------|       |------+------+------. + *                                 |Bright|Bright|      |       |      |Hue-  |Hue+  | + *                                 |ness- |ness+ |------|       |------|      |      | + *                                 |      |      |      |       |      |      |      | + *                                 `--------------------'       `--------------------' + */ +// SYMBOLS +[SYMB] = KEYMAP( +       // left hand +       VRSN,   KC_F1,  KC_F2,  KC_F3,  KC_F4,  KC_F5,  KC_TRNS, +       KC_TRNS,KC_EXLM,NO_AT,  NO_LCBR,NO_RCBR,NO_PIPE,KC_TRNS, +       KC_TRNS,KC_HASH,NO_DLR, NO_LPRN,NO_RPRN,NO_GRV, +       KC_TRNS,KC_PERC,NO_CIRC,NO_LBRC,NO_RBRC,NO_TILD,KC_TRNS, +          EPRM,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, +                                       RGB_MOD,KC_TRNS, +                                               KC_TRNS, +                               RGB_VAD,RGB_VAI,KC_TRNS, +       // right hand +       KC_TRNS, KC_F6,   KC_F7,  KC_F8,   KC_F9,   KC_F10,  KC_F11, +       KC_TRNS, KC_UP,   KC_7,   KC_8,    KC_9,    NO_ASTR, KC_F12, +                KC_DOWN, KC_4,   KC_5,    KC_6,    NO_PLUS, KC_TRNS, +       KC_TRNS, NO_AMPR, KC_1,   KC_2,    KC_3,    NO_MINS, KC_TRNS, +                         KC_TRNS,KC_DOT,  KC_0,    NO_EQL,  KC_TRNS, +       RGB_TOG, RGB_SLD, +       KC_TRNS, +       KC_TRNS, RGB_HUD, RGB_HUI +), + +/* Keymap 2: Media and mouse keys + * + * ,--------------------------------------------------.           ,--------------------------------------------------. + * |        |      |      |      |      |      |      |           |      |      |      |      |      |      |        | + * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------| + * |        |      |      | MsUp |      |      |      |           |      |      |      |      |      |      |        | + * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------| + * |        |      |MsLeft|MsDown|MsRght|      |------|           |------|      |      |      |      |      |  Play  | + * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------| + * |        |      |      |      |      |      |      |           |      |      |      | Prev | Next |      |        | + * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------' + *   |      |      |      | Lclk | Rclk |                                       |VolUp |VolDn | Mute |      |      | + *   `----------------------------------'                                       `----------------------------------' + *                                        ,-------------.       ,-------------. + *                                        |      |      |       |      |      | + *                                 ,------|------|------|       |------+------+------. + *                                 |      |      |      |       |      |      |Brwser| + *                                 |      |      |------|       |------|      |Back  | + *                                 |      |      |      |       |      |      |      | + *                                 `--------------------'       `--------------------' + */ +// MEDIA AND MOUSE +[MDIA] = KEYMAP( +       KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, +       KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, KC_TRNS, KC_TRNS, KC_TRNS, +       KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_TRNS, +       KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, +       KC_TRNS, KC_TRNS, KC_TRNS, KC_BTN1, KC_BTN2, +                                           KC_TRNS, KC_TRNS, +                                                    KC_TRNS, +                                  KC_TRNS, KC_TRNS, KC_TRNS, +    // right hand +       KC_TRNS,  KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, +       KC_TRNS,  KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, +                 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, +       KC_TRNS,  KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS, +                          KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS, +       KC_TRNS, KC_TRNS, +       KC_TRNS, +       KC_TRNS, KC_TRNS, KC_WBAK +), +}; + +const uint16_t PROGMEM fn_actions[] = { +    [1] = ACTION_LAYER_TAP_TOGGLE(SYMB)                // FN1 - Momentary Layer 1 (Symbols) +}; + +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) { +          SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION); +        } +        break; +        case 1: +        if (record->event.pressed) { // For resetting EEPROM +          eeconfig_init(); +        } +        break; +      } +    return MACRO_NONE; +}; + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { +  switch (keycode) { +    // dynamically generate these. +    case EPRM: +      if (record->event.pressed) { +        eeconfig_init(); +      } +      return false; +      break; +    case VRSN: +      if (record->event.pressed) { +        SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION); +      } +      return false; +      break; +    case RGB_SLD: +      if (record->event.pressed) { +        #ifdef RGBLIGHT_ENABLE +          rgblight_mode(1); +        #endif +      } +      return false; +      break; +  } +  return true; +} + +// Runs just one time when the keyboard initializes. +void matrix_init_user(void) { + +}; + + +// Runs constantly in the background, in a loop. +void matrix_scan_user(void) { + +    uint8_t layer = biton32(layer_state); + +    ergodox_board_led_off(); +    ergodox_right_led_1_off(); +    ergodox_right_led_2_off(); +    ergodox_right_led_3_off(); +    switch (layer) { +      // TODO: Make this relevant to the ErgoDox EZ. +        case 1: +            ergodox_right_led_1_on(); +            break; +        case 2: +            ergodox_right_led_2_on(); +            break; +        default: +            // none +            break; +    } + +}; diff --git a/keyboards/ergodox/keymaps/swedish/readme.md b/keyboards/ergodox/keymaps/swedish/readme.md new file mode 100644 index 0000000000..b5b859bce6 --- /dev/null +++ b/keyboards/ergodox/keymaps/swedish/readme.md @@ -0,0 +1,36 @@ +# Swedish (sv_SE) Qwerty layout for ErgoDox EZ, based on the Default configuration + +*NOTE:* it might still be desirable to set the software layout to sv_SE in your +OS. + +Remind me and I'll provide a picture of the layout. + +I have tried making this as close of a match I could between the [default +ErgoDox EZ configuration](https://ergodox-ez.com/pages/our-firmware) and a +standard Swedish Qwerty layout. + +## Notable differences from default: + +* There are three special character buttons (acute accent, circumflex/tilde and +  apostrophe/asterisk) that don't have any buttons to map to naturally. I've put +  these at other places: + +    * Acute accent (´) can be found in the lower left corner, conveniently +      placed to reach for making an é. + +    * Apostrophe (') was put in the lower left corner, close to acute accent. + +    * Circumflex (^) and asterisk (*) was placed in the lower right corner. + +    * Tilde (~) and diaeresis (¨) I couldn't find a good place for, so I left +      those out. I could only get the buttons to produce a single one of the +      characters. How can I get it to work properly? + +* The Alt button on right thumb was exchanged for AltGr (RAlt). + +* I changed the backslash in the numpad (layer 1) for a minus. Thought it was +  more sensible. + +* I didn't find a good place for the "<>|" button, so that one was left out. +  That is a problem that really needs to be resolved. Pipe can be found on layer +  one, however. diff --git a/keyboards/orthodox/Makefile b/keyboards/orthodox/Makefile new file mode 100644 index 0000000000..f5c87d4d65 --- /dev/null +++ b/keyboards/orthodox/Makefile @@ -0,0 +1,5 @@ +SUBPROJECT_DEFAULT = rev2 + +ifndef MAKEFILE_INCLUDED +	include ../../Makefile +endif diff --git a/keyboards/orthodox/common/glcdfont.c b/keyboards/orthodox/common/glcdfont.c new file mode 100644 index 0000000000..6f88bd23a7 --- /dev/null +++ b/keyboards/orthodox/common/glcdfont.c @@ -0,0 +1,276 @@ +// 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 + +static const unsigned char font[] PROGMEM = { +	0x00, 0x00, 0x00, 0x00, 0x00, +	0x3E, 0x5B, 0x4F, 0x5B, 0x3E, +	0x3E, 0x6B, 0x4F, 0x6B, 0x3E, +	0x1C, 0x3E, 0x7C, 0x3E, 0x1C, +	0x18, 0x3C, 0x7E, 0x3C, 0x18, +	0x1C, 0x57, 0x7D, 0x57, 0x1C, +	0x1C, 0x5E, 0x7F, 0x5E, 0x1C, +	0x00, 0x18, 0x3C, 0x18, 0x00, +	0xFF, 0xE7, 0xC3, 0xE7, 0xFF, +	0x00, 0x18, 0x24, 0x18, 0x00, +	0xFF, 0xE7, 0xDB, 0xE7, 0xFF, +	0x30, 0x48, 0x3A, 0x06, 0x0E, +	0x26, 0x29, 0x79, 0x29, 0x26, +	0x40, 0x7F, 0x05, 0x05, 0x07, +	0x40, 0x7F, 0x05, 0x25, 0x3F, +	0x5A, 0x3C, 0xE7, 0x3C, 0x5A, +	0x7F, 0x3E, 0x1C, 0x1C, 0x08, +	0x08, 0x1C, 0x1C, 0x3E, 0x7F, +	0x14, 0x22, 0x7F, 0x22, 0x14, +	0x5F, 0x5F, 0x00, 0x5F, 0x5F, +	0x06, 0x09, 0x7F, 0x01, 0x7F, +	0x00, 0x66, 0x89, 0x95, 0x6A, +	0x60, 0x60, 0x60, 0x60, 0x60, +	0x94, 0xA2, 0xFF, 0xA2, 0x94, +	0x08, 0x04, 0x7E, 0x04, 0x08, +	0x10, 0x20, 0x7E, 0x20, 0x10, +	0x08, 0x08, 0x2A, 0x1C, 0x08, +	0x08, 0x1C, 0x2A, 0x08, 0x08, +	0x1E, 0x10, 0x10, 0x10, 0x10, +	0x0C, 0x1E, 0x0C, 0x1E, 0x0C, +	0x30, 0x38, 0x3E, 0x38, 0x30, +	0x06, 0x0E, 0x3E, 0x0E, 0x06, +	0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x5F, 0x00, 0x00, +	0x00, 0x07, 0x00, 0x07, 0x00, +	0x14, 0x7F, 0x14, 0x7F, 0x14, +	0x24, 0x2A, 0x7F, 0x2A, 0x12, +	0x23, 0x13, 0x08, 0x64, 0x62, +	0x36, 0x49, 0x56, 0x20, 0x50, +	0x00, 0x08, 0x07, 0x03, 0x00, +	0x00, 0x1C, 0x22, 0x41, 0x00, +	0x00, 0x41, 0x22, 0x1C, 0x00, +	0x2A, 0x1C, 0x7F, 0x1C, 0x2A, +	0x08, 0x08, 0x3E, 0x08, 0x08, +	0x00, 0x80, 0x70, 0x30, 0x00, +	0x08, 0x08, 0x08, 0x08, 0x08, +	0x00, 0x00, 0x60, 0x60, 0x00, +	0x20, 0x10, 0x08, 0x04, 0x02, +	0x3E, 0x51, 0x49, 0x45, 0x3E, +	0x00, 0x42, 0x7F, 0x40, 0x00, +	0x72, 0x49, 0x49, 0x49, 0x46, +	0x21, 0x41, 0x49, 0x4D, 0x33, +	0x18, 0x14, 0x12, 0x7F, 0x10, +	0x27, 0x45, 0x45, 0x45, 0x39, +	0x3C, 0x4A, 0x49, 0x49, 0x31, +	0x41, 0x21, 0x11, 0x09, 0x07, +	0x36, 0x49, 0x49, 0x49, 0x36, +	0x46, 0x49, 0x49, 0x29, 0x1E, +	0x00, 0x00, 0x14, 0x00, 0x00, +	0x00, 0x40, 0x34, 0x00, 0x00, +	0x00, 0x08, 0x14, 0x22, 0x41, +	0x14, 0x14, 0x14, 0x14, 0x14, +	0x00, 0x41, 0x22, 0x14, 0x08, +	0x02, 0x01, 0x59, 0x09, 0x06, +	0x3E, 0x41, 0x5D, 0x59, 0x4E, +	0x7C, 0x12, 0x11, 0x12, 0x7C, +	0x7F, 0x49, 0x49, 0x49, 0x36, +	0x3E, 0x41, 0x41, 0x41, 0x22, +	0x7F, 0x41, 0x41, 0x41, 0x3E, +	0x7F, 0x49, 0x49, 0x49, 0x41, +	0x7F, 0x09, 0x09, 0x09, 0x01, +	0x3E, 0x41, 0x41, 0x51, 0x73, +	0x7F, 0x08, 0x08, 0x08, 0x7F, +	0x00, 0x41, 0x7F, 0x41, 0x00, +	0x20, 0x40, 0x41, 0x3F, 0x01, +	0x7F, 0x08, 0x14, 0x22, 0x41, +	0x7F, 0x40, 0x40, 0x40, 0x40, +	0x7F, 0x02, 0x1C, 0x02, 0x7F, +	0x7F, 0x04, 0x08, 0x10, 0x7F, +	0x3E, 0x41, 0x41, 0x41, 0x3E, +	0x7F, 0x09, 0x09, 0x09, 0x06, +	0x3E, 0x41, 0x51, 0x21, 0x5E, +	0x7F, 0x09, 0x19, 0x29, 0x46, +	0x26, 0x49, 0x49, 0x49, 0x32, +	0x03, 0x01, 0x7F, 0x01, 0x03, +	0x3F, 0x40, 0x40, 0x40, 0x3F, +	0x1F, 0x20, 0x40, 0x20, 0x1F, +	0x3F, 0x40, 0x38, 0x40, 0x3F, +	0x63, 0x14, 0x08, 0x14, 0x63, +	0x03, 0x04, 0x78, 0x04, 0x03, +	0x61, 0x59, 0x49, 0x4D, 0x43, +	0x00, 0x7F, 0x41, 0x41, 0x41, +	0x02, 0x04, 0x08, 0x10, 0x20, +	0x00, 0x41, 0x41, 0x41, 0x7F, +	0x04, 0x02, 0x01, 0x02, 0x04, +	0x40, 0x40, 0x40, 0x40, 0x40, +	0x00, 0x03, 0x07, 0x08, 0x00, +	0x20, 0x54, 0x54, 0x78, 0x40, +	0x7F, 0x28, 0x44, 0x44, 0x38, +	0x38, 0x44, 0x44, 0x44, 0x28, +	0x38, 0x44, 0x44, 0x28, 0x7F, +	0x38, 0x54, 0x54, 0x54, 0x18, +	0x00, 0x08, 0x7E, 0x09, 0x02, +	0x18, 0xA4, 0xA4, 0x9C, 0x78, +	0x7F, 0x08, 0x04, 0x04, 0x78, +	0x00, 0x44, 0x7D, 0x40, 0x00, +	0x20, 0x40, 0x40, 0x3D, 0x00, +	0x7F, 0x10, 0x28, 0x44, 0x00, +	0x00, 0x41, 0x7F, 0x40, 0x00, +	0x7C, 0x04, 0x78, 0x04, 0x78, +	0x7C, 0x08, 0x04, 0x04, 0x78, +	0x38, 0x44, 0x44, 0x44, 0x38, +	0xFC, 0x18, 0x24, 0x24, 0x18, +	0x18, 0x24, 0x24, 0x18, 0xFC, +	0x7C, 0x08, 0x04, 0x04, 0x08, +	0x48, 0x54, 0x54, 0x54, 0x24, +	0x04, 0x04, 0x3F, 0x44, 0x24, +	0x3C, 0x40, 0x40, 0x20, 0x7C, +	0x1C, 0x20, 0x40, 0x20, 0x1C, +	0x3C, 0x40, 0x30, 0x40, 0x3C, +	0x44, 0x28, 0x10, 0x28, 0x44, +	0x4C, 0x90, 0x90, 0x90, 0x7C, +	0x44, 0x64, 0x54, 0x4C, 0x44, +	0x00, 0x08, 0x36, 0x41, 0x00, +	0x00, 0x00, 0x77, 0x00, 0x00, +	0x00, 0x41, 0x36, 0x08, 0x00, +	0x02, 0x01, 0x02, 0x04, 0x02, +	0x3C, 0x26, 0x23, 0x26, 0x3C, +	0x1E, 0xA1, 0xA1, 0x61, 0x12, +	0x3A, 0x40, 0x40, 0x20, 0x7A, +	0x38, 0x54, 0x54, 0x55, 0x59, +	0x21, 0x55, 0x55, 0x79, 0x41, +	0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut +	0x21, 0x55, 0x54, 0x78, 0x40, +	0x20, 0x54, 0x55, 0x79, 0x40, +	0x0C, 0x1E, 0x52, 0x72, 0x12, +	0x39, 0x55, 0x55, 0x55, 0x59, +	0x39, 0x54, 0x54, 0x54, 0x59, +	0x39, 0x55, 0x54, 0x54, 0x58, +	0x00, 0x00, 0x45, 0x7C, 0x41, +	0x00, 0x02, 0x45, 0x7D, 0x42, +	0x00, 0x01, 0x45, 0x7C, 0x40, +	0x7D, 0x12, 0x11, 0x12, 0x7D, // A-umlaut +	0xF0, 0x28, 0x25, 0x28, 0xF0, +	0x7C, 0x54, 0x55, 0x45, 0x00, +	0x20, 0x54, 0x54, 0x7C, 0x54, +	0x7C, 0x0A, 0x09, 0x7F, 0x49, +	0x32, 0x49, 0x49, 0x49, 0x32, +	0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut +	0x32, 0x4A, 0x48, 0x48, 0x30, +	0x3A, 0x41, 0x41, 0x21, 0x7A, +	0x3A, 0x42, 0x40, 0x20, 0x78, +	0x00, 0x9D, 0xA0, 0xA0, 0x7D, +	0x3D, 0x42, 0x42, 0x42, 0x3D, // O-umlaut +	0x3D, 0x40, 0x40, 0x40, 0x3D, +	0x3C, 0x24, 0xFF, 0x24, 0x24, +	0x48, 0x7E, 0x49, 0x43, 0x66, +	0x2B, 0x2F, 0xFC, 0x2F, 0x2B, +	0xFF, 0x09, 0x29, 0xF6, 0x20, +	0xC0, 0x88, 0x7E, 0x09, 0x03, +	0x20, 0x54, 0x54, 0x79, 0x41, +	0x00, 0x00, 0x44, 0x7D, 0x41, +	0x30, 0x48, 0x48, 0x4A, 0x32, +	0x38, 0x40, 0x40, 0x22, 0x7A, +	0x00, 0x7A, 0x0A, 0x0A, 0x72, +	0x7D, 0x0D, 0x19, 0x31, 0x7D, +	0x26, 0x29, 0x29, 0x2F, 0x28, +	0x26, 0x29, 0x29, 0x29, 0x26, +	0x30, 0x48, 0x4D, 0x40, 0x20, +	0x38, 0x08, 0x08, 0x08, 0x08, +	0x08, 0x08, 0x08, 0x08, 0x38, +	0x2F, 0x10, 0xC8, 0xAC, 0xBA, +	0x2F, 0x10, 0x28, 0x34, 0xFA, +	0x00, 0x00, 0x7B, 0x00, 0x00, +	0x08, 0x14, 0x2A, 0x14, 0x22, +	0x22, 0x14, 0x2A, 0x14, 0x08, +	0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old code +	0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block +	0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block +	0x00, 0x00, 0x00, 0xFF, 0x00, +	0x10, 0x10, 0x10, 0xFF, 0x00, +	0x14, 0x14, 0x14, 0xFF, 0x00, +	0x10, 0x10, 0xFF, 0x00, 0xFF, +	0x10, 0x10, 0xF0, 0x10, 0xF0, +	0x14, 0x14, 0x14, 0xFC, 0x00, +	0x14, 0x14, 0xF7, 0x00, 0xFF, +	0x00, 0x00, 0xFF, 0x00, 0xFF, +	0x14, 0x14, 0xF4, 0x04, 0xFC, +	0x14, 0x14, 0x17, 0x10, 0x1F, +	0x10, 0x10, 0x1F, 0x10, 0x1F, +	0x14, 0x14, 0x14, 0x1F, 0x00, +	0x10, 0x10, 0x10, 0xF0, 0x00, +	0x00, 0x00, 0x00, 0x1F, 0x10, +	0x10, 0x10, 0x10, 0x1F, 0x10, +	0x10, 0x10, 0x10, 0xF0, 0x10, +	0x00, 0x00, 0x00, 0xFF, 0x10, +	0x10, 0x10, 0x10, 0x10, 0x10, +	0x10, 0x10, 0x10, 0xFF, 0x10, +	0x00, 0x00, 0x00, 0xFF, 0x14, +	0x00, 0x00, 0xFF, 0x00, 0xFF, +	0x00, 0x00, 0x1F, 0x10, 0x17, +	0x00, 0x00, 0xFC, 0x04, 0xF4, +	0x14, 0x14, 0x17, 0x10, 0x17, +	0x14, 0x14, 0xF4, 0x04, 0xF4, +	0x00, 0x00, 0xFF, 0x00, 0xF7, +	0x14, 0x14, 0x14, 0x14, 0x14, +	0x14, 0x14, 0xF7, 0x00, 0xF7, +	0x14, 0x14, 0x14, 0x17, 0x14, +	0x10, 0x10, 0x1F, 0x10, 0x1F, +	0x14, 0x14, 0x14, 0xF4, 0x14, +	0x10, 0x10, 0xF0, 0x10, 0xF0, +	0x00, 0x00, 0x1F, 0x10, 0x1F, +	0x00, 0x00, 0x00, 0x1F, 0x14, +	0x00, 0x00, 0x00, 0xFC, 0x14, +	0x00, 0x00, 0xF0, 0x10, 0xF0, +	0x10, 0x10, 0xFF, 0x10, 0xFF, +	0x14, 0x14, 0x14, 0xFF, 0x14, +	0x10, 0x10, 0x10, 0x1F, 0x00, +	0x00, 0x00, 0x00, 0xF0, 0x10, +	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +	0xF0, 0xF0, 0xF0, 0xF0, 0xF0, +	0xFF, 0xFF, 0xFF, 0x00, 0x00, +	0x00, 0x00, 0x00, 0xFF, 0xFF, +	0x0F, 0x0F, 0x0F, 0x0F, 0x0F, +	0x38, 0x44, 0x44, 0x38, 0x44, +	0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta +	0x7E, 0x02, 0x02, 0x06, 0x06, +	0x02, 0x7E, 0x02, 0x7E, 0x02, +	0x63, 0x55, 0x49, 0x41, 0x63, +	0x38, 0x44, 0x44, 0x3C, 0x04, +	0x40, 0x7E, 0x20, 0x1E, 0x20, +	0x06, 0x02, 0x7E, 0x02, 0x02, +	0x99, 0xA5, 0xE7, 0xA5, 0x99, +	0x1C, 0x2A, 0x49, 0x2A, 0x1C, +	0x4C, 0x72, 0x01, 0x72, 0x4C, +	0x30, 0x4A, 0x4D, 0x4D, 0x30, +	0x30, 0x48, 0x78, 0x48, 0x30, +	0xBC, 0x62, 0x5A, 0x46, 0x3D, +	0x3E, 0x49, 0x49, 0x49, 0x00, +	0x7E, 0x01, 0x01, 0x01, 0x7E, +	0x2A, 0x2A, 0x2A, 0x2A, 0x2A, +	0x44, 0x44, 0x5F, 0x44, 0x44, +	0x40, 0x51, 0x4A, 0x44, 0x40, +	0x40, 0x44, 0x4A, 0x51, 0x40, +	0x00, 0x00, 0xFF, 0x01, 0x03, +	0xE0, 0x80, 0xFF, 0x00, 0x00, +	0x08, 0x08, 0x6B, 0x6B, 0x08, +	0x36, 0x12, 0x36, 0x24, 0x36, +	0x06, 0x0F, 0x09, 0x0F, 0x06, +	0x00, 0x00, 0x18, 0x18, 0x00, +	0x00, 0x00, 0x10, 0x10, 0x00, +	0x30, 0x40, 0xFF, 0x01, 0x01, +	0x00, 0x1F, 0x01, 0x01, 0x1E, +	0x00, 0x19, 0x1D, 0x17, 0x12, +	0x00, 0x3C, 0x3C, 0x3C, 0x3C, +	0x00, 0x00, 0x00, 0x00, 0x00  // #255 NBSP +}; +#endif // FONT5X7_H diff --git a/keyboards/orthodox/config.h b/keyboards/orthodox/config.h new file mode 100644 index 0000000000..008fb09789 --- /dev/null +++ b/keyboards/orthodox/config.h @@ -0,0 +1,32 @@ +/* +Copyright 2012 Jun Wako <[email protected]> + +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" + +#ifdef SUBPROJECT_rev1 +    #include "rev1/config.h" +#endif +#ifdef SUBPROJECT_rev2 +    #include "rev2/config.h" +#endif +#ifdef SUBPROJECT_rev2fliphalf +	#include "../../rev2fliphalf/config.h" +#endif +#endif diff --git a/keyboards/orthodox/i2c.c b/keyboards/orthodox/i2c.c new file mode 100644 index 0000000000..084c890c40 --- /dev/null +++ b/keyboards/orthodox/i2c.c @@ -0,0 +1,162 @@ +#include <util/twi.h> +#include <avr/io.h> +#include <stdlib.h> +#include <avr/interrupt.h> +#include <util/twi.h> +#include <stdbool.h> +#include "i2c.h" + +#ifdef USE_I2C + +// Limits the amount of we wait for any one i2c transaction. +// Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is +// 9 bits, a single transaction will take around 90μs to complete. +// +// (F_CPU/SCL_CLOCK)  =>  # of μC cycles to transfer a bit +// poll loop takes at least 8 clock cycles to execute +#define I2C_LOOP_TIMEOUT (9+1)*(F_CPU/SCL_CLOCK)/8 + +#define BUFFER_POS_INC() (slave_buffer_pos = (slave_buffer_pos+1)%SLAVE_BUFFER_SIZE) + +volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; + +static volatile uint8_t slave_buffer_pos; +static volatile bool slave_has_register_set = false; + +// Wait for an i2c operation to finish +inline static +void i2c_delay(void) { +  uint16_t lim = 0; +  while(!(TWCR & (1<<TWINT)) && lim < I2C_LOOP_TIMEOUT) +    lim++; + +  // easier way, but will wait slightly longer +  // _delay_us(100); +} + +// Setup twi to run at 100kHz +void i2c_master_init(void) { +  // no prescaler +  TWSR = 0; +  // Set TWI clock frequency to SCL_CLOCK. Need TWBR>10. +  // Check datasheets for more info. +  TWBR = ((F_CPU/SCL_CLOCK)-16)/2; +} + +// Start a transaction with the given i2c slave address. The direction of the +// transfer is set with I2C_READ and I2C_WRITE. +// returns: 0 => success +//          1 => error +uint8_t i2c_master_start(uint8_t address) { +  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA); + +  i2c_delay(); + +  // check that we started successfully +  if ( (TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START)) +    return 1; + +  TWDR = address; +  TWCR = (1<<TWINT) | (1<<TWEN); + +  i2c_delay(); + +  if ( (TW_STATUS != TW_MT_SLA_ACK) && (TW_STATUS != TW_MR_SLA_ACK) ) +    return 1; // slave did not acknowledge +  else +    return 0; // success +} + + +// Finish the i2c transaction. +void i2c_master_stop(void) { +  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); + +  uint16_t lim = 0; +  while(!(TWCR & (1<<TWSTO)) && lim < I2C_LOOP_TIMEOUT) +    lim++; +} + +// Write one byte to the i2c slave. +// returns 0 => slave ACK +//         1 => slave NACK +uint8_t i2c_master_write(uint8_t data) { +  TWDR = data; +  TWCR = (1<<TWINT) | (1<<TWEN); + +  i2c_delay(); + +  // check if the slave acknowledged us +  return (TW_STATUS == TW_MT_DATA_ACK) ? 0 : 1; +} + +// Read one byte from the i2c slave. If ack=1 the slave is acknowledged, +// if ack=0 the acknowledge bit is not set. +// returns: byte read from i2c device +uint8_t i2c_master_read(int ack) { +  TWCR = (1<<TWINT) | (1<<TWEN) | (ack<<TWEA); + +  i2c_delay(); +  return TWDR; +} + +void i2c_reset_state(void) { +  TWCR = 0; +} + +void i2c_slave_init(uint8_t address) { +  TWAR = address << 0; // slave i2c address +  // TWEN  - twi enable +  // TWEA  - enable address acknowledgement +  // TWINT - twi interrupt flag +  // TWIE  - enable the twi interrupt +  TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN); +} + +ISR(TWI_vect); + +ISR(TWI_vect) { +  uint8_t ack = 1; +  switch(TW_STATUS) { +    case TW_SR_SLA_ACK: +      // this device has been addressed as a slave receiver +      slave_has_register_set = false; +      break; + +    case TW_SR_DATA_ACK: +      // this device has received data as a slave receiver +      // The first byte that we receive in this transaction sets the location +      // of the read/write location of the slaves memory that it exposes over +      // i2c.  After that, bytes will be written at slave_buffer_pos, incrementing +      // slave_buffer_pos after each write. +      if(!slave_has_register_set) { +        slave_buffer_pos = TWDR; +        // don't acknowledge the master if this memory loctaion is out of bounds +        if ( slave_buffer_pos >= SLAVE_BUFFER_SIZE ) { +          ack = 0; +          slave_buffer_pos = 0; +        } +        slave_has_register_set = true; +      } else { +        i2c_slave_buffer[slave_buffer_pos] = TWDR; +        BUFFER_POS_INC(); +      } +      break; + +    case TW_ST_SLA_ACK: +    case TW_ST_DATA_ACK: +      // master has addressed this device as a slave transmitter and is +      // requesting data. +      TWDR = i2c_slave_buffer[slave_buffer_pos]; +      BUFFER_POS_INC(); +      break; + +    case TW_BUS_ERROR: // something went wrong, reset twi state +      TWCR = 0; +    default: +      break; +  } +  // Reset everything, so we are ready for the next TWI interrupt +  TWCR |= (1<<TWIE) | (1<<TWINT) | (ack<<TWEA) | (1<<TWEN); +} +#endif diff --git a/keyboards/orthodox/i2c.h b/keyboards/orthodox/i2c.h new file mode 100644 index 0000000000..2af843ff60 --- /dev/null +++ b/keyboards/orthodox/i2c.h @@ -0,0 +1,50 @@ +#ifndef I2C_H +#define I2C_H + +#include <stdint.h> +#include "matrix.h" + +#ifndef F_CPU +#define F_CPU 16000000UL +#endif + +#define I2C_READ 1 +#define I2C_WRITE 0 + +#define I2C_ACK 1 +#define I2C_NACK 0 + +#define SLAVE_BUFFER_SIZE 0x10 + +// i2c SCL clock frequency +#define SCL_CLOCK  100000UL + +extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; + +void i2c_master_init(void); +uint8_t i2c_master_start(uint8_t address); +void i2c_master_stop(void); +uint8_t i2c_master_write(uint8_t data); +uint8_t i2c_master_read(int); +void i2c_reset_state(void); +void i2c_slave_init(uint8_t address); + + +static inline unsigned char i2c_start_read(unsigned char addr) { +  return i2c_master_start((addr << 1) | I2C_READ); +} + +static inline unsigned char i2c_start_write(unsigned char addr) { +  return i2c_master_start((addr << 1) | I2C_WRITE); +} + +// from SSD1306 scrips +extern unsigned char i2c_rep_start(unsigned char addr); +extern void i2c_start_wait(unsigned char addr); +extern unsigned char i2c_readAck(void); +extern unsigned char i2c_readNak(void); +extern unsigned char i2c_read(unsigned char ack); + +#define i2c_read(ack)  (ack) ? i2c_readAck() : i2c_readNak(); + +#endif diff --git a/keyboards/orthodox/keymaps/i2c/config.h b/keyboards/orthodox/keymaps/i2c/config.h new file mode 100644 index 0000000000..5425297199 --- /dev/null +++ b/keyboards/orthodox/keymaps/i2c/config.h @@ -0,0 +1,34 @@ +/* +Copyright 2012 Jun Wako <[email protected]> + +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/>. +*/ + + +#define USE_I2C + +//#define MASTER_LEFT +//#define _MASTER_RIGHT +#define EE_HANDS + + +#ifdef SUBPROJECT_rev1 +    #include "../../rev1/config.h" +#endif +#ifdef SUBPROJECT_rev2 +    #include "../../rev2/config.h" +#endif +#ifdef SUBPROJECT_rev2fliphalf +	#include "../../rev2fliphalf/config.h" +#endif diff --git a/keyboards/orthodox/keymaps/i2c/keymap.c b/keyboards/orthodox/keymaps/i2c/keymap.c new file mode 100644 index 0000000000..ed24a3a1f0 --- /dev/null +++ b/keyboards/orthodox/keymaps/i2c/keymap.c @@ -0,0 +1,132 @@ +#include "orthodox.h" +#include "action_layer.h" +#include "eeconfig.h" + +extern keymap_config_t keymap_config; + +// Each layer gets a name for readability, which is then used in the keymap matrix below. +// The underscores don't mean anything - you can have a layer called STUFF or any other name. +// Layer names don't all need to be of the same length, obviously, and you can also skip them +// entirely and just use numbers. +#define _QWERTY 0 +#define _COLEMAK 1 +#define _DVORAK 2 +#define _LOWER 3 +#define _RAISE 4 +#define _ADJUST 16 + +enum custom_keycodes { +  QWERTY = SAFE_RANGE, +  COLEMAK, +  DVORAK, +  LOWER, +  RAISE, +  ADJUST, +}; + +// Fillers to make layering more clear +#define _______ KC_TRNS +#define XXXXXXX KC_NO + +#define LS__SPC MT(MOD_LSFT, KC_SPC) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +[_QWERTY] = KEYMAP( \ +  KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,                                                                   KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_BSPC, \ +  KC_ESC,  KC_A,    KC_S,    KC_D,    KC_F,    KC_G,    KC_LEFT, XXXXXXX, KC_DOWN,          KC_UP,   XXXXXXX, KC_RIGHT,KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT, \ +  KC_LCTL, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    LOWER,   KC_BSPC, KC_ENT,           KC_RALT, LS__SPC, RAISE,   KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_LGUI \ +), + +[_LOWER] = KEYMAP( \ +  KC_TILD, KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC,                                                                KC_CIRC, KC_AMPR,    KC_ASTR,    KC_LPRN, KC_RPRN, KC_BSPC, \ +  KC_DEL,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_LCTL, XXXXXXX, _______,          _______, XXXXXXX, KC_RCTL, KC_F6,   KC_UNDS,    KC_PLUS,    KC_LCBR, KC_RCBR, KC_PIPE, \ +  _______, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  _______, _______, _______,          _______, _______, _______, KC_F12,  KC_HOME,    KC_COMM,    KC_DOT,  KC_END,  _______ \ +), + +[_RAISE] = KEYMAP( \ +  KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,                                                                   KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_BSPC, \ +  KC_DEL,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   _______, XXXXXXX, _______,          _______, XXXXXXX, _______, KC_F6,   KC_MINS, KC_EQL,  KC_LBRC, KC_RBRC, KC_BSLS, \ +  _______, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  _______, _______, _______,          _______, _______, _______, KC_F12,  KC_PGUP, KC_COMM, KC_DOT,  KC_PGDN, _______ \ +), + +[_ADJUST] =  KEYMAP( \ +  _______, RESET,   _______, _______, _______, _______,                                                                _______, _______, _______, _______, _______, KC_DEL,  \ +  _______, _______, _______, AU_ON,   AU_OFF,  AG_NORM, _______, XXXXXXX, _______,          _______, XXXXXXX, _______, AG_SWAP, QWERTY , COLEMAK, DVORAK,  _______, _______, \ +  _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY  \ +) + + +}; + +#ifdef AUDIO_ENABLE +float tone_qwerty[][2]     = SONG(QWERTY_SOUND); +float tone_dvorak[][2]     = SONG(DVORAK_SOUND); +float tone_colemak[][2]    = SONG(COLEMAK_SOUND); +#endif + +void persistent_default_layer_set(uint16_t default_layer) { +  eeconfig_update_default_layer(default_layer); +  default_layer_set(default_layer); +} + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { +  switch (keycode) { +    case QWERTY: +      if (record->event.pressed) { +        #ifdef AUDIO_ENABLE +          PLAY_NOTE_ARRAY(tone_qwerty, false, 0); +        #endif +        persistent_default_layer_set(1UL<<_QWERTY); +      } +      return false; +      break; +    case COLEMAK: +      if (record->event.pressed) { +        #ifdef AUDIO_ENABLE +          PLAY_NOTE_ARRAY(tone_colemak, false, 0); +        #endif +        persistent_default_layer_set(1UL<<_COLEMAK); +      } +      return false; +      break; +    case DVORAK: +      if (record->event.pressed) { +        #ifdef AUDIO_ENABLE +          PLAY_NOTE_ARRAY(tone_dvorak, false, 0); +        #endif +        persistent_default_layer_set(1UL<<_DVORAK); +      } +      return false; +      break; +    case LOWER: +      if (record->event.pressed) { +        layer_on(_LOWER); +        update_tri_layer(_LOWER, _RAISE, _ADJUST); +      } else { +        layer_off(_LOWER); +        update_tri_layer(_LOWER, _RAISE, _ADJUST); +      } +      return false; +      break; +    case RAISE: +      if (record->event.pressed) { +        layer_on(_RAISE); +        update_tri_layer(_LOWER, _RAISE, _ADJUST); +      } else { +        layer_off(_RAISE); +        update_tri_layer(_LOWER, _RAISE, _ADJUST); +      } +      return false; +      break; +    case ADJUST: +      if (record->event.pressed) { +        layer_on(_ADJUST); +      } else { +        layer_off(_ADJUST); +      } +      return false; +      break; +  } +  return true; +} diff --git a/keyboards/orthodox/keymaps/serial/config.h b/keyboards/orthodox/keymaps/serial/config.h new file mode 100644 index 0000000000..5169452baa --- /dev/null +++ b/keyboards/orthodox/keymaps/serial/config.h @@ -0,0 +1,34 @@ +/* +Copyright 2012 Jun Wako <[email protected]> + +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/>. +*/ + + +#define USE_SERIAL + +//#define MASTER_LEFT +//#define _MASTER_RIGHT +#define EE_HANDS + + +#ifdef SUBPROJECT_rev1 +    #include "../../rev1/config.h" +#endif +#ifdef SUBPROJECT_rev2 +    #include "../../rev2/config.h" +#endif +#ifdef SUBPROJECT_rev2fliphalf +	#include "../../rev2fliphalf/config.h" +#endif diff --git a/keyboards/orthodox/keymaps/serial/keymap.c b/keyboards/orthodox/keymaps/serial/keymap.c new file mode 100644 index 0000000000..ed24a3a1f0 --- /dev/null +++ b/keyboards/orthodox/keymaps/serial/keymap.c @@ -0,0 +1,132 @@ +#include "orthodox.h" +#include "action_layer.h" +#include "eeconfig.h" + +extern keymap_config_t keymap_config; + +// Each layer gets a name for readability, which is then used in the keymap matrix below. +// The underscores don't mean anything - you can have a layer called STUFF or any other name. +// Layer names don't all need to be of the same length, obviously, and you can also skip them +// entirely and just use numbers. +#define _QWERTY 0 +#define _COLEMAK 1 +#define _DVORAK 2 +#define _LOWER 3 +#define _RAISE 4 +#define _ADJUST 16 + +enum custom_keycodes { +  QWERTY = SAFE_RANGE, +  COLEMAK, +  DVORAK, +  LOWER, +  RAISE, +  ADJUST, +}; + +// Fillers to make layering more clear +#define _______ KC_TRNS +#define XXXXXXX KC_NO + +#define LS__SPC MT(MOD_LSFT, KC_SPC) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +[_QWERTY] = KEYMAP( \ +  KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,                                                                   KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_BSPC, \ +  KC_ESC,  KC_A,    KC_S,    KC_D,    KC_F,    KC_G,    KC_LEFT, XXXXXXX, KC_DOWN,          KC_UP,   XXXXXXX, KC_RIGHT,KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT, \ +  KC_LCTL, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    LOWER,   KC_BSPC, KC_ENT,           KC_RALT, LS__SPC, RAISE,   KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_LGUI \ +), + +[_LOWER] = KEYMAP( \ +  KC_TILD, KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC,                                                                KC_CIRC, KC_AMPR,    KC_ASTR,    KC_LPRN, KC_RPRN, KC_BSPC, \ +  KC_DEL,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_LCTL, XXXXXXX, _______,          _______, XXXXXXX, KC_RCTL, KC_F6,   KC_UNDS,    KC_PLUS,    KC_LCBR, KC_RCBR, KC_PIPE, \ +  _______, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  _______, _______, _______,          _______, _______, _______, KC_F12,  KC_HOME,    KC_COMM,    KC_DOT,  KC_END,  _______ \ +), + +[_RAISE] = KEYMAP( \ +  KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,                                                                   KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_BSPC, \ +  KC_DEL,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   _______, XXXXXXX, _______,          _______, XXXXXXX, _______, KC_F6,   KC_MINS, KC_EQL,  KC_LBRC, KC_RBRC, KC_BSLS, \ +  _______, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  _______, _______, _______,          _______, _______, _______, KC_F12,  KC_PGUP, KC_COMM, KC_DOT,  KC_PGDN, _______ \ +), + +[_ADJUST] =  KEYMAP( \ +  _______, RESET,   _______, _______, _______, _______,                                                                _______, _______, _______, _______, _______, KC_DEL,  \ +  _______, _______, _______, AU_ON,   AU_OFF,  AG_NORM, _______, XXXXXXX, _______,          _______, XXXXXXX, _______, AG_SWAP, QWERTY , COLEMAK, DVORAK,  _______, _______, \ +  _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY  \ +) + + +}; + +#ifdef AUDIO_ENABLE +float tone_qwerty[][2]     = SONG(QWERTY_SOUND); +float tone_dvorak[][2]     = SONG(DVORAK_SOUND); +float tone_colemak[][2]    = SONG(COLEMAK_SOUND); +#endif + +void persistent_default_layer_set(uint16_t default_layer) { +  eeconfig_update_default_layer(default_layer); +  default_layer_set(default_layer); +} + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { +  switch (keycode) { +    case QWERTY: +      if (record->event.pressed) { +        #ifdef AUDIO_ENABLE +          PLAY_NOTE_ARRAY(tone_qwerty, false, 0); +        #endif +        persistent_default_layer_set(1UL<<_QWERTY); +      } +      return false; +      break; +    case COLEMAK: +      if (record->event.pressed) { +        #ifdef AUDIO_ENABLE +          PLAY_NOTE_ARRAY(tone_colemak, false, 0); +        #endif +        persistent_default_layer_set(1UL<<_COLEMAK); +      } +      return false; +      break; +    case DVORAK: +      if (record->event.pressed) { +        #ifdef AUDIO_ENABLE +          PLAY_NOTE_ARRAY(tone_dvorak, false, 0); +        #endif +        persistent_default_layer_set(1UL<<_DVORAK); +      } +      return false; +      break; +    case LOWER: +      if (record->event.pressed) { +        layer_on(_LOWER); +        update_tri_layer(_LOWER, _RAISE, _ADJUST); +      } else { +        layer_off(_LOWER); +        update_tri_layer(_LOWER, _RAISE, _ADJUST); +      } +      return false; +      break; +    case RAISE: +      if (record->event.pressed) { +        layer_on(_RAISE); +        update_tri_layer(_LOWER, _RAISE, _ADJUST); +      } else { +        layer_off(_RAISE); +        update_tri_layer(_LOWER, _RAISE, _ADJUST); +      } +      return false; +      break; +    case ADJUST: +      if (record->event.pressed) { +        layer_on(_ADJUST); +      } else { +        layer_off(_ADJUST); +      } +      return false; +      break; +  } +  return true; +} diff --git a/keyboards/orthodox/matrix.c b/keyboards/orthodox/matrix.c new file mode 100644 index 0000000000..3b60cead84 --- /dev/null +++ b/keyboards/orthodox/matrix.c @@ -0,0 +1,351 @@ +/* +Copyright 2012 Jun Wako <[email protected]> + +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> +#ifdef USE_I2C +// provides memcpy for copying TWI slave buffer +// #include <string.h> +#endif +#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" +#include "config.h" + +#ifdef USE_I2C +#  include "i2c.h" +#else // USE_SERIAL +#  include "serial.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; + +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); + +__attribute__ ((weak)) +void matrix_init_quantum(void) { +    matrix_init_kb(); +} + +__attribute__ ((weak)) +void matrix_scan_quantum(void) { +    matrix_scan_kb(); +} + +__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; + +    // initialize matrix state: all keys off +    for (uint8_t i=0; i < MATRIX_ROWS; i++) { +        matrix[i] = 0; +        matrix_debouncing[i] = 0; +    } + +    matrix_init_quantum(); +} + +uint8_t _matrix_scan(void) +{ +    // Right hand is stored after the left in the matrix 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_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) { +        /* +        // read from TWI byte-by-byte into matrix_row_t memory space +        size_t i; +        for (i = 0; i < SLAVE_BUFFER_SIZE-1; ++i) { +            *((uint8_t*)&matrix[slaveOffset]+i) = i2c_master_read(I2C_ACK); +        } +        // last byte to be read / end of chunk +        *((uint8_t*)&matrix[slaveOffset]+i) = i2c_master_read(I2C_NACK); +        */ + +        // kludge for column #9: unpack bits for keys (2,9) and (3,9) from (1,7) and (1,8) +        // i2c_master_read(I2C_ACK); +        matrix[slaveOffset+0] = i2c_master_read(I2C_ACK); +        // i2c_master_read(I2C_ACK); +        matrix[slaveOffset+1] = (matrix_row_t)i2c_master_read(I2C_ACK)\ +                                | (matrix[slaveOffset+0]&0x40U)<<2; +        // i2c_master_read(I2C_ACK); +        matrix[slaveOffset+2] = (matrix_row_t)i2c_master_read(I2C_NACK)\ +                                | (matrix[slaveOffset+0]&0x80U)<<1; +        // clear highest two bits on row 1, where the col9 bits were transported +        matrix[slaveOffset+0] &= 0x3F; + +        i2c_master_stop(); +    } else { +i2c_error: // the cable is disconnected, or something else went wrong +        i2c_reset_state(); +        return err; +    } + +    return 0; +} + +#else // USE_SERIAL + +int serial_transaction(void) { +    int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; + +    if (serial_update_buffers()) { +        return 1; +    } + +    for (int i = 0; i < ROWS_PER_HAND; ++i) { +        matrix[slaveOffset+i] = serial_slave_buffer[i]; +    } +    return 0; +} +#endif + +uint8_t matrix_scan(void) +{ +    int ret = _matrix_scan(); + + + +#ifdef USE_I2C +    if( i2c_transaction() ) { +#else // USE_SERIAL +    if( serial_transaction() ) { +#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_I2C +    // SLAVE_BUFFER_SIZE is from i2c.h +    // (MATRIX_ROWS/2*sizeof(matrix_row_t)) +    // memcpy((void*)i2c_slave_buffer, (const void*)&matrix[offset], (ROWS_PER_HAND*sizeof(matrix_row_t))); + +    // kludge for column #9: put bits for keys (2,9) and (3,9) into (1,7) and (1,8) +    i2c_slave_buffer[0] = (uint8_t)(matrix[offset+0])\ +                          | (matrix[offset+1]&0x100U)>>2\ +                          | (matrix[offset+2]&0x100U)>>1; +    i2c_slave_buffer[1] = (uint8_t)(matrix[offset+1]); +    i2c_slave_buffer[2] = (uint8_t)(matrix[offset+2]); +    // note: looks like a possible operator-precedence bug here, in last version? +    /* +    i2c_slave_buffer[1] = (uint8_t)matrix[offset+0]; +    i2c_slave_buffer[2] = (uint8_t)(matrix[offset+1]>>8); +    i2c_slave_buffer[3] = (uint8_t)(matrix[offset+1]>>8); +    i2c_slave_buffer[4] = (uint8_t)(matrix[offset+2]>>8); +    i2c_slave_buffer[5] = (uint8_t)matrix[offset+2]; +    */ +#else // USE_SERIAL +    for (int i = 0; i < ROWS_PER_HAND; ++i) { +        serial_slave_buffer[i] = matrix[offset+i]; +    } +#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); +} diff --git a/keyboards/orthodox/orthodox.c b/keyboards/orthodox/orthodox.c new file mode 100644 index 0000000000..0b366e9449 --- /dev/null +++ b/keyboards/orthodox/orthodox.c @@ -0,0 +1 @@ +#include "orthodox.h"
\ No newline at end of file diff --git a/keyboards/orthodox/orthodox.h b/keyboards/orthodox/orthodox.h new file mode 100644 index 0000000000..bb7efb6ad1 --- /dev/null +++ b/keyboards/orthodox/orthodox.h @@ -0,0 +1,30 @@ +#ifndef ORTHODOX_H +#define ORTHODOX_H + +#ifdef SUBPROJECT_rev1 +    #include "rev1.h" +#endif +#ifdef SUBPROJECT_rev2 +    #include "rev2.h" +#endif +#ifdef SUBPROJECT_rev2fliphalf +	#include "rev2fliphalf.h" +#endif + +// Used to create a keymap using only KC_ prefixed keys +#define KC_KEYMAP( \ +    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, R30, R31, R32, R33, R34, R35 \ +    ) \ +    KEYMAP( \ +        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_##R30, KC_##R31, KC_##R32, KC_##R33, KC_##R34, KC_##R35 \ +    ) + +#include "quantum.h" + +#endif
\ No newline at end of file diff --git a/keyboards/orthodox/pro_micro.h b/keyboards/orthodox/pro_micro.h new file mode 100644 index 0000000000..f9e7ed75d9 --- /dev/null +++ b/keyboards/orthodox/pro_micro.h @@ -0,0 +1,362 @@ +/* +  pins_arduino.h - Pin definition functions for Arduino +  Part of Arduino - http://www.arduino.cc/ + +  Copyright (c) 2007 David A. Mellis + +  This library is free software; you can redistribute it and/or +  modify it under the terms of the GNU Lesser General Public +  License as published by the Free Software Foundation; either +  version 2.1 of the License, or (at your option) any later version. + +  This library 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 +  Lesser General Public License for more details. + +  You should have received a copy of the GNU Lesser General +  Public License along with this library; if not, write to the +  Free Software Foundation, Inc., 59 Temple Place, Suite 330, +  Boston, MA  02111-1307  USA + +  $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $ +*/ + +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include <avr/pgmspace.h> + +// Workaround for wrong definitions in "iom32u4.h". +// This should be fixed in the AVR toolchain. +#undef UHCON +#undef UHINT +#undef UHIEN +#undef UHADDR +#undef UHFNUM +#undef UHFNUML +#undef UHFNUMH +#undef UHFLEN +#undef UPINRQX +#undef UPINTX +#undef UPNUM +#undef UPRST +#undef UPCONX +#undef UPCFG0X +#undef UPCFG1X +#undef UPSTAX +#undef UPCFG2X +#undef UPIENX +#undef UPDATX +#undef TCCR2A +#undef WGM20 +#undef WGM21 +#undef COM2B0 +#undef COM2B1 +#undef COM2A0 +#undef COM2A1 +#undef TCCR2B +#undef CS20 +#undef CS21 +#undef CS22 +#undef WGM22 +#undef FOC2B +#undef FOC2A +#undef TCNT2 +#undef TCNT2_0 +#undef TCNT2_1 +#undef TCNT2_2 +#undef TCNT2_3 +#undef TCNT2_4 +#undef TCNT2_5 +#undef TCNT2_6 +#undef TCNT2_7 +#undef OCR2A +#undef OCR2_0 +#undef OCR2_1 +#undef OCR2_2 +#undef OCR2_3 +#undef OCR2_4 +#undef OCR2_5 +#undef OCR2_6 +#undef OCR2_7 +#undef OCR2B +#undef OCR2_0 +#undef OCR2_1 +#undef OCR2_2 +#undef OCR2_3 +#undef OCR2_4 +#undef OCR2_5 +#undef OCR2_6 +#undef OCR2_7 + +#define NUM_DIGITAL_PINS  30 +#define NUM_ANALOG_INPUTS 12 + +#define TX_RX_LED_INIT  DDRD |= (1<<5), DDRB |= (1<<0) +#define TXLED0          PORTD |= (1<<5) +#define TXLED1          PORTD &= ~(1<<5) +#define RXLED0          PORTB |= (1<<0) +#define RXLED1          PORTB &= ~(1<<0) + +static const uint8_t SDA = 2; +static const uint8_t SCL = 3; +#define LED_BUILTIN 13 + +// Map SPI port to 'new' pins D14..D17 +static const uint8_t SS   = 17; +static const uint8_t MOSI = 16; +static const uint8_t MISO = 14; +static const uint8_t SCK  = 15; + +// Mapping of analog pins as digital I/O +// A6-A11 share with digital pins +static const uint8_t ADC0 = 18; +static const uint8_t ADC1 = 19; +static const uint8_t ADC2 = 20; +static const uint8_t ADC3 = 21; +static const uint8_t ADC4 = 22; +static const uint8_t ADC5 = 23; +static const uint8_t ADC6 = 24;   // D4 +static const uint8_t ADC7 = 25;   // D6 +static const uint8_t ADC8 = 26;   // D8 +static const uint8_t ADC9 = 27;   // D9 +static const uint8_t ADC10 = 28;  // D10 +static const uint8_t ADC11 = 29;  // D12 + +#define digitalPinToPCICR(p)    ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCICR) : ((uint8_t *)0)) +#define digitalPinToPCICRbit(p) 0 +#define digitalPinToPCMSK(p)    ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCMSK0) : ((uint8_t *)0)) +#define digitalPinToPCMSKbit(p) ( ((p) >= 8 && (p) <= 11) ? (p) - 4 : ((p) == 14 ? 3 : ((p) == 15 ? 1 : ((p) == 16 ? 2 : ((p) == 17 ? 0 : (p - A8 + 4)))))) + +//  __AVR_ATmega32U4__ has an unusual mapping of pins to channels +extern const uint8_t PROGMEM analog_pin_to_channel_PGM[]; +#define analogPinToChannel(P)  ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) ) + +#define digitalPinToInterrupt(p) ((p) == 0 ? 2 : ((p) == 1 ? 3 : ((p) == 2 ? 1 : ((p) == 3 ? 0 : ((p) == 7 ? 4 : NOT_AN_INTERRUPT))))) + +#ifdef ARDUINO_MAIN + +// On the Arduino board, digital pins are also used +// for the analog output (software PWM).  Analog input +// pins are a separate set. + +// ATMEL ATMEGA32U4 / ARDUINO LEONARDO +// +// D0               PD2                 RXD1/INT2 +// D1               PD3                 TXD1/INT3 +// D2               PD1     SDA         SDA/INT1 +// D3#              PD0     PWM8/SCL    OC0B/SCL/INT0 +// D4       A6      PD4                 ADC8 +// D5#              PC6     ???         OC3A/#OC4A +// D6#      A7      PD7     FastPWM     #OC4D/ADC10 +// D7               PE6                 INT6/AIN0 +// +// D8       A8      PB4                 ADC11/PCINT4 +// D9#      A9      PB5     PWM16       OC1A/#OC4B/ADC12/PCINT5 +// D10#     A10     PB6     PWM16       OC1B/0c4B/ADC13/PCINT6 +// D11#             PB7     PWM8/16     0C0A/OC1C/#RTS/PCINT7 +// D12      A11     PD6                 T1/#OC4D/ADC9 +// D13#             PC7     PWM10       CLK0/OC4A +// +// A0       D18     PF7                 ADC7 +// A1       D19     PF6                 ADC6 +// A2       D20     PF5                 ADC5 +// A3       D21     PF4                 ADC4 +// A4       D22     PF1                 ADC1 +// A5       D23     PF0                 ADC0 +// +// New pins D14..D17 to map SPI port to digital pins +// +// MISO     D14     PB3                 MISO,PCINT3 +// SCK      D15     PB1                 SCK,PCINT1 +// MOSI     D16     PB2                 MOSI,PCINT2 +// SS       D17     PB0                 RXLED,SS/PCINT0 +// +// Connected LEDs on board for TX and RX +// TXLED    D24     PD5                 XCK1 +// RXLED    D17     PB0 +// HWB              PE2                 HWB + +// these arrays map port names (e.g. port B) to the +// appropriate addresses for various functions (e.g. reading +// and writing) +const uint16_t PROGMEM port_to_mode_PGM[] = { +    NOT_A_PORT, +    NOT_A_PORT, +    (uint16_t) &DDRB, +    (uint16_t) &DDRC, +    (uint16_t) &DDRD, +    (uint16_t) &DDRE, +    (uint16_t) &DDRF, +}; + +const uint16_t PROGMEM port_to_output_PGM[] = { +    NOT_A_PORT, +    NOT_A_PORT, +    (uint16_t) &PORTB, +    (uint16_t) &PORTC, +    (uint16_t) &PORTD, +    (uint16_t) &PORTE, +    (uint16_t) &PORTF, +}; + +const uint16_t PROGMEM port_to_input_PGM[] = { +    NOT_A_PORT, +    NOT_A_PORT, +    (uint16_t) &PINB, +    (uint16_t) &PINC, +    (uint16_t) &PIND, +    (uint16_t) &PINE, +    (uint16_t) &PINF, +}; + +const uint8_t PROGMEM digital_pin_to_port_PGM[] = { +    PD, // D0 - PD2 +    PD, // D1 - PD3 +    PD, // D2 - PD1 +    PD, // D3 - PD0 +    PD, // D4 - PD4 +    PC, // D5 - PC6 +    PD, // D6 - PD7 +    PE, // D7 - PE6 + +    PB, // D8 - PB4 +    PB, // D9 - PB5 +    PB, // D10 - PB6 +    PB, // D11 - PB7 +    PD, // D12 - PD6 +    PC, // D13 - PC7 + +    PB, // D14 - MISO - PB3 +    PB, // D15 - SCK - PB1 +    PB, // D16 - MOSI - PB2 +    PB, // D17 - SS - PB0 + +    PF, // D18 - A0 - PF7 +    PF, // D19 - A1 - PF6 +    PF, // D20 - A2 - PF5 +    PF, // D21 - A3 - PF4 +    PF, // D22 - A4 - PF1 +    PF, // D23 - A5 - PF0 + +    PD, // D24 - PD5 +    PD, // D25 / D6 - A7 - PD7 +    PB, // D26 / D8 - A8 - PB4 +    PB, // D27 / D9 - A9 - PB5 +    PB, // D28 / D10 - A10 - PB6 +    PD, // D29 / D12 - A11 - PD6 +}; + +const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { +    _BV(2), // D0 - PD2 +    _BV(3), // D1 - PD3 +    _BV(1), // D2 - PD1 +    _BV(0), // D3 - PD0 +    _BV(4), // D4 - PD4 +    _BV(6), // D5 - PC6 +    _BV(7), // D6 - PD7 +    _BV(6), // D7 - PE6 + +    _BV(4), // D8 - PB4 +    _BV(5), // D9 - PB5 +    _BV(6), // D10 - PB6 +    _BV(7), // D11 - PB7 +    _BV(6), // D12 - PD6 +    _BV(7), // D13 - PC7 + +    _BV(3), // D14 - MISO - PB3 +    _BV(1), // D15 - SCK - PB1 +    _BV(2), // D16 - MOSI - PB2 +    _BV(0), // D17 - SS - PB0 + +    _BV(7), // D18 - A0 - PF7 +    _BV(6), // D19 - A1 - PF6 +    _BV(5), // D20 - A2 - PF5 +    _BV(4), // D21 - A3 - PF4 +    _BV(1), // D22 - A4 - PF1 +    _BV(0), // D23 - A5 - PF0 + +    _BV(5), // D24 - PD5 +    _BV(7), // D25 / D6 - A7 - PD7 +    _BV(4), // D26 / D8 - A8 - PB4 +    _BV(5), // D27 / D9 - A9 - PB5 +    _BV(6), // D28 / D10 - A10 - PB6 +    _BV(6), // D29 / D12 - A11 - PD6 +}; + +const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { +    NOT_ON_TIMER, +    NOT_ON_TIMER, +    NOT_ON_TIMER, +    TIMER0B,        /* 3 */ +    NOT_ON_TIMER, +    TIMER3A,        /* 5 */ +    TIMER4D,        /* 6 */ +    NOT_ON_TIMER, + +    NOT_ON_TIMER, +    TIMER1A,        /* 9 */ +    TIMER1B,        /* 10 */ +    TIMER0A,        /* 11 */ + +    NOT_ON_TIMER, +    TIMER4A,        /* 13 */ + +    NOT_ON_TIMER, +    NOT_ON_TIMER, +    NOT_ON_TIMER, +    NOT_ON_TIMER, +    NOT_ON_TIMER, +    NOT_ON_TIMER, + +    NOT_ON_TIMER, +    NOT_ON_TIMER, +    NOT_ON_TIMER, +    NOT_ON_TIMER, +    NOT_ON_TIMER, +    NOT_ON_TIMER, +    NOT_ON_TIMER, +    NOT_ON_TIMER, +    NOT_ON_TIMER, +    NOT_ON_TIMER, +}; + +const uint8_t PROGMEM analog_pin_to_channel_PGM[] = { +    7,  // A0               PF7                 ADC7 +    6,  // A1               PF6                 ADC6 +    5,  // A2               PF5                 ADC5 +    4,  // A3               PF4                 ADC4 +    1,  // A4               PF1                 ADC1 +    0,  // A5               PF0                 ADC0 +    8,  // A6       D4      PD4                 ADC8 +    10, // A7       D6      PD7                 ADC10 +    11, // A8       D8      PB4                 ADC11 +    12, // A9       D9      PB5                 ADC12 +    13, // A10      D10     PB6                 ADC13 +    9   // A11      D12     PD6                 ADC9 +}; + +#endif /* ARDUINO_MAIN */ + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use.  For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR        Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL     Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE    Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE       Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN  Hardware serial ports which are open for use.  Their RX & TX +//                            pins are NOT connected to anything by default. +#define SERIAL_PORT_MONITOR        Serial +#define SERIAL_PORT_USBVIRTUAL     Serial +#define SERIAL_PORT_HARDWARE       Serial1 +#define SERIAL_PORT_HARDWARE_OPEN  Serial1 + +#endif /* Pins_Arduino_h */ diff --git a/keyboards/orthodox/readme.md b/keyboards/orthodox/readme.md new file mode 100644 index 0000000000..94bb8ebb97 --- /dev/null +++ b/keyboards/orthodox/readme.md @@ -0,0 +1,165 @@ +Orthodox +======== + +*Please note this guide is a work in progress and is based directly on the Let's Split guide.* + +Orthodox is a split ortholinear keyboard with thumb-clusters designed in 2017 by /u/Deductivemonkee, expected to be available in group buys. +Each half has 18 keys in a 3x6 grid and a five key thumb-cluster, of which three use 1.25-unit keycaps. + + + +Its firmware is based on the Let's Split's. +Each side is controlled by an Arduino Pro Micro (or compatible), and they're connected by a TRRS cable using the serial protocol. +Support for the protocol using TWI (i2c®) is a work-in-progress. + + +## Revisions + +- `Rev.1` Prototype GB version, supporting only Pro Micro in the corner footprint, and using PCB top- and bottom-plates. + +Note that the second number after the `Rev.` text is the pcb *order number.* The prototypes will say 1, and the next order of any revision will say 2 and so on. + +## Keymaps + +[The default layout can be unofficially referred to here.](http://www.keyboard-layout-editor.com/#/gists/f120e2703a22a6a69c7be9a65a9d1342) + +The thumb-clusters are an extension of row 2 and row 3 along columns 7, 8, and 9. +Row 2 does not have a physical key in column 8, so when editing keymaps a placeholder constant (`XXXXXXX` or `KC_NO`) must be used in the row2-col8 position. + +## Build Guide + +[Official build guide by /u/Deductivemonkee](http://imgur.com/a/9c0NP) + +For further reading on build- and flashing-procedures for split ortholinear skeleton-case keyboards, please refer to [An Overly Verbose Guide to Building a Let's Split Keyboard](https://github.com/nicinabox/lets-split-guide), much of which can be applied to the Orthodox. + +## First Time Setup + +Download or clone the whole firmware and navigate to the keyboards/orthodox directory. Once your dev env is setup, you'll be able to generate the default .hex using: + +``` +$ make rev1 +``` + +You will see a lot of output and if everything worked correctly you will see the built hex files in your *root qmk_firmware directory* two levels up: + +``` +orthodox_rev1_serial.hex +``` + +If you would like to use one of the alternative keymaps, or create your own, copy one of the existing [keymaps](keymaps/) and run make like so: + + +``` +$ make rev1-YOUR_KEYMAP_NAME +``` + +If everything worked correctly you will see a file: + +``` +orthodox_rev1_YOUR_KEYMAP_NAME.hex +``` + +For more information on customizing keymaps, take a look at the primary documentation for [Customizing Your Keymap](/readme.md##customizing-your-keymap) in the main readme.md. + + +Features +-------- + +For the full Quantum Mechanical Keyboard feature list, see [the parent readme.md](/readme.md). + +Some features supported by the firmware: + +* Either half can connect to the computer via USB, or both halves can be used +  independently. +* You only need 3 wires to connect the two halves. Two for VCC and GND and one +  for serial communication. + + +Required Hardware +----------------- + +Apart from diodes and key switches for the keyboard matrix in each half, you +will need: + +* 2 Arduino Pro Micro's. You can find theses on aliexpress for ≈3.50USD each. +* 2 TRRS sockets and 1 TRRS cable + + +Notes on Software Configuration +------------------------------- + +Configuring the firmware is similar to any other QMK project. One thing +to note is that `MATRIX_ROWS` in `config.h` is the total number of rows between +the two halves, i.e. if your split keyboard has 3 rows in each half, then +`MATRIX_ROWS=6`. + + +Flashing +------- +From the keymap directory run `make SUBPROJECT-KEYMAP-avrdude` for automatic serial port resolution and flashing. +Example: `make rev2-serial-avrdude` + + +Choosing which board to plug the USB cable into (choosing Master) +-------- +Because the two boards are identical, the firmware has logic to differentiate the left and right board. + +It uses two strategies to figure things out: look at the EEPROM (memory on the chip) or looks if the current board has the usb cable. + +The EEPROM approach requires additional setup (flashing the eeeprom) but allows you to swap the usb cable to either side. + +The USB cable approach is easier to setup and if you just want the usb cable on the left board, you do not need to do anything extra. + +### Setting the left hand as master +If you always plug the usb cable into the left board, nothing extra is needed as this is the default. Comment out `EE_HANDS` and comment out `I2C_MASTER_RIGHT` or `MASTER_RIGHT` if for some reason it was set. + +### Setting the right hand as master +If you always plug the usb cable into the right board, add an extra flag to your `config.h` +``` + #define MASTER_RIGHT +``` + +### Setting EE_hands to use either hands as master +If you define `EE_HANDS` in your `config.h`, you will need to set the +EEPROM for the left and right halves. + +The EEPROM is used to store whether the +half is left handed or right handed. This makes it so that the same firmware +file will run on both hands instead of having to flash left and right handed +versions of the firmware to each half. To flash the EEPROM file for the left +half run: +``` +avrdude -p atmega32u4 -P $(COM_PORT) -c avr109 -U eeprom:w:eeprom-lefthand.eep +// or the equivalent in dfu-programmer + +``` +and similarly for right half +``` +avrdude -p atmega32u4 -P $(COM_PORT) -c avr109 -U eeprom:w:eeprom-righhand.eep +// or the equivalent in dfu-programmer +``` + +NOTE: replace `$(COM_PORT)` with the port of your device (e.g. `/dev/ttyACM0`) + +After you have flashed the EEPROM, you then need to set `EE_HANDS` in your config.h, rebuild the hex files and reflash. + +Note that you need to program both halves, but you have the option of using +different keymaps for each half. You could program the left half with a QWERTY +layout and the right half with a Colemak layout using bootmagic's default layout option. +Then if you connect the left half to a computer by USB the keyboard will use QWERTY and Colemak when the +right half is connected. + + +Notes on Using Pro Micro 3.3V +----------------------------- + +Do update the `F_CPU` parameter in `rules.mk` to `8000000` which reflects +the frequency on the 3.3V board. + +Also, if the slave board is producing weird characters in certain columns, +update the following line in `matrix.c` to the following: + +``` +// _delay_us(30);  // without this wait read unstable value. +_delay_us(300);  // without this wait read unstable value. +``` diff --git a/keyboards/orthodox/rev1/Makefile b/keyboards/orthodox/rev1/Makefile new file mode 100644 index 0000000000..4e2a6f00fd --- /dev/null +++ b/keyboards/orthodox/rev1/Makefile @@ -0,0 +1,3 @@ +ifndef MAKEFILE_INCLUDED +	include ../../Makefile +endif
\ No newline at end of file diff --git a/keyboards/orthodox/rev1/config.h b/keyboards/orthodox/rev1/config.h new file mode 100644 index 0000000000..46bb994402 --- /dev/null +++ b/keyboards/orthodox/rev1/config.h @@ -0,0 +1,99 @@ +/* +Copyright 2012 Jun Wako <[email protected]> + +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      0x3060 +#define DEVICE_VER      0x0001 +#define MANUFACTURER    deductivemonkee +#define PRODUCT         Monkeebs Orthodox Rev.1 +#define DESCRIPTION     Oreodox + +/* key matrix size */ +// Rows are doubled-up +#define MATRIX_ROWS 6 +#define MATRIX_COLS 9 + +// wiring of each half + + +//PRO MICRO +#define MATRIX_ROW_PINS { D4, B4, B5 } +#define MATRIX_COL_PINS { D7, F4, F5, F6, F7, B1, B3, B2, B6 } +//#define MATRIX_COL_PINS { B2, B3, B1, F7, F6, F5, F4, D7 } + +/*/ +//TEENSY +#define MATRIX_ROW_PINS { D0, C6, C7, } +#define MATRIX_COL_PINS { D2, F5, F6, F7, B6, B5, B4, D7, D6 } +/*/ + +#define CATERINA_BOOTLOADER + +/* COL2ROW or ROW2COL */ +#define DIODE_DIRECTION COL2ROW + +/* define if matrix has ghost */ +//#define MATRIX_HAS_GHOST + +/* number of backlight levels */ +// #define BACKLIGHT_LEVELS 3 + +/* Set 0 if debouncing isn't needed */ +#define DEBOUNCING_DELAY 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)) \ +) + +/* ws2812 RGB LED */ +//#define RGB_DI_PIN D3 +//#define RGBLIGHT_TIMER +//#define RGBLED_NUM 16    // Number of LEDs +//#define ws2812_PORTREG  PORTD +//#define ws2812_DDRREG   DDRD + +/* + * 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 diff --git a/keyboards/orthodox/rev1/rev1.c b/keyboards/orthodox/rev1/rev1.c new file mode 100644 index 0000000000..10ece03f08 --- /dev/null +++ b/keyboards/orthodox/rev1/rev1.c @@ -0,0 +1,32 @@ +#include "orthodox.h" + +#ifdef AUDIO_ENABLE +    float tone_startup[][2] = SONG(STARTUP_SOUND); +    float tone_goodbye[][2] = SONG(GOODBYE_SOUND); +#endif + +void matrix_init_kb(void) { + +    #ifdef AUDIO_ENABLE +        _delay_ms(20); // gets rid of tick +        PLAY_NOTE_ARRAY(tone_startup, false, 0); +    #endif + +    // // green led on +    // DDRD |= (1<<5); +    // PORTD &= ~(1<<5); + +    // // orange led on +    // DDRB |= (1<<0); +    // PORTB &= ~(1<<0); + +	matrix_init_user(); +}; + +void shutdown_user(void) { +    #ifdef AUDIO_ENABLE +        PLAY_NOTE_ARRAY(tone_goodbye, false, 0); +	_delay_ms(150); +	stop_all_notes(); +    #endif +} diff --git a/keyboards/orthodox/rev1/rev1.h b/keyboards/orthodox/rev1/rev1.h new file mode 100644 index 0000000000..4f163299d1 --- /dev/null +++ b/keyboards/orthodox/rev1/rev1.h @@ -0,0 +1,25 @@ +#ifndef REV1_H +#define REV1_H + +#include "../orthodox.h" + +//void promicro_bootloader_jmp(bool program); +#include "quantum.h" + +//void promicro_bootloader_jmp(bool program); + +#define KEYMAP( \ +	L00, L01, L02, L03, L04, L05,                     		  R00, R01, R02, R03, R04, R05, \ +	L10, L11, L12, L13, L14, L15, L16, L17,	L18, R10, R11, R12, R13, R14, R15, R16, R17, R18,  \ +	L20, L21, L22, L23, L24, L25, L26, L27, L28, R20, R21, R22, R23, R24, R25, R26, R27, R28 \ +	) \ +	{ \ +		{ L00, L01, L02, L03, L04, L05 }, \ +		{ L10, L11, L12, L13, L14, L15, L16, L17, L18}, \ +		{ L20, L21, L22, L23, L24, L25, L26, L27, L28 }, \ +		{ R05, R04, R03, R02, R01, R00 }, \ +		{ R18, R17, R16, R15, R14, R13, R12, R11, R10 }, \ +		{ R28, R27, R26, R25, R24, R23, R22, R21, R20 } \ +	} + +#endif
\ No newline at end of file diff --git a/keyboards/orthodox/rev1/rules.mk b/keyboards/orthodox/rev1/rules.mk new file mode 100644 index 0000000000..a0825b4ef6 --- /dev/null +++ b/keyboards/orthodox/rev1/rules.mk @@ -0,0 +1,5 @@ +BACKLIGHT_ENABLE = no + +ifndef QUANTUM_DIR +	include ../../../Makefile +endif
\ No newline at end of file diff --git a/keyboards/orthodox/rules.mk b/keyboards/orthodox/rules.mk new file mode 100644 index 0000000000..0efa785505 --- /dev/null +++ b/keyboards/orthodox/rules.mk @@ -0,0 +1,87 @@ +SRC += matrix.c \ +	   i2c.c \ +	   split_util.c \ +	   serial.c + +# 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=4096 + +# Build Options +#   change to "no" to disable the options, or define them in the Makefile in +#   the appropriate keymap folder that will get included automatically +# +BOOTMAGIC_ENABLE ?= no       # Virtual DIP switch configuration(+1000) +MOUSEKEY_ENABLE ?= yes       # Mouse keys(+4700) +EXTRAKEY_ENABLE ?= yes       # Audio control and System control(+450) +CONSOLE_ENABLE ?= no         # Console for debug(+400) +COMMAND_ENABLE ?= yes        # 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 +BACKLIGHT_ENABLE ?= no      # Enable keyboard backlight functionality +MIDI_ENABLE ?= no            # MIDI controls +AUDIO_ENABLE ?= no           # Audio output on port C6 +UNICODE_ENABLE ?= no         # Unicode +BLUETOOTH_ENABLE ?= no       # Enable Bluetooth with the Adafruit EZ-Key HID +RGBLIGHT_ENABLE ?= no       # Enable WS2812 RGB underlight.  Do not enable this with audio at the same time. +SUBPROJECT_rev1 ?= yes +USE_I2C ?= yes +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +SLEEP_LED_ENABLE ?= no    # Breathing sleep LED during USB suspend + +CUSTOM_MATRIX = yes + +avrdude: build +	ls /dev/tty* > /tmp/1; \ +	echo "Reset your Pro Micro now"; \ +	while [[ -z $$USB ]]; do \ +	  sleep 1; \ +	  ls /dev/tty* > /tmp/2; \ +	  USB=`diff /tmp/1 /tmp/2 | grep -o '/dev/tty.*'`; \ +	done; \ +	avrdude -p $(MCU) -c avr109 -P $$USB -U flash:w:$(BUILD_DIR)/$(TARGET).hex + +.PHONY: avrdude diff --git a/keyboards/orthodox/serial.c b/keyboards/orthodox/serial.c new file mode 100644 index 0000000000..4936e4249f --- /dev/null +++ b/keyboards/orthodox/serial.c @@ -0,0 +1,230 @@ +/* + * WARNING: be careful changing this code, it is very timing dependent + */ + +#ifndef F_CPU +#define F_CPU 16000000 +#endif + +#include <avr/io.h> +#include <avr/interrupt.h> +#include <util/delay.h> +#include <stdbool.h> +#include "serial.h" + +#ifdef USE_SERIAL + +// Serial pulse period in microseconds. Its probably a bad idea to lower this +// value. +#define SERIAL_DELAY 24 + +matrix_row_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0}; +matrix_row_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0}; + +#define ROW_MASK (((matrix_row_t)0-1)>>(8*sizeof(matrix_row_t)-MATRIX_COLS)) + +#define SLAVE_DATA_CORRUPT (1<<0) +volatile uint8_t status = 0; + +inline static +void serial_delay(void) { +  _delay_us(SERIAL_DELAY); +} + +inline static +void serial_output(void) { +  SERIAL_PIN_DDR |= SERIAL_PIN_MASK; +} + +// make the serial pin an input with pull-up resistor +inline static +void serial_input(void) { +  SERIAL_PIN_DDR  &= ~SERIAL_PIN_MASK; +  SERIAL_PIN_PORT |= SERIAL_PIN_MASK; +} + +inline static +matrix_row_t serial_read_pin(void) { +  return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK); +} + +inline static +void serial_low(void) { +  SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK; +} + +inline static +void serial_high(void) { +  SERIAL_PIN_PORT |= SERIAL_PIN_MASK; +} + +void serial_master_init(void) { +  serial_output(); +  serial_high(); +} + +void serial_slave_init(void) { +  serial_input(); + +  // Enable INT0 +  EIMSK |= _BV(INT0); +  // Trigger on falling edge of INT0 +  EICRA &= ~(_BV(ISC00) | _BV(ISC01)); +} + +// Used by the master to synchronize timing with the slave. +static +void sync_recv(void) { +  serial_input(); +  // This shouldn't hang if the slave disconnects because the +  // serial line will float to high if the slave does disconnect. +  while (!serial_read_pin()); +  serial_delay(); +} + +// Used by the slave to send a synchronization signal to the master. +static +void sync_send(void) { +  serial_output(); + +  serial_low(); +  serial_delay(); + +  serial_high(); +} + +// Reads a byte from the serial line +static +matrix_row_t serial_read_byte(void) { +  matrix_row_t byte = 0; +  serial_input(); +  for ( uint8_t i = 0; i < MATRIX_COLS; ++i) { +    byte = (byte << 1) | serial_read_pin(); +    serial_delay(); +    _delay_us(1); +  } + +  return byte; +} + +// Sends a byte with MSB ordering +static +void serial_write_byte(matrix_row_t data) { +  matrix_row_t b = MATRIX_COLS; +  serial_output(); +  while( b-- ) { +    if(data & (1UL << b)) { +      serial_high(); +    } else { +      serial_low(); +    } +    serial_delay(); +  } +} + +// interrupt handle to be used by the slave device +ISR(SERIAL_PIN_INTERRUPT) { +  sync_send(); + +  matrix_row_t checksum = 0; +  for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) { +    serial_write_byte(serial_slave_buffer[i]); +    sync_send(); +    checksum += ROW_MASK & serial_slave_buffer[i]; +  } +  serial_write_byte(checksum); +  sync_send(); + +  // wait for the sync to finish sending +  serial_delay(); + +  // read the middle of pulses +  _delay_us(SERIAL_DELAY/2); + +  matrix_row_t checksum_computed = 0; +  for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) { +    serial_master_buffer[i] = serial_read_byte(); +    sync_send(); +    checksum_computed += ROW_MASK & serial_master_buffer[i]; +  } +  matrix_row_t checksum_received = serial_read_byte(); +  sync_send(); + +  serial_input(); // end transaction + +  if ( checksum_computed != checksum_received ) { +    status |= SLAVE_DATA_CORRUPT; +  } else { +    status &= ~SLAVE_DATA_CORRUPT; +  } +} + +inline +bool serial_slave_DATA_CORRUPT(void) { +  return status & SLAVE_DATA_CORRUPT; +} + +// Copies the serial_slave_buffer to the master and sends the +// serial_master_buffer to the slave. +// +// Returns: +// 0 => no error +// 1 => slave did not respond +int serial_update_buffers(void) { +  // this code is very time dependent, so we need to disable interrupts +  cli(); + +  // signal to the slave that we want to start a transaction +  serial_output(); +  serial_low(); +  _delay_us(1); + +  // wait for the slaves response +  serial_input(); +  serial_high(); +  _delay_us(SERIAL_DELAY); + +  // check if the slave is present +  if (serial_read_pin()) { +    // slave failed to pull the line low, assume not present +    sei(); +    return 1; +  } + +  // if the slave is present syncronize with it +  sync_recv(); + +  matrix_row_t checksum_computed = 0; +  // receive data from the slave +  for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) { +    serial_slave_buffer[i] = serial_read_byte(); +    sync_recv(); +    checksum_computed += ROW_MASK & serial_slave_buffer[i]; +  } +  matrix_row_t checksum_received = serial_read_byte(); +  sync_recv(); + +  if (checksum_computed != checksum_received) { +    sei(); +    return 1; +  } + +  matrix_row_t checksum = 0; +  // send data to the slave +  for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) { +    serial_write_byte(serial_master_buffer[i]); +    sync_recv(); +    checksum += ROW_MASK & serial_master_buffer[i]; +  } +  serial_write_byte(checksum); +  sync_recv(); + +  // always, release the line when not in use +  serial_output(); +  serial_high(); + +  sei(); +  return 0; +} + +#endif diff --git a/keyboards/orthodox/serial.h b/keyboards/orthodox/serial.h new file mode 100644 index 0000000000..a46a98c947 --- /dev/null +++ b/keyboards/orthodox/serial.h @@ -0,0 +1,27 @@ +#ifndef MY_SERIAL_H +#define MY_SERIAL_H + +#include "config.h" +#include <stdbool.h> +#include "matrix.h" + +/* TODO:  some defines for interrupt setup */ +#define SERIAL_PIN_DDR DDRD +#define SERIAL_PIN_PORT PORTD +#define SERIAL_PIN_INPUT PIND +#define SERIAL_PIN_MASK _BV(PD0) +#define SERIAL_PIN_INTERRUPT INT0_vect + +#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 +#define SERIAL_MASTER_BUFFER_LENGTH 1 + +// Buffers for master - slave communication +extern volatile matrix_row_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH]; +extern volatile matrix_row_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH]; + +void serial_master_init(void); +void serial_slave_init(void); +int serial_update_buffers(void); +bool serial_slave_data_corrupt(void); + +#endif diff --git a/keyboards/orthodox/split_util.c b/keyboards/orthodox/split_util.c new file mode 100644 index 0000000000..39639c3b4b --- /dev/null +++ b/keyboards/orthodox/split_util.c @@ -0,0 +1,84 @@ +#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" +#include "config.h" + +#ifdef USE_I2C +#  include "i2c.h" +#else +#  include "serial.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_I2C +    i2c_master_init(); +#ifdef SSD1306OLED +    matrix_master_OLED_init (); +#endif +#else +    serial_master_init(); +#endif +} + +static void keyboard_slave_setup(void) { +#ifdef USE_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(); +} + +void keyboard_slave_loop(void) { +   matrix_init(); + +   while (1) { +      matrix_slave_scan(); +   } +} + +// this code runs before the usb and keyboard is initialized +void matrix_setup(void) { +    split_keyboard_setup(); + +    if (!has_usb()) { +        keyboard_slave_loop(); +    } +} diff --git a/keyboards/orthodox/split_util.h b/keyboards/orthodox/split_util.h new file mode 100644 index 0000000000..3ae76c209a --- /dev/null +++ b/keyboards/orthodox/split_util.h @@ -0,0 +1,24 @@ +#ifndef SPLIT_KEYBOARD_UTIL_H +#define SPLIT_KEYBOARD_UTIL_H + +#include <stdbool.h> + +#ifdef EE_HANDS +	#define EECONFIG_BOOTMAGIC_END      (uint8_t *)10 +	#define EECONFIG_HANDEDNESS         EECONFIG_BOOTMAGIC_END +#endif + +#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 keyboard_slave_loop(void); + +void matrix_master_OLED_init (void); + +#endif diff --git a/keyboards/orthodox/ssd1306.c b/keyboards/orthodox/ssd1306.c new file mode 100644 index 0000000000..5c6dff27f8 --- /dev/null +++ b/keyboards/orthodox/ssd1306.c @@ -0,0 +1,470 @@ +#ifdef SSD1306OLED + +#include "ssd1306.h" +#include "config.h" +#include "i2c.h" +#include <string.h> +#include "print.h" +#include "lets_split.h" +#include "common/glcdfont.c" +#ifdef ADAFRUIT_BLE_ENABLE +#include "adafruit_ble.h" +#endif +#ifdef PROTOCOL_LUFA +#include "lufa.h" +#endif +#include "sendchar.h" +#include "pincontrol.h" + +//assign the right code to your layers +#define _BASE 0 +#define _LOWER 8 +#define _RAISE 16 +#define _FNLAYER 64 +#define _NUMLAY 128 +#define _NLOWER 136 +#define _NFNLAYER 192 +#define _MOUSECURSOR 256 +#define _ADJUST 65560 + +// 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 + +// Controls the SSD1306 128x32 OLED display via i2c + +#define i2cAddress 0x3C + +#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; +}; + +static struct CharacterMatrix display; +//static uint16_t last_battery_update; +//static uint32_t vbat; +//#define BatteryUpdateInterval 10000 /* milliseconds */ +#define ScreenOffInterval 300000 /* milliseconds */ +#if DEBUG_TO_SCREEN +static uint8_t displaying; +#endif +static uint16_t last_flush; + +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, +}; + + +// Write command sequence. +// Returns true on success. +static inline bool _send_cmd1(uint8_t cmd) { +  bool res = false; + +  if (i2c_start_write(i2cAddress)) { +    xprintf("failed to start write to %d\n", i2cAddress); +    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 matrix_clear(struct CharacterMatrix *matrix); + +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(i2cAddress)) { +    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(void) { +  bool success = false; + +  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 */); + +/// Flips the display orientation 0 degrees +  send_cmd1(SegRemap | 0x1); +  send_cmd1(ComScanDec); +/* +// the following Flip the display orientation 180 degrees +  send_cmd1(SegRemap); +  send_cmd1(ComScanInc); +// end flip */ +  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; +} + +static 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); +  } +} + +static 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); +} + +static 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 iota_gfx_write(const char *data) { +  matrix_write(&display, data); +} + +static 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); +} + +static 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); +} + +static 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(i2cAddress)) { +    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 - 1)); + +      for (uint8_t glyphCol = 0; glyphCol < FontWidth - 1; ++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); +} + +static void matrix_update(struct CharacterMatrix *dest, +                          const struct CharacterMatrix *source) { +  if (memcmp(dest->display, source->display, sizeof(dest->display))) { +    memcpy(dest->display, source->display, sizeof(dest->display)); +    dest->dirty = true; +  } +} + +static void render_status_info(void) { +#if DEBUG_TO_SCREEN +  if (debug_enable) { +    return; +  } +#endif + +  struct CharacterMatrix matrix; + +  matrix_clear(&matrix); +  matrix_write_P(&matrix, PSTR("USB: ")); +#ifdef PROTOCOL_LUFA +  switch (USB_DeviceState) { +    case DEVICE_STATE_Unattached: +      matrix_write_P(&matrix, PSTR("Unattached")); +      break; +    case DEVICE_STATE_Suspended: +      matrix_write_P(&matrix, PSTR("Suspended")); +      break; +    case DEVICE_STATE_Configured: +      matrix_write_P(&matrix, PSTR("Connected")); +      break; +    case DEVICE_STATE_Powered: +      matrix_write_P(&matrix, PSTR("Powered")); +      break; +    case DEVICE_STATE_Default: +      matrix_write_P(&matrix, PSTR("Default")); +      break; +    case DEVICE_STATE_Addressed: +      matrix_write_P(&matrix, PSTR("Addressed")); +      break; +    default: +      matrix_write_P(&matrix, PSTR("Invalid")); +  } +#endif + +// Define layers here, Have not worked out how to have text displayed for each layer. Copy down the number you see and add a case for it below + +  char buf[40]; +  snprintf(buf,sizeof(buf), "Undef-%ld", layer_state); +  matrix_write_P(&matrix, PSTR("\n\nLayer: ")); +    switch (layer_state) { +        case _BASE: +           matrix_write_P(&matrix, PSTR("Default")); +           break; +        case _RAISE: +           matrix_write_P(&matrix, PSTR("Raise")); +           break; +        case _LOWER: +           matrix_write_P(&matrix, PSTR("Lower")); +           break; +        case _ADJUST: +           matrix_write_P(&matrix, PSTR("ADJUST")); +           break; +        default: +           matrix_write(&matrix, buf); + } +   +  // Host Keyboard LED Status +  char led[40]; +    snprintf(led, sizeof(led), "\n%s  %s  %s", +            (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) ? "NUMLOCK" : "       ", +            (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) ? "CAPS" : "    ", +            (host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) ? "SCLK" : "    "); +  matrix_write(&matrix, led); +  matrix_update(&display, &matrix); +} + +void iota_gfx_task(void) { +  render_status_info(); + +  if (display.dirty) { +    iota_gfx_flush(); +  } + +  if (timer_elapsed(last_flush) > ScreenOffInterval) { +    iota_gfx_off(); +  } +} +#endif diff --git a/keyboards/orthodox/ssd1306.h b/keyboards/orthodox/ssd1306.h new file mode 100644 index 0000000000..b0c74f987e --- /dev/null +++ b/keyboards/orthodox/ssd1306.h @@ -0,0 +1,17 @@ +#ifndef SSD1306_H +#define SSD1306_H + +#include <stdbool.h> +#include <stdio.h> + +bool iota_gfx_init(void); +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); + +#endif diff --git a/keyboards/planck/keymaps/rai-suta/Makefile b/keyboards/planck/keymaps/rai-suta/Makefile new file mode 100644 index 0000000000..4263440ec1 --- /dev/null +++ b/keyboards/planck/keymaps/rai-suta/Makefile @@ -0,0 +1,28 @@ + + +# Build Options +#   change to "no" to disable the options, or define them in the Makefile in  +#   the appropriate keymap folder that will get included automatically +# +BOOTMAGIC_ENABLE = no       # 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 = no        	# Commands for debug and configuration +NKRO_ENABLE = yes           # 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 +AUDIO_ENABLE = no           # Audio output on port C6 +UNICODE_ENABLE = no         # Unicode +BLUETOOTH_ENABLE = no       # Enable Bluetooth with the Adafruit EZ-Key HID +RGBLIGHT_ENABLE = no        # Enable WS2812 RGB underlight.  Do not enable this with audio at the same time. + +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +SLEEP_LED_ENABLE = no    # Breathing sleep LED during USB suspend + +# Option defines +OPT_DEFS += -DJIS_KEYCODE + +ifndef QUANTUM_DIR +	include ../../../../Makefile +endif
\ No newline at end of file diff --git a/keyboards/planck/keymaps/rai-suta/config.h b/keyboards/planck/keymaps/rai-suta/config.h new file mode 100644 index 0000000000..b36aa3db92 --- /dev/null +++ b/keyboards/planck/keymaps/rai-suta/config.h @@ -0,0 +1,8 @@ +#ifndef CONFIG_USER_H +#define CONFIG_USER_H + +#include "../../config.h" + +#define TAPPING_TERM    ( 200 ) + +#endif diff --git a/keyboards/planck/keymaps/rai-suta/keymap.c b/keyboards/planck/keymaps/rai-suta/keymap.c new file mode 100644 index 0000000000..13fc3677e6 --- /dev/null +++ b/keyboards/planck/keymaps/rai-suta/keymap.c @@ -0,0 +1,107 @@ +// This keymap assumes that the keyboard is recognized as JIS keyboard from the OS. + +#include "planck.h" +#include "version.h" + +// Keycode defines +#define _______ KC_TRNS +#define XXXXXXX KC_NO +#define C(kc)   LCTL(kc) +// JIS keyboard +#define JK_CIRC KC_EQL      // ^ +#define JK_AT   KC_LBRC     // @ +#define JK_LBRC KC_RBRC     // [ +#define JK_CLN  KC_QUOT     // : +#define JK_RBRC KC_BSLS     // ] +#define JK_BSLS KC_RO       // Backslash(\) +#define JK_DQT  S(KC_2)     // " +#define JK_AMPR S(KC_6)     // & +#define JK_SQT  S(KC_7)     // ' +#define JK_LPRN S(KC_8)     // ( +#define JK_RPRN S(KC_9)     // ) +#define JK_S0   S(KC_0)     // Tilde(~) at IBM 5576-A01 spec +#define JK_EQ   S(KC_MINS)  // = +#define JK_TLD  S(JK_CIRC)  // ~ +#define JK_PIPE S(KC_JYEN)  // | +#define JK_GRV  S(JK_AT)    // ` +#define JK_LCBR S(JK_LBRC)  // { +#define JK_PLUS S(KC_SCLN)  // + +#define JK_ASTR S(JK_CLN)   // * +#define JK_RCBR S(JK_RBRC)  // } +#define JK_QUES S(KC_SLSH)  // ? +#define JK_UNDS S(JK_BSLS)  // _ + +enum user_macro { +  UM_MHEN, +  UM_HENK, +  UM_DEBUG, +}; +#define M_MHEN  MACROTAP(UM_MHEN) +#define M_HENK  MACROTAP(UM_HENK) +#define M_DEBUG M(UM_DEBUG) + +enum keymap_layer { +  KL_QWERTY, +  KL_LOWER, +  KL_RAISE, +}; +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +  [KL_QWERTY] = { +    { KC_TAB,    KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P, KC_BSPC}, +    {KC_LCTL,    KC_A,    KC_S,    KC_D,    KC_F,    KC_G,    KC_H,    KC_J,    KC_K,    KC_L, KC_SCLN,  JK_CLN}, +    {KC_LSFT,    KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_N,    KC_M, KC_COMM,  KC_DOT, KC_SLSH, KC_RSFT}, +    {KC_ZKHK, KC_KANA, KC_LGUI, KC_LALT,  M_MHEN,  KC_SPC,  KC_SPC,  M_HENK, KC_RALT, KC_RGUI,  KC_APP,  KC_ENT} +  }, + +  [KL_LOWER] = { +    {KC_GESC, KC_EXLM,  JK_DQT, KC_HASH,  KC_DLR, KC_PERC, JK_AMPR,  JK_SQT, JK_LPRN, JK_RPRN,   JK_S0,  KC_DEL}, +    {_______, KC_LEFT,   KC_UP, KC_DOWN, KC_RGHT,  KC_DEL, KC_BSPC,   JK_EQ,  JK_TLD,  JK_GRV, JK_LCBR, JK_PIPE}, +    {_______, C(KC_Z), C(KC_X), C(KC_C), C(KC_V), C(KC_Y), XXXXXXX,  KC_ENT, KC_LABK, KC_RABK, JK_RCBR, JK_UNDS}, +    {  RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______} +  }, + +  [KL_RAISE] = { +    {KC_CAPS,    KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_6,    KC_7,    KC_8,    KC_9,    KC_0,  KC_DEL}, +    {_______,   KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6, KC_MINS, JK_CIRC,   JK_AT, JK_LBRC, KC_JYEN}, +    {_______,   KC_F7,   KC_F8,   KC_F9,   KC_F10, KC_F11,  KC_F12, XXXXXXX, KC_COMM,  KC_DOT, JK_RBRC, JK_BSLS}, +    {M_DEBUG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______} +  }, + +}; + +const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) +{ +  dprintf( "record.\n" +           "  event.pressed = %u\n" +           "  tap.count = %u\n" +           "  tap.interrupted = %u\n" +              , record->event.pressed +              , record->tap.count +              , record->tap.interrupted ); +  dprintf( "id = %u\n", id ); +  dprintf( "opt = %u\n", opt ); + +  switch(id) { + +    case UM_MHEN: { +      return MACRO_TAP_HOLD_LAYER( record, MACRO(TYPE(KC_MHEN), END), KL_LOWER ); +    } break; + +    case UM_HENK: { +      return MACRO_TAP_HOLD_LAYER( record, MACRO(TYPE(KC_HENK), END), KL_RAISE ); +    } break; + +    case UM_DEBUG: { +      if (record->event.pressed) { +        debug_enable = !debug_enable; +        if (debug_enable) { +          dprint("\nDEBUG: enabled.\n"); +          SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION); +        } +      } +    } break; + +  } +  return MACRO_NONE; +}; diff --git a/keyboards/planck/keymaps/rai-suta/readme.md b/keyboards/planck/keymaps/rai-suta/readme.md new file mode 100644 index 0000000000..cb73c172aa --- /dev/null +++ b/keyboards/planck/keymaps/rai-suta/readme.md @@ -0,0 +1,3 @@ +# rai-suta's Planck Layout + +This keymap assumes that the keyboard is recognized as JIS keyboard from the OS. diff --git a/keyboards/whitefox/animations.c b/keyboards/whitefox/animations.c new file mode 100644 index 0000000000..ed1d75efb8 --- /dev/null +++ b/keyboards/whitefox/animations.c @@ -0,0 +1,128 @@ +/* Copyright 2017 Fred Sundvik + * + * 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/>. + */ + +#if defined(VISUALIZER_ENABLE) + +#include "animations.h" +#include "visualizer.h" + +#ifdef BACKLIGHT_ENABLE +#include "led_keyframes.h" +#endif + +#include "visualizer_keyframes.h" + + +#if defined(LCD_ENABLE) || defined(LCD_BACKLIGHT_ENABLE) || defined(BACKLIGHT_ENABLE) + +static bool keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { +#ifdef BACKLIGHT_ENABLE +    led_keyframe_enable(animation, state); +#endif +    return false; +} + +static bool keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { +#ifdef BACKLIGHT_ENABLE +    led_keyframe_disable(animation, state); +#endif +    return false; +} + +static bool keyframe_fade_in(keyframe_animation_t* animation, visualizer_state_t* state) { +    bool ret = false; +#ifdef BACKLIGHT_ENABLE +    ret |= led_keyframe_fade_in_all(animation, state); +#endif +    return ret; +} + +static bool keyframe_fade_out(keyframe_animation_t* animation, visualizer_state_t* state) { +    bool ret = false; +#ifdef BACKLIGHT_ENABLE +    ret |= led_keyframe_fade_out_all(animation, state); +#endif +    return ret; +} + + +// Don't worry, if the startup animation is long, you can use the keyboard like normal +// during that time +keyframe_animation_t default_startup_animation = { +    .num_frames = 2, +    .loop = false, +    .frame_lengths = {0, gfxMillisecondsToTicks(5000)}, +    .frame_functions = { +            keyframe_enable, +            keyframe_fade_in, +    }, +}; + +keyframe_animation_t default_suspend_animation = { +    .num_frames = 2, +    .loop = false, +    .frame_lengths = {gfxMillisecondsToTicks(1000), 0}, +    .frame_functions = { +            keyframe_fade_out, +            keyframe_disable, +    }, +}; +#endif + +#if defined(BACKLIGHT_ENABLE) +#define CROSSFADE_TIME 1000 +#define GRADIENT_TIME 3000 + +keyframe_animation_t led_test_animation = { +    .num_frames = 14, +    .loop = true, +    .frame_lengths = { +        gfxMillisecondsToTicks(1000), // fade in +        gfxMillisecondsToTicks(1000), // no op (leds on) +        gfxMillisecondsToTicks(1000), // fade out +        gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade +        gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in) +        gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade +        gfxMillisecondsToTicks(GRADIENT_TIME), // top_to_bottom +        0,           // mirror leds +        gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade +        gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out) +        gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade +        gfxMillisecondsToTicks(GRADIENT_TIME), // top_to_bottom +        0,           // normal leds +        gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade + +    }, +    .frame_functions = { +        led_keyframe_fade_in_all, +        keyframe_no_operation, +        led_keyframe_fade_out_all, +        led_keyframe_crossfade, +        led_keyframe_left_to_right_gradient, +        led_keyframe_crossfade, +        led_keyframe_top_to_bottom_gradient, +        led_keyframe_mirror_orientation, +        led_keyframe_crossfade, +        led_keyframe_left_to_right_gradient, +        led_keyframe_crossfade, +        led_keyframe_top_to_bottom_gradient, +        led_keyframe_normal_orientation, +        led_keyframe_crossfade, +    }, +}; +#endif + +#endif diff --git a/keyboards/whitefox/animations.h b/keyboards/whitefox/animations.h new file mode 100644 index 0000000000..6d8b9830d9 --- /dev/null +++ b/keyboards/whitefox/animations.h @@ -0,0 +1,30 @@ +/* Copyright 2017 Fred Sundvik + * + * 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 KEYBOARDS_ERGODOX_INFINITY_ANIMATIONS_H_ +#define KEYBOARDS_ERGODOX_INFINITY_ANIMATIONS_H_ + +#include "visualizer.h" + +// You can use these default animations, but of course you can also write your own custom ones instead +extern keyframe_animation_t default_startup_animation; +extern keyframe_animation_t default_suspend_animation; + +// An animation for testing and demonstrating the led support, should probably not be used for real world +// cases +extern keyframe_animation_t led_test_animation; + +#endif /* KEYBOARDS_ERGODOX_INFINITY_ANIMATIONS_H_ */ diff --git a/keyboards/whitefox/config.h b/keyboards/whitefox/config.h index b7116341ff..08de9b9aa8 100644 --- a/keyboards/whitefox/config.h +++ b/keyboards/whitefox/config.h @@ -35,6 +35,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #define MATRIX_ROWS 9  #define MATRIX_COLS 8 +/* number of backlight levels */ +#define BACKLIGHT_LEVELS 3 + +#define LED_BRIGHTNESS_LO       100 +#define LED_BRIGHTNESS_HI       255 +  /* define if matrix has ghost */  //#define MATRIX_HAS_GHOST @@ -76,3 +82,11 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  //#define NO_ACTION_FUNCTION  #endif + +// The visualizer needs gfx thread priorities +#define LED_DISPLAY_NUMBER 0 + +#define LED_NUM_ROWS 5 +#define LED_NUM_COLS 16 + +#define VISUALIZER_THREAD_PRIORITY (NORMAL_PRIORITY - 2) diff --git a/keyboards/whitefox/drivers/gdisp/IS31FL3731C/board_IS31FL3731C.h b/keyboards/whitefox/drivers/gdisp/IS31FL3731C/board_IS31FL3731C.h new file mode 100644 index 0000000000..3dc5327a58 --- /dev/null +++ b/keyboards/whitefox/drivers/gdisp/IS31FL3731C/board_IS31FL3731C.h @@ -0,0 +1,109 @@ +/* +Copyright 2016 Fred Sundvik <[email protected]> + +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 _GDISP_LLD_BOARD_H +#define _GDISP_LLD_BOARD_H + +static const I2CConfig i2ccfg = { +  400000 // clock speed (Hz); 400kHz max for IS31 +}; + +#define GDISP_SCREEN_WIDTH  16 +#define GDISP_SCREEN_HEIGHT 5 + +static const uint8_t led_mask[] = { +	0xFF, 0x00, /* C1-1 -> C1-16 */ +	0xFF, 0x00, /* C2-1 -> C2-16 */ +	0xFF, 0x00, /* C3-1 -> C3-16 */ +	0xFF, 0x00, /* C4-1 -> C4-16 */ +	0xFF, 0x00, /* C5-1 -> C5-16 */ +	0xFF, 0x00, /* C6-1 -> C6-16 */ +	0xFF, 0x00, /* C7-1 -> C7-16 */ +	0xFF, 0x00, /* C8-1 -> C8-16 */ +	0xFE, 0x00, /* C9-1 -> C9-16 */ +}; + +// The address of the LED +#define LA(c, r) (c + r * 16 ) +// Need to be an address that is not mapped, but inside the range of the controller matrix +#define NA LA(8, 8) + +// The numbers in the comments are the led numbers DXX on the PCB +// The mapping is taken from the schematic of left hand side +static const uint8_t led_mapping[GDISP_SCREEN_HEIGHT][GDISP_SCREEN_WIDTH] = { +//   1         2         3         4         5         6         7         8         9         10        11        12        13        14        15        16 +   { LA(0, 0), LA(1, 0), LA(2, 0), LA(3, 0), LA(4, 0), LA(5, 0), LA(6, 0), LA(7, 0), LA(0, 1), LA(1, 1), LA(2, 1), LA(3, 1), LA(4, 1), LA(5, 1), LA(6, 1), LA(7, 1)}, +//   17        18        19        20        21        22        23        24        25        26                  27        28        29        30        31 +   { LA(0, 2), LA(1, 2), LA(2, 2), LA(3, 2), LA(4, 2), LA(5, 2), LA(6, 2), LA(7, 2), LA(0, 3), LA(1, 3), NA,       LA(2, 3), LA(3, 3), LA(4, 3), LA(5, 3), LA(6, 3)}, +//   32        33        34        35        36        37        38        39        40        41                  42        43        44        45        46 +   { LA(7, 3), LA(0, 4), LA(1, 4), LA(2, 4), LA(3, 4), LA(4, 4), LA(5, 4), LA(6, 4), LA(7, 4), LA(0, 5), NA,       LA(1, 5), LA(2, 5), LA(3, 5), LA(4, 5), LA(5, 5)}, +//   47        48        49        50        51        52        53        54        55        56                  57        58        59        60        61 +   { LA(6, 5), LA(7, 5), LA(0, 6), LA(1, 6), LA(2, 6), LA(3, 6), LA(4, 6), LA(5, 6), LA(6, 6), LA(7, 6), NA,       LA(0, 7), LA(1, 7), LA(2, 7), LA(3, 7), LA(4, 7)}, +//   62        63        64                                      65                                      66        67        68        69        70        71 +   { LA(5, 7), LA(6, 7), LA(7, 7), NA,       NA,       NA,       LA(0, 8), NA,       NA,       NA,       LA(1, 8), LA(2, 8), LA(3, 8), LA(4, 8), LA(5, 8), LA(6, 8)}, +}; + + +#define IS31_ADDR_DEFAULT 0x74 // AD connected to GND +#define IS31_TIMEOUT 5000 + +static GFXINLINE void init_board(GDisplay *g) { +    (void) g; +    /* I2C pins */ +    palSetPadMode(GPIOB, 0, PAL_MODE_ALTERNATIVE_2); // PTB0/I2C0/SCL +    palSetPadMode(GPIOB, 1, PAL_MODE_ALTERNATIVE_2); // PTB1/I2C0/SDA +    palSetPadMode(GPIOB, 16, PAL_MODE_OUTPUT_PUSHPULL); +    palClearPad(GPIOB, 16); +    /* start I2C */ +    i2cStart(&I2CD1, &i2ccfg); +    // try high drive (from kiibohd) +    I2CD1.i2c->C2 |= I2Cx_C2_HDRS; +    // try glitch fixing (from kiibohd) +    I2CD1.i2c->FLT = 4; +} + +static GFXINLINE void post_init_board(GDisplay *g) { +	(void) g; +} + +static GFXINLINE const uint8_t* get_led_mask(GDisplay* g) { +    (void) g; +    return led_mask; +} + +static GFXINLINE uint8_t get_led_address(GDisplay* g, uint16_t x, uint16_t y) +{ +    (void) g; +    return led_mapping[y][x]; +} + +static GFXINLINE void set_hardware_shutdown(GDisplay* g, bool shutdown) { +    (void) g; +    if(!shutdown) { +        palSetPad(GPIOB, 16); +    } +    else { +        palClearPad(GPIOB, 16); +    } +} + +static GFXINLINE void write_data(GDisplay *g, uint8_t* data, uint16_t length) { +	(void) g; +	i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, data, length, 0, 0, US2ST(IS31_TIMEOUT)); +} + +#endif /* _GDISP_LLD_BOARD_H */ diff --git a/keyboards/whitefox/drivers/gdisp/IS31FL3731C/driver.mk b/keyboards/whitefox/drivers/gdisp/IS31FL3731C/driver.mk new file mode 100644 index 0000000000..f32d0d8685 --- /dev/null +++ b/keyboards/whitefox/drivers/gdisp/IS31FL3731C/driver.mk @@ -0,0 +1,2 @@ +GFXINC += drivers/gdisp/IS31FL3731C +GFXSRC += drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c diff --git a/keyboards/whitefox/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c b/keyboards/whitefox/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c new file mode 100644 index 0000000000..c807cbd1e2 --- /dev/null +++ b/keyboards/whitefox/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c @@ -0,0 +1,312 @@ +/* +Copyright 2016 Fred Sundvik <[email protected]> + +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/>. +*/ + +#include "gfx.h" + +#if GFX_USE_GDISP + +#define GDISP_DRIVER_VMT			GDISPVMT_IS31FL3731C_WHITEFOX +#include "drivers/gdisp/IS31FL3731C/gdisp_lld_config.h" +#include "src/gdisp/gdisp_driver.h" + +#include "board_IS31FL3731C.h" + + +// Can't include led_tables from here +extern const uint8_t CIE1931_CURVE[]; + +/*===========================================================================*/ +/* Driver local definitions.                                                 */ +/*===========================================================================*/ + +#ifndef GDISP_SCREEN_HEIGHT +	#define GDISP_SCREEN_HEIGHT		9 +#endif +#ifndef GDISP_SCREEN_WIDTH +	#define GDISP_SCREEN_WIDTH		16 +#endif +#ifndef GDISP_INITIAL_CONTRAST +	#define GDISP_INITIAL_CONTRAST	0 +#endif +#ifndef GDISP_INITIAL_BACKLIGHT +	#define GDISP_INITIAL_BACKLIGHT	0 +#endif + +#define GDISP_FLG_NEEDFLUSH			(GDISP_FLG_DRIVER<<0) + +#define IS31_ADDR_DEFAULT 0x74 + +#define IS31_REG_CONFIG  0x00 +// bits in reg +#define IS31_REG_CONFIG_PICTUREMODE 0x00 +#define IS31_REG_CONFIG_AUTOPLAYMODE 0x08 +#define IS31_REG_CONFIG_AUDIOPLAYMODE 0x18 +// D2:D0 bits are starting frame for autoplay mode + +#define IS31_REG_PICTDISP 0x01 // D2:D0 frame select for picture mode + +#define IS31_REG_AUTOPLAYCTRL1 0x02 +// D6:D4 number of loops (000=infty) +// D2:D0 number of frames to be used + +#define IS31_REG_AUTOPLAYCTRL2 0x03 // D5:D0 delay time (*11ms) + +#define IS31_REG_DISPLAYOPT 0x05 +#define IS31_REG_DISPLAYOPT_INTENSITY_SAME 0x20 // same intensity for all frames +#define IS31_REG_DISPLAYOPT_BLINK_ENABLE 0x8 +// D2:D0 bits blink period time (*0.27s) + +#define IS31_REG_AUDIOSYNC 0x06 +#define IS31_REG_AUDIOSYNC_ENABLE 0x1 + +#define IS31_REG_FRAMESTATE 0x07 + +#define IS31_REG_BREATHCTRL1 0x08 +// D6:D4 fade out time (26ms*2^i) +// D2:D0 fade in time (26ms*2^i) + +#define IS31_REG_BREATHCTRL2 0x09 +#define IS31_REG_BREATHCTRL2_ENABLE 0x10 +// D2:D0 extinguish time (3.5ms*2^i) + +#define IS31_REG_SHUTDOWN 0x0A +#define IS31_REG_SHUTDOWN_OFF 0x0 +#define IS31_REG_SHUTDOWN_ON 0x1 + +#define IS31_REG_AGCCTRL 0x0B +#define IS31_REG_ADCRATE 0x0C + +#define IS31_COMMANDREGISTER 0xFD +#define IS31_FUNCTIONREG 0x0B    // helpfully called 'page nine' +#define IS31_FUNCTIONREG_SIZE 0xD + +#define IS31_FRAME_SIZE 0xB4 + +#define IS31_PWM_REG 0x24 +#define IS31_PWM_SIZE 0x90 + +#define IS31_LED_MASK_SIZE 0x12 +#define IS31_SCREEN_WIDTH 16 + +#define IS31 + +/*===========================================================================*/ +/* Driver local functions.                                                   */ +/*===========================================================================*/ + +typedef struct{ +    uint8_t write_buffer_offset; +    uint8_t write_buffer[IS31_FRAME_SIZE]; +    uint8_t frame_buffer[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH]; +    uint8_t page; +}__attribute__((__packed__)) PrivData; + +// Some common routines and macros +#define PRIV(g)                         ((PrivData*)g->priv) + +/*===========================================================================*/ +/* Driver exported functions.                                                */ +/*===========================================================================*/ + +static GFXINLINE void write_page(GDisplay* g, uint8_t page) { +    uint8_t tx[2] __attribute__((aligned(2))); +    tx[0] = IS31_COMMANDREGISTER; +    tx[1] = page; +    write_data(g, tx, 2); +} + +static GFXINLINE void write_register(GDisplay* g, uint8_t page, uint8_t reg, uint8_t data) { +    uint8_t tx[2] __attribute__((aligned(2))); +    tx[0] = reg; +    tx[1] = data; +    write_page(g, page); +    write_data(g, tx, 2); +} + +static GFXINLINE void write_ram(GDisplay *g, uint8_t page, uint16_t offset, uint16_t length) { +    PRIV(g)->write_buffer_offset = offset; +    write_page(g, page); +    write_data(g, (uint8_t*)PRIV(g), length + 1); +} + +LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { +	// The private area is the display surface. +	g->priv = gfxAlloc(sizeof(PrivData)); +    __builtin_memset(PRIV(g), 0, sizeof(PrivData)); +	PRIV(g)->page = 0; + +	// Initialise the board interface +	init_board(g); +	gfxSleepMilliseconds(10); + +    // zero function page, all registers (assuming full_page is all zeroes) +    write_ram(g, IS31_FUNCTIONREG, 0, IS31_FUNCTIONREG_SIZE); +    set_hardware_shutdown(g, false); +    gfxSleepMilliseconds(10); +    // software shutdown +    write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF); +    gfxSleepMilliseconds(10); +    // zero function page, all registers +    write_ram(g, IS31_FUNCTIONREG, 0, IS31_FUNCTIONREG_SIZE); +    gfxSleepMilliseconds(10); + + +    // zero all LED registers on all 8 pages, and enable the mask +    __builtin_memcpy(PRIV(g)->write_buffer, get_led_mask(g), IS31_LED_MASK_SIZE); +    for(uint8_t i=0; i<8; i++) { +        write_ram(g, i, 0, IS31_FRAME_SIZE); +        gfxSleepMilliseconds(1); +    } + +    // software shutdown disable (i.e. turn stuff on) +    write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF); +    gfxSleepMilliseconds(10); + +    // Finish Init +    post_init_board(g); + +	/* Initialise the GDISP structure */ +	g->g.Width = GDISP_SCREEN_WIDTH; +	g->g.Height = GDISP_SCREEN_HEIGHT; +	g->g.Orientation = GDISP_ROTATE_0; +	g->g.Powermode = powerOff; +	g->g.Backlight = GDISP_INITIAL_BACKLIGHT; +	g->g.Contrast = GDISP_INITIAL_CONTRAST; +	return TRUE; +} + +#if GDISP_HARDWARE_FLUSH +	LLDSPEC void gdisp_lld_flush(GDisplay *g) { +		// Don't flush if we don't need it. +		if (!(g->flags & GDISP_FLG_NEEDFLUSH)) +			return; + +		PRIV(g)->page++; +		PRIV(g)->page %= 2; +		// TODO: some smarter algorithm for this +		// We should run only one physical page at a time +		// This way we don't need to send so much data, and +		// we could use slightly less memory +		uint8_t* src = PRIV(g)->frame_buffer; +		for (int y=0;y<GDISP_SCREEN_HEIGHT;y++) { +		    for (int x=0;x<GDISP_SCREEN_WIDTH;x++) { +		        uint8_t val = (uint16_t)*src * g->g.Backlight / 100; +		        PRIV(g)->write_buffer[get_led_address(g, x, y)]=CIE1931_CURVE[val]; +		        ++src; +		    } +		} +        write_ram(g, PRIV(g)->page, IS31_PWM_REG, IS31_PWM_SIZE); +        gfxSleepMilliseconds(1); +        write_register(g, IS31_FUNCTIONREG, IS31_REG_PICTDISP, PRIV(g)->page); + +		g->flags &= ~GDISP_FLG_NEEDFLUSH; +	} +#endif + +#if GDISP_HARDWARE_DRAWPIXEL +	LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { +		coord_t		x, y; + +		switch(g->g.Orientation) { +		default: +		case GDISP_ROTATE_0: +			x = g->p.x; +			y = g->p.y; +			break; +		case GDISP_ROTATE_180: +			x = GDISP_SCREEN_WIDTH-1 - g->p.x; +			y = g->p.y; +			break; +		} +		PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x] = gdispColor2Native(g->p.color); +		g->flags |= GDISP_FLG_NEEDFLUSH; +	} +#endif + +#if GDISP_HARDWARE_PIXELREAD +	LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { +		coord_t		x, y; + +		switch(g->g.Orientation) { +		default: +		case GDISP_ROTATE_0: +			x = g->p.x; +			y = g->p.y; +			break; +		case GDISP_ROTATE_180: +			x = GDISP_SCREEN_WIDTH-1 - g->p.x; +			y = g->p.y; +			break; +		} +		return gdispNative2Color(PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x]); +	} +#endif + +#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL +	LLDSPEC void gdisp_lld_control(GDisplay *g) { +		switch(g->p.x) { +		case GDISP_CONTROL_POWER: +			if (g->g.Powermode == (powermode_t)g->p.ptr) +				return; +			switch((powermode_t)g->p.ptr) { +			case powerOff: +			case powerSleep: +			case powerDeepSleep: +                write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF); +				break; +			case powerOn: +                write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_ON); +				break; +			default: +				return; +			} +			g->g.Powermode = (powermode_t)g->p.ptr; +			return; + +		case GDISP_CONTROL_ORIENTATION: +			if (g->g.Orientation == (orientation_t)g->p.ptr) +				return; +			switch((orientation_t)g->p.ptr) { +			/* Rotation is handled by the drawing routines */ +			case GDISP_ROTATE_0: +			case GDISP_ROTATE_180: +				g->g.Height = GDISP_SCREEN_HEIGHT; +				g->g.Width = GDISP_SCREEN_WIDTH; +				break; +			case GDISP_ROTATE_90: +			case GDISP_ROTATE_270: +				g->g.Height = GDISP_SCREEN_WIDTH; +				g->g.Width = GDISP_SCREEN_HEIGHT; +				break; +			default: +				return; +			} +			g->g.Orientation = (orientation_t)g->p.ptr; +			return; + +		case GDISP_CONTROL_BACKLIGHT: +		    if (g->g.Backlight == (unsigned)g->p.ptr) +                return; +		    unsigned val = (unsigned)g->p.ptr; +		    g->g.Backlight = val > 100 ? 100 : val; +            g->flags |= GDISP_FLG_NEEDFLUSH; +		    return; +		} +	} +#endif // GDISP_NEED_CONTROL + +#endif // GFX_USE_GDISP diff --git a/keyboards/whitefox/drivers/gdisp/IS31FL3731C/gdisp_lld_config.h b/keyboards/whitefox/drivers/gdisp/IS31FL3731C/gdisp_lld_config.h new file mode 100644 index 0000000000..bb28ad775e --- /dev/null +++ b/keyboards/whitefox/drivers/gdisp/IS31FL3731C/gdisp_lld_config.h @@ -0,0 +1,36 @@ +/* +Copyright 2016 Fred Sundvik <[email protected]> + +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 _GDISP_LLD_CONFIG_H +#define _GDISP_LLD_CONFIG_H + +#if GFX_USE_GDISP + +/*===========================================================================*/ +/* Driver hardware support.                                                  */ +/*===========================================================================*/ + +#define GDISP_HARDWARE_FLUSH			TRUE		// This controller requires flushing +#define GDISP_HARDWARE_DRAWPIXEL		TRUE +#define GDISP_HARDWARE_PIXELREAD		TRUE +#define GDISP_HARDWARE_CONTROL			TRUE + +#define GDISP_LLD_PIXELFORMAT			GDISP_PIXELFORMAT_GRAY256 + +#endif	/* GFX_USE_GDISP */ + +#endif	/* _GDISP_LLD_CONFIG_H */ diff --git a/keyboards/whitefox/gfxconf.h b/keyboards/whitefox/gfxconf.h new file mode 100644 index 0000000000..890317a0f4 --- /dev/null +++ b/keyboards/whitefox/gfxconf.h @@ -0,0 +1,329 @@ +/** + * This file has a different license to the rest of the uGFX system. + * You can copy, modify and distribute this file as you see fit. + * You do not need to publish your source modifications to this file. + * The only thing you are not permitted to do is to relicense it + * under a different license. + */ + +/** + * Copy this file into your project directory and rename it as gfxconf.h + * Edit your copy to turn on the uGFX features you want to use. + * The values below are the defaults. + * + * Only remove the comments from lines where you want to change the + * default value. This allows definitions to be included from + * driver makefiles when required and provides the best future + * compatibility for your project. + * + * Please use spaces instead of tabs in this file. + */ + +#ifndef _GFXCONF_H +#define _GFXCONF_H + + +/////////////////////////////////////////////////////////////////////////// +// GOS - One of these must be defined, preferably in your Makefile       // +/////////////////////////////////////////////////////////////////////////// +//#define GFX_USE_OS_CHIBIOS                           TRUE +//#define GFX_USE_OS_FREERTOS                          FALSE +//    #define GFX_FREERTOS_USE_TRACE                   FALSE +//#define GFX_USE_OS_WIN32                             FALSE +//#define GFX_USE_OS_LINUX                             FALSE +//#define GFX_USE_OS_OSX                               FALSE +//#define GFX_USE_OS_ECOS                              FALSE +//#define GFX_USE_OS_RAWRTOS                           FALSE +//#define GFX_USE_OS_ARDUINO                           FALSE +//#define GFX_USE_OS_KEIL                              FALSE +//#define GFX_USE_OS_CMSIS                             FALSE +//#define GFX_USE_OS_RAW32                             FALSE +//    #define INTERRUPTS_OFF()                         optional_code +//    #define INTERRUPTS_ON()                          optional_code +// These are not defined by default for some reason +#define GOS_NEED_X_THREADS	FALSE +#define GOS_NEED_X_HEAP		FALSE + +// Options that (should where relevant) apply to all operating systems +    #define GFX_NO_INLINE                            FALSE +//    #define GFX_COMPILER                             GFX_COMPILER_UNKNOWN +//    #define GFX_CPU                                  GFX_CPU_UNKNOWN +//    #define GFX_OS_HEAP_SIZE                         0 +//    #define GFX_OS_NO_INIT                           FALSE +//    #define GFX_OS_INIT_NO_WARNING                   FALSE +//    #define GFX_OS_PRE_INIT_FUNCTION                 myHardwareInitRoutine +//    #define GFX_OS_EXTRA_INIT_FUNCTION               myOSInitRoutine +//    #define GFX_OS_EXTRA_DEINIT_FUNCTION             myOSDeInitRoutine + + +/////////////////////////////////////////////////////////////////////////// +// GDISP                                                                 // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GDISP                                TRUE + +//#define GDISP_NEED_AUTOFLUSH                         FALSE +//#define GDISP_NEED_TIMERFLUSH                        FALSE +//#define GDISP_NEED_VALIDATION                        TRUE +//#define GDISP_NEED_CLIP                              TRUE +#define GDISP_NEED_CIRCLE                            TRUE +#define GDISP_NEED_ELLIPSE                           TRUE +#define GDISP_NEED_ARC                               TRUE +#define GDISP_NEED_ARCSECTORS                        TRUE +#define GDISP_NEED_CONVEX_POLYGON                    TRUE +//#define GDISP_NEED_SCROLL                            FALSE +#define GDISP_NEED_PIXELREAD                         TRUE +#define GDISP_NEED_CONTROL                           TRUE +//#define GDISP_NEED_QUERY                             FALSE +//#define GDISP_NEED_MULTITHREAD                       FALSE +//#define GDISP_NEED_STREAMING                         FALSE +#define GDISP_NEED_TEXT                              TRUE +//    #define GDISP_NEED_TEXT_WORDWRAP                 FALSE +//    #define GDISP_NEED_ANTIALIAS                     FALSE +//    #define GDISP_NEED_UTF8                          FALSE +    #define GDISP_NEED_TEXT_KERNING                  TRUE +//    #define GDISP_INCLUDE_FONT_UI1                   FALSE +//    #define GDISP_INCLUDE_FONT_UI2                   FALSE		// The smallest preferred font. +//    #define GDISP_INCLUDE_FONT_LARGENUMBERS          FALSE +//    #define GDISP_INCLUDE_FONT_DEJAVUSANS10          FALSE +//    #define GDISP_INCLUDE_FONT_DEJAVUSANS12          FALSE +//    #define GDISP_INCLUDE_FONT_DEJAVUSANS16          FALSE +//    #define GDISP_INCLUDE_FONT_DEJAVUSANS20          FALSE +//    #define GDISP_INCLUDE_FONT_DEJAVUSANS24          FALSE +//    #define GDISP_INCLUDE_FONT_DEJAVUSANS32          FALSE +    #define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12      TRUE +//    #define GDISP_INCLUDE_FONT_FIXED_10X20           FALSE +//    #define GDISP_INCLUDE_FONT_FIXED_7X14            FALSE +    #define GDISP_INCLUDE_FONT_FIXED_5X8             TRUE +//    #define GDISP_INCLUDE_FONT_DEJAVUSANS12_AA       FALSE +//    #define GDISP_INCLUDE_FONT_DEJAVUSANS16_AA       FALSE +//    #define GDISP_INCLUDE_FONT_DEJAVUSANS20_AA       FALSE +//    #define GDISP_INCLUDE_FONT_DEJAVUSANS24_AA       FALSE +//    #define GDISP_INCLUDE_FONT_DEJAVUSANS32_AA       FALSE +//    #define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12_AA   FALSE +//    #define GDISP_INCLUDE_USER_FONTS                 FALSE + +//#define GDISP_NEED_IMAGE                             FALSE +//    #define GDISP_NEED_IMAGE_NATIVE                  FALSE +//    #define GDISP_NEED_IMAGE_GIF                     FALSE +//    #define GDISP_NEED_IMAGE_BMP                     FALSE +//        #define GDISP_NEED_IMAGE_BMP_1               FALSE +//        #define GDISP_NEED_IMAGE_BMP_4               FALSE +//        #define GDISP_NEED_IMAGE_BMP_4_RLE           FALSE +//        #define GDISP_NEED_IMAGE_BMP_8               FALSE +//        #define GDISP_NEED_IMAGE_BMP_8_RLE           FALSE +//        #define GDISP_NEED_IMAGE_BMP_16              FALSE +//        #define GDISP_NEED_IMAGE_BMP_24              FALSE +//        #define GDISP_NEED_IMAGE_BMP_32              FALSE +//    #define GDISP_NEED_IMAGE_JPG                     FALSE +//    #define GDISP_NEED_IMAGE_PNG                     FALSE +//    #define GDISP_NEED_IMAGE_ACCOUNTING              FALSE +#ifdef EMULATOR +#define GDISP_NEED_PIXMAP                            TRUE +#endif +//    #define GDISP_NEED_PIXMAP_IMAGE                  FALSE + +//#define GDISP_DEFAULT_ORIENTATION                    GDISP_ROTATE_LANDSCAPE    // If not defined the native hardware orientation is used. +//#define GDISP_LINEBUF_SIZE                           128 +//#define GDISP_STARTUP_COLOR                          Black +#define GDISP_NEED_STARTUP_LOGO                      FALSE + +//#define GDISP_TOTAL_DISPLAYS		                 2 + +#ifndef EMULATOR +#define GDISP_DRIVER_LIST                            GDISPVMT_IS31FL3731C_WHITEFOX +#endif + +    #ifdef GDISP_DRIVER_LIST +        // For code and speed optimization define as TRUE or FALSE if all controllers have the same capability +        #define GDISP_HARDWARE_STREAM_WRITE          FALSE +        #define GDISP_HARDWARE_STREAM_READ           FALSE +        #define GDISP_HARDWARE_STREAM_POS            FALSE +        #define GDISP_HARDWARE_DRAWPIXEL             TRUE +        #define GDISP_HARDWARE_CLEARS                FALSE +        #define GDISP_HARDWARE_FILLS                 FALSE +        //#define GDISP_HARDWARE_BITFILLS              FALSE +        #define GDISP_HARDWARE_SCROLL                FALSE +        #define GDISP_HARDWARE_PIXELREAD             TRUE +        #define GDISP_HARDWARE_CONTROL               TRUE +        #define GDISP_HARDWARE_QUERY                 FALSE +        #define GDISP_HARDWARE_CLIP                  FALSE + +        #define GDISP_PIXELFORMAT                    GDISP_PIXELFORMAT_RGB888 +    #endif + +// The custom format is not defined for some reason, so define it as error +// so we don't get compiler warnings +#define GDISP_PIXELFORMAT_CUSTOM GDISP_PIXELFORMAT_ERROR + +#define GDISP_USE_GFXNET                             FALSE +//    #define GDISP_GFXNET_PORT                        13001 +//    #define GDISP_GFXNET_CUSTOM_LWIP_STARTUP         FALSE +//    #define GDISP_DONT_WAIT_FOR_NET_DISPLAY          FALSE +//    #define GDISP_GFXNET_UNSAFE_SOCKETS              FALSE + + +/////////////////////////////////////////////////////////////////////////// +// GWIN                                                                  // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GWIN                                 FALSE + +//#define GWIN_NEED_WINDOWMANAGER                      FALSE +//    #define GWIN_REDRAW_IMMEDIATE                    FALSE +//    #define GWIN_REDRAW_SINGLEOP                     FALSE +//    #define GWIN_NEED_FLASHING                       FALSE +//        #define GWIN_FLASHING_PERIOD                 250 + +//#define GWIN_NEED_CONSOLE                            FALSE +//    #define GWIN_CONSOLE_USE_HISTORY                 FALSE +//        #define GWIN_CONSOLE_HISTORY_AVERAGING       FALSE +//        #define GWIN_CONSOLE_HISTORY_ATCREATE        FALSE +//    #define GWIN_CONSOLE_ESCSEQ                      FALSE +//    #define GWIN_CONSOLE_USE_BASESTREAM              FALSE +//    #define GWIN_CONSOLE_USE_FLOAT                   FALSE +//#define GWIN_NEED_GRAPH                              FALSE +//#define GWIN_NEED_GL3D                               FALSE + +//#define GWIN_NEED_WIDGET                             FALSE +//#define GWIN_FOCUS_HIGHLIGHT_WIDTH                   1 +//    #define GWIN_NEED_LABEL                          FALSE +//        #define GWIN_LABEL_ATTRIBUTE                 FALSE +//    #define GWIN_NEED_BUTTON                         FALSE +//        #define GWIN_BUTTON_LAZY_RELEASE             FALSE +//    #define GWIN_NEED_SLIDER                         FALSE +//        #define GWIN_SLIDER_NOSNAP                   FALSE +//        #define GWIN_SLIDER_DEAD_BAND                5 +//        #define GWIN_SLIDER_TOGGLE_INC               20 +//    #define GWIN_NEED_CHECKBOX                       FALSE +//    #define GWIN_NEED_IMAGE                          FALSE +//        #define GWIN_NEED_IMAGE_ANIMATION            FALSE +//    #define GWIN_NEED_RADIO                          FALSE +//    #define GWIN_NEED_LIST                           FALSE +//        #define GWIN_NEED_LIST_IMAGES                FALSE +//    #define GWIN_NEED_PROGRESSBAR                    FALSE +//        #define GWIN_PROGRESSBAR_AUTO                FALSE +//    #define GWIN_NEED_KEYBOARD                       FALSE +//        #define GWIN_KEYBOARD_DEFAULT_LAYOUT         VirtualKeyboard_English1 +//        #define GWIN_NEED_KEYBOARD_ENGLISH1          TRUE +//    #define GWIN_NEED_TEXTEDIT                       FALSE +//    #define GWIN_FLAT_STYLING                        FALSE +//    #define GWIN_WIDGET_TAGS                         FALSE + +//#define GWIN_NEED_CONTAINERS                         FALSE +//    #define GWIN_NEED_CONTAINER                      FALSE +//    #define GWIN_NEED_FRAME                          FALSE +//    #define GWIN_NEED_TABSET                         FALSE +//        #define GWIN_TABSET_TABHEIGHT                18 + + +/////////////////////////////////////////////////////////////////////////// +// GEVENT                                                                // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GEVENT                               TRUE + +//#define GEVENT_ASSERT_NO_RESOURCE                    FALSE +//#define GEVENT_MAXIMUM_SIZE                          32 +//#define GEVENT_MAX_SOURCE_LISTENERS                  32 + + +/////////////////////////////////////////////////////////////////////////// +// GTIMER                                                                // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GTIMER                               FALSE + +//#define GTIMER_THREAD_PRIORITY                       HIGH_PRIORITY +//#define GTIMER_THREAD_WORKAREA_SIZE                  2048 + + +/////////////////////////////////////////////////////////////////////////// +// GQUEUE                                                                // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GQUEUE                               FALSE + +//#define GQUEUE_NEED_ASYNC                            FALSE +//#define GQUEUE_NEED_GSYNC                            FALSE +//#define GQUEUE_NEED_FSYNC                            FALSE +//#define GQUEUE_NEED_BUFFERS                          FALSE + +/////////////////////////////////////////////////////////////////////////// +// GINPUT                                                                // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GINPUT                               FALSE + +//#define GINPUT_NEED_MOUSE                            FALSE +//    #define GINPUT_TOUCH_STARTRAW                    FALSE +//    #define GINPUT_TOUCH_NOTOUCH                     FALSE +//    #define GINPUT_TOUCH_NOCALIBRATE                 FALSE +//    #define GINPUT_TOUCH_NOCALIBRATE_GUI             FALSE +//    #define GINPUT_MOUSE_POLL_PERIOD                 25 +//    #define GINPUT_MOUSE_CLICK_TIME                  300 +//    #define GINPUT_TOUCH_CXTCLICK_TIME               700 +//    #define GINPUT_TOUCH_USER_CALIBRATION_LOAD       FALSE +//    #define GINPUT_TOUCH_USER_CALIBRATION_SAVE       FALSE +//    #define GMOUSE_DRIVER_LIST                       GMOUSEVMT_Win32, GMOUSEVMT_Win32 +//#define GINPUT_NEED_KEYBOARD                         FALSE +//    #define GINPUT_KEYBOARD_POLL_PERIOD              200 +//    #define GKEYBOARD_DRIVER_LIST                    GKEYBOARDVMT_Win32, GKEYBOARDVMT_Win32 +//    #define GKEYBOARD_LAYOUT_OFF                     FALSE +//        #define GKEYBOARD_LAYOUT_SCANCODE2_US        FALSE +//#define GINPUT_NEED_TOGGLE                           FALSE +//#define GINPUT_NEED_DIAL                             FALSE + + +/////////////////////////////////////////////////////////////////////////// +// GFILE                                                                 // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GFILE                                FALSE + +//#define GFILE_NEED_PRINTG                            FALSE +//#define GFILE_NEED_SCANG                             FALSE +//#define GFILE_NEED_STRINGS                           FALSE +//#define GFILE_NEED_FILELISTS                         FALSE +//#define GFILE_NEED_STDIO                             FALSE +//#define GFILE_NEED_NOAUTOMOUNT                       FALSE +//#define GFILE_NEED_NOAUTOSYNC                        FALSE + +//#define GFILE_NEED_MEMFS                             FALSE +//#define GFILE_NEED_ROMFS                             FALSE +//#define GFILE_NEED_RAMFS                             FALSE +//#define GFILE_NEED_FATFS                             FALSE +//#define GFILE_NEED_NATIVEFS                          FALSE +//#define GFILE_NEED_CHBIOSFS                          FALSE + +//#define GFILE_ALLOW_FLOATS                           FALSE +//#define GFILE_ALLOW_DEVICESPECIFIC                   FALSE +//#define GFILE_MAX_GFILES                             3 + +/////////////////////////////////////////////////////////////////////////// +// GADC                                                                  // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GADC                                 FALSE + +//#define GADC_MAX_LOWSPEED_DEVICES                    4 + + +/////////////////////////////////////////////////////////////////////////// +// GAUDIO                                                                // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GAUDIO                               FALSE +// There seems to be a bug in the ugfx code, the wrong define is used +// So define it in order to avoid warnings +#define GFX_USE_GAUDIN                               GFX_USE_GAUDIO +//    #define GAUDIO_NEED_PLAY                         FALSE +//    #define GAUDIO_NEED_RECORD                       FALSE + + +/////////////////////////////////////////////////////////////////////////// +// GMISC                                                                 // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GMISC                                TRUE + +//#define GMISC_NEED_ARRAYOPS                          FALSE +//#define GMISC_NEED_FASTTRIG                          FALSE +//#define GMISC_NEED_FIXEDTRIG                         FALSE +//#define GMISC_NEED_INVSQRT                           FALSE +//    #define GMISC_INVSQRT_MIXED_ENDIAN               FALSE +//    #define GMISC_INVSQRT_REAL_SLOW                  FALSE +#define GMISC_NEED_MATRIXFLOAT2D                     TRUE +#define GMISC_NEED_MATRIXFIXED2D                     FALSE + +#endif /* _GFXCONF_H */ diff --git a/keyboards/whitefox/halconf.h b/keyboards/whitefox/halconf.h index 46b37a4f46..b380315298 100644 --- a/keyboards/whitefox/halconf.h +++ b/keyboards/whitefox/halconf.h @@ -76,7 +76,7 @@   * @brief   Enables the I2C subsystem.   */  #if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) -#define HAL_USE_I2C                 FALSE +#define HAL_USE_I2C                 TRUE  #endif  /** diff --git a/keyboards/whitefox/keymaps/jetpacktuxedo/Makefile b/keyboards/whitefox/keymaps/jetpacktuxedo/Makefile new file mode 100644 index 0000000000..8eb483103c --- /dev/null +++ b/keyboards/whitefox/keymaps/jetpacktuxedo/Makefile @@ -0,0 +1,5 @@ +ifndef QUANTUM_DIR +	include ../../../Makefile +endif + +BACKLIGHT_ENABLE = yes diff --git a/keyboards/whitefox/keymaps/jetpacktuxedo/keymap.c b/keyboards/whitefox/keymaps/jetpacktuxedo/keymap.c index 09f6ca34df..82de171733 100644 --- a/keyboards/whitefox/keymaps/jetpacktuxedo/keymap.c +++ b/keyboards/whitefox/keymaps/jetpacktuxedo/keymap.c @@ -31,11 +31,11 @@ const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = {       * `---------------------------------------------------------------'       */      [0] = KEYMAP( \ -        KC_ESC, KC_1,   KC_2,   KC_3,   KC_4,   KC_5,   KC_6,   KC_7,   KC_8,   KC_9,   KC_0,   KC_MINS,KC_EQL,KC_NO,KC_BSPC,KC_INS, \ -        KC_TAB, KC_Q,   KC_W,   KC_E,   KC_R,   KC_T,   KC_Y,   KC_U,   KC_I,   KC_O,   KC_P,   KC_LBRC,KC_RBRC,   KC_BSLS,  KC_DEL, \ -        MO(1),  KC_A,   KC_S,   KC_D,   KC_F,   KC_G,   KC_H,   KC_J,   KC_K,   KC_L,   KC_SCLN,KC_QUOT,KC_NUHS,  KC_ENT,    KC_PGUP,\ -        KC_LSFT,KC_NUBS,KC_Z,   KC_X,   KC_C,   KC_V,   KC_B,   KC_N,   KC_M,   KC_COMM,KC_DOT, KC_SLSH,    KC_RSFT, KC_UP,  KC_PGDN,\ -        KC_LCTL,KC_LGUI,KC_LALT,                        KC_SPC,                 KC_RALT,KC_RCTL,KC_NO,       KC_LEFT,KC_DOWN,KC_RGHT \ +        KC_GESC, KC_1,   KC_2,   KC_3,   KC_4,   KC_5,   KC_6,   KC_7,   KC_8,   KC_9,   KC_0,   KC_MINS,KC_EQL,KC_NO,KC_BSPC,KC_INS, \ +        KC_TAB,  KC_Q,   KC_W,   KC_E,   KC_R,   KC_T,   KC_Y,   KC_U,   KC_I,   KC_O,   KC_P,   KC_LBRC,KC_RBRC,   KC_BSLS,  KC_DEL, \ +        MO(1),   KC_A,   KC_S,   KC_D,   KC_F,   KC_G,   KC_H,   KC_J,   KC_K,   KC_L,   KC_SCLN,KC_QUOT,KC_NUHS,  KC_ENT,    KC_PGUP,\ +        KC_LSFT, KC_NUBS,KC_Z,   KC_X,   KC_C,   KC_V,   KC_B,   KC_N,   KC_M,   KC_COMM,KC_DOT, KC_SLSH,    KC_RSFT, KC_UP,  KC_PGDN,\ +        KC_LCTL, KC_LGUI,KC_LALT,                        KC_SPC,                 KC_RALT,KC_RCTL,KC_NO,       KC_LEFT,KC_DOWN,KC_RGHT \      ),      /* Layer 1: FN Layer       * ,---------------------------------------------------------------. @@ -52,8 +52,8 @@ const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = {       */      [1] = KEYMAP( \          KC_GRV, KC_F1,  KC_F2,  KC_F3,  KC_F4,  KC_F5,  KC_F6,  KC_F7,  KC_F8,  KC_F9,  KC_F10, KC_F11, KC_F12, KC_TRNS,KC_TRNS,KC_MUTE,\ -        KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_PSCR,KC_SLCK,KC_PAUS,KC_TRNS,        KC_TRNS,\ -        KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,        KC_VOLU,\ +        KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,BL_TOGG,KC_TRNS,KC_TRNS,BL_INC, KC_TRNS,KC_PSCR,KC_SLCK,KC_PAUS,KC_TRNS,        KC_TRNS,\ +        KC_TRNS,KC_TRNS,KC_TRNS,BL_DEC, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,        KC_VOLU,\          KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,        KC_PGUP,KC_VOLD,\          KC_TRNS,KC_TRNS,KC_TRNS,                        KC_TRNS,                KC_TRNS,KC_TRNS,KC_TRNS,        KC_HOME,KC_PGDN,KC_END  \      ), diff --git a/keyboards/whitefox/rules.mk b/keyboards/whitefox/rules.mk index 18b690f492..565381e16b 100644 --- a/keyboards/whitefox/rules.mk +++ b/keyboards/whitefox/rules.mk @@ -1,6 +1,7 @@  # project specific files  SRC =	matrix.c \ -	led.c +	led.c \ +	animations.c  ## chip/board settings  # - the next two should match the directories in @@ -66,3 +67,7 @@ COMMAND_ENABLE ?= yes    # Commands for debug and configuration  #SLEEP_LED_ENABLE ?= yes  # Breathing sleep LED during USB suspend  NKRO_ENABLE ?= yes	    # USB Nkey Rollover  CUSTOM_MATRIX ?= yes # Custom matrix file +BACKLIGHT_ENABLE ?= yes +VISUALIZER_ENABLE ?= yes + +include $(KEYBOARD_PATH)/drivers/gdisp/IS31FL3731C/driver.mk diff --git a/keyboards/whitefox/visualizer.c b/keyboards/whitefox/visualizer.c new file mode 100644 index 0000000000..167e0ec4de --- /dev/null +++ b/keyboards/whitefox/visualizer.c @@ -0,0 +1,60 @@ +/* Copyright 2017 Fred Sundvik + * + * 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 KEYBOARDS_WHITEFOX_SIMPLE_VISUALIZER_H_ +#define KEYBOARDS_WHITEFOX_SIMPLE_VISUALIZER_H_ + +#include "visualizer.h" +#include "visualizer_keyframes.h" +#include "led.h" +#include "animations.h" + + +static bool initial_update = true; + +// Feel free to modify the animations below, or even add new ones if needed + +void initialize_user_visualizer(visualizer_state_t* state) { +    // The brightness will be dynamically adjustable in the future +    // But for now, change it here. +    initial_update = true; +    start_keyframe_animation(&default_startup_animation); +} + + +void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { +    // Add more tests, change the colors and layer texts here +    // Usually you want to check the high bits (higher layers first) +    // because that's the order layers are processed for keypresses +    // You can for check for example: +    // state->status.layer +    // state->status.default_layer +    // state->status.leds (see led.h for available statuses) + +    if (initial_update) { initial_update=false; start_keyframe_animation(&led_test_animation); } +} + + +void user_visualizer_suspend(visualizer_state_t* state) { +    start_keyframe_animation(&default_suspend_animation); +} + +void user_visualizer_resume(visualizer_state_t* state) { +    initial_update = true; +    start_keyframe_animation(&default_startup_animation); +} + +#endif /* KEYBOARDS_WHITEFOX_SIMPLE_VISUALIZER_H_ */ diff --git a/quantum/keycode_config.c b/quantum/keycode_config.c index 4f7bc525ec..eb39c8fe00 100644 --- a/quantum/keycode_config.c +++ b/quantum/keycode_config.c @@ -88,3 +88,31 @@ uint16_t keycode_config(uint16_t keycode) {              return keycode;      }  } + +uint8_t mod_config(uint8_t mod) { +    keymap_config.raw = eeconfig_read_keymap(); +    if (keymap_config.swap_lalt_lgui) { +        if ((mod & MOD_RGUI) == MOD_LGUI) { +            mod &= ~MOD_LGUI; +            mod |= MOD_LALT; +        } else if ((mod & MOD_RALT) == MOD_LALT) { +            mod &= ~MOD_LALT; +            mod |= MOD_LGUI; +        } +    } +    if (keymap_config.swap_ralt_rgui) { +        if ((mod & MOD_RGUI) == MOD_RGUI) { +            mod &= ~MOD_RGUI; +            mod |= MOD_RALT; +        } else if ((mod & MOD_RALT) == MOD_RALT) { +            mod &= ~MOD_RALT; +            mod |= MOD_RGUI; +        } +    } +    if (keymap_config.no_gui) { +        mod &= ~MOD_LGUI; +        mod &= ~MOD_RGUI; +    } + +    return mod; +}
\ No newline at end of file diff --git a/quantum/keycode_config.h b/quantum/keycode_config.h index 293fefecfb..022f4bd19b 100644 --- a/quantum/keycode_config.h +++ b/quantum/keycode_config.h @@ -16,11 +16,13 @@  #include "eeconfig.h"  #include "keycode.h" +#include "action_code.h"  #ifndef KEYCODE_CONFIG_H  #define KEYCODE_CONFIG_H  uint16_t keycode_config(uint16_t keycode); +uint8_t mod_config(uint8_t mod);  /* NOTE: Not portable. Bit field order depends on implementation */  typedef union { diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 9dafc8b516..b1460c53cc 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -123,7 +123,8 @@ action_t action_for_key(uint8_t layer, keypos_t key)              action.code = ACTION_LAYER_TAP_TOGGLE(keycode & 0xFF);              break;          case QK_MOD_TAP ... QK_MOD_TAP_MAX: -            action.code = ACTION_MODS_TAP_KEY((keycode >> 0x8) & 0x1F, keycode & 0xFF); +            mod = mod_config((keycode >> 0x8) & 0x1F); +            action.code = ACTION_MODS_TAP_KEY(mod, keycode & 0xFF);              break;      #ifdef BACKLIGHT_ENABLE          case BL_0 ... BL_15: diff --git a/quantum/keymap_extras/keymap_swedish.h b/quantum/keymap_extras/keymap_swedish.h new file mode 100644 index 0000000000..dcfad720d0 --- /dev/null +++ b/quantum/keymap_extras/keymap_swedish.h @@ -0,0 +1,52 @@ +/* Copyright 2017 Andreas Lindhé + * + * 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 KEYMAP_SWEDISH_H +#define KEYMAP_SWEDISH_H + +#include "keymap_nordic.h" + +// There are slight differrences in the keyboards in the nordic contries + +// Swedish redifinitions from the nordic keyset +#undef  NO_AE +#define NO_AE   KC_QUOT  // ä +#undef  NO_CIRC +#define NO_CIRC LSFT(KC_RBRC)  // ^ +#undef  NO_GRV +#define NO_GRV  LSFT(NO_BSLS)  // +#undef  NO_OSLH +#define NO_OSLH KC_SCLN  // ö + +// Additional Swedish keys not defined in the nordic keyset +#define NO_AA   KC_LBRC  // å +#define NO_ASTR LSFT(KC_BSLS)  // * + +// Norwegian unique MAC characters (not vetted for Swedish) +#define NO_ACUT_MAC KC_EQL  // = +#define NO_APOS_MAC KC_NUBS  // ' +#define NO_AT_MAC   KC_BSLS  // @ +#define NO_BSLS_MAC ALGR(LSFT(KC_7)) // '\' +#define NO_DLR_MAC  LSFT(KC_4) // $ +#define NO_GRV_MAC ALGR(NO_BSLS) // ` +#define NO_GRTR_MAC LSFT(KC_GRV)  // > +#define NO_LCBR_MAC ALGR(LSFT(KC_8))  // } +#define NO_LESS_MAC KC_GRV  // > +#define NO_PIPE_MAC ALGR(KC_7)  // | +#define NO_RCBR_MAC ALGR(LSFT(KC_9))  // } + +#endif + diff --git a/quantum/quantum.c b/quantum/quantum.c index 3b5e52ff12..5bb7b04d53 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -530,7 +530,7 @@ void send_string(const char *str) {            shift = false;          }          else { -          int hi = ascii_code>>4 & 0x0f; +          int hi = ascii_code>>4 & 0x0f,                lo = ascii_code & 0x0f;            keycode = pgm_read_byte(&ascii_to_keycode_lut[hi][lo]);            shift = !!( pgm_read_word(&ascii_to_shift_lut[hi]) & (0x8000u>>lo) ); diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index c34ecafa51..6038e31c46 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -550,13 +550,13 @@ enum quantum_keycodes {  #define OSL(layer) (layer | QK_ONE_SHOT_LAYER)  // One-shot mod -#define OSM(mod) (mod | QK_ONE_SHOT_MOD) +#define OSM(mod) ((mod) | QK_ONE_SHOT_MOD)  // Layer tap-toggle  #define TT(layer) (layer | QK_LAYER_TAP_TOGGLE)  // M-od, T-ap - 256 keycode max -#define MT(mod, kc) (kc | QK_MOD_TAP | ((mod & 0x1F) << 8)) +#define MT(mod, kc) (kc | QK_MOD_TAP | (((mod) & 0x1F) << 8))  #define CTL_T(kc) MT(MOD_LCTL, kc)  #define LCTL_T(kc) MT(MOD_LCTL, kc) diff --git a/quantum/visualizer/led_keyframes.c b/quantum/visualizer/led_keyframes.c index 2f4e200439..7e6e5d1ab9 100644 --- a/quantum/visualizer/led_keyframes.c +++ b/quantum/visualizer/led_keyframes.c @@ -41,8 +41,8 @@ static void keyframe_fade_all_leds_from_to(keyframe_animation_t* animation, uint  }  // TODO: Should be customizable per keyboard -#define NUM_ROWS 7 -#define NUM_COLS 7 +#define NUM_ROWS LED_NUM_ROWS +#define NUM_COLS LED_NUM_COLS  static uint8_t crossfade_start_frame[NUM_ROWS][NUM_COLS];  static uint8_t crossfade_end_frame[NUM_ROWS][NUM_COLS]; diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index a4b3ea7e49..cc99d1e3b6 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -105,15 +105,19 @@ static remote_object_t* remote_objects[] = {  GDisplay* LCD_DISPLAY = 0;  GDisplay* LED_DISPLAY = 0; +#ifdef LCD_DISPLAY_NUMBER  __attribute__((weak))  GDisplay* get_lcd_display(void) { -    return gdispGetDisplay(0); +    return gdispGetDisplay(LCD_DISPLAY_NUMBER);  } +#endif +#ifdef LED_DISPLAY_NUMBER  __attribute__((weak))  GDisplay* get_led_display(void) { -    return gdispGetDisplay(1); +    return gdispGetDisplay(LED_DISPLAY_NUMBER);  } +#endif  void start_keyframe_animation(keyframe_animation_t* animation) {      animation->current_frame = -1; @@ -251,9 +255,9 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {          .mods = 0xFF,          .leds = 0xFFFFFFFF,          .suspended = false, -#ifdef VISUALIZER_USER_DATA_SIZE +    #ifdef VISUALIZER_USER_DATA_SIZE          .user_data = {0}, -#endif +    #endif      };      visualizer_state_t state = { @@ -379,25 +383,26 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {  void visualizer_init(void) {      gfxInit(); -#ifdef LCD_BACKLIGHT_ENABLE +  #ifdef LCD_BACKLIGHT_ENABLE      lcd_backlight_init(); -#endif +  #endif -#ifdef SERIAL_LINK_ENABLE +  #ifdef SERIAL_LINK_ENABLE      add_remote_objects(remote_objects, sizeof(remote_objects) / sizeof(remote_object_t*) ); -#endif +  #endif -#ifdef LCD_ENABLE +  #ifdef LCD_ENABLE      LCD_DISPLAY = get_lcd_display(); -#endif -#ifdef BACKLIGHT_ENABLE +  #endif + +  #ifdef BACKLIGHT_ENABLE      LED_DISPLAY = get_led_display(); -#endif +  #endif      // We are using a low priority thread, the idea is to have it run only      // when the main thread is sleeping during the matrix scanning -    gfxThreadCreate(visualizerThreadStack, sizeof(visualizerThreadStack), -                              VISUALIZER_THREAD_PRIORITY, visualizerThread, NULL); +  gfxThreadCreate(visualizerThreadStack, sizeof(visualizerThreadStack), +                  VISUALIZER_THREAD_PRIORITY, visualizerThread, NULL);  }  void update_status(bool changed) { diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index 6f97603bd8..0f7d8636cf 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -51,19 +51,23 @@ GFXSRC := $(patsubst $(TOP_DIR)/%,%,$(GFXSRC))  GFXDEFS := $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS)))  ifneq ("$(wildcard $(KEYMAP_PATH)/visualizer.c)","") -	SRC += keyboards/$(KEYBOARD)/keymaps/$(KEYMAP)/visualizer.c +    SRC += keyboards/$(KEYBOARD)/keymaps/$(KEYMAP)/visualizer.c  else  -	ifeq ("$(wildcard $(SUBPROJECT_PATH)/keymaps/$(KEYMAP)/visualizer.c)","") -		ifeq ("$(wildcard $(SUBPROJECT_PATH)/visualizer.c)","") -$(error "$(KEYMAP_PATH)/visualizer.c" does not exist) -		else -			SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/visualizer.c -		endif -	else -		SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/keymaps/$(KEYMAP)/visualizer.c -	endif +    ifeq ("$(wildcard $(SUBPROJECT_PATH)/keymaps/$(KEYMAP)/visualizer.c)","") +        ifeq ("$(wildcard $(SUBPROJECT_PATH)/visualizer.c)","") +            ifeq ("$(wildcard $(KEYBOARD_PATH)/visualizer.c)","") +$(error "visualizer.c" not found") +            else +               SRC += keyboards/$(KEYBOARD)/visualizer.c +            endif +        else +            SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/visualizer.c +        endif +    else +        SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/keymaps/$(KEYMAP)/visualizer.c +    endif  endif  ifdef EMULATOR  UINCDIR += $(TMK_DIR)/common -endif
\ No newline at end of file +endif | 
