djinn.c (7696B)
1 // Copyright 2018-2023 Nick Brassel (@tzarc) 2 // SPDX-License-Identifier: GPL-2.0-or-later 3 #include "djinn.h" 4 #include <string.h> 5 #include <hal_pal.h> 6 #include "serial.h" 7 #include "split_util.h" 8 9 painter_device_t lcd; 10 11 // clang-format off 12 #ifdef SWAP_HANDS_ENABLE 13 const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = { 14 { { 6, 6 }, { 5, 6 }, { 4, 6 }, { 3, 6 }, { 2, 6 }, { 1, 6 }, { 0, 6 } }, 15 { { 6, 7 }, { 5, 7 }, { 4, 7 }, { 3, 7 }, { 2, 7 }, { 1, 7 }, { 0, 7 } }, 16 { { 6, 8 }, { 5, 8 }, { 4, 8 }, { 3, 8 }, { 2, 8 }, { 1, 8 }, { 0, 8 } }, 17 { { 6, 9 }, { 5, 9 }, { 4, 9 }, { 3, 9 }, { 2, 9 }, { 1, 9 }, { 0, 9 } }, 18 { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6, 10 }, { 5, 10 }, { 4, 10 }, { 3, 10 } }, 19 { { 0, 0 }, { 6, 11 }, { 5, 11 }, { 4, 11 }, { 3, 11 }, { 2, 11 }, { 1, 11 } }, 20 21 { { 6, 0 }, { 5, 0 }, { 4, 0 }, { 3, 0 }, { 2, 0 }, { 1, 0 }, { 0, 0 } }, 22 { { 6, 1 }, { 5, 1 }, { 4, 1 }, { 3, 1 }, { 2, 1 }, { 1, 1 }, { 0, 1 } }, 23 { { 6, 2 }, { 5, 2 }, { 4, 2 }, { 3, 2 }, { 2, 2 }, { 1, 2 }, { 0, 2 } }, 24 { { 6, 3 }, { 5, 3 }, { 4, 3 }, { 3, 3 }, { 2, 3 }, { 1, 3 }, { 0, 3 } }, 25 { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6, 4 }, { 5, 4 }, { 4, 4 }, { 3, 4 } }, 26 { { 0, 0 }, { 6, 5 }, { 5, 5 }, { 4, 5 }, { 3, 5 }, { 2, 5 }, { 1, 5 } }, 27 }; 28 # ifdef ENCODER_MAP_ENABLE 29 const uint8_t PROGMEM encoder_hand_swap_config[NUM_ENCODERS] = { 1, 0 }; 30 # endif // ENCODER_MAP_ENABLE 31 #endif // SWAP_HANDS_ENABLE 32 // clang-format on 33 34 void board_init(void) { 35 usbpd_init(); 36 } 37 38 //---------------------------------------------------------- 39 // Initialisation 40 41 void keyboard_post_init_kb(void) { 42 // Register keyboard state sync split transaction 43 transaction_register_rpc(RPC_ID_SYNC_STATE_KB, kb_state_sync_slave); 44 45 // Reset the initial shared data value between master and slave 46 memset(&kb_state, 0, sizeof(kb_state)); 47 48 // Turn off increased current limits 49 gpio_set_pin_output(RGB_CURR_1500mA_OK_PIN); 50 gpio_write_pin_low(RGB_CURR_1500mA_OK_PIN); 51 gpio_set_pin_output(RGB_CURR_3000mA_OK_PIN); 52 gpio_write_pin_low(RGB_CURR_3000mA_OK_PIN); 53 54 // Turn on the RGB 55 gpio_set_pin_output(RGB_POWER_ENABLE_PIN); 56 gpio_write_pin_high(RGB_POWER_ENABLE_PIN); 57 58 #ifdef EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN 59 gpio_set_pin_output(EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN); 60 gpio_write_pin_high(EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN); 61 #endif // EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN 62 63 // Turn on the LCD 64 gpio_set_pin_output(LCD_POWER_ENABLE_PIN); 65 gpio_write_pin_high(LCD_POWER_ENABLE_PIN); 66 67 // Let the LCD get some power... 68 wait_ms(150); 69 70 // Initialise the LCD 71 lcd = qp_ili9341_make_spi_device(240, 320, LCD_CS_PIN, LCD_DC_PIN, LCD_RST_PIN, 4, 0); 72 qp_init(lcd, QP_ROTATION_0); 73 74 // Turn on the LCD and clear the display 75 qp_power(lcd, true); 76 qp_rect(lcd, 0, 0, 239, 319, HSV_BLACK, true); 77 78 // Turn on the LCD backlight 79 backlight_enable(); 80 backlight_level(BACKLIGHT_LEVELS); 81 82 // Allow for user post-init 83 keyboard_post_init_user(); 84 } 85 86 //---------------------------------------------------------- 87 // RGB brightness scaling dependent on USBPD state 88 89 #if defined(RGB_MATRIX_ENABLE) 90 rgb_t rgb_matrix_hsv_to_rgb(hsv_t hsv) { 91 float scale; 92 93 # ifdef DJINN_SUPPORTS_3A_FUSE 94 // The updated BOM on the Djinn has properly-spec'ed fuses -- 1500mA/3000mA hold current 95 switch (kb_state.current_setting) { 96 default: 97 case USBPD_500MA: 98 scale = 0.35f; 99 break; 100 case USBPD_1500MA: 101 scale = 0.75f; 102 break; 103 case USBPD_3000MA: 104 scale = 1.0f; 105 break; 106 } 107 # else 108 // The original BOM on the Djinn had wrongly-spec'ed fuses -- 750mA/1500mA hold current 109 switch (kb_state.current_setting) { 110 default: 111 case USBPD_500MA: 112 case USBPD_1500MA: 113 scale = 0.35f; 114 break; 115 case USBPD_3000MA: 116 scale = 0.75f; 117 break; 118 } 119 # endif 120 121 hsv.v = (uint8_t)(hsv.v * scale); 122 return hsv_to_rgb(hsv); 123 } 124 #endif 125 126 //---------------------------------------------------------- 127 // UI Placeholder, implemented in themes 128 129 __attribute__((weak)) void draw_ui_user(bool force_redraw) {} 130 131 //---------------------------------------------------------- 132 // Housekeeping 133 134 void housekeeping_task_kb(void) { 135 // Update kb_state so we can send to slave 136 kb_state_update(); 137 138 // Data sync from master to slave 139 kb_state_sync(); 140 141 // Work out if we've changed our current limit, update the limiter circuit switches 142 static uint8_t current_setting = USBPD_500MA; 143 if (current_setting != kb_state.current_setting) { 144 current_setting = kb_state.current_setting; 145 146 #ifdef DJINN_SUPPORTS_3A_FUSE 147 // The updated BOM on the Djinn has properly-spec'ed fuses -- 1500mA/3000mA hold current 148 switch (current_setting) { 149 default: 150 case USBPD_500MA: 151 gpio_write_pin_low(RGB_CURR_1500mA_OK_PIN); 152 gpio_write_pin_low(RGB_CURR_3000mA_OK_PIN); 153 break; 154 case USBPD_1500MA: 155 gpio_write_pin_high(RGB_CURR_1500mA_OK_PIN); 156 gpio_write_pin_low(RGB_CURR_3000mA_OK_PIN); 157 break; 158 case USBPD_3000MA: 159 gpio_write_pin_high(RGB_CURR_1500mA_OK_PIN); 160 gpio_write_pin_high(RGB_CURR_3000mA_OK_PIN); 161 break; 162 } 163 #else 164 // The original BOM on the Djinn had wrongly-spec'ed fuses -- 750mA/1500mA hold current 165 switch (current_setting) { 166 default: 167 case USBPD_500MA: 168 case USBPD_1500MA: 169 gpio_write_pin_low(RGB_CURR_1500mA_OK_PIN); 170 gpio_write_pin_low(RGB_CURR_3000mA_OK_PIN); 171 break; 172 case USBPD_3000MA: 173 gpio_write_pin_high(RGB_CURR_1500mA_OK_PIN); 174 gpio_write_pin_low(RGB_CURR_3000mA_OK_PIN); 175 break; 176 } 177 #endif 178 179 // If we've changed the current limit, toggle rgb off and on if it was on, to force a brightness update on all LEDs 180 if (is_keyboard_master() && rgb_matrix_is_enabled()) { 181 rgb_matrix_disable_noeeprom(); 182 rgb_matrix_enable_noeeprom(); 183 } 184 } 185 186 // Turn on/off the LCD 187 bool peripherals_on = last_input_activity_elapsed() < LCD_ACTIVITY_TIMEOUT; 188 189 // Enable/disable RGB 190 if (peripherals_on) { 191 // Turn on RGB 192 gpio_write_pin_high(RGB_POWER_ENABLE_PIN); 193 // Modify the RGB state if different to the LCD state 194 if (rgb_matrix_is_enabled() != peripherals_on) { 195 // Wait for a small amount of time to allow the RGB capacitors to charge, before enabling RGB output 196 wait_ms(10); 197 // Enable RGB 198 rgb_matrix_enable_noeeprom(); 199 } 200 } else { 201 // Turn off RGB 202 gpio_write_pin_low(RGB_POWER_ENABLE_PIN); 203 // Disable the PWM output for the RGB 204 if (rgb_matrix_is_enabled() != peripherals_on) { 205 rgb_matrix_disable_noeeprom(); 206 } 207 } 208 209 // Match the backlight to the LCD state 210 if (is_keyboard_master() && is_backlight_enabled() != peripherals_on) { 211 if (peripherals_on) 212 backlight_enable(); 213 else 214 backlight_disable(); 215 } 216 217 // Draw the UI 218 if (peripherals_on) { 219 draw_ui_user(false); 220 } 221 222 // Go into low-scan interrupt-based mode if we haven't had any matrix activity in the last 250 milliseconds 223 if (last_input_activity_elapsed() > 250) { 224 matrix_wait_for_interrupt(); 225 } 226 }