logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

annepro2.c (8977B)


  1. /* Copyright 2021 OpenAnnePro community
  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 "hal.h"
  17. #include "annepro2.h"
  18. #include "annepro2_ble.h"
  19. #include "spi_master.h"
  20. #include "ap2_led.h"
  21. #include "protocol.h"
  22. #define RAM_MAGIC_LOCATION 0x20001ffc
  23. #define IAP_MAGIC_VALUE 0x0000fab2
  24. static const SerialConfig led_uart_init_config = {
  25. .speed = 115200,
  26. };
  27. #ifndef LED_UART_BAUD_RATE
  28. # define LED_UART_BAUD_RATE 115200
  29. #endif // LED_UART_BAUD_RATE
  30. static const SerialConfig led_uart_runtine_config = {
  31. .speed = LED_UART_BAUD_RATE,
  32. };
  33. static const SerialConfig ble_uart_config = {
  34. .speed = 115200,
  35. };
  36. static uint8_t led_mcu_wakeup[11] = {0x7b, 0x10, 0x43, 0x10, 0x03, 0x00, 0x00, 0x7d, 0x02, 0x01, 0x02};
  37. ble_capslock_t ble_capslock = {._dummy = {0}, .caps_lock = false};
  38. #ifdef RGB_MATRIX_ENABLE
  39. static uint8_t led_enabled = 1;
  40. #endif
  41. void mcu_reset(void) {
  42. __disable_irq();
  43. NVIC_SystemReset();
  44. }
  45. void bootloader_jump(void) {
  46. // Send msg to shine to boot into IAP
  47. ap2_set_IAP();
  48. // wait for shine to boot into IAP
  49. wait_ms(15);
  50. // Load ble into IAP
  51. annepro2_ble_bootload();
  52. wait_ms(15);
  53. // Magic key to set keyboard to IAP
  54. // It’s from reversing original boot loader
  55. // If value is that it stays in boot loader aka IAP
  56. *((uint32_t *)RAM_MAGIC_LOCATION) = IAP_MAGIC_VALUE;
  57. // Load the main MCU into IAP
  58. __disable_irq();
  59. NVIC_SystemReset();
  60. }
  61. void keyboard_pre_init_kb(void) {
  62. // Start LED UART
  63. sdStart(&SD0, &led_uart_init_config);
  64. /* Let the LED chip settle a bit before switching the mode.
  65. * That helped at least one person. */
  66. wait_ms(15);
  67. sdWrite(&SD0, led_mcu_wakeup, sizeof(led_mcu_wakeup));
  68. // wait to receive response from wakeup
  69. wait_ms(15);
  70. proto_init(&proto, led_command_callback);
  71. // loop to clear out receive buffer from shine wakeup
  72. while (!sdGetWouldBlock(&SD0)) sdGet(&SD0);
  73. sdStart(&SD0, &led_uart_runtine_config);
  74. keyboard_pre_init_user();
  75. }
  76. void keyboard_post_init_kb(void) {
  77. // Start BLE UART
  78. sdStart(&SD1, &ble_uart_config);
  79. annepro2_ble_startup();
  80. // Give the send uart thread some time to
  81. // send out the queue before we read back
  82. wait_ms(100);
  83. // loop to clear out receive buffer from ble wakeup
  84. while (!sdGetWouldBlock(&SD1)) sdGet(&SD1);
  85. #ifdef RGB_MATRIX_ENABLE
  86. ap2_led_set_manual_control(1);
  87. ap2_led_enable();
  88. #endif
  89. keyboard_post_init_user();
  90. }
  91. void matrix_scan_kb(void) {
  92. // if there's stuff on the ble serial buffer
  93. // read it into the capslock struct
  94. while (!sdGetWouldBlock(&SD1)) {
  95. sdReadTimeout(&SD1, (uint8_t *)&ble_capslock, sizeof(ble_capslock_t), 10);
  96. }
  97. /* While there's data from LED keyboard sent - read it. */
  98. while (!sdGetWouldBlock(&SD0)) {
  99. uint8_t byte = sdGet(&SD0);
  100. proto_consume(&proto, byte);
  101. }
  102. matrix_scan_user();
  103. }
  104. bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
  105. if (record->event.pressed) {
  106. if (ap2_led_status.matrix_enabled && ap2_led_status.is_reactive) {
  107. ap2_led_forward_keypress(record->event.key.row, record->event.key.col);
  108. }
  109. const ap2_led_t blue = {
  110. .p.blue = 0xff,
  111. .p.red = 0x00,
  112. .p.green = 0x00,
  113. .p.alpha = 0xff,
  114. };
  115. switch (keycode) {
  116. case KC_AP2_BT1:
  117. annepro2_ble_broadcast(0);
  118. /* FIXME: This hardcodes col/row position */
  119. ap2_led_blink(record->event.key.row, record->event.key.col, blue, 8, 50);
  120. return false;
  121. case KC_AP2_BT2:
  122. annepro2_ble_broadcast(1);
  123. ap2_led_blink(record->event.key.row, record->event.key.col, blue, 8, 50);
  124. return false;
  125. case KC_AP2_BT3:
  126. annepro2_ble_broadcast(2);
  127. ap2_led_blink(record->event.key.row, record->event.key.col, blue, 8, 50);
  128. return false;
  129. case KC_AP2_BT4:
  130. annepro2_ble_broadcast(3);
  131. ap2_led_blink(record->event.key.row, record->event.key.col, blue, 8, 50);
  132. return false;
  133. case KC_AP2_USB:
  134. annepro2_ble_disconnect();
  135. return false;
  136. case KC_AP2_BT_UNPAIR:
  137. annepro2_ble_unpair();
  138. return false;
  139. case KC_AP_LED_OFF:
  140. ap2_led_disable();
  141. break;
  142. case KC_AP_LED_ON:
  143. if (ap2_led_status.matrix_enabled) {
  144. ap2_led_next_profile();
  145. } else {
  146. ap2_led_enable();
  147. }
  148. ap2_led_reset_foreground_color();
  149. break;
  150. case KC_AP_LED_TOG:
  151. if (ap2_led_status.matrix_enabled) {
  152. ap2_led_disable();
  153. } else {
  154. ap2_led_enable();
  155. ap2_led_reset_foreground_color();
  156. }
  157. break;
  158. case KC_AP_LED_NEXT_PROFILE:
  159. ap2_led_next_profile();
  160. ap2_led_reset_foreground_color();
  161. break;
  162. case KC_AP_LED_PREV_PROFILE:
  163. ap2_led_prev_profile();
  164. ap2_led_reset_foreground_color();
  165. break;
  166. case KC_AP_LED_NEXT_INTENSITY:
  167. ap2_led_next_intensity();
  168. ap2_led_reset_foreground_color();
  169. return false;
  170. case KC_AP_LED_SPEED:
  171. ap2_led_next_animation_speed();
  172. ap2_led_reset_foreground_color();
  173. return false;
  174. #ifdef RGB_MATRIX_ENABLE
  175. case QK_RGB_MATRIX_TOGGLE:
  176. if(rgb_matrix_is_enabled()) ap2_led_disable();
  177. else ap2_led_enable();
  178. return true;
  179. case KC_AP_RGB_VAI:
  180. if (record->event.pressed) {
  181. if (get_mods() & MOD_MASK_SHIFT) {
  182. rgb_matrix_increase_hue();
  183. return false;
  184. } else if (get_mods() & MOD_MASK_CTRL) {
  185. rgb_matrix_decrease_hue();
  186. return false;
  187. } else {
  188. rgb_matrix_increase_val();
  189. }
  190. }
  191. return true;
  192. case KC_AP_RGB_VAD:
  193. if (record->event.pressed) {
  194. if (get_mods() & MOD_MASK_SHIFT) {
  195. rgb_matrix_increase_sat();
  196. return false;
  197. } else if (get_mods() & MOD_MASK_CTRL) {
  198. rgb_matrix_decrease_sat();
  199. return false;
  200. } else {
  201. rgb_matrix_decrease_val();
  202. }
  203. }
  204. return true;
  205. case KC_AP_RGB_TOG:
  206. if (record->event.pressed) {
  207. if (get_mods() & MOD_MASK_SHIFT) {
  208. rgb_matrix_increase_speed();
  209. return false;
  210. } else if (get_mods() & MOD_MASK_CTRL) {
  211. rgb_matrix_decrease_speed();
  212. return false;
  213. } else {
  214. if (led_enabled) {
  215. ap2_led_disable();
  216. rgb_matrix_disable();
  217. led_enabled = 0;
  218. } else {
  219. ap2_led_enable();
  220. rgb_matrix_enable();
  221. led_enabled = 1;
  222. }
  223. return true;
  224. }
  225. }
  226. return true;
  227. case KC_AP_RGB_MOD:
  228. if (record->event.pressed) {
  229. if (get_mods() & MOD_MASK_CTRL) {
  230. rgb_matrix_step_reverse();
  231. return false;
  232. } else {
  233. rgb_matrix_step();
  234. }
  235. }
  236. return true;
  237. #endif
  238. default:
  239. break;
  240. }
  241. }
  242. return process_record_user(keycode, record);
  243. }