intermitent checkin; lots of stuff; i2c on hold; kb logic in progress

partial-rewrite
Ben Blazak 2012-03-27 03:06:52 -07:00
parent b77e74cacd
commit a288b8a045
43 changed files with 5081 additions and 289 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*~
*.swp

View File

@ -1,4 +1,4 @@
## Noob Electronics Stuff
## Electronics Stuff
* [Resistor Color Codes]
(http://www.ladyada.net/wiki/lib/exe/fetch.php?hash=a2c6a9&w=501&h=785&media=http%3A%2F%2Fwww.ladyada.net%2Fimages%2Fmetertutorial%2Frescolorcode.jpg)
@ -34,8 +34,11 @@
* [All About Circuits : Reference]
(http://www.allaboutcircuits.com/vol_5/index.html)
* [Effects of Varying I2C Pull-Up Resistors]
(http://dsscircuits.com/articles/effects-of-varying-i2c-pull-up-resistors.html) : article by Wayne Truchsess
## Noob C Stuff
## C Stuff
* [C Library Reference]
(http://www.cplusplus.com/reference/)
@ -60,18 +63,11 @@
(http://www.ibiblio.org/pub/languages/fortran/append-c.html)
(on <http://www.ibiblio.org/>)
* [C preprocessor and concatenation]
(http://stackoverflow.com/questions/1489932/c-preprocessor-and-concatenation)
(on <http://stackoverflow.com/>)
## Noob Other Stuff
* [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/>)
## AVR C stuff
### For the AVR
* [AVR Libc Library Reference]
(http://www.nongnu.org/avr-libc/user-manual/modules.html)
@ -83,14 +79,47 @@
* [A Brief Tutorial on Programming the AVR without Arduino] by Chris Kuethe
(https://www.mainframe.cx/~ckuethe/avr-c-tutorial/)
## Protocol Stuff
## Articles / Tutorials
### I&sup2;C
* [Arduino I&sup2;C Expansion IO]
(http://www.neufeld.newton.ks.us/electronics/?p=241)
(from [Keith's Electronics Blog]
(http://www.neufeld.newton.ks.us/electronics/))
* [Arduino Playground :: Wire Library, Explored]
(http://arduino.cc/playground/Main/WireLibraryDetailedReference)
### USB
* About Keyboard [Scan Codes]
(http://geekhack.org/showwiki.php?title=Scan+Codes)
(on <http://geekhack.org/>)
* [USB 2.0 Specification]
(http://www.usb.org/developers/docs/usb_20_101111.zip)
: zip (from <http://www.usb.org/developers/docs/>)
* [HID Device Class Definition]
(http://www.usb.org/developers/devclass_docs/HID1_11.pdf)
: pdf (from <http://www.usb.org/developers/hidpage>)
* HID = Human Interface Device
* [HID Usage Tables]
(http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf)
: 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
@ -192,7 +221,7 @@
-------------------------------------------------------------------------------
Copyright &copy; 2012 Ben Blazak
Released under The MIT License (MIT) (see "license.md") at
<https://github.com/benblazak/ergodox-firmware>
Copyright &copy; 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>

View File

@ -3,9 +3,16 @@
[ergodox-firmware]: https://github.com/benblazak/ergodox-firmware
[ergodox keyboard]: http://geekhack.org/showthread.php?22780-Interest-Check-Custom-split-ergo-keyboard
## dependencies
* See the PJRC [Getting Started] (http://pjrc.com/teensy/first_use.html) page
for instructions on how to set up an AVR programming environment. This
project uses C (not Arduino).
-------------------------------------------------------------------------------
Copyright &copy; 2012 Ben Blazak
Released under The MIT License (MIT) (see "license.md") at
<https://github.com/benblazak/ergodox-firmware>
Copyright &copy; 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>

View File

@ -1,15 +1,15 @@
/* ----------------------------------------------------------------------------
* Firmware main file
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak
* Released under The MIT License (MIT) (see "license.md") at
* <https://github.com/benblazak/ergodox-firmware>
* 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 "lib/pjrc/print.h"
#include "keyboard.h"
// #include "keyboard.h"
// TODO

View File

@ -1,12 +0,0 @@
/* ----------------------------------------------------------------------------
* Keyboard specific stuff
* - public things are prefixed by `kb_` or `KB_`
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak
* Released under The MIT License (MIT) (see "license.md") at
* <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
// TODO

0
src/keyboard/ergodox.c Normal file
View File

View File

@ -1,82 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX layout specific stuff
* - public things are prefixed by `layout_` or `LAYOUT_`
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak
* Released under The MIT License (MIT) (see "license.md") at
* <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* ~~~ documentation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* ----------------------------------------------------------------------------
* Matrix [row.column] assignments
* - row and column numbers are in hex
* - coordinates without brackets are unused
* - left and right hands are mirrored, with `row += 6` for left hand rows
* ----------------------------------------------------------------------------
* ....... rows x columns = positions; assigned, unassigned .......
* ....... per hand: 6 x 7 = 42; 38, 4 .......
* ....... total: 12 x 7 = 84; 76, 8 .......
* ----------------------------------------------------------------------------
* [66][65][64][63][62][61][60] [00][01][02][03][04][05][06]
* [76][75][74][73][72][71][70] [10][11][12][13][14][15][16]
* [86][85][84][83][82][81] 80 20 [21][22][23][24][25][26]
* [96][95][94][93][92][91][90] [30][31][32][33][34][35][36]
* [A6][A5][A4][A3][A2] A1 A0 40 41 [42][43][44][45][46]
* [B1] B0 50 [51]
* [B3] [B2] [52] [53]
* [B6][B5][B4] [54][55][56]
* ------------------------------------------------------------------------- */
#include "layout.h"
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* ~~~ variables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
// uint8_t kb_is_pressed[KB_ROWS][KB_COLUMNS] = {
// --- right hand ---
// column 0 1 2 3 4 5 6
// 0, 0, 0, 0, 0, 0, 0, //row 0x0
// 0, 0, 0, 0, 0, 0, 0, //row 0x1
// 0, 0, 0, 0, 0, 0, 0, //row 0x2
// 0, 0, 0, 0, 0, 0, 0, //row 0x3
// 0, 0, 0, 0, 0, 0, 0, //row 0x4
// 0, 0, 0, 0, 0, 0, 0, //row 0x5
// --- left hand ---
// column 0 1 2 3 4 5 6
// 0, 0, 0, 0, 0, 0, 0, //row 0x6
// 0, 0, 0, 0, 0, 0, 0, //row 0x7
// 0, 0, 0, 0, 0, 0, 0, //row 0x8
// 0, 0, 0, 0, 0, 0, 0, //row 0x9
// 0, 0, 0, 0, 0, 0, 0, //row 0xA
// 0, 0, 0, 0, 0, 0, 0 //row 0xB
// };
//
// TODO: this belongs in program space
// uint8_t layout_layers[LAYOUT_LAYERS][LAYOUT_ROWS][LAYOUT_COLUMNS] = {
// ------- layer: default -------
// --- right hand ---
// column 0 1 2 3 4 5 6
// 0, 0, 0, 0, 0, 0, 0, //row 0x0
// 0, 0, 0, 0, 0, 0, 0, //row 0x1
// 0, 0, 0, 0, 0, 0, 0, //row 0x2
// 0, 0, 0, 0, 0, 0, 0, //row 0x3
// 0, 0, 0, 0, 0, 0, 0, //row 0x4
// 0, 0, 0, 0, 0, 0, 0, //row 0x5
// --- left hand ---
// column 0 1 2 3 4 5 6
// 0, 0, 0, 0, 0, 0, 0, //row 0x6
// 0, 0, 0, 0, 0, 0, 0, //row 0x7
// 0, 0, 0, 0, 0, 0, 0, //row 0x8
// 0, 0, 0, 0, 0, 0, 0, //row 0x9
// 0, 0, 0, 0, 0, 0, 0, //row 0xA
// 0, 0, 0, 0, 0, 0, 0 //row 0xB
// };

View File

@ -1,16 +1,42 @@
/* ----------------------------------------------------------------------------
* see "default.c"
* ergoDOX layout
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak
* Released under The MIT License (MIT) (see "license.md") at
* <https://github.com/benblazak/ergodox-firmware>
* 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 LAYOUT_h
#define LAYOUT_h
#define LAYOUT_LAYERS 1
#define LAYOUT_ROWS 12 // must match real life
#define LAYOUT_COLUMNS 7 // must match real life
#include "lib/usb/keyboard-usage-page.h"
#include "matrix.h"
#define KB_LAYERS 1 // anything >= 1, as long as there's memory
extern const uint8_t kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
// TODO (before release): put more effort into this
// ------- layer 0: default -------
// --- right hand ---
/* 0 ---------- 1 --------------- 2 -------------- 3 ----------------- 4 --------------------- 5 -------------------------- 6 -------------------------- */
/* 0 */ 0, KEY_6_Caret, KEY_7_Ampersand, KEY_8_Asterisk, KEY_9_LeftParenthesis, KEY_0_RightParenthesis, KEY_Dash_Underscore, /* 0 */
/* 1 */ 0, KEY_y_Y, KEY_u_U, KEY_i_I, KEY_o_O, KEY_p_P, KEY_LeftBracket_LeftBrace, /* 1 */
/* 2 */ 0,/*unused*/ KEY_h_H, KEY_j_J, KEY_k_K, KEY_l_L, KEY_Semicolon_Colon, KEY_SingleQuote_DoubleQuote, /* 2 */
/* 3 */ 0, KEY_n_N, KEY_m_M, KEY_Comma_LessThan, KEY_Period_GreaterThan, KEY_Slash_Question, KEY_RightShift, /* 3 */
/* 4 */ 0,/*unused*/ 0,/*unused*/ KEY_UpArrow, KEY_DownArrow, KEY_Backslash_Pipe, KEY_RightBracket_RightBrace, 0, /* 4 */
/* 5 */ 0,/*unused*/ KEY_RightControl, KEY_RightAlt, KEY_PageUp, KEY_PageDown, KEY_ReturnEnter, KEY_Spacebar, /* 5 */
/* 0 ---------- 1 --------------- 2 -------------- 3 ----------------- 4 --------------------- 5 -------------------------- 6 -------------------------- */
// --- left hand ---
/* 0 ------------------ 1 -------------------- 2 ----------------- 3 ------------ 4 -------------- 5 ------------ 6 ----------- */
/* 6 */ KEY_Equal_Plus, KEY_1_Exclamation, KEY_2_At, KEY_3_Pound, KEY_4_Dollar, KEY_5_Percent, 0, /* 6 */
/* 7 */ KEY_Tab, KEY_q_Q, KEY_w_W, KEY_e_E, KEY_r_R, KEY_t_T, 0, /* 7 */
/* 8 */ KEY_CapsLock, KEY_a_A, KEY_s_S, KEY_d_D, KEY_f_F, KEY_g_G, 0,/*unused*/ /* 8 */
/* 9 */ KEY_LeftShift, KEY_z_Z, KEY_x_X, KEY_c_C, KEY_v_V, KEY_b_B, 0, /* 9 */
/* A */ 0, KEY_GraveAccent_Tilde, KEY_Backslash_Pipe, KEY_LeftArrow, KEY_RightArrow, 0,/*unused*/ 0,/*unused*/ /* A */
/* B */ KEY_DeleteBackspace, KEY_DeleteForward, KEY_End, KEY_Home, KEY_LeftAlt, KEY_LeftControl, 0, 0 /*unused*/ /* B */
/* 0 ------------------ 1 -------------------- 2 ----------------- 3 ------------ 4 -------------- 5 ------------ 6 ----------- */
}
#endif
// TODO

View File

@ -1,25 +0,0 @@
#include <util/delay.h>
#include "teensy-2-0.h"
int main(void) {
teensy_init();
TEENSY_LED1_ON;
TEENSY_LED2_ON;
TEENSY_LED3_ON;
for(uint8_t i=0;;i++) {
TEENSY_LED1_SET( (i+(3*0xFF/2/3)) % 0xFF/2 );
TEENSY_LED2_SET( (i+(2*0xFF/2/3)) % 0xFF/2 );
TEENSY_LED3_SET( (i+(1*0xFF/2/3)) % 0xFF/2 );
// counting_up
// ? (i == 0xFF ? counting_up = 0 : i++)
// : (i == 0x00 ? counting_up = 1 : i--);
_delay_ms(10);
}
return 0;
}

View File

@ -0,0 +1,22 @@
/* ----------------------------------------------------------------------------
* ergoDOX: keyboard matrix 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 MATRIX_h
#define MATRIX_h
#include "lib/data-types.h"
#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];
bool kb_is_pressed[KB_ROWS][KB_COLUMNS];
#endif

View File

@ -0,0 +1,28 @@
# Documentation : Keyboard Matrix
## Matrix [row.column] assignments
* row and column numbers are in hex
* coordinates without brackets are unused
* left and right hands are mostly the same, except that `row += 6` for left
hand rows
....... rows x columns = positions; assigned, unassigned .......
....... per hand: 6 x 7 = 42; 38, 4 .......
....... total: 12 x 7 = 84; 76, 8 .......
----------------------------------------------------------------------------
[60][61][62][63][64][65][66] [00][01][02][03][04][05][06]
[70][71][72][73][74][75][76] [10][11][12][13][14][15][16]
[80][81][82][83][84][85] 86 20 [21][22][23][24][25][26]
[90][91][92][93][94][95][96] [30][31][32][33][34][35][36]
[A0][A1][A2][A3][A4] A5 A6 40 41 [42][43][44][45][46]
[B0] B6 50 [56]
[B1] [B5] [51] [55]
[B2][B3][B4] [52][53][54]
-------------------------------------------------------------------------------
Copyright &copy; 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>

View File

@ -1,16 +1,80 @@
/* ----------------------------------------------------------------------------
* ergoDOX controller: MCP23018 specific code
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak
* Released under The MIT License (MIT) (see "license.md") at
* <https://github.com/benblazak/ergodox-firmware>
* 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>
* ------------------------------------------------------------------------- */
// TODO: this is not working yet
#define TWI_ADDRESS MCP23018_TWI_ADDRESS // from header file
#if 0 // this is not the one we want; but it has all the right info
#include "lib-other/peter-fleury/i2cmaster/i2cmaster.h"
// so we can say `TWI_ADDRESS|I2C_WRITE`
#define TWI_ADDRESS (MCP23018_TWI_ADDRESS<<1)
uint8_t mcp23018_ready; // false
uint8_t mcp23018_init(void) {
// declare vars
uint8_t error;
// see if the device is ready
// - success: set `mcp23018_ready = true` and continue initializing
// - failure: return `error`; we can try again later
error = i2c_start(TWI_ADDRESS|I2C_WRITE);
if(error) {
return error;
} else {
mcp23018_ready = true;
i2c_stop(); // release bus
}
// set pin direction
// - unused : input : 1
// - rows : output : 0
// - columns : input : 1
i2c_start_wait(TWI_ADDRESS|I2C_WRITE);
i2c_write(IODIRA); // start register address
i2c_write(0b11000000); // IODIRA
i2c_write(0b11111111); // IODIRB
i2c_stop();
// set pull-up
// - unused : on : 1
// - rows : on : 1
// - columns : on : 1
i2c_start_wait(TWI_ADDRESS|I2C_WRITE);
i2c_write(GPPUA); // start register address
i2c_write(0b11111111); // GPPUA
i2c_write(0b11111111); // GPPUB
i2c_stop();
// set output pins high
// - rows : high : 1
// - other : low : 0 (or ignored)
i2c_start_wait(TWI_ADDRESS|I2C_WRITE);
i2c_write(OLATA); // start register address
i2c_write(0b00111111); // OLATA
i2c_stop();
return 0; // success
}
#endif
#include <util/delay.h>
#include <util/twi.h>
// #include "lib-other/arduino/arduino/libraries/Wire/utility/twi.h"
#include "lib-other/pjrc/blinky/print.h"
#include "lib-other/pjrc/blinky/usb_debug_only.h"
#define MCP23018_h_INCLUDE_PRIVATE
#include "mcp23018.h"
#include "teensy-2-0.h"
#include "lib/data-types.h"
#define True ((uint8_t)1)
#define False ((uint8_t)0)
// register addresses (see "mcp23018.md")
#define IODIRA 0x00 // i/o direction register
@ -22,40 +86,89 @@
#define OLATA 0x14 // output latch register
#define OLATB 0x15
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include "lib/arduino/twi.h"
#include "mcp23018.h"
void mcp23018_init(void) {
uint8_t data[3];
// set pin direction
// - unused : input : 1
// - rows : output : 0
// - columns : input : 1
data[0] = IODIRA; // start register address
data[1] = 0b11000000; // IODIRA
data[2] = 0b11111111; // IODIRB
twi_writeTo(TWI_ADDRESS, data, 3, True);
// set pull-up
// - unused : on : 1
// - rows : off : 0
// - columns : on : 1
data[0] = GPPUA; // start register address
data[1] = 0b11000000; // GPPUA
data[2] = 0b11111111; // GPPUB
twi_writeTo(TWI_ADDRESS, data, 3, True);
// set output pins high
// - rows : high : 1
// - other : low : 0 (or ignored)
data[0] = OLATA; // start register address
data[1] = 0b00111111; // OLATA
twi_writeTo(TWI_ADDRESS, data, 2, True);
static void twi_init(void) {
// TWSR &= ~( (1<<TWPS1)|(1<<TWPS0) );
TWSR |= (1<<TWPS1)|(1<<TWPS0); //dbg
// TWBR = ((F_CPU / 100000) - 16) / 2;
TWBR = 0xFF; //dbg
// TWCR = (1<<TWEA)|(1<<TWEN);
}
static uint8_t twi_start(void) {
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != TW_START)
return TWSR & 0xF8; // error
}
static void twi_stop(void) {
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
while (!(TWCR & (1<<TWSTO)));
}
static uint8_t twi_send(uint8_t data) {
TWDR = data;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != TW_MT_SLA_ACK)
return TWSR & 0xF8; // error
}
static void hid_print_number_binary(uint8_t data) {
print("0b");
for(int8_t i=7; i>=0; i--) {
(data & (1<<i))
? pchar('1')
: pchar('0');
}
}
static void hid_print_number_hex(uint8_t data) {
print("0x"); phex(data);
}
static uint8_t try_address(uint8_t address) {
uint8_t error;
print("\naddress "); hid_print_number_binary(address);
twi_start();
error = twi_send(address);
twi_stop();
print(" error "); hid_print_number_hex(error);
return error;
}
uint8_t mcp23018_init(void) {
uint8_t error, address;
twi_init();
// send address, wait
for (uint8_t i=0b000; i<=0b111; i++) {
address = (0b0100<<4)|(i<<1)|TW_WRITE;
error = try_address(address);
}
address = 0;
error = try_address(address);
// for (uint8_t i=0b0000000; i<=0b1111111; i++) {
// address = (i<<1)|TW_WRITE;
// error = try_address(address);
// if (! error == 0x20)
// return error;
// }
// uint8_t data[3];
//
// twi_init();
// twi_setAddress(MCP23018_TWI_ADDRESS);
//
// data[0] = IODIRA;
// data[1] = 0b00000000; // IODIRA
// error = twi_writeTo(MCP23018_TWI_ADDRESS, data, 2, true);
//
// data[0] = OLATA; // start register address
// data[1] = 0b00000000; // OLATA
// twi_writeTo(MCP23018_TWI_ADDRESS, data, 2, true);
return error;
}

View File

@ -1,21 +1,26 @@
/* ----------------------------------------------------------------------------
* ergoDOX controller: MCP23018 specific exports
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak
* Released under The MIT License (MIT) (see "license.md") at
* <https://github.com/benblazak/ergodox-firmware>
* 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 MCP23018_h
#define MCP23018_h
#define MCP23018_h
#include "lib/data-types.h"
#define MCP23018_TWI_ADDRESS 0b0100000
#ifdef MCP23018_h_INCLUDE_PRIVATE
#define MCP23018_TWI_ADDRESS 0b0100000
void mcp23018_init(void);
extern bool mcp23018_ready;
uint8_t mcp23018_init(void);
#endif
#endif

View File

@ -70,6 +70,7 @@
* notes:
* All addresses given for IOCON.BANK = 0, since that's the default value of
the bit, and that's what we'll be using.
* Outputs are open drain, so we want pull-up resistors set for everything.
* abbreviations:
* IODIR = I/O Direction Register
@ -80,17 +81,17 @@
## I&sup2;C Device Protocol (see datasheet section 1.3, figure 1-1)
S : Start OP : Device opcode
SR : Restart ADDR : Device address
P : Stop Dout : Data out from MCP23018
W : Write Din : Data in to MCP23018
R : Read
S : Start OP : Device opcode
SR : Restart ADDR : Device address
P : Stop Dout : Data out from MCP23018
W : Write Din : Data in to MCP23018
R : Read
S OP W ADDR ----> Din ... Din --> P
|
|--> SR OP R Dout ... Dout ---> P
|<-------------------------|
|<--------------------------|
|
|--> SR OP W ADDR ... Din --> P
|
@ -121,7 +122,7 @@
-------------------------------------------------------------------------------
Copyright &copy; 2012 Ben Blazak
Released under The MIT License (MIT) (see "license.md") at
<https://github.com/benblazak/ergodox-firmware>
Copyright &copy; 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>

View File

@ -1,12 +1,18 @@
/* ----------------------------------------------------------------------------
* ergoDOX controller: Teensy 2.0 specific code
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak
* Released under The MIT License (MIT) (see "license.md") at
* <https://github.com/benblazak/ergodox-firmware>
* 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>
#define TEENSY_2_0_h_INCLUDE_PRIVATE
#include "teensy-2-0.h"
// processor frequency (from <http://www.pjrc.com/teensy/prescaler.html>)
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
#define CPU_16MHz 0x00
@ -19,47 +25,39 @@
#define CPU_125kHz 0x07
#define CPU_62kHz 0x08
// TWI
#define TWI_FREQ 400000 // (see "lib/twi.(h|c)")
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <avr/io.h>
#include "lib/arduino/twi.h"
#include "teensy-2-0.h"
void teensy_init(void) {
uint8_t teensy_init(void) {
CPU_PRESCALE(CPU_16MHz); // speed should match F_CPU in makefile
// unused pins
DDRB &= ~0b00001110; // set B(1,2,3) as input
PORTB |= 0b00001110; // set B(1,2,3) internal pull-up enabled
DDRD &= ~0b01110000; // set D(4,5,6) as input
PORTD |= 0b01110000; // set D(4,5,6) internal pull-up enabled
DDRB &= ~0b00001110; // set B(3,2,1) as input
PORTB |= 0b00001110; // set B(3,2,1) internal pull-up enabled
DDRD &= ~0b01110000; // set D(6,5,4) as input
PORTD |= 0b01110000; // set D(6,5,4) internal pull-up enabled
DDRE &= ~0b01000000; // set E(6) as input
PORTE |= 0b01000000; // set E(6) internal pull-up enabled
// LEDs (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md")
DDRB |= 0b11100000; // set B(5,6,7) as output
DDRB |= 0b11100000; // set B(7,6,5) as output
TCCR1A = 0b10101001; // set and configure fast PWM
TCCR1B = 0b00001001; // set and configure fast PWM
// rows
DDRF |= 0b11110011; // set F(0,1,4,5,6,7) as output
PORTF |= 0b11110011; // set F(0,1,4,5,6,7) drive high
DDRF |= 0b11110011; // set F(7,6,5,4,1,0) as output
PORTF |= 0b11110011; // set F(7,6,5,4,1,0) drive high
// columns
DDRB &= ~0b00010001; // set B(0,4) as input
PORTB |= 0b00010001; // set B(0,4) internal pull-up enabled
DDRC &= ~0b11000000; // set C(6,7) as input
PORTC |= 0b11000000; // set C(6,7) internal pull-up enabled
DDRD &= ~0b10001100; // set D(2,3,7) as input
PORTD |= 0b10001100; // set D(2,3,7) internal pull-up enabled
DDRB &= ~0b00010001; // set B(4,0) as input
PORTB |= 0b00010001; // set B(4,0) internal pull-up enabled
DDRC &= ~0b11000000; // set C(7,6) as input
PORTC |= 0b11000000; // set C(7,6) internal pull-up enabled
DDRD &= ~0b10001100; // set D(7,3,2) as input
PORTD |= 0b10001100; // set D(7,3,2) internal pull-up enabled
// I2C (TWI)
twi_init(); // (on pins D(0,1))
// on pins D(1,0); leave them alone here, so the TWI library can do as
// it wishes
return 0; // success
}

View File

@ -10,46 +10,28 @@
#ifndef TEENSY_2_0_h
#define TEENSY_2_0_h
#ifndef INCLUDE_PREFIX
#define INCLUDE_PREFIX teensy_
#endif
#define prefix(s) INCLUDE_PREFIX##s
#define pprefix(s) PRIVATE_INCLUDE_PREFIX##s
// --------------------------------------------------------------------
#include <avr/io.h> // for the register macros
// LED control
#define prefix(LED1_ON) (OCR1A = 0xFF)
#define prefix(LED1_OFF) (OCR1A = 0x00)
#define prefix(LED1_SET)(n) (OCR1A = (uint8_t)(n))
#define prefix(LED1_SET_PERCENT)(n) (OCR1A = (uint8_t)((n) * 0xFF))
#define prefix(LED2_ON) (OCR1B = 0xFF)
#define prefix(LED2_OFF) (OCR1B = 0x00)
#define prefix(LED2_SET)(n) (OCR1B = (uint8_t)(n))
#define prefix(LED2_SET_PERCENT)(n) (OCR1B = (uint8_t)((n) * 0xFF))
#define prefix(LED3_ON) (OCR1C = 0xFF)
#define prefix(LED3_OFF) (OCR1C = 0x00)
#define prefix(LED3_SET)(n) (OCR1C = (uint8_t)(n))
#define prefix(LED3_SET_PERCENT)(n) (OCR1C = (uint8_t)((n) * 0xFF))
#define KB_LED1_ON (OCR1A = 0xFF)
#define KB_LED1_OFF (OCR1A = 0x00)
#define KB_LED1_SET(n) (OCR1A = (uint8_t)(n))
#define KB_LED1_SET_PERCENT(n) (OCR1A = (uint8_t)((n) * 0xFF))
#define KB_LED2_ON (OCR1B = 0xFF)
#define KB_LED2_OFF (OCR1B = 0x00)
#define KB_LED2_SET(n) (OCR1B = (uint8_t)(n))
#define KB_LED2_SET_PERCENT(n) (OCR1B = (uint8_t)((n) * 0xFF))
#define KB_LED3_ON (OCR1C = 0xFF)
#define KB_LED3_OFF (OCR1C = 0x00)
#define KB_LED3_SET(n) (OCR1C = (uint8_t)(n))
#define KB_LED3_SET_PERCENT(n) (OCR1C = (uint8_t)((n) * 0xFF))
// --------------------------------------------------------------------
#ifdef PRIVATE_INCLUDE_PREFIX
#ifdef TEENSY_2_0_h_INCLUDE_PRIVATE
void pprefix(init)(void)
__attribute__((alias ("teensy_init")));
uint8_t teensy_init(void);
#endif
// --------------------------------------------------------------------
#undef prefix
#undef pprefix
#undef INCLUDE_PREFIX
#undef PRIVATE_INCLUDE_PREFIX
#endif

View File

@ -41,10 +41,10 @@
column2 PC7 +-o-o-o-o-o-o
* notes:
* SCL and SDA: Need external pull-up resistors. Sometimes the internal
pull-ups are enough (see datasheet section 20.5.1), but i think for this
project we'll want external ones, in case people want to separate the
halves very far.
* 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, in case people want to separate
the halves very far.
## Notes about Registers
@ -94,7 +94,7 @@
-------------------------------------------------------------------------------
Copyright &copy; 2012 Ben Blazak
Released under The MIT License (MIT) (see "license.md") at
<https://github.com/benblazak/ergodox-firmware>
Copyright &copy; 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>

View File

@ -0,0 +1,473 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>AVR-GCC libraries: I2C Master library</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.4.1 -->
<h1>I2C Master library</h1><hr><a name="_details"></a><h2>Detailed Description</h2>
I2C (TWI) Master Software Library.
<p>
<div class="fragment"><pre class="fragment"><span class="preprocessor"> #include &lt;i2cmaster.h&gt;</span>
</pre></div><p>
Basic routines for communicating with I2C slave devices. This single master implementation is limited to one bus master on the I2C bus.<p>
This I2c library is implemented as a compact assembler software implementation of the I2C protocol which runs on any AVR (i2cmaster.S) and as a TWI hardware interface for all AVR with built-in TWI hardware (twimaster.c). Since the API for these two implementations is exactly the same, an application can be linked either against the software I2C implementation or the hardware I2C implementation.<p>
Use 4.7k pull-up resistor on the SDA and SCL pin.<p>
Adapt the SCL and SDA port and pin definitions and eventually the delay routine in the module i2cmaster.S to your target when using the software I2C implementation !<p>
Adjust the CPU clock frequence F_CPU in twimaster.c or in the Makfile when using the TWI hardware implementaion.<p>
<dl compact><dt><b>Note:</b></dt><dd>The module i2cmaster.S is based on the Atmel Application Note AVR300, corrected and adapted to GNU assembler and AVR-GCC C call interface. Replaced the incorrect quarter period delays found in AVR300 with half period delays.</dd></dl>
<dl compact><dt><b>Author:</b></dt><dd>Peter Fleury <a href="mailto:pfleury@gmx.ch">pfleury@gmx.ch</a> <a href="http://jump.to/fleury">http://jump.to/fleury</a></dd></dl>
<dl compact><dt><b>API Usage Example</b></dt><dd>The following code shows typical usage of this library, see example test_i2cmaster.c</dd></dl>
<div class="fragment"><pre class="fragment"><span class="preprocessor"> #include &lt;i2cmaster.h&gt;</span>
<span class="preprocessor"> #define Dev24C02 0xA2 // device address of EEPROM 24C02, see datasheet</span>
<span class="preprocessor"></span>
<span class="keywordtype">int</span> main(<span class="keywordtype">void</span>)
{
<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> ret;
<a class="code" href="group__pfleury__ic2master.html#ga0">i2c_init</a>(); <span class="comment">// initialize I2C library</span>
<span class="comment">// write 0x75 to EEPROM address 5 (Byte Write) </span>
<a class="code" href="group__pfleury__ic2master.html#ga4">i2c_start_wait</a>(Dev24C02+I2C_WRITE); <span class="comment">// set device address and write mode</span>
<a class="code" href="group__pfleury__ic2master.html#ga5">i2c_write</a>(0x05); <span class="comment">// write address = 5</span>
<a class="code" href="group__pfleury__ic2master.html#ga5">i2c_write</a>(0x75); <span class="comment">// write value 0x75 to EEPROM</span>
<a class="code" href="group__pfleury__ic2master.html#ga1">i2c_stop</a>(); <span class="comment">// set stop conditon = release bus</span>
<span class="comment">// read previously written value back from EEPROM address 5 </span>
<a class="code" href="group__pfleury__ic2master.html#ga4">i2c_start_wait</a>(Dev24C02+I2C_WRITE); <span class="comment">// set device address and write mode</span>
<a class="code" href="group__pfleury__ic2master.html#ga5">i2c_write</a>(0x05); <span class="comment">// write address = 5</span>
<a class="code" href="group__pfleury__ic2master.html#ga3">i2c_rep_start</a>(Dev24C02+I2C_READ); <span class="comment">// set device address and read mode</span>
ret = <a class="code" href="group__pfleury__ic2master.html#ga7">i2c_readNak</a>(); <span class="comment">// read one byte from EEPROM</span>
<a class="code" href="group__pfleury__ic2master.html#ga1">i2c_stop</a>();
<span class="keywordflow">for</span>(;;);
}
</pre></div>
<p>
<table border="0" cellpadding="0" cellspacing="0">
<tr><td></td></tr>
<tr><td colspan="2"><br><h2>Defines</h2></td></tr>
<tr><td class="memItemLeft" nowrap align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__pfleury__ic2master.html#ga9">I2C_READ</a>&nbsp;&nbsp;&nbsp;1</td></tr>
<tr><td class="memItemLeft" nowrap align="right" valign="top">#define&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__pfleury__ic2master.html#ga10">I2C_WRITE</a>&nbsp;&nbsp;&nbsp;0</td></tr>
<tr><td class="memItemLeft" nowrap align="right" valign="top"><a class="anchor" name="ga11" doxytag="pfleury_ic2master::i2c_read"></a>
#define&nbsp;</td><td class="memItemRight" valign="bottom"><b>i2c_read</b>(ack)&nbsp;&nbsp;&nbsp;(ack) ? i2c_readAck() : i2c_readNak();</td></tr>
<tr><td colspan="2"><br><h2>Functions</h2></td></tr>
<tr><td class="memItemLeft" nowrap align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__pfleury__ic2master.html#ga0">i2c_init</a> (void)</td></tr>
<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">initialize the I2C master interace. Need to be called only once <a href="#ga0"></a><br></td></tr>
<tr><td class="memItemLeft" nowrap align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__pfleury__ic2master.html#ga1">i2c_stop</a> (void)</td></tr>
<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Terminates the data transfer and releases the I2C bus. <a href="#ga1"></a><br></td></tr>
<tr><td class="memItemLeft" nowrap align="right" valign="top">unsigned char&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__pfleury__ic2master.html#ga2">i2c_start</a> (unsigned char addr)</td></tr>
<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Issues a start condition and sends address and transfer direction. <a href="#ga2"></a><br></td></tr>
<tr><td class="memItemLeft" nowrap align="right" valign="top">unsigned char&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__pfleury__ic2master.html#ga3">i2c_rep_start</a> (unsigned char addr)</td></tr>
<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Issues a repeated start condition and sends address and transfer direction. <a href="#ga3"></a><br></td></tr>
<tr><td class="memItemLeft" nowrap align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__pfleury__ic2master.html#ga4">i2c_start_wait</a> (unsigned char addr)</td></tr>
<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Issues a start condition and sends address and transfer direction. <a href="#ga4"></a><br></td></tr>
<tr><td class="memItemLeft" nowrap align="right" valign="top">unsigned char&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__pfleury__ic2master.html#ga5">i2c_write</a> (unsigned char data)</td></tr>
<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">Send one byte to I2C device. <a href="#ga5"></a><br></td></tr>
<tr><td class="memItemLeft" nowrap align="right" valign="top">unsigned char&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__pfleury__ic2master.html#ga6">i2c_readAck</a> (void)</td></tr>
<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">read one byte from the I2C device, request more data from device <a href="#ga6"></a><br></td></tr>
<tr><td class="memItemLeft" nowrap align="right" valign="top">unsigned char&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__pfleury__ic2master.html#ga7">i2c_readNak</a> (void)</td></tr>
<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">read one byte from the I2C device, read is followed by a stop condition <a href="#ga7"></a><br></td></tr>
<tr><td class="memItemLeft" nowrap align="right" valign="top">unsigned char&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__pfleury__ic2master.html#ga8">i2c_read</a> (unsigned char ack)</td></tr>
<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">read one byte from the I2C device <a href="#ga8"></a><br></td></tr>
</table>
<hr><h2>Define Documentation</h2>
<a class="anchor" name="ga9" doxytag="i2cmaster.h::I2C_READ"></a><p>
<table class="mdTable" cellpadding="2" cellspacing="0">
<tr>
<td class="mdRow">
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td class="md" nowrap valign="top">#define I2C_READ&nbsp;&nbsp;&nbsp;1 </td>
</tr>
</table>
</td>
</tr>
</table>
<table cellspacing="5" cellpadding="0" border="0">
<tr>
<td>
&nbsp;
</td>
<td>
<p>
defines the data direction (reading from I2C device) in <a class="el" href="group__pfleury__ic2master.html#ga2">i2c_start()</a>,<a class="el" href="group__pfleury__ic2master.html#ga3">i2c_rep_start()</a> </td>
</tr>
</table>
<a class="anchor" name="ga10" doxytag="i2cmaster.h::I2C_WRITE"></a><p>
<table class="mdTable" cellpadding="2" cellspacing="0">
<tr>
<td class="mdRow">
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td class="md" nowrap valign="top">#define I2C_WRITE&nbsp;&nbsp;&nbsp;0 </td>
</tr>
</table>
</td>
</tr>
</table>
<table cellspacing="5" cellpadding="0" border="0">
<tr>
<td>
&nbsp;
</td>
<td>
<p>
defines the data direction (writing to I2C device) in <a class="el" href="group__pfleury__ic2master.html#ga2">i2c_start()</a>,<a class="el" href="group__pfleury__ic2master.html#ga3">i2c_rep_start()</a> </td>
</tr>
</table>
<hr><h2>Function Documentation</h2>
<a class="anchor" name="ga0" doxytag="i2cmaster.h::i2c_init"></a><p>
<table class="mdTable" cellpadding="2" cellspacing="0">
<tr>
<td class="mdRow">
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td class="md" nowrap valign="top">void i2c_init </td>
<td class="md" valign="top">(&nbsp;</td>
<td class="md" nowrap valign="top">void&nbsp;</td>
<td class="mdname1" valign="top" nowrap> </td>
<td class="md" valign="top">&nbsp;)&nbsp;</td>
<td class="md" nowrap></td>
</tr>
</table>
</td>
</tr>
</table>
<table cellspacing="5" cellpadding="0" border="0">
<tr>
<td>
&nbsp;
</td>
<td>
<p>
initialize the I2C master interace. Need to be called only once
<p>
<dl compact><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>void</em>&nbsp;</td><td></td></tr>
</table>
</dl>
<dl compact><dt><b>Returns:</b></dt><dd>none </dd></dl>
</td>
</tr>
</table>
<a class="anchor" name="ga1" doxytag="i2cmaster.h::i2c_stop"></a><p>
<table class="mdTable" cellpadding="2" cellspacing="0">
<tr>
<td class="mdRow">
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td class="md" nowrap valign="top">void i2c_stop </td>
<td class="md" valign="top">(&nbsp;</td>
<td class="md" nowrap valign="top">void&nbsp;</td>
<td class="mdname1" valign="top" nowrap> </td>
<td class="md" valign="top">&nbsp;)&nbsp;</td>
<td class="md" nowrap></td>
</tr>
</table>
</td>
</tr>
</table>
<table cellspacing="5" cellpadding="0" border="0">
<tr>
<td>
&nbsp;
</td>
<td>
<p>
Terminates the data transfer and releases the I2C bus.
<p>
<dl compact><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>void</em>&nbsp;</td><td></td></tr>
</table>
</dl>
<dl compact><dt><b>Returns:</b></dt><dd>none </dd></dl>
</td>
</tr>
</table>
<a class="anchor" name="ga2" doxytag="i2cmaster.h::i2c_start"></a><p>
<table class="mdTable" cellpadding="2" cellspacing="0">
<tr>
<td class="mdRow">
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td class="md" nowrap valign="top">unsigned char i2c_start </td>
<td class="md" valign="top">(&nbsp;</td>
<td class="md" nowrap valign="top">unsigned char&nbsp;</td>
<td class="mdname1" valign="top" nowrap> <em>addr</em> </td>
<td class="md" valign="top">&nbsp;)&nbsp;</td>
<td class="md" nowrap></td>
</tr>
</table>
</td>
</tr>
</table>
<table cellspacing="5" cellpadding="0" border="0">
<tr>
<td>
&nbsp;
</td>
<td>
<p>
Issues a start condition and sends address and transfer direction.
<p>
<dl compact><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>addr</em>&nbsp;</td><td>address and transfer direction of I2C device </td></tr>
</table>
</dl>
<dl compact><dt><b>Return values:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>0</em>&nbsp;</td><td>device accessible </td></tr>
<tr><td valign="top"></td><td valign="top"><em>1</em>&nbsp;</td><td>failed to access device </td></tr>
</table>
</dl>
</td>
</tr>
</table>
<a class="anchor" name="ga3" doxytag="i2cmaster.h::i2c_rep_start"></a><p>
<table class="mdTable" cellpadding="2" cellspacing="0">
<tr>
<td class="mdRow">
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td class="md" nowrap valign="top">unsigned char i2c_rep_start </td>
<td class="md" valign="top">(&nbsp;</td>
<td class="md" nowrap valign="top">unsigned char&nbsp;</td>
<td class="mdname1" valign="top" nowrap> <em>addr</em> </td>
<td class="md" valign="top">&nbsp;)&nbsp;</td>
<td class="md" nowrap></td>
</tr>
</table>
</td>
</tr>
</table>
<table cellspacing="5" cellpadding="0" border="0">
<tr>
<td>
&nbsp;
</td>
<td>
<p>
Issues a repeated start condition and sends address and transfer direction.
<p>
<dl compact><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>addr</em>&nbsp;</td><td>address and transfer direction of I2C device </td></tr>
</table>
</dl>
<dl compact><dt><b>Return values:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>0</em>&nbsp;</td><td>device accessible </td></tr>
<tr><td valign="top"></td><td valign="top"><em>1</em>&nbsp;</td><td>failed to access device </td></tr>
</table>
</dl>
</td>
</tr>
</table>
<a class="anchor" name="ga4" doxytag="i2cmaster.h::i2c_start_wait"></a><p>
<table class="mdTable" cellpadding="2" cellspacing="0">
<tr>
<td class="mdRow">
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td class="md" nowrap valign="top">void i2c_start_wait </td>
<td class="md" valign="top">(&nbsp;</td>
<td class="md" nowrap valign="top">unsigned char&nbsp;</td>
<td class="mdname1" valign="top" nowrap> <em>addr</em> </td>
<td class="md" valign="top">&nbsp;)&nbsp;</td>
<td class="md" nowrap></td>
</tr>
</table>
</td>
</tr>
</table>
<table cellspacing="5" cellpadding="0" border="0">
<tr>
<td>
&nbsp;
</td>
<td>
<p>
Issues a start condition and sends address and transfer direction.
<p>
If device is busy, use ack polling to wait until device ready <dl compact><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>addr</em>&nbsp;</td><td>address and transfer direction of I2C device </td></tr>
</table>
</dl>
<dl compact><dt><b>Returns:</b></dt><dd>none </dd></dl>
</td>
</tr>
</table>
<a class="anchor" name="ga5" doxytag="i2cmaster.h::i2c_write"></a><p>
<table class="mdTable" cellpadding="2" cellspacing="0">
<tr>
<td class="mdRow">
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td class="md" nowrap valign="top">unsigned char i2c_write </td>
<td class="md" valign="top">(&nbsp;</td>
<td class="md" nowrap valign="top">unsigned char&nbsp;</td>
<td class="mdname1" valign="top" nowrap> <em>data</em> </td>
<td class="md" valign="top">&nbsp;)&nbsp;</td>
<td class="md" nowrap></td>
</tr>
</table>
</td>
</tr>
</table>
<table cellspacing="5" cellpadding="0" border="0">
<tr>
<td>
&nbsp;
</td>
<td>
<p>
Send one byte to I2C device.
<p>
<dl compact><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>data</em>&nbsp;</td><td>byte to be transfered </td></tr>
</table>
</dl>
<dl compact><dt><b>Return values:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>0</em>&nbsp;</td><td>write successful </td></tr>
<tr><td valign="top"></td><td valign="top"><em>1</em>&nbsp;</td><td>write failed </td></tr>
</table>
</dl>
</td>
</tr>
</table>
<a class="anchor" name="ga6" doxytag="i2cmaster.h::i2c_readAck"></a><p>
<table class="mdTable" cellpadding="2" cellspacing="0">
<tr>
<td class="mdRow">
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td class="md" nowrap valign="top">unsigned char i2c_readAck </td>
<td class="md" valign="top">(&nbsp;</td>
<td class="md" nowrap valign="top">void&nbsp;</td>
<td class="mdname1" valign="top" nowrap> </td>
<td class="md" valign="top">&nbsp;)&nbsp;</td>
<td class="md" nowrap></td>
</tr>
</table>
</td>
</tr>
</table>
<table cellspacing="5" cellpadding="0" border="0">
<tr>
<td>
&nbsp;
</td>
<td>
<p>
read one byte from the I2C device, request more data from device
<p>
<dl compact><dt><b>Returns:</b></dt><dd>byte read from I2C device </dd></dl>
</td>
</tr>
</table>
<a class="anchor" name="ga7" doxytag="i2cmaster.h::i2c_readNak"></a><p>
<table class="mdTable" cellpadding="2" cellspacing="0">
<tr>
<td class="mdRow">
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td class="md" nowrap valign="top">unsigned char i2c_readNak </td>
<td class="md" valign="top">(&nbsp;</td>
<td class="md" nowrap valign="top">void&nbsp;</td>
<td class="mdname1" valign="top" nowrap> </td>
<td class="md" valign="top">&nbsp;)&nbsp;</td>
<td class="md" nowrap></td>
</tr>
</table>
</td>
</tr>
</table>
<table cellspacing="5" cellpadding="0" border="0">
<tr>
<td>
&nbsp;
</td>
<td>
<p>
read one byte from the I2C device, read is followed by a stop condition
<p>
<dl compact><dt><b>Returns:</b></dt><dd>byte read from I2C device </dd></dl>
</td>
</tr>
</table>
<a class="anchor" name="ga8" doxytag="i2cmaster.h::i2c_read"></a><p>
<table class="mdTable" cellpadding="2" cellspacing="0">
<tr>
<td class="mdRow">
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td class="md" nowrap valign="top">unsigned char i2c_read </td>
<td class="md" valign="top">(&nbsp;</td>
<td class="md" nowrap valign="top">unsigned char&nbsp;</td>
<td class="mdname1" valign="top" nowrap> <em>ack</em> </td>
<td class="md" valign="top">&nbsp;)&nbsp;</td>
<td class="md" nowrap></td>
</tr>
</table>
</td>
</tr>
</table>
<table cellspacing="5" cellpadding="0" border="0">
<tr>
<td>
&nbsp;
</td>
<td>
<p>
read one byte from the I2C device
<p>
Implemented as a macro, which calls either i2c_readAck or i2c_readNak<p>
<dl compact><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"></td><td valign="top"><em>ack</em>&nbsp;</td><td>1 send ack, request more data from device<br>
0 send nak, read is followed by a stop condition </td></tr>
</table>
</dl>
<dl compact><dt><b>Returns:</b></dt><dd>byte read from I2C device </dd></dl>
</td>
</tr>
</table>
<hr size="1"><address style="align: right;"><small>Generated on Tue Mar 29 16:54:08 2005 for AVR-GCC libraries by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.1 </small></address>
</body>
</html>

View File

@ -0,0 +1,302 @@
;*************************************************************************
; Title : I2C (Single) Master Implementation
; Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
; based on Atmel Appl. Note AVR300
; File: $Id: i2cmaster.S,v 1.12 2008/03/02 08:51:27 peter Exp $
; Software: AVR-GCC 3.3 or higher
; Target: any AVR device
;
; DESCRIPTION
; Basic routines for communicating with I2C slave devices. This
; "single" master implementation is limited to one bus master on the
; I2C bus.
;
; Based on the Atmel Application Note AVR300, corrected and adapted
; to GNU assembler and AVR-GCC C call interface
; Replaced the incorrect quarter period delays found in AVR300 with
; half period delays.
;
; USAGE
; These routines can be called from C, refere to file i2cmaster.h.
; See example test_i2cmaster.c
; Adapt the SCL and SDA port and pin definitions and eventually
; the delay routine to your target !
; Use 4.7k pull-up resistor on the SDA and SCL pin.
;
; NOTES
; The I2C routines can be called either from non-interrupt or
; interrupt routines, not both.
;
;*************************************************************************
#if (__GNUC__ * 100 + __GNUC_MINOR__) < 303
#error "This library requires AVR-GCC 3.3 or later, update to newer AVR-GCC compiler !"
#endif
#include <avr/io.h>
;***** Adapt these SCA and SCL port and pin definition to your target !!
;
#define SDA 4 // SDA Port D, Pin 4
#define SCL 5 // SCL Port D, Pin 5
#define SDA_PORT PORTD // SDA Port D
#define SCL_PORT PORTD // SCL Port D
;******
;-- map the IO register back into the IO address space
#define SDA_DDR (_SFR_IO_ADDR(SDA_PORT) - 1)
#define SCL_DDR (_SFR_IO_ADDR(SCL_PORT) - 1)
#define SDA_OUT _SFR_IO_ADDR(SDA_PORT)
#define SCL_OUT _SFR_IO_ADDR(SCL_PORT)
#define SDA_IN (_SFR_IO_ADDR(SDA_PORT) - 2)
#define SCL_IN (_SFR_IO_ADDR(SCL_PORT) - 2)
#ifndef __tmp_reg__
#define __tmp_reg__ 0
#endif
.section .text
;*************************************************************************
; delay half period
; For I2C in normal mode (100kHz), use T/2 > 5us
; For I2C in fast mode (400kHz), use T/2 > 1.3us
;*************************************************************************
.stabs "",100,0,0,i2c_delay_T2
.stabs "i2cmaster.S",100,0,0,i2c_delay_T2
.func i2c_delay_T2 ; delay 5.0 microsec with 4 Mhz crystal
i2c_delay_T2: ; 4 cycles
rjmp 1f ; 2 "
1: rjmp 2f ; 2 "
2: rjmp 3f ; 2 "
3: rjmp 4f ; 2 "
4: rjmp 5f ; 2 "
5: rjmp 6f ; 2 "
6: nop ; 1 "
ret ; 3 "
.endfunc ; total 20 cyles = 5.0 microsec with 4 Mhz crystal
;*************************************************************************
; Initialization of the I2C bus interface. Need to be called only once
;
; extern void i2c_init(void)
;*************************************************************************
.global i2c_init
.func i2c_init
i2c_init:
cbi SDA_DDR,SDA ;release SDA
cbi SCL_DDR,SCL ;release SCL
cbi SDA_OUT,SDA
cbi SCL_OUT,SCL
ret
.endfunc
;*************************************************************************
; Issues a start condition and sends address and transfer direction.
; return 0 = device accessible, 1= failed to access device
;
; extern unsigned char i2c_start(unsigned char addr);
; addr = r24, return = r25(=0):r24
;*************************************************************************
.global i2c_start
.func i2c_start
i2c_start:
sbi SDA_DDR,SDA ;force SDA low
rcall i2c_delay_T2 ;delay T/2
rcall i2c_write ;write address
ret
.endfunc
;*************************************************************************
; Issues a repeated start condition and sends address and transfer direction.
; return 0 = device accessible, 1= failed to access device
;
; extern unsigned char i2c_rep_start(unsigned char addr);
; addr = r24, return = r25(=0):r24
;*************************************************************************
.global i2c_rep_start
.func i2c_rep_start
i2c_rep_start:
sbi SCL_DDR,SCL ;force SCL low
rcall i2c_delay_T2 ;delay T/2
cbi SDA_DDR,SDA ;release SDA
rcall i2c_delay_T2 ;delay T/2
cbi SCL_DDR,SCL ;release SCL
rcall i2c_delay_T2 ;delay T/2
sbi SDA_DDR,SDA ;force SDA low
rcall i2c_delay_T2 ;delay T/2
rcall i2c_write ;write address
ret
.endfunc
;*************************************************************************
; Issues a start condition and sends address and transfer direction.
; If device is busy, use ack polling to wait until device is ready
;
; extern void i2c_start_wait(unsigned char addr);
; addr = r24
;*************************************************************************
.global i2c_start_wait
.func i2c_start_wait
i2c_start_wait:
mov __tmp_reg__,r24
i2c_start_wait1:
sbi SDA_DDR,SDA ;force SDA low
rcall i2c_delay_T2 ;delay T/2
mov r24,__tmp_reg__
rcall i2c_write ;write address
tst r24 ;if device not busy -> done
breq i2c_start_wait_done
rcall i2c_stop ;terminate write operation
rjmp i2c_start_wait1 ;device busy, poll ack again
i2c_start_wait_done:
ret
.endfunc
;*************************************************************************
; Terminates the data transfer and releases the I2C bus
;
; extern void i2c_stop(void)
;*************************************************************************
.global i2c_stop
.func i2c_stop
i2c_stop:
sbi SCL_DDR,SCL ;force SCL low
sbi SDA_DDR,SDA ;force SDA low
rcall i2c_delay_T2 ;delay T/2
cbi SCL_DDR,SCL ;release SCL
rcall i2c_delay_T2 ;delay T/2
cbi SDA_DDR,SDA ;release SDA
rcall i2c_delay_T2 ;delay T/2
ret
.endfunc
;*************************************************************************
; Send one byte to I2C device
; return 0 = write successful, 1 = write failed
;
; extern unsigned char i2c_write( unsigned char data );
; data = r24, return = r25(=0):r24
;*************************************************************************
.global i2c_write
.func i2c_write
i2c_write:
sec ;set carry flag
rol r24 ;shift in carry and out bit one
rjmp i2c_write_first
i2c_write_bit:
lsl r24 ;if transmit register empty
i2c_write_first:
breq i2c_get_ack
sbi SCL_DDR,SCL ;force SCL low
brcc i2c_write_low
nop
cbi SDA_DDR,SDA ;release SDA
rjmp i2c_write_high
i2c_write_low:
sbi SDA_DDR,SDA ;force SDA low
rjmp i2c_write_high
i2c_write_high:
rcall i2c_delay_T2 ;delay T/2
cbi SCL_DDR,SCL ;release SCL
rcall i2c_delay_T2 ;delay T/2
rjmp i2c_write_bit
i2c_get_ack:
sbi SCL_DDR,SCL ;force SCL low
cbi SDA_DDR,SDA ;release SDA
rcall i2c_delay_T2 ;delay T/2
cbi SCL_DDR,SCL ;release SCL
i2c_ack_wait:
sbis SCL_IN,SCL ;wait SCL high (in case wait states are inserted)
rjmp i2c_ack_wait
clr r24 ;return 0
sbic SDA_IN,SDA ;if SDA high -> return 1
ldi r24,1
rcall i2c_delay_T2 ;delay T/2
clr r25
ret
.endfunc
;*************************************************************************
; read one byte from the I2C device, send ack or nak to device
; (ack=1, send ack, request more data from device
; ack=0, send nak, read is followed by a stop condition)
;
; extern unsigned char i2c_read(unsigned char ack);
; ack = r24, return = r25(=0):r24
; extern unsigned char i2c_readAck(void);
; extern unsigned char i2c_readNak(void);
; return = r25(=0):r24
;*************************************************************************
.global i2c_readAck
.global i2c_readNak
.global i2c_read
.func i2c_read
i2c_readNak:
clr r24
rjmp i2c_read
i2c_readAck:
ldi r24,0x01
i2c_read:
ldi r23,0x01 ;data = 0x01
i2c_read_bit:
sbi SCL_DDR,SCL ;force SCL low
cbi SDA_DDR,SDA ;release SDA (from previous ACK)
rcall i2c_delay_T2 ;delay T/2
cbi SCL_DDR,SCL ;release SCL
rcall i2c_delay_T2 ;delay T/2
i2c_read_stretch:
sbis SCL_IN, SCL ;loop until SCL is high (allow slave to stretch SCL)
rjmp i2c_read_stretch
clc ;clear carry flag
sbic SDA_IN,SDA ;if SDA is high
sec ; set carry flag
rol r23 ;store bit
brcc i2c_read_bit ;while receive register not full
i2c_put_ack:
sbi SCL_DDR,SCL ;force SCL low
cpi r24,1
breq i2c_put_ack_low ;if (ack=0)
cbi SDA_DDR,SDA ; release SDA
rjmp i2c_put_ack_high
i2c_put_ack_low: ;else
sbi SDA_DDR,SDA ; force SDA low
i2c_put_ack_high:
rcall i2c_delay_T2 ;delay T/2
cbi SCL_DDR,SCL ;release SCL
i2c_put_ack_wait:
sbis SCL_IN,SCL ;wait SCL high
rjmp i2c_put_ack_wait
rcall i2c_delay_T2 ;delay T/2
mov r24,r23
clr r25
ret
.endfunc

View File

@ -0,0 +1,178 @@
#ifndef _I2CMASTER_H
#define _I2CMASTER_H 1
/*************************************************************************
* Title: C include file for the I2C master interface
* (i2cmaster.S or twimaster.c)
* Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
* File: $Id: i2cmaster.h,v 1.10 2005/03/06 22:39:57 Peter Exp $
* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
* Target: any AVR device
* Usage: see Doxygen manual
**************************************************************************/
#ifdef DOXYGEN
/**
@defgroup pfleury_ic2master I2C Master library
@code #include <i2cmaster.h> @endcode
@brief I2C (TWI) Master Software Library
Basic routines for communicating with I2C slave devices. This single master
implementation is limited to one bus master on the I2C bus.
This I2c library is implemented as a compact assembler software implementation of the I2C protocol
which runs on any AVR (i2cmaster.S) and as a TWI hardware interface for all AVR with built-in TWI hardware (twimaster.c).
Since the API for these two implementations is exactly the same, an application can be linked either against the
software I2C implementation or the hardware I2C implementation.
Use 4.7k pull-up resistor on the SDA and SCL pin.
Adapt the SCL and SDA port and pin definitions and eventually the delay routine in the module
i2cmaster.S to your target when using the software I2C implementation !
Adjust the CPU clock frequence F_CPU in twimaster.c or in the Makfile when using the TWI hardware implementaion.
@note
The module i2cmaster.S is based on the Atmel Application Note AVR300, corrected and adapted
to GNU assembler and AVR-GCC C call interface.
Replaced the incorrect quarter period delays found in AVR300 with
half period delays.
@author Peter Fleury pfleury@gmx.ch http://jump.to/fleury
@par API Usage Example
The following code shows typical usage of this library, see example test_i2cmaster.c
@code
#include <i2cmaster.h>
#define Dev24C02 0xA2 // device address of EEPROM 24C02, see datasheet
int main(void)
{
unsigned char ret;
i2c_init(); // initialize I2C library
// write 0x75 to EEPROM address 5 (Byte Write)
i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
i2c_write(0x05); // write address = 5
i2c_write(0x75); // write value 0x75 to EEPROM
i2c_stop(); // set stop conditon = release bus
// read previously written value back from EEPROM address 5
i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
i2c_write(0x05); // write address = 5
i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode
ret = i2c_readNak(); // read one byte from EEPROM
i2c_stop();
for(;;);
}
@endcode
*/
#endif /* DOXYGEN */
/**@{*/
#if (__GNUC__ * 100 + __GNUC_MINOR__) < 304
#error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !"
#endif
#include <avr/io.h>
/** defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start() */
#define I2C_READ 1
/** defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start() */
#define I2C_WRITE 0
/**
@brief initialize the I2C master interace. Need to be called only once
@param void
@return none
*/
extern void i2c_init(void);
/**
@brief Terminates the data transfer and releases the I2C bus
@param void
@return none
*/
extern void i2c_stop(void);
/**
@brief Issues a start condition and sends address and transfer direction
@param addr address and transfer direction of I2C device
@retval 0 device accessible
@retval 1 failed to access device
*/
extern unsigned char i2c_start(unsigned char addr);
/**
@brief Issues a repeated start condition and sends address and transfer direction
@param addr address and transfer direction of I2C device
@retval 0 device accessible
@retval 1 failed to access device
*/
extern unsigned char i2c_rep_start(unsigned char addr);
/**
@brief Issues a start condition and sends address and transfer direction
If device is busy, use ack polling to wait until device ready
@param addr address and transfer direction of I2C device
@return none
*/
extern void i2c_start_wait(unsigned char addr);
/**
@brief Send one byte to I2C device
@param data byte to be transfered
@retval 0 write successful
@retval 1 write failed
*/
extern unsigned char i2c_write(unsigned char data);
/**
@brief read one byte from the I2C device, request more data from device
@return byte read from I2C device
*/
extern unsigned char i2c_readAck(void);
/**
@brief read one byte from the I2C device, read is followed by a stop condition
@return byte read from I2C device
*/
extern unsigned char i2c_readNak(void);
/**
@brief read one byte from the I2C device
Implemented as a macro, which calls either i2c_readAck or i2c_readNak
@param ack 1 send ack, request more data from device<br>
0 send nak, read is followed by a stop condition
@return byte read from I2C device
*/
extern unsigned char i2c_read(unsigned char ack);
#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak();
/**@}*/
#endif

View File

@ -0,0 +1,392 @@
# Makefile to compile and link the I2C Master library and test program
#
# based on
# WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al.
#
# Note:
# The warnings which appear while converting ELF to AVR Extended COFF (make extcoff)
# can be ignored
#
#
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB).
#
# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio
# 4.07 or greater).
#
# make program = Download the hex file to the device, using avrdude. Please
# customize the avrdude settings below first!
#
# make filename.s = Just compile filename.c into the assembler code only
#
# To rebuild project do "make clean" then "make all".
#
# MCU name
MCU = at90s8515
# Output format. (can be srec, ihex, binary)
FORMAT = ihex
# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s
# Target file name (without extension).
TARGET = test_i2cmaster
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c
# List Assembler source files here.
# Make them always end in a capital .S. Files ending in a lowercase .s
# will not be considered source files but generated files (assembler
# output from the compiler), and will be deleted upon "make clean"!
# Even though the DOS/Win* filesystem matches both .s and .S the same,
# it will preserve the spelling of the filenames, and gcc itself does
# care about how the name is spelled on its command-line.
ASRC = i2cmaster.S
# List any extra directories to look for include files here.
# Each directory must be seperated by a space.
EXTRAINCDIRS =
# Optional compiler flags.
# -g: generate debugging information (for GDB, or for COFF conversion)
# -O*: optimization level
# -f...: tuning, see gcc manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -ahlms: create assembler listing
CFLAGS = -g -O$(OPT) \
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \
-Wall -Wstrict-prototypes \
-Wa,-adhlns=$(<:.c=.lst) \
$(patsubst %,-I%,$(EXTRAINCDIRS))
# Set a "language standard" compiler flag.
# Unremark just one line below to set the language standard to use.
# gnu99 = C99 + GNU extensions. See GCC manual for more information.
#CFLAGS += -std=c89
#CFLAGS += -std=gnu89
#CFLAGS += -std=c99
CFLAGS += -std=gnu99
# Optional assembler flags.
# -Wa,...: tell GCC to pass this to the assembler.
# -ahlms: create listing
# -gstabs: have the assembler create line number information; note that
# for use in COFF files, additional information about filenames
# and function names needs to be present in the assembler source
# files -- see avr-libc docs [FIXME: not yet described there]
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
# Optional linker flags.
# -Wl,...: tell GCC to pass this to linker.
# -Map: create map file
# --cref: add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
# Additional libraries
# Minimalistic printf version
#LDFLAGS += -Wl,-u,vfprintf -lprintf_min
# Floating point printf version (requires -lm below)
#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt
# -lm = math library
LDFLAGS += -lm
# Programming support using avrdude. Settings and variables.
# Programming hardware: alf avr910 avrisp bascom bsd
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
#
# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = stk500
AVRDUDE_PORT = com1 # programmer connected to serial device
#AVRDUDE_PORT = lpt1 # programmer connected to parallel port
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE += -y
# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_FLAGS += -V
# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_FLAGS += -v -v
# ---------------------------------------------------------------------------
# Define directories, if needed.
DIRAVR = c:/winavr
DIRAVRBIN = $(DIRAVR)/bin
DIRAVRUTILS = $(DIRAVR)/utils/bin
DIRINC = .
DIRLIB = $(DIRAVR)/avr/lib
# Define programs and commands.
SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
# Programming support using avrdude.
AVRDUDE = avrdude
REMOVE = rm -f
COPY = cp
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) -A $(TARGET).elf
# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin --------
MSG_END = -------- end --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
# Define all object files.
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)
# Define all listing files.
LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)
# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
# Default target.
all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \
$(TARGET).lss $(TARGET).sym sizeafter finished end
# Eye candy.
# AVR Studio 3.x does not check make's exit code but relies on
# the following magic strings to be generated by the compile job.
begin:
@echo
@echo $(MSG_BEGIN)
finished:
@echo $(MSG_ERRORS_NONE)
end:
@echo $(MSG_END)
@echo
# Display size of file.
sizebefore:
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi
sizeafter:
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
# Display compiler version information.
gccversion :
@$(CC) --version
# Convert ELF to COFF for use in debugging / simulating in
# AVR Studio or VMLAB.
COFFCONVERT=$(OBJCOPY) --debugging \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000
coff: $(TARGET).elf
@echo
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
extcoff: $(TARGET).elf
@echo
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
# Program the device.
program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
%.eep: %.elf
@echo
@echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
# Create extended listing file from ELF output file.
%.lss: %.elf
@echo
@echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S $< > $@
# Create a symbol table from ELF output file.
%.sym: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
avr-nm -n $< > $@
# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
@echo
@echo $(MSG_LINKING) $@
$(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
# Compile: create object files from C source files.
%.o : %.c
@echo
@echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $@
# Compile: create assembler files from C source files.
%.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $@
# Assemble: create object files from assembler source files.
%.o : %.S
@echo
@echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@
# Target: clean project.
clean: begin clean_list finished end
clean_list :
@echo
@echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).obj
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).obj
$(REMOVE) $(TARGET).a90
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lnk
$(REMOVE) $(TARGET).lss
$(REMOVE) $(OBJ)
$(REMOVE) $(LST)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
# Automatically generate C source code dependencies.
# (Code originally taken from the GNU make user manual and modified
# (See README.txt Credits).)
#
# Note that this will work with sh (bash) and sed that is shipped with WinAVR
# (see the SHELL variable defined above).
# This may not work with other shells or other seds.
#
%.d: %.c
set -e; $(CC) -MM $(ALL_CFLAGS) $< \
| sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \
[ -s $@ ] || rm -f $@
# Remove the '-' if you want to see the dependency files generated.
-include $(SRC:.c=.d)
# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \
clean clean_list program

View File

@ -0,0 +1,392 @@
# Makefile to compile and link the I2C Master library and test program
#
# based on
# WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al.
#
# Note:
# The warnings which appear while converting ELF to AVR Extended COFF (make extcoff)
# can be ignored
#
#
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB).
#
# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio
# 4.07 or greater).
#
# make program = Download the hex file to the device, using avrdude. Please
# customize the avrdude settings below first!
#
# make filename.s = Just compile filename.c into the assembler code only
#
# To rebuild project do "make clean" then "make all".
#
# MCU name
MCU = at90s8515
# Output format. (can be srec, ihex, binary)
FORMAT = ihex
# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s
# Target file name (without extension).
TARGET = test_i2cmaster
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c
# List Assembler source files here.
# Make them always end in a capital .S. Files ending in a lowercase .s
# will not be considered source files but generated files (assembler
# output from the compiler), and will be deleted upon "make clean"!
# Even though the DOS/Win* filesystem matches both .s and .S the same,
# it will preserve the spelling of the filenames, and gcc itself does
# care about how the name is spelled on its command-line.
ASRC = i2cmaster.S
# List any extra directories to look for include files here.
# Each directory must be seperated by a space.
EXTRAINCDIRS =
# Optional compiler flags.
# -g: generate debugging information (for GDB, or for COFF conversion)
# -O*: optimization level
# -f...: tuning, see gcc manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -ahlms: create assembler listing
CFLAGS = -g -O$(OPT) \
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \
-Wall -Wstrict-prototypes \
-Wa,-adhlns=$(<:.c=.lst) \
$(patsubst %,-I%,$(EXTRAINCDIRS))
# Set a "language standard" compiler flag.
# Unremark just one line below to set the language standard to use.
# gnu99 = C99 + GNU extensions. See GCC manual for more information.
#CFLAGS += -std=c89
#CFLAGS += -std=gnu89
#CFLAGS += -std=c99
CFLAGS += -std=gnu99
# Optional assembler flags.
# -Wa,...: tell GCC to pass this to the assembler.
# -ahlms: create listing
# -gstabs: have the assembler create line number information; note that
# for use in COFF files, additional information about filenames
# and function names needs to be present in the assembler source
# files -- see avr-libc docs [FIXME: not yet described there]
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
# Optional linker flags.
# -Wl,...: tell GCC to pass this to linker.
# -Map: create map file
# --cref: add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
# Additional libraries
# Minimalistic printf version
#LDFLAGS += -Wl,-u,vfprintf -lprintf_min
# Floating point printf version (requires -lm below)
#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt
# -lm = math library
LDFLAGS += -lm
# Programming support using avrdude. Settings and variables.
# Programming hardware: alf avr910 avrisp bascom bsd
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
#
# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = stk500
AVRDUDE_PORT = com1 # programmer connected to serial device
#AVRDUDE_PORT = lpt1 # programmer connected to parallel port
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE += -y
# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_FLAGS += -V
# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_FLAGS += -v -v
# ---------------------------------------------------------------------------
# Define directories, if needed.
DIRAVR = c:/winavr
DIRAVRBIN = $(DIRAVR)/bin
DIRAVRUTILS = $(DIRAVR)/utils/bin
DIRINC = .
DIRLIB = $(DIRAVR)/avr/lib
# Define programs and commands.
SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
# Programming support using avrdude.
AVRDUDE = avrdude
REMOVE = rm -f
COPY = cp
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) -A $(TARGET).elf
# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin --------
MSG_END = -------- end --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
# Define all object files.
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)
# Define all listing files.
LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)
# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
# Default target.
all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \
$(TARGET).lss $(TARGET).sym sizeafter finished end
# Eye candy.
# AVR Studio 3.x does not check make's exit code but relies on
# the following magic strings to be generated by the compile job.
begin:
@echo
@echo $(MSG_BEGIN)
finished:
@echo $(MSG_ERRORS_NONE)
end:
@echo $(MSG_END)
@echo
# Display size of file.
sizebefore:
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi
sizeafter:
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
# Display compiler version information.
gccversion :
@$(CC) --version
# Convert ELF to COFF for use in debugging / simulating in
# AVR Studio or VMLAB.
COFFCONVERT=$(OBJCOPY) --debugging \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000
coff: $(TARGET).elf
@echo
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
extcoff: $(TARGET).elf
@echo
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
# Program the device.
program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
%.eep: %.elf
@echo
@echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
# Create extended listing file from ELF output file.
%.lss: %.elf
@echo
@echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S $< > $@
# Create a symbol table from ELF output file.
%.sym: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
avr-nm -n $< > $@
# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
@echo
@echo $(MSG_LINKING) $@
$(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
# Compile: create object files from C source files.
%.o : %.c
@echo
@echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $@
# Compile: create assembler files from C source files.
%.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $@
# Assemble: create object files from assembler source files.
%.o : %.S
@echo
@echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@
# Target: clean project.
clean: begin clean_list finished end
clean_list :
@echo
@echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).obj
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).obj
$(REMOVE) $(TARGET).a90
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lnk
$(REMOVE) $(TARGET).lss
$(REMOVE) $(OBJ)
$(REMOVE) $(LST)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
# Automatically generate C source code dependencies.
# (Code originally taken from the GNU make user manual and modified
# (See README.txt Credits).)
#
# Note that this will work with sh (bash) and sed that is shipped with WinAVR
# (see the SHELL variable defined above).
# This may not work with other shells or other seds.
#
%.d: %.c
set -e; $(CC) -MM $(ALL_CFLAGS) $< \
| sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \
[ -s $@ ] || rm -f $@
# Remove the '-' if you want to see the dependency files generated.
-include $(SRC:.c=.d)
# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \
clean clean_list program

View File

@ -0,0 +1,502 @@
# ----------------------------------------------------------------------------
# Makefile to compile and link the TWImaster library and test program
# Author: Peter Fleury
# File: $Id: makefile.twimaster,v 1.1 2005/03/29 14:50:05 Peter Exp $
# based on WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
#
# Adjust F_CPU below to the clock frequency in Mhz of your AVR target
#
# rename this file to "makefile" or invoke with "make -f makefile.twimaster"
#
#----------------------------------------------------------------------------
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF.
#
# make extcoff = Convert ELF to AVR Extended COFF.
#
# make program = Download the hex file to the device, using avrdude.
# Please customize the avrdude settings below first!
#
# make debug = Start either simulavr or avarice as specified for debugging,
# with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
# bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------------------------------------------------------------------------
# MCU name
MCU = atmega8
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
F_CPU = 4000000
# Output format. (can be srec, ihex, binary)
FORMAT = ihex
# Target file name (without extension).
TARGET = test_i2cmaster
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c twimaster.c
# List Assembler source files here.
# Make them always end in a capital .S. Files ending in a lowercase .s
# will not be considered source files but generated files (assembler
# output from the compiler), and will be deleted upon "make clean"!
# Even though the DOS/Win* filesystem matches both .s and .S the same,
# it will preserve the spelling of the filenames, and gcc itself does
# care about how the name is spelled on its command-line.
ASRC =
# Optimization level, can be [0, 1, 2, 3, s].
# 0 = turn off optimization. s = optimize for size.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s
# Debugging format.
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
# AVR Studio 4.10 requires dwarf-2.
# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
DEBUG = dwarf-2
# List any extra directories to look for include files here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRAINCDIRS =
# Compiler flag to set the C Standard level.
# c89 = "ANSI" C
# gnu89 = c89 plus GCC extensions
# c99 = ISO C99 standard (not yet fully implemented)
# gnu99 = c99 plus GCC extensions
CSTANDARD = -std=gnu99
# Place -D or -U options here
CDEFS = -DF_CPU=$(F_CPU)UL
# Place -I options here
CINCS =
#---------------- Compiler Options ----------------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS) $(CINCS)
CFLAGS += -O$(OPT)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wstrict-prototypes
CFLAGS += -Wa,-adhlns=$(<:.c=.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)
#---------------- Assembler Options ----------------
# -Wa,...: tell GCC to pass this to the assembler.
# -ahlms: create listing
# -gstabs: have the assembler create line number information; note that
# for use in COFF files, additional information about filenames
# and function names needs to be present in the assembler source
# files -- see avr-libc docs [FIXME: not yet described there]
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
#---------------- Library Options ----------------
# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB =
#PRINTF_LIB = $(PRINTF_LIB_MIN)
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
# If this is left blank, then it will use the Standard scanf version.
SCANF_LIB =
#SCANF_LIB = $(SCANF_LIB_MIN)
#SCANF_LIB = $(SCANF_LIB_FLOAT)
MATH_LIB = -lm
#---------------- External Memory Options ----------------
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# used for variables (.data/.bss) and heap (malloc()).
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# only used for heap (malloc()).
#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff
EXTMEMOPTS =
#---------------- Linker Options ----------------
# -Wl,...: tell GCC to pass this to linker.
# -Map: create map file
# --cref: add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
#---------------- Programming Options (avrdude) ----------------
# Programming hardware: alf avr910 avrisp bascom bsd
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
#
# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = stk500
# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = com1 # programmer connected to serial device
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE_COUNTER = -y
# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_NO_VERIFY = -V
# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_VERBOSE = -v -v
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
#---------------- Debugging Options ----------------
# For simulavr only - target MCU frequency.
DEBUG_MFREQ = $(F_CPU)
# Set the DEBUG_UI to either gdb or insight.
# DEBUG_UI = gdb
DEBUG_UI = insight
# Set the debugging back-end to either avarice, simulavr.
DEBUG_BACKEND = avarice
#DEBUG_BACKEND = simulavr
# GDB Init Filename.
GDBINIT_FILE = __avr_gdbinit
# When using avarice settings for the JTAG
JTAG_DEV = /dev/com1
# Debugging port used to communicate between GDB / avarice / simulavr.
DEBUG_PORT = 4242
# Debugging host used to communicate between GDB / avarice / simulavr, normally
# just set to localhost unless doing some sort of crazy debugging when
# avarice is running on a different computer.
DEBUG_HOST = localhost
#============================================================================
# Define programs and commands.
SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
COPY = cp
WINSHELL = cmd
# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin --------
MSG_END = -------- end --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
# Define all object files.
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)
# Define all listing files.
LST = $(SRC:.c=.lst) $(ASRC:.S=.lst)
# Compiler flags to generate dependency files.
GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d
# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
# Default target.
all: begin gccversion sizebefore build sizeafter end
build: elf hex eep lss sym
elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(TARGET).lss
sym: $(TARGET).sym
# Eye candy.
# AVR Studio 3.x does not check make's exit code but relies on
# the following magic strings to be generated by the compile job.
begin:
@echo
@echo $(MSG_BEGIN)
end:
@echo $(MSG_END)
@echo
# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) -A $(TARGET).elf
AVRMEM = avr-mem.sh $(TARGET).elf $(MCU)
sizebefore:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
$(AVRMEM) 2>/dev/null; echo; fi
sizeafter:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
$(AVRMEM) 2>/dev/null; echo; fi
# Display compiler version information.
gccversion :
@$(CC) --version
# Program the device.
program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
# Generate avr-gdb config/init file which does the following:
# define the reset signal, load the target file, connect to target, and set
# a breakpoint at main().
gdb-config:
@$(REMOVE) $(GDBINIT_FILE)
@echo define reset >> $(GDBINIT_FILE)
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
@echo end >> $(GDBINIT_FILE)
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
ifeq ($(DEBUG_BACKEND),simulavr)
@echo load >> $(GDBINIT_FILE)
endif
@echo break main >> $(GDBINIT_FILE)
debug: gdb-config $(TARGET).elf
ifeq ($(DEBUG_BACKEND), avarice)
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
@$(WINSHELL) /c pause
else
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
endif
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT=$(OBJCOPY) --debugging \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000
coff: $(TARGET).elf
@echo
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
extcoff: $(TARGET).elf
@echo
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
%.eep: %.elf
@echo
@echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
# Create extended listing file from ELF output file.
%.lss: %.elf
@echo
@echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S $< > $@
# Create a symbol table from ELF output file.
%.sym: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
$(NM) -n $< > $@
# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
@echo
@echo $(MSG_LINKING) $@
$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
# Compile: create object files from C source files.
%.o : %.c
@echo
@echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $@
# Compile: create assembler files from C source files.
%.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $@
# Assemble: create object files from assembler source files.
%.o : %.S
@echo
@echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@
# Create preprocessed source for use in sending a bug report.
%.i : %.c
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
# Target: clean project.
clean: begin clean_list end
clean_list :
@echo
@echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lss
$(REMOVE) $(OBJ)
$(REMOVE) $(LST)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
$(REMOVE) .dep/*
# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion \
build elf hex eep lss sym coff extcoff \
clean clean_list program debug gdb-config

View File

@ -0,0 +1,78 @@
/****************************************************************************
Title: Access serial EEPROM 24C02 using I2C interace
Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
File: $Id: test_i2cmaster.c,v 1.2 2003/12/06 17:07:18 peter Exp $
Software: AVR-GCC 3.3
Hardware: AT90S8515 at 4 Mhz, any AVR device can be used
Description:
This example shows how the I2C library i2cmaster.S can be used to
access a serial eeprom.
Based on Atmel Application Note AVR300, adapted to AVR-GCC C interface
*****************************************************************************/
#include <avr/io.h>
#include "i2cmaster.h"
#define Dev24C02 0xA2 // device address of EEPROM 24C02, see datasheet
int main(void)
{
unsigned char ret;
DDRB = 0xff; // use all pins on port B for output
PORTB = 0xff; // (active low LED's )
i2c_init(); // init I2C interface
/* write 0x75 to eeprom address 0x05 (Byte Write) */
ret = i2c_start(Dev24C02+I2C_WRITE); // set device address and write mode
if ( ret ) {
/* failed to issue start condition, possibly no device found */
i2c_stop();
PORTB=0x00; // activate all 8 LED to show error */
}else {
/* issuing start condition ok, device accessible */
i2c_write(0x05); // write address = 5
i2c_write(0x75); // ret=0 -> Ok, ret=1 -> no ACK
i2c_stop(); // set stop conditon = release bus
/* write ok, read value back from eeprom address 0x05, wait until
the device is no longer busy from the previous write operation */
i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
i2c_write(0x05); // write address = 5
i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode
ret = i2c_readNak(); // read one byte
i2c_stop();
PORTB = ~ret; // output byte on the LED's
/* write 0x70,0x71,072,073 to eeprom address 0x00..0x03 (Page Write),
wait until the device is no longer busy from the previous write operation */
i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
i2c_write(0x00); // write start address = 0
i2c_write(0x70); // write data to address 0
i2c_write(0x71); // " " " " 1
i2c_write(0x72); // " " " " 2
i2c_write(0x74); // " " " " 3
i2c_stop(); // set stop conditon = release bus
/* write ok, read value back from eeprom address 0..3 (Sequencial Read),
wait until the device is no longer busy from the previous write operation */
i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
i2c_write(0x00); // write address = 0
i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode
ret = i2c_readAck(); // read one byte form address 0
ret = i2c_readAck(); // " " " " " 1
ret = i2c_readAck(); // " " " " " 2
ret = i2c_readNak(); // " " " " " 3
i2c_stop(); // set stop condition = release bus
PORTB = ~ret; // output byte on the LED's
}
for(;;);
}

View File

@ -0,0 +1,202 @@
/*************************************************************************
* Title: I2C master library using hardware TWI interface
* Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
* File: $Id: twimaster.c,v 1.3 2005/07/02 11:14:21 Peter Exp $
* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
* Target: any AVR device with hardware TWI
* Usage: API compatible with I2C Software Library i2cmaster.h
**************************************************************************/
#include <inttypes.h>
#include <compat/twi.h>
#include "i2cmaster.h"
/* define CPU frequency in Mhz here if not defined in Makefile */
#ifndef F_CPU
#define F_CPU 4000000UL
#endif
/* I2C clock in Hz */
#define SCL_CLOCK 400000 // previously set to 100000L ::2012, Ben Blazak::
/*************************************************************************
Initialization of the I2C bus interface. Need to be called only once
*************************************************************************/
void i2c_init(void)
{
/* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */
TWSR = 0; /* no prescaler */
TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /* must be > 10 for stable operation */
}/* i2c_init */
/*************************************************************************
Issues a start condition and sends address and transfer direction.
return 0 = device accessible, 1= failed to access device
*************************************************************************/
unsigned char i2c_start(unsigned char address)
{
uint8_t twst;
// send START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
// wait until transmission completed
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
// send device address
TWDR = address;
TWCR = (1<<TWINT) | (1<<TWEN);
// wail until transmission completed and ACK/NACK has been received
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
return 0;
}/* i2c_start */
/*************************************************************************
Issues a start condition and sends address and transfer direction.
If device is busy, use ack polling to wait until device is ready
Input: address and transfer direction of I2C device
*************************************************************************/
void i2c_start_wait(unsigned char address)
{
uint8_t twst;
while ( 1 )
{
// send START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
// wait until transmission completed
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst != TW_START) && (twst != TW_REP_START)) continue;
// send device address
TWDR = address;
TWCR = (1<<TWINT) | (1<<TWEN);
// wail until transmission completed
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) )
{
/* device busy, send stop condition to terminate write operation */
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
// wait until stop condition is executed and bus released
while(TWCR & (1<<TWSTO));
continue;
}
//if( twst != TW_MT_SLA_ACK) return 1;
break;
}
}/* i2c_start_wait */
/*************************************************************************
Issues a repeated start condition and sends address and transfer direction
Input: address and transfer direction of I2C device
Return: 0 device accessible
1 failed to access device
*************************************************************************/
unsigned char i2c_rep_start(unsigned char address)
{
return i2c_start( address );
}/* i2c_rep_start */
/*************************************************************************
Terminates the data transfer and releases the I2C bus
*************************************************************************/
void i2c_stop(void)
{
/* send stop condition */
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
// wait until stop condition is executed and bus released
while(TWCR & (1<<TWSTO));
}/* i2c_stop */
/*************************************************************************
Send one byte to I2C device
Input: byte to be transfered
Return: 0 write successful
1 write failed
*************************************************************************/
unsigned char i2c_write( unsigned char data )
{
uint8_t twst;
// send data to the previously addressed device
TWDR = data;
TWCR = (1<<TWINT) | (1<<TWEN);
// wait until transmission completed
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits
twst = TW_STATUS & 0xF8;
if( twst != TW_MT_DATA_ACK) return 1;
return 0;
}/* i2c_write */
/*************************************************************************
Read one byte from the I2C device, request more data from device
Return: byte read from I2C device
*************************************************************************/
unsigned char i2c_readAck(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
while(!(TWCR & (1<<TWINT)));
return TWDR;
}/* i2c_readAck */
/*************************************************************************
Read one byte from the I2C device, read is followed by a stop condition
Return: byte read from I2C device
*************************************************************************/
unsigned char i2c_readNak(void)
{
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT)));
return TWDR;
}/* i2c_readNak */

View File

@ -1,10 +1,5 @@
# Hey Emacs, this is a -*- makefile -*-
#----------------------------------------------------------------------------
#----------------------------------------------------------------------------
# Copied from <http://pjrc.com/teensy/blinky.zip>. Modified slightly to work
# with <https://github.com/benblazak/ergodox-firmware>.
#----------------------------------------------------------------------------
#----------------------------------------------------------------------------
# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
#
# Released to the Public Domain
@ -46,11 +41,13 @@
# Target file name (without extension).
TARGET = ergodox-firmware
TARGET = blinky
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c
SRC = $(TARGET).c \
usb_debug_only.c \
print.c
# MCU name, you MUST set this to match the board you are using
# type "make clean" after changing this, so all files will be rebuilt

View File

@ -0,0 +1,159 @@
/* LED Blink Example with USB Debug Channel for Teensy USB Development Board
* http://www.pjrc.com/teensy/
* Copyright (c) 2008, 2010 PJRC.COM, LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "usb_debug_only.h"
#include "print.h"
// Teensy 2.0: LED is active high
#if defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB1286__)
#define LED_ON (PORTD |= (1<<6))
#define LED_OFF (PORTD &= ~(1<<6))
// Teensy 1.0: LED is active low
#else
#define LED_ON (PORTD &= ~(1<<6))
#define LED_OFF (PORTD |= (1<<6))
#endif
#define LED_CONFIG (DDRD |= (1<<6))
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
#define DIT 80 /* unit time for morse code */
void morse_character(char c);
void morse_P(const char *s);
const unsigned char morse_code_table[];
int main(void)
{
unsigned char i;
// set for 16 MHz clock, and make sure the LED is off
CPU_PRESCALE(0);
LED_CONFIG;
LED_OFF;
// initialize the USB, but don't want for the host to
// configure. The first several messages sent will be
// lost because the PC hasn't configured the USB yet,
// but we care more about blinking than debug messages!
usb_init();
// blink morse code messages!
while (1) {
for (i=0; i<6; i++) {
morse_P(PSTR("SOS"));
_delay_ms(1500);
}
morse_P(PSTR("DOES ANYBODY STILL KNOW MORSE CODE?"));
_delay_ms(4000);
}
}
// blink a single character in Morse code
void morse_character(char c)
{
unsigned char code, count;
if (c == ' ') {
print("Space\n");
_delay_ms(DIT * 7);
return;
}
if (c < 'A' || c > 'Z') {
print("Opps, unsupported character: ");
pchar(c);
print("\n");
return;
}
print("Char ");
pchar(c);
pchar(':');
code = pgm_read_byte(morse_code_table + (c - 'A'));
for (count = code & 0x07; count > 0; count--) {
LED_ON;
if (code & 0x80) {
print(" dah");
_delay_ms(DIT * 3);
} else {
print(" dit");
_delay_ms(DIT);
}
LED_OFF;
_delay_ms(DIT);
code = code << 1;
}
print("\n");
_delay_ms(DIT * 2);
}
// blink an entire message in Morse code
// the string must be in flash memory (using PSTR macro)
void morse_P(const char *s)
{
char c;
while (1) {
c = pgm_read_byte(s++);
if (!c) break;
morse_character(c);
}
print("\n");
}
// lookup table for all 26 letters. Upper 5 bits are the pulses
// to send (MSB first), and the lower 3 bits are the number of
// bits to send for this letter.
const unsigned char PROGMEM morse_code_table[] = {
0x40 + 2, // A: .-
0x80 + 4, // B: -...
0xA0 + 4, // C: -.-.
0x80 + 3, // D: -..
0x00 + 1, // E: .
0x20 + 4, // F: ..-.
0xC0 + 3, // G: --.
0x00 + 4, // H: ....
0x00 + 2, // I: ..
0x70 + 4, // J: .---
0xA0 + 3, // K: -.-
0x40 + 4, // L: .-..
0xC0 + 2, // M: --
0x80 + 2, // N: -.
0xE0 + 3, // O: ---
0x60 + 4, // P: .--.
0xD0 + 4, // Q: --.-
0x40 + 3, // R: .-.
0x00 + 3, // S: ...
0x80 + 1, // T: -
0x20 + 3, // U: ..-
0x10 + 4, // V: ...-
0x60 + 3, // W: .--
0x90 + 4, // X: -..-
0xB0 + 4, // Y: -.--
0xC0 + 4 // Z: --..
};

View File

@ -0,0 +1,614 @@
# Hey Emacs, this is a -*- makefile -*-
#----------------------------------------------------------------------------
# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
#
# Released to the Public Domain
#
# Additional material for this makefile was written by:
# Peter Fleury
# Tim Henigan
# Colin O'Flynn
# Reiner Patommel
# Markus Pfaff
# Sander Pool
# Frederik Rouleau
# Carlos Lamas
#
#----------------------------------------------------------------------------
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF.
#
# make extcoff = Convert ELF to AVR Extended COFF.
#
# make program = Download the hex file to the device, using avrdude.
# Please customize the avrdude settings below first!
#
# make debug = Start either simulavr or avarice as specified for debugging,
# with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
# bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------------------------------------------------------------------------
# Target file name (without extension).
TARGET = example
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
usb_keyboard.c
# MCU name, you MUST set this to match the board you are using
# type "make clean" after changing this, so all files will be rebuilt
#
#MCU = at90usb162 # Teensy 1.0
MCU = atmega32u4 # Teensy 2.0
#MCU = at90usb646 # Teensy++ 1.0
#MCU = at90usb1286 # Teensy++ 2.0
# Processor frequency.
# Normally the first thing your program should do is set the clock prescaler,
# so your program will run at the correct speed. You should also set this
# variable to same clock speed. The _delay_ms() macro uses this, and many
# examples use this variable to calculate timings. Do not add a "UL" here.
F_CPU = 16000000
# Output format. (can be srec, ihex, binary)
FORMAT = ihex
# Object files directory
# To put object files in current directory, use a dot (.), do NOT make
# this an empty or blank macro!
OBJDIR = .
# List C++ source files here. (C dependencies are automatically generated.)
CPPSRC =
# List Assembler source files here.
# Make them always end in a capital .S. Files ending in a lowercase .s
# will not be considered source files but generated files (assembler
# output from the compiler), and will be deleted upon "make clean"!
# Even though the DOS/Win* filesystem matches both .s and .S the same,
# it will preserve the spelling of the filenames, and gcc itself does
# care about how the name is spelled on its command-line.
ASRC =
# Optimization level, can be [0, 1, 2, 3, s].
# 0 = turn off optimization. s = optimize for size.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s
# Debugging format.
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
# AVR Studio 4.10 requires dwarf-2.
# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
DEBUG = dwarf-2
# List any extra directories to look for include files here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRAINCDIRS =
# Compiler flag to set the C Standard level.
# c89 = "ANSI" C
# gnu89 = c89 plus GCC extensions
# c99 = ISO C99 standard (not yet fully implemented)
# gnu99 = c99 plus GCC extensions
CSTANDARD = -std=gnu99
# Place -D or -U options here for C sources
CDEFS = -DF_CPU=$(F_CPU)UL
# Place -D or -U options here for ASM sources
ADEFS = -DF_CPU=$(F_CPU)
# Place -D or -U options here for C++ sources
CPPDEFS = -DF_CPU=$(F_CPU)UL
#CPPDEFS += -D__STDC_LIMIT_MACROS
#CPPDEFS += -D__STDC_CONSTANT_MACROS
#---------------- Compiler Options C ----------------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS)
CFLAGS += -O$(OPT)
CFLAGS += -funsigned-char
CFLAGS += -funsigned-bitfields
CFLAGS += -ffunction-sections
CFLAGS += -fpack-struct
CFLAGS += -fshort-enums
CFLAGS += -Wall
CFLAGS += -Wstrict-prototypes
#CFLAGS += -mshort-calls
#CFLAGS += -fno-unit-at-a-time
#CFLAGS += -Wundef
#CFLAGS += -Wunreachable-code
#CFLAGS += -Wsign-compare
CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)
#---------------- Compiler Options C++ ----------------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CPPFLAGS = -g$(DEBUG)
CPPFLAGS += $(CPPDEFS)
CPPFLAGS += -O$(OPT)
CPPFLAGS += -funsigned-char
CPPFLAGS += -funsigned-bitfields
CPPFLAGS += -fpack-struct
CPPFLAGS += -fshort-enums
CPPFLAGS += -fno-exceptions
CPPFLAGS += -Wall
CPPFLAGS += -Wundef
#CPPFLAGS += -mshort-calls
#CPPFLAGS += -fno-unit-at-a-time
#CPPFLAGS += -Wstrict-prototypes
#CPPFLAGS += -Wunreachable-code
#CPPFLAGS += -Wsign-compare
CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
#CPPFLAGS += $(CSTANDARD)
#---------------- Assembler Options ----------------
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns: create listing
# -gstabs: have the assembler create line number information; note that
# for use in COFF files, additional information about filenames
# and function names needs to be present in the assembler source
# files -- see avr-libc docs [FIXME: not yet described there]
# -listing-cont-lines: Sets the maximum number of continuation lines of hex
# dump that will be displayed for a given single line of source input.
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
#---------------- Library Options ----------------
# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB =
#PRINTF_LIB = $(PRINTF_LIB_MIN)
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
# If this is left blank, then it will use the Standard scanf version.
SCANF_LIB =
#SCANF_LIB = $(SCANF_LIB_MIN)
#SCANF_LIB = $(SCANF_LIB_FLOAT)
MATH_LIB = -lm
# List any extra directories to look for libraries here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRALIBDIRS =
#---------------- External Memory Options ----------------
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# used for variables (.data/.bss) and heap (malloc()).
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# only used for heap (malloc()).
#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
EXTMEMOPTS =
#---------------- Linker Options ----------------
# -Wl,...: tell GCC to pass this to linker.
# -Map: create map file
# --cref: add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS += -Wl,--relax
LDFLAGS += -Wl,--gc-sections
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
#LDFLAGS += -T linker_script.x
#---------------- Programming Options (avrdude) ----------------
# Programming hardware
# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = stk500v2
# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = com1 # programmer connected to serial device
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE_COUNTER = -y
# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_NO_VERIFY = -V
# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_VERBOSE = -v -v
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
#---------------- Debugging Options ----------------
# For simulavr only - target MCU frequency.
DEBUG_MFREQ = $(F_CPU)
# Set the DEBUG_UI to either gdb or insight.
# DEBUG_UI = gdb
DEBUG_UI = insight
# Set the debugging back-end to either avarice, simulavr.
DEBUG_BACKEND = avarice
#DEBUG_BACKEND = simulavr
# GDB Init Filename.
GDBINIT_FILE = __avr_gdbinit
# When using avarice settings for the JTAG
JTAG_DEV = /dev/com1
# Debugging port used to communicate between GDB / avarice / simulavr.
DEBUG_PORT = 4242
# Debugging host used to communicate between GDB / avarice / simulavr, normally
# just set to localhost unless doing some sort of crazy debugging when
# avarice is running on a different computer.
DEBUG_HOST = localhost
#============================================================================
# Define programs and commands.
SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
AR = avr-ar rcs
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
REMOVEDIR = rm -rf
COPY = cp
WINSHELL = cmd
# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin --------
MSG_END = -------- end --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling C:
MSG_COMPILING_CPP = Compiling C++:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
MSG_CREATING_LIBRARY = Creating library:
# Define all object files.
OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
# Define all listing files.
LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
# Compiler flags to generate dependency files.
GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
# Default target.
all: begin gccversion sizebefore build sizeafter end
# Change the build target to build a HEX file or a library.
build: elf hex eep lss sym
#build: lib
elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(TARGET).lss
sym: $(TARGET).sym
LIBNAME=lib$(TARGET).a
lib: $(LIBNAME)
# Eye candy.
# AVR Studio 3.x does not check make's exit code but relies on
# the following magic strings to be generated by the compile job.
begin:
@echo
@echo $(MSG_BEGIN)
end:
@echo $(MSG_END)
@echo
# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
#ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf
ELFSIZE = $(SIZE) $(TARGET).elf
sizebefore:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
2>/dev/null; echo; fi
sizeafter:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
2>/dev/null; echo; fi
# Display compiler version information.
gccversion :
@$(CC) --version
# Program the device.
program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
# Generate avr-gdb config/init file which does the following:
# define the reset signal, load the target file, connect to target, and set
# a breakpoint at main().
gdb-config:
@$(REMOVE) $(GDBINIT_FILE)
@echo define reset >> $(GDBINIT_FILE)
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
@echo end >> $(GDBINIT_FILE)
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
ifeq ($(DEBUG_BACKEND),simulavr)
@echo load >> $(GDBINIT_FILE)
endif
@echo break main >> $(GDBINIT_FILE)
debug: gdb-config $(TARGET).elf
ifeq ($(DEBUG_BACKEND), avarice)
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
@$(WINSHELL) /c pause
else
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
endif
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT = $(OBJCOPY) --debugging
COFFCONVERT += --change-section-address .data-0x800000
COFFCONVERT += --change-section-address .bss-0x800000
COFFCONVERT += --change-section-address .noinit-0x800000
COFFCONVERT += --change-section-address .eeprom-0x810000
coff: $(TARGET).elf
@echo
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
extcoff: $(TARGET).elf
@echo
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -R .signature $< $@
%.eep: %.elf
@echo
@echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
# Create extended listing file from ELF output file.
%.lss: %.elf
@echo
@echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S -z $< > $@
# Create a symbol table from ELF output file.
%.sym: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
$(NM) -n $< > $@
# Create library from object files.
.SECONDARY : $(TARGET).a
.PRECIOUS : $(OBJ)
%.a: $(OBJ)
@echo
@echo $(MSG_CREATING_LIBRARY) $@
$(AR) $@ $(OBJ)
# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
@echo
@echo $(MSG_LINKING) $@
$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
# Compile: create object files from C source files.
$(OBJDIR)/%.o : %.c
@echo
@echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $@
# Compile: create object files from C++ source files.
$(OBJDIR)/%.o : %.cpp
@echo
@echo $(MSG_COMPILING_CPP) $<
$(CC) -c $(ALL_CPPFLAGS) $< -o $@
# Compile: create assembler files from C source files.
%.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $@
# Compile: create assembler files from C++ source files.
%.s : %.cpp
$(CC) -S $(ALL_CPPFLAGS) $< -o $@
# Assemble: create object files from assembler source files.
$(OBJDIR)/%.o : %.S
@echo
@echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@
# Create preprocessed source for use in sending a bug report.
%.i : %.c
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
# Target: clean project.
clean: begin clean_list end
clean_list :
@echo
@echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lss
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
$(REMOVE) $(SRC:.c=.i)
$(REMOVEDIR) .dep
# Create object files directory
$(shell mkdir $(OBJDIR) 2>/dev/null)
# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion \
build elf hex eep lss sym coff extcoff \
clean clean_list program debug gdb-config

View File

@ -0,0 +1,124 @@
/* Keyboard example for Teensy USB Development Board
* http://www.pjrc.com/teensy/usb_keyboard.html
* Copyright (c) 2008 PJRC.COM, LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "usb_keyboard.h"
#define LED_CONFIG (DDRD |= (1<<6))
#define LED_ON (PORTD &= ~(1<<6))
#define LED_OFF (PORTD |= (1<<6))
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
uint8_t number_keys[10]=
{KEY_0,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7,KEY_8,KEY_9};
uint16_t idle_count=0;
int main(void)
{
uint8_t b, d, mask, i, reset_idle;
uint8_t b_prev=0xFF, d_prev=0xFF;
// set for 16 MHz clock
CPU_PRESCALE(0);
// Configure all port B and port D pins as inputs with pullup resistors.
// See the "Using I/O Pins" page for details.
// http://www.pjrc.com/teensy/pins.html
DDRD = 0x00;
DDRB = 0x00;
PORTB = 0xFF;
PORTD = 0xFF;
// Initialize the USB, and then wait for the host to set configuration.
// If the Teensy is powered without a PC connected to the USB port,
// this will wait forever.
usb_init();
while (!usb_configured()) /* wait */ ;
// Wait an extra second for the PC's operating system to load drivers
// and do whatever it does to actually be ready for input
_delay_ms(1000);
// Configure timer 0 to generate a timer overflow interrupt every
// 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock
// This demonstrates how to use interrupts to implement a simple
// inactivity timeout.
TCCR0A = 0x00;
TCCR0B = 0x05;
TIMSK0 = (1<<TOIE0);
while (1) {
// read all port B and port D pins
b = PINB;
d = PIND;
// check if any pins are low, but were high previously
mask = 1;
reset_idle = 0;
for (i=0; i<8; i++) {
if (((b & mask) == 0) && (b_prev & mask) != 0) {
usb_keyboard_press(KEY_B, KEY_SHIFT);
usb_keyboard_press(number_keys[i], 0);
reset_idle = 1;
}
if (((d & mask) == 0) && (d_prev & mask) != 0) {
usb_keyboard_press(KEY_D, KEY_SHIFT);
usb_keyboard_press(number_keys[i], 0);
reset_idle = 1;
}
mask = mask << 1;
}
// if any keypresses were detected, reset the idle counter
if (reset_idle) {
// variables shared with interrupt routines must be
// accessed carefully so the interrupt routine doesn't
// try to use the variable in the middle of our access
cli();
idle_count = 0;
sei();
}
// now the current pins will be the previous, and
// wait a short delay so we're not highly sensitive
// to mechanical "bounce".
b_prev = b;
d_prev = d;
_delay_ms(2);
}
}
// This interrupt routine is run approx 61 times per second.
// A very simple inactivity timeout is implemented, where we
// will send a space character.
ISR(TIMER0_OVF_vect)
{
idle_count++;
if (idle_count > 61 * 8) {
idle_count = 0;
usb_keyboard_press(KEY_SPACE, 0);
}
}

View File

@ -0,0 +1,592 @@
/* USB Keyboard Example for Teensy USB Development Board
* http://www.pjrc.com/teensy/usb_keyboard.html
* Copyright (c) 2009 PJRC.COM, LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// Version 1.0: Initial Release
// Version 1.1: Add support for Teensy 2.0
#define USB_SERIAL_PRIVATE_INCLUDE
#include "usb_keyboard.h"
/**************************************************************************
*
* Configurable Options
*
**************************************************************************/
// You can change these to give your code its own name.
#define STR_MANUFACTURER L"MfgName"
#define STR_PRODUCT L"Keyboard"
// Mac OS-X and Linux automatically load the correct drivers. On
// Windows, even though the driver is supplied by Microsoft, an
// INF file is needed to load the driver. These numbers need to
// match the INF file.
#define VENDOR_ID 0x16C0
#define PRODUCT_ID 0x047C
// USB devices are supposed to implment a halt feature, which is
// rarely (if ever) used. If you comment this line out, the halt
// code will be removed, saving 102 bytes of space (gcc 4.3.0).
// This is not strictly USB compliant, but works with all major
// operating systems.
#define SUPPORT_ENDPOINT_HALT
/**************************************************************************
*
* Endpoint Buffer Configuration
*
**************************************************************************/
#define ENDPOINT0_SIZE 32
#define KEYBOARD_INTERFACE 0
#define KEYBOARD_ENDPOINT 3
#define KEYBOARD_SIZE 8
#define KEYBOARD_BUFFER EP_DOUBLE_BUFFER
static const uint8_t PROGMEM endpoint_config_table[] = {
0,
0,
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_BUFFER,
0
};
/**************************************************************************
*
* Descriptor Data
*
**************************************************************************/
// Descriptors are the data that your computer reads when it auto-detects
// this USB device (called "enumeration" in USB lingo). The most commonly
// changed items are editable at the top of this file. Changing things
// in here should only be done by those who've read chapter 9 of the USB
// spec and relevant portions of any USB class specifications!
static uint8_t PROGMEM device_descriptor[] = {
18, // bLength
1, // bDescriptorType
0x00, 0x02, // bcdUSB
0, // bDeviceClass
0, // bDeviceSubClass
0, // bDeviceProtocol
ENDPOINT0_SIZE, // bMaxPacketSize0
LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor
LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct
0x00, 0x01, // bcdDevice
1, // iManufacturer
2, // iProduct
0, // iSerialNumber
1 // bNumConfigurations
};
// Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60
static uint8_t PROGMEM keyboard_hid_report_desc[] = {
0x05, 0x01, // Usage Page (Generic Desktop),
0x09, 0x06, // Usage (Keyboard),
0xA1, 0x01, // Collection (Application),
0x75, 0x01, // Report Size (1),
0x95, 0x08, // Report Count (8),
0x05, 0x07, // Usage Page (Key Codes),
0x19, 0xE0, // Usage Minimum (224),
0x29, 0xE7, // Usage Maximum (231),
0x15, 0x00, // Logical Minimum (0),
0x25, 0x01, // Logical Maximum (1),
0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte
0x95, 0x01, // Report Count (1),
0x75, 0x08, // Report Size (8),
0x81, 0x03, // Input (Constant), ;Reserved byte
0x95, 0x05, // Report Count (5),
0x75, 0x01, // Report Size (1),
0x05, 0x08, // Usage Page (LEDs),
0x19, 0x01, // Usage Minimum (1),
0x29, 0x05, // Usage Maximum (5),
0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report
0x95, 0x01, // Report Count (1),
0x75, 0x03, // Report Size (3),
0x91, 0x03, // Output (Constant), ;LED report padding
0x95, 0x06, // Report Count (6),
0x75, 0x08, // Report Size (8),
0x15, 0x00, // Logical Minimum (0),
0x25, 0x68, // Logical Maximum(104),
0x05, 0x07, // Usage Page (Key Codes),
0x19, 0x00, // Usage Minimum (0),
0x29, 0x68, // Usage Maximum (104),
0x81, 0x00, // Input (Data, Array),
0xc0 // End Collection
};
#define CONFIG1_DESC_SIZE (9+9+9+7)
#define KEYBOARD_HID_DESC_OFFSET (9+9)
static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
// configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
9, // bLength;
2, // bDescriptorType;
LSB(CONFIG1_DESC_SIZE), // wTotalLength
MSB(CONFIG1_DESC_SIZE),
1, // bNumInterfaces
1, // bConfigurationValue
0, // iConfiguration
0xC0, // bmAttributes
50, // bMaxPower
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
9, // bLength
4, // bDescriptorType
KEYBOARD_INTERFACE, // bInterfaceNumber
0, // bAlternateSetting
1, // bNumEndpoints
0x03, // bInterfaceClass (0x03 = HID)
0x01, // bInterfaceSubClass (0x01 = Boot)
0x01, // bInterfaceProtocol (0x01 = Keyboard)
0, // iInterface
// HID interface descriptor, HID 1.11 spec, section 6.2.1
9, // bLength
0x21, // bDescriptorType
0x11, 0x01, // bcdHID
0, // bCountryCode
1, // bNumDescriptors
0x22, // bDescriptorType
sizeof(keyboard_hid_report_desc), // wDescriptorLength
0,
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
7, // bLength
5, // bDescriptorType
KEYBOARD_ENDPOINT | 0x80, // bEndpointAddress
0x03, // bmAttributes (0x03=intr)
KEYBOARD_SIZE, 0, // wMaxPacketSize
1 // bInterval
};
// If you're desperate for a little extra code memory, these strings
// can be completely removed if iManufacturer, iProduct, iSerialNumber
// in the device desciptor are changed to zeros.
struct usb_string_descriptor_struct {
uint8_t bLength;
uint8_t bDescriptorType;
int16_t wString[];
};
static struct usb_string_descriptor_struct PROGMEM string0 = {
4,
3,
{0x0409}
};
static struct usb_string_descriptor_struct PROGMEM string1 = {
sizeof(STR_MANUFACTURER),
3,
STR_MANUFACTURER
};
static struct usb_string_descriptor_struct PROGMEM string2 = {
sizeof(STR_PRODUCT),
3,
STR_PRODUCT
};
// This table defines which descriptor data is sent for each specific
// request from the host (in wValue and wIndex).
static struct descriptor_list_struct {
uint16_t wValue;
uint16_t wIndex;
const uint8_t *addr;
uint8_t length;
} PROGMEM descriptor_list[] = {
{0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
{0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
{0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
{0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9},
{0x0300, 0x0000, (const uint8_t *)&string0, 4},
{0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)},
{0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)}
};
#define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct))
/**************************************************************************
*
* Variables - these are the only non-stack RAM usage
*
**************************************************************************/
// zero when we are not configured, non-zero when enumerated
static volatile uint8_t usb_configuration=0;
// which modifier keys are currently pressed
// 1=left ctrl, 2=left shift, 4=left alt, 8=left gui
// 16=right ctrl, 32=right shift, 64=right alt, 128=right gui
uint8_t keyboard_modifier_keys=0;
// which keys are currently pressed, up to 6 keys may be down at once
uint8_t keyboard_keys[6]={0,0,0,0,0,0};
// protocol setting from the host. We use exactly the same report
// either way, so this variable only stores the setting since we
// are required to be able to report which setting is in use.
static uint8_t keyboard_protocol=1;
// the idle configuration, how often we send the report to the
// host (ms * 4) even when it hasn't changed
static uint8_t keyboard_idle_config=125;
// count until idle timeout
static uint8_t keyboard_idle_count=0;
// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
volatile uint8_t keyboard_leds=0;
/**************************************************************************
*
* Public Functions - these are the API intended for the user
*
**************************************************************************/
// initialize USB
void usb_init(void)
{
HW_CONFIG();
USB_FREEZE(); // enable USB
PLL_CONFIG(); // config PLL
while (!(PLLCSR & (1<<PLOCK))) ; // wait for PLL lock
USB_CONFIG(); // start USB clock
UDCON = 0; // enable attach resistor
usb_configuration = 0;
UDIEN = (1<<EORSTE)|(1<<SOFE);
sei();
}
// return 0 if the USB is not configured, or the configuration
// number selected by the HOST
uint8_t usb_configured(void)
{
return usb_configuration;
}
// perform a single keystroke
int8_t usb_keyboard_press(uint8_t key, uint8_t modifier)
{
int8_t r;
keyboard_modifier_keys = modifier;
keyboard_keys[0] = key;
r = usb_keyboard_send();
if (r) return r;
keyboard_modifier_keys = 0;
keyboard_keys[0] = 0;
return usb_keyboard_send();
}
// send the contents of keyboard_keys and keyboard_modifier_keys
int8_t usb_keyboard_send(void)
{
uint8_t i, intr_state, timeout;
if (!usb_configuration) return -1;
intr_state = SREG;
cli();
UENUM = KEYBOARD_ENDPOINT;
timeout = UDFNUML + 50;
while (1) {
// are we ready to transmit?
if (UEINTX & (1<<RWAL)) break;
SREG = intr_state;
// has the USB gone offline?
if (!usb_configuration) return -1;
// have we waited too long?
if (UDFNUML == timeout) return -1;
// get ready to try checking again
intr_state = SREG;
cli();
UENUM = KEYBOARD_ENDPOINT;
}
UEDATX = keyboard_modifier_keys;
UEDATX = 0;
for (i=0; i<6; i++) {
UEDATX = keyboard_keys[i];
}
UEINTX = 0x3A;
keyboard_idle_count = 0;
SREG = intr_state;
return 0;
}
/**************************************************************************
*
* Private Functions - not intended for general user consumption....
*
**************************************************************************/
// USB Device Interrupt - handle all device-level events
// the transmit buffer flushing is triggered by the start of frame
//
ISR(USB_GEN_vect)
{
uint8_t intbits, t, i;
static uint8_t div4=0;
intbits = UDINT;
UDINT = 0;
if (intbits & (1<<EORSTI)) {
UENUM = 0;
UECONX = 1;
UECFG0X = EP_TYPE_CONTROL;
UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
UEIENX = (1<<RXSTPE);
usb_configuration = 0;
}
if ((intbits & (1<<SOFI)) && usb_configuration) {
if (keyboard_idle_config && (++div4 & 3) == 0) {
UENUM = KEYBOARD_ENDPOINT;
if (UEINTX & (1<<RWAL)) {
keyboard_idle_count++;
if (keyboard_idle_count == keyboard_idle_config) {
keyboard_idle_count = 0;
UEDATX = keyboard_modifier_keys;
UEDATX = 0;
for (i=0; i<6; i++) {
UEDATX = keyboard_keys[i];
}
UEINTX = 0x3A;
}
}
}
}
}
// Misc functions to wait for ready and send/receive packets
static inline void usb_wait_in_ready(void)
{
while (!(UEINTX & (1<<TXINI))) ;
}
static inline void usb_send_in(void)
{
UEINTX = ~(1<<TXINI);
}
static inline void usb_wait_receive_out(void)
{
while (!(UEINTX & (1<<RXOUTI))) ;
}
static inline void usb_ack_out(void)
{
UEINTX = ~(1<<RXOUTI);
}
// USB Endpoint Interrupt - endpoint 0 is handled here. The
// other endpoints are manipulated by the user-callable
// functions, and the start-of-frame interrupt.
//
ISR(USB_COM_vect)
{
uint8_t intbits;
const uint8_t *list;
const uint8_t *cfg;
uint8_t i, n, len, en;
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
uint16_t desc_val;
const uint8_t *desc_addr;
uint8_t desc_length;
UENUM = 0;
intbits = UEINTX;
if (intbits & (1<<RXSTPI)) {
bmRequestType = UEDATX;
bRequest = UEDATX;
wValue = UEDATX;
wValue |= (UEDATX << 8);
wIndex = UEDATX;
wIndex |= (UEDATX << 8);
wLength = UEDATX;
wLength |= (UEDATX << 8);
UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
if (bRequest == GET_DESCRIPTOR) {
list = (const uint8_t *)descriptor_list;
for (i=0; ; i++) {
if (i >= NUM_DESC_LIST) {
UECONX = (1<<STALLRQ)|(1<<EPEN); //stall
return;
}
desc_val = pgm_read_word(list);
if (desc_val != wValue) {
list += sizeof(struct descriptor_list_struct);
continue;
}
list += 2;
desc_val = pgm_read_word(list);
if (desc_val != wIndex) {
list += sizeof(struct descriptor_list_struct)-2;
continue;
}
list += 2;
desc_addr = (const uint8_t *)pgm_read_word(list);
list += 2;
desc_length = pgm_read_byte(list);
break;
}
len = (wLength < 256) ? wLength : 255;
if (len > desc_length) len = desc_length;
do {
// wait for host ready for IN packet
do {
i = UEINTX;
} while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
if (i & (1<<RXOUTI)) return; // abort
// send IN packet
n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
for (i = n; i; i--) {
UEDATX = pgm_read_byte(desc_addr++);
}
len -= n;
usb_send_in();
} while (len || n == ENDPOINT0_SIZE);
return;
}
if (bRequest == SET_ADDRESS) {
usb_send_in();
usb_wait_in_ready();
UDADDR = wValue | (1<<ADDEN);
return;
}
if (bRequest == SET_CONFIGURATION && bmRequestType == 0) {
usb_configuration = wValue;
usb_send_in();
cfg = endpoint_config_table;
for (i=1; i<5; i++) {
UENUM = i;
en = pgm_read_byte(cfg++);
UECONX = en;
if (en) {
UECFG0X = pgm_read_byte(cfg++);
UECFG1X = pgm_read_byte(cfg++);
}
}
UERST = 0x1E;
UERST = 0;
return;
}
if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
usb_wait_in_ready();
UEDATX = usb_configuration;
usb_send_in();
return;
}
if (bRequest == GET_STATUS) {
usb_wait_in_ready();
i = 0;
#ifdef SUPPORT_ENDPOINT_HALT
if (bmRequestType == 0x82) {
UENUM = wIndex;
if (UECONX & (1<<STALLRQ)) i = 1;
UENUM = 0;
}
#endif
UEDATX = i;
UEDATX = 0;
usb_send_in();
return;
}
#ifdef SUPPORT_ENDPOINT_HALT
if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE)
&& bmRequestType == 0x02 && wValue == 0) {
i = wIndex & 0x7F;
if (i >= 1 && i <= MAX_ENDPOINT) {
usb_send_in();
UENUM = i;
if (bRequest == SET_FEATURE) {
UECONX = (1<<STALLRQ)|(1<<EPEN);
} else {
UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN);
UERST = (1 << i);
UERST = 0;
}
return;
}
}
#endif
if (wIndex == KEYBOARD_INTERFACE) {
if (bmRequestType == 0xA1) {
if (bRequest == HID_GET_REPORT) {
usb_wait_in_ready();
UEDATX = keyboard_modifier_keys;
UEDATX = 0;
for (i=0; i<6; i++) {
UEDATX = keyboard_keys[i];
}
usb_send_in();
return;
}
if (bRequest == HID_GET_IDLE) {
usb_wait_in_ready();
UEDATX = keyboard_idle_config;
usb_send_in();
return;
}
if (bRequest == HID_GET_PROTOCOL) {
usb_wait_in_ready();
UEDATX = keyboard_protocol;
usb_send_in();
return;
}
}
if (bmRequestType == 0x21) {
if (bRequest == HID_SET_REPORT) {
usb_wait_receive_out();
keyboard_leds = UEDATX;
usb_ack_out();
usb_send_in();
return;
}
if (bRequest == HID_SET_IDLE) {
keyboard_idle_config = (wValue >> 8);
keyboard_idle_count = 0;
usb_send_in();
return;
}
if (bRequest == HID_SET_PROTOCOL) {
keyboard_protocol = wValue;
usb_send_in();
return;
}
}
}
}
UECONX = (1<<STALLRQ) | (1<<EPEN); // stall
}

