Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Add Iris keyboard (#1863)
* Clone Nyquist code to Iris and rename * Set keymap and pins * Work in progress Iris default keymap * Add Iris rev2 * Update Iris files to new build system * Add lewisridden keymap
- Loading branch information
Showing
with
2,149 additions
and 0 deletions.
- +23 −0 keyboards/iris/config.h
- +162 −0 keyboards/iris/i2c.c
- +49 −0 keyboards/iris/i2c.h
- +1 −0 keyboards/iris/iris.c
- +28 −0 keyboards/iris/iris.h
- +41 −0 keyboards/iris/keymaps/default/config.h
- +137 −0 keyboards/iris/keymaps/default/keymap.c
- +6 −0 keyboards/iris/keymaps/default/rules.mk
- +43 −0 keyboards/iris/keymaps/hexwire/config.h
- +143 −0 keyboards/iris/keymaps/hexwire/keymap.c
- +6 −0 keyboards/iris/keymaps/hexwire/rules.mk
- +41 −0 keyboards/iris/keymaps/lewisridden/config.h
- +137 −0 keyboards/iris/keymaps/lewisridden/keymap.c
- +6 −0 keyboards/iris/keymaps/lewisridden/rules.mk
- +477 −0 keyboards/iris/matrix.c
- +20 −0 keyboards/iris/readme.md
- +92 −0 keyboards/iris/rev1/config.h
- +39 −0 keyboards/iris/rev1/rev1.c
- +40 −0 keyboards/iris/rev1/rev1.h
- +1 −0 keyboards/iris/rev1/rules.mk
- +92 −0 keyboards/iris/rev2/config.h
- +39 −0 keyboards/iris/rev2/rev2.c
- +40 −0 keyboards/iris/rev2/rev2.h
- +2 −0 keyboards/iris/rev2/rules.mk
- +77 −0 keyboards/iris/rules.mk
- +228 −0 keyboards/iris/serial.c
- +26 −0 keyboards/iris/serial.h
- +41 −0 keyboards/iris/split_rgb.c
- +6 −0 keyboards/iris/split_rgb.h
- +86 −0 keyboards/iris/split_util.c
- +20 −0 keyboards/iris/split_util.h
@@ -0,0 +1,23 @@ | ||
/* | ||
Copyright 2017 Danny Nguyen <danny@hexwire.com> | ||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 2 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#ifndef CONFIG_H | ||
#define CONFIG_H | ||
|
||
#include "config_common.h" | ||
|
||
#endif // CONFIG_H |
@@ -0,0 +1,162 @@ | ||
#include <util/twi.h> | ||
#include <avr/io.h> | ||
#include <stdlib.h> | ||
#include <avr/interrupt.h> | ||
#include <util/twi.h> | ||
#include <stdbool.h> | ||
#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. | ||
// | ||
// (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<<TWINT)) && lim < I2C_LOOP_TIMEOUT) | ||
lim++; | ||
|
||
// easier way, but will wait slightly longer | ||
// _delay_us(100); | ||
} | ||
|
||
// Setup twi to run at 100kHz | ||
void i2c_master_init(void) { | ||
// no prescaler | ||
TWSR = 0; | ||
// Set TWI clock frequency to SCL_CLOCK. Need TWBR>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<<TWINT) | (1<<TWEN) | (1<<TWSTA); | ||
|
||
i2c_delay(); | ||
|
||
// check that we started successfully | ||
if ( (TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START)) | ||
return 1; | ||
|
||
TWDR = address; | ||
TWCR = (1<<TWINT) | (1<<TWEN); | ||
|
||
i2c_delay(); | ||
|
||
if ( (TW_STATUS != TW_MT_SLA_ACK) && (TW_STATUS != TW_MR_SLA_ACK) ) | ||
return 1; // slave did not acknowledge | ||
else | ||
return 0; // success | ||
} | ||
|
||
|
||
// Finish the i2c transaction. | ||
void i2c_master_stop(void) { | ||
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); | ||
|
||
uint16_t lim = 0; | ||
while(!(TWCR & (1<<TWSTO)) && lim < I2C_LOOP_TIMEOUT) | ||
lim++; | ||
} | ||
|
||
// Write one byte to the i2c slave. | ||
// returns 0 => slave ACK | ||
// 1 => slave NACK | ||
uint8_t i2c_master_write(uint8_t data) { | ||
TWDR = data; | ||
TWCR = (1<<TWINT) | (1<<TWEN); | ||
|
||
i2c_delay(); | ||
|
||
// check if the slave acknowledged us | ||
return (TW_STATUS == TW_MT_DATA_ACK) ? 0 : 1; | ||
} | ||
|
||
// Read one byte from the i2c slave. If ack=1 the slave is acknowledged, | ||
// if ack=0 the acknowledge bit is not set. | ||
// returns: byte read from i2c device | ||
uint8_t i2c_master_read(int ack) { | ||
TWCR = (1<<TWINT) | (1<<TWEN) | (ack<<TWEA); | ||
|
||
i2c_delay(); | ||
return TWDR; | ||
} | ||
|
||
void i2c_reset_state(void) { | ||
TWCR = 0; | ||
} | ||
|
||
void i2c_slave_init(uint8_t address) { | ||
TWAR = address << 0; // slave i2c address | ||
// TWEN - twi enable | ||
// TWEA - enable address acknowledgement | ||
// TWINT - twi interrupt flag | ||
// TWIE - enable the twi interrupt | ||
TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN); | ||
} | ||
|
||
ISR(TWI_vect); | ||
|
||
ISR(TWI_vect) { | ||
uint8_t ack = 1; | ||
switch(TW_STATUS) { | ||
case TW_SR_SLA_ACK: | ||
// this device has been addressed as a slave receiver | ||
slave_has_register_set = false; | ||
break; | ||
|
||
case TW_SR_DATA_ACK: | ||
// this device has received data as a slave receiver | ||
// The first byte that we receive in this transaction sets the location | ||
// of the read/write location of the slaves memory that it exposes over | ||
// i2c. After that, bytes will be written at slave_buffer_pos, incrementing | ||
// slave_buffer_pos after each write. | ||
if(!slave_has_register_set) { | ||
slave_buffer_pos = TWDR; | ||
// don't acknowledge the master if this memory loctaion is out of bounds | ||
if ( slave_buffer_pos >= 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<<TWIE) | (1<<TWINT) | (ack<<TWEA) | (1<<TWEN); | ||
} | ||
#endif |
@@ -0,0 +1,49 @@ | ||
#ifndef I2C_H | ||
#define I2C_H | ||
|
||
#include <stdint.h> | ||
|
||
#ifndef F_CPU | ||
#define F_CPU 16000000UL | ||
#endif | ||
|
||
#define I2C_READ 1 | ||
#define I2C_WRITE 0 | ||
|
||
#define I2C_ACK 1 | ||
#define I2C_NACK 0 | ||
|
||
#define SLAVE_BUFFER_SIZE 0x10 | ||
|
||
// i2c SCL clock frequency | ||
#define SCL_CLOCK 100000L | ||
|
||
extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; | ||
|
||
void i2c_master_init(void); | ||
uint8_t i2c_master_start(uint8_t address); | ||
void i2c_master_stop(void); | ||
uint8_t i2c_master_write(uint8_t data); | ||
uint8_t i2c_master_read(int); | ||
void i2c_reset_state(void); | ||
void i2c_slave_init(uint8_t address); | ||
|
||
|
||
static inline unsigned char i2c_start_read(unsigned char addr) { | ||
return i2c_master_start((addr << 1) | I2C_READ); | ||
} | ||
|
||
static inline unsigned char i2c_start_write(unsigned char addr) { | ||
return i2c_master_start((addr << 1) | I2C_WRITE); | ||
} | ||
|
||
// from SSD1306 scrips | ||
extern unsigned char i2c_rep_start(unsigned char addr); | ||
extern void i2c_start_wait(unsigned char addr); | ||
extern unsigned char i2c_readAck(void); | ||
extern unsigned char i2c_readNak(void); | ||
extern unsigned char i2c_read(unsigned char ack); | ||
|
||
#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak(); | ||
|
||
#endif |
@@ -0,0 +1 @@ | ||
#include "iris.h" |
@@ -0,0 +1,28 @@ | ||
#ifndef IRIS_H | ||
#define IRIS_H | ||
|
||
#ifdef KEYBOARD_iris_rev1 | ||
#include "rev1.h" | ||
#else | ||
#include "rev2.h" | ||
#endif | ||
|
||
#include "quantum.h" | ||
|
||
// Used to create a keymap using only KC_ prefixed keys | ||
#define KC_KEYMAP( \ | ||
L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \ | ||
L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \ | ||
L20, L21, L22, L23, L24, L25, R20, R21, R22, R23, R24, R25, \ | ||
L30, L31, L32, L33, L34, L35, LT4, RT4, R30, R31, R32, R33, R34, R35, \ | ||
LT1, LT2, LT3, RT3, RT2, RT1 \ | ||
) \ | ||
KEYMAP( \ | ||
KC_##L00, KC_##L01, KC_##L02, KC_##L03, KC_##L04, KC_##L05, KC_##R00, KC_##R01, KC_##R02, KC_##R03, KC_##R04, KC_##R05, \ | ||
KC_##L10, KC_##L11, KC_##L12, KC_##L13, KC_##L14, KC_##L15, KC_##R10, KC_##R11, KC_##R12, KC_##R13, KC_##R14, KC_##R15, \ | ||
KC_##L20, KC_##L21, KC_##L22, KC_##L23, KC_##L24, KC_##L25, KC_##R20, KC_##R21, KC_##R22, KC_##R23, KC_##R24, KC_##R25, \ | ||
KC_##L30, KC_##L31, KC_##L32, KC_##L33, KC_##L34, KC_##L35, KC_##LT4, KC_##RT4, KC_##R30, KC_##R31, KC_##R32, KC_##R33, KC_##R34, KC_##R35, \ | ||
KC_##LT1, KC_##LT2, KC_##LT3, KC_##RT3, KC_##RT2, KC_##RT1 \ | ||
) | ||
|
||
#endif |
@@ -0,0 +1,41 @@ | ||
/* | ||
Copyright 2017 Danny Nguyen <danny@hexwire.com> | ||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 2 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#ifndef CONFIG_USER_H | ||
#define CONFIG_USER_H | ||
|
||
#include "config_common.h" | ||
|
||
/* Use I2C or Serial, not both */ | ||
|
||
#define USE_SERIAL | ||
// #define USE_I2C | ||
|
||
/* Select hand configuration */ | ||
|
||
#define MASTER_LEFT | ||
// #define _MASTER_RIGHT | ||
// #define EE_HANDS | ||
|
||
#undef RGBLED_NUM | ||
#define RGBLIGHT_ANIMATIONS | ||
#define RGBLED_NUM 12 | ||
#define RGBLIGHT_HUE_STEP 8 | ||
#define RGBLIGHT_SAT_STEP 8 | ||
#define RGBLIGHT_VAL_STEP 8 | ||
|
||
#endif |
Oops, something went wrong.