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
parent
ff1708796b
commit
b11d8780d9
15
src/TODO
15
src/TODO
|
@ -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
|
||||
|
|
|
@ -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 |
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) \
|
||||
|
|
Loading…
Reference in New Issue