Permalink
Browse files

Swap matrix rows & columns, wire up the LEDs, play with ghosting

  • Loading branch information...
1 parent 3e56b4d commit afc4d0f23be23e8c69bc1dfbe127898a7fe82db7 @lmorchard committed Feb 15, 2016
Showing with 105 additions and 125 deletions.
  1. +2 −2 keyboard/modelm/config.h
  2. +17 −9 keyboard/modelm/keymap.c
  3. +15 −21 keyboard/modelm/led.c
  4. +71 −93 keyboard/modelm/matrix.c
@@ -29,8 +29,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define DESCRIPTION t.m.k. keyboard firmware for IBM Model M
/* matrix size */
-#define MATRIX_ROWS 8
-#define MATRIX_COLS 16
+#define MATRIX_ROWS 16
+#define MATRIX_COLS 8
/* define if matrix has ghost */
#define MATRIX_HAS_GHOST
@@ -40,16 +40,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
K1A, K1B, K1C, K1D, K1E, K1F, K1G, K1H, K1I, K1J, K1K, K1L, K1M, K1N, K1O, K1P, K1Q, \
K0A, K0B, K0C, K0D, K0E, K0F, K0G, K0H, K0I, K0J \
) { \
-/* 00 */ { KC_NO, KC_NO, KC_##K5A, KC_NO, KC_##K5E, KC_##K2F, KC_##K5F, KC_##K2G, KC_##K5G, KC_NO, KC_##K2L, KC_NO, KC_##K0I, KC_##K0J, KC_##K1M, KC_##K0B }, \
-/* 01 */ { KC_NO, KC_##K1A, KC_##K3A, KC_##K2A, KC_##K5D, KC_##K3F, KC_##K4N, KC_##K3G, KC_##K3M, KC_##K5H, KC_##K3L, KC_##K2N, KC_##K2O, KC_##K2P, KC_NO, KC_NO }, \
-/* 02 */ { KC_##K0A, KC_NO, KC_##K4A, KC_##K5B, KC_##K5C, KC_##K4F, KC_##K5J, KC_##K4G, KC_##K4M, KC_##K5I, KC_##K4L, KC_##K3O, KC_##K4O, KC_##K4Q, KC_##K4P, KC_NO }, \
-/* 03 */ { KC_NO, KC_NO, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E, KC_##K5K, KC_##K4H, KC_##K4I, KC_##K4J, KC_##K4K, KC_##K5L, KC_##K5M, KC_##K3Q, KC_##K3P, KC_##K5N }, \
-/* 04 */ { KC_NO, KC_NO, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_NO, KC_##K3H, KC_##K3I, KC_##K3J, KC_##K3K, KC_##K3R, KC_##K3S, KC_##K3T, KC_##K3U, KC_##K5O }, \
-/* 05 */ { KC_NO, KC_NO, KC_##K2B, KC_##K2C, KC_##K2D, KC_##K2E, KC_##K3N, KC_##K2H, KC_##K2I, KC_##K2J, KC_##K2K, KC_##K1N, KC_##K1O, KC_##K1P, KC_##K1Q, KC_NO }, \
-/* 06 */ { KC_##K0E, KC_##K1L, KC_##K1B, KC_##K1C, KC_##K1D, KC_##K1E, KC_##K2M, KC_##K1H, KC_##K1I, KC_##K1J, KC_NO, KC_##K4R, KC_##K4S, KC_##K4T, KC_##K5P, KC_NO }, \
-/* 07 */ { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_##K1F, KC_##K0C, KC_##K1G, KC_NO, KC_NO, KC_##K1K, KC_##K0G, KC_##K0H, KC_##K4U, KC_##K0F, KC_##K0D } \
+/* 00 */ { KC_NO, KC_NO, KC_##K0A, KC_NO, KC_NO, KC_NO, KC_##K0E, KC_NO }, \
+/* 01 */ { KC_NO, KC_##K1A, KC_NO, KC_NO, KC_NO, KC_NO, KC_##K1L, KC_NO }, \
+/* 02 */ { KC_##K5A, KC_##K3A, KC_##K4A, KC_##K4B, KC_##K3B, KC_##K2B, KC_##K1B, KC_NO }, \
+/* 03 */ { KC_NO, KC_##K2A, KC_##K5B, KC_##K4C, KC_##K3C, KC_##K2C, KC_##K1C, KC_NO }, \
+/* 04 */ { KC_##K5E, KC_##K5D, KC_##K5C, KC_##K4D, KC_##K3D, KC_##K2D, KC_##K1D, KC_NO }, \
+/* 05 */ { KC_##K2F, KC_##K3F, KC_##K4F, KC_##K4E, KC_##K3E, KC_##K2E, KC_##K1E, KC_##K1F }, \
+/* 06 */ { KC_##K5F, KC_##K4N, KC_##K5J, KC_##K5K, KC_NO, KC_##K3N, KC_##K2M, KC_##K0C }, \
+/* 07 */ { KC_##K2G, KC_##K3G, KC_##K4G, KC_##K4H, KC_##K3H, KC_##K2H, KC_##K1H, KC_##K1G }, \
+/* 08 */ { KC_##K5G, KC_##K3M, KC_##K4M, KC_##K4I, KC_##K3I, KC_##K2I, KC_##K1I, KC_NO }, \
+/* 09 */ { KC_NO, KC_##K5H, KC_##K5I, KC_##K4J, KC_##K3J, KC_##K2J, KC_##K1J, KC_NO }, \
+/* 0A */ { KC_##K2L, KC_##K3L, KC_##K4L, KC_##K4K, KC_##K3K, KC_##K2K, KC_NO, KC_##K1K }, \
+/* 0B */ { KC_NO, KC_##K2N, KC_##K3O, KC_##K5L, KC_##K3R, KC_##K1N, KC_##K4R, KC_##K0G }, \
+/* 0C */ { KC_##K0I, KC_##K2O, KC_##K4O, KC_##K5M, KC_##K3S, KC_##K1O, KC_##K4S, KC_##K0H }, \
+/* 0D */ { KC_##K0J, KC_##K2P, KC_##K4Q, KC_##K3Q, KC_##K3T, KC_##K1P, KC_##K4T, KC_##K4U }, \
+/* 0E */ { KC_##K1M, KC_NO, KC_##K4P, KC_##K3P, KC_##K3U, KC_##K1Q, KC_##K5P, KC_##K0F }, \
+/* 0F */ { KC_##K0B, KC_NO, KC_NO, KC_##K5N, KC_##K5O, KC_NO, KC_NO, KC_##K0D } \
}
-/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+/* 0 1 2 3 4 5 6 7 */
static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KEYMAP(
View
@@ -21,29 +21,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
void led_set(uint8_t usb_led)
{
- if (usb_led & (1<<USB_LED_CAPS_LOCK))
- {
- // Output high.
- DDRB |= (1<<6);
- PORTB |= (1<<6);
- }
- else
- {
- // Output low.
- DDRB &= ~(1<<6);
- PORTB &= ~(1<<6);
+ DDRB |= (1 << 6) | (1 << 5) | (1 << 4);
+
+ if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
+ PORTB &= ~(1 << 4);
+ } else {
+ PORTB |= (1 << 4);
}
- if (usb_led & (1<<USB_LED_SCROLL_LOCK))
- {
- // Output high.
- DDRB |= (1<<7);
- PORTB |= (1<<7);
+ if (usb_led & (1<<USB_LED_SCROLL_LOCK)) {
+ PORTB &= ~(1 << 5);
+ } else {
+ PORTB |= (1 << 5);
}
- else
- {
- // Output low.
- DDRB &= ~(1<<7);
- PORTB &= ~(1<<7);
+
+ if (usb_led & (1<<USB_LED_NUM_LOCK)) {
+ PORTB &= ~(1 << 6);
+ } else {
+ PORTB |= (1 << 6);
}
}
@@ -27,7 +27,10 @@ static uint8_t debouncing = DEBOUNCE;
static matrix_row_t matrix[MATRIX_ROWS];
static matrix_row_t matrix_debouncing[MATRIX_ROWS];
-static uint8_t read_rows(void);
+#ifdef MATRIX_HAS_GHOST
+static bool matrix_has_ghost_in_row(uint8_t row);
+#endif
+static uint16_t read_rows(void);
static void init_rows(void);
static void unselect_cols(void);
static void select_col(uint8_t col);
@@ -98,8 +101,8 @@ uint8_t matrix_scan(void)
{
for (uint8_t col = 0; col < MATRIX_COLS; col++) { // 0-16
select_col(col);
- _delay_us(3); // without this wait it won't read stable value.
- uint8_t rows = read_rows();
+ _delay_us(30); // without this wait it won't read stable value.
+ uint16_t rows = read_rows();
for (uint8_t row = 0; row < MATRIX_ROWS; row++) { // 0-5
bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col);
bool curr_bit = rows & (1<<row);
@@ -145,13 +148,47 @@ 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++) {
xprintf("%02X: %032lb\n", row, bitrev32(matrix_get_row(row)));
}
}
+*/
+
+void matrix_print(void)
+{
+ print("\nr/c 01234567\n");
+ for (uint8_t row = 0; row < matrix_rows(); row++) {
+ phex(row); print(": ");
+ pbin_reverse(matrix_get_row(row));
+#ifdef MATRIX_HAS_GHOST
+ if (matrix_has_ghost_in_row(row)) {
+ print(" <ghost");
+ }
+#endif
+ print("\n");
+ }
+}
+
+#ifdef MATRIX_HAS_GHOST
+inline
+static bool matrix_has_ghost_in_row(uint8_t row)
+{
+ // no ghost exists in case less than 2 keys on
+ if (((matrix[row] - 1) & matrix[row]) == 0)
+ return false;
+
+ // ghost exists in case same state as other row
+ for (uint8_t i=0; i < MATRIX_ROWS; i++) {
+ if (i != row && (matrix[i] & matrix[row]))
+ return true;
+ }
+ return false;
+}
+#endif
uint8_t matrix_key_count(void)
{
@@ -163,112 +200,53 @@ uint8_t matrix_key_count(void)
}
/* Row pin configuration
- * row: 0 1 2 3 4 5 6 7
- * pin: B6 B5 B4 B3 B2 B1 B0 E7
+ * row: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ * pin: C7 C6 C5 C4 C3 C2 C1 C0 E1 E0 D7 D6 D5 D4 D3 D2
*/
static void init_rows(void)
{
// Input with pull-up(DDR:0, PORT:1)
- DDRB &= ~0b01111111;
- PORTB |= 0b01111111;
- DDRE &= ~0b10000000;
- PORTE |= 0b10000000;
+ DDRC &= ~0b11111111;
+ PORTC |= 0b11111111;
+ DDRE &= ~0b00000011;
+ PORTE |= 0b00000011;
+ DDRD &= ~0b11111100;
+ PORTD |= 0b11111100;
}
-static uint8_t read_rows(void)
+static uint16_t read_rows(void)
{
- return (PINB&(1<<6) ? 0 : (1<<0)) |
- (PINB&(1<<5) ? 0 : (1<<1)) |
- (PINB&(1<<4) ? 0 : (1<<2)) |
- (PINB&(1<<3) ? 0 : (1<<3)) |
- (PINB&(1<<2) ? 0 : (1<<4)) |
- (PINB&(1<<1) ? 0 : (1<<5)) |
- (PINB&(1<<0) ? 0 : (1<<6)) |
- (PINE&(1<<7) ? 0 : (1<<7));
+ return (PINC&(1<<7) ? 0 : (1<<0)) |
+ (PINC&(1<<6) ? 0 : (1<<1)) |
+ (PINC&(1<<5) ? 0 : (1<<2)) |
+ (PINC&(1<<4) ? 0 : (1<<3)) |
+ (PINC&(1<<3) ? 0 : (1<<4)) |
+ (PINC&(1<<2) ? 0 : (1<<5)) |
+ (PINC&(1<<1) ? 0 : (1<<6)) |
+ (PINC&(1<<0) ? 0 : (1<<7)) |
+ (PINE&(1<<1) ? 0 : (1<<8)) |
+ (PINE&(1<<0) ? 0 : (1<<9)) |
+ (PIND&(1<<7) ? 0 : (1<<10)) |
+ (PIND&(1<<6) ? 0 : (1<<11)) |
+ (PIND&(1<<5) ? 0 : (1<<12)) |
+ (PIND&(1<<4) ? 0 : (1<<13)) |
+ (PIND&(1<<3) ? 0 : (1<<14)) |
+ (PIND&(1<<2) ? 0 : (1<<15));
}
/* Column pin configuration
- * col: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- * pin: C7 C6 C5 C4 C3 C2 C1 C0 E1 E0 D7 D6 D5 D4 D3 D2
+ * col: 0 1 2 3 4 5 6 7
+ * pin: F0 F1 F2 F3 F4 F5 F6 E7
*/
static void unselect_cols(void)
{
// Hi-Z(DDR:0, PORT:0) to unselect
- DDRC |= 0b11111111; // PC: 7 6 5 4 3 2 1 0
- PORTC |= 0b11111111;
- DDRE |= 0b00000011; // PE: 1 0
- PORTE |= 0b00000011;
- DDRD |= 0b11111100; // PD: 7 6 5 4 3 2
- PORTD |= 0b11111100;
+ DDRF |= 0b11111111; // PB: 7 6 5 4 3 2 1 0
+ PORTF |= 0b11111111;
}
static void select_col(uint8_t col)
{
- // Output low(DDR:1, PORT:0) to select
- switch (col) {
- case 0:
- DDRC |= (1<<7);
- PORTC &= ~(1<<7);
- break;
- case 1:
- DDRC |= (1<<6);
- PORTC &= ~(1<<6);
- break;
- case 2:
- DDRC |= (1<<5);
- PORTC &= ~(1<<5);
- break;
- case 3:
- DDRC |= (1<<4);
- PORTC &= ~(1<<4);
- break;
- case 4:
- DDRC |= (1<<3);
- PORTC &= ~(1<<3);
- break;
- case 5:
- DDRC |= (1<<2);
- PORTC &= ~(1<<2);
- break;
- case 6:
- DDRC |= (1<<1);
- PORTC &= ~(1<<1);
- break;
- case 7:
- DDRC |= (1<<0);
- PORTC &= ~(1<<0);
- break;
- case 8:
- DDRE |= (1<<1);
- PORTE &= ~(1<<1);
- break;
- case 9:
- DDRE |= (1<<0);
- PORTE &= ~(1<<0);
- break;
- case 10:
- DDRD |= (1<<7);
- PORTD &= ~(1<<7);
- break;
- case 11:
- DDRD |= (1<<6);
- PORTD &= ~(1<<6);
- break;
- case 12:
- DDRD |= (1<<5);
- PORTD &= ~(1<<5);
- break;
- case 13:
- DDRD |= (1<<4);
- PORTD &= ~(1<<4);
- break;
- case 14:
- DDRD |= (1<<3);
- PORTD &= ~(1<<3);
- break;
- case 15:
- DDRD |= (1<<2);
- PORTD &= ~(1<<2);
- break;
- }
+ DDRF |= (1 << col);
+ PORTF &= ~(1 << col);
}

0 comments on commit afc4d0f

Please sign in to comment.