mostly working on mcp23018.c; init() and update() might be ready :)
also, moved the twi code to lib/teensy-2-0/twi*partial-rewrite
parent
b0b9335651
commit
f41502ba3c
|
@ -40,6 +40,13 @@
|
|||
|
||||
## C Stuff
|
||||
|
||||
* [comp.lang.c Frequently Asked Questions]
|
||||
(http://c-faq.com/index.html)
|
||||
|
||||
* [The C Preprocessor]
|
||||
(http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC1)
|
||||
(on <http://gcc.gnu.org/>)
|
||||
|
||||
* [C Library Reference]
|
||||
(http://www.cplusplus.com/reference/)
|
||||
(on <http://cplusplus.com>)
|
||||
|
|
|
@ -14,27 +14,31 @@
|
|||
|
||||
#define KB_LAYERS 1 // anything >= 1, as long as there's memory
|
||||
|
||||
#if KB_ROWS != 12 || KB_COLUMNS != 7
|
||||
#error "Expecting different keyboard dimensions"
|
||||
#endif
|
||||
|
||||
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 -------------------------- */
|
||||
/* 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 ----------- */
|
||||
/* 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
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#define KB_ROWS 12 // must match real life
|
||||
#define KB_COLUMNS 7 // must match real life
|
||||
|
||||
extern bool kb_is_pressed[KB_ROWS][KB_COLUMNS] = {};
|
||||
extern bool kb_is_pressed[KB_ROWS][KB_COLUMNS] = {false};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -6,33 +6,16 @@
|
|||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
// TODO: this is not working yet
|
||||
|
||||
// see if the device is ready
|
||||
// - success: set `mcp23018_ready = true` and continue initializing
|
||||
// - failure: return `error`; we can try again later
|
||||
|
||||
// set pin direction
|
||||
// - unused : input : 1
|
||||
// - rows : output : 0
|
||||
// - columns : input : 1
|
||||
|
||||
// set pull-up
|
||||
// - unused : on : 1
|
||||
// - rows : on : 1
|
||||
// - columns : on : 1
|
||||
|
||||
// set output pins high
|
||||
// - rows : high : 1
|
||||
// - other : low : 0 (or ignored)
|
||||
|
||||
|
||||
#include <util/twi.h>
|
||||
|
||||
#include "lib/data-types.h"
|
||||
#define TWI_FREQ 400000
|
||||
#include "lib/teensy-2-0/twi.h"
|
||||
|
||||
#include "matrix.h"
|
||||
#define MCP23018_h_INCLUDE_PRIVATE
|
||||
#include "mcp23018.h"
|
||||
#include "teensy-2-0.h"
|
||||
#include "lib/data-types.h"
|
||||
|
||||
|
||||
// register addresses (see "mcp23018.md")
|
||||
|
@ -45,83 +28,106 @@
|
|||
#define OLATA 0x14 // output latch register
|
||||
#define OLATB 0x15
|
||||
|
||||
// TWI aliases
|
||||
#define TWI_ADDR_WRITE ( (MCP23018_TWI_ADDRESS<<1) | TW_WRITE )
|
||||
#define TWI_ADDR_READ ( (MCP23018_TWI_ADDRESS<<1) | TW_READ )
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// dbg
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
// error check
|
||||
#if KB_ROWS != 12 || KB_COLUMNS != 7
|
||||
#error "Expecting different keyboard dimensions"
|
||||
#endif
|
||||
|
||||
#define blink_led(time1, time2) { \
|
||||
/* Teensy 2.0 onboard LED on PD6
|
||||
on high, off low */ \
|
||||
PORTD |= (1<<6); \
|
||||
_delay_ms(time1); \
|
||||
PORTD &= ~(1<<6); \
|
||||
_delay_ms(time2); \
|
||||
}
|
||||
|
||||
void blink_hex(uint8_t num) {
|
||||
// initial blink (get ready)
|
||||
blink_led(700, 200);
|
||||
// 1st hex number
|
||||
for (uint8_t i=0; i<(num/0x10); i++) {
|
||||
blink_led(200, 100);
|
||||
}
|
||||
_delay_ms(400);
|
||||
// 2nd hex number
|
||||
for (uint8_t i=0; i<(num%0x10); i++) {
|
||||
blink_led(200, 100);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------- // TWI
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void twi_init(void) {
|
||||
TWSR &= ~( (1<<TWPS1)|(1<<TWPS0) );
|
||||
TWBR = ((F_CPU / 400000) - 16) / 2;
|
||||
// TWSR |= (1<<TWPS1)|(1<<TWPS0); //dbg
|
||||
// TWBR = 0xFF; //dbg
|
||||
}
|
||||
|
||||
uint8_t twi_start(void) {
|
||||
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
|
||||
while (!(TWCR & (1<<TWINT)));
|
||||
if ((TWSR & 0xF8) != TW_START)
|
||||
return TWSR & 0xF8; // error
|
||||
}
|
||||
|
||||
void twi_stop(void) {
|
||||
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
|
||||
while (TWCR & (1<<TWSTO));
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// init function
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* returns:
|
||||
* - success: 0
|
||||
* - failure: twi status code
|
||||
*/
|
||||
uint8_t mcp23018_init(void) {
|
||||
uint8_t ret;
|
||||
|
||||
twi_init();
|
||||
|
||||
// quick check to see if the device is responding; if it is, we'll
|
||||
// assume things are going to work
|
||||
twi_start();
|
||||
ret = twi_send( (MCP23018_TWI_ADDRESS<<1) | TW_WRITE );
|
||||
ret = twi_send(IODIRA);
|
||||
ret = twi_send(0);
|
||||
ret = twi_send(0);
|
||||
ret = twi_send(0);
|
||||
ret = twi_send(TWI_ADDR_WRITE);
|
||||
if (ret) {
|
||||
twi_stop();
|
||||
return ret;
|
||||
}
|
||||
|
||||
blink_hex(ret);
|
||||
// set pin direction
|
||||
// - unused : input : 1
|
||||
// - rows : output : 0
|
||||
// - columns : input : 1
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
twi_send(IODIRA);
|
||||
twi_send(0b11000000); // IODIRA
|
||||
twi_send(0b11111111); // IODIRB
|
||||
|
||||
// set pull-up
|
||||
// - unused : on : 1
|
||||
// - rows : on : 1
|
||||
// - columns : on : 1
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
twi_send(GPPUA);
|
||||
twi_send(0b11111111); // GPPUA
|
||||
twi_send(0b11111111); // GPPUB
|
||||
|
||||
// set output pins high
|
||||
// - unused : low : 0
|
||||
// - rows : high : 1
|
||||
// - columns : low : 0
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
twi_send(GPIOA);
|
||||
twi_send(0b00111111); //GPIOA
|
||||
twi_send(0b00000000); //GPIOB
|
||||
|
||||
twi_stop();
|
||||
}
|
||||
|
||||
/* args:
|
||||
* - `matrix[][]`: `KB_ROWS` and `KB_COLUMNS` must be what we're expecting (see
|
||||
* 'error check' in the `#include` section)
|
||||
*
|
||||
* returns:
|
||||
* - success: 0
|
||||
* - failure: twi status code
|
||||
*/
|
||||
uint8_t mcp23018_update_matrix(uint8_t matrix[KB_ROWS][KB_COLUMNS]) {
|
||||
uint8_t ret, data;
|
||||
|
||||
// quick check to see if the device is responding; if it is, we'll
|
||||
// assume things are going to work
|
||||
twi_start();
|
||||
ret = twi_send(TWI_ADDR_WRITE);
|
||||
if (ret) {
|
||||
twi_stop();
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (uint8_t row=0x6; row<=0xB; row++) {
|
||||
// set row low : 0
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_WRITE);
|
||||
twi_send(GPIOA);
|
||||
twi_send( 0b00111111 & ~(1<<(row-6)) ); // GPIOA
|
||||
|
||||
// get column data
|
||||
twi_start();
|
||||
twi_send(TWI_ADDR_READ);
|
||||
twi_read(&data); // GPIOB TODO: confirm
|
||||
|
||||
// update matrix
|
||||
for (uint8_t col=0; col<=6; col++)
|
||||
matrix[row][col] = !( data & (1<<col) );
|
||||
}
|
||||
|
||||
twi_stop();
|
||||
}
|
||||
|
||||
|
|
|
@ -10,15 +10,13 @@
|
|||
#ifndef MCP23018_h
|
||||
#define MCP23018_h
|
||||
|
||||
#include "lib/data-types.h"
|
||||
|
||||
#ifdef MCP23018_h_INCLUDE_PRIVATE
|
||||
|
||||
#define MCP23018_TWI_ADDRESS 0b0100000
|
||||
|
||||
extern bool mcp23018_ready;
|
||||
|
||||
uint8_t mcp23018_init(void);
|
||||
uint8_t mcp23018_update_matrix(
|
||||
uint8_t matrix[KB_ROWS][KB_COLUMNS] );
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -43,9 +43,11 @@
|
|||
* notes:
|
||||
* ADDR (pin15): Set slave address to `0b0100000` by connecting to Vss(GND).
|
||||
(The user-defined bits are the three least significant).
|
||||
* RESET (pin16) must be externally biased. At least, this is true on the
|
||||
MCP23017, so it seems like it should be true with the MCP23018. Since
|
||||
we're not going to trigger it ourselves, we'll tie it high.
|
||||
* RESET (pin16) must be externally biased.Since we're not going to trigger it
|
||||
ourselves, we'll tie it high.
|
||||
* This is not noted in the I2C Pinout Description section of the MCP23018
|
||||
datasheet, but it's true (empirically), and it is noted in the SPI Pinout
|
||||
Description section, and in the MCP23017 datasheet.
|
||||
* <http://davidn.org/wp/?p=89>
|
||||
* <http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1293498979>
|
||||
|
||||
|
@ -76,6 +78,9 @@
|
|||
* All addresses given for IOCON.BANK = 0, since that's the default value of
|
||||
the bit, and that's what we'll be using.
|
||||
* Outputs are open drain, so we want pull-up resistors set for everything.
|
||||
* We want the row pins set as output high initially, and the column pins set
|
||||
as input. We'll cycle through driving the row pins low and checking the
|
||||
column pins in the update function.
|
||||
|
||||
* abbreviations:
|
||||
* IODIR = I/O Direction Register
|
||||
|
|
|
@ -26,6 +26,10 @@
|
|||
#define CPU_62kHz 0x08
|
||||
|
||||
|
||||
/* returns:
|
||||
* - success: 0
|
||||
* + will never return failure
|
||||
*/
|
||||
uint8_t teensy_init(void) {
|
||||
CPU_PRESCALE(CPU_16MHz); // speed should match F_CPU in makefile
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# Documentation : Teensy 2.0
|
||||
|
||||
|
||||
## Pinouts and Pin assignments
|
||||
|
||||
* `+` indicates pin
|
||||
|
@ -68,7 +67,7 @@
|
|||
LED, so there's no reason to set internal pull-up enabled on it. If we
|
||||
do, it will source current to the LED, which is fine, but unnecessary.
|
||||
* We want the row pins 'drive high' initially, and the column pins set as
|
||||
input with internal pull-up. We'll cycle through driving the row pins low,
|
||||
input with internal pull-up. We'll cycle through driving the row pins low
|
||||
and checking the column pins in the update function.
|
||||
|
||||
### PWM on ports OC1(A|B|C) (see datasheet section 14.10)
|
||||
|
@ -103,30 +102,6 @@
|
|||
* OCR = Output Compare Register
|
||||
* TCCR = Timer/Counter Control Register
|
||||
|
||||
|
||||
## I²C Status Codes (for Master modes)
|
||||
|
||||
### Master Transmitter
|
||||
|
||||
* `0x08` A START condition has been transmitted
|
||||
* `0x10` A repeated START condition has been transmitted
|
||||
* `0x18` SLA+W has been transmitted; ACK has been received
|
||||
* `0x20` SLA+W has been transmitted; NOT ACK has been received
|
||||
* `0x28` Data byte has been transmitted; ACK has been received
|
||||
* `0x30` Data byte has been transmitted; NOT ACK has been received
|
||||
* `0x38` Arbitration lost in SLA+W or data bytes
|
||||
|
||||
### Master Receiver
|
||||
|
||||
* `0x08` A START condition has been transmitted
|
||||
* `0x10` A repeated START condition has been transmitted
|
||||
* `0x38` Arbitration lost in SLA+R or NOT ACK bit
|
||||
* `0x40` SLA+R has been transmitted; ACK has been received
|
||||
* `0x48` SLA+R has been transmitted; NOT ACK has been received
|
||||
* `0x50` Data byte has been received; ACK has been returned
|
||||
* `0x58` Data byte has been received; NOT ACK has been returned
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Copyright © 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
<!--
|
||||
TODO: move the links into references if they're going to disappear from here
|
||||
-->
|
||||
# src/lib-other
|
||||
Files taken from other projects
|
||||
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* Very simple Teensy 2.0 TWI library : code
|
||||
*
|
||||
* - This is mostly straight from the datasheet, section 20.6.6, figure 20-11
|
||||
* (the code example in C), and section 20.8.1, figure 20-12
|
||||
* - Also see the documentation for `<util/twi.h>` at <http://www.nongnu.org/avr-libc/user-manual/group__util__twi.html#ga8d3aca0acc182f459a51797321728168>
|
||||
*
|
||||
* Some other (more complete) TWI libraries for the Teensy 2.0 (and other Amtel
|
||||
* processors):
|
||||
* - [i2cmaster] (http://homepage.hispeed.ch/peterfleury/i2cmaster.zip)
|
||||
* - written by [peter-fleury] (http://homepage.hispeed.ch/peterfleury/)
|
||||
* - [the arduino twi library] (https://github.com/arduino/Arduino/tree/master/libraries/Wire/utility)
|
||||
* - look for an older version if you need one that doesn't depend on all the
|
||||
* other Arduino stuff
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include <util/twi.h>
|
||||
|
||||
#include "twi.h"
|
||||
|
||||
|
||||
void twi_init(void) {
|
||||
// set the prescaler value to 0
|
||||
TWSR &= ~( (1<<TWPS1)|(1<<TWPS0) );
|
||||
// set the bit rate
|
||||
// - TWBR should be 10 or higher (datasheet section 20.5.2)
|
||||
// - TWI_FREQ should be 400000 (400kHz) max (datasheet section 20.1)
|
||||
TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
|
||||
}
|
||||
|
||||
uint8_t twi_start(void) {
|
||||
// send start
|
||||
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
|
||||
// wait for transmission to complete
|
||||
while (!(TWCR & (1<<TWINT)));
|
||||
// if it didn't work, return the status code (else return 0)
|
||||
if (! (TW_STATUS == TW_START) ||
|
||||
(TW_STATUS == TW_REP_START) )
|
||||
return TW_STATUS; // error
|
||||
}
|
||||
|
||||
void twi_stop(void) {
|
||||
// send stop
|
||||
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
|
||||
// wait for transmission to complete
|
||||
while (TWCR & (1<<TWSTO));
|
||||
}
|
||||
|
||||
uint8_t twi_send(uint8_t data) {
|
||||
// load data into the data register
|
||||
TWDR = data;
|
||||
// send data
|
||||
TWCR = (1<<TWINT)|(1<<TWEN);
|
||||
// wait for transmission to complete
|
||||
while (!(TWCR & (1<<TWINT)));
|
||||
// if it didn't work, return the status code (else return 0)
|
||||
if (! (TW_STATUS == TW_MT_SLA_ACK) ||
|
||||
(TW_STATUS == TW_MT_DATA_ACK)||
|
||||
(TW_STATUS == TW_MR_SLA_ACK) )
|
||||
return TW_STATUS; // error
|
||||
}
|
||||
|
||||
uint8_t twi_read(uint8_t * data) {
|
||||
// read 1 byte to TWDR, send ACK
|
||||
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
|
||||
// wait for transmission to complete
|
||||
while (!(TWCR & (1<<TWINT)));
|
||||
// set data variable
|
||||
data = TWDR;
|
||||
// if it didn't work, return the status code (else return 0)
|
||||
if (TW_STATUS != TW_MR_DATA_ACK)
|
||||
return TW_STATUS; // error
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* Very simple Teensy 2.0 TWI library : 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 TWI_h
|
||||
#define TWI_h
|
||||
|
||||
#ifndef TWI_FREQ
|
||||
#define TWI_FREQ 100000
|
||||
#endif
|
||||
|
||||
|
||||
void twi_init(void);
|
||||
uint8_t twi_start(void);
|
||||
void twi_stop(void);
|
||||
uint8_t twi_send(uint8_t data);
|
||||
uint8_t twi_read(uint8_t * data);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# Documentation : Teensy 2.0 I²C
|
||||
|
||||
## I²C Status Codes (for Master modes)
|
||||
|
||||
### Master Transmitter (datasheet section 20.8.1, table 20-3)
|
||||
|
||||
* `0x08` A START condition has been transmitted
|
||||
* `0x10` A repeated START condition has been transmitted
|
||||
* `0x18` SLA+W has been transmitted; ACK has been received
|
||||
* `0x20` SLA+W has been transmitted; NOT ACK has been received
|
||||
* `0x28` Data byte has been transmitted; ACK has been received
|
||||
* `0x30` Data byte has been transmitted; NOT ACK has been received
|
||||
* `0x38` Arbitration lost in SLA+W or data bytes
|
||||
|
||||
### Master Receiver (datasheet section 20.8.2, table 20-4)
|
||||
|
||||
* `0x08` A START condition has been transmitted
|
||||
* `0x10` A repeated START condition has been transmitted
|
||||
* `0x38` Arbitration lost in SLA+R or NOT ACK bit
|
||||
* `0x40` SLA+R has been transmitted; ACK has been received
|
||||
* `0x48` SLA+R has been transmitted; NOT ACK has been received
|
||||
* `0x50` Data byte has been received; ACK has been returned
|
||||
* `0x58` Data byte has been received; NOT ACK has been returned
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
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>
|
||||
|
Loading…
Reference in New Issue