checkin before deleting the debug code; almost ready for first beta!

- simple bug fix in kbfun_press() and kbfun_release()
- no longer check for previous init() in the mcp23018 functions;
  something would happen when i tried to read from it, sometimes, when
  it'd been unplugged or stoped some other way, and it would hang - and
  the only thing that would make it better was running the test_twi_2
  function (a series of writes, with stops after each).  so now
  mcp23018_init() is a series of writes, with stops after each.  it
  doesn't take appreciably longer to run...  maybe it should be looked
  into later though.
- changed the main() loop a little
partial-rewrite
Ben Blazak 2012-04-10 18:58:26 -07:00
parent 57e82aebcf
commit cd6826eeb5
6 changed files with 103 additions and 116 deletions

View File

@ -135,16 +135,6 @@
: pdf (from <http://www.usb.org/developers/hidpage>)
## Miscellaneous
* [Markdown: Syntax]
(http://daringfireball.net/projects/markdown/syntax)
* [Keyboard Scan Rates]
(http://geekhack.org/showwiki.php?title=Keyboard+scan+rates)
list (on <http://geekhack.org/>)
## Other Firmware / Code
* zip: [Phantom Firmware from PrinsValium]
@ -208,7 +198,7 @@
(http://pjrc.com/teensy/gcc.html)
## Chip Documentation
## Hardware Documentation
* [Microchip: Analog & Interface Product Selector Guide]
(http://ww1.microchip.com/downloads/en/DeviceDoc/21060z.pdf)
@ -252,6 +242,20 @@
* from [the PJRC website]
(http://pjrc.com/teensy/datasheets.html)
* [Cherry MX Series Keyswitches : Specifications]
(http://www.cherrycorp.com/english/switches/key/mx.htm)
## Miscellaneous
* [Markdown: Syntax]
(http://daringfireball.net/projects/markdown/syntax)
* [Keyboard Scan Rates]
(http://geekhack.org/showwiki.php?title=Keyboard+scan+rates)
list (on <http://geekhack.org/>)
-------------------------------------------------------------------------------
Copyright &copy; 2012 Ben Blazak <benblazak.dev@gmail.com>

View File

@ -43,8 +43,10 @@ void kbfun_press(
uint8_t * row, uint8_t * col ) {
for (uint8_t i=0; i<6; i++)
if (keyboard_keys[i] == 0)
if (keyboard_keys[i] == 0) {
keyboard_keys[i] = *keycode;
break;
}
}
void kbfun_release(
@ -52,8 +54,10 @@ void kbfun_release(
uint8_t * row, uint8_t * col ) {
for (uint8_t i=0; i<6; i++)
if (keyboard_keys[i] == *keycode)
if (keyboard_keys[i] == *keycode) {
keyboard_keys[i] = 0;
break;
}
}
void kbfun_mod_press(

View File

@ -6,11 +6,6 @@
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
// TODO: still working on all this
// - need to separate the 'check if everything's all right' function, i think
// - do more error checking in update_matrix() ?
// - does update_matrix() really need a helper function? can it be conditional?
// - [and lots of stuff, just need to clean it up] :)
#include <util/twi.h>
@ -37,46 +32,28 @@
#define TWI_ADDR_READ ( (MCP23018_TWI_ADDRESS<<1) | TW_READ )
// ----------------------------------------------------------------------------
/* returns:
* - success: 0
* - failure: twi status code
*
* notes:
* - this checks whether the device is initialized by reading from it. not the
* most efficient method, but easy and fairly reliable.
* - `twi_stop()` must be called *exactly once* for each twi block, the way
* things are currently set up. this may change in the future.
*/
static uint8_t _init(bool release_twi_bus) {
static bool initialized;
uint8_t ret, data;
// check for errors and previous initialization
twi_start();
ret = twi_send(TWI_ADDR_WRITE);
if (ret) goto out; // address write failed (no ACK)
twi_send(OLATA);
twi_start();
twi_send(TWI_ADDR_READ);
ret = twi_read(&data);
if (ret) goto out; // read failed
if (data == 0xFF) goto out; // already initialized (OLATA == 0xFF)
// initialize things, if we need to and we can
uint8_t mcp23018_init(void) {
uint8_t ret;
// set pin direction
// - unused : input : 1
// - rows : output : 0
// - columns : input : 1
twi_start();
twi_send(TWI_ADDR_WRITE);
ret = twi_send(TWI_ADDR_WRITE);
if (ret) goto out; // make sure we got an ACK
twi_send(IODIRA);
twi_send(0b11000000); // IODIRA
twi_send(0b11111111); // IODIRB
twi_stop();
// set pull-up
// - unused : on : 1
@ -87,6 +64,7 @@ static uint8_t _init(bool release_twi_bus) {
twi_send(GPPUA);
twi_send(0b11000000); // GPPUA
twi_send(0b11111111); // GPPUB
twi_stop();
// set logical value (doesn't matter on inputs)
// - unused : high (hi-Z) : 1
@ -99,25 +77,10 @@ static uint8_t _init(bool release_twi_bus) {
twi_send(0b11111111); //OLATB
out:
if (release_twi_bus)
twi_stop();
if (ret) initialized = false;
else initialized = true;
twi_stop();
return ret;
}
// ----------------------------------------------------------------------------
/* returns:
* - success: 0
* - failure: twi status code
*/
uint8_t mcp23018_init(void) {
return _init(true);
}
/* returns:
* - success: 0
* - failure: twi status code
@ -128,8 +91,11 @@ uint8_t mcp23018_init(void) {
uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
uint8_t ret, data;
// initialize things if necessary
ret = _init(false);
// 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) {
@ -138,8 +104,6 @@ uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
for (uint8_t col=0; col<=6; col++)
matrix[row][col] = 0;
// release the twi bus and return
twi_stop();
return ret;
}
@ -150,14 +114,17 @@ uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
twi_start();
twi_send(TWI_ADDR_WRITE);
twi_send(OLATA);
twi_send( 0b11111111 & ~(1<<(row-6)) ); // OLATA
twi_send( 0b11111111 & ~(1<<(row-6)) );
twi_stop();
// get column data
// read column data
twi_start();
twi_send(TWI_ADDR_WRITE);
twi_send(GPIOB);
twi_start();
twi_send(TWI_ADDR_READ);
twi_read(&data); // GPIOB
twi_read(&data);
twi_stop();
// update matrix
for (uint8_t col=0; col<=6; col++)
@ -169,9 +136,8 @@ uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
twi_send(TWI_ADDR_WRITE);
twi_send(GPIOA);
twi_send(0b11111111);
// release the twi bus and return
twi_stop();
return 0; // success
return ret; // success
}

View File

@ -19,6 +19,7 @@
* ------------------------------------------------------------------------- */
#include <util/delay.h> //dbg
#include <util/twi.h>
#include "twi.h"

View File

@ -14,39 +14,30 @@
#include "lib/data-types.h"
// #include "keyboard.h"
//dbg
#define KEYBOARD_INCLUDE_PRIVATE
#include "keyboard/ergodox/teensy-2-0.h"
#include "keyboard/ergodox/mcp23018.h"
#include "keyboard.h"
///
#define DEBOUNCE_TIME 5 // in ms; see the spec for your keyswitches
//dbg
int main(void) {
kb_init(); // does controller initialization too
usb_init();
while (!usb_configured());
_delay_ms(1000); // make sure the OS has had time to load drivers, etc.
for (;;) {
// int current_layer = 0;
KB_LED1_ON; _delay_ms(200); KB_LED1_OFF; _delay_ms(200);
KB_LED1_ON; _delay_ms(200); KB_LED1_OFF; _delay_ms(200);
// for (int row=0; row<KB_ROWS; row++)
// for (int col=0; col<KB_COLUMNS; col++)
// (*kb_is_pressed)[row][col] = 0;
// kb_update_matrix(*kb_is_pressed);
//
// for (int row=0; row<KB_ROWS; row++) {
// for (int col=0; col<KB_COLUMNS; col++) {
// if ((*kb_is_pressed)[row][col]) {
// usb_keyboard_press(kb_layout[current_layer][row][col], 0);
// }
// }
// }
static void _toggle_led3(void) {
static bool led_on = false;
if (led_on) {
KB_LED3_OFF;
led_on = false;
} else {
KB_LED3_ON;
led_on = true;
}
}
#if 0 //dbg
///
int main(void) {
kb_init(); // does controller initialization too
@ -55,6 +46,15 @@ int main(void) {
_delay_ms(1000); // make sure the OS has had time to load drivers, etc.
for (;;) {
//dbg
// KB_LED1_ON; _delay_ms(200); KB_LED1_OFF; _delay_ms(200); //dbg
static int counter=0;
if (counter == 0)
_toggle_led3();
counter++;
if (counter >= 1000)
counter = 0;
///
static uint8_t current_layer = 0;
// swap `kb_is_pressed` and `kb_was_pressed`, then update
@ -64,35 +64,47 @@ int main(void) {
kb_update_matrix(*kb_is_pressed);
// call the appropriate function for each key, then send the report
for (uint8_t row=0; row<KB_ROWS; row++)
for (uint8_t col=0; col<KB_COLUMNS; col++)
if (*kb_is_pressed[row][col] != *kb_was_pressed[row][col]) {
if (!*kb_is_pressed[row][col])
if (*kb_layout_press[current_layer][row][col])
(*kb_layout_press[current_layer][row][col])(
// call the appropriate function for each key, then send the report if
// necessary
for (uint8_t row=0; row<KB_ROWS; row++) {
for (uint8_t col=0; col<KB_COLUMNS; col++) {
bool is_pressed = (*kb_is_pressed)[row][col];
bool was_pressed = (*kb_was_pressed)[row][col];
if (is_pressed != was_pressed) {
if (is_pressed) {
kbfun_funptr_t press_function =
kb_layout_press[current_layer][row][col];
if (press_function) {
(*press_function)(
&kb_layout[current_layer][row][col],
&current_layer, &row, &col );
} else
if (*kb_layout_release[current_layer][row][col])
(*kb_layout_release[current_layer][row][col])(
}
} else {
kbfun_funptr_t release_function =
kb_layout_release[current_layer][row][col];
if (release_function) {
(*release_function)(
&kb_layout[current_layer][row][col],
&current_layer, &row, &col );
}
}
}
usb_keyboard_send();
usb_keyboard_send();
_delay_ms(DEBOUNCE_TIME);
}
}
}
// update LEDs
(keyboard_leds & (1<<0)) ? KB_LED1_ON : KB_LED1_OFF; // num lock
(keyboard_leds & (1<<1)) ? KB_LED2_ON : KB_LED2_OFF; // caps lock
(keyboard_leds & (1<<2)) ? KB_LED3_ON : KB_LED3_OFF; // scroll lock
#if 0 // not implemented right now
// (keyboard_leds & (1<<0)) ? KB_LED1_ON : KB_LED1_OFF; // num lock
// (keyboard_leds & (1<<1)) ? KB_LED2_ON : KB_LED2_OFF; // caps lock
// (keyboard_leds & (1<<2)) ? KB_LED3_ON : KB_LED3_OFF; // scroll lock
#if 0 // not implemented right now
(keyboard_leds & (1<<3)) ? KB_LED4_ON : KB_LED4_OFF; // compose
(keyboard_leds & (1<<4)) ? KB_LED5_ON : KB_LED5_OFF; // kana
#endif
#endif
}
return 0;
}
#endif

View File

@ -8,7 +8,7 @@
# -----------------------------------------------------------------------------
TARGET = ergodox-firmware
TARGET = firmware
SRC = $(shell find -maxdepth 1 -name '*.c') \
$(shell find ./keyboard -name '*.c') \