updated matrix to match PCB; made pin direction an option

- rows are now 0..6, cols now 0..D (matching the pics Fredrik posted of
  his first flippable PCB)
- either rows or columns can now be the driving pins.  the option is in
  ".../keyboard/.../options.h"
partial-rewrite
Ben Blazak 2012-08-19 21:16:52 -07:00
parent ff1708796b
commit b11d8780d9
7 changed files with 337 additions and 235 deletions

View File

@ -1,11 +1,20 @@
- change stuff to correspond with the PCB Fredrik made
-+ change stuff to correspond with the PCB Fredrik made
- rows 0..6, cols 0..13
- write macros so that either rows or columns can be the driving pins (macro
-+ write macros so that either rows or columns can be the driving pins (macro
should be set in the keyboard/.../controller folder somewhere, i think)
- set them by default to match the direction of keyswitch internal diodes; if
-- set them by default to match the direction of keyswitch internal diodes; if
fredrik or dominic put theirs together differently first, i can change the
default to match theirs
+ can't do this, since i don't know which direction internal diodes go!
lol, and i can't seem to find it online. i left a note in the file where
the direction is set (.../keyboard/.../options.h), and hopefully i'll
updated it later (maybe when i get my brown switches). :)
-+ (test)
- (check in)
- (merge)
- (push)
- write the python script for Ben, to extract all that useful stuff from the
.map file and comments

View File

@ -2388,7 +2388,7 @@
sodipodi:role="line"
x="-339.98328"
y="299.83008"
id="tspan12254">col 6</tspan></text>
id="tspan12254">col D</tspan></text>
<text
inkscape:transform-center-y="-4.6435547"
transform="matrix(0,-1,1,0,0,0)"
@ -2401,7 +2401,7 @@
sodipodi:role="line"
x="-340.12976"
y="259.83008"
id="tspan12258">col 4</tspan></text>
id="tspan12258">col B</tspan></text>
<text
transform="matrix(0,-1,1,0,0,0)"
xml:space="preserve"
@ -2413,7 +2413,7 @@
sodipodi:role="line"
x="-340.41687"
y="279.83008"
id="tspan12260">col 5</tspan></text>
id="tspan12260">col C</tspan></text>
<text
transform="matrix(0,-1,1,0,0,0)"
xml:space="preserve"
@ -2425,7 +2425,7 @@
sodipodi:role="line"
x="-300.33484"
y="119.83008"
id="tspan12264">col 0</tspan></text>
id="tspan12264">col 7</tspan></text>
<path
style="fill:none;stroke:#aaaa00;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker11070);display:inline"
d="m 135,127.11218 0,-20.5"
@ -2485,7 +2485,7 @@
sodipodi:role="line"
x="-335.29382"
y="539.83008"
id="tspan12264-1">row B</tspan></text>
id="tspan12264-1">row 5</tspan></text>
<text
transform="matrix(0,-1,1,0,0,0)"
xml:space="preserve"
@ -2497,7 +2497,7 @@
id="tspan13492"
sodipodi:role="line"
x="-334.98328"
y="559.83008">row A</tspan></text>
y="559.83008">row 4</tspan></text>
<text
transform="matrix(0,-1,1,0,0,0)"
xml:space="preserve"
@ -2509,7 +2509,7 @@
id="tspan13494"
sodipodi:role="line"
x="-334.88953"
y="579.83008">row 9</tspan></text>
y="579.83008">row 3</tspan></text>
<text
transform="matrix(0,-1,1,0,0,0)"
xml:space="preserve"
@ -2521,7 +2521,7 @@
id="tspan13496"
sodipodi:role="line"
x="-335.12976"
y="599.83008">row 8</tspan></text>
y="599.83008">row 2</tspan></text>
<text
transform="matrix(0,-1,1,0,0,0)"
xml:space="preserve"
@ -2533,7 +2533,7 @@
id="tspan13498"
sodipodi:role="line"
x="-335.41687"
y="619.83008">row 7</tspan></text>
y="619.83008">row 1</tspan></text>
<text
transform="matrix(0,-1,1,0,0,0)"
xml:space="preserve"
@ -2545,7 +2545,7 @@
id="tspan13502"
sodipodi:role="line"
x="-335.04187"
y="639.83008">row 6</tspan></text>
y="639.83008">row 0</tspan></text>
<text
inkscape:transform-center-y="-3"
inkscape:transform-center-x="-20.5"
@ -2559,7 +2559,7 @@
sodipodi:role="line"
x="-112.33308"
y="558.26935"
id="tspan12234-5">col 1</tspan></text>
id="tspan12234-5">col 5</tspan></text>
<text
inkscape:transform-center-y="-3"
inkscape:transform-center-x="-20.5"
@ -2573,7 +2573,7 @@
id="tspan13461"
sodipodi:role="line"
x="-113.42294"
y="578.09943">col 2</tspan></text>
y="578.09943">col 4</tspan></text>
<text
inkscape:transform-center-y="-3"
inkscape:transform-center-x="-20.5"
@ -2601,7 +2601,7 @@
id="tspan13465"
sodipodi:role="line"
x="-113.42294"
y="618.09943">col 4</tspan></text>
y="618.09943">col 2</tspan></text>
<text
inkscape:transform-center-y="-3"
inkscape:transform-center-x="-20.5"
@ -2615,7 +2615,7 @@
id="tspan13467"
sodipodi:role="line"
x="-113.42294"
y="638.09943">col 5</tspan></text>
y="638.09943">col 1</tspan></text>
<text
inkscape:transform-center-y="-3"
inkscape:transform-center-x="-20.5"
@ -2629,7 +2629,7 @@
id="tspan13469"
sodipodi:role="line"
x="-112.33308"
y="658.26935">col 6</tspan></text>
y="658.26935">col 0</tspan></text>
<path
style="fill:none;stroke:#aaaa00;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker11070);display:inline"
d="m 275,247.36218 0,59.74443"
@ -2787,7 +2787,7 @@
sodipodi:role="line"
x="-112.3392"
y="538.26208"
id="tspan12234-5-3">col 0</tspan></text>
id="tspan12234-5-3">col 6</tspan></text>
<path
style="fill:none;stroke:#770000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#DotM-10-7);marker-end:url(#DotM-10-7);display:inline"
d="m 275.03546,127.24605 c 0.90412,-34.974223 19.03956,-22.61202 7.77819,-102.530485"
@ -2805,7 +2805,7 @@
sodipodi:role="line"
x="-300.46454"
y="139.9549"
id="tspan12264-7">col 1</tspan></text>
id="tspan12264-7">col 8</tspan></text>
<path
style="fill:none;stroke:#aaaa00;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker11070);display:inline"
d="m 135.12482,247.5319 0,20.5"
@ -2823,7 +2823,7 @@
sodipodi:role="line"
x="-300.39969"
y="159.94453"
id="tspan12264-5">col 2</tspan></text>
id="tspan12264-5">col 9</tspan></text>
<path
style="fill:none;stroke:#aaaa00;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker11070);display:inline"
d="m 155.11445,247.46705 0,20.5"
@ -2841,7 +2841,7 @@
sodipodi:role="line"
x="-300.52939"
y="180.06935"
id="tspan12264-7-6">col 3</tspan></text>
id="tspan12264-7-6">col A</tspan></text>
<path
style="fill:none;stroke:#aaaa00;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker11070);display:inline"
d="m 175.23927,247.59677 0,20.5"

