From 05004976129fafd4cea98b18ad0f44a505324c42 Mon Sep 17 00:00:00 2001 From: patrickmt <40182064+patrickmt@users.noreply.github.com> Date: Tue, 16 Apr 2019 09:24:38 -0400 Subject: [PATCH] ctrl alt working but not fully tested --- keyboards/massdrop/alt/config.h | 2 +- keyboards/massdrop/alt/config_adc.h | 81 +++ keyboards/massdrop/alt/config_led.c | 6 +- keyboards/massdrop/alt/config_led.h | 49 +- keyboards/massdrop/alt/config_spi.h | 42 ++ keyboards/massdrop/alt/config_usb.h | 28 + .../massdrop/alt/keymaps/abishalom/keymap.c | 10 +- .../massdrop/alt/keymaps/default/keymap.c | 10 +- .../massdrop/alt/keymaps/default_md/keymap.c | 123 +++-- keyboards/massdrop/alt/keymaps/mac/keymap.c | 10 +- .../massdrop/alt/keymaps/mac_md/keymap.c | 123 +++-- .../massdrop/alt/keymaps/reywood/keymap.c | 8 +- keyboards/massdrop/alt/matrix.c | 27 +- keyboards/massdrop/alt/rules.mk | 2 + keyboards/massdrop/alt/spi.c | 57 ++ keyboards/massdrop/alt/usb.c | 83 +++ keyboards/massdrop/ctrl/config.h | 2 +- keyboards/massdrop/ctrl/config_adc.h | 75 +++ keyboards/massdrop/ctrl/config_led.h | 46 +- keyboards/massdrop/ctrl/config_spi.h | 42 ++ keyboards/massdrop/ctrl/config_usb.h | 28 + .../massdrop/ctrl/keymaps/default/keymap.c | 12 +- .../massdrop/ctrl/keymaps/default_md/keymap.c | 135 +++-- keyboards/massdrop/ctrl/keymaps/mac/keymap.c | 12 +- .../massdrop/ctrl/keymaps/mac_md/keymap.c | 135 +++-- .../ctrl/keymaps/responsive_pattern/keymap.c | 8 +- keyboards/massdrop/ctrl/matrix.c | 27 +- keyboards/massdrop/ctrl/rules.mk | 2 + keyboards/massdrop/ctrl/spi.c | 57 ++ keyboards/massdrop/ctrl/usb.c | 83 +++ keyboards/massdrop/rocketeer/config.h | 129 +++++ keyboards/massdrop/rocketeer/config_adc.h | 118 ++++ keyboards/massdrop/rocketeer/config_led.h | 160 ++++++ keyboards/massdrop/rocketeer/config_spi.h | 42 ++ keyboards/massdrop/rocketeer/config_usb.h | 28 + keyboards/massdrop/rocketeer/info.json | 101 ++++ .../rocketeer/keymaps/default/keymap.c | 250 +++++++++ .../massdrop/rocketeer/keymaps/mac/keymap.c | 250 +++++++++ keyboards/massdrop/rocketeer/matrix.c | 181 ++++++ keyboards/massdrop/rocketeer/matrix.h | 77 +++ keyboards/massdrop/rocketeer/readme.md | 20 + keyboards/massdrop/rocketeer/rocketeer.h | 34 ++ keyboards/massdrop/rocketeer/rules.mk | 38 ++ keyboards/massdrop/rocketeer/spi.c | 60 ++ keyboards/massdrop/rocketeer/usb.c | 119 ++++ keyboards/massdrop/shift/config.h | 159 ++++++ keyboards/massdrop/shift/config_adc.h | 118 ++++ keyboards/massdrop/shift/config_led.h | 233 ++++++++ keyboards/massdrop/shift/config_spi.h | 42 ++ keyboards/massdrop/shift/config_usb.h | 28 + keyboards/massdrop/shift/info.json | 101 ++++ .../massdrop/shift/keymaps/default/keymap.c | 258 +++++++++ keyboards/massdrop/shift/keymaps/mac/keymap.c | 258 +++++++++ keyboards/massdrop/shift/matrix.c | 210 +++++++ keyboards/massdrop/shift/matrix.h | 77 +++ keyboards/massdrop/shift/readme.md | 20 + keyboards/massdrop/shift/rules.mk | 38 ++ keyboards/massdrop/shift/shift.h | 40 ++ keyboards/massdrop/shift/spi.c | 60 ++ keyboards/massdrop/shift/usb.c | 119 ++++ tmk_core/protocol/arm_atsam.mk | 1 + tmk_core/protocol/arm_atsam/adc.c | 232 ++++++-- tmk_core/protocol/arm_atsam/adc.h | 21 +- .../protocol/arm_atsam/arm_atsam_protocol.h | 25 +- tmk_core/protocol/arm_atsam/clks.c | 5 +- tmk_core/protocol/arm_atsam/clks.h | 36 +- tmk_core/protocol/arm_atsam/d51_util.c | 4 +- tmk_core/protocol/arm_atsam/d51_util.h | 59 +- tmk_core/protocol/arm_atsam/i2c_master.c | 52 +- tmk_core/protocol/arm_atsam/i2c_master.h | 3 +- tmk_core/protocol/arm_atsam/led_matrix.c | 317 +++++++---- tmk_core/protocol/arm_atsam/led_matrix.h | 24 +- tmk_core/protocol/arm_atsam/main_arm_atsam.c | 46 +- tmk_core/protocol/arm_atsam/main_arm_atsam.h | 2 + tmk_core/protocol/arm_atsam/md_bootloader.h | 12 +- tmk_core/protocol/arm_atsam/power.c | 100 ++++ tmk_core/protocol/arm_atsam/power.h | 24 + tmk_core/protocol/arm_atsam/spi.c | 129 +++-- tmk_core/protocol/arm_atsam/spi.h | 99 +++- tmk_core/protocol/arm_atsam/usb/usb2422.c | 522 ++++++++++++------ tmk_core/protocol/arm_atsam/usb/usb2422.h | 80 ++- 81 files changed, 5675 insertions(+), 811 deletions(-) create mode 100644 keyboards/massdrop/alt/config_adc.h create mode 100644 keyboards/massdrop/alt/config_spi.h create mode 100644 keyboards/massdrop/alt/config_usb.h create mode 100644 keyboards/massdrop/alt/spi.c create mode 100644 keyboards/massdrop/alt/usb.c create mode 100644 keyboards/massdrop/ctrl/config_adc.h create mode 100644 keyboards/massdrop/ctrl/config_spi.h create mode 100644 keyboards/massdrop/ctrl/config_usb.h create mode 100644 keyboards/massdrop/ctrl/spi.c create mode 100644 keyboards/massdrop/ctrl/usb.c create mode 100644 keyboards/massdrop/rocketeer/config.h create mode 100644 keyboards/massdrop/rocketeer/config_adc.h create mode 100644 keyboards/massdrop/rocketeer/config_led.h create mode 100644 keyboards/massdrop/rocketeer/config_spi.h create mode 100644 keyboards/massdrop/rocketeer/config_usb.h create mode 100644 keyboards/massdrop/rocketeer/info.json create mode 100644 keyboards/massdrop/rocketeer/keymaps/default/keymap.c create mode 100644 keyboards/massdrop/rocketeer/keymaps/mac/keymap.c create mode 100644 keyboards/massdrop/rocketeer/matrix.c create mode 100644 keyboards/massdrop/rocketeer/matrix.h create mode 100644 keyboards/massdrop/rocketeer/readme.md create mode 100644 keyboards/massdrop/rocketeer/rocketeer.h create mode 100644 keyboards/massdrop/rocketeer/rules.mk create mode 100644 keyboards/massdrop/rocketeer/spi.c create mode 100644 keyboards/massdrop/rocketeer/usb.c create mode 100644 keyboards/massdrop/shift/config.h create mode 100644 keyboards/massdrop/shift/config_adc.h create mode 100644 keyboards/massdrop/shift/config_led.h create mode 100644 keyboards/massdrop/shift/config_spi.h create mode 100644 keyboards/massdrop/shift/config_usb.h create mode 100644 keyboards/massdrop/shift/info.json create mode 100644 keyboards/massdrop/shift/keymaps/default/keymap.c create mode 100644 keyboards/massdrop/shift/keymaps/mac/keymap.c create mode 100644 keyboards/massdrop/shift/matrix.c create mode 100644 keyboards/massdrop/shift/matrix.h create mode 100644 keyboards/massdrop/shift/readme.md create mode 100644 keyboards/massdrop/shift/rules.mk create mode 100644 keyboards/massdrop/shift/shift.h create mode 100644 keyboards/massdrop/shift/spi.c create mode 100644 keyboards/massdrop/shift/usb.c create mode 100644 tmk_core/protocol/arm_atsam/power.c create mode 100644 tmk_core/protocol/arm_atsam/power.h diff --git a/keyboards/massdrop/alt/config.h b/keyboards/massdrop/alt/config.h index f63c38bf6f8..b2184b22274 100644 --- a/keyboards/massdrop/alt/config.h +++ b/keyboards/massdrop/alt/config.h @@ -54,7 +54,7 @@ along with this program. If not, see . #define SR_EXP_OE_N_PIN 15 /* SERCOM port to use for Shift Register SPI */ /* DATAOUT and SCLK must be configured to use hardware pins of this port */ -#define SR_EXP_SERCOM SERCOM2 +#define SR_EXP_SERCOM_NUM 2 /* Shift Register SPI Data Out configuration (MCU.SERCOMx.PAD[0] to ShiftRegister.SER) */ #define SR_EXP_DATAOUT_PORT PA #define SR_EXP_DATAOUT_PIN 12 diff --git a/keyboards/massdrop/alt/config_adc.h b/keyboards/massdrop/alt/config_adc.h new file mode 100644 index 00000000000..bb44c845eac --- /dev/null +++ b/keyboards/massdrop/alt/config_adc.h @@ -0,0 +1,81 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +//ADC configuration table column indices +#define ADC_PORT 0 +#define ADC_PIN 1 +#define ADC_MUX 2 +#define ADC_INDEX 3 +#define ADC_MUXPOS 4 +#define ADC_REFSEL 5 +#define ADC_SAMPLENUM 6 +#define ADC_SAMPLEN 7 + +//ADC configuration table row indices +#define ADC_5V 0 //5V bus voltage +#define ADC_C1A5 1 //Connector 1 A5 CC voltage +#define ADC_C1B5 2 //Connector 1 B5 CC voltage +#define ADC_C2A5 3 //Connector 2 A5 CC voltage +#define ADC_C2B5 4 //Connector 2 B5 CC voltage +#define ADC_C1I 5 //Connector 1 current +#define ADC_C2I 6 //Connector 2 current + +//ADC_PORT: PORT of the PIN on the MCU (Ex: 0 = PA, 1 = PB, ...) +// Set ADC_PORT to ADC_NA if it is not available for use +//ADC_PIN: PIN on the MCU (Ex: 0 = 00, 1 = 01, 12 = 12, ...) +//ADC_MUX: PMUX setting for the MCU PIN (Ex: 0 = A, 1 = B, 2 = C, ...) +//ADC_INDEX: ADC to use (Ex: 0 = ADC0, 1 = ADC1, ...) +//ADC_MUXPOS: MUXPOS setting to read on the ADC (Use macros from Atmel library adc.h ADC_INPUTCTRL_MUXPOS_AIN*_Val) +//ADC_REFSEL: Reference the ADC is to use (Use macros from Atmel library adc.h ADC_REFCTRL_REFSEL_*_Val) +//ADC_SAMPLENUM: Number of samples to average for output (Use macros from Atmel library adc.h ADC_AVGCTRL_SAMPLENUM_*_Val) +//ADC_SAMPLEN: Sampling time for each sample in units of CLK_ADC cycles depending on the ADC clock frequency +// ADC_PORT ADC_MUX +// | ADC_PIN | ADC_INDEX +// | | | | ADC_MUXPOS ADC_REFSEL ADC_SAMPLENUM ADC_SAMPLEN +#define ADC_CONFIG_5V 1, 0, 1, 0, ADC_INPUTCTRL_MUXPOS_AIN12_Val, ADC_REFCTRL_REFSEL_INTREF_Val, ADC_AVGCTRL_SAMPLENUM_4_Val, 45 +#define ADC_CONFIG_C1A5 1, 2, 1, 0, ADC_INPUTCTRL_MUXPOS_AIN14_Val, ADC_REFCTRL_REFSEL_INTREF_Val, ADC_AVGCTRL_SAMPLENUM_16_Val, 63 +#define ADC_CONFIG_C1B5 ADC_NA, 0, 0, 0, 0, 0, 0, 0 +#define ADC_CONFIG_C2A5 1, 1, 1, 0, ADC_INPUTCTRL_MUXPOS_AIN13_Val, ADC_REFCTRL_REFSEL_INTREF_Val, ADC_AVGCTRL_SAMPLENUM_16_Val, 63 +#define ADC_CONFIG_C2B5 ADC_NA, 0, 0, 0, 0, 0, 0, 0 +#define ADC_CONFIG_C1I ADC_NA, 0, 0, 0, 0, 0, 0, 0 +#define ADC_CONFIG_C2I ADC_NA, 0, 0, 0, 0, 0, 0, 0 + +//Conversion values dependant upon the circuitry +#define ADC_5V_VOLTS_PER_COUNT 0.001904297f +#define ADC_5V_VOLTS_OFFSET 0.0f +#define ADC_5V_NOMINAL 5.0f +#define ADC_5V_NOMINAL_COUNTS (ADC_5V_NOMINAL / ADC_5V_VOLTS_PER_COUNT) + +//Conversion macros +#define ADC_5V_C2V(icounts) ((float)icounts * ADC_5V_VOLTS_PER_COUNT + ADC_5V_VOLTS_OFFSET) //Converts 5V Bus counts to volts +#define ADC_5V_V2C(v) (((float)v - ADC_5V_VOLTS_OFFSET) / ADC_5V_VOLTS_PER_COUNT) //Converts 5V Bus volts to counts +#define ADC_CC_5VCOR(v5counts, cc) ((float)v5counts == 0 ? 0 : ADC_5V_NOMINAL_COUNTS / (float)v5counts * (float)cc) //Corrects CC counts to nominal 5V value + +#define ADC_USBC_EXTRA_NOMINAL 850 //Nominal ADC value for detection of connected device +#define ADC_USBC_EXTRA_NOMINAL_P1 1250 //Nominal ADC value for detection of connected device + +//Note: Due to assembly error, USBC-1 J2 CC readings are wrong so we must check for special cases +#define USBC_IS_SINK(a5, b5) (USB_HOST_IS_2(g_usb_host_port) ? \ + (a5 < ADC_USBC_EXTRA_NOMINAL_P1 || b5 < ADC_USBC_EXTRA_NOMINAL_P1) \ + : \ + (a5 < ADC_USBC_EXTRA_NOMINAL || b5 < ADC_USBC_EXTRA_NOMINAL) \ + ) + +#define POWER_CHECK_INTERVAL 1 //How often to check power usage for adjustment and safety (ms) +#define V_5V_AVGS 50 //Number of 5V readings to average for algorithms wanting stable readings rather than instantaneous diff --git a/keyboards/massdrop/alt/config_led.c b/keyboards/massdrop/alt/config_led.c index 7d98e47c907..a430adeb116 100644 --- a/keyboards/massdrop/alt/config_led.c +++ b/keyboards/massdrop/alt/config_led.c @@ -8,10 +8,14 @@ // This table can be almost-automatically derived from ISSI3733_LED_MAP that is // defined in config_led.h +// scan in the following equations refers to the scan variable of ISSI3733_LED_MAP +// col = (uint8_t)(scan / 8) +// row = (uint8_t)(scan % 8) +// // You can calculate the (0-244, 0-64) x/y values from the x/y values defined in // ISSI3733_LED_MAP with the following formula: // uint8_t rgb_x = ((ISSI3733_LED_MAP[i].x - MIN_X) / (MAX_X - MIN_X)) * 224; -// uint8_t rgb_y = ((ISSI3733_LED_MAP[i].y - MIN_Y) / (MAX_Y - MIN_Y)) * 64; +// uint8_t rgb_y = ((ISSI3733_LED_MAP[i].y - MIN_Y) / (MAX_Y - MIN_Y)) * 64; //TODO: 64 - this? // Where the min/max vars are the minimum and maximum "bounds" of x/y values // present in ISSI3733_LED_MAP // diff --git a/keyboards/massdrop/alt/config_led.h b/keyboards/massdrop/alt/config_led.h index 82117b33279..159967d09c6 100644 --- a/keyboards/massdrop/alt/config_led.h +++ b/keyboards/massdrop/alt/config_led.h @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,11 +17,11 @@ along with this program. If not, see . #pragma once -//Define number of ISSI3733 drivers being used (1...16) +//Define number of IS31FL3733 drivers being used (1...16) #define ISSI3733_DRIVER_COUNT 2 #define DRIVER_LED_TOTAL ISSI3733_LED_COUNT -//Hardware address of each driver (Refer to ISSI3733 pdf "Table 1 Slave Address" and keyboard schematic) +//Hardware address of each driver (Refer to IS31FL3733 pdf "Table 1 Slave Address" and keyboard schematic) #define ISSI3773_DRIVER_ADDRESSES { 0xA0, 0xBE } //LED I2C bus speed @@ -45,9 +45,9 @@ along with this program. If not, see . #define ISSI3733_GCR_DEFAULT LED_GCR_MAX //Automatic power rollback and recovery -#define V5_HIGH 2540 //5V high level (After low power detect, point at which LEDs are allowed to use more power ) -#define V5_LOW 2480 //5V low level (LED power rolled back to stay above this limit) -#define V5_CAT 2200 //5V catastrophic level (Host USB port potential to shut down) +#define V5_HIGH 2494 //5V high level (After low power detect, point at which LEDs are allowed to use more power ) +#define V5_LOW 2434 //5V low level (LED power rolled back to stay above this limit) +#define V5_CAT 2206 //5V catastrophic level (Host USB port potential to shut down) //LED Mapping - More practically generated from a spreadsheet program //id: ID of the LED (Sync with PCB callouts) @@ -58,7 +58,7 @@ along with this program. If not, see . //swr: Matrix wiring SW Red row (1-12) //swg: Matrix wiring SW Green row (1-12) //swb: Matrix wiring SW Blue row (1-12) -//scan: Associated key scancode if any +//scan: Associated key matrix scancode (set 255 if none or 254 for LED to turn off in alternating mode) //Note: Origin 0,0 may be located anywhere as the software will do the final layout #define ISSI3733_LED_MAP { \ { .id = 1, .x = 0, .y = 0, .adr = { .drv = 2, .cs = 2, .swr = 2, .swg = 1, .swb = 3 }, .scan = 0 }, \ @@ -129,46 +129,45 @@ along with this program. If not, see . { .id = 66, .x = 10.5, .y = -3, .adr = { .drv = 1, .cs = 12, .swr = 8, .swg = 7, .swb = 9 }, .scan = 73 }, \ { .id = 67, .x = 11.25, .y = -3, .adr = { .drv = 1, .cs = 12, .swr = 5, .swg = 4, .swb = 6 }, .scan = 74 }, \ { .id = 68, .x = -0.338, .y = -3.338, .adr = { .drv = 2, .cs = 11, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ - { .id = 69, .x = 0.39, .y = -3.443, .adr = { .drv = 2, .cs = 11, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 69, .x = 0.39, .y = -3.443, .adr = { .drv = 2, .cs = 11, .swr = 8, .swg = 7, .swb = 9 }, .scan = 254 }, \ { .id = 70, .x = 1.263, .y = -3.443, .adr = { .drv = 2, .cs = 11, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ - { .id = 71, .x = 2.135, .y = -3.443, .adr = { .drv = 2, .cs = 11, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 71, .x = 2.135, .y = -3.443, .adr = { .drv = 2, .cs = 11, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 72, .x = 3.008, .y = -3.443, .adr = { .drv = 2, .cs = 12, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 73, .x = 3.88, .y = -3.443, .adr = { .drv = 2, .cs = 12, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 73, .x = 3.88, .y = -3.443, .adr = { .drv = 2, .cs = 12, .swr = 5, .swg = 4, .swb = 6 }, .scan = 254 }, \ { .id = 74, .x = 4.753, .y = -3.443, .adr = { .drv = 2, .cs = 13, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ - { .id = 75, .x = 5.625, .y = -3.443, .adr = { .drv = 2, .cs = 13, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 75, .x = 5.625, .y = -3.443, .adr = { .drv = 2, .cs = 13, .swr = 8, .swg = 7, .swb = 9 }, .scan = 254 }, \ { .id = 76, .x = 6.497, .y = -3.443, .adr = { .drv = 1, .cs = 9, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ - { .id = 77, .x = 7.37, .y = -3.443, .adr = { .drv = 1, .cs = 9, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 77, .x = 7.37, .y = -3.443, .adr = { .drv = 1, .cs = 9, .swr = 5, .swg = 4, .swb = 6 }, .scan = 254 }, \ { .id = 78, .x = 8.242, .y = -3.443, .adr = { .drv = 1, .cs = 9, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 79, .x = 9.115, .y = -3.443, .adr = { .drv = 1, .cs = 13, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 79, .x = 9.115, .y = -3.443, .adr = { .drv = 1, .cs = 13, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 80, .x = 9.987, .y = -3.443, .adr = { .drv = 1, .cs = 13, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ - { .id = 81, .x = 10.86, .y = -3.443, .adr = { .drv = 1, .cs = 13, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 81, .x = 10.86, .y = -3.443, .adr = { .drv = 1, .cs = 13, .swr = 5, .swg = 4, .swb = 6 }, .scan = 254 }, \ { .id = 82, .x = 11.588, .y = -3.338, .adr = { .drv = 1, .cs = 13, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ - { .id = 83, .x = 11.693, .y = -2.623, .adr = { .drv = 1, .cs = 12, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ + { .id = 83, .x = 11.693, .y = -2.623, .adr = { .drv = 1, .cs = 12, .swr = 11, .swg = 10, .swb = 12 }, .scan = 254 }, \ { .id = 84, .x = 11.693, .y = -1.873, .adr = { .drv = 1, .cs = 8, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ { .id = 85, .x = 11.693, .y = -1.123, .adr = { .drv = 1, .cs = 8, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ - { .id = 86, .x = 11.693, .y = -0.373, .adr = { .drv = 1, .cs = 8, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 86, .x = 11.693, .y = -0.373, .adr = { .drv = 1, .cs = 8, .swr = 5, .swg = 4, .swb = 6 }, .scan = 254 }, \ { .id = 87, .x = 11.588, .y = 0.338, .adr = { .drv = 1, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ { .id = 88, .x = 9.908, .y = 0.443, .adr = { .drv = 1, .cs = 6, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 89, .x = 9.288, .y = 0.443, .adr = { .drv = 1, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 89, .x = 9.288, .y = 0.443, .adr = { .drv = 1, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 90, .x = 8.625, .y = 0.443, .adr = { .drv = 1, .cs = 4, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 91, .x = 7.875, .y = 0.443, .adr = { .drv = 1, .cs = 3, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 91, .x = 7.875, .y = 0.443, .adr = { .drv = 1, .cs = 3, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 92, .x = 7.125, .y = 0.443, .adr = { .drv = 1, .cs = 2, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 93, .x = 6.375, .y = 0.443, .adr = { .drv = 1, .cs = 1, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 93, .x = 6.375, .y = 0.443, .adr = { .drv = 1, .cs = 1, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 94, .x = 5.625, .y = 0.443, .adr = { .drv = 1, .cs = 14, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 95, .x = 4.875, .y = 0.443, .adr = { .drv = 2, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 95, .x = 4.875, .y = 0.443, .adr = { .drv = 2, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 96, .x = 4.125, .y = 0.443, .adr = { .drv = 2, .cs = 7, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 97, .x = 3.375, .y = 0.443, .adr = { .drv = 2, .cs = 6, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 97, .x = 3.375, .y = 0.443, .adr = { .drv = 2, .cs = 6, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 98, .x = 2.625, .y = 0.443, .adr = { .drv = 2, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 99, .x = 1.875, .y = 0.443, .adr = { .drv = 2, .cs = 4, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 99, .x = 1.875, .y = 0.443, .adr = { .drv = 2, .cs = 4, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 100, .x = 1.125, .y = 0.443, .adr = { .drv = 2, .cs = 3, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ { .id = 101, .x = -0.338, .y = 0.338, .adr = { .drv = 2, .cs = 1, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 102, .x = -0.443, .y = -0.373, .adr = { .drv = 2, .cs = 1, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 102, .x = -0.443, .y = -0.373, .adr = { .drv = 2, .cs = 1, .swr = 5, .swg = 4, .swb = 6 }, .scan = 254 }, \ { .id = 103, .x = -0.443, .y = -1.123, .adr = { .drv = 2, .cs = 1, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ { .id = 104, .x = -0.443, .y = -1.873, .adr = { .drv = 2, .cs = 1, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ - { .id = 105, .x = -0.443, .y = -2.623, .adr = { .drv = 2, .cs = 10, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ + { .id = 105, .x = -0.443, .y = -2.623, .adr = { .drv = 2, .cs = 10, .swr = 11, .swg = 10, .swb = 12 }, .scan = 254 }, \ }; - #define USB_LED_INDICATOR_ENABLE //Comment out to disable indicator functionality #ifdef USB_LED_INDICATOR_ENABLE //Scan codes refer to actual key matrix codes, not KC_* (255 to disable) #define USB_LED_NUM_LOCK_SCANCODE 255 diff --git a/keyboards/massdrop/alt/config_spi.h b/keyboards/massdrop/alt/config_spi.h new file mode 100644 index 00000000000..5bab7bf37d9 --- /dev/null +++ b/keyboards/massdrop/alt/config_spi.h @@ -0,0 +1,42 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +/* Data structure to define Shift Register output expander hardware */ +/* This structure gets shifted into registers LSB first */ +typedef union { + struct { + uint16_t RSVD4:1; /*!< bit: 0 */ + uint16_t RSVD3:1; /*!< bit: 1 */ + uint16_t RSVD2:1; /*!< bit: 2 */ + uint16_t RSVD1:1; /*!< bit: 3 */ + uint16_t SDB_N:1; /*!< bit: 4 SHUTDOWN IS31FL3733 CHIPS WHEN 0, RUN WHEN 1 */ + uint16_t IRST:1; /*!< bit: 5 RESET IS31FL3733 I2C WHEN 1, RUN WHEN 0 */ + uint16_t SRC_2:1; /*!< bit: 6 ADVERTISE A SOURCE TO USBC-2 CC */ + uint16_t SRC_1:1; /*!< bit: 7 ADVERTISE A SOURCE TO USBC-1 CC */ + uint16_t E_VBUS_2:1; /*!< bit: 8 ENABLE 5V OUT TO USBC-2 WHEN 1 */ + uint16_t E_VBUS_1:1; /*!< bit: 9 ENABLE 5V OUT TO USBC-1 WHEN 1 */ + uint16_t E_DN1_N:1; /*!< bit: 10 ENABLE DN1 1:2 MUX WHEN 0 */ + uint16_t S_DN1:1; /*!< bit: 11 SELECT DN1 PATH 0:USBC-1, 1:USBC-2 */ + uint16_t E_UP_N:1; /*!< bit: 12 ENABLE SUP 1:2 MUX WHEN 0 */ + uint16_t S_UP:1; /*!< bit: 13 SELECT UP PATH 0:USBC-1, 1:USBC-2 */ + uint16_t HUB_RESET_N:1; /*!< bit: 14 RESET USB HUB WHEN 0, RUN WHEN 1 */ + uint16_t HUB_CONNECT:1; /*!< bit: 15 SIGNAL VBUS CONNECT TO USB HUB WHEN 1 */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} sr_exp_t; diff --git a/keyboards/massdrop/alt/config_usb.h b/keyboards/massdrop/alt/config_usb.h new file mode 100644 index 00000000000..9f02b12034c --- /dev/null +++ b/keyboards/massdrop/alt/config_usb.h @@ -0,0 +1,28 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +//Macros to Enable, Disable, and Update USB 5V bus connections +#define USBC_CFG_5V1_VAR sr_exp_data.bit.E_VBUS_1 //Variable storing USBC-1 5V Bus state +#define USBC_CFG_5V1_ENA 1 //Value to enable USBC-1 5V Bus +#define USBC_CFG_5V1_DIS 0 //Value to disable USBC-1 5V Bus +#define USBC_CFG_5V1_UPDATE SR_EXP_WriteData() //Command to run to update value +#define USBC_CFG_5V2_VAR sr_exp_data.bit.E_VBUS_2 //Variable storing USBC-2 5V Bus state +#define USBC_CFG_5V2_ENA 1 //Value to enable USBC-1 5V Bus +#define USBC_CFG_5V2_DIS 0 //Value to disable USBC-1 5V Bus +#define USBC_CFG_5V2_UPDATE SR_EXP_WriteData() //Command to run to update value diff --git a/keyboards/massdrop/alt/keymaps/abishalom/keymap.c b/keyboards/massdrop/alt/keymaps/abishalom/keymap.c index a4519d40490..38889c173b4 100644 --- a/keyboards/massdrop/alt/keymaps/abishalom/keymap.c +++ b/keyboards/massdrop/alt/keymaps/abishalom/keymap.c @@ -1,8 +1,7 @@ #include QMK_KEYBOARD_H enum alt_keycodes { - U_T_AUTO = SAFE_RANGE, //USB Extra Port Toggle Auto Detect / Always Active - U_T_AGCR, //USB Toggle Automatic GCR control + U_T_AGCR = SAFE_RANGE, //USB Toggle Automatic GCR control DBG_TOG, //DEBUG Toggle On / Off DBG_MTRX, //DEBUG Toggle Matrix Prints DBG_KBD, //DEBUG Toggle Keyboard Prints @@ -24,7 +23,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ), [1] = LAYOUT( KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_MUTE, \ - _______, RGB_SPD, RGB_VAI, RGB_SPI, RGB_HUI, RGB_SAI, _______, U_T_AUTO,U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_END, \ + _______, RGB_SPD, RGB_VAI, RGB_SPI, RGB_HUI, RGB_SAI, _______, _______, U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_END, \ _______, RGB_RMOD,RGB_VAD, RGB_MOD, RGB_HUD, RGB_SAD, _______, _______, _______, _______, _______, _______, _______, KC_VOLU, \ _______, RGB_TOG, _______, _______, _______, MD_BOOT, TG_NKRO, DBG_TOG, _______, _______, _______, _______, KC_PGUP, KC_VOLD, \ _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_END \ @@ -56,11 +55,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { static uint32_t key_timer; switch (keycode) { - case U_T_AUTO: - if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { - TOGGLE_FLAG_AND_PRINT(usb_extra_manual, "USB extra port manual mode"); - } - return false; case U_T_AGCR: if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); diff --git a/keyboards/massdrop/alt/keymaps/default/keymap.c b/keyboards/massdrop/alt/keymaps/default/keymap.c index a4519d40490..38889c173b4 100644 --- a/keyboards/massdrop/alt/keymaps/default/keymap.c +++ b/keyboards/massdrop/alt/keymaps/default/keymap.c @@ -1,8 +1,7 @@ #include QMK_KEYBOARD_H enum alt_keycodes { - U_T_AUTO = SAFE_RANGE, //USB Extra Port Toggle Auto Detect / Always Active - U_T_AGCR, //USB Toggle Automatic GCR control + U_T_AGCR = SAFE_RANGE, //USB Toggle Automatic GCR control DBG_TOG, //DEBUG Toggle On / Off DBG_MTRX, //DEBUG Toggle Matrix Prints DBG_KBD, //DEBUG Toggle Keyboard Prints @@ -24,7 +23,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ), [1] = LAYOUT( KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_MUTE, \ - _______, RGB_SPD, RGB_VAI, RGB_SPI, RGB_HUI, RGB_SAI, _______, U_T_AUTO,U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_END, \ + _______, RGB_SPD, RGB_VAI, RGB_SPI, RGB_HUI, RGB_SAI, _______, _______, U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_END, \ _______, RGB_RMOD,RGB_VAD, RGB_MOD, RGB_HUD, RGB_SAD, _______, _______, _______, _______, _______, _______, _______, KC_VOLU, \ _______, RGB_TOG, _______, _______, _______, MD_BOOT, TG_NKRO, DBG_TOG, _______, _______, _______, _______, KC_PGUP, KC_VOLD, \ _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_END \ @@ -56,11 +55,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { static uint32_t key_timer; switch (keycode) { - case U_T_AUTO: - if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { - TOGGLE_FLAG_AND_PRINT(usb_extra_manual, "USB extra port manual mode"); - } - return false; case U_T_AGCR: if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); diff --git a/keyboards/massdrop/alt/keymaps/default_md/keymap.c b/keyboards/massdrop/alt/keymaps/default_md/keymap.c index 7969583df4b..1e591f41c81 100644 --- a/keyboards/massdrop/alt/keymaps/default_md/keymap.c +++ b/keyboards/massdrop/alt/keymaps/default_md/keymap.c @@ -1,24 +1,28 @@ #include QMK_KEYBOARD_H enum alt_keycodes { - L_BRI = SAFE_RANGE, //LED Brightness Increase //Working - L_BRD, //LED Brightness Decrease //Working - L_PTN, //LED Pattern Select Next //Working - L_PTP, //LED Pattern Select Previous //Working - L_PSI, //LED Pattern Speed Increase //Working - L_PSD, //LED Pattern Speed Decrease //Working - L_T_MD, //LED Toggle Mode //Working - L_T_ONF, //LED Toggle On / Off //Broken - L_ON, //LED On //Broken - L_OFF, //LED Off //Broken - L_T_BR, //LED Toggle Breath Effect //Working - L_T_PTD, //LED Toggle Scrolling Pattern Direction //Working - U_T_AGCR, //USB Toggle Automatic GCR control //Working - DBG_TOG, //DEBUG Toggle On / Off // - DBG_MTRX, //DEBUG Toggle Matrix Prints // - DBG_KBD, //DEBUG Toggle Keyboard Prints // - DBG_MOU, //DEBUG Toggle Mouse Prints // - MD_BOOT //Restart into bootloader after hold timeout //Working + L_BRI = SAFE_RANGE, //LED Brightness Increase + L_BRD, //LED Brightness Decrease + L_EDG_I, //LED Edge Brightness Increase + L_EDG_D, //LED Edge Brightness Decrease + L_EDG_M, //LED Edge lighting mode + L_PTN, //LED Pattern Select Next + L_PTP, //LED Pattern Select Previous + L_PSI, //LED Pattern Speed Increase + L_PSD, //LED Pattern Speed Decrease + L_T_MD, //LED Toggle Mode + L_T_ONF, //LED Toggle On / Off + L_ON, //LED On + L_OFF, //LED Off + L_T_BR, //LED Toggle Breath Effect + L_T_PTD, //LED Toggle Scrolling Pattern Direction and effect + U_T_AGCR, //USB Toggle Automatic GCR control + DBG_TOG, //DEBUG Toggle On / Off + DBG_MTRX, //DEBUG Toggle Matrix Prints + DBG_KBD, //DEBUG Toggle Keyboard Prints + DBG_MOU, //DEBUG Toggle Mouse Prints + DBG_FAC, //DEBUG Factory light testing (All on white) + MD_BOOT //Restart into bootloader after hold timeout }; #define TG_NKRO MAGIC_TOGGLE_NKRO //Toggle 6KRO / NKRO mode @@ -35,10 +39,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ), [1] = LAYOUT( KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_MUTE, \ - L_T_BR, L_PSD, L_BRI, L_PSI, _______, _______, _______, _______, U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_END, \ - L_T_PTD, L_PTP, L_BRD, L_PTN, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_VOLU, \ - _______, L_T_MD, L_T_ONF, _______, _______, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, KC_PGUP, KC_VOLD, \ - _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_END \ + L_T_BR, L_PSD, L_BRI, L_PSI, L_EDG_I, _______, _______, _______, U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_END, \ + L_T_PTD, L_PTP, L_BRD, L_PTN, L_EDG_D, _______, _______, _______, _______, _______, _______, _______, _______, KC_VOLU, \ + _______, L_T_MD, L_T_ONF, _______, L_EDG_M, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, KC_PGUP, KC_VOLD, \ + _______, _______, _______, DBG_FAC, _______, _______, KC_HOME, KC_PGDN, KC_END \ ), /* [X] = LAYOUT( @@ -59,12 +63,13 @@ void matrix_init_user(void) { void matrix_scan_user(void) { }; -#define MODS_SHIFT (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT)) -#define MODS_CTRL (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL)) -#define MODS_ALT (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT)) +#define MODS_SHIFT (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT)) +#define MODS_CTRL (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL)) +#define MODS_ALT (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT)) bool process_record_user(uint16_t keycode, keyrecord_t *record) { static uint32_t key_timer; + static uint8_t scroll_effect = 0; switch (keycode) { case L_BRI: @@ -81,6 +86,26 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (led_animation_breathing) gcr_breathe = gcr_desired; } return false; + case L_EDG_M: + if (record->event.pressed) { + led_edge_mode++; + if (led_edge_mode > LED_EDGE_MODE_MAX) { + led_edge_mode = LED_EDGE_MODE_ALL; + } + } + return false; + case L_EDG_I: + if (record->event.pressed) { + led_edge_brightness += 0.1; + if (led_edge_brightness > 1) { led_edge_brightness = 1; } + } + return false; + case L_EDG_D: + if (record->event.pressed) { + led_edge_brightness -= 0.1; + if (led_edge_brightness < 0) { led_edge_brightness = 0; } + } + return false; case L_PTN: if (record->event.pressed) { if (led_animation_id == led_setups_count - 1) led_animation_id = 0; @@ -112,20 +137,17 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { return false; case L_T_ONF: if (record->event.pressed) { - led_enabled = !led_enabled; - I2C3733_Control_Set(led_enabled); + I2C3733_Control_Set(!I2C3733_Control_Get()); } return false; case L_ON: if (record->event.pressed) { - led_enabled = 1; - I2C3733_Control_Set(led_enabled); + I2C3733_Control_Set(1); } return false; case L_OFF: if (record->event.pressed) { - led_enabled = 0; - I2C3733_Control_Set(led_enabled); + I2C3733_Control_Set(1); } return false; case L_T_BR: @@ -140,7 +162,33 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { return false; case L_T_PTD: if (record->event.pressed) { - led_animation_direction = !led_animation_direction; + scroll_effect++; + if (scroll_effect == 1) { //Patterns with scroll move horizontal (Right to left) + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 0; + } else if (scroll_effect == 2) { //Patterns with scroll move vertical (Top to bottom) + led_animation_direction = 1; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 3) { //Patterns with scroll move vertical (Bottom to top) + led_animation_direction = 0; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 4) { //Patterns with scroll explode from center + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 1; + } else if (scroll_effect == 5) { //Patterns with scroll implode on center + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 1; + } else { //Patterns with scroll move horizontal (Left to right) + scroll_effect = 0; + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 0; + } } return false; case U_T_AGCR: @@ -148,6 +196,17 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); } return false; + case DBG_FAC: + if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { + led_lighting_mode = LED_MODE_NORMAL; + led_edge_brightness = 1; + led_edge_mode = LED_EDGE_MODE_ALL; + led_animation_breathing = 0; + led_animation_id = 7; //led_programs.c led_setups leds_white index + gcr_desired = LED_GCR_MAX; + I2C3733_Control_Set(1); + } + return false; case DBG_TOG: if (record->event.pressed) { TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode"); diff --git a/keyboards/massdrop/alt/keymaps/mac/keymap.c b/keyboards/massdrop/alt/keymaps/mac/keymap.c index 26a1c6d0148..e7d876a959e 100644 --- a/keyboards/massdrop/alt/keymaps/mac/keymap.c +++ b/keyboards/massdrop/alt/keymaps/mac/keymap.c @@ -1,8 +1,7 @@ #include QMK_KEYBOARD_H enum alt_keycodes { - U_T_AUTO = SAFE_RANGE, //USB Extra Port Toggle Auto Detect / Always Active - U_T_AGCR, //USB Toggle Automatic GCR control + U_T_AGCR = SAFE_RANGE, //USB Toggle Automatic GCR control DBG_TOG, //DEBUG Toggle On / Off DBG_MTRX, //DEBUG Toggle Matrix Prints DBG_KBD, //DEBUG Toggle Keyboard Prints @@ -24,7 +23,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ), [1] = LAYOUT( KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_MUTE, \ - _______, RGB_SPD, RGB_VAI, RGB_SPI, RGB_HUI, RGB_SAI, _______, U_T_AUTO,U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_END, \ + _______, RGB_SPD, RGB_VAI, RGB_SPI, RGB_HUI, RGB_SAI, _______, _______, U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_END, \ _______, RGB_RMOD,RGB_VAD, RGB_MOD, RGB_HUD, RGB_SAD, _______, _______, _______, _______, _______, _______, _______, KC_VOLU, \ _______, RGB_TOG, _______, _______, _______, MD_BOOT, TG_NKRO, DBG_TOG, _______, _______, _______, _______, KC_PGUP, KC_VOLD, \ _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_END \ @@ -56,11 +55,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { static uint32_t key_timer; switch (keycode) { - case U_T_AUTO: - if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { - TOGGLE_FLAG_AND_PRINT(usb_extra_manual, "USB extra port manual mode"); - } - return false; case U_T_AGCR: if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); diff --git a/keyboards/massdrop/alt/keymaps/mac_md/keymap.c b/keyboards/massdrop/alt/keymaps/mac_md/keymap.c index 8a052cc250e..4f9131ee698 100644 --- a/keyboards/massdrop/alt/keymaps/mac_md/keymap.c +++ b/keyboards/massdrop/alt/keymaps/mac_md/keymap.c @@ -1,24 +1,28 @@ #include QMK_KEYBOARD_H enum alt_keycodes { - L_BRI = SAFE_RANGE, //LED Brightness Increase //Working - L_BRD, //LED Brightness Decrease //Working - L_PTN, //LED Pattern Select Next //Working - L_PTP, //LED Pattern Select Previous //Working - L_PSI, //LED Pattern Speed Increase //Working - L_PSD, //LED Pattern Speed Decrease //Working - L_T_MD, //LED Toggle Mode //Working - L_T_ONF, //LED Toggle On / Off //Broken - L_ON, //LED On //Broken - L_OFF, //LED Off //Broken - L_T_BR, //LED Toggle Breath Effect //Working - L_T_PTD, //LED Toggle Scrolling Pattern Direction //Working - U_T_AGCR, //USB Toggle Automatic GCR control //Working - DBG_TOG, //DEBUG Toggle On / Off // - DBG_MTRX, //DEBUG Toggle Matrix Prints // - DBG_KBD, //DEBUG Toggle Keyboard Prints // - DBG_MOU, //DEBUG Toggle Mouse Prints // - MD_BOOT //Restart into bootloader after hold timeout //Working + L_BRI = SAFE_RANGE, //LED Brightness Increase + L_BRD, //LED Brightness Decrease + L_EDG_I, //LED Edge Brightness Increase + L_EDG_D, //LED Edge Brightness Decrease + L_EDG_M, //LED Edge lighting mode + L_PTN, //LED Pattern Select Next + L_PTP, //LED Pattern Select Previous + L_PSI, //LED Pattern Speed Increase + L_PSD, //LED Pattern Speed Decrease + L_T_MD, //LED Toggle Mode + L_T_ONF, //LED Toggle On / Off + L_ON, //LED On + L_OFF, //LED Off + L_T_BR, //LED Toggle Breath Effect + L_T_PTD, //LED Toggle Scrolling Pattern Direction and effect + U_T_AGCR, //USB Toggle Automatic GCR control + DBG_TOG, //DEBUG Toggle On / Off + DBG_MTRX, //DEBUG Toggle Matrix Prints + DBG_KBD, //DEBUG Toggle Keyboard Prints + DBG_MOU, //DEBUG Toggle Mouse Prints + DBG_FAC, //DEBUG Factory light testing (All on white) + MD_BOOT //Restart into bootloader after hold timeout }; #define TG_NKRO MAGIC_TOGGLE_NKRO //Toggle 6KRO / NKRO mode @@ -35,10 +39,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ), [1] = LAYOUT( KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_MUTE, \ - L_T_BR, L_PSD, L_BRI, L_PSI, _______, _______, _______, _______, U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_END, \ - L_T_PTD, L_PTP, L_BRD, L_PTN, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_VOLU, \ - _______, L_T_MD, L_T_ONF, _______, _______, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, KC_PGUP, KC_VOLD, \ - _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_END \ + L_T_BR, L_PSD, L_BRI, L_PSI, L_EDG_I, _______, _______, _______, U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_END, \ + L_T_PTD, L_PTP, L_BRD, L_PTN, L_EDG_D, _______, _______, _______, _______, _______, _______, _______, _______, KC_VOLU, \ + _______, L_T_MD, L_T_ONF, _______, L_EDG_M, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, KC_PGUP, KC_VOLD, \ + _______, _______, _______, DBG_FAC, _______, _______, KC_HOME, KC_PGDN, KC_END \ ), /* [X] = LAYOUT( @@ -59,12 +63,13 @@ void matrix_init_user(void) { void matrix_scan_user(void) { }; -#define MODS_SHIFT (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT)) -#define MODS_CTRL (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL)) -#define MODS_ALT (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT)) +#define MODS_SHIFT (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT)) +#define MODS_CTRL (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL)) +#define MODS_ALT (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT)) bool process_record_user(uint16_t keycode, keyrecord_t *record) { static uint32_t key_timer; + static uint8_t scroll_effect = 0; switch (keycode) { case L_BRI: @@ -81,6 +86,26 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (led_animation_breathing) gcr_breathe = gcr_desired; } return false; + case L_EDG_M: + if (record->event.pressed) { + led_edge_mode++; + if (led_edge_mode > LED_EDGE_MODE_MAX) { + led_edge_mode = LED_EDGE_MODE_ALL; + } + } + return false; + case L_EDG_I: + if (record->event.pressed) { + led_edge_brightness += 0.1; + if (led_edge_brightness > 1) { led_edge_brightness = 1; } + } + return false; + case L_EDG_D: + if (record->event.pressed) { + led_edge_brightness -= 0.1; + if (led_edge_brightness < 0) { led_edge_brightness = 0; } + } + return false; case L_PTN: if (record->event.pressed) { if (led_animation_id == led_setups_count - 1) led_animation_id = 0; @@ -112,20 +137,17 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { return false; case L_T_ONF: if (record->event.pressed) { - led_enabled = !led_enabled; - I2C3733_Control_Set(led_enabled); + I2C3733_Control_Set(!I2C3733_Control_Get()); } return false; case L_ON: if (record->event.pressed) { - led_enabled = 1; - I2C3733_Control_Set(led_enabled); + I2C3733_Control_Set(1); } return false; case L_OFF: if (record->event.pressed) { - led_enabled = 0; - I2C3733_Control_Set(led_enabled); + I2C3733_Control_Set(1); } return false; case L_T_BR: @@ -140,7 +162,33 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { return false; case L_T_PTD: if (record->event.pressed) { - led_animation_direction = !led_animation_direction; + scroll_effect++; + if (scroll_effect == 1) { //Patterns with scroll move horizontal (Right to left) + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 0; + } else if (scroll_effect == 2) { //Patterns with scroll move vertical (Top to bottom) + led_animation_direction = 1; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 3) { //Patterns with scroll move vertical (Bottom to top) + led_animation_direction = 0; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 4) { //Patterns with scroll explode from center + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 1; + } else if (scroll_effect == 5) { //Patterns with scroll implode on center + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 1; + } else { //Patterns with scroll move horizontal (Left to right) + scroll_effect = 0; + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 0; + } } return false; case U_T_AGCR: @@ -148,6 +196,17 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); } return false; + case DBG_FAC: + if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { + led_lighting_mode = LED_MODE_NORMAL; + led_edge_brightness = 1; + led_edge_mode = LED_EDGE_MODE_ALL; + led_animation_breathing = 0; + led_animation_id = 7; //led_programs.c led_setups leds_white index + gcr_desired = LED_GCR_MAX; + I2C3733_Control_Set(1); + } + return false; case DBG_TOG: if (record->event.pressed) { TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode"); diff --git a/keyboards/massdrop/alt/keymaps/reywood/keymap.c b/keyboards/massdrop/alt/keymaps/reywood/keymap.c index cf60acfe66c..da0c3cf5366 100644 --- a/keyboards/massdrop/alt/keymaps/reywood/keymap.c +++ b/keyboards/massdrop/alt/keymaps/reywood/keymap.c @@ -14,7 +14,6 @@ enum alt_keycodes { L_OFF, //LED Off L_T_BR, //LED Toggle Breath Effect L_T_PTD, //LED Toggle Scrolling Pattern Direction - U_T_AUTO, //USB Extra Port Toggle Auto Detect / Always Active U_T_AGCR, //USB Toggle Automatic GCR control DBG_TOG, //DEBUG Toggle On / Off DBG_MTRX, //DEBUG Toggle Matrix Prints @@ -38,7 +37,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ), [1] = LAYOUT( KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_MUTE, \ - _______, _______, _______, KC_UP, _______, _______, _______, U_T_AUTO,U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_END, \ + _______, _______, _______, KC_UP, _______, _______, _______, _______, U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_END, \ _______, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, KC_VOLU, _______, \ _______, _______, _______, KC_MPLY, MO(2), _______, KC_MRWD, KC_VOLD, KC_MFFD \ @@ -146,11 +145,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { led_animation_direction = !led_animation_direction; } return false; - case U_T_AUTO: - if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { - TOGGLE_FLAG_AND_PRINT(usb_extra_manual, "USB extra port manual mode"); - } - return false; case U_T_AGCR: if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); diff --git a/keyboards/massdrop/alt/matrix.c b/keyboards/massdrop/alt/matrix.c index 472479d303a..2971b905a1d 100644 --- a/keyboards/massdrop/alt/matrix.c +++ b/keyboards/massdrop/alt/matrix.c @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,6 +22,8 @@ along with this program. If not, see . #include "clks.h" #include +#define MCU_PORTS_USED 2 //PA, PB + matrix_row_t mlatest[MATRIX_ROWS]; matrix_row_t mlast[MATRIX_ROWS]; matrix_row_t mdebounced[MATRIX_ROWS]; @@ -30,7 +32,7 @@ uint8_t row_ports[] = { MATRIX_ROW_PORTS }; uint8_t row_pins[] = { MATRIX_ROW_PINS }; uint8_t col_ports[] = { MATRIX_COL_PORTS }; uint8_t col_pins[] = { MATRIX_COL_PINS }; -uint32_t row_masks[2]; //NOTE: If more than PA PB used in the future, adjust code to accomodate +uint32_t row_masks[MCU_PORTS_USED]; //Array size must match number of unique MCU ports used for reads (PA, PB, PC, etc) __attribute__ ((weak)) void matrix_init_kb(void) { @@ -56,9 +58,9 @@ void matrix_init(void) memset(mlast, 0, MATRIX_ROWS * sizeof(matrix_row_t)); memset(mdebounced, 0, MATRIX_ROWS * sizeof(matrix_row_t)); - row_masks[PA] = 0; - row_masks[PB] = 0; + memset(row_masks, 0, sizeof(row_masks)); + //Inputs uint8_t row; for (row = 0; row < MATRIX_ROWS; row++) { @@ -69,6 +71,7 @@ void matrix_init(void) row_masks[row_ports[row]] |= 1 << row_pins[row]; //Add pin to proper row mask } + //Outputs uint8_t col; for (col = 0; col < MATRIX_COLS; col++) { @@ -85,7 +88,7 @@ uint8_t matrix_scan(void) uint8_t mchanged; uint8_t row; uint8_t col; - uint32_t scans[2]; //PA PB + uint32_t scans[MCU_PORTS_USED]; //Array size must match number of unique MCU ports used for reads (PA, PB, PC, etc) if (timer_read64() < mdebouncing) return 1; //mdebouncing == 0 when no debouncing active @@ -93,14 +96,16 @@ uint8_t matrix_scan(void) for (col = 0; col < MATRIX_COLS; col++) { - PORT->Group[col_ports[col]].OUTSET.reg = 1 << col_pins[col]; //Set col output + //Set output + PORT->Group[col_ports[col]].OUTSET.reg = 1 << col_pins[col]; //Set col output + wait_us(1); //Delay for output - wait_us(1); //Delay for output + //Read input (add unique ports as needed, PA, PB, PC, etc) + scans[PA] = PORT->Group[PA].IN.reg & row_masks[PA]; //Read PA row pins data + scans[PB] = PORT->Group[PB].IN.reg & row_masks[PB]; //Read PA row pins data - scans[PA] = PORT->Group[PA].IN.reg & row_masks[PA]; //Read PA row pins data - scans[PB] = PORT->Group[PB].IN.reg & row_masks[PB]; //Read PB row pins data - - PORT->Group[col_ports[col]].OUTCLR.reg = 1 << col_pins[col]; //Clear col output + //Clear output + PORT->Group[col_ports[col]].OUTCLR.reg = 1 << col_pins[col]; //Clear col output for (row = 0; row < MATRIX_ROWS; row++) { diff --git a/keyboards/massdrop/alt/rules.mk b/keyboards/massdrop/alt/rules.mk index aa45c68056d..e63b9aacd40 100644 --- a/keyboards/massdrop/alt/rules.mk +++ b/keyboards/massdrop/alt/rules.mk @@ -1,6 +1,8 @@ # project specific files SRC = matrix.c SRC += config_led.c +SRC += spi.c +SRC += usb.c #For platform and packs ARM_ATSAM = SAMD51J18A diff --git a/keyboards/massdrop/alt/spi.c b/keyboards/massdrop/alt/spi.c new file mode 100644 index 00000000000..0b979ed7990 --- /dev/null +++ b/keyboards/massdrop/alt/spi.c @@ -0,0 +1,57 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "arm_atsam_protocol.h" + +void SR_EXP_Init_kb(void) { + /* Initialize shift register */ + SR_EXP_OE_N_DIS; + SR_EXP_RCLK_HI; + + SR_EXP_SERCOM->SPI.CTRLA.bit.DORD = 1; //Data Order - LSB is transferred first + SR_EXP_SERCOM->SPI.CTRLA.bit.CPOL = 1; //Clock Polarity - SCK high when idle. Leading edge of cycle is falling. Trailing rising. + SR_EXP_SERCOM->SPI.CTRLA.bit.CPHA = 1; //Clock Phase - Leading Edge Falling, change, Trailing Edge - Rising, sample + SR_EXP_SERCOM->SPI.CTRLA.bit.DIPO = 3; //Data In Pinout - SERCOM PAD[3] is used as data input (Configure away from DOPO. Not using input.) + SR_EXP_SERCOM->SPI.CTRLA.bit.DOPO = 0; //Data Output PAD[0], Serial Clock PAD[1] + SR_EXP_SERCOM->SPI.CTRLA.bit.MODE = 3; //Operating Mode - Master operation + + SR_EXP_SERCOM->SPI.CTRLA.bit.ENABLE = 1; //Enable - Peripheral is enabled or being enabled + while (SR_EXP_SERCOM->SPI.SYNCBUSY.bit.ENABLE) { DBGC(DC_SPI_EXP_SYNC_ENABLING); } + + /* Set default shift register values */ + sr_exp_data.reg = 0; //Clear data register + sr_exp_data.bit.HUB_CONNECT = 0; //USB Hub disconnected + sr_exp_data.bit.HUB_RESET_N = 0; //USB Hub in reset state + + sr_exp_data.bit.SRC_1 = 1; //Set CON1 CC A5/B5 as Rd 5.1k + sr_exp_data.bit.SRC_2 = 1; //Set CON2 CC A5/B5 as Rd 5.1k + sr_exp_data.bit.S_UP = 0; //Default USB data to CON1 + sr_exp_data.bit.E_UP_N = 1; //Disable HOST + sr_exp_data.bit.S_DN1 = 1; //Default EXTRA port to CON2 + sr_exp_data.bit.E_DN1_N = 1; //Disable EXTRA + + sr_exp_data.bit.E_VBUS_1 = 0; //Disable CON1 5V + sr_exp_data.bit.E_VBUS_2 = 0; //Disable CON2 5V + sr_exp_data.bit.IRST = 1; //LED drivers I2C in reset + sr_exp_data.bit.SDB_N = 0; //LED drivers in shutdown + + /* Write shift register data */ + SR_EXP_WriteData(); + + /* Enable shift register output */ + SR_EXP_OE_N_ENA; +} diff --git a/keyboards/massdrop/alt/usb.c b/keyboards/massdrop/alt/usb.c new file mode 100644 index 00000000000..760df9347fe --- /dev/null +++ b/keyboards/massdrop/alt/usb.c @@ -0,0 +1,83 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "arm_atsam_protocol.h" + +//Note: rp_best_index not used +void usb_set_host_kb(uint8_t con, uint8_t rp_best_index) { + if (con == 1) { + sr_exp_data.bit.S_UP = 0; //HOST to USBC-1 + sr_exp_data.bit.S_DN1 = 1; //EXTRA to USBC-2 + g_usb_host_port = USB_HOST_PORT_1; //Save host port + sr_exp_data.bit.E_VBUS_1 = 1; //Enable CON1 5V + SR_EXP_WriteData(); //Update port configuration + } else if (con == 2) { + sr_exp_data.bit.S_DN1 = 0; //HOST to USBC-2 + sr_exp_data.bit.S_UP = 1; //EXTRA to USBC-1 + g_usb_host_port = USB_HOST_PORT_2; //Save host port + sr_exp_data.bit.E_VBUS_2 = 1; //Enable CON2 5V + SR_EXP_WriteData(); //Update port configuration + } +} + +void usb_set_extra_kb(uint8_t con) { + if (con == 1) { + sr_exp_data.bit.SRC_1 = 0; //Set CON1 CC A5/B5 as Rp 56k + sr_exp_data.bit.E_VBUS_1 = 0; //Disable CON1 5V + SR_EXP_WriteData(); //Update port configuration + } else if (con == 2) { + sr_exp_data.bit.SRC_2 = 0; //Set CON2 CC A5/B5 as Rp 56k + sr_exp_data.bit.E_VBUS_2 = 0; //Disable CON2 5V + SR_EXP_WriteData(); //Update port configuration + } +} + +void usb_init_host_detection_kb(void) { + //Disable 5V + sr_exp_data.bit.E_VBUS_1 = 0; //Disable CON1 5V + sr_exp_data.bit.E_VBUS_2 = 0; //Disable CON2 5V + + //Configure default paths + sr_exp_data.bit.S_UP = 0; //HOST to USBC-1 + sr_exp_data.bit.S_DN1 = 1; //EXTRA to USBC-2 + + //Configure CC lines + sr_exp_data.bit.SRC_1 = 1; //Set CON1 CC A5/B5 as Rd 5.1k + sr_exp_data.bit.SRC_2 = 1; //Set CON2 CC A5/B5 as Rd 5.1k + + //Enable ports + sr_exp_data.bit.E_UP_N = 0; //Enable HOST for use + sr_exp_data.bit.E_DN1_N = 0; //Enable EXTRA for use + + SR_EXP_WriteData(); //Update port configuration +} + +//Return 1 if configuration successful +//Return 0 otherwise +uint8_t usb_attach_port_configure_kb(uint8_t g_usb_host_port, uint16_t usbc_cc_a5_v, uint16_t usbc_cc_b5_v) { + if (USB_HOST_IS_1(g_usb_host_port)) { //If host is port 1 + //Set up port 2 + usb_set_extra_kb(2); + return 1; + } else if (USB_HOST_IS_2(g_usb_host_port)) { //If host is on port 2 + //Set up port 1 + usb_set_extra_kb(1); + return 1; + } + + return 0; +} diff --git a/keyboards/massdrop/ctrl/config.h b/keyboards/massdrop/ctrl/config.h index df2e5092163..e342c7a4f02 100644 --- a/keyboards/massdrop/ctrl/config.h +++ b/keyboards/massdrop/ctrl/config.h @@ -54,7 +54,7 @@ along with this program. If not, see . #define SR_EXP_OE_N_PIN 15 /* SERCOM port to use for Shift Register SPI */ /* DATAOUT and SCLK must be configured to use hardware pins of this port */ -#define SR_EXP_SERCOM SERCOM2 +#define SR_EXP_SERCOM_NUM 2 /* Shift Register SPI Data Out configuration (MCU.SERCOMx.PAD[0] to ShiftRegister.SER) */ #define SR_EXP_DATAOUT_PORT PA #define SR_EXP_DATAOUT_PIN 12 diff --git a/keyboards/massdrop/ctrl/config_adc.h b/keyboards/massdrop/ctrl/config_adc.h new file mode 100644 index 00000000000..07c74746fad --- /dev/null +++ b/keyboards/massdrop/ctrl/config_adc.h @@ -0,0 +1,75 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +//ADC configuration table column indices +#define ADC_PORT 0 +#define ADC_PIN 1 +#define ADC_MUX 2 +#define ADC_INDEX 3 +#define ADC_MUXPOS 4 +#define ADC_REFSEL 5 +#define ADC_SAMPLENUM 6 +#define ADC_SAMPLEN 7 + +//ADC configuration table row indices +#define ADC_5V 0 //5V bus voltage +#define ADC_C1A5 1 //Connector 1 A5 CC voltage +#define ADC_C1B5 2 //Connector 1 B5 CC voltage +#define ADC_C2A5 3 //Connector 2 A5 CC voltage +#define ADC_C2B5 4 //Connector 2 B5 CC voltage +#define ADC_C1I 5 //Connector 1 current +#define ADC_C2I 6 //Connector 2 current + +//ADC_PORT: PORT of the PIN on the MCU (Ex: 0 = PA, 1 = PB, ...) +// Set ADC_PORT to ADC_NA if it is not available for use +//ADC_PIN: PIN on the MCU (Ex: 0 = 00, 1 = 01, 12 = 12, ...) +//ADC_MUX: PMUX setting for the MCU PIN (Ex: 0 = A, 1 = B, 2 = C, ...) +//ADC_INDEX: ADC to use (Ex: 0 = ADC0, 1 = ADC1, ...) +//ADC_MUXPOS: MUXPOS setting to read on the ADC (Use macros from Atmel library adc.h ADC_INPUTCTRL_MUXPOS_AIN*_Val) +//ADC_REFSEL: Reference the ADC is to use (Use macros from Atmel library adc.h ADC_REFCTRL_REFSEL_*_Val) +//ADC_SAMPLENUM: Number of samples to average for output (Use macros from Atmel library adc.h ADC_AVGCTRL_SAMPLENUM_*_Val) +//ADC_SAMPLEN: Sampling time for each sample in units of CLK_ADC cycles depending on the ADC clock frequency +// ADC_PORT ADC_MUX +// | ADC_PIN | ADC_INDEX +// | | | | ADC_MUXPOS ADC_REFSEL ADC_SAMPLENUM ADC_SAMPLEN +#define ADC_CONFIG_5V 1, 0, 1, 0, ADC_INPUTCTRL_MUXPOS_AIN12_Val, ADC_REFCTRL_REFSEL_INTREF_Val, ADC_AVGCTRL_SAMPLENUM_4_Val, 45 +#define ADC_CONFIG_C1A5 1, 2, 1, 0, ADC_INPUTCTRL_MUXPOS_AIN14_Val, ADC_REFCTRL_REFSEL_INTREF_Val, ADC_AVGCTRL_SAMPLENUM_16_Val, 63 +#define ADC_CONFIG_C1B5 ADC_NA, 0, 0, 0, 0, 0, 0, 0 +#define ADC_CONFIG_C2A5 1, 1, 1, 0, ADC_INPUTCTRL_MUXPOS_AIN13_Val, ADC_REFCTRL_REFSEL_INTREF_Val, ADC_AVGCTRL_SAMPLENUM_16_Val, 63 +#define ADC_CONFIG_C2B5 ADC_NA, 0, 0, 0, 0, 0, 0, 0 +#define ADC_CONFIG_C1I ADC_NA, 0, 0, 0, 0, 0, 0, 0 +#define ADC_CONFIG_C2I ADC_NA, 0, 0, 0, 0, 0, 0, 0 + +//Conversion values dependant upon the circuitry +#define ADC_5V_VOLTS_PER_COUNT 0.001904297f +#define ADC_5V_VOLTS_OFFSET 0.0f +#define ADC_5V_NOMINAL 5.0f +#define ADC_5V_NOMINAL_COUNTS (ADC_5V_NOMINAL / ADC_5V_VOLTS_PER_COUNT) + +//Conversion macros +#define ADC_5V_C2V(icounts) ((float)icounts * ADC_5V_VOLTS_PER_COUNT + ADC_5V_VOLTS_OFFSET) //Converts 5V Bus counts to volts +#define ADC_5V_V2C(v) (((float)v - ADC_5V_VOLTS_OFFSET) / ADC_5V_VOLTS_PER_COUNT) //Converts 5V Bus volts to counts +#define ADC_CC_5VCOR(v5counts, cc) ((float)v5counts == 0 ? 0 : ADC_5V_NOMINAL_COUNTS / (float)v5counts * (float)cc) //Corrects CC counts to nominal 5V value + +#define ADC_USBC_EXTRA_NOMINAL 850 //Nominal ADC value for detection of connected device + +#define USBC_IS_SINK(a5, b5) (a5 < ADC_USBC_EXTRA_NOMINAL || b5 < ADC_USBC_EXTRA_NOMINAL) + +#define POWER_CHECK_INTERVAL 1 //How often to check power usage for adjustment and safety (ms) +#define V_5V_AVGS 50 //Number of 5V readings to average for algorithms wanting stable readings rather than instantaneous diff --git a/keyboards/massdrop/ctrl/config_led.h b/keyboards/massdrop/ctrl/config_led.h index 0c91a0c80ba..713788bf6d3 100644 --- a/keyboards/massdrop/ctrl/config_led.h +++ b/keyboards/massdrop/ctrl/config_led.h @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,11 +17,11 @@ along with this program. If not, see . #pragma once -//Define number of ISSI3733 drivers being used (1...16) +//Define number of IS31FL3733 drivers being used (1...16) #define ISSI3733_DRIVER_COUNT 2 #define DRIVER_LED_TOTAL ISSI3733_LED_COUNT -//Hardware address of each driver (Refer to ISSI3733 pdf "Table 1 Slave Address" and keyboard schematic) +//Hardware address of each driver (Refer to IS31FL3733 pdf "Table 1 Slave Address" and keyboard schematic) #define ISSI3773_DRIVER_ADDRESSES { 0xA0, 0xBE } //LED I2C bus speed @@ -45,9 +45,9 @@ along with this program. If not, see . #define ISSI3733_GCR_DEFAULT LED_GCR_MAX //Automatic power rollback and recovery -#define V5_HIGH 2540 //5V high level (After low power detect, point at which LEDs are allowed to use more power ) -#define V5_LOW 2480 //5V low level (LED power rolled back to stay above this limit) -#define V5_CAT 2200 //5V catastrophic level (Host USB port potential to shut down) +#define V5_HIGH 2494 //5V high level (After low power detect, point at which LEDs are allowed to use more power ) +#define V5_LOW 2434 //5V low level (LED power rolled back to stay above this limit) +#define V5_CAT 2206 //5V catastrophic level (Host USB port potential to shut down) //LED Mapping - More practically generated from a spreadsheet program //id: ID of the LED (Sync with PCB callouts) @@ -58,7 +58,7 @@ along with this program. If not, see . //swr: Matrix wiring SW Red row (1-12) //swg: Matrix wiring SW Green row (1-12) //swb: Matrix wiring SW Blue row (1-12) -//scan: Associated key scancode if any +//scan: Associated key matrix scancode (set 255 if none or 254 for LED to turn off in alternating mode) //Note: Origin 0,0 may be located anywhere as the software will do the final layout #define ISSI3733_LED_MAP { \ { .id = 1, .x = 0, .y = 0, .adr = { .drv = 2, .cs = 2, .swr = 2, .swg = 1, .swb = 3 }, .scan = 0 }, \ @@ -149,37 +149,37 @@ along with this program. If not, see . { .id = 86, .x = 12.375, .y = -4.125, .adr = { .drv = 1, .cs = 12, .swr = 5, .swg = 4, .swb = 6 }, .scan = 85 }, \ { .id = 87, .x = 13.125, .y = -4.125, .adr = { .drv = 1, .cs = 11, .swr = 5, .swg = 4, .swb = 6 }, .scan = 86 }, \ { .id = 88, .x = 13.433, .y = -4.43, .adr = { .drv = 1, .cs = 11, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 89, .x = 12.285, .y = -4.535, .adr = { .drv = 1, .cs = 12, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 89, .x = 12.285, .y = -4.535, .adr = { .drv = 1, .cs = 12, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 90, .x = 11.14, .y = -4.535, .adr = { .drv = 1, .cs = 13, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 91, .x = 9.995, .y = -4.535, .adr = { .drv = 1, .cs = 14, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 91, .x = 9.995, .y = -4.535, .adr = { .drv = 1, .cs = 14, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 92, .x = 8.85, .y = -4.535, .adr = { .drv = 1, .cs = 15, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 93, .x = 7.705, .y = -4.535, .adr = { .drv = 1, .cs = 16, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 93, .x = 7.705, .y = -4.535, .adr = { .drv = 1, .cs = 16, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 94, .x = 6.56, .y = -4.535, .adr = { .drv = 2, .cs = 9, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 95, .x = 5.415, .y = -4.535, .adr = { .drv = 2, .cs = 10, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 95, .x = 5.415, .y = -4.535, .adr = { .drv = 2, .cs = 10, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 96, .x = 4.27, .y = -4.535, .adr = { .drv = 2, .cs = 11, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 97, .x = 3.125, .y = -4.535, .adr = { .drv = 2, .cs = 12, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 97, .x = 3.125, .y = -4.535, .adr = { .drv = 2, .cs = 12, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 98, .x = 1.98, .y = -4.535, .adr = { .drv = 2, .cs = 13, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 99, .x = 0.835, .y = -4.535, .adr = { .drv = 2, .cs = 14, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 99, .x = 0.835, .y = -4.535, .adr = { .drv = 2, .cs = 14, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 100, .x = -0.307, .y = -4.43, .adr = { .drv = 2, .cs = 15, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 101, .x = -0.41, .y = -3.245, .adr = { .drv = 2, .cs = 15, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ + { .id = 101, .x = -0.41, .y = -3.245, .adr = { .drv = 2, .cs = 15, .swr = 11, .swg = 10, .swb = 12 }, .scan = 254 }, \ { .id = 102, .x = -0.41, .y = -2.06, .adr = { .drv = 2, .cs = 15, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ - { .id = 103, .x = -0.41, .y = -0.875, .adr = { .drv = 2, .cs = 15, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 103, .x = -0.41, .y = -0.875, .adr = { .drv = 2, .cs = 15, .swr = 8, .swg = 7, .swb = 9 }, .scan = 254 }, \ { .id = 104, .x = -0.308, .y = 0.31, .adr = { .drv = 2, .cs = 1, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 105, .x = 0.835, .y = 0.415, .adr = { .drv = 2, .cs = 3, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 105, .x = 0.835, .y = 0.415, .adr = { .drv = 2, .cs = 3, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 106, .x = 1.98, .y = 0.415, .adr = { .drv = 2, .cs = 4, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 107, .x = 3.125, .y = 0.415, .adr = { .drv = 2, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 107, .x = 3.125, .y = 0.415, .adr = { .drv = 2, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 108, .x = 4.27, .y = 0.415, .adr = { .drv = 2, .cs = 7, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 109, .x = 5.415, .y = 0.415, .adr = { .drv = 2, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 109, .x = 5.415, .y = 0.415, .adr = { .drv = 2, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 110, .x = 6.56, .y = 0.415, .adr = { .drv = 1, .cs = 1, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 111, .x = 7.705, .y = 0.415, .adr = { .drv = 1, .cs = 2, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 111, .x = 7.705, .y = 0.415, .adr = { .drv = 1, .cs = 2, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 112, .x = 8.85, .y = 0.415, .adr = { .drv = 1, .cs = 3, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 113, .x = 9.995, .y = 0.415, .adr = { .drv = 1, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 113, .x = 9.995, .y = 0.415, .adr = { .drv = 1, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 114, .x = 11.14, .y = 0.415, .adr = { .drv = 1, .cs = 6, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 115, .x = 12.285, .y = 0.415, .adr = { .drv = 1, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 115, .x = 12.285, .y = 0.415, .adr = { .drv = 1, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 116, .x = 13.432, .y = 0.31, .adr = { .drv = 1, .cs = 10, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 117, .x = 13.535, .y = -0.875, .adr = { .drv = 1, .cs = 10, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 117, .x = 13.535, .y = -0.875, .adr = { .drv = 1, .cs = 10, .swr = 8, .swg = 7, .swb = 9 }, .scan = 254 }, \ { .id = 118, .x = 13.535, .y = -2.06, .adr = { .drv = 1, .cs = 10, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ - { .id = 119, .x = 13.535, .y = -3.245, .adr = { .drv = 1, .cs = 10, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 119, .x = 13.535, .y = -3.245, .adr = { .drv = 1, .cs = 10, .swr = 5, .swg = 4, .swb = 6 }, .scan = 254 }, \ }; #define USB_LED_INDICATOR_ENABLE //Comment out to disable indicator functionality diff --git a/keyboards/massdrop/ctrl/config_spi.h b/keyboards/massdrop/ctrl/config_spi.h new file mode 100644 index 00000000000..5bab7bf37d9 --- /dev/null +++ b/keyboards/massdrop/ctrl/config_spi.h @@ -0,0 +1,42 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +/* Data structure to define Shift Register output expander hardware */ +/* This structure gets shifted into registers LSB first */ +typedef union { + struct { + uint16_t RSVD4:1; /*!< bit: 0 */ + uint16_t RSVD3:1; /*!< bit: 1 */ + uint16_t RSVD2:1; /*!< bit: 2 */ + uint16_t RSVD1:1; /*!< bit: 3 */ + uint16_t SDB_N:1; /*!< bit: 4 SHUTDOWN IS31FL3733 CHIPS WHEN 0, RUN WHEN 1 */ + uint16_t IRST:1; /*!< bit: 5 RESET IS31FL3733 I2C WHEN 1, RUN WHEN 0 */ + uint16_t SRC_2:1; /*!< bit: 6 ADVERTISE A SOURCE TO USBC-2 CC */ + uint16_t SRC_1:1; /*!< bit: 7 ADVERTISE A SOURCE TO USBC-1 CC */ + uint16_t E_VBUS_2:1; /*!< bit: 8 ENABLE 5V OUT TO USBC-2 WHEN 1 */ + uint16_t E_VBUS_1:1; /*!< bit: 9 ENABLE 5V OUT TO USBC-1 WHEN 1 */ + uint16_t E_DN1_N:1; /*!< bit: 10 ENABLE DN1 1:2 MUX WHEN 0 */ + uint16_t S_DN1:1; /*!< bit: 11 SELECT DN1 PATH 0:USBC-1, 1:USBC-2 */ + uint16_t E_UP_N:1; /*!< bit: 12 ENABLE SUP 1:2 MUX WHEN 0 */ + uint16_t S_UP:1; /*!< bit: 13 SELECT UP PATH 0:USBC-1, 1:USBC-2 */ + uint16_t HUB_RESET_N:1; /*!< bit: 14 RESET USB HUB WHEN 0, RUN WHEN 1 */ + uint16_t HUB_CONNECT:1; /*!< bit: 15 SIGNAL VBUS CONNECT TO USB HUB WHEN 1 */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} sr_exp_t; diff --git a/keyboards/massdrop/ctrl/config_usb.h b/keyboards/massdrop/ctrl/config_usb.h new file mode 100644 index 00000000000..9f02b12034c --- /dev/null +++ b/keyboards/massdrop/ctrl/config_usb.h @@ -0,0 +1,28 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +//Macros to Enable, Disable, and Update USB 5V bus connections +#define USBC_CFG_5V1_VAR sr_exp_data.bit.E_VBUS_1 //Variable storing USBC-1 5V Bus state +#define USBC_CFG_5V1_ENA 1 //Value to enable USBC-1 5V Bus +#define USBC_CFG_5V1_DIS 0 //Value to disable USBC-1 5V Bus +#define USBC_CFG_5V1_UPDATE SR_EXP_WriteData() //Command to run to update value +#define USBC_CFG_5V2_VAR sr_exp_data.bit.E_VBUS_2 //Variable storing USBC-2 5V Bus state +#define USBC_CFG_5V2_ENA 1 //Value to enable USBC-1 5V Bus +#define USBC_CFG_5V2_DIS 0 //Value to disable USBC-1 5V Bus +#define USBC_CFG_5V2_UPDATE SR_EXP_WriteData() //Command to run to update value diff --git a/keyboards/massdrop/ctrl/keymaps/default/keymap.c b/keyboards/massdrop/ctrl/keymaps/default/keymap.c index 182abbbad4f..83f1610fab9 100644 --- a/keyboards/massdrop/ctrl/keymaps/default/keymap.c +++ b/keyboards/massdrop/ctrl/keymaps/default/keymap.c @@ -1,8 +1,7 @@ #include QMK_KEYBOARD_H enum ctrl_keycodes { - U_T_AUTO = SAFE_RANGE, //USB Extra Port Toggle Auto Detect / Always Active - U_T_AGCR, //USB Toggle Automatic GCR control + U_T_AGCR = SAFE_RANGE, //USB Toggle Automatic GCR control DBG_TOG, //DEBUG Toggle On / Off DBG_MTRX, //DEBUG Toggle Matrix Prints DBG_KBD, //DEBUG Toggle Keyboard Prints @@ -26,7 +25,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [1] = LAYOUT( _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, KC_MSTP, KC_VOLU, \ - _______, RGB_SPD, RGB_VAI, RGB_SPI, RGB_HUI, RGB_SAI, _______, U_T_AUTO,U_T_AGCR,_______, _______, _______, _______, _______, KC_MPRV, KC_MNXT, KC_VOLD, \ + _______, RGB_SPD, RGB_VAI, RGB_SPI, RGB_HUI, RGB_SAI, _______, _______, U_T_AGCR,_______, _______, _______, _______, _______, KC_MPRV, KC_MNXT, KC_VOLD, \ _______, RGB_RMOD,RGB_VAD, RGB_MOD, RGB_HUD, RGB_SAD, _______, _______, _______, _______, _______, _______, _______, \ _______, RGB_TOG, _______, _______, _______, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \ @@ -37,7 +36,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ - _______, _______, _______, _______, _______, _______, TG_NKRO, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \ ), */ @@ -59,11 +58,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { static uint32_t key_timer; switch (keycode) { - case U_T_AUTO: - if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { - TOGGLE_FLAG_AND_PRINT(usb_extra_manual, "USB extra port manual mode"); - } - return false; case U_T_AGCR: if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); diff --git a/keyboards/massdrop/ctrl/keymaps/default_md/keymap.c b/keyboards/massdrop/ctrl/keymaps/default_md/keymap.c index 16f88ffe1dc..d9daec732f0 100644 --- a/keyboards/massdrop/ctrl/keymaps/default_md/keymap.c +++ b/keyboards/massdrop/ctrl/keymaps/default_md/keymap.c @@ -1,24 +1,28 @@ #include QMK_KEYBOARD_H enum ctrl_keycodes { - L_BRI = SAFE_RANGE, //LED Brightness Increase //Working - L_BRD, //LED Brightness Decrease //Working - L_PTN, //LED Pattern Select Next //Working - L_PTP, //LED Pattern Select Previous //Working - L_PSI, //LED Pattern Speed Increase //Working - L_PSD, //LED Pattern Speed Decrease //Working - L_T_MD, //LED Toggle Mode //Working - L_T_ONF, //LED Toggle On / Off //Broken - L_ON, //LED On //Broken - L_OFF, //LED Off //Broken - L_T_BR, //LED Toggle Breath Effect //Working - L_T_PTD, //LED Toggle Scrolling Pattern Direction //Working - U_T_AGCR, //USB Toggle Automatic GCR control //Working - DBG_TOG, //DEBUG Toggle On / Off // - DBG_MTRX, //DEBUG Toggle Matrix Prints // - DBG_KBD, //DEBUG Toggle Keyboard Prints // - DBG_MOU, //DEBUG Toggle Mouse Prints // - MD_BOOT //Restart into bootloader after hold timeout //Working + L_BRI = SAFE_RANGE, //LED Brightness Increase + L_BRD, //LED Brightness Decrease + L_EDG_I, //LED Edge Brightness Increase + L_EDG_D, //LED Edge Brightness Decrease + L_EDG_M, //LED Edge lighting mode + L_PTN, //LED Pattern Select Next + L_PTP, //LED Pattern Select Previous + L_PSI, //LED Pattern Speed Increase + L_PSD, //LED Pattern Speed Decrease + L_T_MD, //LED Toggle Mode + L_T_ONF, //LED Toggle On / Off + L_ON, //LED On + L_OFF, //LED Off + L_T_BR, //LED Toggle Breath Effect + L_T_PTD, //LED Toggle Scrolling Pattern Direction and effect + U_T_AGCR, //USB Toggle Automatic GCR control + DBG_TOG, //DEBUG Toggle On / Off + DBG_MTRX, //DEBUG Toggle Matrix Prints + DBG_KBD, //DEBUG Toggle Keyboard Prints + DBG_MOU, //DEBUG Toggle Mouse Prints + DBG_FAC, //DEBUG Factory light testing (All on white) + MD_BOOT //Restart into bootloader after hold timeout }; #define TG_NKRO MAGIC_TOGGLE_NKRO //Toggle 6KRO / NKRO mode @@ -30,26 +34,26 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SLCK, KC_PAUS, \ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP, \ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN, \ - KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \ - KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, \ - KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT \ + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \ + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, \ + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT \ ), [1] = LAYOUT( _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, KC_MSTP, KC_VOLU, \ - L_T_BR, L_PSD, L_BRI, L_PSI, _______, _______, _______, _______, U_T_AGCR,_______, _______, _______, _______, _______, KC_MPRV, KC_MNXT, KC_VOLD, \ - L_T_PTD, L_PTP, L_BRD, L_PTN, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ - _______, L_T_MD, L_T_ONF, _______, _______, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, _______, \ - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \ + L_T_BR, L_PSD, L_BRI, L_PSI, L_EDG_I, _______, _______, _______, U_T_AGCR,_______, _______, _______, _______, _______, KC_MPRV, KC_MNXT, KC_VOLD, \ + L_T_PTD, L_PTP, L_BRD, L_PTN, L_EDG_D, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, L_T_MD, L_T_ONF, _______, L_EDG_M, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, DBG_FAC, _______, _______, _______, _______, _______, _______, _______ \ ), /* [X] = LAYOUT( _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ - _______, _______, _______, _______, _______, _______, TG_NKRO, _______, _______, _______, _______, _______, _______, \ - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \ ), */ }; @@ -62,12 +66,13 @@ void matrix_init_user(void) { void matrix_scan_user(void) { }; -#define MODS_SHIFT (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT)) -#define MODS_CTRL (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL)) -#define MODS_ALT (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT)) +#define MODS_SHIFT (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT)) +#define MODS_CTRL (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL)) +#define MODS_ALT (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT)) bool process_record_user(uint16_t keycode, keyrecord_t *record) { static uint32_t key_timer; + static uint8_t scroll_effect = 0; switch (keycode) { case L_BRI: @@ -84,6 +89,26 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (led_animation_breathing) gcr_breathe = gcr_desired; } return false; + case L_EDG_M: + if (record->event.pressed) { + led_edge_mode++; + if (led_edge_mode > LED_EDGE_MODE_MAX) { + led_edge_mode = LED_EDGE_MODE_ALL; + } + } + return false; + case L_EDG_I: + if (record->event.pressed) { + led_edge_brightness += 0.1; + if (led_edge_brightness > 1) { led_edge_brightness = 1; } + } + return false; + case L_EDG_D: + if (record->event.pressed) { + led_edge_brightness -= 0.1; + if (led_edge_brightness < 0) { led_edge_brightness = 0; } + } + return false; case L_PTN: if (record->event.pressed) { if (led_animation_id == led_setups_count - 1) led_animation_id = 0; @@ -115,20 +140,17 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { return false; case L_T_ONF: if (record->event.pressed) { - led_enabled = !led_enabled; - I2C3733_Control_Set(led_enabled); + I2C3733_Control_Set(!I2C3733_Control_Get()); } return false; case L_ON: if (record->event.pressed) { - led_enabled = 1; - I2C3733_Control_Set(led_enabled); + I2C3733_Control_Set(1); } return false; case L_OFF: if (record->event.pressed) { - led_enabled = 0; - I2C3733_Control_Set(led_enabled); + I2C3733_Control_Set(1); } return false; case L_T_BR: @@ -143,7 +165,33 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { return false; case L_T_PTD: if (record->event.pressed) { - led_animation_direction = !led_animation_direction; + scroll_effect++; + if (scroll_effect == 1) { //Patterns with scroll move horizontal (Right to left) + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 0; + } else if (scroll_effect == 2) { //Patterns with scroll move vertical (Top to bottom) + led_animation_direction = 1; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 3) { //Patterns with scroll move vertical (Bottom to top) + led_animation_direction = 0; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 4) { //Patterns with scroll explode from center + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 1; + } else if (scroll_effect == 5) { //Patterns with scroll implode on center + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 1; + } else { //Patterns with scroll move horizontal (Left to right) + scroll_effect = 0; + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 0; + } } return false; case U_T_AGCR: @@ -151,6 +199,17 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); } return false; + case DBG_FAC: + if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { + led_lighting_mode = LED_MODE_NORMAL; + led_edge_brightness = 1; + led_edge_mode = LED_EDGE_MODE_ALL; + led_animation_breathing = 0; + led_animation_id = 7; //led_programs.c led_setups leds_white index + gcr_desired = LED_GCR_MAX; + I2C3733_Control_Set(1); + } + return false; case DBG_TOG: if (record->event.pressed) { TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode"); diff --git a/keyboards/massdrop/ctrl/keymaps/mac/keymap.c b/keyboards/massdrop/ctrl/keymaps/mac/keymap.c index 41cf8275724..5cbacea1717 100644 --- a/keyboards/massdrop/ctrl/keymaps/mac/keymap.c +++ b/keyboards/massdrop/ctrl/keymaps/mac/keymap.c @@ -1,8 +1,7 @@ #include QMK_KEYBOARD_H enum ctrl_keycodes { - U_T_AUTO = SAFE_RANGE, //USB Extra Port Toggle Auto Detect / Always Active - U_T_AGCR, //USB Toggle Automatic GCR control + U_T_AGCR = SAFE_RANGE, //USB Toggle Automatic GCR control DBG_TOG, //DEBUG Toggle On / Off DBG_MTRX, //DEBUG Toggle Matrix Prints DBG_KBD, //DEBUG Toggle Keyboard Prints @@ -26,7 +25,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [1] = LAYOUT( _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, KC_MSTP, KC_VOLU, \ - _______, RGB_SPD, RGB_VAI, RGB_SPI, RGB_HUI, RGB_SAI, _______, U_T_AUTO,U_T_AGCR,_______, _______, _______, _______, _______, KC_MPRV, KC_MNXT, KC_VOLD, \ + _______, RGB_SPD, RGB_VAI, RGB_SPI, RGB_HUI, RGB_SAI, _______, _______, U_T_AGCR,_______, _______, _______, _______, _______, KC_MPRV, KC_MNXT, KC_VOLD, \ _______, RGB_RMOD,RGB_VAD, RGB_MOD, RGB_HUD, RGB_SAD, _______, _______, _______, _______, _______, _______, _______, \ _______, RGB_TOG, _______, _______, _______, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \ @@ -37,7 +36,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ - _______, _______, _______, _______, _______, _______, TG_NKRO, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \ ), */ @@ -59,11 +58,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { static uint32_t key_timer; switch (keycode) { - case U_T_AUTO: - if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { - TOGGLE_FLAG_AND_PRINT(usb_extra_manual, "USB extra port manual mode"); - } - return false; case U_T_AGCR: if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); diff --git a/keyboards/massdrop/ctrl/keymaps/mac_md/keymap.c b/keyboards/massdrop/ctrl/keymaps/mac_md/keymap.c index 6dfc2137862..62e44ae0c31 100644 --- a/keyboards/massdrop/ctrl/keymaps/mac_md/keymap.c +++ b/keyboards/massdrop/ctrl/keymaps/mac_md/keymap.c @@ -1,24 +1,28 @@ #include QMK_KEYBOARD_H enum ctrl_keycodes { - L_BRI = SAFE_RANGE, //LED Brightness Increase //Working - L_BRD, //LED Brightness Decrease //Working - L_PTN, //LED Pattern Select Next //Working - L_PTP, //LED Pattern Select Previous //Working - L_PSI, //LED Pattern Speed Increase //Working - L_PSD, //LED Pattern Speed Decrease //Working - L_T_MD, //LED Toggle Mode //Working - L_T_ONF, //LED Toggle On / Off //Broken - L_ON, //LED On //Broken - L_OFF, //LED Off //Broken - L_T_BR, //LED Toggle Breath Effect //Working - L_T_PTD, //LED Toggle Scrolling Pattern Direction //Working - U_T_AGCR, //USB Toggle Automatic GCR control //Working - DBG_TOG, //DEBUG Toggle On / Off // - DBG_MTRX, //DEBUG Toggle Matrix Prints // - DBG_KBD, //DEBUG Toggle Keyboard Prints // - DBG_MOU, //DEBUG Toggle Mouse Prints // - MD_BOOT //Restart into bootloader after hold timeout //Working + L_BRI = SAFE_RANGE, //LED Brightness Increase + L_BRD, //LED Brightness Decrease + L_EDG_I, //LED Edge Brightness Increase + L_EDG_D, //LED Edge Brightness Decrease + L_EDG_M, //LED Edge lighting mode + L_PTN, //LED Pattern Select Next + L_PTP, //LED Pattern Select Previous + L_PSI, //LED Pattern Speed Increase + L_PSD, //LED Pattern Speed Decrease + L_T_MD, //LED Toggle Mode + L_T_ONF, //LED Toggle On / Off + L_ON, //LED On + L_OFF, //LED Off + L_T_BR, //LED Toggle Breath Effect + L_T_PTD, //LED Toggle Scrolling Pattern Direction and effect + U_T_AGCR, //USB Toggle Automatic GCR control + DBG_TOG, //DEBUG Toggle On / Off + DBG_MTRX, //DEBUG Toggle Matrix Prints + DBG_KBD, //DEBUG Toggle Keyboard Prints + DBG_MOU, //DEBUG Toggle Mouse Prints + DBG_FAC, //DEBUG Factory light testing (All on white) + MD_BOOT //Restart into bootloader after hold timeout }; #define TG_NKRO MAGIC_TOGGLE_NKRO //Toggle 6KRO / NKRO mode @@ -30,26 +34,26 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SLCK, KC_PAUS, \ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP, \ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN, \ - KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \ - KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, \ - KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RGUI, MO(1), KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT \ + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \ + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, \ + KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RGUI, MO(1), KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT \ ), [1] = LAYOUT( _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, KC_MSTP, KC_VOLU, \ - L_T_BR, L_PSD, L_BRI, L_PSI, _______, _______, _______, _______, U_T_AGCR,_______, _______, _______, _______, _______, KC_MPRV, KC_MNXT, KC_VOLD, \ - L_T_PTD, L_PTP, L_BRD, L_PTN, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ - _______, L_T_MD, L_T_ONF, _______, _______, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, _______, \ - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \ + L_T_BR, L_PSD, L_BRI, L_PSI, L_EDG_I, _______, _______, _______, U_T_AGCR,_______, _______, _______, _______, _______, KC_MPRV, KC_MNXT, KC_VOLD, \ + L_T_PTD, L_PTP, L_BRD, L_PTN, L_EDG_D, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, L_T_MD, L_T_ONF, _______, L_EDG_M, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, DBG_FAC, _______, _______, _______, _______, _______, _______, _______ \ ), /* [X] = LAYOUT( _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ - _______, _______, _______, _______, _______, _______, TG_NKRO, _______, _______, _______, _______, _______, _______, \ - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \ ), */ }; @@ -62,12 +66,13 @@ void matrix_init_user(void) { void matrix_scan_user(void) { }; -#define MODS_SHIFT (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT)) -#define MODS_CTRL (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL)) -#define MODS_ALT (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT)) +#define MODS_SHIFT (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT)) +#define MODS_CTRL (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL)) +#define MODS_ALT (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT)) bool process_record_user(uint16_t keycode, keyrecord_t *record) { static uint32_t key_timer; + static uint8_t scroll_effect = 0; switch (keycode) { case L_BRI: @@ -84,6 +89,26 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (led_animation_breathing) gcr_breathe = gcr_desired; } return false; + case L_EDG_M: + if (record->event.pressed) { + led_edge_mode++; + if (led_edge_mode > LED_EDGE_MODE_MAX) { + led_edge_mode = LED_EDGE_MODE_ALL; + } + } + return false; + case L_EDG_I: + if (record->event.pressed) { + led_edge_brightness += 0.1; + if (led_edge_brightness > 1) { led_edge_brightness = 1; } + } + return false; + case L_EDG_D: + if (record->event.pressed) { + led_edge_brightness -= 0.1; + if (led_edge_brightness < 0) { led_edge_brightness = 0; } + } + return false; case L_PTN: if (record->event.pressed) { if (led_animation_id == led_setups_count - 1) led_animation_id = 0; @@ -115,20 +140,17 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { return false; case L_T_ONF: if (record->event.pressed) { - led_enabled = !led_enabled; - I2C3733_Control_Set(led_enabled); + I2C3733_Control_Set(!I2C3733_Control_Get()); } return false; case L_ON: if (record->event.pressed) { - led_enabled = 1; - I2C3733_Control_Set(led_enabled); + I2C3733_Control_Set(1); } return false; case L_OFF: if (record->event.pressed) { - led_enabled = 0; - I2C3733_Control_Set(led_enabled); + I2C3733_Control_Set(1); } return false; case L_T_BR: @@ -143,7 +165,33 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { return false; case L_T_PTD: if (record->event.pressed) { - led_animation_direction = !led_animation_direction; + scroll_effect++; + if (scroll_effect == 1) { //Patterns with scroll move horizontal (Right to left) + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 0; + } else if (scroll_effect == 2) { //Patterns with scroll move vertical (Top to bottom) + led_animation_direction = 1; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 3) { //Patterns with scroll move vertical (Bottom to top) + led_animation_direction = 0; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 4) { //Patterns with scroll explode from center + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 1; + } else if (scroll_effect == 5) { //Patterns with scroll implode on center + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 1; + } else { //Patterns with scroll move horizontal (Left to right) + scroll_effect = 0; + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 0; + } } return false; case U_T_AGCR: @@ -151,6 +199,17 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); } return false; + case DBG_FAC: + if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { + led_lighting_mode = LED_MODE_NORMAL; + led_edge_brightness = 1; + led_edge_mode = LED_EDGE_MODE_ALL; + led_animation_breathing = 0; + led_animation_id = 7; //led_programs.c led_setups leds_white index + gcr_desired = LED_GCR_MAX; + I2C3733_Control_Set(1); + } + return false; case DBG_TOG: if (record->event.pressed) { TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode"); diff --git a/keyboards/massdrop/ctrl/keymaps/responsive_pattern/keymap.c b/keyboards/massdrop/ctrl/keymaps/responsive_pattern/keymap.c index 58911aa7574..ccbd377dfd0 100644 --- a/keyboards/massdrop/ctrl/keymaps/responsive_pattern/keymap.c +++ b/keyboards/massdrop/ctrl/keymaps/responsive_pattern/keymap.c @@ -29,7 +29,6 @@ enum ctrl_keycodes { L_OFF, //LED Off L_T_BR, //LED Toggle Breath Effect L_T_PTD, //LED Toggle Scrolling Pattern Direction - U_T_AUTO, //USB Extra Port Toggle Auto Detect / Always Active U_T_AGCR, //USB Toggle Automatic GCR control DBG_TOG, //DEBUG Toggle On / Off DBG_MTRX, //DEBUG Toggle Matrix Prints @@ -67,7 +66,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [1] = LAYOUT( _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, KC_MSTP, KC_VOLU, \ - L_T_BR, L_PSD, L_BRI, L_PSI, _______, _______, _______, U_T_AUTO,U_T_AGCR,_______, MO(2), _______, _______, _______, KC_MPRV, KC_MNXT, KC_VOLD, \ + L_T_BR, L_PSD, L_BRI, L_PSI, _______, _______, _______, _______, U_T_AGCR,_______, MO(2), _______, _______, _______, KC_MPRV, KC_MNXT, KC_VOLD, \ L_T_PTD, L_PTP, L_BRD, L_PTN, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, L_T_MD, L_T_ONF, _______, _______, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \ @@ -777,11 +776,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { led_animation_direction = !led_animation_direction; } return false; - case U_T_AUTO: - if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { - TOGGLE_FLAG_AND_PRINT(usb_extra_manual, "USB extra port manual mode"); - } - return false; case U_T_AGCR: if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); diff --git a/keyboards/massdrop/ctrl/matrix.c b/keyboards/massdrop/ctrl/matrix.c index 5f1741e58a5..956c0bb56f6 100644 --- a/keyboards/massdrop/ctrl/matrix.c +++ b/keyboards/massdrop/ctrl/matrix.c @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,6 +22,8 @@ along with this program. If not, see . #include "clks.h" #include +#define MCU_PORTS_USED 2 //PA, PB + matrix_row_t mlatest[MATRIX_ROWS]; matrix_row_t mlast[MATRIX_ROWS]; matrix_row_t mdebounced[MATRIX_ROWS]; @@ -30,7 +32,7 @@ uint8_t row_ports[] = { MATRIX_ROW_PORTS }; uint8_t row_pins[] = { MATRIX_ROW_PINS }; uint8_t col_ports[] = { MATRIX_COL_PORTS }; uint8_t col_pins[] = { MATRIX_COL_PINS }; -uint32_t row_masks[2]; //NOTE: If more than PA PB used in the future, adjust code to accomodate +uint32_t row_masks[MCU_PORTS_USED]; //Array size must match number of unique MCU ports used for reads (PA, PB, PC, etc) __attribute__ ((weak)) void matrix_init_kb(void) { @@ -56,9 +58,9 @@ void matrix_init(void) memset(mlast, 0, MATRIX_ROWS * sizeof(matrix_row_t)); memset(mdebounced, 0, MATRIX_ROWS * sizeof(matrix_row_t)); - row_masks[PA] = 0; - row_masks[PB] = 0; + memset(row_masks, 0, sizeof(row_masks)); + //Inputs uint8_t row; for (row = 0; row < MATRIX_ROWS; row++) { @@ -69,6 +71,7 @@ void matrix_init(void) row_masks[row_ports[row]] |= 1 << row_pins[row]; //Add pin to proper row mask } + //Outputs uint8_t col; for (col = 0; col < MATRIX_COLS; col++) { @@ -85,7 +88,7 @@ uint8_t matrix_scan(void) uint8_t mchanged; uint8_t row; uint8_t col; - uint32_t scans[2]; //PA PB + uint32_t scans[MCU_PORTS_USED]; //Array size must match number of unique MCU ports used for reads (PA, PB, PC, etc) if (timer_read64() < mdebouncing) return 1; //mdebouncing == 0 when no debouncing active @@ -93,14 +96,16 @@ uint8_t matrix_scan(void) for (col = 0; col < MATRIX_COLS; col++) { - PORT->Group[col_ports[col]].OUTSET.reg = 1 << col_pins[col]; //Set col output + //Set output + PORT->Group[col_ports[col]].OUTSET.reg = 1 << col_pins[col]; //Set col output + wait_us(1); //Delay for output - wait_us(1); //Delay for output + //Read input (add unique ports as needed, PA, PB, PC, etc) + scans[PA] = PORT->Group[PA].IN.reg & row_masks[PA]; //Read PA row pins data + scans[PB] = PORT->Group[PB].IN.reg & row_masks[PB]; //Read PA row pins data - scans[PA] = PORT->Group[PA].IN.reg & row_masks[PA]; //Read PA row pins data - scans[PB] = PORT->Group[PB].IN.reg & row_masks[PB]; //Read PB row pins data - - PORT->Group[col_ports[col]].OUTCLR.reg = 1 << col_pins[col]; //Clear col output + //Clear output + PORT->Group[col_ports[col]].OUTCLR.reg = 1 << col_pins[col]; //Clear col output for (row = 0; row < MATRIX_ROWS; row++) { diff --git a/keyboards/massdrop/ctrl/rules.mk b/keyboards/massdrop/ctrl/rules.mk index aa45c68056d..e63b9aacd40 100644 --- a/keyboards/massdrop/ctrl/rules.mk +++ b/keyboards/massdrop/ctrl/rules.mk @@ -1,6 +1,8 @@ # project specific files SRC = matrix.c SRC += config_led.c +SRC += spi.c +SRC += usb.c #For platform and packs ARM_ATSAM = SAMD51J18A diff --git a/keyboards/massdrop/ctrl/spi.c b/keyboards/massdrop/ctrl/spi.c new file mode 100644 index 00000000000..0b979ed7990 --- /dev/null +++ b/keyboards/massdrop/ctrl/spi.c @@ -0,0 +1,57 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "arm_atsam_protocol.h" + +void SR_EXP_Init_kb(void) { + /* Initialize shift register */ + SR_EXP_OE_N_DIS; + SR_EXP_RCLK_HI; + + SR_EXP_SERCOM->SPI.CTRLA.bit.DORD = 1; //Data Order - LSB is transferred first + SR_EXP_SERCOM->SPI.CTRLA.bit.CPOL = 1; //Clock Polarity - SCK high when idle. Leading edge of cycle is falling. Trailing rising. + SR_EXP_SERCOM->SPI.CTRLA.bit.CPHA = 1; //Clock Phase - Leading Edge Falling, change, Trailing Edge - Rising, sample + SR_EXP_SERCOM->SPI.CTRLA.bit.DIPO = 3; //Data In Pinout - SERCOM PAD[3] is used as data input (Configure away from DOPO. Not using input.) + SR_EXP_SERCOM->SPI.CTRLA.bit.DOPO = 0; //Data Output PAD[0], Serial Clock PAD[1] + SR_EXP_SERCOM->SPI.CTRLA.bit.MODE = 3; //Operating Mode - Master operation + + SR_EXP_SERCOM->SPI.CTRLA.bit.ENABLE = 1; //Enable - Peripheral is enabled or being enabled + while (SR_EXP_SERCOM->SPI.SYNCBUSY.bit.ENABLE) { DBGC(DC_SPI_EXP_SYNC_ENABLING); } + + /* Set default shift register values */ + sr_exp_data.reg = 0; //Clear data register + sr_exp_data.bit.HUB_CONNECT = 0; //USB Hub disconnected + sr_exp_data.bit.HUB_RESET_N = 0; //USB Hub in reset state + + sr_exp_data.bit.SRC_1 = 1; //Set CON1 CC A5/B5 as Rd 5.1k + sr_exp_data.bit.SRC_2 = 1; //Set CON2 CC A5/B5 as Rd 5.1k + sr_exp_data.bit.S_UP = 0; //Default USB data to CON1 + sr_exp_data.bit.E_UP_N = 1; //Disable HOST + sr_exp_data.bit.S_DN1 = 1; //Default EXTRA port to CON2 + sr_exp_data.bit.E_DN1_N = 1; //Disable EXTRA + + sr_exp_data.bit.E_VBUS_1 = 0; //Disable CON1 5V + sr_exp_data.bit.E_VBUS_2 = 0; //Disable CON2 5V + sr_exp_data.bit.IRST = 1; //LED drivers I2C in reset + sr_exp_data.bit.SDB_N = 0; //LED drivers in shutdown + + /* Write shift register data */ + SR_EXP_WriteData(); + + /* Enable shift register output */ + SR_EXP_OE_N_ENA; +} diff --git a/keyboards/massdrop/ctrl/usb.c b/keyboards/massdrop/ctrl/usb.c new file mode 100644 index 00000000000..760df9347fe --- /dev/null +++ b/keyboards/massdrop/ctrl/usb.c @@ -0,0 +1,83 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "arm_atsam_protocol.h" + +//Note: rp_best_index not used +void usb_set_host_kb(uint8_t con, uint8_t rp_best_index) { + if (con == 1) { + sr_exp_data.bit.S_UP = 0; //HOST to USBC-1 + sr_exp_data.bit.S_DN1 = 1; //EXTRA to USBC-2 + g_usb_host_port = USB_HOST_PORT_1; //Save host port + sr_exp_data.bit.E_VBUS_1 = 1; //Enable CON1 5V + SR_EXP_WriteData(); //Update port configuration + } else if (con == 2) { + sr_exp_data.bit.S_DN1 = 0; //HOST to USBC-2 + sr_exp_data.bit.S_UP = 1; //EXTRA to USBC-1 + g_usb_host_port = USB_HOST_PORT_2; //Save host port + sr_exp_data.bit.E_VBUS_2 = 1; //Enable CON2 5V + SR_EXP_WriteData(); //Update port configuration + } +} + +void usb_set_extra_kb(uint8_t con) { + if (con == 1) { + sr_exp_data.bit.SRC_1 = 0; //Set CON1 CC A5/B5 as Rp 56k + sr_exp_data.bit.E_VBUS_1 = 0; //Disable CON1 5V + SR_EXP_WriteData(); //Update port configuration + } else if (con == 2) { + sr_exp_data.bit.SRC_2 = 0; //Set CON2 CC A5/B5 as Rp 56k + sr_exp_data.bit.E_VBUS_2 = 0; //Disable CON2 5V + SR_EXP_WriteData(); //Update port configuration + } +} + +void usb_init_host_detection_kb(void) { + //Disable 5V + sr_exp_data.bit.E_VBUS_1 = 0; //Disable CON1 5V + sr_exp_data.bit.E_VBUS_2 = 0; //Disable CON2 5V + + //Configure default paths + sr_exp_data.bit.S_UP = 0; //HOST to USBC-1 + sr_exp_data.bit.S_DN1 = 1; //EXTRA to USBC-2 + + //Configure CC lines + sr_exp_data.bit.SRC_1 = 1; //Set CON1 CC A5/B5 as Rd 5.1k + sr_exp_data.bit.SRC_2 = 1; //Set CON2 CC A5/B5 as Rd 5.1k + + //Enable ports + sr_exp_data.bit.E_UP_N = 0; //Enable HOST for use + sr_exp_data.bit.E_DN1_N = 0; //Enable EXTRA for use + + SR_EXP_WriteData(); //Update port configuration +} + +//Return 1 if configuration successful +//Return 0 otherwise +uint8_t usb_attach_port_configure_kb(uint8_t g_usb_host_port, uint16_t usbc_cc_a5_v, uint16_t usbc_cc_b5_v) { + if (USB_HOST_IS_1(g_usb_host_port)) { //If host is port 1 + //Set up port 2 + usb_set_extra_kb(2); + return 1; + } else if (USB_HOST_IS_2(g_usb_host_port)) { //If host is on port 2 + //Set up port 1 + usb_set_extra_kb(1); + return 1; + } + + return 0; +} diff --git a/keyboards/massdrop/rocketeer/config.h b/keyboards/massdrop/rocketeer/config.h new file mode 100644 index 00000000000..08ab67c999f --- /dev/null +++ b/keyboards/massdrop/rocketeer/config.h @@ -0,0 +1,129 @@ +/* +Copyright 2015 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0x04D8 +#define PRODUCT_ID 0xEE66 +#define DEVICE_VER 0x0100 + +#define MANUFACTURER "Massdrop Inc." +#define PRODUCT "Massdrop x Zslane Mercury Rocketeer Keyboard" +#define SERIAL_NUM "Unavailable" + +/* key matrix size */ +#define MATRIX_ROWS 5 +#define MATRIX_COLS 14 + +/* MCU Port name definitions */ +#define PA 0 +#define PB 1 + +/* Port and Pin definition of key row hardware configuration */ +#define MATRIX_ROW_PORTS PB, PB, PB, PB, PA +#define MATRIX_ROW_PINS 6, 7, 8, 9, 4 + +/* Port and Pin definition of key column hardware configuration */ +#define MATRIX_COL_PORTS PB, PA, PA, PA, PA, PB, PB, PA, PA, PA, PB, PB, PB, PB +#define MATRIX_COL_PINS 3, 0, 1, 2, 3, 30, 31, 5, 6, 7, 10, 11, 12, 13 + +/* This Shift Register expands available hardware output lines to control additional peripherals */ +/* It uses four lines from the MCU to provide 16 output lines */ +/* Shift Register Clock configuration (MCU to ShiftRegister.RCLK) */ +#define SR_EXP_RCLK_PORT PB +#define SR_EXP_RCLK_PIN 14 +/* Shift Register Output Enable configuration (MCU to ShiftRegister.OE_N) */ +#define SR_EXP_OE_N_PORT PB +#define SR_EXP_OE_N_PIN 15 +/* SERCOM port to use for Shift Register SPI */ +/* DATAOUT and SCLK must be configured to use hardware pins of this port */ +#define SR_EXP_SERCOM_NUM 2 +/* Shift Register SPI Data Out configuration (MCU.SERCOMx.PAD[0] to ShiftRegister.SER) */ +#define SR_EXP_DATAOUT_PORT PA +#define SR_EXP_DATAOUT_PIN 12 +#define SR_EXP_DATAOUT_MUX 2 +/* Shift Register SPI Serial Clock configuration (MCU.SERCOMx.PAD[1] to ShiftRegister.SRCLK) */ +#define SR_EXP_SCLK_PORT PA +#define SR_EXP_SCLK_PIN 13 +#define SR_EXP_SCLK_MUX 2 + +/* Debug LED (Small LED Located near MCU) */ +/* PCB D94 */ +#define DEBUG_LED_ENABLE 1 +#define DEBUG_LED_PORT PA +#define DEBUG_LED_PIN 27 + +/* Additional debugging ports */ +/* PCB M25 */ +#define DEBUG_PORT1_ENABLE 1 +#define DEBUG_PORT1_PORT PA +#define DEBUG_PORT1_PIN 20 +/* PCB M26 */ +#define DEBUG_PORT2_ENABLE 1 +#define DEBUG_PORT2_PORT PA +#define DEBUG_PORT2_PIN 21 +/* PCB M23 */ +#define DEBUG_PORT3_ENABLE 1 +#define DEBUG_PORT3_PORT PB +#define DEBUG_PORT3_PIN 17 + +/* Debug Boot Tracing - During boot sequence, ground this pin to halt and display debug code using Debug LED */ +/* This is useful in determining which hardware device may have malfunctioned or is improperly configured */ +/* Feature is automatically disabled after successful boot */ +/* PCB M27 */ +#define DEBUG_BOOT_TRACING_ENABLE 1 +#define DEBUG_BOOT_TRACING_PORT PB +#define DEBUG_BOOT_TRACING_PIN 23 + +/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ +#define DEBOUNCING_DELAY 5 + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +//#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +//#define LOCKING_RESYNC_ENABLE + +/* Force boot in NKRO mode */ +//#define FORCE_NKRO + +/* + * Feature disable options + * These options are also useful to firmware size reduction. + */ + +/* disable debug print */ +//#define NO_DEBUG + +/* disable print */ +//#define NO_PRINT + +/* disable action features */ +//#define NO_ACTION_LAYER +//#define NO_ACTION_TAPPING +//#define NO_ACTION_ONESHOT +//#define NO_ACTION_MACRO +//#define NO_ACTION_FUNCTION + +#define RGB_MATRIX_KEYPRESSES +#define RGB_MATRIX_LED_PROCESS_LIMIT 15 +#define RGB_MATRIX_LED_FLUSH_LIMIT 10 +#define RGB_MATRIX_EXTRA_TOG + +#include "config_led.h" diff --git a/keyboards/massdrop/rocketeer/config_adc.h b/keyboards/massdrop/rocketeer/config_adc.h new file mode 100644 index 00000000000..94b5a1413ec --- /dev/null +++ b/keyboards/massdrop/rocketeer/config_adc.h @@ -0,0 +1,118 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +//ADC configuration table column indices +#define ADC_PORT 0 +#define ADC_PIN 1 +#define ADC_MUX 2 +#define ADC_INDEX 3 +#define ADC_MUXPOS 4 +#define ADC_REFSEL 5 +#define ADC_SAMPLENUM 6 +#define ADC_SAMPLEN 7 + +//ADC configuration table row indices +#define ADC_5V 0 //5V bus voltage +#define ADC_C1A5 1 //Connector 1 A5 CC voltage +#define ADC_C1B5 2 //Connector 1 B5 CC voltage +#define ADC_C2A5 3 //Connector 2 A5 CC voltage +#define ADC_C2B5 4 //Connector 2 B5 CC voltage +#define ADC_C1I 5 //Connector 1 current +#define ADC_C2I 6 //Connector 2 current + +//ADC_PORT: PORT of the PIN on the MCU (Ex: 0 = PA, 1 = PB, ...) +// Set ADC_PORT to ADC_NA if it is not available for use +//ADC_PIN: PIN on the MCU (Ex: 0 = 00, 1 = 01, 12 = 12, ...) +//ADC_MUX: PMUX setting for the MCU PIN (Ex: 0 = A, 1 = B, 2 = C, ...) +//ADC_INDEX: ADC to use (Ex: 0 = ADC0, 1 = ADC1, ...) +//ADC_MUXPOS: MUXPOS setting to read on the ADC (Use macros from Atmel library adc.h ADC_INPUTCTRL_MUXPOS_AIN*_Val) +//ADC_REFSEL: Reference the ADC is to use (Use macros from Atmel library adc.h ADC_REFCTRL_REFSEL_*_Val) +//ADC_SAMPLENUM: Number of samples to average for output (Use macros from Atmel library adc.h ADC_AVGCTRL_SAMPLENUM_*_Val) +//ADC_SAMPLEN: Sampling time for each sample in units of CLK_ADC cycles depending on the ADC clock frequency +// ADC_PORT ADC_MUX +// | ADC_PIN | ADC_INDEX +// | | | | ADC_MUXPOS ADC_REFSEL ADC_SAMPLENUM ADC_SAMPLEN +#define ADC_CONFIG_5V 1, 0, 1, 0, ADC_INPUTCTRL_MUXPOS_AIN12_Val, ADC_REFCTRL_REFSEL_INTREF_Val, ADC_AVGCTRL_SAMPLENUM_4_Val, 45 +#define ADC_CONFIG_C1A5 1, 2, 1, 0, ADC_INPUTCTRL_MUXPOS_AIN14_Val, ADC_REFCTRL_REFSEL_INTREF_Val, ADC_AVGCTRL_SAMPLENUM_4_Val, 63 +#define ADC_CONFIG_C1B5 1, 4, 1, 1, ADC_INPUTCTRL_MUXPOS_AIN6_Val, ADC_REFCTRL_REFSEL_INTREF_Val, ADC_AVGCTRL_SAMPLENUM_4_Val, 63 +#define ADC_CONFIG_C2A5 1, 1, 1, 0, ADC_INPUTCTRL_MUXPOS_AIN13_Val, ADC_REFCTRL_REFSEL_INTREF_Val, ADC_AVGCTRL_SAMPLENUM_4_Val, 63 +#define ADC_CONFIG_C2B5 1, 5, 1, 1, ADC_INPUTCTRL_MUXPOS_AIN7_Val, ADC_REFCTRL_REFSEL_INTREF_Val, ADC_AVGCTRL_SAMPLENUM_4_Val, 63 +#define ADC_CONFIG_C1I 0, 10, 1, 0, ADC_INPUTCTRL_MUXPOS_AIN10_Val, ADC_REFCTRL_REFSEL_INTVCC1_Val, ADC_AVGCTRL_SAMPLENUM_4_Val, 45 +#define ADC_CONFIG_C2I 0, 11, 1, 0, ADC_INPUTCTRL_MUXPOS_AIN11_Val, ADC_REFCTRL_REFSEL_INTVCC1_Val, ADC_AVGCTRL_SAMPLENUM_4_Val, 45 + +//Conversion values dependant upon the circuitry +#define ADC_I_MILLIAMPS_PER_COUNT -0.000980472f +#define ADC_I_MILLIAMPS_OFFSET 1.979711769f +#define ADC_5V_VOLTS_PER_COUNT 0.001904297f +#define ADC_5V_VOLTS_OFFSET 0.0f +#define ADC_5V_NOMINAL 5.0f +#define ADC_5V_NOMINAL_COUNTS (ADC_5V_NOMINAL / ADC_5V_VOLTS_PER_COUNT) + +//Conversion macros +#define ADC_CI_C2I(macounts) ((float)macounts * ADC_I_MILLIAMPS_PER_COUNT + ADC_I_MILLIAMPS_OFFSET) //Converts connector current counts to milliamps +#define ADC_CI_I2C(ma) (uint16_t)((((float)ma - ADC_I_MILLIAMPS_OFFSET) / ADC_I_MILLIAMPS_PER_COUNT)) //Converts milliamps to connector current counts +#define ADC_5V_C2V(icounts) ((float)icounts * ADC_5V_VOLTS_PER_COUNT + ADC_5V_VOLTS_OFFSET) //Converts 5V Bus counts to volts +#define ADC_5V_V2C(v) (uint16_t)((((float)v - ADC_5V_VOLTS_OFFSET) / ADC_5V_VOLTS_PER_COUNT)) //Converts 5V Bus volts to counts +#define ADC_CC_5VCOR(v5counts, cc) ((float)v5counts == 0 ? 0 : (uint16_t)(ADC_5V_NOMINAL_COUNTS / (float)v5counts * (float)cc)) //Corrects CC counts to nominal 5V value + +//Note: The extra port's onboard/external range is not reliable for onboard/external detection due to varying device implementations, +// so instead the extra port will follow the host port connection of onboard or external. We will still use +// a nominal value for device detection with a wider range though. +#define ADC_USBC_ONBOARD 951 //ADC value indicating the USB-C Connector is on main PCB +#define ADC_USBC_EXTERNAL 881 //ADC value indicating the USB-C Connector is on external PCB +#define ADC_USBC_RANGE ((ADC_USBC_ONBOARD - ADC_USBC_EXTERNAL) / 2) //Range of detection for extra port Rd +#define ADC_USBC_EXTRA_NOMINAL ((ADC_USBC_ONBOARD + ADC_USBC_EXTERNAL) / 2) //Nominal ADC value for detection of connected device +#define ADC_USBC_EXTRA_TOLERANCE (0.20f) //Tolerance for Rd +#define ADC_USBC_EXTRA_ADC_MAX ((float)ADC_USBC_EXTRA_NOMINAL + ((float)ADC_USBC_EXTRA_NOMINAL * ADC_USBC_EXTRA_TOLERANCE)) //Rd ADC max counts +#define ADC_USBC_EXTRA_ADC_MIN ((float)ADC_USBC_EXTRA_NOMINAL - ((float)ADC_USBC_EXTRA_NOMINAL * ADC_USBC_EXTRA_TOLERANCE)) //Rd ADC min counts + +#define USBC_IS_SINK(a5, b5) ((a5 > ADC_USBC_EXTRA_ADC_MIN && a5 < ADC_USBC_EXTRA_ADC_MAX) || \ + (b5 > ADC_USBC_EXTRA_ADC_MIN && b5 < ADC_USBC_EXTRA_ADC_MAX)) + +#define ADC_USBC_RP_DELTA_MAX 400 //Amount of noise to tolerate for Rp detection (this can be very generous as long as ranges do not overlap) + +#define ADC_USBC_RP_TYPES 3 //56k, 22k, 10k +#define ADC_USBC_CON_TYPES 2 //Onboard, External +#define ADC_USBC_TYPES (ADC_USBC_RP_TYPES * ADC_USBC_CON_TYPES) + +//These are the indices for ADC_USBC_RP_NOM +//xxK is a ADC_USBC_RP_TYPES +//ONB is for the onboard USB-C Connector and must have an even index number +//EXT is for the external USB-C Connector and must have an odd index number +#define ADC_USBC_56K_ONB 0 +#define ADC_USBC_56K_EXT 1 +#define ADC_USBC_22K_ONB 2 +#define ADC_USBC_22K_EXT 3 +#define ADC_USBC_10K_ONB 4 +#define ADC_USBC_10K_EXT 5 + +#define ADC_USBC_IS_ONB(a) (a % 2 == 0) //Given a ADC_USBC_RP_NOM index, return true if the index refers to an onboard connector +#define ADC_USBC_IS_EXT(a) (a % 2 == 1) //Given a ADC_USBC_RP_NOM index, return true if the index refers to an external connector + +//These values are for detecting whether or not the host is connected through the onboard USB or external USB +//The counts are calculated from a nominal 5V bus, then scaled depending on the measured 5V bus +//External connectors are detected through addition of a resistor to slightly drop readings while remaining within USB-C CC tolerances +//Set a value to -1 if it is not supported +//Source Rp 56k-Onb 56k-Ext 22k-Onb 22k-Ext 10k-Onb 10k-Ext +#define ADC_USBC_RP_NOM 999, 852, 2232, 1940, 3955, 3528 + +extern uint16_t adc_usbc_rp_nominal[ADC_USBC_TYPES]; + +#define POWER_CHECK_INTERVAL 1 //How often to check power usage for adjustment and safety (ms) +#define V_5V_AVGS 20 //Number of 5V readings to average for algorithms wanting stable readings rather than instantaneous diff --git a/keyboards/massdrop/rocketeer/config_led.h b/keyboards/massdrop/rocketeer/config_led.h new file mode 100644 index 00000000000..cbdebc0047a --- /dev/null +++ b/keyboards/massdrop/rocketeer/config_led.h @@ -0,0 +1,160 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +//Define number of IS31FL3733 drivers being used (1...16) +#define ISSI3733_DRIVER_COUNT 2 +#define DRIVER_LED_TOTAL ISSI3733_LED_COUNT + +//Hardware address of each driver (Refer to IS31FL3733 pdf "Table 1 Slave Address" and keyboard schematic) +#define ISSI3773_DRIVER_ADDRESSES { 0xA0, 0xBE } + +//LED I2C bus speed +#define I2C_HZ 580000 + +//Count of LED bodies +#define ISSI3733_LED_COUNT 87 + +#define LED_GCR_MAX 165 //Max GCR value (0 - 255) WARNING: Raising this value may overload the LED drivers and USB bus +#define LED_GCR_STEP 10 //GCR increment/decrement value + +#ifdef USE_MASSDROP_CONFIGURATOR +#define ANIMATION_SPEED_STEP 1 + +#define BREATHE_STEP 1 +#define BREATHE_MIN_STEP 0 +#define BREATHE_MAX_STEP 255 +#endif + +//Default Global Current Register value (Default brightness 0 - 255) +#define ISSI3733_GCR_DEFAULT LED_GCR_MAX + +//Automatic power rollback and recovery +#define V5_HIGH 2494 //5V high level (After low power detect, point at which LEDs are allowed to use more power ) +#define V5_LOW 2434 //5V low level (LED power rolled back to stay above this limit) +#define V5_CAT 2206 //5V catastrophic level (Host USB port potential to shut down) + +//LED Mapping - More practically generated from a spreadsheet program +//id: ID of the LED (Sync with PCB callouts) +//x: Physical X coordinate of LED (units do not matter) +//y: Physical Y coordinate of LED (units do not matter) +//drv: 1-Based index of ISSI3773_DRIVER_ADDRESSES +//cs: Matrix wiring CS col (1-16) +//swr: Matrix wiring SW Red row (1-12) +//swg: Matrix wiring SW Green row (1-12) +//swb: Matrix wiring SW Blue row (1-12) +//scan: Associated key matrix scancode (set 255 if none or 254 for LED to turn off in alternating mode) +//Note: Origin 0,0 may be located anywhere as the software will do the final layout +#define ISSI3733_LED_MAP { \ + { .id = 1, .x = 0.36, .y = 3.362, .adr = { .drv = 2, .cs = 9, .swr = 2, .swg = 1, .swb = 3 }, .scan = 0 }, \ + { .id = 2, .x = 1.11, .y = 3.362, .adr = { .drv = 2, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 1 }, \ + { .id = 3, .x = 1.86, .y = 3.362, .adr = { .drv = 2, .cs = 8, .swr = 5, .swg = 4, .swb = 6 }, .scan = 2 }, \ + { .id = 4, .x = 2.61, .y = 3.362, .adr = { .drv = 2, .cs = 7, .swr = 2, .swg = 1, .swb = 3 }, .scan = 3 }, \ + { .id = 5, .x = 3.36, .y = 3.362, .adr = { .drv = 2, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 4 }, \ + { .id = 6, .x = 4.11, .y = 3.362, .adr = { .drv = 2, .cs = 5, .swr = 5, .swg = 4, .swb = 6 }, .scan = 5 }, \ + { .id = 7, .x = 4.86, .y = 3.362, .adr = { .drv = 2, .cs = 3, .swr = 2, .swg = 1, .swb = 3 }, .scan = 6 }, \ + { .id = 8, .x = 5.61, .y = 3.362, .adr = { .drv = 1, .cs = 12, .swr = 2, .swg = 1, .swb = 3 }, .scan = 7 }, \ + { .id = 9, .x = 6.36, .y = 3.362, .adr = { .drv = 1, .cs = 11, .swr = 2, .swg = 1, .swb = 3 }, .scan = 8 }, \ + { .id = 10, .x = 7.11, .y = 3.362, .adr = { .drv = 1, .cs = 9, .swr = 2, .swg = 1, .swb = 3 }, .scan = 9 }, \ + { .id = 11, .x = 7.86, .y = 3.362, .adr = { .drv = 1, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 10 }, \ + { .id = 12, .x = 8.61, .y = 3.362, .adr = { .drv = 1, .cs = 7, .swr = 2, .swg = 1, .swb = 3 }, .scan = 11 }, \ + { .id = 13, .x = 9.36, .y = 3.362, .adr = { .drv = 1, .cs = 7, .swr = 5, .swg = 4, .swb = 6 }, .scan = 12 }, \ + { .id = 14, .x = 10.485, .y = 3.362, .adr = { .drv = 1, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 13 }, \ + { .id = 15, .x = 0.548, .y = 2.612, .adr = { .drv = 2, .cs = 9, .swr = 8, .swg = 7, .swb = 9 }, .scan = 14 }, \ + { .id = 16, .x = 1.485, .y = 2.612, .adr = { .drv = 2, .cs = 8, .swr = 11, .swg = 10, .swb = 12 }, .scan = 15 }, \ + { .id = 17, .x = 2.235, .y = 2.612, .adr = { .drv = 2, .cs = 7, .swr = 8, .swg = 7, .swb = 9 }, .scan = 16 }, \ + { .id = 18, .x = 2.985, .y = 2.612, .adr = { .drv = 2, .cs = 7, .swr = 11, .swg = 10, .swb = 12 }, .scan = 17 }, \ + { .id = 19, .x = 3.735, .y = 2.612, .adr = { .drv = 2, .cs = 5, .swr = 11, .swg = 10, .swb = 12 }, .scan = 18 }, \ + { .id = 20, .x = 4.485, .y = 2.612, .adr = { .drv = 2, .cs = 3, .swr = 5, .swg = 4, .swb = 6 }, .scan = 19 }, \ + { .id = 21, .x = 5.235, .y = 2.612, .adr = { .drv = 2, .cs = 3, .swr = 11, .swg = 10, .swb = 12 }, .scan = 20 }, \ + { .id = 22, .x = 5.985, .y = 2.612, .adr = { .drv = 1, .cs = 12, .swr = 8, .swg = 7, .swb = 9 }, .scan = 21 }, \ + { .id = 23, .x = 6.735, .y = 2.612, .adr = { .drv = 1, .cs = 11, .swr = 8, .swg = 7, .swb = 9 }, .scan = 22 }, \ + { .id = 24, .x = 7.485, .y = 2.612, .adr = { .drv = 1, .cs = 9, .swr = 8, .swg = 7, .swb = 9 }, .scan = 23 }, \ + { .id = 25, .x = 8.235, .y = 2.612, .adr = { .drv = 1, .cs = 8, .swr = 8, .swg = 7, .swb = 9 }, .scan = 24 }, \ + { .id = 26, .x = 8.985, .y = 2.612, .adr = { .drv = 1, .cs = 7, .swr = 8, .swg = 7, .swb = 9 }, .scan = 25 }, \ + { .id = 27, .x = 9.735, .y = 2.612, .adr = { .drv = 1, .cs = 5, .swr = 11, .swg = 10, .swb = 12 }, .scan = 26 }, \ + { .id = 28, .x = 10.673, .y = 2.612, .adr = { .drv = 1, .cs = 3, .swr = 5, .swg = 4, .swb = 6 }, .scan = 27 }, \ + { .id = 29, .x = 0.641, .y = 1.862, .adr = { .drv = 2, .cs = 11, .swr = 11, .swg = 10, .swb = 12 }, .scan = 28 }, \ + { .id = 30, .x = 1.673, .y = 1.862, .adr = { .drv = 2, .cs = 11, .swr = 8, .swg = 7, .swb = 9 }, .scan = 29 }, \ + { .id = 31, .x = 2.423, .y = 1.862, .adr = { .drv = 2, .cs = 11, .swr = 2, .swg = 1, .swb = 3 }, .scan = 30 }, \ + { .id = 32, .x = 3.173, .y = 1.862, .adr = { .drv = 2, .cs = 11, .swr = 5, .swg = 4, .swb = 6 }, .scan = 31 }, \ + { .id = 33, .x = 3.923, .y = 1.862, .adr = { .drv = 2, .cs = 2, .swr = 5, .swg = 4, .swb = 6 }, .scan = 32 }, \ + { .id = 34, .x = 4.673, .y = 1.862, .adr = { .drv = 2, .cs = 2, .swr = 8, .swg = 7, .swb = 9 }, .scan = 33 }, \ + { .id = 35, .x = 5.423, .y = 1.862, .adr = { .drv = 2, .cs = 2, .swr = 11, .swg = 10, .swb = 12 }, .scan = 34 }, \ + { .id = 36, .x = 6.173, .y = 1.862, .adr = { .drv = 1, .cs = 12, .swr = 11, .swg = 10, .swb = 12 }, .scan = 35 }, \ + { .id = 37, .x = 6.923, .y = 1.862, .adr = { .drv = 1, .cs = 11, .swr = 11, .swg = 10, .swb = 12 }, .scan = 36 }, \ + { .id = 38, .x = 7.673, .y = 1.862, .adr = { .drv = 1, .cs = 9, .swr = 11, .swg = 10, .swb = 12 }, .scan = 37 }, \ + { .id = 39, .x = 8.423, .y = 1.862, .adr = { .drv = 1, .cs = 8, .swr = 11, .swg = 10, .swb = 12 }, .scan = 38 }, \ + { .id = 40, .x = 9.173, .y = 1.862, .adr = { .drv = 1, .cs = 7, .swr = 11, .swg = 10, .swb = 12 }, .scan = 39 }, \ + { .id = 41, .x = 10.391, .y = 1.862, .adr = { .drv = 1, .cs = 3, .swr = 2, .swg = 1, .swb = 3 }, .scan = 41 }, \ + { .id = 42, .x = 0.829, .y = 1.112, .adr = { .drv = 2, .cs = 12, .swr = 8, .swg = 7, .swb = 9 }, .scan = 42 }, \ + { .id = 43, .x = 2.048, .y = 1.112, .adr = { .drv = 2, .cs = 13, .swr = 11, .swg = 10, .swb = 12 }, .scan = 44 }, \ + { .id = 44, .x = 2.798, .y = 1.112, .adr = { .drv = 2, .cs = 14, .swr = 11, .swg = 10, .swb = 12 }, .scan = 45 }, \ + { .id = 45, .x = 3.548, .y = 1.112, .adr = { .drv = 2, .cs = 14, .swr = 8, .swg = 7, .swb = 9 }, .scan = 46 }, \ + { .id = 46, .x = 4.298, .y = 1.112, .adr = { .drv = 2, .cs = 16, .swr = 8, .swg = 7, .swb = 9 }, .scan = 47 }, \ + { .id = 47, .x = 5.048, .y = 1.112, .adr = { .drv = 2, .cs = 16, .swr = 11, .swg = 10, .swb = 12 }, .scan = 48 }, \ + { .id = 48, .x = 5.798, .y = 1.112, .adr = { .drv = 1, .cs = 13, .swr = 11, .swg = 10, .swb = 12 }, .scan = 49 }, \ + { .id = 49, .x = 6.548, .y = 1.112, .adr = { .drv = 1, .cs = 13, .swr = 8, .swg = 7, .swb = 9 }, .scan = 50 }, \ + { .id = 50, .x = 7.298, .y = 1.112, .adr = { .drv = 1, .cs = 14, .swr = 8, .swg = 7, .swb = 9 }, .scan = 51 }, \ + { .id = 51, .x = 8.048, .y = 1.112, .adr = { .drv = 1, .cs = 14, .swr = 11, .swg = 10, .swb = 12 }, .scan = 52 }, \ + { .id = 52, .x = 8.798, .y = 1.112, .adr = { .drv = 1, .cs = 16, .swr = 11, .swg = 10, .swb = 12 }, .scan = 53 }, \ + { .id = 53, .x = 10.204, .y = 1.112, .adr = { .drv = 1, .cs = 2, .swr = 11, .swg = 10, .swb = 12 }, .scan = 55 }, \ + { .id = 54, .x = 0.454, .y = 0.362, .adr = { .drv = 2, .cs = 12, .swr = 2, .swg = 1, .swb = 3 }, .scan = 56 }, \ + { .id = 55, .x = 1.391, .y = 0.362, .adr = { .drv = 2, .cs = 13, .swr = 2, .swg = 1, .swb = 3 }, .scan = 57 }, \ + { .id = 56, .x = 2.329, .y = 0.362, .adr = { .drv = 2, .cs = 13, .swr = 5, .swg = 4, .swb = 6 }, .scan = 58 }, \ + { .id = 57, .x = 5.141, .y = 0.362, .adr = { .drv = 2, .cs = 16, .swr = 2, .swg = 1, .swb = 3 }, .scan = 62 }, \ + { .id = 58, .x = 7.954, .y = 0.362, .adr = { .drv = 1, .cs = 14, .swr = 2, .swg = 1, .swb = 3 }, .scan = 66 }, \ + { .id = 59, .x = 8.891, .y = 0.362, .adr = { .drv = 1, .cs = 16, .swr = 2, .swg = 1, .swb = 3 }, .scan = 67 }, \ + { .id = 60, .x = 9.829, .y = 0.362, .adr = { .drv = 1, .cs = 2, .swr = 8, .swg = 7, .swb = 9 }, .scan = 68 }, \ + { .id = 61, .x = 10.766, .y = 0.362, .adr = { .drv = 1, .cs = 2, .swr = 2, .swg = 1, .swb = 3 }, .scan = 69 }, \ + { .id = 62, .x = 0.74, .y = 3, .adr = { .drv = 2, .cs = 9, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 63, .x = 1.714, .y = 3, .adr = { .drv = 2, .cs = 8, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 64, .x = 2.688, .y = 3, .adr = { .drv = 2, .cs = 7, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 65, .x = 3.662, .y = 3, .adr = { .drv = 2, .cs = 5, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 66, .x = 4.636, .y = 3, .adr = { .drv = 2, .cs = 3, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 67, .x = 5.61, .y = 3, .adr = { .drv = 1, .cs = 12, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 68, .x = 6.584, .y = 3, .adr = { .drv = 1, .cs = 11, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 69, .x = 7.558, .y = 3, .adr = { .drv = 1, .cs = 9, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 70, .x = 8.532, .y = 3, .adr = { .drv = 1, .cs = 8, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 71, .x = 9.506, .y = 3, .adr = { .drv = 1, .cs = 5, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 72, .x = 10.48, .y = 3, .adr = { .drv = 1, .cs = 5, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 73, .x = 0.74, .y = 0.74, .adr = { .drv = 2, .cs = 12, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 74, .x = 1.714, .y = 0.74, .adr = { .drv = 2, .cs = 13, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 75, .x = 2.688, .y = 0.74, .adr = { .drv = 2, .cs = 14, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 76, .x = 3.662, .y = 0.74, .adr = { .drv = 2, .cs = 14, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 77, .x = 4.636, .y = 0.74, .adr = { .drv = 2, .cs = 16, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 78, .x = 5.61, .y = 0.74, .adr = { .drv = 1, .cs = 13, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 79, .x = 6.584, .y = 0.74, .adr = { .drv = 1, .cs = 13, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 80, .x = 7.558, .y = 0.74, .adr = { .drv = 1, .cs = 14, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 81, .x = 8.532, .y = 0.74, .adr = { .drv = 1, .cs = 16, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 82, .x = 9.506, .y = 0.74, .adr = { .drv = 1, .cs = 16, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 83, .x = 10.48, .y = 0.74, .adr = { .drv = 1, .cs = 2, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 84, .x = 0.74, .y = 2.25, .adr = { .drv = 2, .cs = 9, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ + { .id = 85, .x = 0.74, .y = 1.5, .adr = { .drv = 2, .cs = 12, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ + { .id = 86, .x = 10.48, .y = 2.25, .adr = { .drv = 1, .cs = 3, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 87, .x = 10.48, .y = 1.5, .adr = { .drv = 1, .cs = 3, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ +}; + +#define USB_LED_INDICATOR_ENABLE //Comment out to disable indicator functionality +#ifdef USB_LED_INDICATOR_ENABLE //Scan codes refer to actual key matrix codes, not KC_* (255 to disable) + #define USB_LED_NUM_LOCK_SCANCODE 255 + #define USB_LED_CAPS_LOCK_SCANCODE 28 + #define USB_LED_SCROLL_LOCK_SCANCODE 21 + #define USB_LED_COMPOSE_SCANCODE 255 + #define USB_LED_KANA_SCANCODE 255 +#endif //USB_LED_INDICATOR_ENABLE diff --git a/keyboards/massdrop/rocketeer/config_spi.h b/keyboards/massdrop/rocketeer/config_spi.h new file mode 100644 index 00000000000..86251aff889 --- /dev/null +++ b/keyboards/massdrop/rocketeer/config_spi.h @@ -0,0 +1,42 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +/* Data structure to define Shift Register output expander hardware */ +/* This structure gets shifted into registers LSB first */ +typedef union { + struct { + uint16_t RSVD4:1; /*!< bit: 0 */ + uint16_t SRC_2_B5:1; /*!< bit: 1 USBC-2 CC B5 UFP Rd 5.1k WHEN 1, DFP Rp 56k WHEN 0 */ + uint16_t SRC_1_B5:1; /*!< bit: 2 USBC-1 CC B5 UFP Rd 5.1k WHEN 1, DFP Rp 56k WHEN 0 */ + uint16_t S_B_EXT:1; /*!< bit: 3 B TO EX-1 WHEN 0, B TO USBC-1 WHEN 1 */ + uint16_t SDB_N:1; /*!< bit: 4 SHUTDOWN IS31FL3733 CHIPS WHEN 0, RUN WHEN 1 */ + uint16_t IRST:1; /*!< bit: 5 RESET IS31FL3733 I2C WHEN 1, RUN WHEN 0 */ + uint16_t SRC_2_A5:1; /*!< bit: 6 USBC-2 CC A5 UFP Rd 5.1k WHEN 1, DFP Rp 56k WHEN 0 */ + uint16_t SRC_1_A5:1; /*!< bit: 7 USBC-1 CC A5 UFP Rd 5.1k WHEN 1, DFP Rp 56k WHEN 0 */ + uint16_t E_VBUS_2:1; /*!< bit: 8 ENABLE 5V TO USBC-2/EX-2 WHEN 1, DISABLE WHEN 0 */ + uint16_t E_VBUS_1:1; /*!< bit: 9 ENABLE 5V TO USBC-1/EX-1 WHEN 1, DISABLE WHEN 0 */ + uint16_t ENB:1; /*!< bit: 10 ENABLE CHANNEL B USBC-1/EX-1 WHEN 1, DISABLE WHEN 0 */ + uint16_t S_A_EXT:1; /*!< bit: 11 A TO USBC-2 WHEN 0, A TO EX-2 WHEN 1 */ + uint16_t ENA:1; /*!< bit: 12 ENABLE CHANNEL A USBC-2/EX-2 WHEN 1, DISABLE WHEN 0 */ + uint16_t S_A_UP:1; /*!< bit: 13 DN1 TO A & UP TO B WHEN 1, DN1 TO B & UP TO A WHEN 0 */ + uint16_t HUB_RESET_N:1; /*!< bit: 14 RESET USB HUB WHEN 0, RUN WHEN 1 */ + uint16_t HUB_CONNECT:1; /*!< bit: 15 SIGNAL VBUS CONNECT TO USB HUB WHEN 1 */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} sr_exp_t; diff --git a/keyboards/massdrop/rocketeer/config_usb.h b/keyboards/massdrop/rocketeer/config_usb.h new file mode 100644 index 00000000000..9f02b12034c --- /dev/null +++ b/keyboards/massdrop/rocketeer/config_usb.h @@ -0,0 +1,28 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +//Macros to Enable, Disable, and Update USB 5V bus connections +#define USBC_CFG_5V1_VAR sr_exp_data.bit.E_VBUS_1 //Variable storing USBC-1 5V Bus state +#define USBC_CFG_5V1_ENA 1 //Value to enable USBC-1 5V Bus +#define USBC_CFG_5V1_DIS 0 //Value to disable USBC-1 5V Bus +#define USBC_CFG_5V1_UPDATE SR_EXP_WriteData() //Command to run to update value +#define USBC_CFG_5V2_VAR sr_exp_data.bit.E_VBUS_2 //Variable storing USBC-2 5V Bus state +#define USBC_CFG_5V2_ENA 1 //Value to enable USBC-1 5V Bus +#define USBC_CFG_5V2_DIS 0 //Value to disable USBC-1 5V Bus +#define USBC_CFG_5V2_UPDATE SR_EXP_WriteData() //Command to run to update value diff --git a/keyboards/massdrop/rocketeer/info.json b/keyboards/massdrop/rocketeer/info.json new file mode 100644 index 00000000000..67373a717bd --- /dev/null +++ b/keyboards/massdrop/rocketeer/info.json @@ -0,0 +1,101 @@ +//TODO: JSON +{ + "keyboard_name": "SHIFT", + "url": "https://www.massdrop.com/buy/massdrop-shift-mechanical-keyboard", + "maintainer": "Massdrop", + "width": 18.5, + "height": 6.5, + "layouts": { + "LAYOUT": { + "layout": [ + {"label":"ESCAPE", "x":0, "y":0}, + {"label":"F1", "x":2, "y":0}, + {"label":"F2", "x":3, "y":0}, + {"label":"F3", "x":4, "y":0}, + {"label":"F4", "x":5, "y":0}, + {"label":"F5", "x":6.5, "y":0}, + {"label":"F6", "x":7.5, "y":0}, + {"label":"F7", "x":8.5, "y":0}, + {"label":"F8", "x":9.5, "y":0}, + {"label":"F9", "x":11, "y":0}, + {"label":"F10", "x":12, "y":0}, + {"label":"F11", "x":13, "y":0}, + {"label":"F12", "x":14, "y":0}, + {"label":"PRINT SCREEN", "x":15.5, "y":0}, + {"label":"SCROLL LOCK", "x":16.5, "y":0}, + {"label":"PAUSE BREAK", "x":17.5, "y":0}, + {"label":"BACKTICK", "x":0, "y":1.5}, + {"label":"1", "x":1, "y":1.5}, + {"label":"2", "x":2, "y":1.5}, + {"label":"3", "x":3, "y":1.5}, + {"label":"4", "x":4, "y":1.5}, + {"label":"5", "x":5, "y":1.5}, + {"label":"6", "x":6, "y":1.5}, + {"label":"7", "x":7, "y":1.5}, + {"label":"8", "x":8, "y":1.5}, + {"label":"9", "x":9, "y":1.5}, + {"label":"0", "x":10, "y":1.5}, + {"label":"MINUS", "x":11, "y":1.5}, + {"label":"EQUALS", "x":12, "y":1.5}, + {"label":"BACKSPACE", "x":13, "y":1.5, "w":2}, + {"label":"INSERT", "x":15.5, "y":1.5}, + {"label":"HOME", "x":16.5, "y":1.5}, + {"label":"PAGE UP", "x":17.5, "y":1.5}, + {"label":"TAB", "x":0, "y":2.5, "w":1.5}, + {"label":"Q", "x":1.5, "y":2.5}, + {"label":"W", "x":2.5, "y":2.5}, + {"label":"E", "x":3.5, "y":2.5}, + {"label":"R", "x":4.5, "y":2.5}, + {"label":"T", "x":5.5, "y":2.5}, + {"label":"Y", "x":6.5, "y":2.5}, + {"label":"U", "x":7.5, "y":2.5}, + {"label":"I", "x":8.5, "y":2.5}, + {"label":"O", "x":9.5, "y":2.5}, + {"label":"P", "x":10.5, "y":2.5}, + {"label":"LEFT BRACKET", "x":11.5, "y":2.5}, + {"label":"RIGHT BRACKET", "x":12.5, "y":2.5}, + {"label":"BACK SLASH", "x":13.5, "y":2.5, "w":1.5}, + {"label":"DELETE", "x":15.5, "y":2.5}, + {"label":"END", "x":16.5, "y":2.5}, + {"label":"PAGE DOWN", "x":17.5, "y":2.5}, + {"label":"CAPS LOCK", "x":0, "y":3.5, "w":1.75}, + {"label":"A", "x":1.75, "y":3.5}, + {"label":"S", "x":2.75, "y":3.5}, + {"label":"D", "x":3.75, "y":3.5}, + {"label":"F", "x":4.75, "y":3.5}, + {"label":"G", "x":5.75, "y":3.5}, + {"label":"H", "x":6.75, "y":3.5}, + {"label":"J", "x":7.75, "y":3.5}, + {"label":"K", "x":8.75, "y":3.5}, + {"label":"L", "x":9.75, "y":3.5}, + {"label":"SEMICOLON", "x":10.75, "y":3.5}, + {"label":"SINGLE TICK", "x":11.75, "y":3.5}, + {"label":"ENTER", "x":12.75, "y":3.5, "w":2.25}, + {"label":"LEFT SHIFT", "x":0, "y":4.5, "w":2.25}, + {"label":"Z", "x":2.25, "y":4.5}, + {"label":"X", "x":3.25, "y":4.5}, + {"label":"C", "x":4.25, "y":4.5}, + {"label":"V", "x":5.25, "y":4.5}, + {"label":"B", "x":6.25, "y":4.5}, + {"label":"N", "x":7.25, "y":4.5}, + {"label":"M", "x":8.25, "y":4.5}, + {"label":"COMMA", "x":9.25, "y":4.5}, + {"label":"PERIOD", "x":10.25, "y":4.5}, + {"label":"FORWARD SLASH", "x":11.25, "y":4.5}, + {"label":"RIGHT SHIFT", "x":12.25, "y":4.5, "w":2.75}, + {"label":"UP ARROW", "x":16.5, "y":4.5}, + {"label":"LEFT CTRL", "x":0.005, "y":5.5, "w":1.24}, + {"label":"LEFT WIN", "x":1.255, "y":5.5, "w":1.24}, + {"label":"LEFT ALT", "x":2.505, "y":5.5, "w":1.24}, + {"label":"SPACEBAR", "x":3.75, "y":5.5, "w":6.25}, + {"label":"RIGHT ALT", "x":10, "y":5.5, "w":1.25}, + {"label":"FN", "x":11.25, "y":5.5, "w":1.25}, + {"label":"MENU", "x":12.5, "y":5.5, "w":1.25}, + {"label":"RIGHT CTRL", "x":13.75, "y":5.5, "w":1.25}, + {"label":"LEFT ARROW", "x":15.5, "y":5.5}, + {"label":"DOWN ARROW", "x":16.5, "y":5.5}, + {"label":"RIGHT ARROW", "x":17.5, "y":5.5} + ] + } + } +} diff --git a/keyboards/massdrop/rocketeer/keymaps/default/keymap.c b/keyboards/massdrop/rocketeer/keymaps/default/keymap.c new file mode 100644 index 00000000000..593fac217dc --- /dev/null +++ b/keyboards/massdrop/rocketeer/keymaps/default/keymap.c @@ -0,0 +1,250 @@ +#include QMK_KEYBOARD_H + +enum ctrl_keycodes { + L_BRI = SAFE_RANGE, //LED Brightness Increase + L_BRD, //LED Brightness Decrease + L_EDG_I, //LED Edge Brightness Increase + L_EDG_D, //LED Edge Brightness Decrease + L_EDG_M, //LED Edge lighting mode + L_PTN, //LED Pattern Select Next + L_PTP, //LED Pattern Select Previous + L_PSI, //LED Pattern Speed Increase + L_PSD, //LED Pattern Speed Decrease + L_T_MD, //LED Toggle Mode + L_T_ONF, //LED Toggle On / Off + L_ON, //LED On + L_OFF, //LED Off + L_T_BR, //LED Toggle Breath Effect + L_T_PTD, //LED Toggle Scrolling Pattern Direction and effect + U_T_AGCR, //USB Toggle Automatic GCR control + DBG_TOG, //DEBUG Toggle On / Off + DBG_MTRX, //DEBUG Toggle Matrix Prints + DBG_KBD, //DEBUG Toggle Keyboard Prints + DBG_MOU, //DEBUG Toggle Mouse Prints + DBG_FAC, //DEBUG Factory light testing (All on white) + MD_BOOT //Restart into bootloader after hold timeout +}; + +#define TG_NKRO MAGIC_TOGGLE_NKRO //Toggle 6KRO / NKRO mode + +keymap_config_t keymap_config; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, \ + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, \ + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \ + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, \ + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RGUI, KC_RCTL \ + ), + [1] = LAYOUT( + KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, \ + L_T_BR, L_PSD, L_BRI, L_PSI, _______, _______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_UP, _______, _______, U_T_AGCR,\ + L_T_PTD, L_PTP, L_BRD, L_PTN, _______, _______, KC_INS, KC_HOME, KC_PGUP, KC_LEFT, KC_DOWN, KC_RGHT, _______, \ + _______, L_T_MD, L_T_ONF, _______, _______, MD_BOOT, TG_NKRO, KC_END, KC_PGDN, KC_VOLD, KC_VOLU, _______, \ + _______, _______, _______, DBG_FAC, KC_MUTE, _______, KC_APP, _______ \ + ), + /* + [X] = LAYOUT( + _______ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______ \ + ), + */ +}; + +// Runs just one time when the keyboard initializes. +void matrix_init_user(void) { +}; + +// Runs constantly in the background, in a loop. +void matrix_scan_user(void) { +}; + +#define MODS_SHIFT (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT)) +#define MODS_CTRL (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL)) +#define MODS_ALT (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT)) + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + static uint32_t key_timer; + static uint8_t scroll_effect = 0; + + switch (keycode) { + case L_BRI: + if (record->event.pressed) { + if (LED_GCR_STEP > LED_GCR_MAX - gcr_desired) gcr_desired = LED_GCR_MAX; + else gcr_desired += LED_GCR_STEP; + if (led_animation_breathing) gcr_breathe = gcr_desired; + } + return false; + case L_BRD: + if (record->event.pressed) { + if (LED_GCR_STEP > gcr_desired) gcr_desired = 0; + else gcr_desired -= LED_GCR_STEP; + if (led_animation_breathing) gcr_breathe = gcr_desired; + } + return false; + case L_EDG_M: + if (record->event.pressed) { + led_edge_mode++; + if (led_edge_mode > LED_EDGE_MODE_MAX) { + led_edge_mode = LED_EDGE_MODE_ALL; + } + } + return false; + case L_EDG_I: + if (record->event.pressed) { + led_edge_brightness += 0.1; + if (led_edge_brightness > 1) { led_edge_brightness = 1; } + } + return false; + case L_EDG_D: + if (record->event.pressed) { + led_edge_brightness -= 0.1; + if (led_edge_brightness < 0) { led_edge_brightness = 0; } + } + return false; + case L_PTN: + if (record->event.pressed) { + if (led_animation_id == led_setups_count - 1) led_animation_id = 0; + else led_animation_id++; + } + return false; + case L_PTP: + if (record->event.pressed) { + if (led_animation_id == 0) led_animation_id = led_setups_count - 1; + else led_animation_id--; + } + return false; + case L_PSI: + if (record->event.pressed) { + led_animation_speed += ANIMATION_SPEED_STEP; + } + return false; + case L_PSD: + if (record->event.pressed) { + led_animation_speed -= ANIMATION_SPEED_STEP; + if (led_animation_speed < 0) led_animation_speed = 0; + } + return false; + case L_T_MD: + if (record->event.pressed) { + led_lighting_mode++; + if (led_lighting_mode > LED_MODE_MAX_INDEX) led_lighting_mode = LED_MODE_NORMAL; + } + return false; + case L_T_ONF: + if (record->event.pressed) { + led_enabled = !led_enabled; + I2C3733_Control_Set(led_enabled); + } + return false; + case L_ON: + if (record->event.pressed) { + led_enabled = 1; + I2C3733_Control_Set(led_enabled); + } + return false; + case L_OFF: + if (record->event.pressed) { + led_enabled = 0; + I2C3733_Control_Set(led_enabled); + } + return false; + case L_T_BR: + if (record->event.pressed) { + led_animation_breathing = !led_animation_breathing; + if (led_animation_breathing) { + gcr_breathe = gcr_desired; + led_animation_breathe_cur = BREATHE_MIN_STEP; + breathe_dir = 1; + } + } + return false; + case L_T_PTD: + if (record->event.pressed) { + scroll_effect++; + if (scroll_effect == 1) { //Patterns with scroll move horizontal (Right to left) + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 0; + } else if (scroll_effect == 2) { //Patterns with scroll move vertical (Top to bottom) + led_animation_direction = 1; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 3) { //Patterns with scroll move vertical (Bottom to top) + led_animation_direction = 0; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 4) { //Patterns with scroll explode from center + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 1; + } else if (scroll_effect == 5) { //Patterns with scroll implode on center + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 1; + } else { //Patterns with scroll move horizontal (Left to right) + scroll_effect = 0; + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 0; + } + } + return false; + case U_T_AGCR: + if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { + TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); + } + return false; + case DBG_FAC: + if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { + led_lighting_mode = LED_MODE_NORMAL; + led_edge_brightness = 1; + led_edge_mode = LED_EDGE_MODE_ALL; + led_animation_breathing = 0; + led_animation_id = 7; //led_programs.c led_setups leds_white index + gcr_desired = LED_GCR_MAX; + led_enabled = 1; + I2C3733_Control_Set(led_enabled); + } + return false; + case DBG_TOG: + if (record->event.pressed) { + TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode"); + } + return false; + case DBG_MTRX: + if (record->event.pressed) { + TOGGLE_FLAG_AND_PRINT(debug_matrix, "Debug matrix"); + } + return false; + case DBG_KBD: + if (record->event.pressed) { + TOGGLE_FLAG_AND_PRINT(debug_keyboard, "Debug keyboard"); + } + return false; + case DBG_MOU: + if (record->event.pressed) { + TOGGLE_FLAG_AND_PRINT(debug_mouse, "Debug mouse"); + } + return false; + case MD_BOOT: + if (record->event.pressed) { + key_timer = timer_read32(); + } else { + if (timer_elapsed32(key_timer) >= 500) { + reset_keyboard(); + } + } + return false; + default: + return true; //Process all other keycodes normally + } +} + +void rgb_matrix_init_user(void) { + led_lighting_mode = LED_MODE_INDICATORS_ONLY; //Start Rocketeer with only indicator lights +} diff --git a/keyboards/massdrop/rocketeer/keymaps/mac/keymap.c b/keyboards/massdrop/rocketeer/keymaps/mac/keymap.c new file mode 100644 index 00000000000..ee05b3d67f1 --- /dev/null +++ b/keyboards/massdrop/rocketeer/keymaps/mac/keymap.c @@ -0,0 +1,250 @@ +#include QMK_KEYBOARD_H + +enum ctrl_keycodes { + L_BRI = SAFE_RANGE, //LED Brightness Increase + L_BRD, //LED Brightness Decrease + L_EDG_I, //LED Edge Brightness Increase + L_EDG_D, //LED Edge Brightness Decrease + L_EDG_M, //LED Edge lighting mode + L_PTN, //LED Pattern Select Next + L_PTP, //LED Pattern Select Previous + L_PSI, //LED Pattern Speed Increase + L_PSD, //LED Pattern Speed Decrease + L_T_MD, //LED Toggle Mode + L_T_ONF, //LED Toggle On / Off + L_ON, //LED On + L_OFF, //LED Off + L_T_BR, //LED Toggle Breath Effect + L_T_PTD, //LED Toggle Scrolling Pattern Direction and effect + U_T_AGCR, //USB Toggle Automatic GCR control + DBG_TOG, //DEBUG Toggle On / Off + DBG_MTRX, //DEBUG Toggle Matrix Prints + DBG_KBD, //DEBUG Toggle Keyboard Prints + DBG_MOU, //DEBUG Toggle Mouse Prints + DBG_FAC, //DEBUG Factory light testing (All on white) + MD_BOOT //Restart into bootloader after hold timeout +}; + +#define TG_NKRO MAGIC_TOGGLE_NKRO //Toggle 6KRO / NKRO mode + +keymap_config_t keymap_config; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, \ + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, \ + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \ + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, \ + KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RGUI, MO(1), KC_APP, KC_RCTL \ + ), + [1] = LAYOUT( + KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, \ + L_T_BR, L_PSD, L_BRI, L_PSI, _______, _______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_UP, _______, _______, U_T_AGCR,\ + L_T_PTD, L_PTP, L_BRD, L_PTN, _______, _______, KC_INS, KC_HOME, KC_PGUP, KC_LEFT, KC_DOWN, KC_RGHT, _______, \ + _______, L_T_MD, L_T_ONF, _______, _______, MD_BOOT, TG_NKRO, KC_END, KC_PGDN, KC_VOLD, KC_VOLU, _______, \ + _______, _______, _______, DBG_FAC, KC_MUTE, _______, _______, _______ \ + ), + /* + [X] = LAYOUT( + _______ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______ \ + ), + */ +}; + +// Runs just one time when the keyboard initializes. +void matrix_init_user(void) { +}; + +// Runs constantly in the background, in a loop. +void matrix_scan_user(void) { +}; + +#define MODS_SHIFT (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT)) +#define MODS_CTRL (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL)) +#define MODS_ALT (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT)) + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + static uint32_t key_timer; + static uint8_t scroll_effect = 0; + + switch (keycode) { + case L_BRI: + if (record->event.pressed) { + if (LED_GCR_STEP > LED_GCR_MAX - gcr_desired) gcr_desired = LED_GCR_MAX; + else gcr_desired += LED_GCR_STEP; + if (led_animation_breathing) gcr_breathe = gcr_desired; + } + return false; + case L_BRD: + if (record->event.pressed) { + if (LED_GCR_STEP > gcr_desired) gcr_desired = 0; + else gcr_desired -= LED_GCR_STEP; + if (led_animation_breathing) gcr_breathe = gcr_desired; + } + return false; + case L_EDG_M: + if (record->event.pressed) { + led_edge_mode++; + if (led_edge_mode > LED_EDGE_MODE_MAX) { + led_edge_mode = LED_EDGE_MODE_ALL; + } + } + return false; + case L_EDG_I: + if (record->event.pressed) { + led_edge_brightness += 0.1; + if (led_edge_brightness > 1) { led_edge_brightness = 1; } + } + return false; + case L_EDG_D: + if (record->event.pressed) { + led_edge_brightness -= 0.1; + if (led_edge_brightness < 0) { led_edge_brightness = 0; } + } + return false; + case L_PTN: + if (record->event.pressed) { + if (led_animation_id == led_setups_count - 1) led_animation_id = 0; + else led_animation_id++; + } + return false; + case L_PTP: + if (record->event.pressed) { + if (led_animation_id == 0) led_animation_id = led_setups_count - 1; + else led_animation_id--; + } + return false; + case L_PSI: + if (record->event.pressed) { + led_animation_speed += ANIMATION_SPEED_STEP; + } + return false; + case L_PSD: + if (record->event.pressed) { + led_animation_speed -= ANIMATION_SPEED_STEP; + if (led_animation_speed < 0) led_animation_speed = 0; + } + return false; + case L_T_MD: + if (record->event.pressed) { + led_lighting_mode++; + if (led_lighting_mode > LED_MODE_MAX_INDEX) led_lighting_mode = LED_MODE_NORMAL; + } + return false; + case L_T_ONF: + if (record->event.pressed) { + led_enabled = !led_enabled; + I2C3733_Control_Set(led_enabled); + } + return false; + case L_ON: + if (record->event.pressed) { + led_enabled = 1; + I2C3733_Control_Set(led_enabled); + } + return false; + case L_OFF: + if (record->event.pressed) { + led_enabled = 0; + I2C3733_Control_Set(led_enabled); + } + return false; + case L_T_BR: + if (record->event.pressed) { + led_animation_breathing = !led_animation_breathing; + if (led_animation_breathing) { + gcr_breathe = gcr_desired; + led_animation_breathe_cur = BREATHE_MIN_STEP; + breathe_dir = 1; + } + } + return false; + case L_T_PTD: + if (record->event.pressed) { + scroll_effect++; + if (scroll_effect == 1) { //Patterns with scroll move horizontal (Right to left) + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 0; + } else if (scroll_effect == 2) { //Patterns with scroll move vertical (Top to bottom) + led_animation_direction = 1; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 3) { //Patterns with scroll move vertical (Bottom to top) + led_animation_direction = 0; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 4) { //Patterns with scroll explode from center + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 1; + } else if (scroll_effect == 5) { //Patterns with scroll implode on center + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 1; + } else { //Patterns with scroll move horizontal (Left to right) + scroll_effect = 0; + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 0; + } + } + return false; + case U_T_AGCR: + if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { + TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); + } + return false; + case DBG_FAC: + if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { + led_lighting_mode = LED_MODE_NORMAL; + led_edge_brightness = 1; + led_edge_mode = LED_EDGE_MODE_ALL; + led_animation_breathing = 0; + led_animation_id = 7; //led_programs.c led_setups leds_white index + gcr_desired = LED_GCR_MAX; + led_enabled = 1; + I2C3733_Control_Set(led_enabled); + } + return false; + case DBG_TOG: + if (record->event.pressed) { + TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode"); + } + return false; + case DBG_MTRX: + if (record->event.pressed) { + TOGGLE_FLAG_AND_PRINT(debug_matrix, "Debug matrix"); + } + return false; + case DBG_KBD: + if (record->event.pressed) { + TOGGLE_FLAG_AND_PRINT(debug_keyboard, "Debug keyboard"); + } + return false; + case DBG_MOU: + if (record->event.pressed) { + TOGGLE_FLAG_AND_PRINT(debug_mouse, "Debug mouse"); + } + return false; + case MD_BOOT: + if (record->event.pressed) { + key_timer = timer_read32(); + } else { + if (timer_elapsed32(key_timer) >= 500) { + reset_keyboard(); + } + } + return false; + default: + return true; //Process all other keycodes normally + } +} + +void rgb_matrix_init_user(void) { + led_lighting_mode = LED_MODE_INDICATORS_ONLY; //Start Rocketeer with only indicator lights +} diff --git a/keyboards/massdrop/rocketeer/matrix.c b/keyboards/massdrop/rocketeer/matrix.c new file mode 100644 index 00000000000..8667c1b2b60 --- /dev/null +++ b/keyboards/massdrop/rocketeer/matrix.c @@ -0,0 +1,181 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "rocketeer.h" + +#include "d51_util.h" +#include "debug.h" +#include "clks.h" +#include + +#define MCU_PORTS_USED 2 //PA, PB + +matrix_row_t mlatest[MATRIX_ROWS]; +matrix_row_t mlast[MATRIX_ROWS]; +matrix_row_t mdebounced[MATRIX_ROWS]; + +uint8_t row_ports[] = { MATRIX_ROW_PORTS }; +uint8_t row_pins[] = { MATRIX_ROW_PINS }; +uint8_t col_ports[] = { MATRIX_COL_PORTS }; +uint8_t col_pins[] = { MATRIX_COL_PINS }; +uint32_t row_masks[MCU_PORTS_USED]; //Array size must match number of unique MCU ports used for reads (PA, PB, PC, etc) + +__attribute__ ((weak)) +void matrix_init_kb(void) { + matrix_init_user(); +} + +__attribute__ ((weak)) +void matrix_scan_kb(void) { + matrix_scan_user(); +} + +__attribute__ ((weak)) +void matrix_init_user(void) { +} + +__attribute__ ((weak)) +void matrix_scan_user(void) { +} + +void matrix_init(void) +{ + memset(mlatest, 0, MATRIX_ROWS * sizeof(matrix_row_t)); + memset(mlast, 0, MATRIX_ROWS * sizeof(matrix_row_t)); + memset(mdebounced, 0, MATRIX_ROWS * sizeof(matrix_row_t)); + + memset(row_masks, 0, sizeof(row_masks)); + + //Inputs + uint8_t row; + for (row = 0; row < MATRIX_ROWS; row++) + { + PORT->Group[row_ports[row]].DIRCLR.reg = 1 << row_pins[row]; //Input + PORT->Group[row_ports[row]].OUTCLR.reg = 1 << row_pins[row]; //Low + PORT->Group[row_ports[row]].PINCFG[row_pins[row]].bit.INEN = 1; //Input Enable, + PORT->Group[row_ports[row]].PINCFG[row_pins[row]].bit.PULLEN = 1; //Pull Enable + row_masks[row_ports[row]] |= 1 << row_pins[row]; //Add pin to proper row mask + } + + //Outputs + uint8_t col; + for (col = 0; col < MATRIX_COLS; col++) + { + PORT->Group[col_ports[col]].DIRSET.reg = 1 << col_pins[col]; //Output + PORT->Group[col_ports[col]].OUTCLR.reg = 1 << col_pins[col]; //Low + } + + matrix_init_quantum(); +} + +uint64_t mdebouncing = 0; +uint8_t matrix_scan(void) +{ + uint8_t mchanged; + uint8_t row; + uint8_t col; + uint32_t scans[MCU_PORTS_USED]; //Array size must match number of unique MCU ports used for reads (PA, PB, PC, etc) + + if (timer_read64() < mdebouncing) return 1; //mdebouncing == 0 when no debouncing active + + memset(mlatest, 0, MATRIX_ROWS * sizeof(matrix_row_t)); //Zero the result buffer + + for (col = 0; col < MATRIX_COLS; col++) + { + //Set output + PORT->Group[col_ports[col]].OUTSET.reg = 1 << col_pins[col]; //Set col output + wait_us(1); //Delay for output + + //Read input (add unique ports as needed, PA, PB, PC, etc) + scans[PA] = PORT->Group[PA].IN.reg & row_masks[PA]; //Read PA row pins data + scans[PB] = PORT->Group[PB].IN.reg & row_masks[PB]; //Read PA row pins data + + //Clear output + PORT->Group[col_ports[col]].OUTCLR.reg = 1 << col_pins[col]; //Clear col output + + for (row = 0; row < MATRIX_ROWS; row++) + { + //Move scan bits from scans array into proper row bit locations + if (scans[row_ports[row]] & (1 << row_pins[row])) + mlatest[row] |= 1 << col; + } + } + + mchanged = 0; //Default to no matrix change since last + + for (row = 0; row < MATRIX_ROWS; row++) + { + if (mlast[row] != mlatest[row]) + mchanged = 1; + mlast[row] = mlatest[row]; + } + + if (!mchanged) + { + for (row = 0; row < MATRIX_ROWS; row++) + mdebounced[row] = mlatest[row]; + mdebouncing = 0; + } + else + { + //Begin or extend debounce on change + mdebouncing = timer_read64() + DEBOUNCING_DELAY; + } + + matrix_scan_quantum(); + + return 1; +} + +matrix_row_t matrix_get_row(uint8_t row) +{ + return mdebounced[row]; +} + +void matrix_print(void) +{ + char buf[(MATRIX_COLS+8)*(MATRIX_ROWS+1)] = "R C"; + char *pbuf = buf+3; + uint32_t cols; + uint32_t rows; + matrix_row_t row; + + for (cols = 1; cols <= MATRIX_COLS; cols++) + { + *pbuf = (cols%10)+48; + pbuf++; + } + *pbuf = '\r'; pbuf++; + *pbuf = '\n'; pbuf++; + + for (rows = 1; rows <= MATRIX_ROWS; rows++) + { + row = matrix_get_row(rows-1); + if (rows < 10) { *pbuf = rows+48; pbuf++; *pbuf = ' '; pbuf++; *pbuf = ' '; pbuf++; } + else { *pbuf = (rows/10)+48; pbuf++; *pbuf = (rows%10)+48; pbuf++; *pbuf = ' '; pbuf++; } + for (cols = 0; cols < MATRIX_COLS; cols++) + { + if (row & 1 << cols) *pbuf = 'X'; + else *pbuf = '.'; + pbuf++; + } + *pbuf = '\r'; pbuf++; + *pbuf = '\n'; pbuf++; + } + *pbuf = 0; + dprint(buf); +} diff --git a/keyboards/massdrop/rocketeer/matrix.h b/keyboards/massdrop/rocketeer/matrix.h new file mode 100644 index 00000000000..3eab6dece10 --- /dev/null +++ b/keyboards/massdrop/rocketeer/matrix.h @@ -0,0 +1,77 @@ +/* +Copyright 2011 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef MATRIX_H +#define MATRIX_H + +#include +#include +#include "keyboard.h" + +#if (MATRIX_COLS <= 8) +typedef uint8_t matrix_row_t; +#elif (MATRIX_COLS <= 16) +typedef uint16_t matrix_row_t; +#elif (MATRIX_COLS <= 32) +typedef uint32_t matrix_row_t; +#else +#error "MATRIX_COLS: invalid value" +#endif + +#define MATRIX_IS_ON(row, col) (matrix_get_row(row) && (1<. +*/ + +#include "arm_atsam_protocol.h" + +void SR_EXP_Init_kb(void) { + /* Initialize shift register */ + SR_EXP_OE_N_DIS; + SR_EXP_RCLK_HI; + + SR_EXP_SERCOM->SPI.CTRLA.bit.DORD = 1; //Data Order - LSB is transferred first + SR_EXP_SERCOM->SPI.CTRLA.bit.CPOL = 1; //Clock Polarity - SCK high when idle. Leading edge of cycle is falling. Trailing rising. + SR_EXP_SERCOM->SPI.CTRLA.bit.CPHA = 1; //Clock Phase - Leading Edge Falling, change, Trailing Edge - Rising, sample + SR_EXP_SERCOM->SPI.CTRLA.bit.DIPO = 3; //Data In Pinout - SERCOM PAD[3] is used as data input (Configure away from DOPO. Not using input.) + SR_EXP_SERCOM->SPI.CTRLA.bit.DOPO = 0; //Data Output PAD[0], Serial Clock PAD[1] + SR_EXP_SERCOM->SPI.CTRLA.bit.MODE = 3; //Operating Mode - Master operation + + SR_EXP_SERCOM->SPI.CTRLA.bit.ENABLE = 1; //Enable - Peripheral is enabled or being enabled + while (SR_EXP_SERCOM->SPI.SYNCBUSY.bit.ENABLE) { DBGC(DC_SPI_EXP_SYNC_ENABLING); } + + /* Set default shift register values */ + sr_exp_data.reg = 0; //Clear data register + sr_exp_data.bit.HUB_CONNECT = 0; //USB Hub disconnected + sr_exp_data.bit.HUB_RESET_N = 0; //USB Hub in reset state + + sr_exp_data.bit.SRC_1_A5 = 1; //Set CON1 CC A5 as Rd 5.1k + sr_exp_data.bit.SRC_1_B5 = 1; //Set CON1 CC B5 as Rd 5.1k + sr_exp_data.bit.SRC_2_A5 = 1; //Set CON2 CC A5 as Rd 5.1k + sr_exp_data.bit.SRC_2_B5 = 1; //Set CON2 CC B5 as Rd 5.1k + sr_exp_data.bit.S_A_UP = 0; //0 = DN1 to A and UP to B, 1 = DN1 to B and UP to A + sr_exp_data.bit.S_A_EXT = 1; //0 = Onboard, 1 = Offboard + sr_exp_data.bit.S_B_EXT = 0; //1 = Onboard, 0 = Offboard + + sr_exp_data.bit.ENB = 0; //Disable CON1 + sr_exp_data.bit.ENA = 0; //Disable CON2 + sr_exp_data.bit.E_VBUS_1 = 0; //Disable CON1 5V + sr_exp_data.bit.E_VBUS_2 = 0; //Disable CON2 5V + sr_exp_data.bit.IRST = 1; //LED drivers I2C in reset + sr_exp_data.bit.SDB_N = 0; //LED drivers in shutdown + + /* Write shift register data */ + SR_EXP_WriteData(); + + /* Enable shift register output */ + SR_EXP_OE_N_ENA; +} diff --git a/keyboards/massdrop/rocketeer/usb.c b/keyboards/massdrop/rocketeer/usb.c new file mode 100644 index 00000000000..b5e6c472f56 --- /dev/null +++ b/keyboards/massdrop/rocketeer/usb.c @@ -0,0 +1,119 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "arm_atsam_protocol.h" + +void usb_set_host_kb(uint8_t con, uint8_t rp_best_index) { + if (con == 1) { + //DN1 to A (CON2/EX2), UP to B (CON1/EX1) + sr_exp_data.bit.S_A_UP = 1; //0 = DN1 to B and UP to A, 1 = DN1 to A and UP to B (SAI-SBI) + + if (ADC_USBC_IS_ONB(rp_best_index)) { //Check if the port detected is onboard + sr_exp_data.bit.S_B_EXT = 1; //Onboard port + g_usb_host_port = USB_HOST_PORT_1; //Save host port + } else { //Port is external + sr_exp_data.bit.S_B_EXT = 0; //External port + g_usb_host_port = USB_HOST_PORT_1_EXT; //Save host port + } + + sr_exp_data.bit.E_VBUS_1 = 1; //Enable CON1 5V + + SR_EXP_WriteData(); //Update port configuration + } else if (con == 2) { + //DN1 to B (CON1/EX1), UP to A (CON2/EX2) + sr_exp_data.bit.S_A_UP = 0; //0 = DN1 to B and UP to A, 1 = DN1 to A and UP to B (SAI-SBI) + + if (ADC_USBC_IS_ONB(rp_best_index)) { //Check if the port detected is onboard + sr_exp_data.bit.S_A_EXT = 0; //Onboard port + g_usb_host_port = USB_HOST_PORT_2; //Save host port + } else { //Port is external + sr_exp_data.bit.S_A_EXT = 1; //External port + g_usb_host_port = USB_HOST_PORT_2_EXT; //Save host port + } + + sr_exp_data.bit.E_VBUS_2 = 1; //Enable CON2 5V + + SR_EXP_WriteData(); //Update port configuration + } +} + +void usb_set_extra_kb(uint8_t con) { + if (con == 1) { + sr_exp_data.bit.SRC_1_A5 = 0; //Set CON1 CC A5 as Rp 56k + sr_exp_data.bit.SRC_1_B5 = 0; //Set CON1 CC B5 as Rp 56k + sr_exp_data.bit.E_VBUS_1 = 0; //Disable CON1 5V + SR_EXP_WriteData(); //Update port configuration + } else if (con == 2) { + sr_exp_data.bit.SRC_2_A5 = 0; //Set CON2 CC A5 as Rp 56k + sr_exp_data.bit.SRC_2_B5 = 0; //Set CON2 CC B5 as Rp 56k + sr_exp_data.bit.E_VBUS_2 = 0; //Disable CON2 5V + SR_EXP_WriteData(); //Update port configuration + } +} + +void usb_init_host_detection_kb(void) { + //Disable 5V + sr_exp_data.bit.E_VBUS_1 = 0; //Disable CON1 5V + sr_exp_data.bit.E_VBUS_2 = 0; //Disable CON2 5V + + //Configure default paths + sr_exp_data.bit.S_A_UP = 0; //DN1 TO A & UP TO B WHEN 1, DN1 TO B & UP TO A WHEN 0 + sr_exp_data.bit.S_A_EXT = 1; //0 = Onboard, 1 = Offboard (SAO) + sr_exp_data.bit.S_B_EXT = 0; //1 = Onboard, 0 = Offboard (SBO) + + //Configure CC lines + sr_exp_data.bit.SRC_1_A5 = 1; //Set CON1 CC A5 as Rd 5.1k + sr_exp_data.bit.SRC_1_B5 = 1; //Set CON1 CC B5 as Rd 5.1k + sr_exp_data.bit.SRC_2_A5 = 1; //Set CON2 CC A5 as Rd 5.1k + sr_exp_data.bit.SRC_2_B5 = 1; //Set CON2 CC B5 as Rd 5.1k + + //Enable ports + sr_exp_data.bit.ENB = 1; //Enable CON1/EX1 for use + sr_exp_data.bit.ENA = 1; //Enable CON2/EX2 for use + + SR_EXP_WriteData(); //Update port configuration +} + +//Return 1 if configuration successful +//Return 0 otherwise +uint8_t usb_attach_port_configure_kb(uint8_t g_usb_host_port, uint16_t usbc_cc_a5_v, uint16_t usbc_cc_b5_v) { + if (USB_HOST_IS_1(g_usb_host_port)) { //If host is port 1 + //Set up port 2 + if (USBC_IS_SINK_ONB(usbc_cc_a5_v, usbc_cc_b5_v)) { //If onboard port detected + sr_exp_data.bit.S_A_EXT = 0; //Set port 2 as onboard port + SR_EXP_WriteData(); //Update port configuration + return 1; + } else if (USBC_IS_SINK_EXT(usbc_cc_a5_v, usbc_cc_b5_v)) { //If external port detected + sr_exp_data.bit.S_A_EXT = 1; //Set port 2 as onboard port + SR_EXP_WriteData(); //Update port configuration + return 1; + } + } else if (USB_HOST_IS_2(g_usb_host_port)) { //If host is on port 2 + //Set up port 1 + if (USBC_IS_SINK_ONB(usbc_cc_a5_v, usbc_cc_b5_v)) { //If onboard port detected + sr_exp_data.bit.S_B_EXT = 1; //Set port 1 as onboard port + SR_EXP_WriteData(); //Update port configuration + return 1; + } else if (USBC_IS_SINK_EXT(usbc_cc_a5_v, usbc_cc_b5_v)) { //If external port detected + sr_exp_data.bit.S_B_EXT = 0; //Set port 1 as external port + SR_EXP_WriteData(); //Update port configuration + return 1; + } + } + + return 0; +} diff --git a/keyboards/massdrop/shift/config.h b/keyboards/massdrop/shift/config.h new file mode 100644 index 00000000000..38922cc7daa --- /dev/null +++ b/keyboards/massdrop/shift/config.h @@ -0,0 +1,159 @@ +/* +Copyright 2015 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0x04D8 +#define PRODUCT_ID 0xEE65 +#define DEVICE_VER 0x0100 + +#define MANUFACTURER "Massdrop Inc." +#define PRODUCT "Massdrop SHIFT Keyboard" +#define SERIAL_NUM "Unavailable" + +/* key matrix size */ +#define MATRIX_ROWS 8 +#define MATRIX_COLS 13 + +/* MCU Port name definitions */ +#define PA 0 +#define PB 1 + +/* Shift register IDs for key matrix */ +/* SRBASE must be defined greater than MCU Port name definitions */ +#define SRBASE 10 +#define SRMAX (SRBASE + SERCOM_INST_NUM) +#define S4 (SRBASE + 4) + +/* Macros to differentiate between MCU and Shift Register usage */ +#define PORT_IS_MCU(x) (x < PORT_GROUPS) +#define PORT_IS_SR(x) (x >= SRBASE && x < SRMAX) + +/* Port and Pin definition of key row hardware configuration */ +#define MATRIX_ROW_PORTS PA, PA, PA, PA, PA, PA, PA, PA +#define MATRIX_ROW_PINS 0, 1, 2, 3, 4, 5, 6, 7 + +/* Port and Pin definition of key column hardware configuration */ +#define MATRIX_COL_PORTS S4, S4, S4, S4, S4, S4, S4, S4, S4, S4, S4, S4, S4 +#define MATRIX_COL_PINS 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 + +/* This Shift Register expands available hardware output lines to control additional peripherals */ +/* It uses four lines from the MCU to provide 16 output lines */ +/* Shift Register Clock configuration (MCU to ShiftRegister.RCLK) */ +#define SR_EXP_RCLK_PORT PB +#define SR_EXP_RCLK_PIN 14 +/* Shift Register Output Enable configuration (MCU to ShiftRegister.OE_N) */ +#define SR_EXP_OE_N_PORT PB +#define SR_EXP_OE_N_PIN 15 +/* SERCOM port to use for Shift Register SPI */ +/* DATAOUT and SCLK must be configured to use hardware pins of this port */ +#define SR_EXP_SERCOM_NUM 2 +/* Shift Register SPI Data Out configuration (MCU.SERCOMx.PAD[0] to ShiftRegister.SER) */ +#define SR_EXP_DATAOUT_PORT PA +#define SR_EXP_DATAOUT_PIN 12 +#define SR_EXP_DATAOUT_MUX 2 +/* Shift Register SPI Serial Clock configuration (MCU.SERCOMx.PAD[1] to ShiftRegister.SRCLK) */ +#define SR_EXP_SCLK_PORT PA +#define SR_EXP_SCLK_PIN 13 +#define SR_EXP_SCLK_MUX 2 + +/* This Shift Register is used as the Key Matrix Column Driver */ +/* It uses four lines from the MCU to provide 16 output lines */ +/* Shift Register Clock configuration (MCU to ShiftRegister.RCLK) */ +#define SR_KC_RCLK_PORT PB +#define SR_KC_RCLK_PIN 6 +/* Shift Register Output Enable configuration (MCU to ShiftRegister.OE_N) */ +#define SR_KC_OE_N_PORT PB +#define SR_KC_OE_N_PIN 7 +/* SERCOM port to use for Shift Register SPI */ +/* DATAOUT and SCLK must be configured to use hardware pins of this port */ +#define SR_KC_SERCOM_NUM 4 +/* Shift Register SPI Data Out configuration (MCU.SERCOMx.PAD[0] to ShiftRegister.SER) */ +#define SR_KC_DATAOUT_PORT PB +#define SR_KC_DATAOUT_PIN 8 +#define SR_KC_DATAOUT_MUX 3 +/* Shift Register SPI Serial Clock configuration (MCU.SERCOMx.PAD[1] to ShiftRegister.SRCLK) */ +#define SR_KC_SCLK_PORT PB +#define SR_KC_SCLK_PIN 9 +#define SR_KC_SCLK_MUX 3 + +/* Debug LED (Small LED Located near MCU) */ +/* PCB M15 */ +#define DEBUG_LED_ENABLE 1 +#define DEBUG_LED_PORT PA +#define DEBUG_LED_PIN 27 + +/* Additional debugging ports */ +/* PCB M44 */ +#define DEBUG_PORT1_ENABLE 1 +#define DEBUG_PORT1_PORT PB +#define DEBUG_PORT1_PIN 31 +/* PCB M45 */ +#define DEBUG_PORT2_ENABLE 1 +#define DEBUG_PORT2_PORT PB +#define DEBUG_PORT2_PIN 10 +/* PCB M46 */ +#define DEBUG_PORT3_ENABLE 1 +#define DEBUG_PORT3_PORT PB +#define DEBUG_PORT3_PIN 11 + +/* Debug Boot Tracing - During boot sequence, ground this pin to halt and display debug code using Debug LED */ +/* This is useful in determining which hardware device may have malfunctioned or is improperly configured */ +/* Feature is automatically disabled after successful boot */ +/* PCB M27 */ +#define DEBUG_BOOT_TRACING_ENABLE 1 +#define DEBUG_BOOT_TRACING_PORT PB +#define DEBUG_BOOT_TRACING_PIN 23 + +/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ +#define DEBOUNCING_DELAY 5 + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +//#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +//#define LOCKING_RESYNC_ENABLE + +/* Force boot in NKRO mode */ +//#define FORCE_NKRO + +/* + * Feature disable options + * These options are also useful to firmware size reduction. + */ + +/* disable debug print */ +//#define NO_DEBUG + +/* disable print */ +//#define NO_PRINT + +/* disable action features */ +//#define NO_ACTION_LAYER +//#define NO_ACTION_TAPPING +//#define NO_ACTION_ONESHOT +//#define NO_ACTION_MACRO +//#define NO_ACTION_FUNCTION + +#define RGB_MATRIX_KEYPRESSES +#define RGB_MATRIX_LED_PROCESS_LIMIT 15 +#define RGB_MATRIX_LED_FLUSH_LIMIT 10 +#define RGB_MATRIX_EXTRA_TOG + +#include "config_led.h" diff --git a/keyboards/massdrop/shift/config_adc.h b/keyboards/massdrop/shift/config_adc.h new file mode 100644 index 00000000000..94b5a1413ec --- /dev/null +++ b/keyboards/massdrop/shift/config_adc.h @@ -0,0 +1,118 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +//ADC configuration table column indices +#define ADC_PORT 0 +#define ADC_PIN 1 +#define ADC_MUX 2 +#define ADC_INDEX 3 +#define ADC_MUXPOS 4 +#define ADC_REFSEL 5 +#define ADC_SAMPLENUM 6 +#define ADC_SAMPLEN 7 + +//ADC configuration table row indices +#define ADC_5V 0 //5V bus voltage +#define ADC_C1A5 1 //Connector 1 A5 CC voltage +#define ADC_C1B5 2 //Connector 1 B5 CC voltage +#define ADC_C2A5 3 //Connector 2 A5 CC voltage +#define ADC_C2B5 4 //Connector 2 B5 CC voltage +#define ADC_C1I 5 //Connector 1 current +#define ADC_C2I 6 //Connector 2 current + +//ADC_PORT: PORT of the PIN on the MCU (Ex: 0 = PA, 1 = PB, ...) +// Set ADC_PORT to ADC_NA if it is not available for use +//ADC_PIN: PIN on the MCU (Ex: 0 = 00, 1 = 01, 12 = 12, ...) +//ADC_MUX: PMUX setting for the MCU PIN (Ex: 0 = A, 1 = B, 2 = C, ...) +//ADC_INDEX: ADC to use (Ex: 0 = ADC0, 1 = ADC1, ...) +//ADC_MUXPOS: MUXPOS setting to read on the ADC (Use macros from Atmel library adc.h ADC_INPUTCTRL_MUXPOS_AIN*_Val) +//ADC_REFSEL: Reference the ADC is to use (Use macros from Atmel library adc.h ADC_REFCTRL_REFSEL_*_Val) +//ADC_SAMPLENUM: Number of samples to average for output (Use macros from Atmel library adc.h ADC_AVGCTRL_SAMPLENUM_*_Val) +//ADC_SAMPLEN: Sampling time for each sample in units of CLK_ADC cycles depending on the ADC clock frequency +// ADC_PORT ADC_MUX +// | ADC_PIN | ADC_INDEX +// | | | | ADC_MUXPOS ADC_REFSEL ADC_SAMPLENUM ADC_SAMPLEN +#define ADC_CONFIG_5V 1, 0, 1, 0, ADC_INPUTCTRL_MUXPOS_AIN12_Val, ADC_REFCTRL_REFSEL_INTREF_Val, ADC_AVGCTRL_SAMPLENUM_4_Val, 45 +#define ADC_CONFIG_C1A5 1, 2, 1, 0, ADC_INPUTCTRL_MUXPOS_AIN14_Val, ADC_REFCTRL_REFSEL_INTREF_Val, ADC_AVGCTRL_SAMPLENUM_4_Val, 63 +#define ADC_CONFIG_C1B5 1, 4, 1, 1, ADC_INPUTCTRL_MUXPOS_AIN6_Val, ADC_REFCTRL_REFSEL_INTREF_Val, ADC_AVGCTRL_SAMPLENUM_4_Val, 63 +#define ADC_CONFIG_C2A5 1, 1, 1, 0, ADC_INPUTCTRL_MUXPOS_AIN13_Val, ADC_REFCTRL_REFSEL_INTREF_Val, ADC_AVGCTRL_SAMPLENUM_4_Val, 63 +#define ADC_CONFIG_C2B5 1, 5, 1, 1, ADC_INPUTCTRL_MUXPOS_AIN7_Val, ADC_REFCTRL_REFSEL_INTREF_Val, ADC_AVGCTRL_SAMPLENUM_4_Val, 63 +#define ADC_CONFIG_C1I 0, 10, 1, 0, ADC_INPUTCTRL_MUXPOS_AIN10_Val, ADC_REFCTRL_REFSEL_INTVCC1_Val, ADC_AVGCTRL_SAMPLENUM_4_Val, 45 +#define ADC_CONFIG_C2I 0, 11, 1, 0, ADC_INPUTCTRL_MUXPOS_AIN11_Val, ADC_REFCTRL_REFSEL_INTVCC1_Val, ADC_AVGCTRL_SAMPLENUM_4_Val, 45 + +//Conversion values dependant upon the circuitry +#define ADC_I_MILLIAMPS_PER_COUNT -0.000980472f +#define ADC_I_MILLIAMPS_OFFSET 1.979711769f +#define ADC_5V_VOLTS_PER_COUNT 0.001904297f +#define ADC_5V_VOLTS_OFFSET 0.0f +#define ADC_5V_NOMINAL 5.0f +#define ADC_5V_NOMINAL_COUNTS (ADC_5V_NOMINAL / ADC_5V_VOLTS_PER_COUNT) + +//Conversion macros +#define ADC_CI_C2I(macounts) ((float)macounts * ADC_I_MILLIAMPS_PER_COUNT + ADC_I_MILLIAMPS_OFFSET) //Converts connector current counts to milliamps +#define ADC_CI_I2C(ma) (uint16_t)((((float)ma - ADC_I_MILLIAMPS_OFFSET) / ADC_I_MILLIAMPS_PER_COUNT)) //Converts milliamps to connector current counts +#define ADC_5V_C2V(icounts) ((float)icounts * ADC_5V_VOLTS_PER_COUNT + ADC_5V_VOLTS_OFFSET) //Converts 5V Bus counts to volts +#define ADC_5V_V2C(v) (uint16_t)((((float)v - ADC_5V_VOLTS_OFFSET) / ADC_5V_VOLTS_PER_COUNT)) //Converts 5V Bus volts to counts +#define ADC_CC_5VCOR(v5counts, cc) ((float)v5counts == 0 ? 0 : (uint16_t)(ADC_5V_NOMINAL_COUNTS / (float)v5counts * (float)cc)) //Corrects CC counts to nominal 5V value + +//Note: The extra port's onboard/external range is not reliable for onboard/external detection due to varying device implementations, +// so instead the extra port will follow the host port connection of onboard or external. We will still use +// a nominal value for device detection with a wider range though. +#define ADC_USBC_ONBOARD 951 //ADC value indicating the USB-C Connector is on main PCB +#define ADC_USBC_EXTERNAL 881 //ADC value indicating the USB-C Connector is on external PCB +#define ADC_USBC_RANGE ((ADC_USBC_ONBOARD - ADC_USBC_EXTERNAL) / 2) //Range of detection for extra port Rd +#define ADC_USBC_EXTRA_NOMINAL ((ADC_USBC_ONBOARD + ADC_USBC_EXTERNAL) / 2) //Nominal ADC value for detection of connected device +#define ADC_USBC_EXTRA_TOLERANCE (0.20f) //Tolerance for Rd +#define ADC_USBC_EXTRA_ADC_MAX ((float)ADC_USBC_EXTRA_NOMINAL + ((float)ADC_USBC_EXTRA_NOMINAL * ADC_USBC_EXTRA_TOLERANCE)) //Rd ADC max counts +#define ADC_USBC_EXTRA_ADC_MIN ((float)ADC_USBC_EXTRA_NOMINAL - ((float)ADC_USBC_EXTRA_NOMINAL * ADC_USBC_EXTRA_TOLERANCE)) //Rd ADC min counts + +#define USBC_IS_SINK(a5, b5) ((a5 > ADC_USBC_EXTRA_ADC_MIN && a5 < ADC_USBC_EXTRA_ADC_MAX) || \ + (b5 > ADC_USBC_EXTRA_ADC_MIN && b5 < ADC_USBC_EXTRA_ADC_MAX)) + +#define ADC_USBC_RP_DELTA_MAX 400 //Amount of noise to tolerate for Rp detection (this can be very generous as long as ranges do not overlap) + +#define ADC_USBC_RP_TYPES 3 //56k, 22k, 10k +#define ADC_USBC_CON_TYPES 2 //Onboard, External +#define ADC_USBC_TYPES (ADC_USBC_RP_TYPES * ADC_USBC_CON_TYPES) + +//These are the indices for ADC_USBC_RP_NOM +//xxK is a ADC_USBC_RP_TYPES +//ONB is for the onboard USB-C Connector and must have an even index number +//EXT is for the external USB-C Connector and must have an odd index number +#define ADC_USBC_56K_ONB 0 +#define ADC_USBC_56K_EXT 1 +#define ADC_USBC_22K_ONB 2 +#define ADC_USBC_22K_EXT 3 +#define ADC_USBC_10K_ONB 4 +#define ADC_USBC_10K_EXT 5 + +#define ADC_USBC_IS_ONB(a) (a % 2 == 0) //Given a ADC_USBC_RP_NOM index, return true if the index refers to an onboard connector +#define ADC_USBC_IS_EXT(a) (a % 2 == 1) //Given a ADC_USBC_RP_NOM index, return true if the index refers to an external connector + +//These values are for detecting whether or not the host is connected through the onboard USB or external USB +//The counts are calculated from a nominal 5V bus, then scaled depending on the measured 5V bus +//External connectors are detected through addition of a resistor to slightly drop readings while remaining within USB-C CC tolerances +//Set a value to -1 if it is not supported +//Source Rp 56k-Onb 56k-Ext 22k-Onb 22k-Ext 10k-Onb 10k-Ext +#define ADC_USBC_RP_NOM 999, 852, 2232, 1940, 3955, 3528 + +extern uint16_t adc_usbc_rp_nominal[ADC_USBC_TYPES]; + +#define POWER_CHECK_INTERVAL 1 //How often to check power usage for adjustment and safety (ms) +#define V_5V_AVGS 20 //Number of 5V readings to average for algorithms wanting stable readings rather than instantaneous diff --git a/keyboards/massdrop/shift/config_led.h b/keyboards/massdrop/shift/config_led.h new file mode 100644 index 00000000000..6dda5b5ffa2 --- /dev/null +++ b/keyboards/massdrop/shift/config_led.h @@ -0,0 +1,233 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +//Define number of IS31FL3733 drivers being used (1...16) +#define ISSI3733_DRIVER_COUNT 3 +#define DRIVER_LED_TOTAL ISSI3733_LED_COUNT + +//Hardware address of each driver (Refer to IS31FL3733 pdf "Table 1 Slave Address" and keyboard schematic) +#define ISSI3773_DRIVER_ADDRESSES { 0xA0, 0xBE, 0xA6 } + +//LED I2C bus speed +#define I2C_HZ 870000 + +//Count of LED bodies +#define ISSI3733_LED_COUNT 160 + +#define LED_GCR_MAX 165 //Max GCR value (0 - 255) WARNING: Raising this value may overload the LED drivers and USB bus +#define LED_GCR_STEP 10 //GCR increment/decrement value + +#ifdef USE_MASSDROP_CONFIGURATOR +#define ANIMATION_SPEED_STEP 1 + +#define BREATHE_STEP 1 +#define BREATHE_MIN_STEP 0 +#define BREATHE_MAX_STEP 255 +#endif + +//Default Global Current Register value (Default brightness 0 - 255) +#define ISSI3733_GCR_DEFAULT LED_GCR_MAX + +//Automatic power rollback and recovery +#define V5_HIGH 2494 //5V high level (After low power detect, point at which LEDs are allowed to use more power ) +#define V5_LOW 2434 //5V low level (LED power rolled back to stay above this limit) +#define V5_CAT 2206 //5V catastrophic level (Host USB port potential to shut down) + +//LED Mapping - More practically generated from a spreadsheet program +//id: ID of the LED (Sync with PCB callouts) +//x: Physical X coordinate of LED (units do not matter) +//y: Physical Y coordinate of LED (units do not matter) +//drv: 1-Based index of ISSI3773_DRIVER_ADDRESSES +//cs: Matrix wiring CS col (1-16) +//swr: Matrix wiring SW Red row (1-12) +//swg: Matrix wiring SW Green row (1-12) +//swb: Matrix wiring SW Blue row (1-12) +//scan: Associated key matrix scancode (set 255 if none or 254 for LED to turn off in alternating mode) +//Note: Origin 0,0 may be located anywhere as the software will do the final layout +#define ISSI3733_LED_MAP { \ + { .id = 1, .x = 0.474, .y = 5.162, .adr = { .drv = 1, .cs = 1, .swr = 11, .swg = 10, .swb = 12 }, .scan = 0 }, \ + { .id = 2, .x = 1.974, .y = 5.162, .adr = { .drv = 1, .cs = 2, .swr = 11, .swg = 10, .swb = 12 }, .scan = 1 }, \ + { .id = 3, .x = 2.724, .y = 5.162, .adr = { .drv = 1, .cs = 3, .swr = 11, .swg = 10, .swb = 12 }, .scan = 2 }, \ + { .id = 4, .x = 3.474, .y = 5.162, .adr = { .drv = 1, .cs = 4, .swr = 11, .swg = 10, .swb = 12 }, .scan = 18 }, \ + { .id = 5, .x = 4.224, .y = 5.162, .adr = { .drv = 1, .cs = 5, .swr = 11, .swg = 10, .swb = 12 }, .scan = 3 }, \ + { .id = 6, .x = 5.349, .y = 5.162, .adr = { .drv = 1, .cs = 7, .swr = 11, .swg = 10, .swb = 12 }, .scan = 4 }, \ + { .id = 7, .x = 6.099, .y = 5.162, .adr = { .drv = 1, .cs = 8, .swr = 11, .swg = 10, .swb = 12 }, .scan = 5 }, \ + { .id = 8, .x = 6.849, .y = 5.162, .adr = { .drv = 1, .cs = 9, .swr = 11, .swg = 10, .swb = 12 }, .scan = 6 }, \ + { .id = 9, .x = 7.599, .y = 5.162, .adr = { .drv = 1, .cs = 10, .swr = 11, .swg = 10, .swb = 12 }, .scan = 22 }, \ + { .id = 10, .x = 8.724, .y = 5.162, .adr = { .drv = 2, .cs = 1, .swr = 11, .swg = 10, .swb = 12 }, .scan = 7 }, \ + { .id = 11, .x = 9.474, .y = 5.162, .adr = { .drv = 2, .cs = 2, .swr = 11, .swg = 10, .swb = 12 }, .scan = 23 }, \ + { .id = 12, .x = 10.224, .y = 5.162, .adr = { .drv = 2, .cs = 3, .swr = 11, .swg = 10, .swb = 12 }, .scan = 8 }, \ + { .id = 13, .x = 10.974, .y = 5.162, .adr = { .drv = 2, .cs = 4, .swr = 11, .swg = 10, .swb = 12 }, .scan = 24 }, \ + { .id = 14, .x = 12.099, .y = 5.162, .adr = { .drv = 2, .cs = 5, .swr = 11, .swg = 10, .swb = 12 }, .scan = 9 }, \ + { .id = 15, .x = 12.849, .y = 5.162, .adr = { .drv = 2, .cs = 6, .swr = 11, .swg = 10, .swb = 12 }, .scan = 10 }, \ + { .id = 16, .x = 13.599, .y = 5.162, .adr = { .drv = 2, .cs = 7, .swr = 11, .swg = 10, .swb = 12 }, .scan = 11 }, \ + { .id = 17, .x = 14.349, .y = 5.162, .adr = { .drv = 2, .cs = 8, .swr = 11, .swg = 10, .swb = 12 }, .scan = 12 }, \ + { .id = 18, .x = 12.099, .y = 4.412, .adr = { .drv = 2, .cs = 5, .swr = 8, .swg = 7, .swb = 9 }, .scan = 25 }, \ + { .id = 19, .x = 12.849, .y = 4.412, .adr = { .drv = 2, .cs = 6, .swr = 8, .swg = 7, .swb = 9 }, .scan = 26 }, \ + { .id = 20, .x = 13.599, .y = 4.412, .adr = { .drv = 2, .cs = 7, .swr = 8, .swg = 7, .swb = 9 }, .scan = 27 }, \ + { .id = 21, .x = 14.349, .y = 4.412, .adr = { .drv = 2, .cs = 8, .swr = 8, .swg = 7, .swb = 9 }, .scan = 28 }, \ + { .id = 22, .x = 0.474, .y = 3.662, .adr = { .drv = 1, .cs = 1, .swr = 8, .swg = 7, .swb = 9 }, .scan = 16 }, \ + { .id = 23, .x = 1.224, .y = 3.662, .adr = { .drv = 1, .cs = 11, .swr = 8, .swg = 7, .swb = 9 }, .scan = 17 }, \ + { .id = 24, .x = 1.974, .y = 3.662, .adr = { .drv = 1, .cs = 2, .swr = 8, .swg = 7, .swb = 9 }, .scan = 33 }, \ + { .id = 25, .x = 2.724, .y = 3.662, .adr = { .drv = 1, .cs = 3, .swr = 8, .swg = 7, .swb = 9 }, .scan = 34 }, \ + { .id = 26, .x = 3.474, .y = 3.662, .adr = { .drv = 1, .cs = 4, .swr = 8, .swg = 7, .swb = 9 }, .scan = 50 }, \ + { .id = 27, .x = 4.224, .y = 3.662, .adr = { .drv = 1, .cs = 5, .swr = 8, .swg = 7, .swb = 9 }, .scan = 19 }, \ + { .id = 28, .x = 4.974, .y = 3.662, .adr = { .drv = 1, .cs = 6, .swr = 8, .swg = 7, .swb = 9 }, .scan = 35 }, \ + { .id = 29, .x = 5.724, .y = 3.662, .adr = { .drv = 1, .cs = 7, .swr = 8, .swg = 7, .swb = 9 }, .scan = 20 }, \ + { .id = 30, .x = 6.474, .y = 3.662, .adr = { .drv = 1, .cs = 8, .swr = 8, .swg = 7, .swb = 9 }, .scan = 21 }, \ + { .id = 31, .x = 7.224, .y = 3.662, .adr = { .drv = 1, .cs = 9, .swr = 8, .swg = 7, .swb = 9 }, .scan = 37 }, \ + { .id = 32, .x = 7.974, .y = 3.662, .adr = { .drv = 1, .cs = 10, .swr = 8, .swg = 7, .swb = 9 }, .scan = 38 }, \ + { .id = 33, .x = 8.724, .y = 3.662, .adr = { .drv = 2, .cs = 1, .swr = 5, .swg = 4, .swb = 6 }, .scan = 54 }, \ + { .id = 34, .x = 9.474, .y = 3.662, .adr = { .drv = 2, .cs = 2, .swr = 5, .swg = 4, .swb = 6 }, .scan = 39 }, \ + { .id = 35, .x = 10.599, .y = 3.662, .adr = { .drv = 2, .cs = 4, .swr = 5, .swg = 4, .swb = 6 }, .scan = 40 }, \ + { .id = 36, .x = 12.099, .y = 3.662, .adr = { .drv = 2, .cs = 5, .swr = 5, .swg = 4, .swb = 6 }, .scan = 41 }, \ + { .id = 37, .x = 12.849, .y = 3.662, .adr = { .drv = 2, .cs = 6, .swr = 5, .swg = 4, .swb = 6 }, .scan = 42 }, \ + { .id = 38, .x = 13.599, .y = 3.662, .adr = { .drv = 2, .cs = 7, .swr = 5, .swg = 4, .swb = 6 }, .scan = 43 }, \ + { .id = 39, .x = 14.349, .y = 3.662, .adr = { .drv = 2, .cs = 8, .swr = 5, .swg = 4, .swb = 6 }, .scan = 44 }, \ + { .id = 40, .x = 0.662, .y = 2.912, .adr = { .drv = 1, .cs = 1, .swr = 5, .swg = 4, .swb = 6 }, .scan = 32 }, \ + { .id = 41, .x = 1.599, .y = 2.912, .adr = { .drv = 1, .cs = 2, .swr = 5, .swg = 4, .swb = 6 }, .scan = 49 }, \ + { .id = 42, .x = 2.349, .y = 2.912, .adr = { .drv = 1, .cs = 3, .swr = 5, .swg = 4, .swb = 6 }, .scan = 65 }, \ + { .id = 43, .x = 3.099, .y = 2.912, .adr = { .drv = 1, .cs = 4, .swr = 5, .swg = 4, .swb = 6 }, .scan = 66 }, \ + { .id = 44, .x = 3.849, .y = 2.912, .adr = { .drv = 1, .cs = 5, .swr = 5, .swg = 4, .swb = 6 }, .scan = 51 }, \ + { .id = 45, .x = 4.599, .y = 2.912, .adr = { .drv = 1, .cs = 6, .swr = 5, .swg = 4, .swb = 6 }, .scan = 67 }, \ + { .id = 46, .x = 5.349, .y = 2.912, .adr = { .drv = 1, .cs = 7, .swr = 5, .swg = 4, .swb = 6 }, .scan = 36 }, \ + { .id = 47, .x = 6.099, .y = 2.912, .adr = { .drv = 1, .cs = 8, .swr = 5, .swg = 4, .swb = 6 }, .scan = 52 }, \ + { .id = 48, .x = 6.849, .y = 2.912, .adr = { .drv = 1, .cs = 9, .swr = 5, .swg = 4, .swb = 6 }, .scan = 53 }, \ + { .id = 49, .x = 7.599, .y = 2.912, .adr = { .drv = 1, .cs = 10, .swr = 5, .swg = 4, .swb = 6 }, .scan = 69 }, \ + { .id = 50, .x = 8.349, .y = 2.912, .adr = { .drv = 2, .cs = 1, .swr = 2, .swg = 1, .swb = 3 }, .scan = 70 }, \ + { .id = 51, .x = 9.099, .y = 2.912, .adr = { .drv = 2, .cs = 2, .swr = 2, .swg = 1, .swb = 3 }, .scan = 55 }, \ + { .id = 52, .x = 9.849, .y = 2.912, .adr = { .drv = 2, .cs = 3, .swr = 2, .swg = 1, .swb = 3 }, .scan = 56 }, \ + { .id = 53, .x = 10.787, .y = 2.912, .adr = { .drv = 2, .cs = 4, .swr = 2, .swg = 1, .swb = 3 }, .scan = 72 }, \ + { .id = 54, .x = 12.099, .y = 2.912, .adr = { .drv = 2, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 57 }, \ + { .id = 55, .x = 12.849, .y = 2.912, .adr = { .drv = 2, .cs = 6, .swr = 2, .swg = 1, .swb = 3 }, .scan = 58 }, \ + { .id = 56, .x = 13.599, .y = 2.912, .adr = { .drv = 2, .cs = 7, .swr = 2, .swg = 1, .swb = 3 }, .scan = 59 }, \ + { .id = 57, .x = 14.349, .y = 2.912, .adr = { .drv = 2, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 60 }, \ + { .id = 58, .x = 0.756, .y = 2.162, .adr = { .drv = 1, .cs = 1, .swr = 2, .swg = 1, .swb = 3 }, .scan = 48 }, \ + { .id = 59, .x = 1.787, .y = 2.162, .adr = { .drv = 1, .cs = 2, .swr = 2, .swg = 1, .swb = 3 }, .scan = 81 }, \ + { .id = 60, .x = 2.537, .y = 2.162, .adr = { .drv = 1, .cs = 3, .swr = 2, .swg = 1, .swb = 3 }, .scan = 97 }, \ + { .id = 61, .x = 3.287, .y = 2.162, .adr = { .drv = 1, .cs = 4, .swr = 2, .swg = 1, .swb = 3 }, .scan = 82 }, \ + { .id = 62, .x = 4.037, .y = 2.162, .adr = { .drv = 1, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 83 }, \ + { .id = 63, .x = 4.787, .y = 2.162, .adr = { .drv = 1, .cs = 6, .swr = 2, .swg = 1, .swb = 3 }, .scan = 99 }, \ + { .id = 64, .x = 5.537, .y = 2.162, .adr = { .drv = 1, .cs = 7, .swr = 2, .swg = 1, .swb = 3 }, .scan = 68 }, \ + { .id = 65, .x = 6.287, .y = 2.162, .adr = { .drv = 1, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 84 }, \ + { .id = 66, .x = 7.037, .y = 2.162, .adr = { .drv = 1, .cs = 9, .swr = 2, .swg = 1, .swb = 3 }, .scan = 85 }, \ + { .id = 67, .x = 7.787, .y = 2.162, .adr = { .drv = 1, .cs = 10, .swr = 2, .swg = 1, .swb = 3 }, .scan = 86 }, \ + { .id = 68, .x = 8.537, .y = 2.162, .adr = { .drv = 2, .cs = 9, .swr = 2, .swg = 1, .swb = 3 }, .scan = 71 }, \ + { .id = 69, .x = 9.287, .y = 2.162, .adr = { .drv = 2, .cs = 10, .swr = 2, .swg = 1, .swb = 3 }, .scan = 88 }, \ + { .id = 70, .x = 10.506, .y = 2.162, .adr = { .drv = 2, .cs = 11, .swr = 2, .swg = 1, .swb = 3 }, .scan = 104 }, \ + { .id = 71, .x = 12.099, .y = 2.162, .adr = { .drv = 2, .cs = 13, .swr = 2, .swg = 1, .swb = 3 }, .scan = 73 }, \ + { .id = 72, .x = 12.849, .y = 2.162, .adr = { .drv = 2, .cs = 14, .swr = 2, .swg = 1, .swb = 3 }, .scan = 74 }, \ + { .id = 73, .x = 13.599, .y = 2.162, .adr = { .drv = 2, .cs = 15, .swr = 2, .swg = 1, .swb = 3 }, .scan = 75 }, \ + { .id = 74, .x = 14.349, .y = 2.162, .adr = { .drv = 2, .cs = 16, .swr = 2, .swg = 1, .swb = 3 }, .scan = 76 }, \ + { .id = 75, .x = 0.943, .y = 1.412, .adr = { .drv = 1, .cs = 11, .swr = 2, .swg = 1, .swb = 3 }, .scan = 64 }, \ + { .id = 76, .x = 2.162, .y = 1.412, .adr = { .drv = 1, .cs = 12, .swr = 2, .swg = 1, .swb = 3 }, .scan = 113 }, \ + { .id = 77, .x = 2.912, .y = 1.412, .adr = { .drv = 1, .cs = 13, .swr = 2, .swg = 1, .swb = 3 }, .scan = 98 }, \ + { .id = 78, .x = 3.662, .y = 1.412, .adr = { .drv = 1, .cs = 13, .swr = 8, .swg = 7, .swb = 9 }, .scan = 114 }, \ + { .id = 79, .x = 4.412, .y = 1.412, .adr = { .drv = 1, .cs = 14, .swr = 8, .swg = 7, .swb = 9 }, .scan = 115 }, \ + { .id = 80, .x = 5.162, .y = 1.412, .adr = { .drv = 1, .cs = 14, .swr = 2, .swg = 1, .swb = 3 }, .scan = 100 }, \ + { .id = 81, .x = 5.912, .y = 1.412, .adr = { .drv = 1, .cs = 15, .swr = 5, .swg = 4, .swb = 6 }, .scan = 117 }, \ + { .id = 82, .x = 6.662, .y = 1.412, .adr = { .drv = 1, .cs = 15, .swr = 2, .swg = 1, .swb = 3 }, .scan = 101 }, \ + { .id = 83, .x = 7.414, .y = 1.41, .adr = { .drv = 1, .cs = 16, .swr = 2, .swg = 1, .swb = 3 }, .scan = 102 }, \ + { .id = 84, .x = 8.162, .y = 1.412, .adr = { .drv = 2, .cs = 9, .swr = 5, .swg = 4, .swb = 6 }, .scan = 87 }, \ + { .id = 85, .x = 8.912, .y = 1.412, .adr = { .drv = 2, .cs = 10, .swr = 5, .swg = 4, .swb = 6 }, .scan = 103 }, \ + { .id = 86, .x = 9.943, .y = 1.412, .adr = { .drv = 2, .cs = 11, .swr = 5, .swg = 4, .swb = 6 }, .scan = 120 }, \ + { .id = 87, .x = 12.099, .y = 1.412, .adr = { .drv = 2, .cs = 13, .swr = 5, .swg = 4, .swb = 6 }, .scan = 89 }, \ + { .id = 88, .x = 12.849, .y = 1.412, .adr = { .drv = 2, .cs = 14, .swr = 5, .swg = 4, .swb = 6 }, .scan = 90 }, \ + { .id = 89, .x = 13.599, .y = 1.412, .adr = { .drv = 2, .cs = 15, .swr = 5, .swg = 4, .swb = 6 }, .scan = 91 }, \ + { .id = 90, .x = 11.162, .y = 1.224, .adr = { .drv = 2, .cs = 12, .swr = 5, .swg = 4, .swb = 6 }, .scan = 105 }, \ + { .id = 91, .x = 14.349, .y = 1.037, .adr = { .drv = 2, .cs = 16, .swr = 8, .swg = 7, .swb = 9 }, .scan = 92 }, \ + { .id = 92, .x = 0.568, .y = 0.662, .adr = { .drv = 1, .cs = 11, .swr = 5, .swg = 4, .swb = 6 }, .scan = 80 }, \ + { .id = 93, .x = 1.506, .y = 0.662, .adr = { .drv = 1, .cs = 12, .swr = 5, .swg = 4, .swb = 6 }, .scan = 96 }, \ + { .id = 94, .x = 2.443, .y = 0.662, .adr = { .drv = 1, .cs = 13, .swr = 5, .swg = 4, .swb = 6 }, .scan = 112 }, \ + { .id = 95, .x = 5.256, .y = 0.662, .adr = { .drv = 1, .cs = 14, .swr = 5, .swg = 4, .swb = 6 }, .scan = 116 }, \ + { .id = 96, .x = 8.162, .y = 0.662, .adr = { .drv = 2, .cs = 9, .swr = 8, .swg = 7, .swb = 9 }, .scan = 118 }, \ + { .id = 97, .x = 9.287, .y = 0.662, .adr = { .drv = 2, .cs = 10, .swr = 8, .swg = 7, .swb = 9 }, .scan = 119 }, \ + { .id = 98, .x = 12.849, .y = 0.662, .adr = { .drv = 2, .cs = 14, .swr = 8, .swg = 7, .swb = 9 }, .scan = 107 }, \ + { .id = 99, .x = 13.599, .y = 0.662, .adr = { .drv = 2, .cs = 15, .swr = 8, .swg = 7, .swb = 9 }, .scan = 108 }, \ + { .id = 100, .x = 10.412, .y = 0.474, .adr = { .drv = 2, .cs = 11, .swr = 8, .swg = 7, .swb = 9 }, .scan = 121 }, \ + { .id = 101, .x = 11.162, .y = 0.474, .adr = { .drv = 2, .cs = 12, .swr = 8, .swg = 7, .swb = 9 }, .scan = 122 }, \ + { .id = 102, .x = 11.912, .y = 0.474, .adr = { .drv = 2, .cs = 13, .swr = 8, .swg = 7, .swb = 9 }, .scan = 106 }, \ + { .id = 103, .x = 0.168, .y = 5.468, .adr = { .drv = 3, .cs = 1, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 104, .x = 0.827, .y = 5.571, .adr = { .drv = 3, .cs = 1, .swr = 5, .swg = 4, .swb = 6 }, .scan = 254 }, \ + { .id = 105, .x = 2.144, .y = 5.571, .adr = { .drv = 3, .cs = 2, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 106, .x = 2.802, .y = 5.571, .adr = { .drv = 3, .cs = 3, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ + { .id = 107, .x = 3.461, .y = 5.571, .adr = { .drv = 3, .cs = 3, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 108, .x = 4.119, .y = 5.571, .adr = { .drv = 3, .cs = 4, .swr = 5, .swg = 4, .swb = 6 }, .scan = 254 }, \ + { .id = 109, .x = 4.778, .y = 5.571, .adr = { .drv = 3, .cs = 4, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 110, .x = 5.436, .y = 5.571, .adr = { .drv = 3, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ + { .id = 111, .x = 6.095, .y = 5.571, .adr = { .drv = 3, .cs = 5, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 112, .x = 6.753, .y = 5.571, .adr = { .drv = 3, .cs = 6, .swr = 5, .swg = 4, .swb = 6 }, .scan = 254 }, \ + { .id = 113, .x = 7.412, .y = 5.571, .adr = { .drv = 3, .cs = 6, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 114, .x = 8.07, .y = 5.571, .adr = { .drv = 3, .cs = 7, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ + { .id = 115, .x = 8.729, .y = 5.571, .adr = { .drv = 3, .cs = 7, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 116, .x = 9.387, .y = 5.571, .adr = { .drv = 3, .cs = 8, .swr = 5, .swg = 4, .swb = 6 }, .scan = 254 }, \ + { .id = 117, .x = 10.046, .y = 5.571, .adr = { .drv = 3, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 118, .x = 10.704, .y = 5.571, .adr = { .drv = 3, .cs = 9, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ + { .id = 119, .x = 11.363, .y = 5.571, .adr = { .drv = 3, .cs = 9, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 120, .x = 12.021, .y = 5.571, .adr = { .drv = 3, .cs = 10, .swr = 5, .swg = 4, .swb = 6 }, .scan = 254 }, \ + { .id = 121, .x = 12.68, .y = 5.571, .adr = { .drv = 3, .cs = 10, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 122, .x = 13.997, .y = 5.571, .adr = { .drv = 3, .cs = 11, .swr = 5, .swg = 4, .swb = 6 }, .scan = 254 }, \ + { .id = 123, .x = 14.656, .y = 5.468, .adr = { .drv = 3, .cs = 11, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 124, .x = 14.759, .y = 4.806, .adr = { .drv = 3, .cs = 12, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ + { .id = 125, .x = 14.759, .y = 4.143, .adr = { .drv = 3, .cs = 12, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 126, .x = 14.759, .y = 3.481, .adr = { .drv = 3, .cs = 12, .swr = 11, .swg = 10, .swb = 12 }, .scan = 254 }, \ + { .id = 127, .x = 14.759, .y = 2.818, .adr = { .drv = 3, .cs = 13, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 128, .x = 14.759, .y = 2.156, .adr = { .drv = 3, .cs = 13, .swr = 11, .swg = 10, .swb = 12 }, .scan = 254 }, \ + { .id = 129, .x = 14.759, .y = 1.493, .adr = { .drv = 3, .cs = 13, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 130, .x = 14.759, .y = 0.831, .adr = { .drv = 3, .cs = 14, .swr = 8, .swg = 7, .swb = 9 }, .scan = 254 }, \ + { .id = 131, .x = 14.656, .y = 0.168, .adr = { .drv = 3, .cs = 14, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ + { .id = 132, .x = 13.997, .y = 0.065, .adr = { .drv = 3, .cs = 11, .swr = 11, .swg = 10, .swb = 12 }, .scan = 254 }, \ + { .id = 133, .x = 13.338, .y = 0.065, .adr = { .drv = 3, .cs = 11, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 134, .x = 12.68, .y = 0.065, .adr = { .drv = 3, .cs = 10, .swr = 8, .swg = 7, .swb = 9 }, .scan = 254 }, \ + { .id = 135, .x = 12.021, .y = 0.065, .adr = { .drv = 3, .cs = 10, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ + { .id = 136, .x = 11.363, .y = 0.065, .adr = { .drv = 3, .cs = 9, .swr = 11, .swg = 10, .swb = 12 }, .scan = 254 }, \ + { .id = 137, .x = 10.704, .y = 0.065, .adr = { .drv = 3, .cs = 9, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 138, .x = 10.046, .y = 0.065, .adr = { .drv = 3, .cs = 8, .swr = 8, .swg = 7, .swb = 9 }, .scan = 254 }, \ + { .id = 139, .x = 9.387, .y = 0.065, .adr = { .drv = 3, .cs = 8, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ + { .id = 140, .x = 8.729, .y = 0.065, .adr = { .drv = 3, .cs = 7, .swr = 11, .swg = 10, .swb = 12 }, .scan = 254 }, \ + { .id = 141, .x = 8.07, .y = 0.065, .adr = { .drv = 3, .cs = 7, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 142, .x = 7.412, .y = 0.065, .adr = { .drv = 3, .cs = 6, .swr = 8, .swg = 7, .swb = 9 }, .scan = 254 }, \ + { .id = 143, .x = 6.753, .y = 0.065, .adr = { .drv = 3, .cs = 6, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ + { .id = 144, .x = 6.095, .y = 0.065, .adr = { .drv = 3, .cs = 5, .swr = 11, .swg = 10, .swb = 12 }, .scan = 254 }, \ + { .id = 145, .x = 5.436, .y = 0.065, .adr = { .drv = 3, .cs = 5, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 146, .x = 4.778, .y = 0.065, .adr = { .drv = 3, .cs = 4, .swr = 8, .swg = 7, .swb = 9 }, .scan = 254 }, \ + { .id = 147, .x = 4.119, .y = 0.065, .adr = { .drv = 3, .cs = 4, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ + { .id = 148, .x = 3.461, .y = 0.065, .adr = { .drv = 3, .cs = 3, .swr = 11, .swg = 10, .swb = 12 }, .scan = 254 }, \ + { .id = 149, .x = 2.802, .y = 0.065, .adr = { .drv = 3, .cs = 3, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 150, .x = 2.144, .y = 0.065, .adr = { .drv = 3, .cs = 2, .swr = 8, .swg = 7, .swb = 9 }, .scan = 254 }, \ + { .id = 151, .x = 1.485, .y = 0.065, .adr = { .drv = 3, .cs = 2, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ + { .id = 152, .x = 0.827, .y = 0.065, .adr = { .drv = 3, .cs = 1, .swr = 11, .swg = 10, .swb = 12 }, .scan = 254 }, \ + { .id = 153, .x = 0.168, .y = 0.168, .adr = { .drv = 3, .cs = 1, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 154, .x = 0.065, .y = 0.831, .adr = { .drv = 3, .cs = 15, .swr = 8, .swg = 7, .swb = 9 }, .scan = 254 }, \ + { .id = 155, .x = 0.065, .y = 1.493, .adr = { .drv = 3, .cs = 15, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ + { .id = 156, .x = 0.065, .y = 2.156, .adr = { .drv = 3, .cs = 15, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ + { .id = 157, .x = 0.065, .y = 2.818, .adr = { .drv = 3, .cs = 15, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 158, .x = 0.065, .y = 3.481, .adr = { .drv = 3, .cs = 16, .swr = 11, .swg = 10, .swb = 12 }, .scan = 254 }, \ + { .id = 159, .x = 0.065, .y = 4.143, .adr = { .drv = 3, .cs = 16, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 160, .x = 0.065, .y = 4.806, .adr = { .drv = 3, .cs = 16, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 } \ +}; + +#define USB_LED_INDICATOR_ENABLE //Comment out to disable indicator functionality +#ifdef USB_LED_INDICATOR_ENABLE //Scan codes refer to actual key matrix codes, not KC_* (255 to disable) + #define USB_LED_NUM_LOCK_SCANCODE 41 + #define USB_LED_CAPS_LOCK_SCANCODE 48 + #define USB_LED_SCROLL_LOCK_SCANCODE 28 + #define USB_LED_COMPOSE_SCANCODE 255 + #define USB_LED_KANA_SCANCODE 255 +#endif //USB_LED_INDICATOR_ENABLE diff --git a/keyboards/massdrop/shift/config_spi.h b/keyboards/massdrop/shift/config_spi.h new file mode 100644 index 00000000000..bce1e0835d2 --- /dev/null +++ b/keyboards/massdrop/shift/config_spi.h @@ -0,0 +1,42 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +/* Data structure to define Shift Register output expander hardware */ +/* This structure gets shifted into registers LSB first */ +typedef union { + struct { + uint16_t RSVD4:1; /*!< bit: 0 */ + uint16_t SRC_2_B5:1; /*!< bit: 1 USBC-2 CC B5 UFP Rd 5.1k WHEN 1, DFP Rp 56k WHEN 0 */ + uint16_t SRC_1_B5:1; /*!< bit: 2 USBC-1 CC B5 UFP Rd 5.1k WHEN 1, DFP Rp 56k WHEN 0 */ + uint16_t S_B_EXT:1; /*!< bit: 3 B TO EX-1 WHEN 1, B TO USBC-1 WHEN 0 */ + uint16_t SDB_N:1; /*!< bit: 4 SHUTDOWN IS31FL3733 CHIPS WHEN 0, RUN WHEN 1 */ + uint16_t IRST:1; /*!< bit: 5 RESET IS31FL3733 I2C WHEN 1, RUN WHEN 0 */ + uint16_t SRC_2_A5:1; /*!< bit: 6 USBC-2 CC A5 UFP Rd 5.1k WHEN 1, DFP Rp 56k WHEN 0 */ + uint16_t SRC_1_A5:1; /*!< bit: 7 USBC-1 CC A5 UFP Rd 5.1k WHEN 1, DFP Rp 56k WHEN 0 */ + uint16_t E_VBUS_2:1; /*!< bit: 8 ENABLE 5V TO USBC-2/EX-2 WHEN 1, DISABLE WHEN 0 */ + uint16_t E_VBUS_1:1; /*!< bit: 9 ENABLE 5V TO USBC-1/EX-1 WHEN 1, DISABLE WHEN 0 */ + uint16_t ENB:1; /*!< bit: 10 ENABLE CHANNEL B USBC-1/EX-1 WHEN 1, DISABLE WHEN 0 */ + uint16_t S_A_EXT:1; /*!< bit: 11 A TO USBC-2 WHEN 1, A TO EX-2 WHEN 0 */ + uint16_t ENA:1; /*!< bit: 12 ENABLE CHANNEL A USBC-2/EX-2 WHEN 1, DISABLE WHEN 0 */ + uint16_t S_A_UP:1; /*!< bit: 13 DN1 TO A & UP TO B WHEN 1, DN1 TO B & UP TO A WHEN 0 */ + uint16_t HUB_RESET_N:1; /*!< bit: 14 RESET USB HUB WHEN 0, RUN WHEN 1 */ + uint16_t HUB_CONNECT:1; /*!< bit: 15 SIGNAL VBUS CONNECT TO USB HUB WHEN 1 */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} sr_exp_t; diff --git a/keyboards/massdrop/shift/config_usb.h b/keyboards/massdrop/shift/config_usb.h new file mode 100644 index 00000000000..9f02b12034c --- /dev/null +++ b/keyboards/massdrop/shift/config_usb.h @@ -0,0 +1,28 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +//Macros to Enable, Disable, and Update USB 5V bus connections +#define USBC_CFG_5V1_VAR sr_exp_data.bit.E_VBUS_1 //Variable storing USBC-1 5V Bus state +#define USBC_CFG_5V1_ENA 1 //Value to enable USBC-1 5V Bus +#define USBC_CFG_5V1_DIS 0 //Value to disable USBC-1 5V Bus +#define USBC_CFG_5V1_UPDATE SR_EXP_WriteData() //Command to run to update value +#define USBC_CFG_5V2_VAR sr_exp_data.bit.E_VBUS_2 //Variable storing USBC-2 5V Bus state +#define USBC_CFG_5V2_ENA 1 //Value to enable USBC-1 5V Bus +#define USBC_CFG_5V2_DIS 0 //Value to disable USBC-1 5V Bus +#define USBC_CFG_5V2_UPDATE SR_EXP_WriteData() //Command to run to update value diff --git a/keyboards/massdrop/shift/info.json b/keyboards/massdrop/shift/info.json new file mode 100644 index 00000000000..67373a717bd --- /dev/null +++ b/keyboards/massdrop/shift/info.json @@ -0,0 +1,101 @@ +//TODO: JSON +{ + "keyboard_name": "SHIFT", + "url": "https://www.massdrop.com/buy/massdrop-shift-mechanical-keyboard", + "maintainer": "Massdrop", + "width": 18.5, + "height": 6.5, + "layouts": { + "LAYOUT": { + "layout": [ + {"label":"ESCAPE", "x":0, "y":0}, + {"label":"F1", "x":2, "y":0}, + {"label":"F2", "x":3, "y":0}, + {"label":"F3", "x":4, "y":0}, + {"label":"F4", "x":5, "y":0}, + {"label":"F5", "x":6.5, "y":0}, + {"label":"F6", "x":7.5, "y":0}, + {"label":"F7", "x":8.5, "y":0}, + {"label":"F8", "x":9.5, "y":0}, + {"label":"F9", "x":11, "y":0}, + {"label":"F10", "x":12, "y":0}, + {"label":"F11", "x":13, "y":0}, + {"label":"F12", "x":14, "y":0}, + {"label":"PRINT SCREEN", "x":15.5, "y":0}, + {"label":"SCROLL LOCK", "x":16.5, "y":0}, + {"label":"PAUSE BREAK", "x":17.5, "y":0}, + {"label":"BACKTICK", "x":0, "y":1.5}, + {"label":"1", "x":1, "y":1.5}, + {"label":"2", "x":2, "y":1.5}, + {"label":"3", "x":3, "y":1.5}, + {"label":"4", "x":4, "y":1.5}, + {"label":"5", "x":5, "y":1.5}, + {"label":"6", "x":6, "y":1.5}, + {"label":"7", "x":7, "y":1.5}, + {"label":"8", "x":8, "y":1.5}, + {"label":"9", "x":9, "y":1.5}, + {"label":"0", "x":10, "y":1.5}, + {"label":"MINUS", "x":11, "y":1.5}, + {"label":"EQUALS", "x":12, "y":1.5}, + {"label":"BACKSPACE", "x":13, "y":1.5, "w":2}, + {"label":"INSERT", "x":15.5, "y":1.5}, + {"label":"HOME", "x":16.5, "y":1.5}, + {"label":"PAGE UP", "x":17.5, "y":1.5}, + {"label":"TAB", "x":0, "y":2.5, "w":1.5}, + {"label":"Q", "x":1.5, "y":2.5}, + {"label":"W", "x":2.5, "y":2.5}, + {"label":"E", "x":3.5, "y":2.5}, + {"label":"R", "x":4.5, "y":2.5}, + {"label":"T", "x":5.5, "y":2.5}, + {"label":"Y", "x":6.5, "y":2.5}, + {"label":"U", "x":7.5, "y":2.5}, + {"label":"I", "x":8.5, "y":2.5}, + {"label":"O", "x":9.5, "y":2.5}, + {"label":"P", "x":10.5, "y":2.5}, + {"label":"LEFT BRACKET", "x":11.5, "y":2.5}, + {"label":"RIGHT BRACKET", "x":12.5, "y":2.5}, + {"label":"BACK SLASH", "x":13.5, "y":2.5, "w":1.5}, + {"label":"DELETE", "x":15.5, "y":2.5}, + {"label":"END", "x":16.5, "y":2.5}, + {"label":"PAGE DOWN", "x":17.5, "y":2.5}, + {"label":"CAPS LOCK", "x":0, "y":3.5, "w":1.75}, + {"label":"A", "x":1.75, "y":3.5}, + {"label":"S", "x":2.75, "y":3.5}, + {"label":"D", "x":3.75, "y":3.5}, + {"label":"F", "x":4.75, "y":3.5}, + {"label":"G", "x":5.75, "y":3.5}, + {"label":"H", "x":6.75, "y":3.5}, + {"label":"J", "x":7.75, "y":3.5}, + {"label":"K", "x":8.75, "y":3.5}, + {"label":"L", "x":9.75, "y":3.5}, + {"label":"SEMICOLON", "x":10.75, "y":3.5}, + {"label":"SINGLE TICK", "x":11.75, "y":3.5}, + {"label":"ENTER", "x":12.75, "y":3.5, "w":2.25}, + {"label":"LEFT SHIFT", "x":0, "y":4.5, "w":2.25}, + {"label":"Z", "x":2.25, "y":4.5}, + {"label":"X", "x":3.25, "y":4.5}, + {"label":"C", "x":4.25, "y":4.5}, + {"label":"V", "x":5.25, "y":4.5}, + {"label":"B", "x":6.25, "y":4.5}, + {"label":"N", "x":7.25, "y":4.5}, + {"label":"M", "x":8.25, "y":4.5}, + {"label":"COMMA", "x":9.25, "y":4.5}, + {"label":"PERIOD", "x":10.25, "y":4.5}, + {"label":"FORWARD SLASH", "x":11.25, "y":4.5}, + {"label":"RIGHT SHIFT", "x":12.25, "y":4.5, "w":2.75}, + {"label":"UP ARROW", "x":16.5, "y":4.5}, + {"label":"LEFT CTRL", "x":0.005, "y":5.5, "w":1.24}, + {"label":"LEFT WIN", "x":1.255, "y":5.5, "w":1.24}, + {"label":"LEFT ALT", "x":2.505, "y":5.5, "w":1.24}, + {"label":"SPACEBAR", "x":3.75, "y":5.5, "w":6.25}, + {"label":"RIGHT ALT", "x":10, "y":5.5, "w":1.25}, + {"label":"FN", "x":11.25, "y":5.5, "w":1.25}, + {"label":"MENU", "x":12.5, "y":5.5, "w":1.25}, + {"label":"RIGHT CTRL", "x":13.75, "y":5.5, "w":1.25}, + {"label":"LEFT ARROW", "x":15.5, "y":5.5}, + {"label":"DOWN ARROW", "x":16.5, "y":5.5}, + {"label":"RIGHT ARROW", "x":17.5, "y":5.5} + ] + } + } +} diff --git a/keyboards/massdrop/shift/keymaps/default/keymap.c b/keyboards/massdrop/shift/keymaps/default/keymap.c new file mode 100644 index 00000000000..73f02d4aabb --- /dev/null +++ b/keyboards/massdrop/shift/keymaps/default/keymap.c @@ -0,0 +1,258 @@ +#include QMK_KEYBOARD_H + +enum ctrl_keycodes { + L_BRI = SAFE_RANGE, //LED Brightness Increase + L_BRD, //LED Brightness Decrease + L_EDG_I, //LED Edge Brightness Increase + L_EDG_D, //LED Edge Brightness Decrease + L_EDG_M, //LED Edge lighting mode + L_PTN, //LED Pattern Select Next + L_PTP, //LED Pattern Select Previous + L_PSI, //LED Pattern Speed Increase + L_PSD, //LED Pattern Speed Decrease + L_T_MD, //LED Toggle Mode + L_T_ONF, //LED Toggle On / Off + L_ON, //LED On + L_OFF, //LED Off + L_T_BR, //LED Toggle Breath Effect + L_T_PTD, //LED Toggle Scrolling Pattern Direction and effect + U_T_AGCR, //USB Toggle Automatic GCR control + DBG_TOG, //DEBUG Toggle On / Off + DBG_MTRX, //DEBUG Toggle Matrix Prints + DBG_KBD, //DEBUG Toggle Keyboard Prints + DBG_MOU, //DEBUG Toggle Mouse Prints + DBG_FAC, //DEBUG Factory light testing (All on white) + MD_BOOT //Restart into bootloader after hold timeout +}; + +#define TG_NKRO MAGIC_TOGGLE_NKRO //Toggle 6KRO / NKRO mode + +keymap_config_t keymap_config; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS, KC_HOME, KC_PGUP, KC_PAUS, \ + KC_DEL, KC_END, KC_PGDN, KC_SLCK, \ + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_NLCK, KC_PSLS, KC_PAST, KC_PSCR, \ + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_P7, KC_P8, KC_P9, KC_PMNS, \ + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_P4, KC_P5, KC_P6, KC_PPLS, \ + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_P1, KC_P2, KC_P3, \ + KC_UP, KC_PENT, \ + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_P0, KC_PDOT, \ + KC_LEFT, KC_DOWN, KC_RGHT \ + ), + [1] = LAYOUT( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, KC_MSTP, KC_VOLU, KC_MUTE, \ + KC_MPRV, KC_MNXT, KC_VOLD, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + L_T_BR, L_PSD, L_BRI, L_PSI, L_EDG_I, _______, _______, _______, U_T_AGCR,_______, _______, _______, _______, _______, _______, _______, _______, _______, \ + L_T_PTD, L_PTP, L_BRD, L_PTN, L_EDG_D, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, L_T_MD, L_T_ONF, _______, L_EDG_M, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, \ + _______, _______, _______, DBG_FAC, KC_APP, _______, _______, _______, \ + _______, _______, _______ \ + ), + /* + [X] = LAYOUT( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______ \ + ), + */ +}; + +// Runs just one time when the keyboard initializes. +void matrix_init_user(void) { +}; + +// Runs constantly in the background, in a loop. +void matrix_scan_user(void) { +}; + +#define MODS_SHIFT (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT)) +#define MODS_CTRL (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL)) +#define MODS_ALT (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT)) + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + static uint32_t key_timer; + static uint8_t scroll_effect = 0; + + switch (keycode) { + case L_BRI: + if (record->event.pressed) { + if (LED_GCR_STEP > LED_GCR_MAX - gcr_desired) gcr_desired = LED_GCR_MAX; + else gcr_desired += LED_GCR_STEP; + if (led_animation_breathing) gcr_breathe = gcr_desired; + } + return false; + case L_BRD: + if (record->event.pressed) { + if (LED_GCR_STEP > gcr_desired) gcr_desired = 0; + else gcr_desired -= LED_GCR_STEP; + if (led_animation_breathing) gcr_breathe = gcr_desired; + } + return false; + case L_EDG_M: + if (record->event.pressed) { + led_edge_mode++; + if (led_edge_mode > LED_EDGE_MODE_MAX) { + led_edge_mode = LED_EDGE_MODE_ALL; + } + } + return false; + case L_EDG_I: + if (record->event.pressed) { + led_edge_brightness += 0.1; + if (led_edge_brightness > 1) { led_edge_brightness = 1; } + } + return false; + case L_EDG_D: + if (record->event.pressed) { + led_edge_brightness -= 0.1; + if (led_edge_brightness < 0) { led_edge_brightness = 0; } + } + return false; + case L_PTN: + if (record->event.pressed) { + if (led_animation_id == led_setups_count - 1) led_animation_id = 0; + else led_animation_id++; + } + return false; + case L_PTP: + if (record->event.pressed) { + if (led_animation_id == 0) led_animation_id = led_setups_count - 1; + else led_animation_id--; + } + return false; + case L_PSI: + if (record->event.pressed) { + led_animation_speed += ANIMATION_SPEED_STEP; + } + return false; + case L_PSD: + if (record->event.pressed) { + led_animation_speed -= ANIMATION_SPEED_STEP; + if (led_animation_speed < 0) led_animation_speed = 0; + } + return false; + case L_T_MD: + if (record->event.pressed) { + led_lighting_mode++; + if (led_lighting_mode > LED_MODE_MAX_INDEX) led_lighting_mode = LED_MODE_NORMAL; + } + return false; + case L_T_ONF: + if (record->event.pressed) { + led_enabled = !led_enabled; + I2C3733_Control_Set(led_enabled); + } + return false; + case L_ON: + if (record->event.pressed) { + led_enabled = 1; + I2C3733_Control_Set(led_enabled); + } + return false; + case L_OFF: + if (record->event.pressed) { + led_enabled = 0; + I2C3733_Control_Set(led_enabled); + } + return false; + case L_T_BR: + if (record->event.pressed) { + led_animation_breathing = !led_animation_breathing; + if (led_animation_breathing) { + gcr_breathe = gcr_desired; + led_animation_breathe_cur = BREATHE_MIN_STEP; + breathe_dir = 1; + } + } + return false; + case L_T_PTD: + if (record->event.pressed) { + scroll_effect++; + if (scroll_effect == 1) { //Patterns with scroll move horizontal (Right to left) + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 0; + } else if (scroll_effect == 2) { //Patterns with scroll move vertical (Top to bottom) + led_animation_direction = 1; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 3) { //Patterns with scroll move vertical (Bottom to top) + led_animation_direction = 0; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 4) { //Patterns with scroll explode from center + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 1; + } else if (scroll_effect == 5) { //Patterns with scroll implode on center + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 1; + } else { //Patterns with scroll move horizontal (Left to right) + scroll_effect = 0; + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 0; + } + } + return false; + case U_T_AGCR: + if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { + TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); + } + return false; + case DBG_FAC: + if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { + led_lighting_mode = LED_MODE_NORMAL; + led_edge_brightness = 1; + led_edge_mode = LED_EDGE_MODE_ALL; + led_animation_breathing = 0; + led_animation_id = 7; //led_programs.c led_setups leds_white index + gcr_desired = LED_GCR_MAX; + led_enabled = 1; + I2C3733_Control_Set(led_enabled); + } + return false; + case DBG_TOG: + if (record->event.pressed) { + TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode"); + } + return false; + case DBG_MTRX: + if (record->event.pressed) { + TOGGLE_FLAG_AND_PRINT(debug_matrix, "Debug matrix"); + } + return false; + case DBG_KBD: + if (record->event.pressed) { + TOGGLE_FLAG_AND_PRINT(debug_keyboard, "Debug keyboard"); + } + return false; + case DBG_MOU: + if (record->event.pressed) { + TOGGLE_FLAG_AND_PRINT(debug_mouse, "Debug mouse"); + } + return false; + case MD_BOOT: + if (record->event.pressed) { + key_timer = timer_read32(); + } else { + if (timer_elapsed32(key_timer) >= 500) { + reset_keyboard(); + } + } + return false; + default: + return true; //Process all other keycodes normally + } +} diff --git a/keyboards/massdrop/shift/keymaps/mac/keymap.c b/keyboards/massdrop/shift/keymaps/mac/keymap.c new file mode 100644 index 00000000000..33818d49046 --- /dev/null +++ b/keyboards/massdrop/shift/keymaps/mac/keymap.c @@ -0,0 +1,258 @@ +#include QMK_KEYBOARD_H + +enum ctrl_keycodes { + L_BRI = SAFE_RANGE, //LED Brightness Increase + L_BRD, //LED Brightness Decrease + L_EDG_I, //LED Edge Brightness Increase + L_EDG_D, //LED Edge Brightness Decrease + L_EDG_M, //LED Edge lighting mode + L_PTN, //LED Pattern Select Next + L_PTP, //LED Pattern Select Previous + L_PSI, //LED Pattern Speed Increase + L_PSD, //LED Pattern Speed Decrease + L_T_MD, //LED Toggle Mode + L_T_ONF, //LED Toggle On / Off + L_ON, //LED On + L_OFF, //LED Off + L_T_BR, //LED Toggle Breath Effect + L_T_PTD, //LED Toggle Scrolling Pattern Direction and effect + U_T_AGCR, //USB Toggle Automatic GCR control + DBG_TOG, //DEBUG Toggle On / Off + DBG_MTRX, //DEBUG Toggle Matrix Prints + DBG_KBD, //DEBUG Toggle Keyboard Prints + DBG_MOU, //DEBUG Toggle Mouse Prints + DBG_FAC, //DEBUG Factory light testing (All on white) + MD_BOOT //Restart into bootloader after hold timeout +}; + +#define TG_NKRO MAGIC_TOGGLE_NKRO //Toggle 6KRO / NKRO mode + +keymap_config_t keymap_config; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS, KC_HOME, KC_PGUP, KC_PAUS, \ + KC_DEL, KC_END, KC_PGDN, KC_SLCK, \ + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_NLCK, KC_PSLS, KC_PAST, KC_PSCR, \ + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_P7, KC_P8, KC_P9, KC_PMNS, \ + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_P4, KC_P5, KC_P6, KC_PPLS, \ + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_P1, KC_P2, KC_P3, \ + KC_UP, KC_PENT, \ + KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RGUI, MO(1), KC_P0, KC_PDOT, \ + KC_LEFT, KC_DOWN, KC_RGHT \ + ), + [1] = LAYOUT( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, KC_MSTP, KC_VOLU, KC_MUTE, \ + KC_MPRV, KC_MNXT, KC_VOLD, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + L_T_BR, L_PSD, L_BRI, L_PSI, L_EDG_I, _______, _______, _______, U_T_AGCR,_______, _______, _______, _______, _______, _______, _______, _______, _______, \ + L_T_PTD, L_PTP, L_BRD, L_PTN, L_EDG_D, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, L_T_MD, L_T_ONF, _______, L_EDG_M, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, \ + _______, _______, _______, DBG_FAC, KC_APP, _______, _______, _______, \ + _______, _______, _______ \ + ), + /* + [X] = LAYOUT( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______ \ + ), + */ +}; + +// Runs just one time when the keyboard initializes. +void matrix_init_user(void) { +}; + +// Runs constantly in the background, in a loop. +void matrix_scan_user(void) { +}; + +#define MODS_SHIFT (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT)) +#define MODS_CTRL (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL)) +#define MODS_ALT (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT)) + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + static uint32_t key_timer; + static uint8_t scroll_effect = 0; + + switch (keycode) { + case L_BRI: + if (record->event.pressed) { + if (LED_GCR_STEP > LED_GCR_MAX - gcr_desired) gcr_desired = LED_GCR_MAX; + else gcr_desired += LED_GCR_STEP; + if (led_animation_breathing) gcr_breathe = gcr_desired; + } + return false; + case L_BRD: + if (record->event.pressed) { + if (LED_GCR_STEP > gcr_desired) gcr_desired = 0; + else gcr_desired -= LED_GCR_STEP; + if (led_animation_breathing) gcr_breathe = gcr_desired; + } + return false; + case L_EDG_M: + if (record->event.pressed) { + led_edge_mode++; + if (led_edge_mode > LED_EDGE_MODE_MAX) { + led_edge_mode = LED_EDGE_MODE_ALL; + } + } + return false; + case L_EDG_I: + if (record->event.pressed) { + led_edge_brightness += 0.1; + if (led_edge_brightness > 1) { led_edge_brightness = 1; } + } + return false; + case L_EDG_D: + if (record->event.pressed) { + led_edge_brightness -= 0.1; + if (led_edge_brightness < 0) { led_edge_brightness = 0; } + } + return false; + case L_PTN: + if (record->event.pressed) { + if (led_animation_id == led_setups_count - 1) led_animation_id = 0; + else led_animation_id++; + } + return false; + case L_PTP: + if (record->event.pressed) { + if (led_animation_id == 0) led_animation_id = led_setups_count - 1; + else led_animation_id--; + } + return false; + case L_PSI: + if (record->event.pressed) { + led_animation_speed += ANIMATION_SPEED_STEP; + } + return false; + case L_PSD: + if (record->event.pressed) { + led_animation_speed -= ANIMATION_SPEED_STEP; + if (led_animation_speed < 0) led_animation_speed = 0; + } + return false; + case L_T_MD: + if (record->event.pressed) { + led_lighting_mode++; + if (led_lighting_mode > LED_MODE_MAX_INDEX) led_lighting_mode = LED_MODE_NORMAL; + } + return false; + case L_T_ONF: + if (record->event.pressed) { + led_enabled = !led_enabled; + I2C3733_Control_Set(led_enabled); + } + return false; + case L_ON: + if (record->event.pressed) { + led_enabled = 1; + I2C3733_Control_Set(led_enabled); + } + return false; + case L_OFF: + if (record->event.pressed) { + led_enabled = 0; + I2C3733_Control_Set(led_enabled); + } + return false; + case L_T_BR: + if (record->event.pressed) { + led_animation_breathing = !led_animation_breathing; + if (led_animation_breathing) { + gcr_breathe = gcr_desired; + led_animation_breathe_cur = BREATHE_MIN_STEP; + breathe_dir = 1; + } + } + return false; + case L_T_PTD: + if (record->event.pressed) { + scroll_effect++; + if (scroll_effect == 1) { //Patterns with scroll move horizontal (Right to left) + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 0; + } else if (scroll_effect == 2) { //Patterns with scroll move vertical (Top to bottom) + led_animation_direction = 1; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 3) { //Patterns with scroll move vertical (Bottom to top) + led_animation_direction = 0; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 4) { //Patterns with scroll explode from center + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 1; + } else if (scroll_effect == 5) { //Patterns with scroll implode on center + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 1; + } else { //Patterns with scroll move horizontal (Left to right) + scroll_effect = 0; + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 0; + } + } + return false; + case U_T_AGCR: + if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { + TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); + } + return false; + case DBG_FAC: + if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { + led_lighting_mode = LED_MODE_NORMAL; + led_edge_brightness = 1; + led_edge_mode = LED_EDGE_MODE_ALL; + led_animation_breathing = 0; + led_animation_id = 7; //led_programs.c led_setups leds_white index + gcr_desired = LED_GCR_MAX; + led_enabled = 1; + I2C3733_Control_Set(led_enabled); + } + return false; + case DBG_TOG: + if (record->event.pressed) { + TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode"); + } + return false; + case DBG_MTRX: + if (record->event.pressed) { + TOGGLE_FLAG_AND_PRINT(debug_matrix, "Debug matrix"); + } + return false; + case DBG_KBD: + if (record->event.pressed) { + TOGGLE_FLAG_AND_PRINT(debug_keyboard, "Debug keyboard"); + } + return false; + case DBG_MOU: + if (record->event.pressed) { + TOGGLE_FLAG_AND_PRINT(debug_mouse, "Debug mouse"); + } + return false; + case MD_BOOT: + if (record->event.pressed) { + key_timer = timer_read32(); + } else { + if (timer_elapsed32(key_timer) >= 500) { + reset_keyboard(); + } + } + return false; + default: + return true; //Process all other keycodes normally + } +} diff --git a/keyboards/massdrop/shift/matrix.c b/keyboards/massdrop/shift/matrix.c new file mode 100644 index 00000000000..f83c52fd4c6 --- /dev/null +++ b/keyboards/massdrop/shift/matrix.c @@ -0,0 +1,210 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "shift.h" + +#include "d51_util.h" +#include "debug.h" +#include "clks.h" +#include "spi.h" +#include + +#define MCU_PORTS_USED 1 //PA + +matrix_row_t mlatest[MATRIX_ROWS]; +matrix_row_t mlast[MATRIX_ROWS]; +matrix_row_t mdebounced[MATRIX_ROWS]; + +uint8_t row_ports[] = { MATRIX_ROW_PORTS }; +uint8_t row_pins[] = { MATRIX_ROW_PINS }; +uint8_t col_ports[] = { MATRIX_COL_PORTS }; +uint8_t col_pins[] = { MATRIX_COL_PINS }; +uint32_t row_masks[MCU_PORTS_USED]; //Array size must match number of unique MCU ports used for reads (PA, PB, PC, etc) + +__attribute__ ((weak)) +void matrix_init_kb(void) { + matrix_init_user(); +} + +__attribute__ ((weak)) +void matrix_scan_kb(void) { + matrix_scan_user(); +} + +__attribute__ ((weak)) +void matrix_init_user(void) { +} + +__attribute__ ((weak)) +void matrix_scan_user(void) { +} + +void matrix_init(void) +{ + SR_KC_Init(); + + memset(mlatest, 0, MATRIX_ROWS * sizeof(matrix_row_t)); + memset(mlast, 0, MATRIX_ROWS * sizeof(matrix_row_t)); + memset(mdebounced, 0, MATRIX_ROWS * sizeof(matrix_row_t)); + + memset(row_masks, 0, sizeof(row_masks)); + + //Inputs + uint8_t row; + for (row = 0; row < MATRIX_ROWS; row++) + { + PORT->Group[row_ports[row]].DIRCLR.reg = 1 << row_pins[row]; //Input + PORT->Group[row_ports[row]].OUTCLR.reg = 1 << row_pins[row]; //Low + PORT->Group[row_ports[row]].PINCFG[row_pins[row]].bit.INEN = 1; //Input Enable, + PORT->Group[row_ports[row]].PINCFG[row_pins[row]].bit.PULLEN = 1; //Pull Enable + row_masks[row_ports[row]] |= 1 << row_pins[row]; //Add pin to proper row mask + } + + //Outputs + uint8_t col; + for (col = 0; col < MATRIX_COLS; col++) + { + if (PORT_IS_MCU(col_ports[col])) //PORT_GROUPS from MCU's header file + { + PORT->Group[col_ports[col]].DIRSET.reg = 1 << col_pins[col]; //Output + PORT->Group[col_ports[col]].OUTCLR.reg = 1 << col_pins[col]; //Low + } + else if (PORT_IS_SR(col_ports[col])) //Pins on Shift Register + { + //Outputs Low + sr_kc_data.reg = 0; + SR_KC_WriteData(); + } + } + + matrix_init_quantum(); +} + +uint64_t mdebouncing = 0; +uint8_t matrix_scan(void) +{ + uint8_t mchanged; + uint8_t row; + uint8_t col; + uint32_t scans[MCU_PORTS_USED]; //Array size must match number of unique MCU ports used for reads (PA, PB, PC, etc) + + if (timer_read64() < mdebouncing) return 1; //mdebouncing == 0 when no debouncing active + + memset(mlatest, 0, MATRIX_ROWS * sizeof(matrix_row_t)); //Zero the result buffer + + for (col = 0; col < MATRIX_COLS; col++) + { + //Set output + if (PORT_IS_MCU(col_ports[col])) //Pin is on MCU + { + PORT->Group[col_ports[col]].OUTSET.reg = 1 << col_pins[col]; //Set col output + wait_us(1); //Delay for output + } + else if (PORT_IS_SR(col_ports[col])) //Pin is on Shift Register + { + sr_kc_data.reg |= (1 << col_pins[col]); //Set col output in RAM + SR_KC_WriteData(); //Write shift register update + wait_us(1); //Delay for output + } + else continue; //Bad configuration + + //Read input (add unique ports as needed, PA, PB, PC, etc) + scans[PA] = PORT->Group[PA].IN.reg & row_masks[PA]; //Read PA row pins data + + //Clear output + if (PORT_IS_MCU(col_ports[col])) //Pin is on MCU + { + PORT->Group[col_ports[col]].OUTCLR.reg = 1 << col_pins[col]; //Clear col output + } + else if (PORT_IS_SR(col_ports[col])) //Pin is on Shift Register + { + sr_kc_data.reg &= ~(1 << col_pins[col]); //Clear col output in RAM + SR_KC_WriteData(); //Write shift register update + } + + for (row = 0; row < MATRIX_ROWS; row++) + { + //Move scan bits from scans array into proper row bit locations + if (scans[row_ports[row]] & (1 << row_pins[row])) + mlatest[row] |= 1 << col; + } + } + + mchanged = 0; //Default to no matrix change since last + + for (row = 0; row < MATRIX_ROWS; row++) + { + if (mlast[row] != mlatest[row]) + mchanged = 1; + mlast[row] = mlatest[row]; + } + + if (!mchanged) + { + for (row = 0; row < MATRIX_ROWS; row++) + mdebounced[row] = mlatest[row]; + mdebouncing = 0; + } + else + { + //Begin or extend debounce on change + mdebouncing = timer_read64() + DEBOUNCING_DELAY; + } + + matrix_scan_quantum(); + + return 1; +} + +matrix_row_t matrix_get_row(uint8_t row) +{ + return mdebounced[row]; +} + +void matrix_print(void) +{ + char buf[(MATRIX_COLS+8)*(MATRIX_ROWS+1)] = "R C"; + char *pbuf = buf+3; + uint32_t cols; + uint32_t rows; + matrix_row_t row; + + for (cols = 1; cols <= MATRIX_COLS; cols++) + { + *pbuf = (cols%10)+48; + pbuf++; + } + *pbuf = '\r'; pbuf++; + *pbuf = '\n'; pbuf++; + + for (rows = 1; rows <= MATRIX_ROWS; rows++) + { + row = matrix_get_row(rows-1); + if (rows < 10) { *pbuf = rows+48; pbuf++; *pbuf = ' '; pbuf++; *pbuf = ' '; pbuf++; } + else { *pbuf = (rows/10)+48; pbuf++; *pbuf = (rows%10)+48; pbuf++; *pbuf = ' '; pbuf++; } + for (cols = 0; cols < MATRIX_COLS; cols++) + { + if (row & 1 << cols) *pbuf = 'X'; + else *pbuf = '.'; + pbuf++; + } + *pbuf = '\r'; pbuf++; + *pbuf = '\n'; pbuf++; + } + *pbuf = 0; + dprint(buf); +} diff --git a/keyboards/massdrop/shift/matrix.h b/keyboards/massdrop/shift/matrix.h new file mode 100644 index 00000000000..3eab6dece10 --- /dev/null +++ b/keyboards/massdrop/shift/matrix.h @@ -0,0 +1,77 @@ +/* +Copyright 2011 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef MATRIX_H +#define MATRIX_H + +#include +#include +#include "keyboard.h" + +#if (MATRIX_COLS <= 8) +typedef uint8_t matrix_row_t; +#elif (MATRIX_COLS <= 16) +typedef uint16_t matrix_row_t; +#elif (MATRIX_COLS <= 32) +typedef uint32_t matrix_row_t; +#else +#error "MATRIX_COLS: invalid value" +#endif + +#define MATRIX_IS_ON(row, col) (matrix_get_row(row) && (1<. +*/ + +#include "arm_atsam_protocol.h" + +void SR_EXP_Init_kb(void) { + /* Initialize shift register */ + SR_EXP_OE_N_DIS; + SR_EXP_RCLK_HI; + + SR_EXP_SERCOM->SPI.CTRLA.bit.DORD = 1; //Data Order - LSB is transferred first + SR_EXP_SERCOM->SPI.CTRLA.bit.CPOL = 1; //Clock Polarity - SCK high when idle. Leading edge of cycle is falling. Trailing rising. + SR_EXP_SERCOM->SPI.CTRLA.bit.CPHA = 1; //Clock Phase - Leading Edge Falling, change, Trailing Edge - Rising, sample + SR_EXP_SERCOM->SPI.CTRLA.bit.DIPO = 3; //Data In Pinout - SERCOM PAD[3] is used as data input (Configure away from DOPO. Not using input.) + SR_EXP_SERCOM->SPI.CTRLA.bit.DOPO = 0; //Data Output PAD[0], Serial Clock PAD[1] + SR_EXP_SERCOM->SPI.CTRLA.bit.MODE = 3; //Operating Mode - Master operation + + SR_EXP_SERCOM->SPI.CTRLA.bit.ENABLE = 1; //Enable - Peripheral is enabled or being enabled + while (SR_EXP_SERCOM->SPI.SYNCBUSY.bit.ENABLE) { DBGC(DC_SPI_EXP_SYNC_ENABLING); } + + /* Set default shift register values */ + sr_exp_data.reg = 0; //Clear data register + sr_exp_data.bit.HUB_CONNECT = 0; //USB Hub disconnected + sr_exp_data.bit.HUB_RESET_N = 0; //USB Hub in reset state + + sr_exp_data.bit.SRC_1_A5 = 1; //Set CON1 CC A5 as Rd 5.1k + sr_exp_data.bit.SRC_1_B5 = 1; //Set CON1 CC B5 as Rd 5.1k + sr_exp_data.bit.SRC_2_A5 = 1; //Set CON2 CC A5 as Rd 5.1k + sr_exp_data.bit.SRC_2_B5 = 1; //Set CON2 CC B5 as Rd 5.1k + sr_exp_data.bit.S_A_UP = 0; //0 = DN1 to A and UP to B, 1 = DN1 to B and UP to A + sr_exp_data.bit.S_A_EXT = 1; //1 = Onboard, 0 = Offboard + sr_exp_data.bit.S_B_EXT = 0; //0 = Onboard, 1 = Offboard + + sr_exp_data.bit.ENB = 0; //Disable CON1 + sr_exp_data.bit.ENA = 0; //Disable CON2 + sr_exp_data.bit.E_VBUS_1 = 0; //Disable CON1 5V + sr_exp_data.bit.E_VBUS_2 = 0; //Disable CON2 5V + sr_exp_data.bit.IRST = 1; //LED drivers I2C in reset + sr_exp_data.bit.SDB_N = 0; //LED drivers in shutdown + + /* Write shift register data */ + SR_EXP_WriteData(); + + /* Enable shift register output */ + SR_EXP_OE_N_ENA; +} diff --git a/keyboards/massdrop/shift/usb.c b/keyboards/massdrop/shift/usb.c new file mode 100644 index 00000000000..1610864c923 --- /dev/null +++ b/keyboards/massdrop/shift/usb.c @@ -0,0 +1,119 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "arm_atsam_protocol.h" + +void usb_set_host_kb(uint8_t con, uint8_t rp_best_index) { + if (con == 1) { + //DN1 to A (CON2/EX2), UP to B (CON1/EX1) + sr_exp_data.bit.S_A_UP = 1; //0 = DN1 to B and UP to A, 1 = DN1 to A and UP to B (SAI-SBI) + + if (ADC_USBC_IS_ONB(rp_best_index)) { //Check if the port detected is onboard + sr_exp_data.bit.S_B_EXT = 0; //Onboard port + g_usb_host_port = USB_HOST_PORT_1; //Save host port + } else { //Port is external + sr_exp_data.bit.S_B_EXT = 1; //External port + g_usb_host_port = USB_HOST_PORT_1_EXT; //Save host port + } + + sr_exp_data.bit.E_VBUS_1 = 1; //Enable CON1 5V + + SR_EXP_WriteData(); //Update port configuration + } else if (con == 2) { + //DN1 to B (CON1/EX1), UP to A (CON2/EX2) + sr_exp_data.bit.S_A_UP = 0; //0 = DN1 to B and UP to A, 1 = DN1 to A and UP to B (SAI-SBI) + + if (ADC_USBC_IS_ONB(rp_best_index)) { //Check if the port detected is onboard + sr_exp_data.bit.S_A_EXT = 1; //Onboard port + g_usb_host_port = USB_HOST_PORT_2; //Save host port + } else { //Port is external + sr_exp_data.bit.S_A_EXT = 0; //External port + g_usb_host_port = USB_HOST_PORT_2_EXT; //Save host port + } + + sr_exp_data.bit.E_VBUS_2 = 1; //Enable CON2 5V + + SR_EXP_WriteData(); //Update port configuration + } +} + +void usb_set_extra_kb(uint8_t con) { + if (con == 1) { + sr_exp_data.bit.SRC_1_A5 = 0; //Set CON1 CC A5 as Rp 56k + sr_exp_data.bit.SRC_1_B5 = 0; //Set CON1 CC B5 as Rp 56k + sr_exp_data.bit.E_VBUS_1 = 0; //Disable CON1 5V + SR_EXP_WriteData(); //Update port configuration + } else if (con == 2) { + sr_exp_data.bit.SRC_2_A5 = 0; //Set CON2 CC A5 as Rp 56k + sr_exp_data.bit.SRC_2_B5 = 0; //Set CON2 CC B5 as Rp 56k + sr_exp_data.bit.E_VBUS_2 = 0; //Disable CON2 5V + SR_EXP_WriteData(); //Update port configuration + } +} + +void usb_init_host_detection_kb(void) { + //Disable 5V + sr_exp_data.bit.E_VBUS_1 = 0; //Disable CON1 5V + sr_exp_data.bit.E_VBUS_2 = 0; //Disable CON2 5V + + //Configure default paths + sr_exp_data.bit.S_A_UP = 0; //DN1 TO A & UP TO B WHEN 1, DN1 TO B & UP TO A WHEN 0 + sr_exp_data.bit.S_A_EXT = 1; //1 = Onboard, 0 = Offboard (SAO) + sr_exp_data.bit.S_B_EXT = 0; //0 = Onboard, 1 = Offboard (SBO) + + //Configure CC lines + sr_exp_data.bit.SRC_1_A5 = 1; //Set CON1 CC A5 as Rd 5.1k + sr_exp_data.bit.SRC_1_B5 = 1; //Set CON1 CC B5 as Rd 5.1k + sr_exp_data.bit.SRC_2_A5 = 1; //Set CON2 CC A5 as Rd 5.1k + sr_exp_data.bit.SRC_2_B5 = 1; //Set CON2 CC B5 as Rd 5.1k + + //Enable ports + sr_exp_data.bit.ENB = 1; //Enable CON1/EX1 for use + sr_exp_data.bit.ENA = 1; //Enable CON2/EX2 for use + + SR_EXP_WriteData(); //Update port configuration +} + +//Return 1 if configuration successful +//Return 0 otherwise +uint8_t usb_attach_port_configure_kb(uint8_t g_usb_host_port, uint16_t usbc_cc_a5_v, uint16_t usbc_cc_b5_v) { + if (USB_HOST_IS_1(g_usb_host_port)) { //If host is port 1 + //Set up port 2 + if (USBC_IS_SINK_ONB(usbc_cc_a5_v, usbc_cc_b5_v)) { //If onboard port detected + sr_exp_data.bit.S_A_EXT = 1; //Set port 2 as onboard port + SR_EXP_WriteData(); //Update port configuration + return 1; + } else if (USBC_IS_SINK_EXT(usbc_cc_a5_v, usbc_cc_b5_v)) { //If external port detected + sr_exp_data.bit.S_A_EXT = 0; //Set port 2 as onboard port + SR_EXP_WriteData(); //Update port configuration + return 1; + } + } else if (USB_HOST_IS_2(g_usb_host_port)) { //If host is on port 2 + //Set up port 1 + if (USBC_IS_SINK_ONB(usbc_cc_a5_v, usbc_cc_b5_v)) { //If onboard port detected + sr_exp_data.bit.S_B_EXT = 0; //Set port 1 as onboard port + SR_EXP_WriteData(); //Update port configuration + return 1; + } else if (USBC_IS_SINK_EXT(usbc_cc_a5_v, usbc_cc_b5_v)) { //If external port detected + sr_exp_data.bit.S_B_EXT = 1; //Set port 1 as external port + SR_EXP_WriteData(); //Update port configuration + return 1; + } + } + + return 0; +} diff --git a/tmk_core/protocol/arm_atsam.mk b/tmk_core/protocol/arm_atsam.mk index 8d6f724f099..f8e1bfd4a6f 100644 --- a/tmk_core/protocol/arm_atsam.mk +++ b/tmk_core/protocol/arm_atsam.mk @@ -9,6 +9,7 @@ ifeq ($(RGB_MATRIX_ENABLE),custom) SRC += $(ARM_ATSAM_DIR)/led_matrix.c endif SRC += $(ARM_ATSAM_DIR)/main_arm_atsam.c +SRC += $(ARM_ATSAM_DIR)/power.c SRC += $(ARM_ATSAM_DIR)/spi.c SRC += $(ARM_ATSAM_DIR)/startup.c diff --git a/tmk_core/protocol/arm_atsam/adc.c b/tmk_core/protocol/arm_atsam/adc.c index cb5c349b730..08ce55448c9 100644 --- a/tmk_core/protocol/arm_atsam/adc.c +++ b/tmk_core/protocol/arm_atsam/adc.c @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,13 +17,25 @@ along with this program. If not, see . #include "arm_atsam_protocol.h" -uint16_t v_5v; -uint16_t v_5v_avg; -uint16_t v_con_1; -uint16_t v_con_2; -uint16_t v_con_1_boot; -uint16_t v_con_2_boot; +//Configuration in keyboard's config_adc.h +uint8_t adc_config[][ADC_SAMPLEN + 1] = { + { ADC_CONFIG_5V }, + { ADC_CONFIG_C1A5 }, + { ADC_CONFIG_C1B5 }, + { ADC_CONFIG_C2A5 }, + { ADC_CONFIG_C2B5 }, + { ADC_CONFIG_C1I }, + { ADC_CONFIG_C2I } +}; +#ifdef ADC_USBC_RP_DELTA_MAX +uint16_t adc_usbc_rp_nominal[ADC_USBC_RP_TYPES * ADC_USBC_CON_TYPES] = { ADC_USBC_RP_NOM }; +#endif + +uint16_t g_v_5v; +float g_v_5v_avg; + +__attribute__ ((weak)) void ADC0_clock_init(void) { DBGC(DC_ADC0_CLOCK_INIT_BEGIN); @@ -36,64 +48,174 @@ void ADC0_clock_init(void) DBGC(DC_ADC0_CLOCK_INIT_COMPLETE); } -void ADC0_init(void) +__attribute__ ((weak)) +void ADC1_clock_init(void) { - DBGC(DC_ADC0_INIT_BEGIN); + DBGC(DC_ADC1_CLOCK_INIT_BEGIN); - //MCU - PORT->Group[1].DIRCLR.reg = 1 << 0; //PB00 as input 5V - PORT->Group[1].DIRCLR.reg = 1 << 1; //PB01 as input CON2 - PORT->Group[1].DIRCLR.reg = 1 << 2; //PB02 as input CON1 - PORT->Group[1].PMUX[0].bit.PMUXE = 1; //PB00 mux select B ADC 5V - PORT->Group[1].PMUX[0].bit.PMUXO = 1; //PB01 mux select B ADC CON2 - PORT->Group[1].PMUX[1].bit.PMUXE = 1; //PB02 mux select B ADC CON1 - PORT->Group[1].PINCFG[0].bit.PMUXEN = 1; //PB01 mux ADC Enable 5V - PORT->Group[1].PINCFG[1].bit.PMUXEN = 1; //PB01 mux ADC Enable CON2 - PORT->Group[1].PINCFG[2].bit.PMUXEN = 1; //PB02 mux ADC Enable CON1 + MCLK->APBDMASK.bit.ADC1_ = 1; //ADC1 Clock Enable - //ADC - ADC0->CTRLA.bit.SWRST = 1; - while (ADC0->SYNCBUSY.bit.SWRST) { DBGC(DC_ADC0_SWRST_SYNCING_1); } - while (ADC0->CTRLA.bit.SWRST) { DBGC(DC_ADC0_SWRST_SYNCING_2); } + GCLK->PCHCTRL[ADC1_GCLK_ID].bit.GEN = GEN_OSC0; //Select generator clock + GCLK->PCHCTRL[ADC1_GCLK_ID].bit.CHEN = 1; //Enable peripheral clock - //Clock divide - ADC0->CTRLA.bit.PRESCALER = ADC_CTRLA_PRESCALER_DIV2_Val; + DBGC(DC_ADC1_CLOCK_INIT_COMPLETE); +} - //Averaging - ADC0->AVGCTRL.bit.SAMPLENUM = ADC_AVGCTRL_SAMPLENUM_4_Val; - while (ADC0->SYNCBUSY.bit.AVGCTRL) { DBGC(DC_ADC0_AVGCTRL_SYNCING_1); } - if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_1_Val) ADC0->AVGCTRL.bit.ADJRES = 0; - else if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_2_Val) ADC0->AVGCTRL.bit.ADJRES = 1; - else if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_4_Val) ADC0->AVGCTRL.bit.ADJRES = 2; - else if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_8_Val) ADC0->AVGCTRL.bit.ADJRES = 3; - else ADC0->AVGCTRL.bit.ADJRES = 4; - while (ADC0->SYNCBUSY.bit.AVGCTRL) { DBGC(DC_ADC0_AVGCTRL_SYNCING_2); } - - //Settling - ADC0->SAMPCTRL.bit.SAMPLEN = 45; //Sampling Time Length: 1-63, 1 ADC CLK per - while (ADC0->SYNCBUSY.bit.SAMPCTRL) { DBGC(DC_ADC0_SAMPCTRL_SYNCING_1); } - - //Load factory calibration data +__attribute__ ((weak)) +void ADC0_load_cal(void) +{ ADC0->CALIB.bit.BIASCOMP = ((*(uint32_t *)ADC0_FUSES_BIASCOMP_ADDR) & ADC0_FUSES_BIASCOMP_Msk) >> ADC0_FUSES_BIASCOMP_Pos; ADC0->CALIB.bit.BIASR2R = ((*(uint32_t *)ADC0_FUSES_BIASR2R_ADDR) & ADC0_FUSES_BIASR2R_Msk) >> ADC0_FUSES_BIASR2R_Pos; ADC0->CALIB.bit.BIASREFBUF = ((*(uint32_t *)ADC0_FUSES_BIASREFBUF_ADDR) & ADC0_FUSES_BIASREFBUF_Msk) >> ADC0_FUSES_BIASREFBUF_Pos; - - //Enable - ADC0->CTRLA.bit.ENABLE = 1; - while (ADC0->SYNCBUSY.bit.ENABLE) { DBGC(DC_ADC0_ENABLE_SYNCING_1); } - - DBGC(DC_ADC0_INIT_COMPLETE); } -uint16_t adc_get(uint8_t muxpos) +__attribute__ ((weak)) +void ADC1_load_cal(void) { - ADC0->INPUTCTRL.bit.MUXPOS = muxpos; - while (ADC0->SYNCBUSY.bit.INPUTCTRL) {} - - ADC0->SWTRIG.bit.START = 1; - while (ADC0->SYNCBUSY.bit.SWTRIG) {} - while (!ADC0->INTFLAG.bit.RESRDY) {} - - return ADC0->RESULT.reg; + ADC1->CALIB.bit.BIASCOMP = ((*(uint32_t *)ADC1_FUSES_BIASCOMP_ADDR) & ADC1_FUSES_BIASCOMP_Msk) >> ADC1_FUSES_BIASCOMP_Pos; + ADC1->CALIB.bit.BIASR2R = ((*(uint32_t *)ADC1_FUSES_BIASR2R_ADDR) & ADC1_FUSES_BIASR2R_Msk) >> ADC1_FUSES_BIASR2R_Pos; + ADC1->CALIB.bit.BIASREFBUF = ((*(uint32_t *)ADC1_FUSES_BIASREFBUF_ADDR) & ADC1_FUSES_BIASREFBUF_Msk) >> ADC1_FUSES_BIASREFBUF_Pos; } +__attribute__ ((weak)) +void ADC_init(void) +{ + uint8_t adc_configured[ADC_INST_NUM] = { 0 }; + uint8_t mcu_port; + uint8_t mcu_pin; + uint8_t mcu_mux; + uint8_t adc_index; + PortGroup *port; + uint8_t adc_row; + + for (adc_row = 0; adc_row < sizeof(adc_config) / sizeof(adc_config[0]); adc_row++) + { + DBGC(DC_ADC_INIT_BEGIN); + + mcu_port = adc_config[adc_row][ADC_PORT]; + if (mcu_port == (uint8_t)ADC_NA) + { + continue; //ADC not available + } + + adc_index = adc_config[adc_row][ADC_INDEX]; + mcu_pin = adc_config[adc_row][ADC_PIN]; + mcu_mux = adc_config[adc_row][ADC_MUX]; + port = &PORT->Group[mcu_port]; + + //Set up MCU pins + port->DIRCLR.reg = 1 << mcu_pin; //PIN as input + if (mcu_pin / 2 == 0) + { + port->PMUX[mcu_pin / 2].bit.PMUXE = mcu_mux; //Set MUX + } + else + { + port->PMUX[mcu_pin / 2].bit.PMUXO = mcu_mux; //Set MUX + } + port->PINCFG[mcu_pin].bit.PMUXEN = 1; //Enable MUX + + //Configure ADC if it has not been already + if (adc_configured[adc_index] != 1) + { + ADC_configure(adc_index); + adc_configured[adc_row] = 1; + } + + DBGC(DC_ADC_INIT_COMPLETE); + } +} + +__attribute__ ((weak)) +void ADC_configure(uint8_t adc_index) +{ + Adc *adc_insts[] = ADC_INSTS; + Adc *adc = adc_insts[adc_index]; + + //Reset the ADC + adc->CTRLA.bit.SWRST = 1; + while (adc->SYNCBUSY.bit.SWRST) { DBGC(DC_ADC_SWRST_SYNCING_1); } + while (adc->CTRLA.bit.SWRST) { DBGC(DC_ADC_SWRST_SYNCING_2); } + + //Configure clock divide + adc->CTRLA.bit.PRESCALER = ADC_CTRLA_PRESCALER_DIV2_Val; + + //Load factory calibration data + if (adc_index == 0) + { + ADC0_load_cal(); + ADC0_clock_init(); + } + else if (adc_index == 1) + { + ADC1_load_cal(); + ADC1_clock_init(); + } + + //Enable the ADC + adc->CTRLA.bit.ENABLE = 1; + while (adc->SYNCBUSY.bit.ENABLE) { DBGC(DC_ADC_ENABLE_SYNCING_1); } +} + +//Return ADC_NA if the ADC is not available +//Return ADC counts otherwise +__attribute__ ((weak)) +uint16_t adc_get(uint8_t adc_id) +{ + uint16_t result = 0; + + //Make sure ADC is available + if (adc_config[adc_id][ADC_PORT] == (uint8_t)ADC_NA) + { + result = (uint16_t)ADC_NA; + } + else + { + Adc *adc_insts[] = ADC_INSTS; + Adc *adc = adc_insts[adc_config[adc_id][ADC_INDEX]]; + + adc->INPUTCTRL.bit.MUXPOS = adc_config[adc_id][ADC_MUXPOS]; + while (adc->SYNCBUSY.bit.INPUTCTRL) { DBGC(DC_ADC_GET_INPUTCTRL_SYNCING_1); } + + //Only switch reference if not already selected + if (adc->REFCTRL.bit.REFSEL != adc_config[adc_id][ADC_REFSEL]) + { + adc->REFCTRL.bit.REFSEL = adc_config[adc_id][ADC_REFSEL]; + while (adc->SYNCBUSY.bit.REFCTRL) { DBGC(DC_ADC_GET_REFCTRL_SYNCING_1); } + } + + //Configure averaging + if (adc->AVGCTRL.bit.SAMPLENUM != adc_config[adc_id][ADC_SAMPLENUM]) + { + adc->AVGCTRL.bit.SAMPLENUM = adc_config[adc_id][ADC_SAMPLENUM]; + while (adc->SYNCBUSY.bit.AVGCTRL) { DBGC(DC_ADC_GET_AVGCTRL_SYNCING_1); } + if (adc->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_1_Val) adc->AVGCTRL.bit.ADJRES = 0; + else if (adc->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_2_Val) adc->AVGCTRL.bit.ADJRES = 1; + else if (adc->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_4_Val) adc->AVGCTRL.bit.ADJRES = 2; + else if (adc->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_8_Val) adc->AVGCTRL.bit.ADJRES = 3; + else adc->AVGCTRL.bit.ADJRES = 4; + while (adc->SYNCBUSY.bit.AVGCTRL) { DBGC(DC_ADC_GET_AVGCTRL_SYNCING_2); } + } + + //Configure settling + if (adc->SAMPCTRL.bit.SAMPLEN != adc_config[adc_id][ADC_SAMPLEN]) + { + adc->SAMPCTRL.bit.SAMPLEN = adc_config[adc_id][ADC_SAMPLEN]; + while (adc->SYNCBUSY.bit.SAMPCTRL) { DBGC(DC_ADC_GET_SAMPCTRL_SYNCING_1); } + } + + adc->SWTRIG.bit.START = 1; + while (adc->SYNCBUSY.bit.SWTRIG) { DBGC(DC_ADC_GET_SWTRIG_SYNCING_1); } + while (!adc->INTFLAG.bit.RESRDY) { DBGC(DC_ADC_GET_INTFLAG_RESRDY_WAITING_1); } + + result = adc->RESULT.reg; + + //In the case of a 16-bit ADC, a maxed out reading becomes a return of "ADC not available", so take off one count + if (result == (uint16_t)ADC_NA) + { + result--; + } + } + + return result; +} diff --git a/tmk_core/protocol/arm_atsam/adc.h b/tmk_core/protocol/arm_atsam/adc.h index 5a90ece3fe3..35a476f6e79 100644 --- a/tmk_core/protocol/arm_atsam/adc.h +++ b/tmk_core/protocol/arm_atsam/adc.h @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,20 +18,17 @@ along with this program. If not, see . #ifndef _ADC_H_ #define _ADC_H_ -#define ADC_5V_START_LEVEL 2365 +#include "config_adc.h" //From keyboard's directory -#define ADC_5V ADC_INPUTCTRL_MUXPOS_AIN12_Val -#define ADC_CON1 ADC_INPUTCTRL_MUXPOS_AIN14_Val -#define ADC_CON2 ADC_INPUTCTRL_MUXPOS_AIN13_Val +#define ADC_NA -1 //Value to mark an ADC as not available for use and return from an acquire +#define ADC_5V_START_LEVEL 4.75f //In volts, system will wait until voltage is greater than this -extern uint16_t v_5v; -extern uint16_t v_5v_avg; -extern uint16_t v_con_1; -extern uint16_t v_con_2; -extern uint16_t v_con_1_boot; -extern uint16_t v_con_2_boot; +extern uint16_t g_v_5v; +extern float g_v_5v_avg; void ADC0_clock_init(void); -void ADC0_init(void); +void ADC_init(void); +void ADC_configure(uint8_t adc_index); +uint16_t adc_get(uint8_t adc_id); #endif //_ADC_H_ diff --git a/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h b/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h index 88109186aad..ebe724104cd 100644 --- a/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h +++ b/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,19 +15,29 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#ifndef _ARM_ATSAM_PROTOCOL_H_ -#define _ARM_ATSAM_PROTOCOL_H_ +#pragma once #include "samd51j18a.h" -#include "md_bootloader.h" -#include "timer.h" +#ifdef MD_BOOTLOADER + +#include //For abs() +#include "config.h" //From keyboard's directory + +#endif + +#include "md_bootloader.h" #include "d51_util.h" -#include "clks.h" + +#include "quantum.h" +#include "timer.h" #include "wait.h" + +#include "clks.h" #include "adc.h" #include "i2c_master.h" #include "spi.h" +#include "power.h" #include "./usb/usb2422.h" @@ -44,6 +54,3 @@ along with this program. If not, see . #include "./usb/udi_cdc.h" #endif //MD_BOOTLOADER - -#endif //_ARM_ATSAM_PROTOCOL_H_ - diff --git a/tmk_core/protocol/arm_atsam/clks.c b/tmk_core/protocol/arm_atsam/clks.c index 1ff318e59b3..ee18610eac6 100644 --- a/tmk_core/protocol/arm_atsam/clks.c +++ b/tmk_core/protocol/arm_atsam/clks.c @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -291,6 +291,9 @@ void clk_enable_sercom_apbmask(int sercomn) case 3: pmclk->APBBMASK.bit.SERCOM3_ = 1; break; + case 4: + pmclk->APBDMASK.bit.SERCOM4_ = 1; + break; default: break; } diff --git a/tmk_core/protocol/arm_atsam/clks.h b/tmk_core/protocol/arm_atsam/clks.h index 1b01a1764ef..d9c284f28c6 100644 --- a/tmk_core/protocol/arm_atsam/clks.h +++ b/tmk_core/protocol/arm_atsam/clks.h @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,6 +20,8 @@ along with this program. If not, see . #ifndef MD_BOOTLOADER +#include "samd51j18a.h" + //From keyboard #include "config_led.h" #include "config.h" @@ -28,33 +30,29 @@ along with this program. If not, see . #define PLL_RATIO 47 //mcu frequency ((X+1)MHz) #define FREQ_DFLL_DEFAULT 48000000 //DFLL frequency / usb clock -#define FREQ_SPI_DEFAULT 1000000 //spi to 595 shift regs +#define FREQ_SPI_DEFAULT 12000000 //spi to 595 shift regs +#ifdef SR_KC_SERCOM_NUM +#define FREQ_SPI_KC_DEFAULT 12000000 //spi to 595 shift regs for kc +#endif #define FREQ_I2C0_DEFAULT 100000 //i2c to hub -#define FREQ_I2C1_DEFAULT I2C_HZ //i2c to LED drivers +#define FREQ_I2C1_DEFAULT I2C_HZ //i2c to LED drivers (keyboard's configuration files) #define FREQ_TC45_DEFAULT 1000000 //1 usec resolution +#define FREQ_XOSC0 16000000 //Frequency of the external oscillator -//I2C1 Set ~Result PWM Time (2x Drivers) -// 1000000 1090000 -// 900000 1000000 3.82ms -// 800000 860000 -// 700000 750000 -// 600000 630000 -// 580000 615000 6.08ms -// 500000 522000 - -#define FREQ_XOSC0 16000000 - -#define CHAN_SERCOM_SPI 2 //shift regs -#define CHAN_SERCOM_I2C0 0 //hub -#define CHAN_SERCOM_I2C1 1 //led drivers -#define CHAN_SERCOM_UART 3 //debug util +#define CHAN_SERCOM_SPI_EXP SR_EXP_SERCOM_NUM //shift regs +#ifdef SR_KC_SERCOM_NUM +#define CHAN_SERCOM_SPI_KC SR_KC_SERCOM_NUM //key column drive +#endif +#define CHAN_SERCOM_I2C0 0 //hub +#define CHAN_SERCOM_I2C1 1 //led drivers +#define CHAN_SERCOM_UART 3 //debug util //Generator clock channels #define GEN_DPLL0 0 #define GEN_OSC0 1 #define GEN_TC45 2 -#define SERCOM_COUNT 5 +#define SERCOM_COUNT SERCOM_INST_NUM #define GCLK_COUNT 12 typedef struct clk_s { diff --git a/tmk_core/protocol/arm_atsam/d51_util.c b/tmk_core/protocol/arm_atsam/d51_util.c index ea422585757..440110959a7 100644 --- a/tmk_core/protocol/arm_atsam/d51_util.c +++ b/tmk_core/protocol/arm_atsam/d51_util.c @@ -1,7 +1,7 @@ -#include "d51_util.h" +#include "arm_atsam_protocol.h" static volatile uint32_t w; - + //Display unsigned 32-bit number by port toggling DBG_1 (to view on a scope) //Read as follows: 1230 = | | | | | | || (note zero is fast double toggle) #define DBG_PAUSE 5 diff --git a/tmk_core/protocol/arm_atsam/d51_util.h b/tmk_core/protocol/arm_atsam/d51_util.h index 71431942c7e..d1191d773c5 100644 --- a/tmk_core/protocol/arm_atsam/d51_util.h +++ b/tmk_core/protocol/arm_atsam/d51_util.h @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#ifndef _D51_UTIL_H_ -#define _D51_UTIL_H_ +#pragma once #include "samd51j18a.h" @@ -42,7 +41,7 @@ along with this program. If not, see . #else #define DBG_1_ENA #define DBG_1_DIS -#define DBG_1_ON +#define DBG_1_ON #define DBG_1_OFF #endif @@ -55,7 +54,7 @@ along with this program. If not, see . #else #define DBG_2_ENA #define DBG_2_DIS -#define DBG_2_ON +#define DBG_2_ON #define DBG_2_OFF #endif @@ -68,7 +67,7 @@ along with this program. If not, see . #else #define DBG_3_ENA #define DBG_3_DIS -#define DBG_3_ON +#define DBG_3_ON #define DBG_3_OFF #endif @@ -144,20 +143,20 @@ enum debug_code_list { DC_CLK_OSC_INIT_DPLL_WAIT_CLKRDY, DC_CLK_OSC_INIT_GCLK_SYNC_GENCTRL0, DC_CLK_OSC_INIT_COMPLETE, - DC_SPI_INIT_BEGIN, - DC_SPI_WRITE_DRE, - DC_SPI_WRITE_TXC_1, - DC_SPI_WRITE_TXC_2, - DC_SPI_SYNC_ENABLING, - DC_SPI_INIT_COMPLETE, + DC_SPI_EXP_INIT_BEGIN, + DC_SPI_EXP_WRITE_DRE, + DC_SPI_EXP_WRITE_TXC_1, + DC_SPI_EXP_WRITE_TXC_2, + DC_SPI_EXP_SYNC_ENABLING, + DC_SPI_EXP_INIT_COMPLETE, DC_PORT_DETECT_INIT_BEGIN, DC_PORT_DETECT_INIT_FAILED, DC_PORT_DETECT_INIT_COMPLETE, DC_USB_RESET_BEGIN, DC_USB_RESET_COMPLETE, - DC_USB_SET_HOST_BY_VOLTAGE_BEGIN, - DC_USB_SET_HOST_5V_LOW_WAITING, - DC_USB_SET_HOST_BY_VOLTAGE_COMPLETE, + DC_USB_DETECT_HOST_BEGIN, + DC_USB_DETECT_HOST_5V_LOW_WAITING, + DC_USB_DETECT_HOST_COMPLETE, DC_USB_CONFIGURE_BEGIN, DC_USB_CONFIGURE_GET_SERIAL, DC_USB_CONFIGURE_COMPLETE, @@ -166,14 +165,14 @@ enum debug_code_list { DC_USB_WRITE2422_BLOCK_COMPLETE, DC_ADC0_CLOCK_INIT_BEGIN, DC_ADC0_CLOCK_INIT_COMPLETE, - DC_ADC0_INIT_BEGIN, - DC_ADC0_SWRST_SYNCING_1, - DC_ADC0_SWRST_SYNCING_2, - DC_ADC0_AVGCTRL_SYNCING_1, - DC_ADC0_AVGCTRL_SYNCING_2, - DC_ADC0_SAMPCTRL_SYNCING_1, - DC_ADC0_ENABLE_SYNCING_1, - DC_ADC0_INIT_COMPLETE, + DC_ADC_INIT_BEGIN, + DC_ADC_SWRST_SYNCING_1, + DC_ADC_SWRST_SYNCING_2, + DC_ADC_GET_AVGCTRL_SYNCING_1, + DC_ADC_GET_AVGCTRL_SYNCING_2, + DC_ADC_GET_SAMPCTRL_SYNCING_1, + DC_ADC_ENABLE_SYNCING_1, + DC_ADC_INIT_COMPLETE, DC_I2C0_INIT_BEGIN, DC_I2C0_INIT_SYNC_ENABLING, DC_I2C0_INIT_SYNC_SYSOP, @@ -211,6 +210,18 @@ enum debug_code_list { DC_MAIN_UDC_START_COMPLETE, DC_MAIN_CDC_INIT_BEGIN, DC_MAIN_CDC_INIT_COMPLETE, + DC_SPI_KC_INIT_BEGIN, + DC_SPI_KC_WRITE_DRE, + DC_SPI_KC_WRITE_TXC_1, + DC_SPI_KC_WRITE_TXC_2, + DC_SPI_KC_SYNC_ENABLING, + DC_SPI_KC_INIT_COMPLETE, + DC_ADC1_CLOCK_INIT_BEGIN, + DC_ADC1_CLOCK_INIT_COMPLETE, + DC_ADC_GET_INPUTCTRL_SYNCING_1, + DC_ADC_GET_REFCTRL_SYNCING_1, + DC_ADC_GET_SWTRIG_SYNCING_1, + DC_ADC_GET_INTFLAG_RESRDY_WAITING_1 /* Never change the order of error codes! Only add codes to end! */ }; @@ -219,5 +230,3 @@ enum debug_code_list { #define DBGC(n) {} #endif //DEBUG_BOOT_TRACING_ENABLE - -#endif //_D51_UTIL_H_ diff --git a/tmk_core/protocol/arm_atsam/i2c_master.c b/tmk_core/protocol/arm_atsam/i2c_master.c index 1741d9ac5b0..9e74a0fc36d 100644 --- a/tmk_core/protocol/arm_atsam/i2c_master.c +++ b/tmk_core/protocol/arm_atsam/i2c_master.c @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -120,10 +120,10 @@ void i2c1_init(void) CLK_set_i2c1_freq(CHAN_SERCOM_I2C1, FREQ_I2C1_DEFAULT); /* MCU */ - PORT->Group[0].PMUX[8].bit.PMUXE = 2; - PORT->Group[0].PMUX[8].bit.PMUXO = 2; - PORT->Group[0].PINCFG[16].bit.PMUXEN = 1; - PORT->Group[0].PINCFG[17].bit.PMUXEN = 1; + PORT->Group[0].PMUX[8].bit.PMUXE = 2; //PA16 even + PORT->Group[0].PMUX[8].bit.PMUXO = 2; //PA17 odd + PORT->Group[0].PINCFG[16].bit.PMUXEN = 1; //PA16 + PORT->Group[0].PINCFG[17].bit.PMUXEN = 1; //PA17 /* I2C */ //Note: SW Reset handled in CLK_set_i2c1_freq clks.c @@ -214,15 +214,11 @@ void i2c_led_send_GCR(uint8_t drvid) void i2c_led_send_onoff(uint8_t drvid) { -#if I2C_LED_USE_DMA != 1 if (!i2c_led_q_running) { -#endif i2c_led_send_CRWL(drvid); i2c_led_select_page(drvid, 0); -#if I2C_LED_USE_DMA != 1 } -#endif *issidrv[drvid].onoff = 0; //Force start location offset to zero i2c1_transmit(issidrv[drvid].addr, issidrv[drvid].onoff, ISSI3733_PG0_BYTES, 0); @@ -243,15 +239,11 @@ void i2c_led_send_pur_pdr(uint8_t drvid, uint8_t pur, uint8_t pdr) void i2c_led_send_pwm(uint8_t drvid) { -#if I2C_LED_USE_DMA != 1 if (!i2c_led_q_running) { -#endif i2c_led_send_CRWL(drvid); - i2c_led_select_page(drvid, 0); -#if I2C_LED_USE_DMA != 1 + i2c_led_select_page(drvid, 1); } -#endif *issidrv[drvid].pwm = 0; //Force start location offset to zero i2c1_transmit(issidrv[drvid].addr, issidrv[drvid].pwm, ISSI3733_PG1_BYTES, 0); @@ -292,18 +284,21 @@ uint8_t I2C3733_Init_Drivers(void) i2c_led_select_page(0, 3); i2c_led_send_mode_op_gcr(0, 0, ISSI3733_CR_SSD_NORMAL); //No SYNC due to brightness mismatch with second driver - //Set up slave device - i2c_led_send_CRWL(1); - i2c_led_select_page(1, 3); - i2c_led_send_mode_op_gcr(1, 0, ISSI3733_CR_SSD_NORMAL); //No SYNC due to brightness mismatch with first driver and slight flicker at rgb values 1,2 - i2c_led_send_CRWL(0); i2c_led_select_page(0, 3); i2c_led_send_pur_pdr(0, ISSI3733_SWYR_PUR_8000, ISSI3733_CSXR_PDR_8000); - i2c_led_send_CRWL(1); - i2c_led_select_page(1, 3); - i2c_led_send_pur_pdr(1, ISSI3733_SWYR_PUR_8000, ISSI3733_CSXR_PDR_8000); + //Set up slave devices + for (uint8_t drvid = 1; drvid < ISSI3733_DRIVER_COUNT; drvid++) + { + i2c_led_send_CRWL(drvid); + i2c_led_select_page(drvid, 3); + i2c_led_send_mode_op_gcr(drvid, 0, ISSI3733_CR_SSD_NORMAL); //No SYNC due to brightness mismatch with master driver and slight flicker at rgb values 1,2 + + i2c_led_send_CRWL(drvid); + i2c_led_select_page(drvid, 3); + i2c_led_send_pur_pdr(drvid, ISSI3733_SWYR_PUR_8000, ISSI3733_CSXR_PDR_8000); + } DBGC(DC_I2C3733_INIT_DRIVERS_COMPLETE); @@ -357,12 +352,24 @@ void I2C3733_Control_Set(uint8_t state) { DBGC(DC_I2C3733_CONTROL_SET_BEGIN); + if (sr_exp_data.bit.SDB_N == 0 && state == 1) + { + gcr_actual = 0; //Set low GCR when turning on to prevent instant overload conditions + } + sr_exp_data.bit.SDB_N = (state == 1 ? 1 : 0); SR_EXP_WriteData(); DBGC(DC_I2C3733_CONTROL_SET_COMPLETE); } +//Return 1 if enabled +//Return 0 if disabled +uint8_t I2C3733_Control_Get(void) +{ + return (sr_exp_data.bit.SDB_N == 1); +} + void i2c_led_desc_defaults(void) { dmac_desc.BTCTRL.bit.STEPSIZE = 0; //SRCINC used in favor for auto 1 inc @@ -421,7 +428,6 @@ void i2c_led_send_GCR_dma(uint8_t drvid) void i2c_led_send_pwm_dma(uint8_t drvid) { - //Note: This copies the CURRENT pwm buffer, which may be getting modified memcpy(dma_sendbuf, issidrv[drvid].pwm, ISSI3733_PG1_BYTES); *dma_sendbuf = 0; //Force start location offset to zero i2c_led_prepare_send_dma(dma_sendbuf, ISSI3733_PG1_BYTES); diff --git a/tmk_core/protocol/arm_atsam/i2c_master.h b/tmk_core/protocol/arm_atsam/i2c_master.h index 99481366a57..36922922da6 100644 --- a/tmk_core/protocol/arm_atsam/i2c_master.h +++ b/tmk_core/protocol/arm_atsam/i2c_master.h @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -32,6 +32,7 @@ DmacDescriptor dmac_desc_wb; uint8_t I2C3733_Init_Control(void); uint8_t I2C3733_Init_Drivers(void); void I2C3733_Control_Set(uint8_t state); +uint8_t I2C3733_Control_Get(void); void I2C_DMAC_LED_Init(void); #define I2C_Q_SIZE 100 diff --git a/tmk_core/protocol/arm_atsam/led_matrix.c b/tmk_core/protocol/arm_atsam/led_matrix.c index e29fb6587c9..29142c842ca 100644 --- a/tmk_core/protocol/arm_atsam/led_matrix.c +++ b/tmk_core/protocol/arm_atsam/led_matrix.c @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -64,120 +64,123 @@ issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT]; issi3733_led_t led_map[ISSI3733_LED_COUNT] = ISSI3733_LED_MAP; RGB led_buffer[ISSI3733_LED_COUNT]; -uint8_t gcr_desired; -uint8_t gcr_actual; -uint8_t gcr_actual_last; +uint8_t gcr_desired; //User's desired GCR value (brightness setting) +uint8_t gcr_actual; //The GCR value about to be written to LED drivers +uint8_t gcr_actual_last; //The GCR value last written to LED drivers #ifdef USE_MASSDROP_CONFIGURATOR -uint8_t gcr_breathe; +uint8_t gcr_breathe; //The maximum attained GCR value during a breathe cycle (for smooth light transitions) float breathe_mult; float pomod; -#endif +uint32_t power_sum = 0; //Sum of RGB values for current LED pattern (about to be visible) +uint32_t power_sum_last; //Sum of RGB values for previous LED pattern (currently visible) +#endif // USE_MASSDROP_CONFIGURATOR -#define ACT_GCR_NONE 0 -#define ACT_GCR_INC 1 -#define ACT_GCR_DEC 2 +//Actions to take for GCR +#define ACT_GCR_NONE 0 //Take no action on GCR +#define ACT_GCR_INC 1 //Increase GCR +#define ACT_GCR_DEC 2 //Decrease GCR -#define LED_GCR_STEP_AUTO 2 +//GCR step settings +#define LED_GCR_STEP_AUTO 1 //How many GCR steps to take per increase or decrease call +#define ACT_GCR_DEC_COUNT -1 //Number at which a GCR decrease will actually happen (decrements should happen fast to react to sudden high load) +#define ACT_GCR_INC_COUNT 5 //Number at which a GCR increase will actually happen (increments should happen slow to gently approach power limits) -static uint8_t gcr_min_counter; -static uint8_t v_5v_cat_hit; +int8_t gcr_change_counter; //GCR increase and decrease calls are counted here and acted upon when a count limit is hit +uint16_t v_5v_cat_hit; //Flag for when 5v catastrophic level has been reached, and timer for recovery period +uint64_t v_5v_low_timer; //Timer for disabling USB extra device after causing a low voltage situation for an amount of time (-1 indicates timer not active) //WARNING: Automatic GCR is in place to prevent USB shutdown and LED driver overloading +//Note: GCR updates are currently synced to come before a PWM update, so GCR updates actually happen off the PWM update timer void gcr_compute(void) { - uint8_t action = ACT_GCR_NONE; - uint8_t gcr_use = gcr_desired; + uint8_t action = ACT_GCR_NONE; //Default GCR action to be taken + uint8_t gcr_use = gcr_desired; //The GCR value to test against + + if (!I2C3733_Control_Get()) //If LED drivers are not on + { + gcr_actual = 0; //Minimize GCR + return; //Nothing else to do + } #ifdef USE_MASSDROP_CONFIGURATOR - if (led_animation_breathing) + if (led_animation_breathing) //If breathing effect is being used { - gcr_use = gcr_breathe; + gcr_use = gcr_breathe; //Set max GCR possible to the highest GCR attained during breathe cycles } -#endif +#endif // USE_MASSDROP_CONFIGURATOR - //If the 5v takes a catastrophic hit, disable the LED drivers briefly, assert auto gcr mode, min gcr and let the auto take over - if (v_5v < V5_CAT) + if (usb_gcr_auto) //If automatic GCR is enabled { - I2C3733_Control_Set(0); - //CDC_print("USB: WARNING: 5V catastrophic level reached! Disabling LED drivers!\r\n"); //Blocking print is bad here! - v_5v_cat_hit = 20; //~100ms recover - gcr_actual = 0; //Minimize GCR - usb_gcr_auto = 1; //Force auto mode enabled - return; + //If 5v bus is low or the desired GCR is less than actual, and we have not reached the decrease threshold + if ((uint16_t)g_v_5v_avg < V5_LOW || gcr_desired < gcr_actual) + { + if (gcr_change_counter > ACT_GCR_DEC_COUNT) + { + gcr_change_counter--; //Decrease GCR change count + } + } + else if ((uint16_t)g_v_5v_avg > V5_HIGH) //else if 5v bus is high and we have not reached the increase threshold + { + if (gcr_change_counter < ACT_GCR_INC_COUNT) + { + gcr_change_counter++; //Increase GCR change count + } + } + else + { + //If no action, seek zero + if (gcr_change_counter > 0) { gcr_change_counter--; } + else if (gcr_change_counter < 0) { gcr_change_counter++; } + } + + if (gcr_change_counter == ACT_GCR_DEC_COUNT) //If change counter has reached the decrease threshold + { + //Note: Not checking if there is room to decrease here as that is taken into account differently on the actual decrease action + action = ACT_GCR_DEC; //Set action to decrease + } + else if (gcr_change_counter == ACT_GCR_INC_COUNT) //Else if change counter has reached the increase threshold + { + if (gcr_actual < gcr_use && I2C3733_Control_Get()) //If there is room to increase and LED drivers are on + { + action = ACT_GCR_INC; //Set action to increase + } + } } - else if (v_5v_cat_hit > 1) + else //Else automatic GCR is disabled so immediately follow user's desired value { - v_5v_cat_hit--; - return; - } - else if (v_5v_cat_hit == 1) - { - I2C3733_Control_Set(1); - CDC_print("USB: WARNING: Re-enabling LED drivers\r\n"); - v_5v_cat_hit = 0; - return; + if (gcr_actual < gcr_use) action = ACT_GCR_INC; //If actual has not met the use value, set action to increase + else if (gcr_actual > gcr_use) action = ACT_GCR_DEC; //Else if the actual is more than the use value, set action to decrease } - if (usb_gcr_auto) - { - if (v_5v_avg < V5_LOW) action = ACT_GCR_DEC; - else if (v_5v_avg > V5_HIGH && gcr_actual < gcr_use) action = ACT_GCR_INC; - else if (gcr_actual > gcr_use) action = ACT_GCR_DEC; - } - else - { - if (gcr_actual < gcr_use) action = ACT_GCR_INC; - else if (gcr_actual > gcr_use) action = ACT_GCR_DEC; - } - - if (action == ACT_GCR_NONE) - { - gcr_min_counter = 0; - } - else if (action == ACT_GCR_INC) + if (action == ACT_GCR_INC) { + gcr_change_counter = 0; if (LED_GCR_STEP_AUTO > LED_GCR_MAX - gcr_actual) gcr_actual = LED_GCR_MAX; //Obey max and prevent wrapping else gcr_actual += LED_GCR_STEP_AUTO; - gcr_min_counter = 0; } else if (action == ACT_GCR_DEC) { + gcr_change_counter = 0; if (LED_GCR_STEP_AUTO > gcr_actual) //Prevent wrapping { gcr_actual = 0; - //At this point, power can no longer be cut from the LED drivers, so focus on cutting out extra port if active - if (usb_extra_state != USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG) //If not in a wait for replug state - { - if (usb_extra_state == USB_EXTRA_STATE_ENABLED) //If extra usb is enabled - { - gcr_min_counter++; - if (gcr_min_counter > 200) //5ms per check = 1s delay - { - USB_ExtraSetState(USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG); - usb_extra_manual = 0; //Force disable manual mode of extra port - if (usb_extra_manual) CDC_print("USB: Disabling extra port until replug and manual mode toggle!\r\n"); - else CDC_print("USB: Disabling extra port until replug!\r\n"); - } - } - } } else { //Power successfully cut back from LED drivers gcr_actual -= LED_GCR_STEP_AUTO; - gcr_min_counter = 0; #ifdef USE_MASSDROP_CONFIGURATOR //If breathe mode is active, the top end can fluctuate if the host can not supply enough current - //So set the breathe GCR to where it becomes stable + //So set the breathe GCR to where it can safely reach if (led_animation_breathing == 1) { gcr_breathe = gcr_actual; //PS: At this point, setting breathing to exhale makes a noticebly shorter cycle // and the same would happen maybe one or two more times. Therefore I'm favoring - // powering through one full breathe and letting gcr settle completely + // powering through one full breathe and letting GCR settle completely } -#endif +#endif // USE_MASSDROP_CONFIGURATOR } } } @@ -229,7 +232,7 @@ void led_set_one(int i, uint8_t r, uint8_t g, uint8_t b) led_buffer[i].r = r; led_buffer[i].g = g; led_buffer[i].b = b; -#endif +#endif // USE_MASSDROP_CONFIGURATOR } } @@ -249,7 +252,7 @@ void init(void) led_matrix_prepare(); - gcr_min_counter = 0; + gcr_change_counter = 0; v_5v_cat_hit = 0; DBGC(DC_LED_MATRIX_INIT_COMPLETE); @@ -257,16 +260,34 @@ void init(void) void flush(void) { -#ifdef USE_MASSDROP_CONFIGURATOR - if (!led_enabled) { return; } //Prevent calculations and I2C traffic if LED drivers are not enabled -#else - if (!sr_exp_data.bit.SDB_N) { return; } //Prevent calculations and I2C traffic if LED drivers are not enabled -#endif + uint8_t drvid; - // Wait for previous transfer to complete +#ifdef USE_MASSDROP_CONFIGURATOR + //If there will be a sudden spike in required power, lower GCR prior to change according to some ratio + if (power_sum > (uint32_t)((float)power_sum_last * 1.5)) + { + //Lower GCR according to a percentage of the change in power ratio + gcr_actual = (uint8_t)((((float)gcr_actual * ((float)power_sum_last / (float)power_sum)) * 0.8) + 0.5); + } + power_sum_last = power_sum; + power_sum = 0; + + //NOTE: Allow GCR updates even if the drivers lighting is disabled + if (gcr_actual != gcr_actual_last) + { + for (drvid=0;drvid= BREATHE_MAX_STEP) - breathe_dir = -1; - else if (led_animation_breathe_cur <= BREATHE_MIN_STEP) - breathe_dir = 1; + if (led_animation_breathe_cur >= BREATHE_MAX_STEP) { breathe_dir = -1; } + else if (led_animation_breathe_cur <= BREATHE_MIN_STEP) { breathe_dir = 1; } //Brightness curve created for 256 steps, 0 - ~98% breathe_mult = 0.000015 * led_animation_breathe_cur * led_animation_breathe_cur; - if (breathe_mult > 1) breathe_mult = 1; - else if (breathe_mult < 0) breathe_mult = 0; + if (breathe_mult > 1) { breathe_mult = 1; } + else if (breathe_mult < 0) { breathe_mult = 0; } } - //This should only be performed once per frame - pomod = (float)((g_rgb_counters.tick / 10) % (uint32_t)(1000.0f / led_animation_speed)) / 10.0f * led_animation_speed; + pomod = 0; + if (led_animation_speed != 0) //Avoid DIV0 + { + pomod = (float)((g_rgb_counters.tick / 10) % (uint32_t)(1000.0f / led_animation_speed)) / 10.0f * led_animation_speed; + } pomod *= 100.0f; pomod = (uint32_t)pomod % 10000; pomod /= 100.0f; - #endif // USE_MASSDROP_CONFIGURATOR - - uint8_t drvid; - - //NOTE: GCR does not need to be timed with LED processing, but there is really no harm - if (gcr_actual != gcr_actual_last) - { - for (drvid=0;drvidrgb.r > 127) *led_cur->rgb.r = 0; + //TODO: Old code, see if this hard cutoff is better// else *led_cur->rgb.r = 255; + //TODO: Old code, see if this hard cutoff is better// if (*led_cur->rgb.g > 127) *led_cur->rgb.g = 0; + //TODO: Old code, see if this hard cutoff is better// else *led_cur->rgb.g = 255; + //TODO: Old code, see if this hard cutoff is better// if (*led_cur->rgb.b > 127) *led_cur->rgb.b = 0; + //TODO: Old code, see if this hard cutoff is better// else *led_cur->rgb.b = 255; } } } @@ -372,15 +388,31 @@ uint8_t led_animation_breathing = 0; uint8_t led_animation_id = 0; float led_animation_speed = 4.0f; uint8_t led_lighting_mode = LED_MODE_NORMAL; -uint8_t led_enabled = 1; uint8_t led_animation_breathe_cur = BREATHE_MIN_STEP; uint8_t breathe_dir = 1; +uint8_t led_animation_circular = 0; +float led_edge_brightness = 1.0f; +uint8_t led_edge_mode = LED_EDGE_MODE_ALL; static void led_run_pattern(led_setup_t *f, float* ro, float* go, float* bo, float pos) { float po; while (f->end != 1) { + //OLD-CODE// //TODO: Get this working again if (led_animation_circular) { + //OLD-CODE// //TODO: Get this working again po = sqrtf((powf(fabsf((disp.width / 2) - (led_cur->x - disp.left)), 2) + powf(fabsf((disp.height / 2) - (led_cur->y - disp.bottom)), 2))) / disp.max_distance * 100; + //OLD-CODE// //TODO: Get this working again } + //OLD-CODE// //TODO: Get this working again else { + //OLD-CODE// //TODO: Get this working again if (led_animation_orientation) + //OLD-CODE// //TODO: Get this working again { + //OLD-CODE// //TODO: Get this working again po = led_cur->py; + //OLD-CODE// //TODO: Get this working again } + //OLD-CODE// //TODO: Get this working again else + //OLD-CODE// //TODO: Get this working again { + //OLD-CODE// //TODO: Get this working again po = led_cur->px; + //OLD-CODE// //TODO: Get this working again } + //OLD-CODE// //TODO: Get this working again } + po = pos; //Reset po for new frame //Add in any moving effects @@ -431,22 +463,64 @@ static void led_run_pattern(led_setup_t *f, float* ro, float* go, float* bo, flo } } +//TODO: For circular animation fix?// void disp_calc_extents(void) +//TODO: For circular animation fix?// { +//TODO: For circular animation fix?// issi3733_led_t *cur = led_map; +//TODO: For circular animation fix?// +//TODO: For circular animation fix?// disp.left = 1e10; +//TODO: For circular animation fix?// disp.right = -1e10; +//TODO: For circular animation fix?// disp.top = -1e10; +//TODO: For circular animation fix?// disp.bottom = 1e10; +//TODO: For circular animation fix?// +//TODO: For circular animation fix?// while (cur < lede) +//TODO: For circular animation fix?// { +//TODO: For circular animation fix?// if (cur->x < disp.left) disp.left = cur->x; +//TODO: For circular animation fix?// if (cur->x > disp.right) disp.right = cur->x; +//TODO: For circular animation fix?// if (cur->y < disp.bottom) disp.bottom = cur->y; +//TODO: For circular animation fix?// if (cur->y > disp.top) disp.top = cur->y; +//TODO: For circular animation fix?// +//TODO: For circular animation fix?// cur++; +//TODO: For circular animation fix?// } +//TODO: For circular animation fix?// +//TODO: For circular animation fix?// disp.width = disp.right - disp.left; +//TODO: For circular animation fix?// disp.height = disp.top - disp.bottom; +//TODO: For circular animation fix?// disp.max_distance = sqrtf(powf(disp.width, 2) + powf(disp.height, 2)); +//TODO: For circular animation fix?// } + +#define RGB_MAX_DISTANCE 232.9635f + static void led_matrix_massdrop_config_override(int i) { float ro = 0; float go = 0; float bo = 0; - - float po = (led_animation_orientation) - ? (float)g_rgb_leds[i].point.y / 64.f * 100 - : (float)g_rgb_leds[i].point.x / 224.f * 100; - + float po; uint8_t highest_active_layer = biton32(layer_state); - if (led_lighting_mode == LED_MODE_KEYS_ONLY && g_rgb_leds[i].matrix_co.raw == 0xff) { + if (led_animation_circular) { + //disp.width + //disp.left + //disp.height + //disp.bottom + //disp.max_distance + //TODO: led_animation_circular needs fixing + //For reference, the old function was + //po = sqrtf((powf(fabsf((disp.width / 2) - ((float)g_rgb_leds[i].point.x - disp.left)), 2) + powf(fabsf((disp.height / 2) - ((float)g_rgb_leds[i].point.y - disp.bottom)), 2))) / disp.max_distance * 100; + po = sqrtf((powf(fabsf((224 / 2) - (float)g_rgb_leds[i].point.x), 2) + powf(fabsf((64 / 2) - (float)g_rgb_leds[i].point.y), 2))) / RGB_MAX_DISTANCE * 100; + } else { + if (led_animation_orientation) { + po = (float)g_rgb_leds[i].point.y / 64.f * 100; + } else { + po = (float)g_rgb_leds[i].point.x / 224.f * 100; + } + } + + if (led_lighting_mode == LED_MODE_KEYS_ONLY && LED_IS_EDGE(led_map[i].scan)) { //Do not act on this LED - } else if (led_lighting_mode == LED_MODE_NON_KEYS_ONLY && g_rgb_leds[i].matrix_co.raw != 0xff) { + } else if (led_lighting_mode == LED_MODE_NON_KEYS_ONLY && !LED_IS_EDGE(led_map[i].scan)) { //Do not act on this LED + } else if (led_edge_mode == LED_EDGE_MODE_ALTERNATE && LED_IS_EDGE_ALT(led_map[i].scan)) { + //Do not act on this LED (Edge alternate lighting mode) } else if (led_lighting_mode == LED_MODE_INDICATORS_ONLY) { //Do not act on this LED (Only show indicators) } else { @@ -482,6 +556,7 @@ static void led_matrix_massdrop_config_override(int i) led_cur_instruction++; } + //Clamp values 0-255 if (ro > 255) ro = 255; else if (ro < 0) ro = 0; if (go > 255) go = 255; else if (go < 0) go = 0; if (bo > 255) bo = 255; else if (bo < 0) bo = 0; @@ -494,9 +569,19 @@ static void led_matrix_massdrop_config_override(int i) } } + //Adjust edge LED brightness + if (led_edge_brightness != 1 && LED_IS_EDGE(led_map[i].scan)) + { + ro *= led_edge_brightness; + go *= led_edge_brightness; + bo *= led_edge_brightness; + } + led_buffer[i].r = (uint8_t)ro; led_buffer[i].g = (uint8_t)go; led_buffer[i].b = (uint8_t)bo; + + power_sum += (uint8_t)ro + (uint8_t)go + (uint8_t)bo; } #endif // USE_MASSDROP_CONFIGURATOR diff --git a/tmk_core/protocol/arm_atsam/led_matrix.h b/tmk_core/protocol/arm_atsam/led_matrix.h index 1316efd9a4f..9fb33c52090 100644 --- a/tmk_core/protocol/arm_atsam/led_matrix.h +++ b/tmk_core/protocol/arm_atsam/led_matrix.h @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -47,7 +47,7 @@ typedef struct issi3733_driver_s { uint8_t onoff[ISSI3733_PG_ONOFF_BYTES]; //PG0 - LED Control Register - LED On/Off Register uint8_t open[ISSI3733_PG_OR_BYTES]; //PG0 - LED Control Register - LED Open Register uint8_t shrt[ISSI3733_PG_SR_BYTES]; //PG0 - LED Control Register - LED Short Register - uint8_t pwm[ISSI3733_PG_PWM_BYTES]; //PG1 - PWM Register + uint8_t pwm[ISSI3733_PG_PWM_BYTES]; //PG1 - PWM Register for working data uint8_t abm[ISSI3733_PG_ABM_BYTES]; //PG2 - Auto Breath Mode Register uint8_t conf[ISSI3733_PG_FN_BYTES]; //PG3 - Function Register } issi3733_driver_t; @@ -142,16 +142,30 @@ extern uint8_t led_animation_breathing; extern uint8_t led_animation_id; extern float led_animation_speed; extern uint8_t led_lighting_mode; -extern uint8_t led_enabled; extern uint8_t led_animation_breathe_cur; extern uint8_t led_animation_direction; extern uint8_t breathe_dir; +extern uint8_t led_animation_orientation; +extern uint8_t led_animation_circular; +extern float led_edge_brightness; +extern uint8_t led_edge_mode; -#define LED_MODE_NORMAL 0 //Must be 0 +#define LED_MODE_NORMAL 0 //Must be 0 #define LED_MODE_KEYS_ONLY 1 #define LED_MODE_NON_KEYS_ONLY 2 #define LED_MODE_INDICATORS_ONLY 3 -#define LED_MODE_MAX_INDEX LED_MODE_INDICATORS_ONLY //Must be highest value +#define LED_MODE_MAX_INDEX LED_MODE_INDICATORS_ONLY //Must be highest valued LED mode + +#define LED_EDGE_MODE_ALL 0 //All edge LEDs are active (Must be 0) +#define LED_EDGE_MODE_ALTERNATE 1 //Alternate mode of edge LEDs are active (Intention is for 'only every other edge LED' to be active) +#define LED_EDGE_MODE_MAX LED_EDGE_MODE_ALTERNATE //Must be the highest valued LED edge mode + +#define LED_EDGE_FULL_MODE 255 //LEDs configured with this scan code will always be on for edge lighting modes +#define LED_EDGE_ALT_MODE 254 //LEDs configured with this scan code will turn off in edge alternating mode +#define LED_EDGE_MIN_SCAN 254 //LEDs configured with scan code >= to this are assigned as edge LEDs + +#define LED_IS_EDGE(scan) (scan >= LED_EDGE_MIN_SCAN) //Return true if an LED's scan value indicates an edge LED +#define LED_IS_EDGE_ALT(scan) (scan == LED_EDGE_ALT_MODE) //Return true if an LED's scan value indicates an alternate edge mode LED #endif // USE_MASSDROP_CONFIGURATOR diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c index 0974a230d4c..aafb0f06a43 100644 --- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c +++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,6 +31,8 @@ along with this program. If not, see . //From keyboard's directory #include "config_led.h" +volatile char embed_version[] = COMPILE_VERSION; + uint8_t g_usb_state = USB_FSMSTATUS_FSMSTATE_OFF_Val; //Saved USB state from hardware value to detect changes void main_subtasks(void); @@ -188,9 +190,9 @@ void main_subtask_usb_state(void) { if (fsmstate_on_delay == 0) //If ON delay timer is cleared { - fsmstate_on_delay = timer_read64() + 250; //Set ON delay timer + fsmstate_on_delay = timer_read64() + 250; //Set ON delay timer } - else if (timer_read64() > fsmstate_on_delay) //Else if ON delay timer is active and timed out + else if (timer_read64() > fsmstate_on_delay) //Else if ON delay timer is active and timed out { suspend_wakeup_init(); //Run wakeup routine g_usb_state = fsmstate_now; //Save current USB state @@ -207,12 +209,14 @@ void main_subtask_power_check(void) { static uint64_t next_5v_checkup = 0; - if (timer_read64() > next_5v_checkup) + if (timer_read64() >= next_5v_checkup) { - next_5v_checkup = timer_read64() + 5; + next_5v_checkup = timer_read64() + POWER_CHECK_INTERVAL; - v_5v = adc_get(ADC_5V); - v_5v_avg = 0.9 * v_5v_avg + 0.1 * v_5v; + g_v_5v = adc_get(ADC_5V); + g_v_5v_avg = (((float)V_5V_AVGS - 1) / (float)V_5V_AVGS) * g_v_5v_avg + (1 / (float)V_5V_AVGS) * (float)g_v_5v; + + power_run(); //Check up on 5v bus voltage for spikes or low conditions #ifdef RGB_MATRIX_ENABLE gcr_compute(); @@ -224,9 +228,9 @@ void main_subtask_usb_extra_device(void) { static uint64_t next_usb_checkup = 0; - if (timer_read64() > next_usb_checkup) + if (timer_read64() >= next_usb_checkup) { - next_usb_checkup = timer_read64() + 10; + next_usb_checkup = timer_read64() + USBC_CFG_PERIOD; USB_HandleExtraDevice(); } @@ -253,13 +257,14 @@ int main(void) CLK_init(); - ADC0_init(); + ADC_init(); SR_EXP_Init(); #ifdef RGB_MATRIX_ENABLE i2c1_init(); #endif // RGB_MATRIX_ENABLE + power_init(); matrix_init(); @@ -299,10 +304,10 @@ int main(void) uint64_t next_print = 0; #endif //CONSOLE_ENABLE - v_5v_avg = adc_get(ADC_5V); - debug_code_disable(); + usbc_enable(); + while (1) { main_subtasks(); //Note these tasks will also be run while waiting for USB keyboard polling intervals @@ -323,14 +328,25 @@ int main(void) #ifdef CONSOLE_ENABLE if (timer_read64() > next_print) { - next_print = timer_read64() + 250; + next_print = timer_read64() + 1; + //Add any debug information here that you want to see very often - //dprintf("5v=%u 5vu=%u dlow=%u dhi=%u gca=%u gcd=%u\r\n", v_5v, v_5v_avg, v_5v_avg - V5_LOW, v_5v_avg - V5_HIGH, gcr_actual, gcr_desired); + + //Corrected CC values for host port detection debugging + //dprintf("%4u %4u %4u %4u\n",ADC_CC_5VCOR(g_v_5v, adc_get(ADC_C1A5)), + // ADC_CC_5VCOR(g_v_5v, adc_get(ADC_C1B5)), + // ADC_CC_5VCOR(g_v_5v, adc_get(ADC_C2A5)), + // ADC_CC_5VCOR(g_v_5v, adc_get(ADC_C2B5))); + + //USB state and CC line monitoring + //dprintf("%4u %4u %4u %4u %2u %1u\n",usbc_cc_a5_v,usbc_cc_b5_v,(uint16_t)usbc_cc_a5_v_avg,(uint16_t)usbc_cc_b5_v_avg,usbc.state,usbc.state == USB_STATE_ATTACHED_SRC ? 1 : 0); + + //Power manager monitoring + //dprintf("%4u %4u %3u %3u %3u %i %3u\n",g_v_5v,(uint16_t)g_v_5v_avg,gcr_desired,(uint8_t)gcr_actual,gcr_actual_last,gcr_change_counter,usbc.state); } #endif //CONSOLE_ENABLE } - return 1; } diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.h b/tmk_core/protocol/arm_atsam/main_arm_atsam.h index 78205e2e1be..1b4031e0e76 100644 --- a/tmk_core/protocol/arm_atsam/main_arm_atsam.h +++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.h @@ -18,6 +18,8 @@ along with this program. If not, see . #ifndef _MAIN_ARM_ATSAM_H_ #define _MAIN_ARM_ATSAM_H_ +#define COMPILE_VERSION "VER "__DATE__" "__TIME__" [" QMK_KEYBOARD ":" QMK_KEYMAP "]\n\r" + uint8_t keyboard_leds(void); #endif //_MAIN_ARM_ATSAM_H_ diff --git a/tmk_core/protocol/arm_atsam/md_bootloader.h b/tmk_core/protocol/arm_atsam/md_bootloader.h index 956145c3132..43ee306cff5 100644 --- a/tmk_core/protocol/arm_atsam/md_bootloader.h +++ b/tmk_core/protocol/arm_atsam/md_bootloader.h @@ -1,5 +1,4 @@ -#ifndef _MD_BOOTLOADER_H_ -#define _MD_BOOTLOADER_H_ +#pragma once extern uint32_t _srom; extern uint32_t _lrom; @@ -14,12 +13,3 @@ extern uint32_t _eram; #define MAGIC_ADDR (uint32_t *)(&_eram - 4) #endif -#ifdef MD_BOOTLOADER - -#define MCU_HZ 48000000 -#define I2C_HZ 0 //Not used - -#endif //MD_BOOTLOADER - -#endif //_MD_BOOTLOADER_H_ - diff --git a/tmk_core/protocol/arm_atsam/power.c b/tmk_core/protocol/arm_atsam/power.c new file mode 100644 index 00000000000..b0a17892a48 --- /dev/null +++ b/tmk_core/protocol/arm_atsam/power.c @@ -0,0 +1,100 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#ifndef MD_BOOTLOADER + +#include "arm_atsam_protocol.h" + +uint64_t v_5v_cat_timer; //Timer for recovery period post 5v catastrophic low voltage detected (and LED driver disable)(-1 indicates timer not active) +uint64_t v_5v_low_timer; //Timer for disabling USB extra device after causing a low voltage situation for an amount of time (-1 indicates timer not active) + +//Returns 1 if the 5v bus is in a catastrophic low voltage condition +//Returns 0 if the 5v bus is OK +uint8_t power_5v_check(void) { + if (g_v_5v < V5_CAT) { //If the 5v bus has reached a catastrophic low level + //See if this is a spike condition due to noise by re-testing a few times + uint8_t v_5v_tests; //Current 5v bus test number + uint16_t v_5v_test_cat; //Current 5v bus reading + for (v_5v_tests = 0; v_5v_tests < POWER_5V_SPIKE_TESTS; v_5v_tests++) { //Run spike tests + v_5v_test_cat = adc_get(ADC_5V); //Get new 5v bus reading + if (v_5v_test_cat > V5_CAT) { //If the reading is not catastrophic + g_v_5v = v_5v_test_cat; //Spike was temporary so update to new reading + break; //Break from spike testing + } + } + } + + if (g_v_5v < V5_CAT) { + //The spike is a sustained event, so begin cutting back power where possible to recover + //If the LED drivers are on, disable them briefly, set GCR to minimum, and assert auto GCR mode is enabled + if (I2C3733_Control_Get()) { + I2C3733_Control_Set(0); //Disable all LED drivers + v_5v_cat_timer = timer_read64() + 250; //Begin the catastrophic low voltage timer + gcr_actual = 0; //Minimize GCR + usb_gcr_auto = 1; //Force auto GCR mode enabled + dprintf("USB: WARNING: 5V catastrophic level reached! Disabling LED drivers!\n"); //Debug output + } else { //Else the LED drivers are already disabled or at zero GCR, so the extra port is taking too much power, cut its 5v + if (usbc.state == USB_STATE_ATTACHED_SRC) { //If a device is attached + if (usbc.state != USB_STATE_DISABLED_UNTIL_DETACH) { //If not already in disabled waiting state + usbc.state = USB_STATE_DISABLED_UNTIL_DETACH; //Set state to disable until the device is unplugged + usbc_task(); //Immediately update USBC state to disable 5V + dprintf("USB: Disabling extra port until device unplugged!\n"); //Debug output + } + } + } + } + + if (((uint16_t)g_v_5v_avg < V5_LOW) && (usbc.state == USB_STATE_ATTACHED_SRC)) //If 5v bus is low and a USB device is attached + { + if (v_5v_low_timer == -1) { //If the low voltage timer is not already running + v_5v_low_timer = timer_read64() + 1000; //Set the low voltage timer for 1s + } + if (timer_read64() > v_5v_low_timer) { //If the low voltage timer has expired + usbc.state = USB_STATE_DISABLED_UNTIL_DETACH; //Set usbc state to remove the load + usbc_task(); //Immediately update USBC state to disable 5V + dprintf("USB: Disabling extra port until device unplugged!\n"); //Debug output + v_5v_low_timer = -1; //Disable the low voltage timer + } + } else { //else 5v bus is not low or USB device is not attached + v_5v_low_timer = -1; //Disable the low voltage timer + } + + if (v_5v_cat_timer != -1) { //If the catastrophic timer is active + if (timer_read64() > v_5v_cat_timer) { //If the catastrophic timer has expired + if (!I2C3733_Control_Get()) { //If LED drivers are enabled by the user + I2C3733_Control_Set(1); //Re-enable the LED drivers + } + dprintf("USB: WARNING: Re-enabling LED drivers\n"); //Debug output + v_5v_cat_timer = -1; //Disable the timer + } else { //Else the catastrophic timer is still running + return 1; //Return catastrophic state + } + } + + return 0; //Return OK state +} + +void power_init(void) { + v_5v_cat_timer = -1; //Disable the catastrophic low voltage timer + v_5v_low_timer = -1; //Disable the low voltage timer +} + +void power_run(void) { + power_5v_check(); //Run 5v bus check +} + +#endif //MD_BOOTLOADER diff --git a/tmk_core/protocol/arm_atsam/power.h b/tmk_core/protocol/arm_atsam/power.h new file mode 100644 index 00000000000..a120c8821a5 --- /dev/null +++ b/tmk_core/protocol/arm_atsam/power.h @@ -0,0 +1,24 @@ +/* +Copyright 2019 Massdrop Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +#define POWER_5V_SPIKE_TESTS 3 //Number of tests to do when a catastrophic spike is detected, to determine if it is a sustained event + +uint8_t power_5v_check(void); +void power_init(void); +void power_run(void); diff --git a/tmk_core/protocol/arm_atsam/spi.c b/tmk_core/protocol/arm_atsam/spi.c index e275ba13f4d..5f60263226b 100644 --- a/tmk_core/protocol/arm_atsam/spi.c +++ b/tmk_core/protocol/arm_atsam/spi.c @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,71 +17,114 @@ along with this program. If not, see . #include "arm_atsam_protocol.h" +/* Shift Register output EXPander Data */ sr_exp_t sr_exp_data; +/* Shift Register output EXPander Write Data */ void SR_EXP_WriteData(void) { SR_EXP_RCLK_LO; - while (!(SR_EXP_SERCOM->SPI.INTFLAG.bit.DRE)) { DBGC(DC_SPI_WRITE_DRE); } + while (!(SR_EXP_SERCOM->SPI.INTFLAG.bit.DRE)) { DBGC(DC_SPI_EXP_WRITE_DRE); } - SR_EXP_SERCOM->SPI.DATA.bit.DATA = sr_exp_data.reg & 0xFF; //Shift in bits 7-0 - while (!(SR_EXP_SERCOM->SPI.INTFLAG.bit.TXC)) { DBGC(DC_SPI_WRITE_TXC_1); } + /* Shift in bits 7 - 0 */ + SR_EXP_SERCOM->SPI.DATA.bit.DATA = sr_exp_data.reg & 0xFF; + while (!(SR_EXP_SERCOM->SPI.INTFLAG.bit.TXC)) { DBGC(DC_SPI_EXP_WRITE_TXC_1); } - SR_EXP_SERCOM->SPI.DATA.bit.DATA = (sr_exp_data.reg >> 8) & 0xFF; //Shift in bits 15-8 - while (!(SR_EXP_SERCOM->SPI.INTFLAG.bit.TXC)) { DBGC(DC_SPI_WRITE_TXC_2); } + /* Shift in bits 15 - 8 */ + SR_EXP_SERCOM->SPI.DATA.bit.DATA = (sr_exp_data.reg >> 8) & 0xFF; + while (!(SR_EXP_SERCOM->SPI.INTFLAG.bit.TXC)) { DBGC(DC_SPI_EXP_WRITE_TXC_2); } SR_EXP_RCLK_HI; } +/* Shift Register output EXPander Initialization */ void SR_EXP_Init(void) { - DBGC(DC_SPI_INIT_BEGIN); + DBGC(DC_SPI_EXP_INIT_BEGIN); - CLK_set_spi_freq(CHAN_SERCOM_SPI, FREQ_SPI_DEFAULT); + CLK_set_spi_freq(CHAN_SERCOM_SPI_EXP, FREQ_SPI_DEFAULT); - //Set up MCU Shift Register pins + /* Set up MCU shift register pins */ PORT->Group[SR_EXP_RCLK_PORT].DIRSET.reg = (1 << SR_EXP_RCLK_PIN); PORT->Group[SR_EXP_OE_N_PORT].DIRSET.reg = (1 << SR_EXP_OE_N_PIN); - - //Set up MCU SPI pins + + /* Set up MCU SPI pins */ PORT->Group[SR_EXP_DATAOUT_PORT].PMUX[SR_EXP_DATAOUT_PIN / 2].bit.SR_EXP_DATAOUT_MUX_SEL = SR_EXP_DATAOUT_MUX; //MUX select for sercom PORT->Group[SR_EXP_SCLK_PORT].PMUX[SR_EXP_SCLK_PIN / 2].bit.SR_EXP_SCLK_MUX_SEL = SR_EXP_SCLK_MUX; //MUX select for sercom PORT->Group[SR_EXP_DATAOUT_PORT].PINCFG[SR_EXP_DATAOUT_PIN].bit.PMUXEN = 1; //MUX Enable PORT->Group[SR_EXP_SCLK_PORT].PINCFG[SR_EXP_SCLK_PIN].bit.PMUXEN = 1; //MUX Enable - //Initialize Shift Register - SR_EXP_OE_N_DIS; - SR_EXP_RCLK_HI; + /* Run keyboard init routine to finalize initialization */ + SR_EXP_Init_kb(); - SR_EXP_SERCOM->SPI.CTRLA.bit.DORD = 1; //Data Order - LSB is transferred first - SR_EXP_SERCOM->SPI.CTRLA.bit.CPOL = 1; //Clock Polarity - SCK high when idle. Leading edge of cycle is falling. Trailing rising. - SR_EXP_SERCOM->SPI.CTRLA.bit.CPHA = 1; //Clock Phase - Leading Edge Falling, change, Trailing Edge - Rising, sample - SR_EXP_SERCOM->SPI.CTRLA.bit.DIPO = 3; //Data In Pinout - SERCOM PAD[3] is used as data input (Configure away from DOPO. Not using input.) - SR_EXP_SERCOM->SPI.CTRLA.bit.DOPO = 0; //Data Output PAD[0], Serial Clock PAD[1] - SR_EXP_SERCOM->SPI.CTRLA.bit.MODE = 3; //Operating Mode - Master operation - - SR_EXP_SERCOM->SPI.CTRLA.bit.ENABLE = 1; //Enable - Peripheral is enabled or being enabled - while (SR_EXP_SERCOM->SPI.SYNCBUSY.bit.ENABLE) { DBGC(DC_SPI_SYNC_ENABLING); } - - sr_exp_data.reg = 0; - sr_exp_data.bit.HUB_CONNECT = 0; - sr_exp_data.bit.HUB_RESET_N = 0; - sr_exp_data.bit.S_UP = 0; - sr_exp_data.bit.E_UP_N = 1; - sr_exp_data.bit.S_DN1 = 1; - sr_exp_data.bit.E_DN1_N = 1; - sr_exp_data.bit.E_VBUS_1 = 0; - sr_exp_data.bit.E_VBUS_2 = 0; - sr_exp_data.bit.SRC_1 = 1; - sr_exp_data.bit.SRC_2 = 1; - sr_exp_data.bit.IRST = 1; - sr_exp_data.bit.SDB_N = 0; - SR_EXP_WriteData(); - - //Enable Shift Register output - SR_EXP_OE_N_ENA; - - DBGC(DC_SPI_INIT_COMPLETE); + DBGC(DC_SPI_EXP_INIT_COMPLETE); } +#ifdef SR_KC_SERCOM_NUM + +/* Shift Register Key matrix Column drive Data */ +sr_kc_t sr_kc_data; + +/* Shift Register Key matrix Column drive Write Data */ +void SR_KC_WriteData(void) +{ + SR_KC_RCLK_LO; + + while (!(SR_KC_SERCOM->SPI.INTFLAG.bit.DRE)) { DBGC(DC_SPI_KC_WRITE_DRE); } + + /* Shift in bits 8 - 15 */ + SR_KC_SERCOM->SPI.DATA.bit.DATA = (sr_kc_data.reg >> 8) & 0xFF; + while (!(SR_KC_SERCOM->SPI.INTFLAG.bit.TXC)) { DBGC(DC_SPI_KC_WRITE_TXC_1); } + + /* Shift in bits 0 - 7 */ + SR_KC_SERCOM->SPI.DATA.bit.DATA = sr_kc_data.reg & 0xFF; + while (!(SR_KC_SERCOM->SPI.INTFLAG.bit.TXC)) { DBGC(DC_SPI_KC_WRITE_TXC_2); } + + SR_KC_RCLK_HI; +} + +/* Shift Register Key matrix Column drive Initialization */ +void SR_KC_Init(void) +{ + DBGC(DC_SPI_KC_INIT_BEGIN); + + CLK_set_spi_freq(CHAN_SERCOM_SPI_KC, FREQ_SPI_KC_DEFAULT); + + /* Set up MCU shift register pins */ + PORT->Group[SR_KC_RCLK_PORT].DIRSET.reg = (1 << SR_KC_RCLK_PIN); + PORT->Group[SR_KC_OE_N_PORT].DIRSET.reg = (1 << SR_KC_OE_N_PIN); + + /* Set up MCU SPI pins */ + PORT->Group[SR_KC_DATAOUT_PORT].PMUX[SR_KC_DATAOUT_PIN / 2].bit.SR_KC_DATAOUT_MUX_SEL = SR_KC_DATAOUT_MUX; //MUX select for sercom + PORT->Group[SR_KC_SCLK_PORT].PMUX[SR_KC_SCLK_PIN / 2].bit.SR_KC_SCLK_MUX_SEL = SR_KC_SCLK_MUX; //MUX select for sercom + PORT->Group[SR_KC_DATAOUT_PORT].PINCFG[SR_KC_DATAOUT_PIN].bit.PMUXEN = 1; //MUX Enable + PORT->Group[SR_KC_SCLK_PORT].PINCFG[SR_KC_SCLK_PIN].bit.PMUXEN = 1; //MUX Enable + + /* Initialize shift register */ + SR_KC_OE_N_DIS; + SR_KC_RCLK_HI; + + SR_KC_SERCOM->SPI.CTRLA.bit.DORD = 0; //Data Order - MSB is transferred first + SR_KC_SERCOM->SPI.CTRLA.bit.CPOL = 1; //Clock Polarity - SCK high when idle. Leading edge of cycle is falling. Trailing rising. + SR_KC_SERCOM->SPI.CTRLA.bit.CPHA = 1; //Clock Phase - Leading Edge Falling, change, Trailing Edge - Rising, sample + SR_KC_SERCOM->SPI.CTRLA.bit.DIPO = 3; //Data In Pinout - SERCOM PAD[3] is used as data input (Configure away from DOPO. Not using input.) + SR_KC_SERCOM->SPI.CTRLA.bit.DOPO = 0; //Data Output PAD[0], Serial Clock PAD[1] + SR_KC_SERCOM->SPI.CTRLA.bit.MODE = 3; //Operating Mode - Master operation + + SR_KC_SERCOM->SPI.CTRLA.bit.ENABLE = 1; //Enable - Peripheral is enabled or being enabled + while (SR_KC_SERCOM->SPI.SYNCBUSY.bit.ENABLE) { DBGC(DC_SPI_KC_SYNC_ENABLING); } + + /* Set default shift register values */ + sr_kc_data.reg = 0; + + /* Write shift register data */ + SR_KC_WriteData(); + + /* Enable shift register output */ + SR_KC_OE_N_ENA; + + DBGC(DC_SPI_KC_INIT_COMPLETE); +} + +#endif //SR_KC_SERCOM diff --git a/tmk_core/protocol/arm_atsam/spi.h b/tmk_core/protocol/arm_atsam/spi.h index 4739b775db4..cf33441d6f3 100644 --- a/tmk_core/protocol/arm_atsam/spi.h +++ b/tmk_core/protocol/arm_atsam/spi.h @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,6 +18,18 @@ along with this program. If not, see . #ifndef _SPI_H_ #define _SPI_H_ +#include "config_spi.h" + +/* Various macros for use in this header */ +#define SPI_MACRO_CONCAT(str,var) str ## var +#define SPI_MACRO_EXPAND(str,var) SPI_MACRO_CONCAT(str,var) + +/* Macros to define Shift Register macro (Ex: SERCOM2) */ +#define SR_EXP_SERCOM SPI_MACRO_EXPAND(SERCOM,SR_EXP_SERCOM_NUM) + +/* Macros to define Shift Register Peripheral ID (Ex: ID_SERCOM2) */ +#define SR_EXP_SERCOM_PID SPI_MACRO_EXPAND(ID_SERCOM,SR_EXP_SERCOM_NUM) + /* Macros for Shift Register control */ #define SR_EXP_RCLK_LO PORT->Group[SR_EXP_RCLK_PORT].OUTCLR.reg = (1 << SR_EXP_RCLK_PIN) #define SR_EXP_RCLK_HI PORT->Group[SR_EXP_RCLK_PORT].OUTSET.reg = (1 << SR_EXP_RCLK_PIN) @@ -38,33 +50,72 @@ along with this program. If not, see . #define SR_EXP_SCLK_MUX_SEL PMUXO #endif -/* Data structure to define Shift Register output expander hardware */ -/* This structure gets shifted into registers LSB first */ -typedef union { - struct { - uint16_t RSVD4:1; /*!< bit: 0 */ - uint16_t RSVD3:1; /*!< bit: 1 */ - uint16_t RSVD2:1; /*!< bit: 2 */ - uint16_t RSVD1:1; /*!< bit: 3 */ - uint16_t SDB_N:1; /*!< bit: 4 SHUTDOWN THE CHIP WHEN 0, RUN WHEN 1 */ - uint16_t IRST:1; /*!< bit: 5 RESET THE IS3733 I2C WHEN 1, RUN WHEN 0 */ - uint16_t SRC_2:1; /*!< bit: 6 ADVERTISE A SOURCE TO USBC-2 CC */ - uint16_t SRC_1:1; /*!< bit: 7 ADVERTISE A SOURCE TO USBC-1 CC */ - uint16_t E_VBUS_2:1; /*!< bit: 8 ENABLE 5V OUT TO USBC-2 WHEN 1 */ - uint16_t E_VBUS_1:1; /*!< bit: 9 ENABLE 5V OUT TO USBC-1 WHEN 1 */ - uint16_t E_DN1_N:1; /*!< bit: 10 ENABLE DN1 1:2 MUX WHEN 0 */ - uint16_t S_DN1:1; /*!< bit: 11 SELECT DN1 PATH 0:USBC-1, 1:USBC-2 */ - uint16_t E_UP_N:1; /*!< bit: 12 ENABLE SUP 1:2 MUX WHEN 0 */ - uint16_t S_UP:1; /*!< bit: 13 SELECT UP PATH 0:USBC-1, 1:USBC-2 */ - uint16_t HUB_RESET_N:1; /*!< bit: 14 RESET USB HUB WHEN 0, RUN WHEN 1 */ - uint16_t HUB_CONNECT:1; /*!< bit: 15 SIGNAL VBUS CONNECT TO USB HUB WHEN 1 */ - } bit; /*!< Structure used for bit access */ - uint16_t reg; /*!< Type used for register access */ -} sr_exp_t; +//Note: sr_exp_t struct defined in keyboard's config_spi.h extern sr_exp_t sr_exp_data; void SR_EXP_WriteData(void); void SR_EXP_Init(void); +void SR_EXP_Init_kb(void); + +//For devices which use two shift registers for key matrix column drive +#ifdef SR_KC_SERCOM_NUM + +/* Macros to define Shift Register macro (Ex: SERCOM4) */ +#define SR_KC_SERCOM SPI_MACRO_EXPAND(SERCOM,SR_KC_SERCOM_NUM) + +/* Macros to define Shift Register Peripheral ID (Ex: ID_SERCOM2) */ +#define SR_KC_SERCOM_PID SPI_MACRO_EXPAND(ID_SERCOM,SR_KC_SERCOM_NUM) + +/* Macros for Shift Register control */ +#define SR_KC_RCLK_LO PORT->Group[SR_KC_RCLK_PORT].OUTCLR.reg = (1 << SR_KC_RCLK_PIN) +#define SR_KC_RCLK_HI PORT->Group[SR_KC_RCLK_PORT].OUTSET.reg = (1 << SR_KC_RCLK_PIN) +#define SR_KC_OE_N_ENA PORT->Group[SR_KC_OE_N_PORT].OUTCLR.reg = (1 << SR_KC_OE_N_PIN) +#define SR_KC_OE_N_DIS PORT->Group[SR_KC_OE_N_PORT].OUTSET.reg = (1 << SR_KC_OE_N_PIN) + +/* Determine bits to set for mux selection */ +#if SR_KC_DATAOUT_PIN % 2 == 0 +#define SR_KC_DATAOUT_MUX_SEL PMUXE +#else +#define SR_KC_DATAOUT_MUX_SEL PMUXO +#endif + +/* Determine bits to set for mux selection */ +#if SR_KC_SCLK_PIN % 2 == 0 +#define SR_KC_SCLK_MUX_SEL PMUXE +#else +#define SR_KC_SCLK_MUX_SEL PMUXO +#endif + +/* Data structure to define Shift Register output for key matrix column drive */ +/* This structure gets shifted into registers MSB first */ +typedef union { + struct { + uint16_t KC1:1; /*!< bit: 0 Key matrix column 1 drive */ + uint16_t KC2:1; /*!< bit: 1 Key matrix column 2 drive */ + uint16_t KC3:1; /*!< bit: 2 Key matrix column 3 drive */ + uint16_t KC4:1; /*!< bit: 3 Key matrix column 4 drive */ + uint16_t KC5:1; /*!< bit: 4 Key matrix column 5 drive */ + uint16_t KC6:1; /*!< bit: 5 Key matrix column 6 drive */ + uint16_t KC7:1; /*!< bit: 6 Key matrix column 7 drive */ + uint16_t KC8:1; /*!< bit: 7 Key matrix column 8 drive */ + uint16_t KC9:1; /*!< bit: 8 Key matrix column 9 drive */ + uint16_t KC10:1; /*!< bit: 9 Key matrix column 10 drive */ + uint16_t KC11:1; /*!< bit: 10 Key matrix column 11 drive */ + uint16_t KC12:1; /*!< bit: 11 Key matrix column 12 drive */ + uint16_t KC13:1; /*!< bit: 12 Key matrix column 13 drive */ + uint16_t KC14:1; /*!< bit: 13 Key matrix column 14 drive */ + uint16_t KC15:1; /*!< bit: 14 Key matrix column 15 drive */ + uint16_t KC16:1; /*!< bit: 15 Key matrix column 16 drive */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} sr_kc_t; + +extern sr_kc_t sr_kc_data; + +void SR_KC_WriteData(void); +void SR_KC_Init(void); + +#endif //SR_KC_SERCOM #endif //_SPI_H_ diff --git a/tmk_core/protocol/arm_atsam/usb/usb2422.c b/tmk_core/protocol/arm_atsam/usb/usb2422.c index 76ec3aaaa76..79057f3b730 100644 --- a/tmk_core/protocol/arm_atsam/usb/usb2422.c +++ b/tmk_core/protocol/arm_atsam/usb/usb2422.c @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -36,28 +36,22 @@ const uint16_t SERNAME[BOOTLOADER_SERIAL_MAX_SIZE] = { 'M','D','H','U','B','B',' // space as needed and adjust BOOTLOADER_SERIAL_MAX_SIZE to match amount given #endif //MD_BOOTLOADER -uint8_t usb_host_port; +uint8_t g_usb_host_port; #ifndef MD_BOOTLOADER -uint8_t usb_extra_state; -uint8_t usb_extra_manual; uint8_t usb_gcr_auto; #endif //MD_BOOTLOADER -uint16_t adc_extra; - -void USB_write2422_block(void) -{ +void USB_write2422_block(void) { unsigned char *dest = i2c0_buf; unsigned char *src; unsigned char *base = (unsigned char *)&USB2422_shadow; DBGC(DC_USB_WRITE2422_BLOCK_BEGIN); - for (src = base; src < base + 256; src += 32) - { + for (src = base; src < base + 256; src += 32) { dest[0] = src - base; dest[1] = 32; memcpy(&dest[2], src, 32); @@ -70,8 +64,7 @@ void USB_write2422_block(void) DBGC(DC_USB_WRITE2422_BLOCK_COMPLETE); } -void USB2422_init(void) -{ +void USB2422_init(void) { Gclk *pgclk = GCLK; Mclk *pmclk = MCLK; Port *pport = PORT; @@ -80,7 +73,7 @@ void USB2422_init(void) DBGC(DC_USB2422_INIT_BEGIN); - while ((v_5v = adc_get(ADC_5V)) < ADC_5V_START_LEVEL) { DBGC(DC_USB2422_INIT_WAIT_5V_LOW); } + while (adc_get(ADC_5V) < ADC_5V_V2C(ADC_5V_START_LEVEL)) { DBGC(DC_USB2422_INIT_WAIT_5V_LOW); } //setup peripheral and synchronous bus clocks to USB pgclk->PCHCTRL[10].bit.GEN = 0; @@ -131,15 +124,14 @@ void USB2422_init(void) i2c0_init(); //IC2 clk must be high at USB2422 reset release time to signal SMB configuration - sr_exp_data.bit.HUB_CONNECT = 1; //connect signal - sr_exp_data.bit.HUB_RESET_N = 1; //reset high + sr_exp_data.bit.HUB_CONNECT = 1; //connect signal high to connect + sr_exp_data.bit.HUB_RESET_N = 1; //reset high to run SR_EXP_WriteData(); wait_us(100); #ifndef MD_BOOTLOADER - usb_extra_manual = 0; usb_gcr_auto = 1; #endif //MD_BOOTLOADER @@ -147,22 +139,22 @@ void USB2422_init(void) DBGC(DC_USB2422_INIT_COMPLETE); } -void USB_reset(void) -{ +void USB_reset(void) { DBGC(DC_USB_RESET_BEGIN); //pulse reset for at least 1 usec - sr_exp_data.bit.HUB_RESET_N = 0; //reset low + sr_exp_data.bit.HUB_RESET_N = 0; //reset low to reset SR_EXP_WriteData(); wait_us(2); sr_exp_data.bit.HUB_RESET_N = 1; //reset high to run SR_EXP_WriteData(); + wait_ms(10); + DBGC(DC_USB_RESET_COMPLETE); } -void USB_configure(void) -{ +void USB_configure(void) { Usb2422 *pusb2422 = &USB2422_shadow; memset(pusb2422, 0, sizeof(Usb2422)); @@ -177,15 +169,12 @@ void USB_configure(void) DBGC(DC_USB_CONFIGURE_BEGIN); - if (serial_address != 0xFFFFFFFF && serial_address < serial_ptrloc) //Check for factory programmed serial address - { - if ((serial_address & 0xFF) % 4 == 0) //Check alignment - { + if (serial_address != 0xFFFFFFFF && serial_address < serial_ptrloc) { //Check for factory programmed serial address + if ((serial_address & 0xFF) % 4 == 0) { //Check alignment serial_use = (uint16_t *)(serial_address); serial_length = 0; while ((*(serial_use + serial_length) > 32 && *(serial_use + serial_length) < 127) && - serial_length < BOOTLOADER_SERIAL_MAX_SIZE) - { + serial_length < BOOTLOADER_SERIAL_MAX_SIZE) { serial_length++; DBGC(DC_USB_CONFIGURE_GET_SERIAL); } @@ -215,126 +204,184 @@ void USB_configure(void) pusb2422->STCD.bit.USB_ATTACH = 1; USB_write2422_block(); - adc_extra = 0; - DBGC(DC_USB_CONFIGURE_COMPLETE); } -uint16_t USB_active(void) -{ +uint16_t USB_active(void) { return (PORT->Group[USB2422_HUB_ACTIVE_GROUP].IN.reg & (1 << USB2422_HUB_ACTIVE_PIN)) != 0; } -void USB_set_host_by_voltage(void) -{ - //UP is upstream device (HOST) - //DN1 is downstream device (EXTRA) - //DN2 is keyboard (KEYB) +#define USB_DETECT_INIT_VAL 100 //Default value for rp/cc detection to test against after routines +#define USB_DETECT_METHOD_NONE 0 +#define USB_DETECT_METHOD_RP 1 +#define USB_DETECT_METHOD_V 2 - DBGC(DC_USB_SET_HOST_BY_VOLTAGE_BEGIN); +//Return best Rp value match +uint8_t USB_detect_host(void) { + static uint8_t usb_detect_onb_ext = 0; + uint8_t rp_best_index = 0; - usb_host_port = USB_HOST_PORT_UNKNOWN; -#ifndef MD_BOOTLOADER - usb_extra_state = USB_EXTRA_STATE_UNKNOWN; -#endif //MD_BOOTLOADER - sr_exp_data.bit.SRC_1 = 1; //USBC-1 available for test - sr_exp_data.bit.SRC_2 = 1; //USBC-2 available for test - sr_exp_data.bit.E_UP_N = 1; //HOST disable - sr_exp_data.bit.E_DN1_N = 1; //EXTRA disable - sr_exp_data.bit.E_VBUS_1 = 0; //USBC-1 disable full power I/O - sr_exp_data.bit.E_VBUS_2 = 0; //USBC-2 disable full power I/O + DBGC(DC_USB_DETECT_HOST_BEGIN); - SR_EXP_WriteData(); + g_usb_host_port = USB_HOST_PORT_UNKNOWN; //Initialize host port as unknown - wait_ms(250); + usb_init_host_detection_kb(); //Run keyboard specific initialization - while ((v_5v = adc_get(ADC_5V)) < ADC_5V_START_LEVEL) { DBGC(DC_USB_SET_HOST_5V_LOW_WAITING); } + wait_ms(100); //Allow power dissapation time on CC lines - v_con_1 = adc_get(ADC_CON1); - v_con_2 = adc_get(ADC_CON2); + while (adc_get(ADC_5V) < ADC_5V_V2C(ADC_5V_START_LEVEL)) { DBGC(DC_USB_DETECT_HOST_5V_LOW_WAITING); } //Assert 5V bus adequate - v_con_1_boot = v_con_1; - v_con_2_boot = v_con_2; + uint8_t detect_method = USB_DETECT_METHOD_NONE; //Initial detection method + uint8_t adc_cc_index[] = { ADC_C1A5, ADC_C1B5, ADC_C2A5, ADC_C2B5 }; //Initialize CC lines array + uint16_t cc_readings[] = { 0, 0, 0, 0 }; //Initialize CC readings array + uint8_t cc_index; + uint8_t cc_index_max = sizeof(adc_cc_index) / sizeof(*adc_cc_index); - if (v_con_1 > v_con_2) - { - sr_exp_data.bit.S_UP = 0; //HOST to USBC-1 - sr_exp_data.bit.S_DN1 = 1; //EXTRA to USBC-2 - sr_exp_data.bit.SRC_1 = 1; //HOST on USBC-1 - sr_exp_data.bit.SRC_2 = 0; //EXTRA available on USBC-2 + //Collect CC readings for decision making processes + for (cc_index = 0; cc_index < cc_index_max; cc_index++) { //For each CC line + cc_readings[cc_index] = adc_get(adc_cc_index[cc_index]); //Perform ADC reading + if (cc_readings[cc_index] == (uint16_t)ADC_NA) { //If the ADC was not available for reading + cc_readings[cc_index] = 0; //Set value low to not be used + continue; //ADC not available so skip + } - sr_exp_data.bit.E_VBUS_1 = 1; //USBC-1 enable full power I/O - sr_exp_data.bit.E_VBUS_2 = 0; //USBC-2 disable full power I/O - - SR_EXP_WriteData(); - - sr_exp_data.bit.E_UP_N = 0; //HOST enable - - SR_EXP_WriteData(); - - usb_host_port = USB_HOST_PORT_1; - } - else - { - sr_exp_data.bit.S_UP = 1; //EXTRA to USBC-1 - sr_exp_data.bit.S_DN1 = 0; //HOST to USBC-2 - sr_exp_data.bit.SRC_1 = 0; //EXTRA available on USBC-1 - sr_exp_data.bit.SRC_2 = 1; //HOST on USBC-2 - - sr_exp_data.bit.E_VBUS_1 = 0; //USBC-1 disable full power I/O - sr_exp_data.bit.E_VBUS_2 = 1; //USBC-2 enable full power I/O - - SR_EXP_WriteData(); - - sr_exp_data.bit.E_UP_N = 0; //HOST enable - - SR_EXP_WriteData(); - - usb_host_port = USB_HOST_PORT_2; + cc_readings[cc_index] = ADC_CC_5VCOR(adc_get(ADC_5V), cc_readings[cc_index]); //Correct the ADC reading according to 5V bus } -#ifndef MD_BOOTLOADER - usb_extra_state = USB_EXTRA_STATE_DISABLED; -#endif //MD_BOOTLOADER +#ifdef ADC_USBC_RP_DELTA_MAX + if (detect_method == USB_DETECT_METHOD_NONE) { //If a detection method has not succeeded yet + //Using CC readings, test them for onb or ext + uint16_t rp_delta_least = 5000; //Initialize to a high number out of ADC range + uint16_t rp_delta; //Distance of reading to a test value + uint8_t rp_index; //Index of Rp value being tested + uint8_t cc_best_index = USB_DETECT_INIT_VAL; //Initialize to a high number out of index - USB_reset(); - USB_configure(); + rp_best_index = USB_DETECT_INIT_VAL; //Initialize to a high number out of index + for (cc_index = 0; cc_index < cc_index_max; cc_index++) { //For each CC line + for (rp_index = 0; rp_index < ADC_USBC_TYPES; rp_index++) { //For each Rp + rp_delta = abs(cc_readings[cc_index] - adc_usbc_rp_nominal[rp_index]); //Calculate the distance between reading and Rp + if (rp_delta < rp_delta_least && rp_delta < ADC_USBC_RP_DELTA_MAX) { //If the distance is less than the least and within distance cap + rp_delta_least = rp_delta; //Save the least rp distance + rp_best_index = rp_index; //Save the closest Rp value index + cc_best_index = adc_cc_index[cc_index]; //Save the closest CC line index + } + } + } - DBGC(DC_USB_SET_HOST_BY_VOLTAGE_COMPLETE); + //Set up host port and extra port according to detection + if (rp_best_index != USB_DETECT_INIT_VAL) { //If a decision was made + if (cc_best_index == ADC_C1A5 || cc_best_index == ADC_C1B5) { //If on CON1 + usb_set_host_kb(1, rp_best_index); //Set up host port on CON1 (rp used to set onb/ext) + usb_set_extra_kb(2); //Set up extra port on CON2 + detect_method = USB_DETECT_METHOD_RP; //Set detection method used + } else if (cc_best_index == ADC_C2A5 || cc_best_index == ADC_C2B5) { //Else if on CON2 + usb_set_host_kb(2, rp_best_index); //Set up host port on CON2 (rp used to set onb/ext) + usb_set_extra_kb(1); //Set up extra port on CON1 + detect_method = USB_DETECT_METHOD_RP; //Set detection method used + } + } + } +#endif + + //Detect highest voltage port and test onboard or external + if (detect_method == USB_DETECT_METHOD_NONE) { //If a detection method has not succeeded yet + uint16_t rp_highest_v = 0; //Initialize to the lowest number possible + uint8_t v_best_index = USB_DETECT_INIT_VAL; //Initialize to the lowest number possible + for (cc_index = 0; cc_index < cc_index_max; cc_index++) { //For each CC line + if (cc_readings[cc_index] > rp_highest_v) { //Keep track of the highest voltage level as a secondary host detection method + rp_highest_v = cc_readings[cc_index]; //Save the highest voltage + v_best_index = adc_cc_index[cc_index]; //Save the highest voltage index + } + } + + //Set up host port and extra port according to detection + usb_detect_onb_ext = !usb_detect_onb_ext; //Swap onb/ext detect for this run + rp_best_index = usb_detect_onb_ext; //Force onb/ext setting + if (v_best_index == ADC_C1A5 || v_best_index == ADC_C1B5) { //If on CON1 + usb_set_host_kb(1, rp_best_index); //Set up host port on CON1 + usb_set_extra_kb(2); //Set up extra port on CON2 + detect_method = USB_DETECT_METHOD_V; //Set detection method used + } else if (v_best_index == ADC_C2A5 || v_best_index == ADC_C2B5) { //Else if on CON2 + usb_set_host_kb(2, rp_best_index); //Set up host port on CON2 + usb_set_extra_kb(1); //Set up extra port on CON1 + detect_method = USB_DETECT_METHOD_V; //Set detection method used + } + } + + if (detect_method != USB_DETECT_METHOD_NONE) { //If a detection method succeeded + wait_ms(20); //Allow settling time for switching + USB_reset(); //Reset and enable the USB Hub + USB_configure(); //Configure the USB Hub and send attach + } + + DBGC(DC_USB_DETECT_HOST_COMPLETE); + + return rp_best_index; } -uint8_t USB2422_Port_Detect_Init(void) -{ - uint32_t port_detect_retry_ms; +uint8_t USB2422_Port_Detect_Init(void) { uint32_t tmod; + uint8_t led_state = 0; + uint64_t port_detect_fail_ms; + static uint8_t port_detect_retry_counter = 0; + static uint16_t port_detect_retry_ms = 0; DBGC(DC_PORT_DETECT_INIT_BEGIN); - USB_set_host_by_voltage(); +#ifdef ADC_USBC_IS_EXT + //If the keyboard supports offboard USB extenders, rp_best_index is used to determine onboard/offboard usage + uint8_t rp_best_index = USB_detect_host(); +#else + USB_detect_host(); +#endif - port_detect_retry_ms = timer_read64() + PORT_DETECT_RETRY_INTERVAL; + port_detect_fail_ms = timer_read64() + PORT_DETECT_RETRY_START + port_detect_retry_ms; + uint32_t port_flash_counter = timer_read(); - while (!USB_active()) - { - tmod = timer_read64() % PORT_DETECT_RETRY_INTERVAL; - - if (v_con_1 > v_con_2) //Values updated from USB_set_host_by_voltage(); - { - //1 flash for port 1 detected - if (tmod > 500 && tmod < 600) { DBG_LED_ON; } - else { DBG_LED_OFF; } - } - else if (v_con_2 > v_con_1) //Values updated from USB_set_host_by_voltage(); - { - //2 flash for port 2 detected - if (tmod > 500 && tmod < 600) { DBG_LED_ON; } - else if (tmod > 700 && tmod < 800) { DBG_LED_ON; } - else { DBG_LED_OFF; } + while (!USB_active()) { + tmod = (timer_read() - port_flash_counter); + if (USB_HOST_IS_1(g_usb_host_port)) { + //1 flash for port 1 detected (dit), additional long flash if external port (dit-dah) + if (tmod > 500 && tmod < 600) { + if (!led_state) { DBG_LED_ON; led_state = 1; } + } +#ifdef ADC_USBC_IS_EXT + else if (ADC_USBC_IS_EXT(rp_best_index) && tmod > 1000 && tmod < 1500) { + if (!led_state) { DBG_LED_ON; led_state = 1; } + } +#endif + else if (led_state) { DBG_LED_OFF; led_state = 0; } + } else if (USB_HOST_IS_2(g_usb_host_port)) { + //2 flash for port 2 detected (dit-dit), additional long flash if external port (dit-dit-dah) + if (tmod > 500 && tmod < 600) { + if (!led_state) { DBG_LED_ON; led_state = 1; } + } else if (tmod > 700 && tmod < 800) { + if (!led_state) { DBG_LED_ON; led_state = 1; } + } +#ifdef ADC_USBC_IS_EXT + else if (ADC_USBC_IS_EXT(rp_best_index) && tmod > 1000 && tmod < 1500) { + if (!led_state) { DBG_LED_ON; led_state = 1; } + } +#endif + else if (led_state) { DBG_LED_OFF; led_state = 0; } + } else { + //Flash every 250ms if port unknown (should not get here) + if (tmod % 500 < 250) { + if (!led_state) { DBG_LED_ON; led_state = 1; } + } else if (led_state) { DBG_LED_OFF; led_state = 0; } } - if (timer_read64() > port_detect_retry_ms) - { + if (timer_read64() > port_detect_fail_ms) { //If timeout reached DBGC(DC_PORT_DETECT_INIT_FAILED); + + port_detect_retry_counter++; //Increment retry counter + if (port_detect_retry_counter % 2 == 0) { //Increment timeout every 2 attempts + port_detect_retry_ms += PORT_DETECT_RETRY_INCREMENT; //Increment timeout + } + if (port_detect_retry_ms > PORT_DETECT_RETRY_MAX) { //If the new timeout is greater than the max timeout setting + port_detect_retry_ms = PORT_DETECT_RETRY_MAX; //Set timeout to max + } + return 0; } } @@ -346,64 +393,207 @@ uint8_t USB2422_Port_Detect_Init(void) #ifndef MD_BOOTLOADER -void USB_ExtraSetState(uint8_t state) -{ - uint8_t state_save = state; +usbc_t usbc; - if (state == USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG) - state = USB_EXTRA_STATE_DISABLED; +uint16_t usbc_cc_a5_v; +uint16_t usbc_cc_b5_v; +float usbc_cc_a5_v_avg; +float usbc_cc_b5_v_avg; - if (usb_host_port == USB_HOST_PORT_1) sr_exp_data.bit.E_VBUS_2 = state; - else if (usb_host_port == USB_HOST_PORT_2) sr_exp_data.bit.E_VBUS_1 = state; - else return; - - sr_exp_data.bit.E_DN1_N = !state; - SR_EXP_WriteData(); - - usb_extra_state = state_save; - - if (usb_extra_state == USB_EXTRA_STATE_ENABLED) CDC_print("USB: Extra enabled\r\n"); - else if (usb_extra_state == USB_EXTRA_STATE_DISABLED) - { - CDC_print("USB: Extra disabled\r\n"); -#ifdef USE_MASSDROP_CONFIGURATOR - if (led_animation_breathing) gcr_breathe = gcr_desired; -#endif - } - else if (usb_extra_state == USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG) CDC_print("USB: Extra disabled until replug\r\n"); - else CDC_print("USB: Extra state unknown\r\n"); +void usbc_cc_clear(void) { + usbc_cc_a5_v = 0; + usbc_cc_b5_v = 0; + usbc_cc_a5_v_avg = 0.0f; + usbc_cc_b5_v_avg = 0.0f; } -void USB_HandleExtraDevice(void) -{ - uint16_t adcval; - - if (usb_host_port == USB_HOST_PORT_1) adcval = adc_get(ADC_CON2); - else if (usb_host_port == USB_HOST_PORT_2) adcval = adc_get(ADC_CON1); - else return; - - adc_extra = adc_extra * 0.9 + adcval * 0.1; - - //Check for a forced disable state (such as overload prevention) - if (usb_extra_state == USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG) - { - //Detect unplug and reset state to disabled - if (adc_extra > USB_EXTRA_ADC_THRESHOLD) usb_extra_state = USB_EXTRA_STATE_DISABLED; - - return; //Return even if unplug detected +//Only poll CC lines for port assigned as EXTRA +uint8_t usbc_cc_update(void) { + if (USB_HOST_IS_1(g_usb_host_port)) { + usbc_cc_a5_v = adc_get(ADC_C2A5); + usbc_cc_b5_v = adc_get(ADC_C2B5); + } else if (USB_HOST_IS_2(g_usb_host_port)) { + usbc_cc_a5_v = adc_get(ADC_C1A5); + usbc_cc_b5_v = adc_get(ADC_C1B5); + } else { + return 0; } - if (usb_extra_manual) - { - if (usb_extra_state == USB_EXTRA_STATE_DISABLED) - USB_ExtraSetState(USB_EXTRA_STATE_ENABLED); + usbc_cc_a5_v_avg = 0.9 * usbc_cc_a5_v_avg + 0.1 * (float)usbc_cc_a5_v; + usbc_cc_b5_v_avg = 0.9 * usbc_cc_b5_v_avg + 0.1 * (float)usbc_cc_b5_v; - return; + return 1; +} + +//Disable 5V bus on extra USB port +//If force_update != 0, force update to run +//If force_update == 0, only update if value is changed +uint8_t usbc_5v_disable(uint8_t force_update) { + if (USB_HOST_IS_1(g_usb_host_port)) { + if (force_update || (USBC_CFG_5V2_VAR != USBC_CFG_5V2_DIS)) { + USBC_CFG_5V2_VAR = USBC_CFG_5V2_DIS; + USBC_CFG_5V2_UPDATE; + } + return 1; + } else if (USB_HOST_IS_2(g_usb_host_port)) { + if (force_update || (USBC_CFG_5V1_VAR != USBC_CFG_5V1_DIS)) { + USBC_CFG_5V1_VAR = USBC_CFG_5V1_DIS; + USBC_CFG_5V1_UPDATE; + } + return 1; } - //dpf("a %i %i\r\n",adcval, adc_extra); - if (usb_extra_state == USB_EXTRA_STATE_DISABLED && adc_extra < USB_EXTRA_ADC_THRESHOLD) USB_ExtraSetState(USB_EXTRA_STATE_ENABLED); - else if (usb_extra_state == USB_EXTRA_STATE_ENABLED && adc_extra > USB_EXTRA_ADC_THRESHOLD) USB_ExtraSetState(USB_EXTRA_STATE_DISABLED); + return 0; +} + +//Enable 5V bus on extra USB port +//If force_update != 0, force update to run +//If force_update == 0, only update if value is changed +uint8_t usbc_5v_enable(uint8_t force_update) { + if (USB_HOST_IS_1(g_usb_host_port)) { + if (force_update || (USBC_CFG_5V2_VAR != USBC_CFG_5V2_ENA)) { + USBC_CFG_5V2_VAR = USBC_CFG_5V2_ENA; + USBC_CFG_5V2_UPDATE; + } + return 1; + } else if (USB_HOST_IS_2(g_usb_host_port)) { + if (force_update || (USBC_CFG_5V1_VAR != USBC_CFG_5V1_ENA)) { + USBC_CFG_5V1_VAR = USBC_CFG_5V1_ENA; + USBC_CFG_5V1_UPDATE; + } + return 1; + } + + return 0; +} + +uint8_t usbc_5v_is_enabled(void) { + if (USB_HOST_IS_1(g_usb_host_port)) { + if (USBC_CFG_5V2_VAR == USBC_CFG_5V2_ENA) { + return 1; + } else { + return 0; + } + } else if (USB_HOST_IS_2(g_usb_host_port)) { + if (USBC_CFG_5V1_VAR == USBC_CFG_5V1_ENA) { + return 1; + } else { + return 0; + } + } + + return 0; //Not sure technically due to unknown host port +} + +void usbc_enable(void) { + usbc_5v_disable(1); //Disable 5V bus + usbc.state = USB_STATE_UNATTACHED_WAIT_SRC; //Set starting state to discharge wait + usbc.timer = USBC_CFG_TVCONNDISCHARGE; //Set timer for 5V bus discharge + usbc_cc_clear(); //Clear CC readings +} + +void usbc_disable(void) { + usbc_5v_disable(1); //Disable 5V bus + usbc.state = USB_STATE_DISABLED_WAIT; //Set disabled waiting state + usbc.timer = USBC_CFG_TVCONNDISCHARGE; //Set timer for 5V bus discharge + usbc_cc_clear(); //Clear CC readings +} + +//This macro updates the timer and returns true if timer is complete +#define USBC_TIMER_DONE (0 == (usbc.timer = (usbc.timer > USBC_CFG_PERIOD ? usbc.timer - USBC_CFG_PERIOD : 0))) + +void usbc_task(void) { + if (usbc.state == USB_STATE_UNATTACHED_SRC) { + //Connection detected -> USB_STATE_ATTACH_WAIT_SRC + + usbc.timer = 0; //Note: Changes to this state do not require clearing timer at change + + if (usbc_cc_update()) { //Must have valid readings to continue + if (USBC_IS_SINK((uint16_t)usbc_cc_a5_v_avg, (uint16_t)usbc_cc_b5_v_avg)) { //If Sink detected + usbc.state = USB_STATE_ATTACH_WAIT_SRC; //Set next state + usbc.timer = USBC_CFG_TCCDEBOUNCE; //Set timer + } else { + return; //Nothing more to be done + } + } + } + + if (usbc.state == USB_STATE_ATTACH_WAIT_SRC) { + //Connection removed -> USB_STATE_UNATTACHED_SRC + //Other detection types unsupported -> USB_STATE_UNATTACHED_SRC + if (!usbc_cc_update()) { //Must have valid readings to continue + usbc.state = USB_STATE_UNATTACHED_SRC; //Invalid reading, detach + return; //Nothing more to be done + } else { //Valid CC readings to work with + if (!USBC_IS_SINK((uint16_t)usbc_cc_a5_v_avg, (uint16_t)usbc_cc_b5_v_avg)) { //If not a sink type + usbc.state = USB_STATE_UNATTACHED_SRC; //Detach + return; //Nothing more to be done + } else { + //Detected Sink for tCCDebounce -> USB_STATE_ATTACHED_SRC + if (USBC_TIMER_DONE) { //Update timer and if timer complete + if (usb_attach_port_configure_kb(g_usb_host_port, (uint16_t)usbc_cc_a5_v_avg, (uint16_t)usbc_cc_b5_v_avg)) { //If configuration was successful + usbc_5v_enable(1); //Enable 5V bus + usbc.state = USB_STATE_ATTACHED_SRC; //Set next state + dprintf("USB Extra: Port enabled\n"); + } else { //port was not configured + usbc.state = USB_STATE_UNATTACHED_SRC; //Set next state + } + } + } + } + } + + if (usbc.state == USB_STATE_ATTACHED_SRC) { + //Sink Removed and VCONN was On -> USB_STATE_UNATTACHED_WAIT_SRC + //Sink removed and VCONN was Off -> USB_STATE_UNATTACHED_SRC (Will always assume VCONN was On so ignoring this) + if (!usbc_cc_update()) { //Must have valid readings to continue + usbc_5v_disable(1); //Disable 5V bus + usbc.state = USB_STATE_UNATTACHED_WAIT_SRC; //Enter wait state for 5V bus discharge + usbc.timer = USBC_CFG_TVCONNDISCHARGE; //Set timer for 5V bus discharge + dprintf("USB Extra: Port disabled\n"); + } else { + if (!USBC_IS_SINK((uint16_t)usbc_cc_a5_v_avg, (uint16_t)usbc_cc_b5_v_avg)) { //Sink lost + usbc_5v_disable(1); //Disable 5V bus + usbc.state = USB_STATE_UNATTACHED_WAIT_SRC; //Enter wait state for 5V bus discharge + usbc.timer = USBC_CFG_TVCONNDISCHARGE; //Set timer for 5V bus discharge + dprintf("USB Extra: Port disabled\n"); + } + } + } + + if (usbc.state == USB_STATE_UNATTACHED_WAIT_SRC) { + //Discharge Complete and VCONN Off -> USB_STATE_UNATTACHED_SRC + if (USBC_TIMER_DONE) { //Update timer and if timer complete + usbc.state = USB_STATE_UNATTACHED_SRC; //Set next state + } + } + + if (usbc.state == USB_STATE_DISABLED_WAIT) { + //Wait complete -> USB_STATE_DISABLED + if (USBC_TIMER_DONE) { //Update timer and if timer complete + usbc.state = USB_STATE_DISABLED; //Set next state + } + } + + if (usbc.state == USB_STATE_DISABLED_UNTIL_DETACH) { + if (usbc_5v_is_enabled()) { + usbc_5v_disable(1); //Disable 5V bus + } + + if (!usbc_cc_update()) { //Must have valid readings to continue + usbc.state = USB_STATE_UNATTACHED_WAIT_SRC; //Enter wait state for 5V bus discharge + usbc.timer = USBC_CFG_TVCONNDISCHARGE; //Set timer for 5V bus discharge + } else { + if (!USBC_IS_SINK((uint16_t)usbc_cc_a5_v_avg, (uint16_t)usbc_cc_b5_v_avg)) { //Sink lost + usbc.state = USB_STATE_UNATTACHED_WAIT_SRC; //Enter wait state for 5V bus discharge + usbc.timer = USBC_CFG_TVCONNDISCHARGE; //Set timer for 5V bus discharge + } + } + } +} + +void USB_HandleExtraDevice(void) { + usbc_task(); } #endif //MD_BOOTLOADER diff --git a/tmk_core/protocol/arm_atsam/usb/usb2422.h b/tmk_core/protocol/arm_atsam/usb/usb2422.h index 85ad596a62e..8213f849061 100644 --- a/tmk_core/protocol/arm_atsam/usb/usb2422.h +++ b/tmk_core/protocol/arm_atsam/usb/usb2422.h @@ -1,5 +1,5 @@ /* -Copyright 2018 Massdrop Inc. +Copyright 2019 Massdrop Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,6 +18,8 @@ along with this program. If not, see . #ifndef _USB2422_H_ #define _USB2422_H_ +#include "config_usb.h" //From keyboard's directory + #define REV_USB2422 0x100 #define USB2422_ADDR 0x58 //I2C device address, one instance @@ -372,33 +374,81 @@ typedef struct { } Usb2422; #endif -#define PORT_DETECT_RETRY_INTERVAL 2000 +//When testing for USB enumeration, retry after this many ms +#define PORT_DETECT_RETRY_START 2000 +#define PORT_DETECT_RETRY_INCREMENT 2000 +#define PORT_DETECT_RETRY_MAX 10000 -#define USB_EXTRA_ADC_THRESHOLD 900 +//Onboard ports must have an even number +//External ports must have an odd number +//The only exception is the unknown state +#define USB_HOST_PORT_1 0 +#define USB_HOST_PORT_1_EXT 1 +#define USB_HOST_PORT_2 2 +#define USB_HOST_PORT_2_EXT 3 +#define USB_HOST_PORT_UNKNOWN 4 -#define USB_EXTRA_STATE_DISABLED 0 -#define USB_EXTRA_STATE_ENABLED 1 -#define USB_EXTRA_STATE_UNKNOWN 2 -#define USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG 3 +//Macros to check host port assignment +#define USB_HOST_IS_1(host) (host == USB_HOST_PORT_1 || host == USB_HOST_PORT_1_EXT) +#define USB_HOST_IS_2(host) (host == USB_HOST_PORT_2 || host == USB_HOST_PORT_2_EXT) -#define USB_HOST_PORT_1 0 -#define USB_HOST_PORT_2 1 -#define USB_HOST_PORT_UNKNOWN 2 +//Macros to test if the sink device is connected to the onboard or external port +//Note: USBC_IS_SINK defined in the keyboard's config_adc.h +#define USBC_IS_SINK_ONB(a5, b5) (ADC_USBC_IS_ONB(g_usb_host_port) && USBC_IS_SINK(a5, b5)) +#define USBC_IS_SINK_EXT(a5, b5) (ADC_USBC_IS_EXT(g_usb_host_port) && USBC_IS_SINK(a5, b5)) -extern uint8_t usb_host_port; +//Note: Due to the way timers are implemented, waits will always be slightly longer than defined +#define USBC_TIMER_ATTACH_WAIT 0 +#define USBC_TIMER_DETACH 1 //tCCDebounce +#define USBC_CFG_PERIOD 5 //How often the extra USB port is checked (ms)(This multiple affects the accuracy of USB timers) +#define USBC_CFG_TCCDEBOUNCE 150 //tCCDebounce - Time a port shall wait before it can determine it is attached (ms) +#define USBC_CFG_TSRCDISCONNECT 0 //tSRCDisconnect - Time a Source shall detect the SRC.Open state (As fast as possible)(ms) +#define USBC_CFG_TVCONNDISCHARGE 100 //UnattachedWait time for VCONN discharge +#define USBC_CFG_TDISABLED 100 //Minimum time to wait after state machine disabled + +#define USB_STATE_UNKNOWN 0 //Custom state for init +#define USB_STATE_UNATTACHED_SRC 1 //Directed from any state + //From USB_STATE_UNATTACHED_WAIT_SRC after Discharge Complete and Vconn Off + //From USB_STATE_ATTACHED_SRC if Sink Removed and Vconn was Off + //From USB_STATE_ATTACH_WAIT_SRC if Connection Removed +#define USB_STATE_ATTACH_WAIT_SRC 2 //From USB_STATE_UNATTACHED_SRC when Connection detected +#define USB_STATE_ATTACHED_SRC 3 //From USB_STATE_ATTACHWAIT_SRC when Vbus at vSafe0V and Sink Detected for tCCDebounce +#define USB_STATE_UNATTACHED_WAIT_SRC 4 //From USB_STATE_ATTACHED_SRC when Sink Removed and Vconn was On +#define USB_STATE_DISABLED_WAIT 100 //Custom state for USB 5V Bus discharge then to USB_STATE_DISABLED_WAIT +#define USB_STATE_DISABLED 101 //Directed from any state +#define USB_STATE_DISABLED_UNTIL_DETACH 102 //Custom state for when USB 5V Bus overloads and device must be detached before use + +//USB Type-C State machine for a SOURCE +typedef struct usbc_s { + uint8_t state; + uint16_t timer; +} usbc_t; + +extern uint8_t g_usb_host_port; extern uint8_t usb_extra_state; -extern uint8_t usb_extra_manual; extern uint8_t usb_gcr_auto; +extern usbc_t usbc; +extern uint16_t usbc_cc_a5_v; +extern uint16_t usbc_cc_b5_v; +extern float usbc_cc_a5_v_avg; +extern float usbc_cc_b5_v_avg; void USB2422_init(void); void USB_reset(void); void USB_configure(void); uint16_t USB_active(void); -void USB_set_host_by_voltage(void); -uint16_t adc_get(uint8_t muxpos); +uint8_t USB_detect_host(void); uint8_t USB2422_Port_Detect_Init(void); void USB_HandleExtraDevice(void); -void USB_ExtraSetState(uint8_t state); +void usbc_enable(void); +void usbc_disable(void); +void usbc_task(void); + +//Keyboard defined functions +void usb_set_host_kb(uint8_t con, uint8_t rp_best_index); +void usb_set_extra_kb(uint8_t con); +void usb_init_host_detection_kb(void); +uint8_t usb_attach_port_configure_kb(uint8_t g_usb_host_port, uint16_t usbc_cc_a5_v, uint16_t usbc_cc_b5_v); #endif //_USB2422_H_