You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

330 lines
16 KiB

  1. /* Copyright 2017 F_YUUCHI
  2. * Copyright 2020 Drashna Jaelre <@drashna>
  3. * Copyright 2020 Ben Roesner (keycapsss.com)
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include QMK_KEYBOARD_H
  19. extern uint8_t is_master;
  20. enum layers {
  21. _QWERTY,
  22. _LOWER,
  23. _RAISE,
  24. _ADJUST,
  25. };
  26. #define RAISE MO(_RAISE)
  27. #define LOWER MO(_LOWER)
  28. const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  29. /* QWERTY
  30. * ,-----------------------------------------. ,-----------------------------------------.
  31. * | ESC | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | ` |
  32. * |------+------+------+------+------+------| |------+------+------+------+------+------|
  33. * | Tab | Q | W | E | R | T | | Y | U | I | O | P | - |
  34. * |------+------+------+------+------+------| |------+------+------+------+------+------|
  35. * |LCTRL | A | S | D | F | G |-------. ,-------| H | J | K | L | ; | ' |
  36. * |------+------+------+------+------+------| [ | | ] |------+------+------+------+------+------|
  37. * |LShift| Z | X | C | V | B |-------| |-------| N | M | , | . | / |RShift|
  38. * `-----------------------------------------/ / \ \-----------------------------------------'
  39. * | LAlt | LGUI |LOWER | /Space / \Enter \ |RAISE |BackSP| RGUI |
  40. * | | | |/ / \ \ | | | |
  41. * `----------------------------' '------''--------------------'
  42. */
  43. [_QWERTY] = LAYOUT(
  44. KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_GRV,
  45. KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_MINS,
  46. KC_LCTRL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
  47. KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LBRC, KC_RBRC, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT,
  48. KC_LALT, KC_LGUI,LOWER, KC_SPC, KC_ENT, RAISE, KC_BSPC, KC_RGUI
  49. ),
  50. /* LOWER
  51. * ,-----------------------------------------. ,-----------------------------------------.
  52. * | | | | | | | | | | | | | |
  53. * |------+------+------+------+------+------| |------+------+------+------+------+------|
  54. * | F1 | F2 | F3 | F4 | F5 | F6 | | F7 | F8 | F9 | F10 | F11 | F12 |
  55. * |------+------+------+------+------+------| |------+------+------+------+------+------|
  56. * | ` | ! | @ | # | $ | % |-------. ,-------| ^ | & | * | ( | ) | - |
  57. * |------+------+------+------+------+------| [ | | ] |------+------+------+------+------+------|
  58. * | | | | | | |-------| |-------| | _ | + | { | } | | |
  59. * `-----------------------------------------/ / \ \-----------------------------------------'
  60. * | LAlt | LGUI |LOWER | /Space / \Enter \ |RAISE |BackSP| RGUI |
  61. * | | | |/ / \ \ | | | |
  62. * `----------------------------' '------''--------------------'
  63. */
  64. [_LOWER] = LAYOUT(
  65. _______, _______, _______, _______, _______, _______, _______, _______, _______,_______, _______, _______,
  66. KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,
  67. KC_GRV, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_TILD,
  68. _______, _______, _______, _______, _______, _______, _______, _______, XXXXXXX, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE,
  69. _______, _______, _______, _______, _______, _______, _______, _______
  70. ),
  71. /* RAISE
  72. * ,-----------------------------------------. ,-----------------------------------------.
  73. * | | | | | | | | | | | | | |
  74. * |------+------+------+------+------+------| |------+------+------+------+------+------|
  75. * | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | |
  76. * |------+------+------+------+------+------| |------+------+------+------+------+------|
  77. * | F1 | F2 | F3 | F4 | F5 | F6 |-------. ,-------| | Left | Down | Up |Right | |
  78. * |------+------+------+------+------+------| [ | | ] |------+------+------+------+------+------|
  79. * | F7 | F8 | F9 | F10 | F11 | F12 |-------| |-------| + | - | = | [ | ] | \ |
  80. * `-----------------------------------------/ / \ \-----------------------------------------'
  81. * | LAlt | LGUI |LOWER | /Space / \Enter \ |RAISE |BackSP| RGUI |
  82. * | | | |/ / \ \ | | | |
  83. * `----------------------------' '------''--------------------'
  84. */
  85. [_RAISE] = LAYOUT(
  86. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  87. KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, _______,
  88. KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, XXXXXXX,
  89. KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______, KC_PLUS, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS,
  90. _______, _______, _______, _______, _______, _______, _______, _______
  91. ),
  92. /* ADJUST
  93. * ,-----------------------------------------. ,-----------------------------------------.
  94. * | | | | | | | | | | | | | |
  95. * |------+------+------+------+------+------| |------+------+------+------+------+------|
  96. * | | | | | | | | | | | | | |
  97. * |------+------+------+------+------+------| |------+------+------+------+------+------|
  98. * | | | | | | |-------. ,-------| | |RGB ON| HUE+ | SAT+ | VAL+ |
  99. * |------+------+------+------+------+------| | | |------+------+------+------+------+------|
  100. * | | | | | | |-------| |-------| | | MODE | HUE- | SAT- | VAL- |
  101. * `-----------------------------------------/ / \ \-----------------------------------------'
  102. * | LAlt | LGUI |LOWER | /Space / \Enter \ |RAISE |BackSP| RGUI |
  103. * | | | |/ / \ \ | | | |
  104. * `----------------------------' '------''--------------------'
  105. */
  106. [_ADJUST] = LAYOUT(
  107. XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
  108. XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
  109. XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI,
  110. XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD,
  111. _______, _______, _______, _______, _______, _______, _______, _______
  112. )
  113. };
  114. layer_state_t layer_state_set_user(layer_state_t state) {
  115. state = update_tri_layer_state(state, _RAISE, _LOWER, _ADJUST);
  116. return state;
  117. }
  118. //SSD1306 OLED update loop, make sure to enable OLED_DRIVER_ENABLE=yes in rules.mk
  119. #ifdef OLED_DRIVER_ENABLE
  120. oled_rotation_t oled_init_user(oled_rotation_t rotation) {
  121. if (is_keyboard_master()) {
  122. return OLED_ROTATION_270;
  123. } else {
  124. return OLED_ROTATION_0;
  125. }
  126. }
  127. void render_lily58_logo(void) {
  128. static const char PROGMEM lily58_logo[] = {
  129. // 'logo', 128x32px
  130. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc0, 0x40, 0x40, 0xc0, 0x80, 0x80, 0x80, 0x00, 0x00,
  131. 0x80, 0xe0, 0x70, 0x3c, 0x0e, 0x06, 0x0e, 0x3c, 0x70, 0xe0, 0x80, 0x00, 0x00, 0xc0, 0xc0, 0x00,
  132. 0xc0, 0xc0, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00,
  133. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x80,
  134. 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  135. 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x00, 0x00,
  136. 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00,
  137. 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  138. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0xc0, 0x80, 0x80, 0x80, 0x81, 0x83, 0x83,
  139. 0x07, 0x07, 0x0c, 0x18, 0x70, 0xe0, 0x80, 0x00, 0x00, 0x01, 0xff, 0xfc, 0x80, 0xb6, 0xb6, 0x80,
  140. 0xb0, 0xb0, 0x00, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
  141. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf1, 0x00, 0x00, 0x00, 0x00, 0xff,
  142. 0xff, 0x00, 0x00, 0x00, 0x30, 0xf0, 0xf0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf0, 0xf0,
  143. 0x30, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xe1, 0x71, 0x71, 0xf1, 0xf1, 0xe1, 0xc1, 0x81, 0x00, 0x00,
  144. 0x00, 0x00, 0x0c, 0x3f, 0xff, 0xf3, 0xe1, 0xc1, 0xc1, 0x81, 0x81, 0xc3, 0xff, 0x7f, 0x1c, 0x00,
  145. 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  146. 0x20, 0x70, 0x78, 0xdc, 0xcc, 0x86, 0x06, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  147. 0x01, 0x03, 0x02, 0x06, 0x84, 0xe1, 0xfb, 0x38, 0x1c, 0x0c, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
  148. 0x01, 0x01, 0x03, 0x03, 0x06, 0x86, 0xcc, 0xdc, 0x78, 0x70, 0x20, 0x00, 0xff, 0xff, 0x80, 0x80,
  149. 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
  150. 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x1f, 0x7e, 0xf8, 0xe0, 0xf0, 0x7e, 0x1f, 0x03, 0x00,
  151. 0x00, 0x00, 0x00, 0xe0, 0xe0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0xc0, 0xe1, 0xff, 0x7f, 0x3f, 0x00,
  152. 0x00, 0x00, 0x3e, 0xff, 0xff, 0xc1, 0xc0, 0x80, 0x81, 0x81, 0xc3, 0xc3, 0xff, 0xfe, 0x3c, 0x00,
  153. 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00,
  154. 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x06, 0x06, 0x06, 0x04, 0x04, 0x04, 0x04, 0x06,
  155. 0x06, 0x02, 0x03, 0x01, 0x01, 0x00, 0x01, 0x01, 0x03, 0x02, 0x06, 0x06, 0x04, 0x04, 0x04, 0x04,
  156. 0x06, 0x06, 0x06, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
  157. 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
  158. 0x01, 0x01, 0x01, 0x00, 0x00, 0x60, 0x60, 0x70, 0x38, 0x1f, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x00,
  159. 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
  160. 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
  161. 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00
  162. };
  163. oled_write_raw_P(lily58_logo, sizeof(lily58_logo));
  164. }
  165. # define KEYLOG_LEN 6
  166. char keylog_str[KEYLOG_LEN] = {};
  167. uint8_t keylogs_str_idx = 0;
  168. uint16_t log_timer = 0;
  169. const char code_to_name[60] = {
  170. ' ', ' ', ' ', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
  171. 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
  172. 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
  173. '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
  174. 'R', 'E', 'B', 'T', '_', '-', '=', '[', ']', '\\',
  175. '#', ';', '\'', '`', ',', '.', '/', ' ', ' ', ' '};
  176. void add_keylog(uint16_t keycode) {
  177. if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) {
  178. keycode = keycode & 0xFF;
  179. }
  180. for (uint8_t i = KEYLOG_LEN - 1; i > 0; i--) {
  181. keylog_str[i] = keylog_str[i - 1];
  182. }
  183. if (keycode < 60) {
  184. keylog_str[0] = code_to_name[keycode];
  185. }
  186. keylog_str[KEYLOG_LEN - 1] = 0;
  187. log_timer = timer_read();
  188. }
  189. void update_log(void) {
  190. if (timer_elapsed(log_timer) > 750) {
  191. add_keylog(0);
  192. }
  193. }
  194. void render_keylogger_status(void) {
  195. oled_write_P(PSTR("KLogr"), false);
  196. oled_write(keylog_str, false);
  197. }
  198. void render_default_layer_state(void) {
  199. oled_write_P(PSTR("Layer"), false);
  200. oled_write_P(PSTR(" "), false);
  201. switch (get_highest_layer(layer_state)) {
  202. case _QWERTY:
  203. oled_write_P(PSTR("QRTY"), false);
  204. break;
  205. case _LOWER:
  206. oled_write_ln_P(PSTR("LOW"), false);
  207. break;
  208. case _RAISE:
  209. oled_write_P(PSTR("HIGH"), false);
  210. break;
  211. case _ADJUST:
  212. oled_write_ln_P(PSTR("ADJ"), false);
  213. break;
  214. default:
  215. oled_write_ln_P(PSTR("Undefined"), false);
  216. }
  217. }
  218. void render_keylock_status(led_t led_state) {
  219. oled_write_ln_P(PSTR("Lock"), false);
  220. oled_write_P(PSTR(" "), false);
  221. oled_write_P(PSTR("N"), led_state.num_lock);
  222. oled_write_P(PSTR("C"), led_state.caps_lock);
  223. oled_write_ln_P(PSTR("S"), led_state.scroll_lock);
  224. }
  225. void render_mod_status(uint8_t modifiers) {
  226. oled_write_ln_P(PSTR("Mods"), false);
  227. oled_write_P(PSTR(" "), false);
  228. oled_write_P(PSTR("S"), (modifiers & MOD_MASK_SHIFT));
  229. oled_write_P(PSTR("C"), (modifiers & MOD_MASK_CTRL));
  230. oled_write_P(PSTR("A"), (modifiers & MOD_MASK_ALT));
  231. oled_write_P(PSTR("G"), (modifiers & MOD_MASK_GUI));
  232. }
  233. void render_status_main(void) {
  234. // Show keyboard layout
  235. render_default_layer_state();
  236. // Add a empty line
  237. oled_write_P(PSTR("-----"), false);
  238. // Show host keyboard led status
  239. render_keylock_status(host_keyboard_led_state());
  240. // Add a empty line
  241. oled_write_P(PSTR("-----"), false);
  242. // Show modifier status
  243. render_mod_status(get_mods());
  244. // Add a empty line
  245. oled_write_P(PSTR("-----"), false);
  246. render_keylogger_status();
  247. }
  248. void oled_task_user(void) {
  249. update_log();
  250. if (is_keyboard_master()) {
  251. render_status_main(); // Renders the current keyboard state (layer, lock, caps, scroll, etc)
  252. } else {
  253. render_lily58_logo();
  254. }
  255. }
  256. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  257. if (record->event.pressed) {
  258. add_keylog(keycode);
  259. }
  260. return true;
  261. }
  262. #endif // OLED_DRIVER_ENABLE
  263. // Rotary encoder related code
  264. #ifdef ENCODER_ENABLE
  265. void encoder_update_user(uint8_t index, bool clockwise) {
  266. if (index == 0) { // Encoder on master side
  267. if(IS_LAYER_ON(_RAISE)) { // on Raise layer
  268. // Cursor control
  269. if (clockwise) {
  270. tap_code(KC_MNXT);
  271. } else {
  272. tap_code(KC_MPRV);
  273. }
  274. }
  275. else {
  276. if (clockwise) {
  277. tap_code(KC_VOLU);
  278. } else {
  279. tap_code(KC_VOLD);
  280. }
  281. }
  282. }
  283. else if (index == 1) { // Encoder on slave side
  284. if(IS_LAYER_ON(_LOWER)) { // on Lower layer
  285. //
  286. if (clockwise) {
  287. tap_code(KC_RIGHT);
  288. } else {
  289. tap_code(KC_LEFT);
  290. }
  291. }
  292. else {
  293. if (clockwise) {
  294. tap_code(KC_DOWN);
  295. } else {
  296. tap_code(KC_UP);
  297. }
  298. }
  299. }
  300. }
  301. #endif