Before

Width:  |  Height:  |  Size: 158 KiB

After

Width:  |  Height:  |  Size: 158 KiB

View File

@ -11,11 +11,20 @@
#include <stdint.h>
#include <util/twi.h>
#include "../../../lib/twi.h" // `TWI_FREQ` defined in "teensy-2-0.c"
#include "../options.h"
#include "../matrix.h"
#include "./mcp23018--functions.h"
// ----------------------------------------------------------------------------
// check options
#if (MCP23018__DRIVE_ROWS && MCP23018__DRIVE_COLUMNS) \
|| !(MCP23018__DRIVE_ROWS || MCP23018__DRIVE_COLUMNS)
#error "See 'Pin drive direction' in 'options.h'"
#endif
// ----------------------------------------------------------------------------
// register addresses (see "mcp23018.md")
#define IODIRA 0x00 // i/o direction register
#define IODIRB 0x01
@ -45,32 +54,42 @@ uint8_t mcp23018_init(void) {
// set pin direction
// - unused : input : 1
// - row : input : 1
// - column : output : 0
// - input : input : 1
// - driving : output : 0
twi_start();
ret = twi_send(TWI_ADDR_WRITE);
if (ret) goto out; // make sure we got an ACK
twi_send(IODIRA);
twi_send(0b10000000); // IODIRA
twi_send(0b11111111); // IODIRB
#if MCP23018__DRIVE_ROWS
twi_send(0b11111111); // IODIRA
twi_send(0b11000000); // IODIRB
#elif MCP23018__DRIVE_COLUMNS
twi_send(0b10000000); // IODIRA
twi_send(0b11111111); // IODIRB
#endif
twi_stop();
// set pull-up
// - unused : on : 1
// - rows : on : 1
// - columns : off : 0
// - input : on : 1
// - driving : off : 0
twi_start();
ret = twi_send(TWI_ADDR_WRITE);
if (ret) goto out; // make sure we got an ACK
twi_send(GPPUA);
twi_send(0b10000000); // GPPUA
twi_send(0b11111111); // GPPUB
#if MCP23018__DRIVE_ROWS
twi_send(0b11111111); // GPPUA
twi_send(0b11000000); // GPPUB
#elif MCP23018__DRIVE_COLUMNS
twi_send(0b10000000); // GPPUA
twi_send(0b11111111); // GPPUB
#endif
twi_stop();
// set logical value (doesn't matter on inputs)
// - unused : high (hi-Z) : 1
// - rows : high (hi-Z) : 1
// - columns : high (hi-Z) : 1
// - unused : hi-Z : 1
// - input : hi-Z : 1
// - driving : hi-Z : 1
twi_start();
ret = twi_send(TWI_ADDR_WRITE);
if (ret) goto out; // make sure we got an ACK
@ -87,7 +106,7 @@ out:
* - success: 0
* - failure: twi status code
*/
#if KB_ROWS != 12 || KB_COLUMNS != 7
#if KB_ROWS != 6 || KB_COLUMNS != 14
#error "Expecting different keyboard dimensions"
#endif
uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
@ -102,43 +121,85 @@ uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
// if there was an error
if (ret) {
// clear our part of the matrix
for (uint8_t row=0x6; row<=0xB; row++)
for (uint8_t row=0; row<=5; row++)
for (uint8_t col=0; col<=6; col++)
matrix[row][col] = 0;
return ret;
}
// update our part of the matrix
for (uint8_t col=0; col<=6; col++) {
// set active column low : 0
// set other columns high (hi-Z) : 1
twi_start();
twi_send(TWI_ADDR_WRITE);
twi_send(OLATA);
twi_send( 0xFF & ~(1<<(6-col)) );
twi_stop();
// read row data
// --------------------------------------------------------------------
// update our part of the matrix
#if MCP23018__DRIVE_ROWS
for (uint8_t row=0; row<=5; row++) {
// set active row low : 0
// set other rows hi-Z : 1
twi_start();
twi_send(TWI_ADDR_WRITE);
twi_send(GPIOB);
twi_send( 0xFF & ~(1<<(5-row)) );
twi_stop();
// read column data
twi_start();
twi_send(TWI_ADDR_WRITE);
twi_send(GPIOA);
twi_start();
twi_send(TWI_ADDR_READ);
twi_read(&data);
twi_stop();
// update matrix
for (uint8_t col=0; col<=6; col++) {
matrix[row][col] = !( data & (1<<col) );
}
}
// set all rows hi-Z : 1
twi_start();
twi_send(TWI_ADDR_WRITE);
twi_send(GPIOB);
twi_start();
twi_send(TWI_ADDR_READ);
twi_read(&data);
twi_send(0xFF);
twi_stop();
// update matrix
for (uint8_t row=0x6; row<=0xB; row++)
matrix[row][col] = !( data & (1<<(5-(row-6))) );
}
#elif MCP23018__DRIVE_COLUMNS
for (uint8_t col=0; col<=6; col++) {
// set active column low : 0
// set other columns hi-Z : 1
twi_start();
twi_send(TWI_ADDR_WRITE);
twi_send(GPIOA);
twi_send( 0xFF & ~(1<<col) );
twi_stop();
// set all columns high (hi-Z) : 1
twi_start();
twi_send(TWI_ADDR_WRITE);
twi_send(GPIOA);
twi_send(0xFF);
twi_stop();
// read row data
twi_start();
twi_send(TWI_ADDR_WRITE);
twi_send(GPIOB);
twi_start();
twi_send(TWI_ADDR_READ);
twi_read(&data);
twi_stop();
// update matrix
for (uint8_t row=0; row<=5; row++) {
matrix[row][col] = !( data & (1<<(5-row)) );
}
}
// set all columns hi-Z : 1
twi_start();
twi_send(TWI_ADDR_WRITE);
twi_send(GPIOA);
twi_send(0xFF);
twi_stop();
#endif
// /update our part of the matrix
// --------------------------------------------------------------------
return ret; // success
}

