This commit is contained in:
2023-12-19 09:03:31 -08:00
parent 87029d00c1
commit 7cb29a6bba
14 changed files with 761 additions and 711 deletions

View File

@ -0,0 +1,57 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
Copyright 2013 Oleg Kostyuk <cub.uanic@gmail.com>
Copyright 2015 ZSA Technology Labs Inc (@zsa)
Copyright 2020 Christopher Courtney <drashna@live.com> (@drashna)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
#ifdef RGBLIGHT_ENABLE
#include "betalupi_ergodox.h"
void rgblight_call_driver(LED_TYPE *led, uint8_t led_num) {
i2c_init();
i2c_start(0x84, ERGODOX_EZ_I2C_TIMEOUT);
int i = 0;
# if defined(ERGODOX_LED_30)
// prevent right-half code from trying to bitbang all 30
// so with 30 LEDs, we count from 29 to 15 here, and the
// other half does 0 to 14.
uint8_t half_led_num = RGBLED_NUM / 2;
for (i = half_led_num + half_led_num - 1; i >= half_led_num; --i)
# elif defined(ERGODOX_LED_15_MIRROR)
for (i = 0; i < led_num; ++i)
# else // ERGDOX_LED_15 non-mirrored
for (i = led_num - 1; i >= 0; --i)
# endif
{
uint8_t *data = (uint8_t *)(led + i);
i2c_write(*data++, ERGODOX_EZ_I2C_TIMEOUT);
i2c_write(*data++, ERGODOX_EZ_I2C_TIMEOUT);
i2c_write(*data++, ERGODOX_EZ_I2C_TIMEOUT);
#ifdef RGBW
i2c_write(*data++, ERGODOX_EZ_I2C_TIMEOUT);
#endif
}
i2c_stop();
ws2812_setleds(led, led_num);
}
#endif // RGBLIGHT_ENABLE
*/

View File

@ -0,0 +1,34 @@
// Turns {h, s, v} triples into a macro, so that
// the LEDS_ergodox macro can take them as inputs.
#define LC_HSV(h, s, v) {h, s, v}
// Rearrange a human-readable LED layout into the correct Ergodox order.
// LEDS_ergodox ONLY WORKS WITH MACROS.
// Don't input a standalone triple {h, s, v};
// Use LC_HSV if you need a single-instance color.
#define LEDS_ergodox( \
l01,l02,l03,l04,l05, \
l06,l07,l08,l09,l10, \
l11,l12,l13,l14,l15, \
l16,l17,l18,l19,l20, \
l21,l22,l23,l24, \
\
l25,l26,l27,l28,l29, \
l30,l31,l32,l33,l34, \
l35,l36,l37,l38,l39, \
l40,l41,l42,l43,l44, \
l45,l46,l47,l48 \
) \
{ \
l25,l26,l27,l28,l29, \
l30,l31,l32,l33,l34, \
l35,l36,l37,l38,l39, \
l40,l41,l42,l43,l44, \
l45,l46,l47,l48, \
\
l05,l04,l03,l02,l01, \
l10,l09,l08,l07,l06, \
l15,l14,l13,l12,l11, \
l20,l19,l18,l17,l16, \
l24,l23,l22,l21 \
}

View File

