Add corne keyboard (#3119) * Fork from helix * Move rev2 to rev1 * Remove unused settings * Move split_util to outof rev * Setup KEYMAP for crkbd * Remove old image * Move keymaps directory and glcdfont.c * Remove AUDIO in keymap * Show keylog * Show keylogs * Show time log * Remove EISU/KANA * Use KEYMAP_kc * Remove iota_gfx_record_user wrapping * Remove unused settings for layer * Add keylogger.c * Fix uppercase letters to lower * Add timelogger.c * Default RGBLED_NUM = 27 * Remove unused setting * Add mode icon reader * Add matrix_write_ln * Add layer_state_reader * Move to lib directory * Rename functions * Add host_led_state_reader * Add logo_reader * Cleaning of iota_gfx_task * Fix bugs and add key defines * Remove unnecessary comments * Update crkbd readme * Move libs to lib directories * Rename KEYMAP to LAYOUT
29 files changed, 2710 insertions(+), 0 deletions(-) A keyboards/crkbd/config.h A keyboards/crkbd/crkbd.c A keyboards/crkbd/crkbd.h A keyboards/crkbd/i2c.c A keyboards/crkbd/i2c.h A keyboards/crkbd/keymaps/default/config.h A keyboards/crkbd/keymaps/default/glcdfont.c A keyboards/crkbd/keymaps/default/keymap.c A keyboards/crkbd/keymaps/default/rules.mk A keyboards/crkbd/keymaps/lib/host_led_state_reader.c A keyboards/crkbd/keymaps/lib/keylogger.c A keyboards/crkbd/keymaps/lib/layer_state_reader.c A keyboards/crkbd/keymaps/lib/logo_reader.c A keyboards/crkbd/keymaps/lib/mode_icon_reader.c A keyboards/crkbd/keymaps/lib/timelogger.c A keyboards/crkbd/pro_micro.h A keyboards/crkbd/readme.md A keyboards/crkbd/rev1/config.h A keyboards/crkbd/rev1/matrix.c A keyboards/crkbd/rev1/rev1.c A keyboards/crkbd/rev1/rev1.h A keyboards/crkbd/rev1/rules.mk A keyboards/crkbd/rules.mk A keyboards/crkbd/serial.c A keyboards/crkbd/serial.h A keyboards/crkbd/split_util.c A keyboards/crkbd/split_util.h A keyboards/crkbd/ssd1306.c A keyboards/crkbd/ssd1306.h
A keyboards/crkbd/config.h => keyboards/crkbd/config.h +24 -0
@@ 0,0 1,24 @@ /* Copyright 2012 Jun Wako <wakojun@gmail.com> Copyright 2015 Jack Humbert 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
A keyboards/crkbd/crkbd.c => keyboards/crkbd/crkbd.c +1 -0
A keyboards/crkbd/crkbd.h => keyboards/crkbd/crkbd.h +8 -0
@@ 0,0 1,8 @@ #ifndef CRKBD_H #define CRKBD_H #ifdef KEYBOARD_crkbd_rev1 #include "rev1.h" #endif #endif
A keyboards/crkbd/i2c.c => keyboards/crkbd/i2c.c +162 -0
@@ 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
A keyboards/crkbd/i2c.h => keyboards/crkbd/i2c.h +49 -0
@@ 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 400000L 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
A keyboards/crkbd/keymaps/default/config.h => keyboards/crkbd/keymaps/default/config.h +53 -0
@@ 0,0 1,53 @@ /* This is the c configuration file for the keymap Copyright 2012 Jun Wako <wakojun@gmail.com> Copyright 2015 Jack Humbert 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.h" /* Use I2C or Serial */ #define USE_I2C #define USE_SERIAL //#define USE_MATRIX_I2C /* Select hand configuration */ #define MASTER_LEFT // #define MASTER_RIGHT // #define EE_HANDS #define SSD1306OLED #define USE_SERIAL_PD2 #define PREVENT_STUCK_MODIFIERS #define TAPPING_FORCE_HOLD #define TAPPING_TERM 100 #undef RGBLED_NUM #define RGBLIGHT_ANIMATIONS #define RGBLED_NUM 27 #define RGBLIGHT_LIMIT_VAL 120 #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 #define RGBLIGHT_VAL_STEP 17 #endif
A keyboards/crkbd/keymaps/default/glcdfont.c => keyboards/crkbd/keymaps/default/glcdfont.c +244 -0
@@ 0,0 1,244 @@ // This is the 'classic' fixed-space bitmap font for Adafruit_GFX since 1.0. // See gfxfont.h for newer custom bitmap font info. #ifndef FONT5X7_H #define FONT5X7_H #ifdef __AVR__ #include <avr/io.h> #include <avr/pgmspace.h> #elif defined(ESP8266) #include <pgmspace.h> #else #define PROGMEM #endif // Standard ASCII 5x7 font static const unsigned char font[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00, 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00, 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00, 0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x00, 0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00, 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00, 0x00, 0x18, 0x3C, 0x18, 0x00, 0x00, 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00, 0x00, 0x18, 0x24, 0x18, 0x00, 0x00, 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00, 0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00, 0x26, 0x29, 0x79, 0x29, 0x26, 0x00, 0x40, 0x7F, 0x05, 0x05, 0x07, 0x00, 0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00, 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x00, 0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00, 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00, 0x14, 0x22, 0x7F, 0x22, 0x14, 0x00, 0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00, 0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00, 0x00, 0x66, 0x89, 0x95, 0x6A, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00, 0x08, 0x04, 0x7E, 0x04, 0x08, 0x00, 0x10, 0x20, 0x7E, 0x20, 0x10, 0x00, 0x08, 0x08, 0x2A, 0x1C, 0x08, 0x00, 0x08, 0x1C, 0x2A, 0x08, 0x08, 0x00, 0x1E, 0x10, 0x10, 0x10, 0x10, 0x00, 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x00, 0x30, 0x38, 0x3E, 0x38, 0x30, 0x00, 0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00, 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00, 0x23, 0x13, 0x08, 0x64, 0x62, 0x00, 0x36, 0x49, 0x56, 0x20, 0x50, 0x00, 0x00, 0x08, 0x07, 0x03, 0x00, 0x00, 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00, 0x00, 0x41, 0x22, 0x1C, 0x00, 0x00, 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x00, 0x80, 0x70, 0x30, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00, 0x72, 0x49, 0x49, 0x49, 0x46, 0x00, 0x21, 0x41, 0x49, 0x4D, 0x33, 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00, 0x27, 0x45, 0x45, 0x45, 0x39, 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00, 0x41, 0x21, 0x11, 0x09, 0x07, 0x00, 0x36, 0x49, 0x49, 0x49, 0x36, 0x00, 0x46, 0x49, 0x49, 0x29, 0x1E, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x40, 0x34, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x22, 0x41, 0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x00, 0x41, 0x22, 0x14, 0x08, 0x00, 0x02, 0x01, 0x59, 0x09, 0x06, 0x00, 0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00, 0x3E, 0x41, 0x41, 0x51, 0x73, 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00, 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00, 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00, 0x26, 0x49, 0x49, 0x49, 0x32, 0x00, 0x03, 0x01, 0x7F, 0x01, 0x03, 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00, 0x63, 0x14, 0x08, 0x14, 0x63, 0x00, 0x03, 0x04, 0x78, 0x04, 0x03, 0x00, 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00, 0x00, 0x7F, 0x41, 0x41, 0x41, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x41, 0x41, 0x41, 0x7F, 0x00, 0x04, 0x02, 0x01, 0x02, 0x04, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x03, 0x07, 0x08, 0x00, 0x00, 0x20, 0x54, 0x54, 0x78, 0x40, 0x00, 0x7F, 0x28, 0x44, 0x44, 0x38, 0x00, 0x38, 0x44, 0x44, 0x44, 0x28, 0x00, 0x38, 0x44, 0x44, 0x28, 0x7F, 0x00, 0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x00, 0x08, 0x7E, 0x09, 0x02, 0x00, 0x18, 0xA4, 0xA4, 0x9C, 0x78, 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00, 0x00, 0x20, 0x40, 0x40, 0x3D, 0x00, 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00, 0x7C, 0x04, 0x78, 0x04, 0x78, 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0xFC, 0x18, 0x24, 0x24, 0x18, 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC, 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08, 0x00, 0x48, 0x54, 0x54, 0x54, 0x24, 0x00, 0x04, 0x04, 0x3F, 0x44, 0x24, 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, 0x00, 0x08, 0x36, 0x41, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x41, 0x36, 0x08, 0x00, 0x00, 0x02, 0x01, 0x02, 0x04, 0x02, 0x00, 0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xBE, 0x7F, 0xFF, 0xFF, 0xFE, 0xFE, 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x0E, 0xEF, 0xDF, 0xDE, 0xBE, 0x3C, 0x38, 0x70, 0xE0, 0xDD, 0xBB, 0x7B, 0x07, 0x0E, 0x0E, 0x0C, 0x98, 0xF0, 0xE0, 0xF0, 0xF0, 0xF8, 0x78, 0x3C, 0x1C, 0x1E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, 0x1F, 0xFE, 0xFE, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xF0, 0xF0, 0xF0, 0xE0, 0xEC, 0xEE, 0xF7, 0xF3, 0x70, 0x20, 0x00, 0x7C, 0x7C, 0x7C, 0x7E, 0x00, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7F, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x7E, 0x5B, 0x4F, 0x5B, 0xFE, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0xDC, 0xD7, 0xDE, 0xDE, 0xDE, 0xD7, 0xDC, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x0F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x7F, 0xFF, 0xFE, 0xFD, 0xFB, 0x1B, 0x07, 0x07, 0x0F, 0x1F, 0x1F, 0x1E, 0x1D, 0x0B, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xF8, 0xFE, 0xFF, 0xFF, 0x1F, 0x07, 0x01, 0x01, 0x01, 0x03, 0x06, 0x06, 0x0C, 0x0C, 0x08, 0x0C, 0x0C, 0x0E, 0x07, 0x83, 0xC1, 0xE0, 0x70, 0x30, 0x18, 0x1C, 0x7C, 0xCC, 0x8C, 0xDC, 0xF8, 0xC0, 0xE0, 0xE0, 0x70, 0xB8, 0xF0, 0x60, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0x70, 0xF8, 0xFC, 0xFC, 0x3C, 0x30, 0x38, 0xF8, 0xF8, 0xF8, 0x78, 0x00, 0x80, 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x38, 0x9C, 0xDC, 0xFC, 0x7C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x3F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x3F, 0x1E, 0x0C, 0x00, 0x1F, 0x1F, 0x1F, 0x3F, 0x00, 0x3F, 0x3F, 0x3F, 0x7F, 0x7F, 0x7F, 0x00, 0x30, 0x7B, 0x7F, 0x78, 0x30, 0x20, 0x20, 0x30, 0x78, 0x7F, 0x3B, 0x00, 0x03, 0x00, 0x0F, 0x7F, 0x0F, 0x0F, 0x0F, 0x7F, 0x0F, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x1F, 0x3F, 0x3F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7D, 0x3B, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0F, 0x1F, 0x3F, 0x3F, 0x7E, 0x7C, 0x78, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x78, 0x38, 0x18, 0x1C, 0x0E, 0x07, 0x0F, 0x1F, 0x3F, 0x3C, 0x38, 0x38, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x01, 0x01, 0x01, 0x0E, 0x1F, 0x1F, 0x1C, 0x1C, 0x1E, 0x0F, 0x0F, 0x03, 0x1D, 0x0E, 0x07, 0x03, 0x01, 0x00, 0x00, 0x0E, 0x1F, 0x1F, 0x1D, 0x1E, 0x0F, 0x07, 0x03, 0x03, 0x0F, 0x1F, 0x1F, 0x19, 0x19, 0x19, 0x19, 0x0C, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; #endif // FONT5X7_H
A keyboards/crkbd/keymaps/default/keymap.c => keyboards/crkbd/keymaps/default/keymap.c +246 -0
@@ 0,0 1,246 @@ #include "crkbd.h" #include "bootloader.h" #include "action_layer.h" #include "action_util.h" #include "eeconfig.h" #ifdef PROTOCOL_LUFA #include "lufa.h" #include "split_util.h" #endif #include "LUFA/Drivers/Peripheral/TWI.h" #ifdef SSD1306OLED #include "ssd1306.h" #endif #include "../lib/mode_icon_reader.c" #include "../lib/layer_state_reader.c" #include "../lib/host_led_state_reader.c" #include "../lib/logo_reader.c" #include "../lib/keylogger.c" #include "../lib/timelogger.c" extern keymap_config_t keymap_config; #ifdef RGBLIGHT_ENABLE //Following line allows macro to read current RGB settings extern rgblight_config_t rgblight_config; #endif extern uint8_t is_master; // Each layer gets a name for readability, which is then used in the keymap matrix below. // The underscores don't mean anything - you can have a layer called STUFF or any other name. // Layer names don't all need to be of the same length, obviously, and you can also skip them // entirely and just use numbers. #define _QWERTY 0 #define _LOWER 3 #define _RAISE 4 #define _ADJUST 16 enum custom_keycodes { QWERTY = SAFE_RANGE, LOWER, RAISE, ADJUST, BACKLIT, RGBRST }; enum macro_keycodes { KC_SAMPLEMACRO, }; #define KC______ KC_TRNS #define KC_XXXXX KC_NO #define KC_LOWER LOWER #define KC_RAISE RAISE #define KC_RST RESET #define KC_LRST RGBRST #define KC_LTOG RGB_TOG #define KC_LHUI RGB_HUI #define KC_LHUD RGB_HUD #define KC_LSAI RGB_SAI #define KC_LSAD RGB_SAD #define KC_LVAI RGB_VAI #define KC_LVAD RGB_VAD #define KC_LSMOD RGB_SMOD #define KC_CTLTB CTL_T(KC_TAB) #define KC_GUIEI GUI_T(KC_LANG2) #define KC_ALTKN ALT_T(KC_LANG1) const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_QWERTY] = LAYOUT_kc( \ //,-----------------------------------------. ,-----------------------------------------. ESC, Q, W, E, R, T, Y, U, I, O, P, BSPC,\ //|------+------+------+------+------+------| |------+------+------+------+------+------| CTLTB, A, S, D, F, G, H, J, K, L, SCLN, QUOT,\ //|------+------+------+------+------+------| |------+------+------+------+------+------| LSFT, Z, X, C, V, B, N, M, COMM, DOT, SLSH, RSFT,\ //|------+------+------+------+------+------+------| |------+------+------+------+------+------+------| GUIEI, LOWER, SPC, ENT, RAISE, ALTKN \ //`--------------------' `--------------------' ), [_LOWER] = LAYOUT_kc( \ //,-----------------------------------------. ,-----------------------------------------. ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, BSPC,\ //|------+------+------+------+------+------| |------+------+------+------+------+------| CTLTB, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, XXXXX,\ //|------+------+------+------+------+------| |------+------+------+------+------+------| LSFT, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, XXXXX,\ //|------+------+------+------+------+------+------| |------+------+------+------+------+------+------| GUIEI, LOWER, SPC, ENT, RAISE, ALTKN \ //`--------------------' `--------------------' ), [_RAISE] = LAYOUT_kc( \ //,-----------------------------------------. ,-----------------------------------------. ESC, EXLM, AT, HASH, DLR, PERC, CIRC, AMPR, ASTR, LPRN, RPRN, BSPC,\ //|------+------+------+------+------+------| |------+------+------+------+------+------| CTLTB, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, MINS, EQL, LCBR, RCBR, PIPE, GRV,\ //|------+------+------+------+------+------| |------+------+------+------+------+------| LSFT, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, UNDS, PLUS, LBRC, RBRC, BSLS, TILD,\ //|------+------+------+------+------+------+------| |------+------+------+------+------+------+------| GUIEI, LOWER, SPC, ENT, RAISE, ALTKN \ //`--------------------' `--------------------' ), [_ADJUST] = LAYOUT_kc( \ //,-----------------------------------------. ,-----------------------------------------. RST, LRST, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX,\ //|------+------+------+------+------+------| |------+------+------+------+------+------| LTOG, LHUI, LSAI, LVAI, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX,\ //|------+------+------+------+------+------| |------+------+------+------+------+------| LSMOD, LHUD, LSAD, LVAD, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX,\ //|------+------+------+------+------+------+------| |------+------+------+------+------+------+------| GUIEI, LOWER, SPC, ENT, RAISE, ALTKN \ //`--------------------' `--------------------' ) }; int RGB_current_mode; void persistent_default_layer_set(uint16_t default_layer) { eeconfig_update_default_layer(default_layer); default_layer_set(default_layer); } // Setting ADJUST layer RGB back to default void update_tri_layer_RGB(uint8_t layer1, uint8_t layer2, uint8_t layer3) { if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) { layer_on(layer3); } else { layer_off(layer3); } } void matrix_init_user(void) { #ifdef RGBLIGHT_ENABLE RGB_current_mode = rgblight_config.mode; #endif //SSD1306 OLED init, make sure to add #define SSD1306OLED in config.h #ifdef SSD1306OLED TWI_Init(TWI_BIT_PRESCALE_1, TWI_BITLENGTH_FROM_FREQ(1, 800000)); iota_gfx_init(!has_usb()); // turns on the display #endif } //SSD1306 OLED update loop, make sure to add #define SSD1306OLED in config.h #ifdef SSD1306OLED void matrix_scan_user(void) { iota_gfx_task(); } void matrix_render_user(struct CharacterMatrix *matrix) { if (is_master) { matrix_write_ln(matrix, read_layer_state()); matrix_write_ln(matrix, read_keylog()); matrix_write_ln(matrix, read_keylogs()); //matrix_write_ln(matrix, read_mode_icon(keymap_config.swap_lalt_lgui)); //matrix_write_ln(matrix, read_host_led_state()); //matrix_write_ln(matrix, read_timelog()); } else { matrix_write(matrix, read_logo()); } } void matrix_update(struct CharacterMatrix *dest, const struct CharacterMatrix *source) { if (memcmp(dest->display, source->display, sizeof(dest->display))) { memcpy(dest->display, source->display, sizeof(dest->display)); dest->dirty = true; } } void iota_gfx_task_user(void) { struct CharacterMatrix matrix; matrix_clear(&matrix); matrix_render_user(&matrix); matrix_update(&display, &matrix); } bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (record->event.pressed) { set_keylog(keycode, record); set_timelog(); } switch (keycode) { case QWERTY: if (record->event.pressed) { persistent_default_layer_set(1UL<<_QWERTY); } return false; break; case LOWER: if (record->event.pressed) { layer_on(_LOWER); update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST); } else { layer_off(_LOWER); update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST); } return false; break; case RAISE: if (record->event.pressed) { layer_on(_RAISE); update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST); } else { layer_off(_RAISE); update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST); } return false; break; case ADJUST: if (record->event.pressed) { layer_on(_ADJUST); } else { layer_off(_ADJUST); } return false; break; case RGB_MOD: #ifdef RGBLIGHT_ENABLE if (record->event.pressed) { rgblight_mode(RGB_current_mode); rgblight_step(); RGB_current_mode = rgblight_config.mode; } #endif return false; break; case RGBRST: #ifdef RGBLIGHT_ENABLE if (record->event.pressed) { eeconfig_update_rgblight_default(); rgblight_enable(); RGB_current_mode = rgblight_config.mode; } #endif break; } return true; } #endif
A keyboards/crkbd/keymaps/default/rules.mk => keyboards/crkbd/keymaps/default/rules.mk +25 -0
@@ 0,0 1,25 @@ # Build Options # 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) MOUSEKEY_ENABLE = no # Mouse keys(+4700) EXTRAKEY_ENABLE = no # Audio control and System control(+450) CONSOLE_ENABLE = no # Console for debug(+400) COMMAND_ENABLE = no # Commands for debug and configuration NKRO_ENABLE = no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality MIDI_ENABLE = no # MIDI controls AUDIO_ENABLE = no # Audio output on port C6 UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight. Do not enable this with audio at the same time. ONEHAND_ENABLE = no # Enable one-hand typing # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend ifndef QUANTUM_DIR include ../../../../Makefile endif
A keyboards/crkbd/keymaps/lib/host_led_state_reader.c => keyboards/crkbd/keymaps/lib/host_led_state_reader.c +13 -0
@@ 0,0 1,13 @@ #include "crkbd.h" char host_led_state[40]; char *read_host_led_state(void) { snprintf(host_led_state, sizeof(host_led_state), "\n%s %s %s", (host_keyboard_leds() & (1 << USB_LED_NUM_LOCK)) ? "NUMLOCK" : " ", (host_keyboard_leds() & (1 << USB_LED_CAPS_LOCK)) ? "CAPS" : " ", (host_keyboard_leds() & (1 << USB_LED_SCROLL_LOCK)) ? "SCLK" : " "); return host_led_state; }
A keyboards/crkbd/keymaps/lib/keylogger.c => keyboards/crkbd/keymaps/lib/keylogger.c +49 -0
@@ 0,0 1,49 @@ #include "crkbd.h" char keylog[40] = {}; char keylogs[21] = {}; int keylogs_idx = 0; char code_to_name[60] = { ' ', ' ', ' ', ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'R', 'E', 'B', 'T', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ';', '\'', ' ', ',', '.', '/', ' ', ' ', ' '}; void set_keylog(uint16_t keycode, keyrecord_t *record) { char name = ' '; if (keycode < 60) { name = code_to_name[keycode]; } // update keylog snprintf(keylog, sizeof(keylog), "%dx%d, k%2d : %c", record->event.key.row, record->event.key.col, keycode, name); // update keylogs if (keylogs_idx == sizeof(keylogs) - 1) { keylogs_idx = 0; for (int i = 0; i < sizeof(keylogs) - 1; i++) { keylogs[i] = ' '; } } keylogs[keylogs_idx] = name; keylogs_idx++; } char *read_keylog(void) { return keylog; } char *read_keylogs(void) { return keylogs; }
A keyboards/crkbd/keymaps/lib/layer_state_reader.c => keyboards/crkbd/keymaps/lib/layer_state_reader.c +33 -0
@@ 0,0 1,33 @@ #include "crkbd.h" #define L_BASE 0 #define L_LOWER 8 #define L_RAISE 16 #define L_ADJUST 65536 #define L_ADJUST_TRI 65560 char layer_state_str[40]; char *read_layer_state(void) { switch (layer_state) { case L_BASE: snprintf(layer_state_str, sizeof(layer_state_str), "Layer: Default"); break; case L_RAISE: snprintf(layer_state_str, sizeof(layer_state_str), "Layer: Raise"); break; case L_LOWER: snprintf(layer_state_str, sizeof(layer_state_str), "Layer: Lower"); break; case L_ADJUST: case L_ADJUST_TRI: snprintf(layer_state_str, sizeof(layer_state_str), "Layer: Adjust"); break; default: snprintf(layer_state_str,sizeof(layer_state_str), "Layer: Undef-%ld", layer_state); } return layer_state_str; }
A keyboards/crkbd/keymaps/lib/logo_reader.c => keyboards/crkbd/keymaps/lib/logo_reader.c +12 -0
@@ 0,0 1,12 @@ #include "crkbd.h" char *read_logo(void) { static char logo[]={ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94, 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb1,0xb2,0xb3,0xb4, 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4, 0}; return logo; }
A keyboards/crkbd/keymaps/lib/mode_icon_reader.c => keyboards/crkbd/keymaps/lib/mode_icon_reader.c +15 -0
@@ 0,0 1,15 @@ #include "crkbd.h" char mode_icon[40]; char *read_mode_icon(bool swap) { static char logo[][2][3]={{{0x95,0x96,0},{0xb5,0xb6,0}},{{0x97,0x98,0},{0xb7,0xb8,0}}}; if(swap == false){ snprintf(mode_icon, sizeof(mode_icon), "%s\n%s", logo[0][0], logo[0][1]); }else{ snprintf(mode_icon, sizeof(mode_icon), "%s\n%s", logo[1][0], logo[1][1]); } return mode_icon; }
A keyboards/crkbd/keymaps/lib/timelogger.c => keyboards/crkbd/keymaps/lib/timelogger.c +17 -0
@@ 0,0 1,17 @@ #include "crkbd.h" char timelog[40] = {}; int last_time = 0; int elapsed_time = 0; void set_timelog(void) { elapsed_time = timer_elapsed(last_time); last_time = timer_read(); snprintf(timelog, sizeof(timelog), "lt:%5d, et:%5d", last_time, elapsed_time); } char *read_timelog(void) { return timelog; }
A keyboards/crkbd/pro_micro.h => keyboards/crkbd/pro_micro.h +362 -0
@@ 0,0 1,362 @@ /* pins_arduino.h - Pin definition functions for Arduino Part of Arduino - http://www.arduino.cc/ Copyright (c) 2007 David A. Mellis This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $ */ #ifndef Pins_Arduino_h #define Pins_Arduino_h #include <avr/pgmspace.h> // Workaround for wrong definitions in "iom32u4.h". // This should be fixed in the AVR toolchain. #undef UHCON #undef UHINT #undef UHIEN #undef UHADDR #undef UHFNUM #undef UHFNUML #undef UHFNUMH #undef UHFLEN #undef UPINRQX #undef UPINTX #undef UPNUM #undef UPRST #undef UPCONX #undef UPCFG0X #undef UPCFG1X #undef UPSTAX #undef UPCFG2X #undef UPIENX #undef UPDATX #undef TCCR2A #undef WGM20 #undef WGM21 #undef COM2B0 #undef COM2B1 #undef COM2A0 #undef COM2A1 #undef TCCR2B #undef CS20 #undef CS21 #undef CS22 #undef WGM22 #undef FOC2B #undef FOC2A #undef TCNT2 #undef TCNT2_0 #undef TCNT2_1 #undef TCNT2_2 #undef TCNT2_3 #undef TCNT2_4 #undef TCNT2_5 #undef TCNT2_6 #undef TCNT2_7 #undef OCR2A #undef OCR2_0 #undef OCR2_1 #undef OCR2_2 #undef OCR2_3 #undef OCR2_4 #undef OCR2_5 #undef OCR2_6 #undef OCR2_7 #undef OCR2B #undef OCR2_0 #undef OCR2_1 #undef OCR2_2 #undef OCR2_3 #undef OCR2_4 #undef OCR2_5 #undef OCR2_6 #undef OCR2_7 #define NUM_DIGITAL_PINS 30 #define NUM_ANALOG_INPUTS 12 #define TX_RX_LED_INIT DDRD |= (1<<5), DDRB |= (1<<0) #define TXLED0 PORTD |= (1<<5) #define TXLED1 PORTD &= ~(1<<5) #define RXLED0 PORTB |= (1<<0) #define RXLED1 PORTB &= ~(1<<0) static const uint8_t SDA = 2; static const uint8_t SCL = 3; #define LED_BUILTIN 13 // Map SPI port to 'new' pins D14..D17 static const uint8_t SS = 17; static const uint8_t MOSI = 16; static const uint8_t MISO = 14; static const uint8_t SCK = 15; // Mapping of analog pins as digital I/O // A6-A11 share with digital pins static const uint8_t ADC0 = 18; static const uint8_t ADC1 = 19; static const uint8_t ADC2 = 20; static const uint8_t ADC3 = 21; static const uint8_t ADC4 = 22; static const uint8_t ADC5 = 23; static const uint8_t ADC6 = 24; // D4 static const uint8_t ADC7 = 25; // D6 static const uint8_t ADC8 = 26; // D8 static const uint8_t ADC9 = 27; // D9 static const uint8_t ADC10 = 28; // D10 static const uint8_t ADC11 = 29; // D12 #define digitalPinToPCICR(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCICR) : ((uint8_t *)0)) #define digitalPinToPCICRbit(p) 0 #define digitalPinToPCMSK(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCMSK0) : ((uint8_t *)0)) #define digitalPinToPCMSKbit(p) ( ((p) >= 8 && (p) <= 11) ? (p) - 4 : ((p) == 14 ? 3 : ((p) == 15 ? 1 : ((p) == 16 ? 2 : ((p) == 17 ? 0 : (p - A8 + 4)))))) // __AVR_ATmega32U4__ has an unusual mapping of pins to channels extern const uint8_t PROGMEM analog_pin_to_channel_PGM[]; #define analogPinToChannel(P) ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) ) #define digitalPinToInterrupt(p) ((p) == 0 ? 2 : ((p) == 1 ? 3 : ((p) == 2 ? 1 : ((p) == 3 ? 0 : ((p) == 7 ? 4 : NOT_AN_INTERRUPT))))) #ifdef ARDUINO_MAIN // On the Arduino board, digital pins are also used // for the analog output (software PWM). Analog input // pins are a separate set. // ATMEL ATMEGA32U4 / ARDUINO LEONARDO // // D0 PD2 RXD1/INT2 // D1 PD3 TXD1/INT3 // D2 PD1 SDA SDA/INT1 // D3# PD0 PWM8/SCL OC0B/SCL/INT0 // D4 A6 PD4 ADC8 // D5# PC6 ??? OC3A/#OC4A // D6# A7 PD7 FastPWM #OC4D/ADC10 // D7 PE6 INT6/AIN0 // // D8 A8 PB4 ADC11/PCINT4 // D9# A9 PB5 PWM16 OC1A/#OC4B/ADC12/PCINT5 // D10# A10 PB6 PWM16 OC1B/0c4B/ADC13/PCINT6 // D11# PB7 PWM8/16 0C0A/OC1C/#RTS/PCINT7 // D12 A11 PD6 T1/#OC4D/ADC9 // D13# PC7 PWM10 CLK0/OC4A // // A0 D18 PF7 ADC7 // A1 D19 PF6 ADC6 // A2 D20 PF5 ADC5 // A3 D21 PF4 ADC4 // A4 D22 PF1 ADC1 // A5 D23 PF0 ADC0 // // New pins D14..D17 to map SPI port to digital pins // // MISO D14 PB3 MISO,PCINT3 // SCK D15 PB1 SCK,PCINT1 // MOSI D16 PB2 MOSI,PCINT2 // SS D17 PB0 RXLED,SS/PCINT0 // // Connected LEDs on board for TX and RX // TXLED D24 PD5 XCK1 // RXLED D17 PB0 // HWB PE2 HWB // these arrays map port names (e.g. port B) to the // appropriate addresses for various functions (e.g. reading // and writing) const uint16_t PROGMEM port_to_mode_PGM[] = { NOT_A_PORT, NOT_A_PORT, (uint16_t) &DDRB, (uint16_t) &DDRC, (uint16_t) &DDRD, (uint16_t) &DDRE, (uint16_t) &DDRF, }; const uint16_t PROGMEM port_to_output_PGM[] = { NOT_A_PORT, NOT_A_PORT, (uint16_t) &PORTB, (uint16_t) &PORTC, (uint16_t) &PORTD, (uint16_t) &PORTE, (uint16_t) &PORTF, }; const uint16_t PROGMEM port_to_input_PGM[] = { NOT_A_PORT, NOT_A_PORT, (uint16_t) &PINB, (uint16_t) &PINC, (uint16_t) &PIND, (uint16_t) &PINE, (uint16_t) &PINF, }; const uint8_t PROGMEM digital_pin_to_port_PGM[] = { PD, // D0 - PD2 PD, // D1 - PD3 PD, // D2 - PD1 PD, // D3 - PD0 PD, // D4 - PD4 PC, // D5 - PC6 PD, // D6 - PD7 PE, // D7 - PE6 PB, // D8 - PB4 PB, // D9 - PB5 PB, // D10 - PB6 PB, // D11 - PB7 PD, // D12 - PD6 PC, // D13 - PC7 PB, // D14 - MISO - PB3 PB, // D15 - SCK - PB1 PB, // D16 - MOSI - PB2 PB, // D17 - SS - PB0 PF, // D18 - A0 - PF7 PF, // D19 - A1 - PF6 PF, // D20 - A2 - PF5 PF, // D21 - A3 - PF4 PF, // D22 - A4 - PF1 PF, // D23 - A5 - PF0 PD, // D24 - PD5 PD, // D25 / D6 - A7 - PD7 PB, // D26 / D8 - A8 - PB4 PB, // D27 / D9 - A9 - PB5 PB, // D28 / D10 - A10 - PB6 PD, // D29 / D12 - A11 - PD6 }; const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { _BV(2), // D0 - PD2 _BV(3), // D1 - PD3 _BV(1), // D2 - PD1 _BV(0), // D3 - PD0 _BV(4), // D4 - PD4 _BV(6), // D5 - PC6 _BV(7), // D6 - PD7 _BV(6), // D7 - PE6 _BV(4), // D8 - PB4 _BV(5), // D9 - PB5 _BV(6), // D10 - PB6 _BV(7), // D11 - PB7 _BV(6), // D12 - PD6 _BV(7), // D13 - PC7 _BV(3), // D14 - MISO - PB3 _BV(1), // D15 - SCK - PB1 _BV(2), // D16 - MOSI - PB2 _BV(0), // D17 - SS - PB0 _BV(7), // D18 - A0 - PF7 _BV(6), // D19 - A1 - PF6 _BV(5), // D20 - A2 - PF5 _BV(4), // D21 - A3 - PF4 _BV(1), // D22 - A4 - PF1 _BV(0), // D23 - A5 - PF0 _BV(5), // D24 - PD5 _BV(7), // D25 / D6 - A7 - PD7 _BV(4), // D26 / D8 - A8 - PB4 _BV(5), // D27 / D9 - A9 - PB5 _BV(6), // D28 / D10 - A10 - PB6 _BV(6), // D29 / D12 - A11 - PD6 }; const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, TIMER0B, /* 3 */ NOT_ON_TIMER, TIMER3A, /* 5 */ TIMER4D, /* 6 */ NOT_ON_TIMER, NOT_ON_TIMER, TIMER1A, /* 9 */ TIMER1B, /* 10 */ TIMER0A, /* 11 */ NOT_ON_TIMER, TIMER4A, /* 13 */ NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, }; const uint8_t PROGMEM analog_pin_to_channel_PGM[] = { 7, // A0 PF7 ADC7 6, // A1 PF6 ADC6 5, // A2 PF5 ADC5 4, // A3 PF4 ADC4 1, // A4 PF1 ADC1 0, // A5 PF0 ADC0 8, // A6 D4 PD4 ADC8 10, // A7 D6 PD7 ADC10 11, // A8 D8 PB4 ADC11 12, // A9 D9 PB5 ADC12 13, // A10 D10 PB6 ADC13 9 // A11 D12 PD6 ADC9 }; #endif /* ARDUINO_MAIN */ // These serial port names are intended to allow libraries and architecture-neutral // sketches to automatically default to the correct port name for a particular type // of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, // the first hardware serial port whose RX/TX pins are not dedicated to another use. // // SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor // // SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial // // SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library // // SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. // // SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX // pins are NOT connected to anything by default. #define SERIAL_PORT_MONITOR Serial #define SERIAL_PORT_USBVIRTUAL Serial #define SERIAL_PORT_HARDWARE Serial1 #define SERIAL_PORT_HARDWARE_OPEN Serial1 #endif /* Pins_Arduino_h */
A keyboards/crkbd/readme.md => keyboards/crkbd/readme.md +17 -0
@@ 0,0 1,17 @@ Crkbd ===   A split keyboard with 3x6 vertically staggered keys and 3 thumb keys. Keyboard Maintainer: [foostan](https://github.com/foostan/) [@foostan](https://twitter.com/foostan) Hardware Supported: Crkbd PCB, Pro Micro Hardware Availability: [PCB & Case Data](https://github.com/foostan/crkbd) Make example for this keyboard (after setting up your build environment): make crkbd:default See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information.
A keyboards/crkbd/rev1/config.h => keyboards/crkbd/rev1/config.h +87 -0
@@ 0,0 1,87 @@ /* Copyright 2012 Jun Wako <wakojun@gmail.com> Copyright 2015 Jack Humbert 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 REV1_CONFIG_H #define REV1_CONFIG_H #include "../config.h" /* USB Device descriptor parameter */ #define VENDOR_ID 0xFEED #define PRODUCT_ID 0x3060 #define DEVICE_VER 0x0001 #define MANUFACTURER foostan #define PRODUCT Crkbd #define DESCRIPTION A split keyboard with 3x6 vertically staggered keys and 3 thumb keys /* key matrix size */ // Rows are doubled-up #define MATRIX_ROWS 8 #define MATRIX_COLS 7 #define MATRIX_ROW_PINS { D4, C6, D7, E6 } // wiring of each half #define MATRIX_COL_PINS { F4, F5, F6, F7, B1, B3, B2 } // #define MATRIX_COL_PINS { B2, B3, B1, F7, F6, F5, F4 } //uncomment this line and comment line above if you need to reverse left-to-right key order /* define if matrix has ghost */ //#define MATRIX_HAS_GHOST /* number of backlight levels */ // #define BACKLIGHT_LEVELS 3 /* Set 0 if debouncing isn't needed */ #define DEBOUNCING_DELAY 5 /* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ //#define LOCKING_SUPPORT_ENABLE /* Locking resynchronize hack */ //#define LOCKING_RESYNC_ENABLE /* key combination for command */ #define IS_COMMAND() ( \ keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ ) /* ws2812 RGB LED */ #define RGB_DI_PIN D3 #define RGBLIGHT_TIMER #define RGBLED_NUM 12 // Number of LEDs #define ws2812_PORTREG PORTD #define ws2812_DDRREG DDRD /* * Feature disable options * These options are also useful to firmware size reduction. */ /* disable debug print */ // #define NO_DEBUG /* disable print */ // #define NO_PRINT /* disable action features */ //#define NO_ACTION_LAYER //#define NO_ACTION_TAPPING //#define NO_ACTION_ONESHOT //#define NO_ACTION_MACRO //#define NO_ACTION_FUNCTION #endif
A keyboards/crkbd/rev1/matrix.c => keyboards/crkbd/rev1/matrix.c +348 -0
@@ 0,0 1,348 @@ /* Copyright 2012 Jun Wako <wakojun@gmail.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/>. */ /* * scan matrix */ #include <stdint.h> #include <stdbool.h> #include <avr/io.h> #include <avr/wdt.h> #include <avr/interrupt.h> #include <util/delay.h> #include "print.h" #include "debug.h" #include "util.h" #include "matrix.h" #include "split_util.h" #include "pro_micro.h" #include "config.h" #ifdef USE_MATRIX_I2C # include "i2c.h" #else // USE_SERIAL # include "serial.h" #endif #ifndef DEBOUNCE # define DEBOUNCE 5 #endif #define ERROR_DISCONNECT_COUNT 5 static uint8_t debouncing = DEBOUNCE; static const int ROWS_PER_HAND = MATRIX_ROWS/2; static uint8_t error_count = 0; uint8_t is_master = 0 ; static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; /* matrix state(1:on, 0:off) */ static matrix_row_t matrix[MATRIX_ROWS]; static matrix_row_t matrix_debouncing[MATRIX_ROWS]; static matrix_row_t read_cols(void); static void init_cols(void); static void unselect_rows(void); static void select_row(uint8_t row); static uint8_t matrix_master_scan(void); __attribute__ ((weak)) void matrix_init_kb(void) { matrix_init_user(); } __attribute__ ((weak)) void matrix_scan_kb(void) { matrix_scan_user(); } __attribute__ ((weak)) void matrix_init_user(void) { } __attribute__ ((weak)) void matrix_scan_user(void) { } inline uint8_t matrix_rows(void) { return MATRIX_ROWS; } inline uint8_t matrix_cols(void) { return MATRIX_COLS; } void matrix_init(void) { debug_enable = true; debug_matrix = true; debug_mouse = true; // initialize row and col unselect_rows(); init_cols(); TX_RX_LED_INIT; // initialize matrix state: all keys off for (uint8_t i=0; i < MATRIX_ROWS; i++) { matrix[i] = 0; matrix_debouncing[i] = 0; } is_master = has_usb(); matrix_init_quantum(); } uint8_t _matrix_scan(void) { // Right hand is stored after the left in the matirx so, we need to offset it int offset = isLeftHand ? 0 : (ROWS_PER_HAND); for (uint8_t i = 0; i < ROWS_PER_HAND; i++) { select_row(i); _delay_us(30); // without this wait read unstable value. matrix_row_t cols = read_cols(); if (matrix_debouncing[i+offset] != cols) { matrix_debouncing[i+offset] = cols; debouncing = DEBOUNCE; } unselect_rows(); } if (debouncing) { if (--debouncing) { _delay_ms(1); } else { for (uint8_t i = 0; i < ROWS_PER_HAND; i++) { matrix[i+offset] = matrix_debouncing[i+offset]; } } } return 1; } #ifdef USE_MATRIX_I2C // Get rows from other half over i2c int i2c_transaction(void) { int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; int err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE); if (err) goto i2c_error; // start of matrix stored at 0x00 err = i2c_master_write(0x00); if (err) goto i2c_error; // Start read err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ); if (err) goto i2c_error; if (!err) { int i; for (i = 0; i < ROWS_PER_HAND-1; ++i) { matrix[slaveOffset+i] = i2c_master_read(I2C_ACK); } matrix[slaveOffset+i] = i2c_master_read(I2C_NACK); i2c_master_stop(); } else { i2c_error: // the cable is disconnceted, or something else went wrong i2c_reset_state(); return err; } return 0; } #else // USE_SERIAL int serial_transaction(void) { int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; int ret=serial_update_buffers(); if (ret ) { if(ret==2)RXLED1; return 1; } RXLED0; for (int i = 0; i < ROWS_PER_HAND; ++i) { matrix[slaveOffset+i] = serial_slave_buffer[i]; } return 0; } #endif uint8_t matrix_scan(void) { if (is_master) { matrix_master_scan(); }else{ matrix_slave_scan(); // if(serial_slave_DATA_CORRUPT()){ // TXLED0; int offset = (isLeftHand) ? ROWS_PER_HAND : 0; for (int i = 0; i < ROWS_PER_HAND; ++i) { matrix[offset+i] = serial_master_buffer[i]; } // }else{ // TXLED1; // } matrix_scan_quantum(); } return 1; } uint8_t matrix_master_scan(void) { int ret = _matrix_scan(); int offset = (isLeftHand) ? 0 : ROWS_PER_HAND; #ifdef USE_MATRIX_I2C // for (int i = 0; i < ROWS_PER_HAND; ++i) { /* i2c_slave_buffer[i] = matrix[offset+i]; */ // i2c_slave_buffer[i] = matrix[offset+i]; // } #else // USE_SERIAL for (int i = 0; i < ROWS_PER_HAND; ++i) { serial_master_buffer[i] = matrix[offset+i]; } #endif #ifdef USE_MATRIX_I2C if( i2c_transaction() ) { #else // USE_SERIAL if( serial_transaction() ) { #endif // turn on the indicator led when halves are disconnected TXLED1; error_count++; if (error_count > ERROR_DISCONNECT_COUNT) { // reset other half if disconnected int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; for (int i = 0; i < ROWS_PER_HAND; ++i) { matrix[slaveOffset+i] = 0; } } } else { // turn off the indicator led on no error TXLED0; error_count = 0; } matrix_scan_quantum(); return ret; } void matrix_slave_scan(void) { _matrix_scan(); int offset = (isLeftHand) ? 0 : ROWS_PER_HAND; #ifdef USE_MATRIX_I2C for (int i = 0; i < ROWS_PER_HAND; ++i) { /* i2c_slave_buffer[i] = matrix[offset+i]; */ i2c_slave_buffer[i] = matrix[offset+i]; } #else // USE_SERIAL for (int i = 0; i < ROWS_PER_HAND; ++i) { serial_slave_buffer[i] = matrix[offset+i]; } #endif } bool matrix_is_modified(void) { if (debouncing) return false; return true; } inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1<<col)); } inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; } void matrix_print(void) { print("\nr/c 0123456789ABCDEF\n"); for (uint8_t row = 0; row < MATRIX_ROWS; row++) { phex(row); print(": "); pbin_reverse16(matrix_get_row(row)); print("\n"); } } uint8_t matrix_key_count(void) { uint8_t count = 0; for (uint8_t i = 0; i < MATRIX_ROWS; i++) { count += bitpop16(matrix[i]); } return count; } static void init_cols(void) { for(int x = 0; x < MATRIX_COLS; x++) { _SFR_IO8((col_pins[x] >> 4) + 1) &= ~_BV(col_pins[x] & 0xF); _SFR_IO8((col_pins[x] >> 4) + 2) |= _BV(col_pins[x] & 0xF); } } static matrix_row_t read_cols(void) { matrix_row_t result = 0; 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; } static void unselect_rows(void) { 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); } } static void select_row(uint8_t row) { _SFR_IO8((row_pins[row] >> 4) + 1) |= _BV(row_pins[row] & 0xF); _SFR_IO8((row_pins[row] >> 4) + 2) &= ~_BV(row_pins[row] & 0xF); }
A keyboards/crkbd/rev1/rev1.c => keyboards/crkbd/rev1/rev1.c +32 -0
@@ 0,0 1,32 @@ #include "crkbd.h" #ifdef AUDIO_ENABLE float tone_startup[][2] = SONG(STARTUP_SOUND); float tone_goodbye[][2] = SONG(GOODBYE_SOUND); #endif #ifdef SSD1306OLED void led_set_kb(uint8_t usb_led) { // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here //led_set_user(usb_led); } #endif void matrix_init_kb(void) { #ifdef AUDIO_ENABLE _delay_ms(20); // gets rid of tick PLAY_SONG(tone_startup); #endif matrix_init_user(); }; void shutdown_kb(void) { #ifdef AUDIO_ENABLE PLAY_SONG(tone_goodbye); _delay_ms(150); stop_all_notes(); #endif }
A keyboards/crkbd/rev1/rev1.h => keyboards/crkbd/rev1/rev1.h +53 -0
@@ 0,0 1,53 @@ #ifndef REV1_H #define REV1_CONFIG_H #include "../crkbd.h" //void promicro_bootloader_jmp(bool program); #include "quantum.h" #ifdef RGBLIGHT_ENABLE //rgb led driver #include "ws2812.h" #endif #ifdef USE_I2C #include <stddef.h> #ifdef __AVR__ #include <avr/io.h> #include <avr/interrupt.h> #endif #endif //void promicro_bootloader_jmp(bool program); #define LAYOUT( \ 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, R30, R31, R32 \ ) \ { \ { L00, L01, L02, L03, L04, L05 }, \ { L10, L11, L12, L13, L14, L15 }, \ { L20, L21, L22, L23, L24, L25 }, \ { KC_NO, KC_NO, KC_NO, L30, L31, L32 }, \ { R05, R04, R03, R02, R01, R00 }, \ { R15, R14, R13, R12, R11, R10 }, \ { R25, R24, R23, R22, R21, R20 }, \ { KC_NO, KC_NO, KC_NO, R32, R31, R30 } \ } #define LAYOUT_kc( \ 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, R30, R31, R32 \ ) \ LAYOUT( \ 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_##R30, KC_##R31, KC_##R32 \ ) #endif
A keyboards/crkbd/rev1/rules.mk => keyboards/crkbd/rev1/rules.mk +2 -0
A keyboards/crkbd/rules.mk => keyboards/crkbd/rules.mk +74 -0
@@ 0,0 1,74 @@ SRC += i2c.c \ serial.c \ split_util.c \ ssd1306.c # MCU name #MCU = at90usb1287 MCU = atmega32u4 # Processor frequency. # This will define a symbol, F_CPU, in all source code files equal to the # processor frequency in Hz. 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. # # This will be an integer division of F_USB below, as it is sourced by # F_USB after it has run through any CPU prescalers. Note that this value # does not *change* the processor frequency - it should merely be updated to # reflect the processor speed set externally so that the code can use accurate # software delays. F_CPU = 16000000 # # LUFA specific # # Target architecture (see library "Board Types" documentation). ARCH = AVR8 # Input clock frequency. # This will define a symbol, F_USB, in all source code files equal to the # input clock frequency (before any prescaling is performed) in Hz. This value may # differ from F_CPU if prescaling is used on the latter, and is required as the # raw input clock is fed directly to the PLL sections of the AVR for high speed # clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' # at the end, this will be done automatically to create a 32-bit value in your # source code. # # If no clock division is performed on the input clock inside the AVR (via the # CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. F_USB = $(F_CPU) # Bootloader # This definition is optional, and if your keyboard supports multiple bootloaders of # different sizes, comment this out, and the correct address will be loaded # automatically (+60). See bootloader.mk for all options. BOOTLOADER = caterina # Interrupt driven control endpoint task(+60) OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT # Build Options # 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) MOUSEKEY_ENABLE = no # Mouse keys(+4700) EXTRAKEY_ENABLE = no # Audio control and System control(+450) CONSOLE_ENABLE = no # Console for debug(+400) COMMAND_ENABLE = no # Commands for debug and configuration NKRO_ENABLE = no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality MIDI_ENABLE = no # MIDI controls AUDIO_ENABLE = no # Audio output on port C6 UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time. SUBPROJECT_rev1 = no USE_I2C = yes # 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 DEFAULT_FOLDER = crkbd/rev1
A keyboards/crkbd/serial.c => keyboards/crkbd/serial.c +238 -0
@@ 0,0 1,238 @@ /* * WARNING: be careful changing this code, it is very timing dependent */ #ifndef F_CPU #define F_CPU 16000000 #endif #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #include <stdbool.h> #include "serial.h" #ifdef USE_SERIAL // 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); } void serial_delay_short(void) { _delay_us(SERIAL_DELAY-1); } 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(); #ifndef USE_SERIAL_PD2 // Enable INT0 EIMSK |= _BV(INT0); // Trigger on falling edge of INT0 EICRA &= ~(_BV(ISC00) | _BV(ISC01)); #else // Enable INT2 EIMSK |= _BV(INT2); // Trigger on falling edge of INT2 EICRA &= ~(_BV(ISC20) | _BV(ISC21)); #endif } // 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(); _delay_us(SERIAL_DELAY-5); } // 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 2; } 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; } #endif
A keyboards/crkbd/serial.h => keyboards/crkbd/serial.h +32 -0
@@ 0,0 1,32 @@ #ifndef MY_SERIAL_H #define MY_SERIAL_H #include "config.h" #include <stdbool.h> /* TODO: some defines for interrupt setup */ #define SERIAL_PIN_DDR DDRD #define SERIAL_PIN_PORT PORTD #define SERIAL_PIN_INPUT PIND #ifndef USE_SERIAL_PD2 #define SERIAL_PIN_MASK _BV(PD0) #define SERIAL_PIN_INTERRUPT INT0_vect #else #define SERIAL_PIN_MASK _BV(PD2) #define SERIAL_PIN_INTERRUPT INT2_vect #endif #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 #define SERIAL_MASTER_BUFFER_LENGTH MATRIX_ROWS/2 // 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
A keyboards/crkbd/split_util.c => keyboards/crkbd/split_util.c +71 -0
@@ 0,0 1,71 @@ #include <avr/io.h> #include <avr/wdt.h> #include <avr/power.h> #include <avr/interrupt.h> #include <util/delay.h> #include <avr/eeprom.h> #include "split_util.h" #include "matrix.h" #include "keyboard.h" #include "config.h" #ifdef USE_MATRIX_I2C # include "i2c.h" #else # include "serial.h" #endif volatile bool isLeftHand = true; static void setup_handedness(void) { #ifdef EE_HANDS isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS); #else // I2C_MASTER_RIGHT is deprecated, use MASTER_RIGHT instead, since this works for both serial and i2c #if defined(I2C_MASTER_RIGHT) || defined(MASTER_RIGHT) isLeftHand = !has_usb(); #else isLeftHand = has_usb(); #endif #endif } static void keyboard_master_setup(void) { #ifdef USE_MATRIX_I2C i2c_master_init(); #else serial_master_init(); #endif } static void keyboard_slave_setup(void) { #ifdef USE_MATRIX_I2C i2c_slave_init(SLAVE_I2C_ADDRESS); #else serial_slave_init(); #endif } bool has_usb(void) { USBCON |= (1 << OTGPADE); //enables VBUS pad _delay_us(5); return (USBSTA & (1<<VBUS)); //checks state of VBUS } void split_keyboard_setup(void) { setup_handedness(); if (has_usb()) { keyboard_master_setup(); } else { keyboard_slave_setup(); } sei(); } // this code runs before the usb and keyboard is initialized void matrix_setup(void) { split_keyboard_setup(); }
A keyboards/crkbd/split_util.h => keyboards/crkbd/split_util.h +19 -0
@@ 0,0 1,19 @@ #ifndef SPLIT_KEYBOARD_UTIL_H #define SPLIT_KEYBOARD_UTIL_H #include <stdbool.h> #include "eeconfig.h" #define SLAVE_I2C_ADDRESS 0x32 extern volatile bool isLeftHand; // slave version of matix scan, defined in matrix.c void matrix_slave_scan(void); void split_keyboard_setup(void); bool has_usb(void); void matrix_master_OLED_init (void); #endif
A keyboards/crkbd/ssd1306.c => keyboards/crkbd/ssd1306.c +330 -0
@@ 0,0 1,330 @@ #ifdef SSD1306OLED #include "ssd1306.h" #include "i2c.h" #include <string.h> #include "print.h" #include "glcdfont.c" #ifdef ADAFRUIT_BLE_ENABLE #include "adafruit_ble.h" #endif #ifdef PROTOCOL_LUFA #include "lufa.h" #endif #include "sendchar.h" #include "timer.h" // Set this to 1 to help diagnose early startup problems // when testing power-on with ble. Turn it off otherwise, // as the latency of printing most of the debug info messes // with the matrix scan, causing keys to drop. #define DEBUG_TO_SCREEN 0 //static uint16_t last_battery_update; //static uint32_t vbat; //#define BatteryUpdateInterval 10000 /* milliseconds */ #define ScreenOffInterval 300000 /* milliseconds */ #if DEBUG_TO_SCREEN static uint8_t displaying; #endif static uint16_t last_flush; // Write command sequence. // Returns true on success. static inline bool _send_cmd1(uint8_t cmd) { bool res = false; if (i2c_start_write(SSD1306_ADDRESS)) { xprintf("failed to start write to %d\n", SSD1306_ADDRESS); goto done; } if (i2c_master_write(0x0 /* command byte follows */)) { print("failed to write control byte\n"); goto done; } if (i2c_master_write(cmd)) { xprintf("failed to write command %d\n", cmd); goto done; } res = true; done: i2c_master_stop(); return res; } // Write 2-byte command sequence. // Returns true on success static inline bool _send_cmd2(uint8_t cmd, uint8_t opr) { if (!_send_cmd1(cmd)) { return false; } return _send_cmd1(opr); } // Write 3-byte command sequence. // Returns true on success static inline bool _send_cmd3(uint8_t cmd, uint8_t opr1, uint8_t opr2) { if (!_send_cmd1(cmd)) { return false; } if (!_send_cmd1(opr1)) { return false; } return _send_cmd1(opr2); } #define send_cmd1(c) if (!_send_cmd1(c)) {goto done;} #define send_cmd2(c,o) if (!_send_cmd2(c,o)) {goto done;} #define send_cmd3(c,o1,o2) if (!_send_cmd3(c,o1,o2)) {goto done;} static void clear_display(void) { matrix_clear(&display); // Clear all of the display bits (there can be random noise // in the RAM on startup) send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1); send_cmd3(ColumnAddr, 0, DisplayWidth - 1); if (i2c_start_write(SSD1306_ADDRESS)) { goto done; } if (i2c_master_write(0x40)) { // Data mode goto done; } for (uint8_t row = 0; row < MatrixRows; ++row) { for (uint8_t col = 0; col < DisplayWidth; ++col) { i2c_master_write(0); } } display.dirty = false; done: i2c_master_stop(); } #if DEBUG_TO_SCREEN #undef sendchar static int8_t capture_sendchar(uint8_t c) { sendchar(c); iota_gfx_write_char(c); if (!displaying) { iota_gfx_flush(); } return 0; } #endif bool iota_gfx_init(bool rotate) { bool success = false; send_cmd1(DisplayOff); send_cmd2(SetDisplayClockDiv, 0x80); send_cmd2(SetMultiPlex, DisplayHeight - 1); send_cmd2(SetDisplayOffset, 0); send_cmd1(SetStartLine | 0x0); send_cmd2(SetChargePump, 0x14 /* Enable */); send_cmd2(SetMemoryMode, 0 /* horizontal addressing */); if(rotate){ // the following Flip the display orientation 180 degrees send_cmd1(SegRemap); send_cmd1(ComScanInc); }else{ // Flips the display orientation 0 degrees send_cmd1(SegRemap | 0x1); send_cmd1(ComScanDec); } send_cmd2(SetComPins, 0x2); send_cmd2(SetContrast, 0x8f); send_cmd2(SetPreCharge, 0xf1); send_cmd2(SetVComDetect, 0x40); send_cmd1(DisplayAllOnResume); send_cmd1(NormalDisplay); send_cmd1(DeActivateScroll); send_cmd1(DisplayOn); send_cmd2(SetContrast, 0); // Dim clear_display(); success = true; iota_gfx_flush(); #if DEBUG_TO_SCREEN print_set_sendchar(capture_sendchar); #endif done: return success; } bool iota_gfx_off(void) { bool success = false; send_cmd1(DisplayOff); success = true; done: return success; } bool iota_gfx_on(void) { bool success = false; send_cmd1(DisplayOn); success = true; done: return success; } void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) { *matrix->cursor = c; ++matrix->cursor; if (matrix->cursor - &matrix->display[0][0] == sizeof(matrix->display)) { // We went off the end; scroll the display upwards by one line memmove(&matrix->display[0], &matrix->display[1], MatrixCols * (MatrixRows - 1)); matrix->cursor = &matrix->display[MatrixRows - 1][0]; memset(matrix->cursor, ' ', MatrixCols); } } void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) { matrix->dirty = true; if (c == '\n') { // Clear to end of line from the cursor and then move to the // start of the next line uint8_t cursor_col = (matrix->cursor - &matrix->display[0][0]) % MatrixCols; while (cursor_col++ < MatrixCols) { matrix_write_char_inner(matrix, ' '); } return; } matrix_write_char_inner(matrix, c); } void iota_gfx_write_char(uint8_t c) { matrix_write_char(&display, c); } void matrix_write(struct CharacterMatrix *matrix, const char *data) { const char *end = data + strlen(data); while (data < end) { matrix_write_char(matrix, *data); ++data; } } void matrix_write_ln(struct CharacterMatrix *matrix, const char *data) { char data_ln[strlen(data)+2]; snprintf(data_ln, sizeof(data_ln), "%s\n", data); matrix_write(matrix, data_ln); } void iota_gfx_write(const char *data) { matrix_write(&display, data); } void matrix_write_P(struct CharacterMatrix *matrix, const char *data) { while (true) { uint8_t c = pgm_read_byte(data); if (c == 0) { return; } matrix_write_char(matrix, c); ++data; } } void iota_gfx_write_P(const char *data) { matrix_write_P(&display, data); } void matrix_clear(struct CharacterMatrix *matrix) { memset(matrix->display, ' ', sizeof(matrix->display)); matrix->cursor = &matrix->display[0][0]; matrix->dirty = true; } void iota_gfx_clear_screen(void) { matrix_clear(&display); } void matrix_render(struct CharacterMatrix *matrix) { last_flush = timer_read(); iota_gfx_on(); #if DEBUG_TO_SCREEN ++displaying; #endif // Move to the home position send_cmd3(PageAddr, 0, MatrixRows - 1); send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1); if (i2c_start_write(SSD1306_ADDRESS)) { goto done; } if (i2c_master_write(0x40)) { // Data mode goto done; } for (uint8_t row = 0; row < MatrixRows; ++row) { for (uint8_t col = 0; col < MatrixCols; ++col) { const uint8_t *glyph = font + (matrix->display[row][col] * FontWidth); for (uint8_t glyphCol = 0; glyphCol < FontWidth; ++glyphCol) { uint8_t colBits = pgm_read_byte(glyph + glyphCol); i2c_master_write(colBits); } // 1 column of space between chars (it's not included in the glyph) //i2c_master_write(0); } } matrix->dirty = false; done: i2c_master_stop(); #if DEBUG_TO_SCREEN --displaying; #endif } void iota_gfx_flush(void) { matrix_render(&display); } __attribute__ ((weak)) void iota_gfx_task_user(void) { } void iota_gfx_task(void) { iota_gfx_task_user(); if (display.dirty) { iota_gfx_flush(); } if (timer_elapsed(last_flush) > ScreenOffInterval) { iota_gfx_off(); } } #endif
A keyboards/crkbd/ssd1306.h => keyboards/crkbd/ssd1306.h +94 -0
@@ 0,0 1,94 @@ #ifndef SSD1306_H #define SSD1306_H #include <stdbool.h> #include <stdio.h> #include "pincontrol.h" #include "config.h" enum ssd1306_cmds { DisplayOff = 0xAE, DisplayOn = 0xAF, SetContrast = 0x81, DisplayAllOnResume = 0xA4, DisplayAllOn = 0xA5, NormalDisplay = 0xA6, InvertDisplay = 0xA7, SetDisplayOffset = 0xD3, SetComPins = 0xda, SetVComDetect = 0xdb, SetDisplayClockDiv = 0xD5, SetPreCharge = 0xd9, SetMultiPlex = 0xa8, SetLowColumn = 0x00, SetHighColumn = 0x10, SetStartLine = 0x40, SetMemoryMode = 0x20, ColumnAddr = 0x21, PageAddr = 0x22, ComScanInc = 0xc0, ComScanDec = 0xc8, SegRemap = 0xa0, SetChargePump = 0x8d, ExternalVcc = 0x01, SwitchCapVcc = 0x02, ActivateScroll = 0x2f, DeActivateScroll = 0x2e, SetVerticalScrollArea = 0xa3, RightHorizontalScroll = 0x26, LeftHorizontalScroll = 0x27, VerticalAndRightHorizontalScroll = 0x29, VerticalAndLeftHorizontalScroll = 0x2a, }; // Controls the SSD1306 128x32 OLED display via i2c #ifndef SSD1306_ADDRESS #define SSD1306_ADDRESS 0x3C #endif #define DisplayHeight 32 #define DisplayWidth 128 #define FontHeight 8 #define FontWidth 6 #define MatrixRows (DisplayHeight / FontHeight) #define MatrixCols (DisplayWidth / FontWidth) struct CharacterMatrix { uint8_t display[MatrixRows][MatrixCols]; uint8_t *cursor; bool dirty; }; struct CharacterMatrix display; bool iota_gfx_init(bool rotate); void iota_gfx_task(void); bool iota_gfx_off(void); bool iota_gfx_on(void); void iota_gfx_flush(void); void iota_gfx_write_char(uint8_t c); void iota_gfx_write(const char *data); void iota_gfx_write_P(const char *data); void iota_gfx_clear_screen(void); void iota_gfx_task_user(void); void matrix_clear(struct CharacterMatrix *matrix); void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c); void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c); void matrix_write(struct CharacterMatrix *matrix, const char *data); void matrix_write_ln(struct CharacterMatrix *matrix, const char *data); void matrix_write_P(struct CharacterMatrix *matrix, const char *data); void matrix_render(struct CharacterMatrix *matrix); #endif