intermitent checkin; lots of stuff; i2c on hold; kb logic in progress
parent
b77e74cacd
commit
a288b8a045
|
@ -0,0 +1,3 @@
|
||||||
|
*~
|
||||||
|
*.swp
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
## Noob Electronics Stuff
|
## Electronics Stuff
|
||||||
|
|
||||||
* [Resistor Color Codes]
|
* [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)
|
(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]
|
* [All About Circuits : Reference]
|
||||||
(http://www.allaboutcircuits.com/vol_5/index.html)
|
(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]
|
* [C Library Reference]
|
||||||
(http://www.cplusplus.com/reference/)
|
(http://www.cplusplus.com/reference/)
|
||||||
|
@ -60,18 +63,11 @@
|
||||||
(http://www.ibiblio.org/pub/languages/fortran/append-c.html)
|
(http://www.ibiblio.org/pub/languages/fortran/append-c.html)
|
||||||
(on <http://www.ibiblio.org/>)
|
(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
|
### For the AVR
|
||||||
|
|
||||||
* [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
|
|
||||||
|
|
||||||
* [AVR Libc Library Reference]
|
* [AVR Libc Library Reference]
|
||||||
(http://www.nongnu.org/avr-libc/user-manual/modules.html)
|
(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
|
* [A Brief Tutorial on Programming the AVR without Arduino] by Chris Kuethe
|
||||||
(https://www.mainframe.cx/~ckuethe/avr-c-tutorial/)
|
(https://www.mainframe.cx/~ckuethe/avr-c-tutorial/)
|
||||||
|
|
||||||
|
## Protocol Stuff
|
||||||
|
|
||||||
## Articles / Tutorials
|
### I²C
|
||||||
|
|
||||||
* [Arduino I²C Expansion IO]
|
* [Arduino I²C Expansion IO]
|
||||||
(http://www.neufeld.newton.ks.us/electronics/?p=241)
|
(http://www.neufeld.newton.ks.us/electronics/?p=241)
|
||||||
(from [Keith's Electronics Blog]
|
(from [Keith's Electronics Blog]
|
||||||
(http://www.neufeld.newton.ks.us/electronics/))
|
(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
|
## Other Firmware / Code
|
||||||
|
|
||||||
|
@ -192,7 +221,7 @@
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright © 2012 Ben Blazak
|
Copyright © 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||||
Released under The MIT License (MIT) (see "license.md") at
|
Released under The MIT License (MIT) (see "license.md")
|
||||||
<https://github.com/benblazak/ergodox-firmware>
|
Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||||
|
|
||||||
|
|
13
readme.md
13
readme.md
|
@ -3,9 +3,16 @@
|
||||||
[ergodox-firmware]: https://github.com/benblazak/ergodox-firmware
|
[ergodox-firmware]: https://github.com/benblazak/ergodox-firmware
|
||||||
[ergodox keyboard]: http://geekhack.org/showthread.php?22780-Interest-Check-Custom-split-ergo-keyboard
|
[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 © 2012 Ben Blazak
|
Copyright © 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||||
Released under The MIT License (MIT) (see "license.md") at
|
Released under The MIT License (MIT) (see "license.md")
|
||||||
<https://github.com/benblazak/ergodox-firmware>
|
Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Firmware main file
|
* Firmware main file
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
* Copyright (c) 2012 Ben Blazak
|
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||||
* Released under The MIT License (MIT) (see "license.md") at
|
* Released under The MIT License (MIT) (see "license.md")
|
||||||
* <https://github.com/benblazak/ergodox-firmware>
|
* 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
|
// TODO
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
|
||||||
// };
|
|
||||||
|
|
|
@ -1,16 +1,42 @@
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* see "default.c"
|
* ergoDOX layout
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
* Copyright (c) 2012 Ben Blazak
|
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||||
* Released under The MIT License (MIT) (see "license.md") at
|
* Released under The MIT License (MIT) (see "license.md")
|
||||||
* <https://github.com/benblazak/ergodox-firmware>
|
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#ifndef LAYOUT_h
|
||||||
|
#define LAYOUT_h
|
||||||
|
|
||||||
#define LAYOUT_LAYERS 1
|
#include "lib/usb/keyboard-usage-page.h"
|
||||||
#define LAYOUT_ROWS 12 // must match real life
|
#include "matrix.h"
|
||||||
#define LAYOUT_COLUMNS 7 // must match real life
|
|
||||||
|
#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
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 © 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>
|
||||||
|
|
|
@ -1,16 +1,80 @@
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* ergoDOX controller: MCP23018 specific code
|
* ergoDOX controller: MCP23018 specific code
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
* Copyright (c) 2012 Ben Blazak
|
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||||
* Released under The MIT License (MIT) (see "license.md") at
|
* Released under The MIT License (MIT) (see "license.md")
|
||||||
* <https://github.com/benblazak/ergodox-firmware>
|
* 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")
|
// register addresses (see "mcp23018.md")
|
||||||
#define IODIRA 0x00 // i/o direction register
|
#define IODIRA 0x00 // i/o direction register
|
||||||
|
@ -22,40 +86,89 @@
|
||||||
#define OLATA 0x14 // output latch register
|
#define OLATA 0x14 // output latch register
|
||||||
#define OLATB 0x15
|
#define OLATB 0x15
|
||||||
|
|
||||||
|
static void twi_init(void) {
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// TWSR &= ~( (1<<TWPS1)|(1<<TWPS0) );
|
||||||
|
TWSR |= (1<<TWPS1)|(1<<TWPS0); //dbg
|
||||||
#include "lib/arduino/twi.h"
|
// TWBR = ((F_CPU / 100000) - 16) / 2;
|
||||||
|
TWBR = 0xFF; //dbg
|
||||||
#include "mcp23018.h"
|
// TWCR = (1<<TWEA)|(1<<TWEN);
|
||||||
|
|
||||||
|
|
||||||
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 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;
|
||||||
|
}
|
||||||
|
|
|
@ -1,21 +1,26 @@
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* ergoDOX controller: MCP23018 specific exports
|
* ergoDOX controller: MCP23018 specific exports
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
* Copyright (c) 2012 Ben Blazak
|
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||||
* Released under The MIT License (MIT) (see "license.md") at
|
* Released under The MIT License (MIT) (see "license.md")
|
||||||
* <https://github.com/benblazak/ergodox-firmware>
|
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
#ifndef MCP23018_h
|
#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
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
* notes:
|
* notes:
|
||||||
* All addresses given for IOCON.BANK = 0, since that's the default value of
|
* All addresses given for IOCON.BANK = 0, since that's the default value of
|
||||||
the bit, and that's what we'll be using.
|
the bit, and that's what we'll be using.
|
||||||
|
* Outputs are open drain, so we want pull-up resistors set for everything.
|
||||||
|
|
||||||
* abbreviations:
|
* abbreviations:
|
||||||
* IODIR = I/O Direction Register
|
* IODIR = I/O Direction Register
|
||||||
|
@ -80,17 +81,17 @@
|
||||||
|
|
||||||
## I²C Device Protocol (see datasheet section 1.3, figure 1-1)
|
## I²C Device Protocol (see datasheet section 1.3, figure 1-1)
|
||||||
|
|
||||||
S : Start OP : Device opcode
|
S : Start OP : Device opcode
|
||||||
SR : Restart ADDR : Device address
|
SR : Restart ADDR : Device address
|
||||||
P : Stop Dout : Data out from MCP23018
|
P : Stop Dout : Data out from MCP23018
|
||||||
W : Write Din : Data in to MCP23018
|
W : Write Din : Data in to MCP23018
|
||||||
R : Read
|
R : Read
|
||||||
|
|
||||||
|
|
||||||
S OP W ADDR ----> Din ... Din --> P
|
S OP W ADDR ----> Din ... Din --> P
|
||||||
|
|
|
|
||||||
|--> SR OP R Dout ... Dout ---> P
|
|--> SR OP R Dout ... Dout ---> P
|
||||||
|<-------------------------|
|
|<--------------------------|
|
||||||
|
|
|
|
||||||
|--> SR OP W ADDR ... Din --> P
|
|--> SR OP W ADDR ... Din --> P
|
||||||
|
|
|
|
||||||
|
@ -121,7 +122,7 @@
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright © 2012 Ben Blazak
|
Copyright © 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||||
Released under The MIT License (MIT) (see "license.md") at
|
Released under The MIT License (MIT) (see "license.md")
|
||||||
<https://github.com/benblazak/ergodox-firmware>
|
Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* ergoDOX controller: Teensy 2.0 specific code
|
* ergoDOX controller: Teensy 2.0 specific code
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
* Copyright (c) 2012 Ben Blazak
|
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||||
* Released under The MIT License (MIT) (see "license.md") at
|
* Released under The MIT License (MIT) (see "license.md")
|
||||||
* <https://github.com/benblazak/ergodox-firmware>
|
* 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>)
|
// processor frequency (from <http://www.pjrc.com/teensy/prescaler.html>)
|
||||||
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
|
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
|
||||||
#define CPU_16MHz 0x00
|
#define CPU_16MHz 0x00
|
||||||
|
@ -19,47 +25,39 @@
|
||||||
#define CPU_125kHz 0x07
|
#define CPU_125kHz 0x07
|
||||||
#define CPU_62kHz 0x08
|
#define CPU_62kHz 0x08
|
||||||
|
|
||||||
// TWI
|
|
||||||
#define TWI_FREQ 400000 // (see "lib/twi.(h|c)")
|
|
||||||
|
|
||||||
|
uint8_t teensy_init(void) {
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include "lib/arduino/twi.h"
|
|
||||||
|
|
||||||
#include "teensy-2-0.h"
|
|
||||||
|
|
||||||
|
|
||||||
void teensy_init(void) {
|
|
||||||
CPU_PRESCALE(CPU_16MHz); // speed should match F_CPU in makefile
|
CPU_PRESCALE(CPU_16MHz); // speed should match F_CPU in makefile
|
||||||
|
|
||||||
// unused pins
|
// unused pins
|
||||||
DDRB &= ~0b00001110; // set B(1,2,3) as input
|
DDRB &= ~0b00001110; // set B(3,2,1) as input
|
||||||
PORTB |= 0b00001110; // set B(1,2,3) internal pull-up enabled
|
PORTB |= 0b00001110; // set B(3,2,1) internal pull-up enabled
|
||||||
DDRD &= ~0b01110000; // set D(4,5,6) as input
|
DDRD &= ~0b01110000; // set D(6,5,4) as input
|
||||||
PORTD |= 0b01110000; // set D(4,5,6) internal pull-up enabled
|
PORTD |= 0b01110000; // set D(6,5,4) internal pull-up enabled
|
||||||
DDRE &= ~0b01000000; // set E(6) as input
|
DDRE &= ~0b01000000; // set E(6) as input
|
||||||
PORTE |= 0b01000000; // set E(6) internal pull-up enabled
|
PORTE |= 0b01000000; // set E(6) internal pull-up enabled
|
||||||
|
|
||||||
// LEDs (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md")
|
// 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
|
TCCR1A = 0b10101001; // set and configure fast PWM
|
||||||
TCCR1B = 0b00001001; // set and configure fast PWM
|
TCCR1B = 0b00001001; // set and configure fast PWM
|
||||||
|
|
||||||
// rows
|
// rows
|
||||||
DDRF |= 0b11110011; // set F(0,1,4,5,6,7) as output
|
DDRF |= 0b11110011; // set F(7,6,5,4,1,0) as output
|
||||||
PORTF |= 0b11110011; // set F(0,1,4,5,6,7) drive high
|
PORTF |= 0b11110011; // set F(7,6,5,4,1,0) drive high
|
||||||
|
|
||||||
// columns
|
// columns
|
||||||
DDRB &= ~0b00010001; // set B(0,4) as input
|
DDRB &= ~0b00010001; // set B(4,0) as input
|
||||||
PORTB |= 0b00010001; // set B(0,4) internal pull-up enabled
|
PORTB |= 0b00010001; // set B(4,0) internal pull-up enabled
|
||||||
DDRC &= ~0b11000000; // set C(6,7) as input
|
DDRC &= ~0b11000000; // set C(7,6) as input
|
||||||
PORTC |= 0b11000000; // set C(6,7) internal pull-up enabled
|
PORTC |= 0b11000000; // set C(7,6) internal pull-up enabled
|
||||||
DDRD &= ~0b10001100; // set D(2,3,7) as input
|
DDRD &= ~0b10001100; // set D(7,3,2) as input
|
||||||
PORTD |= 0b10001100; // set D(2,3,7) internal pull-up enabled
|
PORTD |= 0b10001100; // set D(7,3,2) internal pull-up enabled
|
||||||
|
|
||||||
// I2C (TWI)
|
// 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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,46 +10,28 @@
|
||||||
#ifndef TEENSY_2_0_h
|
#ifndef TEENSY_2_0_h
|
||||||
#define 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
|
#include <avr/io.h> // for the register macros
|
||||||
|
|
||||||
// LED control
|
// LED control
|
||||||
#define prefix(LED1_ON) (OCR1A = 0xFF)
|
#define KB_LED1_ON (OCR1A = 0xFF)
|
||||||
#define prefix(LED1_OFF) (OCR1A = 0x00)
|
#define KB_LED1_OFF (OCR1A = 0x00)
|
||||||
#define prefix(LED1_SET)(n) (OCR1A = (uint8_t)(n))
|
#define KB_LED1_SET(n) (OCR1A = (uint8_t)(n))
|
||||||
#define prefix(LED1_SET_PERCENT)(n) (OCR1A = (uint8_t)((n) * 0xFF))
|
#define KB_LED1_SET_PERCENT(n) (OCR1A = (uint8_t)((n) * 0xFF))
|
||||||
#define prefix(LED2_ON) (OCR1B = 0xFF)
|
#define KB_LED2_ON (OCR1B = 0xFF)
|
||||||
#define prefix(LED2_OFF) (OCR1B = 0x00)
|
#define KB_LED2_OFF (OCR1B = 0x00)
|
||||||
#define prefix(LED2_SET)(n) (OCR1B = (uint8_t)(n))
|
#define KB_LED2_SET(n) (OCR1B = (uint8_t)(n))
|
||||||
#define prefix(LED2_SET_PERCENT)(n) (OCR1B = (uint8_t)((n) * 0xFF))
|
#define KB_LED2_SET_PERCENT(n) (OCR1B = (uint8_t)((n) * 0xFF))
|
||||||
#define prefix(LED3_ON) (OCR1C = 0xFF)
|
#define KB_LED3_ON (OCR1C = 0xFF)
|
||||||
#define prefix(LED3_OFF) (OCR1C = 0x00)
|
#define KB_LED3_OFF (OCR1C = 0x00)
|
||||||
#define prefix(LED3_SET)(n) (OCR1C = (uint8_t)(n))
|
#define KB_LED3_SET(n) (OCR1C = (uint8_t)(n))
|
||||||
#define prefix(LED3_SET_PERCENT)(n) (OCR1C = (uint8_t)((n) * 0xFF))
|
#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)
|
uint8_t teensy_init(void);
|
||||||
__attribute__((alias ("teensy_init")));
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
|
||||||
|
|
||||||
#undef prefix
|
|
||||||
#undef pprefix
|
|
||||||
#undef INCLUDE_PREFIX
|
|
||||||
#undef PRIVATE_INCLUDE_PREFIX
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -41,10 +41,10 @@
|
||||||
column2 PC7 +-o-o-o-o-o-o
|
column2 PC7 +-o-o-o-o-o-o
|
||||||
|
|
||||||
* notes:
|
* notes:
|
||||||
* SCL and SDA: Need external pull-up resistors. Sometimes the internal
|
* SCL and SDA: Need external pull-up resistors. Sometimes the Teensy
|
||||||
pull-ups are enough (see datasheet section 20.5.1), but i think for this
|
internal pull-ups are enough (see datasheet section 20.5.1), but i think
|
||||||
project we'll want external ones, in case people want to separate the
|
for this project we'll want external ones, in case people want to separate
|
||||||
halves very far.
|
the halves very far.
|
||||||
|
|
||||||
## Notes about Registers
|
## Notes about Registers
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright © 2012 Ben Blazak
|
Copyright © 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||||
Released under The MIT License (MIT) (see "license.md") at
|
Released under The MIT License (MIT) (see "license.md")
|
||||||
<https://github.com/benblazak/ergodox-firmware>
|
Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||||
|
|
||||||
|
|
|
@ -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 <i2cmaster.h></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 <i2cmaster.h></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 </td><td class="memItemRight" valign="bottom"><a class="el" href="group__pfleury__ic2master.html#ga9">I2C_READ</a> 1</td></tr>
|
||||||
|
|
||||||
|
<tr><td class="memItemLeft" nowrap align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="group__pfleury__ic2master.html#ga10">I2C_WRITE</a> 0</td></tr>
|
||||||
|
|
||||||
|
<tr><td class="memItemLeft" nowrap align="right" valign="top"><a class="anchor" name="ga11" doxytag="pfleury_ic2master::i2c_read"></a>
|
||||||
|
#define </td><td class="memItemRight" valign="bottom"><b>i2c_read</b>(ack) (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 </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"> </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 </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"> </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 </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"> </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 </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"> </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 </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"> </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 </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"> </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 </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"> </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 </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"> </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 </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"> </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 1 </td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table cellspacing="5" cellpadding="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</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 0 </td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table cellspacing="5" cellpadding="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</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">( </td>
|
||||||
|
<td class="md" nowrap valign="top">void </td>
|
||||||
|
<td class="mdname1" valign="top" nowrap> </td>
|
||||||
|
<td class="md" valign="top"> ) </td>
|
||||||
|
<td class="md" nowrap></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table cellspacing="5" cellpadding="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</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> </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">( </td>
|
||||||
|
<td class="md" nowrap valign="top">void </td>
|
||||||
|
<td class="mdname1" valign="top" nowrap> </td>
|
||||||
|
<td class="md" valign="top"> ) </td>
|
||||||
|
<td class="md" nowrap></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table cellspacing="5" cellpadding="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</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> </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">( </td>
|
||||||
|
<td class="md" nowrap valign="top">unsigned char </td>
|
||||||
|
<td class="mdname1" valign="top" nowrap> <em>addr</em> </td>
|
||||||
|
<td class="md" valign="top"> ) </td>
|
||||||
|
<td class="md" nowrap></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table cellspacing="5" cellpadding="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</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> </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> </td><td>device accessible </td></tr>
|
||||||
|
<tr><td valign="top"></td><td valign="top"><em>1</em> </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">( </td>
|
||||||
|
<td class="md" nowrap valign="top">unsigned char </td>
|
||||||
|
<td class="mdname1" valign="top" nowrap> <em>addr</em> </td>
|
||||||
|
<td class="md" valign="top"> ) </td>
|
||||||
|
<td class="md" nowrap></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table cellspacing="5" cellpadding="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</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> </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> </td><td>device accessible </td></tr>
|
||||||
|
<tr><td valign="top"></td><td valign="top"><em>1</em> </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">( </td>
|
||||||
|
<td class="md" nowrap valign="top">unsigned char </td>
|
||||||
|
<td class="mdname1" valign="top" nowrap> <em>addr</em> </td>
|
||||||
|
<td class="md" valign="top"> ) </td>
|
||||||
|
<td class="md" nowrap></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table cellspacing="5" cellpadding="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</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> </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">( </td>
|
||||||
|
<td class="md" nowrap valign="top">unsigned char </td>
|
||||||
|
<td class="mdname1" valign="top" nowrap> <em>data</em> </td>
|
||||||
|
<td class="md" valign="top"> ) </td>
|
||||||
|
<td class="md" nowrap></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table cellspacing="5" cellpadding="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</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> </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> </td><td>write successful </td></tr>
|
||||||
|
<tr><td valign="top"></td><td valign="top"><em>1</em> </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">( </td>
|
||||||
|
<td class="md" nowrap valign="top">void </td>
|
||||||
|
<td class="mdname1" valign="top" nowrap> </td>
|
||||||
|
<td class="md" valign="top"> ) </td>
|
||||||
|
<td class="md" nowrap></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table cellspacing="5" cellpadding="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</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">( </td>
|
||||||
|
<td class="md" nowrap valign="top">void </td>
|
||||||
|
<td class="mdname1" valign="top" nowrap> </td>
|
||||||
|
<td class="md" valign="top"> ) </td>
|
||||||
|
<td class="md" nowrap></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table cellspacing="5" cellpadding="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</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">( </td>
|
||||||
|
<td class="md" nowrap valign="top">unsigned char </td>
|
||||||
|
<td class="mdname1" valign="top" nowrap> <em>ack</em> </td>
|
||||||
|
<td class="md" valign="top"> ) </td>
|
||||||
|
<td class="md" nowrap></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table cellspacing="5" cellpadding="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</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> </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
|
||||||
|
<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>
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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(;;);
|
||||||
|
}
|
|
@ -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 */
|
|
@ -1,10 +1,5 @@
|
||||||
# Hey Emacs, this is a -*- makefile -*-
|
# 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.
|
# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
|
||||||
#
|
#
|
||||||
# Released to the Public Domain
|
# Released to the Public Domain
|
||||||
|
@ -46,11 +41,13 @@
|
||||||
|
|
||||||
|
|
||||||
# Target file name (without extension).
|
# Target file name (without extension).
|
||||||
TARGET = ergodox-firmware
|
TARGET = blinky
|
||||||
|
|
||||||
|
|
||||||
# List C source files here. (C dependencies are automatically generated.)
|
# 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
|
# 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
|
# type "make clean" after changing this, so all files will be rebuilt
|
|
@ -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: --..
|
||||||
|
};
|
||||||
|
|
|
@ -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
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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 © 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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 // - - - -
|
||||||
|
|
|
@ -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 // - -
|
21
src/makefile
21
src/makefile
|
@ -2,16 +2,27 @@
|
||||||
# This is mostly a stub at the moment, but I'm keeping it separate so I can
|
# 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
|
# mess with it later without changing the original
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Copyright (c) 2012 Ben Blazak
|
# Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||||
# Released under The MIT License (MIT) (see "license.md") at
|
# Released under The MIT License (MIT) (see "license.md")
|
||||||
# <https://github.com/benblazak/ergodox-firmware>
|
# 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 = .
|
EXTRAINCDIRS = .
|
||||||
|
|
||||||
TEENSY_MAKE = $(MAKE) -f 'lib/pjrc/Makefile' \
|
TEENSY_MAKE = $(MAKE) -f 'lib-other/pjrc/blinky/Makefile' \
|
||||||
|
TARGET='$(TARGET)' \
|
||||||
SRC='$(SRC)' \
|
SRC='$(SRC)' \
|
||||||
EXTRAINCDIRS='$(EXTRAINCDIRS)'
|
EXTRAINCDIRS='$(EXTRAINCDIRS)'
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue