refactor
parent
8344f05b60
commit
14d0d1cad6
|
@ -35,3 +35,406 @@ uint8_t kb_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
|
||||||
|
|
||||||
return 0; // success
|
return 0; // success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// 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
|
||||||
|
#define GPPUA 0x0C // GPIO pull-up resistor register
|
||||||
|
#define GPPUB 0x0D
|
||||||
|
#define GPIOA 0x12 // general purpose i/o port register (write modifies OLAT)
|
||||||
|
#define GPIOB 0x13
|
||||||
|
#define OLATA 0x14 // output latch register
|
||||||
|
#define OLATB 0x15
|
||||||
|
|
||||||
|
// TWI aliases
|
||||||
|
#define TWI_ADDR_WRITE ( (MCP23018_TWI_ADDRESS<<1) | TW_WRITE )
|
||||||
|
#define TWI_ADDR_READ ( (MCP23018_TWI_ADDRESS<<1) | TW_READ )
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* returns:
|
||||||
|
* - success: 0
|
||||||
|
* - failure: twi status code
|
||||||
|
*
|
||||||
|
* notes:
|
||||||
|
* - `twi_stop()` must be called *exactly once* for each twi block, the way
|
||||||
|
* things are currently set up. this may change in the future.
|
||||||
|
*/
|
||||||
|
uint8_t mcp23018_init(void) {
|
||||||
|
uint8_t ret;
|
||||||
|
|
||||||
|
// set pin direction
|
||||||
|
// - unused : input : 1
|
||||||
|
// - 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);
|
||||||
|
#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
|
||||||
|
// - 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);
|
||||||
|
#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 : 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
|
||||||
|
twi_send(OLATA);
|
||||||
|
twi_send(0b11111111); //OLATA
|
||||||
|
twi_send(0b11111111); //OLATB
|
||||||
|
|
||||||
|
out:
|
||||||
|
twi_stop();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns:
|
||||||
|
* - success: 0
|
||||||
|
* - failure: twi status code
|
||||||
|
*/
|
||||||
|
#if KB_ROWS != 6 || KB_COLUMNS != 14
|
||||||
|
#error "Expecting different keyboard dimensions"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
|
||||||
|
uint8_t ret, data;
|
||||||
|
|
||||||
|
// initialize things, just to make sure
|
||||||
|
// - it's not appreciably faster to skip this, and it takes care of the
|
||||||
|
// case when the i/o expander isn't plugged in during the first
|
||||||
|
// init()
|
||||||
|
ret = mcp23018_init();
|
||||||
|
|
||||||
|
// if there was an error
|
||||||
|
if (ret) {
|
||||||
|
// clear our part of the matrix
|
||||||
|
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
|
||||||
|
|
||||||
|
#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_send(0xFF);
|
||||||
|
twi_stop();
|
||||||
|
|
||||||
|
#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();
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
* them elsewhere.
|
||||||
|
* - note: if you change pin assignments, please be sure to update
|
||||||
|
* "teensy-2-0.md", and the '.svg' circuit diagram.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// --- 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)
|
||||||
|
|
||||||
|
// --- 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) \
|
||||||
|
_teensypin_read(pin)
|
||||||
|
|
||||||
|
#define teensypin_write_all_unused(register, operation) \
|
||||||
|
do { \
|
||||||
|
teensypin_write(register, operation, UNUSED_0); \
|
||||||
|
teensypin_write(register, operation, UNUSED_1); \
|
||||||
|
teensypin_write(register, operation, UNUSED_2); \
|
||||||
|
teensypin_write(register, operation, UNUSED_3); \
|
||||||
|
teensypin_write(register, operation, UNUSED_4); } \
|
||||||
|
while(0)
|
||||||
|
|
||||||
|
#define teensypin_write_all_row(register, operation) \
|
||||||
|
do { \
|
||||||
|
teensypin_write(register, operation, ROW_0); \
|
||||||
|
teensypin_write(register, operation, ROW_1); \
|
||||||
|
teensypin_write(register, operation, ROW_2); \
|
||||||
|
teensypin_write(register, operation, ROW_3); \
|
||||||
|
teensypin_write(register, operation, ROW_4); \
|
||||||
|
teensypin_write(register, operation, ROW_5); } \
|
||||||
|
while(0)
|
||||||
|
|
||||||
|
#define teensypin_write_all_column(register, operation) \
|
||||||
|
do { \
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
|
||||||
|
#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)
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* returns
|
||||||
|
* - success: 0
|
||||||
|
*/
|
||||||
|
uint8_t teensy_init(void) {
|
||||||
|
// CPU speed : should match F_CPU in makefile
|
||||||
|
#if F_CPU != 16000000
|
||||||
|
#error "Expecting different CPU frequency"
|
||||||
|
#endif
|
||||||
|
CPU_PRESCALE(CPU_16MHz);
|
||||||
|
|
||||||
|
// onboard LED
|
||||||
|
// (tied to GND for hardware convenience)
|
||||||
|
DDRD &= ~(1<<6); // set D(6) as input
|
||||||
|
PORTD &= ~(1<<6); // set D(6) internal pull-up disabled
|
||||||
|
|
||||||
|
// (tied to Vcc for hardware convenience)
|
||||||
|
DDRB &= ~(1<<4); // set B(4) as input
|
||||||
|
PORTB &= ~(1<<4); // set B(4) internal pull-up disabled
|
||||||
|
|
||||||
|
// keyboard LEDs (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md")
|
||||||
|
_kb_led_all_off(); // (just to put the pins in a known state)
|
||||||
|
TCCR1A = 0b10101001; // set and configure fast PWM
|
||||||
|
TCCR1B = 0b00001001; // set and configure fast PWM
|
||||||
|
|
||||||
|
// I2C (TWI)
|
||||||
|
twi_init(); // on pins D(1,0)
|
||||||
|
|
||||||
|
// unused pins
|
||||||
|
teensypin_write_all_unused(DDR, CLEAR); // set as input
|
||||||
|
teensypin_write_all_unused(PORT, SET); // set internal pull-up enabled
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns
|
||||||
|
* - success: 0
|
||||||
|
*/
|
||||||
|
#if KB_ROWS != 6 || KB_COLUMNS != 14
|
||||||
|
#error "Expecting different keyboard dimensions"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t teensy_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
|
||||||
|
#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
|
||||||
|
}
|
||||||
|
|
|
@ -8,12 +8,73 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// for "lib/twi.h"
|
||||||
|
#define TWI_FREQ 400000
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "./controller/mcp23018.h"
|
#include <util/twi.h>
|
||||||
#include "./controller/teensy-2-0.h"
|
#include "../lib/teensy-2-0.h"
|
||||||
|
#include "./options.h"
|
||||||
|
#include "./matrix.h"
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
uint8_t kb_init(void);
|
uint8_t kb_init(void);
|
||||||
uint8_t kb_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]);
|
uint8_t kb_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define MCP23018_TWI_ADDRESS 0b0100000
|
||||||
|
|
||||||
|
uint8_t mcp23018_init(void);
|
||||||
|
uint8_t mcp23018_update_matrix( bool matrix[KB_ROWS][KB_COLUMNS] );
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
|
uint8_t teensy_init(void);
|
||||||
|
uint8_t teensy_update_matrix( bool matrix[KB_ROWS][KB_COLUMNS] );
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define _kb_led_1_on() (DDRB |= (1<<5))
|
||||||
|
#define _kb_led_1_off() (DDRB &= ~(1<<5))
|
||||||
|
#define _kb_led_1_set(n) (OCR1A = (uint8_t)(n))
|
||||||
|
#define _kb_led_1_set_percent(n) (OCR1A = (uint8_t)((n) * 0xFF))
|
||||||
|
|
||||||
|
#define _kb_led_2_on() (DDRB |= (1<<6))
|
||||||
|
#define _kb_led_2_off() (DDRB &= ~(1<<6))
|
||||||
|
#define _kb_led_2_set(n) (OCR1B = (uint8_t)(n))
|
||||||
|
#define _kb_led_2_set_percent(n) (OCR1B = (uint8_t)((n) * 0xFF))
|
||||||
|
|
||||||
|
#define _kb_led_3_on() (DDRB |= (1<<7))
|
||||||
|
#define _kb_led_3_off() (DDRB &= ~(1<<7))
|
||||||
|
#define _kb_led_3_set(n) (OCR1C = (uint8_t)(n))
|
||||||
|
#define _kb_led_3_set_percent(n) (OCR1C = (uint8_t)((n) * 0xFF))
|
||||||
|
|
||||||
|
|
||||||
|
#define _kb_led_all_on() do { \
|
||||||
|
_kb_led_1_on(); \
|
||||||
|
_kb_led_2_on(); \
|
||||||
|
_kb_led_3_on(); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define _kb_led_all_off() do { \
|
||||||
|
_kb_led_1_off(); \
|
||||||
|
_kb_led_2_off(); \
|
||||||
|
_kb_led_3_off(); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define _kb_led_all_set(n) do { \
|
||||||
|
_kb_led_1_set(n); \
|
||||||
|
_kb_led_2_set(n); \
|
||||||
|
_kb_led_3_set(n); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define _kb_led_all_set_percent(n) do { \
|
||||||
|
_kb_led_1_set_percent(n); \
|
||||||
|
_kb_led_2_set_percent(n); \
|
||||||
|
_kb_led_3_set_percent(n); \
|
||||||
|
} while(0)
|
||||||
|
|
|
@ -1,199 +0,0 @@
|
||||||
/* ----------------------------------------------------------------------------
|
|
||||||
* ergoDOX : controller: MCP23018 specific code
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
|
||||||
* Released under The MIT License (MIT) (see "license.md")
|
|
||||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
|
||||||
* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
|
|
||||||
#include "./mcp23018.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
|
|
||||||
#define GPPUA 0x0C // GPIO pull-up resistor register
|
|
||||||
#define GPPUB 0x0D
|
|
||||||
#define GPIOA 0x12 // general purpose i/o port register (write modifies OLAT)
|
|
||||||
#define GPIOB 0x13
|
|
||||||
#define OLATA 0x14 // output latch register
|
|
||||||
#define OLATB 0x15
|
|
||||||
|
|
||||||
// TWI aliases
|
|
||||||
#define TWI_ADDR_WRITE ( (MCP23018_TWI_ADDRESS<<1) | TW_WRITE )
|
|
||||||
#define TWI_ADDR_READ ( (MCP23018_TWI_ADDRESS<<1) | TW_READ )
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/* returns:
|
|
||||||
* - success: 0
|
|
||||||
* - failure: twi status code
|
|
||||||
*
|
|
||||||
* notes:
|
|
||||||
* - `twi_stop()` must be called *exactly once* for each twi block, the way
|
|
||||||
* things are currently set up. this may change in the future.
|
|
||||||
*/
|
|
||||||
uint8_t mcp23018_init(void) {
|
|
||||||
uint8_t ret;
|
|
||||||
|
|
||||||
// set pin direction
|
|
||||||
// - unused : input : 1
|
|
||||||
// - 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);
|
|
||||||
#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
|
|
||||||
// - 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);
|
|
||||||
#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 : 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
|
|
||||||
twi_send(OLATA);
|
|
||||||
twi_send(0b11111111); //OLATA
|
|
||||||
twi_send(0b11111111); //OLATB
|
|
||||||
|
|
||||||
out:
|
|
||||||
twi_stop();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns:
|
|
||||||
* - success: 0
|
|
||||||
* - failure: twi status code
|
|
||||||
*/
|
|
||||||
#if KB_ROWS != 6 || KB_COLUMNS != 14
|
|
||||||
#error "Expecting different keyboard dimensions"
|
|
||||||
#endif
|
|
||||||
uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
|
|
||||||
uint8_t ret, data;
|
|
||||||
|
|
||||||
// initialize things, just to make sure
|
|
||||||
// - it's not appreciably faster to skip this, and it takes care of the
|
|
||||||
// case when the i/o expander isn't plugged in during the first
|
|
||||||
// init()
|
|
||||||
ret = mcp23018_init();
|
|
||||||
|
|
||||||
// if there was an error
|
|
||||||
if (ret) {
|
|
||||||
// clear our part of the matrix
|
|
||||||
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
|
|
||||||
|
|
||||||
#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_send(0xFF);
|
|
||||||
twi_stop();
|
|
||||||
|
|
||||||
#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();
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
/* ----------------------------------------------------------------------------
|
|
||||||
* ergoDOX : controller : MCP23018 specific exports : functions
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
|
||||||
* Released under The MIT License (MIT) (see "license.md")
|
|
||||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
|
||||||
* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <util/twi.h>
|
|
||||||
#include "../../lib/teensy-2-0.h" // `TWI_FREQ` defined in "teensy-2-0.c"
|
|
||||||
#include "../options.h"
|
|
||||||
#include "../matrix.h"
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
|
||||||
|
|
||||||
#define MCP23018_TWI_ADDRESS 0b0100000
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
|
||||||
|
|
||||||
uint8_t mcp23018_init(void);
|
|
||||||
uint8_t mcp23018_update_matrix( bool matrix[KB_ROWS][KB_COLUMNS] );
|
|
|
@ -1,54 +0,0 @@
|
||||||
/* ----------------------------------------------------------------------------
|
|
||||||
* ergoDOX : controller : Teensy 2.0 specific exports : LED control
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
|
||||||
* Released under The MIT License (MIT) (see "license.md")
|
|
||||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
|
||||||
* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <avr/io.h> // for the register macros
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
|
||||||
|
|
||||||
#define _kb_led_1_on() (DDRB |= (1<<5))
|
|
||||||
#define _kb_led_1_off() (DDRB &= ~(1<<5))
|
|
||||||
#define _kb_led_1_set(n) (OCR1A = (uint8_t)(n))
|
|
||||||
#define _kb_led_1_set_percent(n) (OCR1A = (uint8_t)((n) * 0xFF))
|
|
||||||
|
|
||||||
#define _kb_led_2_on() (DDRB |= (1<<6))
|
|
||||||
#define _kb_led_2_off() (DDRB &= ~(1<<6))
|
|
||||||
#define _kb_led_2_set(n) (OCR1B = (uint8_t)(n))
|
|
||||||
#define _kb_led_2_set_percent(n) (OCR1B = (uint8_t)((n) * 0xFF))
|
|
||||||
|
|
||||||
#define _kb_led_3_on() (DDRB |= (1<<7))
|
|
||||||
#define _kb_led_3_off() (DDRB &= ~(1<<7))
|
|
||||||
#define _kb_led_3_set(n) (OCR1C = (uint8_t)(n))
|
|
||||||
#define _kb_led_3_set_percent(n) (OCR1C = (uint8_t)((n) * 0xFF))
|
|
||||||
|
|
||||||
|
|
||||||
#define _kb_led_all_on() do { \
|
|
||||||
_kb_led_1_on(); \
|
|
||||||
_kb_led_2_on(); \
|
|
||||||
_kb_led_3_on(); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define _kb_led_all_off() do { \
|
|
||||||
_kb_led_1_off(); \
|
|
||||||
_kb_led_2_off(); \
|
|
||||||
_kb_led_3_off(); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define _kb_led_all_set(n) do { \
|
|
||||||
_kb_led_1_set(n); \
|
|
||||||
_kb_led_2_set(n); \
|
|
||||||
_kb_led_3_set(n); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define _kb_led_all_set_percent(n) do { \
|
|
||||||
_kb_led_1_set_percent(n); \
|
|
||||||
_kb_led_2_set_percent(n); \
|
|
||||||
_kb_led_3_set_percent(n); \
|
|
||||||
} while(0)
|
|
|
@ -1,226 +0,0 @@
|
||||||
/* ----------------------------------------------------------------------------
|
|
||||||
* ergoDOX : controller: Teensy 2.0 specific code
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
|
||||||
* Released under The MIT License (MIT) (see "license.md")
|
|
||||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
|
||||||
* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
|
|
||||||
// for "lib/twi.h"
|
|
||||||
#define TWI_FREQ 400000
|
|
||||||
|
|
||||||
#include "./teensy-2-0.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
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
* them elsewhere.
|
|
||||||
* - note: if you change pin assignments, please be sure to update
|
|
||||||
* "teensy-2-0.md", and the '.svg' circuit diagram.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// --- 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)
|
|
||||||
|
|
||||||
// --- 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) \
|
|
||||||
_teensypin_read(pin)
|
|
||||||
|
|
||||||
#define teensypin_write_all_unused(register, operation) \
|
|
||||||
do { \
|
|
||||||
teensypin_write(register, operation, UNUSED_0); \
|
|
||||||
teensypin_write(register, operation, UNUSED_1); \
|
|
||||||
teensypin_write(register, operation, UNUSED_2); \
|
|
||||||
teensypin_write(register, operation, UNUSED_3); \
|
|
||||||
teensypin_write(register, operation, UNUSED_4); } \
|
|
||||||
while(0)
|
|
||||||
|
|
||||||
#define teensypin_write_all_row(register, operation) \
|
|
||||||
do { \
|
|
||||||
teensypin_write(register, operation, ROW_0); \
|
|
||||||
teensypin_write(register, operation, ROW_1); \
|
|
||||||
teensypin_write(register, operation, ROW_2); \
|
|
||||||
teensypin_write(register, operation, ROW_3); \
|
|
||||||
teensypin_write(register, operation, ROW_4); \
|
|
||||||
teensypin_write(register, operation, ROW_5); } \
|
|
||||||
while(0)
|
|
||||||
|
|
||||||
#define teensypin_write_all_column(register, operation) \
|
|
||||||
do { \
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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)
|
|
||||||
|
|
||||||
#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)
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/* returns
|
|
||||||
* - success: 0
|
|
||||||
*/
|
|
||||||
uint8_t teensy_init(void) {
|
|
||||||
// CPU speed : should match F_CPU in makefile
|
|
||||||
#if F_CPU != 16000000
|
|
||||||
#error "Expecting different CPU frequency"
|
|
||||||
#endif
|
|
||||||
CPU_PRESCALE(CPU_16MHz);
|
|
||||||
|
|
||||||
// onboard LED
|
|
||||||
// (tied to GND for hardware convenience)
|
|
||||||
DDRD &= ~(1<<6); // set D(6) as input
|
|
||||||
PORTD &= ~(1<<6); // set D(6) internal pull-up disabled
|
|
||||||
|
|
||||||
// (tied to Vcc for hardware convenience)
|
|
||||||
DDRB &= ~(1<<4); // set B(4) as input
|
|
||||||
PORTB &= ~(1<<4); // set B(4) internal pull-up disabled
|
|
||||||
|
|
||||||
// keyboard LEDs (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md")
|
|
||||||
_kb_led_all_off(); // (just to put the pins in a known state)
|
|
||||||
TCCR1A = 0b10101001; // set and configure fast PWM
|
|
||||||
TCCR1B = 0b00001001; // set and configure fast PWM
|
|
||||||
|
|
||||||
// I2C (TWI)
|
|
||||||
twi_init(); // on pins D(1,0)
|
|
||||||
|
|
||||||
// unused pins
|
|
||||||
teensypin_write_all_unused(DDR, CLEAR); // set as input
|
|
||||||
teensypin_write_all_unused(PORT, SET); // set internal pull-up enabled
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns
|
|
||||||
* - success: 0
|
|
||||||
*/
|
|
||||||
#if KB_ROWS != 6 || KB_COLUMNS != 14
|
|
||||||
#error "Expecting different keyboard dimensions"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint8_t teensy_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
|
|
||||||
#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
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
/* ----------------------------------------------------------------------------
|
|
||||||
* ergoDOX : controller : Teensy 2.0 specific exports : functions
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
|
||||||
* Released under The MIT License (MIT) (see "license.md")
|
|
||||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
|
||||||
* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include <util/delay.h>
|
|
||||||
#include "../../lib/teensy-2-0.h"
|
|
||||||
#include "../options.h"
|
|
||||||
#include "../matrix.h"
|
|
||||||
#include "./teensy-2-0--led.h"
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
|
||||||
|
|
||||||
uint8_t teensy_init(void);
|
|
||||||
uint8_t teensy_update_matrix( bool matrix[KB_ROWS][KB_COLUMNS] );
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include "../lib/keyboard.h"
|
#include "../lib/keyboard.h"
|
||||||
#include "../lib/key-functions/public.h"
|
#include "../lib/keyfunctions.h"
|
||||||
#include "./controller.h"
|
#include "./controller.h"
|
||||||
|
|
||||||
typedef void (*void_funptr_t)(void);
|
typedef void (*void_funptr_t)(void);
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
# src/lib/key-functions
|
|
||||||
|
|
||||||
These functions may do.. pretty much anything rational that they like. If they
|
|
||||||
want keycodes to be sent to the host in an aggregate report, they're responsible
|
|
||||||
for modifying the appropriate report variables.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright © 2012 Ben Blazak <benblazak.dev@gmail.com>
|
|
||||||
Released under The MIT License (MIT) (see "license.md")
|
|
||||||
Project located at <https://github.com/benblazak/ergodox-firmware>
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#include "./public.h"
|
#include "./keyfunctions.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MediaCodeLookupTable is used to translate from enumeration in keyboard.h to
|
* MediaCodeLookupTable is used to translate from enumeration in keyboard.h to
|
|
@ -12,10 +12,10 @@
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "../../main.h"
|
#include "../main.h"
|
||||||
#include "../../keyboard/layout.h"
|
#include "../keyboard/layout.h"
|
||||||
#include "../../lib-other/pjrc/usb_keyboard/usb_keyboard.h"
|
#include "../lib-other/pjrc/usb_keyboard/usb_keyboard.h"
|
||||||
#include "../../lib/keyboard.h"
|
#include "../lib/keyboard.h"
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
#include "./lib-other/pjrc/usb_keyboard/usb_keyboard.h"
|
#include "./lib-other/pjrc/usb_keyboard/usb_keyboard.h"
|
||||||
#include "./lib/key-functions/public.h"
|
#include "./lib/keyfunctions.h"
|
||||||
#include "./keyboard/controller.h"
|
#include "./keyboard/controller.h"
|
||||||
#include "./keyboard/layout.h"
|
#include "./keyboard/layout.h"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue