keymap.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /*
  2. * Dan's Magicforce 68 (MF68) QMK Keyboard
  3. * Copyright (C) Dan <https://github.com/delivrance>
  4. *
  5. * This file is part of Dan's MF68 QMK Keyboard.
  6. *
  7. * Dan's MF68 QMK Keyboard is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * Dan's MF68 QMK Keyboard is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with Dan's MF68 QMK Keyboard. If not, see <https://www.gnu.org/licenses/>.
  19. */
  20. #include QMK_KEYBOARD_H
  21. #define KC_FN1 MO(_FN)
  22. #define KC_FN2 LT(_FN, KC_CAPS)
  23. #define KC_BLUP BL_INC // Backlight increase
  24. #define KC_BLDN BL_DEC // Backlight decrease
  25. #define KC_BLTOG BL_TOGG // Backlight toggle
  26. #define KC_TERM TERM_ON // Terminal mode on
  27. #define KC_REC1 DM_REC1 // Record macro 1
  28. #define KC_PLY1 DM_PLY1 // Play macro 1
  29. #define KC_REC2 DM_REC2 // Record macro 2
  30. #define KC_PLY2 DM_PLY2 // Play macro 1
  31. #define KC_RSTP DM_RSTP // Stop macro recording
  32. enum {
  33. _QWERTY,
  34. _FN
  35. };
  36. /* ┏━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━━━━━┓ ┏━━━━┳━━━━┓
  37. ┃Esc ┃ 1! ┃ 2@ ┃ 3# ┃ 4$ ┃ 5% ┃ 6^ ┃ 7& ┃ 8* ┃ 9( ┃ 0) ┃ -_ ┃ =+ ┃ ←─ ┃ ┃Ins ┃PgUp┃
  38. ┣━━━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━━━━━┫ ┣━━━━╋━━━━┫
  39. ┃ Tab ┃ Q ┃ W ┃ E ┃ R ┃ T ┃ Y ┃ U ┃ I ┃ O ┃ P ┃ [{ ┃ ]} ┃ \| ┃ ┃Del ┃PgDn┃
  40. ┣━━━━━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━━━━━━┫ ┗━━━━┻━━━━┛
  41. ┃ Caps ┃ A ┃ S ┃ D ┃ F ┃ G ┃ H ┃ J ┃ K ┃ L ┃ ;: ┃ '" ┃ Enter ┃ Magicforce
  42. ┣━━━━━━━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━━━━━━━━━┫ ┏━━━━┓
  43. ┃ Shift ┃ Z ┃ X ┃ C ┃ V ┃ B ┃ N ┃ M ┃ ,< ┃ .> ┃ /? ┃ Shift ┃ ┃ ↑ ┃ Dan
  44. ┣━━━━━┳━━━━┻┳━━━┻━┳━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━┳┻━━━━╋━━━━┻┳━━━━━┳━━┳━━┻━╋━━━━╋━━━━┓
  45. ┃Ctrl ┃ GUI ┃ Alt ┃ ━━━━━ ┃ Alt ┃ Fn ┃Ctrl ┃ ┃ ← ┃ ↓ ┃ → ┃
  46. ┗━━━━━┻━━━━━┻━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━┻━━━━━┻━━━━━┛ ┗━━━━┻━━━━┻━━━━┛ */
  47. // clang-format off
  48. const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  49. [_QWERTY] = LAYOUT_68_ansi( /* Default layer
  50. ┏━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━━━━━┓ ┏━━━━┳━━━━┓ */
  51. 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_BSPC , KC_INS ,KC_PGUP, /*
  52. ┣━━━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━━━━━┫ ┣━━━━╋━━━━┫ */
  53. 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 ,KC_PGDN, /*
  54. ┣━━━━━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━━━━━━┫ ┗━━━━┻━━━━┛ */
  55. KC_FN2 , KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L ,KC_SCLN,KC_QUOT, KC_ENTER , /*
  56. ┣━━━━━━━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━┳━━┻━━━━━━━━━┫ ┏━━━━┓ */
  57. 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_UP , /*
  58. ┣━━━━━┳━━━━┻┳━━━┻━┳━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━┳┻━━━━╋━━━━┻┳━━━━━┳━━┳━━┻━╋━━━━╋━━━━┓ */
  59. KC_LCTL ,KC_LGUI ,KC_LALT , KC_SPACE ,KC_RALT , KC_FN1 ,KC_RCTL , KC_LEFT,KC_DOWN,KC_RGHT /*
  60. ┗━━━━━┻━━━━━┻━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━┻━━━━━┻━━━━━┛ ┗━━━━┻━━━━┻━━━━┛ */),
  61. [_FN] = LAYOUT_68_ansi( /* FN & CAPS layer
  62. ┏━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━━━━━┓ ┏━━━━┳━━━━┓ */
  63. 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_RSTP , KC_PSCR,KC_HOME, /*
  64. ┣Esc ┻ 1! ┻ 2@ ┻ 3# ┻ 4$ ┻ 5% ┻ 6^ ┻ 7& ┻ 8* ┻ 9( ┻ 0) ┻ -_ ┻ =+ ┻━┳━ ←─ ━┫ ┣Ins ╋PgUp┫ */
  65. _______ ,KC_PLY1,KC_PLY2,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_7 , KC_8 , KC_9 ,KC_BLDN,KC_BLUP,KC_BLTOG ,KC_TRNS ,KC_END , /*
  66. ┣ Tab ━┻ Q ━┻ W ━┻ E ━┻ R ━┻ T ━┻ Y ━┻ U ━┻ I ━┻ O ━┻ P ━┻ [{ ┻ ]} ┻━ \| ━┫ ┗Del ┻PgDn┛ */
  67. _______ ,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_4 , KC_5 , KC_6 ,KC_TRNS, KC_TERM , /*
  68. ┣━ Caps ━┻ A ━┻ S ━┻ D ━┻ F ━┻ G ━┻ H ━┻ J ━┻ K ━┻ L ━┻ ;: ┻ '" ┻━ Enter ━┫ ┏━━━━┓ */
  69. _______ ,KC_REC1,KC_REC2,KC_TRNS,KC_TRNS,KC_MSTP,KC_TRNS,KC_MUTE, KC_1 , KC_2 , KC_3 ,KC_TRNS , KC_VOLU, /*
  70. ┣━━ Shift ━┻ Z ━┻ X ━┻ C ━┻ V ━┻ B ━┻ N ━┻ M ━┻ ,< ┻ .> ╋ /? ┻┳━━ Shift ━━┻━╋ ↑ ━╋━━━━┓ */
  71. _______,KC_TRNS ,KC_TRNS , KC_MPLY , KC_0 ,KC_TRNS ,KC_TRNS , KC_MPRV,KC_VOLD,KC_MNXT /*
  72. ┗Ctrl ┻ GUI ┻ Alt ┻━━━━━━━━━━━━ Space ━━━━━━━━━━━━┻ Alt ┻ Fn ━┻Ctrl ┛ ┗ ← ━┻ ↓ ━┻ → ━┛ */)
  73. };
  74. // clang-format on
  75. // Initialization code
  76. // -------------------
  77. void keyboard_post_init_user(void) {
  78. backlight_level(2);
  79. }
  80. // Custom backlight driver
  81. // -----------------------
  82. // http://jared.geek.nz/2013/feb/linear-led-pwm
  83. float cie1931(float x) {
  84. x *= 100.0 / BACKLIGHT_LEVELS;
  85. float y;
  86. if (x < 8) {
  87. y = x / 902.3;
  88. } else {
  89. y = (x + 16.0) / 116.0;
  90. y = y * y * y;
  91. }
  92. return round(y * 255);
  93. }
  94. void backlight_init_ports(void) {
  95. setPinOutput(BACKLIGHT_PIN);
  96. writePinLow(BACKLIGHT_PIN);
  97. TCCR1A = _BV(COM1A1) | _BV(WGM11);
  98. TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10);
  99. ICR1 = 0xFFU; // Set PWM levels to 255 (enables high-frequency PWM)
  100. }
  101. void backlight_set(uint8_t level) {
  102. if (level > BACKLIGHT_LEVELS) {
  103. level = BACKLIGHT_LEVELS;
  104. }
  105. if (level == 0) {
  106. TCCR1A &= ~(_BV(COM1A1)); // Disable PWM
  107. } else {
  108. TCCR1A |= _BV(COM1A1); // Enable PWM
  109. }
  110. OCR1A = cie1931(level);
  111. }
  112. // Custom macro hooks
  113. // ------------------
  114. // Redefine with lower delay
  115. void led_blink(void) {
  116. backlight_toggle();
  117. wait_ms(25);
  118. backlight_toggle();
  119. }
  120. void dynamic_macro_record_start_user(void) {
  121. led_blink();
  122. }
  123. void dynamic_macro_play_user(int8_t direction) {
  124. led_blink();
  125. }
  126. void dynamic_macro_record_key_user(int8_t direction, keyrecord_t *record) {
  127. led_blink();
  128. }
  129. void dynamic_macro_record_end_user(int8_t direction) {
  130. led_blink();
  131. }
  132. // Custom Caps Lock backlight behaviour
  133. // ------------------------------------
  134. void led_set_user(uint8_t usb_led) {
  135. // This exists because I don't like the backlight to turn OFF when the Caps Lock is ON.
  136. // That is, this will turn the backlight ON (at half the brightness) when the Caps Lock is ON as well.
  137. static bool prev_is_caps_on;
  138. bool is_caps_on = IS_LED_ON(usb_led, USB_LED_CAPS_LOCK);
  139. if (prev_is_caps_on != is_caps_on) {
  140. prev_is_caps_on = is_caps_on;
  141. if (is_caps_on) {
  142. backlight_set(BACKLIGHT_LEVELS / 2);
  143. } else {
  144. if (is_backlight_enabled()) {
  145. backlight_set(get_backlight_level());
  146. } else {
  147. backlight_set(0);
  148. }
  149. }
  150. }
  151. // Turn on the Pro Micro's on-board LEDs for Caps Lock
  152. if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) {
  153. // Set to low
  154. setPinOutput(B0);
  155. writePinLow(B0);
  156. setPinOutput(D5);
  157. writePinLow(D5);
  158. } else {
  159. // Set to Hi-Z
  160. setPinInput(B0);
  161. setPinInput(D5);
  162. }
  163. }
  164. // Backlight idle timeout feature
  165. // ------------------------------
  166. static uint32_t timer;
  167. static bool is_idle;
  168. void matrix_scan_user() {
  169. // Check the timer only if the keyboard is not idle
  170. if (!is_idle) {
  171. if (timer_elapsed32(timer) >= (uint32_t) BACKLIGHT_IDLE_TIMEOUT * 1000) {
  172. is_idle = true;
  173. // Both backlight_level and backlight_level_noeeprom modify the global backlight config (not useful)
  174. // Instead, use backlight_set in order to restore the current backlight level later on
  175. backlight_set(0);
  176. }
  177. }
  178. }
  179. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  180. // Reset timer on each keypress
  181. timer = timer_read32();
  182. // Enable backlight back only when keyboard is idling (which implies the backlight was turned off previously)
  183. if (is_idle) {
  184. is_idle = false;
  185. // Set back the original backlight level only if it is actually enabled globally
  186. if (is_backlight_enabled()) {
  187. // The current backlight level can be obtained with get_backlight_level
  188. backlight_set(get_backlight_level());
  189. }
  190. }
  191. return true;
  192. }