@ -0,0 +1,133 @@
#include "betalupi_ergodox.h"
#ifdef SWAP_HANDS_ENABLE
__attribute__ ((weak))
// swap-hands action needs a matrix to define the swap
const keypos_t hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
/* Left hand, matrix positions */
{{0,13}, {1,13}, {2,13}, {3,13}, {4,13}, {5,13}},
{{0,12}, {1,12}, {2,12}, {3,12}, {4,12}, {5,12}},
{{0,11}, {1,11}, {2,11}, {3,11}, {4,11}, {5,11}},
{{0,10}, {1,10}, {2,10}, {3,10}, {4,10}, {5,10}},
{{0,9}, {1,9}, {2,9}, {3,9}, {4,9}, {5,9}},
{{0,8}, {1,8}, {2,8}, {3,8}, {4,8}, {5,8}},
{{0,7}, {1,7}, {2,7}, {3,7}, {4,7}, {5,7}},
/* Right hand, matrix positions */
{{0,6}, {1,6}, {2,6}, {3,6}, {4,6}, {5,6}},
{{0,5}, {1,5}, {2,5}, {3,5}, {4,5}, {5,5}},
{{0,4}, {1,4}, {2,4}, {3,4}, {4,4}, {5,4}},
{{0,3}, {1,3}, {2,3}, {3,3}, {4,3}, {5,3}},
{{0,2}, {1,2}, {2,2}, {3,2}, {4,2}, {5,2}},
{{0,1}, {1,1}, {2,1}, {3,1}, {4,1}, {5,1}},
{{0,0}, {1,0}, {2,0}, {3,0}, {4,0}, {5,0}},
};
#endif
#ifdef RGB_MATRIX_ENABLE
void suspend_power_down_kb(void) {
rgb_matrix_set_suspend_state(true);
suspend_power_down_user();
}
void suspend_wakeup_init_kb(void) {
rgb_matrix_set_suspend_state(false);
suspend_wakeup_init_user();
}
const is31_led g_is31_leds[RGB_MATRIX_LED_COUNT] = {
//{driver, R location, G location, B location}
{0, C3_1, C2_1, C4_1}, // LED1 on right
{0, C6_1, C5_1, C7_1}, // LED2
{0, C4_2, C3_2, C5_2}, // LED3
{0, C7_2, C6_2, C8_2}, // LED4
{0, C2_3, C1_3, C3_3}, // LED5
{0, C5_3, C4_3, C6_3}, // LED6
{0, C8_3, C7_3, C9_3}, // LED7
{0, C2_4, C1_4, C3_4}, // LED8
{0, C6_4, C5_4, C7_4}, // LED9
{0, C2_5, C1_5, C3_5}, // LED10
{0, C7_5, C6_5, C8_5}, // LED11
{0, C2_6, C1_6, C3_6}, // LED12
{0, C5_6, C4_6, C6_6}, // LED13
{0, C8_6, C7_6, C9_6}, // LED14
{0, C2_7, C1_7, C3_7}, // LED15
{0, C5_7, C4_7, C6_7}, // LED16
{0, C2_8, C1_8, C3_8}, // LED17
{0, C5_8, C4_8, C6_8}, // LED18
{0, C3_9, C2_9, C4_9}, // LED19
{0, C6_9, C5_9, C7_9}, // LED20
{0, C4_10, C3_10, C5_10}, // LED21
{0, C7_10, C6_10, C8_10}, // LED22
{0, C2_11, C1_11, C3_11}, // LED23
{0, C5_11, C4_11, C6_11}, // LED24
{1, C3_1, C2_1, C4_1}, // LED1 on left
{1, C6_1, C5_1, C7_1}, // LED2
{1, C4_2, C3_2, C5_2}, // LED3
{1, C7_2, C6_2, C8_2}, // LED4
{1, C2_3, C1_3, C3_3}, // LED5
{1, C5_3, C4_3, C6_3}, // LED6
{1, C8_3, C7_3, C9_3}, // LED7
{1, C2_4, C1_4, C3_4}, // LED8
{1, C6_4, C5_4, C7_4}, // LED9
{1, C2_5, C1_5, C3_5}, // LED10
{1, C7_5, C6_5, C8_5}, // LED11
{1, C2_6, C1_6, C3_6}, // LED12
{1, C5_6, C4_6, C6_6}, // LED13
{1, C8_6, C7_6, C9_6}, // LED14
{1, C2_7, C1_7, C3_7}, // LED15
{1, C5_7, C4_7, C6_7}, // LED16
{1, C2_8, C1_8, C3_8}, // LED17
{1, C5_8, C4_8, C6_8}, // LED18
{1, C3_9, C2_9, C4_9}, // LED19
{1, C6_9, C5_9, C7_9}, // LED20
{1, C4_10, C3_10, C5_10}, // LED21
{1, C7_10, C6_10, C8_10}, // LED22
{1, C2_11, C1_11, C3_11}, // LED23
{1, C5_11, C4_11, C6_11} // LED24
};
led_config_t g_led_config = { {
// Key matrix to LED index
{ NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED },
{ 28, 33, 38, 43, 47, NO_LED },
{ 27, 32, 37, 42, 46, NO_LED },
{ 26, 31, 36, 41, 45, NO_LED },
{ 25, 30, 35, 40, 44, NO_LED },
{ 24, 29, 34, 39, NO_LED, NO_LED },
{ NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED },
{ NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED },
{ 0, 5, 10, 15, NO_LED, NO_LED },
{ 1, 6, 11, 16, 20, NO_LED },
{ 2, 7, 12, 17, 21, NO_LED },
{ 3, 8, 13, 18, 22, NO_LED },
{ 4, 9, 14, 19, 23, NO_LED },
{ NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED }
}, {
// LED index to physical position
{ 137, 0 }, { 154, 0 }, { 172, 0 }, { 189, 0 }, { 206, 0 }, { 137, 12 },
{ 154, 12 }, { 172, 12 }, { 189, 12 }, { 206, 12 }, { 137, 25 }, { 154, 25 },
{ 172, 25 }, { 189, 25 }, { 206, 25 }, { 137, 38 }, { 154, 38 }, { 172, 38 },
{ 189, 38 }, { 206, 38 }, { 154, 51 }, { 172, 51 }, { 189, 51 }, { 206, 51 },
{ 86, 0 }, { 68, 0 }, { 51, 0 }, { 34, 0 }, { 17, 0 }, { 86, 12 },
{ 68, 12 }, { 51, 12 }, { 34, 12 }, { 17, 12 }, { 86, 25 }, { 68, 25 },
{ 51, 25 }, { 34, 25 }, { 17, 25 }, { 86, 38 }, { 68, 38 }, { 51, 38 },
{ 34, 38 }, { 17, 38 }, { 68, 51 }, { 51, 51 }, { 34, 51 }, { 17, 51 }
}, {
// LED index to flag
4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4,
4, 4, 1, 1, 1, 1,
4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4,
4, 4, 1, 1, 1, 1
} };
#endif

