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 }