aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErin Call <hello@erincall.com>2017-11-25 23:18:59 -0800
committerJack Humbert <jack.humb@gmail.com>2017-11-26 02:18:59 -0500
commitf2a0b0ee20619d2634d7e18ae662768d91402961 (patch)
tree0453edfab767b891e4da204c859c3e7ca67dc249
parent18525aa17b744436a2f35f7e5391820491dbc886 (diff)
downloadqmk_firmware-f2a0b0ee20619d2634d7e18ae662768d91402961.tar.gz
qmk_firmware-f2a0b0ee20619d2634d7e18ae662768d91402961.zip
Handwired/Dactyl keyboard (#2058)
* Copy the ergodox_ez code to handwired/dactyl Differences from the Ergodox: * Use QMK_SUBPROJECT_H instead of QMK_KEYBOARD_H, since it's under handwired * Omitted several keymaps. They'll eventually be broken (since the Dactyl has fewer keys), and I don't want to try to fix them. * Omitted the keymap images for the default layout, since they depict a different keyboard. * Everything that said Ergodox now says Dactyl, naturally. * [whitespace] Delete trailing whitespace My editor does this automatically so it's just gonna keep cropping up... * Cut the dactyl down to the right number of columns (Remember, throughout matrix.c, everything called "row" is really a column, and vice-versa). * Remove LED-related code * Tighten up the Dactyl's build options * Whitespace cleanup in twimaster.c * Hardtabs -> spaces * No more trailing whitespace * Typo fix * Correct the CPU frequency units The Teensy's CPU definitely doesn't run at 16 petahertz... * Restore access to ONEHAND_ENABLE I turned it off in 26d47cb42622d990a7c3335e7fcc151aa3edfbf0 while desperately debugging; I just wanted to ensure it wasn't causing the problem I was seeing. It was not, in fact, causing the problem, so it's back. Also fixed the swap matrix in dactyl.c, since it still referred to columns that exist in the Ergodox but not the Dactyl. * Clearer phrasing about TWI's effect on scan rate * Fix up the Dactyl's firmware-loading instructions Sadly, the Dactyl has no hole for the onboard reset button. * Dvorak keymap for the Dactyl * The Erincalling Layout * Erincalling layout: Add a := key I've been working in Go, which uses := a lot, and it's awkward to type in this layout. * Dactyl README: link to the dactyl-keyboard repo * Add a missing copyright line I don't know how much this matters? Honestly, it's enough for me that my name is on the git commit. But hey, let's be consistent until there's a specific reason not to be, right? * Dactyl: remove commented-out code I hate it I hate it I hate it There's not even any information about what it was trying to do!!!! >:( * Add a note about the row/column ridiculousness * [whitespace] realign some constants * Don't claim B4 is tied to VCC It doesn't matter at all? I honestly don't know what the reason ever was. It looks like it dates back to the original ErgoDox and I've never seen one sentence about the purpose. I've been skipping that wire for some time, and I promise it works fine. * Dactyl keymaps: Send RALT for right-hand alt key Not terribly important but I just like things tidy OK * typo fix * Refer to "dactyl.h" explicitly QMK_SUBPROJECT_H has been working locally, but fails in CI. Strange! * Dactyl: Don't use QMK_SUBPROJECT_H at all It's still breaking in CI, even though it was a never a problem locally.
-rw-r--r--keyboards/handwired/dactyl/config.h67
-rw-r--r--keyboards/handwired/dactyl/dactyl.c80
-rw-r--r--keyboards/handwired/dactyl/dactyl.h74
-rw-r--r--keyboards/handwired/dactyl/i2cmaster.h178
-rw-r--r--keyboards/handwired/dactyl/keymaps/default/keymap.c183
-rw-r--r--keyboards/handwired/dactyl/keymaps/default/readme.md10
-rw-r--r--keyboards/handwired/dactyl/keymaps/dvorak/keymap.c183
-rw-r--r--keyboards/handwired/dactyl/keymaps/dvorak/readme.md9
-rw-r--r--keyboards/handwired/dactyl/keymaps/erincalling/keymap.c162
-rw-r--r--keyboards/handwired/dactyl/keymaps/erincalling/readme.md6
-rw-r--r--keyboards/handwired/dactyl/matrix.c393
-rw-r--r--keyboards/handwired/dactyl/readme.md37
-rw-r--r--keyboards/handwired/dactyl/rules.mk86
-rw-r--r--keyboards/handwired/dactyl/twimaster.c207
14 files changed, 1675 insertions, 0 deletions
diff --git a/keyboards/handwired/dactyl/config.h b/keyboards/handwired/dactyl/config.h
new file mode 100644
index 000000000..8129b0a67
--- /dev/null
+++ b/keyboards/handwired/dactyl/config.h
@@ -0,0 +1,67 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3Copyright 2013 Oleg Kostyuk <cub.uanic@gmail.com>
4Copyright 2017 Erin Call <hello@erincall.com>
5
6This program is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#ifndef DACTYL_CONFIG_H
21#define DACTYL_CONFIG_H
22
23#include "config_common.h"
24
25/* USB Device descriptor parameter */
26#define VENDOR_ID 0xFEED
27#define PRODUCT_ID 0x1308
28#define DEVICE_VER 0x0001
29#define MANUFACTURER Adereth
30#define PRODUCT Dactyl
31#define DESCRIPTION An ortholinear, split, 3D-curved keyboard with thumb clusters.
32
33/* key matrix size
34 * At this time, "row" in the dactyl's code actually means "column" on the
35 * physical keyboard. It's confusing. I'm sorry. Blame Jack Humbert :P
36 */
37#define MATRIX_ROWS 12
38#define MATRIX_COLS 6
39
40#define MOUSEKEY_INTERVAL 20
41#define MOUSEKEY_DELAY 0
42#define MOUSEKEY_TIME_TO_MAX 60
43#define MOUSEKEY_MAX_SPEED 7
44#define MOUSEKEY_WHEEL_DELAY 0
45
46#define TAPPING_TOGGLE 1
47
48#define TAPPING_TERM 200
49#define IGNORE_MOD_TAP_INTERRUPT // this makes it possible to do rolling combos (zx) with keys that convert to other keys on hold (z becomes ctrl when you hold it, and when this option isn't enabled, z rapidly followed by x actually sends Ctrl-x. That's bad.)
50
51/* key combination for command */
52#define IS_COMMAND() ( \
53 keyboard_report->mods == (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL)) || \
54 keyboard_report->mods == (MOD_BIT(KC_LSFT) | MOD_BIT(KC_RSFT)) \
55)
56
57/* fix space cadet rollover issue */
58#define DISABLE_SPACE_CADET_ROLLOVER
59
60/* Set 0 if debouncing isn't needed */
61#define DEBOUNCE 15
62
63#define PREVENT_STUCK_MODIFIERS
64
65#define USB_MAX_POWER_CONSUMPTION 500
66
67#endif
diff --git a/keyboards/handwired/dactyl/dactyl.c b/keyboards/handwired/dactyl/dactyl.c
new file mode 100644
index 000000000..3f59154fd
--- /dev/null
+++ b/keyboards/handwired/dactyl/dactyl.c
@@ -0,0 +1,80 @@
1#include "dactyl.h"
2#include "i2cmaster.h"
3
4
5bool i2c_initialized = 0;
6uint8_t mcp23018_status = 0x20;
7
8void matrix_init_kb(void) {
9 DDRB &= ~(1<<4); // set B(4) as input
10 PORTB &= ~(1<<4); // set B(4) internal pull-up disabled
11
12 // unused pins - C7, D4, D5, D7, E6
13 // set as input with internal pull-up enabled
14 DDRC &= ~(1<<7);
15 DDRD &= ~(1<<5 | 1<<4);
16 DDRE &= ~(1<<6);
17 PORTC |= (1<<7);
18 PORTD |= (1<<5 | 1<<4);
19 PORTE |= (1<<6);
20
21 matrix_init_user();
22}
23
24uint8_t init_mcp23018(void) {
25 mcp23018_status = 0x20;
26
27 // I2C subsystem
28
29 if (i2c_initialized == 0) {
30 i2c_init(); // on pins D(1,0)
31 i2c_initialized = true;
32 _delay_ms(1000);
33 }
34
35 // set pin direction
36 // - unused : input : 1
37 // - input : input : 1
38 // - driving : output : 0
39 mcp23018_status = i2c_start(I2C_ADDR_WRITE); if (mcp23018_status) goto out;
40 mcp23018_status = i2c_write(IODIRA); if (mcp23018_status) goto out;
41 mcp23018_status = i2c_write(0b00000000); if (mcp23018_status) goto out;
42 mcp23018_status = i2c_write(0b00111111); if (mcp23018_status) goto out;
43 i2c_stop();
44
45 // set pull-up
46 // - unused : on : 1
47 // - input : on : 1
48 // - driving : off : 0
49 mcp23018_status = i2c_start(I2C_ADDR_WRITE); if (mcp23018_status) goto out;
50 mcp23018_status = i2c_write(GPPUA); if (mcp23018_status) goto out;
51 mcp23018_status = i2c_write(0b00000000); if (mcp23018_status) goto out;
52 mcp23018_status = i2c_write(0b00111111); if (mcp23018_status) goto out;
53
54out:
55 i2c_stop();
56
57 return mcp23018_status;
58}
59
60#ifdef ONEHAND_ENABLE
61__attribute__ ((weak))
62// swap-hands action needs a matrix to define the swap
63const keypos_t hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
64 /* Left hand, matrix positions */
65 {{0,11}, {1,11}, {2,11}, {3,11}, {4,11}, {5,11}},
66 {{0,10}, {1,10}, {2,10}, {3,10}, {4,10}, {5,10}},
67 {{0,9}, {1,9}, {2,9}, {3,9}, {4,9}, {5,9}},
68 {{0,8}, {1,8}, {2,8}, {3,8}, {4,8}, {5,8}},
69 {{0,7}, {1,7}, {2,7}, {3,7}, {4,7}, {5,7}},
70 {{0,6}, {1,6}, {2,6}, {3,6}, {4,6}, {5,6}},
71
72 /* Right hand, matrix positions */
73 {{0,5}, {1,5}, {2,5}, {3,5}, {4,5}, {5,5}},
74 {{0,4}, {1,4}, {2,4}, {3,4}, {4,4}, {5,4}},
75 {{0,3}, {1,3}, {2,3}, {3,3}, {4,3}, {5,3}},
76 {{0,2}, {1,2}, {2,2}, {3,2}, {4,2}, {5,2}},
77 {{0,1}, {1,1}, {2,1}, {3,1}, {4,1}, {5,1}},
78 {{0,0}, {1,0}, {2,0}, {3,0}, {4,0}, {5,0}},
79};
80#endif
diff --git a/keyboards/handwired/dactyl/dactyl.h b/keyboards/handwired/dactyl/dactyl.h
new file mode 100644
index 000000000..aa573ebd2
--- /dev/null
+++ b/keyboards/handwired/dactyl/dactyl.h
@@ -0,0 +1,74 @@
1#ifndef DACTYL_H
2#define DACTYL_H
3
4#include "quantum.h"
5#include <stdint.h>
6#include <stdbool.h>
7#include "i2cmaster.h"
8#include <util/delay.h>
9
10#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
11#define CPU_16MHz 0x00
12
13// I2C aliases and register addresses (see "mcp23018.md")
14#define I2C_ADDR 0b0100000
15#define I2C_ADDR_WRITE ( (I2C_ADDR<<1) | I2C_WRITE )
16#define I2C_ADDR_READ ( (I2C_ADDR<<1) | I2C_READ )
17#define IODIRA 0x00 // i/o direction register
18#define IODIRB 0x01
19#define GPPUA 0x0C // GPIO pull-up resistor register
20#define GPPUB 0x0D
21#define GPIOA 0x12 // general purpose i/o port register (write modifies OLAT)
22#define GPIOB 0x13
23#define OLATA 0x14 // output latch register
24#define OLATB 0x15
25
26extern uint8_t mcp23018_status;
27
28void init_dactyl(void);
29uint8_t init_mcp23018(void);
30
31#define KEYMAP( \
32 \
33 /* left hand, spatial positions */ \
34 k00,k01,k02,k03,k04,k05, \
35 k10,k11,k12,k13,k14,k15, \
36 k20,k21,k22,k23,k24,k25, \
37 k30,k31,k32,k33,k34,k35, \
38 k40,k41,k42,k43,k44, \
39 k55,k50, \
40 k54, \
41 k53,k52,k51, \
42 \
43 /* right hand, spatial positions */ \
44 k06,k07,k08,k09,k0A,k0B, \
45 k16,k17,k18,k19,k1A,k1B, \
46 k26,k27,k28,k29,k2A,k2B, \
47 k36,k37,k38,k39,k3A,k3B, \
48 k47,k48,k49,k4A,k4B, \
49 k5B,k56, \
50 k57, \
51 k5A,k59,k58 ) \
52 \
53 /* matrix positions */ \
54 { \
55 { k00, k10, k20, k30, k40, k50 }, \
56 { k01, k11, k21, k31, k41, k51 }, \
57 { k02, k12, k22, k32, k42, k52 }, \
58 { k03, k13, k23, k33, k43, k53 }, \
59 { k04, k14, k24, k34, k44, k54 }, \
60 { k05, k15, k25, k35, KC_NO, k55 }, \
61 \
62 { k06, k16, k26, k36, KC_NO, k56 }, \
63 { k07, k17, k27, k37, k47, k57 }, \
64 { k08, k18, k28, k38, k48, k58 }, \
65 { k09, k19, k29, k39, k49, k59 }, \
66 { k0A, k1A, k2A, k3A, k4A, k5A }, \
67 { k0B, k1B, k2B, k3B, k4B, k5B } \
68 }
69
70
71
72#define LAYOUT_dactyl KEYMAP
73
74#endif
diff --git a/keyboards/handwired/dactyl/i2cmaster.h b/keyboards/handwired/dactyl/i2cmaster.h
new file mode 100644
index 000000000..3917b9e6c
--- /dev/null
+++ b/keyboards/handwired/dactyl/i2cmaster.h
@@ -0,0 +1,178 @@
1#ifndef _I2CMASTER_H
2#define _I2CMASTER_H 1
3/*************************************************************************
4* Title: C include file for the I2C master interface
5* (i2cmaster.S or twimaster.c)
6* Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
7* File: $Id: i2cmaster.h,v 1.10 2005/03/06 22:39:57 Peter Exp $
8* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
9* Target: any AVR device
10* Usage: see Doxygen manual
11**************************************************************************/
12
13#ifdef DOXYGEN
14/**
15 @defgroup pfleury_ic2master I2C Master library
16 @code #include <i2cmaster.h> @endcode
17
18 @brief I2C (TWI) Master Software Library
19
20 Basic routines for communicating with I2C slave devices. This single master
21 implementation is limited to one bus master on the I2C bus.
22
23 This I2c library is implemented as a compact assembler software implementation of the I2C protocol
24 which runs on any AVR (i2cmaster.S) and as a TWI hardware interface for all AVR with built-in TWI hardware (twimaster.c).
25 Since the API for these two implementations is exactly the same, an application can be linked either against the
26 software I2C implementation or the hardware I2C implementation.
27
28 Use 4.7k pull-up resistor on the SDA and SCL pin.
29
30 Adapt the SCL and SDA port and pin definitions and eventually the delay routine in the module
31 i2cmaster.S to your target when using the software I2C implementation !
32
33 Adjust the CPU clock frequence F_CPU in twimaster.c or in the Makfile when using the TWI hardware implementaion.
34
35 @note
36 The module i2cmaster.S is based on the Atmel Application Note AVR300, corrected and adapted
37 to GNU assembler and AVR-GCC C call interface.
38 Replaced the incorrect quarter period delays found in AVR300 with
39 half period delays.
40
41 @author Peter Fleury pfleury@gmx.ch http://jump.to/fleury
42
43 @par API Usage Example
44 The following code shows typical usage of this library, see example test_i2cmaster.c
45
46 @code
47
48 #include <i2cmaster.h>
49
50
51 #define Dev24C02 0xA2 // device address of EEPROM 24C02, see datasheet
52
53 int main(void)
54 {
55 unsigned char ret;
56
57 i2c_init(); // initialize I2C library
58
59 // write 0x75 to EEPROM address 5 (Byte Write)
60 i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
61 i2c_write(0x05); // write address = 5
62 i2c_write(0x75); // write value 0x75 to EEPROM
63 i2c_stop(); // set stop conditon = release bus
64
65
66 // read previously written value back from EEPROM address 5
67 i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
68
69 i2c_write(0x05); // write address = 5
70 i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode
71
72 ret = i2c_readNak(); // read one byte from EEPROM
73 i2c_stop();
74
75 for(;;);
76 }
77 @endcode
78
79*/
80#endif /* DOXYGEN */
81
82/**@{*/
83
84#if (__GNUC__ * 100 + __GNUC_MINOR__) < 304
85#error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !"
86#endif
87
88#include <avr/io.h>
89
90/** defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start() */
91#define I2C_READ 1
92
93/** defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start() */
94#define I2C_WRITE 0
95
96
97/**
98 @brief initialize the I2C master interace. Need to be called only once
99 @param void
100 @return none
101 */
102extern void i2c_init(void);
103
104
105/**
106 @brief Terminates the data transfer and releases the I2C bus
107 @param void
108 @return none
109 */
110extern void i2c_stop(void);
111
112
113/**
114 @brief Issues a start condition and sends address and transfer direction
115
116 @param addr address and transfer direction of I2C device
117 @retval 0 device accessible
118 @retval 1 failed to access device
119 */
120extern unsigned char i2c_start(unsigned char addr);
121
122
123/**
124 @brief Issues a repeated start condition and sends address and transfer direction
125
126 @param addr address and transfer direction of I2C device
127 @retval 0 device accessible
128 @retval 1 failed to access device
129 */
130extern unsigned char i2c_rep_start(unsigned char addr);
131
132
133/**
134 @brief Issues a start condition and sends address and transfer direction
135
136 If device is busy, use ack polling to wait until device ready
137 @param addr address and transfer direction of I2C device
138 @return none
139 */
140extern void i2c_start_wait(unsigned char addr);
141
142
143/**
144 @brief Send one byte to I2C device
145 @param data byte to be transfered
146 @retval 0 write successful
147 @retval 1 write failed
148 */
149extern unsigned char i2c_write(unsigned char data);
150
151
152/**
153 @brief read one byte from the I2C device, request more data from device
154 @return byte read from I2C device
155 */
156extern unsigned char i2c_readAck(void);
157
158/**
159 @brief read one byte from the I2C device, read is followed by a stop condition
160 @return byte read from I2C device
161 */
162extern unsigned char i2c_readNak(void);
163
164/**
165 @brief read one byte from the I2C device
166
167 Implemented as a macro, which calls either i2c_readAck or i2c_readNak
168
169 @param ack 1 send ack, request more data from device<br>
170 0 send nak, read is followed by a stop condition
171 @return byte read from I2C device
172 */
173extern unsigned char i2c_read(unsigned char ack);
174#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak();
175
176
177/**@}*/
178#endif
diff --git a/keyboards/handwired/dactyl/keymaps/default/keymap.c b/keyboards/handwired/dactyl/keymaps/default/keymap.c
new file mode 100644
index 000000000..0d414d85b
--- /dev/null
+++ b/keyboards/handwired/dactyl/keymaps/default/keymap.c
@@ -0,0 +1,183 @@
1#include "dactyl.h"
2#include "debug.h"
3#include "action_layer.h"
4#include "version.h"
5
6#define BASE 0 // default layer
7#define SYMB 1 // symbols
8#define MDIA 2 // media keys
9
10enum custom_keycodes {
11 PLACEHOLDER = SAFE_RANGE, // ensure these codes start after the highest keycode defined in Quantum
12 VRSN,
13};
14
15const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
16/* Keymap 0: Basic layer
17 *
18 * ,-----------------------------------------. ,-----------------------------------------.
19 * | = | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | - |
20 * |------+------+------+------+------+------| |------+------+------+------+------+------|
21 * | Del | Q | W | E | R | T | | Y | U | I | O | P | \ |
22 * |------+------+------+------+------+------| |------+------+------+------+------+------|
23 * | BkSp | A | S | D | F | G | | H | J | K | L |; / L2|'/Cmd |
24 * |------+------+------+------+------+------| |------+------+------+------+------+------|
25 * |LShift|Z/Ctrl| X | C | V | B | | N | M | , | . |//Ctrl|RShift|
26 * |------+------+------+------+------+------' `------+------+------+------+------+------|
27 * |Grv/L1| '" |AltShf| Left | Right| | Up | Down | [ | ] | ~L1 |
28 * `----------------------------------' `----------------------------------'
29 * ,-------------. ,-------------.
30 * | App | LGui | | Alt | ^/Esc|
31 * ,------|------|------| |------+------+------.
32 * | | | Home | | PgUp | | |
33 * | Space|Backsp|------| |------| Tab |Enter |
34 * | |ace | End | | PgDn | | |
35 * `--------------------' `--------------------'
36 */
37[BASE] = LAYOUT_dactyl( // layer 0 : default
38 // left hand
39 KC_EQL, KC_1, KC_2, KC_3, KC_4, KC_5,
40 KC_DELT, KC_Q, KC_W, KC_E, KC_R, KC_T,
41 KC_BSPC, KC_A, KC_S, KC_D, KC_F, KC_G,
42 KC_LSFT, CTL_T(KC_Z), KC_X, KC_C, KC_V, KC_B,
43 LT(SYMB,KC_GRV), KC_QUOT, LALT(KC_LSFT), KC_LEFT, KC_RGHT,
44 ALT_T(KC_APP), KC_LGUI,
45 KC_HOME,
46 KC_SPC, KC_BSPC, KC_END,
47 // right hand
48 KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
49 KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLS,
50 KC_H, KC_J, KC_K, KC_L, LT(MDIA, KC_SCLN), GUI_T(KC_QUOT),
51 KC_N, KC_M, KC_COMM, KC_DOT, CTL_T(KC_SLSH), KC_RSFT,
52 KC_UP, KC_DOWN, KC_LBRC, KC_RBRC, KC_FN1,
53 KC_RALT, CTL_T(KC_ESC),
54 KC_PGUP,
55 KC_PGDN, KC_TAB, KC_ENT
56 ),
57/* Keymap 1: Symbol Layer
58 *
59 * ,-----------------------------------------. ,-----------------------------------------.
60 * |Versn | F1 | F2 | F3 | F4 | F5 | | F6 | F7 | F8 | F9 | F10 | F11 |
61 * |------+------+------+------+------+------| |------+------+------+------+------+------|
62 * | | ! | @ | { | } | | | | Up | 7 | 8 | 9 | * | F12 |
63 * |------+------+------+------+------+------| |------+------+------+------+------+------|
64 * | | # | $ | ( | ) | ` | | Down | 4 | 5 | 6 | + | |
65 * |------+------+------+------+------+------| |------+------+------+------+------+------|
66 * | | % | ^ | [ | ] | ~ | | & | 1 | 2 | 3 | \ | |
67 * |------+------+------+------+------+------' `------+------+------+------+------+------|
68 * |RESET | | | | | | | . | 0 | = | |
69 * `----------------------------------' `----------------------------------'
70 * ,-------------. ,-------------.
71 * | | | | | |
72 * ,------|------|------| |------+------+------.
73 * | | | | | | | |
74 * | | |------| |------| | |
75 * | | | | | | | |
76 * `--------------------' `--------------------'
77 */
78// SYMBOLS
79[SYMB] = LAYOUT_dactyl(
80 // left hand
81 VRSN, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5,
82 KC_TRNS, KC_EXLM, KC_AT, KC_LCBR, KC_RCBR, KC_PIPE,
83 KC_TRNS, KC_HASH, KC_DLR, KC_LPRN, KC_RPRN, KC_GRV,
84 KC_TRNS, KC_PERC, KC_CIRC, KC_LBRC, KC_RBRC, KC_TILD,
85 RESET, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
86 KC_TRNS, KC_TRNS,
87 KC_TRNS,
88 KC_TRNS, KC_TRNS, KC_TRNS,
89 // right hand
90 KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
91 KC_UP, KC_7, KC_8, KC_9, KC_ASTR, KC_F12,
92 KC_DOWN, KC_4, KC_5, KC_6, KC_PLUS, KC_TRNS,
93 KC_AMPR, KC_1, KC_2, KC_3, KC_BSLS, KC_TRNS,
94 KC_TRNS, KC_DOT, KC_0, KC_EQL, KC_TRNS,
95 KC_TRNS, KC_TRNS,
96 KC_TRNS,
97 KC_TRNS, KC_TRNS, KC_TRNS
98),
99/* Keymap 2: Media and mouse keys
100 * ,-----------------------------------------. ,-----------------------------------------.
101 * | | | | | | | | | | | | | |
102 * |------+------+------+------+------+------| |------+------+------+------+------+------|
103 * | | | | MsUp | | | | | | | | | |
104 * |------+------+------+------+------+------| |------+------+------+------+------+------|
105 * | | |MsLeft|MsDown|MsRght| | | | | | | | Play |
106 * |------+------+------+------+------+------| |------+------+------+------+------+------|
107 * | | | | | | | | | | Prev | Next | | |
108 * |------+------+------+------+------+------' `------+------+------+------+------+------|
109 * | | | | Lclk | Rclk | | VolUp| VolDn| Mute | | |
110 * `----------------------------------' `----------------------------------'
111 * ,-------------. ,-------------.
112 * | | | | | |
113 * ,------|------|------| |------+------+------.
114 * | | | | | | |Brwser|
115 * | | |------| |------| |Back |
116 * | | | | | | | |
117 * `--------------------' `--------------------'
118 *
119 */
120// MEDIA AND MOUSE
121[MDIA] = LAYOUT_dactyl(
122 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
123 KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, KC_TRNS, KC_TRNS,
124 KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_TRNS,
125 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
126 KC_TRNS, KC_TRNS, KC_TRNS, KC_BTN1, KC_BTN2,
127 KC_TRNS, KC_TRNS,
128 KC_TRNS,
129 KC_TRNS, KC_TRNS, KC_TRNS,
130 // right hand
131 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
132 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
133 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY,
134 KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS,
135 KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS,
136 KC_TRNS, KC_TRNS,
137 KC_TRNS,
138 KC_TRNS, KC_TRNS, KC_WBAK
139),
140};
141
142const uint16_t PROGMEM fn_actions[] = {
143 [1] = ACTION_LAYER_TAP_TOGGLE(SYMB) // FN1 - Momentary Layer 1 (Symbols)
144};
145
146const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
147{
148 // MACRODOWN only works in this function
149 switch(id) {
150 case 0:
151 if (record->event.pressed) {
152 SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
153 }
154 break;
155 case 1:
156 if (record->event.pressed) { // For resetting EEPROM
157 eeconfig_init();
158 }
159 break;
160 }
161 return MACRO_NONE;
162};
163
164bool process_record_user(uint16_t keycode, keyrecord_t *record) {
165 switch (keycode) {
166 case VRSN:
167 if (record->event.pressed) {
168 SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
169 }
170 return false;
171 break;
172 }
173 return true;
174}
175
176// Runs just one time when the keyboard initializes.
177void matrix_init_user(void) {
178
179};
180
181
182// Runs constantly in the background, in a loop.
183void matrix_scan_user(void) {};
diff --git a/keyboards/handwired/dactyl/keymaps/default/readme.md b/keyboards/handwired/dactyl/keymaps/default/readme.md
new file mode 100644
index 000000000..e393e396e
--- /dev/null
+++ b/keyboards/handwired/dactyl/keymaps/default/readme.md
@@ -0,0 +1,10 @@
1# Dactyl Default Configuration
2
3## Changelog
4
5* Nov 2017:
6 * Copied and adapted from the Ergodox EZ equivalent
7 * Notable differences:
8 - Don't try to have the columns that don't exist, naturally
9 - Removed RGB keys, since there are no RGB LEDs in the Dactyl (as designed, at least)
10
diff --git a/keyboards/handwired/dactyl/keymaps/dvorak/keymap.c b/keyboards/handwired/dactyl/keymaps/dvorak/keymap.c
new file mode 100644
index 000000000..a0b98b993
--- /dev/null
+++ b/keyboards/handwired/dactyl/keymaps/dvorak/keymap.c
@@ -0,0 +1,183 @@
1#include "dactyl.h"
2#include "debug.h"
3#include "action_layer.h"
4#include "version.h"
5
6#define BASE 0 // default layer
7#define SYMB 1 // symbols
8#define MDIA 2 // media keys
9
10enum custom_keycodes {
11 PLACEHOLDER = SAFE_RANGE, // ensure these codes start after the highest keycode defined in Quantum
12 VRSN,
13};
14
15const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
16/* Keymap 0: Basic layer
17 *
18 * ,-----------------------------------------. ,-----------------------------------------.
19 * | = | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | - |
20 * |------+------+------+------+------+------| |------+------+------+------+------+------|
21 * | Del | '" | , | . | P | Y | | F | G | C | R | L | \ |
22 * |------+------+------+------+------+------| |------+------+------+------+------+------|
23 * | BkSp | A | O | E | U | I | | D | H | T | N | S/L2 |//Cmd |
24 * |------+------+------+------+------+------| |------+------+------+------+------+------|
25 * |LShift|;/Ctrl| Q | J | K | X | | B | M | W | V |Z/Ctrl|RShift|
26 * |------+------+------+------+------+------' `------+------+------+------+------+------|
27 * |Grv/L1| = |AltShf| Left | Right| | Up | Down | [ | ] | ~L1 |
28 * `----------------------------------' `----------------------------------'
29 * ,-------------. ,-------------.
30 * | App | LGui | | Alt | ^/Esc|
31 * ,------|------|------| |------+------+------.
32 * | | | Home | | PgUp | | |
33 * | Space|Backsp|------| |------| Tab |Enter |
34 * | |ace | End | | PgDn | | |
35 * `--------------------' `--------------------'
36 */
37[BASE] = LAYOUT_dactyl( // layer 0 : default
38 // left hand
39 KC_EQL, KC_1, KC_2, KC_3, KC_4, KC_5,
40 KC_DELT, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y,
41 KC_BSPC, KC_A, KC_O, KC_E, KC_U, KC_I,
42 KC_LSFT, CTL_T(KC_SCLN), KC_Q, KC_J, KC_K, KC_X,
43 LT(SYMB,KC_GRV), KC_EQL, LALT(KC_LSFT), KC_LEFT, KC_RGHT,
44 ALT_T(KC_APP), KC_LGUI,
45 KC_HOME,
46 KC_SPC, KC_BSPC, KC_END,
47 // right hand
48 KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
49 KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSLS,
50 KC_D, KC_H, KC_T, KC_N, LT(MDIA, KC_S), GUI_T(KC_SLSH),
51 KC_B, KC_M, KC_W, KC_V, CTL_T(KC_Z), KC_RSFT,
52 KC_UP, KC_DOWN, KC_LBRC, KC_RBRC, KC_FN1,
53 KC_RALT, CTL_T(KC_ESC),
54 KC_PGUP,
55 KC_PGDN, KC_TAB, KC_ENT
56 ),
57/* Keymap 1: Symbol Layer
58 *
59 * ,-----------------------------------------. ,-----------------------------------------.
60 * |Versn | F1 | F2 | F3 | F4 | F5 | | F6 | F7 | F8 | F9 | F10 | F11 |
61 * |------+------+------+------+------+------| |------+------+------+------+------+------|
62 * | | ! | @ | { | } | | | | Up | 7 | 8 | 9 | * | F12 |
63 * |------+------+------+------+------+------| |------+------+------+------+------+------|
64 * | | # | $ | ( | ) | ` | | Down | 4 | 5 | 6 | + | |
65 * |------+------+------+------+------+------| |------+------+------+------+------+------|
66 * | | % | ^ | [ | ] | ~ | | & | 1 | 2 | 3 | \ | |
67 * |------+------+------+------+------+------' `------+------+------+------+------+------|
68 * |RESET | | | | | | | . | 0 | = | |
69 * `----------------------------------' `----------------------------------'
70 * ,-------------. ,-------------.
71 * | | | | | |
72 * ,------|------|------| |------+------+------.
73 * | | | | | | | |
74 * | | |------| |------| | |
75 * | | | | | | | |
76 * `--------------------' `--------------------'
77 */
78// SYMBOLS
79[SYMB] = LAYOUT_dactyl(
80 // left hand
81 VRSN, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5,
82 KC_TRNS, KC_EXLM, KC_AT, KC_LCBR, KC_RCBR, KC_PIPE,
83 KC_TRNS, KC_HASH, KC_DLR, KC_LPRN, KC_RPRN, KC_GRV,
84 KC_TRNS, KC_PERC, KC_CIRC, KC_LBRC, KC_RBRC, KC_TILD,
85 RESET, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
86 KC_TRNS, KC_TRNS,
87 KC_TRNS,
88 KC_TRNS, KC_TRNS, KC_TRNS,
89 // right hand
90 KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
91 KC_UP, KC_7, KC_8, KC_9, KC_ASTR, KC_F12,
92 KC_DOWN, KC_4, KC_5, KC_6, KC_PLUS, KC_TRNS,
93 KC_AMPR, KC_1, KC_2, KC_3, KC_BSLS, KC_TRNS,
94 KC_TRNS, KC_DOT, KC_0, KC_EQL, KC_TRNS,
95 KC_TRNS, KC_TRNS,
96 KC_TRNS,
97 KC_TRNS, KC_TRNS, KC_TRNS
98),
99/* Keymap 2: Media and mouse keys
100 * ,-----------------------------------------. ,-----------------------------------------.
101 * | | | | | | | | | | | | | |
102 * |------+------+------+------+------+------| |------+------+------+------+------+------|
103 * | | | | MsUp | | | | | | | | | |
104 * |------+------+------+------+------+------| |------+------+------+------+------+------|
105 * | | |MsLeft|MsDown|MsRght| | | | | | | | Play |
106 * |------+------+------+------+------+------| |------+------+------+------+------+------|
107 * | | | | | | | | | | Prev | Next | | |
108 * |------+------+------+------+------+------' `------+------+------+------+------+------|
109 * | | | | Lclk | Rclk | | VolUp| VolDn| Mute | | |
110 * `----------------------------------' `----------------------------------'
111 * ,-------------. ,-------------.
112 * | | | | | |
113 * ,------|------|------| |------+------+------.
114 * | | | | | | |Brwser|
115 * | | |------| |------| |Back |
116 * | | | | | | | |
117 * `--------------------' `--------------------'
118 *
119 */
120// MEDIA AND MOUSE
121[MDIA] = LAYOUT_dactyl(
122 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
123 KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, KC_TRNS, KC_TRNS,
124 KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_TRNS,
125 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
126 KC_TRNS, KC_TRNS, KC_TRNS, KC_BTN1, KC_BTN2,
127 KC_TRNS, KC_TRNS,
128 KC_TRNS,
129 KC_TRNS, KC_TRNS, KC_TRNS,
130 // right hand
131 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
132 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
133 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY,
134 KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS,
135 KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS,
136 KC_TRNS, KC_TRNS,
137 KC_TRNS,
138 KC_TRNS, KC_TRNS, KC_WBAK
139),
140};
141
142const uint16_t PROGMEM fn_actions[] = {
143 [1] = ACTION_LAYER_TAP_TOGGLE(SYMB) // FN1 - Momentary Layer 1 (Symbols)
144};
145
146const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
147{
148 // MACRODOWN only works in this function
149 switch(id) {
150 case 0:
151 if (record->event.pressed) {
152 SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
153 }
154 break;
155 case 1:
156 if (record->event.pressed) { // For resetting EEPROM
157 eeconfig_init();
158 }
159 break;
160 }
161 return MACRO_NONE;
162};
163
164bool process_record_user(uint16_t keycode, keyrecord_t *record) {
165 switch (keycode) {
166 case VRSN:
167 if (record->event.pressed) {
168 SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
169 }
170 return false;
171 break;
172 }
173 return true;
174}
175
176// Runs just one time when the keyboard initializes.
177void matrix_init_user(void) {
178
179};
180
181
182// Runs constantly in the background, in a loop.
183void matrix_scan_user(void) {};
diff --git a/keyboards/handwired/dactyl/keymaps/dvorak/readme.md b/keyboards/handwired/dactyl/keymaps/dvorak/readme.md
new file mode 100644
index 000000000..42ec3cd4f
--- /dev/null
+++ b/keyboards/handwired/dactyl/keymaps/dvorak/readme.md
@@ -0,0 +1,9 @@
1# Dactyl Dvorak keymap
2
3Modifiers and layers 1+ are the same as in the default layout.
4Only the layer-0 dvorak-relevant keys are different.
5
6## Changelog
7
8* Nov 2017:
9 * Copied and adapted from the default keymap.
diff --git a/keyboards/handwired/dactyl/keymaps/erincalling/keymap.c b/keyboards/handwired/dactyl/keymaps/erincalling/keymap.c
new file mode 100644
index 000000000..d22d138a0
--- /dev/null
+++ b/keyboards/handwired/dactyl/keymaps/erincalling/keymap.c
@@ -0,0 +1,162 @@
1#include "dactyl.h"
2#include "debug.h"
3#include "action_layer.h"
4#include "version.h"
5
6#define BASE 0 // default layer
7#define CONT 1 // control layer
8#define QWER 2 // qwerty layer
9
10enum custom_keycodes {
11 PLACEHOLDER = SAFE_RANGE, // ensure these codes start after the highest keycode defined in Quantum
12 COLON_EQ,
13};
14
15const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
16/* Keymap 0: Basic layer
17 *
18 * ,-----------------------------------------. ,-----------------------------------------.
19 * | Esc | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | \ |
20 * |------+------+------+------+------+------| |------+------+------+------+------+------|
21 * | Tab | '" | , | . | P | Y | | F | G | C | R | L | / |
22 * |------+------+------+------+------+------| |------+------+------+------+------+------|
23 * | := | A | O | E | U | I | | D | H | T | N | S | - |
24 * |------+------+------+------+------+------| |------+------+------+------+------+------|
25 * |LShift| ; | Q | J | K | X | | B | M | W | V | Z |RShift|
26 * |------+------+------+------+------+------' `------+------+------+------+------+------|
27 * | Home | ` | = | Left | Right| | Up | Down | [ | ] | End |
28 * `----------------------------------' `----------------------------------'
29 * ,-------------. ,-------------.
30 * | LCtl | LAlt | | RCtl | Ralt |
31 * ,------|------|------| |------+------+------.
32 * | | | L1 | | L1 | | |
33 * | Back |Delete|------| |------|Enter |Space |
34 * |Space | | LGui | | RGui | | |
35 * `--------------------' `--------------------'
36 */
37[BASE] = LAYOUT_dactyl( // layer 0 : default
38 // left hand
39 KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5,
40 KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y,
41 COLON_EQ, KC_A, KC_O, KC_E, KC_U, KC_I,
42 KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X,
43 KC_HOME, KC_GRV, KC_EQL, KC_LEFT, KC_RGHT,
44 KC_LCTRL, KC_LALT,
45 MO(CONT),
46 KC_BSPC, KC_DEL, KC_LGUI,
47 // right hand
48 KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSLS,
49 KC_F, KC_G, KC_C, KC_R, KC_L, KC_SLSH,
50 KC_D, KC_H, KC_T, KC_N, KC_S, KC_MINS,
51 KC_B, KC_M, KC_W, KC_V, KC_Z, KC_RSFT,
52 KC_UP, KC_DOWN, KC_LBRC, KC_RBRC, KC_END,
53 KC_RALT, KC_RCTL,
54 MO(CONT),
55 KC_RGUI, KC_ENT, KC_SPACE
56 ),
57/* Keymap 1: Control layer (media keys, Fkeys, numpad)
58 *
59 * ,-----------------------------------------. ,-----------------------------------------.
60 * | | F1 | F2 | F3 | F4 | F5 | | F6 | F7 | F8 | F9 | F10 | RESET|
61 * |------+------+------+------+------+------| |------+------+------+------+------+------|
62 * | | | Mute | VolD | VolU | | | | 7 | 8 | 9 | + | |
63 * |------+------+------+------+------+------| |------+------+------+------+------+------|
64 * | | | Prev |PPause| Next | | | | 4 | 5 | 6 | = | |
65 * |------+------+------+------+------+------| |------+------+------+------+------+------|
66 * | | | | | | | | | 1 | 2 | 3 | , | |
67 * |------+------+------+------+------+------' `------+------+------+------+------+------|
68 * |PageUp| | | | | | 0 | 0 | . | |PageDn|
69 * `----------------------------------' `----------------------------------'
70 * ,-------------. ,-------------.
71 * | | | | | |
72 * ,------|------|------| |------+------+------.
73 * | | | | | | | |
74 * | | |------| |------| | |
75 * | | | | | | | |
76 * `--------------------' `--------------------'
77 */
78// SYMBOLS
79[CONT] = LAYOUT_dactyl(
80 // left hand
81 KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5,
82 KC_TRNS, KC_TRNS, KC_MUTE, KC_VOLD, KC_VOLU, KC_TRNS,
83 TG(QWER), KC_TRNS, KC_MPRV, KC_MPLY, KC_MNXT, KC_TRNS,
84 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
85 KC_PGUP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
86 KC_TRNS, KC_TRNS,
87 KC_TRNS,
88 KC_TRNS, KC_TRNS, KC_TRNS,
89 // right hand
90 KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, RESET,
91 KC_TRNS, KC_7, KC_8, KC_9, KC_KP_PLUS, KC_TRNS,
92 KC_TRNS, KC_4, KC_5, KC_6, KC_EQL, KC_TRNS,
93 KC_TRNS, KC_1, KC_2, KC_3, KC_COMM, KC_TRNS,
94 KC_0, KC_0, KC_DOT, KC_TRNS, KC_PGDN,
95 KC_TRNS, KC_TRNS,
96 KC_TRNS,
97 KC_TRNS, KC_TRNS, KC_TRNS
98),
99/* Keymap 2: QWERTY overlay
100 * ,-----------------------------------------. ,-----------------------------------------.
101 * | | | | | | | | | | | | | [ |
102 * |------+------+------+------+------+------| |------+------+------+------+------+------|
103 * | | Q | W | E | R | T | | Y | U | I | O | P | ] |
104 * |------+------+------+------+------+------| |------+------+------+------+------+------|
105 * | | A | S | D | F | G | | H | J | K | L | ; | '" |
106 * |------+------+------+------+------+------| |------+------+------+------+------+------|
107 * | | Z | X | C | V | B | | N | M | , | . | / | |
108 * |------+------+------+------+------+------' `------+------+------+------+------+------|
109 * | | | | | | | | | - | \ | |
110 * `----------------------------------' `----------------------------------'
111 * ,-------------. ,-------------.
112 * | | | | | |
113 * ,------|------|------| |------+------+------.
114 * | | | | | | | |
115 * | | |------| |------| | |
116 * | | | | | | | |
117 * `--------------------' `--------------------'
118 *
119 */
120// QWERTY
121[QWER] = LAYOUT_dactyl(
122 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
123 KC_TRNS, KC_Q, KC_W, KC_E, KC_R, KC_T,
124 KC_TRNS, KC_A, KC_S, KC_D, KC_F, KC_G,
125 KC_TRNS, KC_Z, KC_X, KC_C, KC_V, KC_B,
126 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
127 KC_TRNS, KC_TRNS,
128 KC_TRNS,
129 KC_TRNS, KC_TRNS, KC_TRNS,
130 // right hand
131 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_LBRC,
132 KC_Y, KC_U, KC_I, KC_O, KC_P, KC_RBRC,
133 KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
134 KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_TRNS,
135 KC_TRNS, KC_TRNS, KC_MINS, KC_BSLS, KC_TRNS,
136 KC_TRNS, KC_TRNS,
137 KC_TRNS,
138 KC_TRNS, KC_TRNS, KC_TRNS
139),
140};
141
142bool process_record_user(uint16_t keycode, keyrecord_t *record) {
143 if (record->event.pressed) {
144 switch(keycode) {
145 case COLON_EQ:
146 SEND_STRING(":=");
147 return false;
148 break;
149 }
150 }
151
152 return true;
153}
154
155// Runs just one time when the keyboard initializes.
156void matrix_init_user(void) {
157
158};
159
160
161// Runs constantly in the background, in a loop.
162void matrix_scan_user(void) {};
diff --git a/keyboards/handwired/dactyl/keymaps/erincalling/readme.md b/keyboards/handwired/dactyl/keymaps/erincalling/readme.md
new file mode 100644
index 000000000..7528ed07e
--- /dev/null
+++ b/keyboards/handwired/dactyl/keymaps/erincalling/readme.md
@@ -0,0 +1,6 @@
1# Erincalling Dactyl keymap
2
3## Changelog
4
5* Nov 2017:
6 * Ported and adapted from the ergodox-firmware layout I'd been using
diff --git a/keyboards/handwired/dactyl/matrix.c b/keyboards/handwired/dactyl/matrix.c
new file mode 100644
index 000000000..0626f93d7
--- /dev/null
+++ b/keyboards/handwired/dactyl/matrix.c
@@ -0,0 +1,393 @@
1/*
2
3Copyright 2013 Oleg Kostyuk <cub.uanic@gmail.com>
4Copyright 2017 Erin Call <hello@erincall.com>
5
6This program is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/*
21 * scan matrix
22 */
23#include <stdint.h>
24#include <stdbool.h>
25#include <avr/io.h>
26#include "wait.h"
27#include "action_layer.h"
28#include "print.h"
29#include "debug.h"
30#include "util.h"
31#include "matrix.h"
32#include "dactyl.h"
33#include "i2cmaster.h"
34#ifdef DEBUG_MATRIX_SCAN_RATE
35#include "timer.h"
36#endif
37
38/*
39 * This constant define not debouncing time in msecs, but amount of matrix
40 * scan loops which should be made to get stable debounced results.
41 *
42 * On the Dactyl, the matrix scan rate is relatively low, because
43 * communicating with the left hand's I/O expander is slower than simply
44 * selecting local pins.
45 * Now it's only 317 scans/second, or about 3.15 msec/scan.
46 * According to Cherry specs, debouncing time is 5 msec.
47 *
48 * And so, there is no sense to have DEBOUNCE higher than 2.
49 */
50
51#ifndef DEBOUNCE
52# define DEBOUNCE 5
53#endif
54
55/* matrix state(1:on, 0:off) */
56static matrix_row_t matrix[MATRIX_ROWS];
57
58// Debouncing: store for each key the number of scans until it's eligible to
59// change. When scanning the matrix, ignore any changes in keys that have
60// already changed in the last DEBOUNCE scans.
61static uint8_t debounce_matrix[MATRIX_ROWS * MATRIX_COLS];
62
63static matrix_row_t read_cols(uint8_t row);
64static void init_cols(void);
65static void unselect_rows(void);
66static void select_row(uint8_t row);
67
68static uint8_t mcp23018_reset_loop;
69
70#ifdef DEBUG_MATRIX_SCAN_RATE
71uint32_t matrix_timer;
72uint32_t matrix_scan_count;
73#endif
74
75
76__attribute__ ((weak))
77void matrix_init_user(void) {}
78
79__attribute__ ((weak))
80void matrix_scan_user(void) {}
81
82__attribute__ ((weak))
83void matrix_init_kb(void) {
84 matrix_init_user();
85}
86
87__attribute__ ((weak))
88void matrix_scan_kb(void) {
89 matrix_scan_user();
90}
91
92inline
93uint8_t matrix_rows(void)
94{
95 return MATRIX_ROWS;
96}
97
98inline
99uint8_t matrix_cols(void)
100{
101 return MATRIX_COLS;
102}
103
104void matrix_init(void)
105{
106 // initialize row and col
107
108 mcp23018_status = init_mcp23018();
109
110
111 unselect_rows();
112 init_cols();
113
114 // initialize matrix state: all keys off
115 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
116 matrix[i] = 0;
117 for (uint8_t j=0; j < MATRIX_COLS; ++j) {
118 debounce_matrix[i * MATRIX_COLS + j] = 0;
119 }
120 }
121
122#ifdef DEBUG_MATRIX_SCAN_RATE
123 matrix_timer = timer_read32();
124 matrix_scan_count = 0;
125#endif
126
127 matrix_init_quantum();
128
129}
130
131void matrix_power_up(void) {
132 mcp23018_status = init_mcp23018();
133
134 unselect_rows();
135 init_cols();
136
137 // initialize matrix state: all keys off
138 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
139 matrix[i] = 0;
140 }
141
142#ifdef DEBUG_MATRIX_SCAN_RATE
143 matrix_timer = timer_read32();
144 matrix_scan_count = 0;
145#endif
146}
147
148// Returns a matrix_row_t whose bits are set if the corresponding key should be
149// eligible to change in this scan.
150matrix_row_t debounce_mask(uint8_t row) {
151 matrix_row_t result = 0;
152 for (uint8_t j=0; j < MATRIX_COLS; ++j) {
153 if (debounce_matrix[row * MATRIX_COLS + j]) {
154 --debounce_matrix[row * MATRIX_COLS + j];
155 } else {
156 result |= (1 << j);
157 }
158 }
159 return result;
160}
161
162// Report changed keys in the given row. Resets the debounce countdowns
163// corresponding to each set bit in 'change' to DEBOUNCE.
164void debounce_report(matrix_row_t change, uint8_t row) {
165 for (uint8_t i = 0; i < MATRIX_COLS; ++i) {
166 if (change & (1 << i)) {
167 debounce_matrix[row * MATRIX_COLS + i] = DEBOUNCE;
168 }
169 }
170}
171
172uint8_t matrix_scan(void)
173{
174 if (mcp23018_status) { // if there was an error
175 if (++mcp23018_reset_loop == 0) {
176 // since mcp23018_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans
177 // this will be approx bit more frequent than once per second
178 print("trying to reset mcp23018\n");
179 mcp23018_status = init_mcp23018();
180 if (mcp23018_status) {
181 print("left side not responding\n");
182 } else {
183 print("left side attached\n");
184 }
185 }
186 }
187
188#ifdef DEBUG_MATRIX_SCAN_RATE
189 matrix_scan_count++;
190
191 uint32_t timer_now = timer_read32();
192 if (TIMER_DIFF_32(timer_now, matrix_timer)>1000) {
193 print("matrix scan frequency: ");
194 pdec(matrix_scan_count);
195 print("\n");
196
197 matrix_timer = timer_now;
198 matrix_scan_count = 0;
199 }
200#endif
201
202 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
203 select_row(i);
204 wait_us(30); // without this wait read unstable value.
205 matrix_row_t mask = debounce_mask(i);
206 matrix_row_t cols = (read_cols(i) & mask) | (matrix[i] & ~mask);
207 debounce_report(cols ^ matrix[i], i);
208 matrix[i] = cols;
209
210 unselect_rows();
211 }
212
213 matrix_scan_quantum();
214
215 return 1;
216}
217
218bool matrix_is_modified(void) // deprecated and evidently not called.
219{
220 return true;
221}
222
223inline
224bool matrix_is_on(uint8_t row, uint8_t col)
225{
226 return (matrix[row] & ((matrix_row_t)1<<col));
227}
228
229inline
230matrix_row_t matrix_get_row(uint8_t row)
231{
232 return matrix[row];
233}
234
235void matrix_print(void)
236{
237 print("\nr/c 0123456789ABCDEF\n");
238 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
239 phex(row); print(": ");
240 pbin_reverse16(matrix_get_row(row));
241 print("\n");
242 }
243}
244
245uint8_t matrix_key_count(void)
246{
247 uint8_t count = 0;
248 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
249 count += bitpop16(matrix[i]);
250 }
251 return count;
252}
253
254/* Column pin configuration
255 *
256 * Teensy
257 * col: 0 1 2 3 4 5
258 * pin: F0 F1 F4 F5 F6 F7
259 *
260 * MCP23018
261 * col: 0 1 2 3 4 5
262 * pin: B5 B4 B3 B2 B1 B0
263 */
264static void init_cols(void)
265{
266 // init on mcp23018
267 // not needed, already done as part of init_mcp23018()
268
269 // init on teensy
270 // Input with pull-up(DDR:0, PORT:1)
271 DDRF &= ~(1<<7 | 1<<6 | 1<<5 | 1<<4 | 1<<1 | 1<<0);
272 PORTF |= (1<<7 | 1<<6 | 1<<5 | 1<<4 | 1<<1 | 1<<0);
273}
274
275static matrix_row_t read_cols(uint8_t row)
276{
277 if (row < 6) {
278 if (mcp23018_status) { // if there was an error
279 return 0;
280 } else {
281 uint8_t data = 0;
282 mcp23018_status = i2c_start(I2C_ADDR_WRITE); if (mcp23018_status) goto out;
283 mcp23018_status = i2c_write(GPIOB); if (mcp23018_status) goto out;
284 mcp23018_status = i2c_start(I2C_ADDR_READ); if (mcp23018_status) goto out;
285 data = i2c_readNak();
286 data = ~data;
287 out:
288 i2c_stop();
289 return data;
290 }
291 } else {
292 // read from teensy
293 return
294 (PINF&(1<<0) ? 0 : (1<<0)) |
295 (PINF&(1<<1) ? 0 : (1<<1)) |
296 (PINF&(1<<4) ? 0 : (1<<2)) |
297 (PINF&(1<<5) ? 0 : (1<<3)) |
298 (PINF&(1<<6) ? 0 : (1<<4)) |
299 (PINF&(1<<7) ? 0 : (1<<5)) ;
300 }
301}
302
303/* Row pin configuration
304 *
305 * Teensy
306 * row: 6 7 8 9 10 11
307 * pin: B1 B2 B3 D2 D3 C6
308 *
309 * MCP23018
310 * row: 0 1 2 3 4 5
311 * pin: A0 A1 A2 A3 A4 A5
312 */
313static void unselect_rows(void)
314{
315 // unselect on mcp23018
316 if (mcp23018_status) { // if there was an error
317 // do nothing
318 } else {
319 // set all rows hi-Z : 1
320 mcp23018_status = i2c_start(I2C_ADDR_WRITE); if (mcp23018_status) goto out;
321 mcp23018_status = i2c_write(GPIOA); if (mcp23018_status) goto out;
322 mcp23018_status = i2c_write(0xFF); if (mcp23018_status) goto out;
323 out:
324 i2c_stop();
325 }
326
327 // unselect on teensy
328 // Hi-Z(DDR:0, PORT:0) to unselect
329 DDRB &= ~(1<<1 | 1<<2 | 1<<3);
330 PORTB &= ~(1<<1 | 1<<2 | 1<<3);
331 DDRD &= ~(1<<2 | 1<<3);
332 PORTD &= ~(1<<2 | 1<<3);
333 DDRC &= ~(1<<6);
334 PORTC &= ~(1<<6);
335}
336
337/* Row pin configuration
338 *
339 * Teensy
340 * row: 6 7 8 9 10 11
341 * pin: B1 B2 B3 D2 D3 C6
342 *
343 * MCP23018
344 * row: 0 1 2 3 4 5
345 * pin: A0 A1 A2 A3 A4 A5
346 */
347static void select_row(uint8_t row)
348{
349 if (row < 6) {
350 // select on mcp23018
351 if (mcp23018_status) { // if there was an error
352 // do nothing
353 } else {
354 // set active row low : 0
355 // set other rows hi-Z : 1
356 mcp23018_status = i2c_start(I2C_ADDR_WRITE); if (mcp23018_status) goto out;
357 mcp23018_status = i2c_write(GPIOA); if (mcp23018_status) goto out;
358 mcp23018_status = i2c_write(0xFF & ~(1<<row)); if (mcp23018_status) goto out;
359 out:
360 i2c_stop();
361 }
362 } else {
363 // select on teensy
364 // Output low(DDR:1, PORT:0) to select
365 switch (row) {
366 case 6:
367 DDRB |= (1<<1);
368 PORTB &= ~(1<<1);
369 break;
370 case 7:
371 DDRB |= (1<<2);
372 PORTB &= ~(1<<2);
373 break;
374 case 8:
375 DDRB |= (1<<3);
376 PORTB &= ~(1<<3);
377 break;
378 case 9:
379 DDRD |= (1<<2);
380 PORTD &= ~(1<<3);
381 break;
382 case 10:
383 DDRD |= (1<<3);
384 PORTD &= ~(1<<3);
385 break;
386 case 11:
387 DDRC |= (1<<6);
388 PORTC &= ~(1<<6);
389 break;
390 }
391 }
392}
393
diff --git a/keyboards/handwired/dactyl/readme.md b/keyboards/handwired/dactyl/readme.md
new file mode 100644
index 000000000..f473b020e
--- /dev/null
+++ b/keyboards/handwired/dactyl/readme.md
@@ -0,0 +1,37 @@
1# Dactyl
2
3See https://github.com/adereth/dactyl-keyboard
4
5The Dactyl uses the [Teensy Loader](https://www.pjrc.com/teensy/loader.html).
6
7Linux users need to modify udev rules as described on the [Teensy
8Linux page]. Some distributions provide a binary, maybe called
9`teensy-loader-cli`.
10
11[Teensy Linux page]: https://www.pjrc.com/teensy/loader_linux.html
12
13To flash the firmware:
14
15 - Build the firmware with `make handwired-dactyl-keymapname`, for example `make handwired-dactyl-default`
16 - This will result in a hex file called `handwired_dactyl_keymapname.hex`, e.g.
17 `handwired_dactyl_default.hex`
18
19 - Start the teensy loader.
20
21 - Load the .hex file into it.
22
23 - Put the Teensy in firmware-loading mode:
24 * If your current layout has a RESET key, press it.
25 * If you lack a RESET key, press the reset button on the Teensy board itself.
26
27 - Click the button in the Teensy app to download the firmware.
28
29To flash with ´teensy-loader-cli´:
30
31 - Build the firmware as above
32
33 - Run `<path/to/>teensy_loader_cli -mmcu=atmega32u4 -w handwired_dactyl_<keymap>.hex`
34
35 - Put the Teensy in firmware-loading mode:
36 * If your current layout has a RESET key, press it.
37 * If you lack a RESET key, press the reset button on the Teensy board itself.
diff --git a/keyboards/handwired/dactyl/rules.mk b/keyboards/handwired/dactyl/rules.mk
new file mode 100644
index 000000000..90a29bd2d
--- /dev/null
+++ b/keyboards/handwired/dactyl/rules.mk
@@ -0,0 +1,86 @@
1#----------------------------------------------------------------------------
2# On command line:
3#
4# make = Make software.
5#
6# make clean = Clean out built project files.
7#
8# That's pretty much all you need. To compile, always go make clean,
9# followed by make.
10#
11# For advanced users only:
12# make teensy = Download the hex file to the device, using teensy_loader_cli.
13# (must have teensy_loader_cli installed).
14#
15#----------------------------------------------------------------------------
16
17# # project specific files
18SRC = twimaster.c \
19 matrix.c
20
21# MCU name
22MCU = atmega32u4
23
24# Processor frequency.
25# This will define a symbol, F_CPU, in all source code files equal to the
26# processor frequency in Hz. You can then use this symbol in your source code to
27# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
28# automatically to create a 32-bit value in your source code.
29#
30# This will be an integer division of F_USB below, as it is sourced by
31# F_USB after it has run through any CPU prescalers. Note that this value
32# does not *change* the processor frequency - it should merely be updated to
33# reflect the processor speed set externally so that the code can use accurate
34# software delays.
35F_CPU = 16000000
36
37
38#
39# LUFA specific
40#
41# Target architecture (see library "Board Types" documentation).
42ARCH = AVR8
43
44# Input clock frequency.
45# This will define a symbol, F_USB, in all source code files equal to the
46# input clock frequency (before any prescaling is performed) in Hz. This value may
47# differ from F_CPU if prescaling is used on the latter, and is required as the
48# raw input clock is fed directly to the PLL sections of the AVR for high speed
49# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
50# at the end, this will be done automatically to create a 32-bit value in your
51# source code.
52#
53# If no clock division is performed on the input clock inside the AVR (via the
54# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
55F_USB = $(F_CPU)
56
57# Interrupt driven control endpoint task(+60)
58OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
59
60
61# Boot Section Size in *bytes*
62# Teensy halfKay 512
63# Teensy++ halfKay 1024
64# Atmel DFU loader 4096
65# LUFA bootloader 4096
66# USBaspLoader 2048
67OPT_DEFS += -DBOOTLOADER_SIZE=512
68
69
70# Build Options
71# comment out to disable the options.
72#
73BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
74MIDI_ENABLE = no # MIDI support (+2400 to 4200)
75POINTING_DEVICE_ENABLE = no
76MOUSEKEY_ENABLE = no # Mouse keys(+4700)
77EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
78CONSOLE_ENABLE = no # Console for debug(+8000)
79COMMAND_ENABLE = no # Commands for debug and configuration
80CUSTOM_MATRIX = yes # Custom matrix file for the Dactyl
81NKRO_ENABLE = yes # USB Nkey Rollover
82UNICODE_ENABLE = yes # Unicode
83ONEHAND_ENABLE = yes # Allow swapping hands of keyboard
84SLEEP_LED_ENABLE = no
85API_SYSEX_ENABLE = no
86RGBLIGHT_ENABLE = no
diff --git a/keyboards/handwired/dactyl/twimaster.c b/keyboards/handwired/dactyl/twimaster.c
new file mode 100644
index 000000000..2557f7e22
--- /dev/null
+++ b/keyboards/handwired/dactyl/twimaster.c
@@ -0,0 +1,207 @@
1/*************************************************************************
2* Title: I2C master library using hardware TWI interface
3* Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
4* File: $Id: twimaster.c,v 1.3 2005/07/02 11:14:21 Peter Exp $
5* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
6* Target: any AVR device with hardware TWI
7* Usage: API compatible with I2C Software Library i2cmaster.h
8**************************************************************************/
9#include <inttypes.h>
10#include <compat/twi.h>
11
12#include <i2cmaster.h>
13
14/* define CPU frequency in Hz here if not defined in Makefile */
15#ifndef F_CPU
16#define F_CPU 16000000UL
17#endif
18
19/* I2C clock in Hz */
20#define SCL_CLOCK 400000L
21
22
23/*************************************************************************
24 Initialization of the I2C bus interface. Need to be called only once
25*************************************************************************/
26void i2c_init(void)
27{
28 /* initialize TWI clock
29 * minimal values in Bit Rate Register (TWBR) and minimal Prescaler
30 * bits in the TWI Status Register should give us maximal possible
31 * I2C bus speed - about 444 kHz
32 *
33 * for more details, see 20.5.2 in ATmega16/32 secification
34 */
35
36 TWSR = 0; /* no prescaler */
37 TWBR = 10; /* must be >= 10 for stable operation */
38
39}/* i2c_init */
40
41
42/*************************************************************************
43 Issues a start condition and sends address and transfer direction.
44 return 0 = device accessible, 1= failed to access device
45*************************************************************************/
46unsigned char i2c_start(unsigned char address)
47{
48 uint8_t twst;
49
50 // send START condition
51 TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
52
53 // wait until transmission completed
54 while(!(TWCR & (1<<TWINT)));
55
56 // check value of TWI Status Register. Mask prescaler bits.
57 twst = TW_STATUS & 0xF8;
58 if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
59
60 // send device address
61 TWDR = address;
62 TWCR = (1<<TWINT) | (1<<TWEN);
63
64 // wail until transmission completed and ACK/NACK has been received
65 while(!(TWCR & (1<<TWINT)));
66
67 // check value of TWI Status Register. Mask prescaler bits.
68 twst = TW_STATUS & 0xF8;
69 if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
70
71 return 0;
72
73}/* i2c_start */
74
75
76/*************************************************************************
77 Issues a start condition and sends address and transfer direction.
78 If device is busy, use ack polling to wait until device is ready
79
80 Input: address and transfer direction of I2C device
81*************************************************************************/
82void i2c_start_wait(unsigned char address)
83{
84 uint8_t twst;
85
86
87 while ( 1 )
88 {
89 // send START condition
90 TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
91
92 // wait until transmission completed
93 while(!(TWCR & (1<<TWINT)));
94
95 // check value of TWI Status Register. Mask prescaler bits.
96 twst = TW_STATUS & 0xF8;
97 if ( (twst != TW_START) && (twst != TW_REP_START)) continue;
98
99 // send device address
100 TWDR = address;
101 TWCR = (1<<TWINT) | (1<<TWEN);
102
103 // wail until transmission completed
104 while(!(TWCR & (1<<TWINT)));
105
106 // check value of TWI Status Register. Mask prescaler bits.
107 twst = TW_STATUS & 0xF8;
108 if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) )
109 {
110 /* device busy, send stop condition to terminate write operation */
111 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
112
113 // wait until stop condition is executed and bus released
114 while(TWCR & (1<<TWSTO));
115
116 continue;
117 }
118 //if( twst != TW_MT_SLA_ACK) return 1;
119 break;
120 }
121
122}/* i2c_start_wait */
123
124
125/*************************************************************************
126 Issues a repeated start condition and sends address and transfer direction
127
128 Input: address and transfer direction of I2C device
129
130 Return: 0 device accessible
131 1 failed to access device
132*************************************************************************/
133unsigned char i2c_rep_start(unsigned char address)
134{
135 return i2c_start( address );
136
137}/* i2c_rep_start */
138
139
140/*************************************************************************
141 Terminates the data transfer and releases the I2C bus
142*************************************************************************/
143void i2c_stop(void)
144{
145 /* send stop condition */
146 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
147
148 // wait until stop condition is executed and bus released
149 while(TWCR & (1<<TWSTO));
150
151}/* i2c_stop */
152
153
154/*************************************************************************
155 Send one byte to I2C device
156
157 Input: byte to be transfered
158 Return: 0 write successful
159 1 write failed
160*************************************************************************/
161unsigned char i2c_write( unsigned char data )
162{
163 uint8_t twst;
164
165 // send data to the previously addressed device
166 TWDR = data;
167 TWCR = (1<<TWINT) | (1<<TWEN);
168
169 // wait until transmission completed
170 while(!(TWCR & (1<<TWINT)));
171
172 // check value of TWI Status Register. Mask prescaler bits
173 twst = TW_STATUS & 0xF8;
174 if( twst != TW_MT_DATA_ACK) return 1;
175 return 0;
176
177}/* i2c_write */
178
179
180/*************************************************************************
181 Read one byte from the I2C device, request more data from device
182
183 Return: byte read from I2C device
184*************************************************************************/
185unsigned char i2c_readAck(void)
186{
187 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
188 while(!(TWCR & (1<<TWINT)));
189
190 return TWDR;
191
192}/* i2c_readAck */
193
194
195/*************************************************************************
196 Read one byte from the I2C device, read is followed by a stop condition
197
198 Return: byte read from I2C device
199*************************************************************************/
200unsigned char i2c_readNak(void)
201{
202 TWCR = (1<<TWINT) | (1<<TWEN);
203 while(!(TWCR & (1<<TWINT)));
204
205 return TWDR;
206
207}/* i2c_readNak */