View File

@ -0,0 +1,227 @@
#include <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include "wait.h"
#include "action_layer.h"
#include "print.h"
#include "debug.h"
#include "util.h"
#include "matrix.h"
#include "debounce.h"
#include "betalupi_ergodox.h"
/*
* This constant define not debouncing time in msecs, assuming eager_pr.
*
* 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.
*
* However, some switches seem to have higher debouncing requirements, or
* something else might be wrong. (Also, the scan speed has improved since
* that comment was written.)
*/
/* 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 read_cols(uint8_t row);
static void init_cols(void);
static void unselect_rows(void);
static void select_row(uint8_t row);
static uint8_t mcp23018_reset_loop;
void matrix_init_custom(void) {
// initialize row and col
mcp23018_status = init_mcp23018();
unselect_rows();
init_cols();
}
// 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;
}
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();
#ifdef RGB_MATRIX_ENABLE
rgb_matrix_init(); // re-init driver on reconnect
#endif
}
}
}
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();
}
return changed;
}
/* Column pin configuration
*
* Teensy
* col: 0 1 2 3 4 5
* pin: F0 F1 F4 F5 F6 F7
*
* MCP23018
* col: 0 1 2 3 4 5
* 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);
}
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;
}
} 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
*
* Teensy
* row: 7 8 9 10 11 12 13
* pin: B0 B1 B2 B3 D2 D3 C6
*
* MCP23018
* row: 0 1 2 3 4 5 6
* 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);
}
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();
}
} 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;
}
}
}
// DO NOT REMOVE
// Needed for proper wake/sleep
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;
}
}