qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

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