qmk_firmware

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

rev_0100.c (5870B)


      1 /* Copyright 2023 ArthurCyy <https://github.com/ArthurCyy>
      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 "rev_0100.h"
     18 #include "usb_main.h"
     19 #include "usb_util.h"
     20 
     21 #define LOOP_10HZ_PERIOD    100
     22 deferred_token loop10hz_token  = INVALID_DEFERRED_TOKEN;
     23 uint32_t loop_10Hz(uint32_t trigger_time, void *cb_arg);
     24 
     25 static const SerialConfig mwproto_uart_config = {
     26     .speed = MWPROTO_BITRATE,
     27 };
     28 
     29 static void POWER_EnterSleep(void) {
     30     /* Clear Wake-up flag */
     31     PWR->CR |= PWR_CR_CWUF | PWR_CR_CSBF;
     32     /* Select Sleep mode */
     33     /* PWR->CR |= PWR_CR_PDDS | PWR_CR_LPDS; */
     34     /* Set SLEEPDEEP bit of Cortex System Control Register */
     35     SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
     36     /* Request Wait For Interrupt */
     37     __WFI();
     38     /* Reset SLEEPDEEP bit of Cortex System Control Register */
     39     SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
     40     NVIC_SystemReset();
     41 }
     42 
     43 extern void ws2812_poweron(void);
     44 extern void ws2812_poweroff(void);
     45 
     46 static bool p_setup = false;
     47 static bool s_init = false;
     48 void ws2812_poweron(void) {
     49     if(p_setup) return;
     50     p_setup = true;
     51     s_init = false;
     52     gpio_set_pin_output(RGB_EN_PIN);
     53     gpio_write_pin_high(RGB_EN_PIN);
     54 }
     55 
     56 void ws2812_poweroff(void) {
     57     if(!p_setup) return;
     58     p_setup = false;
     59     gpio_set_pin_input_low(WS2812_DI_PIN);
     60     gpio_write_pin_low(RGB_EN_PIN);
     61 }
     62 
     63 void keyboard_pre_init_kb() {
     64 	keyboard_pre_init_user();
     65 
     66     gpio_set_pin_input_low(MWPROTO_STATUS_PIN);
     67     gpio_set_pin_output(MWPROTO_WAKEUP_PIN);
     68     gpio_write_pin_low(MWPROTO_WAKEUP_PIN);
     69     wait_ms(2);
     70     gpio_write_pin_high(MWPROTO_WAKEUP_PIN);
     71 
     72 	palSetLineMode(MWPROTO_TX_PIN, PAL_MODE_ALTERNATE(MWPROTO_TX_PAL_MODE) | PAL_OUTPUT_TYPE_OPENDRAIN);
     73 	sdStart(&MWPROTO_DRIVER, &mwproto_uart_config);
     74 }
     75 
     76 void keyboard_post_init_kb(void) {
     77     keyboard_post_init_user();
     78 
     79     print(/* clang-format off */
     80         "\n<--QMK Keyboard-->\n"
     81         "Vendor: " STR(MANUFACTURER) "(" STR(VENDOR_ID) ")\n"
     82         "Product: " STR(PRODUCT) " (" STR(PRODUCT_ID) ")\n"
     83         "Version: " STR(DEVICE_VER) "\n"
     84         "BUILD: " __DATE__ "\n"
     85     ); /* clang-format on */
     86 
     87     gpio_write_pin_low(MWPROTO_WAKEUP_PIN);
     88     wait_ms(50);
     89     sdPutI(&MWPROTO_DRIVER, 0xA5);
     90     sdPutI(&MWPROTO_DRIVER, 0x12);
     91     sdPutI(&MWPROTO_DRIVER, 0x01);
     92     sdPutI(&MWPROTO_DRIVER, 0x02);
     93     sdPutI(&MWPROTO_DRIVER, 0xB4);
     94     gpio_write_pin_high(MWPROTO_WAKEUP_PIN);
     95 
     96     ws2812_poweron();
     97     loop10hz_token = defer_exec(LOOP_10HZ_PERIOD, loop_10Hz, NULL);
     98 }
     99 
    100 bool shutdown_kb(bool jump_to_bootloader) {
    101     if (shutdown_user(jump_to_bootloader)) {
    102 #ifdef RGB_MATRIX_ENABLE
    103         rgb_matrix_set_suspend_state(true);
    104 #endif // RGB_MATRIX_ENABLE
    105         wait_ms(10);
    106     }
    107     ws2812_poweroff();
    108     return true;
    109 }
    110 
    111 #ifdef DIP_SWITCH_ENABLE
    112 bool dip_switch_update_mask_kb(uint32_t state) {
    113     if (!dip_switch_update_mask_user(state)) { return false; }
    114 
    115     if(state & 0x01) {
    116         led_suspend();
    117         usbDisconnectBus(&USB_DRIVER);
    118         usbStop(&USB_DRIVER);
    119         shutdown_user(true);
    120         gpio_set_pin_input_high(POWER_SWITCH_PIN);
    121         palEnableLineEvent(POWER_SWITCH_PIN, PAL_EVENT_MODE_RISING_EDGE);
    122         POWER_EnterSleep();
    123     }
    124 
    125     return true;
    126 }
    127 #endif
    128 
    129 uint32_t loop_10Hz(uint32_t trigger_time, void *cb_arg) {
    130 
    131     if(last_input_activity_elapsed() > 1000) {
    132         static uint32_t pmu_timer = 0;
    133         if(timer_elapsed32(pmu_timer) > 3000) {
    134             pmu_timer = timer_read32();
    135             gpio_write_pin_low(MWPROTO_WAKEUP_PIN);
    136             if(gpio_read_pin(MWPROTO_STATUS_PIN))
    137                 wait_us(500);
    138             else
    139                 wait_us(1500);
    140             sdPutI(&MWPROTO_DRIVER, 0xA5);
    141             sdPutI(&MWPROTO_DRIVER, 0x28);
    142             sdPutI(&MWPROTO_DRIVER, 0x00);
    143             sdPutI(&MWPROTO_DRIVER, 0x8D);
    144             gpio_write_pin_high(MWPROTO_WAKEUP_PIN);
    145         }
    146     }
    147 
    148     extern matrix_row_t matrix[MATRIX_ROWS];
    149     static uint32_t restore_tick = 0;
    150     if(matrix[0] == 0x4000 && matrix[1] == 0 &&
    151        matrix[2] == 0 && matrix[3] == 0 && matrix[4] == 0 && matrix[5] == 0x201) {
    152         if(restore_tick++ > 50) {
    153             restore_tick = 0;
    154             gpio_write_pin_low(MWPROTO_WAKEUP_PIN);
    155             if(gpio_read_pin(MWPROTO_STATUS_PIN))
    156                 wait_us(500);
    157             else
    158                 wait_us(1500);
    159             sdPutI(&MWPROTO_DRIVER, 0xA5);
    160             sdPutI(&MWPROTO_DRIVER, 0x1F);
    161             sdPutI(&MWPROTO_DRIVER, 0x01);
    162             sdPutI(&MWPROTO_DRIVER, 0x0F);
    163             sdPutI(&MWPROTO_DRIVER, 0xB4);
    164             gpio_write_pin_high(MWPROTO_WAKEUP_PIN);
    165             wait_ms(50);
    166             eeconfig_init();
    167     #ifdef RGB_MATRIX_ENABLE
    168             for(int i = 0; i < 5; i++) {
    169                 rgb_matrix_set_color_all(RGB_WHITE);
    170                 rgb_matrix_update_pwm_buffers();
    171                 wait_ms(500);
    172                 rgb_matrix_set_color_all(RGB_OFF);
    173                 rgb_matrix_update_pwm_buffers();
    174                 wait_ms(500);
    175             }
    176     #endif
    177             wait_ms(500);
    178             soft_reset_keyboard();
    179         }
    180     } else {
    181         restore_tick = 0;
    182     }
    183 
    184     static uint32_t debug_tick = 0;
    185 	if (debug_tick++ > 9 ) {
    186         dprintf("trigger %d\n", trigger_time);
    187 		debug_tick = 0;
    188 	}
    189 
    190     return LOOP_10HZ_PERIOD;
    191 }