View File

@ -27,13 +27,13 @@
power_negative Vss(GND) +01---.---28o NC
NC o02 27o GPA7
row_B GPB0 +03 26+ GPA6 column_0
row_A GPB1 +04 25+ GPA5 column_1
row_9 GPB2 +05 24+ GPA4 column_2
row_8 GPB3 +06 23+ GPA3 column_3
row_7 GPB4 +07 22+ GPA2 column_4
row_6 GPB5 +08 21+ GPA1 column_5
GPB6 o09 20+ GPA0 column_6
row_5 GPB0 +03 26+ GPA6 column_6
row_4 GPB1 +04 25+ GPA5 column_5
row_3 GPB2 +05 24+ GPA4 column_4
row_2 GPB3 +06 23+ GPA3 column_3
row_1 GPB4 +07 22+ GPA2 column_2
row_0 GPB5 +08 21+ GPA1 column_1
GPB6 o09 20+ GPA0 column_0
GPB7 o10 19o INTA
power_positive Vdd(Vcc) +11 18o INTB
I2C SCL +12 17o NC
@ -42,10 +42,11 @@
* notes:
* Row and column assignments are to matrix positions, which may or may
correspond to the physical position of the key: e.g. the key where
`row_8` and `column_2` cross will be scanned into the matrix at `[8][2]`,
wherever it happens to be located on the keyboard. Mapping from one to
the other (which only matters for defining layouts) is handled elsewhere.
or may not correspond to the physical position of the key: e.g. the key
where `row_4` and `column_2` cross will be scanned into the matrix at
`[4][2]`, wherever it happens to be located on the keyboard. Mapping
from one to the other (which only matters for defining layouts) is
handled elsewhere.
* ADDR (pin15): Set slave address to `0b0100000` by connecting to Vss(GND).
* The user-defined bits are the three least significant
* I2C addresses are 7 bits long (the last bit in the byte is used for
@ -85,10 +86,10 @@
* notes:
* All addresses given for IOCON.BANK = 0, since that's the default value of
the bit, and that's what we'll be using.
* We want the column pins set as output high (hi-Z) without pull-ups
initially, and the row pins set as input with pull-ups. We'll cycle
through driving the column pins low and checking the row pins in the
update function.
* Initially, we want either columns or rows (see <../options.h>) set as
hi-Z without pull-ups, and the other set of pins set as input with
pull-ups. During the update function, we'll cycle through setting the
first set low and checking each pin in the second set.
* abbreviations:
* IODIR = I/O Direction Register

View File

@ -15,26 +15,35 @@
#include <avr/io.h>
#include <util/delay.h>
#include "../../../lib/twi.h"
#include "../options.h"
#include "../matrix.h"
#include "./teensy-2-0--functions.h"
#include "./teensy-2-0--led.h"
// ----------------------------------------------------------------------------
// check options
#if (TEENSY__DRIVE_ROWS && TEENSY__DRIVE_COLUMNS) \
|| !(TEENSY__DRIVE_ROWS || TEENSY__DRIVE_COLUMNS)
#error "See 'Pin drive direction' in 'options.h'"
#endif
// ----------------------------------------------------------------------------
// processor frequency (from <http://www.pjrc.com/teensy/prescaler.html>)
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
#define CPU_16MHz 0x00
#define CPU_8MHz 0x01
#define CPU_4MHz 0x02
#define CPU_2MHz 0x03
#define CPU_1MHz 0x04
#define CPU_500kHz 0x05
#define CPU_250kHz 0x06
#define CPU_125kHz 0x07
#define CPU_62kHz 0x08
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
#define CPU_16MHz 0x00
#define CPU_8MHz 0x01
#define CPU_4MHz 0x02
#define CPU_2MHz 0x03
#define CPU_1MHz 0x04
#define CPU_500kHz 0x05
#define CPU_250kHz 0x06
#define CPU_125kHz 0x07
#define CPU_62kHz 0x08
/* pin macros
/*
* pin macros
* - note: you can move the `UNUSED`, `ROW`, and `COLUMN` pins around, but be
* sure to keep the set of all the pins listed constant. other pins are not
* movable, and either are referenced explicitly or have macros defined for
@ -43,20 +52,48 @@
* "teensy-2-0.md", and the '.svg' circuit diagram.
*/
// --- helpers
#define _teensypin_write(register, operation, pin_letter, pin_number) \
((register##pin_letter) operation (1<<(pin_number)))
#define teensypin_write(register, operation, pin) do { \
_teensypin_write(register, operation, pin); \
_delay_us(1); /* allow pins time to stabilize */ \
} while(0)
// --- unused
#define UNUSED_0 C, 7
#define UNUSED_1 D, 7
#define UNUSED_2 D, 4 // hard to use with breadboard (on the end)
#define UNUSED_3 D, 5 // hard to use with breadboard (on the end)
#define UNUSED_4 E, 6 // hard to use with breadboard (internal)
#define _teensypin_read(pin_letter, pin_number) \
// --- rows
#define ROW_0 F, 7
#define ROW_1 F, 6
#define ROW_2 F, 5
#define ROW_3 F, 4
#define ROW_4 F, 1
#define ROW_5 F, 0
// --- columns
#define COLUMN_7 B, 0
#define COLUMN_8 B, 1
#define COLUMN_9 B, 2
#define COLUMN_A B, 3
#define COLUMN_B D, 2
#define COLUMN_C D, 3
#define COLUMN_D C, 6
// --- helpers
#define SET |=
#define CLEAR &=~
#define _teensypin_write(register, operation, pin_letter, pin_number) \
do { \
((register##pin_letter) operation (1<<(pin_number))); \
_delay_us(1); /* allow pins time to stabilize */ \
} while(0)
#define teensypin_write(register, operation, pin) \
_teensypin_write(register, operation, pin)
#define _teensypin_read(pin_letter, pin_number) \
((PIN##pin_letter) & (1<<(pin_number)))
#define teensypin_read(pin) \
#define teensypin_read(pin) \
_teensypin_read(pin)
#define teensypin_write_all_unused(register, operation) \
#define teensypin_write_all_unused(register, operation) \
do { \
teensypin_write(register, operation, UNUSED_0); \
teensypin_write(register, operation, UNUSED_1); \
@ -65,7 +102,7 @@
teensypin_write(register, operation, UNUSED_4); } \
while(0)
#define teensypin_write_all_row(register, operation) \
#define teensypin_write_all_row(register, operation) \
do { \
teensypin_write(register, operation, ROW_0); \
teensypin_write(register, operation, ROW_1); \
@ -75,43 +112,51 @@
teensypin_write(register, operation, ROW_5); } \
while(0)
#define teensypin_write_all_column(register, operation) \
#define teensypin_write_all_column(register, operation) \
do { \
teensypin_write(register, operation, COLUMN_0); \
teensypin_write(register, operation, COLUMN_1); \
teensypin_write(register, operation, COLUMN_2); \
teensypin_write(register, operation, COLUMN_3); \
teensypin_write(register, operation, COLUMN_4); \
teensypin_write(register, operation, COLUMN_5); \
teensypin_write(register, operation, COLUMN_6); } \
teensypin_write(register, operation, COLUMN_7); \
teensypin_write(register, operation, COLUMN_8); \
teensypin_write(register, operation, COLUMN_9); \
teensypin_write(register, operation, COLUMN_A); \
teensypin_write(register, operation, COLUMN_B); \
teensypin_write(register, operation, COLUMN_C); \
teensypin_write(register, operation, COLUMN_D); } \
while(0)
#define SET |=
#define CLEAR &=~
// --- unused
#define UNUSED_0 C, 7
#define UNUSED_1 D, 7
#define UNUSED_2 D, 4 // hard to use with breadboard (on the end)
#define UNUSED_3 D, 5 // hard to use with breadboard (on the end)
#define UNUSED_4 E, 6 // hard to use with breadboard (internal)
/*
* update macros
*/
#define update_rows_for_column(matrix, column) \
do { \
/* set column low (set as output) */ \
teensypin_write(DDR, SET, COLUMN_##column); \
/* read rows 0..5 and update matrix */ \
matrix[0x0][0x##column] = ! teensypin_read(ROW_0); \
matrix[0x1][0x##column] = ! teensypin_read(ROW_1); \
matrix[0x2][0x##column] = ! teensypin_read(ROW_2); \
matrix[0x3][0x##column] = ! teensypin_read(ROW_3); \
matrix[0x4][0x##column] = ! teensypin_read(ROW_4); \
matrix[0x5][0x##column] = ! teensypin_read(ROW_5); \
/* set column hi-Z (set as input) */ \
teensypin_write(DDR, CLEAR, COLUMN_##column); \
} while(0)
// --- rows
#define ROW_0 F, 7
#define ROW_1 F, 6
#define ROW_2 F, 5
#define ROW_3 F, 4
#define ROW_4 F, 1
#define ROW_5 F, 0
// --- columns
#define COLUMN_0 B, 0
#define COLUMN_1 B, 1
#define COLUMN_2 B, 2
#define COLUMN_3 B, 3
#define COLUMN_4 D, 2
#define COLUMN_5 D, 3
#define COLUMN_6 C, 6
#define update_columns_for_row(matrix, row) \
do { \
/* set row low (set as output) */ \
teensypin_write(DDR, SET, ROW_##row); \
/* read columns 7..D and update matrix */ \
matrix[0x##row][0x7] = ! teensypin_read(COLUMN_7); \
matrix[0x##row][0x8] = ! teensypin_read(COLUMN_8); \
matrix[0x##row][0x9] = ! teensypin_read(COLUMN_9); \
matrix[0x##row][0xA] = ! teensypin_read(COLUMN_A); \
matrix[0x##row][0xB] = ! teensypin_read(COLUMN_B); \
matrix[0x##row][0xC] = ! teensypin_read(COLUMN_C); \
matrix[0x##row][0xD] = ! teensypin_read(COLUMN_D); \
/* set row hi-Z (set as input) */ \
teensypin_write(DDR, CLEAR, ROW_##row); \
} while(0)
// ----------------------------------------------------------------------------
@ -146,14 +191,16 @@ uint8_t teensy_init(void) {
teensypin_write_all_unused(DDR, CLEAR); // set as input
teensypin_write_all_unused(PORT, SET); // set internal pull-up enabled
// rows
teensypin_write_all_row(DDR, CLEAR); // set as input
teensypin_write_all_row(PORT, SET); // set internal pull-up enabled
// columns
teensypin_write_all_column(DDR, CLEAR); // set as input (hi-Z)
teensypin_write_all_column(PORT, CLEAR); // set internal pull-up
// disabled
// rows and columns
teensypin_write_all_row(DDR, CLEAR); // set as input (hi-Z)
teensypin_write_all_column(DDR, CLEAR); // set as input (hi-Z)
#if TEENSY__DRIVE_ROWS
teensypin_write_all_row(PORT, CLEAR); // pull-up disabled
teensypin_write_all_column(PORT, SET); // pull-up enabled
#elif TEENSY__DRIVE_COLUMNS
teensypin_write_all_row(PORT, SET); // pull-up enabled
teensypin_write_all_column(PORT, CLEAR); // pull-up disabled
#endif
return 0; // success
}
@ -161,47 +208,27 @@ uint8_t teensy_init(void) {
/* returns
* - success: 0
*/
#if KB_ROWS != 12 || KB_COLUMNS != 7
#if KB_ROWS != 6 || KB_COLUMNS != 14
#error "Expecting different keyboard dimensions"
#endif
static inline void _update_rows(
bool matrix[KB_ROWS][KB_COLUMNS], uint8_t column ) {
matrix[0][column] = ! teensypin_read(ROW_0);
matrix[1][column] = ! teensypin_read(ROW_1);
matrix[2][column] = ! teensypin_read(ROW_2);
matrix[3][column] = ! teensypin_read(ROW_3);
matrix[4][column] = ! teensypin_read(ROW_4);
matrix[5][column] = ! teensypin_read(ROW_5);
}
uint8_t teensy_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
teensypin_write(DDR, SET, COLUMN_0); // set col low (set as output)
_update_rows(matrix, 0); // read row 0..5 & update matrix
teensypin_write(DDR, CLEAR, COLUMN_0); // set col hi-Z (set as input)
teensypin_write(DDR, SET, COLUMN_1);
_update_rows(matrix, 1);
teensypin_write(DDR, CLEAR, COLUMN_1);
teensypin_write(DDR, SET, COLUMN_2);
_update_rows(matrix, 2);
teensypin_write(DDR, CLEAR, COLUMN_2);
teensypin_write(DDR, SET, COLUMN_3);
_update_rows(matrix, 3);
teensypin_write(DDR, CLEAR, COLUMN_3);
teensypin_write(DDR, SET, COLUMN_4);
_update_rows(matrix, 4);
teensypin_write(DDR, CLEAR, COLUMN_4);
teensypin_write(DDR, SET, COLUMN_5);
_update_rows(matrix, 5);
teensypin_write(DDR, CLEAR, COLUMN_5);
teensypin_write(DDR, SET, COLUMN_6);
_update_rows(matrix, 6);
teensypin_write(DDR, CLEAR, COLUMN_6);
#if TEENSY__DRIVE_ROWS
update_columns_for_row(matrix, 0);
update_columns_for_row(matrix, 1);
update_columns_for_row(matrix, 2);
update_columns_for_row(matrix, 3);
update_columns_for_row(matrix, 4);
update_columns_for_row(matrix, 5);
#elif TEENSY__DRIVE_COLUMNS
update_rows_for_column(matrix, 7);
update_rows_for_column(matrix, 8);
update_rows_for_column(matrix, 9);
update_rows_for_column(matrix, A);
update_rows_for_column(matrix, B);
update_rows_for_column(matrix, C);
update_rows_for_column(matrix, D);
#endif
return 0; // success
}

View File

@ -29,16 +29,16 @@
### Teensy 2.0 Pin Assignments
power_negative GND +---.....---+ Vcc power_positive
column_0 PB0 + + PF0 row_5
column_1 PB1 + + PF1 row_4
column_2 PB2 + + PF4 row_3
column_3 PB3 + o o + PF5 row_2
column_7 PB0 + + PF0 row_5
column_8 PB1 + + PF1 row_4
column_9 PB2 + + PF4 row_3
column_A PB3 + o o + PF5 row_2
(OC1C) LED_3 PB7 + PE6 AREF + PF6 row_1
(SCL) I2C PD0 + + PF7 row_0
(SDA) I2C PD1 + + PB6 LED_2 (OC1B)
column_4 PD2 + + PB5 LED_1 (OC1A)
column_5 PD3 + + PB4 = Vcc
column_6 PC6 + o PD7
column_B PD2 + + PB5 LED_1 (OC1A)
column_C PD3 + + PB4 = Vcc
column_D PC6 + o PD7
PC7 o-o-o-o-o-o-+ PD6 onboardLED = GND
PD5 --/ | | | \-- PD4
Vcc ----/ | \---- RST
@ -46,10 +46,13 @@
* notes:
* Row and column assignments are to matrix positions, which may or may
correspond to the physical position of the key: e.g. the key where
`row_4` and `column_2` cross will be scanned into the matrix at `[4][2]`,
wherever it happens to be located on the keyboard. Mapping from one to
the other (which only matters for defining layouts) is handled elsewhere.
or may not correspond to the physical position of the key: e.g. the key
where `row_4` and `column_2` cross will be scanned into the matrix at
`[4][2]`, wherever it happens to be located on the keyboard. Mapping
from one to the other (which only matters for defining layouts) is
handled elsewhere.
* LEDs are labeled using numbers (starting with '1') instead of letters
(starting with 'A') as on the PCB.
* SCL and SDA: Need external pull-up resistors. Sometimes the Teensy
internal pull-ups are enough (see datasheet section 20.5.1), but i think
for this project we'll want external ones. The general recommendation
@ -76,14 +79,16 @@
* PD6 (the onboard LED) already has a defined level (low), so there's no
reason to set internal pull-up enabled on it. If we do, it will source
current to the LED, which is fine, but unnecessary.
* We want the columns to be hi-Z when that column's not being scanned,
drive low when it is, and the rows to be input with pull-up enabled.
We'll cycle through driving the columns low and scanning all rows.
* Initially, we want either columns or rows (see <../options.h>) set as
hi-Z without pull-ups, and the other set of pins set as input with
pull-ups. During the update function, we'll cycle through setting the
first set low and checking each pin in the second set.
* To set a pin hi-Z on this board, set it as input with pull-up
disabled.
* Switching the row pins between hi-Z and drive low (treating them as
if they were open drain) seems just as good as, and a little safer
than, driving them high when the row's not active.
* Switching the driving pins (the first set of pins) between hi-Z and
drive low (treating them as if they were open drain) seems just as
good as, and a little safer than, driving them high when they're not
active.
* We need to delay for at least 1 μs between changing the column pins and
reading the row pins. I would assume this is to allow the pins time to
stabalize.

View File

@ -12,8 +12,8 @@
// --------------------------------------------------------------------
#define KB_ROWS 12 // must match real life
#define KB_COLUMNS 7 // must match real life
#define KB_ROWS 6 // must match real life
#define KB_COLUMNS 14 // must match real life
// --------------------------------------------------------------------
@ -27,56 +27,55 @@
* and 'column' are single digit hex numbers corresponding to the
* matrix position (which also corresponds to the row and column pin
* labels used in the teensy and mcp23018 files)
* - coordinates not listed are unused
*
* - coordinates in the thumb group with row=1|7 are for optional keys
* - coordinates
* - optional keys
* k15, k16 (left hand thumb group)
* k17, k18 (right hand thumb group)
* - unused keys
* k36, k00 (left hand)
* k37, k0D (right hand)
*
* --- other info -----------------------------------------------------
* rows x columns = positions; used, unused
* per hand: 6 x 7 = 42; 40, 2
* total: 12 x 7 = 84; 80, 4
* per hand: 6 x 7 = 42; 40, 2
* total: 6 x 14 = 84; 80, 4
*
* left hand : cols 0..6, rows 6..B
* right hand : cols 0..6, rows 0..5
* left hand : rows 0..5, cols 0..6
* right hand : rows 0..5, cols 7..D
* --------------------------------------------------------------------
*/
#define KB_MATRIX_LAYER( \
/* for unused positions */ \
na, \
\
/* left hand, spatial positions */ \
kB6,kB5,kB4,kB3,kB2,kB1,kB0, \
kA6,kA5,kA4,kA3,kA2,kA1,kA0, \
k96,k95,k94,k93,k92,k91, \
k86,k85,k84,k83,k82,k81,k80, \
k76,k75,k74,k73,k72, \
k63,k71, \
k64,k70,k61, \
k65,k62,k60, \
\
/* right hand, spatial positions */ \
k50,k51,k52,k53,k54,k55,k56, \
k40,k41,k42,k43,k44,k45,k46, \
k31,k32,k33,k34,k35,k36, \
k20,k21,k22,k23,k24,k25,k26, \
k12,k13,k14,k15,k16, \
k11,k03, \
k01,k10,k04, \
k00,k02,k05 ) \
\
/* matrix positions */ \
{ { k00,k01,k02,k03,k04,k05, na,}, \
{ k10,k11,k12,k13,k14,k15,k16,}, \
{ k20,k21,k22,k23,k24,k25,k26,}, \
{ na,k31,k32,k33,k34,k35,k36,}, \
{ k40,k41,k42,k43,k44,k45,k46,}, \
{ k50,k51,k52,k53,k54,k55,k56,}, \
{ k60,k61,k62,k63,k64,k65, na,}, \
{ k70,k71,k72,k73,k74,k75,k76,}, \
{ k80,k81,k82,k83,k84,k85,k86,}, \
{ na,k91,k92,k93,k94,k95,k96,}, \
{ kA0,kA1,kA2,kA3,kA4,kA5,kA6,}, \
{ kB0,kB1,kB2,kB3,kB4,kB5,kB6 } }
#define KB_MATRIX_LAYER( \
/* for unused positions */ \
na, \
\
/* left hand, spatial positions */ \
k50,k51,k52,k53,k54,k55,k56, \
k40,k41,k42,k43,k44,k45,k46, \
k30,k31,k32,k33,k34,k35, \
k20,k21,k22,k23,k24,k25,k26, \
k10,k11,k12,k13,k14, \
k03,k15, \
k02,k16,k05, \
k01,k04,k06, \
\
/* right hand, spatial positions */ \
k57,k58,k59,k5A,k5B,k5C,k5D, \
k47,k48,k49,k4A,k4B,k4C,k4D, \
k38,k39,k3A,k3B,k3C,k3D, \
k27,k28,k29,k2A,k2B,k2C,k2D, \
k19,k1A,k1B,k1C,k1D, \
k18,k0A, \
k08,k17,k0B, \
k07,k09,k0C ) \
\
/* matrix positions */ \
{{ na,k01,k02,k03,k04,k05,k06, k07,k08,k09,k0A,k0B,k0C, na }, \
{ k10,k11,k12,k13,k14,k15,k16, k17,k18,k19,k1A,k1B,k1C,k1D }, \
{ k20,k21,k22,k23,k24,k25,k26, k27,k28,k29,k2A,k2B,k2C,k2D }, \
{ k30,k31,k32,k33,k34,k35, na, na,k38,k39,k3A,k3B,k3C,k3D }, \
{ k40,k41,k42,k43,k44,k45,k46, k47,k48,k49,k4A,k4B,k4C,k4D }, \
{ k50,k51,k52,k53,k54,k55,k56, k57,k58,k59,k5A,k5B,k5C,k5D }}
#define KB_MATRIX_LAYER_SET_ALL(na, kxx) \