logo

qmk_firmware

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

ap2_led.c (6564B)


  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 <string.h>
  17. #include <stdio.h>
  18. #include "hal.h"
  19. #include "annepro2.h"
  20. #include "ap2_led.h"
  21. #include "protocol.h"
  22. ap2_led_t led_mask[KEY_COUNT];
  23. ap2_led_t led_colors[KEY_COUNT];
  24. ap2_led_status_t ap2_led_status;
  25. void led_command_callback(const message_t *msg) {
  26. switch (msg->command) {
  27. case CMD_LED_STATUS:
  28. ap2_led_status.amount_of_profiles = msg->payload[0];
  29. ap2_led_status.current_profile = msg->payload[1];
  30. ap2_led_status.matrix_enabled = msg->payload[2];
  31. ap2_led_status.is_reactive = msg->payload[3];
  32. ap2_led_status.led_intensity = msg->payload[4];
  33. ap2_led_status.errors = msg->payload[5];
  34. break;
  35. #ifdef CONSOLE_ENABLE
  36. case CMD_LED_DEBUG:
  37. /* TODO: Don't use printf. */
  38. printf("LED:");
  39. for (int i = 0; i < msg->payload_size; i++) {
  40. printf("%02x ", msg->payload[i]);
  41. }
  42. for (int i = 0; i < msg->payload_size; i++) {
  43. printf("%c", msg->payload[i]);
  44. }
  45. printf("\n");
  46. break;
  47. #endif
  48. }
  49. }
  50. void ap2_set_IAP(void) { proto_tx(CMD_LED_IAP, NULL, 0, 3); }
  51. void ap2_led_disable(void) { proto_tx(CMD_LED_OFF, NULL, 0, 3); }
  52. void ap2_led_enable(void) { proto_tx(CMD_LED_ON, NULL, 0, 3); }
  53. void ap2_led_set_profile(uint8_t prof) { proto_tx(CMD_LED_SET_PROFILE, &prof, sizeof(prof), 3); }
  54. void ap2_led_next_profile(void) { proto_tx(CMD_LED_NEXT_PROFILE, NULL, 0, 3); }
  55. void ap2_led_next_intensity(void) { proto_tx(CMD_LED_NEXT_INTENSITY, NULL, 0, 3); }
  56. void ap2_led_next_animation_speed(void) { proto_tx(CMD_LED_NEXT_ANIMATION_SPEED, NULL, 0, 3); }
  57. void ap2_led_prev_profile(void) { proto_tx(CMD_LED_PREV_PROFILE, NULL, 0, 3); }
  58. void ap2_led_mask_set_key(uint8_t row, uint8_t col, ap2_led_t color) {
  59. uint8_t payload[] = {row, col, color.p.blue, color.p.green, color.p.red, color.p.alpha};
  60. proto_tx(CMD_LED_MASK_SET_KEY, payload, sizeof(payload), 1);
  61. }
  62. /* Push a whole local row to the shine */
  63. void ap2_led_mask_set_row(uint8_t row) {
  64. uint8_t payload[NUM_COLUMN * sizeof(ap2_led_t) + 1];
  65. payload[0] = row;
  66. memcpy(payload + 1, &led_mask[ROWCOL2IDX(row, 0)], sizeof(*led_mask) * NUM_COLUMN);
  67. proto_tx(CMD_LED_MASK_SET_ROW, payload, sizeof(payload), 1);
  68. }
  69. /* Synchronize all rows */
  70. void ap2_led_mask_set_all(void) {
  71. for (int row = 0; row < 5; row++) ap2_led_mask_set_row(row);
  72. }
  73. /* Set all keys to a given color */
  74. void ap2_led_mask_set_mono(const ap2_led_t color) { proto_tx(CMD_LED_MASK_SET_MONO, (uint8_t *)&color, sizeof(color), 1); }
  75. void ap2_led_colors_set_key(uint8_t row, uint8_t col, ap2_led_t color) {
  76. uint8_t payload[] = {row, col, color.p.blue, color.p.green, color.p.red, color.p.alpha};
  77. proto_tx(CMD_LED_COLOR_SET_KEY, payload, sizeof(payload), 1);
  78. }
  79. /* Push a whole local row to the shine */
  80. void ap2_led_colors_set_row(uint8_t row) {
  81. uint8_t payload[NUM_COLUMN * sizeof(ap2_led_t) + 1];
  82. payload[0] = row;
  83. memcpy(payload + 1, &led_colors[ROWCOL2IDX(row, 0)], sizeof(*led_colors) * NUM_COLUMN);
  84. proto_tx(CMD_LED_COLOR_SET_ROW, payload, sizeof(payload), 1);
  85. }
  86. /* Synchronize all rows */
  87. void ap2_led_colors_set_all(void) {
  88. for (int row = 0; row < 5; row++) ap2_led_colors_set_row(row);
  89. }
  90. /* Set all keys to a given color */
  91. void ap2_led_colors_set_mono(const ap2_led_t color) { proto_tx(CMD_LED_COLOR_SET_MONO, (uint8_t *)&color, sizeof(color), 1); }
  92. void ap2_led_set_manual_control(uint8_t manual) {
  93. uint8_t payload[] = {manual};
  94. proto_tx(CMD_LED_SET_MANUAL, payload, sizeof(payload), 1);
  95. }
  96. void ap2_led_blink(uint8_t row, uint8_t col, ap2_led_t color, uint8_t count, uint8_t hundredths) {
  97. uint8_t payload[] = {row, col, color.p.blue, color.p.green, color.p.red, color.p.alpha, count, hundredths};
  98. proto_tx(CMD_LED_KEY_BLINK, payload, sizeof(payload), 1);
  99. }
  100. void ap2_led_set_foreground_color(uint8_t red, uint8_t green, uint8_t blue) {
  101. ap2_led_t color = {.p.red = red, .p.green = green, .p.blue = blue, .p.alpha = 0xff};
  102. ap2_led_mask_set_mono(color);
  103. }
  104. void ap2_led_reset_foreground_color(void) {
  105. ap2_led_t color = {
  106. .p.red = 0,
  107. .p.green = 0,
  108. .p.blue = 0,
  109. .p.alpha = 0,
  110. };
  111. ap2_led_mask_set_mono(color);
  112. }
  113. void ap2_led_sticky_set_key(uint8_t row, uint8_t col, ap2_led_t color) {
  114. uint8_t payload[] = {row, col, color.p.blue, color.p.green, color.p.red, color.p.alpha};
  115. proto_tx(CMD_LED_STICKY_SET_KEY, payload, sizeof(payload), 1);
  116. }
  117. void ap2_led_unset_sticky_key(uint8_t row, uint8_t col) {
  118. uint8_t payload[] = {row, col};
  119. proto_tx(CMD_LED_STICKY_UNSET_KEY, payload, sizeof(payload), 1);
  120. }
  121. void ap2_led_unset_sticky_row(uint8_t row) {
  122. uint8_t payload[] = {row};
  123. proto_tx(CMD_LED_STICKY_UNSET_ROW, payload, sizeof(payload), 1);
  124. }
  125. void ap2_led_unset_sticky_all(void) {
  126. proto_tx(CMD_LED_STICKY_UNSET_ALL, NULL, 0, 1);
  127. }
  128. /*
  129. * Currently keypresses are unified with other messages, still with single 1
  130. * byte payload. Transfer is normally fast enough for that to not be a problem -
  131. * especially with asynchronous message reading.
  132. *
  133. *
  134. * Previous description:
  135. * If enabled, this data is sent to LED MCU on every keypress.
  136. * In order to improve performance, both row and column values
  137. * are packed into a single byte.
  138. * Row range is [0, 4] and requires only 3 bits.
  139. * Column range is [0, 13] and requires 4 bits.
  140. *
  141. * In order to differentiate this command from regular commands,
  142. * the leftmost bit is set to 1 (0b10000000).
  143. * Following it are 3 bits of row and 4 bits of col.
  144. * 1 + 3 + 4 = 8 bits - only a single byte is sent for every keypress.
  145. */
  146. void ap2_led_forward_keypress(uint8_t row, uint8_t col) {
  147. const uint8_t payload = row << 4 | col;
  148. proto_tx(CMD_LED_KEY_DOWN, &payload, 1, 1);
  149. }