View File

@ -0,0 +1,206 @@
#ifndef usb_serial_h__
#define usb_serial_h__
#include <stdint.h>
void usb_init(void); // initialize everything
uint8_t usb_configured(void); // is the USB port configured
int8_t usb_keyboard_press(uint8_t key, uint8_t modifier);
int8_t usb_keyboard_send(void);
extern uint8_t keyboard_modifier_keys;
extern uint8_t keyboard_keys[6];
extern volatile uint8_t keyboard_leds;
// This file does not include the HID debug functions, so these empty
// macros replace them with nothing, so users can compile code that
// has calls to these functions.
#define usb_debug_putchar(c)
#define usb_debug_flush_output()
#define KEY_CTRL 0x01
#define KEY_SHIFT 0x02
#define KEY_ALT 0x04
#define KEY_GUI 0x08
#define KEY_LEFT_CTRL 0x01
#define KEY_LEFT_SHIFT 0x02
#define KEY_LEFT_ALT 0x04
#define KEY_LEFT_GUI 0x08
#define KEY_RIGHT_CTRL 0x10
#define KEY_RIGHT_SHIFT 0x20
#define KEY_RIGHT_ALT 0x40
#define KEY_RIGHT_GUI 0x80
#define KEY_A 4
#define KEY_B 5
#define KEY_C 6
#define KEY_D 7
#define KEY_E 8
#define KEY_F 9
#define KEY_G 10
#define KEY_H 11
#define KEY_I 12
#define KEY_J 13
#define KEY_K 14
#define KEY_L 15
#define KEY_M 16
#define KEY_N 17
#define KEY_O 18
#define KEY_P 19
#define KEY_Q 20
#define KEY_R 21
#define KEY_S 22
#define KEY_T 23
#define KEY_U 24
#define KEY_V 25
#define KEY_W 26
#define KEY_X 27
#define KEY_Y 28
#define KEY_Z 29
#define KEY_1 30
#define KEY_2 31
#define KEY_3 32
#define KEY_4 33
#define KEY_5 34
#define KEY_6 35
#define KEY_7 36
#define KEY_8 37
#define KEY_9 38
#define KEY_0 39
#define KEY_ENTER 40
#define KEY_ESC 41
#define KEY_BACKSPACE 42
#define KEY_TAB 43
#define KEY_SPACE 44
#define KEY_MINUS 45
#define KEY_EQUAL 46
#define KEY_LEFT_BRACE 47
#define KEY_RIGHT_BRACE 48
#define KEY_BACKSLASH 49
#define KEY_NUMBER 50
#define KEY_SEMICOLON 51
#define KEY_QUOTE 52
#define KEY_TILDE 53
#define KEY_COMMA 54
#define KEY_PERIOD 55
#define KEY_SLASH 56
#define KEY_CAPS_LOCK 57
#define KEY_F1 58
#define KEY_F2 59
#define KEY_F3 60
#define KEY_F4 61
#define KEY_F5 62
#define KEY_F6 63
#define KEY_F7 64
#define KEY_F8 65
#define KEY_F9 66
#define KEY_F10 67
#define KEY_F11 68
#define KEY_F12 69
#define KEY_PRINTSCREEN 70
#define KEY_SCROLL_LOCK 71
#define KEY_PAUSE 72
#define KEY_INSERT 73
#define KEY_HOME 74
#define KEY_PAGE_UP 75
#define KEY_DELETE 76
#define KEY_END 77
#define KEY_PAGE_DOWN 78
#define KEY_RIGHT 79
#define KEY_LEFT 80
#define KEY_DOWN 81
#define KEY_UP 82
#define KEY_NUM_LOCK 83
#define KEYPAD_SLASH 84
#define KEYPAD_ASTERIX 85
#define KEYPAD_MINUS 86
#define KEYPAD_PLUS 87
#define KEYPAD_ENTER 88
#define KEYPAD_1 89
#define KEYPAD_2 90
#define KEYPAD_3 91
#define KEYPAD_4 92
#define KEYPAD_5 93
#define KEYPAD_6 94
#define KEYPAD_7 95
#define KEYPAD_8 96
#define KEYPAD_9 97
#define KEYPAD_0 98
#define KEYPAD_PERIOD 99
// Everything below this point is only intended for usb_serial.c
#ifdef USB_SERIAL_PRIVATE_INCLUDE
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#define EP_TYPE_CONTROL 0x00
#define EP_TYPE_BULK_IN 0x81
#define EP_TYPE_BULK_OUT 0x80
#define EP_TYPE_INTERRUPT_IN 0xC1
#define EP_TYPE_INTERRUPT_OUT 0xC0
#define EP_TYPE_ISOCHRONOUS_IN 0x41
#define EP_TYPE_ISOCHRONOUS_OUT 0x40
#define EP_SINGLE_BUFFER 0x02
#define EP_DOUBLE_BUFFER 0x06
#define EP_SIZE(s) ((s) == 64 ? 0x30 : \
((s) == 32 ? 0x20 : \
((s) == 16 ? 0x10 : \
0x00)))
#define MAX_ENDPOINT 4
#define LSB(n) (n & 255)
#define MSB(n) ((n >> 8) & 255)
#if defined(__AVR_AT90USB162__)
#define HW_CONFIG()
#define PLL_CONFIG() (PLLCSR = ((1<<PLLE)|(1<<PLLP0)))
#define USB_CONFIG() (USBCON = (1<<USBE))
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
#elif defined(__AVR_ATmega32U4__)
#define HW_CONFIG() (UHWCON = 0x01)
#define PLL_CONFIG() (PLLCSR = 0x12)
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
#elif defined(__AVR_AT90USB646__)
#define HW_CONFIG() (UHWCON = 0x81)
#define PLL_CONFIG() (PLLCSR = 0x1A)
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
#elif defined(__AVR_AT90USB1286__)
#define HW_CONFIG() (UHWCON = 0x81)
#define PLL_CONFIG() (PLLCSR = 0x16)
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
#endif
// standard control endpoint request types
#define GET_STATUS 0
#define CLEAR_FEATURE 1
#define SET_FEATURE 3
#define SET_ADDRESS 5
#define GET_DESCRIPTOR 6
#define GET_CONFIGURATION 8
#define SET_CONFIGURATION 9
#define GET_INTERFACE 10
#define SET_INTERFACE 11
// HID (human interface device)
#define HID_GET_REPORT 1
#define HID_GET_IDLE 2
#define HID_GET_PROTOCOL 3
#define HID_SET_REPORT 9
#define HID_SET_IDLE 10
#define HID_SET_PROTOCOL 11
// CDC (communication class device)
#define CDC_SET_LINE_CODING 0x20
#define CDC_GET_LINE_CODING 0x21
#define CDC_SET_CONTROL_LINE_STATE 0x22
#endif
#endif

