summaryrefslogtreecommitdiffstats
path: root/tmk_core/protocol/arm_atsam/led_matrix.c
diff options
context:
space:
mode:
authorJames Young <18669334+noroadsleft@users.noreply.github.com>2020-11-28 12:02:18 -0800
committerGitHub <noreply@github.com>2020-11-28 12:02:18 -0800
commitc66df1664497546f32662409778731143e45a552 (patch)
treeda73a2d532a27685a31d932b3a44a707d4a3af81 /tmk_core/protocol/arm_atsam/led_matrix.c
parent15385d4113414d42bd062c60c9de5df797d3157f (diff)
2020 November 28 Breaking Changes Update (#11053)
* Branch point for 2020 November 28 Breaking Change * Remove matrix_col_t to allow MATRIX_ROWS > 32 (#10183) * Add support for soft serial to ATmega32U2 (#10204) * Change MIDI velocity implementation to allow direct control of velocity value (#9940) * Add ability to build a subset of all keyboards based on platform. * Actually use eeprom_driver_init(). * Make bootloader_jump weak for ChibiOS. (#10417) * Joystick 16-bit support (#10439) * Per-encoder resolutions (#10259) * Share button state from mousekey to pointing_device (#10179) * Add hotfix for chibios keyboards not wake (#10088) * Add advanced/efficient RGB Matrix Indicators (#8564) * Naming change. * Support for STM32 GPIOF,G,H,I,J,K (#10206) * Add milc as a dependency and remove the installed milc (#10563) * ChibiOS upgrade: early init conversions (#10214) * ChibiOS upgrade: configuration file migrator (#9952) * Haptic and solenoid cleanup (#9700) * XD75 cleanup (#10524) * OLED display update interval support (#10388) * Add definition based on currently-selected serial driver. (#10716) * New feature: Retro Tapping per key (#10622) * Allow for modification of output RGB values when using rgblight/rgb_matrix. (#10638) * Add housekeeping task callbacks so that keyboards/keymaps are capable of executing code for each main loop iteration. (#10530) * Rescale both ChibiOS and AVR backlighting. * Reduce Helix keyboard build variation (#8669) * Minor change to behavior allowing display updates to continue between task ticks (#10750) * Some GPIO manipulations in matrix.c change to atomic. (#10491) * qmk cformat (#10767) * [Keyboard] Update the Speedo firmware for v3.0 (#10657) * Maartenwut/Maarten namechange to evyd13/Evy (#10274) * [quantum] combine repeated lines of code (#10837) * Add step sequencer feature (#9703) * aeboards/ext65 refactor (#10820) * Refactor xelus/dawn60 for Rev2 later (#10584) * add DEBUG_MATRIX_SCAN_RATE_ENABLE to common_features.mk (#10824) * [Core] Added `add_oneshot_mods` & `del_oneshot_mods` (#10549) * update chibios os usb for the otg driver (#8893) * Remove HD44780 References, Part 4 (#10735) * [Keyboard] Add Valor FRL TKL (+refactor) (#10512) * Fix cursor position bug in oled_write_raw functions (#10800) * Fixup version.h writing when using SKIP_VERSION=yes (#10972) * Allow for certain code in the codebase assuming length of string. (#10974) * Add AT90USB support for serial.c (#10706) * Auto shift: support repeats and early registration (#9826) * Rename ledmatrix.h to match .c file (#7949) * Split RGB_MATRIX_ENABLE into _ENABLE and _DRIVER (#10231) * Split LED_MATRIX_ENABLE into _ENABLE and _DRIVER (#10840) * Merge point for 2020 Nov 28 Breaking Change
Diffstat (limited to 'tmk_core/protocol/arm_atsam/led_matrix.c')
-rw-r--r--tmk_core/protocol/arm_atsam/led_matrix.c472
1 files changed, 0 insertions, 472 deletions
diff --git a/tmk_core/protocol/arm_atsam/led_matrix.c b/tmk_core/protocol/arm_atsam/led_matrix.c
deleted file mode 100644
index 69cb03a9f7..0000000000
--- a/tmk_core/protocol/arm_atsam/led_matrix.c
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
-Copyright 2018 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include "arm_atsam_protocol.h"
-#include "tmk_core/common/led.h"
-#include "rgb_matrix.h"
-#include <string.h>
-#include <math.h>
-
-#ifdef USE_MASSDROP_CONFIGURATOR
-__attribute__((weak)) led_instruction_t led_instructions[] = {{.end = 1}};
-static void led_matrix_massdrop_config_override(int i);
-#endif // USE_MASSDROP_CONFIGURATOR
-
-void SERCOM1_0_Handler(void) {
- if (SERCOM1->I2CM.INTFLAG.bit.ERROR) {
- SERCOM1->I2CM.INTFLAG.reg = SERCOM_I2CM_INTENCLR_ERROR;
- }
-}
-
-void DMAC_0_Handler(void) {
- if (DMAC->Channel[0].CHINTFLAG.bit.TCMPL) {
- DMAC->Channel[0].CHINTFLAG.reg = DMAC_CHINTENCLR_TCMPL;
-
- i2c1_stop();
-
- i2c_led_q_running = 0;
-
- i2c_led_q_run();
-
- return;
- }
-
- if (DMAC->Channel[0].CHINTFLAG.bit.TERR) {
- DMAC->Channel[0].CHINTFLAG.reg = DMAC_CHINTENCLR_TERR;
- }
-}
-
-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;
-#ifdef USE_MASSDROP_CONFIGURATOR
-uint8_t gcr_breathe;
-float breathe_mult;
-float pomod;
-#endif
-
-#define ACT_GCR_NONE 0
-#define ACT_GCR_INC 1
-#define ACT_GCR_DEC 2
-
-#define LED_GCR_STEP_AUTO 2
-
-static uint8_t gcr_min_counter;
-static uint8_t v_5v_cat_hit;
-
-// WARNING: Automatic GCR is in place to prevent USB shutdown and LED driver overloading
-void gcr_compute(void) {
- uint8_t action = ACT_GCR_NONE;
- uint8_t gcr_use = gcr_desired;
-
-#ifdef USE_MASSDROP_CONFIGURATOR
- if (led_animation_breathing) {
- gcr_use = gcr_breathe;
- }
-#endif
-
- // 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) {
- 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;
- } else if (v_5v_cat_hit > 1) {
- 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 (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 (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) {
- 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
- 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
- }
-#endif
- }
- }
-}
-
-void issi3733_prepare_arrays(void) {
- memset(issidrv, 0, sizeof(issi3733_driver_t) * ISSI3733_DRIVER_COUNT);
-
- int i;
- uint8_t addrs[ISSI3733_DRIVER_COUNT] = ISSI3773_DRIVER_ADDRESSES;
-
- for (i = 0; i < ISSI3733_DRIVER_COUNT; i++) {
- issidrv[i].addr = addrs[i];
- }
-
- for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
- // BYTE: 1 + (SW-1)*16 + (CS-1)
- led_map[i].rgb.g = issidrv[led_map[i].adr.drv - 1].pwm + 1 + ((led_map[i].adr.swg - 1) * 16 + (led_map[i].adr.cs - 1));
- led_map[i].rgb.r = issidrv[led_map[i].adr.drv - 1].pwm + 1 + ((led_map[i].adr.swr - 1) * 16 + (led_map[i].adr.cs - 1));
- led_map[i].rgb.b = issidrv[led_map[i].adr.drv - 1].pwm + 1 + ((led_map[i].adr.swb - 1) * 16 + (led_map[i].adr.cs - 1));
-
- // BYTE: 1 + (SW-1)*2 + (CS-1)/8
- // BIT: (CS-1)%8
- *(issidrv[led_map[i].adr.drv - 1].onoff + 1 + (led_map[i].adr.swg - 1) * 2 + (led_map[i].adr.cs - 1) / 8) |= (1 << ((led_map[i].adr.cs - 1) % 8));
- *(issidrv[led_map[i].adr.drv - 1].onoff + 1 + (led_map[i].adr.swr - 1) * 2 + (led_map[i].adr.cs - 1) / 8) |= (1 << ((led_map[i].adr.cs - 1) % 8));
- *(issidrv[led_map[i].adr.drv - 1].onoff + 1 + (led_map[i].adr.swb - 1) * 2 + (led_map[i].adr.cs - 1) / 8) |= (1 << ((led_map[i].adr.cs - 1) % 8));
- }
-}
-
-void led_matrix_prepare(void) {
- for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
- *led_map[i].rgb.r = 0;
- *led_map[i].rgb.g = 0;
- *led_map[i].rgb.b = 0;
- }
-}
-
-void led_set_one(int i, uint8_t r, uint8_t g, uint8_t b) {
- if (i < ISSI3733_LED_COUNT) {
-#ifdef USE_MASSDROP_CONFIGURATOR
- led_matrix_massdrop_config_override(i);
-#else
- led_buffer[i].r = r;
- led_buffer[i].g = g;
- led_buffer[i].b = b;
-#endif
- }
-}
-
-void led_set_all(uint8_t r, uint8_t g, uint8_t b) {
- for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
- led_set_one(i, r, g, b);
- }
-}
-
-void init(void) {
- DBGC(DC_LED_MATRIX_INIT_BEGIN);
-
- issi3733_prepare_arrays();
-
- led_matrix_prepare();
-
- gcr_min_counter = 0;
- v_5v_cat_hit = 0;
-
- DBGC(DC_LED_MATRIX_INIT_COMPLETE);
-}
-
-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
-
- // Wait for previous transfer to complete
- while (i2c_led_q_running) {
- }
-
- // Copy buffer to live DMA region
- for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
- *led_map[i].rgb.r = led_buffer[i].r;
- *led_map[i].rgb.g = led_buffer[i].g;
- *led_map[i].rgb.b = led_buffer[i].b;
- }
-
-#ifdef USE_MASSDROP_CONFIGURATOR
- breathe_mult = 1;
-
- if (led_animation_breathing) {
- //+60us 119 LED
- led_animation_breathe_cur += BREATHE_STEP * breathe_dir;
-
- 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;
- }
-
- // This should only be performed once per frame
- pomod = (float)((g_rgb_timer / 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; drvid < ISSI3733_DRIVER_COUNT; drvid++) I2C_LED_Q_GCR(drvid); // Queue data
- gcr_actual_last = gcr_actual;
- }
-
- for (drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++) I2C_LED_Q_PWM(drvid); // Queue data
-
- i2c_led_q_run();
-}
-
-void led_matrix_indicators(void) {
- uint8_t kbled = keyboard_leds();
- if (kbled && rgb_matrix_config.enable) {
- for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
- if (
-#if USB_LED_NUM_LOCK_SCANCODE != 255
- (led_map[i].scan == USB_LED_NUM_LOCK_SCANCODE && (kbled & (1 << USB_LED_NUM_LOCK))) ||
-#endif // NUM LOCK
-#if USB_LED_CAPS_LOCK_SCANCODE != 255
- (led_map[i].scan == USB_LED_CAPS_LOCK_SCANCODE && (kbled & (1 << USB_LED_CAPS_LOCK))) ||
-#endif // CAPS LOCK
-#if USB_LED_SCROLL_LOCK_SCANCODE != 255
- (led_map[i].scan == USB_LED_SCROLL_LOCK_SCANCODE && (kbled & (1 << USB_LED_SCROLL_LOCK))) ||
-#endif // SCROLL LOCK
-#if USB_LED_COMPOSE_SCANCODE != 255
- (led_map[i].scan == USB_LED_COMPOSE_SCANCODE && (kbled & (1 << USB_LED_COMPOSE))) ||
-#endif // COMPOSE
-#if USB_LED_KANA_SCANCODE != 255
- (led_map[i].scan == USB_LED_KANA_SCANCODE && (kbled & (1 << USB_LED_KANA))) ||
-#endif // KANA
- (0)) {
- if (rgb_matrix_get_flags() & LED_FLAG_INDICATOR) {
- led_buffer[i].r = 255 - led_buffer[i].r;
- led_buffer[i].g = 255 - led_buffer[i].g;
- led_buffer[i].b = 255 - led_buffer[i].b;
- }
- }
- }
- }
-}
-
-const rgb_matrix_driver_t rgb_matrix_driver = {.init = init, .flush = flush, .set_color = led_set_one, .set_color_all = led_set_all};
-
-/*==============================================================================
-= Legacy Lighting Support =
-==============================================================================*/
-
-#ifdef USE_MASSDROP_CONFIGURATOR
-// Ported from Massdrop QMK GitHub Repo
-
-// TODO?: wire these up to keymap.c
-uint8_t led_animation_orientation = 0;
-uint8_t led_animation_direction = 0;
-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;
-
-static void led_run_pattern(led_setup_t* f, float* ro, float* go, float* bo, float pos) {
- float po;
-
- while (f->end != 1) {
- po = pos; // Reset po for new frame
-
- // Add in any moving effects
- if ((!led_animation_direction && f->ef & EF_SCR_R) || (led_animation_direction && (f->ef & EF_SCR_L))) {
- po -= pomod;
-
- if (po > 100)
- po -= 100;
- else if (po < 0)
- po += 100;
- } else if ((!led_animation_direction && f->ef & EF_SCR_L) || (led_animation_direction && (f->ef & EF_SCR_R))) {
- po += pomod;
-
- if (po > 100)
- po -= 100;
- else if (po < 0)
- po += 100;
- }
-
- // Check if LED's po is in current frame
- if (po < f->hs) {
- f++;
- continue;
- }
- if (po > f->he) {
- f++;
- continue;
- }
- // note: < 0 or > 100 continue
-
- // Calculate the po within the start-stop percentage for color blending
- po = (po - f->hs) / (f->he - f->hs);
-
- // Add in any color effects
- if (f->ef & EF_OVER) {
- *ro = (po * (f->re - f->rs)) + f->rs; // + 0.5;
- *go = (po * (f->ge - f->gs)) + f->gs; // + 0.5;
- *bo = (po * (f->be - f->bs)) + f->bs; // + 0.5;
- } else if (f->ef & EF_SUBTRACT) {
- *ro -= (po * (f->re - f->rs)) + f->rs; // + 0.5;
- *go -= (po * (f->ge - f->gs)) + f->gs; // + 0.5;
- *bo -= (po * (f->be - f->bs)) + f->bs; // + 0.5;
- } else {
- *ro += (po * (f->re - f->rs)) + f->rs; // + 0.5;
- *go += (po * (f->ge - f->gs)) + f->gs; // + 0.5;
- *bo += (po * (f->be - f->bs)) + f->bs; // + 0.5;
- }
-
- f++;
- }
-}
-
-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_led_config.point[i].y / 64.f * 100 : (float)g_led_config.point[i].x / 224.f * 100;
-
- uint8_t highest_active_layer = biton32(layer_state);
-
- if (led_lighting_mode == LED_MODE_KEYS_ONLY && HAS_FLAGS(g_led_config.flags[i], LED_FLAG_UNDERGLOW)) {
- // Do not act on this LED
- } else if (led_lighting_mode == LED_MODE_NON_KEYS_ONLY && !HAS_FLAGS(g_led_config.flags[i], LED_FLAG_UNDERGLOW)) {
- // Do not act on this LED
- } else if (led_lighting_mode == LED_MODE_INDICATORS_ONLY) {
- // Do not act on this LED (Only show indicators)
- } else {
- led_instruction_t* led_cur_instruction = led_instructions;
- while (!led_cur_instruction->end) {
- // Check if this applies to current layer
- if ((led_cur_instruction->flags & LED_FLAG_MATCH_LAYER) && (led_cur_instruction->layer != highest_active_layer)) {
- goto next_iter;
- }
-
- // Check if this applies to current index
- if (led_cur_instruction->flags & LED_FLAG_MATCH_ID) {
- uint8_t modid = i / 32; // Calculate which id# contains the led bit
- uint32_t modidbit = 1 << (i % 32); // Calculate the bit within the id#
- uint32_t* bitfield = &led_cur_instruction->id0 + modid; // Add modid as offset to id0 address. *bitfield is now idX of the led id
- if (~(*bitfield) & modidbit) { // Check if led bit is not set in idX
- goto next_iter;
- }
- }
-
- if (led_cur_instruction->flags & LED_FLAG_USE_RGB) {
- ro = led_cur_instruction->r;
- go = led_cur_instruction->g;
- bo = led_cur_instruction->b;
- } else if (led_cur_instruction->flags & LED_FLAG_USE_PATTERN) {
- led_run_pattern(led_setups[led_cur_instruction->pattern_id], &ro, &go, &bo, po);
- } else if (led_cur_instruction->flags & LED_FLAG_USE_ROTATE_PATTERN) {
- led_run_pattern(led_setups[led_animation_id], &ro, &go, &bo, po);
- }
-
- next_iter:
- led_cur_instruction++;
- }
-
- 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;
-
- if (led_animation_breathing) {
- ro *= breathe_mult;
- go *= breathe_mult;
- bo *= breathe_mult;
- }
- }
-
- led_buffer[i].r = (uint8_t)ro;
- led_buffer[i].g = (uint8_t)go;
- led_buffer[i].b = (uint8_t)bo;
-}
-
-#endif // USE_MASSDROP_CONFIGURATOR