aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Humbert <jack.humb@gmail.com>2019-01-10 11:26:40 -0500
committerMechMerlin <30334081+mechmerlin@users.noreply.github.com>2019-01-10 08:26:40 -0800
commitd28684da90536b54ff7d145decb80e0bd9290996 (patch)
tree5e7607561b8440ae3f1d078c9d00bdcdfbdd653b
parent3cf179be61a10860b2b66aecf2ec5ca6f0e30605 (diff)
downloadqmk_firmware-d28684da90536b54ff7d145decb80e0bd9290996.tar.gz
qmk_firmware-d28684da90536b54ff7d145decb80e0bd9290996.zip
Adds support for JacoBurge's TouchPad (#4186)
* add touchpad * progress * working with leds and vibrations * adds readme * Update keyboards/touchpad/readme.md Co-Authored-By: jackhumbert <jack.humb@gmail.com> * updates
-rwxr-xr-xdrivers/avr/i2c_master.c5
-rw-r--r--keyboards/touchpad/config.h70
-rw-r--r--keyboards/touchpad/keymaps/default/keymap.c30
-rw-r--r--keyboards/touchpad/matrix.c291
-rw-r--r--keyboards/touchpad/readme.md15
-rw-r--r--keyboards/touchpad/rules.mk67
-rw-r--r--keyboards/touchpad/touchpad.c1
-rw-r--r--keyboards/touchpad/touchpad.h2
8 files changed, 480 insertions, 1 deletions
diff --git a/drivers/avr/i2c_master.c b/drivers/avr/i2c_master.c
index a04e6570d..19bae33e9 100755
--- a/drivers/avr/i2c_master.c
+++ b/drivers/avr/i2c_master.c
@@ -179,6 +179,9 @@ i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16
179 status = i2c_write(regaddr, timeout); 179 status = i2c_write(regaddr, timeout);
180 if (status) return status; 180 if (status) return status;
181 181
182 status = i2c_stop(timeout);
183 if (status) return status;
184
182 status = i2c_start(devaddr | 0x01, timeout); 185 status = i2c_start(devaddr | 0x01, timeout);
183 if (status) return status; 186 if (status) return status;
184 187
@@ -217,4 +220,4 @@ i2c_status_t i2c_stop(uint16_t timeout)
217 } 220 }
218 221
219 return I2C_STATUS_SUCCESS; 222 return I2C_STATUS_SUCCESS;
220} \ No newline at end of file 223}
diff --git a/keyboards/touchpad/config.h b/keyboards/touchpad/config.h
new file mode 100644
index 000000000..8d34daae1
--- /dev/null
+++ b/keyboards/touchpad/config.h
@@ -0,0 +1,70 @@
1/*
2Copyright 2018 Jack Humbert <jack.humb@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#pragma once
19
20#include "config_common.h"
21
22/* USB Device descriptor parameter */
23#define VENDOR_ID 0x16D0
24#define PRODUCT_ID 0x0DB8
25#define DEVICE_VER 0x0001
26#define MANUFACTURER JacoBurge
27#define PRODUCT TouchPad
28#define DESCRIPTION A capacitive touchpad
29
30/* key matrix size */
31#define MATRIX_ROWS 6
32#define MATRIX_COLS 6
33
34
35/* define if matrix has ghost */
36//#define MATRIX_HAS_GHOST
37
38/* number of backlight levels */
39#define BACKLIGHT_LEVELS 3
40
41/* Set 0 if debouncing isn't needed */
42#define DEBOUNCING_DELAY 5
43
44/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
45#define LOCKING_SUPPORT_ENABLE
46/* Locking resynchronize hack */
47#define LOCKING_RESYNC_ENABLE
48
49/* key combination for command */
50#define IS_COMMAND() ( \
51 keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
52)
53
54/*
55 * Feature disable options
56 * These options are also useful to firmware size reduction.
57 */
58
59/* disable debug print */
60//#define NO_DEBUG
61
62/* disable print */
63//#define NO_PRINT
64
65/* disable action features */
66//#define NO_ACTION_LAYER
67//#define NO_ACTION_TAPPING
68//#define NO_ACTION_ONESHOT
69//#define NO_ACTION_MACRO
70//#define NO_ACTION_FUNCTION
diff --git a/keyboards/touchpad/keymaps/default/keymap.c b/keyboards/touchpad/keymaps/default/keymap.c
new file mode 100644
index 000000000..92f772aaa
--- /dev/null
+++ b/keyboards/touchpad/keymaps/default/keymap.c
@@ -0,0 +1,30 @@
1/* Copyright 2018 Jack Humbert <jack.humb@gmail.com>
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include QMK_KEYBOARD_H
18
19const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
20
21[0] = {
22 { KC_A, KC_B, KC_C, KC_D, KC_E, KC_F },
23 { KC_A, KC_B, KC_C, KC_D, KC_E, KC_F },
24 { KC_A, KC_B, KC_C, KC_D, KC_E, KC_F },
25 { KC_A, KC_B, KC_C, KC_D, KC_E, KC_F },
26 { KC_A, KC_B, KC_C, KC_D, KC_E, KC_F },
27 { KC_A, KC_B, KC_C, KC_D, KC_E, KC_F }
28}
29
30};
diff --git a/keyboards/touchpad/matrix.c b/keyboards/touchpad/matrix.c
new file mode 100644
index 000000000..3af4c5c3c
--- /dev/null
+++ b/keyboards/touchpad/matrix.c
@@ -0,0 +1,291 @@
1/*
2MIT License
3Copyright (c) 2018, JacoBurge
4Adapted for QMK by Jack Humbert in 2018
5
6Permission is hereby granted, free of charge, to any person obtaining a copy
7of this software and associated documentation files (the "Software"), to deal
8in the Software without restriction, including without limitation the rights
9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copies of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12The above copyright notice and this permission notice shall be included in all
13copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21SOFTWARE.
22*/
23
24#include "matrix.h"
25#include "i2c_master.h"
26#include "quantum.h"
27
28#define VIBRATE_LENGTH 50 //Defines number of interrupts motor will vibrate for, must be bigger than 8 for correct operation
29volatile uint8_t vibrate = 0; //Trigger vibration in interrupt
30
31static matrix_row_t matrix[MATRIX_ROWS];
32
33const uint8_t SENr[6] = {1, 2, 3, 5, 6, 7};//Maps capacitive pads to pins
34const uint8_t SENc[6] = {0, 4, 8, 9, 10, 11};
35
36volatile uint8_t LEDs[6][6] = {{0}};//Stores current LED values
37
38//Read data from the cap touch IC
39uint8_t readDataFromTS(uint8_t reg) {
40 uint8_t rx[1] = { 0 };
41 if (i2c_readReg(0x1C << 1, reg, rx, 1, 100) == 0) {
42 return rx[0];
43 }
44 return 0;
45}
46
47//Write data to cap touch IC
48uint8_t writeDataToTS(uint8_t reg, uint8_t data) {
49 uint8_t tx[2] = { reg, data };
50 if (i2c_transmit(0x1C << 1, tx, 2, 100) == 0) {
51 return 1;
52 } else {
53 return 0;
54 }
55}
56
57
58uint8_t checkTSPres(void) {
59 return (readDataFromTS(0x00) == 0x3E);
60}
61
62uint8_t capSetup(void) {
63
64 uint8_t temp_return = checkTSPres();
65
66 if (temp_return == 1) {
67 // Perform measurements every 16ms
68 writeDataToTS(0x08, 1);
69
70 // Increase detection integrator value
71 writeDataToTS(0x0B, 1);
72
73 // Oversample to gain two bits for columns
74 writeDataToTS(0x28, 0x42);
75 writeDataToTS(0x29, 0x00);
76 writeDataToTS(0x2A, 0x00);
77 writeDataToTS(0x2B, 0x00);
78 writeDataToTS(0x2C, 0x42);
79 writeDataToTS(0x2D, 0x00);
80 writeDataToTS(0x2E, 0x00);
81 writeDataToTS(0x2F, 0x00);
82 writeDataToTS(0x30, 0x42);
83 writeDataToTS(0x31, 0x42);
84 writeDataToTS(0x32, 0x42);
85 writeDataToTS(0x33, 0x42);
86
87 // Recalibration if touch detected for more than 8 seconds n*0.16s
88 writeDataToTS(0x0C, 50);
89
90 // Enable keys and set key groups
91 writeDataToTS(0x1C, 0x00 | 0x04);
92 writeDataToTS(0x1D, 0x00 | 0x08);
93 writeDataToTS(0x1E, 0x00 | 0x08);
94 writeDataToTS(0x1F, 0x00 | 0x08);
95 writeDataToTS(0x20, 0x00 | 0x04);
96 writeDataToTS(0x21, 0x00 | 0x08);
97 writeDataToTS(0x22, 0x00 | 0x08);
98 writeDataToTS(0x23, 0x00 | 0x08);
99 writeDataToTS(0x24, 0x00 | 0x04);
100 writeDataToTS(0x25, 0x00 | 0x04);
101 writeDataToTS(0x26, 0x00 | 0x04);
102 writeDataToTS(0x27, 0x00 | 0x04);
103
104 }
105 return temp_return;
106}
107
108__attribute__ ((weak))
109void matrix_init_user(void) {}
110
111__attribute__ ((weak))
112void matrix_scan_user(void) {}
113
114__attribute__ ((weak))
115void matrix_init_kb(void) {
116 matrix_init_user();
117}
118
119__attribute__ ((weak))
120void matrix_scan_kb(void) {
121 matrix_scan_user();
122}
123
124void matrix_init(void) {
125
126 i2c_init();
127
128 //Motor enable
129 setPinOutput(E6);
130 //Motor PWM
131 setPinOutput(D7);
132
133 //Power LED
134 setPinOutput(B7);
135 writePinHigh(B7);
136
137 //LEDs Columns
138 setPinOutput(F7);
139 setPinOutput(F6);
140 setPinOutput(F5);
141 setPinOutput(F4);
142 setPinOutput(F1);
143 setPinOutput(F0);
144
145 //LEDs Rows
146 setPinOutput(D6);
147 setPinOutput(B4);
148 setPinOutput(B5);
149 setPinOutput(B6);
150 setPinOutput(C6);
151 setPinOutput(C7);
152
153 //Capacitive Interrupt
154 setPinInput(D2);
155
156 capSetup();
157 writeDataToTS(0x06, 0x12); //Calibrate capacitive touch IC
158
159 memset(matrix, 0, MATRIX_ROWS * sizeof(matrix_row_t));
160
161 matrix_init_quantum();
162}
163
164
165uint16_t touchDetectionRoutine(void) {
166 uint16_t data;
167 uint8_t temp1, temp2;
168
169 temp1 = readDataFromTS(0x04);
170 temp2 = readDataFromTS(0x03);
171 data = temp1;
172 data = (data << 8) | temp2;
173 return data;
174
175}
176
177//Process raw capacitive data, map pins to rows and columns
178void decodeArray(uint16_t dataIn, uint8_t *column, uint8_t *row) {
179 uint8_t i1 = 20, i2 = 20;
180 for (uint8_t i = 0; i < 12; i++) {
181 if ((dataIn & 0b1) == 1) {
182 if (i1 == 20) {
183 i1 = i;
184 } else if (i2 == 20) {
185 i2 = i;
186 }
187 }
188 dataIn = dataIn >> 1;
189 }
190
191 for (uint8_t j = 0; j < 6; j++) {
192 if (SENr[j] == i1 || SENr[j] == i2) {
193 *row = j;
194 }
195 if (SENc[j] == i1 || SENc[j] == i2) {
196 *column = j;
197 }
198 }
199}
200
201void touchClearCurrentDetections(void) {
202 readDataFromTS(0x05);
203 readDataFromTS(0x02);
204 readDataFromTS(0x03);
205 readDataFromTS(0x04);
206}
207
208//Check interrupt pin
209uint8_t isTouchChangeDetected(void) {
210 return !readPin(D2);
211}
212
213uint8_t matrix_scan(void) {
214 if (isTouchChangeDetected()) {
215 uint16_t dataIn = touchDetectionRoutine();
216 if ((dataIn & 0b111100010001) > 0 && (dataIn & 0b000011101110) > 0) {
217 uint8_t column = 10, row = 10;
218 decodeArray(dataIn, &column, &row);
219 if (column != 10 && row != 10) {
220 vibrate = VIBRATE_LENGTH; //Trigger vibration
221 matrix[row] = _BV(column);
222 } else {
223 memset(matrix, 0, MATRIX_ROWS * sizeof(matrix_row_t));
224 }
225 } else {
226 memset(matrix, 0, MATRIX_ROWS * sizeof(matrix_row_t));
227 }
228 touchClearCurrentDetections();
229 }
230
231 for (uint8_t c = 0; c < 6; c++) {
232 for (uint8_t r = 0; r < 6; r++) {
233 switch (r) {
234 case 0: writePin(D6, matrix_is_on(r, c)); break;
235 case 1: writePin(B4, matrix_is_on(r, c)); break;
236 case 2: writePin(B5, matrix_is_on(r, c)); break;
237 case 3: writePin(B6, matrix_is_on(r, c)); break;
238 case 4: writePin(C6, matrix_is_on(r, c)); break;
239 case 5: writePin(C7, matrix_is_on(r, c)); break;
240 }
241
242 switch (c) {
243 case 0: writePin(F5, !matrix_is_on(r, c)); break;
244 case 1: writePin(F4, !matrix_is_on(r, c)); break;
245 case 2: writePin(F1, !matrix_is_on(r, c)); break;
246 case 3: writePin(F0, !matrix_is_on(r, c)); break;
247 case 4: writePin(F6, !matrix_is_on(r, c)); break;
248 case 5: writePin(F7, !matrix_is_on(r, c)); break;
249 }
250 }
251 }
252
253 if (vibrate == VIBRATE_LENGTH) {
254 writePinHigh(E6);
255 writePinHigh(D7);
256 vibrate--;
257 } else if (vibrate > 0) {
258 vibrate--;
259 } else if (vibrate == 0) {
260 writePinLow(D7);
261 writePinLow(E6);
262 }
263
264 matrix_scan_quantum();
265
266 return 1;
267
268}
269
270bool matrix_is_on(uint8_t row, uint8_t col) {
271 return (matrix[row] & (1<<col));
272}
273
274matrix_row_t matrix_get_row(uint8_t row) {
275 return matrix[row];
276}
277
278void matrix_print(void) {
279 printf("\nr/c 01234567\n");
280 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
281 printf("%X0: ", row);
282 matrix_row_t data = matrix_get_row(row);
283 for (int col = 0; col < MATRIX_COLS; col++) {
284 if (data & (1<<col))
285 printf("1");
286 else
287 printf("0");
288 }
289 printf("\n");
290 }
291}
diff --git a/keyboards/touchpad/readme.md b/keyboards/touchpad/readme.md
new file mode 100644
index 000000000..f80bfa87b
--- /dev/null
+++ b/keyboards/touchpad/readme.md
@@ -0,0 +1,15 @@
1# Touchpad
2
3![TouchPad](https://static1.squarespace.com/static/561b7180e4b05a82a1747f0b/59d8985903596eb5953e1803/5a43f205e4966b67c55878a2/1521104083905/IMG_2183.jpg?format=2500w)
4
5A small capacitive 6x6 touchpad for launching programs. [More info](https://jacoburge.co.uk/touch-pad/)
6
7Keyboard Maintainer: QMK Community
8Hardware Supported: TouchPad PCB
9Hardware Availability: [JaboBurge's Shop](https://jacoburge.co.uk/shop)
10
11Make example for this keyboard (after setting up your build environment):
12
13 make touchpad:default
14
15See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/touchpad/rules.mk b/keyboards/touchpad/rules.mk
new file mode 100644
index 000000000..e4fa2ac13
--- /dev/null
+++ b/keyboards/touchpad/rules.mk
@@ -0,0 +1,67 @@
1# MCU name
2MCU = atmega32u4
3
4SRC = matrix.c i2c_master.c
5
6# Processor frequency.
7# This will define a symbol, F_CPU, in all source code files equal to the
8# processor frequency in Hz. You can then use this symbol in your source code to
9# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
10# automatically to create a 32-bit value in your source code.
11#
12# This will be an integer division of F_USB below, as it is sourced by
13# F_USB after it has run through any CPU prescalers. Note that this value
14# does not *change* the processor frequency - it should merely be updated to
15# reflect the processor speed set externally so that the code can use accurate
16# software delays.
17F_CPU = 16000000
18
19#
20# LUFA specific
21#
22# Target architecture (see library "Board Types" documentation).
23ARCH = AVR8
24
25# Input clock frequency.
26# This will define a symbol, F_USB, in all source code files equal to the
27# input clock frequency (before any prescaling is performed) in Hz. This value may
28# differ from F_CPU if prescaling is used on the latter, and is required as the
29# raw input clock is fed directly to the PLL sections of the AVR for high speed
30# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
31# at the end, this will be done automatically to create a 32-bit value in your
32# source code.
33#
34# If no clock division is performed on the input clock inside the AVR (via the
35# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
36F_USB = $(F_CPU)
37
38# Bootloader
39# This definition is optional, and if your keyboard supports multiple bootloaders of
40# different sizes, comment this out, and the correct address will be loaded
41# automatically (+60). See bootloader.mk for all options.
42BOOTLOADER = caterina
43
44# Interrupt driven control endpoint task(+60)
45OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
46
47# Build Options
48# change to "no" to disable the options, or define them in the Makefile in
49# the appropriate keymap folder that will get included automatically
50#
51BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
52MOUSEKEY_ENABLE = no # Mouse keys(+4700)
53EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
54CONSOLE_ENABLE = yes # Console for debug(+400)
55COMMAND_ENABLE = no # Commands for debug and configuration
56NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
57BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
58MIDI_ENABLE = no # MIDI controls
59AUDIO_ENABLE = no # Audio output on port C6
60UNICODE_ENABLE = no # Unicode
61BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
62RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight.
63API_SYSEX_ENABLE = no
64CUSTOM_MATRIX = yes
65
66# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
67SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
diff --git a/keyboards/touchpad/touchpad.c b/keyboards/touchpad/touchpad.c
new file mode 100644
index 000000000..fe96d56b6
--- /dev/null
+++ b/keyboards/touchpad/touchpad.c
@@ -0,0 +1 @@
#include "touchpad.h"
diff --git a/keyboards/touchpad/touchpad.h b/keyboards/touchpad/touchpad.h
new file mode 100644
index 000000000..010d4b138
--- /dev/null
+++ b/keyboards/touchpad/touchpad.h
@@ -0,0 +1,2 @@
1#pragma once
2#include "quantum.h"