aboutsummaryrefslogtreecommitdiff
path: root/keyboards/zinc/rev1
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/zinc/rev1')
-rw-r--r--keyboards/zinc/rev1/config.h149
-rw-r--r--keyboards/zinc/rev1/info.json13
-rw-r--r--keyboards/zinc/rev1/matrix.c356
-rw-r--r--keyboards/zinc/rev1/rev1.c6
-rw-r--r--keyboards/zinc/rev1/rev1.h44
-rw-r--r--keyboards/zinc/rev1/rules.mk4
-rw-r--r--keyboards/zinc/rev1/serial_config.h18
-rw-r--r--keyboards/zinc/rev1/serial_config_simpleapi.h8
-rw-r--r--keyboards/zinc/rev1/split_scomm.c95
-rw-r--r--keyboards/zinc/rev1/split_scomm.h24
-rw-r--r--keyboards/zinc/rev1/split_util.c70
-rw-r--r--keyboards/zinc/rev1/split_util.h19
12 files changed, 806 insertions, 0 deletions
diff --git a/keyboards/zinc/rev1/config.h b/keyboards/zinc/rev1/config.h
new file mode 100644
index 000000000..c628400f2
--- /dev/null
+++ b/keyboards/zinc/rev1/config.h
@@ -0,0 +1,149 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3Copyright 2015 Jack Humbert
4
5This program is free software: you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation, either version 2 of the License, or
8(at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#pragma once
20
21//#ifndef REV1_CONFIG_H
22//#define REV1_CONFIG_H
23
24/* USB Device descriptor parameter */
25#define VENDOR_ID 0xFEED
26#define PRODUCT_ID 0x9991
27#define DEVICE_VER 0x0001
28#define MANUFACTURER monksoffunk
29#define PRODUCT zinc rev.1
30#define DESCRIPTION A split keyboard
31
32
33#define PREVENT_STUCK_MODIFIERS
34#define TAPPING_FORCE_HOLD
35#define TAPPING_TERM 100
36
37/* Use I2C or Serial */
38//#define USE_I2C
39#define USE_SERIAL
40//#define USE_MATRIX_I2C
41
42/* Select hand configuration */
43#define MASTER_LEFT
44//#define MASTER_RIGHT
45//#define EE_HANDS
46
47
48/* key matrix size */
49// Rows are doubled-up
50 #define MATRIX_ROWS 8
51 #define MATRIX_ROW_PINS { F6, F7, B1, B3 }
52
53// wiring of each half
54#define MATRIX_COLS 6
55#define MATRIX_COL_PINS { F4, D4, C6, D7, E6, B4 }
56
57/* define if matrix has ghost */
58//#define MATRIX_HAS_GHOST
59
60/* number of backlight levels */
61// #define BACKLIGHT_LEVELS 3
62
63/* Set 0 if debouncing isn't needed */
64#define DEBOUNCING_DELAY 5
65
66/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
67//#define LOCKING_SUPPORT_ENABLE
68/* Locking resynchronize hack */
69//#define LOCKING_RESYNC_ENABLE
70
71/* key combination for command */
72#define IS_COMMAND() ( \
73 keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
74)
75
76/* ws2812 RGB LED */
77#define RGB_DI_PIN D3
78#define RGBLIGHT_TIMER
79//#define RGBLED_NUM 12 // Number of LEDs. see ./keymaps/default/config.h
80#define ws2812_PORTREG PORTD
81#define ws2812_DDRREG DDRD
82
83// RGB LED support
84//#define RGBLIGHT_ANIMATIONS : see ./rules.mk: LED_ANIMATIONS = yes or no
85// see ./rules.mk: LED_BACK_ENABLE or LED_UNDERGLOW_ENABLE set yes
86#ifdef RGBLED_BACK
87 #define RGBLED_NUM 24
88#else
89 #define RGBLED_NUM 6
90#endif
91
92#ifndef IOS_DEVICE_ENABLE
93 #if RGBLED_NUM <= 6
94 #define RGBLIGHT_LIMIT_VAL 255
95 #else
96 #if RGBLED_NUM <= 16
97 #define RGBLIGHT_LIMIT_VAL 130
98 #else
99 #define RGBLIGHT_LIMIT_VAL 120
100 #endif
101 #endif
102 #define RGBLIGHT_VAL_STEP 17
103#else
104 #if RGBLED_NUM <= 6
105 #define RGBLIGHT_LIMIT_VAL 90
106 #else
107 #if RGBLED_NUM <= 16
108 #define RGBLIGHT_LIMIT_VAL 45
109 #else
110 #define RGBLIGHT_LIMIT_VAL 35
111 #endif
112 #endif
113 #define RGBLIGHT_VAL_STEP 4
114#endif
115#define RGBLIGHT_HUE_STEP 10
116#define RGBLIGHT_SAT_STEP 17
117
118#if defined(RGBLIGHT_ENABLE) && !defined(IOS_DEVICE_ENABLE)
119// USB_MAX_POWER_CONSUMPTION value
120// 120 RGBoff
121// 330 RGB 6
122// 300 RGB 32
123 #define USB_MAX_POWER_CONSUMPTION 400
124#else
125 // fix iPhone and iPad power adapter issue
126 // iOS device need lessthan 100
127 #define USB_MAX_POWER_CONSUMPTION 100
128#endif
129
130/*
131 * Feature disable options
132 * These options are also useful to firmware size reduction.
133 */
134
135/* disable debug print */
136// #define NO_DEBUG
137
138/* disable print */
139// #define NO_PRINT
140
141/* disable action features */
142//#define NO_ACTION_LAYER
143//#define NO_ACTION_TAPPING
144//#define NO_ACTION_ONESHOT
145//#define NO_ACTION_MACRO
146//#define NO_ACTION_FUNCTION
147
148
149//#endif
diff --git a/keyboards/zinc/rev1/info.json b/keyboards/zinc/rev1/info.json
new file mode 100644
index 000000000..0ca8acded
--- /dev/null
+++ b/keyboards/zinc/rev1/info.json
@@ -0,0 +1,13 @@
1{
2 "keyboard_name": "Zinc rev.1",
3 "url": "https://github.com/monksoffunk/zinc",
4 "maintainer": "monksoffunk",
5 "width": 15,
6 "height": 4,
7 "layouts": {
8 "LAYOUT": {
9 "key_count": 48,
10 "layout": [{"x":0, "y":0}, {"x":1, "y":0}, {"x":2, "y":0}, {"x":3, "y":0}, {"x":4, "y":0}, {"x":5, "y":0}, {"x":9, "y":0}, {"x":10, "y":0}, {"x":11, "y":0}, {"x":12, "y":0}, {"x":13, "y":0}, {"x":14, "y":0}, {"x":0, "y":1}, {"x":1, "y":1}, {"x":2, "y":1}, {"x":3, "y":1}, {"x":4, "y":1}, {"x":5, "y":1}, {"x":9, "y":1}, {"x":10, "y":1}, {"x":11, "y":1}, {"x":12, "y":1}, {"x":13, "y":1}, {"x":14, "y":1}, {"x":0, "y":2}, {"x":1, "y":2}, {"x":2, "y":2}, {"x":3, "y":2}, {"x":4, "y":2}, {"x":5, "y":2}, {"x":9, "y":2}, {"x":10, "y":2}, {"x":11, "y":2}, {"x":12, "y":2}, {"x":13, "y":2}, {"x":14, "y":2}, {"x":0, "y":3}, {"x":1, "y":3}, {"x":2, "y":3}, {"x":3, "y":3}, {"x":4, "y":3}, {"x":5, "y":3}, {"x":9, "y":3}, {"x":10, "y":3}, {"x":11, "y":3}, {"x":12, "y":3}, {"x":13, "y":3}, {"x":14, "y":3}]
11 }
12 }
13}
diff --git a/keyboards/zinc/rev1/matrix.c b/keyboards/zinc/rev1/matrix.c
new file mode 100644
index 000000000..220954f05
--- /dev/null
+++ b/keyboards/zinc/rev1/matrix.c
@@ -0,0 +1,356 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18/*
19 * scan matrix
20 */
21#include <stdint.h>
22#include <stdbool.h>
23#include <string.h>
24#include <avr/io.h>
25#include <avr/wdt.h>
26#include <avr/interrupt.h>
27#include <util/delay.h>
28#include "print.h"
29#include "debug.h"
30#include "util.h"
31#include "matrix.h"
32#include "split_util.h"
33#include "pro_micro.h"
34
35#ifdef USE_MATRIX_I2C
36# include "i2c.h"
37#else // USE_SERIAL
38# include "split_scomm.h"
39#endif
40
41#ifndef DEBOUNCE
42# define DEBOUNCE 5
43#endif
44
45#define ERROR_DISCONNECT_COUNT 5
46
47static uint8_t debouncing = DEBOUNCE;
48static const int ROWS_PER_HAND = MATRIX_ROWS/2;
49static uint8_t error_count = 0;
50uint8_t is_master = 0 ;
51
52static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
53static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
54
55/* matrix state(1:on, 0:off) */
56static matrix_row_t matrix[MATRIX_ROWS];
57static matrix_row_t matrix_debouncing[MATRIX_ROWS];
58
59static matrix_row_t read_cols(void);
60static void init_cols(void);
61static void unselect_rows(void);
62static void select_row(uint8_t row);
63static uint8_t matrix_master_scan(void);
64
65
66__attribute__ ((weak))
67void matrix_init_kb(void) {
68 matrix_init_user();
69}
70
71__attribute__ ((weak))
72void matrix_scan_kb(void) {
73 matrix_scan_user();
74}
75
76__attribute__ ((weak))
77void matrix_init_user(void) {
78}
79
80__attribute__ ((weak))
81void matrix_scan_user(void) {
82}
83
84inline
85uint8_t matrix_rows(void)
86{
87 return MATRIX_ROWS;
88}
89
90inline
91uint8_t matrix_cols(void)
92{
93 return MATRIX_COLS;
94}
95
96void matrix_init(void)
97{
98 debug_enable = true;
99 debug_matrix = true;
100 debug_mouse = true;
101 // initialize row and col
102 unselect_rows();
103 init_cols();
104
105 TX_RX_LED_INIT;
106 TXLED0;
107 RXLED0;
108
109 // initialize matrix state: all keys off
110 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
111 matrix[i] = 0;
112 matrix_debouncing[i] = 0;
113 }
114
115 is_master = has_usb();
116
117 matrix_init_quantum();
118}
119
120uint8_t _matrix_scan(void)
121{
122 // Right hand is stored after the left in the matirx so, we need to offset it
123 int offset = isLeftHand ? 0 : (ROWS_PER_HAND);
124
125 for (uint8_t i = 0; i < ROWS_PER_HAND; i++) {
126 select_row(i);
127 _delay_us(30); // without this wait read unstable value.
128 matrix_row_t cols = read_cols();
129 if (matrix_debouncing[i+offset] != cols) {
130 matrix_debouncing[i+offset] = cols;
131 debouncing = DEBOUNCE;
132 }
133 unselect_rows();
134 }
135
136 if (debouncing) {
137 if (--debouncing) {
138 _delay_ms(1);
139 } else {
140 for (uint8_t i = 0; i < ROWS_PER_HAND; i++) {
141 matrix[i+offset] = matrix_debouncing[i+offset];
142 }
143 }
144 }
145
146 return 1;
147}
148
149#ifdef USE_MATRIX_I2C
150
151// Get rows from other half over i2c
152int i2c_transaction(void) {
153 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
154
155 int err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);
156 if (err) goto i2c_error;
157
158 // start of matrix stored at 0x00
159 err = i2c_master_write(0x00);
160 if (err) goto i2c_error;
161
162 // Start read
163 err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ);
164 if (err) goto i2c_error;
165
166 if (!err) {
167 int i;
168 for (i = 0; i < ROWS_PER_HAND-1; ++i) {
169 matrix[slaveOffset+i] = i2c_master_read(I2C_ACK);
170 }
171 matrix[slaveOffset+i] = i2c_master_read(I2C_NACK);
172 i2c_master_stop();
173 } else {
174i2c_error: // the cable is disconnceted, or something else went wrong
175 i2c_reset_state();
176 return err;
177 }
178
179 return 0;
180}
181
182#else // USE_SERIAL
183
184int serial_transaction(int master_changed) {
185 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
186#ifdef SERIAL_USE_MULTI_TRANSACTION
187 int ret=serial_update_buffers(master_changed);
188#else
189 int ret=serial_update_buffers();
190#endif
191 if (ret ) {
192 if(ret==2) RXLED1;
193 return 1;
194 }
195 RXLED0;
196 memcpy(&matrix[slaveOffset],
197 (void *)serial_slave_buffer, sizeof(serial_slave_buffer));
198 return 0;
199}
200#endif
201
202uint8_t matrix_scan(void)
203{
204 if (is_master) {
205 matrix_master_scan();
206 }else{
207 matrix_slave_scan();
208 int offset = (isLeftHand) ? ROWS_PER_HAND : 0;
209 memcpy(&matrix[offset],
210 (void *)serial_master_buffer, sizeof(serial_master_buffer));
211 matrix_scan_quantum();
212 }
213 return 1;
214}
215
216
217uint8_t matrix_master_scan(void) {
218
219 int ret = _matrix_scan();
220 int mchanged = 1;
221 int offset = (isLeftHand) ? 0 : ROWS_PER_HAND;
222
223#ifdef USE_MATRIX_I2C
224// for (int i = 0; i < ROWS_PER_HAND; ++i) {
225 /* i2c_slave_buffer[i] = matrix[offset+i]; */
226// i2c_slave_buffer[i] = matrix[offset+i];
227// }
228#else // USE_SERIAL
229 #ifdef SERIAL_USE_MULTI_TRANSACTION
230 mchanged = memcmp((void *)serial_master_buffer,
231 &matrix[offset], sizeof(serial_master_buffer));
232 #endif
233 memcpy((void *)serial_master_buffer,
234 &matrix[offset], sizeof(serial_master_buffer));
235#endif
236
237#ifdef USE_MATRIX_I2C
238 if( i2c_transaction() ) {
239#else // USE_SERIAL
240 if( serial_transaction(mchanged) ) {
241#endif
242 // turn on the indicator led when halves are disconnected
243 TXLED1;
244
245 error_count++;
246
247 if (error_count > ERROR_DISCONNECT_COUNT) {
248 // reset other half if disconnected
249 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
250 for (int i = 0; i < ROWS_PER_HAND; ++i) {
251 matrix[slaveOffset+i] = 0;
252 }
253 }
254 } else {
255 // turn off the indicator led on no error
256 TXLED0;
257 error_count = 0;
258 }
259 matrix_scan_quantum();
260 return ret;
261}
262
263void matrix_slave_scan(void) {
264 _matrix_scan();
265
266 int offset = (isLeftHand) ? 0 : ROWS_PER_HAND;
267
268#ifdef USE_MATRIX_I2C
269 for (int i = 0; i < ROWS_PER_HAND; ++i) {
270 /* i2c_slave_buffer[i] = matrix[offset+i]; */
271 i2c_slave_buffer[i] = matrix[offset+i];
272 }
273#else // USE_SERIAL
274 #ifdef SERIAL_USE_MULTI_TRANSACTION
275 int change = 0;
276 #endif
277 for (int i = 0; i < ROWS_PER_HAND; ++i) {
278 #ifdef SERIAL_USE_MULTI_TRANSACTION
279 if( serial_slave_buffer[i] != matrix[offset+i] )
280 change = 1;
281 #endif
282 serial_slave_buffer[i] = matrix[offset+i];
283 }
284 #ifdef SERIAL_USE_MULTI_TRANSACTION
285 slave_buffer_change_count += change;
286 #endif
287#endif
288}
289
290bool matrix_is_modified(void)
291{
292 if (debouncing) return false;
293 return true;
294}
295
296inline
297bool matrix_is_on(uint8_t row, uint8_t col)
298{
299 return (matrix[row] & ((matrix_row_t)1<<col));
300}
301
302inline
303matrix_row_t matrix_get_row(uint8_t row)
304{
305 return matrix[row];
306}
307
308void matrix_print(void)
309{
310 print("\nr/c 0123456789ABCDEF\n");
311 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
312 phex(row); print(": ");
313 pbin_reverse16(matrix_get_row(row));
314 print("\n");
315 }
316}
317
318uint8_t matrix_key_count(void)
319{
320 uint8_t count = 0;
321 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
322 count += bitpop16(matrix[i]);
323 }
324 return count;
325}
326
327static void init_cols(void)
328{
329 for(int x = 0; x < MATRIX_COLS; x++) {
330 _SFR_IO8((col_pins[x] >> 4) + 1) &= ~_BV(col_pins[x] & 0xF);
331 _SFR_IO8((col_pins[x] >> 4) + 2) |= _BV(col_pins[x] & 0xF);
332 }
333}
334
335static matrix_row_t read_cols(void)
336{
337 matrix_row_t result = 0;
338 for(int x = 0; x < MATRIX_COLS; x++) {
339 result |= (_SFR_IO8(col_pins[x] >> 4) & _BV(col_pins[x] & 0xF)) ? 0 : (1 << x);
340 }
341 return result;
342}
343
344static void unselect_rows(void)
345{
346 for(int x = 0; x < ROWS_PER_HAND; x++) {
347 _SFR_IO8((row_pins[x] >> 4) + 1) &= ~_BV(row_pins[x] & 0xF);
348 _SFR_IO8((row_pins[x] >> 4) + 2) |= _BV(row_pins[x] & 0xF);
349 }
350}
351
352static void select_row(uint8_t row)
353{
354 _SFR_IO8((row_pins[row] >> 4) + 1) |= _BV(row_pins[row] & 0xF);
355 _SFR_IO8((row_pins[row] >> 4) + 2) &= ~_BV(row_pins[row] & 0xF);
356}
diff --git a/keyboards/zinc/rev1/rev1.c b/keyboards/zinc/rev1/rev1.c
new file mode 100644
index 000000000..2ce08a07c
--- /dev/null
+++ b/keyboards/zinc/rev1/rev1.c
@@ -0,0 +1,6 @@
1#include "zinc.h"
2
3void matrix_init_kb(void) {
4 matrix_init_user();
5};
6
diff --git a/keyboards/zinc/rev1/rev1.h b/keyboards/zinc/rev1/rev1.h
new file mode 100644
index 000000000..933e635c2
--- /dev/null
+++ b/keyboards/zinc/rev1/rev1.h
@@ -0,0 +1,44 @@
1#pragma once
2
3#include "../zinc.h"
4
5//void promicro_bootloader_jmp(bool program);
6#include "quantum.h"
7
8#ifdef RGBLIGHT_ENABLE
9//rgb led driver
10#include "ws2812.h"
11#endif
12
13#ifdef USE_I2C
14#include <stddef.h>
15#ifdef __AVR__
16 #include <avr/io.h>
17 #include <avr/interrupt.h>
18#endif
19#endif
20
21//void promicro_bootloader_jmp(bool program);
22
23
24
25// Standard Keymap
26// (TRRS jack on both halves are to the left side)
27#define LAYOUT( \
28 L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \
29 L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \
30 L20, L21, L22, L23, L24, L25, R20, R21, R22, R23, R24, R25, \
31 L30, L31, L32, L33, L34, L35, R30, R31, R32, R33, R34, R35 \
32 ) \
33 { \
34 { L00, L01, L02, L03, L04, L05}, \
35 { L10, L11, L12, L13, L14, L15}, \
36 { L20, L21, L22, L23, L24, L25}, \
37 { L30, L31, L32, L33, L34, L35}, \
38 { R00, R01, R02, R03, R04, R05 }, \
39 { R10, R11, R12, R13, R14, R15 }, \
40 { R20, R21, R22, R23, R24, R25 }, \
41 { R30, R31, R32, R33, R34, R35 }, \
42 }
43
44#define LAYOUT_ortho_4x12 LAYOUT
diff --git a/keyboards/zinc/rev1/rules.mk b/keyboards/zinc/rev1/rules.mk
new file mode 100644
index 000000000..e78b9258d
--- /dev/null
+++ b/keyboards/zinc/rev1/rules.mk
@@ -0,0 +1,4 @@
1SRC += rev1/matrix.c
2SRC += rev1/split_util.c
3SRC += rev1/split_scomm.c
4SRC += ws2812.c
diff --git a/keyboards/zinc/rev1/serial_config.h b/keyboards/zinc/rev1/serial_config.h
new file mode 100644
index 000000000..9fb5dfc67
--- /dev/null
+++ b/keyboards/zinc/rev1/serial_config.h
@@ -0,0 +1,18 @@
1#ifndef SOFT_SERIAL_CONFIG_H
2#define SOFT_SERIAL_CONFIG_H
3
4#ifndef SOFT_SERIAL_PIN
5/* Soft Serial defines */
6#define SOFT_SERIAL_PIN D2
7// OPTIONAL: #define SELECT_SOFT_SERIAL_SPEED ? // ? = 1,2,3,4,5
8// // 1: about 137kbps (default)
9// // 2: about 75kbps
10// // 3: about 39kbps
11// // 4: about 26kbps
12// // 5: about 20kbps
13#endif
14
15//// USE flexible API (using multi-type transaction function)
16#define SERIAL_USE_MULTI_TRANSACTION
17
18#endif /* SOFT_SERIAL_CONFIG_H */
diff --git a/keyboards/zinc/rev1/serial_config_simpleapi.h b/keyboards/zinc/rev1/serial_config_simpleapi.h
new file mode 100644
index 000000000..e2d22a41e
--- /dev/null
+++ b/keyboards/zinc/rev1/serial_config_simpleapi.h
@@ -0,0 +1,8 @@
1#ifndef SERIAL_CONFIG_SIMPLEAPI_H
2#define SERIAL_CONFIG_SIMPLEAPI_H
3
4#undef SERIAL_USE_MULTI_TRANSACTION
5#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
6#define SERIAL_MASTER_BUFFER_LENGTH MATRIX_ROWS/2
7
8#endif // SERIAL_CONFIG_SIMPLEAPI_H
diff --git a/keyboards/zinc/rev1/split_scomm.c b/keyboards/zinc/rev1/split_scomm.c
new file mode 100644
index 000000000..50d233ce9
--- /dev/null
+++ b/keyboards/zinc/rev1/split_scomm.c
@@ -0,0 +1,95 @@
1#ifdef USE_SERIAL
2#ifdef SERIAL_USE_MULTI_TRANSACTION
3/* --- USE flexible API (using multi-type transaction function) --- */
4
5#include <stdbool.h>
6#include <stdint.h>
7#include <stddef.h>
8#include <split_scomm.h>
9#include "serial.h"
10#ifdef SERIAL_DEBUG_MODE
11#include <avr/io.h>
12#endif
13#ifdef CONSOLE_ENABLE
14 #include <print.h>
15#endif
16
17uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0};
18uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0};
19uint8_t volatile status_com = 0;
20uint8_t volatile status1 = 0;
21uint8_t slave_buffer_change_count = 0;
22uint8_t s_change_old = 0xff;
23uint8_t s_change_new = 0xff;
24
25SSTD_t transactions[] = {
26#define GET_SLAVE_STATUS 0
27 /* master buffer not changed, only recive slave_buffer_change_count */
28 { (uint8_t *)&status_com,
29 0, NULL,
30 sizeof(slave_buffer_change_count), &slave_buffer_change_count,
31 },
32#define PUT_MASTER_GET_SLAVE_STATUS 1
33 /* master buffer changed need send, and recive slave_buffer_change_count */
34 { (uint8_t *)&status_com,
35 sizeof(serial_master_buffer), (uint8_t *)serial_master_buffer,
36 sizeof(slave_buffer_change_count), &slave_buffer_change_count,
37 },
38#define GET_SLAVE_BUFFER 2
39 /* recive serial_slave_buffer */
40 { (uint8_t *)&status1,
41 0, NULL,
42 sizeof(serial_slave_buffer), (uint8_t *)serial_slave_buffer
43 }
44};
45
46void serial_master_init(void)
47{
48 soft_serial_initiator_init(transactions, TID_LIMIT(transactions));
49}
50
51void serial_slave_init(void)
52{
53 soft_serial_target_init(transactions, TID_LIMIT(transactions));
54}
55
56// 0 => no error
57// 1 => slave did not respond
58// 2 => checksum error
59int serial_update_buffers(int master_update)
60{
61 int status, smatstatus;
62 static int need_retry = 0;
63
64 if( s_change_old != s_change_new ) {
65 smatstatus = soft_serial_transaction(GET_SLAVE_BUFFER);
66 if( smatstatus == TRANSACTION_END ) {
67 s_change_old = s_change_new;
68#ifdef CONSOLE_ENABLE
69 uprintf("slave matrix = %b %b %b %b %b\n",
70 serial_slave_buffer[0], serial_slave_buffer[1],
71 serial_slave_buffer[2], serial_slave_buffer[3],
72 serial_slave_buffer[4] );
73#endif
74 }
75 } else {
76 // serial_slave_buffer dosen't change
77 smatstatus = TRANSACTION_END; // dummy status
78 }
79
80 if( !master_update && !need_retry) {
81 status = soft_serial_transaction(GET_SLAVE_STATUS);
82 } else {
83 status = soft_serial_transaction(PUT_MASTER_GET_SLAVE_STATUS);
84 }
85 if( status == TRANSACTION_END ) {
86 s_change_new = slave_buffer_change_count;
87 need_retry = 0;
88 } else {
89 need_retry = 1;
90 }
91 return smatstatus;
92}
93
94#endif // SERIAL_USE_MULTI_TRANSACTION
95#endif /* USE_SERIAL */
diff --git a/keyboards/zinc/rev1/split_scomm.h b/keyboards/zinc/rev1/split_scomm.h
new file mode 100644
index 000000000..873d8939d
--- /dev/null
+++ b/keyboards/zinc/rev1/split_scomm.h
@@ -0,0 +1,24 @@
1#ifndef SPLIT_COMM_H
2#define SPLIT_COMM_H
3
4#ifndef SERIAL_USE_MULTI_TRANSACTION
5/* --- USE Simple API (OLD API, compatible with let's split serial.c) --- */
6#include "serial.h"
7
8#else
9/* --- USE flexible API (using multi-type transaction function) --- */
10// Buffers for master - slave communication
11#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
12#define SERIAL_MASTER_BUFFER_LENGTH MATRIX_ROWS/2
13
14extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH];
15extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH];
16extern uint8_t slave_buffer_change_count;
17
18void serial_master_init(void);
19void serial_slave_init(void);
20int serial_update_buffers(int master_changed);
21
22#endif
23
24#endif /* SPLIT_COMM_H */
diff --git a/keyboards/zinc/rev1/split_util.c b/keyboards/zinc/rev1/split_util.c
new file mode 100644
index 000000000..e1ff8b437
--- /dev/null
+++ b/keyboards/zinc/rev1/split_util.c
@@ -0,0 +1,70 @@
1#include <avr/io.h>
2#include <avr/wdt.h>
3#include <avr/power.h>
4#include <avr/interrupt.h>
5#include <util/delay.h>
6#include <avr/eeprom.h>
7#include "split_util.h"
8#include "matrix.h"
9#include "keyboard.h"
10
11#ifdef USE_MATRIX_I2C
12# include "i2c.h"
13#else
14# include "split_scomm.h"
15#endif
16
17volatile bool isLeftHand = true;
18
19static void setup_handedness(void) {
20 #ifdef EE_HANDS
21 isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS);
22 #else
23 // I2C_MASTER_RIGHT is deprecated, use MASTER_RIGHT instead, since this works for both serial and i2c
24 #if defined(I2C_MASTER_RIGHT) || defined(MASTER_RIGHT)
25 isLeftHand = !has_usb();
26 #else
27 isLeftHand = has_usb();
28 #endif
29 #endif
30}
31
32static void keyboard_master_setup(void) {
33
34#ifdef USE_MATRIX_I2C
35 i2c_master_init();
36#else
37 serial_master_init();
38#endif
39}
40
41static void keyboard_slave_setup(void) {
42
43#ifdef USE_MATRIX_I2C
44 i2c_slave_init(SLAVE_I2C_ADDRESS);
45#else
46 serial_slave_init();
47#endif
48}
49
50bool has_usb(void) {
51 USBCON |= (1 << OTGPADE); //enables VBUS pad
52 _delay_us(5);
53 return (USBSTA & (1<<VBUS)); //checks state of VBUS
54}
55
56void split_keyboard_setup(void) {
57 setup_handedness();
58
59 if (has_usb()) {
60 keyboard_master_setup();
61 } else {
62 keyboard_slave_setup();
63 }
64 sei();
65}
66
67// this code runs before the usb and keyboard is initialized
68void matrix_setup(void) {
69 split_keyboard_setup();
70}
diff --git a/keyboards/zinc/rev1/split_util.h b/keyboards/zinc/rev1/split_util.h
new file mode 100644
index 000000000..687ca19bd
--- /dev/null
+++ b/keyboards/zinc/rev1/split_util.h
@@ -0,0 +1,19 @@
1#ifndef SPLIT_KEYBOARD_UTIL_H
2#define SPLIT_KEYBOARD_UTIL_H
3
4#include <stdbool.h>
5#include "eeconfig.h"
6
7#define SLAVE_I2C_ADDRESS 0x32
8
9extern volatile bool isLeftHand;
10
11// slave version of matix scan, defined in matrix.c
12void matrix_slave_scan(void);
13
14void split_keyboard_setup(void);
15bool has_usb(void);
16
17void matrix_master_OLED_init (void);
18
19#endif