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.

143 lines
5.0 KiB

  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 DIP_SWITCH_ENABLE
  18. bool dip_switch_update_kb(uint8_t index, bool active) {
  19. if (!dip_switch_update_user(index, active)) {
  20. return false;
  21. }
  22. if (index == 0) {
  23. default_layer_set(1UL << (active ? 0 : 2));
  24. }
  25. return true;
  26. }
  27. #endif
  28. #if defined(RGB_MATRIX_ENABLE) && defined(CAPS_LOCK_LED_INDEX)
  29. bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
  30. if (!process_record_user(keycode, record)) {
  31. return false;
  32. }
  33. switch (keycode) {
  34. case RGB_TOG:
  35. if (record->event.pressed) {
  36. switch (rgb_matrix_get_flags()) {
  37. case LED_FLAG_ALL: {
  38. rgb_matrix_set_flags(LED_FLAG_NONE);
  39. rgb_matrix_set_color_all(0, 0, 0);
  40. } break;
  41. default: {
  42. rgb_matrix_set_flags(LED_FLAG_ALL);
  43. } break;
  44. }
  45. }
  46. if (!rgb_matrix_is_enabled()) {
  47. rgb_matrix_set_flags(LED_FLAG_ALL);
  48. rgb_matrix_enable();
  49. }
  50. return false;
  51. }
  52. return true;
  53. }
  54. bool rgb_matrix_indicators_advanced_kb(uint8_t led_min, uint8_t led_max) {
  55. if (!rgb_matrix_indicators_advanced_user(led_min, led_max)) {
  56. return false;
  57. }
  58. // RGB_MATRIX_INDICATOR_SET_COLOR(index, red, green, blue);
  59. # if defined(CAPS_LOCK_LED_INDEX)
  60. if (host_keyboard_led_state().caps_lock) {
  61. RGB_MATRIX_INDICATOR_SET_COLOR(CAPS_LOCK_LED_INDEX, 255, 255, 255);
  62. } else {
  63. if (!rgb_matrix_get_flags()) {
  64. RGB_MATRIX_INDICATOR_SET_COLOR(CAPS_LOCK_LED_INDEX, 0, 0, 0);
  65. }
  66. }
  67. # endif // CAPS_LOCK_LED_INDEX
  68. # if defined(NUM_LOCK_LED_INDEX)
  69. if (host_keyboard_led_state().num_lock) {
  70. RGB_MATRIX_INDICATOR_SET_COLOR(NUM_LOCK_LED_INDEX, 255, 255, 255);
  71. } else {
  72. if (!rgb_matrix_get_flags()) {
  73. RGB_MATRIX_INDICATOR_SET_COLOR(NUM_LOCK_LED_INDEX, 0, 0, 0);
  74. }
  75. }
  76. # endif // NUM_LOCK_LED_INDEX
  77. return true;
  78. }
  79. #endif
  80. #define ADC_BUFFER_DEPTH 1
  81. #define ADC_NUM_CHANNELS 1
  82. #define ADC_SAMPLING_RATE ADC_SMPR_SMP_12P5
  83. #define ADC_RESOLUTION ADC_CFGR_RES_10BITS
  84. static int16_t analogReadPin_my(pin_t pin) {
  85. ADCConfig adcCfg = {};
  86. adcsample_t sampleBuffer[ADC_NUM_CHANNELS * ADC_BUFFER_DEPTH];
  87. ADCDriver *targetDriver = &ADCD1;
  88. ADCConversionGroup adcConversionGroup = {
  89. .circular = FALSE,
  90. .num_channels = (uint16_t)(ADC_NUM_CHANNELS),
  91. .cfgr = ADC_RESOLUTION,
  92. };
  93. palSetLineMode(pin, PAL_MODE_INPUT_ANALOG);
  94. switch (pin) {
  95. case B0:
  96. adcConversionGroup.smpr[2] = ADC_SMPR2_SMP_AN15(ADC_SAMPLING_RATE);
  97. adcConversionGroup.sqr[0] = ADC_SQR1_SQ1_N(ADC_CHANNEL_IN15);
  98. sampleBuffer[0] = 0;
  99. break;
  100. case B1:
  101. adcConversionGroup.smpr[2] = ADC_SMPR2_SMP_AN16(ADC_SAMPLING_RATE);
  102. adcConversionGroup.sqr[0] = ADC_SQR1_SQ1_N(ADC_CHANNEL_IN16);
  103. sampleBuffer[0] = 0;
  104. break;
  105. default:
  106. return 0;
  107. }
  108. adcStart(targetDriver, &adcCfg);
  109. if (adcConvert(targetDriver, &adcConversionGroup, &sampleBuffer[0], ADC_BUFFER_DEPTH) != MSG_OK) {
  110. return 0;
  111. }
  112. return *sampleBuffer;
  113. }
  114. void keyboard_post_init_kb(void) {
  115. // 1. The pin A5/B5 of the USB C interface in the left hand is connected to the pin A0 of MCU,
  116. // A0 will be set to output and write high when keyboard initial.
  117. // 2. The same pin in the right hand is connected to the pin B0 and B1 of MCU respectively,
  118. // and the ADC function of B0 and B1 will be enabled when keyboard initial.
  119. // 3. because the serial usart RXD and TXD is multiplexed on USB's D+ and D- in the right hand.
  120. // So detect the voltage on the pin A5/B5 of the USB C interface by ADC,
  121. // and disable USB connectivity when the ADC value exceeds 1000,
  122. // to avoid affecting the serial usart communication between the left hand and the right hand.
  123. if (is_keyboard_left()) {
  124. gpio_set_pin_output(A0);
  125. gpio_write_pin_high(A0);
  126. } else {
  127. if ((analogReadPin_my(B0) > 1000) || (analogReadPin_my(B1) > 1000)) {
  128. gpio_set_pin_input(A11);
  129. gpio_set_pin_input(A12);
  130. }
  131. }
  132. keyboard_post_init_user();
  133. }