lots and lots; now writing/debugging keyboard logic
also, mcp23018_init() needs fixing: `twi_stop()` needs to be at the end of transmission blocks. i wouldn't think that would be necessary, but it seems to be the only thing that'll make it work, and it also seems consistent with the protocol diagram in the datasheet (lol, imagine that), so i think that's what i'll have to do. not as though it matters much i guess, since it's a single master / single slave system anyway, i was just hoping not to release the bus till i was finished..partial-rewrite
parent
92c3d541f1
commit
57e82aebcf
|
@ -70,12 +70,28 @@
|
|||
(http://www.ibiblio.org/pub/languages/fortran/append-c.html)
|
||||
(on <http://www.ibiblio.org/>)
|
||||
|
||||
* [how to use array of function pointers?]
|
||||
(http://stackoverflow.com/questions/252748/how-to-use-array-of-function-pointers)
|
||||
(on <http://stackoverflow.com/>)
|
||||
|
||||
* [The Function Pointer Tutorials]
|
||||
(http://www.newty.de/fpt/index.html)
|
||||
|
||||
* [C preprocessor and concatenation]
|
||||
(http://stackoverflow.com/questions/1489932/c-preprocessor-and-concatenation)
|
||||
(on <http://stackoverflow.com/>)
|
||||
|
||||
* [The New C: Inline Functions]
|
||||
(http://drdobbs.com/184401540)
|
||||
by Randy Meyers
|
||||
(on <http://drdobbs.com/>)
|
||||
|
||||
### For the AVR
|
||||
|
||||
* [AVR Newbie guide]
|
||||
(http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=70673)
|
||||
by stu_san (on <http://www.avrfreaks.net/>)
|
||||
|
||||
* [AVR Libc Library Reference]
|
||||
(http://www.nongnu.org/avr-libc/user-manual/modules.html)
|
||||
|
||||
|
@ -83,8 +99,9 @@
|
|||
(http://svn.savannah.nongnu.org/viewvc/trunk/avr-libc/include/avr/iom32u4.h?revision=2288&root=avr-libc&view=markup)
|
||||
: list of registers and associated bit numbers for ATmega32U4
|
||||
|
||||
* [A Brief Tutorial on Programming the AVR without Arduino] by Chris Kuethe
|
||||
* [A Brief Tutorial on Programming the AVR without Arduino]
|
||||
(https://www.mainframe.cx/~ckuethe/avr-c-tutorial/)
|
||||
by Chris Kuethe
|
||||
|
||||
## Protocol Stuff
|
||||
|
||||
|
@ -137,13 +154,22 @@
|
|||
(http://geekhack.org/showwiki.php?title=Island:26742)
|
||||
article (on <http://geekhack.org/>)
|
||||
|
||||
* github: [tmk / tmk_keyboard]
|
||||
(https://github.com/tmk/tmk_keyboard)
|
||||
|
||||
* github: [Pyrolistical / tmk_keyboard]
|
||||
(https://github.com/Pyrolistical/tmk_keyboard/tree/master/fourway)
|
||||
* forked by [Pyrolistical / tmk_keyboard]
|
||||
(https://github.com/Pyrolistical/tmk_keyboard/tree/master/fourway)
|
||||
|
||||
* mentioned in the [KeyPoard]
|
||||
(http://geekhack.org/showwiki.php?title=Island:26845)
|
||||
article (on <http://geekhack.org/>)
|
||||
* mentioned in the [KeyPoard]
|
||||
(http://geekhack.org/showwiki.php?title=Island:26845)
|
||||
article on <http://geekhack.org/>
|
||||
|
||||
* forked by [riffautae / tmk_keyboard]
|
||||
(https://github.com/riffautae/tmk_keyboard)
|
||||
|
||||
* mentioned on the [Teensy Keyboard Firmware Discussion]
|
||||
(http://geekhack.org/showthread.php?26730-Teensy-Keyboard-Firmware-Discussion/page2)
|
||||
thread on <http://geekhack.org/>
|
||||
|
||||
* github: [humblehacker / keyboard]
|
||||
(https://github.com/humblehacker/keyboard)
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* main()
|
||||
* ----------------------------------------------------------------------------
|
||||
* 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 "lib/pjrc/print.h"
|
||||
|
||||
// #include "keyboard.h"
|
||||
|
||||
|
||||
// TODO
|
||||
int main(void) {
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* key functions: 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 "lib-other/pjrc/usb_keyboard/usb_keyboard.h"
|
||||
|
||||
#include "lib/data-types.h"
|
||||
#include "lib/usb/keyboard-usage-page.h"
|
||||
|
||||
#include "keyboard.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if 0 // not being used right now
|
||||
static uint8_t _inc_current_layer(uint8_t * current_layer) {
|
||||
if (*current_layer < (KB_LAYERS-1))
|
||||
(*current_layer)++;
|
||||
else
|
||||
return 1; // error: can't increase
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
static uint8_t _dec_current_layer(uint8_t * current_layer) {
|
||||
if (*current_layer > 0)
|
||||
(*current_layer)--;
|
||||
else
|
||||
return 1; // error: can't decrease
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void kbfun_press(
|
||||
uint8_t * keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col ) {
|
||||
|
||||
for (uint8_t i=0; i<6; i++)
|
||||
if (keyboard_keys[i] == 0)
|
||||
keyboard_keys[i] = *keycode;
|
||||
}
|
||||
|
||||
void kbfun_release(
|
||||
uint8_t * keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col ) {
|
||||
|
||||
for (uint8_t i=0; i<6; i++)
|
||||
if (keyboard_keys[i] == *keycode)
|
||||
keyboard_keys[i] = 0;
|
||||
}
|
||||
|
||||
void kbfun_mod_press(
|
||||
uint8_t * keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col ) {
|
||||
|
||||
switch (*keycode) {
|
||||
case KEY_LeftControl: keyboard_modifier_keys |= (1<<0); break;
|
||||
case KEY_LeftShift: keyboard_modifier_keys |= (1<<1); break;
|
||||
case KEY_LeftAlt: keyboard_modifier_keys |= (1<<2); break;
|
||||
case KEY_LeftGUI: keyboard_modifier_keys |= (1<<3); break;
|
||||
case KEY_RightControl: keyboard_modifier_keys |= (1<<4); break;
|
||||
case KEY_RightShift: keyboard_modifier_keys |= (1<<5); break;
|
||||
case KEY_RightAlt: keyboard_modifier_keys |= (1<<6); break;
|
||||
case KEY_RightGUI: keyboard_modifier_keys |= (1<<7); break;
|
||||
}
|
||||
}
|
||||
|
||||
void kbfun_mod_release(
|
||||
uint8_t * keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col ) {
|
||||
|
||||
switch (*keycode) {
|
||||
case KEY_LeftControl: keyboard_modifier_keys &= ~(1<<0); break;
|
||||
case KEY_LeftShift: keyboard_modifier_keys &= ~(1<<1); break;
|
||||
case KEY_LeftAlt: keyboard_modifier_keys &= ~(1<<2); break;
|
||||
case KEY_LeftGUI: keyboard_modifier_keys &= ~(1<<3); break;
|
||||
case KEY_RightControl:keyboard_modifier_keys &= ~(1<<4); break;
|
||||
case KEY_RightShift: keyboard_modifier_keys &= ~(1<<5); break;
|
||||
case KEY_RightAlt: keyboard_modifier_keys &= ~(1<<6); break;
|
||||
case KEY_RightGUI: keyboard_modifier_keys &= ~(1<<7); break;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* key functions: exports
|
||||
* ----------------------------------------------------------------------------
|
||||
* 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>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef KEY_FUNCTIONS_h
|
||||
#define KEY_FUNCTIONS_h
|
||||
|
||||
#include "lib/data-types.h"
|
||||
|
||||
typedef void (*kbfun_funptr_t)(uint8_t*, uint8_t*, uint8_t*, uint8_t*);
|
||||
|
||||
void kbfun_press(
|
||||
uint8_t * keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col );
|
||||
void kbfun_release(
|
||||
uint8_t * keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col );
|
||||
void kbfun_mod_press(
|
||||
uint8_t * keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col );
|
||||
void kbfun_mod_release(
|
||||
uint8_t * keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col );
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* keyboard specific exports
|
||||
* use this file to include the keyboard you're compiling for
|
||||
* ----------------------------------------------------------------------------
|
||||
* 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 "keyboard/ergodox.h" // only supported keyboard right now
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* ergoDOX specific code: tying it all together
|
||||
* ----------------------------------------------------------------------------
|
||||
* 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 "lib/data-types.h"
|
||||
|
||||
#define KEYBOARD_INCLUDE_PRIVATE
|
||||
#include "ergodox/matrix.h"
|
||||
#include "ergodox/mcp23018.h"
|
||||
#include "ergodox/teensy-2-0.h"
|
||||
|
||||
|
||||
/* returns
|
||||
* - success: 0
|
||||
* - error: number of the function that failed
|
||||
*/
|
||||
uint8_t kb_init(void) {
|
||||
if (teensy_init()) // must be first
|
||||
return 1;
|
||||
if (mcp23018_init()) // must be second
|
||||
return 2;
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
/* returns
|
||||
* - success: 0
|
||||
* - error: number of the function that failed
|
||||
*/
|
||||
uint8_t kb_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
|
||||
if (teensy_update_matrix(matrix)) // must be first
|
||||
return 1;
|
||||
if (mcp23018_update_matrix(matrix)) // must be second
|
||||
return 2;
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* ergoDOX specific exports
|
||||
* ----------------------------------------------------------------------------
|
||||
* 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>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef ERGODOX_h
|
||||
#define ERGODOX_h
|
||||
|
||||
#include "lib/data-types.h"
|
||||
|
||||
#include "ergodox/layout.h" // number of layers, layout
|
||||
#include "ergodox/matrix.h" // kb dimensions, matrix status
|
||||
#include "ergodox/mcp23018.h" // (nothing right now)
|
||||
#include "ergodox/teensy-2-0.h" // LED controls
|
||||
|
||||
uint8_t kb_init(void);
|
||||
uint8_t kb_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]);
|
||||
|
||||
#endif
|
||||
|
|
@ -10,15 +10,20 @@
|
|||
#include "lib/data-types.h"
|
||||
#include "lib/usb/keyboard-usage-page.h"
|
||||
|
||||
#include "key-functions.h"
|
||||
|
||||
#include "matrix.h"
|
||||
#include "layout.h"
|
||||
|
||||
|
||||
// TODO (before release): put more effort into this
|
||||
#if KB_ROWS != 12 || KB_COLUMNS != 7
|
||||
// error check; everything below assumes these dimensions
|
||||
#if KB_LAYERS != 1 || KB_ROWS != 12 || KB_COLUMNS != 7
|
||||
#error "Expecting different keyboard dimensions"
|
||||
#endif
|
||||
uint8_t const kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
|
||||
|
||||
|
||||
// TODO (before release): put more effort into this
|
||||
uint8_t kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
|
||||
{ // layer 0: default
|
||||
// right hand
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
|
@ -39,6 +44,51 @@ uint8_t const kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
|
|||
/* B */ { KEY_DeleteBackspace, KEY_DeleteForward, KEY_End, KEY_Home, KEY_LeftAlt, KEY_LeftControl, 0/*unused*/ } /* B */
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
kbfun_funptr_t kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
|
||||
{ // layer 0: default
|
||||
// right hand
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
/* 0 */ { NULL, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press }, /* 0 */
|
||||
/* 1 */ { NULL, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press }, /* 1 */
|
||||
/* 2 */ { NULL,/*unused*/ &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press }, /* 2 */
|
||||
/* 3 */ { NULL, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_mod_press }, /* 3 */
|
||||
/* 4 */ { NULL,/*unused*/ NULL,/*unused*/ &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, NULL }, /* 4 */
|
||||
/* 5 */ { NULL,/*unused*/ &kbfun_mod_press, &kbfun_mod_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press }, /* 5 */
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
// left hand
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
/* 6 */ { &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, NULL }, /* 6 */
|
||||
/* 7 */ { &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, NULL }, /* 7 */
|
||||
/* 8 */ { &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, NULL/*unused*/ }, /* 8 */
|
||||
/* 9 */ { &kbfun_mod_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, NULL }, /* 9 */
|
||||
/* A */ { NULL, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, NULL,/*unused*/ NULL/*unused*/ }, /* A */
|
||||
/* B */ { &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_press, &kbfun_mod_press, &kbfun_mod_press, NULL/*unused*/ } /* B */
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
}
|
||||
};
|
||||
|
||||
kbfun_funptr_t kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
|
||||
{ // layer 0: default
|
||||
// right hand
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
/* 0 */ { NULL, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release }, /* 0 */
|
||||
/* 1 */ { NULL, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release }, /* 1 */
|
||||
/* 2 */ { NULL,/*unused*/ &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release }, /* 2 */
|
||||
/* 3 */ { NULL, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_mod_release }, /* 3 */
|
||||
/* 4 */ { NULL,/*unused*/ NULL,/*unused*/ &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, NULL }, /* 4 */
|
||||
/* 5 */ { NULL,/*unused*/ &kbfun_mod_release, &kbfun_mod_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release }, /* 5 */
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
// left hand
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
/* 6 */ { &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, NULL }, /* 6 */
|
||||
/* 7 */ { &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, NULL }, /* 7 */
|
||||
/* 8 */ { &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, NULL/*unused*/ }, /* 8 */
|
||||
/* 9 */ { &kbfun_mod_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, NULL }, /* 9 */
|
||||
/* A */ { NULL, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, NULL,/*unused*/ NULL/*unused*/ }, /* A */
|
||||
/* B */ { &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_release, &kbfun_mod_release, &kbfun_mod_release, NULL/*unused*/ } /* B */
|
||||
/* 0 -------------------------- 1 -------------------------- 2 -------------------------- 3 -------------------------- 4 -------------------------- 5 -------------------------- 6 -------------------------- */
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -11,11 +11,18 @@
|
|||
|
||||
#include "lib/data-types.h"
|
||||
|
||||
#include "key-functions.h"
|
||||
|
||||
#include "matrix.h"
|
||||
|
||||
#define KB_LAYERS 1 // anything >= 1, as long as there's memory
|
||||
#define KB_LAYERS 1 // must match what's defined in "layout.c"
|
||||
|
||||
extern uint8_t const kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS];
|
||||
extern uint8_t
|
||||
kb_layout [KB_LAYERS][KB_ROWS][KB_COLUMNS];
|
||||
extern kbfun_funptr_t
|
||||
kb_layout_press [KB_LAYERS][KB_ROWS][KB_COLUMNS];
|
||||
extern kbfun_funptr_t
|
||||
kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS];
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -12,5 +12,9 @@
|
|||
#include "matrix.h"
|
||||
|
||||
|
||||
bool kb_is_pressed[KB_ROWS][KB_COLUMNS] = {{false}};
|
||||
static bool _kb_is_pressed[KB_ROWS][KB_COLUMNS];
|
||||
static bool _kb_was_pressed[KB_ROWS][KB_COLUMNS];
|
||||
|
||||
bool (*kb_is_pressed)[KB_ROWS][KB_COLUMNS] = &_kb_is_pressed;
|
||||
bool (*kb_was_pressed)[KB_ROWS][KB_COLUMNS] = &_kb_was_pressed;
|
||||
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
#define KB_ROWS 12 // must match real life
|
||||
#define KB_COLUMNS 7 // must match real life
|
||||
|
||||
extern bool kb_is_pressed[KB_ROWS][KB_COLUMNS];
|
||||
extern bool (*kb_is_pressed)[KB_ROWS][KB_COLUMNS];
|
||||
extern bool (*kb_was_pressed)[KB_ROWS][KB_COLUMNS];
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -6,15 +6,19 @@
|
|||
* 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>
|
||||
|
||||
#include "lib/data-types.h"
|
||||
#define TWI_FREQ 400000
|
||||
#include "lib/teensy-2-0/twi.h"
|
||||
#include "lib/teensy-2-0/twi.h" // `TWI_FREQ` defined in "teensy-2-0.c"
|
||||
|
||||
#define KEYBOARD_INCLUDE_PRIVATE
|
||||
#include "matrix.h"
|
||||
#define MCP23018_h_INCLUDE_PRIVATE
|
||||
#include "mcp23018.h"
|
||||
|
||||
|
||||
|
@ -23,7 +27,7 @@
|
|||
#define IODIRB 0x01
|
||||
#define GPPUA 0x0C // GPIO pull-up resistor register
|
||||
#define GPPUB 0x0D
|
||||
#define GPIOA 0x12 // general purpose i/o port register
|
||||
#define GPIOA 0x12 // general purpose i/o port register (write modifies OLAT)
|
||||
#define GPIOB 0x13
|
||||
#define OLATA 0x14 // output latch register
|
||||
#define OLATB 0x15
|
||||
|
@ -33,24 +37,36 @@
|
|||
#define TWI_ADDR_READ ( (MCP23018_TWI_ADDRESS<<1) | TW_READ )
|
||||
|
||||
|
||||
/*
|
||||
* returns:
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
uint8_t mcp23018_init(void) {
|
||||
uint8_t ret;
|
||||
static uint8_t _init(bool release_twi_bus) {
|
||||
static bool initialized;
|
||||
uint8_t ret, data;
|
||||
|
||||
twi_init();
|
||||
// check for errors and previous initialization
|
||||
|
||||
// quick check to see if the device is responding; if it is, we'll
|
||||
// assume things are going to work
|
||||
twi_start();
|
||||
ret = twi_send(TWI_ADDR_WRITE);
|
||||
if (ret) {
|
||||
twi_stop();
|
||||
return ret;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// set pin direction
|
||||
// - unused : input : 1
|
||||
|
@ -78,13 +94,28 @@ uint8_t mcp23018_init(void) {
|
|||
// - columns : high (hi-Z) : 1
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
twi_send(GPIOA);
|
||||
twi_send(0b11111111); //GPIOA
|
||||
twi_send(0b11111111); //GPIOB
|
||||
|
||||
twi_stop();
|
||||
twi_send(OLATA);
|
||||
twi_send(0b11111111); //OLATA
|
||||
twi_send(0b11111111); //OLATB
|
||||
|
||||
return 0; // success
|
||||
out:
|
||||
if (release_twi_bus)
|
||||
twi_stop();
|
||||
|
||||
if (ret) initialized = false;
|
||||
else initialized = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/* returns:
|
||||
* - success: 0
|
||||
* - failure: twi status code
|
||||
*/
|
||||
uint8_t mcp23018_init(void) {
|
||||
return _init(true);
|
||||
}
|
||||
|
||||
/* returns:
|
||||
|
@ -94,44 +125,53 @@ uint8_t mcp23018_init(void) {
|
|||
#if KB_ROWS != 12 || KB_COLUMNS != 7
|
||||
#error "Expecting different keyboard dimensions"
|
||||
#endif
|
||||
uint8_t mcp23018_update_matrix(uint8_t matrix[KB_ROWS][KB_COLUMNS]) {
|
||||
uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
|
||||
uint8_t ret, data;
|
||||
|
||||
// quick check to see if the device is responding; if it is, we'll
|
||||
// assume things are going to work
|
||||
twi_start();
|
||||
ret = twi_send(TWI_ADDR_WRITE);
|
||||
// initialize things if necessary
|
||||
ret = _init(false);
|
||||
|
||||
// if there was an error
|
||||
if (ret) {
|
||||
// clear the matrix
|
||||
for (uint8_t row=0x6; row<=0xB; row++)
|
||||
for (uint8_t col=0; col<=6; col++)
|
||||
matrix[row][col] = 0;
|
||||
|
||||
// release the twi bus and return
|
||||
twi_stop();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// update our part of the matrix
|
||||
for (uint8_t row=0x6; row<=0xB; row++) {
|
||||
// set row low : 0
|
||||
// set other rows high : 1
|
||||
// set active row low : 0
|
||||
// set other rows high (hi-Z) : 1
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
twi_send(GPIOA);
|
||||
twi_send( 0b11111111 & ~(1<<(row-6)) ); // GPIOA
|
||||
twi_send(OLATA);
|
||||
twi_send( 0b11111111 & ~(1<<(row-6)) ); // OLATA
|
||||
|
||||
// get column data
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
twi_send(GPIOB);
|
||||
twi_send(TWI_ADDR_READ);
|
||||
twi_read(&data); // GPIOB TODO: confirm
|
||||
twi_read(&data); // GPIOB
|
||||
|
||||
// update matrix
|
||||
for (uint8_t col=0; col<=6; col++)
|
||||
matrix[row][col] = !( data & (1<<col) );
|
||||
}
|
||||
|
||||
// set all rows high : 1
|
||||
// set all rows high (hi-Z) : 1
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
twi_send(GPIOA);
|
||||
twi_send(0b11111111);
|
||||
|
||||
// release the twi bus and return
|
||||
twi_stop();
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
|
||||
#include "lib/data-types.h"
|
||||
|
||||
#ifdef MCP23018_h_INCLUDE_PRIVATE
|
||||
#ifdef KEYBOARD_INCLUDE_PRIVATE
|
||||
|
||||
#define MCP23018_TWI_ADDRESS 0b0100000
|
||||
|
||||
uint8_t mcp23018_init(void);
|
||||
uint8_t mcp23018_update_matrix(
|
||||
uint8_t matrix[KB_ROWS][KB_COLUMNS] );
|
||||
bool matrix[KB_ROWS][KB_COLUMNS] );
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Documentation : MCP23018
|
||||
|
||||
## Pinouts and Pin assignments
|
||||
## Pinout and Pin assignments
|
||||
|
||||
* `+` indicates pin
|
||||
* `o` indicates unused pin
|
||||
|
@ -66,7 +66,7 @@
|
|||
OLATB 0x15 / write: modifies the output latches that control the
|
||||
pins configured as output
|
||||
|
||||
* IOCON (see datasheet section 1.6, table 1-5, register 1-8)
|
||||
* IOCON register (see datasheet section 1.6, table 1-5, register 1-8)
|
||||
* BANK: bit 7; read/write; default = 0
|
||||
* 1: The registers associated with each port are separated into different
|
||||
banks
|
||||
|
|
|
@ -10,9 +10,11 @@
|
|||
#include <avr/io.h>
|
||||
|
||||
#include "lib/data-types.h"
|
||||
#define TWI_FREQ 400000
|
||||
#include "lib/teensy-2-0/twi.h"
|
||||
|
||||
#define KEYBOARD_INCLUDE_PRIVATE
|
||||
#include "matrix.h"
|
||||
#define TEENSY_2_0_h_INCLUDE_PRIVATE
|
||||
#include "teensy-2-0.h"
|
||||
|
||||
|
||||
|
@ -77,9 +79,8 @@
|
|||
#define COLUMN_6 B, 0
|
||||
|
||||
|
||||
/* returns:
|
||||
/* returns
|
||||
* - success: 0
|
||||
* + will never return failure
|
||||
*/
|
||||
uint8_t teensy_init(void) {
|
||||
CPU_PRESCALE(CPU_16MHz); // speed should match F_CPU in makefile
|
||||
|
@ -93,9 +94,12 @@ uint8_t teensy_init(void) {
|
|||
TCCR1A = 0b10101001; // set and configure fast PWM
|
||||
TCCR1B = 0b00001001; // set and configure fast PWM
|
||||
|
||||
KB_LED1_SET_PERCENT(0.5); KB_LED1_OFF;
|
||||
KB_LED2_SET_PERCENT(0.5); KB_LED2_OFF;
|
||||
KB_LED3_SET_PERCENT(0.5); KB_LED3_OFF;
|
||||
|
||||
// I2C (TWI)
|
||||
// on pins D(1,0); leave them alone here so the TWI library can do as
|
||||
// it wishes
|
||||
twi_init(); // on pins D(1,0)
|
||||
|
||||
// unused pins
|
||||
// --- set as input
|
||||
|
@ -150,15 +154,14 @@ uint8_t teensy_init(void) {
|
|||
return 0; // success
|
||||
}
|
||||
|
||||
/* returns:
|
||||
/* returns
|
||||
* - success: 0
|
||||
* + will never return failure
|
||||
*/
|
||||
#if KB_ROWS != 12 || KB_COLUMNS != 7
|
||||
#error "Expecting different keyboard dimensions"
|
||||
#endif
|
||||
static inline void _update_columns(
|
||||
uint8_t matrix[KB_ROWS][KB_COLUMNS], uint8_t row ) {
|
||||
bool matrix[KB_ROWS][KB_COLUMNS], uint8_t row ) {
|
||||
matrix[row][0] = ! TEENSYPIN_READ(COLUMN_0);
|
||||
matrix[row][1] = ! TEENSYPIN_READ(COLUMN_1);
|
||||
matrix[row][2] = ! TEENSYPIN_READ(COLUMN_2);
|
||||
|
@ -167,30 +170,30 @@ static inline void _update_columns(
|
|||
matrix[row][5] = ! TEENSYPIN_READ(COLUMN_5);
|
||||
matrix[row][6] = ! TEENSYPIN_READ(COLUMN_6);
|
||||
}
|
||||
uint8_t teensy_update_matrix(uint8_t matrix[KB_ROWS][KB_COLUMNS]) {
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_0); // set row low (as output)
|
||||
uint8_t teensy_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
|
||||
TEENSYPIN_WRITE(DDR, SET, ROW_0); // set row low (set as output)
|
||||
_update_columns(matrix, 0); // read col 0..6 and update matrix
|
||||
TEENSYPIN_WRITE(DDR, SET, ROW_0); // set row hi-Z (as input)
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_0); // set row hi-Z (set as input)
|
||||
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_1);
|
||||
_update_columns(matrix, 1);
|
||||
TEENSYPIN_WRITE(DDR, SET, ROW_1);
|
||||
_update_columns(matrix, 1);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_1);
|
||||
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_2);
|
||||
_update_columns(matrix, 2);
|
||||
TEENSYPIN_WRITE(DDR, SET, ROW_2);
|
||||
_update_columns(matrix, 2);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_2);
|
||||
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_3);
|
||||
_update_columns(matrix, 3);
|
||||
TEENSYPIN_WRITE(DDR, SET, ROW_3);
|
||||
_update_columns(matrix, 3);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_3);
|
||||
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_4);
|
||||
_update_columns(matrix, 4);
|
||||
TEENSYPIN_WRITE(DDR, SET, ROW_4);
|
||||
_update_columns(matrix, 4);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_4);
|
||||
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_5);
|
||||
_update_columns(matrix, 5);
|
||||
TEENSYPIN_WRITE(DDR, SET, ROW_5);
|
||||
_update_columns(matrix, 5);
|
||||
TEENSYPIN_WRITE(DDR, CLEAR, ROW_5);
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
#include "lib/data-types.h"
|
||||
|
||||
#include "matrix.h"
|
||||
|
||||
// LED control
|
||||
#define KB_LED1_ON (DDRB |= (1<<5))
|
||||
#define KB_LED1_OFF (DDRB &= ~(1<<5))
|
||||
|
@ -29,11 +31,11 @@
|
|||
#define KB_LED3_SET_PERCENT(n) (OCR1C = (uint8_t)((n) * 0xFF))
|
||||
|
||||
|
||||
#ifdef TEENSY_2_0_h_INCLUDE_PRIVATE
|
||||
#ifdef KEYBOARD_INCLUDE_PRIVATE
|
||||
|
||||
uint8_t teensy_init(void);
|
||||
uint8_t teensy_update_matrix(
|
||||
uint8_t matrix[KB_ROWS][KB_COLUMNS] );
|
||||
bool matrix[KB_ROWS][KB_COLUMNS] );
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Documentation : Teensy 2.0
|
||||
|
||||
## Pinouts and Pin assignments
|
||||
## Pinout and Pin assignments
|
||||
|
||||
* `+` indicates pin
|
||||
* `o` indicates unused pin
|
||||
|
@ -38,12 +38,13 @@
|
|||
column3 PD2 + + OC1A LED1
|
||||
column4 PD3 + + PB4 column0
|
||||
column1 PC6 + + PD7 column5
|
||||
column2 PC7 +-o-o-o-o-o-o
|
||||
column2 PC7 +-o-o-o-o-o-+ PD6 onboardLED
|
||||
|
||||
* notes:
|
||||
* 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.
|
||||
for this project we'll want external ones. The general recommendation for
|
||||
400kHz I²C seems to be 2.2kΩ.
|
||||
|
||||
|
||||
## Notes about Registers
|
||||
|
@ -61,11 +62,11 @@
|
|||
read returns the logical value (1|0) of the pin
|
||||
|
||||
* notes:
|
||||
* Unused pins should be set as input with internal pullup enabled (see
|
||||
datasheet section 10.2.6) in order to give them a defined level.
|
||||
* PD6 already has a defined level (low) since it's hooked up to the onboard
|
||||
LED, 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.
|
||||
* Unused pins should be set as input, with internal pullup enabled in order
|
||||
to give them a defined level (see datasheet section 10.2.6).
|
||||
* 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 row pins 'hi-Z' initially (set as input with pull-up disabled),
|
||||
and the column pins set as input with internal pull-up enabled. We'll
|
||||
cycle through driving the row pins low (setting them as output) and
|
||||
|
@ -86,7 +87,8 @@
|
|||
"Clear OCnA/OCnB/OCnC on compare match, set OCnA/OCnB/OCnC at TOP"
|
||||
(see table 14-3)
|
||||
this way higher values of `OCR1(A|B|C)` will mean longer 'on' times for the
|
||||
LEDs
|
||||
LEDs (provided they're hooked up to GND; other way around if they're hooked
|
||||
up to Vcc)
|
||||
* when in a fast PWM mode, set `TCCR1A[7,6,5,4,3,2]` to `1,0,1,0,1,0`
|
||||
* we want "Clock Select Bit Description" to be `0b001`
|
||||
"clkI/O/1 (No prescaling)"
|
||||
|
|
|
@ -349,7 +349,8 @@ int8_t usb_keyboard_send(void)
|
|||
//
|
||||
ISR(USB_GEN_vect)
|
||||
{
|
||||
uint8_t intbits, t, i;
|
||||
uint8_t intbits, i; // used to declare `t` as well, but it wasn't used
|
||||
// ::Blazak, 2012::
|
||||
static uint8_t div4=0;
|
||||
|
||||
intbits = UDINT;
|
||||
|
|
|
@ -19,6 +19,8 @@ extern volatile uint8_t keyboard_leds;
|
|||
#define usb_debug_flush_output()
|
||||
|
||||
|
||||
#if 0 // removed in favor of equilivent code elsewhere ::Ben Blazak, 2012::
|
||||
|
||||
#define KEY_CTRL 0x01
|
||||
#define KEY_SHIFT 0x02
|
||||
#define KEY_ALT 0x04
|
||||
|
@ -129,6 +131,8 @@ extern volatile uint8_t keyboard_leds;
|
|||
#define KEYPAD_0 98
|
||||
#define KEYPAD_PERIOD 99
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#ifndef DATA_TYPES_h
|
||||
#define DATA_TYPES_h
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define bool _Bool
|
||||
|
|
|
@ -39,8 +39,8 @@ uint8_t twi_start(void) {
|
|||
// wait for transmission to complete
|
||||
while (!(TWCR & (1<<TWINT)));
|
||||
// if it didn't work, return the status code (else return 0)
|
||||
if (! (TW_STATUS == TW_START) ||
|
||||
(TW_STATUS == TW_REP_START) )
|
||||
if ( (TW_STATUS != TW_START) &&
|
||||
(TW_STATUS != TW_REP_START) )
|
||||
return TW_STATUS; // error
|
||||
return 0; // success
|
||||
}
|
||||
|
@ -60,9 +60,9 @@ uint8_t twi_send(uint8_t data) {
|
|||
// wait for transmission to complete
|
||||
while (!(TWCR & (1<<TWINT)));
|
||||
// if it didn't work, return the status code (else return 0)
|
||||
if (! (TW_STATUS == TW_MT_SLA_ACK) ||
|
||||
(TW_STATUS == TW_MT_DATA_ACK)||
|
||||
(TW_STATUS == TW_MR_SLA_ACK) )
|
||||
if ( (TW_STATUS != TW_MT_SLA_ACK) &&
|
||||
(TW_STATUS != TW_MT_DATA_ACK) &&
|
||||
(TW_STATUS != TW_MR_SLA_ACK) )
|
||||
return TW_STATUS; // error
|
||||
return 0; // success
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#define TWI_h
|
||||
|
||||
#ifndef TWI_FREQ
|
||||
#define TWI_FREQ 100000
|
||||
#define TWI_FREQ 100000 // in Hz
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
// vim: ts=4 sw=4 sts=4
|
||||
/* ----------------------------------------------------------------------------
|
||||
* main()
|
||||
* ----------------------------------------------------------------------------
|
||||
* 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 <util/delay.h>
|
||||
|
||||
#include "lib-other/pjrc/usb_keyboard/usb_keyboard.h"
|
||||
|
||||
#include "lib/data-types.h"
|
||||
|
||||
#include "keyboard.h"
|
||||
|
||||
//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);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 //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 (;;) {
|
||||
static uint8_t current_layer = 0;
|
||||
|
||||
// swap `kb_is_pressed` and `kb_was_pressed`, then update
|
||||
bool (*temp)[KB_ROWS][KB_COLUMNS] = kb_was_pressed;
|
||||
kb_was_pressed = kb_is_pressed;
|
||||
kb_is_pressed = temp;
|
||||
|
||||
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])(
|
||||
&kb_layout[current_layer][row][col],
|
||||
¤t_layer, &row, &col );
|
||||
} else
|
||||
if (*kb_layout_release[current_layer][row][col])
|
||||
(*kb_layout_release[current_layer][row][col])(
|
||||
&kb_layout[current_layer][row][col],
|
||||
¤t_layer, &row, &col );
|
||||
}
|
||||
|
||||
usb_keyboard_send();
|
||||
|
||||
// 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<<3)) ? KB_LED4_ON : KB_LED4_OFF; // compose
|
||||
(keyboard_leds & (1<<4)) ? KB_LED5_ON : KB_LED5_OFF; // kana
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
10
src/makefile
10
src/makefile
|
@ -12,8 +12,9 @@ TARGET = ergodox-firmware
|
|||
|
||||
SRC = $(shell find -maxdepth 1 -name '*.c') \
|
||||
$(shell find ./keyboard -name '*.c') \
|
||||
$(shell find ./lib -name '*.c')
|
||||
|
||||
$(shell find ./lib -name '*.c') \
|
||||
'./lib-other/pjrc/usb_keyboard/usb_keyboard.c'
|
||||
|
||||
|
||||
EXTRAINCDIRS = .
|
||||
|
||||
|
@ -23,7 +24,7 @@ TEENSY_MAKE = $(MAKE) -f 'lib-other/pjrc/blinky/Makefile' \
|
|||
EXTRAINCDIRS='$(EXTRAINCDIRS)'
|
||||
|
||||
|
||||
.PHONY: all clean
|
||||
.PHONY: all clean debug
|
||||
|
||||
all:
|
||||
$(TEENSY_MAKE) all
|
||||
|
@ -32,3 +33,6 @@ clean:
|
|||
$(TEENSY_MAKE) clean
|
||||
git clean -X
|
||||
|
||||
debug:
|
||||
$(TEENSY_MAKE) debug
|
||||
|
||||
|
|
|
@ -10,13 +10,13 @@
|
|||
|
||||
TARGET = test
|
||||
|
||||
EXTRAINCDIRS = .
|
||||
EXTRAINCDIRS = ..
|
||||
|
||||
TEENSY_MAKE = $(MAKE) -f '../lib-other/pjrc/blinky/Makefile' \
|
||||
TARGET='$(TARGET)' \
|
||||
EXTRAINCDIRS='$(EXTRAINCDIRS)'
|
||||
|
||||
.PHONY: test_pwm test_twi
|
||||
.PHONY: test_pwm test_twi test_twi_2
|
||||
|
||||
test_pwm:
|
||||
$(TEENSY_MAKE) all \
|
||||
|
@ -26,6 +26,10 @@ test_twi:
|
|||
$(TEENSY_MAKE) all \
|
||||
SRC='test_twi.c'
|
||||
|
||||
test_twi_2:
|
||||
$(TEENSY_MAKE) all \
|
||||
SRC='test_twi_2.c'
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
|
|
|
@ -8,19 +8,39 @@
|
|||
|
||||
|
||||
#include <util/delay.h>
|
||||
|
||||
#define TEENSY_2_0_h_INCLUDE_PRIVATE
|
||||
#include "../keyboard/ergodox/teensy-2-0.h"
|
||||
#include "../keyboard/ergodox/teensy-2-0.c"
|
||||
#include <avr/io.h>
|
||||
|
||||
|
||||
#define bool uint8_t
|
||||
#define bool _Bool
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
|
||||
|
||||
// LED control
|
||||
#define KB_LED1_ON (DDRB |= (1<<5))
|
||||
#define KB_LED1_OFF (DDRB &= ~(1<<5))
|
||||
#define KB_LED1_SET(n) (OCR1A = (uint8_t)(n))
|
||||
#define KB_LED1_SET_PERCENT(n) (OCR1A = (uint8_t)((n) * 0xFF))
|
||||
#define KB_LED2_ON (DDRB |= (1<<6))
|
||||
#define KB_LED2_OFF (DDRB &= ~(1<<6))
|
||||
#define KB_LED2_SET(n) (OCR1B = (uint8_t)(n))
|
||||
#define KB_LED2_SET_PERCENT(n) (OCR1B = (uint8_t)((n) * 0xFF))
|
||||
#define KB_LED3_ON (DDRB |= (1<<7))
|
||||
#define KB_LED3_OFF (DDRB &= ~(1<<7))
|
||||
#define KB_LED3_SET(n) (OCR1C = (uint8_t)(n))
|
||||
#define KB_LED3_SET_PERCENT(n) (OCR1C = (uint8_t)((n) * 0xFF))
|
||||
|
||||
|
||||
int main(void) {
|
||||
CPU_PRESCALE(0); // set for 16MHz
|
||||
|
||||
// pwm init for keyboard LEDs
|
||||
// (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md")
|
||||
DDRB |= 0b11100000; // set B(7,6,5) as output
|
||||
TCCR1A = 0b10101001; // set and configure fast PWM
|
||||
TCCR1B = 0b00001001; // set and configure fast PWM
|
||||
|
||||
void main(void) {
|
||||
teensy_init();
|
||||
|
||||
for (uint8_t i=0; i<3; i++) {
|
||||
KB_LED1_SET(0x10);
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* Test TWI write (with a Teensy 2.0 and I/O expander)
|
||||
* ----------------------------------------------------------------------------
|
||||
* 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 <avr/io.h>
|
||||
#include <util/twi.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#define TWI_FREQ 400000
|
||||
#include "../lib/teensy-2-0/twi.c"
|
||||
|
||||
|
||||
// processor frequency (from <http://www.pjrc.com/teensy/prescaler.html>)
|
||||
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
|
||||
#define CPU_16MHz 0x00
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// helper functions
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define blink_led(time1, time2) { \
|
||||
/* Teensy 2.0 onboard LED on PD6
|
||||
on high, off low */ \
|
||||
PORTD |= (1<<6); \
|
||||
_delay_ms(time1); \
|
||||
PORTD &= ~(1<<6); \
|
||||
_delay_ms(time2); \
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------- // TWI
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define IODIRA 0x00
|
||||
#define IODIRB 0x01
|
||||
#define GPPUA 0x0C
|
||||
#define GPPUB 0x0D
|
||||
#define GPIOA 0x12
|
||||
#define GPIOB 0x13
|
||||
#define OLATA 0x14
|
||||
#define OLATB 0x15
|
||||
|
||||
#define TWI_ADDR_WRITE (0b0100000<<1)|TW_WRITE
|
||||
#define TWI_ADDR_READ (0b0100000<<1)|TW_READ
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// main
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/* notes:
|
||||
* - won't work without the `twi_stop()`s after each block
|
||||
*/
|
||||
int main(void) {
|
||||
CPU_PRESCALE(CPU_16MHz);
|
||||
|
||||
twi_init();
|
||||
|
||||
// set all gpio pins as:
|
||||
|
||||
// output
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
twi_send(IODIRA);
|
||||
twi_send(0);
|
||||
twi_send(0);
|
||||
twi_stop();
|
||||
|
||||
// with pull-up
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
twi_send(GPPUA);
|
||||
twi_send(0xff);
|
||||
twi_send(0xff);
|
||||
twi_stop();
|
||||
|
||||
// logical 1
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
twi_send(OLATA);
|
||||
twi_send(0xff);
|
||||
twi_send(0xff);
|
||||
twi_stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue