annepro2.c 8.7 KB

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