ansi_encoder.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /* Copyright 2023 @ Keychron (https://www.keychron.com)
  2. *
  3. * This program is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "quantum.h"
  17. #ifdef RGB_MATRIX_ENABLE
  18. // clang-format off
  19. const ckled2001_led PROGMEM g_ckled2001_leds[RGB_MATRIX_LED_COUNT] = {
  20. /* Refer to IS31 manual for these locations
  21. * driver
  22. * | R location
  23. * | | G location
  24. * | | | B location
  25. * | | | | */
  26. {0, A_2, C_2, B_2}, // ESC
  27. {0, A_3, C_3, B_3}, // F1
  28. {0, A_4, C_4, B_4}, // F2
  29. {0, A_5, C_5, B_5}, // F3
  30. {0, A_6, C_6, B_6}, // F4
  31. {0, A_7, C_7, B_7}, // F5
  32. {0, A_8, C_8, B_8}, // F6
  33. {0, D_1, F_1, E_1}, // M1
  34. {0, D_2, F_2, E_2}, // `~
  35. {0, D_3, F_3, E_3}, // 1!
  36. {0, D_4, F_4, E_4}, // 2@
  37. {0, D_5, F_5, E_5}, // 3#
  38. {0, D_6, F_6, E_6}, // 4$
  39. {0, D_7, F_7, E_7}, // 5%
  40. {0, D_8, F_8, E_8}, // 6^
  41. {0, G_1, I_1, H_1}, // M2
  42. {0, G_2, I_2, H_2}, // TAB
  43. {0, G_3, I_3, H_3}, // Q
  44. {0, G_4, I_4, H_4}, // W
  45. {0, G_5, I_5, H_5}, // E
  46. {0, G_6, I_6, H_6}, // R
  47. {0, G_7, I_7, H_7}, // T
  48. {0, J_1, L_1, K_1}, // M3
  49. {0, J_2, L_2, K_2}, // CapsJock
  50. {0, J_3, L_3, K_3}, // A
  51. {0, J_4, L_4, K_4}, // S
  52. {0, J_5, L_5, K_5}, // D
  53. {0, J_6, L_6, K_6}, // F
  54. {0, J_7, L_7, K_7}, // G
  55. {0, J_9, L_9, K_9}, // M4
  56. {0, J_11, L_11, K_11}, // Shift_J
  57. {0, J_12, L_12, K_12}, // Z
  58. {0, J_13, L_13, K_13}, // X
  59. {0, J_14, L_14, K_14}, // C
  60. {0, J_15, L_15, K_15}, // V
  61. {0, J_16, L_16, K_16}, // B
  62. {0, G_9, I_9, H_9}, // M5
  63. {0, G_10, I_10, H_10}, // Ctrl_L
  64. {0, G_11, I_11, H_11}, // WGn_L
  65. {0, G_12, I_12, H_12}, // Alt_L
  66. {0, G_13, I_13, H_13}, // Fn
  67. {0, G_15, I_15, H_15}, // Space
  68. {0, A_16, C_16, B_16}, // F7
  69. {0, A_15, C_15, B_15}, // F8
  70. {0, A_14, C_14, B_14}, // F9
  71. {0, A_13, C_13, B_13}, // F11
  72. {0, A_12, C_12, B_12}, // F11
  73. {0, A_11, C_11, B_11}, // F12
  74. {0, A_10, C_10, B_10}, // INS
  75. {0, A_9, C_9, B_9}, // DEL
  76. {0, D_16, F_16, E_16}, // 7&
  77. {0, D_15, F_15, E_15}, // 8*
  78. {0, D_14, F_14, E_14}, // 9(
  79. {0, D_13, F_13, E_13}, // 1)
  80. {0, D_12, F_12, E_12}, // -_
  81. {0, D_11, F_11, E_11}, // =+
  82. {0, D_10, F_10, E_10}, // BackSpace
  83. {0, D_8, F_8, E_8}, // PgUp
  84. {0, G_16, I_16, H_16}, // Y
  85. {0, G_15, I_15, H_15}, // U
  86. {0, G_14, I_14, H_14}, // G
  87. {0, G_13, I_13, H_13}, // O
  88. {0, G_12, I_12, H_12}, // P
  89. {0, G_11, I_11, H_11}, // [
  90. {0, G_10, I_10, H_10}, // ]
  91. {0, G_9, I_9, H_9}, // \||
  92. {0, G_8, I_8, H_8}, // PgDn
  93. {0, J_16, L_16, K_16}, // H
  94. {0, J_15, L_15, K_15}, // J
  95. {0, J_14, L_14, K_14}, // KKEY_PRESS_HOME
  96. {0, J_13, L_13, K_13}, // J
  97. {0, J_12, L_12, K_12}, // ;:
  98. {0, J_11, L_11, K_11}, // '"
  99. {0, J_9, L_9, K_9}, // Enter
  100. {0, J_8, L_8, K_8}, // Home
  101. {0, J_7, L_7, K_7}, // N
  102. {0, J_6, L_6, K_6}, // M
  103. {0, J_5, L_5, K_5}, // ,<
  104. {0, J_4, L_4, K_4}, // .>
  105. {0, J_3, L_3, K_3}, // ?/
  106. {0, J_2, L_2, K_2}, // Shift_R
  107. {0, J_1, L_1, K_1}, // Up
  108. {0, G_6, I_6, H_6}, // Space
  109. {0, G_5, I_5, H_5}, // Win_R
  110. {0, G_4, I_4, H_4}, // Fn
  111. {0, G_3, I_3, H_3}, // Ctrl_R
  112. {0, G_2, I_2, H_2}, // Left
  113. {0, G_1, I_1, H_1}, // Down
  114. {0, G_7, I_7, H_7}, // Right
  115. };
  116. #define __ NO_LED
  117. led_config_t g_led_config = {
  118. {
  119. // Key Matrix to LED Index
  120. { __, 0, 1, 2, 3, 4, 5, 6, __ },
  121. { 7, 8, 9, 10, 11, 12, 13, 14, __ },
  122. { 15, 16, 17, 18, 19, __, 20, 21, __ },
  123. { 22, 23, 24, 25, 26, 27, 28, __, __ },
  124. { 29, __, 30, 31, 32, 33, 34, 35, __ },
  125. { 36, 37, 38, 39, 40, __, 41, __, __ },
  126. { 42, 43, 44, 45, 46, 47, 48, 49, __ },
  127. { 50, 51, 52, 53, 54, 55, 56, __, 57 },
  128. { 58, 59, 60, 61, 62, 63, 64, 65, 66 },
  129. { 67, 68, 69, 70, 71, 72, __, 73, 74 },
  130. { 75, 76, 77, 78, 79, 80, __, 81, __ },
  131. { __, 82, 83, 84, 85, __, 86, 87, 88 },
  132. },
  133. {
  134. // LED Index to Physical Position
  135. {17,0}, {31,0}, {45,0}, {59,0}, {72,0}, {86,0}, {100,0},
  136. {0,15}, {17,15}, {31,15}, {45,15}, {59,15}, {72,15}, {86,15}, {100,15},
  137. {0,27}, {21,27}, {38,27}, {52,27}, {66,27}, {79,27}, {93,27},
  138. {0,40}, {22,40}, {41,40}, {55,40}, {69,40}, {83,40}, {97,40},
  139. {0,52}, {26,52}, {48,52}, {61,52}, {76,52}, {90,52}, {102,52},
  140. {0,64}, {19,64}, {36,64}, {53,64}, {70,64}, {94,64},
  141. {110,0}, {124,0}, {138,0}, {152,0}, {165,0}, {179,0}, {193,0}, {207,0},
  142. {110,15}, {124,15}, {138,15}, {152,15}, {165,15}, {179,15}, {200,15}, {224,15},
  143. {104,27}, {117,27}, {131,27}, {145,27}, {158,27}, {172,27}, {186,27}, {203,27}, {224,27},
  144. {107,40}, {121,40}, {134,40}, {148,40}, {162,40}, {176,40}, {198,40}, {224,40},
  145. {114,52}, {127,52}, {141,52}, {155,52}, {169,52}, {188,52}, {210,52},
  146. {126,64}, {152,64}, {166,64}, {180,64}, {196,64}, {210,64}, {224,64},
  147. },
  148. {
  149. // RGB LED Index to Flag
  150. 1, 1, 1, 1, 1, 1, 1,
  151. 1, 1, 4, 4, 4, 4, 4, 4,
  152. 1, 1, 4, 4, 4, 4, 4,
  153. 1, 8, 4, 4, 4, 4, 4,
  154. 1, 1, 4, 4, 4, 4, 4,
  155. 1, 1, 1, 1, 1, 4,
  156. 1, 1, 1, 1, 1, 1, 1, 1,
  157. 4, 4, 4, 4, 4, 4, 1, 1,
  158. 4, 4, 4, 4, 4, 4, 4, 4, 1,
  159. 4, 4, 4, 4, 4, 4, 1, 1,
  160. 4, 4, 4, 4, 4, 1, 1,
  161. 4, 1, 1, 1, 1, 1, 1,
  162. }
  163. };
  164. // clang-format on
  165. #endif
  166. #define ADC_BUFFER_DEPTH 1
  167. #define ADC_NUM_CHANNELS 1
  168. #define ADC_SAMPLING_RATE ADC_SMPR_SMP_12P5
  169. #define ADC_RESOLUTION ADC_CFGR_RES_10BITS
  170. static int16_t analogReadPin_my(pin_t pin) {
  171. ADCConfig adcCfg = {};
  172. adcsample_t sampleBuffer[ADC_NUM_CHANNELS*ADC_BUFFER_DEPTH];
  173. ADCDriver* targetDriver = &ADCD1;
  174. ADCConversionGroup adcConversionGroup = {
  175. .circular = FALSE,
  176. .num_channels = (uint16_t)(ADC_NUM_CHANNELS),
  177. .cfgr = ADC_RESOLUTION,
  178. };
  179. palSetLineMode(pin, PAL_MODE_INPUT_ANALOG);
  180. switch (pin) {
  181. case B0:
  182. adcConversionGroup.smpr[2] = ADC_SMPR2_SMP_AN15(ADC_SAMPLING_RATE);
  183. adcConversionGroup.sqr[0] = ADC_SQR1_SQ1_N(ADC_CHANNEL_IN15);
  184. sampleBuffer[0] = 0;
  185. break;
  186. case B1:
  187. adcConversionGroup.smpr[2] = ADC_SMPR2_SMP_AN16(ADC_SAMPLING_RATE);
  188. adcConversionGroup.sqr[0] = ADC_SQR1_SQ1_N(ADC_CHANNEL_IN16);
  189. sampleBuffer[0] = 0;
  190. break;
  191. default:
  192. return 0;
  193. }
  194. adcStart(targetDriver, &adcCfg);
  195. if (adcConvert(targetDriver, &adcConversionGroup, &sampleBuffer[0], ADC_BUFFER_DEPTH) != MSG_OK) {
  196. return 0;
  197. }
  198. return *sampleBuffer;
  199. }
  200. void keyboard_post_init_kb(void) {
  201. // 1. The pin A5/B5 of the USB C interface in the left hand is connected to the pin A0 of MCU,
  202. // A0 will be set to output and write high when keyboard initial.
  203. // 2. The same pin in the right hand is connected to the pin B0 and B1 of MCU respectively,
  204. // and the ADC function of B0 and B1 will be enabled when keyboard initial.
  205. // 3. because the serial usart RXD and TXD is multiplexed on USB's D+ and D- in the right hand.
  206. // So detect the voltage on the pin A5/B5 of the USB C interface by ADC,
  207. // and disable USB connectivity when the ADC value exceeds 1000,
  208. // to avoid affecting the serial usart communication between the left hand and the right hand.
  209. if (is_keyboard_left()) {
  210. setPinOutput(A0);
  211. writePinHigh(A0);
  212. } else {
  213. if ((analogReadPin_my(B0) > 1000) || (analogReadPin_my(B1) > 1000)) {
  214. setPinInput(A11);
  215. setPinInput(A12);
  216. }
  217. }
  218. keyboard_post_init_user();
  219. }