From 132c04746910f7230b63ed33717c4ed65599ed1b Mon Sep 17 00:00:00 2001 From: Rubén Díaz-Jorge Date: Sat, 2 Jul 2016 10:26:04 +0200 Subject: Fix for '~' in spanish layout --- quantum/keymap_extras/keymap_spanish.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_spanish.h b/quantum/keymap_extras/keymap_spanish.h index 512d8a374..af76e39fc 100644 --- a/quantum/keymap_extras/keymap_spanish.h +++ b/quantum/keymap_extras/keymap_spanish.h @@ -49,7 +49,7 @@ #define ES_PIPE ALGR(KC_1) #define ES_AT ALGR(KC_2) #define ES_HASH ALGR(KC_3) -#define ES_TILD ALGR(KC_4) +#define ES_TILD ALGR(ES_NTIL) #define ES_EURO ALGR(KC_5) #define ES_NOT ALGR(KC_6) @@ -59,4 +59,4 @@ #define ES_LCBR ALGR(ES_ACUT) #define ES_RCRB ALGR(ES_CCED) -#endif \ No newline at end of file +#endif -- cgit v1.3.1 From 8e88d55bfd7c88cb15845e0c6415e4e892532861 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Mon, 4 Jul 2016 11:45:58 -0400 Subject: reverts #343 for the most part (#474) --- quantum/matrix.c | 292 +++++++++++++++++++++++------------------- tmk_core/common/avr/suspend.c | 6 +- tmk_core/common/bootmagic.c | 16 ++- tmk_core/common/keyboard.c | 107 +++++++++------- tmk_core/common/matrix.h | 57 ++++----- 5 files changed, 261 insertions(+), 217 deletions(-) (limited to 'quantum') diff --git a/quantum/matrix.c b/quantum/matrix.c index a38c13f15..094917025 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -26,32 +26,46 @@ along with this program. If not, see . #include "util.h" #include "matrix.h" -#ifdef MATRIX_HAS_GHOST -# error "The universal matrix.c file cannot be used for this keyboard." -#endif +/* Set 0 if debouncing isn't needed */ +/* + * This constant define not debouncing time in msecs, but amount of matrix + * scan loops which should be made to get stable debounced results. + * + * On Ergodox matrix scan rate is relatively low, because of slow I2C. + * Now it's only 317 scans/second, or about 3.15 msec/scan. + * According to Cherry specs, debouncing time is 5 msec. + * + * And so, there is no sense to have DEBOUNCE higher than 2. + */ #ifndef DEBOUNCING_DELAY # define DEBOUNCING_DELAY 5 #endif +static uint8_t debouncing = DEBOUNCING_DELAY; static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; -/* matrix state */ -#if DIODE_DIRECTION == COL2ROW + +/* matrix state(1:on, 0:off) */ static matrix_row_t matrix[MATRIX_ROWS]; -#else -static matrix_col_t matrix[MATRIX_COLS]; +static matrix_row_t matrix_debouncing[MATRIX_ROWS]; + +#if DIODE_DIRECTION == ROW2COL + static matrix_row_t matrix_reversed[MATRIX_COLS]; + static matrix_row_t matrix_reversed_debouncing[MATRIX_COLS]; #endif -static int8_t debouncing_delay = -1; -#if DIODE_DIRECTION == COL2ROW -static void toggle_row(uint8_t row); -static matrix_row_t read_cols(void); +#if MATRIX_COLS > 16 + #define SHIFTER 1UL #else -static void toggle_col(uint8_t col); -static matrix_col_t read_rows(void); + #define SHIFTER 1 #endif +static matrix_row_t read_cols(void); +static void init_cols(void); +static void unselect_rows(void); +static void select_row(uint8_t row); + __attribute__ ((weak)) void matrix_init_quantum(void) { matrix_init_kb(); @@ -80,10 +94,12 @@ __attribute__ ((weak)) void matrix_scan_user(void) { } +inline uint8_t matrix_rows(void) { return MATRIX_ROWS; } +inline uint8_t matrix_cols(void) { return MATRIX_COLS; } @@ -113,161 +129,179 @@ uint8_t matrix_cols(void) { // } void matrix_init(void) { - /* frees PORTF by setting the JTD bit twice within four cycles */ + // To use PORTF disable JTAG with writing JTD bit twice within four cycles. #ifdef __AVR_ATmega32U4__ MCUCR |= _BV(JTD); MCUCR |= _BV(JTD); #endif - /* initializes the I/O pins */ -#if DIODE_DIRECTION == COL2ROW - for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { - /* DDRxn */ - _SFR_IO8((row_pins[r] >> 4) + 1) |= _BV(row_pins[r] & 0xF); - toggle_row(r); - } - for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { - /* PORTxn */ - _SFR_IO8((col_pins[c] >> 4) + 2) |= _BV(col_pins[c] & 0xF); - } -#else - for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { - /* DDRxn */ - _SFR_IO8((col_pins[c] >> 4) + 1) |= _BV(col_pins[c] & 0xF); - toggle_col(c); - } - for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { - /* PORTxn */ - _SFR_IO8((row_pins[r] >> 4) + 2) |= _BV(row_pins[r] & 0xF); + + // initialize row and col + unselect_rows(); + init_cols(); + + // initialize matrix state: all keys off + for (uint8_t i=0; i < MATRIX_ROWS; i++) { + matrix[i] = 0; + matrix_debouncing[i] = 0; } -#endif + matrix_init_quantum(); } +uint8_t matrix_scan(void) +{ + #if DIODE_DIRECTION == COL2ROW -uint8_t matrix_scan(void) { - static matrix_row_t debouncing_matrix[MATRIX_ROWS]; - for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { - toggle_row(r); - matrix_row_t state = read_cols(); - if (debouncing_matrix[r] != state) { - debouncing_matrix[r] = state; - debouncing_delay = DEBOUNCING_DELAY; - } - toggle_row(r); - } - if (debouncing_delay >= 0) { - dprintf("Debouncing delay remaining: %X\n", debouncing_delay); - --debouncing_delay; - if (debouncing_delay >= 0) { - wait_ms(1); - } - else { - for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { - matrix[r] = debouncing_matrix[r]; + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + select_row(i); + wait_us(30); // without this wait read unstable value. + matrix_row_t cols = read_cols(); + if (matrix_debouncing[i] != cols) { + matrix_debouncing[i] = cols; + if (debouncing) { + debug("bounce!: "); debug_hex(debouncing); debug("\n"); } + debouncing = DEBOUNCING_DELAY; } + unselect_rows(); } - matrix_scan_quantum(); - return 1; -} - -static void toggle_row(uint8_t row) { - /* PINxn */ - _SFR_IO8((row_pins[row] >> 4)) = _BV(row_pins[row] & 0xF); -} -static matrix_row_t read_cols(void) { - matrix_row_t state = 0; - for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { - /* PINxn */ - if (!(_SFR_IO8((col_pins[c] >> 4)) & _BV(col_pins[c] & 0xF))) { - state |= (matrix_row_t)1 << c; + if (debouncing) { + if (--debouncing) { + wait_us(1); + } else { + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + matrix[i] = matrix_debouncing[i]; + } } } - return state; -} - -matrix_row_t matrix_get_row(uint8_t row) { - return matrix[row]; -} - #else -uint8_t matrix_scan(void) { - static matrix_col_t debouncing_matrix[MATRIX_COLS]; - for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { - toggle_col(c); - matrix_col_t state = read_rows(); - if (debouncing_matrix[c] != state) { - debouncing_matrix[c] = state; - debouncing_delay = DEBOUNCING_DELAY; + for (uint8_t i = 0; i < MATRIX_COLS; i++) { + select_row(i); + wait_us(30); // without this wait read unstable value. + matrix_row_t rows = read_cols(); + if (matrix_reversed_debouncing[i] != rows) { + matrix_reversed_debouncing[i] = rows; + if (debouncing) { + debug("bounce!: "); debug_hex(debouncing); debug("\n"); + } + debouncing = DEBOUNCING_DELAY; } - toggle_col(c); + unselect_rows(); } - if (debouncing_delay >= 0) { - dprintf("Debouncing delay remaining: %X\n", debouncing_delay); - --debouncing_delay; - if (debouncing_delay >= 0) { - wait_ms(1); - } - else { - for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { - matrix[c] = debouncing_matrix[c]; + + if (debouncing) { + if (--debouncing) { + wait_us(1); + } else { + for (uint8_t i = 0; i < MATRIX_COLS; i++) { + matrix_reversed[i] = matrix_reversed_debouncing[i]; } } } + for (uint8_t y = 0; y < MATRIX_ROWS; y++) { + matrix_row_t row = 0; + for (uint8_t x = 0; x < MATRIX_COLS; x++) { + row |= ((matrix_reversed[x] & (1<> y) << x; + } + matrix[y] = row; + } +#endif + matrix_scan_quantum(); + return 1; } -static void toggle_col(uint8_t col) { - /* PINxn */ - _SFR_IO8((col_pins[col] >> 4)) = _BV(col_pins[col] & 0xF); +bool matrix_is_modified(void) +{ + if (debouncing) return false; + return true; } -static matrix_col_t read_rows(void) { - matrix_col_t state = 0; - for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { - /* PINxn */ - if (!(_SFR_IO8((row_pins[r] >> 4)) & _BV(row_pins[r] & 0xF))) { - state |= (matrix_col_t)1 << r; - } +inline +bool matrix_is_on(uint8_t row, uint8_t col) +{ + return (matrix[row] & ((matrix_row_t)1= 0; --c) { - if (matrix[c] & mask) { - state |= (matrix_row_t)1 << c; - } +uint8_t matrix_key_count(void) +{ + uint8_t count = 0; + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + count += bitpop16(matrix[i]); } - return state; + return count; } +static void init_cols(void) +{ +#if DIODE_DIRECTION == COL2ROW + for(int x = 0; x < MATRIX_COLS; x++) { + int pin = col_pins[x]; +#else + for(int x = 0; x < MATRIX_ROWS; x++) { + int pin = row_pins[x]; #endif - -bool matrix_is_modified(void) { - if (debouncing_delay >= 0) return false; - return true; + _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); + _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); + } } -bool matrix_is_on(uint8_t row, uint8_t col) { - return matrix_get_row(row) & (matrix_row_t)1 << col; -} +static matrix_row_t read_cols(void) +{ + matrix_row_t result = 0; -void matrix_print(void) { - dprintln("Human-readable matrix state:"); - for (uint8_t r = 0; r < MATRIX_ROWS; r++) { - dprintf("State of row %X: %016b\n", r, bitrev16(matrix_get_row(r))); +#if DIODE_DIRECTION == COL2ROW + for(int x = 0; x < MATRIX_COLS; x++) { + int pin = col_pins[x]; +#else + for(int x = 0; x < MATRIX_ROWS; x++) { + int pin = row_pins[x]; +#endif + result |= (_SFR_IO8(pin >> 4) & _BV(pin & 0xF)) ? 0 : (SHIFTER << x); } + return result; } -uint8_t matrix_key_count(void) { - uint8_t count = 0; - for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { - count += bitpop16(matrix_get_row(r)); +static void unselect_rows(void) +{ +#if DIODE_DIRECTION == COL2ROW + for(int x = 0; x < MATRIX_ROWS; x++) { + int pin = row_pins[x]; +#else + for(int x = 0; x < MATRIX_COLS; x++) { + int pin = col_pins[x]; +#endif + _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); + _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); } - return count; +} + +static void select_row(uint8_t row) +{ + +#if DIODE_DIRECTION == COL2ROW + int pin = row_pins[row]; +#else + int pin = col_pins[row]; +#endif + _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); + _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); } diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c index a6f3c6441..8a7272bbc 100644 --- a/tmk_core/common/avr/suspend.c +++ b/tmk_core/common/avr/suspend.c @@ -114,8 +114,10 @@ bool suspend_wakeup_condition(void) matrix_power_up(); matrix_scan(); matrix_power_down(); - if (matrix_key_count()) return true; - return false; + for (uint8_t r = 0; r < MATRIX_ROWS; r++) { + if (matrix_get_row(r)) return true; + } + return false; } // run immediately after wakeup diff --git a/tmk_core/common/bootmagic.c b/tmk_core/common/bootmagic.c index 90275a18b..6730a2a4a 100644 --- a/tmk_core/common/bootmagic.c +++ b/tmk_core/common/bootmagic.c @@ -106,13 +106,15 @@ void bootmagic(void) } } -static bool scan_keycode(uint8_t keycode) { - for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { +static bool scan_keycode(uint8_t keycode) +{ + for (uint8_t r = 0; r < MATRIX_ROWS; r++) { matrix_row_t matrix_row = matrix_get_row(r); - for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { - if (matrix_row & (matrix_row_t)1 << c) { - keypos_t key = (keypos_t){ .row = r, .col = c }; - if (keycode == keymap_key_to_keycode(0, key)) return true; + for (uint8_t c = 0; c < MATRIX_COLS; c++) { + if (matrix_row & ((matrix_row_t)1<. #endif #ifdef MATRIX_HAS_GHOST -static bool is_row_ghosting(uint8_t row){ - matrix_row_t state = matrix_get_row(row); - /* no ghosting happens when only one key in the row is pressed */ - if (!(state - 1 & state)) return false; - /* ghosting occurs when two keys in the same column are pressed */ - for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { - if (r != row && matrix_get_row(r) & state) return true; +static bool has_ghost_in_row(uint8_t row) +{ + matrix_row_t matrix_row = matrix_get_row(row); + // No ghost exists when less than 2 keys are down on the row + if (((matrix_row - 1) & matrix_row) == 0) + return false; + + // Ghost occurs when the row shares column line with other row + for (uint8_t i=0; i < MATRIX_ROWS; i++) { + if (i != row && (matrix_get_row(i) & matrix_row)) + return true; } return false; } - #endif __attribute__ ((weak)) @@ -100,72 +103,86 @@ void keyboard_init(void) { #endif } -/* does routine keyboard jobs */ -void keyboard_task(void) { - static uint8_t led_status; +/* + * Do keyboard routine jobs: scan mantrix, light LEDs, ... + * This is repeatedly called as fast as possible. + */ +void keyboard_task(void) +{ + static matrix_row_t matrix_prev[MATRIX_ROWS]; +#ifdef MATRIX_HAS_GHOST + static matrix_row_t matrix_ghost[MATRIX_ROWS]; +#endif + static uint8_t led_status = 0; + matrix_row_t matrix_row = 0; + matrix_row_t matrix_change = 0; + matrix_scan(); - for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { - static matrix_row_t previous_matrix[MATRIX_ROWS]; - matrix_row_t state = matrix_get_row(r); - matrix_row_t changes = state ^ previous_matrix[r]; - if (changes) { + for (uint8_t r = 0; r < MATRIX_ROWS; r++) { + matrix_row = matrix_get_row(r); + matrix_change = matrix_row ^ matrix_prev[r]; + if (matrix_change) { #ifdef MATRIX_HAS_GHOST - static matrix_row_t deghosting_matrix[MATRIX_ROWS]; - if (is_row_ghosting(r)) { - /* debugs the deghosting mechanism */ - /* doesn't update previous_matrix until the ghosting has stopped - * in order to prevent the last key from being lost + if (has_ghost_in_row(r)) { + /* Keep track of whether ghosted status has changed for + * debugging. But don't update matrix_prev until un-ghosted, or + * the last key would be lost. */ - if (debug_matrix && deghosting_matrix[r] != state) { + if (debug_matrix && matrix_ghost[r] != matrix_row) { matrix_print(); } - deghosting_matrix[r] = state; + matrix_ghost[r] = matrix_row; continue; } - deghosting_matrix[r] = state; + matrix_ghost[r] = matrix_row; #endif if (debug_matrix) matrix_print(); - for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { - matrix_row_t mask = (matrix_row_t)1 << c; - if (changes & mask) { - keyevent_t event; - event.key = (keypos_t){ .row = r, .col = c }; - event.pressed = state & mask; - /* the time should not be 0 */ - event.time = timer_read() | 1; - action_exec(event); - /* records the processed key event */ - previous_matrix[r] ^= mask; - /* processes one key event per call */ - goto event_processed; + for (uint8_t c = 0; c < MATRIX_COLS; c++) { + if (matrix_change & ((matrix_row_t)1<. #include #include -#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; + +#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 "There are too many columns." +#error "MATRIX_COLS: invalid value" #endif -#if DIODE_DIRECTION == ROW2COL -# if MATRIX_ROWS <= 8 -typedef uint8_t matrix_col_t; -# elif MATRIX_ROWS <= 16 -typedef uint16_t matrix_col_t; -# elif MATRIX_ROWS <= 32 -typedef uint32_t matrix_col_t; -# else -# error "There are too many rows." -# endif -#endif +#define MATRIX_IS_ON(row, col) (matrix_get_row(row) && (1< Date: Mon, 4 Jul 2016 19:56:08 -0700 Subject: Allow Space Cadet state to be canceled by alternate Shift key Allows you to press RSHIFT to cancel the insertion of a "(" when holding down LSHIFT. Alternatively, allows you to press LSHIFT to cancel the insertion of a ")" when holding down RSHIFT. This change enables you to renege from outputting a character should you press a shift key erroneously. --- quantum/quantum.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index d59bd5a3f..65290338d 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -162,6 +162,10 @@ bool process_record_quantum(keyrecord_t *record) { register_mods(MOD_BIT(KC_LSFT)); } else { + if (get_mods() & MOD_BIT(KC_RSFT)) { + shift_interrupted[0] = true; + shift_interrupted[1] = true; + } if (!shift_interrupted[0]) { register_code(LSPO_KEY); unregister_code(LSPO_KEY); @@ -178,6 +182,10 @@ bool process_record_quantum(keyrecord_t *record) { register_mods(MOD_BIT(KC_RSFT)); } else { + if (get_mods() & MOD_BIT(KC_LSFT)) { + shift_interrupted[0] = true; + shift_interrupted[1] = true; + } if (!shift_interrupted[1]) { register_code(RSPC_KEY); unregister_code(RSPC_KEY); -- cgit v1.3.1 From 6b0c9cc905c0985f96a80306cf5fe0d6724b28fc Mon Sep 17 00:00:00 2001 From: Smilliam Date: Mon, 4 Jul 2016 19:58:26 -0700 Subject: fixed indentation. --- quantum/quantum.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index 65290338d..71c3c723b 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -162,10 +162,10 @@ bool process_record_quantum(keyrecord_t *record) { register_mods(MOD_BIT(KC_LSFT)); } else { - if (get_mods() & MOD_BIT(KC_RSFT)) { - shift_interrupted[0] = true; - shift_interrupted[1] = true; - } + if (get_mods() & MOD_BIT(KC_RSFT)) { + shift_interrupted[0] = true; + shift_interrupted[1] = true; + } if (!shift_interrupted[0]) { register_code(LSPO_KEY); unregister_code(LSPO_KEY); @@ -182,10 +182,10 @@ bool process_record_quantum(keyrecord_t *record) { register_mods(MOD_BIT(KC_RSFT)); } else { - if (get_mods() & MOD_BIT(KC_LSFT)) { - shift_interrupted[0] = true; - shift_interrupted[1] = true; - } + if (get_mods() & MOD_BIT(KC_LSFT)) { + shift_interrupted[0] = true; + shift_interrupted[1] = true; + } if (!shift_interrupted[1]) { register_code(RSPC_KEY); unregister_code(RSPC_KEY); -- cgit v1.3.1 From 3577e26fd9916ceab58779ec6323d43da54eb3b5 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 6 Jul 2016 00:24:31 -0400 Subject: fix/annotate wait_us lines --- keyboards/ergodox_ez/matrix.c | 12 ++++++++++++ quantum/matrix.c | 14 ++------------ 2 files changed, 14 insertions(+), 12 deletions(-) (limited to 'quantum') diff --git a/keyboards/ergodox_ez/matrix.c b/keyboards/ergodox_ez/matrix.c index 9c1efa1d0..dc29cf5cd 100644 --- a/keyboards/ergodox_ez/matrix.c +++ b/keyboards/ergodox_ez/matrix.c @@ -39,6 +39,17 @@ along with this program. If not, see . #include "timer.h" #endif +/* + * This constant define not debouncing time in msecs, but amount of matrix + * scan loops which should be made to get stable debounced results. + * + * On Ergodox matrix scan rate is relatively low, because of slow I2C. + * Now it's only 317 scans/second, or about 3.15 msec/scan. + * According to Cherry specs, debouncing time is 5 msec. + * + * And so, there is no sense to have DEBOUNCE higher than 2. + */ + #ifndef DEBOUNCE # define DEBOUNCE 5 #endif @@ -181,6 +192,7 @@ uint8_t matrix_scan(void) if (debouncing) { if (--debouncing) { wait_us(1); + // this should be wait_ms(1) but has been left as-is at EZ's request } else { for (uint8_t i = 0; i < MATRIX_ROWS; i++) { matrix[i] = matrix_debouncing[i]; diff --git a/quantum/matrix.c b/quantum/matrix.c index 094917025..3174e0739 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -27,16 +27,6 @@ along with this program. If not, see . #include "matrix.h" /* Set 0 if debouncing isn't needed */ -/* - * This constant define not debouncing time in msecs, but amount of matrix - * scan loops which should be made to get stable debounced results. - * - * On Ergodox matrix scan rate is relatively low, because of slow I2C. - * Now it's only 317 scans/second, or about 3.15 msec/scan. - * According to Cherry specs, debouncing time is 5 msec. - * - * And so, there is no sense to have DEBOUNCE higher than 2. - */ #ifndef DEBOUNCING_DELAY # define DEBOUNCING_DELAY 5 @@ -168,7 +158,7 @@ uint8_t matrix_scan(void) if (debouncing) { if (--debouncing) { - wait_us(1); + wait_ms(1); } else { for (uint8_t i = 0; i < MATRIX_ROWS; i++) { matrix[i] = matrix_debouncing[i]; @@ -192,7 +182,7 @@ uint8_t matrix_scan(void) if (debouncing) { if (--debouncing) { - wait_us(1); + wait_ms(1); } else { for (uint8_t i = 0; i < MATRIX_COLS; i++) { matrix_reversed[i] = matrix_reversed_debouncing[i]; -- cgit v1.3.1 From 3ac52b2e7623152f177670549b780492a0447c12 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Wed, 6 Jul 2016 13:09:51 +0300 Subject: Remove serial_link .gitignore and .gitmodules --- quantum/serial_link/.gitignore | 1 - quantum/serial_link/.gitmodules | 3 --- 2 files changed, 4 deletions(-) delete mode 100644 quantum/serial_link/.gitignore delete mode 100644 quantum/serial_link/.gitmodules (limited to 'quantum') diff --git a/quantum/serial_link/.gitignore b/quantum/serial_link/.gitignore deleted file mode 100644 index 2d68e206e..000000000 --- a/quantum/serial_link/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.stackdump diff --git a/quantum/serial_link/.gitmodules b/quantum/serial_link/.gitmodules deleted file mode 100644 index 991cfe96d..000000000 --- a/quantum/serial_link/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "cgreen/cgreen"] - path = cgreen/cgreen - url = http://github.com/cgreen-devs/cgreen -- cgit v1.3.1 From c5bf090d16cf1fc4d8186f1e8fbbd62457e72da6 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Wed, 6 Jul 2016 13:10:30 +0300 Subject: Remove CGreen make files --- quantum/serial_link/cgreen/Makefile | 38 ------------------------------- quantum/serial_link/cgreen/Makefile.build | 33 --------------------------- quantum/serial_link/cgreen/cgreen | 1 - 3 files changed, 72 deletions(-) delete mode 100644 quantum/serial_link/cgreen/Makefile delete mode 100644 quantum/serial_link/cgreen/Makefile.build delete mode 160000 quantum/serial_link/cgreen/cgreen (limited to 'quantum') diff --git a/quantum/serial_link/cgreen/Makefile b/quantum/serial_link/cgreen/Makefile deleted file mode 100644 index 6b31a3f92..000000000 --- a/quantum/serial_link/cgreen/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# This Makefile ensures that the build is made out of source in a subdirectory called 'build' -# If it doesn't exist, it is created and a Makefile created there (from Makefile.build) -# -# This Makefile also contains delegation of the most common make commands -# -# If you have cmake installed you should be able to do: -# -# make -# make test -# make install -# make package -# -# That should build cgreen for C and C++, run some tests, install it locally and -# generate two distributable packages. - -all: build - cd $(CGREEN_BUILD_DIR); make all - -test: build - cd $(CGREEN_BUILD_DIR); make test - -clean: build - cd $(CGREEN_BUILD_DIR); make clean - -package: build - cd $(CGREEN_BUILD_DIR); make package - -install: - cd $(CGREEN_BUILD_DIR); make install - -############# Internal - -build: - mkdir -p $(CGREEN_BUILD_DIR) - cp Makefile.build $(CGREEN_BUILD_DIR)/Makefile - - -.SILENT: diff --git a/quantum/serial_link/cgreen/Makefile.build b/quantum/serial_link/cgreen/Makefile.build deleted file mode 100644 index f76165244..000000000 --- a/quantum/serial_link/cgreen/Makefile.build +++ /dev/null @@ -1,33 +0,0 @@ -# This Makefile is copied from the cgreen top directory (where it is -# named Makefile.build) and put in a subdirectory called 'build' where -# builds are made This Makefile then automatically creates -# subdirectories for C and C++ builds configuring them using the cmake -# command. Once created you can always tweak the cmake setup as with -# any cmake build directory - -all: build-c build-c++ - for d in build-* ; do cd $$d; make ; cd .. ; done - -clean: - for d in build-* ; do cd $$d; make clean ; cd .. ; done - -check test: - for d in build-* ; do cd $$d; make check ; cd .. ; done - -package: - for d in build-* ; do cd $$d; make package ; cd .. ; done - -install: - for d in build-* ; do cd $$d; make install ; cd .. ; done - -############ Internal - -build-c: - mkdir build-c - cd build-c; cmake -G "Unix Makefiles" $(CGREEN_DIR) - -build-c++: - mkdir build-c++ - cd build-c++; cmake -G "Unix Makefiles" -DWITH_CXX:bool=ON $(CGREEN_DIR) - -.SILENT: diff --git a/quantum/serial_link/cgreen/cgreen b/quantum/serial_link/cgreen/cgreen deleted file mode 160000 index d4d438dda..000000000 --- a/quantum/serial_link/cgreen/cgreen +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d4d438dda1b7131f0bd0530b2c258e9dea6a2a9f -- cgit v1.3.1 From d5e7603d551a31836bf0c59db259ddc3593a1aa7 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Wed, 6 Jul 2016 13:26:20 +0300 Subject: Remove extra serial_link subdirectory --- quantum/serial_link/README.md | 2 +- quantum/serial_link/protocol/byte_stuffer.c | 145 ++++++ quantum/serial_link/protocol/byte_stuffer.h | 34 ++ quantum/serial_link/protocol/frame_router.c | 69 +++ quantum/serial_link/protocol/frame_router.h | 38 ++ quantum/serial_link/protocol/frame_validator.c | 121 +++++ quantum/serial_link/protocol/frame_validator.h | 34 ++ quantum/serial_link/protocol/physical.h | 30 ++ quantum/serial_link/protocol/transport.c | 124 +++++ quantum/serial_link/protocol/transport.h | 151 ++++++ .../serial_link/protocol/triple_buffered_object.c | 78 ++++ .../serial_link/protocol/triple_buffered_object.h | 51 +++ quantum/serial_link/serial_link.mk | 27 -- .../serial_link/protocol/byte_stuffer.c | 145 ------ .../serial_link/protocol/byte_stuffer.h | 34 -- .../serial_link/protocol/frame_router.c | 69 --- .../serial_link/protocol/frame_router.h | 38 -- .../serial_link/protocol/frame_validator.c | 121 ----- .../serial_link/protocol/frame_validator.h | 34 -- .../serial_link/serial_link/protocol/physical.h | 30 -- .../serial_link/serial_link/protocol/transport.c | 124 ----- .../serial_link/serial_link/protocol/transport.h | 151 ------ .../serial_link/protocol/triple_buffered_object.c | 78 ---- .../serial_link/protocol/triple_buffered_object.h | 51 --- .../serial_link/serial_link/system/serial_link.c | 265 ----------- .../serial_link/serial_link/system/serial_link.h | 63 --- quantum/serial_link/serial_link/tests/Makefile | 61 --- .../serial_link/tests/byte_stuffer_tests.c | 506 --------------------- .../serial_link/tests/frame_router_tests.c | 231 ---------- .../serial_link/tests/frame_validator_tests.c | 101 ---- .../serial_link/tests/transport_tests.c | 168 ------- .../tests/triple_buffered_object_tests.c | 82 ---- quantum/serial_link/serial_link_tests.mk | 34 -- quantum/serial_link/system/serial_link.c | 265 +++++++++++ quantum/serial_link/system/serial_link.h | 63 +++ quantum/serial_link/tests/Makefile | 61 +++ quantum/serial_link/tests/byte_stuffer_tests.c | 506 +++++++++++++++++++++ quantum/serial_link/tests/frame_router_tests.c | 231 ++++++++++ quantum/serial_link/tests/frame_validator_tests.c | 101 ++++ quantum/serial_link/tests/transport_tests.c | 168 +++++++ .../tests/triple_buffered_object_tests.c | 82 ++++ 41 files changed, 2353 insertions(+), 2414 deletions(-) create mode 100644 quantum/serial_link/protocol/byte_stuffer.c create mode 100644 quantum/serial_link/protocol/byte_stuffer.h create mode 100644 quantum/serial_link/protocol/frame_router.c create mode 100644 quantum/serial_link/protocol/frame_router.h create mode 100644 quantum/serial_link/protocol/frame_validator.c create mode 100644 quantum/serial_link/protocol/frame_validator.h create mode 100644 quantum/serial_link/protocol/physical.h create mode 100644 quantum/serial_link/protocol/transport.c create mode 100644 quantum/serial_link/protocol/transport.h create mode 100644 quantum/serial_link/protocol/triple_buffered_object.c create mode 100644 quantum/serial_link/protocol/triple_buffered_object.h delete mode 100644 quantum/serial_link/serial_link.mk delete mode 100644 quantum/serial_link/serial_link/protocol/byte_stuffer.c delete mode 100644 quantum/serial_link/serial_link/protocol/byte_stuffer.h delete mode 100644 quantum/serial_link/serial_link/protocol/frame_router.c delete mode 100644 quantum/serial_link/serial_link/protocol/frame_router.h delete mode 100644 quantum/serial_link/serial_link/protocol/frame_validator.c delete mode 100644 quantum/serial_link/serial_link/protocol/frame_validator.h delete mode 100644 quantum/serial_link/serial_link/protocol/physical.h delete mode 100644 quantum/serial_link/serial_link/protocol/transport.c delete mode 100644 quantum/serial_link/serial_link/protocol/transport.h delete mode 100644 quantum/serial_link/serial_link/protocol/triple_buffered_object.c delete mode 100644 quantum/serial_link/serial_link/protocol/triple_buffered_object.h delete mode 100644 quantum/serial_link/serial_link/system/serial_link.c delete mode 100644 quantum/serial_link/serial_link/system/serial_link.h delete mode 100644 quantum/serial_link/serial_link/tests/Makefile delete mode 100644 quantum/serial_link/serial_link/tests/byte_stuffer_tests.c delete mode 100644 quantum/serial_link/serial_link/tests/frame_router_tests.c delete mode 100644 quantum/serial_link/serial_link/tests/frame_validator_tests.c delete mode 100644 quantum/serial_link/serial_link/tests/transport_tests.c delete mode 100644 quantum/serial_link/serial_link/tests/triple_buffered_object_tests.c delete mode 100644 quantum/serial_link/serial_link_tests.mk create mode 100644 quantum/serial_link/system/serial_link.c create mode 100644 quantum/serial_link/system/serial_link.h create mode 100644 quantum/serial_link/tests/Makefile create mode 100644 quantum/serial_link/tests/byte_stuffer_tests.c create mode 100644 quantum/serial_link/tests/frame_router_tests.c create mode 100644 quantum/serial_link/tests/frame_validator_tests.c create mode 100644 quantum/serial_link/tests/transport_tests.c create mode 100644 quantum/serial_link/tests/triple_buffered_object_tests.c (limited to 'quantum') diff --git a/quantum/serial_link/README.md b/quantum/serial_link/README.md index 94af9125c..e8490e290 100644 --- a/quantum/serial_link/README.md +++ b/quantum/serial_link/README.md @@ -1 +1 @@ -# tmk_serial_link \ No newline at end of file +# qmk_serial_link \ No newline at end of file diff --git a/quantum/serial_link/protocol/byte_stuffer.c b/quantum/serial_link/protocol/byte_stuffer.c new file mode 100644 index 000000000..fb4c45a8d --- /dev/null +++ b/quantum/serial_link/protocol/byte_stuffer.c @@ -0,0 +1,145 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "serial_link/protocol/byte_stuffer.h" +#include "serial_link/protocol/frame_validator.h" +#include "serial_link/protocol/physical.h" +#include + +// This implements the "Consistent overhead byte stuffing protocol" +// https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing +// http://www.stuartcheshire.org/papers/COBSforToN.pdf + +#define MAX_FRAME_SIZE 1024 +#define NUM_LINKS 2 + +typedef struct byte_stuffer_state { + uint16_t next_zero; + uint16_t data_pos; + bool long_frame; + uint8_t data[MAX_FRAME_SIZE]; +}byte_stuffer_state_t; + +static byte_stuffer_state_t states[NUM_LINKS]; + +void init_byte_stuffer_state(byte_stuffer_state_t* state) { + state->next_zero = 0; + state->data_pos = 0; + state->long_frame = false; +} + +void init_byte_stuffer(void) { + int i; + for (i=0;inext_zero == 0) { + state->next_zero = data; + state->long_frame = data == 0xFF; + state->data_pos = 0; + return; + } + + state->next_zero--; + if (data == 0) { + if (state->next_zero == 0) { + // The frame is completed + if (state->data_pos > 0) { + validator_recv_frame(link, state->data, state->data_pos); + } + } + else { + // The frame is invalid, so reset + init_byte_stuffer_state(state); + } + } + else { + if (state->data_pos == MAX_FRAME_SIZE) { + // We exceeded our maximum frame size + // therefore there's nothing else to do than reset to a new frame + state->next_zero = data; + state->long_frame = data == 0xFF; + state->data_pos = 0; + } + else if (state->next_zero == 0) { + if (state->long_frame) { + // This is part of a long frame, so continue + state->next_zero = data; + state->long_frame = data == 0xFF; + } + else { + // Special case for zeroes + state->next_zero = data; + state->data[state->data_pos++] = 0; + } + } + else { + state->data[state->data_pos++] = data; + } + } +} + +static void send_block(uint8_t link, uint8_t* start, uint8_t* end, uint8_t num_non_zero) { + send_data(link, &num_non_zero, 1); + if (end > start) { + send_data(link, start, end-start); + } +} + +void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size) { + const uint8_t zero = 0; + if (size > 0) { + uint16_t num_non_zero = 1; + uint8_t* end = data + size; + uint8_t* start = data; + while (data < end) { + if (num_non_zero == 0xFF) { + // There's more data after big non-zero block + // So send it, and start a new block + send_block(link, start, data, num_non_zero); + start = data; + num_non_zero = 1; + } + else { + if (*data == 0) { + // A zero encountered, so send the block + send_block(link, start, data, num_non_zero); + start = data + 1; + num_non_zero = 1; + } + else { + num_non_zero++; + } + ++data; + } + } + send_block(link, start, data, num_non_zero); + send_data(link, &zero, 1); + } +} diff --git a/quantum/serial_link/protocol/byte_stuffer.h b/quantum/serial_link/protocol/byte_stuffer.h new file mode 100644 index 000000000..2cc88beb4 --- /dev/null +++ b/quantum/serial_link/protocol/byte_stuffer.h @@ -0,0 +1,34 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef SERIAL_LINK_BYTE_STUFFER_H +#define SERIAL_LINK_BYTE_STUFFER_H + +#include + +void init_byte_stuffer(void); +void byte_stuffer_recv_byte(uint8_t link, uint8_t data); +void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size); + +#endif diff --git a/quantum/serial_link/protocol/frame_router.c b/quantum/serial_link/protocol/frame_router.c new file mode 100644 index 000000000..04b8c2e75 --- /dev/null +++ b/quantum/serial_link/protocol/frame_router.c @@ -0,0 +1,69 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "serial_link/protocol/frame_router.h" +#include "serial_link/protocol/transport.h" +#include "serial_link/protocol/frame_validator.h" + +static bool is_master; + +void router_set_master(bool master) { + is_master = master; +} + +void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size){ + if (is_master) { + if (link == DOWN_LINK) { + transport_recv_frame(data[size-1], data, size - 1); + } + } + else { + if (link == UP_LINK) { + if (data[size-1] & 1) { + transport_recv_frame(0, data, size - 1); + } + data[size-1] >>= 1; + validator_send_frame(DOWN_LINK, data, size); + } + else { + data[size-1]++; + validator_send_frame(UP_LINK, data, size); + } + } +} + +void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) { + if (destination == 0) { + if (!is_master) { + data[size] = 1; + validator_send_frame(UP_LINK, data, size + 1); + } + } + else { + if (is_master) { + data[size] = destination; + validator_send_frame(DOWN_LINK, data, size + 1); + } + } +} diff --git a/quantum/serial_link/protocol/frame_router.h b/quantum/serial_link/protocol/frame_router.h new file mode 100644 index 000000000..712250ff3 --- /dev/null +++ b/quantum/serial_link/protocol/frame_router.h @@ -0,0 +1,38 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef SERIAL_LINK_FRAME_ROUTER_H +#define SERIAL_LINK_FRAME_ROUTER_H + +#include +#include + +#define UP_LINK 0 +#define DOWN_LINK 1 + +void router_set_master(bool master); +void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size); +void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size); + +#endif diff --git a/quantum/serial_link/protocol/frame_validator.c b/quantum/serial_link/protocol/frame_validator.c new file mode 100644 index 000000000..474f80ee8 --- /dev/null +++ b/quantum/serial_link/protocol/frame_validator.c @@ -0,0 +1,121 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "serial_link/protocol/frame_validator.h" +#include "serial_link/protocol/frame_router.h" +#include "serial_link/protocol/byte_stuffer.h" +#include + +const uint32_t poly8_lookup[256] = +{ + 0, 0x77073096, 0xEE0E612C, 0x990951BA, + 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, + 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, + 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, + 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, + 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, + 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, + 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, + 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, + 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, + 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, + 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, + 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, + 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, + 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, + 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +}; + +static uint32_t crc32_byte(uint8_t *p, uint32_t bytelength) +{ + uint32_t crc = 0xffffffff; + while (bytelength-- !=0) crc = poly8_lookup[((uint8_t) crc ^ *(p++))] ^ (crc >> 8); + // return (~crc); also works + return (crc ^ 0xffffffff); +} + +void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size) { + if (size > 4) { + uint32_t frame_crc; + memcpy(&frame_crc, data + size -4, 4); + uint32_t expected_crc = crc32_byte(data, size - 4); + if (frame_crc == expected_crc) { + route_incoming_frame(link, data, size-4); + } + } +} + +void validator_send_frame(uint8_t link, uint8_t* data, uint16_t size) { + uint32_t crc = crc32_byte(data, size); + memcpy(data + size, &crc, 4); + byte_stuffer_send_frame(link, data, size + 4); +} diff --git a/quantum/serial_link/protocol/frame_validator.h b/quantum/serial_link/protocol/frame_validator.h new file mode 100644 index 000000000..4a910d510 --- /dev/null +++ b/quantum/serial_link/protocol/frame_validator.h @@ -0,0 +1,34 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef SERIAL_LINK_FRAME_VALIDATOR_H +#define SERIAL_LINK_FRAME_VALIDATOR_H + +#include + +void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size); +// The buffer pointed to by the data needs 4 additional bytes +void validator_send_frame(uint8_t link, uint8_t* data, uint16_t size); + +#endif diff --git a/quantum/serial_link/protocol/physical.h b/quantum/serial_link/protocol/physical.h new file mode 100644 index 000000000..425e06cdd --- /dev/null +++ b/quantum/serial_link/protocol/physical.h @@ -0,0 +1,30 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef SERIAL_LINK_PHYSICAL_H +#define SERIAL_LINK_PHYSICAL_H + +void send_data(uint8_t link, const uint8_t* data, uint16_t size); + +#endif diff --git a/quantum/serial_link/protocol/transport.c b/quantum/serial_link/protocol/transport.c new file mode 100644 index 000000000..f418d11ce --- /dev/null +++ b/quantum/serial_link/protocol/transport.c @@ -0,0 +1,124 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "serial_link/protocol/transport.h" +#include "serial_link/protocol/frame_router.h" +#include "serial_link/protocol/triple_buffered_object.h" +#include + +#define MAX_REMOTE_OBJECTS 16 +static remote_object_t* remote_objects[MAX_REMOTE_OBJECTS]; +static uint32_t num_remote_objects = 0; + +void add_remote_objects(remote_object_t** _remote_objects, uint32_t _num_remote_objects) { + unsigned int i; + for(i=0;i<_num_remote_objects;i++) { + remote_object_t* obj = _remote_objects[i]; + remote_objects[num_remote_objects++] = obj; + if (obj->object_type == MASTER_TO_ALL_SLAVES) { + triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; + triple_buffer_init(tb); + uint8_t* start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size); + tb = (triple_buffer_object_t*)start; + triple_buffer_init(tb); + } + else if(obj->object_type == MASTER_TO_SINGLE_SLAVE) { + uint8_t* start = obj->buffer; + unsigned int j; + for (j=0;jobject_size); + } + triple_buffer_object_t* tb = (triple_buffer_object_t*)start; + triple_buffer_init(tb); + } + else { + uint8_t* start = obj->buffer; + triple_buffer_object_t* tb = (triple_buffer_object_t*)start; + triple_buffer_init(tb); + start += LOCAL_OBJECT_SIZE(obj->object_size); + unsigned int j; + for (j=0;jobject_size); + } + } + } +} + +void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) { + uint8_t id = data[size-1]; + if (id < num_remote_objects) { + remote_object_t* obj = remote_objects[id]; + if (obj->object_size == size - 1) { + uint8_t* start; + if (obj->object_type == MASTER_TO_ALL_SLAVES) { + start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size); + } + else if(obj->object_type == SLAVE_TO_MASTER) { + start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size); + start += (from - 1) * REMOTE_OBJECT_SIZE(obj->object_size); + } + else { + start = obj->buffer + NUM_SLAVES * LOCAL_OBJECT_SIZE(obj->object_size); + } + triple_buffer_object_t* tb = (triple_buffer_object_t*)start; + void* ptr = triple_buffer_begin_write_internal(obj->object_size, tb); + memcpy(ptr, data, size - 1); + triple_buffer_end_write_internal(tb); + } + } +} + +void update_transport(void) { + unsigned int i; + for(i=0;iobject_type == MASTER_TO_ALL_SLAVES || obj->object_type == SLAVE_TO_MASTER) { + triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; + uint8_t* ptr = (uint8_t*)triple_buffer_read_internal(obj->object_size + LOCAL_OBJECT_EXTRA, tb); + if (ptr) { + ptr[obj->object_size] = i; + uint8_t dest = obj->object_type == MASTER_TO_ALL_SLAVES ? 0xFF : 0; + router_send_frame(dest, ptr, obj->object_size + 1); + } + } + else { + uint8_t* start = obj->buffer; + unsigned int j; + for (j=0;jobject_size + LOCAL_OBJECT_EXTRA, tb); + if (ptr) { + ptr[obj->object_size] = i; + uint8_t dest = j + 1; + router_send_frame(dest, ptr, obj->object_size + 1); + } + start += LOCAL_OBJECT_SIZE(obj->object_size); + } + } + } +} diff --git a/quantum/serial_link/protocol/transport.h b/quantum/serial_link/protocol/transport.h new file mode 100644 index 000000000..9a052d880 --- /dev/null +++ b/quantum/serial_link/protocol/transport.h @@ -0,0 +1,151 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef SERIAL_LINK_TRANSPORT_H +#define SERIAL_LINK_TRANSPORT_H + +#include "serial_link/protocol/triple_buffered_object.h" +#include "serial_link/system/serial_link.h" + +#define NUM_SLAVES 8 +#define LOCAL_OBJECT_EXTRA 16 + +// master -> slave = 1 local(target all), 1 remote object +// slave -> master = 1 local(target 0), multiple remote objects +// master -> single slave (multiple local, target id), 1 remote object +typedef enum { + MASTER_TO_ALL_SLAVES, + MASTER_TO_SINGLE_SLAVE, + SLAVE_TO_MASTER, +} remote_object_type; + +typedef struct { + remote_object_type object_type; + uint16_t object_size; + uint8_t buffer[] __attribute__((aligned(4))); +} remote_object_t; + +#define REMOTE_OBJECT_SIZE(objectsize) \ + (sizeof(triple_buffer_object_t) + objectsize * 3) +#define LOCAL_OBJECT_SIZE(objectsize) \ + (sizeof(triple_buffer_object_t) + (objectsize + LOCAL_OBJECT_EXTRA) * 3) + +#define REMOTE_OBJECT_HELPER(name, type, num_local, num_remote) \ +typedef struct { \ + remote_object_t object; \ + uint8_t buffer[ \ + num_remote * REMOTE_OBJECT_SIZE(sizeof(type)) + \ + num_local * LOCAL_OBJECT_SIZE(sizeof(type))]; \ +} remote_object_##name##_t; + +#define MASTER_TO_ALL_SLAVES_OBJECT(name, type) \ + REMOTE_OBJECT_HELPER(name, type, 1, 1) \ + remote_object_##name##_t remote_object_##name = { \ + .object = { \ + .object_type = MASTER_TO_ALL_SLAVES, \ + .object_size = sizeof(type), \ + } \ + }; \ + type* begin_write_##name(void) { \ + remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ + triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; \ + return (type*)triple_buffer_begin_write_internal(sizeof(type) + LOCAL_OBJECT_EXTRA, tb); \ + }\ + void end_write_##name(void) { \ + remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ + triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; \ + triple_buffer_end_write_internal(tb); \ + signal_data_written(); \ + }\ + type* read_##name(void) { \ + remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ + uint8_t* start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size);\ + triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ + return triple_buffer_read_internal(obj->object_size, tb); \ + } + +#define MASTER_TO_SINGLE_SLAVE_OBJECT(name, type) \ + REMOTE_OBJECT_HELPER(name, type, NUM_SLAVES, 1) \ + remote_object_##name##_t remote_object_##name = { \ + .object = { \ + .object_type = MASTER_TO_SINGLE_SLAVE, \ + .object_size = sizeof(type), \ + } \ + }; \ + type* begin_write_##name(uint8_t slave) { \ + remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ + uint8_t* start = obj->buffer;\ + start += slave * LOCAL_OBJECT_SIZE(obj->object_size); \ + triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ + return (type*)triple_buffer_begin_write_internal(sizeof(type) + LOCAL_OBJECT_EXTRA, tb); \ + }\ + void end_write_##name(uint8_t slave) { \ + remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ + uint8_t* start = obj->buffer;\ + start += slave * LOCAL_OBJECT_SIZE(obj->object_size); \ + triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ + triple_buffer_end_write_internal(tb); \ + signal_data_written(); \ + }\ + type* read_##name() { \ + remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ + uint8_t* start = obj->buffer + NUM_SLAVES * LOCAL_OBJECT_SIZE(obj->object_size);\ + triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ + return triple_buffer_read_internal(obj->object_size, tb); \ + } + +#define SLAVE_TO_MASTER_OBJECT(name, type) \ + REMOTE_OBJECT_HELPER(name, type, 1, NUM_SLAVES) \ + remote_object_##name##_t remote_object_##name = { \ + .object = { \ + .object_type = SLAVE_TO_MASTER, \ + .object_size = sizeof(type), \ + } \ + }; \ + type* begin_write_##name(void) { \ + remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ + triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; \ + return (type*)triple_buffer_begin_write_internal(sizeof(type) + LOCAL_OBJECT_EXTRA, tb); \ + }\ + void end_write_##name(void) { \ + remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ + triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; \ + triple_buffer_end_write_internal(tb); \ + signal_data_written(); \ + }\ + type* read_##name(uint8_t slave) { \ + remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ + uint8_t* start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size);\ + start+=slave * REMOTE_OBJECT_SIZE(obj->object_size); \ + triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ + return triple_buffer_read_internal(obj->object_size, tb); \ + } + +#define REMOTE_OBJECT(name) (remote_object_t*)&remote_object_##name + +void add_remote_objects(remote_object_t** remote_objects, uint32_t num_remote_objects); +void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size); +void update_transport(void); + +#endif diff --git a/quantum/serial_link/protocol/triple_buffered_object.c b/quantum/serial_link/protocol/triple_buffered_object.c new file mode 100644 index 000000000..e3e8989d3 --- /dev/null +++ b/quantum/serial_link/protocol/triple_buffered_object.c @@ -0,0 +1,78 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "serial_link/protocol/triple_buffered_object.h" +#include "serial_link/system/serial_link.h" +#include +#include + +#define GET_READ_INDEX() object->state & 3 +#define GET_WRITE_INDEX() (object->state >> 2) & 3 +#define GET_SHARED_INDEX() (object->state >> 4) & 3 +#define GET_DATA_AVAILABLE() (object->state >> 6) & 1 + +#define SET_READ_INDEX(i) object->state = ((object->state & ~3) | i) +#define SET_WRITE_INDEX(i) object->state = ((object->state & ~(3 << 2)) | (i << 2)) +#define SET_SHARED_INDEX(i) object->state = ((object->state & ~(3 << 4)) | (i << 4)) +#define SET_DATA_AVAILABLE(i) object->state = ((object->state & ~(1 << 6)) | (i << 6)) + +void triple_buffer_init(triple_buffer_object_t* object) { + object->state = 0; + SET_WRITE_INDEX(0); + SET_READ_INDEX(1); + SET_SHARED_INDEX(2); + SET_DATA_AVAILABLE(0); +} + +void* triple_buffer_read_internal(uint16_t object_size, triple_buffer_object_t* object) { + serial_link_lock(); + if (GET_DATA_AVAILABLE()) { + uint8_t shared_index = GET_SHARED_INDEX(); + uint8_t read_index = GET_READ_INDEX(); + SET_READ_INDEX(shared_index); + SET_SHARED_INDEX(read_index); + SET_DATA_AVAILABLE(false); + serial_link_unlock(); + return object->buffer + object_size * shared_index; + } + else { + serial_link_unlock(); + return NULL; + } +} + +void* triple_buffer_begin_write_internal(uint16_t object_size, triple_buffer_object_t* object) { + uint8_t write_index = GET_WRITE_INDEX(); + return object->buffer + object_size * write_index; +} + +void triple_buffer_end_write_internal(triple_buffer_object_t* object) { + serial_link_lock(); + uint8_t shared_index = GET_SHARED_INDEX(); + uint8_t write_index = GET_WRITE_INDEX(); + SET_SHARED_INDEX(write_index); + SET_WRITE_INDEX(shared_index); + SET_DATA_AVAILABLE(true); + serial_link_unlock(); +} diff --git a/quantum/serial_link/protocol/triple_buffered_object.h b/quantum/serial_link/protocol/triple_buffered_object.h new file mode 100644 index 000000000..2e57db3f5 --- /dev/null +++ b/quantum/serial_link/protocol/triple_buffered_object.h @@ -0,0 +1,51 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef SERIAL_LINK_TRIPLE_BUFFERED_OBJECT_H +#define SERIAL_LINK_TRIPLE_BUFFERED_OBJECT_H + +#include + +typedef struct { + uint8_t state; + uint8_t buffer[] __attribute__((aligned(4))); +}triple_buffer_object_t; + +void triple_buffer_init(triple_buffer_object_t* object); + +#define triple_buffer_begin_write(object) \ + (typeof(*object.buffer[0])*)triple_buffer_begin_write_internal(sizeof(*object.buffer[0]), (triple_buffer_object_t*)object) + +#define triple_buffer_end_write(object) \ + triple_buffer_end_write_internal((triple_buffer_object_t*)object) + +#define triple_buffer_read(object) \ + (typeof(*object.buffer[0])*)triple_buffer_read_internal(sizeof(*object.buffer[0]), (triple_buffer_object_t*)object) + +void* triple_buffer_begin_write_internal(uint16_t object_size, triple_buffer_object_t* object); +void triple_buffer_end_write_internal(triple_buffer_object_t* object); +void* triple_buffer_read_internal(uint16_t object_size, triple_buffer_object_t* object); + + +#endif diff --git a/quantum/serial_link/serial_link.mk b/quantum/serial_link/serial_link.mk deleted file mode 100644 index e164cc5ff..000000000 --- a/quantum/serial_link/serial_link.mk +++ /dev/null @@ -1,27 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2016 Fred Sundvik -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -UINCDIR += $(SERIAL_DIR) -SRC += $(wildcard $(SERIAL_DIR)/serial_link/protocol/*.c) -SRC += $(wildcard $(SERIAL_DIR)/serial_link/system/*.c) -SRC += serial_link_hal.c -OPT_DEFS += -DUSE_SERIAL_LINK diff --git a/quantum/serial_link/serial_link/protocol/byte_stuffer.c b/quantum/serial_link/serial_link/protocol/byte_stuffer.c deleted file mode 100644 index fb4c45a8d..000000000 --- a/quantum/serial_link/serial_link/protocol/byte_stuffer.c +++ /dev/null @@ -1,145 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "serial_link/protocol/byte_stuffer.h" -#include "serial_link/protocol/frame_validator.h" -#include "serial_link/protocol/physical.h" -#include - -// This implements the "Consistent overhead byte stuffing protocol" -// https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing -// http://www.stuartcheshire.org/papers/COBSforToN.pdf - -#define MAX_FRAME_SIZE 1024 -#define NUM_LINKS 2 - -typedef struct byte_stuffer_state { - uint16_t next_zero; - uint16_t data_pos; - bool long_frame; - uint8_t data[MAX_FRAME_SIZE]; -}byte_stuffer_state_t; - -static byte_stuffer_state_t states[NUM_LINKS]; - -void init_byte_stuffer_state(byte_stuffer_state_t* state) { - state->next_zero = 0; - state->data_pos = 0; - state->long_frame = false; -} - -void init_byte_stuffer(void) { - int i; - for (i=0;inext_zero == 0) { - state->next_zero = data; - state->long_frame = data == 0xFF; - state->data_pos = 0; - return; - } - - state->next_zero--; - if (data == 0) { - if (state->next_zero == 0) { - // The frame is completed - if (state->data_pos > 0) { - validator_recv_frame(link, state->data, state->data_pos); - } - } - else { - // The frame is invalid, so reset - init_byte_stuffer_state(state); - } - } - else { - if (state->data_pos == MAX_FRAME_SIZE) { - // We exceeded our maximum frame size - // therefore there's nothing else to do than reset to a new frame - state->next_zero = data; - state->long_frame = data == 0xFF; - state->data_pos = 0; - } - else if (state->next_zero == 0) { - if (state->long_frame) { - // This is part of a long frame, so continue - state->next_zero = data; - state->long_frame = data == 0xFF; - } - else { - // Special case for zeroes - state->next_zero = data; - state->data[state->data_pos++] = 0; - } - } - else { - state->data[state->data_pos++] = data; - } - } -} - -static void send_block(uint8_t link, uint8_t* start, uint8_t* end, uint8_t num_non_zero) { - send_data(link, &num_non_zero, 1); - if (end > start) { - send_data(link, start, end-start); - } -} - -void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size) { - const uint8_t zero = 0; - if (size > 0) { - uint16_t num_non_zero = 1; - uint8_t* end = data + size; - uint8_t* start = data; - while (data < end) { - if (num_non_zero == 0xFF) { - // There's more data after big non-zero block - // So send it, and start a new block - send_block(link, start, data, num_non_zero); - start = data; - num_non_zero = 1; - } - else { - if (*data == 0) { - // A zero encountered, so send the block - send_block(link, start, data, num_non_zero); - start = data + 1; - num_non_zero = 1; - } - else { - num_non_zero++; - } - ++data; - } - } - send_block(link, start, data, num_non_zero); - send_data(link, &zero, 1); - } -} diff --git a/quantum/serial_link/serial_link/protocol/byte_stuffer.h b/quantum/serial_link/serial_link/protocol/byte_stuffer.h deleted file mode 100644 index 2cc88beb4..000000000 --- a/quantum/serial_link/serial_link/protocol/byte_stuffer.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#ifndef SERIAL_LINK_BYTE_STUFFER_H -#define SERIAL_LINK_BYTE_STUFFER_H - -#include - -void init_byte_stuffer(void); -void byte_stuffer_recv_byte(uint8_t link, uint8_t data); -void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size); - -#endif diff --git a/quantum/serial_link/serial_link/protocol/frame_router.c b/quantum/serial_link/serial_link/protocol/frame_router.c deleted file mode 100644 index 04b8c2e75..000000000 --- a/quantum/serial_link/serial_link/protocol/frame_router.c +++ /dev/null @@ -1,69 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "serial_link/protocol/frame_router.h" -#include "serial_link/protocol/transport.h" -#include "serial_link/protocol/frame_validator.h" - -static bool is_master; - -void router_set_master(bool master) { - is_master = master; -} - -void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size){ - if (is_master) { - if (link == DOWN_LINK) { - transport_recv_frame(data[size-1], data, size - 1); - } - } - else { - if (link == UP_LINK) { - if (data[size-1] & 1) { - transport_recv_frame(0, data, size - 1); - } - data[size-1] >>= 1; - validator_send_frame(DOWN_LINK, data, size); - } - else { - data[size-1]++; - validator_send_frame(UP_LINK, data, size); - } - } -} - -void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) { - if (destination == 0) { - if (!is_master) { - data[size] = 1; - validator_send_frame(UP_LINK, data, size + 1); - } - } - else { - if (is_master) { - data[size] = destination; - validator_send_frame(DOWN_LINK, data, size + 1); - } - } -} diff --git a/quantum/serial_link/serial_link/protocol/frame_router.h b/quantum/serial_link/serial_link/protocol/frame_router.h deleted file mode 100644 index 712250ff3..000000000 --- a/quantum/serial_link/serial_link/protocol/frame_router.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#ifndef SERIAL_LINK_FRAME_ROUTER_H -#define SERIAL_LINK_FRAME_ROUTER_H - -#include -#include - -#define UP_LINK 0 -#define DOWN_LINK 1 - -void router_set_master(bool master); -void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size); -void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size); - -#endif diff --git a/quantum/serial_link/serial_link/protocol/frame_validator.c b/quantum/serial_link/serial_link/protocol/frame_validator.c deleted file mode 100644 index 474f80ee8..000000000 --- a/quantum/serial_link/serial_link/protocol/frame_validator.c +++ /dev/null @@ -1,121 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "serial_link/protocol/frame_validator.h" -#include "serial_link/protocol/frame_router.h" -#include "serial_link/protocol/byte_stuffer.h" -#include - -const uint32_t poly8_lookup[256] = -{ - 0, 0x77073096, 0xEE0E612C, 0x990951BA, - 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, - 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, - 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, - 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, - 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, - 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, - 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, - 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, - 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, - 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, - 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, - 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, - 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, - 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, - 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, - 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, - 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, - 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -}; - -static uint32_t crc32_byte(uint8_t *p, uint32_t bytelength) -{ - uint32_t crc = 0xffffffff; - while (bytelength-- !=0) crc = poly8_lookup[((uint8_t) crc ^ *(p++))] ^ (crc >> 8); - // return (~crc); also works - return (crc ^ 0xffffffff); -} - -void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size) { - if (size > 4) { - uint32_t frame_crc; - memcpy(&frame_crc, data + size -4, 4); - uint32_t expected_crc = crc32_byte(data, size - 4); - if (frame_crc == expected_crc) { - route_incoming_frame(link, data, size-4); - } - } -} - -void validator_send_frame(uint8_t link, uint8_t* data, uint16_t size) { - uint32_t crc = crc32_byte(data, size); - memcpy(data + size, &crc, 4); - byte_stuffer_send_frame(link, data, size + 4); -} diff --git a/quantum/serial_link/serial_link/protocol/frame_validator.h b/quantum/serial_link/serial_link/protocol/frame_validator.h deleted file mode 100644 index 4a910d510..000000000 --- a/quantum/serial_link/serial_link/protocol/frame_validator.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#ifndef SERIAL_LINK_FRAME_VALIDATOR_H -#define SERIAL_LINK_FRAME_VALIDATOR_H - -#include - -void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size); -// The buffer pointed to by the data needs 4 additional bytes -void validator_send_frame(uint8_t link, uint8_t* data, uint16_t size); - -#endif diff --git a/quantum/serial_link/serial_link/protocol/physical.h b/quantum/serial_link/serial_link/protocol/physical.h deleted file mode 100644 index 425e06cdd..000000000 --- a/quantum/serial_link/serial_link/protocol/physical.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#ifndef SERIAL_LINK_PHYSICAL_H -#define SERIAL_LINK_PHYSICAL_H - -void send_data(uint8_t link, const uint8_t* data, uint16_t size); - -#endif diff --git a/quantum/serial_link/serial_link/protocol/transport.c b/quantum/serial_link/serial_link/protocol/transport.c deleted file mode 100644 index f418d11ce..000000000 --- a/quantum/serial_link/serial_link/protocol/transport.c +++ /dev/null @@ -1,124 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "serial_link/protocol/transport.h" -#include "serial_link/protocol/frame_router.h" -#include "serial_link/protocol/triple_buffered_object.h" -#include - -#define MAX_REMOTE_OBJECTS 16 -static remote_object_t* remote_objects[MAX_REMOTE_OBJECTS]; -static uint32_t num_remote_objects = 0; - -void add_remote_objects(remote_object_t** _remote_objects, uint32_t _num_remote_objects) { - unsigned int i; - for(i=0;i<_num_remote_objects;i++) { - remote_object_t* obj = _remote_objects[i]; - remote_objects[num_remote_objects++] = obj; - if (obj->object_type == MASTER_TO_ALL_SLAVES) { - triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; - triple_buffer_init(tb); - uint8_t* start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size); - tb = (triple_buffer_object_t*)start; - triple_buffer_init(tb); - } - else if(obj->object_type == MASTER_TO_SINGLE_SLAVE) { - uint8_t* start = obj->buffer; - unsigned int j; - for (j=0;jobject_size); - } - triple_buffer_object_t* tb = (triple_buffer_object_t*)start; - triple_buffer_init(tb); - } - else { - uint8_t* start = obj->buffer; - triple_buffer_object_t* tb = (triple_buffer_object_t*)start; - triple_buffer_init(tb); - start += LOCAL_OBJECT_SIZE(obj->object_size); - unsigned int j; - for (j=0;jobject_size); - } - } - } -} - -void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) { - uint8_t id = data[size-1]; - if (id < num_remote_objects) { - remote_object_t* obj = remote_objects[id]; - if (obj->object_size == size - 1) { - uint8_t* start; - if (obj->object_type == MASTER_TO_ALL_SLAVES) { - start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size); - } - else if(obj->object_type == SLAVE_TO_MASTER) { - start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size); - start += (from - 1) * REMOTE_OBJECT_SIZE(obj->object_size); - } - else { - start = obj->buffer + NUM_SLAVES * LOCAL_OBJECT_SIZE(obj->object_size); - } - triple_buffer_object_t* tb = (triple_buffer_object_t*)start; - void* ptr = triple_buffer_begin_write_internal(obj->object_size, tb); - memcpy(ptr, data, size - 1); - triple_buffer_end_write_internal(tb); - } - } -} - -void update_transport(void) { - unsigned int i; - for(i=0;iobject_type == MASTER_TO_ALL_SLAVES || obj->object_type == SLAVE_TO_MASTER) { - triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; - uint8_t* ptr = (uint8_t*)triple_buffer_read_internal(obj->object_size + LOCAL_OBJECT_EXTRA, tb); - if (ptr) { - ptr[obj->object_size] = i; - uint8_t dest = obj->object_type == MASTER_TO_ALL_SLAVES ? 0xFF : 0; - router_send_frame(dest, ptr, obj->object_size + 1); - } - } - else { - uint8_t* start = obj->buffer; - unsigned int j; - for (j=0;jobject_size + LOCAL_OBJECT_EXTRA, tb); - if (ptr) { - ptr[obj->object_size] = i; - uint8_t dest = j + 1; - router_send_frame(dest, ptr, obj->object_size + 1); - } - start += LOCAL_OBJECT_SIZE(obj->object_size); - } - } - } -} diff --git a/quantum/serial_link/serial_link/protocol/transport.h b/quantum/serial_link/serial_link/protocol/transport.h deleted file mode 100644 index 9a052d880..000000000 --- a/quantum/serial_link/serial_link/protocol/transport.h +++ /dev/null @@ -1,151 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#ifndef SERIAL_LINK_TRANSPORT_H -#define SERIAL_LINK_TRANSPORT_H - -#include "serial_link/protocol/triple_buffered_object.h" -#include "serial_link/system/serial_link.h" - -#define NUM_SLAVES 8 -#define LOCAL_OBJECT_EXTRA 16 - -// master -> slave = 1 local(target all), 1 remote object -// slave -> master = 1 local(target 0), multiple remote objects -// master -> single slave (multiple local, target id), 1 remote object -typedef enum { - MASTER_TO_ALL_SLAVES, - MASTER_TO_SINGLE_SLAVE, - SLAVE_TO_MASTER, -} remote_object_type; - -typedef struct { - remote_object_type object_type; - uint16_t object_size; - uint8_t buffer[] __attribute__((aligned(4))); -} remote_object_t; - -#define REMOTE_OBJECT_SIZE(objectsize) \ - (sizeof(triple_buffer_object_t) + objectsize * 3) -#define LOCAL_OBJECT_SIZE(objectsize) \ - (sizeof(triple_buffer_object_t) + (objectsize + LOCAL_OBJECT_EXTRA) * 3) - -#define REMOTE_OBJECT_HELPER(name, type, num_local, num_remote) \ -typedef struct { \ - remote_object_t object; \ - uint8_t buffer[ \ - num_remote * REMOTE_OBJECT_SIZE(sizeof(type)) + \ - num_local * LOCAL_OBJECT_SIZE(sizeof(type))]; \ -} remote_object_##name##_t; - -#define MASTER_TO_ALL_SLAVES_OBJECT(name, type) \ - REMOTE_OBJECT_HELPER(name, type, 1, 1) \ - remote_object_##name##_t remote_object_##name = { \ - .object = { \ - .object_type = MASTER_TO_ALL_SLAVES, \ - .object_size = sizeof(type), \ - } \ - }; \ - type* begin_write_##name(void) { \ - remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ - triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; \ - return (type*)triple_buffer_begin_write_internal(sizeof(type) + LOCAL_OBJECT_EXTRA, tb); \ - }\ - void end_write_##name(void) { \ - remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ - triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; \ - triple_buffer_end_write_internal(tb); \ - signal_data_written(); \ - }\ - type* read_##name(void) { \ - remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ - uint8_t* start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size);\ - triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ - return triple_buffer_read_internal(obj->object_size, tb); \ - } - -#define MASTER_TO_SINGLE_SLAVE_OBJECT(name, type) \ - REMOTE_OBJECT_HELPER(name, type, NUM_SLAVES, 1) \ - remote_object_##name##_t remote_object_##name = { \ - .object = { \ - .object_type = MASTER_TO_SINGLE_SLAVE, \ - .object_size = sizeof(type), \ - } \ - }; \ - type* begin_write_##name(uint8_t slave) { \ - remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ - uint8_t* start = obj->buffer;\ - start += slave * LOCAL_OBJECT_SIZE(obj->object_size); \ - triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ - return (type*)triple_buffer_begin_write_internal(sizeof(type) + LOCAL_OBJECT_EXTRA, tb); \ - }\ - void end_write_##name(uint8_t slave) { \ - remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ - uint8_t* start = obj->buffer;\ - start += slave * LOCAL_OBJECT_SIZE(obj->object_size); \ - triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ - triple_buffer_end_write_internal(tb); \ - signal_data_written(); \ - }\ - type* read_##name() { \ - remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ - uint8_t* start = obj->buffer + NUM_SLAVES * LOCAL_OBJECT_SIZE(obj->object_size);\ - triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ - return triple_buffer_read_internal(obj->object_size, tb); \ - } - -#define SLAVE_TO_MASTER_OBJECT(name, type) \ - REMOTE_OBJECT_HELPER(name, type, 1, NUM_SLAVES) \ - remote_object_##name##_t remote_object_##name = { \ - .object = { \ - .object_type = SLAVE_TO_MASTER, \ - .object_size = sizeof(type), \ - } \ - }; \ - type* begin_write_##name(void) { \ - remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ - triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; \ - return (type*)triple_buffer_begin_write_internal(sizeof(type) + LOCAL_OBJECT_EXTRA, tb); \ - }\ - void end_write_##name(void) { \ - remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ - triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; \ - triple_buffer_end_write_internal(tb); \ - signal_data_written(); \ - }\ - type* read_##name(uint8_t slave) { \ - remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ - uint8_t* start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size);\ - start+=slave * REMOTE_OBJECT_SIZE(obj->object_size); \ - triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ - return triple_buffer_read_internal(obj->object_size, tb); \ - } - -#define REMOTE_OBJECT(name) (remote_object_t*)&remote_object_##name - -void add_remote_objects(remote_object_t** remote_objects, uint32_t num_remote_objects); -void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size); -void update_transport(void); - -#endif diff --git a/quantum/serial_link/serial_link/protocol/triple_buffered_object.c b/quantum/serial_link/serial_link/protocol/triple_buffered_object.c deleted file mode 100644 index e3e8989d3..000000000 --- a/quantum/serial_link/serial_link/protocol/triple_buffered_object.c +++ /dev/null @@ -1,78 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "serial_link/protocol/triple_buffered_object.h" -#include "serial_link/system/serial_link.h" -#include -#include - -#define GET_READ_INDEX() object->state & 3 -#define GET_WRITE_INDEX() (object->state >> 2) & 3 -#define GET_SHARED_INDEX() (object->state >> 4) & 3 -#define GET_DATA_AVAILABLE() (object->state >> 6) & 1 - -#define SET_READ_INDEX(i) object->state = ((object->state & ~3) | i) -#define SET_WRITE_INDEX(i) object->state = ((object->state & ~(3 << 2)) | (i << 2)) -#define SET_SHARED_INDEX(i) object->state = ((object->state & ~(3 << 4)) | (i << 4)) -#define SET_DATA_AVAILABLE(i) object->state = ((object->state & ~(1 << 6)) | (i << 6)) - -void triple_buffer_init(triple_buffer_object_t* object) { - object->state = 0; - SET_WRITE_INDEX(0); - SET_READ_INDEX(1); - SET_SHARED_INDEX(2); - SET_DATA_AVAILABLE(0); -} - -void* triple_buffer_read_internal(uint16_t object_size, triple_buffer_object_t* object) { - serial_link_lock(); - if (GET_DATA_AVAILABLE()) { - uint8_t shared_index = GET_SHARED_INDEX(); - uint8_t read_index = GET_READ_INDEX(); - SET_READ_INDEX(shared_index); - SET_SHARED_INDEX(read_index); - SET_DATA_AVAILABLE(false); - serial_link_unlock(); - return object->buffer + object_size * shared_index; - } - else { - serial_link_unlock(); - return NULL; - } -} - -void* triple_buffer_begin_write_internal(uint16_t object_size, triple_buffer_object_t* object) { - uint8_t write_index = GET_WRITE_INDEX(); - return object->buffer + object_size * write_index; -} - -void triple_buffer_end_write_internal(triple_buffer_object_t* object) { - serial_link_lock(); - uint8_t shared_index = GET_SHARED_INDEX(); - uint8_t write_index = GET_WRITE_INDEX(); - SET_SHARED_INDEX(write_index); - SET_WRITE_INDEX(shared_index); - SET_DATA_AVAILABLE(true); - serial_link_unlock(); -} diff --git a/quantum/serial_link/serial_link/protocol/triple_buffered_object.h b/quantum/serial_link/serial_link/protocol/triple_buffered_object.h deleted file mode 100644 index 2e57db3f5..000000000 --- a/quantum/serial_link/serial_link/protocol/triple_buffered_object.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#ifndef SERIAL_LINK_TRIPLE_BUFFERED_OBJECT_H -#define SERIAL_LINK_TRIPLE_BUFFERED_OBJECT_H - -#include - -typedef struct { - uint8_t state; - uint8_t buffer[] __attribute__((aligned(4))); -}triple_buffer_object_t; - -void triple_buffer_init(triple_buffer_object_t* object); - -#define triple_buffer_begin_write(object) \ - (typeof(*object.buffer[0])*)triple_buffer_begin_write_internal(sizeof(*object.buffer[0]), (triple_buffer_object_t*)object) - -#define triple_buffer_end_write(object) \ - triple_buffer_end_write_internal((triple_buffer_object_t*)object) - -#define triple_buffer_read(object) \ - (typeof(*object.buffer[0])*)triple_buffer_read_internal(sizeof(*object.buffer[0]), (triple_buffer_object_t*)object) - -void* triple_buffer_begin_write_internal(uint16_t object_size, triple_buffer_object_t* object); -void triple_buffer_end_write_internal(triple_buffer_object_t* object); -void* triple_buffer_read_internal(uint16_t object_size, triple_buffer_object_t* object); - - -#endif diff --git a/quantum/serial_link/serial_link/system/serial_link.c b/quantum/serial_link/serial_link/system/serial_link.c deleted file mode 100644 index 75c7e77a7..000000000 --- a/quantum/serial_link/serial_link/system/serial_link.c +++ /dev/null @@ -1,265 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ -#include "report.h" -#include "host_driver.h" -#include "serial_link/system/serial_link.h" -#include "hal.h" -#include "serial_link/protocol/byte_stuffer.h" -#include "serial_link/protocol/transport.h" -#include "serial_link/protocol/frame_router.h" -#include "matrix.h" -#include -#include "print.h" -#include "config.h" - -static event_source_t new_data_event; -static bool serial_link_connected; -static bool is_master = false; - -static uint8_t keyboard_leds(void); -static void send_keyboard(report_keyboard_t *report); -static void send_mouse(report_mouse_t *report); -static void send_system(uint16_t data); -static void send_consumer(uint16_t data); - -host_driver_t serial_driver = { - keyboard_leds, - send_keyboard, - send_mouse, - send_system, - send_consumer -}; - -// Define these in your Config.h file -#ifndef SERIAL_LINK_BAUD -#error "Serial link baud is not set" -#endif - -#ifndef SERIAL_LINK_THREAD_PRIORITY -#error "Serial link thread priority not set" -#endif - -static SerialConfig config = { - .sc_speed = SERIAL_LINK_BAUD -}; - -//#define DEBUG_LINK_ERRORS - -static uint32_t read_from_serial(SerialDriver* driver, uint8_t link) { - const uint32_t buffer_size = 16; - uint8_t buffer[buffer_size]; - uint32_t bytes_read = sdAsynchronousRead(driver, buffer, buffer_size); - uint8_t* current = buffer; - uint8_t* end = current + bytes_read; - while(current < end) { - byte_stuffer_recv_byte(link, *current); - current++; - } - return bytes_read; -} - -static void print_error(char* str, eventflags_t flags, SerialDriver* driver) { -#ifdef DEBUG_LINK_ERRORS - if (flags & SD_PARITY_ERROR) { - print(str); - print(" Parity error\n"); - } - if (flags & SD_FRAMING_ERROR) { - print(str); - print(" Framing error\n"); - } - if (flags & SD_OVERRUN_ERROR) { - print(str); - uint32_t size = qSpaceI(&(driver->iqueue)); - xprintf(" Overrun error, queue size %d\n", size); - - } - if (flags & SD_NOISE_ERROR) { - print(str); - print(" Noise error\n"); - } - if (flags & SD_BREAK_DETECTED) { - print(str); - print(" Break detected\n"); - } -#else - (void)str; - (void)flags; - (void)driver; -#endif -} - -bool is_serial_link_master(void) { - return is_master; -} - -// TODO: Optimize the stack size, this is probably way too big -static THD_WORKING_AREA(serialThreadStack, 1024); -static THD_FUNCTION(serialThread, arg) { - (void)arg; - event_listener_t new_data_listener; - event_listener_t sd1_listener; - event_listener_t sd2_listener; - chEvtRegister(&new_data_event, &new_data_listener, 0); - eventflags_t events = CHN_INPUT_AVAILABLE - | SD_PARITY_ERROR | SD_FRAMING_ERROR | SD_OVERRUN_ERROR | SD_NOISE_ERROR | SD_BREAK_DETECTED; - chEvtRegisterMaskWithFlags(chnGetEventSource(&SD1), - &sd1_listener, - EVENT_MASK(1), - events); - chEvtRegisterMaskWithFlags(chnGetEventSource(&SD2), - &sd2_listener, - EVENT_MASK(2), - events); - bool need_wait = false; - while(true) { - eventflags_t flags1 = 0; - eventflags_t flags2 = 0; - if (need_wait) { - eventmask_t mask = chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(1000)); - if (mask & EVENT_MASK(1)) { - flags1 = chEvtGetAndClearFlags(&sd1_listener); - print_error("DOWNLINK", flags1, &SD1); - } - if (mask & EVENT_MASK(2)) { - flags2 = chEvtGetAndClearFlags(&sd2_listener); - print_error("UPLINK", flags2, &SD2); - } - } - - // Always stay as master, even if the USB goes into sleep mode - is_master |= usbGetDriverStateI(&USBD1) == USB_ACTIVE; - router_set_master(is_master); - - need_wait = true; - need_wait &= read_from_serial(&SD2, UP_LINK) == 0; - need_wait &= read_from_serial(&SD1, DOWN_LINK) == 0; - update_transport(); - } -} - -void send_data(uint8_t link, const uint8_t* data, uint16_t size) { - if (link == DOWN_LINK) { - sdWrite(&SD1, data, size); - } - else { - sdWrite(&SD2, data, size); - } -} - -static systime_t last_update = 0; - -typedef struct { - matrix_row_t rows[MATRIX_ROWS]; -} matrix_object_t; - -static matrix_object_t last_matrix = {}; - -SLAVE_TO_MASTER_OBJECT(keyboard_matrix, matrix_object_t); -MASTER_TO_ALL_SLAVES_OBJECT(serial_link_connected, bool); - -static remote_object_t* remote_objects[] = { - REMOTE_OBJECT(serial_link_connected), - REMOTE_OBJECT(keyboard_matrix), -}; - -void init_serial_link(void) { - serial_link_connected = false; - init_serial_link_hal(); - add_remote_objects(remote_objects, sizeof(remote_objects)/sizeof(remote_object_t*)); - init_byte_stuffer(); - sdStart(&SD1, &config); - sdStart(&SD2, &config); - chEvtObjectInit(&new_data_event); - (void)chThdCreateStatic(serialThreadStack, sizeof(serialThreadStack), - SERIAL_LINK_THREAD_PRIORITY, serialThread, NULL); -} - -void matrix_set_remote(matrix_row_t* rows, uint8_t index); - -void serial_link_update(void) { - if (read_serial_link_connected()) { - serial_link_connected = true; - } - - matrix_object_t matrix; - bool changed = false; - for(uint8_t i=0;i US2ST(1000)) { - last_update = current_time; - last_matrix = matrix; - matrix_object_t* m = begin_write_keyboard_matrix(); - for(uint8_t i=0;irows[i] = matrix.rows[i]; - } - end_write_keyboard_matrix(); - *begin_write_serial_link_connected() = true; - end_write_serial_link_connected(); - } - - matrix_object_t* m = read_keyboard_matrix(0); - if (m) { - matrix_set_remote(m->rows, 0); - } -} - -void signal_data_written(void) { - chEvtBroadcast(&new_data_event); -} - -bool is_serial_link_connected(void) { - return serial_link_connected; -} - -host_driver_t* get_serial_link_driver(void) { - return &serial_driver; -} - -// NOTE: The driver does nothing, because the master handles everything -uint8_t keyboard_leds(void) { - return 0; -} - -void send_keyboard(report_keyboard_t *report) { - (void)report; -} - -void send_mouse(report_mouse_t *report) { - (void)report; -} - -void send_system(uint16_t data) { - (void)data; -} - -void send_consumer(uint16_t data) { - (void)data; -} - diff --git a/quantum/serial_link/serial_link/system/serial_link.h b/quantum/serial_link/serial_link/system/serial_link.h deleted file mode 100644 index 351e03877..000000000 --- a/quantum/serial_link/serial_link/system/serial_link.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#ifndef SERIAL_LINK_H -#define SERIAL_LINK_H - -#include "host_driver.h" -#include - -void init_serial_link(void); -void init_serial_link_hal(void); -bool is_serial_link_connected(void); -bool is_serial_link_master(void); -host_driver_t* get_serial_link_driver(void); -void serial_link_update(void); - -#if defined(PROTOCOL_CHIBIOS) -#include "ch.h" - -static inline void serial_link_lock(void) { - chSysLock(); -} - -static inline void serial_link_unlock(void) { - chSysUnlock(); -} - -void signal_data_written(void); - -#else - -inline void serial_link_lock(void) { -} - -inline void serial_link_unlock(void) { -} - -void signal_data_written(void); - -#endif - -#endif diff --git a/quantum/serial_link/serial_link/tests/Makefile b/quantum/serial_link/serial_link/tests/Makefile deleted file mode 100644 index 1b072c6f1..000000000 --- a/quantum/serial_link/serial_link/tests/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2016 Fred Sundvik -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -CC = gcc -CFLAGS = -INCLUDES = -I. -I../../ -LDFLAGS = -L$(BUILDDIR)/cgreen/build-c/src -shared -LDLIBS = -lcgreen -UNITOBJ = $(BUILDDIR)/serialtest/unitobj -DEPDIR = $(BUILDDIR)/serialtest/unit.d -UNITTESTS = $(BUILDDIR)/serialtest/unittests -DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td -EXT = .so -UNAME := $(shell uname) -ifneq (, $(findstring MINGW, $(UNAME))) - EXT = .dll -endif -ifneq (, $(findstring CYGWIN, $(UNAME))) - EXT = .dll -endif - -SRC = $(wildcard *.c) -TESTFILES = $(patsubst %.c, $(UNITTESTS)/%$(EXT), $(SRC)) -$(shell mkdir -p $(DEPDIR) >/dev/null) - -test: $(TESTFILES) - @$(BUILDDIR)/cgreen/build-c/tools/cgreen-runner --color $(TESTFILES) - -$(UNITTESTS)/%$(EXT): $(UNITOBJ)/%.o - @mkdir -p $(UNITTESTS) - $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) - -$(UNITOBJ)/%.o : %.c -$(UNITOBJ)/%.o: %.c $(DEPDIR)/%.d - @mkdir -p $(UNITOBJ) - $(CC) $(CFLAGS) $(DEPFLAGS) $(INCLUDES) -c $< -o $@ - @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d - -$(DEPDIR)/%.d: ; -.PRECIOUS: $(DEPDIR)/%.d - --include $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRC))) \ No newline at end of file diff --git a/quantum/serial_link/serial_link/tests/byte_stuffer_tests.c b/quantum/serial_link/serial_link/tests/byte_stuffer_tests.c deleted file mode 100644 index 64b170e8c..000000000 --- a/quantum/serial_link/serial_link/tests/byte_stuffer_tests.c +++ /dev/null @@ -1,506 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include -#include -#include "serial_link/protocol/byte_stuffer.h" -#include "serial_link/protocol/byte_stuffer.c" -#include "serial_link/protocol/frame_validator.h" -#include "serial_link/protocol/physical.h" - -static uint8_t sent_data[MAX_FRAME_SIZE*2]; -static uint16_t sent_data_size; - -Describe(ByteStuffer); -BeforeEach(ByteStuffer) { - init_byte_stuffer(); - sent_data_size = 0; -} -AfterEach(ByteStuffer) {} - -void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size) { - mock(data, size); -} - -void send_data(uint8_t link, const uint8_t* data, uint16_t size) { - memcpy(sent_data + sent_data_size, data, size); - sent_data_size += size; -} - -Ensure(ByteStuffer, receives_no_frame_for_a_single_zero_byte) { - never_expect(validator_recv_frame); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_no_frame_for_a_single_FF_byte) { - never_expect(validator_recv_frame); - byte_stuffer_recv_byte(0, 0xFF); -} - -Ensure(ByteStuffer, receives_no_frame_for_a_single_random_byte) { - never_expect(validator_recv_frame); - byte_stuffer_recv_byte(0, 0x4A); -} - -Ensure(ByteStuffer, receives_no_frame_for_a_zero_length_frame) { - never_expect(validator_recv_frame); - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_single_byte_valid_frame) { - uint8_t expected[] = {0x37}; - expect(validator_recv_frame, - when(size, is_equal_to(1)), - when(data, is_equal_to_contents_of(expected, 1)) - ); - byte_stuffer_recv_byte(0, 2); - byte_stuffer_recv_byte(0, 0x37); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_three_bytes_valid_frame) { - uint8_t expected[] = {0x37, 0x99, 0xFF}; - expect(validator_recv_frame, - when(size, is_equal_to(3)), - when(data, is_equal_to_contents_of(expected, 3)) - ); - byte_stuffer_recv_byte(0, 4); - byte_stuffer_recv_byte(0, 0x37); - byte_stuffer_recv_byte(0, 0x99); - byte_stuffer_recv_byte(0, 0xFF); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_single_zero_valid_frame) { - uint8_t expected[] = {0}; - expect(validator_recv_frame, - when(size, is_equal_to(1)), - when(data, is_equal_to_contents_of(expected, 1)) - ); - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_valid_frame_with_zeroes) { - uint8_t expected[] = {5, 0, 3, 0}; - expect(validator_recv_frame, - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(expected, 4)) - ); - byte_stuffer_recv_byte(0, 2); - byte_stuffer_recv_byte(0, 5); - byte_stuffer_recv_byte(0, 2); - byte_stuffer_recv_byte(0, 3); - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_two_valid_frames) { - uint8_t expected1[] = {5, 0}; - uint8_t expected2[] = {3}; - expect(validator_recv_frame, - when(size, is_equal_to(2)), - when(data, is_equal_to_contents_of(expected1, 2)) - ); - expect(validator_recv_frame, - when(size, is_equal_to(1)), - when(data, is_equal_to_contents_of(expected2, 1)) - ); - byte_stuffer_recv_byte(1, 2); - byte_stuffer_recv_byte(1, 5); - byte_stuffer_recv_byte(1, 1); - byte_stuffer_recv_byte(1, 0); - byte_stuffer_recv_byte(1, 2); - byte_stuffer_recv_byte(1, 3); - byte_stuffer_recv_byte(1, 0); -} - -Ensure(ByteStuffer, receives_valid_frame_after_unexpected_zero) { - uint8_t expected[] = {5, 7}; - expect(validator_recv_frame, - when(size, is_equal_to(2)), - when(data, is_equal_to_contents_of(expected, 2)) - ); - byte_stuffer_recv_byte(1, 3); - byte_stuffer_recv_byte(1, 1); - byte_stuffer_recv_byte(1, 0); - byte_stuffer_recv_byte(1, 3); - byte_stuffer_recv_byte(1, 5); - byte_stuffer_recv_byte(1, 7); - byte_stuffer_recv_byte(1, 0); -} - -Ensure(ByteStuffer, receives_valid_frame_after_unexpected_non_zero) { - uint8_t expected[] = {5, 7}; - expect(validator_recv_frame, - when(size, is_equal_to(2)), - when(data, is_equal_to_contents_of(expected, 2)) - ); - byte_stuffer_recv_byte(0, 2); - byte_stuffer_recv_byte(0, 9); - byte_stuffer_recv_byte(0, 4); // This should have been zero - byte_stuffer_recv_byte(0, 0); - byte_stuffer_recv_byte(0, 3); - byte_stuffer_recv_byte(0, 5); - byte_stuffer_recv_byte(0, 7); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_and_then_end_of_frame) { - uint8_t expected[254]; - int i; - for (i=0;i<254;i++) { - expected[i] = i + 1; - } - expect(validator_recv_frame, - when(size, is_equal_to(254)), - when(data, is_equal_to_contents_of(expected, 254)) - ); - byte_stuffer_recv_byte(0, 0xFF); - for (i=0;i<254;i++) { - byte_stuffer_recv_byte(0, i+1); - } - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_non_zero) { - uint8_t expected[255]; - int i; - for (i=0;i<254;i++) { - expected[i] = i + 1; - } - expected[254] = 7; - expect(validator_recv_frame, - when(size, is_equal_to(255)), - when(data, is_equal_to_contents_of(expected, 255)) - ); - byte_stuffer_recv_byte(0, 0xFF); - for (i=0;i<254;i++) { - byte_stuffer_recv_byte(0, i+1); - } - byte_stuffer_recv_byte(0, 2); - byte_stuffer_recv_byte(0, 7); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_zero) { - uint8_t expected[255]; - int i; - for (i=0;i<254;i++) { - expected[i] = i + 1; - } - expected[254] = 0; - expect(validator_recv_frame, - when(size, is_equal_to(255)), - when(data, is_equal_to_contents_of(expected, 255)) - ); - byte_stuffer_recv_byte(0, 0xFF); - for (i=0;i<254;i++) { - byte_stuffer_recv_byte(0, i+1); - } - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_two_long_frames_and_some_more) { - uint8_t expected[515]; - int i; - int j; - for (j=0;j<2;j++) { - for (i=0;i<254;i++) { - expected[i+254*j] = i + 1; - } - } - for (i=0;i<7;i++) { - expected[254*2+i] = i + 1; - } - expect(validator_recv_frame, - when(size, is_equal_to(515)), - when(data, is_equal_to_contents_of(expected, 510)) - ); - byte_stuffer_recv_byte(0, 0xFF); - for (i=0;i<254;i++) { - byte_stuffer_recv_byte(0, i+1); - } - byte_stuffer_recv_byte(0, 0xFF); - for (i=0;i<254;i++) { - byte_stuffer_recv_byte(0, i+1); - } - byte_stuffer_recv_byte(0, 8); - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 2); - byte_stuffer_recv_byte(0, 3); - byte_stuffer_recv_byte(0, 4); - byte_stuffer_recv_byte(0, 5); - byte_stuffer_recv_byte(0, 6); - byte_stuffer_recv_byte(0, 7); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_an_all_zeros_frame_that_is_maximum_size) { - uint8_t expected[MAX_FRAME_SIZE] = {}; - expect(validator_recv_frame, - when(size, is_equal_to(MAX_FRAME_SIZE)), - when(data, is_equal_to_contents_of(expected, MAX_FRAME_SIZE)) - ); - int i; - byte_stuffer_recv_byte(0, 1); - for(i=0;i -#include -#include "serial_link/protocol/byte_stuffer.c" -#include "serial_link/protocol/frame_validator.c" -#include "serial_link/protocol/frame_router.c" -#include "serial_link/protocol/transport.h" - -static uint8_t received_data[256]; -static uint16_t received_data_size; - -typedef struct { - uint8_t sent_data[256]; - uint16_t sent_data_size; -} receive_buffer_t; - -typedef struct { - receive_buffer_t send_buffers[2]; -} router_buffer_t; - -router_buffer_t router_buffers[8]; - -router_buffer_t* current_router_buffer; - - -Describe(FrameRouter); -BeforeEach(FrameRouter) { - init_byte_stuffer(); - memset(router_buffers, 0, sizeof(router_buffers)); - current_router_buffer = 0; -} -AfterEach(FrameRouter) {} - -typedef struct { - uint32_t data; - uint8_t extra[16]; -} frame_buffer_t; - - -void send_data(uint8_t link, const uint8_t* data, uint16_t size) { - receive_buffer_t* buffer = ¤t_router_buffer->send_buffers[link]; - memcpy(buffer->sent_data + buffer->sent_data_size, data, size); - buffer->sent_data_size += size; -} - -static void receive_data(uint8_t link, uint8_t* data, uint16_t size) { - int i; - for(i=0;i to) { - receive_data(DOWN_LINK, - router_buffers[from].send_buffers[UP_LINK].sent_data, - router_buffers[from].send_buffers[UP_LINK].sent_data_size); - } - else if(to > from) { - receive_data(UP_LINK, - router_buffers[from].send_buffers[DOWN_LINK].sent_data, - router_buffers[from].send_buffers[DOWN_LINK].sent_data_size); - } -} - -void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) { - mock(from, data, size); -} - - -Ensure(FrameRouter, master_broadcast_is_received_by_everyone) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(0); - router_send_frame(0xFF, (uint8_t*)&data, 4); - assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - - expect(transport_recv_frame, - when(from, is_equal_to(0)), - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(&data.data, 4)) - ); - simulate_transport(0, 1); - assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - - expect(transport_recv_frame, - when(from, is_equal_to(0)), - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(&data.data, 4)) - ); - simulate_transport(1, 2); - assert_that(router_buffers[2].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[2].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); -} - -Ensure(FrameRouter, master_send_is_received_by_targets) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(0); - router_send_frame((1 << 1) | (1 << 2), (uint8_t*)&data, 4); - assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - - simulate_transport(0, 1); - assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - - expect(transport_recv_frame, - when(from, is_equal_to(0)), - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(&data.data, 4)) - ); - simulate_transport(1, 2); - assert_that(router_buffers[2].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[2].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - - expect(transport_recv_frame, - when(from, is_equal_to(0)), - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(&data.data, 4)) - ); - simulate_transport(2, 3); - assert_that(router_buffers[3].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[3].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); -} - -Ensure(FrameRouter, first_link_sends_to_master) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(1); - router_send_frame(0, (uint8_t*)&data, 4); - assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); - - expect(transport_recv_frame, - when(from, is_equal_to(1)), - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(&data.data, 4)) - ); - simulate_transport(1, 0); - assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); - assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); -} - -Ensure(FrameRouter, second_link_sends_to_master) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(2); - router_send_frame(0, (uint8_t*)&data, 4); - assert_that(router_buffers[2].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[2].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); - - simulate_transport(2, 1); - assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); - - expect(transport_recv_frame, - when(from, is_equal_to(2)), - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(&data.data, 4)) - ); - simulate_transport(1, 0); - assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); - assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); -} - -Ensure(FrameRouter, master_sends_to_master_does_nothing) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(0); - router_send_frame(0, (uint8_t*)&data, 4); - assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); -} - -Ensure(FrameRouter, link_sends_to_other_link_does_nothing) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(1); - router_send_frame(2, (uint8_t*)&data, 4); - assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); -} - -Ensure(FrameRouter, master_receives_on_uplink_does_nothing) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(1); - router_send_frame(0, (uint8_t*)&data, 4); - assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); - - never_expect(transport_recv_frame); - activate_router(0); - receive_data(UP_LINK, - router_buffers[1].send_buffers[UP_LINK].sent_data, - router_buffers[1].send_buffers[UP_LINK].sent_data_size); - assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); -} diff --git a/quantum/serial_link/serial_link/tests/frame_validator_tests.c b/quantum/serial_link/serial_link/tests/frame_validator_tests.c deleted file mode 100644 index d20947e2c..000000000 --- a/quantum/serial_link/serial_link/tests/frame_validator_tests.c +++ /dev/null @@ -1,101 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include -#include -#include "serial_link/protocol/frame_validator.c" - -void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size) { - mock(data, size); -} - -void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size) { - mock(data, size); -} - -Describe(FrameValidator); -BeforeEach(FrameValidator) {} -AfterEach(FrameValidator) {} - -Ensure(FrameValidator, doesnt_validate_frames_under_5_bytes) { - never_expect(route_incoming_frame); - uint8_t data[] = {1, 2}; - validator_recv_frame(0, 0, 1); - validator_recv_frame(0, data, 2); - validator_recv_frame(0, data, 3); - validator_recv_frame(0, data, 4); -} - -Ensure(FrameValidator, validates_one_byte_frame_with_correct_crc) { - uint8_t data[] = {0x44, 0x04, 0x6A, 0xB3, 0xA3}; - expect(route_incoming_frame, - when(size, is_equal_to(1)), - when(data, is_equal_to_contents_of(data, 1)) - ); - validator_recv_frame(0, data, 5); -} - -Ensure(FrameValidator, does_not_validate_one_byte_frame_with_incorrect_crc) { - uint8_t data[] = {0x44, 0, 0, 0, 0}; - never_expect(route_incoming_frame); - validator_recv_frame(1, data, 5); -} - -Ensure(FrameValidator, validates_four_byte_frame_with_correct_crc) { - uint8_t data[] = {0x44, 0x10, 0xFF, 0x00, 0x74, 0x4E, 0x30, 0xBA}; - expect(route_incoming_frame, - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(data, 4)) - ); - validator_recv_frame(1, data, 8); -} - -Ensure(FrameValidator, validates_five_byte_frame_with_correct_crc) { - uint8_t data[] = {1, 2, 3, 4, 5, 0xF4, 0x99, 0x0B, 0x47}; - expect(route_incoming_frame, - when(size, is_equal_to(5)), - when(data, is_equal_to_contents_of(data, 5)) - ); - validator_recv_frame(0, data, 9); -} - -Ensure(FrameValidator, sends_one_byte_with_correct_crc) { - uint8_t original[] = {0x44, 0, 0, 0, 0}; - uint8_t expected[] = {0x44, 0x04, 0x6A, 0xB3, 0xA3}; - expect(byte_stuffer_send_frame, - when(size, is_equal_to(sizeof(expected))), - when(data, is_equal_to_contents_of(expected, sizeof(expected))) - ); - validator_send_frame(0, original, 1); -} - -Ensure(FrameValidator, sends_five_bytes_with_correct_crc) { - uint8_t original[] = {1, 2, 3, 4, 5, 0, 0, 0, 0}; - uint8_t expected[] = {1, 2, 3, 4, 5, 0xF4, 0x99, 0x0B, 0x47}; - expect(byte_stuffer_send_frame, - when(size, is_equal_to(sizeof(expected))), - when(data, is_equal_to_contents_of(expected, sizeof(expected))) - ); - validator_send_frame(0, original, 5); -} diff --git a/quantum/serial_link/serial_link/tests/transport_tests.c b/quantum/serial_link/serial_link/tests/transport_tests.c deleted file mode 100644 index 358e1b9fd..000000000 --- a/quantum/serial_link/serial_link/tests/transport_tests.c +++ /dev/null @@ -1,168 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include -#include -#include "serial_link/protocol/transport.c" -#include "serial_link/protocol/triple_buffered_object.c" - -void signal_data_written(void) { - mock(); -} - -static uint8_t sent_data[2048]; -static uint16_t sent_data_size; - -void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) { - mock(destination); - memcpy(sent_data + sent_data_size, data, size); - sent_data_size += size; -} - -typedef struct { - uint32_t test; -} test_object1_t; - -typedef struct { - uint32_t test1; - uint32_t test2; -} test_object2_t; - -MASTER_TO_ALL_SLAVES_OBJECT(master_to_slave, test_object1_t); -MASTER_TO_SINGLE_SLAVE_OBJECT(master_to_single_slave, test_object1_t); -SLAVE_TO_MASTER_OBJECT(slave_to_master, test_object1_t); - -static remote_object_t* test_remote_objects[] = { - REMOTE_OBJECT(master_to_slave), - REMOTE_OBJECT(master_to_single_slave), - REMOTE_OBJECT(slave_to_master), -}; - -Describe(Transport); -BeforeEach(Transport) { - add_remote_objects(test_remote_objects, sizeof(test_remote_objects) / sizeof(remote_object_t*)); - sent_data_size = 0; -} -AfterEach(Transport) {} - -Ensure(Transport, write_to_local_signals_an_event) { - begin_write_master_to_slave(); - expect(signal_data_written); - end_write_master_to_slave(); - begin_write_slave_to_master(); - expect(signal_data_written); - end_write_slave_to_master(); - begin_write_master_to_single_slave(1); - expect(signal_data_written); - end_write_master_to_single_slave(1); -} - -Ensure(Transport, writes_from_master_to_all_slaves) { - update_transport(); - test_object1_t* obj = begin_write_master_to_slave(); - obj->test = 5; - expect(signal_data_written); - end_write_master_to_slave(); - expect(router_send_frame, - when(destination, is_equal_to(0xFF))); - update_transport(); - transport_recv_frame(0, sent_data, sent_data_size); - test_object1_t* obj2 = read_master_to_slave(); - assert_that(obj2, is_not_equal_to(NULL)); - assert_that(obj2->test, is_equal_to(5)); -} - -Ensure(Transport, writes_from_slave_to_master) { - update_transport(); - test_object1_t* obj = begin_write_slave_to_master(); - obj->test = 7; - expect(signal_data_written); - end_write_slave_to_master(); - expect(router_send_frame, - when(destination, is_equal_to(0))); - update_transport(); - transport_recv_frame(3, sent_data, sent_data_size); - test_object1_t* obj2 = read_slave_to_master(2); - assert_that(read_slave_to_master(0), is_equal_to(NULL)); - assert_that(obj2, is_not_equal_to(NULL)); - assert_that(obj2->test, is_equal_to(7)); -} - -Ensure(Transport, writes_from_master_to_single_slave) { - update_transport(); - test_object1_t* obj = begin_write_master_to_single_slave(3); - obj->test = 7; - expect(signal_data_written); - end_write_master_to_single_slave(3); - expect(router_send_frame, - when(destination, is_equal_to(4))); - update_transport(); - transport_recv_frame(0, sent_data, sent_data_size); - test_object1_t* obj2 = read_master_to_single_slave(); - assert_that(obj2, is_not_equal_to(NULL)); - assert_that(obj2->test, is_equal_to(7)); -} - -Ensure(Transport, ignores_object_with_invalid_id) { - update_transport(); - test_object1_t* obj = begin_write_master_to_single_slave(3); - obj->test = 7; - expect(signal_data_written); - end_write_master_to_single_slave(3); - expect(router_send_frame, - when(destination, is_equal_to(4))); - update_transport(); - sent_data[sent_data_size - 1] = 44; - transport_recv_frame(0, sent_data, sent_data_size); - test_object1_t* obj2 = read_master_to_single_slave(); - assert_that(obj2, is_equal_to(NULL)); -} - -Ensure(Transport, ignores_object_with_size_too_small) { - update_transport(); - test_object1_t* obj = begin_write_master_to_slave(); - obj->test = 7; - expect(signal_data_written); - end_write_master_to_slave(); - expect(router_send_frame); - update_transport(); - sent_data[sent_data_size - 2] = 0; - transport_recv_frame(0, sent_data, sent_data_size - 1); - test_object1_t* obj2 = read_master_to_slave(); - assert_that(obj2, is_equal_to(NULL)); -} - -Ensure(Transport, ignores_object_with_size_too_big) { - update_transport(); - test_object1_t* obj = begin_write_master_to_slave(); - obj->test = 7; - expect(signal_data_written); - end_write_master_to_slave(); - expect(router_send_frame); - update_transport(); - sent_data[sent_data_size + 21] = 0; - transport_recv_frame(0, sent_data, sent_data_size + 22); - test_object1_t* obj2 = read_master_to_slave(); - assert_that(obj2, is_equal_to(NULL)); -} diff --git a/quantum/serial_link/serial_link/tests/triple_buffered_object_tests.c b/quantum/serial_link/serial_link/tests/triple_buffered_object_tests.c deleted file mode 100644 index 6f7c82b46..000000000 --- a/quantum/serial_link/serial_link/tests/triple_buffered_object_tests.c +++ /dev/null @@ -1,82 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include -#include "serial_link/protocol/triple_buffered_object.c" - -typedef struct { - uint8_t state; - uint32_t buffer[3]; -}test_object_t; - -test_object_t test_object; - -Describe(TripleBufferedObject); -BeforeEach(TripleBufferedObject) { - triple_buffer_init((triple_buffer_object_t*)&test_object); -} -AfterEach(TripleBufferedObject) {} - - -Ensure(TripleBufferedObject, writes_and_reads_object) { - *triple_buffer_begin_write(&test_object) = 0x3456ABCC; - triple_buffer_end_write(&test_object); - assert_that(*triple_buffer_read(&test_object), is_equal_to(0x3456ABCC)); -} - -Ensure(TripleBufferedObject, does_not_read_empty) { - assert_that(triple_buffer_read(&test_object), is_equal_to(NULL)); -} - -Ensure(TripleBufferedObject, writes_twice_and_reads_object) { - *triple_buffer_begin_write(&test_object) = 0x3456ABCC; - triple_buffer_end_write(&test_object); - *triple_buffer_begin_write(&test_object) = 0x44778899; - triple_buffer_end_write(&test_object); - assert_that(*triple_buffer_read(&test_object), is_equal_to(0x44778899)); -} - -Ensure(TripleBufferedObject, performs_another_write_in_the_middle_of_read) { - *triple_buffer_begin_write(&test_object) = 1; - triple_buffer_end_write(&test_object); - uint32_t* read = triple_buffer_read(&test_object); - *triple_buffer_begin_write(&test_object) = 2; - triple_buffer_end_write(&test_object); - assert_that(*read, is_equal_to(1)); - assert_that(*triple_buffer_read(&test_object), is_equal_to(2)); - assert_that(triple_buffer_read(&test_object), is_equal_to(NULL)); -} - -Ensure(TripleBufferedObject, performs_two_writes_in_the_middle_of_read) { - *triple_buffer_begin_write(&test_object) = 1; - triple_buffer_end_write(&test_object); - uint32_t* read = triple_buffer_read(&test_object); - *triple_buffer_begin_write(&test_object) = 2; - triple_buffer_end_write(&test_object); - *triple_buffer_begin_write(&test_object) = 3; - triple_buffer_end_write(&test_object); - assert_that(*read, is_equal_to(1)); - assert_that(*triple_buffer_read(&test_object), is_equal_to(3)); - assert_that(triple_buffer_read(&test_object), is_equal_to(NULL)); -} diff --git a/quantum/serial_link/serial_link_tests.mk b/quantum/serial_link/serial_link_tests.mk deleted file mode 100644 index e292f582a..000000000 --- a/quantum/serial_link/serial_link_tests.mk +++ /dev/null @@ -1,34 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2016 Fred Sundvik -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -CGREEN_LIB = $(BUILDDIR)/cgreen/build-c/src/libcgreen.a - -CGREEN_DIR = "$(CURDIR)/$(SERIAL_DIR)/cgreen/cgreen" -CGREEN_BUILD_DIR = "$(CURDIR)/$(BUILDDIR)/cgreen" -export CGREEN_DIR -export CGREEN_BUILD_DIR -$(CGREEN_LIB): - @make -C $(SERIAL_DIR)/cgreen - -.PHONY serialtest: -serialtest : $(CGREEN_LIB) - @make -C $(SERIAL_DIR)/serial_link/tests BUILDDIR=../../../$(BUILDDIR) \ No newline at end of file diff --git a/quantum/serial_link/system/serial_link.c b/quantum/serial_link/system/serial_link.c new file mode 100644 index 000000000..75c7e77a7 --- /dev/null +++ b/quantum/serial_link/system/serial_link.c @@ -0,0 +1,265 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ +#include "report.h" +#include "host_driver.h" +#include "serial_link/system/serial_link.h" +#include "hal.h" +#include "serial_link/protocol/byte_stuffer.h" +#include "serial_link/protocol/transport.h" +#include "serial_link/protocol/frame_router.h" +#include "matrix.h" +#include +#include "print.h" +#include "config.h" + +static event_source_t new_data_event; +static bool serial_link_connected; +static bool is_master = false; + +static uint8_t keyboard_leds(void); +static void send_keyboard(report_keyboard_t *report); +static void send_mouse(report_mouse_t *report); +static void send_system(uint16_t data); +static void send_consumer(uint16_t data); + +host_driver_t serial_driver = { + keyboard_leds, + send_keyboard, + send_mouse, + send_system, + send_consumer +}; + +// Define these in your Config.h file +#ifndef SERIAL_LINK_BAUD +#error "Serial link baud is not set" +#endif + +#ifndef SERIAL_LINK_THREAD_PRIORITY +#error "Serial link thread priority not set" +#endif + +static SerialConfig config = { + .sc_speed = SERIAL_LINK_BAUD +}; + +//#define DEBUG_LINK_ERRORS + +static uint32_t read_from_serial(SerialDriver* driver, uint8_t link) { + const uint32_t buffer_size = 16; + uint8_t buffer[buffer_size]; + uint32_t bytes_read = sdAsynchronousRead(driver, buffer, buffer_size); + uint8_t* current = buffer; + uint8_t* end = current + bytes_read; + while(current < end) { + byte_stuffer_recv_byte(link, *current); + current++; + } + return bytes_read; +} + +static void print_error(char* str, eventflags_t flags, SerialDriver* driver) { +#ifdef DEBUG_LINK_ERRORS + if (flags & SD_PARITY_ERROR) { + print(str); + print(" Parity error\n"); + } + if (flags & SD_FRAMING_ERROR) { + print(str); + print(" Framing error\n"); + } + if (flags & SD_OVERRUN_ERROR) { + print(str); + uint32_t size = qSpaceI(&(driver->iqueue)); + xprintf(" Overrun error, queue size %d\n", size); + + } + if (flags & SD_NOISE_ERROR) { + print(str); + print(" Noise error\n"); + } + if (flags & SD_BREAK_DETECTED) { + print(str); + print(" Break detected\n"); + } +#else + (void)str; + (void)flags; + (void)driver; +#endif +} + +bool is_serial_link_master(void) { + return is_master; +} + +// TODO: Optimize the stack size, this is probably way too big +static THD_WORKING_AREA(serialThreadStack, 1024); +static THD_FUNCTION(serialThread, arg) { + (void)arg; + event_listener_t new_data_listener; + event_listener_t sd1_listener; + event_listener_t sd2_listener; + chEvtRegister(&new_data_event, &new_data_listener, 0); + eventflags_t events = CHN_INPUT_AVAILABLE + | SD_PARITY_ERROR | SD_FRAMING_ERROR | SD_OVERRUN_ERROR | SD_NOISE_ERROR | SD_BREAK_DETECTED; + chEvtRegisterMaskWithFlags(chnGetEventSource(&SD1), + &sd1_listener, + EVENT_MASK(1), + events); + chEvtRegisterMaskWithFlags(chnGetEventSource(&SD2), + &sd2_listener, + EVENT_MASK(2), + events); + bool need_wait = false; + while(true) { + eventflags_t flags1 = 0; + eventflags_t flags2 = 0; + if (need_wait) { + eventmask_t mask = chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(1000)); + if (mask & EVENT_MASK(1)) { + flags1 = chEvtGetAndClearFlags(&sd1_listener); + print_error("DOWNLINK", flags1, &SD1); + } + if (mask & EVENT_MASK(2)) { + flags2 = chEvtGetAndClearFlags(&sd2_listener); + print_error("UPLINK", flags2, &SD2); + } + } + + // Always stay as master, even if the USB goes into sleep mode + is_master |= usbGetDriverStateI(&USBD1) == USB_ACTIVE; + router_set_master(is_master); + + need_wait = true; + need_wait &= read_from_serial(&SD2, UP_LINK) == 0; + need_wait &= read_from_serial(&SD1, DOWN_LINK) == 0; + update_transport(); + } +} + +void send_data(uint8_t link, const uint8_t* data, uint16_t size) { + if (link == DOWN_LINK) { + sdWrite(&SD1, data, size); + } + else { + sdWrite(&SD2, data, size); + } +} + +static systime_t last_update = 0; + +typedef struct { + matrix_row_t rows[MATRIX_ROWS]; +} matrix_object_t; + +static matrix_object_t last_matrix = {}; + +SLAVE_TO_MASTER_OBJECT(keyboard_matrix, matrix_object_t); +MASTER_TO_ALL_SLAVES_OBJECT(serial_link_connected, bool); + +static remote_object_t* remote_objects[] = { + REMOTE_OBJECT(serial_link_connected), + REMOTE_OBJECT(keyboard_matrix), +}; + +void init_serial_link(void) { + serial_link_connected = false; + init_serial_link_hal(); + add_remote_objects(remote_objects, sizeof(remote_objects)/sizeof(remote_object_t*)); + init_byte_stuffer(); + sdStart(&SD1, &config); + sdStart(&SD2, &config); + chEvtObjectInit(&new_data_event); + (void)chThdCreateStatic(serialThreadStack, sizeof(serialThreadStack), + SERIAL_LINK_THREAD_PRIORITY, serialThread, NULL); +} + +void matrix_set_remote(matrix_row_t* rows, uint8_t index); + +void serial_link_update(void) { + if (read_serial_link_connected()) { + serial_link_connected = true; + } + + matrix_object_t matrix; + bool changed = false; + for(uint8_t i=0;i US2ST(1000)) { + last_update = current_time; + last_matrix = matrix; + matrix_object_t* m = begin_write_keyboard_matrix(); + for(uint8_t i=0;irows[i] = matrix.rows[i]; + } + end_write_keyboard_matrix(); + *begin_write_serial_link_connected() = true; + end_write_serial_link_connected(); + } + + matrix_object_t* m = read_keyboard_matrix(0); + if (m) { + matrix_set_remote(m->rows, 0); + } +} + +void signal_data_written(void) { + chEvtBroadcast(&new_data_event); +} + +bool is_serial_link_connected(void) { + return serial_link_connected; +} + +host_driver_t* get_serial_link_driver(void) { + return &serial_driver; +} + +// NOTE: The driver does nothing, because the master handles everything +uint8_t keyboard_leds(void) { + return 0; +} + +void send_keyboard(report_keyboard_t *report) { + (void)report; +} + +void send_mouse(report_mouse_t *report) { + (void)report; +} + +void send_system(uint16_t data) { + (void)data; +} + +void send_consumer(uint16_t data) { + (void)data; +} + diff --git a/quantum/serial_link/system/serial_link.h b/quantum/serial_link/system/serial_link.h new file mode 100644 index 000000000..351e03877 --- /dev/null +++ b/quantum/serial_link/system/serial_link.h @@ -0,0 +1,63 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef SERIAL_LINK_H +#define SERIAL_LINK_H + +#include "host_driver.h" +#include + +void init_serial_link(void); +void init_serial_link_hal(void); +bool is_serial_link_connected(void); +bool is_serial_link_master(void); +host_driver_t* get_serial_link_driver(void); +void serial_link_update(void); + +#if defined(PROTOCOL_CHIBIOS) +#include "ch.h" + +static inline void serial_link_lock(void) { + chSysLock(); +} + +static inline void serial_link_unlock(void) { + chSysUnlock(); +} + +void signal_data_written(void); + +#else + +inline void serial_link_lock(void) { +} + +inline void serial_link_unlock(void) { +} + +void signal_data_written(void); + +#endif + +#endif diff --git a/quantum/serial_link/tests/Makefile b/quantum/serial_link/tests/Makefile new file mode 100644 index 000000000..1b072c6f1 --- /dev/null +++ b/quantum/serial_link/tests/Makefile @@ -0,0 +1,61 @@ +# The MIT License (MIT) +# +# Copyright (c) 2016 Fred Sundvik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +CC = gcc +CFLAGS = +INCLUDES = -I. -I../../ +LDFLAGS = -L$(BUILDDIR)/cgreen/build-c/src -shared +LDLIBS = -lcgreen +UNITOBJ = $(BUILDDIR)/serialtest/unitobj +DEPDIR = $(BUILDDIR)/serialtest/unit.d +UNITTESTS = $(BUILDDIR)/serialtest/unittests +DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td +EXT = .so +UNAME := $(shell uname) +ifneq (, $(findstring MINGW, $(UNAME))) + EXT = .dll +endif +ifneq (, $(findstring CYGWIN, $(UNAME))) + EXT = .dll +endif + +SRC = $(wildcard *.c) +TESTFILES = $(patsubst %.c, $(UNITTESTS)/%$(EXT), $(SRC)) +$(shell mkdir -p $(DEPDIR) >/dev/null) + +test: $(TESTFILES) + @$(BUILDDIR)/cgreen/build-c/tools/cgreen-runner --color $(TESTFILES) + +$(UNITTESTS)/%$(EXT): $(UNITOBJ)/%.o + @mkdir -p $(UNITTESTS) + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) + +$(UNITOBJ)/%.o : %.c +$(UNITOBJ)/%.o: %.c $(DEPDIR)/%.d + @mkdir -p $(UNITOBJ) + $(CC) $(CFLAGS) $(DEPFLAGS) $(INCLUDES) -c $< -o $@ + @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d + +$(DEPDIR)/%.d: ; +.PRECIOUS: $(DEPDIR)/%.d + +-include $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRC))) \ No newline at end of file diff --git a/quantum/serial_link/tests/byte_stuffer_tests.c b/quantum/serial_link/tests/byte_stuffer_tests.c new file mode 100644 index 000000000..64b170e8c --- /dev/null +++ b/quantum/serial_link/tests/byte_stuffer_tests.c @@ -0,0 +1,506 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include +#include +#include "serial_link/protocol/byte_stuffer.h" +#include "serial_link/protocol/byte_stuffer.c" +#include "serial_link/protocol/frame_validator.h" +#include "serial_link/protocol/physical.h" + +static uint8_t sent_data[MAX_FRAME_SIZE*2]; +static uint16_t sent_data_size; + +Describe(ByteStuffer); +BeforeEach(ByteStuffer) { + init_byte_stuffer(); + sent_data_size = 0; +} +AfterEach(ByteStuffer) {} + +void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size) { + mock(data, size); +} + +void send_data(uint8_t link, const uint8_t* data, uint16_t size) { + memcpy(sent_data + sent_data_size, data, size); + sent_data_size += size; +} + +Ensure(ByteStuffer, receives_no_frame_for_a_single_zero_byte) { + never_expect(validator_recv_frame); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_no_frame_for_a_single_FF_byte) { + never_expect(validator_recv_frame); + byte_stuffer_recv_byte(0, 0xFF); +} + +Ensure(ByteStuffer, receives_no_frame_for_a_single_random_byte) { + never_expect(validator_recv_frame); + byte_stuffer_recv_byte(0, 0x4A); +} + +Ensure(ByteStuffer, receives_no_frame_for_a_zero_length_frame) { + never_expect(validator_recv_frame); + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_single_byte_valid_frame) { + uint8_t expected[] = {0x37}; + expect(validator_recv_frame, + when(size, is_equal_to(1)), + when(data, is_equal_to_contents_of(expected, 1)) + ); + byte_stuffer_recv_byte(0, 2); + byte_stuffer_recv_byte(0, 0x37); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_three_bytes_valid_frame) { + uint8_t expected[] = {0x37, 0x99, 0xFF}; + expect(validator_recv_frame, + when(size, is_equal_to(3)), + when(data, is_equal_to_contents_of(expected, 3)) + ); + byte_stuffer_recv_byte(0, 4); + byte_stuffer_recv_byte(0, 0x37); + byte_stuffer_recv_byte(0, 0x99); + byte_stuffer_recv_byte(0, 0xFF); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_single_zero_valid_frame) { + uint8_t expected[] = {0}; + expect(validator_recv_frame, + when(size, is_equal_to(1)), + when(data, is_equal_to_contents_of(expected, 1)) + ); + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_valid_frame_with_zeroes) { + uint8_t expected[] = {5, 0, 3, 0}; + expect(validator_recv_frame, + when(size, is_equal_to(4)), + when(data, is_equal_to_contents_of(expected, 4)) + ); + byte_stuffer_recv_byte(0, 2); + byte_stuffer_recv_byte(0, 5); + byte_stuffer_recv_byte(0, 2); + byte_stuffer_recv_byte(0, 3); + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_two_valid_frames) { + uint8_t expected1[] = {5, 0}; + uint8_t expected2[] = {3}; + expect(validator_recv_frame, + when(size, is_equal_to(2)), + when(data, is_equal_to_contents_of(expected1, 2)) + ); + expect(validator_recv_frame, + when(size, is_equal_to(1)), + when(data, is_equal_to_contents_of(expected2, 1)) + ); + byte_stuffer_recv_byte(1, 2); + byte_stuffer_recv_byte(1, 5); + byte_stuffer_recv_byte(1, 1); + byte_stuffer_recv_byte(1, 0); + byte_stuffer_recv_byte(1, 2); + byte_stuffer_recv_byte(1, 3); + byte_stuffer_recv_byte(1, 0); +} + +Ensure(ByteStuffer, receives_valid_frame_after_unexpected_zero) { + uint8_t expected[] = {5, 7}; + expect(validator_recv_frame, + when(size, is_equal_to(2)), + when(data, is_equal_to_contents_of(expected, 2)) + ); + byte_stuffer_recv_byte(1, 3); + byte_stuffer_recv_byte(1, 1); + byte_stuffer_recv_byte(1, 0); + byte_stuffer_recv_byte(1, 3); + byte_stuffer_recv_byte(1, 5); + byte_stuffer_recv_byte(1, 7); + byte_stuffer_recv_byte(1, 0); +} + +Ensure(ByteStuffer, receives_valid_frame_after_unexpected_non_zero) { + uint8_t expected[] = {5, 7}; + expect(validator_recv_frame, + when(size, is_equal_to(2)), + when(data, is_equal_to_contents_of(expected, 2)) + ); + byte_stuffer_recv_byte(0, 2); + byte_stuffer_recv_byte(0, 9); + byte_stuffer_recv_byte(0, 4); // This should have been zero + byte_stuffer_recv_byte(0, 0); + byte_stuffer_recv_byte(0, 3); + byte_stuffer_recv_byte(0, 5); + byte_stuffer_recv_byte(0, 7); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_and_then_end_of_frame) { + uint8_t expected[254]; + int i; + for (i=0;i<254;i++) { + expected[i] = i + 1; + } + expect(validator_recv_frame, + when(size, is_equal_to(254)), + when(data, is_equal_to_contents_of(expected, 254)) + ); + byte_stuffer_recv_byte(0, 0xFF); + for (i=0;i<254;i++) { + byte_stuffer_recv_byte(0, i+1); + } + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_non_zero) { + uint8_t expected[255]; + int i; + for (i=0;i<254;i++) { + expected[i] = i + 1; + } + expected[254] = 7; + expect(validator_recv_frame, + when(size, is_equal_to(255)), + when(data, is_equal_to_contents_of(expected, 255)) + ); + byte_stuffer_recv_byte(0, 0xFF); + for (i=0;i<254;i++) { + byte_stuffer_recv_byte(0, i+1); + } + byte_stuffer_recv_byte(0, 2); + byte_stuffer_recv_byte(0, 7); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_zero) { + uint8_t expected[255]; + int i; + for (i=0;i<254;i++) { + expected[i] = i + 1; + } + expected[254] = 0; + expect(validator_recv_frame, + when(size, is_equal_to(255)), + when(data, is_equal_to_contents_of(expected, 255)) + ); + byte_stuffer_recv_byte(0, 0xFF); + for (i=0;i<254;i++) { + byte_stuffer_recv_byte(0, i+1); + } + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_two_long_frames_and_some_more) { + uint8_t expected[515]; + int i; + int j; + for (j=0;j<2;j++) { + for (i=0;i<254;i++) { + expected[i+254*j] = i + 1; + } + } + for (i=0;i<7;i++) { + expected[254*2+i] = i + 1; + } + expect(validator_recv_frame, + when(size, is_equal_to(515)), + when(data, is_equal_to_contents_of(expected, 510)) + ); + byte_stuffer_recv_byte(0, 0xFF); + for (i=0;i<254;i++) { + byte_stuffer_recv_byte(0, i+1); + } + byte_stuffer_recv_byte(0, 0xFF); + for (i=0;i<254;i++) { + byte_stuffer_recv_byte(0, i+1); + } + byte_stuffer_recv_byte(0, 8); + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 2); + byte_stuffer_recv_byte(0, 3); + byte_stuffer_recv_byte(0, 4); + byte_stuffer_recv_byte(0, 5); + byte_stuffer_recv_byte(0, 6); + byte_stuffer_recv_byte(0, 7); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_an_all_zeros_frame_that_is_maximum_size) { + uint8_t expected[MAX_FRAME_SIZE] = {}; + expect(validator_recv_frame, + when(size, is_equal_to(MAX_FRAME_SIZE)), + when(data, is_equal_to_contents_of(expected, MAX_FRAME_SIZE)) + ); + int i; + byte_stuffer_recv_byte(0, 1); + for(i=0;i +#include +#include "serial_link/protocol/byte_stuffer.c" +#include "serial_link/protocol/frame_validator.c" +#include "serial_link/protocol/frame_router.c" +#include "serial_link/protocol/transport.h" + +static uint8_t received_data[256]; +static uint16_t received_data_size; + +typedef struct { + uint8_t sent_data[256]; + uint16_t sent_data_size; +} receive_buffer_t; + +typedef struct { + receive_buffer_t send_buffers[2]; +} router_buffer_t; + +router_buffer_t router_buffers[8]; + +router_buffer_t* current_router_buffer; + + +Describe(FrameRouter); +BeforeEach(FrameRouter) { + init_byte_stuffer(); + memset(router_buffers, 0, sizeof(router_buffers)); + current_router_buffer = 0; +} +AfterEach(FrameRouter) {} + +typedef struct { + uint32_t data; + uint8_t extra[16]; +} frame_buffer_t; + + +void send_data(uint8_t link, const uint8_t* data, uint16_t size) { + receive_buffer_t* buffer = ¤t_router_buffer->send_buffers[link]; + memcpy(buffer->sent_data + buffer->sent_data_size, data, size); + buffer->sent_data_size += size; +} + +static void receive_data(uint8_t link, uint8_t* data, uint16_t size) { + int i; + for(i=0;i to) { + receive_data(DOWN_LINK, + router_buffers[from].send_buffers[UP_LINK].sent_data, + router_buffers[from].send_buffers[UP_LINK].sent_data_size); + } + else if(to > from) { + receive_data(UP_LINK, + router_buffers[from].send_buffers[DOWN_LINK].sent_data, + router_buffers[from].send_buffers[DOWN_LINK].sent_data_size); + } +} + +void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) { + mock(from, data, size); +} + + +Ensure(FrameRouter, master_broadcast_is_received_by_everyone) { + frame_buffer_t data; + data.data = 0xAB7055BB; + activate_router(0); + router_send_frame(0xFF, (uint8_t*)&data, 4); + assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); + + expect(transport_recv_frame, + when(from, is_equal_to(0)), + when(size, is_equal_to(4)), + when(data, is_equal_to_contents_of(&data.data, 4)) + ); + simulate_transport(0, 1); + assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); + + expect(transport_recv_frame, + when(from, is_equal_to(0)), + when(size, is_equal_to(4)), + when(data, is_equal_to_contents_of(&data.data, 4)) + ); + simulate_transport(1, 2); + assert_that(router_buffers[2].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[2].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); +} + +Ensure(FrameRouter, master_send_is_received_by_targets) { + frame_buffer_t data; + data.data = 0xAB7055BB; + activate_router(0); + router_send_frame((1 << 1) | (1 << 2), (uint8_t*)&data, 4); + assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); + + simulate_transport(0, 1); + assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); + + expect(transport_recv_frame, + when(from, is_equal_to(0)), + when(size, is_equal_to(4)), + when(data, is_equal_to_contents_of(&data.data, 4)) + ); + simulate_transport(1, 2); + assert_that(router_buffers[2].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[2].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); + + expect(transport_recv_frame, + when(from, is_equal_to(0)), + when(size, is_equal_to(4)), + when(data, is_equal_to_contents_of(&data.data, 4)) + ); + simulate_transport(2, 3); + assert_that(router_buffers[3].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[3].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); +} + +Ensure(FrameRouter, first_link_sends_to_master) { + frame_buffer_t data; + data.data = 0xAB7055BB; + activate_router(1); + router_send_frame(0, (uint8_t*)&data, 4); + assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); + + expect(transport_recv_frame, + when(from, is_equal_to(1)), + when(size, is_equal_to(4)), + when(data, is_equal_to_contents_of(&data.data, 4)) + ); + simulate_transport(1, 0); + assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); + assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); +} + +Ensure(FrameRouter, second_link_sends_to_master) { + frame_buffer_t data; + data.data = 0xAB7055BB; + activate_router(2); + router_send_frame(0, (uint8_t*)&data, 4); + assert_that(router_buffers[2].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[2].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); + + simulate_transport(2, 1); + assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); + + expect(transport_recv_frame, + when(from, is_equal_to(2)), + when(size, is_equal_to(4)), + when(data, is_equal_to_contents_of(&data.data, 4)) + ); + simulate_transport(1, 0); + assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); + assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); +} + +Ensure(FrameRouter, master_sends_to_master_does_nothing) { + frame_buffer_t data; + data.data = 0xAB7055BB; + activate_router(0); + router_send_frame(0, (uint8_t*)&data, 4); + assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); + assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); +} + +Ensure(FrameRouter, link_sends_to_other_link_does_nothing) { + frame_buffer_t data; + data.data = 0xAB7055BB; + activate_router(1); + router_send_frame(2, (uint8_t*)&data, 4); + assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); + assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); +} + +Ensure(FrameRouter, master_receives_on_uplink_does_nothing) { + frame_buffer_t data; + data.data = 0xAB7055BB; + activate_router(1); + router_send_frame(0, (uint8_t*)&data, 4); + assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); + + never_expect(transport_recv_frame); + activate_router(0); + receive_data(UP_LINK, + router_buffers[1].send_buffers[UP_LINK].sent_data, + router_buffers[1].send_buffers[UP_LINK].sent_data_size); + assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); + assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); +} diff --git a/quantum/serial_link/tests/frame_validator_tests.c b/quantum/serial_link/tests/frame_validator_tests.c new file mode 100644 index 000000000..d20947e2c --- /dev/null +++ b/quantum/serial_link/tests/frame_validator_tests.c @@ -0,0 +1,101 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include +#include +#include "serial_link/protocol/frame_validator.c" + +void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size) { + mock(data, size); +} + +void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size) { + mock(data, size); +} + +Describe(FrameValidator); +BeforeEach(FrameValidator) {} +AfterEach(FrameValidator) {} + +Ensure(FrameValidator, doesnt_validate_frames_under_5_bytes) { + never_expect(route_incoming_frame); + uint8_t data[] = {1, 2}; + validator_recv_frame(0, 0, 1); + validator_recv_frame(0, data, 2); + validator_recv_frame(0, data, 3); + validator_recv_frame(0, data, 4); +} + +Ensure(FrameValidator, validates_one_byte_frame_with_correct_crc) { + uint8_t data[] = {0x44, 0x04, 0x6A, 0xB3, 0xA3}; + expect(route_incoming_frame, + when(size, is_equal_to(1)), + when(data, is_equal_to_contents_of(data, 1)) + ); + validator_recv_frame(0, data, 5); +} + +Ensure(FrameValidator, does_not_validate_one_byte_frame_with_incorrect_crc) { + uint8_t data[] = {0x44, 0, 0, 0, 0}; + never_expect(route_incoming_frame); + validator_recv_frame(1, data, 5); +} + +Ensure(FrameValidator, validates_four_byte_frame_with_correct_crc) { + uint8_t data[] = {0x44, 0x10, 0xFF, 0x00, 0x74, 0x4E, 0x30, 0xBA}; + expect(route_incoming_frame, + when(size, is_equal_to(4)), + when(data, is_equal_to_contents_of(data, 4)) + ); + validator_recv_frame(1, data, 8); +} + +Ensure(FrameValidator, validates_five_byte_frame_with_correct_crc) { + uint8_t data[] = {1, 2, 3, 4, 5, 0xF4, 0x99, 0x0B, 0x47}; + expect(route_incoming_frame, + when(size, is_equal_to(5)), + when(data, is_equal_to_contents_of(data, 5)) + ); + validator_recv_frame(0, data, 9); +} + +Ensure(FrameValidator, sends_one_byte_with_correct_crc) { + uint8_t original[] = {0x44, 0, 0, 0, 0}; + uint8_t expected[] = {0x44, 0x04, 0x6A, 0xB3, 0xA3}; + expect(byte_stuffer_send_frame, + when(size, is_equal_to(sizeof(expected))), + when(data, is_equal_to_contents_of(expected, sizeof(expected))) + ); + validator_send_frame(0, original, 1); +} + +Ensure(FrameValidator, sends_five_bytes_with_correct_crc) { + uint8_t original[] = {1, 2, 3, 4, 5, 0, 0, 0, 0}; + uint8_t expected[] = {1, 2, 3, 4, 5, 0xF4, 0x99, 0x0B, 0x47}; + expect(byte_stuffer_send_frame, + when(size, is_equal_to(sizeof(expected))), + when(data, is_equal_to_contents_of(expected, sizeof(expected))) + ); + validator_send_frame(0, original, 5); +} diff --git a/quantum/serial_link/tests/transport_tests.c b/quantum/serial_link/tests/transport_tests.c new file mode 100644 index 000000000..358e1b9fd --- /dev/null +++ b/quantum/serial_link/tests/transport_tests.c @@ -0,0 +1,168 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include +#include +#include "serial_link/protocol/transport.c" +#include "serial_link/protocol/triple_buffered_object.c" + +void signal_data_written(void) { + mock(); +} + +static uint8_t sent_data[2048]; +static uint16_t sent_data_size; + +void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) { + mock(destination); + memcpy(sent_data + sent_data_size, data, size); + sent_data_size += size; +} + +typedef struct { + uint32_t test; +} test_object1_t; + +typedef struct { + uint32_t test1; + uint32_t test2; +} test_object2_t; + +MASTER_TO_ALL_SLAVES_OBJECT(master_to_slave, test_object1_t); +MASTER_TO_SINGLE_SLAVE_OBJECT(master_to_single_slave, test_object1_t); +SLAVE_TO_MASTER_OBJECT(slave_to_master, test_object1_t); + +static remote_object_t* test_remote_objects[] = { + REMOTE_OBJECT(master_to_slave), + REMOTE_OBJECT(master_to_single_slave), + REMOTE_OBJECT(slave_to_master), +}; + +Describe(Transport); +BeforeEach(Transport) { + add_remote_objects(test_remote_objects, sizeof(test_remote_objects) / sizeof(remote_object_t*)); + sent_data_size = 0; +} +AfterEach(Transport) {} + +Ensure(Transport, write_to_local_signals_an_event) { + begin_write_master_to_slave(); + expect(signal_data_written); + end_write_master_to_slave(); + begin_write_slave_to_master(); + expect(signal_data_written); + end_write_slave_to_master(); + begin_write_master_to_single_slave(1); + expect(signal_data_written); + end_write_master_to_single_slave(1); +} + +Ensure(Transport, writes_from_master_to_all_slaves) { + update_transport(); + test_object1_t* obj = begin_write_master_to_slave(); + obj->test = 5; + expect(signal_data_written); + end_write_master_to_slave(); + expect(router_send_frame, + when(destination, is_equal_to(0xFF))); + update_transport(); + transport_recv_frame(0, sent_data, sent_data_size); + test_object1_t* obj2 = read_master_to_slave(); + assert_that(obj2, is_not_equal_to(NULL)); + assert_that(obj2->test, is_equal_to(5)); +} + +Ensure(Transport, writes_from_slave_to_master) { + update_transport(); + test_object1_t* obj = begin_write_slave_to_master(); + obj->test = 7; + expect(signal_data_written); + end_write_slave_to_master(); + expect(router_send_frame, + when(destination, is_equal_to(0))); + update_transport(); + transport_recv_frame(3, sent_data, sent_data_size); + test_object1_t* obj2 = read_slave_to_master(2); + assert_that(read_slave_to_master(0), is_equal_to(NULL)); + assert_that(obj2, is_not_equal_to(NULL)); + assert_that(obj2->test, is_equal_to(7)); +} + +Ensure(Transport, writes_from_master_to_single_slave) { + update_transport(); + test_object1_t* obj = begin_write_master_to_single_slave(3); + obj->test = 7; + expect(signal_data_written); + end_write_master_to_single_slave(3); + expect(router_send_frame, + when(destination, is_equal_to(4))); + update_transport(); + transport_recv_frame(0, sent_data, sent_data_size); + test_object1_t* obj2 = read_master_to_single_slave(); + assert_that(obj2, is_not_equal_to(NULL)); + assert_that(obj2->test, is_equal_to(7)); +} + +Ensure(Transport, ignores_object_with_invalid_id) { + update_transport(); + test_object1_t* obj = begin_write_master_to_single_slave(3); + obj->test = 7; + expect(signal_data_written); + end_write_master_to_single_slave(3); + expect(router_send_frame, + when(destination, is_equal_to(4))); + update_transport(); + sent_data[sent_data_size - 1] = 44; + transport_recv_frame(0, sent_data, sent_data_size); + test_object1_t* obj2 = read_master_to_single_slave(); + assert_that(obj2, is_equal_to(NULL)); +} + +Ensure(Transport, ignores_object_with_size_too_small) { + update_transport(); + test_object1_t* obj = begin_write_master_to_slave(); + obj->test = 7; + expect(signal_data_written); + end_write_master_to_slave(); + expect(router_send_frame); + update_transport(); + sent_data[sent_data_size - 2] = 0; + transport_recv_frame(0, sent_data, sent_data_size - 1); + test_object1_t* obj2 = read_master_to_slave(); + assert_that(obj2, is_equal_to(NULL)); +} + +Ensure(Transport, ignores_object_with_size_too_big) { + update_transport(); + test_object1_t* obj = begin_write_master_to_slave(); + obj->test = 7; + expect(signal_data_written); + end_write_master_to_slave(); + expect(router_send_frame); + update_transport(); + sent_data[sent_data_size + 21] = 0; + transport_recv_frame(0, sent_data, sent_data_size + 22); + test_object1_t* obj2 = read_master_to_slave(); + assert_that(obj2, is_equal_to(NULL)); +} diff --git a/quantum/serial_link/tests/triple_buffered_object_tests.c b/quantum/serial_link/tests/triple_buffered_object_tests.c new file mode 100644 index 000000000..6f7c82b46 --- /dev/null +++ b/quantum/serial_link/tests/triple_buffered_object_tests.c @@ -0,0 +1,82 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include +#include "serial_link/protocol/triple_buffered_object.c" + +typedef struct { + uint8_t state; + uint32_t buffer[3]; +}test_object_t; + +test_object_t test_object; + +Describe(TripleBufferedObject); +BeforeEach(TripleBufferedObject) { + triple_buffer_init((triple_buffer_object_t*)&test_object); +} +AfterEach(TripleBufferedObject) {} + + +Ensure(TripleBufferedObject, writes_and_reads_object) { + *triple_buffer_begin_write(&test_object) = 0x3456ABCC; + triple_buffer_end_write(&test_object); + assert_that(*triple_buffer_read(&test_object), is_equal_to(0x3456ABCC)); +} + +Ensure(TripleBufferedObject, does_not_read_empty) { + assert_that(triple_buffer_read(&test_object), is_equal_to(NULL)); +} + +Ensure(TripleBufferedObject, writes_twice_and_reads_object) { + *triple_buffer_begin_write(&test_object) = 0x3456ABCC; + triple_buffer_end_write(&test_object); + *triple_buffer_begin_write(&test_object) = 0x44778899; + triple_buffer_end_write(&test_object); + assert_that(*triple_buffer_read(&test_object), is_equal_to(0x44778899)); +} + +Ensure(TripleBufferedObject, performs_another_write_in_the_middle_of_read) { + *triple_buffer_begin_write(&test_object) = 1; + triple_buffer_end_write(&test_object); + uint32_t* read = triple_buffer_read(&test_object); + *triple_buffer_begin_write(&test_object) = 2; + triple_buffer_end_write(&test_object); + assert_that(*read, is_equal_to(1)); + assert_that(*triple_buffer_read(&test_object), is_equal_to(2)); + assert_that(triple_buffer_read(&test_object), is_equal_to(NULL)); +} + +Ensure(TripleBufferedObject, performs_two_writes_in_the_middle_of_read) { + *triple_buffer_begin_write(&test_object) = 1; + triple_buffer_end_write(&test_object); + uint32_t* read = triple_buffer_read(&test_object); + *triple_buffer_begin_write(&test_object) = 2; + triple_buffer_end_write(&test_object); + *triple_buffer_begin_write(&test_object) = 3; + triple_buffer_end_write(&test_object); + assert_that(*read, is_equal_to(1)); + assert_that(*triple_buffer_read(&test_object), is_equal_to(3)); + assert_that(triple_buffer_read(&test_object), is_equal_to(NULL)); +} -- cgit v1.3.1 From f727801bc69b3db28f84b7b8986756193bbfd21e Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Wed, 6 Jul 2016 20:17:16 +0300 Subject: Delete .gitmodules from visualizer --- quantum/visualizer/.gitmodules | 3 --- quantum/visualizer/ugfx | 1 - 2 files changed, 4 deletions(-) delete mode 100644 quantum/visualizer/.gitmodules delete mode 160000 quantum/visualizer/ugfx (limited to 'quantum') diff --git a/quantum/visualizer/.gitmodules b/quantum/visualizer/.gitmodules deleted file mode 100644 index b320458c0..000000000 --- a/quantum/visualizer/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "ugfx"] - path = ugfx - url = https://bitbucket.org/fredizzimo/ugfx.git diff --git a/quantum/visualizer/ugfx b/quantum/visualizer/ugfx deleted file mode 160000 index e221a6906..000000000 --- a/quantum/visualizer/ugfx +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e221a690616e20f87e0b0088baffdbd5427be862 -- cgit v1.3.1 From 70797bb8f21c72cba15b314b2d0a6684bfedc369 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Thu, 7 Jul 2016 00:20:20 +0300 Subject: Makefile changes and files to compile Visualizer --- Makefile | 15 +- keyboards/infinity_ergodox/Makefile | 3 + keyboards/infinity_ergodox/gfxconf.h | 331 +++++++++++++++++++++++++ keyboards/infinity_ergodox/lcd_backlight_hal.c | 84 +++++++ keyboards/infinity_ergodox/visualizer_user.c | 168 +++++++++++++ quantum/visualizer/visualizer.c | 2 - quantum/visualizer/visualizer.h | 2 - quantum/visualizer/visualizer.mk | 22 +- 8 files changed, 604 insertions(+), 23 deletions(-) create mode 100644 keyboards/infinity_ergodox/gfxconf.h create mode 100644 keyboards/infinity_ergodox/lcd_backlight_hal.c create mode 100644 keyboards/infinity_ergodox/visualizer_user.c (limited to 'quantum') diff --git a/Makefile b/Makefile index 7c00ce2cc..a7a10bf32 100644 --- a/Makefile +++ b/Makefile @@ -218,14 +218,6 @@ ifeq ($(strip $(SERIAL_LINK_ENABLE)), yes) VAPTH += $(SERIAL_PATH) endif -ifeq ($(MASTER),right) - OPT_DEFS += -DMASTER_IS_ON_RIGHT -else - ifneq ($(MASTER),left) -$(error MASTER does not have a valid value(left/right)) - endif -endif - # Optimize size but this may cause error "relocation truncated to fit" #EXTRALDFLAGS = -Wl,--relax @@ -257,10 +249,17 @@ ifeq ($(PLATFORM),AVR) else ifeq ($(PLATFORM),CHIBIOS) include $(TMK_PATH)/protocol/chibios.mk include $(TMK_PATH)/chibios.mk + OPT_OS = chibios else $(error Unknown platform) endif +ifeq ($(strip $(VISUALIZER_ENABLE)), yes) + VISUALIZER_DIR = $(QUANTUM_DIR)/visualizer + VISUALIZER_PATH = $(QUANTUM_PATH)/visualizer + include $(VISUALIZER_PATH)/visualizer.mk +endif + include $(TMK_PATH)/rules.mk GIT_VERSION := $(shell git describe --abbrev=6 --dirty --always --tags 2>/dev/null || date +"%Y-%m-%d-%H:%M:%S") diff --git a/keyboards/infinity_ergodox/Makefile b/keyboards/infinity_ergodox/Makefile index efa32e037..8be2f51b1 100644 --- a/keyboards/infinity_ergodox/Makefile +++ b/keyboards/infinity_ergodox/Makefile @@ -67,6 +67,9 @@ SLEEP_LED_ENABLE ?= yes # Breathing sleep LED during USB suspend NKRO_ENABLE ?= yes # USB Nkey Rollover CUSTOM_MATRIX ?= yes # Custom matrix file SERIAL_LINK_ENABLE = yes +VISUALIZER_ENABLE ?= yes +LCD_ENABLE ?= yes +LCD_BACKLIGHT_ENABLE ?= yes ifndef QUANTUM_DIR include ../../Makefile diff --git a/keyboards/infinity_ergodox/gfxconf.h b/keyboards/infinity_ergodox/gfxconf.h new file mode 100644 index 000000000..8caa577b7 --- /dev/null +++ b/keyboards/infinity_ergodox/gfxconf.h @@ -0,0 +1,331 @@ +/** + * 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 _GFXCONF_H +#define _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 + +#ifndef EMULATOR +#define GDISP_DRIVER_LIST GDISPVMT_ST7565_ERGODOX, GDISPVMT_IS31FL3731C_ERGODOX +#else +#define GDISP_DRIVER_LIST GDISPVMT_EMULATOR_LCD_ERGODOX, GDISPVMT_EMULATOR_LED_ERGODOX +#endif + + #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 /* _GFXCONF_H */ diff --git a/keyboards/infinity_ergodox/lcd_backlight_hal.c b/keyboards/infinity_ergodox/lcd_backlight_hal.c new file mode 100644 index 000000000..05fc810b4 --- /dev/null +++ b/keyboards/infinity_ergodox/lcd_backlight_hal.c @@ -0,0 +1,84 @@ +/* +Copyright 2016 Fred Sundvik +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 . +*/ +#include "lcd_backlight.h" +#include "hal.h" + +#define RED_PIN 1 +#define GREEN_PIN 2 +#define BLUE_PIN 3 +#define CHANNEL_RED FTM0->CHANNEL[0] +#define CHANNEL_GREEN FTM0->CHANNEL[1] +#define CHANNEL_BLUE FTM0->CHANNEL[2] + +#define RGB_PORT PORTC +#define RGB_PORT_GPIO GPIOC + +// Base FTM clock selection (72 MHz system clock) +// @ 0xFFFF period, 72 MHz / (0xFFFF * 2) = Actual period +// Higher pre-scalar will use the most power (also look the best) +// Pre-scalar calculations +// 0 - 72 MHz -> 549 Hz +// 1 - 36 MHz -> 275 Hz +// 2 - 18 MHz -> 137 Hz +// 3 - 9 MHz -> 69 Hz (Slightly visible flicker) +// 4 - 4 500 kHz -> 34 Hz (Visible flickering) +// 5 - 2 250 kHz -> 17 Hz +// 6 - 1 125 kHz -> 9 Hz +// 7 - 562 500 Hz -> 4 Hz +// Using a higher pre-scalar without flicker is possible but FTM0_MOD will need to be reduced +// Which will reduce the brightness range +#define PRESCALAR_DEFINE 0 + +void lcd_backlight_hal_init(void) { + // Setup Backlight + SIM->SCGC6 |= SIM_SCGC6_FTM0; + FTM0->CNT = 0; // Reset counter + + // PWM Period + // 16-bit maximum + FTM0->MOD = 0xFFFF; + + // Set FTM to PWM output - Edge Aligned, Low-true pulses +#define CNSC_MODE FTM_SC_CPWMS | FTM_SC_PS(4) | FTM_SC_CLKS(0) + CHANNEL_RED.CnSC = CNSC_MODE; + CHANNEL_GREEN.CnSC = CNSC_MODE; + CHANNEL_BLUE.CnSC = CNSC_MODE; + + // System clock, /w prescalar setting + FTM0->SC = FTM_SC_CLKS(1) | FTM_SC_PS(PRESCALAR_DEFINE); + + CHANNEL_RED.CnV = 0; + CHANNEL_GREEN.CnV = 0; + CHANNEL_BLUE.CnV = 0; + + RGB_PORT_GPIO->PDDR |= (1 << RED_PIN); + RGB_PORT_GPIO->PDDR |= (1 << GREEN_PIN); + RGB_PORT_GPIO->PDDR |= (1 << BLUE_PIN); + +#define RGB_MODE PORTx_PCRn_SRE | PORTx_PCRn_DSE | PORTx_PCRn_MUX(4) + RGB_PORT->PCR[RED_PIN] = RGB_MODE; + RGB_PORT->PCR[GREEN_PIN] = RGB_MODE; + RGB_PORT->PCR[BLUE_PIN] = RGB_MODE; +} + +void lcd_backlight_hal_color(uint16_t r, uint16_t g, uint16_t b) { + CHANNEL_RED.CnV = r; + CHANNEL_GREEN.CnV = g; + CHANNEL_BLUE.CnV = b; +} + diff --git a/keyboards/infinity_ergodox/visualizer_user.c b/keyboards/infinity_ergodox/visualizer_user.c new file mode 100644 index 000000000..c0d335ce6 --- /dev/null +++ b/keyboards/infinity_ergodox/visualizer_user.c @@ -0,0 +1,168 @@ +/* +Copyright 2016 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 . +*/ + +// Currently we are assuming that both the backlight and LCD are enabled +// But it's entirely possible to write a custom visualizer that use only +// one of them +#ifndef LCD_BACKLIGHT_ENABLE +#error This visualizer needs that LCD backlight is enabled +#endif + +#ifndef LCD_ENABLE +#error This visualizer needs that LCD is enabled +#endif + +#include "visualizer.h" +#include "led_test.h" + +static const char* welcome_text[] = {"TMK", "Infinity Ergodox"}; + +// Just an example how to write custom keyframe functions, we could have moved +// all this into the init function +bool display_welcome(keyframe_animation_t* animation, visualizer_state_t* state) { + (void)animation; + // Read the uGFX documentation for information how to use the displays + // http://wiki.ugfx.org/index.php/Main_Page + gdispClear(White); + // You can use static variables for things that can't be found in the animation + // or state structs + gdispDrawString(0, 3, welcome_text[0], state->font_dejavusansbold12, Black); + gdispDrawString(0, 15, welcome_text[1], state->font_dejavusansbold12, Black); + // Always remember to flush the display + gdispFlush(); + // you could set the backlight color as well, but we won't do it here, since + // it's part of the following animation + // lcd_backlight_color(hue, saturation, intensity); + // We don't need constant updates, just drawing the screen once is enough + return false; +} + +// Feel free to modify the animations below, or even add new ones if needed + +// Don't worry, if the startup animation is long, you can use the keyboard like normal +// during that time +static keyframe_animation_t startup_animation = { + .num_frames = 4, + .loop = false, + .frame_lengths = {0, gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(5000), 0}, + .frame_functions = { + display_welcome, + keyframe_animate_backlight_color, + keyframe_no_operation, + enable_visualization + }, +}; + +// The color animation animates the LCD color when you change layers +static keyframe_animation_t color_animation = { + .num_frames = 2, + .loop = false, + // Note that there's a 200 ms no-operation frame, + // this prevents the color from changing when activating the layer + // momentarily + .frame_lengths = {gfxMillisecondsToTicks(200), gfxMillisecondsToTicks(500)}, + .frame_functions = {keyframe_no_operation, keyframe_animate_backlight_color}, +}; + +// The LCD animation alternates between the layer name display and a +// bitmap that displays all active layers +static keyframe_animation_t lcd_animation = { + .num_frames = 2, + .loop = true, + .frame_lengths = {gfxMillisecondsToTicks(2000), gfxMillisecondsToTicks(2000)}, + .frame_functions = {keyframe_display_layer_text, keyframe_display_layer_bitmap}, +}; + +static keyframe_animation_t suspend_animation = { + .num_frames = 3, + .loop = false, + .frame_lengths = {0, gfxMillisecondsToTicks(1000), 0}, + .frame_functions = { + keyframe_display_layer_text, + keyframe_animate_backlight_color, + keyframe_disable_lcd_and_backlight, + }, +}; + +static keyframe_animation_t resume_animation = { + .num_frames = 5, + .loop = false, + .frame_lengths = {0, 0, gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(5000), 0}, + .frame_functions = { + keyframe_enable_lcd_and_backlight, + display_welcome, + keyframe_animate_backlight_color, + keyframe_no_operation, + enable_visualization, + }, +}; + +void initialize_user_visualizer(visualizer_state_t* state) { + // The brightness will be dynamically adjustable in the future + // But for now, change it here. + lcd_backlight_brightness(0x50); + state->current_lcd_color = LCD_COLOR(0x00, 0x00, 0xFF); + state->target_lcd_color = LCD_COLOR(0x10, 0xFF, 0xFF); + start_keyframe_animation(&startup_animation); + start_keyframe_animation(&led_test_animation); +} + +void update_user_visualizer_state(visualizer_state_t* state) { + // Add more tests, change the colors and layer texts here + // Usually you want to check the high bits (higher layers first) + // because that's the order layers are processed for keypresses + // You can for check for example: + // state->status.layer + // state->status.default_layer + // state->status.leds (see led.h for available statuses) + if (state->status.layer & 0x8) { + state->target_lcd_color = LCD_COLOR(0xC0, 0xB0, 0xFF); + state->layer_text = "Numpad"; + } + else if (state->status.layer & 0x4) { + state->target_lcd_color = LCD_COLOR(0, 0xB0, 0xFF); + state->layer_text = "KBD functions"; + } + else if (state->status.layer & 0x2) { + state->target_lcd_color = LCD_COLOR(0x80, 0xB0, 0xFF); + state->layer_text = "Function keys"; + } + else { + state->target_lcd_color = LCD_COLOR(0x40, 0xB0, 0xFF); + state->layer_text = "Default"; + } + // You can also stop existing animations, and start your custom ones here + // remember that you should normally have only one animation for the LCD + // and one for the background. But you can also combine them if you want. + start_keyframe_animation(&lcd_animation); + start_keyframe_animation(&color_animation); +} + +void user_visualizer_suspend(visualizer_state_t* state) { + state->layer_text = "Suspending..."; + uint8_t hue = LCD_HUE(state->current_lcd_color); + uint8_t sat = LCD_SAT(state->current_lcd_color); + state->target_lcd_color = LCD_COLOR(hue, sat, 0); + start_keyframe_animation(&suspend_animation); +} + +void user_visualizer_resume(visualizer_state_t* state) { + state->current_lcd_color = LCD_COLOR(0x00, 0x00, 0x00); + state->target_lcd_color = LCD_COLOR(0x10, 0xFF, 0xFF); + start_keyframe_animation(&resume_animation); + start_keyframe_animation(&led_test_animation); +} diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index c24073405..abca22d85 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -29,9 +29,7 @@ SOFTWARE. #include "ch.h" #endif -#ifdef LCD_ENABLE #include "gfx.h" -#endif #ifdef LCD_BACKLIGHT_ENABLE #include "lcd_backlight.h" diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h index 45cfa9aa9..53e250725 100644 --- a/quantum/visualizer/visualizer.h +++ b/quantum/visualizer/visualizer.h @@ -28,9 +28,7 @@ SOFTWARE. #include #include -#ifdef LCD_ENABLE #include "gfx.h" -#endif #ifdef LCD_BACKLIGHT_ENABLE #include "lcd_backlight.h" diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index 56525ffd9..b5dfad8e1 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -20,14 +20,14 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -GFXLIB = $(VISUALIZER_DIR)/ugfx SRC += $(VISUALIZER_DIR)/visualizer.c -UINCDIR += $(GFXINC) $(VISUALIZER_DIR) +EXTRAINCDIRS += $(GFXINC) $(VISUALIZER_DIR) +GFXLIB = $(LIB_PATH)/ugfx +VPATH += $(VISUALIZER_PATH) ifdef LCD_ENABLE -UDEFS += -DLCD_ENABLE +OPT_DEFS += -DLCD_ENABLE ULIBS += -lm -USE_UGFX = yes endif ifdef LCD_BACKLIGHT_ENABLE @@ -35,21 +35,21 @@ SRC += $(VISUALIZER_DIR)/lcd_backlight.c ifndef EMULATOR SRC += lcd_backlight_hal.c endif -UDEFS += -DLCD_BACKLIGHT_ENABLE +OPT_DEFS += -DLCD_BACKLIGHT_ENABLE endif ifdef LED_ENABLE SRC += $(VISUALIZER_DIR)/led_test.c UDEFS += -DLED_ENABLE -USE_UGFX = yes endif -ifdef USE_UGFX include $(GFXLIB)/gfx.mk -SRC += $(GFXSRC) -UDEFS += $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) -ULIBS += $(patsubst %,-l%,$(patsubst -l%,%,$(GFXLIBS))) -endif +#SERIAL_SRC = $(wildcard $(SERIAL_PATH)/protocol/*.c) +#SERIAL_SRC += $(wildcard $(SERIAL_PATH)/system/*.c) +#SRC += $(patsubst $(QUANTUM_PATH)/%,%,$(SERIAL_SRC)) +#SRC += $(GFXSRC) +OPT_DEFS += $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) +#ULIBS += $(patsubst %,-l%,$(patsubst -l%,%,$(GFXLIBS))) ifndef VISUALIZER_USER VISUALIZER_USER = visualizer_user.c -- cgit v1.3.1 From a4bf46f9b1d0a0be0cecb2cd0f0d941aa7c71bd3 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 6 Jul 2016 22:48:19 -0400 Subject: default keymap, reset sorted out for now, added serial to makefile --- keyboards/atreus/Makefile | 1 + keyboards/lets_split/Makefile | 3 +- keyboards/lets_split/config.h | 6 +- keyboards/lets_split/keymaps/default/keymap.c | 200 ++++++++++++++++++++++++-- keyboards/lets_split/lets_split.c | 26 +--- keyboards/lets_split/lets_split.h | 8 +- quantum/quantum.c | 2 +- tmk_core/common/avr/bootloader.c | 54 ++++--- 8 files changed, 241 insertions(+), 59 deletions(-) (limited to 'quantum') diff --git a/keyboards/atreus/Makefile b/keyboards/atreus/Makefile index 72b694faa..95ee1d4d7 100644 --- a/keyboards/atreus/Makefile +++ b/keyboards/atreus/Makefile @@ -5,6 +5,7 @@ ifdef TEENSY2 ATRUES_UPLOAD_COMMAND = teensy_loader_cli -w -mmcu=$(MCU) $(TARGET).hex else OPT_DEFS += -DATREUS_ASTAR + OPT_DEFS += -DCATERINA_BOOTLOADER ATRUES_UPLOAD_COMMAND = while [ ! -r $(USB) ]; do sleep 1; done; \ avrdude -p $(MCU) -c avr109 -U flash:w:$(TARGET).hex -P $(USB) endif diff --git a/keyboards/lets_split/Makefile b/keyboards/lets_split/Makefile index d8e283896..b9f07636b 100644 --- a/keyboards/lets_split/Makefile +++ b/keyboards/lets_split/Makefile @@ -1,6 +1,7 @@ SRC += matrix.c \ i2c.c \ - split_util.c + split_util.c \ + serial.c # MCU name #MCU = at90usb1287 diff --git a/keyboards/lets_split/config.h b/keyboards/lets_split/config.h index 5937ca44e..6f90997ab 100644 --- a/keyboards/lets_split/config.h +++ b/keyboards/lets_split/config.h @@ -37,7 +37,9 @@ along with this program. If not, see . #define MATRIX_ROW_PINS { B5, B4, E6, D7 } #define MATRIX_COL_PINS { F4, F5, F6, F7, B1, B3 } -#define USE_I2C +#define CATERINA_BOOTLOADER + +// #define USE_I2C // #define EE_HANDS @@ -51,7 +53,7 @@ along with this program. If not, see . //#define MATRIX_HAS_GHOST /* number of backlight levels */ -#define BACKLIGHT_LEVELS 3 +// #define BACKLIGHT_LEVELS 3 /* Set 0 if debouncing isn't needed */ #define DEBOUNCING_DELAY 5 diff --git a/keyboards/lets_split/keymaps/default/keymap.c b/keyboards/lets_split/keymaps/default/keymap.c index 01e3593c2..0d2d94b67 100644 --- a/keyboards/lets_split/keymaps/default/keymap.c +++ b/keyboards/lets_split/keymaps/default/keymap.c @@ -1,11 +1,27 @@ #include "lets_split.h" #include "action_layer.h" +#include "eeconfig.h" -#define BASE 0 +extern keymap_config_t keymap_config; -enum preonic_keycodes { - KC_IDK = SAFE_RANGE, - PM_RESET +// Each layer gets a name for readability, which is then used in the keymap matrix below. +// The underscores don't mean anything - you can have a layer called STUFF or any other name. +// Layer names don't all need to be of the same length, obviously, and you can also skip them +// entirely and just use numbers. +#define _QWERTY 0 +#define _COLEMAK 1 +#define _DVORAK 2 +#define _LOWER 3 +#define _RAISE 4 +#define _ADJUST 16 + +enum custom_keycodes { + QWERTY = SAFE_RANGE, + COLEMAK, + DVORAK, + LOWER, + RAISE, + ADJUST, }; // Fillers to make layering more clear @@ -14,29 +30,185 @@ enum preonic_keycodes { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { -[BASE] = KEYMAP( - KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, \ - KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, \ - KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT, \ - KC_IDK, KC_LCTL, KC_LALT, KC_LGUI, PM_RESET,KC_SPC, KC_SPC, PM_RESET,KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \ +/* Qwerty + * ,-----------------------------------------------------------------------------------. + * | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Esc | A | S | D | F | G | H | J | K | L | ; | " | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | Shift| Z | X | C | V | B | N | M | , | . | / |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * |Adjust| Ctrl | Alt | GUI |Lower |Space |Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_QWERTY] = KEYMAP( \ + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, \ + KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, \ + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT , \ + ADJUST, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \ +), + +/* Colemak + * ,-----------------------------------------------------------------------------------. + * | Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Esc | A | R | S | T | D | H | N | E | I | O | " | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | Shift| Z | X | C | V | B | K | M | , | . | / |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * |Adjust| Ctrl | Alt | GUI |Lower |Space |Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_COLEMAK] = KEYMAP( \ + KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC, \ + KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT, \ + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT , \ + ADJUST, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \ +), + +/* Dvorak + * ,-----------------------------------------------------------------------------------. + * | Tab | " | , | . | P | Y | F | G | C | R | L | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Esc | A | O | E | U | I | D | H | T | N | S | / | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * |Adjust| Ctrl | Alt | GUI |Lower |Space |Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_DVORAK] = KEYMAP( \ + KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC, \ + KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH, \ + KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_ENT , \ + ADJUST, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \ +), + +/* Lower + * ,-----------------------------------------------------------------------------------. + * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Del | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | | \ | | | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | | |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | Next | Vol- | Vol+ | Play | + * `-----------------------------------------------------------------------------------' + */ +[_LOWER] = KEYMAP( \ + KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, \ + KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, \ + _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,S(KC_NUHS),S(KC_NUBS),_______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \ +), + +/* Raise + * ,-----------------------------------------------------------------------------------. + * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Del | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO # |ISO / | | |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | Next | Vol- | Vol+ | Play | + * `-----------------------------------------------------------------------------------' + */ +[_RAISE] = KEYMAP( \ + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, \ + KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, \ + _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \ +), + +/* Adjust (Lower + Raise) + * ,-----------------------------------------------------------------------------------. + * | | Reset| | | | | | | | | | Del | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | | | |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak| | | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | | | | | | | | | | | | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | | | | | + * `-----------------------------------------------------------------------------------' + */ +[_ADJUST] = KEYMAP( \ + _______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL, \ + _______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \ ) + }; +#ifdef AUDIO_ENABLE +float tone_qwerty[][2] = SONG(QWERTY_SOUND); +float tone_dvorak[][2] = SONG(DVORAK_SOUND); +float tone_colemak[][2] = SONG(COLEMAK_SOUND); +#endif + +void persistant_default_layer_set(uint16_t default_layer) { + eeconfig_update_default_layer(default_layer); + default_layer_set(default_layer); +} + bool process_record_user(uint16_t keycode, keyrecord_t *record) { switch (keycode) { - case KC_IDK: + case QWERTY: + if (record->event.pressed) { + #ifdef AUDIO_ENABLE + PLAY_NOTE_ARRAY(tone_qwerty, false, 0); + #endif + persistant_default_layer_set(1UL<<_QWERTY); + } + return false; + break; + case COLEMAK: + if (record->event.pressed) { + #ifdef AUDIO_ENABLE + PLAY_NOTE_ARRAY(tone_colemak, false, 0); + #endif + persistant_default_layer_set(1UL<<_COLEMAK); + } + return false; + break; + case DVORAK: + if (record->event.pressed) { + #ifdef AUDIO_ENABLE + PLAY_NOTE_ARRAY(tone_dvorak, false, 0); + #endif + persistant_default_layer_set(1UL<<_DVORAK); + } + return false; + break; + case LOWER: + if (record->event.pressed) { + layer_on(_LOWER); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } else { + layer_off(_LOWER); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } + return false; + break; + case RAISE: if (record->event.pressed) { - SEND_STRING("IDK. "); + layer_on(_RAISE); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } else { + layer_off(_RAISE); + update_tri_layer(_LOWER, _RAISE, _ADJUST); } return false; break; - case PM_RESET: + case ADJUST: if (record->event.pressed) { - promicro_bootloader_jmp(true); + layer_on(_ADJUST); + } else { + layer_off(_ADJUST); } return false; break; } return true; -}; \ No newline at end of file +} \ No newline at end of file diff --git a/keyboards/lets_split/lets_split.c b/keyboards/lets_split/lets_split.c index 1859dc20a..574c116a7 100644 --- a/keyboards/lets_split/lets_split.c +++ b/keyboards/lets_split/lets_split.c @@ -23,26 +23,8 @@ void matrix_init_kb(void) { matrix_init_user(); }; -void promicro_bootloader_jmp(bool program) { - - #ifdef AUDIO_ENABLE - PLAY_NOTE_ARRAY(tone_goodbye, false, 0); - _delay_ms(150); - stop_all_notes(); - #endif - - uint16_t *const bootKeyPtr = (uint16_t *)0x0800; - - // Value used by Caterina bootloader use to determine whether to run the - // sketch or the bootloader programmer. - uint16_t bootKey = program ? 0x7777 : 0; - - *bootKeyPtr = bootKey; - - // setup watchdog timeout - wdt_enable(WDTO_60MS); - - while(1) {} // wait for watchdog timer to trigger +void shutdown_user(void) { + PLAY_NOTE_ARRAY(tone_goodbye, false, 0); + _delay_ms(150); + stop_all_notes(); } - - diff --git a/keyboards/lets_split/lets_split.h b/keyboards/lets_split/lets_split.h index e59aed592..fe7ae0767 100644 --- a/keyboards/lets_split/lets_split.h +++ b/keyboards/lets_split/lets_split.h @@ -1,5 +1,7 @@ +#ifndef LETS_SPLIT_H +#define LETS_SPLIT_H + #include "quantum.h" -#include void promicro_bootloader_jmp(bool program); @@ -18,4 +20,6 @@ void promicro_bootloader_jmp(bool program); { k50, k51, k52, k53, k54, k55 }, \ { k60, k61, k62, k63, k64, k65 }, \ { k70, k71, k72, k73, k74, k75 } \ - } \ No newline at end of file + } + +#endif \ No newline at end of file diff --git a/quantum/quantum.c b/quantum/quantum.c index d59bd5a3f..d8e43a465 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -89,7 +89,7 @@ bool process_record_quantum(keyrecord_t *record) { shutdown_user(); #endif wait_ms(250); - #ifdef ATREUS_ASTAR + #ifdef CATERINA_BOOTLOADER *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific #endif bootloader_jump(); diff --git a/tmk_core/common/avr/bootloader.c b/tmk_core/common/avr/bootloader.c index 7c744e8c7..fb9bf2d1c 100644 --- a/tmk_core/common/avr/bootloader.c +++ b/tmk_core/common/avr/bootloader.c @@ -73,26 +73,46 @@ uint32_t reset_key __attribute__ ((section (".noinit"))); /* initialize MCU status by watchdog reset */ void bootloader_jump(void) { -#ifdef PROTOCOL_LUFA - USB_Disable(); - cli(); - _delay_ms(2000); -#endif + #ifndef CATERINA_BOOTLOADER -#ifdef PROTOCOL_PJRC - cli(); - UDCON = 1; - USBCON = (1< Date: Thu, 7 Jul 2016 12:46:10 +0300 Subject: Makefile fixes and update of Visualizer --- keyboards/infinity_ergodox/Makefile | 9 +++++++++ quantum/visualizer/led_test.c | 4 ++-- quantum/visualizer/visualizer.mk | 8 +++----- tmk_core/common/keyboard.c | 8 ++++++++ tmk_core/protocol/chibios/main.c | 7 +++++++ 5 files changed, 29 insertions(+), 7 deletions(-) (limited to 'quantum') diff --git a/keyboards/infinity_ergodox/Makefile b/keyboards/infinity_ergodox/Makefile index 8be2f51b1..7edc03d8c 100644 --- a/keyboards/infinity_ergodox/Makefile +++ b/keyboards/infinity_ergodox/Makefile @@ -69,8 +69,17 @@ CUSTOM_MATRIX ?= yes # Custom matrix file SERIAL_LINK_ENABLE = yes VISUALIZER_ENABLE ?= yes LCD_ENABLE ?= yes +LED_ENABLE ?= yes LCD_BACKLIGHT_ENABLE ?= yes +ifdef LCD_ENABLE +include drivers/gdisp/st7565ergodox/driver.mk +endif + +ifdef LED_ENABLE +include drivers/gdisp/IS31FL3731C/driver.mk +endif + ifndef QUANTUM_DIR include ../../Makefile endif \ No newline at end of file diff --git a/quantum/visualizer/led_test.c b/quantum/visualizer/led_test.c index c2ea30b55..a9abace8d 100644 --- a/quantum/visualizer/led_test.c +++ b/quantum/visualizer/led_test.c @@ -89,8 +89,8 @@ static uint8_t crossfade_start_frame[NUM_ROWS][NUM_COLS]; static uint8_t crossfade_end_frame[NUM_ROWS][NUM_COLS]; static uint8_t compute_gradient_color(float t, float index, float num) { - const float two_pi = 2.0f * PI; - float normalized_index = (1.0f - index / (num - 1)) * two_pi; + const float two_pi = M_2_PI; + float normalized_index = (1.0f - index / (num - 1.0f)) * two_pi; float x = t * two_pi + normalized_index; float v = 0.5 * (cosf(x) + 1.0f); return (uint8_t)(255.0f * v); diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index b5dfad8e1..149968de7 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -25,6 +25,8 @@ EXTRAINCDIRS += $(GFXINC) $(VISUALIZER_DIR) GFXLIB = $(LIB_PATH)/ugfx VPATH += $(VISUALIZER_PATH) +OPT_DEFS += -DVISUALIZER_ENABLE + ifdef LCD_ENABLE OPT_DEFS += -DLCD_ENABLE ULIBS += -lm @@ -44,12 +46,8 @@ UDEFS += -DLED_ENABLE endif include $(GFXLIB)/gfx.mk -#SERIAL_SRC = $(wildcard $(SERIAL_PATH)/protocol/*.c) -#SERIAL_SRC += $(wildcard $(SERIAL_PATH)/system/*.c) -#SRC += $(patsubst $(QUANTUM_PATH)/%,%,$(SERIAL_SRC)) -#SRC += $(GFXSRC) +SRC += $(patsubst $(TOP_DIR)/%,%,$(GFXSRC)) OPT_DEFS += $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) -#ULIBS += $(patsubst %,-l%,$(patsubst -l%,%,$(GFXLIBS))) ifndef VISUALIZER_USER VISUALIZER_USER = visualizer_user.c diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c index 3a1262a9f..c46a701b3 100644 --- a/tmk_core/common/keyboard.c +++ b/tmk_core/common/keyboard.c @@ -29,6 +29,7 @@ along with this program. If not, see . #include "sendchar.h" #include "eeconfig.h" #include "backlight.h" +#include "action_layer.h" #ifdef BOOTMAGIC_ENABLE # include "bootmagic.h" #else @@ -52,6 +53,9 @@ along with this program. If not, see . #ifdef SERIAL_LINK_ENABLE # include "serial_link/system/serial_link.h" #endif +#ifdef VISUALIZER_ENABLE +# include "visualizer/visualizer.h" +#endif #ifdef MATRIX_HAS_GHOST static bool has_ghost_in_row(uint8_t row) @@ -181,6 +185,10 @@ MATRIX_LOOP_END: serial_link_update(); #endif +#ifdef VISUALIZER_ENABLE + visualizer_update(default_layer_state, layer_state, host_keyboard_leds()); +#endif + // update LED if (led_status != host_keyboard_leds()) { led_status = host_keyboard_leds(); diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c index aeb11752f..6bf9c1668 100644 --- a/tmk_core/protocol/chibios/main.c +++ b/tmk_core/protocol/chibios/main.c @@ -38,6 +38,9 @@ #ifdef SERIAL_LINK_ENABLE #include "serial_link/system/serial_link.h" #endif +#ifdef VISUALIZER_ENABLE +#include "visualizer/visualizer.h" +#endif #include "suspend.h" @@ -101,6 +104,10 @@ int main(void) { /* init printf */ init_printf(NULL,sendchar_pf); +#ifdef VISUALIZER_ENABLE + visualizer_init(); +#endif + #ifdef SERIAL_LINK_ENABLE init_serial_link(); #endif -- cgit v1.3.1 From 7229751ba9d402b2a6c9dc1b7b29385b5162fe41 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Thu, 7 Jul 2016 14:01:20 +0300 Subject: Fix visualizer crash at startup Visualizer and serial link initialized in the wrong order. The LED_ENABLED define wasn't set properly uGfx is always initialized --- quantum/visualizer/visualizer.c | 2 -- quantum/visualizer/visualizer.mk | 2 +- tmk_core/protocol/chibios/main.c | 7 ++++--- 3 files changed, 5 insertions(+), 6 deletions(-) (limited to 'quantum') diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index abca22d85..dfa2ff4ee 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -456,9 +456,7 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { } void visualizer_init(void) { -#ifdef LCD_ENABLE gfxInit(); -#endif #ifdef LCD_BACKLIGHT_ENABLE lcd_backlight_init(); diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index 149968de7..379496fb6 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -42,7 +42,7 @@ endif ifdef LED_ENABLE SRC += $(VISUALIZER_DIR)/led_test.c -UDEFS += -DLED_ENABLE +OPT_DEFS += -DLED_ENABLE endif include $(GFXLIB)/gfx.mk diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c index 6bf9c1668..36fd45d45 100644 --- a/tmk_core/protocol/chibios/main.c +++ b/tmk_core/protocol/chibios/main.c @@ -104,13 +104,14 @@ int main(void) { /* init printf */ init_printf(NULL,sendchar_pf); +#ifdef SERIAL_LINK_ENABLE + init_serial_link(); +#endif + #ifdef VISUALIZER_ENABLE visualizer_init(); #endif -#ifdef SERIAL_LINK_ENABLE - init_serial_link(); -#endif host_driver_t* driver = NULL; -- cgit v1.3.1 From dae7c9bfb3325412c542fbbe4342c9c8e0fc1904 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Thu, 7 Jul 2016 14:12:56 +0300 Subject: Fix the SERIAL_LINK_ENABLE macro in Visualizer Rename from USE_SERIAL_LINK -> SERIAL_LINK_ENABLE --- quantum/visualizer/visualizer.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'quantum') diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index dfa2ff4ee..54f6faaa4 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -43,7 +43,7 @@ SOFTWARE. #include "nodebug.h" #endif -#ifdef USE_SERIAL_LINK +#ifdef SERIAL_LINK_ENABLE #include "serial_link/protocol/transport.h" #include "serial_link/system/serial_link.h" #endif @@ -73,7 +73,7 @@ static bool visualizer_enabled = false; #define MAX_SIMULTANEOUS_ANIMATIONS 4 static keyframe_animation_t* animations[MAX_SIMULTANEOUS_ANIMATIONS] = {}; -#ifdef USE_SERIAL_LINK +#ifdef SERIAL_LINK_ENABLE MASTER_TO_ALL_SLAVES_OBJECT(current_status, visualizer_keyboard_status_t); static remote_object_t* remote_objects[] = { @@ -462,7 +462,7 @@ void visualizer_init(void) { lcd_backlight_init(); #endif -#ifdef USE_SERIAL_LINK +#ifdef SERIAL_LINK_ENABLE add_remote_objects(remote_objects, sizeof(remote_objects) / sizeof(remote_object_t*) ); #endif @@ -486,7 +486,7 @@ void update_status(bool changed) { geventSendEvent(listener); } } -#ifdef USE_SERIAL_LINK +#ifdef SERIAL_LINK_ENABLE static systime_t last_update = 0; systime_t current_update = chVTGetSystemTimeX(); systime_t delta = current_update - last_update; @@ -506,7 +506,7 @@ void visualizer_update(uint32_t default_state, uint32_t state, uint32_t leds) { // Alternatively a mutex could be used instead of the volatile variables bool changed = false; -#ifdef USE_SERIAL_LINK +#ifdef SERIAL_LINK_ENABLE if (is_serial_link_connected ()) { visualizer_keyboard_status_t* new_status = read_current_status(); if (new_status) { -- cgit v1.3.1 From aaac254ebce2005272e7385488b5690bbbe6d7c8 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Thu, 7 Jul 2016 14:29:53 +0300 Subject: Delete lcd_backlight_hal.c The functionality can now be found in the infinity_erogodox.c file instead. --- keyboards/infinity_ergodox/infinity_ergodox.c | 65 ++++++++++++++++++++ keyboards/infinity_ergodox/lcd_backlight_hal.c | 84 -------------------------- quantum/visualizer/visualizer.mk | 3 - 3 files changed, 65 insertions(+), 87 deletions(-) delete mode 100644 keyboards/infinity_ergodox/lcd_backlight_hal.c (limited to 'quantum') diff --git a/keyboards/infinity_ergodox/infinity_ergodox.c b/keyboards/infinity_ergodox/infinity_ergodox.c index 85054775e..87ed40fab 100644 --- a/keyboards/infinity_ergodox/infinity_ergodox.c +++ b/keyboards/infinity_ergodox/infinity_ergodox.c @@ -2,6 +2,7 @@ #include "ch.h" #include "hal.h" #include "serial_link/system/serial_link.h" +#include "lcd_backlight.h" void init_serial_link_hal(void) { PORTA->PCR[1] = PORTx_PCRn_PE | PORTx_PCRn_PS | PORTx_PCRn_PFE | PORTx_PCRn_MUX(2); @@ -9,3 +10,67 @@ void init_serial_link_hal(void) { PORTE->PCR[0] = PORTx_PCRn_PE | PORTx_PCRn_PS | PORTx_PCRn_PFE | PORTx_PCRn_MUX(3); PORTE->PCR[1] = PORTx_PCRn_DSE | PORTx_PCRn_SRE | PORTx_PCRn_MUX(3); } + +#define RED_PIN 1 +#define GREEN_PIN 2 +#define BLUE_PIN 3 +#define CHANNEL_RED FTM0->CHANNEL[0] +#define CHANNEL_GREEN FTM0->CHANNEL[1] +#define CHANNEL_BLUE FTM0->CHANNEL[2] + +#define RGB_PORT PORTC +#define RGB_PORT_GPIO GPIOC + +// Base FTM clock selection (72 MHz system clock) +// @ 0xFFFF period, 72 MHz / (0xFFFF * 2) = Actual period +// Higher pre-scalar will use the most power (also look the best) +// Pre-scalar calculations +// 0 - 72 MHz -> 549 Hz +// 1 - 36 MHz -> 275 Hz +// 2 - 18 MHz -> 137 Hz +// 3 - 9 MHz -> 69 Hz (Slightly visible flicker) +// 4 - 4 500 kHz -> 34 Hz (Visible flickering) +// 5 - 2 250 kHz -> 17 Hz +// 6 - 1 125 kHz -> 9 Hz +// 7 - 562 500 Hz -> 4 Hz +// Using a higher pre-scalar without flicker is possible but FTM0_MOD will need to be reduced +// Which will reduce the brightness range +#define PRESCALAR_DEFINE 0 + +void lcd_backlight_hal_init(void) { + // Setup Backlight + SIM->SCGC6 |= SIM_SCGC6_FTM0; + FTM0->CNT = 0; // Reset counter + + // PWM Period + // 16-bit maximum + FTM0->MOD = 0xFFFF; + + // Set FTM to PWM output - Edge Aligned, Low-true pulses +#define CNSC_MODE FTM_SC_CPWMS | FTM_SC_PS(4) | FTM_SC_CLKS(0) + CHANNEL_RED.CnSC = CNSC_MODE; + CHANNEL_GREEN.CnSC = CNSC_MODE; + CHANNEL_BLUE.CnSC = CNSC_MODE; + + // System clock, /w prescalar setting + FTM0->SC = FTM_SC_CLKS(1) | FTM_SC_PS(PRESCALAR_DEFINE); + + CHANNEL_RED.CnV = 0; + CHANNEL_GREEN.CnV = 0; + CHANNEL_BLUE.CnV = 0; + + RGB_PORT_GPIO->PDDR |= (1 << RED_PIN); + RGB_PORT_GPIO->PDDR |= (1 << GREEN_PIN); + RGB_PORT_GPIO->PDDR |= (1 << BLUE_PIN); + +#define RGB_MODE PORTx_PCRn_SRE | PORTx_PCRn_DSE | PORTx_PCRn_MUX(4) + RGB_PORT->PCR[RED_PIN] = RGB_MODE; + RGB_PORT->PCR[GREEN_PIN] = RGB_MODE; + RGB_PORT->PCR[BLUE_PIN] = RGB_MODE; +} + +void lcd_backlight_hal_color(uint16_t r, uint16_t g, uint16_t b) { + CHANNEL_RED.CnV = r; + CHANNEL_GREEN.CnV = g; + CHANNEL_BLUE.CnV = b; +} diff --git a/keyboards/infinity_ergodox/lcd_backlight_hal.c b/keyboards/infinity_ergodox/lcd_backlight_hal.c deleted file mode 100644 index 05fc810b4..000000000 --- a/keyboards/infinity_ergodox/lcd_backlight_hal.c +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright 2016 Fred Sundvik -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 . -*/ -#include "lcd_backlight.h" -#include "hal.h" - -#define RED_PIN 1 -#define GREEN_PIN 2 -#define BLUE_PIN 3 -#define CHANNEL_RED FTM0->CHANNEL[0] -#define CHANNEL_GREEN FTM0->CHANNEL[1] -#define CHANNEL_BLUE FTM0->CHANNEL[2] - -#define RGB_PORT PORTC -#define RGB_PORT_GPIO GPIOC - -// Base FTM clock selection (72 MHz system clock) -// @ 0xFFFF period, 72 MHz / (0xFFFF * 2) = Actual period -// Higher pre-scalar will use the most power (also look the best) -// Pre-scalar calculations -// 0 - 72 MHz -> 549 Hz -// 1 - 36 MHz -> 275 Hz -// 2 - 18 MHz -> 137 Hz -// 3 - 9 MHz -> 69 Hz (Slightly visible flicker) -// 4 - 4 500 kHz -> 34 Hz (Visible flickering) -// 5 - 2 250 kHz -> 17 Hz -// 6 - 1 125 kHz -> 9 Hz -// 7 - 562 500 Hz -> 4 Hz -// Using a higher pre-scalar without flicker is possible but FTM0_MOD will need to be reduced -// Which will reduce the brightness range -#define PRESCALAR_DEFINE 0 - -void lcd_backlight_hal_init(void) { - // Setup Backlight - SIM->SCGC6 |= SIM_SCGC6_FTM0; - FTM0->CNT = 0; // Reset counter - - // PWM Period - // 16-bit maximum - FTM0->MOD = 0xFFFF; - - // Set FTM to PWM output - Edge Aligned, Low-true pulses -#define CNSC_MODE FTM_SC_CPWMS | FTM_SC_PS(4) | FTM_SC_CLKS(0) - CHANNEL_RED.CnSC = CNSC_MODE; - CHANNEL_GREEN.CnSC = CNSC_MODE; - CHANNEL_BLUE.CnSC = CNSC_MODE; - - // System clock, /w prescalar setting - FTM0->SC = FTM_SC_CLKS(1) | FTM_SC_PS(PRESCALAR_DEFINE); - - CHANNEL_RED.CnV = 0; - CHANNEL_GREEN.CnV = 0; - CHANNEL_BLUE.CnV = 0; - - RGB_PORT_GPIO->PDDR |= (1 << RED_PIN); - RGB_PORT_GPIO->PDDR |= (1 << GREEN_PIN); - RGB_PORT_GPIO->PDDR |= (1 << BLUE_PIN); - -#define RGB_MODE PORTx_PCRn_SRE | PORTx_PCRn_DSE | PORTx_PCRn_MUX(4) - RGB_PORT->PCR[RED_PIN] = RGB_MODE; - RGB_PORT->PCR[GREEN_PIN] = RGB_MODE; - RGB_PORT->PCR[BLUE_PIN] = RGB_MODE; -} - -void lcd_backlight_hal_color(uint16_t r, uint16_t g, uint16_t b) { - CHANNEL_RED.CnV = r; - CHANNEL_GREEN.CnV = g; - CHANNEL_BLUE.CnV = b; -} - diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index 379496fb6..449957d63 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -34,9 +34,6 @@ endif ifdef LCD_BACKLIGHT_ENABLE SRC += $(VISUALIZER_DIR)/lcd_backlight.c -ifndef EMULATOR -SRC += lcd_backlight_hal.c -endif OPT_DEFS += -DLCD_BACKLIGHT_ENABLE endif -- cgit v1.3.1 From caedec92d2c22480313c43a364408fb920c55364 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Thu, 7 Jul 2016 14:42:16 +0300 Subject: Move the visualizer_user file to keymap folder Also rename it to visualizer.c --- .../infinity_ergodox/keymaps/default/visualizer.c | 168 +++++++++++++++++++++ keyboards/infinity_ergodox/visualizer_user.c | 168 --------------------- quantum/visualizer/visualizer.mk | 11 +- 3 files changed, 176 insertions(+), 171 deletions(-) create mode 100644 keyboards/infinity_ergodox/keymaps/default/visualizer.c delete mode 100644 keyboards/infinity_ergodox/visualizer_user.c (limited to 'quantum') diff --git a/keyboards/infinity_ergodox/keymaps/default/visualizer.c b/keyboards/infinity_ergodox/keymaps/default/visualizer.c new file mode 100644 index 000000000..c0d335ce6 --- /dev/null +++ b/keyboards/infinity_ergodox/keymaps/default/visualizer.c @@ -0,0 +1,168 @@ +/* +Copyright 2016 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 . +*/ + +// Currently we are assuming that both the backlight and LCD are enabled +// But it's entirely possible to write a custom visualizer that use only +// one of them +#ifndef LCD_BACKLIGHT_ENABLE +#error This visualizer needs that LCD backlight is enabled +#endif + +#ifndef LCD_ENABLE +#error This visualizer needs that LCD is enabled +#endif + +#include "visualizer.h" +#include "led_test.h" + +static const char* welcome_text[] = {"TMK", "Infinity Ergodox"}; + +// Just an example how to write custom keyframe functions, we could have moved +// all this into the init function +bool display_welcome(keyframe_animation_t* animation, visualizer_state_t* state) { + (void)animation; + // Read the uGFX documentation for information how to use the displays + // http://wiki.ugfx.org/index.php/Main_Page + gdispClear(White); + // You can use static variables for things that can't be found in the animation + // or state structs + gdispDrawString(0, 3, welcome_text[0], state->font_dejavusansbold12, Black); + gdispDrawString(0, 15, welcome_text[1], state->font_dejavusansbold12, Black); + // Always remember to flush the display + gdispFlush(); + // you could set the backlight color as well, but we won't do it here, since + // it's part of the following animation + // lcd_backlight_color(hue, saturation, intensity); + // We don't need constant updates, just drawing the screen once is enough + return false; +} + +// Feel free to modify the animations below, or even add new ones if needed + +// Don't worry, if the startup animation is long, you can use the keyboard like normal +// during that time +static keyframe_animation_t startup_animation = { + .num_frames = 4, + .loop = false, + .frame_lengths = {0, gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(5000), 0}, + .frame_functions = { + display_welcome, + keyframe_animate_backlight_color, + keyframe_no_operation, + enable_visualization + }, +}; + +// The color animation animates the LCD color when you change layers +static keyframe_animation_t color_animation = { + .num_frames = 2, + .loop = false, + // Note that there's a 200 ms no-operation frame, + // this prevents the color from changing when activating the layer + // momentarily + .frame_lengths = {gfxMillisecondsToTicks(200), gfxMillisecondsToTicks(500)}, + .frame_functions = {keyframe_no_operation, keyframe_animate_backlight_color}, +}; + +// The LCD animation alternates between the layer name display and a +// bitmap that displays all active layers +static keyframe_animation_t lcd_animation = { + .num_frames = 2, + .loop = true, + .frame_lengths = {gfxMillisecondsToTicks(2000), gfxMillisecondsToTicks(2000)}, + .frame_functions = {keyframe_display_layer_text, keyframe_display_layer_bitmap}, +}; + +static keyframe_animation_t suspend_animation = { + .num_frames = 3, + .loop = false, + .frame_lengths = {0, gfxMillisecondsToTicks(1000), 0}, + .frame_functions = { + keyframe_display_layer_text, + keyframe_animate_backlight_color, + keyframe_disable_lcd_and_backlight, + }, +}; + +static keyframe_animation_t resume_animation = { + .num_frames = 5, + .loop = false, + .frame_lengths = {0, 0, gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(5000), 0}, + .frame_functions = { + keyframe_enable_lcd_and_backlight, + display_welcome, + keyframe_animate_backlight_color, + keyframe_no_operation, + enable_visualization, + }, +}; + +void initialize_user_visualizer(visualizer_state_t* state) { + // The brightness will be dynamically adjustable in the future + // But for now, change it here. + lcd_backlight_brightness(0x50); + state->current_lcd_color = LCD_COLOR(0x00, 0x00, 0xFF); + state->target_lcd_color = LCD_COLOR(0x10, 0xFF, 0xFF); + start_keyframe_animation(&startup_animation); + start_keyframe_animation(&led_test_animation); +} + +void update_user_visualizer_state(visualizer_state_t* state) { + // Add more tests, change the colors and layer texts here + // Usually you want to check the high bits (higher layers first) + // because that's the order layers are processed for keypresses + // You can for check for example: + // state->status.layer + // state->status.default_layer + // state->status.leds (see led.h for available statuses) + if (state->status.layer & 0x8) { + state->target_lcd_color = LCD_COLOR(0xC0, 0xB0, 0xFF); + state->layer_text = "Numpad"; + } + else if (state->status.layer & 0x4) { + state->target_lcd_color = LCD_COLOR(0, 0xB0, 0xFF); + state->layer_text = "KBD functions"; + } + else if (state->status.layer & 0x2) { + state->target_lcd_color = LCD_COLOR(0x80, 0xB0, 0xFF); + state->layer_text = "Function keys"; + } + else { + state->target_lcd_color = LCD_COLOR(0x40, 0xB0, 0xFF); + state->layer_text = "Default"; + } + // You can also stop existing animations, and start your custom ones here + // remember that you should normally have only one animation for the LCD + // and one for the background. But you can also combine them if you want. + start_keyframe_animation(&lcd_animation); + start_keyframe_animation(&color_animation); +} + +void user_visualizer_suspend(visualizer_state_t* state) { + state->layer_text = "Suspending..."; + uint8_t hue = LCD_HUE(state->current_lcd_color); + uint8_t sat = LCD_SAT(state->current_lcd_color); + state->target_lcd_color = LCD_COLOR(hue, sat, 0); + start_keyframe_animation(&suspend_animation); +} + +void user_visualizer_resume(visualizer_state_t* state) { + state->current_lcd_color = LCD_COLOR(0x00, 0x00, 0x00); + state->target_lcd_color = LCD_COLOR(0x10, 0xFF, 0xFF); + start_keyframe_animation(&resume_animation); + start_keyframe_animation(&led_test_animation); +} diff --git a/keyboards/infinity_ergodox/visualizer_user.c b/keyboards/infinity_ergodox/visualizer_user.c deleted file mode 100644 index c0d335ce6..000000000 --- a/keyboards/infinity_ergodox/visualizer_user.c +++ /dev/null @@ -1,168 +0,0 @@ -/* -Copyright 2016 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 . -*/ - -// Currently we are assuming that both the backlight and LCD are enabled -// But it's entirely possible to write a custom visualizer that use only -// one of them -#ifndef LCD_BACKLIGHT_ENABLE -#error This visualizer needs that LCD backlight is enabled -#endif - -#ifndef LCD_ENABLE -#error This visualizer needs that LCD is enabled -#endif - -#include "visualizer.h" -#include "led_test.h" - -static const char* welcome_text[] = {"TMK", "Infinity Ergodox"}; - -// Just an example how to write custom keyframe functions, we could have moved -// all this into the init function -bool display_welcome(keyframe_animation_t* animation, visualizer_state_t* state) { - (void)animation; - // Read the uGFX documentation for information how to use the displays - // http://wiki.ugfx.org/index.php/Main_Page - gdispClear(White); - // You can use static variables for things that can't be found in the animation - // or state structs - gdispDrawString(0, 3, welcome_text[0], state->font_dejavusansbold12, Black); - gdispDrawString(0, 15, welcome_text[1], state->font_dejavusansbold12, Black); - // Always remember to flush the display - gdispFlush(); - // you could set the backlight color as well, but we won't do it here, since - // it's part of the following animation - // lcd_backlight_color(hue, saturation, intensity); - // We don't need constant updates, just drawing the screen once is enough - return false; -} - -// Feel free to modify the animations below, or even add new ones if needed - -// Don't worry, if the startup animation is long, you can use the keyboard like normal -// during that time -static keyframe_animation_t startup_animation = { - .num_frames = 4, - .loop = false, - .frame_lengths = {0, gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(5000), 0}, - .frame_functions = { - display_welcome, - keyframe_animate_backlight_color, - keyframe_no_operation, - enable_visualization - }, -}; - -// The color animation animates the LCD color when you change layers -static keyframe_animation_t color_animation = { - .num_frames = 2, - .loop = false, - // Note that there's a 200 ms no-operation frame, - // this prevents the color from changing when activating the layer - // momentarily - .frame_lengths = {gfxMillisecondsToTicks(200), gfxMillisecondsToTicks(500)}, - .frame_functions = {keyframe_no_operation, keyframe_animate_backlight_color}, -}; - -// The LCD animation alternates between the layer name display and a -// bitmap that displays all active layers -static keyframe_animation_t lcd_animation = { - .num_frames = 2, - .loop = true, - .frame_lengths = {gfxMillisecondsToTicks(2000), gfxMillisecondsToTicks(2000)}, - .frame_functions = {keyframe_display_layer_text, keyframe_display_layer_bitmap}, -}; - -static keyframe_animation_t suspend_animation = { - .num_frames = 3, - .loop = false, - .frame_lengths = {0, gfxMillisecondsToTicks(1000), 0}, - .frame_functions = { - keyframe_display_layer_text, - keyframe_animate_backlight_color, - keyframe_disable_lcd_and_backlight, - }, -}; - -static keyframe_animation_t resume_animation = { - .num_frames = 5, - .loop = false, - .frame_lengths = {0, 0, gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(5000), 0}, - .frame_functions = { - keyframe_enable_lcd_and_backlight, - display_welcome, - keyframe_animate_backlight_color, - keyframe_no_operation, - enable_visualization, - }, -}; - -void initialize_user_visualizer(visualizer_state_t* state) { - // The brightness will be dynamically adjustable in the future - // But for now, change it here. - lcd_backlight_brightness(0x50); - state->current_lcd_color = LCD_COLOR(0x00, 0x00, 0xFF); - state->target_lcd_color = LCD_COLOR(0x10, 0xFF, 0xFF); - start_keyframe_animation(&startup_animation); - start_keyframe_animation(&led_test_animation); -} - -void update_user_visualizer_state(visualizer_state_t* state) { - // Add more tests, change the colors and layer texts here - // Usually you want to check the high bits (higher layers first) - // because that's the order layers are processed for keypresses - // You can for check for example: - // state->status.layer - // state->status.default_layer - // state->status.leds (see led.h for available statuses) - if (state->status.layer & 0x8) { - state->target_lcd_color = LCD_COLOR(0xC0, 0xB0, 0xFF); - state->layer_text = "Numpad"; - } - else if (state->status.layer & 0x4) { - state->target_lcd_color = LCD_COLOR(0, 0xB0, 0xFF); - state->layer_text = "KBD functions"; - } - else if (state->status.layer & 0x2) { - state->target_lcd_color = LCD_COLOR(0x80, 0xB0, 0xFF); - state->layer_text = "Function keys"; - } - else { - state->target_lcd_color = LCD_COLOR(0x40, 0xB0, 0xFF); - state->layer_text = "Default"; - } - // You can also stop existing animations, and start your custom ones here - // remember that you should normally have only one animation for the LCD - // and one for the background. But you can also combine them if you want. - start_keyframe_animation(&lcd_animation); - start_keyframe_animation(&color_animation); -} - -void user_visualizer_suspend(visualizer_state_t* state) { - state->layer_text = "Suspending..."; - uint8_t hue = LCD_HUE(state->current_lcd_color); - uint8_t sat = LCD_SAT(state->current_lcd_color); - state->target_lcd_color = LCD_COLOR(hue, sat, 0); - start_keyframe_animation(&suspend_animation); -} - -void user_visualizer_resume(visualizer_state_t* state) { - state->current_lcd_color = LCD_COLOR(0x00, 0x00, 0x00); - state->target_lcd_color = LCD_COLOR(0x10, 0xFF, 0xFF); - start_keyframe_animation(&resume_animation); - start_keyframe_animation(&led_test_animation); -} diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index 449957d63..2f4a41d66 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -46,10 +46,15 @@ include $(GFXLIB)/gfx.mk SRC += $(patsubst $(TOP_DIR)/%,%,$(GFXSRC)) OPT_DEFS += $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) -ifndef VISUALIZER_USER -VISUALIZER_USER = visualizer_user.c +ifneq ("$(wildcard $(KEYMAP_PATH)/visualizer.c)","") + SRC += keyboards/$(KEYBOARD)/keymaps/$(KEYMAP)/visualizer.c +else + ifeq ("$(wildcard $(SUBPROJECT_PATH)/keymaps/$(KEYMAP)/visualizer.c)","") +$(error "$(KEYMAP_PATH)/visualizer.c" does not exist) + else + SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/keymaps/$(KEYMAP)/visualizer.c + endif endif -SRC += $(VISUALIZER_USER) ifdef EMULATOR UINCDIR += $(TMK_DIR)/common -- cgit v1.3.1 From 589df84d6cd19ad7d776cc19bcddade1cd178ddc Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Thu, 7 Jul 2016 09:58:44 -0400 Subject: corrects quantum template --- quantum/template/template.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/template/template.c b/quantum/template/template.c index dcc4b0a22..3057557ea 100644 --- a/quantum/template/template.c +++ b/quantum/template/template.c @@ -18,7 +18,7 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) { // put your per-action keyboard code here // runs for every action, just before processing by the firmware - return process_action_user(record); + return process_record_user(record); } void led_set_kb(uint8_t usb_led) { -- cgit v1.3.1 From 57e08eb8badc5db2fb44d2df684f32ea48cce411 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Thu, 7 Jul 2016 11:33:32 -0400 Subject: updates rgblight implementation, makes non-timer stuff compatible with audio --- keyboards/clueboard/rev1/config.h | 5 +- keyboards/clueboard/rev2/config.h | 5 +- keyboards/cluepad/config.h | 13 +++-- keyboards/kc60/keymaps/ws2812/config.h | 5 +- keyboards/lets_split/config.h | 5 +- keyboards/phantom/config.h | 13 +++-- keyboards/planck/keymaps/experimental/Makefile | 6 +-- keyboards/planck/keymaps/experimental/config.h | 8 +++ keyboards/planck/keymaps/experimental/keymap.c | 73 ++++++++++++++++++++++++-- keyboards/planck/keymaps/pvc/config.h | 5 +- keyboards/planck/keymaps/yang/config.h | 5 +- keyboards/preonic/config.h | 5 +- keyboards/satan/config.h | 14 ++--- quantum/light_ws2812.c | 25 ++++++--- quantum/rgblight.c | 23 ++++++-- quantum/rgblight.h | 7 ++- readme.md | 17 +++--- 17 files changed, 160 insertions(+), 74 deletions(-) (limited to 'quantum') diff --git a/keyboards/clueboard/rev1/config.h b/keyboards/clueboard/rev1/config.h index 9bb58f56e..8c9497232 100644 --- a/keyboards/clueboard/rev1/config.h +++ b/keyboards/clueboard/rev1/config.h @@ -25,9 +25,8 @@ /* Underlight configuration */ -#define ws2812_PORTREG PORTB -#define ws2812_DDRREG DDRB -#define ws2812_pin 2 +#define RGB_DI_PIN B2 +#define RGBLIGHT_TIMER #define RGBLED_NUM 14 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/clueboard/rev2/config.h b/keyboards/clueboard/rev2/config.h index e2f8336be..02982ff29 100644 --- a/keyboards/clueboard/rev2/config.h +++ b/keyboards/clueboard/rev2/config.h @@ -29,9 +29,8 @@ /* Underlight configuration */ -#define ws2812_PORTREG PORTD -#define ws2812_DDRREG DDRD -#define ws2812_pin 7 +#define RGB_DI_PIN D7 +#define RGBLIGHT_TIMER #define RGBLED_NUM 14 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/cluepad/config.h b/keyboards/cluepad/config.h index 0955e0f70..bae05fade 100644 --- a/keyboards/cluepad/config.h +++ b/keyboards/cluepad/config.h @@ -69,13 +69,12 @@ along with this program. If not, see . /* Underlight configuration */ - #define ws2812_PORTREG PORTF - #define ws2812_DDRREG DDRF - #define ws2812_pin 6 - #define RGBLED_NUM 4 // Number of LEDs - #define RGBLIGHT_HUE_STEP 10 - #define RGBLIGHT_SAT_STEP 17 - #define RGBLIGHT_VAL_STEP 17 +#define RGB_DI_PIN F6 +#define RGBLIGHT_TIMER +#define RGBLED_NUM 4 // Number of LEDs +#define RGBLIGHT_HUE_STEP 10 +#define RGBLIGHT_SAT_STEP 17 +#define RGBLIGHT_VAL_STEP 17 /* * Feature disable options diff --git a/keyboards/kc60/keymaps/ws2812/config.h b/keyboards/kc60/keymaps/ws2812/config.h index 933bb0d2d..2f39ea8e5 100644 --- a/keyboards/kc60/keymaps/ws2812/config.h +++ b/keyboards/kc60/keymaps/ws2812/config.h @@ -1,9 +1,8 @@ #include "../../config.h" /* WS2812B RGB Underglow LED */ -#define ws2812_PORTREG PORTF -#define ws2812_DDRREG DDRF -#define ws2812_pin PF5 // Based on wiring depicted in ws2812_wiring.jpg +#define RGB_DI_PIN F5 // Based on wiring depicted in ws2812_wiring.jpg +#define RGBLIGHT_TIMER #define RGBLED_NUM 16 // Number of LEDs. Change this to match your use case. #define RGBLIGHT_HUE_STEP 8 #define RGBLIGHT_SAT_STEP 8 diff --git a/keyboards/lets_split/config.h b/keyboards/lets_split/config.h index 6f90997ab..833818ce6 100644 --- a/keyboards/lets_split/config.h +++ b/keyboards/lets_split/config.h @@ -69,9 +69,8 @@ along with this program. If not, see . ) /* ws2812 RGB LED */ -#define ws2812_PORTREG PORTD -#define ws2812_DDRREG DDRD -#define ws2812_pin PD1 +#define RGB_DI_PIN D2 +#define RGBLIGHT_TIMER #define RGBLED_NUM 28 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/phantom/config.h b/keyboards/phantom/config.h index d5878766f..983a1d73f 100644 --- a/keyboards/phantom/config.h +++ b/keyboards/phantom/config.h @@ -62,13 +62,12 @@ along with this program. If not, see . /* Underlight configuration */ - #define ws2812_PORTREG PORTE - #define ws2812_DDRREG DDRE - #define ws2812_pin 2 - #define RGBLED_NUM 20 // Number of LEDs - #define RGBLIGHT_HUE_STEP 10 - #define RGBLIGHT_SAT_STEP 17 - #define RGBLIGHT_VAL_STEP 17 +#define RGB_DI_PIN E2 +#define RGBLIGHT_TIMER +#define RGBLED_NUM 20 // Number of LEDs +#define RGBLIGHT_HUE_STEP 10 +#define RGBLIGHT_SAT_STEP 17 +#define RGBLIGHT_VAL_STEP 17 /* * Feature disable options diff --git a/keyboards/planck/keymaps/experimental/Makefile b/keyboards/planck/keymaps/experimental/Makefile index 581e08cd0..877c4aed0 100644 --- a/keyboards/planck/keymaps/experimental/Makefile +++ b/keyboards/planck/keymaps/experimental/Makefile @@ -10,12 +10,12 @@ EXTRAKEY_ENABLE = yes # Audio control and System control(+450) CONSOLE_ENABLE = no # Console for debug(+400) COMMAND_ENABLE = yes # Commands for debug and configuration NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work -BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality +BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality MIDI_ENABLE = no # MIDI controls -AUDIO_ENABLE = yes # Audio output on port C6 +AUDIO_ENABLE = no # Audio output on port C6 UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID -RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time. +RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight. Do not enable this with audio at the same time. # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend diff --git a/keyboards/planck/keymaps/experimental/config.h b/keyboards/planck/keymaps/experimental/config.h index 985e250ab..52acd1905 100644 --- a/keyboards/planck/keymaps/experimental/config.h +++ b/keyboards/planck/keymaps/experimental/config.h @@ -6,4 +6,12 @@ #define LEADER_TIMEOUT 300 #define BACKLIGHT_BREATHING + +/* ws2812 RGB LED */ +#define RGB_DI_PIN B1 +#define RGBLIGHT_TIMER +#define RGBLED_NUM 8 // Number of LEDs +#define RGBLIGHT_HUE_STEP 10 +#define RGBLIGHT_SAT_STEP 17 + #endif diff --git a/keyboards/planck/keymaps/experimental/keymap.c b/keyboards/planck/keymaps/experimental/keymap.c index 8ec335d7d..d9303fcae 100644 --- a/keyboards/planck/keymaps/experimental/keymap.c +++ b/keyboards/planck/keymaps/experimental/keymap.c @@ -15,7 +15,7 @@ extern keymap_config_t keymap_config; // The underscores don't mean anything - you can have a layer called STUFF or any other name. // Layer names don't all need to be of the same length, obviously, and you can also skip them // entirely and just use numbers. -#define _QWERTY 0 +#define _QWERTY 10 #define _COLEMAK 1 #define _DVORAK 2 #define _LOWER 3 @@ -31,7 +31,15 @@ enum planck_keycodes { LOWER, RAISE, BACKLIT, - EXT_PLV + EXT_PLV, + RGBLED_TOGGLE, + RGBLED_STEP_MODE, + RGBLED_INCREASE_HUE, + RGBLED_DECREASE_HUE, + RGBLED_INCREASE_SAT, + RGBLED_DECREASE_SAT, + RGBLED_INCREASE_VAL, + RGBLED_DECREASE_VAL, }; // Fillers to make layering more clear @@ -39,14 +47,20 @@ enum planck_keycodes { #define XXXXXXX KC_NO const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { +[0] = { + {KC_NO, KC_NO, KC_NO, KC_NO, RGBLED_TOGGLE, RGBLED_STEP_MODE, RGBLED_INCREASE_HUE, RGBLED_DECREASE_HUE, RGBLED_INCREASE_SAT, RGBLED_DECREASE_SAT, RGBLED_INCREASE_VAL, RGBLED_DECREASE_VAL}, + {KC_NO, KC_NO, KC_NO, KC_NO, RGBLED_TOGGLE, RGBLED_STEP_MODE, RGBLED_INCREASE_HUE, RGBLED_DECREASE_HUE, RGBLED_INCREASE_SAT, RGBLED_DECREASE_SAT, RGBLED_INCREASE_VAL, RGBLED_DECREASE_VAL}, + {KC_NO, KC_NO, KC_NO, KC_NO, RGBLED_TOGGLE, RGBLED_STEP_MODE, RGBLED_INCREASE_HUE, RGBLED_DECREASE_HUE, RGBLED_INCREASE_SAT, RGBLED_DECREASE_SAT, RGBLED_INCREASE_VAL, RGBLED_DECREASE_VAL}, + {KC_NO, KC_NO, KC_NO, KC_NO, RGBLED_TOGGLE, RGBLED_STEP_MODE, RGBLED_INCREASE_HUE, RGBLED_DECREASE_HUE, RGBLED_INCREASE_SAT, RGBLED_DECREASE_SAT, RGBLED_INCREASE_VAL, RGBLED_DECREASE_VAL} +}, /* Qwerty - * ,-----------------------------------------------------------------------------------. + ,-----------------------------------------------------------------------------------. * | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp | * |------+------+------+------+------+-------------+------+------+------+------+------| * | Esc | A | S | D | F | G | H | J | K | L | ; | " | * |------+------+------+------+------+------|------+------+------+------+------+------| - * | Shift| Z | X | C | V | B | N | M | , | . | / |Enter | + * | Shift| Z | X | C | V | B | N | M |, | . | / |Enter | * |------+------+------+------+------+------+------+------+------+------+------+------| * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | * `-----------------------------------------------------------------------------------' @@ -292,6 +306,57 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { break; return false; + case RGBLED_TOGGLE: + //led operations + if (record->event.pressed) { + rgblight_toggle(); + } + return false; + break; + case RGBLED_INCREASE_HUE: + if (record->event.pressed) { + rgblight_increase_hue(); + } + return false; + break; + case RGBLED_DECREASE_HUE: + if (record->event.pressed) { + rgblight_decrease_hue(); + } + return false; + break; + case RGBLED_INCREASE_SAT: + if (record->event.pressed) { + rgblight_increase_sat(); + } + return false; + break; + case RGBLED_DECREASE_SAT: + if (record->event.pressed) { + rgblight_decrease_sat(); + } + return false; + break; + case RGBLED_INCREASE_VAL: + if (record->event.pressed) { + rgblight_increase_val(); + } + return false; + break; + case RGBLED_DECREASE_VAL: + if (record->event.pressed) { + rgblight_decrease_val(); + } + return false; + break; + case RGBLED_STEP_MODE: + if (record->event.pressed) { + rgblight_step(); + } + return false; + break; + + } return true; }; diff --git a/keyboards/planck/keymaps/pvc/config.h b/keyboards/planck/keymaps/pvc/config.h index b64893108..c857a3e89 100644 --- a/keyboards/planck/keymaps/pvc/config.h +++ b/keyboards/planck/keymaps/pvc/config.h @@ -60,9 +60,8 @@ along with this program. If not, see . ) /* ws2812 RGB LED */ -#define ws2812_PORTREG PORTD -#define ws2812_DDRREG DDRD -#define ws2812_pin PD1 +#define RGB_DI_PIN D1 +#define RGBLIGHT_TIMER #define RGBLED_NUM 28 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/planck/keymaps/yang/config.h b/keyboards/planck/keymaps/yang/config.h index 5921e9377..feb5a1190 100644 --- a/keyboards/planck/keymaps/yang/config.h +++ b/keyboards/planck/keymaps/yang/config.h @@ -4,9 +4,8 @@ #include "../../config.h" /* ws2812 RGB LED */ -#define ws2812_PORTREG PORTD -#define ws2812_DDRREG DDRD -#define ws2812_pin PD1 +#define RGB_DI_PIN D1 +#define RGBLIGHT_TIMER #define RGBLED_NUM 28 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/preonic/config.h b/keyboards/preonic/config.h index 04946f7fb..3fb978c2f 100644 --- a/keyboards/preonic/config.h +++ b/keyboards/preonic/config.h @@ -62,9 +62,8 @@ along with this program. If not, see . ) /* ws2812 RGB LED */ -#define ws2812_PORTREG PORTD -#define ws2812_DDRREG DDRD -#define ws2812_pin PD1 +#define RGB_DI_PIN D1 +#define RGBLIGHT_TIMER #define RGBLED_NUM 28 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/satan/config.h b/keyboards/satan/config.h index a7ea8f904..7e9f91cc8 100644 --- a/keyboards/satan/config.h +++ b/keyboards/satan/config.h @@ -65,13 +65,13 @@ along with this program. If not, see . /* Underlight configuration */ - #define ws2812_PORTREG PORTE - #define ws2812_DDRREG DDRE - #define ws2812_pin 2 - #define RGBLED_NUM 8 // Number of LEDs - #define RGBLIGHT_HUE_STEP 10 - #define RGBLIGHT_SAT_STEP 17 - #define RGBLIGHT_VAL_STEP 17 + +#define RGB_DI_PIN E2 +#define RGBLIGHT_TIMER +#define RGBLED_NUM 8 // Number of LEDs +#define RGBLIGHT_HUE_STEP 10 +#define RGBLIGHT_SAT_STEP 17 +#define RGBLIGHT_VAL_STEP 17 /* * Feature disable options diff --git a/quantum/light_ws2812.c b/quantum/light_ws2812.c index f20043067..401845e85 100755 --- a/quantum/light_ws2812.c +++ b/quantum/light_ws2812.c @@ -19,12 +19,16 @@ // Setleds for standard RGB void inline ws2812_setleds(struct cRGB *ledarray, uint16_t leds) { - ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin)); + // ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin)); + ws2812_setleds_pin(ledarray,leds, _BV(RGB_DI_PIN & 0xF)); } void inline ws2812_setleds_pin(struct cRGB *ledarray, uint16_t leds, uint8_t pinmask) { - ws2812_DDRREG |= pinmask; // Enable DDR + // 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); } @@ -32,14 +36,17 @@ void inline ws2812_setleds_pin(struct cRGB *ledarray, uint16_t leds, uint8_t pin // Setleds for SK6812RGBW void inline ws2812_setleds_rgbw(struct cRGBW *ledarray, uint16_t leds) { - ws2812_DDRREG |= _BV(ws2812_pin); // Enable DDR - ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(ws2812_pin)); + // 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)); _delay_us(80); } void ws2812_sendarray(uint8_t *data,uint16_t datlen) { - ws2812_sendarray_mask(data,datlen,_BV(ws2812_pin)); + ws2812_sendarray_mask(data,datlen,_BV(RGB_DI_PIN & 0xF)); } /* @@ -108,8 +115,10 @@ 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&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(); @@ -173,7 +182,7 @@ w_nop16 " dec %0 \n\t" // '1' [+2] '0' [+2] " brne loop%=\n\t" // '1' [+3] '0' [+4] : "=&d" (ctr) - : "r" (curbyte), "I" (_SFR_IO_ADDR(ws2812_PORTREG)), "r" (maskhi), "r" (masklo) + : "r" (curbyte), "I" (_SFR_IO_ADDR(_SFR_IO8((RGB_DI_PIN >> 4) + 2))), "r" (maskhi), "r" (masklo) ); } diff --git a/quantum/rgblight.c b/quantum/rgblight.c index c29ffedc3..b1b0f035d 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -146,7 +146,9 @@ void rgblight_init(void) { } eeconfig_debug_rgblight(); // display current eeprom values - rgblight_timer_init(); // setup the timer + #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + rgblight_timer_init(); // setup the timer + #endif if (rgblight_config.enable) { rgblight_mode(rgblight_config.mode); @@ -192,14 +194,19 @@ void rgblight_mode(uint8_t mode) { eeconfig_update_rgblight(rgblight_config.raw); xprintf("rgblight mode: %u\n", rgblight_config.mode); if (rgblight_config.mode == 1) { - rgblight_timer_disable(); + #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + rgblight_timer_disable(); + #endif } else if (rgblight_config.mode >=2 && rgblight_config.mode <=23) { // MODE 2-5, breathing // MODE 6-8, rainbow mood // MODE 9-14, rainbow swirl // MODE 15-20, snake // MODE 21-23, knight - rgblight_timer_enable(); + + #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + rgblight_timer_enable(); + #endif } rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } @@ -211,7 +218,10 @@ void rgblight_toggle(void) { if (rgblight_config.enable) { rgblight_mode(rgblight_config.mode); } else { - rgblight_timer_disable(); + + #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + rgblight_timer_disable(); + #endif _delay_ms(50); rgblight_set(); } @@ -328,6 +338,9 @@ void rgblight_set(void) { } } + +#if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + // Animation timer -- AVR Timer3 void rgblight_timer_init(void) { static uint8_t rgblight_timer_is_init = 0; @@ -503,3 +516,5 @@ void rgblight_effect_knight(uint8_t interval) { } } + +#endif \ No newline at end of file diff --git a/quantum/rgblight.h b/quantum/rgblight.h index 64f92523e..def26c428 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -1,8 +1,11 @@ #ifndef RGBLIGHT_H #define RGBLIGHT_H -#ifndef RGBLIGHT_MODES -#define RGBLIGHT_MODES 23 + +#if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + #define RGBLIGHT_MODES 23 +#else + #define RGBLIGHT_MODES 1 #endif #ifndef RGBLIGHT_EFFECT_SNAKE_LENGTH diff --git a/readme.md b/readme.md index c24d951d8..e87481251 100644 --- a/readme.md +++ b/readme.md @@ -704,23 +704,18 @@ For this mod, you need an unused pin wiring to DI of WS2812 strip. After wiring RGBLIGHT_ENABLE = yes -Please note that the underglow is not compatible with audio output. So you cannot enable both of them at the same time. +In order to use the underglow timer functions, you need to have `#define RGBLIGHT_TIMER` in your `config.h`, and have audio disabled (`AUDIO_ENABLE = no` in your Makefile). -Please add the following options into your config.h, and set them up according your hardware configuration. These settings are for the F4 by default: - - #define ws2812_PORTREG PORTF - #define ws2812_DDRREG DDRF - #define ws2812_pin PF4 +Please add the following options into your config.h, and set them up according your hardware configuration. These settings are for the `F4` pin by default: + + #define RGB_DI_PIN F4 // The pin your RGB strip is wired to + #define RGBLIGHT_TIMER // Require for fancier stuff (not compatible with audio) #define RGBLED_NUM 14 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 #define RGBLIGHT_VAL_STEP 17 -You'll need to edit `PORTF`, `DDRF`, and `PF4` on the first three lines to the port/pin you have your LED(s) wired to, eg for B3 change things to: - - #define ws2812_PORTREG PORTB - #define ws2812_DDRREG DDRB - #define ws2812_pin PB3 +You'll need to edit `RGB_DI_PIN` to the pin you have your `DI` on your RGB strip wired to. The firmware supports 5 different light effects, and the color (hue, saturation, brightness) can be customized in most effects. To control the underglow, you need to modify your keymap file to assign those functions to some keys/key combinations. For details, please check this keymap. `keyboards/planck/keymaps/yang/keymap.c` -- cgit v1.3.1 From c1dfb636ef61159456bdb24f4fee3f27e5babbeb Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Thu, 7 Jul 2016 12:22:10 -0400 Subject: fixes quantum template (actually) --- quantum/template/template.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/template/template.c b/quantum/template/template.c index 3057557ea..5ef349583 100644 --- a/quantum/template/template.c +++ b/quantum/template/template.c @@ -18,7 +18,7 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) { // put your per-action keyboard code here // runs for every action, just before processing by the firmware - return process_record_user(record); + return process_record_user(keycode, record); } void led_set_kb(uint8_t usb_led) { -- cgit v1.3.1 From 9870082a06386eba8c0c5f22da90d0256ef6244b Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Thu, 7 Jul 2016 19:48:39 +0300 Subject: Fix the range for consumer keys --- quantum/keymap_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 76872ac59..d0a8312c1 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -62,7 +62,7 @@ action_t action_for_key(uint8_t layer, keypos_t key) case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE: action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode)); break; - case KC_AUDIO_MUTE ... KC_WWW_FAVORITES: + case KC_AUDIO_MUTE ... KC_MEDIA_REWIND: action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode)); break; case KC_MS_UP ... KC_MS_ACCEL2: -- cgit v1.3.1 From 50c686587ed49d8079ba1b11d45ceb6a55d6cd4b Mon Sep 17 00:00:00 2001 From: TerryMathews Date: Thu, 7 Jul 2016 23:34:33 -0400 Subject: Create keycodes for RGB control functions Moves RGB controls out of the macro function and assigns them their own keycodes: RGB_TOG (toggle on/off) RGB_MOD (mode step) RGB_HUI (increase hue) RGB_HUD (decrease hue) RGB_SAI (increase saturation) RGB_SAD (decrease saturation) RGB_VAI (increase brightness) RGB_VAD (decrease brightness) --- keyboards/clueboard/keymaps/default/keymap.c | 72 ++------------------------- keyboards/clueboard/keymaps/max/keymap.c | 66 ++----------------------- keyboards/cluepad/keymaps/default/keymap.c | 67 ++----------------------- keyboards/kc60/keymaps/stanleylai/keymap.c | 67 +------------------------ keyboards/kc60/keymaps/ws2812/keymap.c | 65 +------------------------ keyboards/phantom/keymaps/default/keymap.c | 69 +------------------------- keyboards/planck/keymaps/yang/keymap.c | 62 ++--------------------- keyboards/satan/keymaps/default/keymap.c | 68 +------------------------- keyboards/satan/keymaps/sethbc/keymap.c | 73 ++-------------------------- quantum/keymap.h | 10 ++++ quantum/quantum.c | 50 +++++++++++++++++++ 11 files changed, 83 insertions(+), 586 deletions(-) (limited to 'quantum') diff --git a/keyboards/clueboard/keymaps/default/keymap.c b/keyboards/clueboard/keymaps/default/keymap.c index 89f71e83a..896bc7ebc 100644 --- a/keyboards/clueboard/keymaps/default/keymap.c +++ b/keyboards/clueboard/keymaps/default/keymap.c @@ -67,11 +67,11 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { */ [_RS] = KEYMAP( #ifdef RGBLIGHT_ENABLE - KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, F(1), F(7), \ - KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,RESET, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, F(8), \ + KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_TOG, RGB_VAI, \ + KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,RESET, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_VAD, \ KC_TRNS, KC_TRNS, MO(_RS),KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \ - MO(_FL), KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, MO(_FL), F(5), \ - KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS, F(2), F(2), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, F(4), F(6), F(3)), + MO(_FL), KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, MO(_FL), RGB_SAI, \ + KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS, RGB_MOD, RGB_MOD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_HUD, RGB_SAD, RGB_HUI), #else KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \ KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,RESET, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \ @@ -83,30 +83,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { enum function_id { SHIFT_ESC, - #ifdef RGBLIGHT_ENABLE - RGBLED_TOGGLE, - RGBLED_STEP_MODE, - RGBLED_INCREASE_HUE, - RGBLED_DECREASE_HUE, - RGBLED_INCREASE_SAT, - RGBLED_DECREASE_SAT, - RGBLED_INCREASE_VAL, - RGBLED_DECREASE_VAL - #endif }; const uint16_t PROGMEM fn_actions[] = { [0] = ACTION_FUNCTION(SHIFT_ESC), - #ifdef RGBLIGHT_ENABLE - [1] = ACTION_FUNCTION(RGBLED_TOGGLE), - [2] = ACTION_FUNCTION(RGBLED_STEP_MODE), - [3] = ACTION_FUNCTION(RGBLED_INCREASE_HUE), - [4] = ACTION_FUNCTION(RGBLED_DECREASE_HUE), - [5] = ACTION_FUNCTION(RGBLED_INCREASE_SAT), - [6] = ACTION_FUNCTION(RGBLED_DECREASE_SAT), - [7] = ACTION_FUNCTION(RGBLED_INCREASE_VAL), - [8] = ACTION_FUNCTION(RGBLED_DECREASE_VAL), - #endif }; void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { @@ -132,49 +112,5 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { } } break; - //led operations - #ifdef RGBLIGHT_ENABLE - case RGBLED_TOGGLE: - if (record->event.pressed) { - rgblight_toggle(); - } - - break; - case RGBLED_INCREASE_HUE: - if (record->event.pressed) { - rgblight_increase_hue(); - } - break; - case RGBLED_DECREASE_HUE: - if (record->event.pressed) { - rgblight_decrease_hue(); - } - break; - case RGBLED_INCREASE_SAT: - if (record->event.pressed) { - rgblight_increase_sat(); - } - break; - case RGBLED_DECREASE_SAT: - if (record->event.pressed) { - rgblight_decrease_sat(); - } - break; - case RGBLED_INCREASE_VAL: - if (record->event.pressed) { - rgblight_increase_val(); - } - break; - case RGBLED_DECREASE_VAL: - if (record->event.pressed) { - rgblight_decrease_val(); - } - break; - case RGBLED_STEP_MODE: - if (record->event.pressed) { - rgblight_step(); - } - break; - #endif } } diff --git a/keyboards/clueboard/keymaps/max/keymap.c b/keyboards/clueboard/keymaps/max/keymap.c index 82c93401d..080b4930b 100644 --- a/keyboards/clueboard/keymaps/max/keymap.c +++ b/keyboards/clueboard/keymaps/max/keymap.c @@ -66,78 +66,20 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * `----------------------------------------------------------------------------------' */ [_RS] = KEYMAP( - KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, F(0), F(6), \ - KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,RESET, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, F(7), \ + KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_TOG, RGB_VAI, \ + KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,RESET, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_VAD, \ KC_TRNS, KC_TRNS, MO(_RS),KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \ - MO(_FL), KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, MO(_FL), F(4), \ - KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS, F(1), F(1), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, F(3), F(5), F(2)), + MO(_FL), KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, MO(_FL), RGB_SAI, \ + KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS, RGB_MOD, RGB_MOD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_HUD, RGB_SAD, RGB_HUI), }; enum function_id { - RGBLED_TOGGLE, - RGBLED_STEP_MODE, - RGBLED_INCREASE_HUE, - RGBLED_DECREASE_HUE, - RGBLED_INCREASE_SAT, - RGBLED_DECREASE_SAT, - RGBLED_INCREASE_VAL, - RGBLED_DECREASE_VAL, }; const uint16_t PROGMEM fn_actions[] = { - [0] = ACTION_FUNCTION(RGBLED_TOGGLE), - [1] = ACTION_FUNCTION(RGBLED_STEP_MODE), - [2] = ACTION_FUNCTION(RGBLED_INCREASE_HUE), - [3] = ACTION_FUNCTION(RGBLED_DECREASE_HUE), - [4] = ACTION_FUNCTION(RGBLED_INCREASE_SAT), - [5] = ACTION_FUNCTION(RGBLED_DECREASE_SAT), - [6] = ACTION_FUNCTION(RGBLED_INCREASE_VAL), - [7] = ACTION_FUNCTION(RGBLED_DECREASE_VAL), }; void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { switch (id) { - case RGBLED_TOGGLE: - //led operations - if (record->event.pressed) { - rgblight_toggle(); - } - - break; - case RGBLED_INCREASE_HUE: - if (record->event.pressed) { - rgblight_increase_hue(); - } - break; - case RGBLED_DECREASE_HUE: - if (record->event.pressed) { - rgblight_decrease_hue(); - } - break; - case RGBLED_INCREASE_SAT: - if (record->event.pressed) { - rgblight_increase_sat(); - } - break; - case RGBLED_DECREASE_SAT: - if (record->event.pressed) { - rgblight_decrease_sat(); - } - break; - case RGBLED_INCREASE_VAL: - if (record->event.pressed) { - rgblight_increase_val(); - } - break; - case RGBLED_DECREASE_VAL: - if (record->event.pressed) { - rgblight_decrease_val(); - } - break; - case RGBLED_STEP_MODE: - if (record->event.pressed) { - rgblight_step(); - } - break; } } diff --git a/keyboards/cluepad/keymaps/default/keymap.c b/keyboards/cluepad/keymaps/default/keymap.c index 8ba49952f..10881e8de 100644 --- a/keyboards/cluepad/keymaps/default/keymap.c +++ b/keyboards/cluepad/keymaps/default/keymap.c @@ -1,7 +1,6 @@ #include "cluepad.h" #include "backlight.h" -#include "rgblight.h" // Each layer gets a name for readability, which is then used in the keymap matrix below. // The underscores don't mean anything - you can have a layer called STUFF or any other name. @@ -46,77 +45,21 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * '-------------------' */ [_FL] = KEYMAP( - LT(_FL, KC_NLCK), KC_TRNS, KC_TRNS, F(0), \ - KC_TRNS, F(4), KC_TRNS, F(6), \ - F(3), BL_STEP, F(2), \ - KC_TRNS, F(5), KC_TRNS, F(7), \ - F(1), KC_TRNS) + LT(_FL, KC_NLCK), KC_TRNS, KC_TRNS, RGB_TOG, \ + KC_TRNS, RGB_SAI, KC_TRNS, RGB_VAI, \ + RGB_HUD, BL_STEP, RGB_HUI, \ + KC_TRNS, RGB_SAD, KC_TRNS, RGB_VAD, \ + RGB_MOD, KC_TRNS) }; enum function_id { - RGBLED_TOGGLE, - RGBLED_STEP_MODE, - RGBLED_INCREASE_HUE, - RGBLED_DECREASE_HUE, - RGBLED_INCREASE_SAT, - RGBLED_DECREASE_SAT, - RGBLED_INCREASE_VAL, - RGBLED_DECREASE_VAL, }; const uint16_t PROGMEM fn_actions[] = { - [0] = ACTION_FUNCTION(RGBLED_TOGGLE), - [1] = ACTION_FUNCTION(RGBLED_STEP_MODE), - [2] = ACTION_FUNCTION(RGBLED_INCREASE_HUE), - [3] = ACTION_FUNCTION(RGBLED_DECREASE_HUE), - [4] = ACTION_FUNCTION(RGBLED_INCREASE_SAT), - [5] = ACTION_FUNCTION(RGBLED_DECREASE_SAT), - [6] = ACTION_FUNCTION(RGBLED_INCREASE_VAL), - [7] = ACTION_FUNCTION(RGBLED_DECREASE_VAL), }; void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { switch (id) { - case RGBLED_TOGGLE: - if (record->event.pressed) { - rgblight_toggle(); - } - break; - case RGBLED_INCREASE_HUE: - if (record->event.pressed) { - rgblight_increase_hue(); - } - break; - case RGBLED_DECREASE_HUE: - if (record->event.pressed) { - rgblight_decrease_hue(); - } - break; - case RGBLED_INCREASE_SAT: - if (record->event.pressed) { - rgblight_increase_sat(); - } - break; - case RGBLED_DECREASE_SAT: - if (record->event.pressed) { - rgblight_decrease_sat(); - } - break; - case RGBLED_INCREASE_VAL: - if (record->event.pressed) { - rgblight_increase_val(); - } - break; - case RGBLED_DECREASE_VAL: - if (record->event.pressed) { - rgblight_decrease_val(); - } - break; - case RGBLED_STEP_MODE: - if (record->event.pressed) { - rgblight_step(); - } - break; } } diff --git a/keyboards/kc60/keymaps/stanleylai/keymap.c b/keyboards/kc60/keymaps/stanleylai/keymap.c index a7ea6040d..057c73bf4 100644 --- a/keyboards/kc60/keymaps/stanleylai/keymap.c +++ b/keyboards/kc60/keymaps/stanleylai/keymap.c @@ -38,7 +38,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { RESET, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, \ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, \ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, \ - KC_TRNS,KC_NO, F(1), F(2), F(3), F(4), F(5), F(6), F(7), F(8), BL_STEP,BL_TOGG, KC_TRNS, KC_TRNS,\ + KC_TRNS,KC_NO, RGB_TOG,RGB_MOD,RGB_HUI,RGB_HUD,RGB_SAI,RGB_SAD,RGB_VAI,RGB_VAD,BL_STEP,BL_TOGG, KC_TRNS, KC_TRNS,\ KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS), #else RESET, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, \ @@ -52,30 +52,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { enum function_id { SHIFT_ESC, - #ifdef RGBLIGHT_ENABLE - RGBLED_TOGGLE, - RGBLED_STEP_MODE, - RGBLED_INCREASE_HUE, - RGBLED_DECREASE_HUE, - RGBLED_INCREASE_SAT, - RGBLED_DECREASE_SAT, - RGBLED_INCREASE_VAL, - RGBLED_DECREASE_VAL, - #endif }; const uint16_t PROGMEM fn_actions[] = { [0] = ACTION_FUNCTION(SHIFT_ESC), - #ifdef RGBLIGHT_ENABLE - [1] = ACTION_FUNCTION(RGBLED_TOGGLE), - [2] = ACTION_FUNCTION(RGBLED_STEP_MODE), - [3] = ACTION_FUNCTION(RGBLED_INCREASE_HUE), - [4] = ACTION_FUNCTION(RGBLED_DECREASE_HUE), - [5] = ACTION_FUNCTION(RGBLED_INCREASE_SAT), - [6] = ACTION_FUNCTION(RGBLED_DECREASE_SAT), - [7] = ACTION_FUNCTION(RGBLED_INCREASE_VAL), - [8] = ACTION_FUNCTION(RGBLED_DECREASE_VAL), - #endif }; #define MODS_CTRL_MASK (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)) @@ -102,50 +82,5 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { } } break; - - #ifdef RGBLIGHT_ENABLE - - case RGBLED_TOGGLE: - //led operations - if (record->event.pressed) { - rgblight_toggle(); - } - break; - case RGBLED_INCREASE_HUE: - if (record->event.pressed) { - rgblight_increase_hue(); - } - break; - case RGBLED_DECREASE_HUE: - if (record->event.pressed) { - rgblight_decrease_hue(); - } - break; - case RGBLED_INCREASE_SAT: - if (record->event.pressed) { - rgblight_increase_sat(); - } - break; - case RGBLED_DECREASE_SAT: - if (record->event.pressed) { - rgblight_decrease_sat(); - } - break; - case RGBLED_INCREASE_VAL: - if (record->event.pressed) { - rgblight_increase_val(); - } - break; - case RGBLED_DECREASE_VAL: - if (record->event.pressed) { - rgblight_decrease_val(); - } - break; - case RGBLED_STEP_MODE: - if (record->event.pressed) { - rgblight_step(); - } - break; - #endif } } diff --git a/keyboards/kc60/keymaps/ws2812/keymap.c b/keyboards/kc60/keymaps/ws2812/keymap.c index bd5bef787..1c0574df0 100644 --- a/keyboards/kc60/keymaps/ws2812/keymap.c +++ b/keyboards/kc60/keymaps/ws2812/keymap.c @@ -52,7 +52,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 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, \ KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BL_DEC, BL_INC, BL_TOGG, \ KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \ - KC_TRNS, KC_TRNS, F(1), F(2), F(3), F(4), F(5), F(6), F(7), F(8), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \ + KC_TRNS, KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET), #else 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, \ @@ -65,30 +65,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { enum function_id { SHIFT_ESC, - #ifdef RGBLIGHT_ENABLE - RGBLED_TOGGLE, - RGBLED_STEP_MODE, - RGBLED_INCREASE_HUE, - RGBLED_DECREASE_HUE, - RGBLED_INCREASE_SAT, - RGBLED_DECREASE_SAT, - RGBLED_INCREASE_VAL, - RGBLED_DECREASE_VAL - #endif }; const uint16_t PROGMEM fn_actions[] = { [0] = ACTION_FUNCTION(SHIFT_ESC), - #ifdef RGBLIGHT_ENABLE - [1] = ACTION_FUNCTION(RGBLED_TOGGLE), - [2] = ACTION_FUNCTION(RGBLED_STEP_MODE), - [3] = ACTION_FUNCTION(RGBLED_INCREASE_HUE), - [4] = ACTION_FUNCTION(RGBLED_DECREASE_HUE), - [5] = ACTION_FUNCTION(RGBLED_INCREASE_SAT), - [6] = ACTION_FUNCTION(RGBLED_DECREASE_SAT), - [7] = ACTION_FUNCTION(RGBLED_INCREASE_VAL), - [8] = ACTION_FUNCTION(RGBLED_DECREASE_VAL), - #endif }; void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { @@ -114,48 +94,5 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { } } break; - //led operations - #ifdef RGBLIGHT_ENABLE - case RGBLED_TOGGLE: - if (record->event.pressed) { - rgblight_toggle(); - } - break; - case RGBLED_INCREASE_HUE: - if (record->event.pressed) { - rgblight_increase_hue(); - } - break; - case RGBLED_DECREASE_HUE: - if (record->event.pressed) { - rgblight_decrease_hue(); - } - break; - case RGBLED_INCREASE_SAT: - if (record->event.pressed) { - rgblight_increase_sat(); - } - break; - case RGBLED_DECREASE_SAT: - if (record->event.pressed) { - rgblight_decrease_sat(); - } - break; - case RGBLED_INCREASE_VAL: - if (record->event.pressed) { - rgblight_increase_val(); - } - break; - case RGBLED_DECREASE_VAL: - if (record->event.pressed) { - rgblight_decrease_val(); - } - break; - case RGBLED_STEP_MODE: - if (record->event.pressed) { - rgblight_step(); - } - break; - #endif } } diff --git a/keyboards/phantom/keymaps/default/keymap.c b/keyboards/phantom/keymaps/default/keymap.c index 1368226aa..a4fc319ac 100644 --- a/keyboards/phantom/keymaps/default/keymap.c +++ b/keyboards/phantom/keymaps/default/keymap.c @@ -1,9 +1,5 @@ #include "phantom.h" -#ifdef RGBLIGHT_ENABLE -#include "rgblight.h" -#endif - // Used for SHIFT_ESC #define MODS_CTRL_MASK (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)) @@ -59,7 +55,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET, KC_TRNS, KC_TRNS, KC_TRNS, \ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, \ - KC_TRNS, F(1), F(2), F(3), F(4), F(5), F(6), F(7), F(8), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \ + KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), #else KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \ @@ -73,30 +69,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { enum function_id { SHIFT_ESC, - #ifdef RGBLIGHT_ENABLE - RGBLED_TOGGLE, - RGBLED_STEP_MODE, - RGBLED_INCREASE_HUE, - RGBLED_DECREASE_HUE, - RGBLED_INCREASE_SAT, - RGBLED_DECREASE_SAT, - RGBLED_INCREASE_VAL, - RGBLED_DECREASE_VAL - #endif }; const uint16_t PROGMEM fn_actions[] = { [0] = ACTION_FUNCTION(SHIFT_ESC), - #ifdef RGBLIGHT_ENABLE - [1] = ACTION_FUNCTION(RGBLED_TOGGLE), - [2] = ACTION_FUNCTION(RGBLED_STEP_MODE), - [3] = ACTION_FUNCTION(RGBLED_INCREASE_HUE), - [4] = ACTION_FUNCTION(RGBLED_DECREASE_HUE), - [5] = ACTION_FUNCTION(RGBLED_INCREASE_SAT), - [6] = ACTION_FUNCTION(RGBLED_DECREASE_SAT), - [7] = ACTION_FUNCTION(RGBLED_INCREASE_VAL), - [8] = ACTION_FUNCTION(RGBLED_DECREASE_VAL), - #endif }; void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { @@ -122,48 +98,5 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { } } break; - //led operations - #ifdef RGBLIGHT_ENABLE - case RGBLED_TOGGLE: - if (record->event.pressed) { - rgblight_toggle(); - } - break; - case RGBLED_INCREASE_HUE: - if (record->event.pressed) { - rgblight_increase_hue(); - } - break; - case RGBLED_DECREASE_HUE: - if (record->event.pressed) { - rgblight_decrease_hue(); - } - break; - case RGBLED_INCREASE_SAT: - if (record->event.pressed) { - rgblight_increase_sat(); - } - break; - case RGBLED_DECREASE_SAT: - if (record->event.pressed) { - rgblight_decrease_sat(); - } - break; - case RGBLED_INCREASE_VAL: - if (record->event.pressed) { - rgblight_increase_val(); - } - break; - case RGBLED_DECREASE_VAL: - if (record->event.pressed) { - rgblight_decrease_val(); - } - break; - case RGBLED_STEP_MODE: - if (record->event.pressed) { - rgblight_step(); - } - break; - #endif } } diff --git a/keyboards/planck/keymaps/yang/keymap.c b/keyboards/planck/keymaps/yang/keymap.c index 541b1a57e..5f2907a08 100644 --- a/keyboards/planck/keymaps/yang/keymap.c +++ b/keyboards/planck/keymaps/yang/keymap.c @@ -51,33 +51,18 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_RGB] = { /* RGBLIGHT */ {KC_TRNS, KC_PGUP, KC_UP, KC_PGDN, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_DEL}, {KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_HOME, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_END, KC_TRNS}, - {KC_TRNS, F(1), F(2), F(3), F(4), F(5), F(6), F(7), F(8), KC_TRNS, KC_TRNS, KC_TRNS}, + {KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_TRNS, KC_TRNS, KC_TRNS}, {KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS} } }; enum function_id { - RGBLED_TOGGLE, - RGBLED_STEP_MODE, - RGBLED_INCREASE_HUE, - RGBLED_DECREASE_HUE, - RGBLED_INCREASE_SAT, - RGBLED_DECREASE_SAT, - RGBLED_INCREASE_VAL, - RGBLED_DECREASE_VAL, + }; const uint16_t PROGMEM fn_actions[] = { [0] = ACTION_LAYER_TAP_KEY(_RGB, KC_SPC), - [1] = ACTION_FUNCTION(RGBLED_TOGGLE), - [2] = ACTION_FUNCTION(RGBLED_STEP_MODE), - [3] = ACTION_FUNCTION(RGBLED_INCREASE_HUE), - [4] = ACTION_FUNCTION(RGBLED_DECREASE_HUE), - [5] = ACTION_FUNCTION(RGBLED_INCREASE_SAT), - [6] = ACTION_FUNCTION(RGBLED_DECREASE_SAT), - [7] = ACTION_FUNCTION(RGBLED_INCREASE_VAL), - [8] = ACTION_FUNCTION(RGBLED_DECREASE_VAL), }; const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) @@ -100,47 +85,6 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { switch (id) { - case RGBLED_TOGGLE: - //led operations - if (record->event.pressed) { - rgblight_toggle(); - } - - break; - case RGBLED_INCREASE_HUE: - if (record->event.pressed) { - rgblight_increase_hue(); - } - break; - case RGBLED_DECREASE_HUE: - if (record->event.pressed) { - rgblight_decrease_hue(); - } - break; - case RGBLED_INCREASE_SAT: - if (record->event.pressed) { - rgblight_increase_sat(); - } - break; - case RGBLED_DECREASE_SAT: - if (record->event.pressed) { - rgblight_decrease_sat(); - } - break; - case RGBLED_INCREASE_VAL: - if (record->event.pressed) { - rgblight_increase_val(); - } - break; - case RGBLED_DECREASE_VAL: - if (record->event.pressed) { - rgblight_decrease_val(); - } - break; - case RGBLED_STEP_MODE: - if (record->event.pressed) { - rgblight_step(); - } - break; + } } diff --git a/keyboards/satan/keymaps/default/keymap.c b/keyboards/satan/keymaps/default/keymap.c index b19404afc..35dbbb77b 100644 --- a/keyboards/satan/keymaps/default/keymap.c +++ b/keyboards/satan/keymaps/default/keymap.c @@ -1,8 +1,5 @@ #include "satan.h" -#ifdef RGBLIGHT_ENABLE -#include "rgblight.h" -#endif // Used for SHIFT_ESC #define MODS_CTRL_MASK (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)) @@ -53,7 +50,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_GRV, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET, \ KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, BL_DEC, BL_INC, BL_TOGG, \ KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \ - KC_TRNS, F(1), F(2), F(3), F(4), F(5), F(6), F(7), F(8), KC_TRNS, KC_TRNS, KC_TRNS, \ + KC_TRNS,RGB_TOG,RGB_MOD,RGB_HUI,RGB_HUD,RGB_SAI,RGB_SAD,RGB_VAI,RGB_VAD, KC_TRNS, KC_TRNS, KC_TRNS, \ KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), #else KC_GRV, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET, \ @@ -66,30 +63,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { enum function_id { SHIFT_ESC, - #ifdef RGBLIGHT_ENABLE - RGBLED_TOGGLE, - RGBLED_STEP_MODE, - RGBLED_INCREASE_HUE, - RGBLED_DECREASE_HUE, - RGBLED_INCREASE_SAT, - RGBLED_DECREASE_SAT, - RGBLED_INCREASE_VAL, - RGBLED_DECREASE_VAL - #endif }; const uint16_t PROGMEM fn_actions[] = { [0] = ACTION_FUNCTION(SHIFT_ESC), - #ifdef RGBLIGHT_ENABLE - [1] = ACTION_FUNCTION(RGBLED_TOGGLE), - [2] = ACTION_FUNCTION(RGBLED_STEP_MODE), - [3] = ACTION_FUNCTION(RGBLED_INCREASE_HUE), - [4] = ACTION_FUNCTION(RGBLED_DECREASE_HUE), - [5] = ACTION_FUNCTION(RGBLED_INCREASE_SAT), - [6] = ACTION_FUNCTION(RGBLED_DECREASE_SAT), - [7] = ACTION_FUNCTION(RGBLED_INCREASE_VAL), - [8] = ACTION_FUNCTION(RGBLED_DECREASE_VAL), - #endif }; void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { @@ -115,48 +92,5 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { } } break; - //led operations - #ifdef RGBLIGHT_ENABLE - case RGBLED_TOGGLE: - if (record->event.pressed) { - rgblight_toggle(); - } - break; - case RGBLED_INCREASE_HUE: - if (record->event.pressed) { - rgblight_increase_hue(); - } - break; - case RGBLED_DECREASE_HUE: - if (record->event.pressed) { - rgblight_decrease_hue(); - } - break; - case RGBLED_INCREASE_SAT: - if (record->event.pressed) { - rgblight_increase_sat(); - } - break; - case RGBLED_DECREASE_SAT: - if (record->event.pressed) { - rgblight_decrease_sat(); - } - break; - case RGBLED_INCREASE_VAL: - if (record->event.pressed) { - rgblight_increase_val(); - } - break; - case RGBLED_DECREASE_VAL: - if (record->event.pressed) { - rgblight_decrease_val(); - } - break; - case RGBLED_STEP_MODE: - if (record->event.pressed) { - rgblight_step(); - } - break; - #endif } } diff --git a/keyboards/satan/keymaps/sethbc/keymap.c b/keyboards/satan/keymaps/sethbc/keymap.c index 0ea4a7ae4..f8991f9fd 100644 --- a/keyboards/satan/keymaps/sethbc/keymap.c +++ b/keyboards/satan/keymaps/sethbc/keymap.c @@ -1,9 +1,5 @@ #include "satan.h" -#ifdef RGBLIGHT_ENABLE -#include "rgblight.h" -#endif - // Used for SHIFT_ESC #define MODS_CTRL_MASK (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)) @@ -44,39 +40,19 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), #else 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_TRNS, RESET, \ - KC_CAPS, KC_TRNS, F(1), F(2), F(3), KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, KC_TRNS, KC_BSPC, \ - KC_TRNS, KC_VOLD, F(4), F(5), F(6), KC_TRNS, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_PENT, \ - KC_TRNS, F(7), F(8), KC_TRNS, KC_TRNS, KC_TRNS, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, KC_TRNS, KC_TRNS, \ + KC_CAPS, KC_TRNS, RGB_TOG,RGB_MOD,RGB_HUI, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, KC_TRNS, KC_BSPC, \ + KC_TRNS, KC_VOLD, RGB_HUD,RGB_SAI,RGB_SAD, KC_TRNS, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_PENT, \ + KC_TRNS, RGB_VAI,RGB_VAD,KC_TRNS, KC_TRNS, KC_TRNS, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, KC_TRNS, KC_TRNS, \ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), #endif }; enum function_id { SHIFT_ESC, - #ifdef RGBLIGHT_ENABLE - RGBLED_TOGGLE, - RGBLED_STEP_MODE, - RGBLED_INCREASE_HUE, - RGBLED_DECREASE_HUE, - RGBLED_INCREASE_SAT, - RGBLED_DECREASE_SAT, - RGBLED_INCREASE_VAL, - RGBLED_DECREASE_VAL - #endif }; const uint16_t PROGMEM fn_actions[] = { [0] = ACTION_FUNCTION(SHIFT_ESC), - #ifdef RGBLIGHT_ENABLE - [1] = ACTION_FUNCTION(RGBLED_TOGGLE), - [2] = ACTION_FUNCTION(RGBLED_STEP_MODE), - [3] = ACTION_FUNCTION(RGBLED_INCREASE_HUE), - [4] = ACTION_FUNCTION(RGBLED_DECREASE_HUE), - [5] = ACTION_FUNCTION(RGBLED_INCREASE_SAT), - [6] = ACTION_FUNCTION(RGBLED_DECREASE_SAT), - [7] = ACTION_FUNCTION(RGBLED_INCREASE_VAL), - [8] = ACTION_FUNCTION(RGBLED_DECREASE_VAL), - #endif }; void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { @@ -102,48 +78,5 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { } } break; - //led operations - #ifdef RGBLIGHT_ENABLE - case RGBLED_TOGGLE: - if (record->event.pressed) { - rgblight_toggle(); - } - break; - case RGBLED_INCREASE_HUE: - if (record->event.pressed) { - rgblight_increase_hue(); - } - break; - case RGBLED_DECREASE_HUE: - if (record->event.pressed) { - rgblight_decrease_hue(); - } - break; - case RGBLED_INCREASE_SAT: - if (record->event.pressed) { - rgblight_increase_sat(); - } - break; - case RGBLED_DECREASE_SAT: - if (record->event.pressed) { - rgblight_decrease_sat(); - } - break; - case RGBLED_INCREASE_VAL: - if (record->event.pressed) { - rgblight_increase_val(); - } - break; - case RGBLED_DECREASE_VAL: - if (record->event.pressed) { - rgblight_decrease_val(); - } - break; - case RGBLED_STEP_MODE: - if (record->event.pressed) { - rgblight_step(); - } - break; - #endif } } diff --git a/quantum/keymap.h b/quantum/keymap.h index 73f99f821..a15865183 100644 --- a/quantum/keymap.h +++ b/quantum/keymap.h @@ -156,6 +156,16 @@ enum quantum_keycodes { BL_INC, BL_TOGG, BL_STEP, + + // RGB functionality + RGB_TOG, + RGB_MOD, + RGB_HUI, + RGB_HUD, + RGB_SAI, + RGB_SAD, + RGB_VAI, + RGB_VAD, // Left shift, open paren KC_LSPO, diff --git a/quantum/quantum.c b/quantum/quantum.c index d8e43a465..5c0b53e22 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -103,6 +103,56 @@ bool process_record_quantum(keyrecord_t *record) { return false; } break; + #ifdef RGBLIGHT_ENABLE + case RGB_TOG: + if (record->event.pressed) { + rgblight_toggle(); + return false; + } + break; + case RGB_MOD: + if (record->event.pressed) { + rgblight_step(); + return false; + } + break; + case RGB_HUI: + if (record->event.pressed) { + rgblight_increase_hue(); + return false; + } + break; + case RGB_HUD: + if (record->event.pressed) { + rgblight_decrease_hue(); + return false; + } + break; + case RGB_SAI: + if (record->event.pressed) { + rgblight_increase_sat(); + return false; + } + break; + case RGB_SAD: + if (record->event.pressed) { + rgblight_decrease_sat(); + return false; + } + break; + case RGB_VAI: + if (record->event.pressed) { + rgblight_increase_val(); + return false; + } + break; + case RGB_VAD: + if (record->event.pressed) { + rgblight_decrease_val(); + return false; + } + break; + #endif case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_UNSWAP_ALT_GUI: if (record->event.pressed) { // MAGIC actions (BOOTMAGIC without the boot) -- cgit v1.3.1 From f7a86822266603b8ffd21e9f89ec1de8d4950791 Mon Sep 17 00:00:00 2001 From: TerryMathews Date: Fri, 8 Jul 2016 03:32:28 -0400 Subject: Move return out of event if block According to Jack, this makes the return case not be processed. Doesn't break anything in the firmware. --- quantum/quantum.c | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index 5c0b53e22..09daa4712 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -93,65 +93,65 @@ bool process_record_quantum(keyrecord_t *record) { *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific #endif bootloader_jump(); - return false; } + return false; break; case DEBUG: if (record->event.pressed) { print("\nDEBUG: enabled.\n"); debug_enable = true; - return false; } + return false; break; #ifdef RGBLIGHT_ENABLE case RGB_TOG: if (record->event.pressed) { rgblight_toggle(); - return false; - } - break; + } + return false; + break; case RGB_MOD: if (record->event.pressed) { rgblight_step(); - return false; - } - break; + } + return false; + break; case RGB_HUI: if (record->event.pressed) { rgblight_increase_hue(); - return false; - } - break; + } + return false; + break; case RGB_HUD: if (record->event.pressed) { rgblight_decrease_hue(); - return false; - } - break; + } + return false; + break; case RGB_SAI: if (record->event.pressed) { rgblight_increase_sat(); - return false; - } - break; + } + return false; + break; case RGB_SAD: if (record->event.pressed) { rgblight_decrease_sat(); - return false; - } - break; + } + return false; + break; case RGB_VAI: if (record->event.pressed) { rgblight_increase_val(); - return false; - } - break; + } + return false; + break; case RGB_VAD: if (record->event.pressed) { rgblight_decrease_val(); - return false; - } - break; + } + return false; + break; #endif case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_UNSWAP_ALT_GUI: if (record->event.pressed) { -- cgit v1.3.1 From b12fe6abb25db1feca6a7649097a8d1cb67a063f Mon Sep 17 00:00:00 2001 From: Smilliam Date: Sun, 10 Jul 2016 19:04:01 -0700 Subject: Made rollover behavior for space cadet optional --- keyboards/kc60/Makefile | 4 ++-- keyboards/kc60/config.h | 6 ++++++ quantum/quantum.c | 20 ++++++++++++-------- readme.md | 6 ++++++ 4 files changed, 26 insertions(+), 10 deletions(-) (limited to 'quantum') diff --git a/keyboards/kc60/Makefile b/keyboards/kc60/Makefile index 9717b519c..855e81b1c 100644 --- a/keyboards/kc60/Makefile +++ b/keyboards/kc60/Makefile @@ -53,11 +53,11 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096 # Build Options # change yes to no to disable # -BOOTMAGIC_ENABLE ?= yes # Virtual DIP switch configuration(+1000) +BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000) MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700) EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450) CONSOLE_ENABLE ?= yes # Console for debug(+400) -COMMAND_ENABLE ?= yes # Commands for debug and configuration +COMMAND_ENABLE ?= no # Commands for debug and configuration KEYBOARD_LOCK_ENABLE ?= yes # Allow locking of keyboard via magic key # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend diff --git a/keyboards/kc60/config.h b/keyboards/kc60/config.h index c4a9b9ff8..a315f688f 100644 --- a/keyboards/kc60/config.h +++ b/keyboards/kc60/config.h @@ -107,6 +107,12 @@ along with this program. If not, see . keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ ) +/* Prevent stuck modifiers when switching between FN layers */ +#define PREVENT_STUCK_MODIFIERS + +/* Enable opposite shift key to cancel space cadet state */ +#define DISABLE_SPACE_CADET_ROLLOVER + /* control how magic key switches layers */ //#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true //#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true diff --git a/quantum/quantum.c b/quantum/quantum.c index 71c3c723b..d91b8f2d0 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -162,10 +162,12 @@ bool process_record_quantum(keyrecord_t *record) { register_mods(MOD_BIT(KC_LSFT)); } else { - if (get_mods() & MOD_BIT(KC_RSFT)) { - shift_interrupted[0] = true; - shift_interrupted[1] = true; - } + #ifdef DISABLE_SPACE_CADET_ROLLOVER + if (get_mods() & MOD_BIT(KC_RSFT)) { + shift_interrupted[0] = true; + shift_interrupted[1] = true; + } + #endif if (!shift_interrupted[0]) { register_code(LSPO_KEY); unregister_code(LSPO_KEY); @@ -182,10 +184,12 @@ bool process_record_quantum(keyrecord_t *record) { register_mods(MOD_BIT(KC_RSFT)); } else { - if (get_mods() & MOD_BIT(KC_LSFT)) { - shift_interrupted[0] = true; - shift_interrupted[1] = true; - } + #ifdef DISABLE_SPACE_CADET_ROLLOVER + if (get_mods() & MOD_BIT(KC_LSFT)) { + shift_interrupted[0] = true; + shift_interrupted[1] = true; + } + #endif if (!shift_interrupted[1]) { register_code(RSPC_KEY); unregister_code(RSPC_KEY); diff --git a/readme.md b/readme.md index c24d951d8..cc36a34ff 100644 --- a/readme.md +++ b/readme.md @@ -309,6 +309,12 @@ It's defaulted to work on US keyboards, but if your layout uses different keys f #define LSPO_KEY KC_9 #define RSPC_KEY KC_0 +You can also choose between different rollover behaviors of the shift keys by defining: + + #define DISABLE_SPACE_CADET_ROLLOVER + +in your `config.h`. Disabling rollover allows you to use the opposite shift key to cancel the space cadet state in the event of an erroneous press instead of emitting a pair of parentheses when the keys are released. + The only other thing you're going to want to do is create a `Makefile` in your keymap directory and set the following: ``` -- cgit v1.3.1 From a28a6e5b79c819e5f9323f62686498eca3ef399f Mon Sep 17 00:00:00 2001 From: Pavlos Vinieratos Date: Wed, 13 Jul 2016 16:38:02 +0200 Subject: extract reset keyboard into a function that makes it easy to call reset_keyboard() from a function in a keymap --- quantum/quantum.c | 24 ++++++++++++++---------- quantum/quantum.h | 2 ++ 2 files changed, 16 insertions(+), 10 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index d5b9753b7..bc2da510f 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -15,6 +15,19 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { return true; } +void reset_keyboard(void) { + clear_keyboard(); +#ifdef AUDIO_ENABLE + stop_all_notes(); + shutdown_user(); +#endif + wait_ms(250); +#ifdef CATERINA_BOOTLOADER + *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific +#endif + bootloader_jump(); +} + // Shift / paren setup #ifndef LSPO_KEY @@ -83,16 +96,7 @@ bool process_record_quantum(keyrecord_t *record) { switch(keycode) { case RESET: if (record->event.pressed) { - clear_keyboard(); - #ifdef AUDIO_ENABLE - stop_all_notes(); - shutdown_user(); - #endif - wait_ms(250); - #ifdef CATERINA_BOOTLOADER - *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific - #endif - bootloader_jump(); + reset_keyboard(); } return false; break; diff --git a/quantum/quantum.h b/quantum/quantum.h index 3a0b74202..7ebfb24e3 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -77,6 +77,8 @@ bool process_action_kb(keyrecord_t *record); bool process_record_kb(uint16_t keycode, keyrecord_t *record); bool process_record_user(uint16_t keycode, keyrecord_t *record); +void reset_keyboard(void); + void startup_user(void); void shutdown_user(void); -- cgit v1.3.1 From 010dd1308420e25b327fa4d5d6b13f67a849408b Mon Sep 17 00:00:00 2001 From: "Jonathan A. Kollasch" Date: Thu, 14 Jul 2016 11:04:25 -0500 Subject: keymap_extras: add newline at end of files --- quantum/keymap_extras/keymap_french.h | 2 +- quantum/keymap_extras/keymap_uk.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_french.h b/quantum/keymap_extras/keymap_french.h index 2a44c80b1..4fd1f61ae 100644 --- a/quantum/keymap_extras/keymap_french.h +++ b/quantum/keymap_extras/keymap_french.h @@ -80,4 +80,4 @@ #define FR_EURO ALGR(KC_E) #define FR_BULT ALGR(FR_DLR) -#endif \ No newline at end of file +#endif diff --git a/quantum/keymap_extras/keymap_uk.h b/quantum/keymap_extras/keymap_uk.h index 5c5d95179..1458d64a9 100644 --- a/quantum/keymap_extras/keymap_uk.h +++ b/quantum/keymap_extras/keymap_uk.h @@ -33,4 +33,4 @@ #define UK_AACT ALGR(KC_A) -#endif \ No newline at end of file +#endif -- cgit v1.3.1 From 25938a09a6bfb2624bc96841b53897eda532e293 Mon Sep 17 00:00:00 2001 From: "Jonathan A. Kollasch" Date: Thu, 14 Jul 2016 11:13:35 -0500 Subject: extra_keymaps: use RALT() instead of 0x1400 for AltGr --- quantum/keymap_extras/keymap_fr_ch.h | 2 +- quantum/keymap_extras/keymap_french.h | 2 +- quantum/keymap_extras/keymap_german.h | 2 +- quantum/keymap_extras/keymap_german_ch.h | 2 +- quantum/keymap_extras/keymap_nordic.h | 2 +- quantum/keymap_extras/keymap_spanish.h | 2 +- quantum/keymap_extras/keymap_uk.h | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_fr_ch.h b/quantum/keymap_extras/keymap_fr_ch.h index 3fd971357..87d4bb24c 100644 --- a/quantum/keymap_extras/keymap_fr_ch.h +++ b/quantum/keymap_extras/keymap_fr_ch.h @@ -4,7 +4,7 @@ #include "keymap.h" // Alt gr -#define ALGR(kc) kc | 0x1400 +#define ALGR(kc) RALT(kc) #define FR_CH_ALGR KC_RALT // normal characters diff --git a/quantum/keymap_extras/keymap_french.h b/quantum/keymap_extras/keymap_french.h index 4fd1f61ae..834c69650 100644 --- a/quantum/keymap_extras/keymap_french.h +++ b/quantum/keymap_extras/keymap_french.h @@ -4,7 +4,7 @@ #include "keymap.h" // Alt gr -#define ALGR(kc) kc | 0x1400 +#define ALGR(kc) RALT(kc) #define NO_ALGR KC_RALT // Normal characters diff --git a/quantum/keymap_extras/keymap_german.h b/quantum/keymap_extras/keymap_german.h index 3f9ae8bad..7e2e0ed44 100644 --- a/quantum/keymap_extras/keymap_german.h +++ b/quantum/keymap_extras/keymap_german.h @@ -4,7 +4,7 @@ #include "keymap.h" // Alt gr -#define ALGR(kc) kc | 0x1400 +#define ALGR(kc) RALT(kc) #define DE_ALGR KC_RALT // normal characters diff --git a/quantum/keymap_extras/keymap_german_ch.h b/quantum/keymap_extras/keymap_german_ch.h index 6a782bcd7..b66d582a4 100644 --- a/quantum/keymap_extras/keymap_german_ch.h +++ b/quantum/keymap_extras/keymap_german_ch.h @@ -4,7 +4,7 @@ #include "keymap.h" // Alt gr -#define ALGR(kc) kc | 0x1400 +#define ALGR(kc) RALT(kc) #define CH_ALGR KC_RALT // normal characters diff --git a/quantum/keymap_extras/keymap_nordic.h b/quantum/keymap_extras/keymap_nordic.h index 3acb8b698..f8cf4e2e4 100644 --- a/quantum/keymap_extras/keymap_nordic.h +++ b/quantum/keymap_extras/keymap_nordic.h @@ -4,7 +4,7 @@ #include "keymap.h" // Alt gr -#define ALGR(kc) kc | 0x1400 +#define ALGR(kc) RALT(kc) #define NO_ALGR KC_RALT // Normal characters diff --git a/quantum/keymap_extras/keymap_spanish.h b/quantum/keymap_extras/keymap_spanish.h index af76e39fc..4ba568af2 100644 --- a/quantum/keymap_extras/keymap_spanish.h +++ b/quantum/keymap_extras/keymap_spanish.h @@ -4,7 +4,7 @@ #include "keymap.h" // Alt gr -#define ALGR(kc) kc | 0x1400 +#define ALGR(kc) RALT(kc) #define NO_ALGR KC_RALT // Normal characters diff --git a/quantum/keymap_extras/keymap_uk.h b/quantum/keymap_extras/keymap_uk.h index 1458d64a9..00c87afc3 100644 --- a/quantum/keymap_extras/keymap_uk.h +++ b/quantum/keymap_extras/keymap_uk.h @@ -4,7 +4,7 @@ #include "keymap.h" // Alt gr -#define ALGR(kc) kc | 0x1400 +#define ALGR(kc) RALT(kc) #define NO_ALGR KC_RALT // Normal characters -- cgit v1.3.1 From 4278d8861526ed285d9d00badcdc8c121454be60 Mon Sep 17 00:00:00 2001 From: "Jonathan A. Kollasch" Date: Thu, 14 Jul 2016 11:32:43 -0500 Subject: keymap_dvorak.h: add missing shifted keys, fix whitespace --- quantum/keymap_extras/keymap_dvorak.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_dvorak.h b/quantum/keymap_extras/keymap_dvorak.h index e855056e8..17f205977 100644 --- a/quantum/keymap_extras/keymap_dvorak.h +++ b/quantum/keymap_extras/keymap_dvorak.h @@ -18,18 +18,19 @@ #define DV_LBRC KC_MINS #define DV_RBRC KC_EQL -#define DV_QUOT KC_Q +#define DV_QUOT KC_Q #define DV_COMM KC_W #define DV_DOT KC_E #define DV_P KC_R #define DV_Y KC_T #define DV_F KC_Y #define DV_G KC_U -#define DV_C KC_I +#define DV_C KC_I #define DV_R KC_O #define DV_L KC_P #define DV_SLSH KC_LBRC #define DV_EQL KC_RBRC +#define DV_BSLS KC_BSLS #define DV_A KC_A #define DV_O KC_S @@ -68,7 +69,13 @@ #define DV_RPRN LSFT(DV_0) #define DV_LCBR LSFT(DV_LBRC) #define DV_RCBR LSFT(DV_RBRC) -#define DV_UNDS LSFT(DV_MINS) -#define DV_PLUS LSFT(DV_EQL) + +#define DV_QUES LSFT(DV_SLSH) +#define DV_PLUS LSFT(DV_EQL) +#define DV_PIPE LSFT(DV_BSLS) + +#define DV_UNDS LSFT(DV_MINS) + +#define DV_COLN LSFT(DV_SCLN) #endif -- cgit v1.3.1 From 1a7e954f9fc4d250ba1ae46e3bfc168aca2b5cce Mon Sep 17 00:00:00 2001 From: Pavlos Vinieratos Date: Wed, 13 Jul 2016 00:20:28 +0200 Subject: in case its NULL --- quantum/process_keycode/process_tap_dance.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 9b172e1b6..186889bc2 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -22,7 +22,9 @@ static void _process_tap_dance_action_pair (qk_tap_dance_state_t *state, static void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, qk_tap_dance_user_fn_t fn) { - fn(state); + if (fn) { + fn(state); + } } void process_tap_dance_action (uint16_t keycode) -- cgit v1.3.1 From f3b56701ed7e6c622dc48e429780124ba5fde172 Mon Sep 17 00:00:00 2001 From: Pavlos Vinieratos Date: Wed, 13 Jul 2016 16:47:45 +0200 Subject: add an `anyway` and a `reset` callback when using tap dance, we have the `regular` callback that is called on the last tap. this commit adds an `anyway` callback that is called on every tap, and a `reset` callback that is called on reset of the tap dance taps. --- quantum/process_keycode/process_tap_dance.c | 36 ++++++++++++++++++++++++++++- quantum/process_keycode/process_tap_dance.h | 28 ++++++++++++++++++---- 2 files changed, 59 insertions(+), 5 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 186889bc2..40fba2a6a 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -40,7 +40,24 @@ void process_tap_dance_action (uint16_t keycode) action.pair.kc1, action.pair.kc2); break; case QK_TAP_DANCE_TYPE_FN: - _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn); + _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.regular); + break; + + default: + break; + } +} + +void process_tap_dance_action_anyway (uint16_t keycode) +{ + uint16_t idx = keycode - QK_TAP_DANCE; + qk_tap_dance_action_t action; + + action = tap_dance_actions[idx]; + + switch (action.type) { + case QK_TAP_DANCE_TYPE_FN: + _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.anyway); break; default: @@ -53,6 +70,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { switch(keycode) { case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: + process_tap_dance_action_anyway (qk_tap_dance_state.keycode); if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) { process_tap_dance_action (qk_tap_dance_state.keycode); } else { @@ -68,6 +86,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { default: if (qk_tap_dance_state.keycode) { + //process_tap_dance_action_anyway (qk_tap_dance_state.keycode); process_tap_dance_action (qk_tap_dance_state.keycode); reset_tap_dance (&qk_tap_dance_state); @@ -87,6 +106,21 @@ void matrix_scan_tap_dance () { } void reset_tap_dance (qk_tap_dance_state_t *state) { + uint16_t idx = state->keycode - QK_TAP_DANCE; + qk_tap_dance_action_t action; + + action = tap_dance_actions[idx]; + switch (action.type) { + case QK_TAP_DANCE_TYPE_FN: + if (action.fn.reset) { + action.fn.reset(); + } + break; + + default: + break; + } + state->keycode = 0; state->count = 0; } diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index b9d7c7fcf..bf925df0f 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h @@ -22,6 +22,7 @@ typedef enum } qk_tap_dance_type_t; typedef void (*qk_tap_dance_user_fn_t) (qk_tap_dance_state_t *state); +typedef void (*qk_tap_dance_user_fn_reset_t) (void); typedef struct { @@ -31,18 +32,37 @@ typedef struct uint16_t kc1; uint16_t kc2; } pair; - qk_tap_dance_user_fn_t fn; + struct { + qk_tap_dance_user_fn_t regular; + qk_tap_dance_user_fn_t anyway; + qk_tap_dance_user_fn_reset_t reset; + } fn; }; } qk_tap_dance_action_t; #define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \ - .type = QK_TAP_DANCE_TYPE_PAIR, \ - .pair = { kc1, kc2 } \ + .type = QK_TAP_DANCE_TYPE_PAIR, \ + .pair = { kc1, kc2 } \ } #define ACTION_TAP_DANCE_FN(user_fn) { \ .type = QK_TAP_DANCE_TYPE_FN, \ - .fn = user_fn \ + .fn = { user_fn, NULL, NULL } \ + } + +#define ACTION_TAP_DANCE_FN_ANYWAY(user_fn, user_fn_anyway) { \ + .type = QK_TAP_DANCE_TYPE_FN, \ + .fn = { user_fn, user_fn_anyway, NULL } \ + } + +#define ACTION_TAP_DANCE_FN_RESET(user_fn, user_fn_reset) { \ + .type = QK_TAP_DANCE_TYPE_FN, \ + .fn = { user_fn, NULL, user_fn_reset } \ + } + +#define ACTION_TAP_DANCE_FN_ANYWAY_RESET(user_fn, user_fn_anyway, user_fn_reset) { \ + .type = QK_TAP_DANCE_TYPE_FN, \ + .fn = { user_fn, user_fn_anyway, user_fn_reset } \ } extern const qk_tap_dance_action_t tap_dance_actions[]; -- cgit v1.3.1 From d3091faf363afc8fef73ddf4948f872439b0e827 Mon Sep 17 00:00:00 2001 From: Pavlos Vinieratos Date: Fri, 15 Jul 2016 23:54:08 +0200 Subject: change naming, and remove extraneous definition --- quantum/process_keycode/process_tap_dance.c | 32 ++++++++++++++--------------- quantum/process_keycode/process_tap_dance.h | 27 ++++++++---------------- 2 files changed, 23 insertions(+), 36 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 40fba2a6a..93b326b5f 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -27,7 +27,7 @@ static void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, } } -void process_tap_dance_action (uint16_t keycode) +void process_tap_dance_action_on_each_tap (uint16_t keycode) { uint16_t idx = keycode - QK_TAP_DANCE; qk_tap_dance_action_t action; @@ -35,12 +35,8 @@ void process_tap_dance_action (uint16_t keycode) action = tap_dance_actions[idx]; switch (action.type) { - case QK_TAP_DANCE_TYPE_PAIR: - _process_tap_dance_action_pair (&qk_tap_dance_state, - action.pair.kc1, action.pair.kc2); - break; case QK_TAP_DANCE_TYPE_FN: - _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.regular); + _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.on_each_tap); break; default: @@ -48,7 +44,7 @@ void process_tap_dance_action (uint16_t keycode) } } -void process_tap_dance_action_anyway (uint16_t keycode) +void process_tap_dance_action_on_dance_finished (uint16_t keycode) { uint16_t idx = keycode - QK_TAP_DANCE; qk_tap_dance_action_t action; @@ -56,8 +52,12 @@ void process_tap_dance_action_anyway (uint16_t keycode) action = tap_dance_actions[idx]; switch (action.type) { + case QK_TAP_DANCE_TYPE_PAIR: + _process_tap_dance_action_pair (&qk_tap_dance_state, + action.pair.kc1, action.pair.kc2); + break; case QK_TAP_DANCE_TYPE_FN: - _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.anyway); + _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.on_dance_finished); break; default: @@ -70,9 +70,9 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { switch(keycode) { case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: - process_tap_dance_action_anyway (qk_tap_dance_state.keycode); + process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) { - process_tap_dance_action (qk_tap_dance_state.keycode); + process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); } else { r = false; } @@ -85,10 +85,9 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { break; default: + process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); if (qk_tap_dance_state.keycode) { - //process_tap_dance_action_anyway (qk_tap_dance_state.keycode); - process_tap_dance_action (qk_tap_dance_state.keycode); - + process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); reset_tap_dance (&qk_tap_dance_state); } break; @@ -99,8 +98,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { void matrix_scan_tap_dance () { if (qk_tap_dance_state.keycode && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) { - process_tap_dance_action (qk_tap_dance_state.keycode); - + process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); reset_tap_dance (&qk_tap_dance_state); } } @@ -112,8 +110,8 @@ void reset_tap_dance (qk_tap_dance_state_t *state) { action = tap_dance_actions[idx]; switch (action.type) { case QK_TAP_DANCE_TYPE_FN: - if (action.fn.reset) { - action.fn.reset(); + if (action.fn.on_reset) { + action.fn.on_reset(state); } break; diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index bf925df0f..7b820584a 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h @@ -22,7 +22,6 @@ typedef enum } qk_tap_dance_type_t; typedef void (*qk_tap_dance_user_fn_t) (qk_tap_dance_state_t *state); -typedef void (*qk_tap_dance_user_fn_reset_t) (void); typedef struct { @@ -33,9 +32,9 @@ typedef struct uint16_t kc2; } pair; struct { - qk_tap_dance_user_fn_t regular; - qk_tap_dance_user_fn_t anyway; - qk_tap_dance_user_fn_reset_t reset; + qk_tap_dance_user_fn_t on_each_tap; + qk_tap_dance_user_fn_t on_dance_finished; + qk_tap_dance_user_fn_t on_reset; } fn; }; } qk_tap_dance_action_t; @@ -45,24 +44,14 @@ typedef struct .pair = { kc1, kc2 } \ } -#define ACTION_TAP_DANCE_FN(user_fn) { \ +#define ACTION_TAP_DANCE_FN(user_fn) { \ .type = QK_TAP_DANCE_TYPE_FN, \ - .fn = { user_fn, NULL, NULL } \ + .fn = { NULL, user_fn, NULL } \ } -#define ACTION_TAP_DANCE_FN_ANYWAY(user_fn, user_fn_anyway) { \ - .type = QK_TAP_DANCE_TYPE_FN, \ - .fn = { user_fn, user_fn_anyway, NULL } \ - } - -#define ACTION_TAP_DANCE_FN_RESET(user_fn, user_fn_reset) { \ - .type = QK_TAP_DANCE_TYPE_FN, \ - .fn = { user_fn, NULL, user_fn_reset } \ - } - -#define ACTION_TAP_DANCE_FN_ANYWAY_RESET(user_fn, user_fn_anyway, user_fn_reset) { \ - .type = QK_TAP_DANCE_TYPE_FN, \ - .fn = { user_fn, user_fn_anyway, user_fn_reset } \ +#define ACTION_TAP_DANCE_FN_ADVANCED(user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset) { \ + .type = QK_TAP_DANCE_TYPE_FN, \ + .fn = { user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset } \ } extern const qk_tap_dance_action_t tap_dance_actions[]; -- cgit v1.3.1 From dda2fd6ff3984ed96f8275c661b47a0484f9ee18 Mon Sep 17 00:00:00 2001 From: Pavlos Vinieratos Date: Mon, 18 Jul 2016 23:34:02 +0200 Subject: in the default case, it should be called if there is actually a tap dance happening, and in the normal case, it should be called when the tap down is happening. --- quantum/process_keycode/process_tap_dance.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 93b326b5f..bab6bb81b 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -70,7 +70,6 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { switch(keycode) { case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: - process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) { process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); } else { @@ -81,12 +80,13 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { qk_tap_dance_state.keycode = keycode; qk_tap_dance_state.timer = timer_read (); qk_tap_dance_state.count++; + process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); } break; default: - process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); if (qk_tap_dance_state.keycode) { + process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); reset_tap_dance (&qk_tap_dance_state); } -- cgit v1.3.1 From d5daec2a58019ebdb9804787e0f786e4fc3c05b9 Mon Sep 17 00:00:00 2001 From: Pavlos Vinieratos Date: Tue, 19 Jul 2016 18:00:59 +0200 Subject: on_each_tap_fn is called on tap down and tap up --- quantum/process_keycode/process_tap_dance.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index bab6bb81b..58192413f 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -70,6 +70,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { switch(keycode) { case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: + process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) { process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); } else { @@ -80,7 +81,6 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { qk_tap_dance_state.keycode = keycode; qk_tap_dance_state.timer = timer_read (); qk_tap_dance_state.count++; - process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); } break; -- cgit v1.3.1 From 4e6a8627d8ebd7af942f68142d1a959d60361d90 Mon Sep 17 00:00:00 2001 From: Pavlos Vinieratos Date: Tue, 19 Jul 2016 18:02:13 +0200 Subject: add a couple of comments --- quantum/process_keycode/process_tap_dance.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 58192413f..b9b836df2 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -86,6 +86,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { default: if (qk_tap_dance_state.keycode) { + // if we are here, the tap dance was interrupted by a different key process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); reset_tap_dance (&qk_tap_dance_state); @@ -98,6 +99,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { void matrix_scan_tap_dance () { if (qk_tap_dance_state.keycode && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) { + // if we are here, the tap dance was timed out process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); reset_tap_dance (&qk_tap_dance_state); } -- cgit v1.3.1 From 70e42489dec375e558d8e81ed5ebfb69b4f3dbd9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 20 Jul 2016 10:22:52 +0200 Subject: tap-dance: Support for holding keys With this change, tap dance will now store the pressed state of the tap-dance key, and allow one to make an action sooner, while the key is still held, and only unregister when the key is released. The registration must happen in the `on_dance_finished` callback, while unregistering goes to `on_reset`. The surrounding code makes sure not to call either multiple times. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_tap_dance.c | 11 ++++++++++- quantum/process_keycode/process_tap_dance.h | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index b9b836df2..097440405 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -73,10 +73,14 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) { process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); + } else if (qk_tap_dance_state.active && qk_tap_dance_state.pressed) { + reset_tap_dance (&qk_tap_dance_state); } else { r = false; } + qk_tap_dance_state.active = true; + qk_tap_dance_state.pressed = record->event.pressed; if (record->event.pressed) { qk_tap_dance_state.keycode = keycode; qk_tap_dance_state.timer = timer_read (); @@ -90,6 +94,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); reset_tap_dance (&qk_tap_dance_state); + qk_tap_dance_state.active = false; } break; } @@ -98,7 +103,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { } void matrix_scan_tap_dance () { - if (qk_tap_dance_state.keycode && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) { + if (qk_tap_dance_state.active && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) { // if we are here, the tap dance was timed out process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); reset_tap_dance (&qk_tap_dance_state); @@ -109,6 +114,9 @@ void reset_tap_dance (qk_tap_dance_state_t *state) { uint16_t idx = state->keycode - QK_TAP_DANCE; qk_tap_dance_action_t action; + if (state->pressed) + return; + action = tap_dance_actions[idx]; switch (action.type) { case QK_TAP_DANCE_TYPE_FN: @@ -123,4 +131,5 @@ void reset_tap_dance (qk_tap_dance_state_t *state) { state->keycode = 0; state->count = 0; + state->active = false; } diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index 7b820584a..d457db9b3 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h @@ -11,6 +11,8 @@ typedef struct uint8_t count; uint16_t keycode; uint16_t timer; + bool active:1; + bool pressed:1; } qk_tap_dance_state_t; #define TD(n) (QK_TAP_DANCE + n) -- cgit v1.3.1 From ce8cc9219fca5dde077f1142d03d011b38d27479 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 20 Jul 2016 11:34:45 +0200 Subject: tap-dance: Support user_data for the callbacks Refactored the code a little, so all callbacks now receive a `user_data` pointer, which can be anything. As an example, the key pairs from `ACTION_TAP_DANCE_DOUBLE` now use this, and custom, built-in functions. This makes it easier to extend the tap dance functionality, and also simplifies the code a little. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_tap_dance.c | 61 ++++++++++------------------- quantum/process_keycode/process_tap_dance.h | 41 +++++++++---------- 2 files changed, 38 insertions(+), 64 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 097440405..94b6af130 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -2,28 +2,32 @@ static qk_tap_dance_state_t qk_tap_dance_state; -static void _process_tap_dance_action_pair (qk_tap_dance_state_t *state, - uint16_t kc1, uint16_t kc2) { - uint16_t kc; +void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data) { + qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; - if (state->count == 0) - return; - - kc = (state->count == 1) ? kc1 : kc2; + if (state->count == 1) { + register_code (pair->kc1); + } else if (state->count == 2) { + register_code (pair->kc2); + } +} - register_code (kc); - unregister_code (kc); +void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data) { + qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; - if (state->count >= 2) { - reset_tap_dance (state); + if (state->count == 1) { + unregister_code (pair->kc1); + } else if (state->count == 2) { + unregister_code (pair->kc2); } } static void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, + void *user_data, qk_tap_dance_user_fn_t fn) { if (fn) { - fn(state); + fn(state, user_data); } } @@ -34,14 +38,7 @@ void process_tap_dance_action_on_each_tap (uint16_t keycode) action = tap_dance_actions[idx]; - switch (action.type) { - case QK_TAP_DANCE_TYPE_FN: - _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.on_each_tap); - break; - - default: - break; - } + _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_each_tap); } void process_tap_dance_action_on_dance_finished (uint16_t keycode) @@ -51,18 +48,7 @@ void process_tap_dance_action_on_dance_finished (uint16_t keycode) action = tap_dance_actions[idx]; - switch (action.type) { - case QK_TAP_DANCE_TYPE_PAIR: - _process_tap_dance_action_pair (&qk_tap_dance_state, - action.pair.kc1, action.pair.kc2); - break; - case QK_TAP_DANCE_TYPE_FN: - _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.on_dance_finished); - break; - - default: - break; - } + _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_dance_finished); } bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { @@ -118,15 +104,8 @@ void reset_tap_dance (qk_tap_dance_state_t *state) { return; action = tap_dance_actions[idx]; - switch (action.type) { - case QK_TAP_DANCE_TYPE_FN: - if (action.fn.on_reset) { - action.fn.on_reset(state); - } - break; - - default: - break; + if (action.fn.on_reset) { + action.fn.on_reset(state, action.user_data); } state->keycode = 0; diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index d457db9b3..e2c74efe9 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h @@ -17,42 +17,34 @@ typedef struct #define TD(n) (QK_TAP_DANCE + n) -typedef enum -{ - QK_TAP_DANCE_TYPE_PAIR, - QK_TAP_DANCE_TYPE_FN, -} qk_tap_dance_type_t; - -typedef void (*qk_tap_dance_user_fn_t) (qk_tap_dance_state_t *state); +typedef void (*qk_tap_dance_user_fn_t) (qk_tap_dance_state_t *state, void *user_data); typedef struct { - qk_tap_dance_type_t type; - union { - struct { - uint16_t kc1; - uint16_t kc2; - } pair; - struct { - qk_tap_dance_user_fn_t on_each_tap; - qk_tap_dance_user_fn_t on_dance_finished; - qk_tap_dance_user_fn_t on_reset; - } fn; - }; + struct { + qk_tap_dance_user_fn_t on_each_tap; + qk_tap_dance_user_fn_t on_dance_finished; + qk_tap_dance_user_fn_t on_reset; + } fn; + void *user_data; } qk_tap_dance_action_t; +typedef struct +{ + uint16_t kc1; + uint16_t kc2; +} qk_tap_dance_pair_t; + #define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \ - .type = QK_TAP_DANCE_TYPE_PAIR, \ - .pair = { kc1, kc2 } \ + .fn = { NULL, qk_tap_dance_pair_finished, qk_tap_dance_pair_reset }, \ + .user_data = (void *)&((qk_tap_dance_pair_t) { kc1, kc2 }) \ } #define ACTION_TAP_DANCE_FN(user_fn) { \ - .type = QK_TAP_DANCE_TYPE_FN, \ .fn = { NULL, user_fn, NULL } \ } #define ACTION_TAP_DANCE_FN_ADVANCED(user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset) { \ - .type = QK_TAP_DANCE_TYPE_FN, \ .fn = { user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset } \ } @@ -64,6 +56,9 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record); void matrix_scan_tap_dance (void); void reset_tap_dance (qk_tap_dance_state_t *state); +void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data); +void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data); + #else #define TD(n) KC_NO -- cgit v1.3.1 From 44e16ffc80620b61eaa17aedcfdd8233d9c99bd9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 20 Jul 2016 11:49:59 +0200 Subject: tap-dance: Code cleanup Removes a number of duplicated code, by passing actions around instead of keycodes, so the various dance action functions do not have to look up the action, but the caller does that for them. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_tap_dance.c | 45 +++++++++++++++-------------- 1 file changed, 24 insertions(+), 21 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 94b6af130..d240dc2e6 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -22,7 +22,7 @@ void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data) { } } -static void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, +static inline void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, void *user_data, qk_tap_dance_user_fn_t fn) { @@ -31,34 +31,33 @@ static void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, } } -void process_tap_dance_action_on_each_tap (uint16_t keycode) +static inline void process_tap_dance_action_on_each_tap (qk_tap_dance_action_t action) { - uint16_t idx = keycode - QK_TAP_DANCE; - qk_tap_dance_action_t action; - - action = tap_dance_actions[idx]; - _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_each_tap); } -void process_tap_dance_action_on_dance_finished (uint16_t keycode) +static inline void process_tap_dance_action_on_dance_finished (qk_tap_dance_action_t action) { - uint16_t idx = keycode - QK_TAP_DANCE; - qk_tap_dance_action_t action; - - action = tap_dance_actions[idx]; - _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_dance_finished); } +static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t action) +{ + _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_reset); +} + bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { bool r = true; + uint16_t idx = keycode - QK_TAP_DANCE; + qk_tap_dance_action_t action; switch(keycode) { case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: - process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); + action = tap_dance_actions[idx]; + + process_tap_dance_action_on_each_tap (action); if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) { - process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); + process_tap_dance_action_on_dance_finished (action); } else if (qk_tap_dance_state.active && qk_tap_dance_state.pressed) { reset_tap_dance (&qk_tap_dance_state); } else { @@ -77,8 +76,11 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { default: if (qk_tap_dance_state.keycode) { // if we are here, the tap dance was interrupted by a different key - process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); - process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); + idx = qk_tap_dance_state.keycode - QK_TAP_DANCE; + action = tap_dance_actions[idx]; + + process_tap_dance_action_on_each_tap (action); + process_tap_dance_action_on_dance_finished (action); reset_tap_dance (&qk_tap_dance_state); qk_tap_dance_state.active = false; } @@ -91,7 +93,10 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { void matrix_scan_tap_dance () { if (qk_tap_dance_state.active && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) { // if we are here, the tap dance was timed out - process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); + uint16_t idx = qk_tap_dance_state.keycode - QK_TAP_DANCE; + qk_tap_dance_action_t action = tap_dance_actions[idx]; + + process_tap_dance_action_on_dance_finished (action); reset_tap_dance (&qk_tap_dance_state); } } @@ -104,9 +109,7 @@ void reset_tap_dance (qk_tap_dance_state_t *state) { return; action = tap_dance_actions[idx]; - if (action.fn.on_reset) { - action.fn.on_reset(state, action.user_data); - } + process_tap_dance_action_on_reset (action); state->keycode = 0; state->count = 0; -- cgit v1.3.1 From 7b4d30ee50aa534a973473c715924964991739f0 Mon Sep 17 00:00:00 2001 From: Vivien Alger Date: Sun, 24 Jul 2016 10:57:49 +0200 Subject: Fix some errors in bepo mapping --- quantum/keymap_extras/keymap_bepo.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_bepo.h b/quantum/keymap_extras/keymap_bepo.h index 4c3096054..e5ef39552 100644 --- a/quantum/keymap_extras/keymap_bepo.h +++ b/quantum/keymap_extras/keymap_bepo.h @@ -118,7 +118,7 @@ // Fourth row #define BP_COLON LSFT(BP_DOT) // : #define BP_COLN BP_COLON -#define BP_QUESTION LSFT(BP_QUOTE) // ? +#define BP_QUESTION LSFT(BP_APOS) // ? #define BP_QEST BP_QUESTION // Space bar @@ -183,7 +183,7 @@ // Third row #define BP_AE_LIGATURE ALTGR(BP_A) // æ #define BP_AE BP_AE_LIGATURE -#define BP_U_GRAVE AGR(BP_U) // ù +#define BP_U_GRAVE ALTGR(BP_U) // ù #define BP_UGRV BP_U_GRAVE #define BP_DEAD_TREMA ALTGR(BP_I) // dead ¨ (trema/umlaut/diaresis) #define BP_DTRM BP_DEAD_TREMA -- cgit v1.3.1 From 3ea738e450e9326b0d3ee4192da881cffb4c13c1 Mon Sep 17 00:00:00 2001 From: Robert Dale Date: Sun, 24 Jul 2016 10:00:39 -0400 Subject: ensure there's a recording to play before playing; also enables the LGUI button to play a tone --- quantum/process_keycode/process_music.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_music.c b/quantum/process_keycode/process_music.c index c8f3ddb90..2d52e47a7 100644 --- a/quantum/process_keycode/process_music.c +++ b/quantum/process_keycode/process_music.c @@ -6,6 +6,7 @@ int offset = 7; // music sequencer static bool music_sequence_recording = false; +static bool music_sequence_recorded = false; static bool music_sequence_playing = false; static float music_sequence[16] = {0}; static uint8_t music_sequence_count = 0; @@ -77,6 +78,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) { if (keycode == KC_LCTL && record->event.pressed) { // Start recording stop_all_notes(); music_sequence_recording = true; + music_sequence_recorded = false; music_sequence_playing = false; music_sequence_count = 0; return false; @@ -84,12 +86,15 @@ bool process_music(uint16_t keycode, keyrecord_t *record) { if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing stop_all_notes(); + if (music_sequence_recording) { // was recording + music_sequence_recorded = true; + } music_sequence_recording = false; music_sequence_playing = false; return false; } - if (keycode == KC_LGUI && record->event.pressed) { // Start playing + if (keycode == KC_LGUI && record->event.pressed && music_sequence_recorded) { // Start playing stop_all_notes(); music_sequence_recording = false; music_sequence_playing = true; -- cgit v1.3.1 From 8b94e26d7c3b30cc57d710a11e5651d15e8e3b20 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sun, 24 Jul 2016 22:07:43 -0400 Subject: Fixes midi functionality --- Makefile | 2 +- keyboards/lets_split/config.h | 4 ++-- keyboards/planck/keymaps/default/Makefile | 2 +- quantum/keymap_common.c | 2 +- quantum/process_keycode/process_midi.c | 24 ++++++++++++------------ 5 files changed, 17 insertions(+), 17 deletions(-) (limited to 'quantum') diff --git a/Makefile b/Makefile index a7a10bf32..980ab26b2 100644 --- a/Makefile +++ b/Makefile @@ -181,7 +181,7 @@ endif ifeq ($(strip $(MIDI_ENABLE)), yes) OPT_DEFS += -DMIDI_ENABLE - SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c + SRC += $(QUANTUM_DIR)/process_keycode/process_midi.c endif ifeq ($(strip $(AUDIO_ENABLE)), yes) diff --git a/keyboards/lets_split/config.h b/keyboards/lets_split/config.h index 833818ce6..ec99514aa 100644 --- a/keyboards/lets_split/config.h +++ b/keyboards/lets_split/config.h @@ -69,9 +69,9 @@ along with this program. If not, see . ) /* ws2812 RGB LED */ -#define RGB_DI_PIN D2 +#define RGB_DI_PIN D4 #define RGBLIGHT_TIMER -#define RGBLED_NUM 28 // Number of LEDs +#define RGBLED_NUM 8 // Number of LEDs #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 #define RGBLIGHT_VAL_STEP 17 diff --git a/keyboards/planck/keymaps/default/Makefile b/keyboards/planck/keymaps/default/Makefile index 581e08cd0..38a504a27 100644 --- a/keyboards/planck/keymaps/default/Makefile +++ b/keyboards/planck/keymaps/default/Makefile @@ -11,7 +11,7 @@ CONSOLE_ENABLE = no # Console for debug(+400) COMMAND_ENABLE = yes # Commands for debug and configuration NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality -MIDI_ENABLE = no # MIDI controls +MIDI_ENABLE = yes # MIDI controls AUDIO_ENABLE = yes # Audio output on port C6 UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index d0a8312c1..833e5a8f8 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -30,7 +30,7 @@ along with this program. If not, see . #include "quantum.h" #ifdef MIDI_ENABLE - #include "keymap_midi.h" + #include "process_midi.h" #endif extern keymap_config_t keymap_config; diff --git a/quantum/process_keycode/process_midi.c b/quantum/process_keycode/process_midi.c index d6ab9c626..8784e64f3 100644 --- a/quantum/process_keycode/process_midi.c +++ b/quantum/process_keycode/process_midi.c @@ -1,8 +1,8 @@ #include "process_midi.h" bool midi_activated = false; -uint8_t starting_note = 0x0C; -int offset = 7; +uint8_t midi_starting_note = 0x0C; +int midi_offset = 7; bool process_midi(uint16_t keycode, keyrecord_t *record) { if (keycode == MI_ON && record->event.pressed) { @@ -20,42 +20,42 @@ bool process_midi(uint16_t keycode, keyrecord_t *record) { if (midi_activated) { if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) { if (record->event.pressed) { - starting_note++; // Change key + midi_starting_note++; // Change key midi_send_cc(&midi_device, 0, 0x7B, 0); } return false; } if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) { if (record->event.pressed) { - starting_note--; // Change key + midi_starting_note--; // Change key midi_send_cc(&midi_device, 0, 0x7B, 0); } return false; } if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { - offset++; // Change scale + midi_offset++; // Change scale midi_send_cc(&midi_device, 0, 0x7B, 0); return false; } if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { - offset--; // Change scale + midi_offset--; // Change scale midi_send_cc(&midi_device, 0, 0x7B, 0); return false; } // basic - // uint8_t note = (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row); + // uint8_t note = (midi_starting_note + SCALE[record->event.key.col + midi_offset])+12*(MATRIX_ROWS - record->event.key.row); // advanced - // uint8_t note = (starting_note + record->event.key.col + offset)+12*(MATRIX_ROWS - record->event.key.row); + // uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+12*(MATRIX_ROWS - record->event.key.row); // guitar - uint8_t note = (starting_note + record->event.key.col + offset)+5*(MATRIX_ROWS - record->event.key.row); + uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+5*(MATRIX_ROWS - record->event.key.row); // violin - // uint8_t note = (starting_note + record->event.key.col + offset)+7*(MATRIX_ROWS - record->event.key.row); + // uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+7*(MATRIX_ROWS - record->event.key.row); if (record->event.pressed) { - // midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127); + // midi_send_noteon(&midi_device, record->event.key.row, midi_starting_note + SCALE[record->event.key.col], 127); midi_send_noteon(&midi_device, 0, note, 127); } else { - // midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127); + // midi_send_noteoff(&midi_device, record->event.key.row, midi_starting_note + SCALE[record->event.key.col], 127); midi_send_noteoff(&midi_device, 0, note, 127); } -- cgit v1.3.1 From b6fa762234fb5a3590d0ff91ffdf5aa3ae322c8f Mon Sep 17 00:00:00 2001 From: Andreas Lindhé Date: Mon, 25 Jul 2016 11:29:54 +0200 Subject: Fix misspelled command in Norwegian helper --- quantum/keymap_extras/keymap_norwegian.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_norwegian.h b/quantum/keymap_extras/keymap_norwegian.h index 018bfeae5..5c4e8c495 100644 --- a/quantum/keymap_extras/keymap_norwegian.h +++ b/quantum/keymap_extras/keymap_norwegian.h @@ -13,7 +13,7 @@ #undef NO_BSLS #define NO_BSLS KC_EQL // '\' #undef NO_CIRC -#define NO_CIRC LSFT(C_RBRC) // ^ +#define NO_CIRC LSFT(KC_RBRC) // ^ #undef NO_GRV #define NO_GRV LSFT(NO_BSLS) // #undef NO_OSLH -- cgit v1.3.1 From 283ebbe14298fe75128765fa42c46f02534fb761 Mon Sep 17 00:00:00 2001 From: Andreas Lindhé Date: Mon, 25 Jul 2016 12:50:27 +0200 Subject: Change Nordic ampersand code to match the English Changed from "NO_AMP" to "NO_AMPR" since the KC one is "KC_AMPR" --- quantum/keymap_extras/keymap_nordic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_nordic.h b/quantum/keymap_extras/keymap_nordic.h index f8cf4e2e4..da5c82975 100644 --- a/quantum/keymap_extras/keymap_nordic.h +++ b/quantum/keymap_extras/keymap_nordic.h @@ -25,7 +25,7 @@ #define NO_SECT LSFT(NO_HALF) #define NO_QUO2 LSFT(KC_2) #define NO_BULT LSFT(KC_4) -#define NO_AMP LSFT(KC_6) +#define NO_AMPR LSFT(KC_6) #define NO_SLSH LSFT(KC_7) #define NO_LPRN LSFT(KC_8) #define NO_RPRN LSFT(KC_9) -- cgit v1.3.1 From 3a860c4bc210857f03ef9fae5043d6d5736d140d Mon Sep 17 00:00:00 2001 From: Jordi Orlando <0xdec@users.noreply.github.com> Date: Tue, 26 Jul 2016 14:43:45 -0500 Subject: Clean up rgblight.c Fix formatting issues, clarify comments --- quantum/rgblight.c | 731 +++++++++++++++++++++++++++-------------------------- 1 file changed, 377 insertions(+), 354 deletions(-) (limited to 'quantum') diff --git a/quantum/rgblight.c b/quantum/rgblight.c index b1b0f035d..1b3c576d1 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -7,24 +7,41 @@ #include "debug.h" const uint8_t DIM_CURVE[] PROGMEM = { - 0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, - 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, - 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, - 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, - 20, 20, 21, 21, 22, 22, 22, 23, 23, 24, 24, 25, 25, 25, 26, 26, - 27, 27, 28, 28, 29, 29, 30, 30, 31, 32, 32, 33, 33, 34, 35, 35, - 36, 36, 37, 38, 38, 39, 40, 40, 41, 42, 43, 43, 44, 45, 46, 47, - 48, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 68, 69, 70, 71, 73, 74, 75, 76, 78, 79, 81, 82, - 83, 85, 86, 88, 90, 91, 93, 94, 96, 98, 99, 101, 103, 105, 107, 109, - 110, 112, 114, 116, 118, 121, 123, 125, 127, 129, 132, 134, 136, 139, 141, 144, - 146, 149, 151, 154, 157, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, 190, - 193, 196, 200, 203, 207, 211, 214, 218, 222, 226, 230, 234, 238, 242, 248, 255, + 0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, + 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, + 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, + 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, + 20, 20, 21, 21, 22, 22, 22, 23, 23, 24, 24, 25, 25, 25, 26, 26, + 27, 27, 28, 28, 29, 29, 30, 30, 31, 32, 32, 33, 33, 34, 35, 35, + 36, 36, 37, 38, 38, 39, 40, 40, 41, 42, 43, 43, 44, 45, 46, 47, + 48, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 68, 69, 70, 71, 73, 74, 75, 76, 78, 79, 81, 82, + 83, 85, 86, 88, 90, 91, 93, 94, 96, 98, 99, 101, 103, 105, 107, 109, + 110, 112, 114, 116, 118, 121, 123, 125, 127, 129, 132, 134, 136, 139, 141, 144, + 146, 149, 151, 154, 157, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, 190, + 193, 196, 200, 203, 207, 211, 214, 218, 222, 226, 230, 234, 238, 242, 248, 255 +}; +const uint8_t RGBLED_BREATHING_TABLE[] PROGMEM = { + 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9, + 10, 11, 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35, + 37, 40, 42, 44, 47, 49, 52, 54, 57, 59, 62, 65, 67, 70, 73, 76, + 79, 82, 85, 88, 90, 93, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, + 127, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 162, 165, 167, 170, 173, + 176, 179, 182, 185, 188, 190, 193, 196, 198, 201, 203, 206, 208, 211, 213, 215, + 218, 220, 222, 224, 226, 228, 230, 232, 234, 235, 237, 238, 240, 241, 243, 244, + 245, 246, 248, 249, 250, 250, 251, 252, 253, 253, 254, 254, 254, 255, 255, 255, + 255, 255, 255, 255, 254, 254, 254, 253, 253, 252, 251, 250, 250, 249, 248, 246, + 245, 244, 243, 241, 240, 238, 237, 235, 234, 232, 230, 228, 226, 224, 222, 220, + 218, 215, 213, 211, 208, 206, 203, 201, 198, 196, 193, 190, 188, 185, 182, 179, + 176, 173, 170, 167, 165, 162, 158, 155, 152, 149, 146, 143, 140, 137, 134, 131, + 128, 124, 121, 118, 115, 112, 109, 106, 103, 100, 97, 93, 90, 88, 85, 82, + 79, 76, 73, 70, 67, 65, 62, 59, 57, 54, 52, 49, 47, 44, 42, 40, + 37, 35, 33, 31, 29, 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11, + 10, 9, 7, 6, 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0 }; -const uint8_t RGBLED_BREATHING_TABLE[] PROGMEM = {0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,17,18,20,21,23,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,65,67,70,73,76,79,82,85,88,90,93,97,100,103,106,109,112,115,118,121,124,127,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255,255,255,255,255,254,254,254,253,253,252,251,250,250,249,248,246,245,244,243,241,240,238,237,235,234,232,230,228,226,224,222,220,218,215,213,211,208,206,203,201,198,196,193,190,188,185,182,179,176,173,170,167,165,162,158,155,152,149,146,143,140,137,134,131,128,124,121,118,115,112,109,106,103,100,97,93,90,88,85,82,79,76,73,70,67,65,62,59,57,54,52,49,47,44,42,40,37,35,33,31,29,27,25,23,21,20,18,17,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0}; const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5}; const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30}; const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20}; @@ -38,62 +55,56 @@ uint8_t rgblight_inited = 0; void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1) { - /* convert hue, saturation and brightness ( HSB/HSV ) to RGB - The DIM_CURVE is used only on brightness/value and on saturation (inverted). - This looks the most natural. - */ + /* Convert hue, saturation and brightness ( HSB/HSV ) to RGB. The DIM_CURVE is + used only on brightness/value and on saturation (inverted). This looks the + most natural. */ uint8_t r = 0, g = 0, b = 0; val = pgm_read_byte(&DIM_CURVE[val]); - sat = 255 - pgm_read_byte(&DIM_CURVE[255 - sat]); - - uint8_t base; - - if (sat == 0) { // Acromatic color (gray). Hue doesn't mind. - r = val; - g = val; - b = val; - } else { - base = ((255 - sat) * val) >> 8; - - switch (hue / 60) { - case 0: - r = val; - g = (((val - base)*hue) / 60) + base; - b = base; - break; - - case 1: - r = (((val - base)*(60 - (hue % 60))) / 60) + base; - g = val; - b = base; - break; - - case 2: - r = base; - g = val; - b = (((val - base)*(hue % 60)) / 60) + base; - break; - - case 3: - r = base; - g = (((val - base)*(60 - (hue % 60))) / 60) + base; - b = val; - break; - - case 4: - r = (((val - base)*(hue % 60)) / 60) + base; - g = base; - b = val; - break; - - case 5: - r = val; - g = base; - b = (((val - base)*(60 - (hue % 60))) / 60) + base; - break; - } - } + sat = 255 - pgm_read_byte(&DIM_CURVE[255 - sat]); + + uint8_t base; + + if (sat == 0) { // Acromatic color (gray). Hue doesn't mind. + r = val; + g = val; + b = val; + } else { + base = ((255 - sat) * val) >> 8; + + switch (hue / 60) { + case 0: + r = val; + g = (((val - base) * hue) / 60) + base; + b = base; + break; + case 1: + r = (((val - base) * (60 - (hue % 60))) / 60) + base; + g = val; + b = base; + break; + case 2: + r = base; + g = val; + b = (((val - base) * (hue % 60)) / 60) + base; + break; + case 3: + r = base; + g = (((val - base) * (60 - (hue % 60))) / 60) + base; + b = val; + break; + case 4: + r = (((val - base) * (hue % 60)) / 60) + base; + g = base; + b = val; + break; + case 5: + r = val; + g = base; + b = (((val - base) * (60 - (hue % 60))) / 60) + base; + break; + } + } setrgb(r,g,b, led1); } @@ -111,44 +122,44 @@ void eeconfig_update_rgblight(uint32_t val) { eeprom_update_dword(EECONFIG_RGBLIGHT, val); } void eeconfig_update_rgblight_default(void) { - dprintf("eeconfig_update_rgblight_default\n"); - rgblight_config.enable = 1; - rgblight_config.mode = 1; - rgblight_config.hue = 200; - rgblight_config.sat = 204; - rgblight_config.val = 204; - eeconfig_update_rgblight(rgblight_config.raw); + dprintf("eeconfig_update_rgblight_default\n"); + rgblight_config.enable = 1; + rgblight_config.mode = 1; + rgblight_config.hue = 200; + rgblight_config.sat = 204; + rgblight_config.val = 204; + eeconfig_update_rgblight(rgblight_config.raw); } void eeconfig_debug_rgblight(void) { - dprintf("rgblight_config eprom\n"); - dprintf("rgblight_config.enable = %d\n", rgblight_config.enable); - dprintf("rghlight_config.mode = %d\n", rgblight_config.mode); - dprintf("rgblight_config.hue = %d\n", rgblight_config.hue); - dprintf("rgblight_config.sat = %d\n", rgblight_config.sat); - dprintf("rgblight_config.val = %d\n", rgblight_config.val); + dprintf("rgblight_config eprom\n"); + dprintf("rgblight_config.enable = %d\n", rgblight_config.enable); + dprintf("rghlight_config.mode = %d\n", rgblight_config.mode); + dprintf("rgblight_config.hue = %d\n", rgblight_config.hue); + dprintf("rgblight_config.sat = %d\n", rgblight_config.sat); + dprintf("rgblight_config.val = %d\n", rgblight_config.val); } void rgblight_init(void) { debug_enable = 1; // Debug ON! - dprintf("rgblight_init called.\n"); + dprintf("rgblight_init called.\n"); rgblight_inited = 1; - dprintf("rgblight_init start!\n"); + dprintf("rgblight_init start!\n"); if (!eeconfig_is_enabled()) { - dprintf("rgblight_init eeconfig is not enabled.\n"); + dprintf("rgblight_init eeconfig is not enabled.\n"); eeconfig_init(); - eeconfig_update_rgblight_default(); + eeconfig_update_rgblight_default(); } rgblight_config.raw = eeconfig_read_rgblight(); - if (!rgblight_config.mode) { - dprintf("rgblight_init rgblight_config.mode = 0. Write default values to EEPROM.\n"); - eeconfig_update_rgblight_default(); - rgblight_config.raw = eeconfig_read_rgblight(); - } - eeconfig_debug_rgblight(); // display current eeprom values + if (!rgblight_config.mode) { + dprintf("rgblight_init rgblight_config.mode = 0. Write default values to EEPROM.\n"); + eeconfig_update_rgblight_default(); + rgblight_config.raw = eeconfig_read_rgblight(); + } + eeconfig_debug_rgblight(); // display current eeprom values - #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) - rgblight_timer_init(); // setup the timer - #endif + #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + rgblight_timer_init(); // setup the timer + #endif if (rgblight_config.enable) { rgblight_mode(rgblight_config.mode); @@ -156,58 +167,57 @@ void rgblight_init(void) { } void rgblight_increase(void) { - uint8_t mode = 0; + uint8_t mode = 0; if (rgblight_config.mode < RGBLIGHT_MODES) { mode = rgblight_config.mode + 1; } - rgblight_mode(mode); + rgblight_mode(mode); } - void rgblight_decrease(void) { - uint8_t mode = 0; - if (rgblight_config.mode > 1) { //mode will never < 1, if mode is less than 1, eeprom need to be initialized. - mode = rgblight_config.mode-1; + uint8_t mode = 0; + // Mode will never be < 1. If it ever is, eeprom needs to be initialized. + if (rgblight_config.mode > 1) { + mode = rgblight_config.mode - 1; } - rgblight_mode(mode); + rgblight_mode(mode); } - void rgblight_step(void) { - uint8_t mode = 0; + uint8_t mode = 0; mode = rgblight_config.mode + 1; if (mode > RGBLIGHT_MODES) { mode = 1; } - rgblight_mode(mode); + rgblight_mode(mode); } void rgblight_mode(uint8_t mode) { - if (!rgblight_config.enable) { - return; - } - if (mode<1) { - rgblight_config.mode = 1; - } else if (mode > RGBLIGHT_MODES) { - rgblight_config.mode = RGBLIGHT_MODES; - } else { - rgblight_config.mode = mode; - } + if (!rgblight_config.enable) { + return; + } + if (mode < 1) { + rgblight_config.mode = 1; + } else if (mode > RGBLIGHT_MODES) { + rgblight_config.mode = RGBLIGHT_MODES; + } else { + rgblight_config.mode = mode; + } eeconfig_update_rgblight(rgblight_config.raw); xprintf("rgblight mode: %u\n", rgblight_config.mode); - if (rgblight_config.mode == 1) { - #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) - rgblight_timer_disable(); - #endif - } else if (rgblight_config.mode >=2 && rgblight_config.mode <=23) { - // MODE 2-5, breathing - // MODE 6-8, rainbow mood - // MODE 9-14, rainbow swirl - // MODE 15-20, snake - // MODE 21-23, knight - - #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) - rgblight_timer_enable(); - #endif - } + if (rgblight_config.mode == 1) { + #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + rgblight_timer_disable(); + #endif + } else if (rgblight_config.mode >= 2 && rgblight_config.mode <= 23) { + // MODE 2-5, breathing + // MODE 6-8, rainbow mood + // MODE 9-14, rainbow swirl + // MODE 15-20, snake + // MODE 21-23, knight + + #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + rgblight_timer_enable(); + #endif + } rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } @@ -215,127 +225,125 @@ void rgblight_toggle(void) { rgblight_config.enable ^= 1; eeconfig_update_rgblight(rgblight_config.raw); xprintf("rgblight toggle: rgblight_config.enable = %u\n", rgblight_config.enable); - if (rgblight_config.enable) { - rgblight_mode(rgblight_config.mode); - } else { - - #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) - rgblight_timer_disable(); - #endif - _delay_ms(50); - rgblight_set(); - } + if (rgblight_config.enable) { + rgblight_mode(rgblight_config.mode); + } else { + #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + rgblight_timer_disable(); + #endif + _delay_ms(50); + rgblight_set(); + } } -void rgblight_increase_hue(void){ - uint16_t hue; +void rgblight_increase_hue(void) { + uint16_t hue; hue = (rgblight_config.hue+RGBLIGHT_HUE_STEP) % 360; rgblight_sethsv(hue, rgblight_config.sat, rgblight_config.val); } -void rgblight_decrease_hue(void){ - uint16_t hue; - if (rgblight_config.hue-RGBLIGHT_HUE_STEP <0 ) { - hue = (rgblight_config.hue+360-RGBLIGHT_HUE_STEP) % 360; - } else { - hue = (rgblight_config.hue-RGBLIGHT_HUE_STEP) % 360; - } +void rgblight_decrease_hue(void) { + uint16_t hue; + if (rgblight_config.hue-RGBLIGHT_HUE_STEP < 0) { + hue = (rgblight_config.hue + 360 - RGBLIGHT_HUE_STEP) % 360; + } else { + hue = (rgblight_config.hue - RGBLIGHT_HUE_STEP) % 360; + } rgblight_sethsv(hue, rgblight_config.sat, rgblight_config.val); } void rgblight_increase_sat(void) { - uint8_t sat; + uint8_t sat; if (rgblight_config.sat + RGBLIGHT_SAT_STEP > 255) { sat = 255; } else { - sat = rgblight_config.sat+RGBLIGHT_SAT_STEP; + sat = rgblight_config.sat + RGBLIGHT_SAT_STEP; } rgblight_sethsv(rgblight_config.hue, sat, rgblight_config.val); } -void rgblight_decrease_sat(void){ - uint8_t sat; +void rgblight_decrease_sat(void) { + uint8_t sat; if (rgblight_config.sat - RGBLIGHT_SAT_STEP < 0) { sat = 0; } else { - sat = rgblight_config.sat-RGBLIGHT_SAT_STEP; + sat = rgblight_config.sat - RGBLIGHT_SAT_STEP; } rgblight_sethsv(rgblight_config.hue, sat, rgblight_config.val); } -void rgblight_increase_val(void){ - uint8_t val; +void rgblight_increase_val(void) { + uint8_t val; if (rgblight_config.val + RGBLIGHT_VAL_STEP > 255) { val = 255; } else { - val = rgblight_config.val+RGBLIGHT_VAL_STEP; + val = rgblight_config.val + RGBLIGHT_VAL_STEP; } rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, val); } void rgblight_decrease_val(void) { - uint8_t val; + uint8_t val; if (rgblight_config.val - RGBLIGHT_VAL_STEP < 0) { val = 0; } else { - val = rgblight_config.val-RGBLIGHT_VAL_STEP; + val = rgblight_config.val - RGBLIGHT_VAL_STEP; } rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, val); } -void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val){ - inmem_config.raw = rgblight_config.raw; +void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) { + inmem_config.raw = rgblight_config.raw; if (rgblight_config.enable) { struct cRGB tmp_led; sethsv(hue, sat, val, &tmp_led); - inmem_config.hue = hue; - inmem_config.sat = sat; - inmem_config.val = val; + inmem_config.hue = hue; + inmem_config.sat = sat; + inmem_config.val = val; // dprintf("rgblight set hue [MEMORY]: %u,%u,%u\n", inmem_config.hue, inmem_config.sat, inmem_config.val); rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b); } } -void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val){ +void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val) { if (rgblight_config.enable) { - if (rgblight_config.mode == 1) { - // same static color - rgblight_sethsv_noeeprom(hue, sat, val); - } else { - // all LEDs in same color - if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) { - // breathing mode, ignore the change of val, use in memory value instead - val = rgblight_config.val; - } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 14) { - // rainbow mood and rainbow swirl, ignore the change of hue - hue = rgblight_config.hue; - } - } - rgblight_config.hue = hue; - rgblight_config.sat = sat; - rgblight_config.val = val; - eeconfig_update_rgblight(rgblight_config.raw); - xprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); - } -} - -void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b){ + if (rgblight_config.mode == 1) { + // same static color + rgblight_sethsv_noeeprom(hue, sat, val); + } else { + // all LEDs in same color + if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) { + // breathing mode, ignore the change of val, use in memory value instead + val = rgblight_config.val; + } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 14) { + // rainbow mood and rainbow swirl, ignore the change of hue + hue = rgblight_config.hue; + } + } + rgblight_config.hue = hue; + rgblight_config.sat = sat; + rgblight_config.val = val; + eeconfig_update_rgblight(rgblight_config.raw); + xprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); + } +} + +void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) { // dprintf("rgblight set rgb: %u,%u,%u\n", r,g,b); - for (uint8_t i=0;i>8)&0xff; - OCR3AL = RGBLED_TIMER_TOP&0xff; - SREG = sreg; + static uint8_t rgblight_timer_is_init = 0; + if (rgblight_timer_is_init) { + return; + } + rgblight_timer_is_init = 1; + /* Timer 3 setup */ + TCCR3B = _BV(WGM32) //CTC mode OCR3A as TOP + | _BV(CS30); //Clock selelct: clk/1 + /* Set TOP value */ + uint8_t sreg = SREG; + cli(); + OCR3AH = (RGBLED_TIMER_TOP >> 8) & 0xff; + OCR3AL = RGBLED_TIMER_TOP & 0xff; + SREG = sreg; } void rgblight_timer_enable(void) { - TIMSK3 |= _BV(OCIE3A); - dprintf("TIMER3 enabled.\n"); + TIMSK3 |= _BV(OCIE3A); + dprintf("TIMER3 enabled.\n"); } void rgblight_timer_disable(void) { - TIMSK3 &= ~_BV(OCIE3A); - dprintf("TIMER3 disabled.\n"); + TIMSK3 &= ~_BV(OCIE3A); + dprintf("TIMER3 disabled.\n"); } void rgblight_timer_toggle(void) { - TIMSK3 ^= _BV(OCIE3A); - dprintf("TIMER3 toggled.\n"); + TIMSK3 ^= _BV(OCIE3A); + dprintf("TIMER3 toggled.\n"); } ISR(TIMER3_COMPA_vect) { - // Mode = 1, static light, do nothing here - if (rgblight_config.mode>=2 && rgblight_config.mode<=5) { - // mode = 2 to 5, breathing mode - rgblight_effect_breathing(rgblight_config.mode-2); - - } else if (rgblight_config.mode>=6 && rgblight_config.mode<=8) { - rgblight_effect_rainbow_mood(rgblight_config.mode-6); - } else if (rgblight_config.mode>=9 && rgblight_config.mode<=14) { - rgblight_effect_rainbow_swirl(rgblight_config.mode-9); - } else if (rgblight_config.mode>=15 && rgblight_config.mode<=20) { - rgblight_effect_snake(rgblight_config.mode-15); - } else if (rgblight_config.mode>=21 && rgblight_config.mode<=23) { - rgblight_effect_knight(rgblight_config.mode-21); - } -} - -// effects + // mode = 1, static light, do nothing here + if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) { + // mode = 2 to 5, breathing mode + rgblight_effect_breathing(rgblight_config.mode - 2); + } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 8) { + // mode = 6 to 8, rainbow mood mod + rgblight_effect_rainbow_mood(rgblight_config.mode - 6); + } else if (rgblight_config.mode >= 9 && rgblight_config.mode <= 14) { + // mode = 9 to 14, rainbow swirl mode + rgblight_effect_rainbow_swirl(rgblight_config.mode - 9); + } else if (rgblight_config.mode >= 15 && rgblight_config.mode <= 20) { + // mode = 15 to 20, snake mode + rgblight_effect_snake(rgblight_config.mode - 15); + } else if (rgblight_config.mode >= 21 && rgblight_config.mode <= 23) { + // mode = 21 to 23, knight mode + rgblight_effect_knight(rgblight_config.mode - 21); + } +} + +// Effects void rgblight_effect_breathing(uint8_t interval) { - static uint8_t pos = 0; - static uint16_t last_timer = 0; + static uint8_t pos = 0; + static uint16_t last_timer = 0; - if (timer_elapsed(last_timer)=RGBLED_NUM) k=RGBLED_NUM-1; - if (i==k) { - sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, &preled[i]); - } - } - } - if (RGBLIGHT_EFFECT_KNIGHT_OFFSET) { - for (i=0;iRGBLED_NUM+RGBLIGHT_EFFECT_KNIGHT_LENGTH) { - pos = RGBLED_NUM+RGBLIGHT_EFFECT_KNIGHT_LENGTH-1; - increament = 1; - } else { - pos += 1; - } - } - -} - -#endif \ No newline at end of file + static int8_t pos = 0; + static uint16_t last_timer = 0; + uint8_t i, j, cur; + int8_t k; + struct cRGB preled[RGBLED_NUM]; + static int8_t increament = -1; + if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_KNIGHT_INTERVALS[interval])) { + return; + } + last_timer = timer_read(); + for (i = 0; i < RGBLED_NUM; i++) { + preled[i].r = 0; + preled[i].g = 0; + preled[i].b = 0; + for (j = 0; j < RGBLIGHT_EFFECT_KNIGHT_LENGTH; j++) { + k = pos + j * increament; + if (k < 0) { + k = 0; + } + if (k >= RGBLED_NUM) { + k = RGBLED_NUM - 1; + } + if (i == k) { + sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, &preled[i]); + } + } + } + if (RGBLIGHT_EFFECT_KNIGHT_OFFSET) { + for (i = 0; i < RGBLED_NUM; i++) { + cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % RGBLED_NUM; + led[i].r = preled[cur].r; + led[i].g = preled[cur].g; + led[i].b = preled[cur].b; + } + } + rgblight_set(); + if (increament == 1) { + if (pos - 1 < 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH) { + pos = 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH; + increament = -1; + } else { + pos -= 1; + } + } else { + if (pos + 1 > RGBLED_NUM + RGBLIGHT_EFFECT_KNIGHT_LENGTH) { + pos = RGBLED_NUM + RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1; + increament = 1; + } else { + pos += 1; + } + } +} + +#endif -- cgit v1.3.1 From 899c88cd8bf024792760fcf3ee8be6fed13fb315 Mon Sep 17 00:00:00 2001 From: Jordi Orlando <0xdec@users.noreply.github.com> Date: Tue, 26 Jul 2016 14:46:30 -0500 Subject: Increament -> increment --- quantum/rgblight.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'quantum') diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 1b3c576d1..c2841b851 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -453,9 +453,9 @@ void rgblight_effect_snake(uint8_t interval) { static uint16_t last_timer = 0; uint8_t i, j; int8_t k; - int8_t increament = 1; + int8_t increment = 1; if (interval % 2) { - increament = -1; + increment = -1; } if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_SNAKE_INTERVALS[interval / 2])) { return; @@ -466,7 +466,7 @@ void rgblight_effect_snake(uint8_t interval) { led[i].g = 0; led[i].b = 0; for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) { - k = pos + j * increament; + k = pos + j * increment; if (k < 0) { k = k + RGBLED_NUM; } @@ -476,7 +476,7 @@ void rgblight_effect_snake(uint8_t interval) { } } rgblight_set(); - if (increament == 1) { + if (increment == 1) { if (pos - 1 < 0) { pos = RGBLED_NUM - 1; } else { @@ -492,7 +492,7 @@ void rgblight_effect_knight(uint8_t interval) { uint8_t i, j, cur; int8_t k; struct cRGB preled[RGBLED_NUM]; - static int8_t increament = -1; + static int8_t increment = -1; if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_KNIGHT_INTERVALS[interval])) { return; } @@ -502,7 +502,7 @@ void rgblight_effect_knight(uint8_t interval) { preled[i].g = 0; preled[i].b = 0; for (j = 0; j < RGBLIGHT_EFFECT_KNIGHT_LENGTH; j++) { - k = pos + j * increament; + k = pos + j * increment; if (k < 0) { k = 0; } @@ -523,17 +523,17 @@ void rgblight_effect_knight(uint8_t interval) { } } rgblight_set(); - if (increament == 1) { + if (increment == 1) { if (pos - 1 < 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH) { pos = 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH; - increament = -1; + increment = -1; } else { pos -= 1; } } else { if (pos + 1 > RGBLED_NUM + RGBLIGHT_EFFECT_KNIGHT_LENGTH) { pos = RGBLED_NUM + RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1; - increament = 1; + increment = 1; } else { pos += 1; } -- cgit v1.3.1 From ea2d2f5d5841791745c93ef27cd1528a7fd69c97 Mon Sep 17 00:00:00 2001 From: Jordi Orlando <0xdec@users.noreply.github.com> Date: Tue, 26 Jul 2016 15:31:22 -0500 Subject: Simplify HSV->RGB calculation De-dupe repeated code --- quantum/rgblight.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) (limited to 'quantum') diff --git a/quantum/rgblight.c b/quantum/rgblight.c index c2841b851..f82e3ec55 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -55,57 +55,56 @@ uint8_t rgblight_inited = 0; void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1) { - /* Convert hue, saturation and brightness ( HSB/HSV ) to RGB. The DIM_CURVE is - used only on brightness/value and on saturation (inverted). This looks the - most natural. */ - uint8_t r = 0, g = 0, b = 0; + // Convert hue, saturation, and value (HSV/HSB) to RGB. DIM_CURVE is used only + // on value and saturation (inverted). This looks the most natural. + uint8_t r = 0, g = 0, b = 0, base, color; val = pgm_read_byte(&DIM_CURVE[val]); sat = 255 - pgm_read_byte(&DIM_CURVE[255 - sat]); - uint8_t base; - if (sat == 0) { // Acromatic color (gray). Hue doesn't mind. r = val; g = val; b = val; } else { base = ((255 - sat) * val) >> 8; + color = (val - base) * (hue % 60) / 60; switch (hue / 60) { case 0: r = val; - g = (((val - base) * hue) / 60) + base; + g = base + color; b = base; break; case 1: - r = (((val - base) * (60 - (hue % 60))) / 60) + base; + r = val - color; g = val; b = base; break; case 2: r = base; g = val; - b = (((val - base) * (hue % 60)) / 60) + base; + b = base + color; break; case 3: r = base; - g = (((val - base) * (60 - (hue % 60))) / 60) + base; + g = val - color; b = val; break; case 4: - r = (((val - base) * (hue % 60)) / 60) + base; + r = base + color; g = base; b = val; break; case 5: r = val; g = base; - b = (((val - base) * (60 - (hue % 60))) / 60) + base; + b = val - color; break; } } - setrgb(r,g,b, led1); + + setrgb(r, g, b, led1); } void setrgb(uint8_t r, uint8_t g, uint8_t b, struct cRGB *led1) { @@ -346,7 +345,6 @@ void rgblight_set(void) { } } - #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) // Animation timer -- AVR Timer3 -- cgit v1.3.1 From b21e8b97acb722bfa7b85831cfd010716ed77962 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 27 Jul 2016 08:42:09 +0200 Subject: tap-dance: Add some debugging support Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_tap_dance.c | 15 +++++++++++++++ quantum/process_keycode/process_tap_dance.h | 1 + 2 files changed, 16 insertions(+) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index d240dc2e6..5429e3438 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -1,6 +1,18 @@ #include "quantum.h" static qk_tap_dance_state_t qk_tap_dance_state; +bool td_debug_enable = false; + +#if CONSOLE_ENABLE +#define td_debug(s) if (td_debug_enable) \ + { \ + xprintf ("D:tap_dance:%s:%s = { keycode = %d, count = %d, active = %d, pressed = %d }\n", __FUNCTION__, s, \ + qk_tap_dance_state.keycode, qk_tap_dance_state.count, \ + qk_tap_dance_state.active, qk_tap_dance_state.pressed); \ + } +#else +#define td_debug(s) +#endif void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data) { qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; @@ -33,16 +45,19 @@ static inline void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, static inline void process_tap_dance_action_on_each_tap (qk_tap_dance_action_t action) { + td_debug("trigger"); _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_each_tap); } static inline void process_tap_dance_action_on_dance_finished (qk_tap_dance_action_t action) { + td_debug("trigger"); _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_dance_finished); } static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t action) { + td_debug("trigger") _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_reset); } diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index e2c74efe9..6a1258067 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h @@ -49,6 +49,7 @@ typedef struct } extern const qk_tap_dance_action_t tap_dance_actions[]; +extern bool td_debug_enable; /* To be used internally */ -- cgit v1.3.1 From e01b4c3fd9a7b66276ffd22dcac25d569d7bb7ff Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 9 Jul 2016 00:41:15 +0300 Subject: Most ergodox keymaps compiles on Infinity There are linker errors due to missing led funcitonality though --- .../drivers/gdisp/IS31FL3731C/board_IS31FL3731C.h | 113 +++++++ .../ergodox/drivers/gdisp/IS31FL3731C/driver.mk | 2 + .../drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c | 333 +++++++++++++++++++++ .../drivers/gdisp/IS31FL3731C/gdisp_lld_config.h | 36 +++ .../ergodox/drivers/gdisp/emulator_lcd/driver.mk | 2 + .../drivers/gdisp/emulator_lcd/emulator_lcd.c | 10 + .../ergodox/drivers/gdisp/emulator_led/driver.mk | 2 + .../drivers/gdisp/emulator_led/emulator_led.c | 10 + .../drivers/gdisp/st7565ergodox/board_ST7565.h | 127 ++++++++ .../ergodox/drivers/gdisp/st7565ergodox/driver.mk | 2 + .../drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c | 292 ++++++++++++++++++ .../drivers/gdisp/st7565ergodox/gdisp_lld_config.h | 26 ++ .../ergodox/drivers/gdisp/st7565ergodox/st7565.h | 37 +++ keyboards/ergodox/ergodox.c | 8 - keyboards/ergodox/ergodox.h | 1 - keyboards/ergodox/infinity/Makefile | 4 +- .../drivers/gdisp/IS31FL3731C/board_IS31FL3731C.h | 113 ------- .../infinity/drivers/gdisp/IS31FL3731C/driver.mk | 2 - .../drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c | 333 --------------------- .../drivers/gdisp/IS31FL3731C/gdisp_lld_config.h | 36 --- .../infinity/drivers/gdisp/emulator_lcd/driver.mk | 2 - .../drivers/gdisp/emulator_lcd/emulator_lcd.c | 10 - .../infinity/drivers/gdisp/emulator_led/driver.mk | 2 - .../drivers/gdisp/emulator_led/emulator_led.c | 10 - .../drivers/gdisp/st7565ergodox/board_ST7565.h | 127 -------- .../infinity/drivers/gdisp/st7565ergodox/driver.mk | 2 - .../drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c | 292 ------------------ .../drivers/gdisp/st7565ergodox/gdisp_lld_config.h | 26 -- .../infinity/drivers/gdisp/st7565ergodox/st7565.h | 37 --- keyboards/ergodox/infinity/infinity.c | 21 +- keyboards/ergodox/infinity/infinity.h | 36 +-- keyboards/ergodox/infinity/matrix.c | 3 + quantum/quantum.h | 1 + tmk_core/common/print.h | 4 +- 34 files changed, 1038 insertions(+), 1024 deletions(-) create mode 100644 keyboards/ergodox/drivers/gdisp/IS31FL3731C/board_IS31FL3731C.h create mode 100644 keyboards/ergodox/drivers/gdisp/IS31FL3731C/driver.mk create mode 100644 keyboards/ergodox/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c create mode 100644 keyboards/ergodox/drivers/gdisp/IS31FL3731C/gdisp_lld_config.h create mode 100644 keyboards/ergodox/drivers/gdisp/emulator_lcd/driver.mk create mode 100644 keyboards/ergodox/drivers/gdisp/emulator_lcd/emulator_lcd.c create mode 100644 keyboards/ergodox/drivers/gdisp/emulator_led/driver.mk create mode 100644 keyboards/ergodox/drivers/gdisp/emulator_led/emulator_led.c create mode 100644 keyboards/ergodox/drivers/gdisp/st7565ergodox/board_ST7565.h create mode 100644 keyboards/ergodox/drivers/gdisp/st7565ergodox/driver.mk create mode 100644 keyboards/ergodox/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c create mode 100644 keyboards/ergodox/drivers/gdisp/st7565ergodox/gdisp_lld_config.h create mode 100644 keyboards/ergodox/drivers/gdisp/st7565ergodox/st7565.h delete mode 100644 keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/board_IS31FL3731C.h delete mode 100644 keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/driver.mk delete mode 100644 keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c delete mode 100644 keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/gdisp_lld_config.h delete mode 100644 keyboards/ergodox/infinity/drivers/gdisp/emulator_lcd/driver.mk delete mode 100644 keyboards/ergodox/infinity/drivers/gdisp/emulator_lcd/emulator_lcd.c delete mode 100644 keyboards/ergodox/infinity/drivers/gdisp/emulator_led/driver.mk delete mode 100644 keyboards/ergodox/infinity/drivers/gdisp/emulator_led/emulator_led.c delete mode 100644 keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h delete mode 100644 keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/driver.mk delete mode 100644 keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c delete mode 100644 keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_config.h delete mode 100644 keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/st7565.h (limited to 'quantum') diff --git a/keyboards/ergodox/drivers/gdisp/IS31FL3731C/board_IS31FL3731C.h b/keyboards/ergodox/drivers/gdisp/IS31FL3731C/board_IS31FL3731C.h new file mode 100644 index 000000000..2ea73f1fb --- /dev/null +++ b/keyboards/ergodox/drivers/gdisp/IS31FL3731C/board_IS31FL3731C.h @@ -0,0 +1,113 @@ +/* +Copyright 2016 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 . +*/ + +#ifndef _GDISP_LLD_BOARD_H +#define _GDISP_LLD_BOARD_H + +static const I2CConfig i2ccfg = { + 400000 // clock speed (Hz); 400kHz max for IS31 +}; + +#define GDISP_SCREEN_WIDTH 7 +#define GDISP_SCREEN_HEIGHT 7 + +static const uint8_t led_mask[] = { + 0xFF, 0x00, /* C1-1 -> C1-16 */ + 0xFF, 0x00, /* C2-1 -> C2-16 */ + 0xFF, 0x00, /* C3-1 -> C3-16 */ + 0xFF, 0x00, /* C4-1 -> C4-16 */ + 0x3F, 0x00, /* C5-1 -> C5-16 */ + 0x00, 0x00, /* C6-1 -> C6-16 */ + 0x00, 0x00, /* C7-1 -> C7-16 */ + 0x00, 0x00, /* C8-1 -> C8-16 */ + 0x00, 0x00, /* C9-1 -> C9-16 */ +}; + +// The address of the LED +#define LA(c, r) (c + r * 16 ) +// Need to be an address that is not mapped, but inside the range of the controller matrix +#define NA LA(8, 8) + +// The numbers in the comments are the led numbers DXX on the PCB +// The mapping is taken from the schematic of left hand side +static const uint8_t led_mapping[GDISP_SCREEN_HEIGHT][GDISP_SCREEN_WIDTH] = { +// 45 44 43 42 41 40 39 + { LA(1, 1), LA(1, 0), LA(0, 4), LA(0, 3), LA(0, 2), LA(0, 1), LA(0, 0)}, +// 52 51 50 49 48 47 46 + { LA(2, 3), LA(2, 2), LA(2, 1), LA(2, 0), LA(1, 4), LA(1, 3), LA(1, 2) }, +// 58 57 56 55 54 53 N/A + { LA(3, 4), LA(3, 3), LA(3, 2), LA(3, 1), LA(3, 0), LA(2, 4), NA }, +// 67 66 65 64 63 62 61 + { LA(5, 3), LA(5, 2), LA(5, 1), LA(5, 0), LA(4, 4), LA(4, 3), LA(4, 2) }, +// 76 75 74 73 72 60 59 + { LA(7, 3), LA(7, 2), LA(7, 1), LA(7, 0), LA(6, 3), LA(4, 1), LA(4, 0) }, +// N/A N/A N/A N/A N/A N/A 68 + { NA, NA, NA, NA, NA, NA, LA(5, 4) }, +// N/A N/A N/A N/A 71 70 69 + { NA, NA, NA, NA, LA(6, 2), LA(6, 1), LA(6, 0) }, +}; + + +#define IS31_ADDR_DEFAULT 0x74 // AD connected to GND +#define IS31_TIMEOUT 5000 + +static GFXINLINE void init_board(GDisplay *g) { + (void) g; + /* I2C pins */ + palSetPadMode(GPIOB, 0, PAL_MODE_ALTERNATIVE_2); // PTB0/I2C0/SCL + palSetPadMode(GPIOB, 1, PAL_MODE_ALTERNATIVE_2); // PTB1/I2C0/SDA + palSetPadMode(GPIOB, 16, PAL_MODE_OUTPUT_PUSHPULL); + palClearPad(GPIOB, 16); + /* start I2C */ + i2cStart(&I2CD1, &i2ccfg); + // try high drive (from kiibohd) + I2CD1.i2c->C2 |= I2Cx_C2_HDRS; + // try glitch fixing (from kiibohd) + I2CD1.i2c->FLT = 4; +} + +static GFXINLINE void post_init_board(GDisplay *g) { + (void) g; +} + +static GFXINLINE const uint8_t* get_led_mask(GDisplay* g) { + (void) g; + return led_mask; +} + +static GFXINLINE uint8_t get_led_address(GDisplay* g, uint16_t x, uint16_t y) +{ + (void) g; + return led_mapping[y][x]; +} + +static GFXINLINE void set_hardware_shutdown(GDisplay* g, bool shutdown) { + (void) g; + if(!shutdown) { + palSetPad(GPIOB, 16); + } + else { + palClearPad(GPIOB, 16); + } +} + +static GFXINLINE void write_data(GDisplay *g, uint8_t* data, uint16_t length) { + (void) g; + i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, data, length, 0, 0, US2ST(IS31_TIMEOUT)); +} + +#endif /* _GDISP_LLD_BOARD_H */ diff --git a/keyboards/ergodox/drivers/gdisp/IS31FL3731C/driver.mk b/keyboards/ergodox/drivers/gdisp/IS31FL3731C/driver.mk new file mode 100644 index 000000000..f32d0d868 --- /dev/null +++ b/keyboards/ergodox/drivers/gdisp/IS31FL3731C/driver.mk @@ -0,0 +1,2 @@ +GFXINC += drivers/gdisp/IS31FL3731C +GFXSRC += drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c diff --git a/keyboards/ergodox/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c b/keyboards/ergodox/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c new file mode 100644 index 000000000..1d21f0c49 --- /dev/null +++ b/keyboards/ergodox/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c @@ -0,0 +1,333 @@ +/* +Copyright 2016 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 . +*/ + +#include "gfx.h" + +#if GFX_USE_GDISP + +#define GDISP_DRIVER_VMT GDISPVMT_IS31FL3731C_ERGODOX +#include "drivers/gdisp/IS31FL3731C/gdisp_lld_config.h" +#include "src/gdisp/gdisp_driver.h" + +#include "board_IS31FL3731C.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#ifndef GDISP_SCREEN_HEIGHT + #define GDISP_SCREEN_HEIGHT 9 +#endif +#ifndef GDISP_SCREEN_WIDTH + #define GDISP_SCREEN_WIDTH 16 +#endif +#ifndef GDISP_INITIAL_CONTRAST + #define GDISP_INITIAL_CONTRAST 0 +#endif +#ifndef GDISP_INITIAL_BACKLIGHT + #define GDISP_INITIAL_BACKLIGHT 100 +#endif + +#define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER<<0) + +#define IS31_ADDR_DEFAULT 0x74 + +#define IS31_REG_CONFIG 0x00 +// bits in reg +#define IS31_REG_CONFIG_PICTUREMODE 0x00 +#define IS31_REG_CONFIG_AUTOPLAYMODE 0x08 +#define IS31_REG_CONFIG_AUDIOPLAYMODE 0x18 +// D2:D0 bits are starting frame for autoplay mode + +#define IS31_REG_PICTDISP 0x01 // D2:D0 frame select for picture mode + +#define IS31_REG_AUTOPLAYCTRL1 0x02 +// D6:D4 number of loops (000=infty) +// D2:D0 number of frames to be used + +#define IS31_REG_AUTOPLAYCTRL2 0x03 // D5:D0 delay time (*11ms) + +#define IS31_REG_DISPLAYOPT 0x05 +#define IS31_REG_DISPLAYOPT_INTENSITY_SAME 0x20 // same intensity for all frames +#define IS31_REG_DISPLAYOPT_BLINK_ENABLE 0x8 +// D2:D0 bits blink period time (*0.27s) + +#define IS31_REG_AUDIOSYNC 0x06 +#define IS31_REG_AUDIOSYNC_ENABLE 0x1 + +#define IS31_REG_FRAMESTATE 0x07 + +#define IS31_REG_BREATHCTRL1 0x08 +// D6:D4 fade out time (26ms*2^i) +// D2:D0 fade in time (26ms*2^i) + +#define IS31_REG_BREATHCTRL2 0x09 +#define IS31_REG_BREATHCTRL2_ENABLE 0x10 +// D2:D0 extinguish time (3.5ms*2^i) + +#define IS31_REG_SHUTDOWN 0x0A +#define IS31_REG_SHUTDOWN_OFF 0x0 +#define IS31_REG_SHUTDOWN_ON 0x1 + +#define IS31_REG_AGCCTRL 0x0B +#define IS31_REG_ADCRATE 0x0C + +#define IS31_COMMANDREGISTER 0xFD +#define IS31_FUNCTIONREG 0x0B // helpfully called 'page nine' +#define IS31_FUNCTIONREG_SIZE 0xD + +#define IS31_FRAME_SIZE 0xB4 + +#define IS31_PWM_REG 0x24 +#define IS31_PWM_SIZE 0x90 + +#define IS31_LED_MASK_SIZE 0x12 +#define IS31_SCREEN_WIDTH 16 + +#define IS31 + +//Generated by http://jared.geek.nz/2013/feb/linear-led-pwm +const unsigned char cie[256] = { + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, + 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, + 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, + 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, + 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, + 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, + 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, + 28, 28, 29, 29, 30, 31, 31, 32, 32, 33, + 34, 34, 35, 36, 37, 37, 38, 39, 39, 40, + 41, 42, 43, 43, 44, 45, 46, 47, 47, 48, + 49, 50, 51, 52, 53, 54, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 70, 71, 72, 73, 74, 75, 76, 77, 79, + 80, 81, 82, 83, 85, 86, 87, 88, 90, 91, + 92, 94, 95, 96, 98, 99, 100, 102, 103, 105, + 106, 108, 109, 110, 112, 113, 115, 116, 118, 120, + 121, 123, 124, 126, 128, 129, 131, 132, 134, 136, + 138, 139, 141, 143, 145, 146, 148, 150, 152, 154, + 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, + 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, + 196, 198, 200, 202, 204, 207, 209, 211, 214, 216, + 218, 220, 223, 225, 228, 230, 232, 235, 237, 240, + 242, 245, 247, 250, 252, 255, +}; + + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +typedef struct{ + uint8_t write_buffer_offset; + uint8_t write_buffer[IS31_FRAME_SIZE]; + uint8_t frame_buffer[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH]; + uint8_t page; +}__attribute__((__packed__)) PrivData; + +// Some common routines and macros +#define PRIV(g) ((PrivData*)g->priv) + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +static GFXINLINE void write_page(GDisplay* g, uint8_t page) { + uint8_t tx[2] __attribute__((aligned(2))); + tx[0] = IS31_COMMANDREGISTER; + tx[1] = page; + write_data(g, tx, 2); +} + +static GFXINLINE void write_register(GDisplay* g, uint8_t page, uint8_t reg, uint8_t data) { + uint8_t tx[2] __attribute__((aligned(2))); + tx[0] = reg; + tx[1] = data; + write_page(g, page); + write_data(g, tx, 2); +} + +static GFXINLINE void write_ram(GDisplay *g, uint8_t page, uint16_t offset, uint16_t length) { + PRIV(g)->write_buffer_offset = offset; + write_page(g, page); + write_data(g, (uint8_t*)PRIV(g), length + 1); +} + +LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { + // The private area is the display surface. + g->priv = gfxAlloc(sizeof(PrivData)); + __builtin_memset(PRIV(g), 0, sizeof(PrivData)); + PRIV(g)->page = 0; + + // Initialise the board interface + init_board(g); + gfxSleepMilliseconds(10); + + // zero function page, all registers (assuming full_page is all zeroes) + write_ram(g, IS31_FUNCTIONREG, 0, IS31_FUNCTIONREG_SIZE); + set_hardware_shutdown(g, false); + gfxSleepMilliseconds(10); + // software shutdown + write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF); + gfxSleepMilliseconds(10); + // zero function page, all registers + write_ram(g, IS31_FUNCTIONREG, 0, IS31_FUNCTIONREG_SIZE); + gfxSleepMilliseconds(10); + + + // zero all LED registers on all 8 pages, and enable the mask + __builtin_memcpy(PRIV(g)->write_buffer, get_led_mask(g), IS31_LED_MASK_SIZE); + for(uint8_t i=0; i<8; i++) { + write_ram(g, i, 0, IS31_FRAME_SIZE); + gfxSleepMilliseconds(1); + } + + // software shutdown disable (i.e. turn stuff on) + write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_ON); + gfxSleepMilliseconds(10); + + // Finish Init + post_init_board(g); + + /* Initialise the GDISP structure */ + g->g.Width = GDISP_SCREEN_WIDTH; + g->g.Height = GDISP_SCREEN_HEIGHT; + g->g.Orientation = GDISP_ROTATE_0; + g->g.Powermode = powerOn; + g->g.Backlight = GDISP_INITIAL_BACKLIGHT; + g->g.Contrast = GDISP_INITIAL_CONTRAST; + return TRUE; +} + +#if GDISP_HARDWARE_FLUSH + LLDSPEC void gdisp_lld_flush(GDisplay *g) { + // Don't flush if we don't need it. + if (!(g->flags & GDISP_FLG_NEEDFLUSH)) + return; + + PRIV(g)->page++; + PRIV(g)->page %= 2; + // TODO: some smarter algorithm for this + // We should run only one physical page at a time + // This way we don't need to send so much data, and + // we could use slightly less memory + uint8_t* src = PRIV(g)->frame_buffer; + for (int y=0;ywrite_buffer[get_led_address(g, x, y)]=cie[*src]; + ++src; + } + } + write_ram(g, PRIV(g)->page, IS31_PWM_REG, IS31_PWM_SIZE); + gfxSleepMilliseconds(1); + write_register(g, IS31_FUNCTIONREG, IS31_REG_PICTDISP, PRIV(g)->page); + + g->flags &= ~GDISP_FLG_NEEDFLUSH; + } +#endif + +#if GDISP_HARDWARE_DRAWPIXEL + LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { + coord_t x, y; + + switch(g->g.Orientation) { + default: + case GDISP_ROTATE_0: + x = g->p.x; + y = g->p.y; + break; + case GDISP_ROTATE_180: + x = GDISP_SCREEN_WIDTH-1 - g->p.x; + y = g->p.y; + break; + } + PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x] = gdispColor2Native(g->p.color); + g->flags |= GDISP_FLG_NEEDFLUSH; + } +#endif + +#if GDISP_HARDWARE_PIXELREAD + LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { + coord_t x, y; + + switch(g->g.Orientation) { + default: + case GDISP_ROTATE_0: + x = g->p.x; + y = g->p.y; + break; + case GDISP_ROTATE_180: + x = GDISP_SCREEN_WIDTH-1 - g->p.x; + y = g->p.y; + break; + } + return gdispNative2Color(PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x]); + } +#endif + +#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL + LLDSPEC void gdisp_lld_control(GDisplay *g) { + switch(g->p.x) { + case GDISP_CONTROL_POWER: + if (g->g.Powermode == (powermode_t)g->p.ptr) + return; + switch((powermode_t)g->p.ptr) { + case powerOff: + case powerSleep: + case powerDeepSleep: + write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF); + break; + case powerOn: + write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_ON); + break; + default: + return; + } + g->g.Powermode = (powermode_t)g->p.ptr; + return; + + case GDISP_CONTROL_ORIENTATION: + if (g->g.Orientation == (orientation_t)g->p.ptr) + return; + switch((orientation_t)g->p.ptr) { + /* Rotation is handled by the drawing routines */ + case GDISP_ROTATE_0: + case GDISP_ROTATE_180: + g->g.Height = GDISP_SCREEN_HEIGHT; + g->g.Width = GDISP_SCREEN_WIDTH; + break; + case GDISP_ROTATE_90: + case GDISP_ROTATE_270: + g->g.Height = GDISP_SCREEN_WIDTH; + g->g.Width = GDISP_SCREEN_HEIGHT; + break; + default: + return; + } + g->g.Orientation = (orientation_t)g->p.ptr; + return; + + case GDISP_CONTROL_CONTRAST: + return; + } + } +#endif // GDISP_NEED_CONTROL + +#endif // GFX_USE_GDISP diff --git a/keyboards/ergodox/drivers/gdisp/IS31FL3731C/gdisp_lld_config.h b/keyboards/ergodox/drivers/gdisp/IS31FL3731C/gdisp_lld_config.h new file mode 100644 index 000000000..bb28ad775 --- /dev/null +++ b/keyboards/ergodox/drivers/gdisp/IS31FL3731C/gdisp_lld_config.h @@ -0,0 +1,36 @@ +/* +Copyright 2016 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 . +*/ + +#ifndef _GDISP_LLD_CONFIG_H +#define _GDISP_LLD_CONFIG_H + +#if GFX_USE_GDISP + +/*===========================================================================*/ +/* Driver hardware support. */ +/*===========================================================================*/ + +#define GDISP_HARDWARE_FLUSH TRUE // This controller requires flushing +#define GDISP_HARDWARE_DRAWPIXEL TRUE +#define GDISP_HARDWARE_PIXELREAD TRUE +#define GDISP_HARDWARE_CONTROL TRUE + +#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_GRAY256 + +#endif /* GFX_USE_GDISP */ + +#endif /* _GDISP_LLD_CONFIG_H */ diff --git a/keyboards/ergodox/drivers/gdisp/emulator_lcd/driver.mk b/keyboards/ergodox/drivers/gdisp/emulator_lcd/driver.mk new file mode 100644 index 000000000..16c3f80f5 --- /dev/null +++ b/keyboards/ergodox/drivers/gdisp/emulator_lcd/driver.mk @@ -0,0 +1,2 @@ +GFXINC += drivers/gdisp/emulator_lcd +GFXSRC += drivers/gdisp/emulator_lcd/emulator_lcd.c diff --git a/keyboards/ergodox/drivers/gdisp/emulator_lcd/emulator_lcd.c b/keyboards/ergodox/drivers/gdisp/emulator_lcd/emulator_lcd.c new file mode 100644 index 000000000..babfe2b36 --- /dev/null +++ b/keyboards/ergodox/drivers/gdisp/emulator_lcd/emulator_lcd.c @@ -0,0 +1,10 @@ +#define GDISP_DRIVER_VMT GDISPVMT_EMULATOR_LCD_ERGODOX +#define GDISP_HARDWARE_DRAWPIXEL TRUE +#define GDISP_HARDWARE_PIXELREAD TRUE +#define GDISP_HARDWARE_CONTROL TRUE +#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO +#define GDISP_SCREEN_WIDTH 128 +#define GDISP_SCREEN_HEIGHT 32 +#define ROTATE_180_IS_FLIP + +#include "emulator/emulator_driver_impl.h" diff --git a/keyboards/ergodox/drivers/gdisp/emulator_led/driver.mk b/keyboards/ergodox/drivers/gdisp/emulator_led/driver.mk new file mode 100644 index 000000000..255434432 --- /dev/null +++ b/keyboards/ergodox/drivers/gdisp/emulator_led/driver.mk @@ -0,0 +1,2 @@ +GFXINC += drivers/gdisp/emulator_led +GFXSRC += drivers/gdisp/emulator_led/emulator_led.c diff --git a/keyboards/ergodox/drivers/gdisp/emulator_led/emulator_led.c b/keyboards/ergodox/drivers/gdisp/emulator_led/emulator_led.c new file mode 100644 index 000000000..b0ebcdc47 --- /dev/null +++ b/keyboards/ergodox/drivers/gdisp/emulator_led/emulator_led.c @@ -0,0 +1,10 @@ +#define GDISP_DRIVER_VMT GDISPVMT_EMULATOR_LED_ERGODOX +#define GDISP_HARDWARE_DRAWPIXEL TRUE +#define GDISP_HARDWARE_PIXELREAD TRUE +#define GDISP_HARDWARE_CONTROL TRUE +#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO +#define GDISP_SCREEN_WIDTH 7 +#define GDISP_SCREEN_HEIGHT 7 +#define ROTATE_180_IS_FLIP + +#include "emulator/emulator_driver_impl.h" diff --git a/keyboards/ergodox/drivers/gdisp/st7565ergodox/board_ST7565.h b/keyboards/ergodox/drivers/gdisp/st7565ergodox/board_ST7565.h new file mode 100644 index 000000000..290571ce5 --- /dev/null +++ b/keyboards/ergodox/drivers/gdisp/st7565ergodox/board_ST7565.h @@ -0,0 +1,127 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#ifndef _GDISP_LLD_BOARD_H +#define _GDISP_LLD_BOARD_H + +#include "print.h" + +#define ST7565_LCD_BIAS ST7565_LCD_BIAS_9 // actually 6 +#define ST7565_ADC ST7565_ADC_NORMAL +#define ST7565_COM_SCAN ST7565_COM_SCAN_DEC +#define ST7565_PAGE_ORDER 0,1,2,3 +/* + * Custom page order for several LCD boards, e.g. HEM12864-99 + * #define ST7565_PAGE_ORDER 4,5,6,7,0,1,2,3 + */ + +#define ST7565_GPIOPORT GPIOC +#define ST7565_PORT PORTC +#define ST7565_A0_PIN 7 +#define ST7565_RST_PIN 8 +#define ST7565_MOSI_PIN 6 +#define ST7565_SLCK_PIN 5 +#define ST7565_SS_PIN 4 + +#define palSetPadModeRaw(portname, bits) \ + ST7565_PORT->PCR[ST7565_##portname##_PIN] = bits + +#define palSetPadModeNamed(portname, portmode) \ + palSetPadMode(ST7565_GPIOPORT, ST7565_##portname##_PIN, portmode) + +#define ST7565_SPI_MODE PORTx_PCRn_DSE | PORTx_PCRn_MUX(2) +// DSPI Clock and Transfer Attributes +// Frame Size: 8 bits +// MSB First +// CLK Low by default +static const SPIConfig spi1config = { + NULL, + /* HW dependent part.*/ + ST7565_GPIOPORT, + ST7565_SS_PIN, + SPIx_CTARn_FMSZ(7) + | SPIx_CTARn_ASC(7) + | SPIx_CTARn_DT(7) + | SPIx_CTARn_CSSCK(7) + | SPIx_CTARn_PBR(0) + | SPIx_CTARn_BR(7) + //SPI_CR1_BR_0 +}; + +static bool_t st7565_is_data_mode = 1; + +static GFXINLINE void init_board(GDisplay *g) { + (void) g; + palSetPadModeNamed(A0, PAL_MODE_OUTPUT_PUSHPULL); + palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); + st7565_is_data_mode = 1; + palSetPadModeNamed(RST, PAL_MODE_OUTPUT_PUSHPULL); + palSetPad(ST7565_GPIOPORT, ST7565_RST_PIN); + palSetPadModeRaw(MOSI, ST7565_SPI_MODE); + palSetPadModeRaw(SLCK, ST7565_SPI_MODE); + palSetPadModeRaw(SS, ST7565_SPI_MODE); + + spiInit(); + spiStart(&SPID1, &spi1config); + spiSelect(&SPID1); +} + +static GFXINLINE void post_init_board(GDisplay *g) { + (void) g; +} + +static GFXINLINE void setpin_reset(GDisplay *g, bool_t state) { + (void) g; + if (state) { + palClearPad(ST7565_GPIOPORT, ST7565_RST_PIN); + } + else { + palSetPad(ST7565_GPIOPORT, ST7565_RST_PIN); + } +} + +static GFXINLINE void acquire_bus(GDisplay *g) { + (void) g; + // Only the LCD is using the SPI bus, so no need to acquire + // spiAcquireBus(&SPID1); +} + +static GFXINLINE void release_bus(GDisplay *g) { + (void) g; + // Only the LCD is using the SPI bus, so no need to release + //spiReleaseBus(&SPID1); +} + +static GFXINLINE void write_cmd(GDisplay *g, uint8_t cmd) { + (void) g; + if (st7565_is_data_mode) { + // The sleeps need to be at lest 10 vs 25 ns respectively + // So let's sleep two ticks, one tick might not be enough + // if we are at the end of the tick + chThdSleep(2); + palClearPad(ST7565_GPIOPORT, ST7565_A0_PIN); + chThdSleep(2); + st7565_is_data_mode = 0; + } + spiSend(&SPID1, 1, &cmd); +} + +static GFXINLINE void write_data(GDisplay *g, uint8_t* data, uint16_t length) { + (void) g; + if (!st7565_is_data_mode) { + // The sleeps need to be at lest 10 vs 25 ns respectively + // So let's sleep two ticks, one tick might not be enough + // if we are at the end of the tick + chThdSleep(2); + palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); + chThdSleep(2); + st7565_is_data_mode = 1; + } + spiSend(&SPID1, length, data); +} + +#endif /* _GDISP_LLD_BOARD_H */ diff --git a/keyboards/ergodox/drivers/gdisp/st7565ergodox/driver.mk b/keyboards/ergodox/drivers/gdisp/st7565ergodox/driver.mk new file mode 100644 index 000000000..889a1a031 --- /dev/null +++ b/keyboards/ergodox/drivers/gdisp/st7565ergodox/driver.mk @@ -0,0 +1,2 @@ +GFXINC += drivers/gdisp/st7565ergodox +GFXSRC += drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c diff --git a/keyboards/ergodox/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c b/keyboards/ergodox/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c new file mode 100644 index 000000000..c33aea81a --- /dev/null +++ b/keyboards/ergodox/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c @@ -0,0 +1,292 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#include "gfx.h" + +#if GFX_USE_GDISP + +#define GDISP_DRIVER_VMT GDISPVMT_ST7565_ERGODOX +#include "drivers/gdisp/st7565ergodox/gdisp_lld_config.h" +#include "src/gdisp/gdisp_driver.h" + +#include "board_ST7565.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#ifndef GDISP_SCREEN_HEIGHT + #define GDISP_SCREEN_HEIGHT 32 +#endif +#ifndef GDISP_SCREEN_WIDTH + #define GDISP_SCREEN_WIDTH 128 +#endif +#ifndef GDISP_INITIAL_CONTRAST + #define GDISP_INITIAL_CONTRAST 0 +#endif +#ifndef GDISP_INITIAL_BACKLIGHT + #define GDISP_INITIAL_BACKLIGHT 100 +#endif + +#define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER<<0) + +#include "drivers/gdisp/st7565ergodox/st7565.h" + +/*===========================================================================*/ +/* Driver config defaults for backward compatibility. */ +/*===========================================================================*/ +#ifndef ST7565_LCD_BIAS + #define ST7565_LCD_BIAS ST7565_LCD_BIAS_7 +#endif +#ifndef ST7565_ADC + #define ST7565_ADC ST7565_ADC_NORMAL +#endif +#ifndef ST7565_COM_SCAN + #define ST7565_COM_SCAN ST7565_COM_SCAN_INC +#endif +#ifndef ST7565_PAGE_ORDER + #define ST7565_PAGE_ORDER 0,1,2,3 +#endif + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +typedef struct{ + bool_t buffer2; + uint8_t ram[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8]; +}PrivData; + +// Some common routines and macros +#define PRIV(g) ((PrivData*)g->priv) +#define RAM(g) (PRIV(g)->ram) +#define write_cmd2(g, cmd1, cmd2) { write_cmd(g, cmd1); write_cmd(g, cmd2); } +#define write_cmd3(g, cmd1, cmd2, cmd3) { write_cmd(g, cmd1); write_cmd(g, cmd2); write_cmd(g, cmd3); } + +// Some common routines and macros +#define delay(us) gfxSleepMicroseconds(us) +#define delay_ms(ms) gfxSleepMilliseconds(ms) + +#define xyaddr(x, y) ((x) + ((y)>>3)*GDISP_SCREEN_WIDTH) +#define xybit(y) (1<<((y)&7)) + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/* + * As this controller can't update on a pixel boundary we need to maintain the + * the entire display surface in memory so that we can do the necessary bit + * operations. Fortunately it is a small display in monochrome. + * 64 * 128 / 8 = 1024 bytes. + */ + +LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { + // The private area is the display surface. + g->priv = gfxAlloc(sizeof(PrivData)); + PRIV(g)->buffer2 = false; + + // Initialise the board interface + init_board(g); + + // Hardware reset + setpin_reset(g, TRUE); + gfxSleepMilliseconds(20); + setpin_reset(g, FALSE); + gfxSleepMilliseconds(20); + + acquire_bus(g); + write_cmd(g, ST7565_DISPLAY_OFF); + write_cmd(g, ST7565_LCD_BIAS); + write_cmd(g, ST7565_ADC); + write_cmd(g, ST7565_COM_SCAN); + + write_cmd(g, ST7565_START_LINE | 0); + + write_cmd(g, ST7565_RESISTOR_RATIO | 0x6); + + // turn on voltage converter (VC=1, VR=0, VF=0) + write_cmd(g, ST7565_POWER_CONTROL | 0x04); + delay_ms(50); + + // turn on voltage regulator (VC=1, VR=1, VF=0) + write_cmd(g, ST7565_POWER_CONTROL | 0x06); + delay_ms(50); + + // turn on voltage follower (VC=1, VR=1, VF=1) + write_cmd(g, ST7565_POWER_CONTROL | 0x07); + delay_ms(50); + + write_cmd(g, 0xE2); + write_cmd(g, ST7565_COM_SCAN); + write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST*64/101); + //write_cmd2(g, ST7565_CONTRAST, 0); + write_cmd(g, ST7565_DISPLAY_ON); + write_cmd(g, ST7565_ALLON_NORMAL); + write_cmd(g, ST7565_INVERT_DISPLAY); + + write_cmd(g, ST7565_RMW); + + // Finish Init + post_init_board(g); + + // Release the bus + release_bus(g); + + /* Initialise the GDISP structure */ + g->g.Width = GDISP_SCREEN_WIDTH; + g->g.Height = GDISP_SCREEN_HEIGHT; + g->g.Orientation = GDISP_ROTATE_0; + g->g.Powermode = powerOn; + g->g.Backlight = GDISP_INITIAL_BACKLIGHT; + g->g.Contrast = GDISP_INITIAL_CONTRAST; + return TRUE; +} + +#if GDISP_HARDWARE_FLUSH + LLDSPEC void gdisp_lld_flush(GDisplay *g) { + unsigned p; + + // Don't flush if we don't need it. + if (!(g->flags & GDISP_FLG_NEEDFLUSH)) + return; + + acquire_bus(g); + unsigned dstOffset = (PRIV(g)->buffer2 ? 4 : 0); + for (p = 0; p < 4; p++) { + write_cmd(g, ST7565_PAGE | (p + dstOffset)); + write_cmd(g, ST7565_COLUMN_MSB | 0); + write_cmd(g, ST7565_COLUMN_LSB | 0); + write_cmd(g, ST7565_RMW); + write_data(g, RAM(g) + (p*GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH); + } + unsigned line = (PRIV(g)->buffer2 ? 32 : 0); + write_cmd(g, ST7565_START_LINE | line); + PRIV(g)->buffer2 = !PRIV(g)->buffer2; + release_bus(g); + + g->flags &= ~GDISP_FLG_NEEDFLUSH; + } +#endif + +#if GDISP_HARDWARE_DRAWPIXEL + LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { + coord_t x, y; + + switch(g->g.Orientation) { + default: + case GDISP_ROTATE_0: + x = g->p.x; + y = g->p.y; + break; + case GDISP_ROTATE_90: + x = g->p.y; + y = GDISP_SCREEN_HEIGHT-1 - g->p.x; + break; + case GDISP_ROTATE_180: + x = GDISP_SCREEN_WIDTH-1 - g->p.x; + y = GDISP_SCREEN_HEIGHT-1 - g->p.y; + break; + case GDISP_ROTATE_270: + x = GDISP_SCREEN_HEIGHT-1 - g->p.y; + y = g->p.x; + break; + } + if (gdispColor2Native(g->p.color) != Black) + RAM(g)[xyaddr(x, y)] |= xybit(y); + else + RAM(g)[xyaddr(x, y)] &= ~xybit(y); + g->flags |= GDISP_FLG_NEEDFLUSH; + } +#endif + +#if GDISP_HARDWARE_PIXELREAD + LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { + coord_t x, y; + + switch(g->g.Orientation) { + default: + case GDISP_ROTATE_0: + x = g->p.x; + y = g->p.y; + break; + case GDISP_ROTATE_90: + x = g->p.y; + y = GDISP_SCREEN_HEIGHT-1 - g->p.x; + break; + case GDISP_ROTATE_180: + x = GDISP_SCREEN_WIDTH-1 - g->p.x; + y = GDISP_SCREEN_HEIGHT-1 - g->p.y; + break; + case GDISP_ROTATE_270: + x = GDISP_SCREEN_HEIGHT-1 - g->p.y; + y = g->p.x; + break; + } + return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black; + } +#endif + +#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL + LLDSPEC void gdisp_lld_control(GDisplay *g) { + switch(g->p.x) { + case GDISP_CONTROL_POWER: + if (g->g.Powermode == (powermode_t)g->p.ptr) + return; + switch((powermode_t)g->p.ptr) { + case powerOff: + case powerSleep: + case powerDeepSleep: + acquire_bus(g); + write_cmd(g, ST7565_DISPLAY_OFF); + release_bus(g); + break; + case powerOn: + acquire_bus(g); + write_cmd(g, ST7565_DISPLAY_ON); + release_bus(g); + break; + default: + return; + } + g->g.Powermode = (powermode_t)g->p.ptr; + return; + + case GDISP_CONTROL_ORIENTATION: + if (g->g.Orientation == (orientation_t)g->p.ptr) + return; + switch((orientation_t)g->p.ptr) { + /* Rotation is handled by the drawing routines */ + case GDISP_ROTATE_0: + case GDISP_ROTATE_180: + g->g.Height = GDISP_SCREEN_HEIGHT; + g->g.Width = GDISP_SCREEN_WIDTH; + break; + case GDISP_ROTATE_90: + case GDISP_ROTATE_270: + g->g.Height = GDISP_SCREEN_WIDTH; + g->g.Width = GDISP_SCREEN_HEIGHT; + break; + default: + return; + } + g->g.Orientation = (orientation_t)g->p.ptr; + return; + + case GDISP_CONTROL_CONTRAST: + if ((unsigned)g->p.ptr > 100) + g->p.ptr = (void *)100; + acquire_bus(g); + write_cmd2(g, ST7565_CONTRAST, ((((unsigned)g->p.ptr)<<6)/101) & 0x3F); + release_bus(g); + g->g.Contrast = (unsigned)g->p.ptr; + return; + } + } +#endif // GDISP_NEED_CONTROL + +#endif // GFX_USE_GDISP diff --git a/keyboards/ergodox/drivers/gdisp/st7565ergodox/gdisp_lld_config.h b/keyboards/ergodox/drivers/gdisp/st7565ergodox/gdisp_lld_config.h new file mode 100644 index 000000000..48587b9e1 --- /dev/null +++ b/keyboards/ergodox/drivers/gdisp/st7565ergodox/gdisp_lld_config.h @@ -0,0 +1,26 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#ifndef _GDISP_LLD_CONFIG_H +#define _GDISP_LLD_CONFIG_H + +#if GFX_USE_GDISP + +/*===========================================================================*/ +/* Driver hardware support. */ +/*===========================================================================*/ + +#define GDISP_HARDWARE_FLUSH TRUE // This controller requires flushing +#define GDISP_HARDWARE_DRAWPIXEL TRUE +#define GDISP_HARDWARE_PIXELREAD TRUE +#define GDISP_HARDWARE_CONTROL TRUE + +#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO + +#endif /* GFX_USE_GDISP */ + +#endif /* _GDISP_LLD_CONFIG_H */ diff --git a/keyboards/ergodox/drivers/gdisp/st7565ergodox/st7565.h b/keyboards/ergodox/drivers/gdisp/st7565ergodox/st7565.h new file mode 100644 index 000000000..48636b33d --- /dev/null +++ b/keyboards/ergodox/drivers/gdisp/st7565ergodox/st7565.h @@ -0,0 +1,37 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#ifndef _ST7565_H +#define _ST7565_H + +#define ST7565_CONTRAST 0x81 +#define ST7565_ALLON_NORMAL 0xA4 +#define ST7565_ALLON 0xA5 +#define ST7565_POSITIVE_DISPLAY 0xA6 +#define ST7565_INVERT_DISPLAY 0xA7 +#define ST7565_DISPLAY_OFF 0xAE +#define ST7565_DISPLAY_ON 0xAF + +#define ST7565_LCD_BIAS_7 0xA3 +#define ST7565_LCD_BIAS_9 0xA2 + +#define ST7565_ADC_NORMAL 0xA0 +#define ST7565_ADC_REVERSE 0xA1 + +#define ST7565_COM_SCAN_INC 0xC0 +#define ST7565_COM_SCAN_DEC 0xC8 + +#define ST7565_START_LINE 0x40 +#define ST7565_PAGE 0xB0 +#define ST7565_COLUMN_MSB 0x10 +#define ST7565_COLUMN_LSB 0x00 +#define ST7565_RMW 0xE0 + +#define ST7565_RESISTOR_RATIO 0x20 +#define ST7565_POWER_CONTROL 0x28 + +#endif /* _ST7565_H */ diff --git a/keyboards/ergodox/ergodox.c b/keyboards/ergodox/ergodox.c index 992e95d81..e69de29bb 100644 --- a/keyboards/ergodox/ergodox.c +++ b/keyboards/ergodox/ergodox.c @@ -1,8 +0,0 @@ -/* - * ergodox.c - * - * Created on: 7 jul 2016 - * Author: Fred Wales - */ - - diff --git a/keyboards/ergodox/ergodox.h b/keyboards/ergodox/ergodox.h index fe54e3260..f8ec8b5bf 100644 --- a/keyboards/ergodox/ergodox.h +++ b/keyboards/ergodox/ergodox.h @@ -1,6 +1,5 @@ #ifndef KEYBOARDS_ERGODOX_ERGODOX_H_ #define KEYBOARDS_ERGODOX_ERGODOX_H_ - #ifdef SUBPROJECT_ez #include "ez.h" #endif diff --git a/keyboards/ergodox/infinity/Makefile b/keyboards/ergodox/infinity/Makefile index 942032f83..22065e4d2 100644 --- a/keyboards/ergodox/infinity/Makefile +++ b/keyboards/ergodox/infinity/Makefile @@ -52,14 +52,14 @@ ARMV = 7 # Vector table for application # 0x00000000-0x00001000 area is occupied by bootlaoder.*/ # The CORTEX_VTOR... is needed only for MCHCK/Infinity KB -OPT_DEFS = -DCORTEX_VTOR_INIT=0x00002000 +OPT_DEFS += -DCORTEX_VTOR_INIT=0x00002000 # Build Options # comment out to disable the options. # CUSTOM_MATRIX ?= yes # Custom matrix file SERIAL_LINK_ENABLE = yes -VISUALIZER_ENABLE ?= yes +VISUALIZER_ENABLE ?= no #temporarily disabled to make everything compile LCD_ENABLE ?= yes LED_ENABLE ?= yes LCD_BACKLIGHT_ENABLE ?= yes diff --git a/keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/board_IS31FL3731C.h b/keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/board_IS31FL3731C.h deleted file mode 100644 index 2ea73f1fb..000000000 --- a/keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/board_IS31FL3731C.h +++ /dev/null @@ -1,113 +0,0 @@ -/* -Copyright 2016 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 . -*/ - -#ifndef _GDISP_LLD_BOARD_H -#define _GDISP_LLD_BOARD_H - -static const I2CConfig i2ccfg = { - 400000 // clock speed (Hz); 400kHz max for IS31 -}; - -#define GDISP_SCREEN_WIDTH 7 -#define GDISP_SCREEN_HEIGHT 7 - -static const uint8_t led_mask[] = { - 0xFF, 0x00, /* C1-1 -> C1-16 */ - 0xFF, 0x00, /* C2-1 -> C2-16 */ - 0xFF, 0x00, /* C3-1 -> C3-16 */ - 0xFF, 0x00, /* C4-1 -> C4-16 */ - 0x3F, 0x00, /* C5-1 -> C5-16 */ - 0x00, 0x00, /* C6-1 -> C6-16 */ - 0x00, 0x00, /* C7-1 -> C7-16 */ - 0x00, 0x00, /* C8-1 -> C8-16 */ - 0x00, 0x00, /* C9-1 -> C9-16 */ -}; - -// The address of the LED -#define LA(c, r) (c + r * 16 ) -// Need to be an address that is not mapped, but inside the range of the controller matrix -#define NA LA(8, 8) - -// The numbers in the comments are the led numbers DXX on the PCB -// The mapping is taken from the schematic of left hand side -static const uint8_t led_mapping[GDISP_SCREEN_HEIGHT][GDISP_SCREEN_WIDTH] = { -// 45 44 43 42 41 40 39 - { LA(1, 1), LA(1, 0), LA(0, 4), LA(0, 3), LA(0, 2), LA(0, 1), LA(0, 0)}, -// 52 51 50 49 48 47 46 - { LA(2, 3), LA(2, 2), LA(2, 1), LA(2, 0), LA(1, 4), LA(1, 3), LA(1, 2) }, -// 58 57 56 55 54 53 N/A - { LA(3, 4), LA(3, 3), LA(3, 2), LA(3, 1), LA(3, 0), LA(2, 4), NA }, -// 67 66 65 64 63 62 61 - { LA(5, 3), LA(5, 2), LA(5, 1), LA(5, 0), LA(4, 4), LA(4, 3), LA(4, 2) }, -// 76 75 74 73 72 60 59 - { LA(7, 3), LA(7, 2), LA(7, 1), LA(7, 0), LA(6, 3), LA(4, 1), LA(4, 0) }, -// N/A N/A N/A N/A N/A N/A 68 - { NA, NA, NA, NA, NA, NA, LA(5, 4) }, -// N/A N/A N/A N/A 71 70 69 - { NA, NA, NA, NA, LA(6, 2), LA(6, 1), LA(6, 0) }, -}; - - -#define IS31_ADDR_DEFAULT 0x74 // AD connected to GND -#define IS31_TIMEOUT 5000 - -static GFXINLINE void init_board(GDisplay *g) { - (void) g; - /* I2C pins */ - palSetPadMode(GPIOB, 0, PAL_MODE_ALTERNATIVE_2); // PTB0/I2C0/SCL - palSetPadMode(GPIOB, 1, PAL_MODE_ALTERNATIVE_2); // PTB1/I2C0/SDA - palSetPadMode(GPIOB, 16, PAL_MODE_OUTPUT_PUSHPULL); - palClearPad(GPIOB, 16); - /* start I2C */ - i2cStart(&I2CD1, &i2ccfg); - // try high drive (from kiibohd) - I2CD1.i2c->C2 |= I2Cx_C2_HDRS; - // try glitch fixing (from kiibohd) - I2CD1.i2c->FLT = 4; -} - -static GFXINLINE void post_init_board(GDisplay *g) { - (void) g; -} - -static GFXINLINE const uint8_t* get_led_mask(GDisplay* g) { - (void) g; - return led_mask; -} - -static GFXINLINE uint8_t get_led_address(GDisplay* g, uint16_t x, uint16_t y) -{ - (void) g; - return led_mapping[y][x]; -} - -static GFXINLINE void set_hardware_shutdown(GDisplay* g, bool shutdown) { - (void) g; - if(!shutdown) { - palSetPad(GPIOB, 16); - } - else { - palClearPad(GPIOB, 16); - } -} - -static GFXINLINE void write_data(GDisplay *g, uint8_t* data, uint16_t length) { - (void) g; - i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, data, length, 0, 0, US2ST(IS31_TIMEOUT)); -} - -#endif /* _GDISP_LLD_BOARD_H */ diff --git a/keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/driver.mk b/keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/driver.mk deleted file mode 100644 index f32d0d868..000000000 --- a/keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/driver.mk +++ /dev/null @@ -1,2 +0,0 @@ -GFXINC += drivers/gdisp/IS31FL3731C -GFXSRC += drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c diff --git a/keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c b/keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c deleted file mode 100644 index 1d21f0c49..000000000 --- a/keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c +++ /dev/null @@ -1,333 +0,0 @@ -/* -Copyright 2016 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 . -*/ - -#include "gfx.h" - -#if GFX_USE_GDISP - -#define GDISP_DRIVER_VMT GDISPVMT_IS31FL3731C_ERGODOX -#include "drivers/gdisp/IS31FL3731C/gdisp_lld_config.h" -#include "src/gdisp/gdisp_driver.h" - -#include "board_IS31FL3731C.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -#ifndef GDISP_SCREEN_HEIGHT - #define GDISP_SCREEN_HEIGHT 9 -#endif -#ifndef GDISP_SCREEN_WIDTH - #define GDISP_SCREEN_WIDTH 16 -#endif -#ifndef GDISP_INITIAL_CONTRAST - #define GDISP_INITIAL_CONTRAST 0 -#endif -#ifndef GDISP_INITIAL_BACKLIGHT - #define GDISP_INITIAL_BACKLIGHT 100 -#endif - -#define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER<<0) - -#define IS31_ADDR_DEFAULT 0x74 - -#define IS31_REG_CONFIG 0x00 -// bits in reg -#define IS31_REG_CONFIG_PICTUREMODE 0x00 -#define IS31_REG_CONFIG_AUTOPLAYMODE 0x08 -#define IS31_REG_CONFIG_AUDIOPLAYMODE 0x18 -// D2:D0 bits are starting frame for autoplay mode - -#define IS31_REG_PICTDISP 0x01 // D2:D0 frame select for picture mode - -#define IS31_REG_AUTOPLAYCTRL1 0x02 -// D6:D4 number of loops (000=infty) -// D2:D0 number of frames to be used - -#define IS31_REG_AUTOPLAYCTRL2 0x03 // D5:D0 delay time (*11ms) - -#define IS31_REG_DISPLAYOPT 0x05 -#define IS31_REG_DISPLAYOPT_INTENSITY_SAME 0x20 // same intensity for all frames -#define IS31_REG_DISPLAYOPT_BLINK_ENABLE 0x8 -// D2:D0 bits blink period time (*0.27s) - -#define IS31_REG_AUDIOSYNC 0x06 -#define IS31_REG_AUDIOSYNC_ENABLE 0x1 - -#define IS31_REG_FRAMESTATE 0x07 - -#define IS31_REG_BREATHCTRL1 0x08 -// D6:D4 fade out time (26ms*2^i) -// D2:D0 fade in time (26ms*2^i) - -#define IS31_REG_BREATHCTRL2 0x09 -#define IS31_REG_BREATHCTRL2_ENABLE 0x10 -// D2:D0 extinguish time (3.5ms*2^i) - -#define IS31_REG_SHUTDOWN 0x0A -#define IS31_REG_SHUTDOWN_OFF 0x0 -#define IS31_REG_SHUTDOWN_ON 0x1 - -#define IS31_REG_AGCCTRL 0x0B -#define IS31_REG_ADCRATE 0x0C - -#define IS31_COMMANDREGISTER 0xFD -#define IS31_FUNCTIONREG 0x0B // helpfully called 'page nine' -#define IS31_FUNCTIONREG_SIZE 0xD - -#define IS31_FRAME_SIZE 0xB4 - -#define IS31_PWM_REG 0x24 -#define IS31_PWM_SIZE 0x90 - -#define IS31_LED_MASK_SIZE 0x12 -#define IS31_SCREEN_WIDTH 16 - -#define IS31 - -//Generated by http://jared.geek.nz/2013/feb/linear-led-pwm -const unsigned char cie[256] = { - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, - 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, - 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, - 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, - 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, - 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, - 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, - 28, 28, 29, 29, 30, 31, 31, 32, 32, 33, - 34, 34, 35, 36, 37, 37, 38, 39, 39, 40, - 41, 42, 43, 43, 44, 45, 46, 47, 47, 48, - 49, 50, 51, 52, 53, 54, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 70, 71, 72, 73, 74, 75, 76, 77, 79, - 80, 81, 82, 83, 85, 86, 87, 88, 90, 91, - 92, 94, 95, 96, 98, 99, 100, 102, 103, 105, - 106, 108, 109, 110, 112, 113, 115, 116, 118, 120, - 121, 123, 124, 126, 128, 129, 131, 132, 134, 136, - 138, 139, 141, 143, 145, 146, 148, 150, 152, 154, - 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, - 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, - 196, 198, 200, 202, 204, 207, 209, 211, 214, 216, - 218, 220, 223, 225, 228, 230, 232, 235, 237, 240, - 242, 245, 247, 250, 252, 255, -}; - - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -typedef struct{ - uint8_t write_buffer_offset; - uint8_t write_buffer[IS31_FRAME_SIZE]; - uint8_t frame_buffer[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH]; - uint8_t page; -}__attribute__((__packed__)) PrivData; - -// Some common routines and macros -#define PRIV(g) ((PrivData*)g->priv) - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -static GFXINLINE void write_page(GDisplay* g, uint8_t page) { - uint8_t tx[2] __attribute__((aligned(2))); - tx[0] = IS31_COMMANDREGISTER; - tx[1] = page; - write_data(g, tx, 2); -} - -static GFXINLINE void write_register(GDisplay* g, uint8_t page, uint8_t reg, uint8_t data) { - uint8_t tx[2] __attribute__((aligned(2))); - tx[0] = reg; - tx[1] = data; - write_page(g, page); - write_data(g, tx, 2); -} - -static GFXINLINE void write_ram(GDisplay *g, uint8_t page, uint16_t offset, uint16_t length) { - PRIV(g)->write_buffer_offset = offset; - write_page(g, page); - write_data(g, (uint8_t*)PRIV(g), length + 1); -} - -LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { - // The private area is the display surface. - g->priv = gfxAlloc(sizeof(PrivData)); - __builtin_memset(PRIV(g), 0, sizeof(PrivData)); - PRIV(g)->page = 0; - - // Initialise the board interface - init_board(g); - gfxSleepMilliseconds(10); - - // zero function page, all registers (assuming full_page is all zeroes) - write_ram(g, IS31_FUNCTIONREG, 0, IS31_FUNCTIONREG_SIZE); - set_hardware_shutdown(g, false); - gfxSleepMilliseconds(10); - // software shutdown - write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF); - gfxSleepMilliseconds(10); - // zero function page, all registers - write_ram(g, IS31_FUNCTIONREG, 0, IS31_FUNCTIONREG_SIZE); - gfxSleepMilliseconds(10); - - - // zero all LED registers on all 8 pages, and enable the mask - __builtin_memcpy(PRIV(g)->write_buffer, get_led_mask(g), IS31_LED_MASK_SIZE); - for(uint8_t i=0; i<8; i++) { - write_ram(g, i, 0, IS31_FRAME_SIZE); - gfxSleepMilliseconds(1); - } - - // software shutdown disable (i.e. turn stuff on) - write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_ON); - gfxSleepMilliseconds(10); - - // Finish Init - post_init_board(g); - - /* Initialise the GDISP structure */ - g->g.Width = GDISP_SCREEN_WIDTH; - g->g.Height = GDISP_SCREEN_HEIGHT; - g->g.Orientation = GDISP_ROTATE_0; - g->g.Powermode = powerOn; - g->g.Backlight = GDISP_INITIAL_BACKLIGHT; - g->g.Contrast = GDISP_INITIAL_CONTRAST; - return TRUE; -} - -#if GDISP_HARDWARE_FLUSH - LLDSPEC void gdisp_lld_flush(GDisplay *g) { - // Don't flush if we don't need it. - if (!(g->flags & GDISP_FLG_NEEDFLUSH)) - return; - - PRIV(g)->page++; - PRIV(g)->page %= 2; - // TODO: some smarter algorithm for this - // We should run only one physical page at a time - // This way we don't need to send so much data, and - // we could use slightly less memory - uint8_t* src = PRIV(g)->frame_buffer; - for (int y=0;ywrite_buffer[get_led_address(g, x, y)]=cie[*src]; - ++src; - } - } - write_ram(g, PRIV(g)->page, IS31_PWM_REG, IS31_PWM_SIZE); - gfxSleepMilliseconds(1); - write_register(g, IS31_FUNCTIONREG, IS31_REG_PICTDISP, PRIV(g)->page); - - g->flags &= ~GDISP_FLG_NEEDFLUSH; - } -#endif - -#if GDISP_HARDWARE_DRAWPIXEL - LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { - coord_t x, y; - - switch(g->g.Orientation) { - default: - case GDISP_ROTATE_0: - x = g->p.x; - y = g->p.y; - break; - case GDISP_ROTATE_180: - x = GDISP_SCREEN_WIDTH-1 - g->p.x; - y = g->p.y; - break; - } - PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x] = gdispColor2Native(g->p.color); - g->flags |= GDISP_FLG_NEEDFLUSH; - } -#endif - -#if GDISP_HARDWARE_PIXELREAD - LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { - coord_t x, y; - - switch(g->g.Orientation) { - default: - case GDISP_ROTATE_0: - x = g->p.x; - y = g->p.y; - break; - case GDISP_ROTATE_180: - x = GDISP_SCREEN_WIDTH-1 - g->p.x; - y = g->p.y; - break; - } - return gdispNative2Color(PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x]); - } -#endif - -#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL - LLDSPEC void gdisp_lld_control(GDisplay *g) { - switch(g->p.x) { - case GDISP_CONTROL_POWER: - if (g->g.Powermode == (powermode_t)g->p.ptr) - return; - switch((powermode_t)g->p.ptr) { - case powerOff: - case powerSleep: - case powerDeepSleep: - write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF); - break; - case powerOn: - write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_ON); - break; - default: - return; - } - g->g.Powermode = (powermode_t)g->p.ptr; - return; - - case GDISP_CONTROL_ORIENTATION: - if (g->g.Orientation == (orientation_t)g->p.ptr) - return; - switch((orientation_t)g->p.ptr) { - /* Rotation is handled by the drawing routines */ - case GDISP_ROTATE_0: - case GDISP_ROTATE_180: - g->g.Height = GDISP_SCREEN_HEIGHT; - g->g.Width = GDISP_SCREEN_WIDTH; - break; - case GDISP_ROTATE_90: - case GDISP_ROTATE_270: - g->g.Height = GDISP_SCREEN_WIDTH; - g->g.Width = GDISP_SCREEN_HEIGHT; - break; - default: - return; - } - g->g.Orientation = (orientation_t)g->p.ptr; - return; - - case GDISP_CONTROL_CONTRAST: - return; - } - } -#endif // GDISP_NEED_CONTROL - -#endif // GFX_USE_GDISP diff --git a/keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/gdisp_lld_config.h b/keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/gdisp_lld_config.h deleted file mode 100644 index bb28ad775..000000000 --- a/keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/gdisp_lld_config.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2016 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 . -*/ - -#ifndef _GDISP_LLD_CONFIG_H -#define _GDISP_LLD_CONFIG_H - -#if GFX_USE_GDISP - -/*===========================================================================*/ -/* Driver hardware support. */ -/*===========================================================================*/ - -#define GDISP_HARDWARE_FLUSH TRUE // This controller requires flushing -#define GDISP_HARDWARE_DRAWPIXEL TRUE -#define GDISP_HARDWARE_PIXELREAD TRUE -#define GDISP_HARDWARE_CONTROL TRUE - -#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_GRAY256 - -#endif /* GFX_USE_GDISP */ - -#endif /* _GDISP_LLD_CONFIG_H */ diff --git a/keyboards/ergodox/infinity/drivers/gdisp/emulator_lcd/driver.mk b/keyboards/ergodox/infinity/drivers/gdisp/emulator_lcd/driver.mk deleted file mode 100644 index 16c3f80f5..000000000 --- a/keyboards/ergodox/infinity/drivers/gdisp/emulator_lcd/driver.mk +++ /dev/null @@ -1,2 +0,0 @@ -GFXINC += drivers/gdisp/emulator_lcd -GFXSRC += drivers/gdisp/emulator_lcd/emulator_lcd.c diff --git a/keyboards/ergodox/infinity/drivers/gdisp/emulator_lcd/emulator_lcd.c b/keyboards/ergodox/infinity/drivers/gdisp/emulator_lcd/emulator_lcd.c deleted file mode 100644 index babfe2b36..000000000 --- a/keyboards/ergodox/infinity/drivers/gdisp/emulator_lcd/emulator_lcd.c +++ /dev/null @@ -1,10 +0,0 @@ -#define GDISP_DRIVER_VMT GDISPVMT_EMULATOR_LCD_ERGODOX -#define GDISP_HARDWARE_DRAWPIXEL TRUE -#define GDISP_HARDWARE_PIXELREAD TRUE -#define GDISP_HARDWARE_CONTROL TRUE -#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO -#define GDISP_SCREEN_WIDTH 128 -#define GDISP_SCREEN_HEIGHT 32 -#define ROTATE_180_IS_FLIP - -#include "emulator/emulator_driver_impl.h" diff --git a/keyboards/ergodox/infinity/drivers/gdisp/emulator_led/driver.mk b/keyboards/ergodox/infinity/drivers/gdisp/emulator_led/driver.mk deleted file mode 100644 index 255434432..000000000 --- a/keyboards/ergodox/infinity/drivers/gdisp/emulator_led/driver.mk +++ /dev/null @@ -1,2 +0,0 @@ -GFXINC += drivers/gdisp/emulator_led -GFXSRC += drivers/gdisp/emulator_led/emulator_led.c diff --git a/keyboards/ergodox/infinity/drivers/gdisp/emulator_led/emulator_led.c b/keyboards/ergodox/infinity/drivers/gdisp/emulator_led/emulator_led.c deleted file mode 100644 index b0ebcdc47..000000000 --- a/keyboards/ergodox/infinity/drivers/gdisp/emulator_led/emulator_led.c +++ /dev/null @@ -1,10 +0,0 @@ -#define GDISP_DRIVER_VMT GDISPVMT_EMULATOR_LED_ERGODOX -#define GDISP_HARDWARE_DRAWPIXEL TRUE -#define GDISP_HARDWARE_PIXELREAD TRUE -#define GDISP_HARDWARE_CONTROL TRUE -#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO -#define GDISP_SCREEN_WIDTH 7 -#define GDISP_SCREEN_HEIGHT 7 -#define ROTATE_180_IS_FLIP - -#include "emulator/emulator_driver_impl.h" diff --git a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h deleted file mode 100644 index 290571ce5..000000000 --- a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - * http://ugfx.org/license.html - */ - -#ifndef _GDISP_LLD_BOARD_H -#define _GDISP_LLD_BOARD_H - -#include "print.h" - -#define ST7565_LCD_BIAS ST7565_LCD_BIAS_9 // actually 6 -#define ST7565_ADC ST7565_ADC_NORMAL -#define ST7565_COM_SCAN ST7565_COM_SCAN_DEC -#define ST7565_PAGE_ORDER 0,1,2,3 -/* - * Custom page order for several LCD boards, e.g. HEM12864-99 - * #define ST7565_PAGE_ORDER 4,5,6,7,0,1,2,3 - */ - -#define ST7565_GPIOPORT GPIOC -#define ST7565_PORT PORTC -#define ST7565_A0_PIN 7 -#define ST7565_RST_PIN 8 -#define ST7565_MOSI_PIN 6 -#define ST7565_SLCK_PIN 5 -#define ST7565_SS_PIN 4 - -#define palSetPadModeRaw(portname, bits) \ - ST7565_PORT->PCR[ST7565_##portname##_PIN] = bits - -#define palSetPadModeNamed(portname, portmode) \ - palSetPadMode(ST7565_GPIOPORT, ST7565_##portname##_PIN, portmode) - -#define ST7565_SPI_MODE PORTx_PCRn_DSE | PORTx_PCRn_MUX(2) -// DSPI Clock and Transfer Attributes -// Frame Size: 8 bits -// MSB First -// CLK Low by default -static const SPIConfig spi1config = { - NULL, - /* HW dependent part.*/ - ST7565_GPIOPORT, - ST7565_SS_PIN, - SPIx_CTARn_FMSZ(7) - | SPIx_CTARn_ASC(7) - | SPIx_CTARn_DT(7) - | SPIx_CTARn_CSSCK(7) - | SPIx_CTARn_PBR(0) - | SPIx_CTARn_BR(7) - //SPI_CR1_BR_0 -}; - -static bool_t st7565_is_data_mode = 1; - -static GFXINLINE void init_board(GDisplay *g) { - (void) g; - palSetPadModeNamed(A0, PAL_MODE_OUTPUT_PUSHPULL); - palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); - st7565_is_data_mode = 1; - palSetPadModeNamed(RST, PAL_MODE_OUTPUT_PUSHPULL); - palSetPad(ST7565_GPIOPORT, ST7565_RST_PIN); - palSetPadModeRaw(MOSI, ST7565_SPI_MODE); - palSetPadModeRaw(SLCK, ST7565_SPI_MODE); - palSetPadModeRaw(SS, ST7565_SPI_MODE); - - spiInit(); - spiStart(&SPID1, &spi1config); - spiSelect(&SPID1); -} - -static GFXINLINE void post_init_board(GDisplay *g) { - (void) g; -} - -static GFXINLINE void setpin_reset(GDisplay *g, bool_t state) { - (void) g; - if (state) { - palClearPad(ST7565_GPIOPORT, ST7565_RST_PIN); - } - else { - palSetPad(ST7565_GPIOPORT, ST7565_RST_PIN); - } -} - -static GFXINLINE void acquire_bus(GDisplay *g) { - (void) g; - // Only the LCD is using the SPI bus, so no need to acquire - // spiAcquireBus(&SPID1); -} - -static GFXINLINE void release_bus(GDisplay *g) { - (void) g; - // Only the LCD is using the SPI bus, so no need to release - //spiReleaseBus(&SPID1); -} - -static GFXINLINE void write_cmd(GDisplay *g, uint8_t cmd) { - (void) g; - if (st7565_is_data_mode) { - // The sleeps need to be at lest 10 vs 25 ns respectively - // So let's sleep two ticks, one tick might not be enough - // if we are at the end of the tick - chThdSleep(2); - palClearPad(ST7565_GPIOPORT, ST7565_A0_PIN); - chThdSleep(2); - st7565_is_data_mode = 0; - } - spiSend(&SPID1, 1, &cmd); -} - -static GFXINLINE void write_data(GDisplay *g, uint8_t* data, uint16_t length) { - (void) g; - if (!st7565_is_data_mode) { - // The sleeps need to be at lest 10 vs 25 ns respectively - // So let's sleep two ticks, one tick might not be enough - // if we are at the end of the tick - chThdSleep(2); - palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); - chThdSleep(2); - st7565_is_data_mode = 1; - } - spiSend(&SPID1, length, data); -} - -#endif /* _GDISP_LLD_BOARD_H */ diff --git a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/driver.mk b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/driver.mk deleted file mode 100644 index 889a1a031..000000000 --- a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/driver.mk +++ /dev/null @@ -1,2 +0,0 @@ -GFXINC += drivers/gdisp/st7565ergodox -GFXSRC += drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c diff --git a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c deleted file mode 100644 index c33aea81a..000000000 --- a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - * http://ugfx.org/license.html - */ - -#include "gfx.h" - -#if GFX_USE_GDISP - -#define GDISP_DRIVER_VMT GDISPVMT_ST7565_ERGODOX -#include "drivers/gdisp/st7565ergodox/gdisp_lld_config.h" -#include "src/gdisp/gdisp_driver.h" - -#include "board_ST7565.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -#ifndef GDISP_SCREEN_HEIGHT - #define GDISP_SCREEN_HEIGHT 32 -#endif -#ifndef GDISP_SCREEN_WIDTH - #define GDISP_SCREEN_WIDTH 128 -#endif -#ifndef GDISP_INITIAL_CONTRAST - #define GDISP_INITIAL_CONTRAST 0 -#endif -#ifndef GDISP_INITIAL_BACKLIGHT - #define GDISP_INITIAL_BACKLIGHT 100 -#endif - -#define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER<<0) - -#include "drivers/gdisp/st7565ergodox/st7565.h" - -/*===========================================================================*/ -/* Driver config defaults for backward compatibility. */ -/*===========================================================================*/ -#ifndef ST7565_LCD_BIAS - #define ST7565_LCD_BIAS ST7565_LCD_BIAS_7 -#endif -#ifndef ST7565_ADC - #define ST7565_ADC ST7565_ADC_NORMAL -#endif -#ifndef ST7565_COM_SCAN - #define ST7565_COM_SCAN ST7565_COM_SCAN_INC -#endif -#ifndef ST7565_PAGE_ORDER - #define ST7565_PAGE_ORDER 0,1,2,3 -#endif - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -typedef struct{ - bool_t buffer2; - uint8_t ram[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8]; -}PrivData; - -// Some common routines and macros -#define PRIV(g) ((PrivData*)g->priv) -#define RAM(g) (PRIV(g)->ram) -#define write_cmd2(g, cmd1, cmd2) { write_cmd(g, cmd1); write_cmd(g, cmd2); } -#define write_cmd3(g, cmd1, cmd2, cmd3) { write_cmd(g, cmd1); write_cmd(g, cmd2); write_cmd(g, cmd3); } - -// Some common routines and macros -#define delay(us) gfxSleepMicroseconds(us) -#define delay_ms(ms) gfxSleepMilliseconds(ms) - -#define xyaddr(x, y) ((x) + ((y)>>3)*GDISP_SCREEN_WIDTH) -#define xybit(y) (1<<((y)&7)) - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/* - * As this controller can't update on a pixel boundary we need to maintain the - * the entire display surface in memory so that we can do the necessary bit - * operations. Fortunately it is a small display in monochrome. - * 64 * 128 / 8 = 1024 bytes. - */ - -LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { - // The private area is the display surface. - g->priv = gfxAlloc(sizeof(PrivData)); - PRIV(g)->buffer2 = false; - - // Initialise the board interface - init_board(g); - - // Hardware reset - setpin_reset(g, TRUE); - gfxSleepMilliseconds(20); - setpin_reset(g, FALSE); - gfxSleepMilliseconds(20); - - acquire_bus(g); - write_cmd(g, ST7565_DISPLAY_OFF); - write_cmd(g, ST7565_LCD_BIAS); - write_cmd(g, ST7565_ADC); - write_cmd(g, ST7565_COM_SCAN); - - write_cmd(g, ST7565_START_LINE | 0); - - write_cmd(g, ST7565_RESISTOR_RATIO | 0x6); - - // turn on voltage converter (VC=1, VR=0, VF=0) - write_cmd(g, ST7565_POWER_CONTROL | 0x04); - delay_ms(50); - - // turn on voltage regulator (VC=1, VR=1, VF=0) - write_cmd(g, ST7565_POWER_CONTROL | 0x06); - delay_ms(50); - - // turn on voltage follower (VC=1, VR=1, VF=1) - write_cmd(g, ST7565_POWER_CONTROL | 0x07); - delay_ms(50); - - write_cmd(g, 0xE2); - write_cmd(g, ST7565_COM_SCAN); - write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST*64/101); - //write_cmd2(g, ST7565_CONTRAST, 0); - write_cmd(g, ST7565_DISPLAY_ON); - write_cmd(g, ST7565_ALLON_NORMAL); - write_cmd(g, ST7565_INVERT_DISPLAY); - - write_cmd(g, ST7565_RMW); - - // Finish Init - post_init_board(g); - - // Release the bus - release_bus(g); - - /* Initialise the GDISP structure */ - g->g.Width = GDISP_SCREEN_WIDTH; - g->g.Height = GDISP_SCREEN_HEIGHT; - g->g.Orientation = GDISP_ROTATE_0; - g->g.Powermode = powerOn; - g->g.Backlight = GDISP_INITIAL_BACKLIGHT; - g->g.Contrast = GDISP_INITIAL_CONTRAST; - return TRUE; -} - -#if GDISP_HARDWARE_FLUSH - LLDSPEC void gdisp_lld_flush(GDisplay *g) { - unsigned p; - - // Don't flush if we don't need it. - if (!(g->flags & GDISP_FLG_NEEDFLUSH)) - return; - - acquire_bus(g); - unsigned dstOffset = (PRIV(g)->buffer2 ? 4 : 0); - for (p = 0; p < 4; p++) { - write_cmd(g, ST7565_PAGE | (p + dstOffset)); - write_cmd(g, ST7565_COLUMN_MSB | 0); - write_cmd(g, ST7565_COLUMN_LSB | 0); - write_cmd(g, ST7565_RMW); - write_data(g, RAM(g) + (p*GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH); - } - unsigned line = (PRIV(g)->buffer2 ? 32 : 0); - write_cmd(g, ST7565_START_LINE | line); - PRIV(g)->buffer2 = !PRIV(g)->buffer2; - release_bus(g); - - g->flags &= ~GDISP_FLG_NEEDFLUSH; - } -#endif - -#if GDISP_HARDWARE_DRAWPIXEL - LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { - coord_t x, y; - - switch(g->g.Orientation) { - default: - case GDISP_ROTATE_0: - x = g->p.x; - y = g->p.y; - break; - case GDISP_ROTATE_90: - x = g->p.y; - y = GDISP_SCREEN_HEIGHT-1 - g->p.x; - break; - case GDISP_ROTATE_180: - x = GDISP_SCREEN_WIDTH-1 - g->p.x; - y = GDISP_SCREEN_HEIGHT-1 - g->p.y; - break; - case GDISP_ROTATE_270: - x = GDISP_SCREEN_HEIGHT-1 - g->p.y; - y = g->p.x; - break; - } - if (gdispColor2Native(g->p.color) != Black) - RAM(g)[xyaddr(x, y)] |= xybit(y); - else - RAM(g)[xyaddr(x, y)] &= ~xybit(y); - g->flags |= GDISP_FLG_NEEDFLUSH; - } -#endif - -#if GDISP_HARDWARE_PIXELREAD - LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { - coord_t x, y; - - switch(g->g.Orientation) { - default: - case GDISP_ROTATE_0: - x = g->p.x; - y = g->p.y; - break; - case GDISP_ROTATE_90: - x = g->p.y; - y = GDISP_SCREEN_HEIGHT-1 - g->p.x; - break; - case GDISP_ROTATE_180: - x = GDISP_SCREEN_WIDTH-1 - g->p.x; - y = GDISP_SCREEN_HEIGHT-1 - g->p.y; - break; - case GDISP_ROTATE_270: - x = GDISP_SCREEN_HEIGHT-1 - g->p.y; - y = g->p.x; - break; - } - return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black; - } -#endif - -#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL - LLDSPEC void gdisp_lld_control(GDisplay *g) { - switch(g->p.x) { - case GDISP_CONTROL_POWER: - if (g->g.Powermode == (powermode_t)g->p.ptr) - return; - switch((powermode_t)g->p.ptr) { - case powerOff: - case powerSleep: - case powerDeepSleep: - acquire_bus(g); - write_cmd(g, ST7565_DISPLAY_OFF); - release_bus(g); - break; - case powerOn: - acquire_bus(g); - write_cmd(g, ST7565_DISPLAY_ON); - release_bus(g); - break; - default: - return; - } - g->g.Powermode = (powermode_t)g->p.ptr; - return; - - case GDISP_CONTROL_ORIENTATION: - if (g->g.Orientation == (orientation_t)g->p.ptr) - return; - switch((orientation_t)g->p.ptr) { - /* Rotation is handled by the drawing routines */ - case GDISP_ROTATE_0: - case GDISP_ROTATE_180: - g->g.Height = GDISP_SCREEN_HEIGHT; - g->g.Width = GDISP_SCREEN_WIDTH; - break; - case GDISP_ROTATE_90: - case GDISP_ROTATE_270: - g->g.Height = GDISP_SCREEN_WIDTH; - g->g.Width = GDISP_SCREEN_HEIGHT; - break; - default: - return; - } - g->g.Orientation = (orientation_t)g->p.ptr; - return; - - case GDISP_CONTROL_CONTRAST: - if ((unsigned)g->p.ptr > 100) - g->p.ptr = (void *)100; - acquire_bus(g); - write_cmd2(g, ST7565_CONTRAST, ((((unsigned)g->p.ptr)<<6)/101) & 0x3F); - release_bus(g); - g->g.Contrast = (unsigned)g->p.ptr; - return; - } - } -#endif // GDISP_NEED_CONTROL - -#endif // GFX_USE_GDISP diff --git a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_config.h b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_config.h deleted file mode 100644 index 48587b9e1..000000000 --- a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_config.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - * http://ugfx.org/license.html - */ - -#ifndef _GDISP_LLD_CONFIG_H -#define _GDISP_LLD_CONFIG_H - -#if GFX_USE_GDISP - -/*===========================================================================*/ -/* Driver hardware support. */ -/*===========================================================================*/ - -#define GDISP_HARDWARE_FLUSH TRUE // This controller requires flushing -#define GDISP_HARDWARE_DRAWPIXEL TRUE -#define GDISP_HARDWARE_PIXELREAD TRUE -#define GDISP_HARDWARE_CONTROL TRUE - -#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO - -#endif /* GFX_USE_GDISP */ - -#endif /* _GDISP_LLD_CONFIG_H */ diff --git a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/st7565.h b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/st7565.h deleted file mode 100644 index 48636b33d..000000000 --- a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/st7565.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - * http://ugfx.org/license.html - */ - -#ifndef _ST7565_H -#define _ST7565_H - -#define ST7565_CONTRAST 0x81 -#define ST7565_ALLON_NORMAL 0xA4 -#define ST7565_ALLON 0xA5 -#define ST7565_POSITIVE_DISPLAY 0xA6 -#define ST7565_INVERT_DISPLAY 0xA7 -#define ST7565_DISPLAY_OFF 0xAE -#define ST7565_DISPLAY_ON 0xAF - -#define ST7565_LCD_BIAS_7 0xA3 -#define ST7565_LCD_BIAS_9 0xA2 - -#define ST7565_ADC_NORMAL 0xA0 -#define ST7565_ADC_REVERSE 0xA1 - -#define ST7565_COM_SCAN_INC 0xC0 -#define ST7565_COM_SCAN_DEC 0xC8 - -#define ST7565_START_LINE 0x40 -#define ST7565_PAGE 0xB0 -#define ST7565_COLUMN_MSB 0x10 -#define ST7565_COLUMN_LSB 0x00 -#define ST7565_RMW 0xE0 - -#define ST7565_RESISTOR_RATIO 0x20 -#define ST7565_POWER_CONTROL 0x28 - -#endif /* _ST7565_H */ diff --git a/keyboards/ergodox/infinity/infinity.c b/keyboards/ergodox/infinity/infinity.c index 87ed40fab..85e61e3aa 100644 --- a/keyboards/ergodox/infinity/infinity.c +++ b/keyboards/ergodox/infinity/infinity.c @@ -1,8 +1,10 @@ -#include "infinity_ergodox.h" +#include "infinity.h" #include "ch.h" #include "hal.h" #include "serial_link/system/serial_link.h" +#ifdef VISUALIZER_ENABLE #include "lcd_backlight.h" +#endif void init_serial_link_hal(void) { PORTA->PCR[1] = PORTx_PCRn_PE | PORTx_PCRn_PS | PORTx_PCRn_PFE | PORTx_PCRn_MUX(2); @@ -36,7 +38,7 @@ void init_serial_link_hal(void) { // Using a higher pre-scalar without flicker is possible but FTM0_MOD will need to be reduced // Which will reduce the brightness range #define PRESCALAR_DEFINE 0 - +#ifdef VISUALIZER_ENABLE void lcd_backlight_hal_init(void) { // Setup Backlight SIM->SCGC6 |= SIM_SCGC6_FTM0; @@ -74,3 +76,18 @@ void lcd_backlight_hal_color(uint16_t r, uint16_t g, uint16_t b) { CHANNEL_GREEN.CnV = g; CHANNEL_BLUE.CnV = b; } +#endif + +void matrix_init_kb(void) { + // put your keyboard start-up code here + // runs once when the firmware starts up + + matrix_init_user(); +} + +void matrix_scan_kb(void) { + // put your looping keyboard code here + // runs every cycle (a lot) + + matrix_scan_user(); +} diff --git a/keyboards/ergodox/infinity/infinity.h b/keyboards/ergodox/infinity/infinity.h index de7267594..a92aa89bb 100644 --- a/keyboards/ergodox/infinity/infinity.h +++ b/keyboards/ergodox/infinity/infinity.h @@ -21,24 +21,24 @@ B04, \ B14, B24, B34 \ ) { \ - { KC_NO, KC_NO, KC_NO, KC_##A03, KC_##A04 }, \ - { KC_NO, KC_NO, KC_NO, KC_##A13, KC_##A14 }, \ - { KC_##A20, KC_##A21, KC_NO, KC_##A23, KC_##A24 }, \ - { KC_##A30, KC_##A31, KC_##A32, KC_##A33, KC_##A34 }, \ - { KC_##A40, KC_##A41, KC_##A42, KC_##A43, KC_##A44 }, \ - { KC_##A50, KC_##A51, KC_##A52, KC_##A53, KC_##A54 }, \ - { KC_##A60, KC_##A61, KC_##A62, KC_##A63, KC_##A64 }, \ - { KC_##A70, KC_##A71, KC_##A72, KC_##A73, KC_##A74 }, \ - { KC_##A80, KC_##A81, KC_##A82, KC_##A83, KC_##A84 }, \ - { KC_NO, KC_NO, KC_NO, KC_##B03, KC_##B04 }, \ - { KC_NO, KC_NO, KC_NO, KC_##B13, KC_##B14 }, \ - { KC_##B20, KC_##B21, KC_NO, KC_##B23, KC_##B24 }, \ - { KC_##B30, KC_##B31, KC_##B32, KC_##B33, KC_##B34 }, \ - { KC_##B40, KC_##B41, KC_##B42, KC_##B43, KC_##B44 }, \ - { KC_##B50, KC_##B51, KC_##B52, KC_##B53, KC_##B54 }, \ - { KC_##B60, KC_##B61, KC_##B62, KC_##B63, KC_##B64 }, \ - { KC_##B70, KC_##B71, KC_##B72, KC_##B73, KC_##B74 }, \ - { KC_##B80, KC_##B81, KC_##B82, KC_##B83, KC_##B84 } \ + { KC_NO, KC_NO, KC_NO, A03, A04 }, \ + { KC_NO, KC_NO, KC_NO, A13, A14 }, \ + { A20, A21, KC_NO, A23, A24 }, \ + { A30, A31, A32, A33, A34 }, \ + { A40, A41, A42, A43, A44 }, \ + { A50, A51, A52, A53, A54 }, \ + { A60, A61, A62, A63, A64 }, \ + { A70, A71, A72, A73, A74 }, \ + { A80, A81, A82, A83, A84 }, \ + { KC_NO, KC_NO, KC_NO, B03, B04 }, \ + { KC_NO, KC_NO, KC_NO, B13, B14 }, \ + { B20, B21, KC_NO, B23, B24 }, \ + { B30, B31, B32, B33, B34 }, \ + { B40, B41, B42, B43, B44 }, \ + { B50, B51, B52, B53, B54 }, \ + { B60, B61, B62, B63, B64 }, \ + { B70, B71, B72, B73, B74 }, \ + { B80, B81, B82, B83, B84 } \ } #endif /* KEYBOARDS_INFINITY_ERGODOX_INFINITY_ERGODOX_H_ */ diff --git a/keyboards/ergodox/infinity/matrix.c b/keyboards/ergodox/infinity/matrix.c index 2b806cd64..1fda90484 100644 --- a/keyboards/ergodox/infinity/matrix.c +++ b/keyboards/ergodox/infinity/matrix.c @@ -63,6 +63,8 @@ void matrix_init(void) memset(matrix, 0, MATRIX_ROWS); memset(matrix_debouncing, 0, LOCAL_MATRIX_ROWS); + + matrix_init_quantum(); } uint8_t matrix_scan(void) @@ -127,6 +129,7 @@ uint8_t matrix_scan(void) } debouncing = false; } + matrix_scan_quantum(); return 1; } diff --git a/quantum/quantum.h b/quantum/quantum.h index 7ebfb24e3..6e3fbcc79 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -25,6 +25,7 @@ #include "led.h" #include "action_util.h" #include +#include "print.h" extern uint32_t default_layer_state; diff --git a/tmk_core/common/print.h b/tmk_core/common/print.h index 0368bcd4a..a1352527f 100644 --- a/tmk_core/common/print.h +++ b/tmk_core/common/print.h @@ -29,7 +29,9 @@ #include #include "util.h" - +#if defined(PROTOCOL_CHIBIOS) +#define PSTR(x) x +#endif #ifndef NO_PRINT -- cgit v1.3.1 From 7d0345ef25b5e1924f1e98c76d78607778e0b17d Mon Sep 17 00:00:00 2001 From: JeeBak Kim Date: Sat, 30 Jul 2016 01:52:33 -0700 Subject: Add IN_LIKE_FLINT song --- quantum/audio/song_list.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'quantum') diff --git a/quantum/audio/song_list.h b/quantum/audio/song_list.h index fc6fcdeef..8022ca672 100644 --- a/quantum/audio/song_list.h +++ b/quantum/audio/song_list.h @@ -28,6 +28,14 @@ Q__NOTE(_E4), Q__NOTE(_C4), \ Q__NOTE(_E4), +/* Requires: PLAY_NOTE_ARRAY(..., ..., STACCATO); */ +#define IN_LIKE_FLINT \ + E__NOTE(_AS4), E__NOTE(_AS4), QD_NOTE(_B4), \ + E__NOTE(_AS4), E__NOTE(_B4), QD_NOTE(_CS4), \ + E__NOTE(_B4), E__NOTE(_CS4), QD_NOTE(_DS4), \ + E__NOTE(_CS4), E__NOTE(_B4), QD_NOTE(_AS4), \ + E__NOTE(_AS4), E__NOTE(_AS4), QD_NOTE(_B4), + #define GOODBYE_SOUND \ E__NOTE(_E7), \ E__NOTE(_A6), \ -- cgit v1.3.1 From c70b276b1b29e31945a5a03f560961d8a008176d Mon Sep 17 00:00:00 2001 From: kuel Date: Tue, 2 Aug 2016 14:09:01 -0500 Subject: Add keymap_cyrillic.h, lots of cyrillic characters --- quantum/keymap_extras/keymap_cyrillic.h | 161 ++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 quantum/keymap_extras/keymap_cyrillic.h (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_cyrillic.h b/quantum/keymap_extras/keymap_cyrillic.h new file mode 100644 index 000000000..d5390afff --- /dev/null +++ b/quantum/keymap_extras/keymap_cyrillic.h @@ -0,0 +1,161 @@ +#ifndef KEYMAP_CYRILLIC_H +#define KEYMAP_CYRILLIC_H + +#include "keymap.h" + +/* + * This is based off of + * https://en.wikipedia.org/wiki/Cyrillic_script + */ + +// Capital Char russian/ukrainian/bulgarian +#define CY_A UC(0x0410) // А rus ukr bul +#define CY_BE UC(0x0411) // Б rus ukr bul +#define CY_VE UC(0x0412) // В rus ukr bul +#define CY_GHE UC(0x0413) // Г rus ukr bul +#define CY_GHEUP UC(0x0490) // Ґ ukr +#define CY_DE UC(0x0414) // Д rus ukr bul +#define CY_DJE UC(0x0402) // Ђ +#define CY_GJE UC(0x0403) // Ѓ +#define CY_IE UC(0x0415) // Е rus ukr bul +#define CY_IO UC(0x0401) // Ё rus +#define CY_UIE UC(0x0404) // Є ukr +#define CY_ZHE UC(0x0416) // Ж rus ukr bul +#define CY_ZE UC(0x0417) // З rus ukr bul +#define CY_DZE UC(0x0405) // Ѕ +#define CY_I UC(0x0418) // И rus ukr bul +#define CY_B_U_I UC(0x0406) // І ukr +#define CY_YI UC(0x0407) // Ї ukr +#define CY_SRT_I UC(0x0419) // Й rus ukr bul +#define CY_JE UC(0x0408) // Ј +#define CY_KA UC(0x041a) // К rus ukr bul +#define CY_EL UC(0x041b) // Л rus ukr bul +#define CY_LJE UC(0x0409) // Љ +#define CY_EM UC(0x041c) // М rus ukr bul +#define CY_EN UC(0x041d) // Н rus ukr bul +#define CY_NJE UC(0x040a) // Њ +#define CY_O UC(0x041e) // О rus ukr bul +#define CY_PE UC(0x041f) // П rus ukr bul +#define CY_ER UC(0x0420) // Р rus ukr bul +#define CY_ES UC(0x0421) // С rus ukr bul +#define CY_TE UC(0x0422) // Т rus ukr bul +#define CY_TSHE UC(0x040b) // Ћ +#define CY_KJE UC(0x040c) // Ќ +#define CY_U UC(0x0423) // У rus ukr bul +#define CY_SRT_U UC(0x040e) // Ў +#define CY_EF UC(0x0424) // Ф rus ukr bul +#define CY_HA UC(0x0425) // Х rus bul +#define CY_TSE UC(0x0426) // Ц rus ukr bul +#define CY_CHE UC(0x0427) // Ч rus ukr bul +#define CY_DZHE UC(0x040f) // Џ +#define CY_SHA UC(0x0428) // Ш rus ukr bul +#define CY_SHCHA UC(0x0429) // Щ rus ukr bul +#define CY_HSIGN UC(0x042a) // Ъ rus bul +#define CY_YERU UC(0x042b) // Ы rus +#define CY_SSIGN UC(0x042c) // Ь rus ukr bul +#define CY_E UC(0x042d) // Э rus +#define CY_YU UC(0x042e) // Ю rus ukr bul +#define CY_YA UC(0x042f) // Я rus ukr bul +// Important Cyrillic non-Slavic letters +#define CY_PALOCHKA UC(0x04c0) // Ӏ +#define CY_SCHWA UC(0x04d8) // Ә +#define CY_GHE_S UC(0x0492) // Ғ +#define CY_ZE_D UC(0x0498) // Ҙ +#define CY_ES_D UC(0x04aa) // Ҫ +#define CY_BR_KA UC(0x04a0) // Ҡ +#define CY_ZHE_D UC(0x0496) // Җ +#define CY_KA_D UC(0x049a) // Қ +#define CY_EN_D UC(0x04a2) // Ң +#define CY_ENGHE UC(0x04a4) // Ҥ +#define CY_BRD_O UC(0x04e8) // Ө +#define CY_STR_U UC(0x04ae) // Ү +#define CY_S_U_S UC(0x04b0) // Ұ +#define CY_SHHA UC(0x04ba) // Һ +#define CY_HA_D UC(0x04b2) // Ҳ + + +// Small +#define CY_a UC(0x0430) // a rus ukr bul +#define CY_be UC(0x0431) // б rus ukr bul +#define CY_ve UC(0x0432) // в rus ukr bul +#define CY_ghe UC(0x0433) // г rus ukr bul +#define CY_gheup UC(0x0491) // ґ ukr +#define CY_de UC(0x0434) // д rus ukr bul +#define CY_dje UC(0x0452) // ђ +#define CY_gje UC(0x0453) // ѓ +#define CY_ie UC(0x0435) // е rus ukr bul +#define CY_io UC(0x0451) // ё rus +#define CY_uie UC(0x0454) // є ukr +#define CY_zhe UC(0x0436) // ж rus ukr bul +#define CY_ze UC(0x0437) // з rus ukr bul +#define CY_dze UC(0x0455) // ѕ +#define CY_i UC(0x0438) // и rus ukr bul +#define CY_b_u_i UC(0x0456) // і ukr +#define CY_yi UC(0x0457) // ї ukr +#define CY_srt_i UC(0x0439) // й rus ukr bul +#define CY_je UC(0x0458) // ј +#define CY_ka UC(0x043a) // к rus ukr bul +#define CY_el UC(0x043b) // л rus ukr bul +#define CY_lje UC(0x0459) // љ +#define CY_em UC(0x043c) // м rus ukr bul +#define CY_en UC(0x043d) // н rus ukr bul +#define CY_nje UC(0x045a) // њ +#define CY_o UC(0x043e) // о rus ukr bul +#define CY_pe UC(0x043f) // п rus ukr bul +#define CY_er UC(0x0440) // р rus ukr bul +#define CY_es UC(0x0441) // с rus ukr bul +#define CY_te UC(0x0442) // т rus ukr bul +#define CY_tshe UC(0x045b) // ћ +#define CY_kje UC(0x045c) // ќ +#define CY_u UC(0x0443) // у rus ukr bul +#define CY_srt_u UC(0x045e) // ў +#define CY_ef UC(0x0444) // ф rus ukr bul +#define CY_ha UC(0x0445) // х rus ukr bul +#define CY_tse UC(0x0446) // ц rus ukr bul +#define CY_che UC(0x0447) // ч rus ukr bul +#define CY_dzhe UC(0x045f) // џ +#define CY_sha UC(0x0448) // ш rus ukr bul +#define CY_shcha UC(0x0449) // щ rus ukr bul +#define CY_hsign UC(0x044a) // ъ rus bul +#define CY_yeru UC(0x044b) // ы rus +#define CY_ssign UC(0x044c) // ь rus ukr bul +#define CY_e UC(0x044d) // э rus +#define CY_yu UC(0x044e) // ю rus ukr bul +#define CY_ya UC(0x044f) // я rus ukr bul +// Important Cyrillic non-Slavic letters +#define CY_palochka UC(0x04cf) // ӏ +#define CY_schwa UC(0x04d9) // ә +#define CY_ghe_s UC(0x0493) // ғ +#define CY_ze_d UC(0x0499) // ҙ +#define CY_es_d UC(0x04ab) // ҫ +#define CY_br_ka UC(0x04a1) // ҡ +#define CY_zhe_d UC(0x0497) // җ +#define CY_ka_d UC(0x049b) // қ +#define CY_en_d UC(0x04a3) // ң +#define CY_enghe UC(0x04a5) // ҥ +#define CY_brd_o UC(0x04e9) // ө +#define CY_str_u UC(0x04af) // ү +#define CY_s_u_s UC(0x04b1) // ұ +#define CY_shha UC(0x04bb) // һ +#define CY_ha_d UC(0x04b3) // ҳ + + +// Extra +#define CY_slr_ve UC(0x1c80) // ᲀ CYRILLIC SMALL LETTER ROUNDED VE +#define CY_ll_de UC(0x1c81) // ᲁ CYRILLIC SMALL LETTER LONG-LEGGED DE +#define CY_ZEMLYA UC(0xa640) // Ꙁ CYRILLIC CAPITAL LETTER ZEMLYA +#define CY_zemlya UC(0xa641) // ꙁ CYRILLIC SMALL LETTER ZEMLYA +#define CY_RV_DZE UC(0xa644) // Ꙅ CYRILLIC CAPITAL LETTER REVERSED DZE +#define CY_rv_DZE UC(0xa645) // ꙅ CYRILLIC SMALL LETTER REVERSED DZE +#define CY_slw_es UC(0x1c83) // ᲃ CYRILLIC SMALL LETTER WIDE ES +#define CY_st_te UC(0x1c84) // ᲄ CYRILLIC SMALL LETTER TALL TE +#define CY_3l_te UC(0x1c85) // ᲅ CYRILLIC SMALL LETTER THREE-LEGGED TE +#define CY_thsign UC(0x1c86) // ᲆ CYRILLIC SMALL LETTER TALL HARD SIGN +#define CY_YERUBY UC(0xa650) // Ꙑ CYRILLIC CAPITAL LETTER YERU WITH BACK YER +#define CY_yeruby UC(0xa651) // ꙑ CYRILLIC SMALL LETTER YERU WITH BACK YER +#define CY_RUBLE UC(0x20bd) // ₽ +#define CY_NUMERO UC(0x2116) // № + +// The letters Zje and Sje are made for other letters and accent marks + +#endif -- cgit v1.3.1 From c5ee24a6c3ea39e9725dfc276c92d5bce726ca78 Mon Sep 17 00:00:00 2001 From: kuel Date: Sun, 7 Aug 2016 11:01:12 -0500 Subject: Add keymap_russian.h, a software implementation of Russian rename keymap_cyrillic.h to keymap_unicode_cyrillic.h changed CY_RUBLE and CY_NUMERO to CY_RUBL and CY_NMRO in keymap_unicode_cyrillic.h --- quantum/keymap_extras/keymap_cyrillic.h | 161 ----------------------- quantum/keymap_extras/keymap_russian.h | 79 ++++++++++++ quantum/keymap_extras/keymap_unicode_cyrillic.h | 163 ++++++++++++++++++++++++ 3 files changed, 242 insertions(+), 161 deletions(-) delete mode 100644 quantum/keymap_extras/keymap_cyrillic.h create mode 100644 quantum/keymap_extras/keymap_russian.h create mode 100644 quantum/keymap_extras/keymap_unicode_cyrillic.h (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_cyrillic.h b/quantum/keymap_extras/keymap_cyrillic.h deleted file mode 100644 index d5390afff..000000000 --- a/quantum/keymap_extras/keymap_cyrillic.h +++ /dev/null @@ -1,161 +0,0 @@ -#ifndef KEYMAP_CYRILLIC_H -#define KEYMAP_CYRILLIC_H - -#include "keymap.h" - -/* - * This is based off of - * https://en.wikipedia.org/wiki/Cyrillic_script - */ - -// Capital Char russian/ukrainian/bulgarian -#define CY_A UC(0x0410) // А rus ukr bul -#define CY_BE UC(0x0411) // Б rus ukr bul -#define CY_VE UC(0x0412) // В rus ukr bul -#define CY_GHE UC(0x0413) // Г rus ukr bul -#define CY_GHEUP UC(0x0490) // Ґ ukr -#define CY_DE UC(0x0414) // Д rus ukr bul -#define CY_DJE UC(0x0402) // Ђ -#define CY_GJE UC(0x0403) // Ѓ -#define CY_IE UC(0x0415) // Е rus ukr bul -#define CY_IO UC(0x0401) // Ё rus -#define CY_UIE UC(0x0404) // Є ukr -#define CY_ZHE UC(0x0416) // Ж rus ukr bul -#define CY_ZE UC(0x0417) // З rus ukr bul -#define CY_DZE UC(0x0405) // Ѕ -#define CY_I UC(0x0418) // И rus ukr bul -#define CY_B_U_I UC(0x0406) // І ukr -#define CY_YI UC(0x0407) // Ї ukr -#define CY_SRT_I UC(0x0419) // Й rus ukr bul -#define CY_JE UC(0x0408) // Ј -#define CY_KA UC(0x041a) // К rus ukr bul -#define CY_EL UC(0x041b) // Л rus ukr bul -#define CY_LJE UC(0x0409) // Љ -#define CY_EM UC(0x041c) // М rus ukr bul -#define CY_EN UC(0x041d) // Н rus ukr bul -#define CY_NJE UC(0x040a) // Њ -#define CY_O UC(0x041e) // О rus ukr bul -#define CY_PE UC(0x041f) // П rus ukr bul -#define CY_ER UC(0x0420) // Р rus ukr bul -#define CY_ES UC(0x0421) // С rus ukr bul -#define CY_TE UC(0x0422) // Т rus ukr bul -#define CY_TSHE UC(0x040b) // Ћ -#define CY_KJE UC(0x040c) // Ќ -#define CY_U UC(0x0423) // У rus ukr bul -#define CY_SRT_U UC(0x040e) // Ў -#define CY_EF UC(0x0424) // Ф rus ukr bul -#define CY_HA UC(0x0425) // Х rus bul -#define CY_TSE UC(0x0426) // Ц rus ukr bul -#define CY_CHE UC(0x0427) // Ч rus ukr bul -#define CY_DZHE UC(0x040f) // Џ -#define CY_SHA UC(0x0428) // Ш rus ukr bul -#define CY_SHCHA UC(0x0429) // Щ rus ukr bul -#define CY_HSIGN UC(0x042a) // Ъ rus bul -#define CY_YERU UC(0x042b) // Ы rus -#define CY_SSIGN UC(0x042c) // Ь rus ukr bul -#define CY_E UC(0x042d) // Э rus -#define CY_YU UC(0x042e) // Ю rus ukr bul -#define CY_YA UC(0x042f) // Я rus ukr bul -// Important Cyrillic non-Slavic letters -#define CY_PALOCHKA UC(0x04c0) // Ӏ -#define CY_SCHWA UC(0x04d8) // Ә -#define CY_GHE_S UC(0x0492) // Ғ -#define CY_ZE_D UC(0x0498) // Ҙ -#define CY_ES_D UC(0x04aa) // Ҫ -#define CY_BR_KA UC(0x04a0) // Ҡ -#define CY_ZHE_D UC(0x0496) // Җ -#define CY_KA_D UC(0x049a) // Қ -#define CY_EN_D UC(0x04a2) // Ң -#define CY_ENGHE UC(0x04a4) // Ҥ -#define CY_BRD_O UC(0x04e8) // Ө -#define CY_STR_U UC(0x04ae) // Ү -#define CY_S_U_S UC(0x04b0) // Ұ -#define CY_SHHA UC(0x04ba) // Һ -#define CY_HA_D UC(0x04b2) // Ҳ - - -// Small -#define CY_a UC(0x0430) // a rus ukr bul -#define CY_be UC(0x0431) // б rus ukr bul -#define CY_ve UC(0x0432) // в rus ukr bul -#define CY_ghe UC(0x0433) // г rus ukr bul -#define CY_gheup UC(0x0491) // ґ ukr -#define CY_de UC(0x0434) // д rus ukr bul -#define CY_dje UC(0x0452) // ђ -#define CY_gje UC(0x0453) // ѓ -#define CY_ie UC(0x0435) // е rus ukr bul -#define CY_io UC(0x0451) // ё rus -#define CY_uie UC(0x0454) // є ukr -#define CY_zhe UC(0x0436) // ж rus ukr bul -#define CY_ze UC(0x0437) // з rus ukr bul -#define CY_dze UC(0x0455) // ѕ -#define CY_i UC(0x0438) // и rus ukr bul -#define CY_b_u_i UC(0x0456) // і ukr -#define CY_yi UC(0x0457) // ї ukr -#define CY_srt_i UC(0x0439) // й rus ukr bul -#define CY_je UC(0x0458) // ј -#define CY_ka UC(0x043a) // к rus ukr bul -#define CY_el UC(0x043b) // л rus ukr bul -#define CY_lje UC(0x0459) // љ -#define CY_em UC(0x043c) // м rus ukr bul -#define CY_en UC(0x043d) // н rus ukr bul -#define CY_nje UC(0x045a) // њ -#define CY_o UC(0x043e) // о rus ukr bul -#define CY_pe UC(0x043f) // п rus ukr bul -#define CY_er UC(0x0440) // р rus ukr bul -#define CY_es UC(0x0441) // с rus ukr bul -#define CY_te UC(0x0442) // т rus ukr bul -#define CY_tshe UC(0x045b) // ћ -#define CY_kje UC(0x045c) // ќ -#define CY_u UC(0x0443) // у rus ukr bul -#define CY_srt_u UC(0x045e) // ў -#define CY_ef UC(0x0444) // ф rus ukr bul -#define CY_ha UC(0x0445) // х rus ukr bul -#define CY_tse UC(0x0446) // ц rus ukr bul -#define CY_che UC(0x0447) // ч rus ukr bul -#define CY_dzhe UC(0x045f) // џ -#define CY_sha UC(0x0448) // ш rus ukr bul -#define CY_shcha UC(0x0449) // щ rus ukr bul -#define CY_hsign UC(0x044a) // ъ rus bul -#define CY_yeru UC(0x044b) // ы rus -#define CY_ssign UC(0x044c) // ь rus ukr bul -#define CY_e UC(0x044d) // э rus -#define CY_yu UC(0x044e) // ю rus ukr bul -#define CY_ya UC(0x044f) // я rus ukr bul -// Important Cyrillic non-Slavic letters -#define CY_palochka UC(0x04cf) // ӏ -#define CY_schwa UC(0x04d9) // ә -#define CY_ghe_s UC(0x0493) // ғ -#define CY_ze_d UC(0x0499) // ҙ -#define CY_es_d UC(0x04ab) // ҫ -#define CY_br_ka UC(0x04a1) // ҡ -#define CY_zhe_d UC(0x0497) // җ -#define CY_ka_d UC(0x049b) // қ -#define CY_en_d UC(0x04a3) // ң -#define CY_enghe UC(0x04a5) // ҥ -#define CY_brd_o UC(0x04e9) // ө -#define CY_str_u UC(0x04af) // ү -#define CY_s_u_s UC(0x04b1) // ұ -#define CY_shha UC(0x04bb) // һ -#define CY_ha_d UC(0x04b3) // ҳ - - -// Extra -#define CY_slr_ve UC(0x1c80) // ᲀ CYRILLIC SMALL LETTER ROUNDED VE -#define CY_ll_de UC(0x1c81) // ᲁ CYRILLIC SMALL LETTER LONG-LEGGED DE -#define CY_ZEMLYA UC(0xa640) // Ꙁ CYRILLIC CAPITAL LETTER ZEMLYA -#define CY_zemlya UC(0xa641) // ꙁ CYRILLIC SMALL LETTER ZEMLYA -#define CY_RV_DZE UC(0xa644) // Ꙅ CYRILLIC CAPITAL LETTER REVERSED DZE -#define CY_rv_DZE UC(0xa645) // ꙅ CYRILLIC SMALL LETTER REVERSED DZE -#define CY_slw_es UC(0x1c83) // ᲃ CYRILLIC SMALL LETTER WIDE ES -#define CY_st_te UC(0x1c84) // ᲄ CYRILLIC SMALL LETTER TALL TE -#define CY_3l_te UC(0x1c85) // ᲅ CYRILLIC SMALL LETTER THREE-LEGGED TE -#define CY_thsign UC(0x1c86) // ᲆ CYRILLIC SMALL LETTER TALL HARD SIGN -#define CY_YERUBY UC(0xa650) // Ꙑ CYRILLIC CAPITAL LETTER YERU WITH BACK YER -#define CY_yeruby UC(0xa651) // ꙑ CYRILLIC SMALL LETTER YERU WITH BACK YER -#define CY_RUBLE UC(0x20bd) // ₽ -#define CY_NUMERO UC(0x2116) // № - -// The letters Zje and Sje are made for other letters and accent marks - -#endif diff --git a/quantum/keymap_extras/keymap_russian.h b/quantum/keymap_extras/keymap_russian.h new file mode 100644 index 000000000..efb63a5cc --- /dev/null +++ b/quantum/keymap_extras/keymap_russian.h @@ -0,0 +1,79 @@ +#ifndef KEYMAP_RUSSIAN_H +#define KEYMAP_RUSSIAN_H + +#include "keymap.h" + +// rename ruble and numero in keymap_cyrillic.c + +// Normal Chracters // reg SHIFT +#define RU_A KC_F // а and А +#define RU_BE KC_COMM // б and Б +#define RU_VE KC_D // в and В +#define RU_GHE KC_U // г and Г +#define RU_DE KC_L // д and Д +#define RU_IE KC_T // е and Е +#define RU_IO KC_GRV // ё and Ё +#define RU_ZHE KC_SCLN // ж and Ж +#define RU_ZE KC_P // з and З +#define RU_I KC_B // и and И +#define RU_SRT_I KC_Q // й and Й +#define RU_KA KC_R // к and К +#define RU_EL KC_K // л and Л +#define RU_EM KC_V // м and М +#define RU_EN KC_Y // н and Н +#define RU_O KC_J // о and О +#define RU_PE KC_G // п and П +#define RU_ER KC_H // р and Р +#define RU_ES KC_C // с and С +#define RU_TE KC_N // т and Т +#define RU_U KC_E // у and У +#define RU_EF KC_A // ф and Ф +#define RU_HA KC_LBRC // х and Х +#define RU_TSE KC_W // ц and Ц +#define RU_CHE KC_X // ч and Ч +#define RU_SHA KC_I // ш and Ш +#define RU_SHCHA KC_O // щ and Щ +#define RU_HSIGN KC_RBRC // ъ and Ъ +#define RU_YERU KC_S // ы and Ы +#define RU_SSIGN KC_M // ь and Ь +#define RU_E KC_QUOT // э and Э +#define RU_YU KC_DOT // ю and Ю +#define RU_YA KC_Z // я and Я + +#define RU_1 KC_1 // 1 and ! +#define RU_2 KC_2 // 2 and " +#define RU_3 KC_3 // 3 and № +#define RU_4 KC_4 // 4 and ; +#define RU_5 KC_5 // 5 and % +#define RU_6 KC_6 // 6 and : +#define RU_7 KC_7 // 7 and ? +#define RU_8 KC_8 // 8 and * +#define RU_9 KC_9 // 9 and ( +#define RU_0 KC_0 // 0 and ) + +#define RU_MINS KC_MINS // - and _ +#define RU_EQL KC_EQL // = and + +#define RU_BSLS KC_BSLS // \ and / +#define RU_DOT KC_SLSH // . and , + +// Shifted Chracters +#define RU_EXLM LSFT(RU_1) // ! +#define RU_DQUT LSFT(RU_2) // " +#define RU_NMRO LSFT(RU_3) // № +#define RU_SCLN LSFT(RU_4) // ; +#define RU_PERC LSFT(RU_5) // % +#define RU_COLN LSFT(RU_6) // : +#define RU_QUES LSFT(RU_7) // ? +#define RU_ASTR LSFT(RU_8) // * +#define RU_LPRN LSFT(RU_9) // ( +#define RU_RPRN LSFT(RU_0) // ) + +#define RU_UNDR LSFT(RU_MINS) // _ +#define RU_PLUS LSFT(RU_EQL) // + +#define RU_SLSH LSFT(RU_BSLS) // / +#define RU_COMM LSFT(RU_DOT) // , + +// Alt Gr-ed characters +#define RU_RUBL RALT(RU_8) // ₽ + +#endif diff --git a/quantum/keymap_extras/keymap_unicode_cyrillic.h b/quantum/keymap_extras/keymap_unicode_cyrillic.h new file mode 100644 index 000000000..a40626d91 --- /dev/null +++ b/quantum/keymap_extras/keymap_unicode_cyrillic.h @@ -0,0 +1,163 @@ +#ifndef KEYMAP_CYRILLIC_H +#define KEYMAP_CYRILLIC_H + +#include "keymap.h" + +/* + * This is based off of + * https://en.wikipedia.org/wiki/Cyrillic_script + * + * Unicode is iffy, a software implementation is preferred + */ + +// Capital Char russian/ukrainian/bulgarian +#define CY_A UC(0x0410) // А rus ukr bul +#define CY_BE UC(0x0411) // Б rus ukr bul +#define CY_VE UC(0x0412) // В rus ukr bul +#define CY_GHE UC(0x0413) // Г rus ukr bul +#define CY_GHEUP UC(0x0490) // Ґ ukr +#define CY_DE UC(0x0414) // Д rus ukr bul +#define CY_DJE UC(0x0402) // Ђ +#define CY_GJE UC(0x0403) // Ѓ +#define CY_IE UC(0x0415) // Е rus ukr bul +#define CY_IO UC(0x0401) // Ё rus +#define CY_UIE UC(0x0404) // Є ukr +#define CY_ZHE UC(0x0416) // Ж rus ukr bul +#define CY_ZE UC(0x0417) // З rus ukr bul +#define CY_DZE UC(0x0405) // Ѕ +#define CY_I UC(0x0418) // И rus ukr bul +#define CY_B_U_I UC(0x0406) // І ukr +#define CY_YI UC(0x0407) // Ї ukr +#define CY_SRT_I UC(0x0419) // Й rus ukr bul +#define CY_JE UC(0x0408) // Ј +#define CY_KA UC(0x041a) // К rus ukr bul +#define CY_EL UC(0x041b) // Л rus ukr bul +#define CY_LJE UC(0x0409) // Љ +#define CY_EM UC(0x041c) // М rus ukr bul +#define CY_EN UC(0x041d) // Н rus ukr bul +#define CY_NJE UC(0x040a) // Њ +#define CY_O UC(0x041e) // О rus ukr bul +#define CY_PE UC(0x041f) // П rus ukr bul +#define CY_ER UC(0x0420) // Р rus ukr bul +#define CY_ES UC(0x0421) // С rus ukr bul +#define CY_TE UC(0x0422) // Т rus ukr bul +#define CY_TSHE UC(0x040b) // Ћ +#define CY_KJE UC(0x040c) // Ќ +#define CY_U UC(0x0423) // У rus ukr bul +#define CY_SRT_U UC(0x040e) // Ў +#define CY_EF UC(0x0424) // Ф rus ukr bul +#define CY_HA UC(0x0425) // Х rus bul +#define CY_TSE UC(0x0426) // Ц rus ukr bul +#define CY_CHE UC(0x0427) // Ч rus ukr bul +#define CY_DZHE UC(0x040f) // Џ +#define CY_SHA UC(0x0428) // Ш rus ukr bul +#define CY_SHCHA UC(0x0429) // Щ rus ukr bul +#define CY_HSIGN UC(0x042a) // Ъ rus bul +#define CY_YERU UC(0x042b) // Ы rus +#define CY_SSIGN UC(0x042c) // Ь rus ukr bul +#define CY_E UC(0x042d) // Э rus +#define CY_YU UC(0x042e) // Ю rus ukr bul +#define CY_YA UC(0x042f) // Я rus ukr bul +// Important Cyrillic non-Slavic letters +#define CY_PALOCHKA UC(0x04c0) // Ӏ +#define CY_SCHWA UC(0x04d8) // Ә +#define CY_GHE_S UC(0x0492) // Ғ +#define CY_ZE_D UC(0x0498) // Ҙ +#define CY_ES_D UC(0x04aa) // Ҫ +#define CY_BR_KA UC(0x04a0) // Ҡ +#define CY_ZHE_D UC(0x0496) // Җ +#define CY_KA_D UC(0x049a) // Қ +#define CY_EN_D UC(0x04a2) // Ң +#define CY_ENGHE UC(0x04a4) // Ҥ +#define CY_BRD_O UC(0x04e8) // Ө +#define CY_STR_U UC(0x04ae) // Ү +#define CY_S_U_S UC(0x04b0) // Ұ +#define CY_SHHA UC(0x04ba) // Һ +#define CY_HA_D UC(0x04b2) // Ҳ + + +// Small +#define CY_a UC(0x0430) // a rus ukr bul +#define CY_be UC(0x0431) // б rus ukr bul +#define CY_ve UC(0x0432) // в rus ukr bul +#define CY_ghe UC(0x0433) // г rus ukr bul +#define CY_gheup UC(0x0491) // ґ ukr +#define CY_de UC(0x0434) // д rus ukr bul +#define CY_dje UC(0x0452) // ђ +#define CY_gje UC(0x0453) // ѓ +#define CY_ie UC(0x0435) // е rus ukr bul +#define CY_io UC(0x0451) // ё rus +#define CY_uie UC(0x0454) // є ukr +#define CY_zhe UC(0x0436) // ж rus ukr bul +#define CY_ze UC(0x0437) // з rus ukr bul +#define CY_dze UC(0x0455) // ѕ +#define CY_i UC(0x0438) // и rus ukr bul +#define CY_b_u_i UC(0x0456) // і ukr +#define CY_yi UC(0x0457) // ї ukr +#define CY_srt_i UC(0x0439) // й rus ukr bul +#define CY_je UC(0x0458) // ј +#define CY_ka UC(0x043a) // к rus ukr bul +#define CY_el UC(0x043b) // л rus ukr bul +#define CY_lje UC(0x0459) // љ +#define CY_em UC(0x043c) // м rus ukr bul +#define CY_en UC(0x043d) // н rus ukr bul +#define CY_nje UC(0x045a) // њ +#define CY_o UC(0x043e) // о rus ukr bul +#define CY_pe UC(0x043f) // п rus ukr bul +#define CY_er UC(0x0440) // р rus ukr bul +#define CY_es UC(0x0441) // с rus ukr bul +#define CY_te UC(0x0442) // т rus ukr bul +#define CY_tshe UC(0x045b) // ћ +#define CY_kje UC(0x045c) // ќ +#define CY_u UC(0x0443) // у rus ukr bul +#define CY_srt_u UC(0x045e) // ў +#define CY_ef UC(0x0444) // ф rus ukr bul +#define CY_ha UC(0x0445) // х rus ukr bul +#define CY_tse UC(0x0446) // ц rus ukr bul +#define CY_che UC(0x0447) // ч rus ukr bul +#define CY_dzhe UC(0x045f) // џ +#define CY_sha UC(0x0448) // ш rus ukr bul +#define CY_shcha UC(0x0449) // щ rus ukr bul +#define CY_hsign UC(0x044a) // ъ rus bul +#define CY_yeru UC(0x044b) // ы rus +#define CY_ssign UC(0x044c) // ь rus ukr bul +#define CY_e UC(0x044d) // э rus +#define CY_yu UC(0x044e) // ю rus ukr bul +#define CY_ya UC(0x044f) // я rus ukr bul +// Important Cyrillic non-Slavic letters +#define CY_palochka UC(0x04cf) // ӏ +#define CY_schwa UC(0x04d9) // ә +#define CY_ghe_s UC(0x0493) // ғ +#define CY_ze_d UC(0x0499) // ҙ +#define CY_es_d UC(0x04ab) // ҫ +#define CY_br_ka UC(0x04a1) // ҡ +#define CY_zhe_d UC(0x0497) // җ +#define CY_ka_d UC(0x049b) // қ +#define CY_en_d UC(0x04a3) // ң +#define CY_enghe UC(0x04a5) // ҥ +#define CY_brd_o UC(0x04e9) // ө +#define CY_str_u UC(0x04af) // ү +#define CY_s_u_s UC(0x04b1) // ұ +#define CY_shha UC(0x04bb) // һ +#define CY_ha_d UC(0x04b3) // ҳ + + +// Extra +#define CY_slr_ve UC(0x1c80) // ᲀ CYRILLIC SMALL LETTER ROUNDED VE +#define CY_ll_de UC(0x1c81) // ᲁ CYRILLIC SMALL LETTER LONG-LEGGED DE +#define CY_ZEMLYA UC(0xa640) // Ꙁ CYRILLIC CAPITAL LETTER ZEMLYA +#define CY_zemlya UC(0xa641) // ꙁ CYRILLIC SMALL LETTER ZEMLYA +#define CY_RV_DZE UC(0xa644) // Ꙅ CYRILLIC CAPITAL LETTER REVERSED DZE +#define CY_rv_DZE UC(0xa645) // ꙅ CYRILLIC SMALL LETTER REVERSED DZE +#define CY_slw_es UC(0x1c83) // ᲃ CYRILLIC SMALL LETTER WIDE ES +#define CY_st_te UC(0x1c84) // ᲄ CYRILLIC SMALL LETTER TALL TE +#define CY_3l_te UC(0x1c85) // ᲅ CYRILLIC SMALL LETTER THREE-LEGGED TE +#define CY_thsign UC(0x1c86) // ᲆ CYRILLIC SMALL LETTER TALL HARD SIGN +#define CY_YERUBY UC(0xa650) // Ꙑ CYRILLIC CAPITAL LETTER YERU WITH BACK YER +#define CY_yeruby UC(0xa651) // ꙑ CYRILLIC SMALL LETTER YERU WITH BACK YER +#define CY_RUBL UC(0x20bd) // ₽ +#define CY_NMRO UC(0x2116) // № + +// The letters Zje and Sje are made for other letters and accent marks + +#endif -- cgit v1.3.1 From 2a0121a78643b1dc774d82352f8c9e246010803e Mon Sep 17 00:00:00 2001 From: kuel Date: Sun, 7 Aug 2016 11:07:38 -0500 Subject: Removed unnecessary comment --- quantum/keymap_extras/keymap_russian.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_russian.h b/quantum/keymap_extras/keymap_russian.h index efb63a5cc..237e9abde 100644 --- a/quantum/keymap_extras/keymap_russian.h +++ b/quantum/keymap_extras/keymap_russian.h @@ -3,8 +3,6 @@ #include "keymap.h" -// rename ruble and numero in keymap_cyrillic.c - // Normal Chracters // reg SHIFT #define RU_A KC_F // а and А #define RU_BE KC_COMM // б and Б -- cgit v1.3.1 From e692ebf86a962e90c51302e7b17a953ea2858f79 Mon Sep 17 00:00:00 2001 From: shela Date: Fri, 12 Aug 2016 20:38:26 +0900 Subject: fix typo --- quantum/keymap.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap.h b/quantum/keymap.h index a15865183..f2d94d75c 100644 --- a/quantum/keymap.h +++ b/quantum/keymap.h @@ -156,16 +156,16 @@ enum quantum_keycodes { BL_INC, BL_TOGG, BL_STEP, - - // RGB functionality - RGB_TOG, - RGB_MOD, - RGB_HUI, - RGB_HUD, - RGB_SAI, - RGB_SAD, - RGB_VAI, - RGB_VAD, + + // RGB functionality + RGB_TOG, + RGB_MOD, + RGB_HUI, + RGB_HUD, + RGB_SAI, + RGB_SAD, + RGB_VAI, + RGB_VAD, // Left shift, open paren KC_LSPO, @@ -309,7 +309,7 @@ enum quantum_keycodes { #define OSL(layer) (layer | QK_ONE_SHOT_LAYER) // One-shot mod -#define OSM(layer) (layer | QK_ONE_SHOT_MOD) +#define OSM(mod) (mod | QK_ONE_SHOT_MOD) // M-od, T-ap - 256 keycode max #define MT(mod, kc) (kc | QK_MOD_TAP | ((mod & 0xF) << 8)) -- cgit v1.3.1 From 8bdf745909bc2581491acce11225f56a85bc8f24 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Aug 2016 10:33:47 +0200 Subject: process_unicode: Fix set_unicode_input_mode() In the header, this was defined as `set_unicode_input_mode`, but the implementation had `set_unicode_mode` for a name. Changed the implementation to match the header. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index ad5d7f86b..3fcac15ce 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -13,7 +13,7 @@ uint16_t hex_to_keycode(uint8_t hex) } } -void set_unicode_mode(uint8_t os_target) +void set_unicode_input_mode(uint8_t os_target) { input_mode = os_target; } -- cgit v1.3.1 From 63e5782d2cdf0ee282ad434c773463d9da9db6b3 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Aug 2016 10:43:22 +0200 Subject: process_unicode: Small refactor & linux fix This moves the unicode input start / end sequences into their own functions, so keymaps and other functionality can build on it too. At the same time, it changes how the Linux variant works, to match reality: CTRL+SHIFT must be unregistered too, and we close the thing with a Space instead. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 76 ++++++++++++++++++------------- quantum/process_keycode/process_unicode.h | 3 ++ 2 files changed, 48 insertions(+), 31 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index 3fcac15ce..55e47f179 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -18,40 +18,54 @@ void set_unicode_input_mode(uint8_t os_target) input_mode = os_target; } +void unicode_input_start (void) { + switch(input_mode) { + case UC_OSX: + register_code(KC_LALT); + break; + case UC_LNX: + register_code(KC_LCTL); + register_code(KC_LSFT); + register_code(KC_U); + unregister_code(KC_U); + unregister_code(KC_LSFT); + unregister_code(KC_LCTL); + break; + case UC_WIN: + register_code(KC_LALT); + register_code(KC_PPLS); + unregister_code(KC_PPLS); + break; + } +} + +void unicode_input_finish (void) { + switch(input_mode) { + case UC_OSX: + case UC_WIN: + unregister_code(KC_LALT); + break; + case UC_LNX: + register_code(KC_SPC); + unregister_code(KC_SPC); + break; + } +} + +void register_hex(uint16_t hex) { + for(int i = 3; i >= 0; i--) { + uint8_t digit = ((hex >> (i*4)) & 0xF); + register_code(hex_to_keycode(digit)); + unregister_code(hex_to_keycode(digit)); + } +} + bool process_unicode(uint16_t keycode, keyrecord_t *record) { if (keycode > QK_UNICODE && record->event.pressed) { uint16_t unicode = keycode & 0x7FFF; - switch(input_mode) { - case UC_OSX: - register_code(KC_LALT); - break; - case UC_LNX: - register_code(KC_LCTL); - register_code(KC_LSFT); - register_code(KC_U); - unregister_code(KC_U); - break; - case UC_WIN: - register_code(KC_LALT); - register_code(KC_PPLS); - unregister_code(KC_PPLS); - break; - } - for(int i = 3; i >= 0; i--) { - uint8_t digit = ((unicode >> (i*4)) & 0xF); - register_code(hex_to_keycode(digit)); - unregister_code(hex_to_keycode(digit)); - } - switch(input_mode) { - case UC_OSX: - case UC_WIN: - unregister_code(KC_LALT); - break; - case UC_LNX: - unregister_code(KC_LCTL); - unregister_code(KC_LSFT); - break; - } + unicode_input_start(); + register_hex(unicode); + unicode_input_finish(); } return true; } \ No newline at end of file diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index ca17f8f66..f719a1226 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -9,6 +9,9 @@ #define UC_BSD 3 void set_unicode_input_mode(uint8_t os_target); +void unicode_input_start(void); +void unicode_input_finish(void); +void register_hex(uint16_t hex); bool process_unicode(uint16_t keycode, keyrecord_t *record); -- cgit v1.3.1 From fa06a163607e8c6c4bd0968c2de96a9a298b777c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Aug 2016 10:46:38 +0200 Subject: process_unicode: Add a way to enter unicode symbols by name The purpose of this change is to allow keymaps to specify a dictionary of unicode symbol name to code mappings, and let the person at the keyboard enter unicode symbols by name. This is done by having a way to trigger unicode symbol input mode, when all keys are cached until Esc, Enter or Space are pressed. Once that happens, we try to look up the symbol from our lookup table. If found, we erase back, and type the unicode magic in to get that symbol. If not found, we still erase back, start unicode input mode, and replay what the user typed in. Signed-off-by: Gergely Nagy --- Makefile | 7 ++- quantum/process_keycode/process_unicode.c | 93 ++++++++++++++++++++++++++++++- quantum/process_keycode/process_unicode.h | 29 +++++++++- 3 files changed, 126 insertions(+), 3 deletions(-) (limited to 'quantum') diff --git a/Makefile b/Makefile index 053c8532a..693edc9f0 100644 --- a/Makefile +++ b/Makefile @@ -198,6 +198,11 @@ ifeq ($(strip $(AUDIO_ENABLE)), yes) SRC += $(QUANTUM_DIR)/audio/luts.c endif +ifeq ($(strip $(UCIS_ENABLE)), yes) + OPT_DEFS += -DUCIS_ENABLE + UNICODE_ENABLE = yes +endif + ifeq ($(strip $(UNICODE_ENABLE)), yes) OPT_DEFS += -DUNICODE_ENABLE SRC += $(QUANTUM_DIR)/process_keycode/process_unicode.c @@ -273,4 +278,4 @@ BUILD_DATE := $(shell date +"%Y-%m-%d-%H:%M:%S") OPT_DEFS += -DQMK_KEYBOARD=\"$(KEYBOARD)\" -DQMK_KEYMAP=\"$(KEYMAP)\" $(shell echo '#define QMK_VERSION "$(GIT_VERSION)"' > $(QUANTUM_PATH)/version.h) -$(shell echo '#define QMK_BUILDDATE "$(BUILD_DATE)"' >> $(QUANTUM_PATH)/version.h) \ No newline at end of file +$(shell echo '#define QMK_BUILDDATE "$(BUILD_DATE)"' >> $(QUANTUM_PATH)/version.h) diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index 55e47f179..8a6509300 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -68,4 +68,95 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record) { unicode_input_finish(); } return true; -} \ No newline at end of file +} + +#ifdef UCIS_ENABLE +void qk_ucis_start(void) { + qk_ucis_state.count = 0; + qk_ucis_state.in_progress = true; + + unicode_input_start(); + register_hex(0x2328); + unicode_input_finish(); +} + +static bool is_uni_seq(char *seq) { + uint8_t i; + + for (i = 0; seq[i]; i++) { + uint16_t code; + if (('1' <= seq[i]) && (seq[i] <= '0')) + code = seq[i] - '1' + KC_1; + else + code = seq[i] - 'a' + KC_A; + + if (i > qk_ucis_state.count || qk_ucis_state.codes[i] != code) + return false; + } + + return (qk_ucis_state.codes[i] == KC_ENT || + qk_ucis_state.codes[i] == KC_SPC); +} + +__attribute__((weak)) +void qk_ucis_symbol_fallback (void) { + for (uint8_t i = 0; i < qk_ucis_state.count - 1; i++) { + uint8_t code = qk_ucis_state.codes[i]; + register_code(code); + unregister_code(code); + } +} + +bool process_record_ucis (uint16_t keycode, keyrecord_t *record) { + uint8_t i; + + if (!qk_ucis_state.in_progress || !record->event.pressed) + return true; + + qk_ucis_state.codes[qk_ucis_state.count] = keycode; + qk_ucis_state.count++; + + if (keycode == KC_BSPC) { + if (qk_ucis_state.count >= 2) { + qk_ucis_state.count -= 2; + return true; + } else { + qk_ucis_state.count--; + return false; + } + } + + if (keycode == KC_ENT || keycode == KC_SPC || keycode == KC_ESC) { + bool symbol_found = false; + + for (i = qk_ucis_state.count; i > 0; i--) { + register_code (KC_BSPC); + unregister_code (KC_BSPC); + } + + if (keycode == KC_ESC) { + qk_ucis_state.in_progress = false; + return false; + } + + unicode_input_start(); + for (i = 0; ucis_symbol_table[i].symbol; i++) { + if (is_uni_seq (ucis_symbol_table[i].symbol)) { + symbol_found = true; + for (uint8_t j = 0; ucis_symbol_table[i].codes[j]; j++) { + register_hex(ucis_symbol_table[i].codes[j]); + } + break; + } + } + if (!symbol_found) { + qk_ucis_symbol_fallback(); + } + unicode_input_finish(); + + qk_ucis_state.in_progress = false; + return false; + } + return true; +} +#endif diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index f719a1226..372ea2f0d 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -15,6 +15,33 @@ void register_hex(uint16_t hex); bool process_unicode(uint16_t keycode, keyrecord_t *record); +#ifdef UCIS_ENABLE +#ifndef UCIS_MAX_SYMBOL_LENGTH +#define UCIS_MAX_SYMBOL_LENGTH 32 +#endif + +typedef struct { + char *symbol; + uint16_t codes[4]; +} qk_ucis_symbol_t; + +struct { + uint8_t count; + uint16_t codes[UCIS_MAX_SYMBOL_LENGTH]; + bool in_progress:1; +} qk_ucis_state; + +#define UCIS_TABLE(...) {__VA_ARGS__, {NULL, {}}} +#define UCIS_SYM(name, ...) {name, {__VA_ARGS__, 0}} + +extern const qk_ucis_symbol_t ucis_symbol_table[]; + +void qk_ucis_start(void); +void qk_ucis_symbol_fallback (void); +bool process_record_ucis (uint16_t keycode, keyrecord_t *record); + +#endif + #define UC_BSPC UC(0x0008) #define UC_SPC UC(0x0020) @@ -122,4 +149,4 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record); #define UC_TILD UC(0x007E) #define UC_DEL UC(0x007F) -#endif \ No newline at end of file +#endif -- cgit v1.3.1 From 0b6861827faea747345ea38202d64c8004ab128c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Aug 2016 11:11:22 +0200 Subject: process_unicode: Handle too long UCIS symbol names If the symbol name being entered is longer than the max, stop recording it, and stop processing keycodes apart from the ones that can delete, finish or cancel the sequence. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index 8a6509300..851a96eaa 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -110,7 +110,15 @@ void qk_ucis_symbol_fallback (void) { bool process_record_ucis (uint16_t keycode, keyrecord_t *record) { uint8_t i; - if (!qk_ucis_state.in_progress || !record->event.pressed) + if (!qk_ucis_state.in_progress) + return true; + + if (qk_ucis_state.count >= UCIS_MAX_SYMBOL_LENGTH && + !(keycode == KC_BSPC || keycode == KC_ESC || keycode == KC_SPC || keycode == KC_ENT)) { + return false; + } + + if (!record->event.pressed) return true; qk_ucis_state.codes[qk_ucis_state.count] = keycode; -- cgit v1.3.1 From 857aa5bef6a74f8785a7039feea5286c07bf7067 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Aug 2016 11:14:42 +0200 Subject: process_unicode: Call process_ucis() automatically If UCIS is enabled, call process_ucis() automatically from process_record_quantum(). Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 2 +- quantum/process_keycode/process_unicode.h | 2 +- quantum/quantum.c | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index 851a96eaa..d71434411 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -107,7 +107,7 @@ void qk_ucis_symbol_fallback (void) { } } -bool process_record_ucis (uint16_t keycode, keyrecord_t *record) { +bool process_ucis (uint16_t keycode, keyrecord_t *record) { uint8_t i; if (!qk_ucis_state.in_progress) diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index 372ea2f0d..c5005897e 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -38,7 +38,7 @@ extern const qk_ucis_symbol_t ucis_symbol_table[]; void qk_ucis_start(void); void qk_ucis_symbol_fallback (void); -bool process_record_ucis (uint16_t keycode, keyrecord_t *record); +bool process_ucis (uint16_t keycode, keyrecord_t *record); #endif diff --git a/quantum/quantum.c b/quantum/quantum.c index bc2da510f..a4c5c2ddb 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -86,6 +86,9 @@ bool process_record_quantum(keyrecord_t *record) { #endif #ifdef UNICODE_ENABLE process_unicode(keycode, record) && + #endif + #ifdef UCIS_ENABLE + process_ucis(keycode, record) && #endif true)) { return false; -- cgit v1.3.1 From 234dd276cf03be6fd6961473e9d9c8f35deec682 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Aug 2016 10:37:51 +0200 Subject: process_unicode: Make the startup overridable Extract out the part of `qk_ucis_start` that inputs the placeholder symbol, and make it weak, so it can be overridden. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 5 +++++ quantum/process_keycode/process_unicode.h | 1 + 2 files changed, 6 insertions(+) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index d71434411..c474483e7 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -75,6 +75,11 @@ void qk_ucis_start(void) { qk_ucis_state.count = 0; qk_ucis_state.in_progress = true; + qk_ucis_start_user(); +} + +__attribute__((weak)) +void qk_ucis_start_user(void) { unicode_input_start(); register_hex(0x2328); unicode_input_finish(); diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index c5005897e..75607e40e 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -37,6 +37,7 @@ struct { extern const qk_ucis_symbol_t ucis_symbol_table[]; void qk_ucis_start(void); +void qk_ucis_start_user(void); void qk_ucis_symbol_fallback (void); bool process_ucis (uint16_t keycode, keyrecord_t *record); -- cgit v1.3.1 From a312cbf712764277e0dbbbb99410c2f6fc6c7484 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Aug 2016 14:34:52 +0200 Subject: process_unicode: Use uint32_t for UCIS purposes Use a single uint32_t to store the unicode of a symbol, instead of an array of uint16_ts. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 12 +++++++++--- quantum/process_keycode/process_unicode.h | 7 ++++--- 2 files changed, 13 insertions(+), 6 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index c474483e7..698cc3c02 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -60,6 +60,14 @@ void register_hex(uint16_t hex) { } } +void register_hex32(uint32_t hex) { + for(int i = 7; i >= 0; i--) { + uint8_t digit = ((hex >> (i*8)) & 0xF); + register_code(hex_to_keycode(digit)); + unregister_code(hex_to_keycode(digit)); + } +} + bool process_unicode(uint16_t keycode, keyrecord_t *record) { if (keycode > QK_UNICODE && record->event.pressed) { uint16_t unicode = keycode & 0x7FFF; @@ -156,9 +164,7 @@ bool process_ucis (uint16_t keycode, keyrecord_t *record) { for (i = 0; ucis_symbol_table[i].symbol; i++) { if (is_uni_seq (ucis_symbol_table[i].symbol)) { symbol_found = true; - for (uint8_t j = 0; ucis_symbol_table[i].codes[j]; j++) { - register_hex(ucis_symbol_table[i].codes[j]); - } + register_hex32(ucis_symbol_table[i].code); break; } } diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index 75607e40e..dd6dd7138 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -12,6 +12,7 @@ void set_unicode_input_mode(uint8_t os_target); void unicode_input_start(void); void unicode_input_finish(void); void register_hex(uint16_t hex); +void register_hex32(uint32_t hex); bool process_unicode(uint16_t keycode, keyrecord_t *record); @@ -22,7 +23,7 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record); typedef struct { char *symbol; - uint16_t codes[4]; + uint32_t code; } qk_ucis_symbol_t; struct { @@ -31,8 +32,8 @@ struct { bool in_progress:1; } qk_ucis_state; -#define UCIS_TABLE(...) {__VA_ARGS__, {NULL, {}}} -#define UCIS_SYM(name, ...) {name, {__VA_ARGS__, 0}} +#define UCIS_TABLE(...) {__VA_ARGS__, {NULL, 0}} +#define UCIS_SYM(name, code) {name, code} extern const qk_ucis_symbol_t ucis_symbol_table[]; -- cgit v1.3.1 From 43d08629cf275d0b32281ffe8785258fff226b49 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 15 Aug 2016 10:02:05 +0200 Subject: process_unicode: Replace register_hex32 It turns out that register_hex32 did not work reliably, and some systems only allow 7 chars after the unicode magic sequence, while others allow 8. To remedy the situation, store the codes as strings, and type those in instead of doing bit shifting magic. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 37 +++++++++++++++++++++++-------- quantum/process_keycode/process_unicode.h | 8 +++---- 2 files changed, 32 insertions(+), 13 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index 698cc3c02..d8a0f667c 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -60,14 +60,6 @@ void register_hex(uint16_t hex) { } } -void register_hex32(uint32_t hex) { - for(int i = 7; i >= 0; i--) { - uint8_t digit = ((hex >> (i*8)) & 0xF); - register_code(hex_to_keycode(digit)); - unregister_code(hex_to_keycode(digit)); - } -} - bool process_unicode(uint16_t keycode, keyrecord_t *record) { if (keycode > QK_UNICODE && record->event.pressed) { uint16_t unicode = keycode & 0x7FFF; @@ -120,6 +112,33 @@ void qk_ucis_symbol_fallback (void) { } } +void register_ucis(const char *hex) { + for(int i = 0; hex[i]; i++) { + uint8_t kc = 0; + char c = hex[i]; + + switch (c) { + case '0': + kc = KC_0; + break; + case '1' ... '9': + kc = c - '1' + KC_1; + break; + case 'a' ... 'f': + kc = c - 'a' + KC_A; + break; + case 'A' ... 'F': + kc = c - 'A' + KC_A; + break; + } + + if (kc) { + register_code (kc); + unregister_code (kc); + } + } +} + bool process_ucis (uint16_t keycode, keyrecord_t *record) { uint8_t i; @@ -164,7 +183,7 @@ bool process_ucis (uint16_t keycode, keyrecord_t *record) { for (i = 0; ucis_symbol_table[i].symbol; i++) { if (is_uni_seq (ucis_symbol_table[i].symbol)) { symbol_found = true; - register_hex32(ucis_symbol_table[i].code); + register_ucis(ucis_symbol_table[i].code + 2); break; } } diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index dd6dd7138..be24ddc2b 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -12,7 +12,6 @@ void set_unicode_input_mode(uint8_t os_target); void unicode_input_start(void); void unicode_input_finish(void); void register_hex(uint16_t hex); -void register_hex32(uint32_t hex); bool process_unicode(uint16_t keycode, keyrecord_t *record); @@ -23,7 +22,7 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record); typedef struct { char *symbol; - uint32_t code; + char *code; } qk_ucis_symbol_t; struct { @@ -32,14 +31,15 @@ struct { bool in_progress:1; } qk_ucis_state; -#define UCIS_TABLE(...) {__VA_ARGS__, {NULL, 0}} -#define UCIS_SYM(name, code) {name, code} +#define UCIS_TABLE(...) {__VA_ARGS__, {NULL, NULL}} +#define UCIS_SYM(name, code) {name, #code} extern const qk_ucis_symbol_t ucis_symbol_table[]; void qk_ucis_start(void); void qk_ucis_start_user(void); void qk_ucis_symbol_fallback (void); +void register_ucis(const char *hex); bool process_ucis (uint16_t keycode, keyrecord_t *record); #endif -- cgit v1.3.1 From e8845f0daf8dc7a7674dc5420cc5a684bbbea09b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 15 Aug 2016 10:07:13 +0200 Subject: process_unicode: Introduce a slight delay When entering unicode codes, use some delay, so the OS has time to process the information. This is not needed on all systems, but some seem to require it. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 4 ++++ quantum/process_keycode/process_unicode.h | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index d8a0f667c..72c809c30 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -37,6 +37,7 @@ void unicode_input_start (void) { unregister_code(KC_PPLS); break; } + wait_ms(UNICODE_TYPE_DELAY); } void unicode_input_finish (void) { @@ -109,6 +110,7 @@ void qk_ucis_symbol_fallback (void) { uint8_t code = qk_ucis_state.codes[i]; register_code(code); unregister_code(code); + wait_ms(UNICODE_TYPE_DELAY); } } @@ -135,6 +137,7 @@ void register_ucis(const char *hex) { if (kc) { register_code (kc); unregister_code (kc); + wait_ms (UNICODE_TYPE_DELAY); } } } @@ -172,6 +175,7 @@ bool process_ucis (uint16_t keycode, keyrecord_t *record) { for (i = qk_ucis_state.count; i > 0; i--) { register_code (KC_BSPC); unregister_code (KC_BSPC); + wait_ms(UNICODE_TYPE_DELAY); } if (keycode == KC_ESC) { diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index be24ddc2b..85364e8eb 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -8,6 +8,10 @@ #define UC_WIN 2 #define UC_BSD 3 +#ifndef UNICODE_TYPE_DELAY +#define UNICODE_TYPE_DELAY 10 +#endif + void set_unicode_input_mode(uint8_t os_target); void unicode_input_start(void); void unicode_input_finish(void); -- cgit v1.3.1 From d78058cc75a9b05a6885991506d5f807ebb2a9f9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 17 Aug 2016 10:28:08 +0200 Subject: tap-dance: Include action_tapping.h for TAPPING_TERM Include `action_tapping.h`, so the keymap does not have to define a `TAPPING_TERM` for us, and we can use the default. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_tap_dance.c | 1 + 1 file changed, 1 insertion(+) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 5429e3438..bab5c4dbd 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -1,4 +1,5 @@ #include "quantum.h" +#include "action_tapping.h" static qk_tap_dance_state_t qk_tap_dance_state; bool td_debug_enable = false; -- cgit v1.3.1 From 29f64d7a93d941167c6c6e95f893ab84586b2205 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 17 Aug 2016 13:04:50 +0200 Subject: tap-dance: Major rework, to make it more reliable This reworks how the tap-dance feature works: instead of one global state, we have a state for each tap-dance key, so we can cancel them when another tap-dance key is in flight. This fixes #527. Since we have a state for each key, we can avoid situation where a keyup would mess with our global state. This fixes #563. And while here, we also make sure to fire events only once, and this fixes #574. There is one breaking change, though: tap-dance debugging support was removed, because dumping the whole state would increase the firmware size too much. Any keymap that made use of this, will have to be updated (but there's no such keymap in the repo). Also, there's a nice trick used in this rework: we need to iterate through tap_dance_actions in a few places, to check for timeouts, and so on. For this, we'd need to know the size of the array. We can't discover that at compile-time, because tap-dance gets compiled separately. We'd like to avoid having to terminate the list with a sentinel value, because that would require updates to all keymaps that use the feature. So, we keep track of the highest tap-dance code seen so far, and iterate until that index. Signed-off-by: Gergely Nagy --- keyboards/ergodox/keymaps/algernon/keymap.c | 2 +- keyboards/preonic/keymaps/kinesis/keymap.c | 2 +- quantum/process_keycode/process_tap_dance.c | 121 ++++++++++++++-------------- quantum/process_keycode/process_tap_dance.h | 9 ++- readme.md | 4 +- 5 files changed, 70 insertions(+), 68 deletions(-) (limited to 'quantum') diff --git a/keyboards/ergodox/keymaps/algernon/keymap.c b/keyboards/ergodox/keymaps/algernon/keymap.c index 244bfb51f..144030e2e 100644 --- a/keyboards/ergodox/keymaps/algernon/keymap.c +++ b/keyboards/ergodox/keymaps/algernon/keymap.c @@ -853,7 +853,7 @@ void ang_tap_dance_ta_reset (qk_tap_dance_state_t *state, void *user_data) { td_ta->finished_once = false; } -const qk_tap_dance_action_t tap_dance_actions[] = { +qk_tap_dance_action_t tap_dance_actions[] = { [CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, ang_tap_dance_cln_finished, ang_tap_dance_cln_reset) ,[CT_MNS] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, ang_tap_dance_mns_finished, ang_tap_dance_mns_reset) ,[CT_TA] = { diff --git a/keyboards/preonic/keymaps/kinesis/keymap.c b/keyboards/preonic/keymaps/kinesis/keymap.c index 1cd6eb993..9691be91d 100644 --- a/keyboards/preonic/keymaps/kinesis/keymap.c +++ b/keyboards/preonic/keymaps/kinesis/keymap.c @@ -123,7 +123,7 @@ void music_scale_user(void) } -const qk_tap_dance_action_t tap_dance_actions[] = { +qk_tap_dance_action_t tap_dance_actions[] = { //Tap once for equal, twice for hyper + X (alfred lock) [TD_EQ_LOCK] = ACTION_TAP_DANCE_DOUBLE(KC_EQL, HYPR(KC_X)), //Tap once for minus, twice for time.heals.nothing diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index bab5c4dbd..e152f2350 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -1,19 +1,8 @@ #include "quantum.h" #include "action_tapping.h" -static qk_tap_dance_state_t qk_tap_dance_state; -bool td_debug_enable = false; - -#if CONSOLE_ENABLE -#define td_debug(s) if (td_debug_enable) \ - { \ - xprintf ("D:tap_dance:%s:%s = { keycode = %d, count = %d, active = %d, pressed = %d }\n", __FUNCTION__, s, \ - qk_tap_dance_state.keycode, qk_tap_dance_state.count, \ - qk_tap_dance_state.active, qk_tap_dance_state.pressed); \ - } -#else -#define td_debug(s) -#endif +static uint16_t last_td; +static int8_t highest_td = -1; void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data) { qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; @@ -36,98 +25,110 @@ void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data) { } static inline void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, - void *user_data, - qk_tap_dance_user_fn_t fn) + void *user_data, + qk_tap_dance_user_fn_t fn) { if (fn) { fn(state, user_data); } } -static inline void process_tap_dance_action_on_each_tap (qk_tap_dance_action_t action) +static inline void process_tap_dance_action_on_each_tap (qk_tap_dance_action_t *action) { - td_debug("trigger"); - _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_each_tap); + _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_each_tap); } -static inline void process_tap_dance_action_on_dance_finished (qk_tap_dance_action_t action) +static inline void process_tap_dance_action_on_dance_finished (qk_tap_dance_action_t *action) { - td_debug("trigger"); - _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_dance_finished); + if (action->state.finished) + return; + action->state.finished = true; + _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_dance_finished); } -static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t action) +static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t *action) { - td_debug("trigger") - _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_reset); + _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_reset); } bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { - bool r = true; uint16_t idx = keycode - QK_TAP_DANCE; - qk_tap_dance_action_t action; + qk_tap_dance_action_t *action; + + if (last_td && last_td != keycode) { + (&tap_dance_actions[last_td - QK_TAP_DANCE])->state.interrupted = true; + } switch(keycode) { case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: - action = tap_dance_actions[idx]; - - process_tap_dance_action_on_each_tap (action); - if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) { - process_tap_dance_action_on_dance_finished (action); - } else if (qk_tap_dance_state.active && qk_tap_dance_state.pressed) { - reset_tap_dance (&qk_tap_dance_state); - } else { - r = false; - } + if ((int16_t)idx > highest_td) + highest_td = idx; + action = &tap_dance_actions[idx]; - qk_tap_dance_state.active = true; - qk_tap_dance_state.pressed = record->event.pressed; + action->state.keycode = keycode; + action->state.pressed = record->event.pressed; if (record->event.pressed) { - qk_tap_dance_state.keycode = keycode; - qk_tap_dance_state.timer = timer_read (); - qk_tap_dance_state.count++; + action->state.count++; + action->state.timer = timer_read(); + + if (last_td && last_td != keycode) { + qk_tap_dance_action_t *paction = &tap_dance_actions[last_td - QK_TAP_DANCE]; + paction->state.interrupted = true; + process_tap_dance_action_on_dance_finished (paction); + reset_tap_dance (&paction->state); + } } + last_td = keycode; + break; default: - if (qk_tap_dance_state.keycode) { - // if we are here, the tap dance was interrupted by a different key - idx = qk_tap_dance_state.keycode - QK_TAP_DANCE; - action = tap_dance_actions[idx]; + if (!record->event.pressed) + return true; + + if (highest_td == -1) + return true; - process_tap_dance_action_on_each_tap (action); + for (int i = 0; i <= highest_td; i++) { + action = &tap_dance_actions[i]; + if (action->state.count == 0) + continue; + action->state.interrupted = true; process_tap_dance_action_on_dance_finished (action); - reset_tap_dance (&qk_tap_dance_state); - qk_tap_dance_state.active = false; + reset_tap_dance (&action->state); } break; } - return r; + return true; } void matrix_scan_tap_dance () { - if (qk_tap_dance_state.active && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) { - // if we are here, the tap dance was timed out - uint16_t idx = qk_tap_dance_state.keycode - QK_TAP_DANCE; - qk_tap_dance_action_t action = tap_dance_actions[idx]; + if (highest_td == -1) + return; + + for (int i = 0; i <= highest_td; i++) { + qk_tap_dance_action_t *action = &tap_dance_actions[i]; - process_tap_dance_action_on_dance_finished (action); - reset_tap_dance (&qk_tap_dance_state); + if (action->state.count && timer_elapsed (action->state.timer) > TAPPING_TERM) { + process_tap_dance_action_on_dance_finished (action); + reset_tap_dance (&action->state); + } } } void reset_tap_dance (qk_tap_dance_state_t *state) { - uint16_t idx = state->keycode - QK_TAP_DANCE; - qk_tap_dance_action_t action; + qk_tap_dance_action_t *action; if (state->pressed) return; - action = tap_dance_actions[idx]; + action = &tap_dance_actions[state->keycode - QK_TAP_DANCE]; + process_tap_dance_action_on_reset (action); - state->keycode = 0; state->count = 0; - state->active = false; + state->interrupted = false; + state->finished = false; + last_td = 0; } diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index 6a1258067..d7b857bdc 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h @@ -11,8 +11,9 @@ typedef struct uint8_t count; uint16_t keycode; uint16_t timer; - bool active:1; - bool pressed:1; + bool interrupted; + bool pressed; + bool finished; } qk_tap_dance_state_t; #define TD(n) (QK_TAP_DANCE + n) @@ -26,6 +27,7 @@ typedef struct qk_tap_dance_user_fn_t on_dance_finished; qk_tap_dance_user_fn_t on_reset; } fn; + qk_tap_dance_state_t state; void *user_data; } qk_tap_dance_action_t; @@ -48,8 +50,7 @@ typedef struct .fn = { user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset } \ } -extern const qk_tap_dance_action_t tap_dance_actions[]; -extern bool td_debug_enable; +extern qk_tap_dance_action_t tap_dance_actions[]; /* To be used internally */ diff --git a/readme.md b/readme.md index e2221e749..8c07a5d1f 100644 --- a/readme.md +++ b/readme.md @@ -431,7 +431,7 @@ enum { }; //Tap Dance Definitions -const qk_tap_dance_action_t tap_dance_actions[] = { +qk_tap_dance_action_t tap_dance_actions[] = { //Tap once for Esc, twice for Caps Lock [TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS) // Other declarations would go here, separated by commas, if you have them @@ -517,7 +517,7 @@ void dance_flsh_reset(qk_tap_dance_state_t *state, void *user_data) { ergodox_right_led_3_off(); } -const qk_tap_dance_action_t tap_dance_actions[] = { +qk_tap_dance_action_t tap_dance_actions[] = { [CT_SE] = ACTION_TAP_DANCE_DOUBLE (KC_SPC, KC_ENT) ,[CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, dance_cln_finished, dance_cln_reset) ,[CT_EGG] = ACTION_TAP_DANCE_FN (dance_egg) -- cgit v1.3.1 From 644c8c79271db8cf1bd934b9a80a0215585e46e7 Mon Sep 17 00:00:00 2001 From: Wojciech Siewierski Date: Thu, 18 Aug 2016 01:34:05 +0200 Subject: Fix the process_record_nocache function This function relies on checking the disable_action_cache static variable before accessing the layer cache. --- quantum/quantum.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index a4c5c2ddb..cb1ba04ff 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -46,18 +46,20 @@ bool process_record_quantum(keyrecord_t *record) { uint16_t keycode; #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS) - uint8_t layer; + /* TODO: Use store_or_get_action() or a similar function. */ + if (!disable_action_cache) { + uint8_t layer; - if (record->event.pressed) { - layer = layer_switch_get_layer(key); - update_source_layers_cache(key, layer); - } else { - layer = read_source_layers_cache(key); - } - keycode = keymap_key_to_keycode(layer, key); - #else - keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key); + if (record->event.pressed) { + layer = layer_switch_get_layer(key); + update_source_layers_cache(key, layer); + } else { + layer = read_source_layers_cache(key); + } + keycode = keymap_key_to_keycode(layer, key); + } else #endif + keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key); // This is how you use actions here // if (keycode == KC_LEAD) { -- cgit v1.3.1 From 39e8e61258b51a2c33a94dd877e983f0b1dae0c1 Mon Sep 17 00:00:00 2001 From: Wojciech Siewierski Date: Thu, 18 Aug 2016 01:37:13 +0200 Subject: Implement the dynamic macros that are recorded in runtime --- quantum/dynamic_macro.h | 226 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 quantum/dynamic_macro.h (limited to 'quantum') diff --git a/quantum/dynamic_macro.h b/quantum/dynamic_macro.h new file mode 100644 index 000000000..a3ad61bc7 --- /dev/null +++ b/quantum/dynamic_macro.h @@ -0,0 +1,226 @@ +/* Author: Wojciech Siewierski < wojciech dot siewierski at onet dot pl > */ +#ifndef DYNAMIC_MACROS_H +#define DYNAMIC_MACROS_H + +#include "action_layer.h" + +#ifndef DYNAMIC_MACRO_SIZE +/* May be overridden with a custom value. Be aware that the effective + * macro length is half of this value: each keypress is recorded twice + * because of the down-event and up-event. This is not a bug, it's the + * intended behavior. */ +#define DYNAMIC_MACRO_SIZE 256 +#endif + +/* DYNAMIC_MACRO_RANGE must be set as the last element of user's + * "planck_keycodes" enum prior to including this header. This allows + * us to 'extend' it. + */ +enum dynamic_macro_keycodes { + DYN_REC_START1 = DYNAMIC_MACRO_RANGE, + DYN_REC_START2, + DYN_MACRO_PLAY1, + DYN_MACRO_PLAY2, +}; + +/* Blink the LEDs to notify the user about some event. */ +void dynamic_macro_led_blink(void) +{ + backlight_toggle(); + _delay_ms(100); + backlight_toggle(); +} + +/** + * Start recording of the dynamic macro. + * + * @param[out] macro_pointer The new macro buffer iterator. + * @param[in] macro_buffer The macro buffer used to initialize macro_pointer. + */ +void dynamic_macro_record_start( + keyrecord_t **macro_pointer, keyrecord_t *macro_buffer) +{ + dynamic_macro_led_blink(); + + clear_keyboard(); + layer_clear(); + *macro_pointer = macro_buffer; +} + +/** + * Play the dynamic macro. + * + * @param macro_buffer[in] The beginning of the macro buffer being played. + * @param macro_end[in] The element after the last macro buffer element. + * @param direction[in] Either +1 or -1, which way to iterate the buffer. + */ +void dynamic_macro_play( + keyrecord_t *macro_buffer, keyrecord_t *macro_end, int8_t direction) +{ + uint32_t saved_layer_state = layer_state; + + clear_keyboard(); + layer_clear(); + + while (macro_buffer != macro_end) { + process_record(macro_buffer); + macro_buffer += direction; + } + + clear_keyboard(); + + layer_state = saved_layer_state; +} + +/** + * Record a single key in a dynamic macro. + * + * @param macro_pointer[in,out] The current buffer position. + * @param macro_end2[in] The end of the other macro which shouldn't be overwritten. + * @param direction[in] Either +1 or -1, which way to iterate the buffer. + * @param record[in] The current keypress. + */ +void dynamic_macro_record_key( + keyrecord_t **macro_pointer, + keyrecord_t *macro_end2, + int8_t direction, + keyrecord_t *record) +{ + if (*macro_pointer + direction != macro_end2) { + **macro_pointer = *record; + *macro_pointer += direction; + } else { + /* Notify about the end of buffer. The blinks are paired + * because they should happen on both down and up events. */ + backlight_toggle(); + } +} + +/** + * End recording of the dynamic macro. Essentially just update the + * pointer to the end of the macro. + */ +void dynamic_macro_record_end(keyrecord_t *macro_pointer, keyrecord_t **macro_end) +{ + dynamic_macro_led_blink(); + + *macro_end = macro_pointer; +} + +/* Handle the key events related to the dynamic macros. Should be + * called from process_record_user() like this: + * + * bool process_record_user(uint16_t keycode, keyrecord_t *record) { + * if (!process_record_dynamic_macro(keycode, record)) { + * return false; + * } + * <...THE REST OF THE FUNCTION...> + * } + */ +bool process_record_dynamic_macro(uint16_t keycode, keyrecord_t *record) +{ + /* Both macros use the same buffer but read/write on different + * ends of it. + * + * Macro1 is written left-to-right starting from the beginning of + * the buffer. + * + * Macro2 is written right-to-left starting from the end of the + * buffer. + * + * ¯o_buffer macro_end + * v v + * +------------------------------------------------------------+ + * |>>>>>> MACRO1 >>>>>>| |<<<<<<<<<<<<< MACRO2 <<<<<<<<<<<<<| + * +------------------------------------------------------------+ + * ^ ^ + * r_macro_end r_macro_buffer + * + * During the recording when one macro encounters the end of the + * other macro, the recording is stopped. Apart from this, there + * are no arbitrary limits for the macros' length in relation to + * each other: for example one can either have two medium sized + * macros or one long macro and one short macro. Or even one empty + * and one using the whole buffer. + */ + static keyrecord_t macro_buffer[DYNAMIC_MACRO_SIZE]; + + /* Pointer to the first buffer element after the first macro. + * Initially points to the very beginning of the buffer since the + * macro is empty. */ + static keyrecord_t *macro_end = macro_buffer; + + /* The other end of the macro buffer. Serves as the beginning of + * the second macro. */ + static keyrecord_t *const r_macro_buffer = macro_buffer + DYNAMIC_MACRO_SIZE - 1; + + /* Like macro_end but for the second macro. */ + static keyrecord_t *r_macro_end = r_macro_buffer; + + /* A persistent pointer to the current macro position (iterator) + * used during the recording. */ + static keyrecord_t *macro_pointer = NULL; + + /* 0 - no macro is being recorded right now + * 1,2 - either macro 1 or 2 is being recorded */ + static uint8_t macro_id = 0; + + if (macro_id == 0) { + /* No macro recording in progress. */ + if (!record->event.pressed) { + switch (keycode) { + case DYN_REC_START1: + dynamic_macro_record_start(¯o_pointer, macro_buffer); + macro_id = 1; + return false; + case DYN_REC_START2: + dynamic_macro_record_start(¯o_pointer, r_macro_buffer); + macro_id = 2; + return false; + case DYN_MACRO_PLAY1: + dynamic_macro_play(macro_buffer, macro_end, +1); + return false; + case DYN_MACRO_PLAY2: + dynamic_macro_play(r_macro_buffer, r_macro_end, -1); + return false; + } + } + } else { + /* A macro is being recorded right now. */ + switch (keycode) { + case MO(_DYN): + /* Use the layer key used to access the macro recording as + * a stop button. */ + if (record->event.pressed) { /* Ignore the initial release + * just after the recoding + * starts. */ + switch (macro_id) { + case 1: + dynamic_macro_record_end(macro_pointer, ¯o_end); + break; + case 2: + dynamic_macro_record_end(macro_pointer, &r_macro_end); + break; + } + macro_id = 0; + } + return false; + default: + /* Store the key in the macro buffer and process it normally. */ + switch (macro_id) { + case 1: + dynamic_macro_record_key(¯o_pointer, r_macro_end, +1, record); + break; + case 2: + dynamic_macro_record_key(¯o_pointer, macro_end, -1, record); + break; + } + return true; + break; + } + } + + return true; +} + +#endif -- cgit v1.3.1 From 0d28787c5cf2173d12f57b397515f91cffaa820a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 18 Aug 2016 11:29:53 +0200 Subject: Add a register/unregister_code16 pair of functions These functions register not only the 8bit keycode, but the modifiers too. It doesn't handle the full range of the upper 8bits, just the mods, but that's a good start. Changed the tap-dance pair functions to use these, so one can do: `ACTION_TAP_DANCE_DOUBLE (KC_COLN, KC_SCLN)` ...and that will do the right thing. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_tap_dance.c | 8 +++---- quantum/quantum.c | 37 +++++++++++++++++++++++++++++ quantum/quantum.h | 3 +++ 3 files changed, 44 insertions(+), 4 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index e152f2350..07de3ecb8 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -8,9 +8,9 @@ void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data) { qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; if (state->count == 1) { - register_code (pair->kc1); + register_code16 (pair->kc1); } else if (state->count == 2) { - register_code (pair->kc2); + register_code16 (pair->kc2); } } @@ -18,9 +18,9 @@ void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data) { qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; if (state->count == 1) { - unregister_code (pair->kc1); + unregister_code16 (pair->kc1); } else if (state->count == 2) { - unregister_code (pair->kc2); + unregister_code16 (pair->kc2); } } diff --git a/quantum/quantum.c b/quantum/quantum.c index cb1ba04ff..e3a20f43e 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -1,5 +1,42 @@ #include "quantum.h" +static void do_code16 (uint16_t code, void (*f) (uint8_t)) { + switch (code) { + case QK_MODS ... QK_MODS_MAX: + break; + default: + return; + } + + if (code & QK_LCTL) + f(KC_LCTL); + if (code & QK_LSFT) + f(KC_LSFT); + if (code & QK_LALT) + f(KC_LALT); + if (code & QK_LGUI) + f(KC_LGUI); + + if (code & QK_RCTL) + f(KC_RCTL); + if (code & QK_RSFT) + f(KC_RSFT); + if (code & QK_RALT) + f(KC_RALT); + if (code & QK_RGUI) + f(KC_RGUI); +} + +void register_code16 (uint16_t code) { + do_code16 (code, register_code); + register_code (code); +} + +void unregister_code16 (uint16_t code) { + unregister_code (code); + do_code16 (code, unregister_code); +} + __attribute__ ((weak)) bool process_action_kb(keyrecord_t *record) { return true; diff --git a/quantum/quantum.h b/quantum/quantum.h index 6e3fbcc79..0c6046649 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -83,6 +83,9 @@ void reset_keyboard(void); void startup_user(void); void shutdown_user(void); +void register_code16 (uint16_t code); +void unregister_code16 (uint16_t code); + #ifdef BACKLIGHT_ENABLE void backlight_init_ports(void); -- cgit v1.3.1