diff options
Diffstat (limited to 'quantum')
24 files changed, 1094 insertions, 765 deletions
diff --git a/quantum/analog.c b/quantum/analog.c deleted file mode 100644 index 1ec38df75..000000000 --- a/quantum/analog.c +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright 2015 Jack Humbert - * - * 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/>. - */ - -// Simple analog to digitial conversion - -#include <avr/io.h> -#include <avr/pgmspace.h> -#include <stdint.h> -#include "analog.h" - - -static uint8_t aref = (1<<REFS0); // default to AREF = Vcc - - -void analogReference(uint8_t mode) -{ - aref = mode & 0xC0; -} - - -// Arduino compatible pin input -int16_t analogRead(uint8_t pin) -{ -#if defined(__AVR_ATmega32U4__) - static const uint8_t PROGMEM pin_to_mux[] = { - 0x00, 0x01, 0x04, 0x05, 0x06, 0x07, - 0x25, 0x24, 0x23, 0x22, 0x21, 0x20}; - if (pin >= 12) return 0; - return adc_read(pgm_read_byte(pin_to_mux + pin)); -#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) - if (pin >= 8) return 0; - return adc_read(pin); -#else - return 0; -#endif -} - -// Mux input -int16_t adc_read(uint8_t mux) -{ -#if defined(__AVR_AT90USB162__) - return 0; -#else - uint8_t low; - - ADCSRA = (1<<ADEN) | ADC_PRESCALER; // enable ADC - ADCSRB = (1<<ADHSM) | (mux & 0x20); // high speed mode - ADMUX = aref | (mux & 0x1F); // configure mux input - ADCSRA = (1<<ADEN) | ADC_PRESCALER | (1<<ADSC); // start the conversion - while (ADCSRA & (1<<ADSC)) ; // wait for result - low = ADCL; // must read LSB first - return (ADCH << 8) | low; // must read MSB only once! -#endif -} - - diff --git a/quantum/analog.h b/quantum/analog.h deleted file mode 100644 index 8d93de7dc..000000000 --- a/quantum/analog.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright 2015 Jack Humbert - * - * 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/>. - */ - -#ifndef _analog_h_included__ -#define _analog_h_included__ - -#include <stdint.h> - -void analogReference(uint8_t mode); -int16_t analogRead(uint8_t pin); -int16_t adc_read(uint8_t mux); - -#define ADC_REF_POWER (1<<REFS0) -#define ADC_REF_INTERNAL ((1<<REFS1) | (1<<REFS0)) -#define ADC_REF_EXTERNAL (0) - -// These prescaler values are for high speed mode, ADHSM = 1 -#if F_CPU == 16000000L -#define ADC_PRESCALER ((1<<ADPS2) | (1<<ADPS1)) -#elif F_CPU == 8000000L -#define ADC_PRESCALER ((1<<ADPS2) | (1<<ADPS0)) -#elif F_CPU == 4000000L -#define ADC_PRESCALER ((1<<ADPS2)) -#elif F_CPU == 2000000L -#define ADC_PRESCALER ((1<<ADPS1) | (1<<ADPS0)) -#elif F_CPU == 1000000L -#define ADC_PRESCALER ((1<<ADPS1)) -#else -#define ADC_PRESCALER ((1<<ADPS0)) -#endif - -// some avr-libc versions do not properly define ADHSM -#if defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) -#if !defined(ADHSM) -#define ADHSM (7) -#endif -#endif - -#endif diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 597073611..c924f2bd5 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -33,17 +33,41 @@ // TIMSK3 - Timer/Counter #3 Interrupt Mask Register // Turn on/off 3A interputs, stopping/enabling the ISR calls -#define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A) -#define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A) +#ifdef C6_AUDIO + #define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A) + #define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A) +#endif + +#ifdef B5_AUDIO + #define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1A) + #define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1A) +#endif // TCCR3A: Timer/Counter #3 Control Register // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6 -#define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1); -#define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0)); + +#ifdef C6_AUDIO + #define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1); + #define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0)); +#endif + +#ifdef B5_AUDIO + #define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1A1); + #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0)); +#endif // Fast PWM Mode Controls -#define TIMER_3_PERIOD ICR3 -#define TIMER_3_DUTY_CYCLE OCR3A + +#ifdef C6_AUDIO + #define TIMER_3_PERIOD ICR3 + #define TIMER_3_DUTY_CYCLE OCR3A +#endif + +#ifdef B5_AUDIO + #define TIMER_1_PERIOD ICR1 + #define TIMER_1_DUTY_CYCLE OCR1A +#endif + // ----------------------------------------------------------------------------- @@ -51,6 +75,7 @@ int voices = 0; int voice_place = 0; float frequency = 0; +float frequency_alt = 0; int volume = 0; long position = 0; @@ -105,16 +130,43 @@ void audio_init() audio_config.raw = eeconfig_read_audio(); // Set port PC6 (OC3A and /OC4A) as output - DDRC |= _BV(PORTC6); - DISABLE_AUDIO_COUNTER_3_ISR; + #ifdef C6_AUDIO + DDRC |= _BV(PORTC6); + #else + DDRC |= _BV(PORTC6); + PORTC &= ~_BV(PORTC6); + #endif + + #ifdef B5_AUDIO + DDRB |= _BV(PORTB5); + #else + DDRB |= _BV(PORTB5); + PORTB &= ~_BV(PORTB5); + #endif + + #ifdef C6_AUDIO + DISABLE_AUDIO_COUNTER_3_ISR; + #endif + + #ifdef B5_AUDIO + DISABLE_AUDIO_COUNTER_1_ISR; + #endif // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6 // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A) // Clock Select (CS3n) = 0b010 = Clock / 8 - TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); - TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); + + #ifdef C6_AUDIO + TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); + TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); + #endif + + #ifdef B5_AUDIO + TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10); + TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10); + #endif audio_initialized = true; } @@ -128,12 +180,21 @@ void stop_all_notes() } voices = 0; - DISABLE_AUDIO_COUNTER_3_ISR; - DISABLE_AUDIO_COUNTER_3_OUTPUT; + + #ifdef C6_AUDIO + DISABLE_AUDIO_COUNTER_3_ISR; + DISABLE_AUDIO_COUNTER_3_OUTPUT; + #endif + + #ifdef B5_AUDIO + DISABLE_AUDIO_COUNTER_1_ISR; + DISABLE_AUDIO_COUNTER_1_OUTPUT; + #endif playing_notes = false; playing_note = false; frequency = 0; + frequency_alt = 0; volume = 0; for (uint8_t i = 0; i < 8; i++) @@ -171,9 +232,16 @@ void stop_note(float freq) voice_place = 0; } if (voices == 0) { - DISABLE_AUDIO_COUNTER_3_ISR; - DISABLE_AUDIO_COUNTER_3_OUTPUT; + #ifdef C6_AUDIO + DISABLE_AUDIO_COUNTER_3_ISR; + DISABLE_AUDIO_COUNTER_3_OUTPUT; + #endif + #ifdef B5_AUDIO + DISABLE_AUDIO_COUNTER_1_ISR; + DISABLE_AUDIO_COUNTER_1_OUTPUT; + #endif frequency = 0; + frequency_alt = 0; volume = 0; playing_note = false; } @@ -200,12 +268,56 @@ float vibrato(float average_freq) { #endif +#ifdef C6_AUDIO ISR(TIMER3_COMPA_vect) { float freq; if (playing_note) { if (voices > 0) { + + #ifdef B5_AUDIO + float freq_alt = 0; + if (voices > 1) { + if (polyphony_rate == 0) { + if (glissando) { + if (frequency_alt != 0 && frequency_alt < frequencies[voices - 2] && frequency_alt < frequencies[voices - 2] * pow(2, -440/frequencies[voices - 2]/12/2)) { + frequency_alt = frequency_alt * pow(2, 440/frequency_alt/12/2); + } else if (frequency_alt != 0 && frequency_alt > frequencies[voices - 2] && frequency_alt > frequencies[voices - 2] * pow(2, 440/frequencies[voices - 2]/12/2)) { + frequency_alt = frequency_alt * pow(2, -440/frequency_alt/12/2); + } else { + frequency_alt = frequencies[voices - 2]; + } + } else { + frequency_alt = frequencies[voices - 2]; + } + + #ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + freq_alt = vibrato(frequency_alt); + } else { + freq_alt = frequency_alt; + } + #else + freq_alt = frequency_alt; + #endif + } + + if (envelope_index < 65535) { + envelope_index++; + } + + freq_alt = voice_envelope(freq_alt); + + if (freq_alt < 30.517578125) { + freq_alt = 30.52; + } + + TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq_alt * CPU_PRESCALER)); + TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq_alt * CPU_PRESCALER)) * note_timbre); + } + #endif + if (polyphony_rate > 0) { if (voices > 1) { voice_place %= voices; @@ -328,6 +440,140 @@ ISR(TIMER3_COMPA_vect) playing_note = false; } } +#endif + +#ifdef B5_AUDIO +ISR(TIMER1_COMPA_vect) +{ + #if defined(B5_AUDIO) && !defined(C6_AUDIO) + float freq = 0; + + if (playing_note) { + if (voices > 0) { + if (polyphony_rate > 0) { + if (voices > 1) { + voice_place %= voices; + if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { + voice_place = (voice_place + 1) % voices; + place = 0.0; + } + } + + #ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + freq = vibrato(frequencies[voice_place]); + } else { + freq = frequencies[voice_place]; + } + #else + freq = frequencies[voice_place]; + #endif + } else { + if (glissando) { + if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { + frequency = frequency * pow(2, 440/frequency/12/2); + } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { + frequency = frequency * pow(2, -440/frequency/12/2); + } else { + frequency = frequencies[voices - 1]; + } + } else { + frequency = frequencies[voices - 1]; + } + + #ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + freq = vibrato(frequency); + } else { + freq = frequency; + } + #else + freq = frequency; + #endif + } + + if (envelope_index < 65535) { + envelope_index++; + } + + freq = voice_envelope(freq); + + if (freq < 30.517578125) { + freq = 30.52; + } + + TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); + TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); + } + } + + if (playing_notes) { + if (note_frequency > 0) { + #ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + freq = vibrato(note_frequency); + } else { + freq = note_frequency; + } + #else + freq = note_frequency; + #endif + + if (envelope_index < 65535) { + envelope_index++; + } + freq = voice_envelope(freq); + + TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); + TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); + } else { + TIMER_1_PERIOD = 0; + TIMER_1_DUTY_CYCLE = 0; + } + + note_position++; + bool end_of_note = false; + if (TIMER_1_PERIOD > 0) { + end_of_note = (note_position >= (note_length / TIMER_1_PERIOD * 0xFFFF)); + } else { + end_of_note = (note_position >= (note_length * 0x7FF)); + } + + if (end_of_note) { + current_note++; + if (current_note >= notes_count) { + if (notes_repeat) { + current_note = 0; + } else { + DISABLE_AUDIO_COUNTER_1_ISR; + DISABLE_AUDIO_COUNTER_1_OUTPUT; + playing_notes = false; + return; + } + } + if (!note_resting && (notes_rest > 0)) { + note_resting = true; + note_frequency = 0; + note_length = notes_rest; + current_note--; + } else { + note_resting = false; + envelope_index = 0; + note_frequency = (*notes_pointer)[current_note][0]; + note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); + } + + note_position = 0; + } + } + + if (!audio_config.enable) { + playing_notes = false; + playing_note = false; + } +#endif +} +#endif void play_note(float freq, int vol) { @@ -338,7 +584,12 @@ void play_note(float freq, int vol) { } if (audio_config.enable && voices < 8) { - DISABLE_AUDIO_COUNTER_3_ISR; + #ifdef C6_AUDIO + DISABLE_AUDIO_COUNTER_3_ISR; + #endif + #ifdef B5_AUDIO + DISABLE_AUDIO_COUNTER_1_ISR; + #endif // Cancel notes if notes are playing if (playing_notes) @@ -354,8 +605,21 @@ void play_note(float freq, int vol) { voices++; } - ENABLE_AUDIO_COUNTER_3_ISR; - ENABLE_AUDIO_COUNTER_3_OUTPUT; + #ifdef C6_AUDIO + ENABLE_AUDIO_COUNTER_3_ISR; + ENABLE_AUDIO_COUNTER_3_OUTPUT; + #endif + #ifdef B5_AUDIO + #ifdef C6_AUDIO + if (voices > 1) { + ENABLE_AUDIO_COUNTER_1_ISR; + ENABLE_AUDIO_COUNTER_1_OUTPUT; + } + #else + ENABLE_AUDIO_COUNTER_1_ISR; + ENABLE_AUDIO_COUNTER_1_OUTPUT; + #endif + #endif } } @@ -369,7 +633,12 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) if (audio_config.enable) { - DISABLE_AUDIO_COUNTER_3_ISR; + #ifdef C6_AUDIO + DISABLE_AUDIO_COUNTER_3_ISR; + #endif + #ifdef B5_AUDIO + DISABLE_AUDIO_COUNTER_1_ISR; + #endif // Cancel note if a note is playing if (playing_note) @@ -390,8 +659,16 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) note_position = 0; - ENABLE_AUDIO_COUNTER_3_ISR; - ENABLE_AUDIO_COUNTER_3_OUTPUT; + #ifdef C6_AUDIO + ENABLE_AUDIO_COUNTER_3_ISR; + ENABLE_AUDIO_COUNTER_3_OUTPUT; + #endif + #ifdef B5_AUDIO + #ifndef C6_AUDIO + ENABLE_AUDIO_COUNTER_1_ISR; + ENABLE_AUDIO_COUNTER_1_OUTPUT; + #endif + #endif } } diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 54ebd423b..94147ccb6 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -44,7 +44,7 @@ float voice_envelope(float frequency) { switch (voice) { case default_voice: - glissando = true; + glissando = false; note_timbre = TIMBRE_50; polyphony_rate = 0; break; diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index b1460c53c..1c522e8b8 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -169,7 +169,6 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) } // translates key to keycode -__attribute__ ((weak)) uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) { // Read entire word (16bits) diff --git a/quantum/keymap_extras/keymap_swedish.h b/quantum/keymap_extras/keymap_swedish.h new file mode 100644 index 000000000..dcfad720d --- /dev/null +++ b/quantum/keymap_extras/keymap_swedish.h @@ -0,0 +1,52 @@ +/* Copyright 2017 Andreas Lindhé + * + * 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/>. + */ + +#ifndef KEYMAP_SWEDISH_H +#define KEYMAP_SWEDISH_H + +#include "keymap_nordic.h" + +// There are slight differrences in the keyboards in the nordic contries + +// Swedish redifinitions from the nordic keyset +#undef NO_AE +#define NO_AE KC_QUOT // ä +#undef NO_CIRC +#define NO_CIRC LSFT(KC_RBRC) // ^ +#undef NO_GRV +#define NO_GRV LSFT(NO_BSLS) // +#undef NO_OSLH +#define NO_OSLH KC_SCLN // ö + +// Additional Swedish keys not defined in the nordic keyset +#define NO_AA KC_LBRC // å +#define NO_ASTR LSFT(KC_BSLS) // * + +// Norwegian unique MAC characters (not vetted for Swedish) +#define NO_ACUT_MAC KC_EQL // = +#define NO_APOS_MAC KC_NUBS // ' +#define NO_AT_MAC KC_BSLS // @ +#define NO_BSLS_MAC ALGR(LSFT(KC_7)) // '\' +#define NO_DLR_MAC LSFT(KC_4) // $ +#define NO_GRV_MAC ALGR(NO_BSLS) // ` +#define NO_GRTR_MAC LSFT(KC_GRV) // > +#define NO_LCBR_MAC ALGR(LSFT(KC_8)) // } +#define NO_LESS_MAC KC_GRV // > +#define NO_PIPE_MAC ALGR(KC_7) // | +#define NO_RCBR_MAC ALGR(LSFT(KC_9)) // } + +#endif + diff --git a/quantum/keymap_extras/sendstring_colemak.h b/quantum/keymap_extras/sendstring_colemak.h new file mode 100644 index 000000000..fa9ace929 --- /dev/null +++ b/quantum/keymap_extras/sendstring_colemak.h @@ -0,0 +1,41 @@ +/* Copyright 2016 Jack Humbert + * + * 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/>. + */ +/* Sendstring definitions for the Colemak layout */ +#ifndef SENDSTRING_COLEMAK +#define SENDSTRING_COLEMAK + +#include "keymap_colemak.h" + +const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = { + 0, 0, 0, 0, 0, 0, 0, 0, + KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, KC_ESC, 0, 0, 0, 0, + KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT, + KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH, + KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, + KC_8, KC_9, CM_SCLN, CM_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH, + KC_2, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G, + CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O, + CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W, + CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS, + KC_GRV, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G, + CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O, + CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W, + CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL +}; + +#endif diff --git a/quantum/keymap_extras/sendstring_dvorak.h b/quantum/keymap_extras/sendstring_dvorak.h new file mode 100644 index 000000000..f5c5c818b --- /dev/null +++ b/quantum/keymap_extras/sendstring_dvorak.h @@ -0,0 +1,41 @@ +/* Copyright 2016 Jack Humbert + * + * 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/>. + */ +/* Sendstring definitions for the Dvorak layout */ +#ifndef SENDSTRING_DVORAK +#define SENDSTRING_DVORAK + +#include "keymap_dvorak.h" + +const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = { + 0, 0, 0, 0, 0, 0, 0, 0, + KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, KC_ESC, 0, 0, 0, 0, + KC_SPC, DV_1, DV_QUOT, DV_3, DV_4, DV_5, DV_7, DV_QUOT, + DV_9, DV_0, DV_8, DV_EQL, DV_COMM, DV_MINS, DV_DOT, DV_SLSH, + DV_0, DV_1, DV_2, DV_3, DV_4, DV_5, DV_6, DV_7, + DV_8, DV_9, DV_SCLN, DV_SCLN, DV_COMM, DV_EQL, DV_DOT, DV_SLSH, + DV_2, DV_A, DV_B, DV_C, DV_D, DV_E, DV_F, DV_G, + DV_H, DV_I, DV_J, DV_K, DV_L, DV_M, DV_N, DV_O, + DV_P, DV_Q, DV_R, DV_S, DV_T, DV_U, DV_V, DV_W, + DV_X, DV_Y, DV_Z, DV_LBRC, DV_BSLS, DV_RBRC, DV_6, DV_MINS, + DV_GRV, DV_A, DV_B, DV_C, DV_D, DV_E, DV_F, DV_G, + DV_H, DV_I, DV_J, DV_K, DV_L, DV_M, DV_N, DV_O, + DV_P, DV_Q, DV_R, DV_S, DV_T, DV_U, DV_V, DV_W, + DV_X, DV_Y, DV_Z, DV_LBRC, DV_BSLS, DV_RBRC, DV_GRV, KC_DEL +}; + +#endif diff --git a/quantum/keymap_extras/sendstring_jis.h b/quantum/keymap_extras/sendstring_jis.h new file mode 100644 index 000000000..c5a38c6a5 --- /dev/null +++ b/quantum/keymap_extras/sendstring_jis.h @@ -0,0 +1,58 @@ +/* Copyright 2016 Jack Humbert + * + * 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/>. + */ +/* Sendstring definitions for the JIS keyboard layout */ +#ifndef SENDSTRING_JIS +#define SENDSTRING_JIS + +const bool ascii_to_shift_lut[0x80] PROGMEM = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 0 +}; + +const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = { + 0, 0, 0, 0, 0, 0, 0, 0, + KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, KC_ESC, 0, 0, 0, 0, + KC_SPC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, + KC_8, KC_9, KC_QUOT, KC_SCLN, KC_COMM, KC_MINS, KC_DOT, KC_SLSH, + KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, + KC_8, KC_9, KC_QUOT, KC_SCLN, KC_COMM, KC_MINS, KC_DOT, KC_SLSH, + KC_LBRC, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, + KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O, + KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, + KC_X, KC_Y, KC_Z, KC_RBRC, KC_JYEN, KC_BSLS, KC_EQL, KC_RO, + KC_LBRC, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, + KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O, + KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, + KC_X, KC_Y, KC_Z, KC_RBRC, KC_JYEN, KC_BSLS, KC_EQL, KC_DEL, +}; + +#endif diff --git a/quantum/light_ws2812.c b/quantum/light_ws2812.c deleted file mode 100755 index 2506e3d8e..000000000 --- a/quantum/light_ws2812.c +++ /dev/null @@ -1,342 +0,0 @@ -/* -* light weight WS2812 lib V2.0b -* -* Controls WS2811/WS2812/WS2812B RGB-LEDs -* Author: Tim (cpldcpu@gmail.com) -* -* Jan 18th, 2014 v2.0b Initial Version -* Nov 29th, 2015 v2.3 Added SK6812RGBW support -* -* 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 "light_ws2812.h" -#include <avr/interrupt.h> -#include <avr/io.h> -#include <util/delay.h> -#include "debug.h" - -#ifdef RGBW_BB_TWI - -// Port for the I2C -#define I2C_DDR DDRD -#define I2C_PIN PIND -#define I2C_PORT PORTD - -// Pins to be used in the bit banging -#define I2C_CLK 0 -#define I2C_DAT 1 - -#define I2C_DATA_HI()\ -I2C_DDR &= ~ (1 << I2C_DAT);\ -I2C_PORT |= (1 << I2C_DAT); -#define I2C_DATA_LO()\ -I2C_DDR |= (1 << I2C_DAT);\ -I2C_PORT &= ~ (1 << I2C_DAT); - -#define I2C_CLOCK_HI()\ -I2C_DDR &= ~ (1 << I2C_CLK);\ -I2C_PORT |= (1 << I2C_CLK); -#define I2C_CLOCK_LO()\ -I2C_DDR |= (1 << I2C_CLK);\ -I2C_PORT &= ~ (1 << I2C_CLK); - -#define I2C_DELAY 1 - -void I2C_WriteBit(unsigned char c) -{ - if (c > 0) - { - I2C_DATA_HI(); - } - else - { - I2C_DATA_LO(); - } - - I2C_CLOCK_HI(); - _delay_us(I2C_DELAY); - - I2C_CLOCK_LO(); - _delay_us(I2C_DELAY); - - if (c > 0) - { - I2C_DATA_LO(); - } - - _delay_us(I2C_DELAY); -} - -// Inits bitbanging port, must be called before using the functions below -// -void I2C_Init(void) -{ - I2C_PORT &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK)); - - I2C_CLOCK_HI(); - I2C_DATA_HI(); - - _delay_us(I2C_DELAY); -} - -// Send a START Condition -// -void I2C_Start(void) -{ - // set both to high at the same time - I2C_DDR &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK)); - _delay_us(I2C_DELAY); - - I2C_DATA_LO(); - _delay_us(I2C_DELAY); - - I2C_CLOCK_LO(); - _delay_us(I2C_DELAY); -} - -// Send a STOP Condition -// -void I2C_Stop(void) -{ - I2C_CLOCK_HI(); - _delay_us(I2C_DELAY); - - I2C_DATA_HI(); - _delay_us(I2C_DELAY); -} - -// write a byte to the I2C slave device -// -unsigned char I2C_Write(unsigned char c) -{ - for (char i = 0; i < 8; i++) - { - I2C_WriteBit(c & 128); - - c <<= 1; - } - - - I2C_WriteBit(0); - _delay_us(I2C_DELAY); - _delay_us(I2C_DELAY); - - // _delay_us(I2C_DELAY); - //return I2C_ReadBit(); - return 0; -} - - -#endif - -// Setleds for standard RGB -void inline ws2812_setleds(LED_TYPE *ledarray, uint16_t leds) -{ - // ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin)); - ws2812_setleds_pin(ledarray,leds, _BV(RGB_DI_PIN & 0xF)); -} - -void inline ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmask) -{ - // ws2812_DDRREG |= pinmask; // Enable DDR - // new universal format (DDR) - _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= pinmask; - - ws2812_sendarray_mask((uint8_t*)ledarray,leds+leds+leds,pinmask); - _delay_us(50); -} - -// Setleds for SK6812RGBW -void inline ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t leds) -{ - - #ifdef RGBW_BB_TWI - uint8_t sreg_prev, twcr_prev; - sreg_prev=SREG; - twcr_prev=TWCR; - cli(); - TWCR &= ~(1<<TWEN); - I2C_Init(); - I2C_Start(); - I2C_Write(0x84); - uint16_t datlen = leds<<2; - uint8_t curbyte; - uint8_t * data = (uint8_t*)ledarray; - while (datlen--) { - curbyte=*data++; - I2C_Write(curbyte); - } - I2C_Stop(); - SREG=sreg_prev; - TWCR=twcr_prev; - #endif - - - // ws2812_DDRREG |= _BV(ws2812_pin); // Enable DDR - // new universal format (DDR) - _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= _BV(RGB_DI_PIN & 0xF); - - ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(RGB_DI_PIN & 0xF)); - - - #ifndef RGBW_BB_TWI - _delay_us(80); - #endif -} - -void ws2812_sendarray(uint8_t *data,uint16_t datlen) -{ - ws2812_sendarray_mask(data,datlen,_BV(RGB_DI_PIN & 0xF)); -} - -/* - This routine writes an array of bytes with RGB values to the Dataout pin - using the fast 800kHz clockless WS2811/2812 protocol. -*/ - -// Timing in ns -#define w_zeropulse 350 -#define w_onepulse 900 -#define w_totalperiod 1250 - -// Fixed cycles used by the inner loop -#define w_fixedlow 2 -#define w_fixedhigh 4 -#define w_fixedtotal 8 - -// Insert NOPs to match the timing, if possible -#define w_zerocycles (((F_CPU/1000)*w_zeropulse )/1000000) -#define w_onecycles (((F_CPU/1000)*w_onepulse +500000)/1000000) -#define w_totalcycles (((F_CPU/1000)*w_totalperiod +500000)/1000000) - -// w1 - nops between rising edge and falling edge - low -#define w1 (w_zerocycles-w_fixedlow) -// w2 nops between fe low and fe high -#define w2 (w_onecycles-w_fixedhigh-w1) -// w3 nops to complete loop -#define w3 (w_totalcycles-w_fixedtotal-w1-w2) - -#if w1>0 - #define w1_nops w1 -#else - #define w1_nops 0 -#endif - -// The only critical timing parameter is the minimum pulse length of the "0" -// Warn or throw error if this timing can not be met with current F_CPU settings. -#define w_lowtime ((w1_nops+w_fixedlow)*1000000)/(F_CPU/1000) -#if w_lowtime>550 - #error "Light_ws2812: Sorry, the clock speed is too low. Did you set F_CPU correctly?" -#elif w_lowtime>450 - #warning "Light_ws2812: The timing is critical and may only work on WS2812B, not on WS2812(S)." - #warning "Please consider a higher clockspeed, if possible" -#endif - -#if w2>0 -#define w2_nops w2 -#else -#define w2_nops 0 -#endif - -#if w3>0 -#define w3_nops w3 -#else -#define w3_nops 0 -#endif - -#define w_nop1 "nop \n\t" -#define w_nop2 "rjmp .+0 \n\t" -#define w_nop4 w_nop2 w_nop2 -#define w_nop8 w_nop4 w_nop4 -#define w_nop16 w_nop8 w_nop8 - -void inline ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi) -{ - uint8_t curbyte,ctr,masklo; - uint8_t sreg_prev; - - // masklo =~maskhi&ws2812_PORTREG; - // maskhi |= ws2812_PORTREG; - masklo =~maskhi&_SFR_IO8((RGB_DI_PIN >> 4) + 2); - maskhi |= _SFR_IO8((RGB_DI_PIN >> 4) + 2); - sreg_prev=SREG; - cli(); - - while (datlen--) { - curbyte=(*data++); - - asm volatile( - " ldi %0,8 \n\t" - "loop%=: \n\t" - " out %2,%3 \n\t" // '1' [01] '0' [01] - re -#if (w1_nops&1) -w_nop1 -#endif -#if (w1_nops&2) -w_nop2 -#endif -#if (w1_nops&4) -w_nop4 -#endif -#if (w1_nops&8) -w_nop8 -#endif -#if (w1_nops&16) -w_nop16 -#endif - " sbrs %1,7 \n\t" // '1' [03] '0' [02] - " out %2,%4 \n\t" // '1' [--] '0' [03] - fe-low - " lsl %1 \n\t" // '1' [04] '0' [04] -#if (w2_nops&1) - w_nop1 -#endif -#if (w2_nops&2) - w_nop2 -#endif -#if (w2_nops&4) - w_nop4 -#endif -#if (w2_nops&8) - w_nop8 -#endif -#if (w2_nops&16) - w_nop16 -#endif - " out %2,%4 \n\t" // '1' [+1] '0' [+1] - fe-high -#if (w3_nops&1) -w_nop1 -#endif -#if (w3_nops&2) -w_nop2 -#endif -#if (w3_nops&4) -w_nop4 -#endif -#if (w3_nops&8) -w_nop8 -#endif -#if (w3_nops&16) -w_nop16 -#endif - - " dec %0 \n\t" // '1' [+2] '0' [+2] - " brne loop%=\n\t" // '1' [+3] '0' [+4] - : "=&d" (ctr) - : "r" (curbyte), "I" (_SFR_IO_ADDR(_SFR_IO8((RGB_DI_PIN >> 4) + 2))), "r" (maskhi), "r" (masklo) - ); - } - - SREG=sreg_prev; -} diff --git a/quantum/light_ws2812.h b/quantum/light_ws2812.h deleted file mode 100755 index 60924a0fb..000000000 --- a/quantum/light_ws2812.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * light weight WS2812 lib include - * - * Version 2.3 - Nev 29th 2015 - * Author: Tim (cpldcpu@gmail.com) - * - * Please do not change this file! All configuration is handled in "ws2812_config.h" - * - * 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/>. - */ - -#ifndef LIGHT_WS2812_H_ -#define LIGHT_WS2812_H_ - -#include <avr/io.h> -#include <avr/interrupt.h> -//#include "ws2812_config.h" -//#include "i2cmaster.h" - -#ifdef RGBW - #define LED_TYPE struct cRGBW -#else - #define LED_TYPE struct cRGB -#endif - - -/* - * Structure of the LED array - * - * cRGB: RGB for WS2812S/B/C/D, SK6812, SK6812Mini, SK6812WWA, APA104, APA106 - * cRGBW: RGBW for SK6812RGBW - */ - -struct cRGB { uint8_t g; uint8_t r; uint8_t b; }; -struct cRGBW { uint8_t g; uint8_t r; uint8_t b; uint8_t w;}; - - - -/* User Interface - * - * Input: - * ledarray: An array of GRB data describing the LED colors - * number_of_leds: The number of LEDs to write - * pinmask (optional): Bitmask describing the output bin. e.g. _BV(PB0) - * - * The functions will perform the following actions: - * - Set the data-out pin as output - * - Send out the LED data - * - Wait 50�s to reset the LEDs - */ - -void ws2812_setleds (LED_TYPE *ledarray, uint16_t number_of_leds); -void ws2812_setleds_pin (LED_TYPE *ledarray, uint16_t number_of_leds,uint8_t pinmask); -void ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t number_of_leds); - -/* - * Old interface / Internal functions - * - * The functions take a byte-array and send to the data output as WS2812 bitstream. - * The length is the number of bytes to send - three per LED. - */ - -void ws2812_sendarray (uint8_t *array,uint16_t length); -void ws2812_sendarray_mask(uint8_t *array,uint16_t length, uint8_t pinmask); - - -/* - * Internal defines - */ -#ifndef CONCAT -#define CONCAT(a, b) a ## b -#endif -#ifndef CONCAT_EXP -#define CONCAT_EXP(a, b) CONCAT(a, b) -#endif - -// #define ws2812_PORTREG CONCAT_EXP(PORT,ws2812_port) -// #define ws2812_DDRREG CONCAT_EXP(DDR,ws2812_port) - -#endif /* LIGHT_WS2812_H_ */ diff --git a/quantum/quantum.c b/quantum/quantum.c index 5bb7b04d5..36e586d31 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -455,103 +455,8 @@ bool process_record_quantum(keyrecord_t *record) { return process_action_kb(record); } -#ifdef JIS_KEYCODE -static const uint16_t ascii_to_shift_lut[8] PROGMEM = { - 0x0000, /*0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,*/ - 0x0000, /*0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,*/ - 0x7ff0, /*0, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 0, 0, 0,*/ - 0x000f, /*0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 1,*/ - 0x7fff, /*0, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1,*/ - 0xffe1, /*1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 0, 0, 0, 0, 1,*/ - 0x8000, /*1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,*/ - 0x001e, /*0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 0*/ -}; - -static const struct { - uint8_t controls_0[16], - controls_1[16], - numerics[16], - alphabets_0[16], - alphabets_1[16]; -} lower_to_keycode PROGMEM = { - .controls_0 = { - 0, 0, 0, 0, 0, 0, 0, 0, - KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0, - }, - .controls_1 = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, KC_ESC, 0, 0, 0, 0, - }, - .numerics = { - KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, - KC_8, KC_9, KC_QUOT, KC_SCLN, KC_COMM, KC_MINS, KC_DOT, KC_SLSH, - }, - .alphabets_0 = { - KC_LBRC, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, - KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O, - }, - .alphabets_1 = { - KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, - KC_X, KC_Y, KC_Z, KC_RBRC, KC_JYEN, KC_BSLS, KC_EQL, KC_RO, - }, -}; -static const uint8_t* ascii_to_keycode_lut[8] = { - lower_to_keycode.controls_0, - lower_to_keycode.controls_1, - lower_to_keycode.numerics, - lower_to_keycode.numerics, - lower_to_keycode.alphabets_0, - lower_to_keycode.alphabets_1, - lower_to_keycode.alphabets_0, - lower_to_keycode.alphabets_1 -}; - -void send_string(const char *str) { - while (1) { - uint8_t keycode; - bool shift; - uint8_t ascii_code = pgm_read_byte(str); - - if ( ascii_code == 0x00u ){ break; } - else if (ascii_code == 0x20u) { - keycode = KC_SPC; - shift = false; - } - else if (ascii_code == 0x7Fu) { - keycode = KC_DEL; - shift = false; - } - else { - int hi = ascii_code>>4 & 0x0f, - lo = ascii_code & 0x0f; - keycode = pgm_read_byte(&ascii_to_keycode_lut[hi][lo]); - shift = !!( pgm_read_word(&ascii_to_shift_lut[hi]) & (0x8000u>>lo) ); - } - - if (shift) { - register_code(KC_LSFT); - register_code(keycode); - unregister_code(keycode); - unregister_code(KC_LSFT); - } - else { - register_code(keycode); - unregister_code(keycode); - } - ++str; - } -} - -#else -static const bool ascii_to_qwerty_shift_lut[0x80] PROGMEM = { +__attribute__ ((weak)) +const bool ascii_to_shift_lut[0x80] PROGMEM = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -570,7 +475,8 @@ static const bool ascii_to_qwerty_shift_lut[0x80] PROGMEM = { 0, 0, 0, 1, 1, 1, 1, 0 }; -static const uint8_t ascii_to_qwerty_keycode_lut[0x80] PROGMEM = { +__attribute__ ((weak)) +const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = { 0, 0, 0, 0, 0, 0, 0, 0, KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -590,12 +496,16 @@ static const uint8_t ascii_to_qwerty_keycode_lut[0x80] PROGMEM = { }; void send_string(const char *str) { + send_string_with_delay(str, 0); +} + +void send_string_with_delay(const char *str, uint8_t interval) { while (1) { uint8_t keycode; uint8_t ascii_code = pgm_read_byte(str); if (!ascii_code) break; - keycode = pgm_read_byte(&ascii_to_qwerty_keycode_lut[ascii_code]); - if (pgm_read_byte(&ascii_to_qwerty_shift_lut[ascii_code])) { + keycode = pgm_read_byte(&ascii_to_keycode_lut[ascii_code]); + if (pgm_read_byte(&ascii_to_shift_lut[ascii_code])) { register_code(KC_LSFT); register_code(keycode); unregister_code(keycode); @@ -606,55 +516,11 @@ void send_string(const char *str) { unregister_code(keycode); } ++str; + // interval + { uint8_t ms = interval; while (ms--) wait_ms(1); } } } -#endif - -/* for users whose OSes are set to Colemak */ -#if 0 -#include "keymap_colemak.h" - -const bool ascii_to_colemak_shift_lut[0x80] PROGMEM = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 1, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 0 -}; - -const uint8_t ascii_to_colemak_keycode_lut[0x80] PROGMEM = { - 0, 0, 0, 0, 0, 0, 0, 0, - KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, KC_ESC, 0, 0, 0, 0, - KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT, - KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH, - KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, - KC_8, KC_9, CM_SCLN, CM_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH, - KC_2, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G, - CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O, - CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W, - CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS, - KC_GRV, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G, - CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O, - CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W, - CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL -}; - -#endif - void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) { layer_on(layer3); diff --git a/quantum/quantum.h b/quantum/quantum.h index 2bf18d095..e00fe2346 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -95,7 +95,10 @@ extern uint32_t default_layer_state; #endif #define SEND_STRING(str) send_string(PSTR(str)) +extern const bool ascii_to_shift_lut[0x80]; +extern const uint8_t ascii_to_keycode_lut[0x80]; void send_string(const char *str); +void send_string_with_delay(const char *str, uint8_t interval); // For tri-layer void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3); diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index c34ecafa5..6038e31c4 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -550,13 +550,13 @@ enum quantum_keycodes { #define OSL(layer) (layer | QK_ONE_SHOT_LAYER) // One-shot mod -#define OSM(mod) (mod | QK_ONE_SHOT_MOD) +#define OSM(mod) ((mod) | QK_ONE_SHOT_MOD) // Layer tap-toggle #define TT(layer) (layer | QK_LAYER_TAP_TOGGLE) // M-od, T-ap - 256 keycode max -#define MT(mod, kc) (kc | QK_MOD_TAP | ((mod & 0x1F) << 8)) +#define MT(mod, kc) (kc | QK_MOD_TAP | (((mod) & 0x1F) << 8)) #define CTL_T(kc) MT(MOD_LCTL, kc) #define LCTL_T(kc) MT(MOD_LCTL, kc) diff --git a/quantum/rgblight.h b/quantum/rgblight.h index 92130192c..8fea96a9e 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -61,7 +61,7 @@ #include <stdint.h> #include <stdbool.h> #include "eeconfig.h" -#include "light_ws2812.h" +#include "ws2812.h" extern LED_TYPE led[RGBLED_NUM]; diff --git a/quantum/visualizer/common_gfxconf.h b/quantum/visualizer/common_gfxconf.h new file mode 100644 index 000000000..eb705b188 --- /dev/null +++ b/quantum/visualizer/common_gfxconf.h @@ -0,0 +1,325 @@ +/** + * This file has a different license to the rest of the uGFX system. + * You can copy, modify and distribute this file as you see fit. + * You do not need to publish your source modifications to this file. + * The only thing you are not permitted to do is to relicense it + * under a different license. + */ + +/** + * Copy this file into your project directory and rename it as gfxconf.h + * Edit your copy to turn on the uGFX features you want to use. + * The values below are the defaults. + * + * Only remove the comments from lines where you want to change the + * default value. This allows definitions to be included from + * driver makefiles when required and provides the best future + * compatibility for your project. + * + * Please use spaces instead of tabs in this file. + */ + +#ifndef COMMON_GFXCONF_H +#define COMMON_GFXCONF_H + + +/////////////////////////////////////////////////////////////////////////// +// GOS - One of these must be defined, preferably in your Makefile // +/////////////////////////////////////////////////////////////////////////// +//#define GFX_USE_OS_CHIBIOS TRUE +//#define GFX_USE_OS_FREERTOS FALSE +// #define GFX_FREERTOS_USE_TRACE FALSE +//#define GFX_USE_OS_WIN32 FALSE +//#define GFX_USE_OS_LINUX FALSE +//#define GFX_USE_OS_OSX FALSE +//#define GFX_USE_OS_ECOS FALSE +//#define GFX_USE_OS_RAWRTOS FALSE +//#define GFX_USE_OS_ARDUINO FALSE +//#define GFX_USE_OS_KEIL FALSE +//#define GFX_USE_OS_CMSIS FALSE +//#define GFX_USE_OS_RAW32 FALSE +// #define INTERRUPTS_OFF() optional_code +// #define INTERRUPTS_ON() optional_code +// These are not defined by default for some reason +#define GOS_NEED_X_THREADS FALSE +#define GOS_NEED_X_HEAP FALSE + +// Options that (should where relevant) apply to all operating systems + #define GFX_NO_INLINE FALSE +// #define GFX_COMPILER GFX_COMPILER_UNKNOWN +// #define GFX_CPU GFX_CPU_UNKNOWN +// #define GFX_OS_HEAP_SIZE 0 +// #define GFX_OS_NO_INIT FALSE +// #define GFX_OS_INIT_NO_WARNING FALSE +// #define GFX_OS_PRE_INIT_FUNCTION myHardwareInitRoutine +// #define GFX_OS_EXTRA_INIT_FUNCTION myOSInitRoutine +// #define GFX_OS_EXTRA_DEINIT_FUNCTION myOSDeInitRoutine + + +/////////////////////////////////////////////////////////////////////////// +// GDISP // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GDISP TRUE + +//#define GDISP_NEED_AUTOFLUSH FALSE +//#define GDISP_NEED_TIMERFLUSH FALSE +//#define GDISP_NEED_VALIDATION TRUE +//#define GDISP_NEED_CLIP TRUE +#define GDISP_NEED_CIRCLE TRUE +#define GDISP_NEED_ELLIPSE TRUE +#define GDISP_NEED_ARC TRUE +#define GDISP_NEED_ARCSECTORS TRUE +#define GDISP_NEED_CONVEX_POLYGON TRUE +//#define GDISP_NEED_SCROLL FALSE +#define GDISP_NEED_PIXELREAD TRUE +#define GDISP_NEED_CONTROL TRUE +//#define GDISP_NEED_QUERY FALSE +//#define GDISP_NEED_MULTITHREAD FALSE +//#define GDISP_NEED_STREAMING FALSE +#define GDISP_NEED_TEXT TRUE +// #define GDISP_NEED_TEXT_WORDWRAP FALSE +// #define GDISP_NEED_ANTIALIAS FALSE +// #define GDISP_NEED_UTF8 FALSE + #define GDISP_NEED_TEXT_KERNING TRUE +// #define GDISP_INCLUDE_FONT_UI1 FALSE +// #define GDISP_INCLUDE_FONT_UI2 FALSE // The smallest preferred font. +// #define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE +// #define GDISP_INCLUDE_FONT_DEJAVUSANS10 FALSE +// #define GDISP_INCLUDE_FONT_DEJAVUSANS12 FALSE +// #define GDISP_INCLUDE_FONT_DEJAVUSANS16 FALSE +// #define GDISP_INCLUDE_FONT_DEJAVUSANS20 FALSE +// #define GDISP_INCLUDE_FONT_DEJAVUSANS24 FALSE +// #define GDISP_INCLUDE_FONT_DEJAVUSANS32 FALSE + #define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12 TRUE +// #define GDISP_INCLUDE_FONT_FIXED_10X20 FALSE +// #define GDISP_INCLUDE_FONT_FIXED_7X14 FALSE + #define GDISP_INCLUDE_FONT_FIXED_5X8 TRUE +// #define GDISP_INCLUDE_FONT_DEJAVUSANS12_AA FALSE +// #define GDISP_INCLUDE_FONT_DEJAVUSANS16_AA FALSE +// #define GDISP_INCLUDE_FONT_DEJAVUSANS20_AA FALSE +// #define GDISP_INCLUDE_FONT_DEJAVUSANS24_AA FALSE +// #define GDISP_INCLUDE_FONT_DEJAVUSANS32_AA FALSE +// #define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12_AA FALSE +// #define GDISP_INCLUDE_USER_FONTS FALSE + +//#define GDISP_NEED_IMAGE FALSE +// #define GDISP_NEED_IMAGE_NATIVE FALSE +// #define GDISP_NEED_IMAGE_GIF FALSE +// #define GDISP_NEED_IMAGE_BMP FALSE +// #define GDISP_NEED_IMAGE_BMP_1 FALSE +// #define GDISP_NEED_IMAGE_BMP_4 FALSE +// #define GDISP_NEED_IMAGE_BMP_4_RLE FALSE +// #define GDISP_NEED_IMAGE_BMP_8 FALSE +// #define GDISP_NEED_IMAGE_BMP_8_RLE FALSE +// #define GDISP_NEED_IMAGE_BMP_16 FALSE +// #define GDISP_NEED_IMAGE_BMP_24 FALSE +// #define GDISP_NEED_IMAGE_BMP_32 FALSE +// #define GDISP_NEED_IMAGE_JPG FALSE +// #define GDISP_NEED_IMAGE_PNG FALSE +// #define GDISP_NEED_IMAGE_ACCOUNTING FALSE +#ifdef EMULATOR +#define GDISP_NEED_PIXMAP TRUE +#endif +// #define GDISP_NEED_PIXMAP_IMAGE FALSE + +//#define GDISP_DEFAULT_ORIENTATION GDISP_ROTATE_LANDSCAPE // If not defined the native hardware orientation is used. +//#define GDISP_LINEBUF_SIZE 128 +//#define GDISP_STARTUP_COLOR Black +#define GDISP_NEED_STARTUP_LOGO FALSE + +//#define GDISP_TOTAL_DISPLAYS 2 + + #ifdef GDISP_DRIVER_LIST + // For code and speed optimization define as TRUE or FALSE if all controllers have the same capability + #define GDISP_HARDWARE_STREAM_WRITE FALSE + #define GDISP_HARDWARE_STREAM_READ FALSE + #define GDISP_HARDWARE_STREAM_POS FALSE + #define GDISP_HARDWARE_DRAWPIXEL TRUE + #define GDISP_HARDWARE_CLEARS FALSE + #define GDISP_HARDWARE_FILLS FALSE + //#define GDISP_HARDWARE_BITFILLS FALSE + #define GDISP_HARDWARE_SCROLL FALSE + #define GDISP_HARDWARE_PIXELREAD TRUE + #define GDISP_HARDWARE_CONTROL TRUE + #define GDISP_HARDWARE_QUERY FALSE + #define GDISP_HARDWARE_CLIP FALSE + + #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888 + #endif + +// The custom format is not defined for some reason, so define it as error +// so we don't get compiler warnings +#define GDISP_PIXELFORMAT_CUSTOM GDISP_PIXELFORMAT_ERROR + +#define GDISP_USE_GFXNET FALSE +// #define GDISP_GFXNET_PORT 13001 +// #define GDISP_GFXNET_CUSTOM_LWIP_STARTUP FALSE +// #define GDISP_DONT_WAIT_FOR_NET_DISPLAY FALSE +// #define GDISP_GFXNET_UNSAFE_SOCKETS FALSE + + +/////////////////////////////////////////////////////////////////////////// +// GWIN // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GWIN FALSE + +//#define GWIN_NEED_WINDOWMANAGER FALSE +// #define GWIN_REDRAW_IMMEDIATE FALSE +// #define GWIN_REDRAW_SINGLEOP FALSE +// #define GWIN_NEED_FLASHING FALSE +// #define GWIN_FLASHING_PERIOD 250 + +//#define GWIN_NEED_CONSOLE FALSE +// #define GWIN_CONSOLE_USE_HISTORY FALSE +// #define GWIN_CONSOLE_HISTORY_AVERAGING FALSE +// #define GWIN_CONSOLE_HISTORY_ATCREATE FALSE +// #define GWIN_CONSOLE_ESCSEQ FALSE +// #define GWIN_CONSOLE_USE_BASESTREAM FALSE +// #define GWIN_CONSOLE_USE_FLOAT FALSE +//#define GWIN_NEED_GRAPH FALSE +//#define GWIN_NEED_GL3D FALSE + +//#define GWIN_NEED_WIDGET FALSE +//#define GWIN_FOCUS_HIGHLIGHT_WIDTH 1 +// #define GWIN_NEED_LABEL FALSE +// #define GWIN_LABEL_ATTRIBUTE FALSE +// #define GWIN_NEED_BUTTON FALSE +// #define GWIN_BUTTON_LAZY_RELEASE FALSE +// #define GWIN_NEED_SLIDER FALSE +// #define GWIN_SLIDER_NOSNAP FALSE +// #define GWIN_SLIDER_DEAD_BAND 5 +// #define GWIN_SLIDER_TOGGLE_INC 20 +// #define GWIN_NEED_CHECKBOX FALSE +// #define GWIN_NEED_IMAGE FALSE +// #define GWIN_NEED_IMAGE_ANIMATION FALSE +// #define GWIN_NEED_RADIO FALSE +// #define GWIN_NEED_LIST FALSE +// #define GWIN_NEED_LIST_IMAGES FALSE +// #define GWIN_NEED_PROGRESSBAR FALSE +// #define GWIN_PROGRESSBAR_AUTO FALSE +// #define GWIN_NEED_KEYBOARD FALSE +// #define GWIN_KEYBOARD_DEFAULT_LAYOUT VirtualKeyboard_English1 +// #define GWIN_NEED_KEYBOARD_ENGLISH1 TRUE +// #define GWIN_NEED_TEXTEDIT FALSE +// #define GWIN_FLAT_STYLING FALSE +// #define GWIN_WIDGET_TAGS FALSE + +//#define GWIN_NEED_CONTAINERS FALSE +// #define GWIN_NEED_CONTAINER FALSE +// #define GWIN_NEED_FRAME FALSE +// #define GWIN_NEED_TABSET FALSE +// #define GWIN_TABSET_TABHEIGHT 18 + + +/////////////////////////////////////////////////////////////////////////// +// GEVENT // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GEVENT TRUE + +//#define GEVENT_ASSERT_NO_RESOURCE FALSE +//#define GEVENT_MAXIMUM_SIZE 32 +//#define GEVENT_MAX_SOURCE_LISTENERS 32 + + +/////////////////////////////////////////////////////////////////////////// +// GTIMER // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GTIMER FALSE + +//#define GTIMER_THREAD_PRIORITY HIGH_PRIORITY +//#define GTIMER_THREAD_WORKAREA_SIZE 2048 + + +/////////////////////////////////////////////////////////////////////////// +// GQUEUE // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GQUEUE FALSE + +//#define GQUEUE_NEED_ASYNC FALSE +//#define GQUEUE_NEED_GSYNC FALSE +//#define GQUEUE_NEED_FSYNC FALSE +//#define GQUEUE_NEED_BUFFERS FALSE + +/////////////////////////////////////////////////////////////////////////// +// GINPUT // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GINPUT FALSE + +//#define GINPUT_NEED_MOUSE FALSE +// #define GINPUT_TOUCH_STARTRAW FALSE +// #define GINPUT_TOUCH_NOTOUCH FALSE +// #define GINPUT_TOUCH_NOCALIBRATE FALSE +// #define GINPUT_TOUCH_NOCALIBRATE_GUI FALSE +// #define GINPUT_MOUSE_POLL_PERIOD 25 +// #define GINPUT_MOUSE_CLICK_TIME 300 +// #define GINPUT_TOUCH_CXTCLICK_TIME 700 +// #define GINPUT_TOUCH_USER_CALIBRATION_LOAD FALSE +// #define GINPUT_TOUCH_USER_CALIBRATION_SAVE FALSE +// #define GMOUSE_DRIVER_LIST GMOUSEVMT_Win32, GMOUSEVMT_Win32 +//#define GINPUT_NEED_KEYBOARD FALSE +// #define GINPUT_KEYBOARD_POLL_PERIOD 200 +// #define GKEYBOARD_DRIVER_LIST GKEYBOARDVMT_Win32, GKEYBOARDVMT_Win32 +// #define GKEYBOARD_LAYOUT_OFF FALSE +// #define GKEYBOARD_LAYOUT_SCANCODE2_US FALSE +//#define GINPUT_NEED_TOGGLE FALSE +//#define GINPUT_NEED_DIAL FALSE + + +/////////////////////////////////////////////////////////////////////////// +// GFILE // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GFILE FALSE + +//#define GFILE_NEED_PRINTG FALSE +//#define GFILE_NEED_SCANG FALSE +//#define GFILE_NEED_STRINGS FALSE +//#define GFILE_NEED_FILELISTS FALSE +//#define GFILE_NEED_STDIO FALSE +//#define GFILE_NEED_NOAUTOMOUNT FALSE +//#define GFILE_NEED_NOAUTOSYNC FALSE + +//#define GFILE_NEED_MEMFS FALSE +//#define GFILE_NEED_ROMFS FALSE +//#define GFILE_NEED_RAMFS FALSE +//#define GFILE_NEED_FATFS FALSE +//#define GFILE_NEED_NATIVEFS FALSE +//#define GFILE_NEED_CHBIOSFS FALSE + +//#define GFILE_ALLOW_FLOATS FALSE +//#define GFILE_ALLOW_DEVICESPECIFIC FALSE +//#define GFILE_MAX_GFILES 3 + +/////////////////////////////////////////////////////////////////////////// +// GADC // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GADC FALSE + +//#define GADC_MAX_LOWSPEED_DEVICES 4 + + +/////////////////////////////////////////////////////////////////////////// +// GAUDIO // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GAUDIO FALSE +// There seems to be a bug in the ugfx code, the wrong define is used +// So define it in order to avoid warnings +#define GFX_USE_GAUDIN GFX_USE_GAUDIO +// #define GAUDIO_NEED_PLAY FALSE +// #define GAUDIO_NEED_RECORD FALSE + + +/////////////////////////////////////////////////////////////////////////// +// GMISC // +/////////////////////////////////////////////////////////////////////////// +#define GFX_USE_GMISC TRUE + +//#define GMISC_NEED_ARRAYOPS FALSE +//#define GMISC_NEED_FASTTRIG FALSE +//#define GMISC_NEED_FIXEDTRIG FALSE +//#define GMISC_NEED_INVSQRT FALSE +// #define GMISC_INVSQRT_MIXED_ENDIAN FALSE +// #define GMISC_INVSQRT_REAL_SLOW FALSE +#define GMISC_NEED_MATRIXFLOAT2D TRUE +#define GMISC_NEED_MATRIXFIXED2D FALSE + +#endif /* COMMON_GFXCONF_H */ diff --git a/quantum/visualizer/default_animations.c b/quantum/visualizer/default_animations.c new file mode 100644 index 000000000..2d0327372 --- /dev/null +++ b/quantum/visualizer/default_animations.c @@ -0,0 +1,176 @@ +/* Copyright 2017 Fred Sundvik + * + * 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/>. + */ + +#if defined(VISUALIZER_ENABLE) + +#include "default_animations.h" +#include "visualizer.h" +#ifdef LCD_ENABLE +#include "lcd_keyframes.h" +#endif +#ifdef LCD_BACKLIGHT_ENABLE +#include "lcd_backlight_keyframes.h" +#endif + +#ifdef BACKLIGHT_ENABLE +#include "led_backlight_keyframes.h" +#endif + +#include "visualizer_keyframes.h" + + +#if defined(LCD_ENABLE) || defined(LCD_BACKLIGHT_ENABLE) || defined(BACKLIGHT_ENABLE) + +static bool keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { +#ifdef LCD_ENABLE + lcd_keyframe_enable(animation, state); +#endif +#ifdef LCD_BACKLIGHT_ENABLE + lcd_backlight_keyframe_enable(animation, state); +#endif +#ifdef BACKLIGHT_ENABLE + led_backlight_keyframe_enable(animation, state); +#endif + return false; +} + +static bool keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { +#ifdef LCD_ENABLE + lcd_keyframe_disable(animation, state); +#endif +#ifdef LCD_BACKLIGHT_ENABLE + lcd_backlight_keyframe_disable(animation, state); +#endif +#ifdef BACKLIGHT_ENABLE + led_backlight_keyframe_disable(animation, state); +#endif + return false; +} + +static bool keyframe_fade_in(keyframe_animation_t* animation, visualizer_state_t* state) { + bool ret = false; +#ifdef LCD_BACKLIGHT_ENABLE + ret |= lcd_backlight_keyframe_animate_color(animation, state); +#endif +#ifdef BACKLIGHT_ENABLE + ret |= led_backlight_keyframe_fade_in_all(animation, state); +#endif + return ret; +} + +static bool keyframe_fade_out(keyframe_animation_t* animation, visualizer_state_t* state) { + bool ret = false; +#ifdef LCD_BACKLIGHT_ENABLE + ret |= lcd_backlight_keyframe_animate_color(animation, state); +#endif +#ifdef BACKLIGHT_ENABLE + ret |= led_backlight_keyframe_fade_out_all(animation, state); +#endif + return ret; +} + + +// Don't worry, if the startup animation is long, you can use the keyboard like normal +// during that time +keyframe_animation_t default_startup_animation = { +#if LCD_ENABLE + .num_frames = 3, +#else + .num_frames = 2, +#endif + .loop = false, + .frame_lengths = { + 0, +#if LCD_ENABLE + 0, +#endif + gfxMillisecondsToTicks(5000)}, + .frame_functions = { + keyframe_enable, +#if LCD_ENABLE + lcd_keyframe_draw_logo, +#endif + keyframe_fade_in, + }, +}; + +keyframe_animation_t default_suspend_animation = { +#if LCD_ENABLE + .num_frames = 3, +#else + .num_frames = 2, +#endif + .loop = false, + .frame_lengths = { +#if LCD_ENABLE + 0, +#endif + gfxMillisecondsToTicks(1000), + 0}, + .frame_functions = { +#if LCD_ENABLE + lcd_keyframe_display_layer_text, +#endif + keyframe_fade_out, + keyframe_disable, + }, +}; +#endif + +#if defined(BACKLIGHT_ENABLE) +#define CROSSFADE_TIME 1000 +#define GRADIENT_TIME 3000 + +keyframe_animation_t led_test_animation = { + .num_frames = 14, + .loop = true, + .frame_lengths = { + gfxMillisecondsToTicks(1000), // fade in + gfxMillisecondsToTicks(1000), // no op (leds on) + gfxMillisecondsToTicks(1000), // fade out + gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade + gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in) + gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade + gfxMillisecondsToTicks(GRADIENT_TIME), // top_to_bottom + 0, // mirror leds + gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade + gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out) + gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade + gfxMillisecondsToTicks(GRADIENT_TIME), // top_to_bottom + 0, // normal leds + gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade + + }, + .frame_functions = { + led_backlight_keyframe_fade_in_all, + keyframe_no_operation, + led_backlight_keyframe_fade_out_all, + led_backlight_keyframe_crossfade, + led_backlight_keyframe_left_to_right_gradient, + led_backlight_keyframe_crossfade, + led_backlight_keyframe_top_to_bottom_gradient, + led_backlight_keyframe_mirror_orientation, + led_backlight_keyframe_crossfade, + led_backlight_keyframe_left_to_right_gradient, + led_backlight_keyframe_crossfade, + led_backlight_keyframe_top_to_bottom_gradient, + led_backlight_keyframe_normal_orientation, + led_backlight_keyframe_crossfade, + }, +}; +#endif + +#endif diff --git a/quantum/visualizer/lcd_backlight_keyframes.h b/quantum/visualizer/default_animations.h index e1c125cf9..51320b8b8 100644 --- a/quantum/visualizer/lcd_backlight_keyframes.h +++ b/quantum/visualizer/default_animations.h @@ -14,17 +14,17 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef QUANTUM_VISUALIZER_LCD_BACKLIGHT_KEYFRAMES_H_ -#define QUANTUM_VISUALIZER_LCD_BACKLIGHT_KEYFRAMES_H_ +#ifndef DEFAULT_ANIMATIONS_H_ +#define DEFAULT_ANIMATIONS_H_ #include "visualizer.h" -// Animates the LCD backlight color between the current color and the target color (of the state) -bool backlight_keyframe_animate_color(keyframe_animation_t* animation, visualizer_state_t* state); -// Sets the backlight color to the target color -bool backlight_keyframe_set_color(keyframe_animation_t* animation, visualizer_state_t* state); +// You can use these default animations, but of course you can also write your own custom ones instead +extern keyframe_animation_t default_startup_animation; +extern keyframe_animation_t default_suspend_animation; -bool backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state); -bool backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state); +// An animation for testing and demonstrating the led support, should probably not be used for real world +// cases +extern keyframe_animation_t led_test_animation; -#endif /* QUANTUM_VISUALIZER_LCD_BACKLIGHT_KEYFRAMES_H_ */ +#endif /* DEFAULT_ANIMATIONS_H_ */ diff --git a/quantum/visualizer/lcd_backlight_keyframes.c b/quantum/visualizer/lcd_backlight_keyframes.c index 8436d4e3d..8c402baf6 100644 --- a/quantum/visualizer/lcd_backlight_keyframes.c +++ b/quantum/visualizer/lcd_backlight_keyframes.c @@ -16,7 +16,7 @@ #include "lcd_backlight_keyframes.h" -bool backlight_keyframe_animate_color(keyframe_animation_t* animation, visualizer_state_t* state) { +bool lcd_backlight_keyframe_animate_color(keyframe_animation_t* animation, visualizer_state_t* state) { int frame_length = animation->frame_lengths[animation->current_frame]; int current_pos = frame_length - animation->time_left_in_frame; uint8_t t_h = LCD_HUE(state->target_lcd_color); @@ -49,7 +49,7 @@ bool backlight_keyframe_animate_color(keyframe_animation_t* animation, visualize return true; } -bool backlight_keyframe_set_color(keyframe_animation_t* animation, visualizer_state_t* state) { +bool lcd_backlight_keyframe_set_color(keyframe_animation_t* animation, visualizer_state_t* state) { (void)animation; state->prev_lcd_color = state->target_lcd_color; state->current_lcd_color = state->target_lcd_color; @@ -60,14 +60,14 @@ bool backlight_keyframe_set_color(keyframe_animation_t* animation, visualizer_st return false; } -bool backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { +bool lcd_backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { (void)animation; (void)state; lcd_backlight_hal_color(0, 0, 0); return false; } -bool backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { +bool lcd_backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { (void)animation; (void)state; lcd_backlight_color(LCD_HUE(state->current_lcd_color), diff --git a/quantum/visualizer/lcd_keyframes.c b/quantum/visualizer/lcd_keyframes.c index 82e4184d2..75eb45700 100644 --- a/quantum/visualizer/lcd_keyframes.c +++ b/quantum/visualizer/lcd_keyframes.c @@ -166,8 +166,8 @@ bool lcd_keyframe_draw_logo(keyframe_animation_t* animation, visualizer_state_t* // or state structs, here we use the image //gdispGBlitArea is a tricky function to use since it supports blitting part of the image - // if you have full screen image, then just use 128 and 32 for both source and target dimensions - gdispGBlitArea(GDISP, 0, 0, 128, 32, 0, 0, 128, (pixel_t*)resource_lcd_logo); + // if you have full screen image, then just use LCD_WIDTH and LCD_HEIGHT for both source and target dimensions + gdispGBlitArea(GDISP, 0, 0, LCD_WIDTH, LCD_HEIGHT, 0, 0, LCD_WIDTH, (pixel_t*)resource_lcd_logo); return false; } diff --git a/quantum/visualizer/led_keyframes.c b/quantum/visualizer/led_backlight_keyframes.c index 7e6e5d1ab..eb3f5561d 100644 --- a/quantum/visualizer/led_keyframes.c +++ b/quantum/visualizer/led_backlight_keyframes.c @@ -23,7 +23,7 @@ SOFTWARE. */ #include "gfx.h" #include "math.h" -#include "led_keyframes.h" +#include "led_backlight_keyframes.h" static uint8_t fade_led_color(keyframe_animation_t* animation, int from, int to) { int frame_length = animation->frame_lengths[animation->current_frame]; @@ -41,8 +41,8 @@ static void keyframe_fade_all_leds_from_to(keyframe_animation_t* animation, uint } // TODO: Should be customizable per keyboard -#define NUM_ROWS LED_NUM_ROWS -#define NUM_COLS LED_NUM_COLS +#define NUM_ROWS LED_HEIGHT +#define NUM_COLS LED_WIDTH static uint8_t crossfade_start_frame[NUM_ROWS][NUM_COLS]; static uint8_t crossfade_end_frame[NUM_ROWS][NUM_COLS]; @@ -55,19 +55,19 @@ static uint8_t compute_gradient_color(float t, float index, float num) { return (uint8_t)(255.0f * v); } -bool led_keyframe_fade_in_all(keyframe_animation_t* animation, visualizer_state_t* state) { +bool led_backlight_keyframe_fade_in_all(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; keyframe_fade_all_leds_from_to(animation, 0, 255); return true; } -bool led_keyframe_fade_out_all(keyframe_animation_t* animation, visualizer_state_t* state) { +bool led_backlight_keyframe_fade_out_all(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; keyframe_fade_all_leds_from_to(animation, 255, 0); return true; } -bool led_keyframe_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state) { +bool led_backlight_keyframe_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; float frame_length = animation->frame_lengths[animation->current_frame]; float current_pos = frame_length - animation->time_left_in_frame; @@ -79,7 +79,7 @@ bool led_keyframe_left_to_right_gradient(keyframe_animation_t* animation, visual return true; } -bool led_keyframe_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state) { +bool led_backlight_keyframe_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; float frame_length = animation->frame_lengths[animation->current_frame]; float current_pos = frame_length - animation->time_left_in_frame; @@ -98,7 +98,7 @@ static void copy_current_led_state(uint8_t* dest) { } } } -bool led_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t* state) { +bool led_backlight_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; if (animation->first_update_of_frame) { copy_current_led_state(&crossfade_start_frame[0][0]); @@ -114,28 +114,28 @@ bool led_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t* return true; } -bool led_keyframe_mirror_orientation(keyframe_animation_t* animation, visualizer_state_t* state) { +bool led_backlight_keyframe_mirror_orientation(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; (void)animation; gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_180); return false; } -bool led_keyframe_normal_orientation(keyframe_animation_t* animation, visualizer_state_t* state) { +bool led_backlight_keyframe_normal_orientation(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; (void)animation; gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_0); return false; } -bool led_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { +bool led_backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; (void)animation; gdispGSetPowerMode(LED_DISPLAY, powerOff); return false; } -bool led_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { +bool led_backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; (void)animation; gdispGSetPowerMode(LED_DISPLAY, powerOn); diff --git a/quantum/visualizer/led_keyframes.h b/quantum/visualizer/led_backlight_keyframes.h index a59a4f37d..487151013 100644 --- a/quantum/visualizer/led_keyframes.h +++ b/quantum/visualizer/led_backlight_keyframes.h @@ -22,21 +22,21 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef LED_KEYFRAMES_H -#define LED_KEYFRAMES_H +#ifndef LED_BACKLIGHT_KEYFRAMES_H +#define LED_BACKLIGHT_KEYFRAMES_H #include "visualizer.h" -bool led_keyframe_fade_in_all(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_keyframe_fade_out_all(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_keyframe_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_keyframe_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_keyframe_mirror_orientation(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_keyframe_normal_orientation(keyframe_animation_t* animation, visualizer_state_t* state); +bool led_backlight_keyframe_fade_in_all(keyframe_animation_t* animation, visualizer_state_t* state); +bool led_backlight_keyframe_fade_out_all(keyframe_animation_t* animation, visualizer_state_t* state); +bool led_backlight_keyframe_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state); +bool led_backlight_keyframe_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state); +bool led_backlight_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t* state); +bool led_backlight_keyframe_mirror_orientation(keyframe_animation_t* animation, visualizer_state_t* state); +bool led_backlight_keyframe_normal_orientation(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state); +bool led_backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state); +bool led_backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state); extern keyframe_animation_t led_test_animation; diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index cc99d1e3b..5b4d8d603 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -52,7 +52,8 @@ SOFTWARE. // Define this in config.h #ifndef VISUALIZER_THREAD_PRIORITY -#define "Visualizer thread priority not defined" +// The visualizer needs gfx thread priorities +#define VISUALIZER_THREAD_PRIORITY (NORMAL_PRIORITY - 2) #endif static visualizer_keyboard_status_t current_status = { @@ -255,6 +256,9 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { .mods = 0xFF, .leds = 0xFFFFFFFF, .suspended = false, + #ifdef BACKLIGHT_ENABLE + .backlight_level = 0, + #endif #ifdef VISUALIZER_USER_DATA_SIZE .user_data = {0}, #endif @@ -299,6 +303,7 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { else { gdispGSetPowerMode(LED_DISPLAY, powerOff); } + state.status.backlight_level = current_status.backlight_level; } #endif if (visualizer_enabled) { diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index 0f7d8636c..102d23b7e 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -20,6 +20,30 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +define ADD_DRIVER + $(1)_DRIVER:=$(strip $($(1)_DRIVER)) + $(1)_WIDTH:=$(strip $($(1)_WIDTH)) + $(1)_HEIGHT:=$(strip $($(1)_HEIGHT)) + ifeq ($($(1)_DRIVER),) + $$(error $(1)_DRIVER is not defined) + endif + ifeq ($($(1)_WIDTH),) + $$(error $(1)_WIDTH is not defined) + endif + ifeq ($($(1)_HEIGHT),) + $$(error $(1)_HEIGHT is not defined) + endif + OPT_DEFS+=-D$(1)_WIDTH=$($(1)_WIDTH) + OPT_DEFS+=-D$(1)_HEIGHT=$($(1)_HEIGHT) + GFXDEFS+=-D$(1)_WIDTH=$($(1)_WIDTH) + GFXDEFS+=-D$(1)_HEIGHT=$($(1)_HEIGHT) + $(1)_DISPLAY_NUMBER:=$$(words $$(GDISP_DRIVER_LIST)) + OPT_DEFS+=-D$(1)_DISPLAY_NUMBER=$$($(1)_DISPLAY_NUMBER) + include $(TOP_DIR)/drivers/ugfx/gdisp/$($(1)_DRIVER)/driver.mk +endef + +GDISP_DRIVER_LIST:= + SRC += $(VISUALIZER_DIR)/visualizer.c \ $(VISUALIZER_DIR)/visualizer_keyframes.c EXTRAINCDIRS += $(GFXINC) $(VISUALIZER_DIR) @@ -40,16 +64,32 @@ SRC += $(VISUALIZER_DIR)/lcd_backlight_keyframes.c # Note, that the linker will strip out any resources that are not actually in use SRC += $(VISUALIZER_DIR)/resources/lcd_logo.c OPT_DEFS += -DLCD_BACKLIGHT_ENABLE +$(eval $(call ADD_DRIVER,LCD)) endif ifeq ($(strip $(BACKLIGHT_ENABLE)), yes) -SRC += $(VISUALIZER_DIR)/led_keyframes.c +SRC += $(VISUALIZER_DIR)/led_backlight_keyframes.c +$(eval $(call ADD_DRIVER,LED)) endif +SRC += $(VISUALIZER_DIR)/default_animations.c + include $(GFXLIB)/gfx.mk +# For the common_gfxconf.h +GFXINC += quantum/visualizer + GFXSRC := $(patsubst $(TOP_DIR)/%,%,$(GFXSRC)) GFXDEFS := $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) +GDISP_LIST_COMMA=, +GDISP_LIST_EMPTY= +GDISP_LIST_SPACE=$(GDISP_LIST_EMPTY) $(GDISP_LIST_EMPTY) + +GDISP_DRIVER_LIST := $(strip $(GDISP_DRIVER_LIST)) +GDISP_DRIVER_LIST := $(subst $(GDISP_LIST_SPACE),$(GDISP_LIST_COMMA),$(GDISP_DRIVER_LIST)) + +GFXDEFS +=-DGDISP_DRIVER_LIST="$(GDISP_DRIVER_LIST)" + ifneq ("$(wildcard $(KEYMAP_PATH)/visualizer.c)","") SRC += keyboards/$(KEYBOARD)/keymaps/$(KEYMAP)/visualizer.c else |