From edd58256f58b44b00f8ae811941c63862693e4c4 Mon Sep 17 00:00:00 2001 From: Florian Didron <0x6664@hey.com> Date: Tue, 13 Oct 2020 21:08:29 +0900 Subject: Revert "Convert ErgoDox EZ to Matrix Lite (qmk#10189)" This reverts commit 396b86b92d8010ac929f30768cc98643ea019986. --- keyboards/ergodox_ez/config.h | 19 +-- keyboards/ergodox_ez/ergodox_ez.c | 2 +- keyboards/ergodox_ez/ergodox_ez.h | 4 + keyboards/ergodox_ez/matrix.c | 339 +++++++++++++++++++++++--------------- keyboards/ergodox_ez/rules.mk | 84 ++++++++-- 5 files changed, 286 insertions(+), 162 deletions(-) (limited to 'keyboards') diff --git a/keyboards/ergodox_ez/config.h b/keyboards/ergodox_ez/config.h index 64289666de..5e6446b0ff 100644 --- a/keyboards/ergodox_ez/config.h +++ b/keyboards/ergodox_ez/config.h @@ -18,7 +18,9 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#pragma once +#ifndef ERGODOX_EZ_CONFIG_H +#define ERGODOX_EZ_CONFIG_H +#endif #include "config_common.h" @@ -26,8 +28,9 @@ along with this program. If not, see . #define VENDOR_ID 0x3297 #define PRODUCT_ID 0x4974 #define DEVICE_VER 0x0001 -#define MANUFACTURER ZSA Technology Labs Inc -#define PRODUCT ErgoDox EZ +#define MANUFACTURER ZSA +#define PRODUCT Ergodox EZ +#define DESCRIPTION QMK keyboard firmware for Ergodox EZ #define WEBUSB_LANDING_PAGE_URL u8"configure.ergodox-ez.com" /* key matrix size */ @@ -35,16 +38,6 @@ along with this program. If not, see . #define MATRIX_ROWS_PER_SIDE (MATRIX_ROWS / 2) #define MATRIX_COLS 6 -#define COL_EXPANDED { true, true, true, true, true, true, true, false, false, false, false, false, false, false } -#define MATRIX_ONBOARD_ROW_PINS { 0, 0, 0, 0, 0, 0, 0, B0, B1, B2, B3, D2, D3, C6 } -#define MATRIX_ONBOARD_COL_PINS { F0, F1, F4, F5, F6, F7 } -#define DIODE_DIRECTION COL2ROW -#define EXPANDER_COL_REGISTER GPIOB -#define EXPANDER_ROW_REGISTER GPIOA -#define MATRIX_EXPANDER_COL_PINS { 5, 4, 3, 2, 1, 0 } -#define MATRIX_EXPANDER_ROW_PINS { 0, 1, 2, 3, 4, 5, 6 } - - #define MOUSEKEY_INTERVAL 20 #define MOUSEKEY_DELAY 0 #define MOUSEKEY_TIME_TO_MAX 60 diff --git a/keyboards/ergodox_ez/ergodox_ez.c b/keyboards/ergodox_ez/ergodox_ez.c index a2bbbfe09d..8c2ccc180c 100644 --- a/keyboards/ergodox_ez/ergodox_ez.c +++ b/keyboards/ergodox_ez/ergodox_ez.c @@ -18,7 +18,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "ergodox_ez.h" +#include QMK_KEYBOARD_H extern inline void ergodox_board_led_on(void); extern inline void ergodox_right_led_1_on(void); diff --git a/keyboards/ergodox_ez/ergodox_ez.h b/keyboards/ergodox_ez/ergodox_ez.h index a10e0fee63..74b9c06d68 100644 --- a/keyboards/ergodox_ez/ergodox_ez.h +++ b/keyboards/ergodox_ez/ergodox_ez.h @@ -24,6 +24,10 @@ along with this program. If not, see . #include #include #include "i2c_master.h" +#include + +#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) +#define CPU_16MHz 0x00 #if defined(KEYBOARD_ergodox_ez_glow) # include "glow.h" diff --git a/keyboards/ergodox_ez/matrix.c b/keyboards/ergodox_ez/matrix.c index d18800f19b..18c576060d 100644 --- a/keyboards/ergodox_ez/matrix.c +++ b/keyboards/ergodox_ez/matrix.c @@ -37,8 +37,7 @@ along with this program. If not, see . #include "util.h" #include "matrix.h" #include "debounce.h" -#include "ergodox_ez.h" - +#include QMK_KEYBOARD_H /* * This constant define not debouncing time in msecs, assuming eager_pr. @@ -52,9 +51,13 @@ along with this program. If not, see . * that comment was written.) */ +#ifndef DEBOUNCE +# define DEBOUNCE 5 +#endif + /* matrix state(1:on, 0:off) */ -extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values -extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values +static matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values +static matrix_row_t matrix[MATRIX_ROWS]; // debounced values static matrix_row_t read_cols(uint8_t row); static void init_cols(void); @@ -62,62 +65,132 @@ static void unselect_rows(void); static void select_row(uint8_t row); static uint8_t mcp23018_reset_loop; +// static uint16_t mcp23018_reset_loop; -void matrix_init_custom(void) { - // initialize row and col +__attribute__((weak)) void matrix_init_user(void) {} - mcp23018_status = init_mcp23018(); +__attribute__((weak)) void matrix_scan_user(void) {} - unselect_rows(); - init_cols(); +__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); } + +__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); } + +inline uint8_t matrix_rows(void) { return MATRIX_ROWS; } + +inline uint8_t matrix_cols(void) { return MATRIX_COLS; } + +void matrix_init(void) { + // initialize row and col + + mcp23018_status = init_mcp23018(); + + unselect_rows(); + init_cols(); + + // initialize matrix state: all keys off + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + matrix[i] = 0; + raw_matrix[i] = 0; + } + + debounce_init(MATRIX_ROWS); + matrix_init_quantum(); +} + +void matrix_power_up(void) { + mcp23018_status = init_mcp23018(); + + unselect_rows(); + init_cols(); + + // initialize matrix state: all keys off + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + matrix[i] = 0; + } } // Reads and stores a row, returning // whether a change occurred. static inline bool store_raw_matrix_row(uint8_t index) { - matrix_row_t temp = read_cols(index); - if (raw_matrix[index] != temp) { - raw_matrix[index] = temp; - return true; - } - return false; + matrix_row_t temp = read_cols(index); + if (raw_matrix[index] != temp) { + raw_matrix[index] = temp; + return true; + } + return false; } -bool matrix_scan_custom(matrix_row_t current_matrix[]) { - if (mcp23018_status) { // if there was an error - if (++mcp23018_reset_loop == 0) { - print("trying to reset mcp23018\n"); - mcp23018_status = init_mcp23018(); - if (mcp23018_status) { - print("left side not responding\n"); - } else { - print("left side attached\n"); - ergodox_blink_all_leds(); +uint8_t matrix_scan(void) { + if (mcp23018_status) { // if there was an error + if (++mcp23018_reset_loop == 0) { + // if (++mcp23018_reset_loop >= 1300) { + // since mcp23018_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans + // this will be approx bit more frequent than once per second + print("trying to reset mcp23018\n"); + mcp23018_status = init_mcp23018(); + if (mcp23018_status) { + print("left side not responding\n"); + } else { + print("left side attached\n"); #ifdef RGB_MATRIX_ENABLE - rgb_matrix_init(); // re-init driver on reconnect + rgb_matrix_init(); #endif - } - } + ergodox_blink_all_leds(); + } } + } #ifdef LEFT_LEDS - mcp23018_status = ergodox_left_leds_update(); + mcp23018_status = ergodox_left_leds_update(); #endif // LEFT_LEDS - bool changed = false; - for (uint8_t i = 0; i < MATRIX_ROWS_PER_SIDE; i++) { - // select rows from left and right hands - uint8_t left_index = i; - uint8_t right_index = i + MATRIX_ROWS_PER_SIDE; - select_row(left_index); - select_row(right_index); - - changed |= store_raw_matrix_row(left_index); - changed |= store_raw_matrix_row(right_index); - - unselect_rows(); - } + bool changed = false; + for (uint8_t i = 0; i < MATRIX_ROWS_PER_SIDE; i++) { + // select rows from left and right hands + uint8_t left_index = i; + uint8_t right_index = i + MATRIX_ROWS_PER_SIDE; + select_row(left_index); + select_row(right_index); + + // we don't need a 30us delay anymore, because selecting a + // left-hand row requires more than 30us for i2c. - return changed; + changed |= store_raw_matrix_row(left_index); + changed |= store_raw_matrix_row(right_index); + + unselect_rows(); + } + + debounce(raw_matrix, matrix, MATRIX_ROWS, changed); + matrix_scan_quantum(); + + return (uint8_t)changed; +} + +bool matrix_is_modified(void) // deprecated and evidently not called. +{ + return true; +} + +inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); } + +inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; } + +void matrix_print(void) { + print("\nr/c 0123456789ABCDEF\n"); + for (uint8_t row = 0; row < MATRIX_ROWS; row++) { + phex(row); + print(": "); + pbin_reverse16(matrix_get_row(row)); + print("\n"); + } +} + +uint8_t matrix_key_count(void) { + uint8_t count = 0; + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + count += bitpop16(matrix[i]); + } + return count; } /* Column pin configuration @@ -131,43 +204,44 @@ bool matrix_scan_custom(matrix_row_t current_matrix[]) { * pin: B5 B4 B3 B2 B1 B0 */ static void init_cols(void) { - // init on mcp23018 - // not needed, already done as part of init_mcp23018() - - // init on teensy - setPinInputHigh(F0); - setPinInputHigh(F1); - setPinInputHigh(F4); - setPinInputHigh(F5); - setPinInputHigh(F6); - setPinInputHigh(F7); + // init on mcp23018 + // not needed, already done as part of init_mcp23018() + + // init on teensy + // Input with pull-up(DDR:0, PORT:1) + DDRF &= ~(1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 1 | 1 << 0); + PORTF |= (1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 1 | 1 << 0); } static matrix_row_t read_cols(uint8_t row) { - if (row < 7) { - if (mcp23018_status) { // if there was an error - return 0; - } else { - uint8_t data = 0; - // reading GPIOB (column port) since in mcp23018's sequential mode - // it is addressed directly after writing to GPIOA in select_row() - mcp23018_status = i2c_start(I2C_ADDR_READ, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_read_nack(ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status < 0) goto out; - data = ~((uint8_t)mcp23018_status); - mcp23018_status = I2C_STATUS_SUCCESS; - out: - i2c_stop(); - return data; - } + if (row < 7) { + if (mcp23018_status) { // if there was an error + return 0; } else { - /* read from teensy - * bitmask is 0b11110011, but we want those all - * in the lower six bits. - * we'll return 1s for the top two, but that's harmless. - */ - - return ~((PINF & 0x03) | ((PINF & 0xF0) >> 2)); + uint8_t data = 0; + mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); + if (mcp23018_status) goto out; + mcp23018_status = i2c_write(GPIOB, ERGODOX_EZ_I2C_TIMEOUT); + if (mcp23018_status) goto out; + mcp23018_status = i2c_start(I2C_ADDR_READ, ERGODOX_EZ_I2C_TIMEOUT); + if (mcp23018_status) goto out; + mcp23018_status = i2c_read_nack(ERGODOX_EZ_I2C_TIMEOUT); + if (mcp23018_status < 0) goto out; + data = ~((uint8_t)mcp23018_status); + mcp23018_status = I2C_STATUS_SUCCESS; + out: + i2c_stop(); + return data; } + } else { + /* read from teensy + * bitmask is 0b11110011, but we want those all + * in the lower six bits. + * we'll return 1s for the top two, but that's harmless. + */ + + return ~((PINF & 0x03) | ((PINF & 0xF0) >> 2)); + } } /* Row pin configuration @@ -181,64 +255,69 @@ static matrix_row_t read_cols(uint8_t row) { * pin: A0 A1 A2 A3 A4 A5 A6 */ static void unselect_rows(void) { - // no need to unselect on mcp23018, because the select step sets all - // the other row bits high, and it's not changing to a different - // direction - - // unselect on teensy - setPinInput(B0); - setPinInput(B1); - setPinInput(B2); - setPinInput(B3); - setPinInput(D2); - setPinInput(D3); - setPinInput(C6); + // no need to unselect on mcp23018, because the select step sets all + // the other row bits high, and it's not changing to a different + // direction + + // unselect on teensy + // Hi-Z(DDR:0, PORT:0) to unselect + DDRB &= ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3); + PORTB &= ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3); + DDRD &= ~(1 << 2 | 1 << 3); + PORTD &= ~(1 << 2 | 1 << 3); + DDRC &= ~(1 << 6); + PORTC &= ~(1 << 6); } static void select_row(uint8_t row) { - if (row < 7) { - // select on mcp23018 - if (!mcp23018_status) { - // set active row low : 0 - // set other rows hi-Z : 1 - mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPIOA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0xFF & ~(1 << row), ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; - out: - i2c_stop(); - } + if (row < 7) { + // select on mcp23018 + if (mcp23018_status) { // if there was an error + // do nothing } else { - // select on teensy - // Output low(DDR:1, PORT:0) to select - switch (row) { - case 7: - setPinOutput(B0); - writePinLow(B0); - break; - case 8: - setPinOutput(B1); - writePinLow(B1); - break; - case 9: - setPinOutput(B2); - writePinLow(B2); - break; - case 10: - setPinOutput(B3); - writePinLow(B3); - break; - case 11: - setPinOutput(D2); - writePinLow(D2); - break; - case 12: - setPinOutput(D3); - writePinLow(D3); - break; - case 13: - setPinOutput(C6); - writePinLow(C6); - break; - } + // set active row low : 0 + // set other rows hi-Z : 1 + mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); + if (mcp23018_status) goto out; + mcp23018_status = i2c_write(GPIOA, ERGODOX_EZ_I2C_TIMEOUT); + if (mcp23018_status) goto out; + mcp23018_status = i2c_write(0xFF & ~(1 << row), ERGODOX_EZ_I2C_TIMEOUT); + if (mcp23018_status) goto out; + out: + i2c_stop(); + } + } else { + // select on teensy + // Output low(DDR:1, PORT:0) to select + switch (row) { + case 7: + DDRB |= (1 << 0); + PORTB &= ~(1 << 0); + break; + case 8: + DDRB |= (1 << 1); + PORTB &= ~(1 << 1); + break; + case 9: + DDRB |= (1 << 2); + PORTB &= ~(1 << 2); + break; + case 10: + DDRB |= (1 << 3); + PORTB &= ~(1 << 3); + break; + case 11: + DDRD |= (1 << 2); + PORTD &= ~(1 << 2); + break; + case 12: + DDRD |= (1 << 3); + PORTD &= ~(1 << 3); + break; + case 13: + DDRC |= (1 << 6); + PORTC &= ~(1 << 6); + break; } + } } diff --git a/keyboards/ergodox_ez/rules.mk b/keyboards/ergodox_ez/rules.mk index b6311aca3e..728a7a4467 100644 --- a/keyboards/ergodox_ez/rules.mk +++ b/keyboards/ergodox_ez/rules.mk @@ -1,16 +1,64 @@ +#---------------------------------------------------------------------------- +# On command line: +# +# make = Make software. +# +# make clean = Clean out built project files. +# +# That's pretty much all you need. To compile, always go make clean, +# followed by make. +# +# For advanced users only: +# make teensy = Download the hex file to the device, using teensy_loader_cli. +# (must have teensy_loader_cli installed). +# +#---------------------------------------------------------------------------- + # MCU name MCU = atmega32u4 -# Bootloader selection -# Teensy halfkay -# Pro Micro caterina -# Atmel DFU atmel-dfu -# LUFA DFU lufa-dfu -# QMK DFU qmk-dfu -# ATmega32A bootloadHID -# ATmega328P USBasp +# Processor frequency. +# This will define a symbol, F_CPU, in all source code files equal to the +# processor frequency in Hz. You can then use this symbol in your source code to +# calculate timings. Do NOT tack on a 'UL' at the end, this will be done +# automatically to create a 32-bit value in your source code. +# +# This will be an integer division of F_USB below, as it is sourced by +# F_USB after it has run through any CPU prescalers. Note that this value +# does not *change* the processor frequency - it should merely be updated to +# reflect the processor speed set externally so that the code can use accurate +# software delays. +F_CPU = 16000000 + + +# +# LUFA specific +# +# Target architecture (see library "Board Types" documentation). +ARCH = AVR8 + +# Input clock frequency. +# This will define a symbol, F_USB, in all source code files equal to the +# input clock frequency (before any prescaling is performed) in Hz. This value may +# differ from F_CPU if prescaling is used on the latter, and is required as the +# raw input clock is fed directly to the PLL sections of the AVR for high speed +# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' +# at the end, this will be done automatically to create a 32-bit value in your +# source code. +# +# If no clock division is performed on the input clock inside the AVR (via the +# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. +F_USB = $(F_CPU) + +# Bootloader +# This definition is optional, and if your keyboard supports multiple bootloaders of +# different sizes, comment this out, and the correct address will be loaded +# automatically (+60). See bootloader.mk for all options. BOOTLOADER = halfkay +# Interrupt driven control endpoint task(+60) +OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT + # If you have Left LEDs (see # https://geekhack.org/index.php?topic=22780.msg873819#msg873819 for # details), include the following define: @@ -19,19 +67,19 @@ BOOTLOADER = halfkay # Build Options # comment out to disable the options. # -BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration -MOUSEKEY_ENABLE = yes # Mouse keys -EXTRAKEY_ENABLE = yes # Audio control and System control -CONSOLE_ENABLE = no # Console for debug -COMMAND_ENABLE = yes # Commands for debug and configuration -CUSTOM_MATRIX = lite # Custom matrix file for the ErgoDox EZ -NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work -UNICODE_ENABLE = yes # Unicode -SWAP_HANDS_ENABLE= yes # Allow swapping hands of keyboard +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 = no # Console for debug(+400) +COMMAND_ENABLE = yes # Commands for debug and configuration +CUSTOM_MATRIX = yes # Custom matrix file for the ErgoDox EZ +NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +UNICODE_ENABLE = yes # Unicode +SWAP_HANDS_ENABLE= yes # Allow swapping hands of keyboard SLEEP_LED_ENABLE = no API_SYSEX_ENABLE = no -RGB_MATRIX_ENABLE = no # enable later +RGB_MATRIX_ENABLE = no # enable later DEBOUNCE_TYPE = eager_pr # project specific files -- cgit v1.2.3