From d707738616c140f8d9c8eded7b64e5fc806f4b24 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 5 Jul 2016 23:27:10 -0400 Subject: i2c working --- keyboards/lets_split/i2c.c | 159 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 keyboards/lets_split/i2c.c (limited to 'keyboards/lets_split/i2c.c') diff --git a/keyboards/lets_split/i2c.c b/keyboards/lets_split/i2c.c new file mode 100644 index 000000000..c72789403 --- /dev/null +++ b/keyboards/lets_split/i2c.c @@ -0,0 +1,159 @@ +#include +#include +#include +#include +#include +#include +#include "i2c.h" + +// Limits the amount of we wait for any one i2c transaction. +// Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is +// 9 bits, a single transaction will take around 90μs to complete. +// +// (F_CPU/SCL_CLOCK) => # of μC cycles to transfer a bit +// poll loop takes at least 8 clock cycles to execute +#define I2C_LOOP_TIMEOUT (9+1)*(F_CPU/SCL_CLOCK)/8 + +#define BUFFER_POS_INC() (slave_buffer_pos = (slave_buffer_pos+1)%SLAVE_BUFFER_SIZE) + +volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; + +static volatile uint8_t slave_buffer_pos; +static volatile bool slave_has_register_set = false; + +// Wait for an i2c operation to finish +inline static +void i2c_delay(void) { + uint16_t lim = 0; + while(!(TWCR & (1<10. + // Check datasheets for more info. + TWBR = ((F_CPU/SCL_CLOCK)-16)/2; +} + +// Start a transaction with the given i2c slave address. The direction of the +// transfer is set with I2C_READ and I2C_WRITE. +// returns: 0 => success +// 1 => error +uint8_t i2c_master_start(uint8_t address) { + TWCR = (1< slave ACK +// 1 => slave NACK +uint8_t i2c_master_write(uint8_t data) { + TWDR = data; + TWCR = (1<= SLAVE_BUFFER_SIZE ) { + ack = 0; + slave_buffer_pos = 0; + } + slave_has_register_set = true; + } else { + i2c_slave_buffer[slave_buffer_pos] = TWDR; + BUFFER_POS_INC(); + } + break; + + case TW_ST_SLA_ACK: + case TW_ST_DATA_ACK: + // master has addressed this device as a slave transmitter and is + // requesting data. + TWDR = i2c_slave_buffer[slave_buffer_pos]; + BUFFER_POS_INC(); + break; + + case TW_BUS_ERROR: // something went wrong, reset twi state + TWCR = 0; + default: + break; + } + // Reset everything, so we are ready for the next TWI interrupt + TWCR |= (1< Date: Tue, 20 Sep 2016 21:38:59 -0500 Subject: Made Serial and I2C not include the Other This saves 192 bytes --- keyboards/lets_split/config.h | 7 ++++++- keyboards/lets_split/i2c.c | 3 +++ keyboards/lets_split/matrix.c | 23 +++++++++++++++-------- keyboards/lets_split/rules.mk | 4 ++-- keyboards/lets_split/serial.c | 5 ++++- keyboards/lets_split/split_util.c | 8 ++++++-- 6 files changed, 36 insertions(+), 14 deletions(-) (limited to 'keyboards/lets_split/i2c.c') diff --git a/keyboards/lets_split/config.h b/keyboards/lets_split/config.h index ec99514aa..f4d900acc 100644 --- a/keyboards/lets_split/config.h +++ b/keyboards/lets_split/config.h @@ -41,6 +41,11 @@ along with this program. If not, see . // #define USE_I2C +// Use serial if not using I2C +#ifndef USE_I2C +# define USE_SERIAL +#endif + // #define EE_HANDS #define I2C_MASTER_LEFT @@ -94,4 +99,4 @@ along with this program. If not, see . //#define NO_ACTION_MACRO //#define NO_ACTION_FUNCTION -#endif \ No newline at end of file +#endif diff --git a/keyboards/lets_split/i2c.c b/keyboards/lets_split/i2c.c index c72789403..084c890c4 100644 --- a/keyboards/lets_split/i2c.c +++ b/keyboards/lets_split/i2c.c @@ -6,6 +6,8 @@ #include #include "i2c.h" +#ifdef USE_I2C + // Limits the amount of we wait for any one i2c transaction. // Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is // 9 bits, a single transaction will take around 90μs to complete. @@ -157,3 +159,4 @@ ISR(TWI_vect) { // Reset everything, so we are ready for the next TWI interrupt TWCR |= (1<. #include "debug.h" #include "util.h" #include "matrix.h" -#include "i2c.h" -#include "serial.h" #include "split_util.h" #include "pro_micro.h" #include "config.h" +#ifdef USE_I2C +# include "i2c.h" +#else // USE_SERIAL +# include "serial.h" +#endif + #ifndef DEBOUNCE -# define DEBOUNCE 5 +# define DEBOUNCE 5 #endif #define ERROR_DISCONNECT_COUNT 5 @@ -145,6 +149,8 @@ uint8_t _matrix_scan(void) return 1; } +#ifdef USE_I2C + // Get rows from other half over i2c int i2c_transaction(void) { int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; @@ -176,7 +182,8 @@ i2c_error: // the cable is disconnceted, or something else went wrong return 0; } -#ifndef USE_I2C +#else // USE_SERIAL + int serial_transaction(void) { int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; @@ -199,7 +206,7 @@ uint8_t matrix_scan(void) #ifdef USE_I2C if( i2c_transaction() ) { -#else +#else // USE_SERIAL if( serial_transaction() ) { #endif // turn on the indicator led when halves are disconnected @@ -235,7 +242,7 @@ void matrix_slave_scan(void) { /* i2c_slave_buffer[i] = matrix[offset+i]; */ i2c_slave_buffer[i] = matrix[offset+i]; } -#else +#else // USE_SERIAL for (int i = 0; i < ROWS_PER_HAND; ++i) { serial_slave_buffer[i] = matrix[offset+i]; } @@ -290,7 +297,7 @@ static void init_cols(void) static matrix_row_t read_cols(void) { matrix_row_t result = 0; - for(int x = 0; x < MATRIX_COLS; x++) { + for(int x = 0; x < MATRIX_COLS; x++) { result |= (_SFR_IO8(col_pins[x] >> 4) & _BV(col_pins[x] & 0xF)) ? 0 : (1 << x); } return result; @@ -298,7 +305,7 @@ static matrix_row_t read_cols(void) static void unselect_rows(void) { - for(int x = 0; x < ROWS_PER_HAND; x++) { + for(int x = 0; x < ROWS_PER_HAND; x++) { _SFR_IO8((row_pins[x] >> 4) + 1) &= ~_BV(row_pins[x] & 0xF); _SFR_IO8((row_pins[x] >> 4) + 2) |= _BV(row_pins[x] & 0xF); } diff --git a/keyboards/lets_split/rules.mk b/keyboards/lets_split/rules.mk index 6961fbd55..6fde8a444 100644 --- a/keyboards/lets_split/rules.mk +++ b/keyboards/lets_split/rules.mk @@ -52,7 +52,7 @@ OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT OPT_DEFS += -DBOOTLOADER_SIZE=4096 # Build Options -# change to "no" to disable the options, or define them in the Makefile in +# change to "no" to disable the options, or define them in the Makefile in # the appropriate keymap folder that will get included automatically # BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000) @@ -71,4 +71,4 @@ RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight. Do not enable this # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend -CUSTOM_MATRIX = yes \ No newline at end of file +CUSTOM_MATRIX = yes diff --git a/keyboards/lets_split/serial.c b/keyboards/lets_split/serial.c index f439c2f20..6faed09ce 100644 --- a/keyboards/lets_split/serial.c +++ b/keyboards/lets_split/serial.c @@ -10,9 +10,10 @@ #include #include #include - #include "serial.h" +#ifdef USE_SERIAL + // Serial pulse period in microseconds. Its probably a bad idea to lower this // value. #define SERIAL_DELAY 24 @@ -223,3 +224,5 @@ int serial_update_buffers(void) { sei(); return 0; } + +#endif diff --git a/keyboards/lets_split/split_util.c b/keyboards/lets_split/split_util.c index 65003a71a..461921798 100644 --- a/keyboards/lets_split/split_util.c +++ b/keyboards/lets_split/split_util.c @@ -6,11 +6,15 @@ #include #include "split_util.h" #include "matrix.h" -#include "i2c.h" -#include "serial.h" #include "keyboard.h" #include "config.h" +#ifdef USE_I2C +# include "i2c.h" +#else +# include "serial.h" +#endif + volatile bool isLeftHand = true; static void setup_handedness(void) { -- cgit v1.2.3-70-g09d2