From ce01f88c43adef9344727998f53bb1cf74913f65 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 5 Jul 2016 23:40:54 -0400 Subject: [PATCH] images, docks, clean-up [skip ci] --- .../imgs/split-keyboard-i2c-schematic.png | Bin 0 -> 26565 bytes .../imgs/split-keyboard-serial-schematic.png | Bin 0 -> 19487 bytes keyboards/lets_split/matrix.c | 1 + keyboards/lets_split/readme.md | 102 ++++++++ keyboards/lets_split/serial.c | 225 ++++++++++++++++++ keyboards/lets_split/serial.h | 26 ++ keyboards/lets_split/split_util.c | 9 + keyboards/lets_split/split_util.h | 6 +- .../{uno-slave => uno_slave}/Makefile | 0 .../keyboard-i2c-slave.c | 0 .../{uno-slave => uno_slave}/readme.md | 0 .../{uno-slave => uno_slave}/uno-matrix.c | 0 .../{uno-slave => uno_slave}/uno-matrix.h | 0 13 files changed, 367 insertions(+), 2 deletions(-) create mode 100644 keyboards/lets_split/imgs/split-keyboard-i2c-schematic.png create mode 100644 keyboards/lets_split/imgs/split-keyboard-serial-schematic.png create mode 100644 keyboards/lets_split/serial.c create mode 100644 keyboards/lets_split/serial.h rename keyboards/lets_split/{uno-slave => uno_slave}/Makefile (100%) rename keyboards/lets_split/{uno-slave => uno_slave}/keyboard-i2c-slave.c (100%) rename keyboards/lets_split/{uno-slave => uno_slave}/readme.md (100%) rename keyboards/lets_split/{uno-slave => uno_slave}/uno-matrix.c (100%) rename keyboards/lets_split/{uno-slave => uno_slave}/uno-matrix.h (100%) diff --git a/keyboards/lets_split/imgs/split-keyboard-i2c-schematic.png b/keyboards/lets_split/imgs/split-keyboard-i2c-schematic.png new file mode 100644 index 0000000000000000000000000000000000000000..8882947187b15ae4c0cf70c90725d67fb2386d87 GIT binary patch literal 26565 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. #include "util.h" #include "matrix.h" #include "i2c.h" +#include "serial.h" #include "split_util.h" #include "pro_micro.h" #include "config.h" diff --git a/keyboards/lets_split/readme.md b/keyboards/lets_split/readme.md index e69de29bb2..73fdb0f789 100644 --- a/keyboards/lets_split/readme.md +++ b/keyboards/lets_split/readme.md @@ -0,0 +1,102 @@ +Let's Split +====== + +This readme and most of the code are from https://github.com/ahtn/tmk_keyboard/ + +Split keyboard firmware for Arduino Pro Micro or other ATmega32u4 +based boards. + +Features +-------- + +Some features supported by the firmware: + +* Either half can connect to the computer via USB, or both halves can be used + independently. +* You only need 3 wires to connect the two halves. Two for VCC and GND and one + for serial communication. +* Optional support for I2C connection between the two halves if for some + reason you require a faster connection between the two halves. Note this + requires an extra wire between halves and pull-up resistors on the data lines. + +Required Hardware +----------------- + +Apart from diodes and key switches for the keyboard matrix in each half, you +will need: + +* 2 Arduino Pro Micro's. You can find theses on aliexpress for ≈3.50USD each. +* 2 TRS sockets +* 1 TRS cable. + +Alternatively, you can use any sort of cable and socket that has at least 3 +wires. If you want to use I2C to communicate between halves, you will need a +cable with at least 4 wires and 2x 4.7kΩ pull-up resistors + +Optional Hardware +----------------- + +A speaker can be hooked-up to either side to the `5` (`C6`) pin and `GND`, and turned on via `AUDIO_ENABLE`. + +Wiring +------ + +The 3 wires of the TRS cable need to connect GND, VCC, and digital pin 3 (i.e. +PD0 on the ATmega32u4) between the two Pro Micros. + +Then wire your key matrix to any of the remaining 17 IO pins of the pro micro +and modify the `matrix.c` accordingly. + +The wiring for serial: + +![serial wiring](imgs/split-keyboard-serial-schematic.png) + +The wiring for i2c: + +![i2c wiring](imgs/split-keyboard-i2c-schematic.png) + +The pull-up resistors may be placed on either half. It is also possible +to use 4 resistors and have the pull-ups in both halves, but this is +unnecessary in simple use cases. + +Notes on Software Configuration +------------------------------- + +Configuring the firmware is similar to any other TMK project. One thing +to note is that `MATIX_ROWS` in `config.h` is the total number of rows between +the two halves, i.e. if your split keyboard has 4 rows in each half, then +`MATRIX_ROWS=8`. + +Also the current implementation assumes a maximum of 8 columns, but it would +not be very difficult to adapt it to support more if required. + + +Flashing +-------- + +If you define `EE_HANDS` in your `config.h`, you will need to set the +EEPROM for the left and right halves. The EEPROM is used to store whether the +half is left handed or right handed. This makes it so that the same firmware +file will run on both hands instead of having to flash left and right handed +versions of the firmware to each half. To flash the EEPROM file for the left +half run: +``` +make eeprom-left +``` +and similarly for right half +``` +make eeprom-right +``` + +After you have flashed the EEPROM for the first time, you then need to program +the flash memory: +``` +make program +``` +Note that you need to program both halves, but you have the option of using +different keymaps for each half. You could program the left half with a QWERTY +layout and the right half with a Colemak layout. Then if you connect the left +half to a computer by USB the keyboard will use QWERTY and Colemak when the +right half is connected. + + diff --git a/keyboards/lets_split/serial.c b/keyboards/lets_split/serial.c new file mode 100644 index 0000000000..f439c2f20b --- /dev/null +++ b/keyboards/lets_split/serial.c @@ -0,0 +1,225 @@ +/* + * WARNING: be careful changing this code, it is very timing dependent + */ + +#ifndef F_CPU +#define F_CPU 16000000 +#endif + +#include +#include +#include +#include + +#include "serial.h" + +// Serial pulse period in microseconds. Its probably a bad idea to lower this +// value. +#define SERIAL_DELAY 24 + +uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0}; +uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0}; + +#define SLAVE_DATA_CORRUPT (1<<0) +volatile uint8_t status = 0; + +inline static +void serial_delay(void) { + _delay_us(SERIAL_DELAY); +} + +inline static +void serial_output(void) { + SERIAL_PIN_DDR |= SERIAL_PIN_MASK; +} + +// make the serial pin an input with pull-up resistor +inline static +void serial_input(void) { + SERIAL_PIN_DDR &= ~SERIAL_PIN_MASK; + SERIAL_PIN_PORT |= SERIAL_PIN_MASK; +} + +inline static +uint8_t serial_read_pin(void) { + return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK); +} + +inline static +void serial_low(void) { + SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK; +} + +inline static +void serial_high(void) { + SERIAL_PIN_PORT |= SERIAL_PIN_MASK; +} + +void serial_master_init(void) { + serial_output(); + serial_high(); +} + +void serial_slave_init(void) { + serial_input(); + + // Enable INT0 + EIMSK |= _BV(INT0); + // Trigger on falling edge of INT0 + EICRA &= ~(_BV(ISC00) | _BV(ISC01)); +} + +// Used by the master to synchronize timing with the slave. +static +void sync_recv(void) { + serial_input(); + // This shouldn't hang if the slave disconnects because the + // serial line will float to high if the slave does disconnect. + while (!serial_read_pin()); + serial_delay(); +} + +// Used by the slave to send a synchronization signal to the master. +static +void sync_send(void) { + serial_output(); + + serial_low(); + serial_delay(); + + serial_high(); +} + +// Reads a byte from the serial line +static +uint8_t serial_read_byte(void) { + uint8_t byte = 0; + serial_input(); + for ( uint8_t i = 0; i < 8; ++i) { + byte = (byte << 1) | serial_read_pin(); + serial_delay(); + _delay_us(1); + } + + return byte; +} + +// Sends a byte with MSB ordering +static +void serial_write_byte(uint8_t data) { + uint8_t b = 8; + serial_output(); + while( b-- ) { + if(data & (1 << b)) { + serial_high(); + } else { + serial_low(); + } + serial_delay(); + } +} + +// interrupt handle to be used by the slave device +ISR(SERIAL_PIN_INTERRUPT) { + sync_send(); + + uint8_t checksum = 0; + for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) { + serial_write_byte(serial_slave_buffer[i]); + sync_send(); + checksum += serial_slave_buffer[i]; + } + serial_write_byte(checksum); + sync_send(); + + // wait for the sync to finish sending + serial_delay(); + + // read the middle of pulses + _delay_us(SERIAL_DELAY/2); + + uint8_t checksum_computed = 0; + for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) { + serial_master_buffer[i] = serial_read_byte(); + sync_send(); + checksum_computed += serial_master_buffer[i]; + } + uint8_t checksum_received = serial_read_byte(); + sync_send(); + + serial_input(); // end transaction + + if ( checksum_computed != checksum_received ) { + status |= SLAVE_DATA_CORRUPT; + } else { + status &= ~SLAVE_DATA_CORRUPT; + } +} + +inline +bool serial_slave_DATA_CORRUPT(void) { + return status & SLAVE_DATA_CORRUPT; +} + +// Copies the serial_slave_buffer to the master and sends the +// serial_master_buffer to the slave. +// +// Returns: +// 0 => no error +// 1 => slave did not respond +int serial_update_buffers(void) { + // this code is very time dependent, so we need to disable interrupts + cli(); + + // signal to the slave that we want to start a transaction + serial_output(); + serial_low(); + _delay_us(1); + + // wait for the slaves response + serial_input(); + serial_high(); + _delay_us(SERIAL_DELAY); + + // check if the slave is present + if (serial_read_pin()) { + // slave failed to pull the line low, assume not present + sei(); + return 1; + } + + // if the slave is present syncronize with it + sync_recv(); + + uint8_t checksum_computed = 0; + // receive data from the slave + for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) { + serial_slave_buffer[i] = serial_read_byte(); + sync_recv(); + checksum_computed += serial_slave_buffer[i]; + } + uint8_t checksum_received = serial_read_byte(); + sync_recv(); + + if (checksum_computed != checksum_received) { + sei(); + return 1; + } + + uint8_t checksum = 0; + // send data to the slave + for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) { + serial_write_byte(serial_master_buffer[i]); + sync_recv(); + checksum += serial_master_buffer[i]; + } + serial_write_byte(checksum); + sync_recv(); + + // always, release the line when not in use + serial_output(); + serial_high(); + + sei(); + return 0; +} diff --git a/keyboards/lets_split/serial.h b/keyboards/lets_split/serial.h new file mode 100644 index 0000000000..15fe4db7b4 --- /dev/null +++ b/keyboards/lets_split/serial.h @@ -0,0 +1,26 @@ +#ifndef MY_SERIAL_H +#define MY_SERIAL_H + +#include "config.h" +#include + +/* TODO: some defines for interrupt setup */ +#define SERIAL_PIN_DDR DDRD +#define SERIAL_PIN_PORT PORTD +#define SERIAL_PIN_INPUT PIND +#define SERIAL_PIN_MASK _BV(PD0) +#define SERIAL_PIN_INTERRUPT INT0_vect + +#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 +#define SERIAL_MASTER_BUFFER_LENGTH 1 + +// Buffers for master - slave communication +extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH]; +extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH]; + +void serial_master_init(void); +void serial_slave_init(void); +int serial_update_buffers(void); +bool serial_slave_data_corrupt(void); + +#endif diff --git a/keyboards/lets_split/split_util.c b/keyboards/lets_split/split_util.c index c394596e0c..65003a71a4 100644 --- a/keyboards/lets_split/split_util.c +++ b/keyboards/lets_split/split_util.c @@ -7,13 +7,22 @@ #include "split_util.h" #include "matrix.h" #include "i2c.h" +#include "serial.h" #include "keyboard.h" #include "config.h" volatile bool isLeftHand = true; static void setup_handedness(void) { + #ifdef EE_HANDS isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS); + #else + #ifdef I2C_MASTER_RIGHT + isLeftHand = !has_usb(); + #else + isLeftHand = has_usb(); + #endif + #endif } static void keyboard_master_setup(void) { diff --git a/keyboards/lets_split/split_util.h b/keyboards/lets_split/split_util.h index cf6890d37f..6b896679ca 100644 --- a/keyboards/lets_split/split_util.h +++ b/keyboards/lets_split/split_util.h @@ -3,8 +3,10 @@ #include -#define EECONFIG_BOOTMAGIC_END (uint8_t *)10 -#define EECONFIG_HANDEDNESS EECONFIG_BOOTMAGIC_END +#ifdef EE_HANDS + #define EECONFIG_BOOTMAGIC_END (uint8_t *)10 + #define EECONFIG_HANDEDNESS EECONFIG_BOOTMAGIC_END +#endif #define SLAVE_I2C_ADDRESS 0x32 diff --git a/keyboards/lets_split/uno-slave/Makefile b/keyboards/lets_split/uno_slave/Makefile similarity index 100% rename from keyboards/lets_split/uno-slave/Makefile rename to keyboards/lets_split/uno_slave/Makefile diff --git a/keyboards/lets_split/uno-slave/keyboard-i2c-slave.c b/keyboards/lets_split/uno_slave/keyboard-i2c-slave.c similarity index 100% rename from keyboards/lets_split/uno-slave/keyboard-i2c-slave.c rename to keyboards/lets_split/uno_slave/keyboard-i2c-slave.c diff --git a/keyboards/lets_split/uno-slave/readme.md b/keyboards/lets_split/uno_slave/readme.md similarity index 100% rename from keyboards/lets_split/uno-slave/readme.md rename to keyboards/lets_split/uno_slave/readme.md diff --git a/keyboards/lets_split/uno-slave/uno-matrix.c b/keyboards/lets_split/uno_slave/uno-matrix.c similarity index 100% rename from keyboards/lets_split/uno-slave/uno-matrix.c rename to keyboards/lets_split/uno_slave/uno-matrix.c diff --git a/keyboards/lets_split/uno-slave/uno-matrix.h b/keyboards/lets_split/uno_slave/uno-matrix.h similarity index 100% rename from keyboards/lets_split/uno-slave/uno-matrix.h rename to keyboards/lets_split/uno_slave/uno-matrix.h