34
src/lib-other/readme.md Normal file
View File

@ -0,0 +1,34 @@
# src/lib-other
Files taken from other projects
## links to original files
* [pjrc] (http://pjrc.com/teensy/)
* [blinky] (http://pjrc.com/teensy/blinky.zip)
* [usb_keyboard] (http://pjrc.com/teensy/usb_keyboard.zip)
* [peter-fleury] (http://homepage.hispeed.ch/peterfleury/)
* note: This code is licensed under the GNU GPL
(per [the author's web site]
(http://homepage.hispeed.ch/peterfleury/avr-software.html)).
The MIT License is compatible with GPL
(see [the Wikipedia entry]
(http://en.wikipedia.org/wiki/MIT_License),
and [the list of compatible licenses]
(http://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses)
on <http://www.gnu.org/>).
* [i2cmaster] (http://homepage.hispeed.ch/peterfleury/i2cmaster.zip)
* [arduino] (https://github.com/arduino)
* [arduino] (https://github.com/arduino/Arduino)
* .../twi.c and .../twi.h
* note: The version here is from the Ubuntu package, so it's probably
old. The (new) version from github has dependencies galore on random
other Arduino files, so it wasn't really usable.
-------------------------------------------------------------------------------
Copyright &copy; 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>

22
src/lib/data-types.h Normal file
View File

@ -0,0 +1,22 @@
/* ----------------------------------------------------------------------------
* Common data types
* ----------------------------------------------------------------------------
* 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 DATA_TYPES_h
#define DATA_TYPES_h
// --------------------------------------------------------------------
#define bool _Bool
#define true ((bool)1)
#define false ((bool)0)
// --------------------------------------------------------------------
#endif

View File

@ -0,0 +1,264 @@
/* ----------------------------------------------------------------------------
* USB Keyboard Key Codes (usage page 0x07)
*
* Taken from [the HID Usage Tables pdf][1], Section 10,
* which can be found on [the HID Page][2] at <http://www.usb.org>
*
* - `Boot Keyboard Req.` indicates that the usage code is one that should be
* supported by the listed types of keyboards (104-key, ...) on boot
*
* - `KEY_` indicates a Keyboard key
* - `KEYPAD_` indicates a Keypad key
* - Multiple names concatenated in CamelCase indicate a single value
* - Multiple names separated by `_`s indicate shifted or alternate values
*
* [1]: http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf
* [2]: http://www.usb.org/developers/hidpage
* ----------------------------------------------------------------------------
* 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>
* ------------------------------------------------------------------------- */
// Name ID // PC Mac Unix Boot Keyboard Req.
// --------------------------- ---- -- --- ---- ---------------------
// (Reserved) 0x00 // √ √ √ 84/101/104
#define KEY_ErrorRollOver 0x01 // √ √ √ 84/101/104
#define KEY_POSTFail 0x02 // √ √ √ 84/101/104
#define KEY_ErrorUndefined 0x03 // √ √ √ 84/101/104
#define KEY_a_A 0x04 // √ √ √ 84/101/104
#define KEY_b_B 0x05 // √ √ √ 84/101/104
#define KEY_c_C 0x06 // √ √ √ 84/101/104
#define KEY_d_D 0x07 // √ √ √ 84/101/104
#define KEY_e_E 0x08 // √ √ √ 84/101/104
#define KEY_f_F 0x09 // √ √ √ 84/101/104
#define KEY_g_G 0x0A // √ √ √ 84/101/104
#define KEY_h_H 0x0B // √ √ √ 84/101/104
#define KEY_i_I 0x0C // √ √ √ 84/101/104
#define KEY_j_J 0x0D // √ √ √ 84/101/104
#define KEY_k_K 0x0E // √ √ √ 84/101/104
#define KEY_l_L 0x0F // √ √ √ 84/101/104
#define KEY_m_M 0x10 // √ √ √ 84/101/104
#define KEY_n_N 0x11 // √ √ √ 84/101/104
#define KEY_o_O 0x12 // √ √ √ 84/101/104
#define KEY_p_P 0x13 // √ √ √ 84/101/104
#define KEY_q_Q 0x14 // √ √ √ 84/101/104
#define KEY_r_R 0x15 // √ √ √ 84/101/104
#define KEY_s_S 0x16 // √ √ √ 84/101/104
#define KEY_t_T 0x17 // √ √ √ 84/101/104
#define KEY_u_U 0x18 // √ √ √ 84/101/104
#define KEY_v_V 0x19 // √ √ √ 84/101/104
#define KEY_w_W 0x1A // √ √ √ 84/101/104
#define KEY_x_X 0x1B // √ √ √ 84/101/104
#define KEY_y_Y 0x1C // √ √ √ 84/101/104
#define KEY_z_Z 0x1D // √ √ √ 84/101/104
#define KEY_1_Exclamation 0x1E // √ √ √ 84/101/104
#define KEY_2_At 0x1F // √ √ √ 84/101/104
#define KEY_3_Pound 0x20 // √ √ √ 84/101/104
#define KEY_4_Dollar 0x21 // √ √ √ 84/101/104
#define KEY_5_Percent 0x22 // √ √ √ 84/101/104
#define KEY_6_Caret 0x23 // √ √ √ 84/101/104
#define KEY_7_Ampersand 0x24 // √ √ √ 84/101/104
#define KEY_8_Asterisk 0x25 // √ √ √ 84/101/104
#define KEY_9_LeftParenthesis 0x26 // √ √ √ 84/101/104
#define KEY_0_RightParenthesis 0x27 // √ √ √ 84/101/104
#define KEY_ReturnEnter 0x28 // √ √ √ 84/101/104
#define KEY_Escape 0x29 // √ √ √ 84/101/104
#define KEY_DeleteBackspace 0x2A // √ √ √ 84/101/104
#define KEY_Tab 0x2B // √ √ √ 84/101/104
#define KEY_Spacebar 0x2C // √ √ √ 84/101/104
#define KEY_Dash_Underscore 0x2D // √ √ √ 84/101/104
#define KEY_Equal_Plus 0x2E // √ √ √ 84/101/104
#define KEY_LeftBracket_LeftBrace 0x2F // √ √ √ 84/101/104
#define KEY_RightBracket_RightBrace 0x30 // √ √ √ 84/101/104
#define KEY_Backslash_Pipe 0x31 // √ √ √ 84/101/104
#define KEY_NonUS_Pound_Tilde 0x32 // √ √ √ 84/101/104
#define KEY_Semicolon_Colon 0x33 // √ √ √ 84/101/104
#define KEY_SingleQuote_DoubleQuote 0x34 // √ √ √ 84/101/104
#define KEY_GraveAccent_Tilde 0x35 // √ √ √ 84/101/104
#define KEY_Comma_LessThan 0x36 // √ √ √ 84/101/104
#define KEY_Period_GreaterThan 0x37 // √ √ √ 84/101/104
#define KEY_Slash_Question 0x38 // √ √ √ 84/101/104
#define KEY_CapsLock 0x39 // √ √ √ 84/101/104
#define KEY_F1 0x3A // √ √ √ 84/101/104
#define KEY_F2 0x3B // √ √ √ 84/101/104
#define KEY_F3 0x3C // √ √ √ 84/101/104
#define KEY_F4 0x3D // √ √ √ 84/101/104
#define KEY_F5 0x3E // √ √ √ 84/101/104
#define KEY_F6 0x3F // √ √ √ 84/101/104
#define KEY_F7 0x40 // √ √ √ 84/101/104
#define KEY_F8 0x41 // √ √ √ 84/101/104
#define KEY_F9 0x42 // √ √ √ 84/101/104
#define KEY_F10 0x43 // √ √ √ 84/101/104
#define KEY_F11 0x44 // √ √ √ 101/104
#define KEY_F12 0x45 // √ √ √ 101/104
#define KEY_PrintScreen 0x46 // √ √ √ 101/104
#define KEY_ScrollLock 0x47 // √ √ √ 84/101/104
#define KEY_Pause 0x48 // √ √ √ 101/104
#define KEY_Insert 0x49 // √ √ √ 101/104
#define KEY_Home 0x4A // √ √ √ 101/104
#define KEY_PageUp 0x4B // √ √ √ 101/104
#define KEY_DeleteForward 0x4C // √ √ √ 101/104
#define KEY_End 0x4D // √ √ √ 101/104
#define KEY_PageDown 0x4E // √ √ √ 101/104
#define KEY_RightArrow 0x4F // √ √ √ 101/104
#define KEY_LeftArrow 0x50 // √ √ √ 101/104
#define KEY_DownArrow 0x51 // √ √ √ 101/104
#define KEY_UpArrow 0x52 // √ √ √ 101/104
#define KEYPAD_NumLock_Clear 0x53 // √ √ √ 101/104
#define KEYPAD_Slash 0x54 // √ √ √ 101/104
#define KEYPAD_Asterisk 0x55 // √ √ √ 84/101/104
#define KEYPAD_Minus 0x56 // √ √ √ 84/101/104
#define KEYPAD_Plus 0x57 // √ √ √ 84/101/104
#define KEYPAD_ENTER 0x58 // √ √ √ 101/104
#define KEYPAD_1_End 0x59 // √ √ √ 84/101/104
#define KEYPAD_2_DownArrow 0x5A // √ √ √ 84/101/104
#define KEYPAD_3_PageDown 0x5B // √ √ √ 84/101/104
#define KEYPAD_4_LeftArrow 0x5C // √ √ √ 84/101/104
#define KEYPAD_5 0x5D // √ √ √ 84/101/104
#define KEYPAD_6_RightArrow 0x5E // √ √ √ 84/101/104
#define KEYPAD_7_Home 0x5F // √ √ √ 84/101/104
#define KEYPAD_8_UpArrow 0x60 // √ √ √ 84/101/104
#define KEYPAD_9_PageUp 0x61 // √ √ √ 84/101/104
#define KEYPAD_0_Insert 0x62 // √ √ √ 84/101/104
#define KEYPAD_Period_Delete 0x63 // √ √ √ 84/101/104
#define KEY_NonUS_Backslash_Pipe 0x64 // √ √ √ 84/101/104
#define KEY_Application 0x65 // √ - √ 104
#define KEY_Power 0x66 // - √ √ -
#define KEYPAD_Equal 0x67 // - √ - -
#define KEY_F13 0x68 // - √ - -
#define KEY_F14 0x69 // - √ - -
#define KEY_F15 0x6A // - √ - -
#define KEY_F16 0x6B // - - - -
#define KEY_F17 0x6C // - - - -
#define KEY_F18 0x6D // - - - -
#define KEY_F19 0x6E // - - - -
#define KEY_F20 0x6F // - - - -
#define KEY_F21 0x70 // - - - -
#define KEY_F22 0x71 // - - - -
#define KEY_F23 0x72 // - - - -
#define KEY_F24 0x73 // - - - -
#define KEY_Execute 0x74 // - - √ -
#define KEY_Help 0x75 // - - √ -
#define KEY_Menu 0x76 // - - √ -
#define KEY_Select 0x77 // - - √ -
#define KEY_Stop 0x78 // - - √ -
#define KEY_Again 0x79 // - - √ -
#define KEY_Undo 0x7A // - - √ -
#define KEY_Cut 0x7B // - - √ -
#define KEY_Copy 0x7C // - - √ -
#define KEY_Paste 0x7D // - - √ -
#define KEY_Find 0x7E // - - √ -
#define KEY_Mute 0x7F // - - √ -
#define KEY_VolumeUp 0x80 // - - √ -
#define KEY_VolumeDown 0x81 // - - √ -
#define KEY_LockingCapsLock 0x82 // - - √ -
#define KEY_LockingNumLock 0x83 // - - √ -
#define KEY_LockingScrollLock 0x84 // - - √ -
#define KEYPAD_Comma 0x85 // - - - -
#define KEYPAD_Equal 0x86 // - - - -
#define KEY_International1 0x87 // - - - -
#define KEY_International2 0x88 // - - - -
#define KEY_International3 0x89 // - - - -
#define KEY_International4 0x8A // - - - -
#define KEY_International5 0x8B // - - - -
#define KEY_International6 0x8C // - - - -
#define KEY_International7 0x8D // - - - -
#define KEY_International8 0x8E // - - - -
#define KEY_International9 0x8F // - - - -
#define KEY_LANG1 0x90 // - - - -
#define KEY_LANG2 0x91 // - - - -
#define KEY_LANG3 0x92 // - - - -
#define KEY_LANG4 0x93 // - - - -
#define KEY_LANG5 0x94 // - - - -
#define KEY_LANG6 0x95 // - - - -
#define KEY_LANG7 0x96 // - - - -
#define KEY_LANG8 0x97 // - - - -
#define KEY_LANG9 0x98 // - - - -
#define KEY_AlternateErase 0x99 // - - - -
#define KEY_SysReq_Attention 0x9A // - - - -
#define KEY_Cancel 0x9B // - - - -
#define KEY_Clear 0x9C // - - - -
#define KEY_Prior 0x9D // - - - -
#define KEY_Return 0x9E // - - - -
#define KEY_Separator 0x9F // - - - -
#define KEY_Out 0xA0 // - - - -
#define KEY_Oper 0xA1 // - - - -
#define KEY_Clear_Again 0xA2 // - - - -
#define KEY_CrSel_Props 0xA3 // - - - -
#define KEY_ExSel 0xA4 // - - - -
// (Reserved) 0xA5..0xAF // - - - -
#define KEYPAD_00 0xB0 // - - - -
#define KEYPAD_000 0xB1 // - - - -
#define KEY_ThousandsSeparator 0xB2 // - - - -
#define KEY_DecimalSeparator 0xB3 // - - - -
#define KEY_CurrencyUnit 0xB4 // - - - -
#define KEY_CurrencySubunit 0xB5 // - - - -
#define KEYPAD_LeftParenthesis 0xB6 // - - - -
#define KEYPAD_RightParenthesis 0xB7 // - - - -
#define KEYPAD_LeftBrace 0xB8 // - - - -
#define KEYPAD_RightBrace 0xB9 // - - - -
#define KEYPAD_Tab 0xBA // - - - -
#define KEYPAD_Backspace 0xBB // - - - -
#define KEYPAD_A 0xBC // - - - -
#define KEYPAD_B 0xBD // - - - -
#define KEYPAD_C 0xBE // - - - -
#define KEYPAD_D 0xBF // - - - -
#define KEYPAD_E 0xC0 // - - - -
#define KEYPAD_F 0xC1 // - - - -
#define KEYPAD_XOR 0xC2 // - - - -
#define KEYPAD_Caret 0xC3 // - - - -
#define KEYPAD_Percent 0xC4 // - - - -
#define KEYPAD_LessThan 0xC5 // - - - -
#define KEYPAD_GreaterThan 0xC6 // - - - -
#define KEYPAD_Ampersand 0xC7 // - - - -
#define KEYPAD_AmpersandAmpersand 0xC8 // - - - -
#define KEYPAD_Pipe 0xC9 // - - - -
#define KEYPAD_PipePipe 0xCA // - - - -
#define KEYPAD_Colon 0xCB // - - - -
#define KEYPAD_Pound 0xCC // - - - -
#define KEYPAD_Space 0xCD // - - - -
#define KEYPAD_At 0xCE // - - - -
#define KEYPAD_Exclamation 0xCF // - - - -
#define KEYPAD_MemoryStore 0xD0 // - - - -
#define KEYPAD_MemoryRecall 0xD1 // - - - -
#define KEYPAD_MemoryClear 0xD2 // - - - -
#define KEYPAD_MemoryAdd 0xD3 // - - - -
#define KEYPAD_MemorySubtract 0xD4 // - - - -
#define KEYPAD_MemoryMultiply 0xD5 // - - - -
#define KEYPAD_MemoryDivide 0xD6 // - - - -
#define KEYPAD_PlusMinux 0xD7 // - - - -
#define KEYPAD_Clear 0xD8 // - - - -
#define KEYPAD_ClearEntry 0xD9 // - - - -
#define KEYPAD_Binary 0xDA // - - - -
#define KEYPAD_Octal 0xDB // - - - -
#define KEYPAD_Decimal 0xDC // - - - -
#define KEYPAD_Hexadecimal 0xDD // - - - -
// (Reserved) 0xDE..0xDF // - - - -
#define KEY_LeftControl 0xE0 // √ √ √ 84/101/104
#define KEY_LeftShift 0xE1 // √ √ √ 84/101/104
#define KEY_LeftAlt 0xE2 // √ √ √ 84/101/104
#define KEY_LeftGUI 0xE3 // √ √ √ 104
#define KEY_RightControl 0xE4 // √ √ √ 101/104
#define KEY_RightShift 0xE5 // √ √ √ 84/101/104
#define KEY_RightAlt 0xE6 // √ √ √ 101/104
#define KEY_RightGUI 0xE7 // √ √ √ 104
// (Reserved) 0xE8..0xFFFF // - - - -

View File

@ -0,0 +1,106 @@
/* ----------------------------------------------------------------------------
* USB LED Codes (usage page 0x08)
*
* Taken from [the HID Usage Tables pdf][1], Section 11,
* which can be found on [the HID Page][2] at <http://www.usb.org>
*
* - applicable Usage Types (from Section 3.4)
* - OOC : On/Off Control
* - Sel : Selector
* - DV : Dynamic Value
* - US : Usage Switch
* - UM : Usage Modifier
*
* [1]: http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf
* [2]: http://www.usb.org/developers/hidpage
* ----------------------------------------------------------------------------
* 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>
* ------------------------------------------------------------------------- */
// Name ID Usage Type Section of HID Tables
// --------------------------- ---- ---------- ----------------------
// (Undefined) 0x00 // - -
#define LED_NumLock 0x01 // OOC 11.1
#define LED_CapsLock 0x02 // OOC 11.1
#define LED_ScrollLock 0x03 // OOC 11.1
#define LED_Compose 0x04 // OOC 11.1
#define LED_Kana 0x05 // OOC 11.1
#define LED_Power 0x06 // OOC 11.6
#define LED_Shift 0x07 // OOC 11.1
#define LED_DoNotDisturb 0x08 // OOC 11.2
#define LED_Mute 0x09 // OOC 11.3
#define LED_ToneEnable 0x0A // OOC 11.3
#define LED_HighCutFilter 0x0B // OOC 11.3
#define LED_LowCutFilter 0x0C // OOC 11.3
#define LED_EqualizerEnable 0x0D // OOC 11.3
#define LED_SoundFieldOn 0x0E // OOC 11.3
#define LED_SurroundOn 0x0F // OOC 11.3
#define LED_Repeat 0x10 // OOC 11.3
#define LED_Stereo 0x11 // OOC 11.3
#define LED_SamplingRateDetect 0x12 // OOC 11.3
#define LED_Spinning 0x13 // OOC 11.4
#define LED_CAV 0x14 // OOC 11.3
#define LED_CLV 0x15 // OOC 11.3
#define LED_RecordingFormatDetect 0x16 // OOC 11.4
#define LED_OffHook 0x17 // OOC 11.2
#define LED_Ring 0x18 // OOC 11.2
#define LED_MessageWaiting 0x19 // OOC 11.2
#define LED_DataMode 0x1A // OOC 11.2
#define LED_BatteryOperation 0x1B // OOC 11.6
#define LED_BatteryOK 0x1C // OOC 11.6
#define LED_BatteryLow 0x1D // OOC 11.6
#define LED_Speaker 0x1E // OOC 11.2
#define LED_HeadSet 0x1F // OOC 11.2
#define LED_Hold 0x20 // OOC 11.2
#define LED_Microphone 0x21 // OOC 11.2
#define LED_Coverage 0x22 // OOC 11.2
#define LED_NightMode 0x23 // OOC 11.2
#define LED_SendCalls 0x24 // OOC 11.2
#define LED_CallPickup 0x25 // OOC 11.2
#define LED_Conference 0x26 // OOC 11.2
#define LED_Standby 0x27 // OOC 11.6
#define LED_CameraOn 0x28 // OOC 11.3
#define LED_CameraOff 0x29 // OOC 11.3
#define LED_OnLine 0x2A // OOC 11.6
#define LED_OffLine 0x2B // OOC 11.6
#define LED_Busy 0x2C // OOC 11.6
#define LED_Ready 0x2D // OOC 11.6
#define LED_PaperOut 0x2E // OOC 11.5
#define LED_PaperJam 0x2F // OOC 11.5
#define LED_Remote 0x30 // OOC 11.6
#define LED_Forward 0x31 // OOC 11.4
#define LED_Reverse 0x32 // OOC 11.4
#define LED_Stop 0x33 // OOC 11.4
#define LED_Rewind 0x34 // OOC 11.4
#define LED_FastForward 0x35 // OOC 11.4
#define LED_Play 0x36 // OOC 11.4
#define LED_Pause 0x37 // OOC 11.4
#define LED_Record 0x38 // OOC 11.4
#define LED_Error 0x39 // OOC 11.6
#define LED_UsageSelectedIndicator 0x3A // US 11.6
#define LED_UsageInUseIndicator 0x3B // US 11.6
#define LED_UsageMultiModeIndicator 0x3C // UM 11.6
#define LED_IndicatorOn 0x3D // Sel 11.6
#define LED_IndicatorFlash 0x3E // Sel 11.6
#define LED_IndicatorSlowBlink 0x3F // Sel 11.6
#define LED_IndicatorFastBlink 0x40 // Sel 11.6
#define LED_IndicatorOff 0x41 // Sel 11.6
#define LED_FlashOnTime 0x42 // DV 11.6
#define LED_SlowBlinkOnTime 0x43 // DV 11.6
#define LED_SlowBlinkOffTime 0x44 // DV 11.6
#define LED_FastBlinkOnTime 0x45 // DV 11.6
#define LED_FastBlinkOffTime 0x46 // DV 11.6
#define LED_UsageIndicatorColor 0x47 // UM 11.6
#define LED_IndicatorRed 0x48 // Sel 11.6
#define LED_IndicatorGreen 0x49 // Sel 11.6
#define LED_IndicatorAmber 0x4A // Sel 11.6
#define LED_GenericIndicator 0x4B // OOC 11.6
#define LED_SystemSuspend 0x4C // OOC 11.6
#define LED_ExternalPowerConnected 0x4D // OOC 11.6
// (Reserved) 0x4E..0xFFFF // - -

View File

@ -2,16 +2,27 @@
# This is mostly a stub at the moment, but I'm keeping it separate so I can
# mess with it later without changing the original
# -----------------------------------------------------------------------------
# Copyright (c) 2012 Ben Blazak
# Released under The MIT License (MIT) (see "license.md") at
# <https://github.com/benblazak/ergodox-firmware>
# 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>
# -----------------------------------------------------------------------------
SRC = $(shell find -name '*.c')
TARGET = ergodox-firmware
SRC = $(shell find -maxdepth 1 -name '*.c') \
$(shell find ./keyboard -name '*.c') \
$(shell find ./lib -name '*.c') \
./lib-other/peter-fleury/i2cmaster/twimaster.c \
./lib-other/pjrc/blinky/print.c \
./lib-other/pjrc/blinky/usb_debug_only.c \
./lib-other/arduino/arduino/libraries/Wire/utility/twi.c
EXTRAINCDIRS = .
TEENSY_MAKE = $(MAKE) -f 'lib/pjrc/Makefile' \
TEENSY_MAKE = $(MAKE) -f 'lib-other/pjrc/blinky/Makefile' \
TARGET='$(TARGET)' \
SRC='$(SRC)' \
EXTRAINCDIRS='$(EXTRAINCDIRS)'

49
src/test.c Normal file
View File

@ -0,0 +1,49 @@
#include <stdio.h>
#include <util/delay.h>
#include "lib-other/pjrc/blinky/print.h"
#include "lib-other/pjrc/blinky/usb_debug_only.h"
#define TEENSY_2_0_h_INCLUDE_PRIVATE
#include "keyboard/ergodox/teensy-2-0.h"
int test_i2c(void);
int test_kb_teensy(void);
int main(void);
// ----------------------------------------------------------------------------
int main(void) {
test_i2c();
print("--------------");
test_kb_teensy();
}
// ----------------------------------------------------------------------------
int test_i2c(void) {
usb_init();
_delay_ms(500); // just to be safe
uint8_t ret;
uint8_t len;
char str[10];
print("\nhello");
ret = teensy_init();
print("\nteensy_init() returned: 0x"); phex(ret);
ret = mcp23018_init();
print("\nmcp23018_init() returned: 0x"); phex(ret);
usb_debug_flush_output();
return 0;
}
// ----------------------------------------------------------------------------
int test_kb_teensy(void) {
}