aboutsummaryrefslogtreecommitdiff
path: root/keyboards/comet46
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/comet46')
-rw-r--r--keyboards/comet46/comet46.c1
-rw-r--r--keyboards/comet46/comet46.h21
-rw-r--r--keyboards/comet46/config.h73
-rw-r--r--keyboards/comet46/i2c.c162
-rw-r--r--keyboards/comet46/i2c.h46
-rw-r--r--keyboards/comet46/info.json60
-rw-r--r--keyboards/comet46/keymaps/default-rgbled/keymap.c223
-rw-r--r--keyboards/comet46/keymaps/default-rgbled/readme.md3
-rw-r--r--keyboards/comet46/keymaps/default/config.h29
-rw-r--r--keyboards/comet46/keymaps/default/keymap.c253
-rw-r--r--keyboards/comet46/keymaps/default/readme.md3
-rw-r--r--keyboards/comet46/keymaps/default/rules.mk5
-rw-r--r--keyboards/comet46/keymaps/satt/action_pseudo_lut.c143
-rw-r--r--keyboards/comet46/keymaps/satt/action_pseudo_lut.h15
-rw-r--r--keyboards/comet46/keymaps/satt/config.h29
-rw-r--r--keyboards/comet46/keymaps/satt/keymap.c288
-rw-r--r--keyboards/comet46/keymaps/satt/keymap_jis2us.h32
-rw-r--r--keyboards/comet46/keymaps/satt/readme.md6
-rw-r--r--keyboards/comet46/keymaps/satt/rules.mk8
-rw-r--r--keyboards/comet46/lib/glcdfont.c137
-rw-r--r--keyboards/comet46/lib/host_led_state_reader.c15
-rw-r--r--keyboards/comet46/lib/keylogger.c288
-rw-r--r--keyboards/comet46/lib/modifier_state_reader.c18
-rw-r--r--keyboards/comet46/matrix.c154
-rw-r--r--keyboards/comet46/readme.md17
-rw-r--r--keyboards/comet46/rules.mk23
-rw-r--r--keyboards/comet46/ssd1306.c343
-rw-r--r--keyboards/comet46/ssd1306.h90
28 files changed, 2485 insertions, 0 deletions
diff --git a/keyboards/comet46/comet46.c b/keyboards/comet46/comet46.c
new file mode 100644
index 000000000..7c7edba93
--- /dev/null
+++ b/keyboards/comet46/comet46.c
@@ -0,0 +1 @@
#include "comet46.h"
diff --git a/keyboards/comet46/comet46.h b/keyboards/comet46/comet46.h
new file mode 100644
index 000000000..094d960e2
--- /dev/null
+++ b/keyboards/comet46/comet46.h
@@ -0,0 +1,21 @@
1#pragma once
2
3#include "quantum.h"
4
5#define XXX KC_NO
6
7// This a shortcut to help you visually see your layout.
8// The first section contains all of the arguements
9// The second converts the arguments into a two-dimensional array
10#define LAYOUT( \
11 k04, k01, k13, k10, k22, k33, k36, k27, k19, k16, k08, k05, \
12 k03, k00, k12, k24, k21, k32, k43, k46, k37, k28, k25, k17, k09, k06, \
13 k02, k14, k11, k23, k20, k31, k42, k47, k38, k29, k26, k18, k15, k07, \
14 k34, k44, k41, k48, k45, k35 \
15) { \
16 { k00, k01, k02, k03, k04, k05, k06, k07, k08, k09 }, \
17 { k10, k11, k12, k13, k14, k15, k16, k17, k18, k19 }, \
18 { k20, k21, k22, k23, k24, k25, k26, k27, k28, k29 }, \
19 { XXX, k31, k32, k33, k34, k35, k36, k37, k38, XXX }, \
20 { XXX, k41, k42, k43, k44, k45, k46, k47, k48, XXX } \
21}
diff --git a/keyboards/comet46/config.h b/keyboards/comet46/config.h
new file mode 100644
index 000000000..067dabb10
--- /dev/null
+++ b/keyboards/comet46/config.h
@@ -0,0 +1,73 @@
1/*
2Copyright 2012 Jun Wako <[email protected]>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include "config_common.h"
21
22/* USB Device descriptor parameter */
23
24#define VENDOR_ID 0xFEED
25#define PRODUCT_ID 0x6060
26#define DEVICE_VER 0x0001
27#define MANUFACTURER SatT
28#define PRODUCT Comet46
29
30/* key matrix size */
31#define MATRIX_ROWS 5
32#define MATRIX_COLS 10
33
34/* define if matrix has ghost */
35//#define MATRIX_HAS_GHOST
36
37/* number of backlight levels */
38//#define BACKLIGHT_LEVELS 3
39
40#define ONESHOT_TIMEOUT 500
41
42/*
43 * Feature disable options
44 * These options are also useful to firmware size reduction.
45 */
46
47/* disable debug print */
48//#define NO_DEBUG
49
50/* disable print */
51//#define NO_PRINT
52
53/* disable action features */
54//#define NO_ACTION_LAYER
55//#define NO_ACTION_TAPPING
56//#define NO_ACTION_ONESHOT
57//#define NO_ACTION_MACRO
58//#define NO_ACTION_FUNCTION
59
60// Define masks for modifiers
61#define MODS_SHIFT_MASK (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT))
62#define MODS_CTRL_MASK (MOD_BIT(KC_LCTL)|MOD_BIT(KC_RCTRL))
63#define MODS_ALT_MASK (MOD_BIT(KC_LALT)|MOD_BIT(KC_RALT))
64#define MODS_GUI_MASK (MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI))
65
66//UART settings for communication with the RF microcontroller
67#define SERIAL_UART_BAUD 1000000
68#define SERIAL_UART_RXD_PRESENT (UCSR1A & _BV(RXC1))
69#define SERIAL_UART_INIT_CUSTOM \
70 /* enable TX and RX */ \
71 UCSR1B = _BV(TXEN1) | _BV(RXEN1); \
72 /* 8-bit data */ \
73 UCSR1C = _BV(UCSZ11) | _BV(UCSZ10);
diff --git a/keyboards/comet46/i2c.c b/keyboards/comet46/i2c.c
new file mode 100644
index 000000000..4bee5c639
--- /dev/null
+++ b/keyboards/comet46/i2c.c
@@ -0,0 +1,162 @@
1#include <util/twi.h>
2#include <avr/io.h>
3#include <stdlib.h>
4#include <avr/interrupt.h>
5#include <util/twi.h>
6#include <stdbool.h>
7#include "i2c.h"
8
9#ifdef USE_I2C
10
11// Limits the amount of we wait for any one i2c transaction.
12// Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is
13// 9 bits, a single transaction will take around 90μs to complete.
14//
15// (F_CPU/SCL_CLOCK) => # of μC cycles to transfer a bit
16// poll loop takes at least 8 clock cycles to execute
17#define I2C_LOOP_TIMEOUT (9+1)*(F_CPU/SCL_CLOCK)/8
18
19#define BUFFER_POS_INC() (slave_buffer_pos = (slave_buffer_pos+1)%SLAVE_BUFFER_SIZE)
20
21volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE];
22
23static volatile uint8_t slave_buffer_pos;
24static volatile bool slave_has_register_set = false;
25
26// Wait for an i2c operation to finish
27inline static
28void i2c_delay(void) {
29 uint16_t lim = 0;
30 while(!(TWCR & (1<<TWINT)) && lim < I2C_LOOP_TIMEOUT)
31 lim++;
32
33 // easier way, but will wait slightly longer
34 // _delay_us(100);
35}
36
37// Setup twi to run at 100kHz or 400kHz (see ./i2c.h SCL_CLOCK)
38void i2c_master_init(void) {
39 // no prescaler
40 TWSR = 0;
41 // Set TWI clock frequency to SCL_CLOCK. Need TWBR>10.
42 // Check datasheets for more info.
43 TWBR = ((F_CPU/SCL_CLOCK)-16)/2;
44}
45
46// Start a transaction with the given i2c slave address. The direction of the
47// transfer is set with I2C_READ and I2C_WRITE.
48// returns: 0 => success
49// 1 => error
50uint8_t i2c_master_start(uint8_t address) {
51 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA);
52
53 i2c_delay();
54
55 // check that we started successfully
56 if ( (TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START))
57 return 1;
58
59 TWDR = address;
60 TWCR = (1<<TWINT) | (1<<TWEN);
61
62 i2c_delay();
63
64 if ( (TW_STATUS != TW_MT_SLA_ACK) && (TW_STATUS != TW_MR_SLA_ACK) )
65 return 1; // slave did not acknowledge
66 else
67 return 0; // success
68}
69
70
71// Finish the i2c transaction.
72void i2c_master_stop(void) {
73 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
74
75 uint16_t lim = 0;
76 while(!(TWCR & (1<<TWSTO)) && lim < I2C_LOOP_TIMEOUT)
77 lim++;
78}
79
80// Write one byte to the i2c slave.
81// returns 0 => slave ACK
82// 1 => slave NACK
83uint8_t i2c_master_write(uint8_t data) {
84 TWDR = data;
85 TWCR = (1<<TWINT) | (1<<TWEN);
86
87 i2c_delay();
88
89 // check if the slave acknowledged us
90 return (TW_STATUS == TW_MT_DATA_ACK) ? 0 : 1;
91}
92
93// Read one byte from the i2c slave. If ack=1 the slave is acknowledged,
94// if ack=0 the acknowledge bit is not set.
95// returns: byte read from i2c device
96uint8_t i2c_master_read(int ack) {
97 TWCR = (1<<TWINT) | (1<<TWEN) | (ack<<TWEA);
98
99 i2c_delay();
100 return TWDR;
101}
102
103void i2c_reset_state(void) {
104 TWCR = 0;
105}
106
107void i2c_slave_init(uint8_t address) {
108 TWAR = address << 0; // slave i2c address
109 // TWEN - twi enable
110 // TWEA - enable address acknowledgement
111 // TWINT - twi interrupt flag
112 // TWIE - enable the twi interrupt
113 TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN);
114}
115
116ISR(TWI_vect);
117
118ISR(TWI_vect) {
119 uint8_t ack = 1;
120 switch(TW_STATUS) {
121 case TW_SR_SLA_ACK:
122 // this device has been addressed as a slave receiver
123 slave_has_register_set = false;
124 break;
125
126 case TW_SR_DATA_ACK:
127 // this device has received data as a slave receiver
128 // The first byte that we receive in this transaction sets the location
129 // of the read/write location of the slaves memory that it exposes over
130 // i2c. After that, bytes will be written at slave_buffer_pos, incrementing
131 // slave_buffer_pos after each write.
132 if(!slave_has_register_set) {
133 slave_buffer_pos = TWDR;
134 // don't acknowledge the master if this memory loctaion is out of bounds
135 if ( slave_buffer_pos >= SLAVE_BUFFER_SIZE ) {
136 ack = 0;
137 slave_buffer_pos = 0;
138 }
139 slave_has_register_set = true;
140 } else {
141 i2c_slave_buffer[slave_buffer_pos] = TWDR;
142 BUFFER_POS_INC();
143 }
144 break;
145
146 case TW_ST_SLA_ACK:
147 case TW_ST_DATA_ACK:
148 // master has addressed this device as a slave transmitter and is
149 // requesting data.
150 TWDR = i2c_slave_buffer[slave_buffer_pos];
151 BUFFER_POS_INC();
152 break;
153
154 case TW_BUS_ERROR: // something went wrong, reset twi state
155 TWCR = 0;
156 default:
157 break;
158 }
159 // Reset everything, so we are ready for the next TWI interrupt
160 TWCR |= (1<<TWIE) | (1<<TWINT) | (ack<<TWEA) | (1<<TWEN);
161}
162#endif
diff --git a/keyboards/comet46/i2c.h b/keyboards/comet46/i2c.h
new file mode 100644
index 000000000..710662c7a
--- /dev/null
+++ b/keyboards/comet46/i2c.h
@@ -0,0 +1,46 @@
1#pragma once
2
3#include <stdint.h>
4
5#ifndef F_CPU
6#define F_CPU 16000000UL
7#endif
8
9#define I2C_READ 1
10#define I2C_WRITE 0
11
12#define I2C_ACK 1
13#define I2C_NACK 0
14
15#define SLAVE_BUFFER_SIZE 0x10
16
17// i2c SCL clock frequency 400kHz
18#define SCL_CLOCK 400000L
19
20extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE];
21
22void i2c_master_init(void);
23uint8_t i2c_master_start(uint8_t address);
24void i2c_master_stop(void);
25uint8_t i2c_master_write(uint8_t data);
26uint8_t i2c_master_read(int);
27void i2c_reset_state(void);
28void i2c_slave_init(uint8_t address);
29
30
31static inline unsigned char i2c_start_read(unsigned char addr) {
32 return i2c_master_start((addr << 1) | I2C_READ);
33}
34
35static inline unsigned char i2c_start_write(unsigned char addr) {
36 return i2c_master_start((addr << 1) | I2C_WRITE);
37}
38
39// from SSD1306 scrips
40extern unsigned char i2c_rep_start(unsigned char addr);
41extern void i2c_start_wait(unsigned char addr);
42extern unsigned char i2c_readAck(void);
43extern unsigned char i2c_readNak(void);
44extern unsigned char i2c_read(unsigned char ack);
45
46#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak();
diff --git a/keyboards/comet46/info.json b/keyboards/comet46/info.json
new file mode 100644
index 000000000..f49c878e0
--- /dev/null
+++ b/keyboards/comet46/info.json
@@ -0,0 +1,60 @@
1{
2 "keyboard_name": "Comet46",
3 "url": "",
4 "maintainer": "SatT",
5 "layouts": {
6 "LAYOUT": {
7 "layout": [
8 {"label":"TAB", "x":0, "y":0.45},
9 {"label":"Q", "x":1, "y":0.45},
10 {"label":"W", "x":2, "y":0.15},
11 {"label":"E", "x":3, "y":0},
12 {"label":"R", "x":4, "y":0.30},
13 {"label":"T", "x":5, "y":0.45},
14 {"label":"Y", "x":9, "y":0.45},
15 {"label":"U", "x":10, "y":0.30},
16 {"label":"I", "x":11, "y":0},
17 {"label":"O", "x":12, "y":0.15},
18 {"label":"P", "x":13, "y":0.45},
19 {"label":"BSPC", "x":14, "y":0.45},
20
21 {"label":"LCTL", "x":0, "y":1.45},
22 {"label":"A", "x":1, "y":1.45},
23 {"label":"S", "x":2, "y":1.15},
24 {"label":"D", "x":3, "y":1},
25 {"label":"F", "x":4, "y":1.30},
26 {"label":"G", "x":5, "y":1.45},
27 {"label":"ESC", "x":6, "y":1},
28 {"label":"DEL", "x":8, "y":1},
29 {"label":"H", "x":9, "y":1.45},
30 {"label":"J", "x":10, "y":1.30},
31 {"label":"K", "x":11, "y":1},
32 {"label":"L", "x":12, "y":1.15},
33 {"label":"SCLN", "x":13, "y":1.45},
34 {"label":"QUOT", "x":14, "y":1.45},
35
36 {"label":"LSFT", "x":0, "y":2.45},
37 {"label":"Z", "x":1, "y":2.45},
38 {"label":"X", "x":2, "y":2.15},
39 {"label":"C", "x":3, "y":2},
40 {"label":"V", "x":4, "y":2.30},
41 {"label":"B", "x":5, "y":2.45},
42 {"label":"LCBR", "x":6, "y":2},
43 {"label":"RCBR", "x":8, "y":2},
44 {"label":"N", "x":9, "y":2.45},
45 {"label":"M", "x":10, "y":2.30},
46 {"label":"COMM", "x":11, "y":2},
47 {"label":"DOT", "x":12, "y":2.15},
48 {"label":"SLSH", "x":13, "y":2.45},
49 {"label":"RSFT", "x":14, "y":2.45},
50
51 {"label":"LGUI", "x":4, "y":3.9},
52 {"label":"LOWER", "x":5, "y":3.9},
53 {"label":"SPACE", "x":6, "y":3.4, "h":1.5},
54 {"label":"ENTER", "x":8, "y":3.4, "h":1.5},
55 {"label":"RAISE", "x":9, "y":3.9},
56 {"label":"LALT", "x":10, "y":3.9}
57 ]
58 }
59 }
60}
diff --git a/keyboards/comet46/keymaps/default-rgbled/keymap.c b/keyboards/comet46/keymaps/default-rgbled/keymap.c
new file mode 100644
index 000000000..d1e5b663d
--- /dev/null
+++ b/keyboards/comet46/keymaps/default-rgbled/keymap.c
@@ -0,0 +1,223 @@
1// this is the style you want to emulate.
2// This is the canonical layout file for the Quantum project. If you want to add another keyboard,
3
4#include QMK_KEYBOARD_H
5
6// Each layer gets a name for readability, which is then used in the keymap matrix below.
7// The underscores don't mean anything - you can have a layer called STUFF or any other name.
8// Layer names don't all need to be of the same length, obviously, and you can also skip them
9// entirely and just use numbers.
10enum comet46_layers
11{
12 _QWERTY,
13 _COLEMAK,
14 _DVORAK,
15 _LOWER,
16 _RAISE,
17 _ADJUST,
18};
19
20enum custom_keycodes {
21 QWERTY = SAFE_RANGE,
22 COLEMAK,
23 DVORAK,
24 LOWER,
25 RAISE,
26};
27
28#define LOWER MO(_LOWER)
29#define RAISE MO(_RAISE)
30
31const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
32
33 /* Qwerty
34 * ,-----------------------------------------+ +-----------------------------------------.
35 * | Tab | Q | W | E | R | T | | Y | U | I | O | P | Bksp |
36 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
37 * | Ctl | A | S | D | F | G | Esc | | Del | H | J | K | L | ; | " |
38 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
39 * | Shift| Z | X | C | V | B | { | | } | N | M | , | . | / | Shift|
40 * |------+------+------+------+------+------+------+ +------+------+------+------+------+-------------|
41 * | GUI | Lower| Space| | Enter| Raise| Alt |
42 * +--------------------/ \--------------------+
43 */
44 [_QWERTY] = LAYOUT(
45 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC,
46 KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_ESC, KC_DEL, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
47 KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LCBR, KC_RCBR, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT,
48 KC_LGUI, LOWER, KC_SPC, KC_ENT, RAISE, KC_LALT
49 ),
50
51 /* Colemak
52 * ,-----------------------------------------+ +-----------------------------------------.
53 * | Tab | Q | W | F | P | G | | J | L | U | Y | ; | Bksp |
54 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
55 * | Ctl | A | R | S | T | D | Esc | | Del | H | N | E | I | O | " |
56 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
57 * | Shift| Z | X | C | V | B | { | | } | K | M | , | . | / | Shift|
58 * |------+------+------+------+------+------+------+ +------+------+------+------+------+-------------|
59 * | GUI | Lower| Space| | Enter| Raise| Alt |
60 * +--------------------/ \--------------------+
61 */
62 [_COLEMAK] = LAYOUT(
63 KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC,
64 KC_LCTL, KC_A, KC_R, KC_S, KC_T, KC_D, KC_ESC, KC_DEL, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT,
65 KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LCBR, KC_RCBR, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT,
66 KC_LGUI, LOWER, KC_SPC, KC_ENT, RAISE, KC_LALT
67 ),
68
69 /* Dvorak
70 * ,-----------------------------------------+ +-----------------------------------------.
71 * | Tab | " | , | . | P | Y | | F | G | C | R | L | Bksp |
72 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
73 * | Ctl | A | O | E | U | I | Esc | | Del | D | H | T | N | S | / |
74 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
75 * | Shift| ; | Q | J | K | X | { | | } | B | M | W | V | Z | Shift|
76 * |------+------+------+------+------+------+------+ +------+------+------+------+------+-------------|
77 * | GUI | Lower| Space| | Enter| Raise| Alt |
78 * +--------------------/ \--------------------+
79 */
80 [_DVORAK] = LAYOUT(
81 KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC,
82 KC_LCTL, KC_A, KC_O, KC_E, KC_U, KC_I, KC_ESC, KC_DEL, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH,
83 KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_LCBR, KC_RCBR, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_RSFT,
84 KC_LGUI, LOWER, KC_SPC, KC_ENT, RAISE, KC_LALT
85 ),
86
87 /* Lower
88 * ,-----------------------------------------+ +-----------------------------------------.
89 * | | ! | @ | # | $ | % | | ^ | & | * | ( | ) | |
90 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
91 * | | | | | | | | | ` | \ | - | = | [ | ] | |
92 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
93 * | | | | | | | | | ~ | | | _ | + | { | } | |
94 * |------+------+------+------+------+------+------+ +------+------+------+------+------+-------------|
95 * | | | | | | | |
96 * +--------------------/ \--------------------+
97 */
98 [_LOWER] = LAYOUT(
99 _______, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, _______,
100 _______, _______, _______, _______, _______, _______, _______, KC_GRV, KC_BSLS, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, _______,
101 _______, _______, _______, _______, _______, _______, _______, KC_TILD, KC_PIPE, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, _______,
102 _______, _______, _______, _______, _______, _______
103 ),
104
105 /* Raise
106 * ,-----------------------------------------+ +-----------------------------------------.
107 * | | 1 | 2 | 3 | 4 | 5 | | | | | | | |
108 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
109 * | | F1 | F2 | F3 | F4 | F5 | F6 | | | Left | Down | Up |Right | End | |
110 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
111 * | | F7 | F8 | F9 | F10 | F11 | F12 | | Home | | PgDn | PgUp | | | |
112 * |------+------+------+------+------+------+------+ +------+------+------+------+------+-------------|
113 * | | | | | | | |
114 * +--------------------/ \--------------------+
115 */
116 [_RAISE] = LAYOUT(
117 _______, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, _______,
118 _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_END, _______,
119 _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_HOME, XXXXXXX, KC_PGDN, KC_PGUP, XXXXXXX, XXXXXXX, _______,
120 _______, _______, _______, _______, _______, _______
121 ),
122
123 /* Adjust
124 * ,-----------------------------------------+ +-----------------------------------------.
125 * | | | | | | | | | | | | | |
126 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
127 * | | | | | | |Qwerty| |Colemk| | | | | | |
128 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
129 * | | | | | | |Reset | |Dvorak| | | | | | |
130 * |------+------+------+------+------+------+------+ +------+------+------+------+------+-------------|
131 * | | | | | | | |
132 * +--------------------/ \--------------------+
133 */
134 [_ADJUST] = LAYOUT(
135 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
136 _______, _______, _______, _______, _______, _______, QWERTY, COLEMAK, _______, _______, _______, _______, _______, _______,
137 _______, _______, _______, _______, _______, _______, RESET, DVORAK, _______, _______, _______, _______, _______, _______,
138 _______, _______, _______, _______, _______, _______
139 )
140};
141
142
143layer_state_t layer_state_set_user(layer_state_t state) {
144 return update_tri_layer_state(state, _RAISE, _LOWER, _ADJUST);
145}
146
147// settings for LED on receiver
148void led_init(void) {
149 DDRD |= (1<<1);
150 PORTD |= (1<<1);
151 DDRF |= (1<<4) | (1<<5);
152 PORTF |= (1<<4) | (1<<5);
153}
154
155#define red_led_off PORTF |= (1<<5)
156#define red_led_on PORTF &= ~(1<<5)
157#define blu_led_off PORTF |= (1<<4)
158#define blu_led_on PORTF &= ~(1<<4)
159#define grn_led_off PORTD |= (1<<1)
160#define grn_led_on PORTD &= ~(1<<1)
161
162#define set_led_off red_led_off; grn_led_off; blu_led_off
163#define set_led_red red_led_on; grn_led_off; blu_led_off
164#define set_led_blue red_led_off; grn_led_off; blu_led_on
165#define set_led_green red_led_off; grn_led_on; blu_led_off
166#define set_led_yellow red_led_on; grn_led_on; blu_led_off
167#define set_led_magenta red_led_on; grn_led_off; blu_led_on
168#define set_led_cyan red_led_off; grn_led_on; blu_led_on
169#define set_led_white red_led_on; grn_led_on; blu_led_on
170
171void matrix_init_user(void) {
172 led_init();
173}
174
175void matrix_scan_user(void) {
176 uint8_t layer = biton32(layer_state);
177 uint8_t default_layer = biton32(eeconfig_read_default_layer());
178 switch (layer) {
179 case _LOWER:
180 set_led_red;
181 break;
182 case _RAISE:
183 set_led_blue;
184 break;
185 case _ADJUST:
186 set_led_magenta;
187 break;
188 default:
189 switch (default_layer) {
190 case _COLEMAK:
191 set_led_white;
192 break;
193 case _DVORAK:
194 set_led_yellow;
195 break;
196 default:
197 set_led_green;
198 break;
199 }
200 break;
201 }
202};
203
204bool process_record_user(uint16_t keycode, keyrecord_t *record) {
205 switch (keycode) {
206 case QWERTY:
207 if (record->event.pressed) {
208 set_single_persistent_default_layer(_QWERTY);
209 }
210 break;
211 case COLEMAK:
212 if (record->event.pressed) {
213 set_single_persistent_default_layer(_COLEMAK);
214 }
215 break;
216 case DVORAK:
217 if (record->event.pressed) {
218 set_single_persistent_default_layer(_DVORAK);
219 }
220 break;
221 }
222 return true;
223}
diff --git a/keyboards/comet46/keymaps/default-rgbled/readme.md b/keyboards/comet46/keymaps/default-rgbled/readme.md
new file mode 100644
index 000000000..40cc74433
--- /dev/null
+++ b/keyboards/comet46/keymaps/default-rgbled/readme.md
@@ -0,0 +1,3 @@
1## default-led
2
3A keymap that is compatible with mitosis-type receivers, which use RGB LED for layer indication.
diff --git a/keyboards/comet46/keymaps/default/config.h b/keyboards/comet46/keymaps/default/config.h
new file mode 100644
index 000000000..ee02a94b7
--- /dev/null
+++ b/keyboards/comet46/keymaps/default/config.h
@@ -0,0 +1,29 @@
1/*
2This is the c configuration file for the keymap
3
4Copyright 2012 Jun Wako <[email protected]>
5Copyright 2015 Jack Humbert
6
7This program is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#pragma once
22
23// place overrides here
24
25
26/* Use I2C or Serial */
27
28#define USE_I2C
29#define SSD1306OLED
diff --git a/keyboards/comet46/keymaps/default/keymap.c b/keyboards/comet46/keymaps/default/keymap.c
new file mode 100644
index 000000000..7a8c29dcb
--- /dev/null
+++ b/keyboards/comet46/keymaps/default/keymap.c
@@ -0,0 +1,253 @@
1// this is the style you want to emulate.
2// This is the canonical layout file for the Quantum project. If you want to add another keyboard,
3
4#include QMK_KEYBOARD_H
5#ifdef SSD1306OLED
6 #include "ssd1306.h"
7#endif
8
9
10// Each layer gets a name for readability, which is then used in the keymap matrix below.
11// The underscores don't mean anything - you can have a layer called STUFF or any other name.
12// Layer names don't all need to be of the same length, obviously, and you can also skip them
13// entirely and just use numbers.
14enum comet46_layers
15{
16 _QWERTY,
17 _COLEMAK,
18 _DVORAK,
19 _LOWER,
20 _RAISE,
21 _ADJUST,
22};
23
24enum custom_keycodes {
25 QWERTY = SAFE_RANGE,
26 COLEMAK,
27 DVORAK,
28 LOWER,
29 RAISE,
30};
31
32#define LOWER MO(_LOWER)
33#define RAISE MO(_RAISE)
34
35const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
36
37 /* Qwerty
38 * ,-----------------------------------------+ +-----------------------------------------.
39 * | Tab | Q | W | E | R | T | | Y | U | I | O | P | Bksp |
40 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
41 * | Ctl | A | S | D | F | G | Esc | | Del | H | J | K | L | ; | " |
42 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
43 * | Shift| Z | X | C | V | B | { | | } | N | M | , | . | / | Shift|
44 * |------+------+------+------+------+------+------+ +------+------+------+------+------+-------------|
45 * | GUI | Lower| Space| | Enter| Raise| Alt |
46 * +--------------------/ \--------------------+
47 */
48 [_QWERTY] = LAYOUT(
49 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC,
50 KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_ESC, KC_DEL, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
51 KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LCBR, KC_RCBR, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT,
52 KC_LGUI, LOWER, KC_SPC, KC_ENT, RAISE, KC_LALT
53 ),
54
55 /* Colemak
56 * ,-----------------------------------------+ +-----------------------------------------.
57 * | Tab | Q | W | F | P | G | | J | L | U | Y | ; | Bksp |
58 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
59 * | Ctl | A | R | S | T | D | Esc | | Del | H | N | E | I | O | " |
60 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
61 * | Shift| Z | X | C | V | B | { | | } | K | M | , | . | / | Shift|
62 * |------+------+------+------+------+------+------+ +------+------+------+------+------+-------------|
63 * | GUI | Lower| Space| | Enter| Raise| Alt |
64 * +--------------------/ \--------------------+
65 */
66 [_COLEMAK] = LAYOUT(
67 KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC,
68 KC_LCTL, KC_A, KC_R, KC_S, KC_T, KC_D, KC_ESC, KC_DEL, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT,
69 KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LCBR, KC_RCBR, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT,
70 KC_LGUI, LOWER, KC_SPC, KC_ENT, RAISE, KC_LALT
71 ),
72
73 /* Dvorak
74 * ,-----------------------------------------+ +-----------------------------------------.
75 * | Tab | " | , | . | P | Y | | F | G | C | R | L | Bksp |
76 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
77 * | Ctl | A | O | E | U | I | Esc | | Del | D | H | T | N | S | / |
78 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
79 * | Shift| ; | Q | J | K | X | { | | } | B | M | W | V | Z | Shift|
80 * |------+------+------+------+------+------+------+ +------+------+------+------+------+-------------|
81 * | GUI | Lower| Space| | Enter| Raise| Alt |
82 * +--------------------/ \--------------------+
83 */
84 [_DVORAK] = LAYOUT(
85 KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC,
86 KC_LCTL, KC_A, KC_O, KC_E, KC_U, KC_I, KC_ESC, KC_DEL, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH,
87 KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_LCBR, KC_RCBR, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_RSFT,
88 KC_LGUI, LOWER, KC_SPC, KC_ENT, RAISE, KC_LALT
89 ),
90
91 /* Lower
92 * ,-----------------------------------------+ +-----------------------------------------.
93 * | | ! | @ | # | $ | % | | ^ | & | * | ( | ) | |
94 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
95 * | | | | | | | | | ` | \ | - | = | [ | ] | |
96 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
97 * | | | | | | | | | ~ | | | _ | + | { | } | |
98 * |------+------+------+------+------+------+------+ +------+------+------+------+------+-------------|
99 * | | | | | | | |
100 * +--------------------/ \--------------------+
101 */
102 [_LOWER] = LAYOUT(
103 _______, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, _______,
104 _______, _______, _______, _______, _______, _______, _______, KC_GRV, KC_BSLS, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, _______,
105 _______, _______, _______, _______, _______, _______, _______, KC_TILD, KC_PIPE, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, _______,
106 _______, _______, _______, _______, _______, _______
107 ),
108
109 /* Raise
110 * ,-----------------------------------------+ +-----------------------------------------.
111 * | | 1 | 2 | 3 | 4 | 5 | | | | | | | |
112 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
113 * | | F1 | F2 | F3 | F4 | F5 | F6 | | | Left | Down | Up |Right | End | |
114 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
115 * | | F7 | F8 | F9 | F10 | F11 | F12 | | Home | | PgDn | PgUp | | | |
116 * |------+------+------+------+------+------+------+ +------+------+------+------+------+-------------|
117 * | | | | | | | |
118 * +--------------------/ \--------------------+
119 */
120 [_RAISE] = LAYOUT(
121 _______, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, _______,
122 _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_END, _______,
123 _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_HOME, XXXXXXX, KC_PGDN, KC_PGUP, XXXXXXX, XXXXXXX, _______,
124 _______, _______, _______, _______, _______, _______
125 ),
126
127 /* Adjust
128 * ,-----------------------------------------+ +-----------------------------------------.
129 * | | | | | | | | | | | | | |
130 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
131 * | | | | | | |Qwerty| |Colemk| | | | | | |
132 * |------+------+------+------+------+------+------+ +------+------+------+------+------+------+------|
133 * | | | | | | |Reset | |Dvorak| | | | | | |
134 * |------+------+------+------+------+------+------+ +------+------+------+------+------+-------------|
135 * | | | | | | | |
136 * +--------------------/ \--------------------+
137 */
138 [_ADJUST] = LAYOUT(
139 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
140 _______, _______, _______, _______, _______, _______, QWERTY, COLEMAK, _______, _______, _______, _______, _______, _______,
141 _______, _______, _______, _______, _______, _______, RESET, DVORAK, _______, _______, _______, _______, _______, _______,
142 _______, _______, _______, _______, _______, _______
143 )
144};
145
146
147layer_state_t layer_state_set_user(layer_state_t state) {
148 return update_tri_layer_state(state, _RAISE, _LOWER, _ADJUST);
149}
150
151//SSD1306 OLED update loop, make sure to add #define SSD1306OLED in config.h
152#ifdef SSD1306OLED
153
154// You need to add source files to SRC in rules.mk when using OLED display functions
155void set_keylog(uint16_t keycode);
156const char *read_keylog(void);
157const char *read_modifier_state(void);
158const char *read_host_led_state(void);
159
160void matrix_init_user(void) {
161 iota_gfx_init(false); // turns on the display
162}
163
164void matrix_scan_user(void) {
165 iota_gfx_task(); // this is what updates the display continuously
166}
167
168void matrix_update(struct CharacterMatrix *dest, const struct CharacterMatrix *source) {
169 if (memcmp(dest->display, source->display, sizeof(dest->display))) {
170 memcpy(dest->display, source->display, sizeof(dest->display));
171 dest->dirty = true;
172 }
173}
174
175void render_status(struct CharacterMatrix *matrix) {
176 // Layer state
177 char layer_str[22];
178 matrix_write(matrix, "Layer: ");
179 uint8_t layer = biton32(layer_state);
180 uint8_t default_layer = biton32(eeconfig_read_default_layer());
181 switch (layer) {
182 case _QWERTY:
183 switch (default_layer) {
184 case _QWERTY:
185 snprintf(layer_str, sizeof(layer_str), "Qwerty");
186 break;
187 case _COLEMAK:
188 snprintf(layer_str, sizeof(layer_str), "Colemak");
189 break;
190 case _DVORAK:
191 snprintf(layer_str, sizeof(layer_str), "Dvorak");
192 break;
193 default:
194 snprintf(layer_str, sizeof(layer_str), "Undef-%d", default_layer);
195 break;
196 }
197 break;
198 case _RAISE:
199 snprintf(layer_str, sizeof(layer_str), "Raise");
200 break;
201 case _LOWER:
202 snprintf(layer_str, sizeof(layer_str), "Lower");
203 break;
204 case _ADJUST:
205 snprintf(layer_str, sizeof(layer_str), "Adjust");
206 break;
207 default:
208 snprintf(layer_str, sizeof(layer_str), "Undef-%d", layer);
209 }
210 matrix_write_ln(matrix, layer_str);
211 // Last entered keycode
212 matrix_write_ln(matrix, read_keylog());
213 // Modifier state
214 matrix_write_ln(matrix, read_modifier_state());
215 // Host Keyboard LED Status
216 matrix_write(matrix, read_host_led_state());
217}
218
219
220void iota_gfx_task_user(void) {
221 struct CharacterMatrix matrix;
222 matrix_clear(&matrix);
223 render_status(&matrix);
224 matrix_update(&display, &matrix);
225}
226
227#endif//SSD1306OLED
228
229bool process_record_user(uint16_t keycode, keyrecord_t *record) {
230 #ifdef SSD1306OLED
231 if (record->event.pressed) {
232 set_keylog(keycode);
233 }
234 #endif
235 switch (keycode) {
236 case QWERTY:
237 if (record->event.pressed) {
238 set_single_persistent_default_layer(_QWERTY);
239 }
240 break;
241 case COLEMAK:
242 if (record->event.pressed) {
243 set_single_persistent_default_layer(_COLEMAK);
244 }
245 break;
246 case DVORAK:
247 if (record->event.pressed) {
248 set_single_persistent_default_layer(_DVORAK);
249 }
250 break;
251 }
252 return true;
253}
diff --git a/keyboards/comet46/keymaps/default/readme.md b/keyboards/comet46/keymaps/default/readme.md
new file mode 100644
index 000000000..b0085d2a6
--- /dev/null
+++ b/keyboards/comet46/keymaps/default/readme.md
@@ -0,0 +1,3 @@
1## default-oled-display
2
3A keymap that is compatible with receivers with an OLED display.
diff --git a/keyboards/comet46/keymaps/default/rules.mk b/keyboards/comet46/keymaps/default/rules.mk
new file mode 100644
index 000000000..3fa01f96a
--- /dev/null
+++ b/keyboards/comet46/keymaps/default/rules.mk
@@ -0,0 +1,5 @@
1# If you want to change display settings of the OLED, you need to change the following lines
2SRC += ./lib/glcdfont.c \
3 ./lib/keylogger.c \
4 ./lib/modifier_state_reader.c \
5 ./lib/host_led_state_reader.c
diff --git a/keyboards/comet46/keymaps/satt/action_pseudo_lut.c b/keyboards/comet46/keymaps/satt/action_pseudo_lut.c
new file mode 100644
index 000000000..4a7cb3a3a
--- /dev/null
+++ b/keyboards/comet46/keymaps/satt/action_pseudo_lut.c
@@ -0,0 +1,143 @@
1#include "quantum.h"
2#include "command.h"
3#include "action_pseudo_lut.h"
4
5static uint8_t send_key_shift_bit[SHIFT_BIT_SIZE];
6
7/*
8 * Pseudo layout action.
9 * This action converts a keycode in order to output the character according to the keymap you specified
10 * still your keyboard layout recognized wrongly on your OS.
11 * Memo: Using other layer keymap to get keycode
12 */
13void action_pseudo_lut(keyrecord_t *record, uint8_t base_keymap_id, const uint16_t (*keymap)[2]) {
14 uint8_t prev_shift;
15 uint16_t keycode;
16 uint16_t pseudo_keycode;
17
18 /* get keycode from keymap you specified */
19 keycode = keymap_key_to_keycode(base_keymap_id, record->event.key);
20
21 prev_shift = keyboard_report->mods & (MOD_BIT(KC_LSFT) | MOD_BIT(KC_RSFT));
22
23 if (record->event.pressed) {
24 /* when magic commands entered, keycode does not converted */
25 if (IS_COMMAND()) {
26 if (prev_shift) {
27 add_shift_bit(keycode);
28 }
29 register_code(keycode);
30 return;
31 }
32
33 if (prev_shift) {
34 pseudo_keycode = convert_keycode(keymap, keycode, true);
35 dprintf("pressed: %02X, converted: %04X\n", keycode, pseudo_keycode);
36 add_shift_bit(keycode);
37
38 if (IS_LSFT(pseudo_keycode)) {
39 register_code(QK_LSFT ^ pseudo_keycode);
40 } else {
41 /* delete shift mod temporarily */
42 del_mods(prev_shift);
43 send_keyboard_report();
44 register_code(pseudo_keycode);
45 add_mods(prev_shift);
46 send_keyboard_report();
47 }
48 } else {
49 pseudo_keycode = convert_keycode(keymap, keycode, false);
50 dprintf("pressed: %02X, converted: %04X\n", keycode, pseudo_keycode);
51
52 if (IS_LSFT(pseudo_keycode)) {
53 add_weak_mods(MOD_BIT(KC_LSFT));
54 send_keyboard_report();
55 register_code(QK_LSFT ^ pseudo_keycode);
56 /* on Windows, prevent key repeat to avoid unintended output */
57 unregister_code(QK_LSFT ^ pseudo_keycode);
58 del_weak_mods(MOD_BIT(KC_LSFT));
59 send_keyboard_report();
60 } else {
61 register_code(pseudo_keycode);
62 }
63 }
64 } else {
65 if (get_shift_bit(keycode)) {
66 del_shift_bit(keycode);
67 pseudo_keycode = convert_keycode(keymap, keycode, true);
68 } else {
69 pseudo_keycode = convert_keycode(keymap, keycode, false);
70 }
71 dprintf("released: %02X, converted: %04X\n", keycode, pseudo_keycode);
72
73 if (IS_LSFT(pseudo_keycode)) {
74 unregister_code(QK_LSFT ^ pseudo_keycode);
75 } else {
76 unregister_code(pseudo_keycode);
77 }
78 }
79}
80
81uint16_t convert_keycode(const uint16_t (*keymap)[2], uint16_t keycode, bool shift_modded)
82{
83 uint16_t pseudo_keycode;
84
85 switch (keycode) {
86 case KC_A ... KC_CAPSLOCK:
87 #if defined(__AVR__)
88 if (shift_modded) {
89 pseudo_keycode = pgm_read_word(&keymap[keycode][1]);
90 } else {
91 pseudo_keycode = pgm_read_word(&keymap[keycode][0]);
92 }
93 #else
94 if (shift_modded) {
95 pseudo_keycode = keymap[keycode][1];
96 } else {
97 pseudo_keycode = keymap[keycode][0];
98 }
99 #endif
100 /* if undefined, use got keycode as it is */
101 if (pseudo_keycode == 0x00) {
102 if (shift_modded) {
103 pseudo_keycode = S(keycode);
104 } else {
105 pseudo_keycode = keycode;
106 }
107 }
108 break;
109 default:
110 if (shift_modded) {
111 pseudo_keycode = S(keycode);
112 } else {
113 pseudo_keycode = keycode;
114 }
115 break;
116 }
117 return pseudo_keycode;
118}
119
120uint8_t get_shift_bit(uint16_t keycode) {
121 if ((keycode >> 3) < SHIFT_BIT_SIZE) {
122 return send_key_shift_bit[keycode >> 3] & (1 << (keycode & 7));
123 } else {
124 dprintf("get_shift_bit: Can't get shift bit. keycode: %02X\n", keycode);
125 return 0;
126 }
127}
128
129void add_shift_bit(uint16_t keycode) {
130 if ((keycode >> 3) < SHIFT_BIT_SIZE) {
131 send_key_shift_bit[keycode >> 3] |= (1 << (keycode & 7));
132 } else {
133 dprintf("add_shift_bit: Can't add shift bit. keycode: %02X\n", keycode);
134 }
135}
136
137void del_shift_bit(uint16_t keycode) {
138 if ((keycode >> 3) < SHIFT_BIT_SIZE) {
139 send_key_shift_bit[keycode >> 3] &= ~(1 << (keycode & 7));
140 } else {
141 dprintf("del_shift_bit: Can't delete shift bit. keycode: %02X\n", keycode);
142 }
143}
diff --git a/keyboards/comet46/keymaps/satt/action_pseudo_lut.h b/keyboards/comet46/keymaps/satt/action_pseudo_lut.h
new file mode 100644
index 000000000..681252440
--- /dev/null
+++ b/keyboards/comet46/keymaps/satt/action_pseudo_lut.h
@@ -0,0 +1,15 @@
1#ifndef ACTION_PSEUDO_LUT_H
2#define ACTION_PSEUDO_LUT_H
3
4#define SHIFT_BIT_SIZE (0xE7 / 8 + 1) // 1bit per 1key
5
6#define IS_LSFT(kc) ((QK_LSFT & (kc)) == QK_LSFT)
7
8void action_pseudo_lut(keyrecord_t *, uint8_t, const uint16_t (*)[2]);
9uint16_t convert_keycode(const uint16_t (*)[2], uint16_t, bool);
10
11uint8_t get_shift_bit(uint16_t);
12void add_shift_bit(uint16_t);
13void del_shift_bit(uint16_t);
14
15#endif
diff --git a/keyboards/comet46/keymaps/satt/config.h b/keyboards/comet46/keymaps/satt/config.h
new file mode 100644
index 000000000..a3ca2ebfe
--- /dev/null
+++ b/keyboards/comet46/keymaps/satt/config.h
@@ -0,0 +1,29 @@
1/*
2This is the c configuration file for the keymap
3
4Copyright 2012 Jun Wako <[email protected]>
5Copyright 2015 Jack Humbert
6
7This program is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#ifndef CONFIG_USER_H
22#define CONFIG_USER_H
23
24/* Use I2C or Serial */
25
26#define USE_I2C
27#define SSD1306OLED
28
29#endif
diff --git a/keyboards/comet46/keymaps/satt/keymap.c b/keyboards/comet46/keymaps/satt/keymap.c
new file mode 100644
index 000000000..57aa63593
--- /dev/null
+++ b/keyboards/comet46/keymaps/satt/keymap.c
@@ -0,0 +1,288 @@
1// this is the style you want to emulate.
2// This is the canonical layout file for the Quantum project. If you want to add another keyboard,
3
4#include QMK_KEYBOARD_H
5#include "keymap_jis2us.h"
6#include "action_pseudo_lut.h"
7#include "keymap_jp.h"
8#ifdef SSD1306OLED
9 #include "ssd1306.h"
10#endif
11
12// Each layer gets a name for readability, which is then used in the keymap matrix below.
13// The underscores don't mean anything - you can have a layer called STUFF or any other name.
14// Layer names don't all need to be of the same length, obviously, and you can also skip them
15// entirely and just use numbers.
16enum comet46_layers {
17 _QWERTY,
18 _LOWER,
19 _RAISE,
20 _PSEUDO_US,
21 _PSEUDO_US_LOWER,
22 _PSEUDO_US_RAISE,
23 _ADJUST
24};
25
26enum custom_keycodes {
27 QWERTY = SAFE_RANGE,
28 PSEUDO_US,
29 JIS2US,
30};
31
32// JIS keycodes
33#define KC_JZHT JP_ZKHK // hankaku/zenkaku|kanzi
34#define KC_JCIR JP_CIRC // ^, ~
35#define KC_JAT JP_AT // @, `
36#define KC_JLBR JP_LBRC // [, {
37#define KC_JCOL JP_COLN // :, *
38#define KC_JRBR JP_RBRC // ], }
39#define KC_JBSL JP_BSLS // \, _
40#define KC_JMHE JP_MHEN // muhenkan
41#define KC_JHEN JP_HENK // henkan
42#define KC_JKAN JP_KANA // katakana/hiragana|ro-mazi
43#define KC_JMKA JP_LANG1 //kana on MacOSX
44#define KC_JMEI KC_LANG2 //eisu on MacOSX
45#define KC_JAMP JP_AMPR // &
46#define KC_JQUO JP_QUOT // '
47#define KC_JLPR JP_LPRN // (
48#define KC_JRPR JP_RPRN // )
49#define KC_JEQL JP_EQL // =
50#define KC_JTIL JP_TILD // ~
51#define KC_JPIP JP_PIPE // |
52#define KC_JGRV JP_GRV // `
53#define KC_JLCB JP_LCBR // {
54#define KC_JPLU JP_PLUS // +
55#define KC_JAST JP_ASTR // *
56#define KC_JRCB JP_RCBR // }
57#define KC_JUND JP_UNDS // _
58
59// Layer related keycodes
60#define KC_LWR MO(_LOWER)
61#define KC_RSE MO(_RAISE)
62#define KC_P_LW MO(_PSEUDO_US_LOWER)
63#define KC_P_RS MO(_PSEUDO_US_RAISE)
64#define KC_QWRT QWERTY
65#define KC_P_US PSEUDO_US
66#define KC_J2US JIS2US
67
68// Special keycodes
69#define KC_SPCT CTL_T(KC_SPC)
70#define KC_ENSF SFT_T(KC_ENT)
71#define KC_CAEC MT(MOD_LCTL | MOD_LALT, KC_ESC)
72#define KC_CSTB C_S_T(KC_TAB)
73#define KC_IMON ALT_T(KC_F13)
74#define KC_IMOF GUI_T(KC_F14)
75#define KC_CAD LCA(KC_DEL)
76#define KC_RST RESET
77
78const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
79
80 [_QWERTY] = LAYOUT(
81 //,----+----+----+----+----+----+ +----+----+----+----+----+----.
82 KC_CAEC, KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P ,KC_DEL ,
83 //|----+----+----+----+----+----+----+ +----+----+----+----+----+----+----|
84 KC_CSTB, KC_A , KC_S , KC_D , KC_F , KC_G ,KC_LPRN, KC_RPRN, KC_H , KC_J , KC_K , KC_L ,KC_SCLN,KC_BSPC,
85 //|----+----+----+----+----+----+----| |----+----+----+----+----+----+----|
86 KC_LSFT, KC_Z , KC_X , KC_C , KC_V , KC_B ,KC_LBRC, KC_RBRC, KC_N , KC_M ,KC_COMM,KC_DOT ,KC_SLSH,KC_QUOT,
87 //|----+----+----+----+----+----+----| |----+----+----+----+----+----+----|
88 KC_IMOF,KC_LWR ,KC_SPCT, KC_ENSF,KC_RSE ,KC_IMON
89 // +----+----+---/ \---+----+----+
90 ),
91
92 [_LOWER] = LAYOUT(
93 //,----+----+----+----+----+----+ +----+----+----+----+----+----.
94 _______,KC_EXLM, KC_AT ,KC_HASH,KC_DLR ,KC_PERC, KC_CIRC,KC_AMPR,KC_ASTR,KC_LPRN,KC_RPRN,_______,
95 //|----+----+----+----+----+----+----+ +----+----+----+----+----+----+----|
96 _______, KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_F6 , KC_GRV ,KC_BSLS,KC_MINS,KC_EQL ,KC_LBRC,KC_RBRC,_______,
97 //|----+----+----+----+----+----+----| |----+----+----+----+----+----+----|
98 _______, KC_F7 , KC_F8 , KC_F9 , KC_F10, KC_F11, KC_F12, KC_TILD,KC_PIPE,KC_UNDS,KC_PLUS,KC_LCBR,KC_RCBR,_______,
99 //|----+----+----+----+----+----+----| |----+----+----+----+----+----+----|
100 _______,_______,_______, _______,_______,_______
101 // +----+----+---/ \---+----+----+
102 ),
103
104 [_RAISE] = LAYOUT(
105 //,----+----+----+----+----+----+ +----+----+----+----+----+----.
106 _______, KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 ,_______,
107 //|----+----+----+----+----+----+----+ +----+----+----+----+----+----+----|
108 _______,_______,_______,_______,_______,_______,_______, XXXXXXX,KC_LEFT,KC_DOWN, KC_UP ,KC_RGHT,KC_END ,_______,
109 //|----+----+----+----+----+----+----| |----+----+----+----+----+----+----|
110 _______,_______,_______,_______,_______,_______,_______, KC_HOME,XXXXXXX,KC_PGDN,KC_PGUP,XXXXXXX,XXXXXXX,_______,
111 //|----+----+----+----+----+----+----| |----+----+----+----+----+----+----|
112 _______,_______,_______, _______,_______,_______
113 // +----+----+---/ \---+----+----+
114 ),
115
116 [_PSEUDO_US] = LAYOUT(
117 //,----+----+----+----+----+----+ +----+----+----+----+----+----.
118 KC_CAEC, KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P ,KC_DEL ,
119 //|----+----+----+----+----+----+----+ +----+----+----+----+----+----+----|
120 KC_CSTB, KC_A , KC_S , KC_D , KC_F , KC_G ,KC_JLPR, KC_JRPR, KC_H , KC_J , KC_K , KC_L ,KC_J2US,KC_BSPC,
121 //|----+----+----+----+----+----+----| |----+----+----+----+----+----+----|
122 KC_LSFT, KC_Z , KC_X , KC_C , KC_V , KC_B ,KC_J2US, KC_J2US, KC_N , KC_M ,KC_COMM,KC_DOT ,KC_SLSH,KC_J2US,
123 //|----+----+----+----+----+----+----| |----+----+----+----+----+----+----|
124 KC_IMOF,KC_P_LW,KC_SPCT, KC_ENSF,KC_P_RS,KC_IMON
125 // +----+----+---/ \---+----+----+
126 ),
127
128
129 [_PSEUDO_US_LOWER] = LAYOUT(
130 //,----+----+----+----+----+----+ +----+----+----+----+----+----.
131 _______,KC_EXLM,KC_JAT ,KC_HASH,KC_DLR ,KC_PERC, KC_JCIR,KC_JAMP,KC_JAST,KC_JLPR,KC_JRPR,_______,
132 //|----+----+----+----+----+----+----+ +----+----+----+----+----+----+----|
133 _______, KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_F6 , KC_JGRV,KC_JBSL,KC_MINS,KC_JEQL,KC_JLBR,KC_JRBR,_______,
134 //|----+----+----+----+----+----+----| |----+----+----+----+----+----+----|
135 _______, KC_F7 , KC_F8 , KC_F9 , KC_F10, KC_F11, KC_F12, KC_JTIL,KC_JPIP,KC_JUND,KC_JPLU,KC_JLCB,KC_JRCB,_______,
136 //|----+----+----+----+----+----+----| |----+----+----+----+----+----+----|
137 _______,_______,_______, _______,_______,_______
138 // +----+----+---/ \---+----+----+
139 ),
140
141 [_PSEUDO_US_RAISE] = LAYOUT(
142 //,----+----+----+----+----+----+ +----+----+----+----+----+----.
143 _______, KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 ,_______,
144 //|----+----+----+----+----+----+----+ +----+----+----+----+----+----+----|
145 _______,_______,_______,_______,_______,_______,KC_JZHT, XXXXXXX,KC_LEFT,KC_DOWN, KC_UP ,KC_RGHT,KC_END ,_______,
146 //|----+----+----+----+----+----+----| |----+----+----+----+----+----+----|
147 _______,_______,_______,_______,_______,_______,_______, KC_HOME,XXXXXXX,KC_PGDN,KC_PGUP,XXXXXXX,XXXXXXX,_______,
148 //|----+----+----+----+----+----+----| |----+----+----+----+----+----+----|
149 _______,_______,_______, _______,_______,_______
150 // +----+----+---/ \---+----+----+
151 ),
152
153 [_ADJUST] = LAYOUT(
154 //,----+----+----+----+----+----+ +----+----+----+----+----+----.
155 _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______,
156 //|----+----+----+----+----+----+----+ +----+----+----+----+----+----+----|
157 _______,_______,_______,_______,_______,_______,KC_CAD , KC_QWRT,_______,_______,_______,_______,_______,_______,
158 //|----+----+----+----+----+----+----| |----+----+----+----+----+----+----|
159 _______,_______,_______,_______,_______,_______,KC_RST , KC_P_US,_______,_______,_______,_______,_______,_______,
160 //|----+----+----+----+----+----+----| |----+----+----+----+----+----+----|
161 _______,_______,_______, _______,_______,_______
162 // +----+----+---/ \---+----+----+
163 )
164
165};
166
167layer_state_t layer_state_set_user(layer_state_t state) {
168 switch (biton32(state)) {
169 case _PSEUDO_US_LOWER:
170 case _PSEUDO_US_RAISE:
171 return update_tri_layer_state(state, _PSEUDO_US_RAISE, _PSEUDO_US_LOWER, _ADJUST);
172 break;
173 default:
174 return update_tri_layer_state(state, _RAISE, _LOWER, _ADJUST);
175 break;
176 }
177}
178
179//SSD1306 OLED update loop, make sure to add #define SSD1306OLED in config.h
180#ifdef SSD1306OLED
181
182// You need to add source files to SRC in rules.mk when using OLED display functions
183void set_keylog(uint16_t keycode);
184const char *read_keylog(void);
185const char *read_modifier_state(void);
186const char *read_host_led_state(void);
187
188void matrix_init_user(void) {
189 iota_gfx_init(false); // turns on the display
190}
191
192void matrix_scan_user(void) {
193 iota_gfx_task(); // this is what updates the display continuously
194}
195
196void matrix_update(struct CharacterMatrix *dest, const struct CharacterMatrix *source) {
197 if (memcmp(dest->display, source->display, sizeof(dest->display))) {
198 memcpy(dest->display, source->display, sizeof(dest->display));
199 dest->dirty = true;
200 }
201}
202
203void render_status(struct CharacterMatrix *matrix) {
204 // Layer state
205 char layer_str[22];
206 matrix_write(matrix, "Layer: ");
207 uint8_t layer = biton32(layer_state);
208 uint8_t default_layer = biton32(eeconfig_read_default_layer());
209 switch (layer) {
210 case _QWERTY:
211 switch (default_layer) {
212 case _QWERTY:
213 snprintf(layer_str, sizeof(layer_str), "Qwerty");
214 break;
215 case _PSEUDO_US:
216 snprintf(layer_str, sizeof(layer_str), "Psuedo_US");
217 break;
218 default:
219 snprintf(layer_str, sizeof(layer_str), "Undef-%d", default_layer);
220 break;
221 }
222 break;
223 case _RAISE:
224 snprintf(layer_str, sizeof(layer_str), "Raise");
225 break;
226 case _LOWER:
227 snprintf(layer_str, sizeof(layer_str), "Lower");
228 break;
229 case _PSEUDO_US_RAISE:
230 snprintf(layer_str, sizeof(layer_str), "P_US_Raise");
231 break;
232 case _PSEUDO_US_LOWER:
233 snprintf(layer_str, sizeof(layer_str), "P_US_Lower");
234 break;
235 case _ADJUST:
236 snprintf(layer_str, sizeof(layer_str), "Adjust");
237 break;
238 default:
239 snprintf(layer_str, sizeof(layer_str), "Undef-%d", layer);
240 }
241 matrix_write_ln(matrix, layer_str);
242 // Last entered keycode
243 matrix_write_ln(matrix, read_keylog());
244 // Modifier state
245 matrix_write_ln(matrix, read_modifier_state());
246 // Host Keyboard LED Status
247 matrix_write(matrix, read_host_led_state());
248}
249
250void iota_gfx_task_user(void) {
251 struct CharacterMatrix matrix;
252
253#if DEBUG_TO_SCREEN
254 if (debug_enable) {
255 return;
256 }
257#endif
258
259 matrix_clear(&matrix);
260 render_status(&matrix);
261 matrix_update(&display, &matrix);
262}
263
264#endif//SSD1306OLED
265
266bool process_record_user(uint16_t keycode, keyrecord_t *record) {
267 #ifdef SSD1306OLED
268 if (record->event.pressed) {
269 set_keylog(keycode);
270 }
271 #endif
272 switch (keycode) {
273 case QWERTY:
274 if (record->event.pressed) {
275 set_single_persistent_default_layer(_QWERTY);
276 }
277 break;
278 case PSEUDO_US:
279 if (record->event.pressed) {
280 set_single_persistent_default_layer(_PSEUDO_US);
281 }
282 break;
283 case JIS2US:
284 action_pseudo_lut(record, _QWERTY, keymap_jis2us);
285 break;
286 }
287 return true;
288}
diff --git a/keyboards/comet46/keymaps/satt/keymap_jis2us.h b/keyboards/comet46/keymaps/satt/keymap_jis2us.h
new file mode 100644
index 000000000..e32a0579a
--- /dev/null
+++ b/keyboards/comet46/keymaps/satt/keymap_jis2us.h
@@ -0,0 +1,32 @@
1#ifndef KEYMAP_JIS2US_H
2#define KEYMAP_JIS2US_H
3
4/* keymap for convert from JIS to US */
5const uint16_t PROGMEM keymap_jis2us[][2] = {
6 [KC_A ... KC_CAPS] = { 0x00, 0x00 }, /* default value */
7
8 [KC_1] = { KC_1, KC_EXLM }, /* 1 and ! -> 1 and ! */
9 [KC_2] = { KC_2, KC_LBRC }, /* 2 and " -> 2 and @ */
10 [KC_3] = { KC_3, KC_HASH }, /* 3 and # -> 3 and # */
11 [KC_4] = { KC_4, KC_DLR }, /* 4 and $ -> 4 and $ */
12 [KC_5] = { KC_5, KC_PERC }, /* 5 and % -> 5 and % */
13 [KC_6] = { KC_6, KC_EQL }, /* 6 and & -> 6 and ^ */
14 [KC_7] = { KC_7, KC_CIRC }, /* 7 and ' -> 7 and & */
15 [KC_8] = { KC_8, KC_DQT }, /* 8 and ( -> 8 and * */
16 [KC_9] = { KC_9, KC_ASTR }, /* 9 and ) -> 9 and ( */
17 [KC_0] = { KC_0, KC_LPRN }, /* 0 and (no assign) -> 0 and ) */
18 [KC_MINS] = { KC_MINS, S(KC_RO) }, /* - and = -> - and _ */
19 [KC_EQL] = { KC_UNDS, KC_COLN }, /* ^ and ~ -> = and + */
20 [KC_LBRC] = { KC_RBRC, KC_RCBR }, /* @ and ` -> [ and { */
21 [KC_RBRC] = { KC_BSLS, KC_PIPE }, /* [ and { -> ] and } */
22 [KC_BSLS] = { KC_JYEN, S(KC_JYEN) }, /* ] and } -> / and | */
23 [KC_NUHS] = { KC_NUHS, S(KC_NUHS) }, /* (no assign) */
24 [KC_SCLN] = { KC_SCLN, KC_QUOT }, /* ; and + -> ; and : */
25 [KC_QUOT] = { KC_AMPR, KC_AT }, /* : and * -> ' and " */
26 [KC_GRV] = { KC_LCBR, KC_PLUS }, /* (no assign) -> ` and ~ */
27 [KC_COMM] = { KC_COMM, KC_LT }, /* , and < -> , and < */
28 [KC_DOT] = { KC_DOT, KC_GT }, /* . and > -> . and > */
29 [KC_SLSH] = { KC_SLSH, KC_QUES }, /* / and ? -> / and ? */
30};
31
32#endif
diff --git a/keyboards/comet46/keymaps/satt/readme.md b/keyboards/comet46/keymaps/satt/readme.md
new file mode 100644
index 000000000..33bbad326
--- /dev/null
+++ b/keyboards/comet46/keymaps/satt/readme.md
@@ -0,0 +1,6 @@
1## Pseudo US Layout
2
3On a Japanese Windows environment, ANSI keyboards may be recognized wrongly as a JIS keyboard.
4By using this code, you can use your ANSI keyboard under a JIS keyboard environment without changing the settings and registry of your environment.
5
6Original code by [Shela](https://github.com/qmk/qmk_firmware/tree/master/keyboards/hhkb/keymaps/shela)
diff --git a/keyboards/comet46/keymaps/satt/rules.mk b/keyboards/comet46/keymaps/satt/rules.mk
new file mode 100644
index 000000000..91609dd4f
--- /dev/null
+++ b/keyboards/comet46/keymaps/satt/rules.mk
@@ -0,0 +1,8 @@
1SRC += action_pseudo_lut.c
2
3# If you want to change display settings of the OLED, you need to change the following lines
4SRC += ./lib/glcdfont.c \
5 ./lib/keylogger.c \
6 ./lib/modifier_state_reader.c \
7 ./lib/host_led_state_reader.c
8
diff --git a/keyboards/comet46/lib/glcdfont.c b/keyboards/comet46/lib/glcdfont.c
new file mode 100644
index 000000000..361d0c3dc
--- /dev/null
+++ b/keyboards/comet46/lib/glcdfont.c
@@ -0,0 +1,137 @@
1// This is the 'classic' fixed-space bitmap font for Adafruit_GFX since 1.0.
2// See gfxfont.h for newer custom bitmap font info.
3
4#include "progmem.h"
5
6// Standard ASCII 5x7 font
7
8const unsigned char font[] PROGMEM = {
9 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00,
11 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00,
12 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00,
13 0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x00,
14 0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00,
15 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00,
16 0x00, 0x18, 0x3C, 0x18, 0x00, 0x00,
17 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00,
18 0x00, 0x18, 0x24, 0x18, 0x00, 0x00,
19 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00,
20 0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00,
21 0x26, 0x29, 0x79, 0x29, 0x26, 0x00,
22 0x40, 0x7F, 0x05, 0x05, 0x07, 0x00,
23 0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00,
24 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x00,
25 0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00,
26 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00,
27 0x14, 0x22, 0x7F, 0x22, 0x14, 0x00,
28 0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00,
29 0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00,
30 0x00, 0x66, 0x89, 0x95, 0x6A, 0x00,
31 0x60, 0x60, 0x60, 0x60, 0x60, 0x00,
32 0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00,
33 0x08, 0x04, 0x7E, 0x04, 0x08, 0x00,
34 0x10, 0x20, 0x7E, 0x20, 0x10, 0x00,
35 0x08, 0x08, 0x2A, 0x1C, 0x08, 0x00,
36 0x08, 0x1C, 0x2A, 0x08, 0x08, 0x00,
37 0x1E, 0x10, 0x10, 0x10, 0x10, 0x00,
38 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x00,
39 0x30, 0x38, 0x3E, 0x38, 0x30, 0x00,
40 0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00,
41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00,
43 0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
44 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00,
45 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00,
46 0x23, 0x13, 0x08, 0x64, 0x62, 0x00,
47 0x36, 0x49, 0x56, 0x20, 0x50, 0x00,
48 0x00, 0x08, 0x07, 0x03, 0x00, 0x00,
49 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00,
50 0x00, 0x41, 0x22, 0x1C, 0x00, 0x00,
51 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00,
52 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00,
53 0x00, 0x80, 0x70, 0x30, 0x00, 0x00,
54 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
55 0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
56 0x20, 0x10, 0x08, 0x04, 0x02, 0x00,
57 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00,
58 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00,
59 0x72, 0x49, 0x49, 0x49, 0x46, 0x00,
60 0x21, 0x41, 0x49, 0x4D, 0x33, 0x00,
61 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00,
62 0x27, 0x45, 0x45, 0x45, 0x39, 0x00,
63 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00,
64 0x41, 0x21, 0x11, 0x09, 0x07, 0x00,
65 0x36, 0x49, 0x49, 0x49, 0x36, 0x00,
66 0x46, 0x49, 0x49, 0x29, 0x1E, 0x00,
67 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
68 0x00, 0x40, 0x34, 0x00, 0x00, 0x00,
69 0x00, 0x08, 0x14, 0x22, 0x41, 0x00,
70 0x14, 0x14, 0x14, 0x14, 0x14, 0x00,
71 0x00, 0x41, 0x22, 0x14, 0x08, 0x00,
72 0x02, 0x01, 0x59, 0x09, 0x06, 0x00,
73 0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00,
74 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00,
75 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00,
76 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00,
77 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00,
78 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00,
79 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00,
80 0x3E, 0x41, 0x41, 0x51, 0x73, 0x00,
81 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00,
82 0x00, 0x41, 0x7F, 0x41, 0x00, 0x00,
83 0x20, 0x40, 0x41, 0x3F, 0x01, 0x00,
84 0x7F, 0x08, 0x14, 0x22, 0x41, 0x00,
85 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00,
86 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00,
87 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00,
88 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00,
89 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00,
90 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00,
91 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00,
92 0x26, 0x49, 0x49, 0x49, 0x32, 0x00,
93 0x03, 0x01, 0x7F, 0x01, 0x03, 0x00,
94 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00,
95 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00,
96 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00,
97 0x63, 0x14, 0x08, 0x14, 0x63, 0x00,
98 0x03, 0x04, 0x78, 0x04, 0x03, 0x00,
99 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00,
100 0x00, 0x7F, 0x41, 0x41, 0x41, 0x00,
101 0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
102 0x00, 0x41, 0x41, 0x41, 0x7F, 0x00,
103 0x04, 0x02, 0x01, 0x02, 0x04, 0x00,
104 0x40, 0x40, 0x40, 0x40, 0x40, 0x00,
105 0x00, 0x03, 0x07, 0x08, 0x00, 0x00,
106 0x20, 0x54, 0x54, 0x78, 0x40, 0x00,
107 0x7F, 0x28, 0x44, 0x44, 0x38, 0x00,
108 0x38, 0x44, 0x44, 0x44, 0x28, 0x00,
109 0x38, 0x44, 0x44, 0x28, 0x7F, 0x00,
110 0x38, 0x54, 0x54, 0x54, 0x18, 0x00,
111 0x00, 0x08, 0x7E, 0x09, 0x02, 0x00,
112 0x18, 0xA4, 0xA4, 0x9C, 0x78, 0x00,
113 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00,
114 0x00, 0x44, 0x7D, 0x40, 0x00, 0x00,
115 0x20, 0x40, 0x40, 0x3D, 0x00, 0x00,
116 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00,
117 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00,
118 0x7C, 0x04, 0x78, 0x04, 0x78, 0x00,
119 0x7C, 0x08, 0x04, 0x04, 0x78, 0x00,
120 0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
121 0xFC, 0x18, 0x24, 0x24, 0x18, 0x00,
122 0x18, 0x24, 0x24, 0x18, 0xFC, 0x00,
123 0x7C, 0x08, 0x04, 0x04, 0x08, 0x00,
124 0x48, 0x54, 0x54, 0x54, 0x24, 0x00,
125 0x04, 0x04, 0x3F, 0x44, 0x24, 0x00,
126 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00,
127 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00,
128 0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00,
129 0x44, 0x28, 0x10, 0x28, 0x44, 0x00,
130 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00,
131 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00,
132 0x00, 0x08, 0x36, 0x41, 0x00, 0x00,
133 0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
134 0x00, 0x41, 0x36, 0x08, 0x00, 0x00,
135 0x02, 0x01, 0x02, 0x04, 0x02, 0x00,
136 0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00
137};
diff --git a/keyboards/comet46/lib/host_led_state_reader.c b/keyboards/comet46/lib/host_led_state_reader.c
new file mode 100644
index 000000000..864b1e244
--- /dev/null
+++ b/keyboards/comet46/lib/host_led_state_reader.c
@@ -0,0 +1,15 @@
1#include <stdio.h>
2#include "comet46.h"
3
4char host_led_state_str[22];
5
6const char *read_host_led_state(void) {
7 uint8_t leds = host_keyboard_leds();
8
9 snprintf(host_led_state_str, sizeof(host_led_state_str), "Lock: %s%s%s",
10 (leds & (1 << USB_LED_CAPS_LOCK)) ? "CAPL " : "",
11 (leds & (1 << USB_LED_SCROLL_LOCK)) ? "SCRL " : "",
12 (leds & (1 << USB_LED_NUM_LOCK)) ? "NUML" : "");
13
14 return host_led_state_str;
15}
diff --git a/keyboards/comet46/lib/keylogger.c b/keyboards/comet46/lib/keylogger.c
new file mode 100644
index 000000000..a0abdd79a
--- /dev/null
+++ b/keyboards/comet46/lib/keylogger.c
@@ -0,0 +1,288 @@
1#include <stdio.h>
2#include "progmem.h"
3
4#define NUM_USB_HID_KEYCODES 255
5#define LEN_KEYCODE_STR 4
6
7char keylog[22] = {"KC: ID: "};
8
9// Quick and dirty way to display USB HID keycodes used in QMK
10// USB HID keycodes from 0x0000 to 0x00FF are stored in a 4x256+1 length char
11const char code_to_name[] PROGMEM = {
12 "NO " //0x00
13 "TRNS"
14 "? "
15 "? "
16 "A "
17 "B "
18 "C "
19 "D "
20 "E "
21 "F "
22 "G "
23 "H "
24 "I "
25 "J "
26 "K "
27 "L "
28 "M " //0x10
29 "N "
30 "O "
31 "P "
32 "Q "
33 "R "
34 "S "
35 "T "
36 "U "
37 "V "
38 "W "
39 "X "
40 "Y "
41 "Z "
42 "1 "
43 "2 "
44 "3 " //0x20
45 "4 "
46 "5 "
47 "6 "
48 "7 "
49 "8 "
50 "9 "
51 "0 "
52 "ENT "
53 "ESC "
54 "BSPC"
55 "TAB "
56 "SPC "
57 "MINS"
58 "EQL "
59 "LBRC"
60 "RBRC" //0x30
61 "BSLS"
62 "NUHS"
63 "SCLN"
64 "QUOT"
65 "GRV "
66 "COMM"
67 "DOT "
68 "SLSH"
69 "CAPS"
70 "F1 "
71 "F2 "
72 "F3 "
73 "F4 "
74 "F5 "
75 "F6 "
76 "F7 " //0x40
77 "F8 "
78 "F9 "
79 "F10 "
80 "F11 "
81 "F12 "
82 "PSCR"
83 "SLCK"
84 "PAUS"
85 "INS "
86 "HOME"
87 "PGUP"
88 "DEL "
89 "END "
90 "PGDN"
91 "RGHT"
92 "LEFT" //0x50
93 "DOWN"
94 "UP "
95 "NLCK"
96 "PSLS"
97 "PAST"
98 "PMNS"
99 "PPLS"
100 "PENT"
101 "P1 "
102 "P2 "
103 "P3 "
104 "P4 "
105 "P5 "
106 "P6 "
107 "P7 "
108 "P8 " //0x60
109 "P9 "
110 "P0 "
111 "PDOT"
112 "NUBS"
113 "APP "
114 "POW "
115 "PEQL"
116 "F13 "
117 "F14 "
118 "F15 "
119 "F16 "
120 "F17 "
121 "F18 "
122 "F19 "
123 "F20 "
124 "F21 " //0x70
125 "F22 "
126 "F23 "
127 "F24 "
128 "EXEC"
129 "HELP"
130 "MENU"
131 "SLCT"
132 "STOP"
133 "AGIN"
134 "UNDO"
135 "CUT "
136 "COPY"
137 "PSTE"
138 "FIND"
139 "_MUT"
140 "_VUP" //0x80
141 "_VDN"
142 "LCAP"
143 "LNUM"
144 "LSCR"
145 "PCMM"
146 "PEQA"
147 "INT1"
148 "INT2"
149 "INT3"
150 "INT4"
151 "INT5"
152 "INT6"
153 "INT7"
154 "INT8"
155 "INT9"
156 "LAN1" //0x90
157 "LAN2"
158 "LAN3"
159 "LAN4"
160 "LAN5"
161 "LAN6"
162 "LAN7"
163 "LAN8"
164 "LAN9"
165 "ERAS"
166 "SYSR"
167 "CNCL"
168 "CLR "
169 "PRIR"
170 "RTRN"
171 "SEP "
172 "OUT " //0xA0
173 "OPER"
174 "CLRA"
175 "CSEL"
176 "ESEL"
177 "PWR " //0xA5
178 "SLEP"
179 "WAKE"
180 "MUTE"
181 "VOLU"
182 "VOLD"
183 "MNXT"
184 "MPRV"
185 "MSTP"
186 "MPLY"
187 "MSEL"
188 "EJCT" //0xB0
189 "MAIL"
190 "CALC"
191 "MYCM"
192 "WSCH"
193 "WHOM"
194 "WBAK"
195 "WFWD"
196 "WSTP"
197 "WREF"
198 "WFAV"
199 "MFFD"
200 "MRWD"
201 "BRIU"
202 "BRID"
203 "? "
204 "FN0 " //0xC0
205 "FN1 "
206 "FN2 "
207 "FN3 "
208 "FN4 "
209 "FN5 "
210 "FN6 "
211 "FN7 "
212 "FN8 "
213 "FN9 "
214 "FN10"
215 "FN11"
216 "FN12"
217 "FN13"
218 "FN14"
219 "FN15"
220 "FN16" //0xD0
221 "FN17"
222 "FN18"
223 "FN19"
224 "FN20"
225 "FN21"
226 "FN22"
227 "FN23"
228 "FN24"
229 "FN25"
230 "FN26"
231 "FN27"
232 "FN28"
233 "FN29"
234 "FN30"
235 "FN31"
236 "LCTL" //0xE0
237 "LSFT"
238 "LALT"
239 "LGUI"
240 "RCTL"
241 "RSFT"
242 "RALT"
243 "RGUI"
244 "? "
245 "? "
246 "? "
247 "? "
248 "? "
249 "? "
250 "? "
251 "? "
252 "MS_U" //0xF0
253 "MS_D"
254 "MS_L"
255 "MS_R"
256 "BTN1"
257 "BTN2"
258 "BTN3"
259 "BTN4"
260 "BTN5"
261 "WH_U"
262 "WH_D"
263 "WH_L"
264 "WH_R"
265 "ACL0"
266 "ACL1"
267 "ACL2"
268};
269
270void set_keylog(uint16_t keycode)
271{
272 char name[LEN_KEYCODE_STR+1] = "? ";
273
274 if (keycode <= NUM_USB_HID_KEYCODES) {
275 for (uint8_t k = 0; k < LEN_KEYCODE_STR; k++) {
276 name[k] = pgm_read_byte_near(code_to_name + keycode * LEN_KEYCODE_STR + k);
277 }
278 } else if (keycode > NUM_USB_HID_KEYCODES) {
279 snprintf(name, sizeof(name), "QMK ");
280 }
281
282 // update keylog
283 snprintf(keylog, sizeof(keylog), "KC: %s ID: %d", name, keycode);
284}
285
286const char *read_keylog(void) {
287 return keylog;
288}
diff --git a/keyboards/comet46/lib/modifier_state_reader.c b/keyboards/comet46/lib/modifier_state_reader.c
new file mode 100644
index 000000000..518eef92a
--- /dev/null
+++ b/keyboards/comet46/lib/modifier_state_reader.c
@@ -0,0 +1,18 @@
1#include <stdio.h>
2#include "comet46.h"
3
4char modifier_state_str[22];
5
6const char *read_modifier_state(void) {
7 uint8_t modifiers = get_mods();
8 uint8_t one_shot = get_oneshot_mods();
9
10 snprintf(modifier_state_str, sizeof(modifier_state_str), "Mod: %s%s%s%s",
11 (modifiers & MODS_CTRL_MASK || one_shot & MODS_CTRL_MASK) ? "CTL " : "",
12 (modifiers & MODS_GUI_MASK || one_shot & MODS_GUI_MASK) ? "GUI " : "",
13 (modifiers & MODS_ALT_MASK || one_shot & MODS_ALT_MASK) ? "ALT " : "",
14 (modifiers & MODS_SHIFT_MASK || one_shot & MODS_SHIFT_MASK) ? "SFT" : ""
15 );
16
17 return modifier_state_str;
18}
diff --git a/keyboards/comet46/matrix.c b/keyboards/comet46/matrix.c
new file mode 100644
index 000000000..34930af7e
--- /dev/null
+++ b/keyboards/comet46/matrix.c
@@ -0,0 +1,154 @@
1/*
2Copyright 2012 Jun Wako
3Copyright 2014 Jack Humbert
4
5This program is free software: you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation, either version 2 of the License, or
8(at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18#include <stdint.h>
19#include <stdbool.h>
20#if defined(__AVR__)
21#include <avr/io.h>
22#endif
23#include "wait.h"
24#include "print.h"
25#include "debug.h"
26#include "util.h"
27#include "matrix.h"
28#include "timer.h"
29#include "protocol/serial.h"
30
31#if (MATRIX_COLS <= 8)
32# define print_matrix_header() print("\nr/c 01234567\n")
33# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
34# define matrix_bitpop(i) bitpop(matrix[i])
35# define ROW_SHIFTER ((uint8_t)1)
36#elif (MATRIX_COLS <= 16)
37# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
38# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
39# define matrix_bitpop(i) bitpop16(matrix[i])
40# define ROW_SHIFTER ((uint16_t)1)
41#elif (MATRIX_COLS <= 32)
42# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
43# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
44# define matrix_bitpop(i) bitpop32(matrix[i])
45# define ROW_SHIFTER ((uint32_t)1)
46#endif
47
48/* matrix state(1:on, 0:off) */
49static matrix_row_t matrix[MATRIX_ROWS];
50
51__attribute__ ((weak))
52void matrix_init_kb(void) {
53 matrix_init_user();
54}
55
56__attribute__ ((weak))
57void matrix_scan_kb(void) {
58 matrix_scan_user();
59}
60
61__attribute__ ((weak))
62void matrix_init_user(void) {
63}
64
65__attribute__ ((weak))
66void matrix_scan_user(void) {
67}
68
69inline
70uint8_t matrix_rows(void) {
71 return MATRIX_ROWS;
72}
73
74inline
75uint8_t matrix_cols(void) {
76 return MATRIX_COLS;
77}
78
79void matrix_init(void) {
80
81 matrix_init_quantum();
82 serial_init();
83}
84
85uint8_t matrix_scan(void)
86{
87 uint32_t timeout = 0;
88
89 //the s character requests the RF slave to send the matrix
90 SERIAL_UART_DATA = 's';
91
92 //trust the external keystates entirely, erase the last data
93 uint8_t uart_data[11] = {0};
94
95 //there are 10 bytes corresponding to 10 columns, and an end byte
96 for (uint8_t i = 0; i < 11; i++) {
97 //wait for the serial data, timeout if it's been too long
98 //this only happened in testing with a loose wire, but does no
99 //harm to leave it in here
100 while(!SERIAL_UART_RXD_PRESENT){
101 timeout++;
102 if (timeout > 10000){
103 break;
104 }
105 }
106 uart_data[i] = SERIAL_UART_DATA;
107 }
108
109 //check for the end packet, the key state bytes use the LSBs, so 0xE0
110 //will only show up here if the correct bytes were recieved
111 if (uart_data[10] == 0xE0)
112 {
113 //shifting and transferring the keystates to the QMK matrix variable
114 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
115 matrix[i] = (uint16_t) uart_data[i*2] | (uint16_t) uart_data[i*2+1] << 5;
116 }
117 }
118
119
120 matrix_scan_quantum();
121 return 1;
122}
123
124inline
125bool matrix_is_on(uint8_t row, uint8_t col)
126{
127 return (matrix[row] & ((matrix_row_t)1<<col));
128}
129
130inline
131matrix_row_t matrix_get_row(uint8_t row)
132{
133 return matrix[row];
134}
135
136void matrix_print(void)
137{
138 print_matrix_header();
139
140 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
141 print_hex8(row); print(": ");
142 print_matrix_row(row);
143 print("\n");
144 }
145}
146
147uint8_t matrix_key_count(void)
148{
149 uint8_t count = 0;
150 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
151 count += matrix_bitpop(i);
152 }
153 return count;
154}
diff --git a/keyboards/comet46/readme.md b/keyboards/comet46/readme.md
new file mode 100644
index 000000000..3db64d291
--- /dev/null
+++ b/keyboards/comet46/readme.md
@@ -0,0 +1,17 @@
1# Comet46
2
3![Comet46](https://user-images.githubusercontent.com/39004890/50396817-a1660600-07af-11e9-8611-3156c635db43.jpg)
4
5A split wireless 40% column-staggered keyboard
6
7Keyboard Maintainer: [SatT](https://github.com/satt99)
8Hardware Supported: Comet46 PCB, atmega32u4, nRF51822
9Hardware Availability: [Comet46 PCB, case, and receiver](https://github.com/satt99/comet46-hardware)
10Firmware for nordic MCUs: [SRC and precompiled](https://github.com/satt99/comet46-firmware)
11
12Make example for this keyboard (after setting up your build environment):
13
14 make comet46:default
15
16See [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) then the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information.
17
diff --git a/keyboards/comet46/rules.mk b/keyboards/comet46/rules.mk
new file mode 100644
index 000000000..814622226
--- /dev/null
+++ b/keyboards/comet46/rules.mk
@@ -0,0 +1,23 @@
1# MCU name
2MCU = atmega32u4
3
4# Bootloader selection
5BOOTLOADER = caterina
6
7# Build Options
8# change yes to no to disable
9#
10BOOTMAGIC_ENABLE = no # Enable Bootmagic Lite
11MOUSEKEY_ENABLE = no # Mouse keys
12EXTRAKEY_ENABLE = no # Audio control and System control
13CONSOLE_ENABLE = no # Console for debug
14COMMAND_ENABLE = no # Commands for debug and configuration
15CUSTOM_MATRIX = yes # Remote matrix from the wireless bridge
16NKRO_ENABLE = yes # Enable N-Key Rollover
17# BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
18
19# project specific files
20SRC += matrix.c \
21 i2c.c \
22 ssd1306.c \
23 serial_uart.c
diff --git a/keyboards/comet46/ssd1306.c b/keyboards/comet46/ssd1306.c
new file mode 100644
index 000000000..4bd2d80bc
--- /dev/null
+++ b/keyboards/comet46/ssd1306.c
@@ -0,0 +1,343 @@
1#ifdef SSD1306OLED
2
3#include "ssd1306.h"
4#include "i2c.h"
5#include <string.h>
6#include "print.h"
7#ifdef PROTOCOL_LUFA
8#include "lufa.h"
9#endif
10#include "sendchar.h"
11#include "timer.h"
12
13struct CharacterMatrix display;
14
15extern const unsigned char font[] PROGMEM;
16
17// Set this to 1 to help diagnose early startup problems
18// when testing power-on with ble. Turn it off otherwise,
19// as the latency of printing most of the debug info messes
20// with the matrix scan, causing keys to drop.
21#define DEBUG_TO_SCREEN 0
22
23//static uint16_t last_battery_update;
24//static uint32_t vbat;
25//#define BatteryUpdateInterval 10000 /* milliseconds */
26
27// 'last_flush' is declared as uint16_t,
28// so this must be less than 65535
29#define ScreenOffInterval 60000 /* milliseconds */
30#if DEBUG_TO_SCREEN
31static uint8_t displaying;
32#endif
33static uint16_t last_flush;
34
35static bool force_dirty = true;
36
37// Write command sequence.
38// Returns true on success.
39static inline bool _send_cmd1(uint8_t cmd) {
40 bool res = false;
41
42 if (i2c_start_write(SSD1306_ADDRESS)) {
43 xprintf("failed to start write to %d\n", SSD1306_ADDRESS);
44 goto done;
45 }
46
47 if (i2c_master_write(0x0 /* command byte follows */)) {
48 print("failed to write control byte\n");
49
50 goto done;
51 }
52
53 if (i2c_master_write(cmd)) {
54 xprintf("failed to write command %d\n", cmd);
55 goto done;
56 }
57 res = true;
58done:
59 i2c_master_stop();
60 return res;
61}
62
63// Write 2-byte command sequence.
64// Returns true on success
65static inline bool _send_cmd2(uint8_t cmd, uint8_t opr) {
66 if (!_send_cmd1(cmd)) {
67 return false;
68 }
69 return _send_cmd1(opr);
70}
71
72// Write 3-byte command sequence.
73// Returns true on success
74static inline bool _send_cmd3(uint8_t cmd, uint8_t opr1, uint8_t opr2) {
75 if (!_send_cmd1(cmd)) {
76 return false;
77 }
78 if (!_send_cmd1(opr1)) {
79 return false;
80 }
81 return _send_cmd1(opr2);
82}
83
84#define send_cmd1(c) if (!_send_cmd1(c)) {goto done;}
85#define send_cmd2(c,o) if (!_send_cmd2(c,o)) {goto done;}
86#define send_cmd3(c,o1,o2) if (!_send_cmd3(c,o1,o2)) {goto done;}
87
88static void clear_display(void) {
89 matrix_clear(&display);
90
91 // Clear all of the display bits (there can be random noise
92 // in the RAM on startup)
93 send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1);
94 send_cmd3(ColumnAddr, 0, DisplayWidth - 1);
95
96 if (i2c_start_write(SSD1306_ADDRESS)) {
97 goto done;
98 }
99 if (i2c_master_write(0x40)) {
100 // Data mode
101 goto done;
102 }
103 for (uint8_t row = 0; row < MatrixRows; ++row) {
104 for (uint8_t col = 0; col < DisplayWidth; ++col) {
105 i2c_master_write(0);
106 }
107 }
108
109 display.dirty = false;
110
111done:
112 i2c_master_stop();
113}
114
115#if DEBUG_TO_SCREEN
116#undef sendchar
117static int8_t capture_sendchar(uint8_t c) {
118 sendchar(c);
119 iota_gfx_write_char(c);
120
121 if (!displaying) {
122 iota_gfx_flush();
123 }
124 return 0;
125}
126#endif
127
128bool iota_gfx_init(bool rotate) {
129 bool success = false;
130
131 i2c_master_init();
132 send_cmd1(DisplayOff);
133 send_cmd2(SetDisplayClockDiv, 0x80);
134 send_cmd2(SetMultiPlex, DisplayHeight - 1);
135
136 send_cmd2(SetDisplayOffset, 0);
137
138
139 send_cmd1(SetStartLine | 0x0);
140 send_cmd2(SetChargePump, 0x14 /* Enable */);
141 send_cmd2(SetMemoryMode, 0 /* horizontal addressing */);
142
143 if(rotate){
144 // the following Flip the display orientation 180 degrees
145 send_cmd1(SegRemap);
146 send_cmd1(ComScanInc);
147 }else{
148 // Flips the display orientation 0 degrees
149 send_cmd1(SegRemap | 0x1);
150 send_cmd1(ComScanDec);
151 }
152
153 send_cmd2(SetComPins, 0x2);
154 send_cmd2(SetContrast, 0x8f);
155 send_cmd2(SetPreCharge, 0xf1);
156 send_cmd2(SetVComDetect, 0x40);
157 send_cmd1(DisplayAllOnResume);
158 send_cmd1(NormalDisplay);
159 send_cmd1(DeActivateScroll);
160 send_cmd1(DisplayOn);
161
162 send_cmd2(SetContrast, 0); // Dim
163
164 clear_display();
165
166 success = true;
167
168 iota_gfx_flush();
169
170#if DEBUG_TO_SCREEN
171 print_set_sendchar(capture_sendchar);
172#endif
173
174done:
175 return success;
176}
177
178bool iota_gfx_off(void) {
179 bool success = false;
180
181 send_cmd1(DisplayOff);
182 success = true;
183
184done:
185 return success;
186}
187
188bool iota_gfx_on(void) {
189 bool success = false;
190
191 send_cmd1(DisplayOn);
192 success = true;
193
194done:
195 return success;
196}
197
198void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) {
199 *matrix->cursor = c;
200 ++matrix->cursor;
201
202 if (matrix->cursor - &matrix->display[0][0] == sizeof(matrix->display)) {
203 // We went off the end; scroll the display upwards by one line
204 memmove(&matrix->display[0], &matrix->display[1],
205 MatrixCols * (MatrixRows - 1));
206 matrix->cursor = &matrix->display[MatrixRows - 1][0];
207 memset(matrix->cursor, ' ', MatrixCols);
208 }
209}
210
211void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) {
212 matrix->dirty = true;
213
214 if (c == '\n') {
215 // Clear to end of line from the cursor and then move to the
216 // start of the next line
217 uint8_t cursor_col = (matrix->cursor - &matrix->display[0][0]) % MatrixCols;
218
219 while (cursor_col++ < MatrixCols) {
220 matrix_write_char_inner(matrix, ' ');
221 }
222 return;
223 }
224
225 matrix_write_char_inner(matrix, c);
226}
227
228void iota_gfx_write_char(uint8_t c) {
229 matrix_write_char(&display, c);
230}
231
232void matrix_write(struct CharacterMatrix *matrix, const char *data) {
233 const char *end = data + strlen(data);
234 while (data < end) {
235 matrix_write_char(matrix, *data);
236 ++data;
237 }
238}
239
240void matrix_write_ln(struct CharacterMatrix *matrix, const char *data) {
241 char data_ln[strlen(data)+2];
242 snprintf(data_ln, sizeof(data_ln), "%s\n", data);
243 matrix_write(matrix, data_ln);
244}
245
246void iota_gfx_write(const char *data) {
247 matrix_write(&display, data);
248}
249
250void matrix_write_P(struct CharacterMatrix *matrix, const char *data) {
251 while (true) {
252 uint8_t c = pgm_read_byte(data);
253 if (c == 0) {
254 return;
255 }
256 matrix_write_char(matrix, c);
257 ++data;
258 }
259}
260
261void iota_gfx_write_P(const char *data) {
262 matrix_write_P(&display, data);
263}
264
265void matrix_clear(struct CharacterMatrix *matrix) {
266 memset(matrix->display, ' ', sizeof(matrix->display));
267 matrix->cursor = &matrix->display[0][0];
268 matrix->dirty = true;
269}
270
271void iota_gfx_clear_screen(void) {
272 matrix_clear(&display);
273}
274
275void matrix_render(struct CharacterMatrix *matrix) {
276 last_flush = timer_read();
277 iota_gfx_on();
278#if DEBUG_TO_SCREEN
279 ++displaying;
280#endif
281
282 // Move to the home position
283 send_cmd3(PageAddr, 0, MatrixRows - 1);
284 send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1);
285
286 if (i2c_start_write(SSD1306_ADDRESS)) {
287 goto done;
288 }
289 if (i2c_master_write(0x40)) {
290 // Data mode
291 goto done;
292 }
293
294 for (uint8_t row = 0; row < MatrixRows; ++row) {
295 for (uint8_t col = 0; col < MatrixCols; ++col) {
296 const uint8_t *glyph = font + (matrix->display[row][col] * FontWidth);
297
298 for (uint8_t glyphCol = 0; glyphCol < FontWidth; ++glyphCol) {
299 uint8_t colBits = pgm_read_byte(glyph + glyphCol);
300 i2c_master_write(colBits);
301 }
302
303 // 1 column of space between chars (it's not included in the glyph)
304 //i2c_master_write(0);
305 }
306 }
307
308 matrix->dirty = false;
309
310done:
311 i2c_master_stop();
312#if DEBUG_TO_SCREEN
313 --displaying;
314#endif
315}
316
317void iota_gfx_flush(void) {
318 matrix_render(&display);
319}
320
321__attribute__ ((weak))
322void iota_gfx_task_user(void) {
323}
324
325void iota_gfx_task(void) {
326 iota_gfx_task_user();
327
328 if (display.dirty|| force_dirty) {
329 iota_gfx_flush();
330 force_dirty = false;
331 }
332
333 if (timer_elapsed(last_flush) > ScreenOffInterval) {
334 iota_gfx_off();
335 }
336}
337
338bool process_record_gfx(uint16_t keycode, keyrecord_t *record) {
339 force_dirty = true;
340 return true;
341}
342
343#endif
diff --git a/keyboards/comet46/ssd1306.h b/keyboards/comet46/ssd1306.h
new file mode 100644
index 000000000..11a3cc67f
--- /dev/null
+++ b/keyboards/comet46/ssd1306.h
@@ -0,0 +1,90 @@
1#pragma once
2
3#include <stdbool.h>
4#include <stdio.h>
5#include "action.h"
6
7enum ssd1306_cmds {
8 DisplayOff = 0xAE,
9 DisplayOn = 0xAF,
10
11 SetContrast = 0x81,
12 DisplayAllOnResume = 0xA4,
13
14 DisplayAllOn = 0xA5,
15 NormalDisplay = 0xA6,
16 InvertDisplay = 0xA7,
17 SetDisplayOffset = 0xD3,
18 SetComPins = 0xda,
19 SetVComDetect = 0xdb,
20 SetDisplayClockDiv = 0xD5,
21 SetPreCharge = 0xd9,
22 SetMultiPlex = 0xa8,
23 SetLowColumn = 0x00,
24 SetHighColumn = 0x10,
25 SetStartLine = 0x40,
26
27 SetMemoryMode = 0x20,
28 ColumnAddr = 0x21,
29 PageAddr = 0x22,
30
31 ComScanInc = 0xc0,
32 ComScanDec = 0xc8,
33 SegRemap = 0xa0,
34 SetChargePump = 0x8d,
35 ExternalVcc = 0x01,
36 SwitchCapVcc = 0x02,
37
38 ActivateScroll = 0x2f,
39 DeActivateScroll = 0x2e,
40 SetVerticalScrollArea = 0xa3,
41 RightHorizontalScroll = 0x26,
42 LeftHorizontalScroll = 0x27,
43 VerticalAndRightHorizontalScroll = 0x29,
44 VerticalAndLeftHorizontalScroll = 0x2a,
45};
46
47// Controls the SSD1306 128x32 OLED display via i2c
48
49#ifndef SSD1306_ADDRESS
50#define SSD1306_ADDRESS 0x3C
51#endif
52
53#define DisplayHeight 32
54#define DisplayWidth 128
55
56#define FontHeight 8
57#define FontWidth 6
58
59#define MatrixRows (DisplayHeight / FontHeight)
60#define MatrixCols (DisplayWidth / FontWidth)
61
62struct CharacterMatrix {
63 uint8_t display[MatrixRows][MatrixCols];
64 uint8_t *cursor;
65 bool dirty;
66};
67
68extern struct CharacterMatrix display;
69
70bool iota_gfx_init(bool rotate);
71void iota_gfx_task(void);
72bool iota_gfx_off(void);
73bool iota_gfx_on(void);
74void iota_gfx_flush(void);
75void iota_gfx_write_char(uint8_t c);
76void iota_gfx_write(const char *data);
77void iota_gfx_write_P(const char *data);
78void iota_gfx_clear_screen(void);
79
80void iota_gfx_task_user(void);
81
82void matrix_clear(struct CharacterMatrix *matrix);
83void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c);
84void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c);
85void matrix_write(struct CharacterMatrix *matrix, const char *data);
86void matrix_write_ln(struct CharacterMatrix *matrix, const char *data);
87void matrix_write_P(struct CharacterMatrix *matrix, const char *data);
88void matrix_render(struct CharacterMatrix *matrix);
89
90bool process_record_gfx(uint16_t keycode, keyrecord_t *record);