diff options
Diffstat (limited to 'keyboards/comet46')
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 | /* | ||
2 | Copyright 2012 Jun Wako <[email protected]> | ||
3 | |||
4 | This program is free software: you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation, either version 2 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along 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 | |||
21 | volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; | ||
22 | |||
23 | static volatile uint8_t slave_buffer_pos; | ||
24 | static volatile bool slave_has_register_set = false; | ||
25 | |||
26 | // Wait for an i2c operation to finish | ||
27 | inline static | ||
28 | void 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) | ||
38 | void 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 | ||
50 | uint8_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. | ||
72 | void 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 | ||
83 | uint8_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 | ||
96 | uint8_t i2c_master_read(int ack) { | ||
97 | TWCR = (1<<TWINT) | (1<<TWEN) | (ack<<TWEA); | ||
98 | |||
99 | i2c_delay(); | ||
100 | return TWDR; | ||
101 | } | ||
102 | |||
103 | void i2c_reset_state(void) { | ||
104 | TWCR = 0; | ||
105 | } | ||
106 | |||
107 | void 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 | |||
116 | ISR(TWI_vect); | ||
117 | |||
118 | ISR(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 | |||
20 | extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; | ||
21 | |||
22 | void i2c_master_init(void); | ||
23 | uint8_t i2c_master_start(uint8_t address); | ||
24 | void i2c_master_stop(void); | ||
25 | uint8_t i2c_master_write(uint8_t data); | ||
26 | uint8_t i2c_master_read(int); | ||
27 | void i2c_reset_state(void); | ||
28 | void i2c_slave_init(uint8_t address); | ||
29 | |||
30 | |||
31 | static inline unsigned char i2c_start_read(unsigned char addr) { | ||
32 | return i2c_master_start((addr << 1) | I2C_READ); | ||
33 | } | ||
34 | |||
35 | static inline unsigned char i2c_start_write(unsigned char addr) { | ||
36 | return i2c_master_start((addr << 1) | I2C_WRITE); | ||
37 | } | ||
38 | |||
39 | // from SSD1306 scrips | ||
40 | extern unsigned char i2c_rep_start(unsigned char addr); | ||
41 | extern void i2c_start_wait(unsigned char addr); | ||
42 | extern unsigned char i2c_readAck(void); | ||
43 | extern unsigned char i2c_readNak(void); | ||
44 | extern 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. | ||
10 | enum comet46_layers | ||
11 | { | ||
12 | _QWERTY, | ||
13 | _COLEMAK, | ||
14 | _DVORAK, | ||
15 | _LOWER, | ||
16 | _RAISE, | ||
17 | _ADJUST, | ||
18 | }; | ||
19 | |||
20 | enum 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 | |||
31 | const 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 | |||
143 | layer_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 | ||
148 | void 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 | |||
171 | void matrix_init_user(void) { | ||
172 | led_init(); | ||
173 | } | ||
174 | |||
175 | void 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 | |||
204 | bool 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 | |||
3 | A 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 | /* | ||
2 | This is the c configuration file for the keymap | ||
3 | |||
4 | Copyright 2012 Jun Wako <[email protected]> | ||
5 | Copyright 2015 Jack Humbert | ||
6 | |||
7 | This program is free software: you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation, either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along 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. | ||
14 | enum comet46_layers | ||
15 | { | ||
16 | _QWERTY, | ||
17 | _COLEMAK, | ||
18 | _DVORAK, | ||
19 | _LOWER, | ||
20 | _RAISE, | ||
21 | _ADJUST, | ||
22 | }; | ||
23 | |||
24 | enum 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 | |||
35 | const 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 | |||
147 | layer_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 | ||
155 | void set_keylog(uint16_t keycode); | ||
156 | const char *read_keylog(void); | ||
157 | const char *read_modifier_state(void); | ||
158 | const char *read_host_led_state(void); | ||
159 | |||
160 | void matrix_init_user(void) { | ||
161 | iota_gfx_init(false); // turns on the display | ||
162 | } | ||
163 | |||
164 | void matrix_scan_user(void) { | ||
165 | iota_gfx_task(); // this is what updates the display continuously | ||
166 | } | ||
167 | |||
168 | void 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 | |||
175 | void 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 | |||
220 | void 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 | |||
229 | bool 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 | |||
3 | A 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 | ||
2 | SRC += ./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 | |||
5 | static 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 | */ | ||
13 | void 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 | |||
81 | uint16_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 | |||
120 | uint8_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 | |||
129 | void 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 | |||
137 | void 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 | |||
8 | void action_pseudo_lut(keyrecord_t *, uint8_t, const uint16_t (*)[2]); | ||
9 | uint16_t convert_keycode(const uint16_t (*)[2], uint16_t, bool); | ||
10 | |||
11 | uint8_t get_shift_bit(uint16_t); | ||
12 | void add_shift_bit(uint16_t); | ||
13 | void 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 | /* | ||
2 | This is the c configuration file for the keymap | ||
3 | |||
4 | Copyright 2012 Jun Wako <[email protected]> | ||
5 | Copyright 2015 Jack Humbert | ||
6 | |||
7 | This program is free software: you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation, either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along 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. | ||
16 | enum comet46_layers { | ||
17 | _QWERTY, | ||
18 | _LOWER, | ||
19 | _RAISE, | ||
20 | _PSEUDO_US, | ||
21 | _PSEUDO_US_LOWER, | ||
22 | _PSEUDO_US_RAISE, | ||
23 | _ADJUST | ||
24 | }; | ||
25 | |||
26 | enum 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 | |||
78 | const 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 | |||
167 | layer_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 | ||
183 | void set_keylog(uint16_t keycode); | ||
184 | const char *read_keylog(void); | ||
185 | const char *read_modifier_state(void); | ||
186 | const char *read_host_led_state(void); | ||
187 | |||
188 | void matrix_init_user(void) { | ||
189 | iota_gfx_init(false); // turns on the display | ||
190 | } | ||
191 | |||
192 | void matrix_scan_user(void) { | ||
193 | iota_gfx_task(); // this is what updates the display continuously | ||
194 | } | ||
195 | |||
196 | void 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 | |||
203 | void 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 | |||
250 | void 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 | |||
266 | bool 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 */ | ||
5 | const 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 | |||
3 | On a Japanese Windows environment, ANSI keyboards may be recognized wrongly as a JIS keyboard. | ||
4 | By using this code, you can use your ANSI keyboard under a JIS keyboard environment without changing the settings and registry of your environment. | ||
5 | |||
6 | Original 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 @@ | |||
1 | SRC += action_pseudo_lut.c | ||
2 | |||
3 | # If you want to change display settings of the OLED, you need to change the following lines | ||
4 | SRC += ./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 | |||
8 | const 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 | |||
4 | char host_led_state_str[22]; | ||
5 | |||
6 | const 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 | |||
7 | char 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 | ||
11 | const 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 | |||
270 | void 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 | |||
286 | const 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 | |||
4 | char modifier_state_str[22]; | ||
5 | |||
6 | const 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 | /* | ||
2 | Copyright 2012 Jun Wako | ||
3 | Copyright 2014 Jack Humbert | ||
4 | |||
5 | This program is free software: you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation, either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along 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) */ | ||
49 | static matrix_row_t matrix[MATRIX_ROWS]; | ||
50 | |||
51 | __attribute__ ((weak)) | ||
52 | void matrix_init_kb(void) { | ||
53 | matrix_init_user(); | ||
54 | } | ||
55 | |||
56 | __attribute__ ((weak)) | ||
57 | void matrix_scan_kb(void) { | ||
58 | matrix_scan_user(); | ||
59 | } | ||
60 | |||
61 | __attribute__ ((weak)) | ||
62 | void matrix_init_user(void) { | ||
63 | } | ||
64 | |||
65 | __attribute__ ((weak)) | ||
66 | void matrix_scan_user(void) { | ||
67 | } | ||
68 | |||
69 | inline | ||
70 | uint8_t matrix_rows(void) { | ||
71 | return MATRIX_ROWS; | ||
72 | } | ||
73 | |||
74 | inline | ||
75 | uint8_t matrix_cols(void) { | ||
76 | return MATRIX_COLS; | ||
77 | } | ||
78 | |||
79 | void matrix_init(void) { | ||
80 | |||
81 | matrix_init_quantum(); | ||
82 | serial_init(); | ||
83 | } | ||
84 | |||
85 | uint8_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 | |||
124 | inline | ||
125 | bool matrix_is_on(uint8_t row, uint8_t col) | ||
126 | { | ||
127 | return (matrix[row] & ((matrix_row_t)1<<col)); | ||
128 | } | ||
129 | |||
130 | inline | ||
131 | matrix_row_t matrix_get_row(uint8_t row) | ||
132 | { | ||
133 | return matrix[row]; | ||
134 | } | ||
135 | |||
136 | void 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 | |||
147 | uint8_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 |  | ||
4 | |||
5 | A split wireless 40% column-staggered keyboard | ||
6 | |||
7 | Keyboard Maintainer: [SatT](https://github.com/satt99) | ||
8 | Hardware Supported: Comet46 PCB, atmega32u4, nRF51822 | ||
9 | Hardware Availability: [Comet46 PCB, case, and receiver](https://github.com/satt99/comet46-hardware) | ||
10 | Firmware for nordic MCUs: [SRC and precompiled](https://github.com/satt99/comet46-firmware) | ||
11 | |||
12 | Make example for this keyboard (after setting up your build environment): | ||
13 | |||
14 | make comet46:default | ||
15 | |||
16 | See [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 | ||
2 | MCU = atmega32u4 | ||
3 | |||
4 | # Bootloader selection | ||
5 | BOOTLOADER = caterina | ||
6 | |||
7 | # Build Options | ||
8 | # change yes to no to disable | ||
9 | # | ||
10 | BOOTMAGIC_ENABLE = no # Enable Bootmagic Lite | ||
11 | MOUSEKEY_ENABLE = no # Mouse keys | ||
12 | EXTRAKEY_ENABLE = no # Audio control and System control | ||
13 | CONSOLE_ENABLE = no # Console for debug | ||
14 | COMMAND_ENABLE = no # Commands for debug and configuration | ||
15 | CUSTOM_MATRIX = yes # Remote matrix from the wireless bridge | ||
16 | NKRO_ENABLE = yes # Enable N-Key Rollover | ||
17 | # BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality | ||
18 | |||
19 | # project specific files | ||
20 | SRC += 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 | |||
13 | struct CharacterMatrix display; | ||
14 | |||
15 | extern 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 | ||
31 | static uint8_t displaying; | ||
32 | #endif | ||
33 | static uint16_t last_flush; | ||
34 | |||
35 | static bool force_dirty = true; | ||
36 | |||
37 | // Write command sequence. | ||
38 | // Returns true on success. | ||
39 | static 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; | ||
58 | done: | ||
59 | i2c_master_stop(); | ||
60 | return res; | ||
61 | } | ||
62 | |||
63 | // Write 2-byte command sequence. | ||
64 | // Returns true on success | ||
65 | static 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 | ||
74 | static 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 | |||
88 | static 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 | |||
111 | done: | ||
112 | i2c_master_stop(); | ||
113 | } | ||
114 | |||
115 | #if DEBUG_TO_SCREEN | ||
116 | #undef sendchar | ||
117 | static 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 | |||
128 | bool 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 | |||
174 | done: | ||
175 | return success; | ||
176 | } | ||
177 | |||
178 | bool iota_gfx_off(void) { | ||
179 | bool success = false; | ||
180 | |||
181 | send_cmd1(DisplayOff); | ||
182 | success = true; | ||
183 | |||
184 | done: | ||
185 | return success; | ||
186 | } | ||
187 | |||
188 | bool iota_gfx_on(void) { | ||
189 | bool success = false; | ||
190 | |||
191 | send_cmd1(DisplayOn); | ||
192 | success = true; | ||
193 | |||
194 | done: | ||
195 | return success; | ||
196 | } | ||
197 | |||
198 | void 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 | |||
211 | void 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 | |||
228 | void iota_gfx_write_char(uint8_t c) { | ||
229 | matrix_write_char(&display, c); | ||
230 | } | ||
231 | |||
232 | void 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 | |||
240 | void 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 | |||
246 | void iota_gfx_write(const char *data) { | ||
247 | matrix_write(&display, data); | ||
248 | } | ||
249 | |||
250 | void 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 | |||
261 | void iota_gfx_write_P(const char *data) { | ||
262 | matrix_write_P(&display, data); | ||
263 | } | ||
264 | |||
265 | void 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 | |||
271 | void iota_gfx_clear_screen(void) { | ||
272 | matrix_clear(&display); | ||
273 | } | ||
274 | |||
275 | void 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 | |||
310 | done: | ||
311 | i2c_master_stop(); | ||
312 | #if DEBUG_TO_SCREEN | ||
313 | --displaying; | ||
314 | #endif | ||
315 | } | ||
316 | |||
317 | void iota_gfx_flush(void) { | ||
318 | matrix_render(&display); | ||
319 | } | ||
320 | |||
321 | __attribute__ ((weak)) | ||
322 | void iota_gfx_task_user(void) { | ||
323 | } | ||
324 | |||
325 | void 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 | |||
338 | bool 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 | |||
7 | enum 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 | |||
62 | struct CharacterMatrix { | ||
63 | uint8_t display[MatrixRows][MatrixCols]; | ||
64 | uint8_t *cursor; | ||
65 | bool dirty; | ||
66 | }; | ||
67 | |||
68 | extern struct CharacterMatrix display; | ||
69 | |||
70 | bool iota_gfx_init(bool rotate); | ||
71 | void iota_gfx_task(void); | ||
72 | bool iota_gfx_off(void); | ||
73 | bool iota_gfx_on(void); | ||
74 | void iota_gfx_flush(void); | ||
75 | void iota_gfx_write_char(uint8_t c); | ||
76 | void iota_gfx_write(const char *data); | ||
77 | void iota_gfx_write_P(const char *data); | ||
78 | void iota_gfx_clear_screen(void); | ||
79 | |||
80 | void iota_gfx_task_user(void); | ||
81 | |||
82 | void matrix_clear(struct CharacterMatrix *matrix); | ||
83 | void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c); | ||
84 | void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c); | ||
85 | void matrix_write(struct CharacterMatrix *matrix, const char *data); | ||
86 | void matrix_write_ln(struct CharacterMatrix *matrix, const char *data); | ||
87 | void matrix_write_P(struct CharacterMatrix *matrix, const char *data); | ||
88 | void matrix_render(struct CharacterMatrix *matrix); | ||
89 | |||
90 | bool process_record_gfx(uint16_t keycode, keyrecord_t *record); | ||