aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCole Markham <github@ccmcomputing.net>2017-11-17 12:01:21 -0600
committerJack Humbert <jack.humb@gmail.com>2017-12-09 00:05:35 -0500
commita9a46adba0e005f6fecfb5ed47fe8a5eec4b06f4 (patch)
tree4dac82993f8ced6e3c7791b6d55a97c84122634b
parentc51dfef958bce4a792b66db337d5c7cdf0956fc4 (diff)
downloadqmk_firmware-a9a46adba0e005f6fecfb5ed47fe8a5eec4b06f4.tar.gz
qmk_firmware-a9a46adba0e005f6fecfb5ed47fe8a5eec4b06f4.zip
Add support for Meira
-rwxr-xr-xkeyboards/meira/TWIlib.c287
-rwxr-xr-xkeyboards/meira/TWIlib.h81
-rw-r--r--keyboards/meira/config.h53
-rw-r--r--keyboards/meira/featherble/config.h175
-rw-r--r--keyboards/meira/featherble/featherble.c1
-rw-r--r--keyboards/meira/featherble/featherble.h9
-rw-r--r--keyboards/meira/featherble/rules.mk4
-rwxr-xr-xkeyboards/meira/issi.c286
-rwxr-xr-xkeyboards/meira/issi.h40
-rw-r--r--keyboards/meira/keymaps/default/config.h24
-rw-r--r--keyboards/meira/keymaps/default/keymap.c320
-rw-r--r--keyboards/meira/keymaps/default/readme.md1
-rwxr-xr-xkeyboards/meira/lighting.c95
-rwxr-xr-xkeyboards/meira/lighting.h9
-rw-r--r--keyboards/meira/matrix.c314
-rw-r--r--keyboards/meira/meira.c145
-rw-r--r--keyboards/meira/meira.h48
-rw-r--r--keyboards/meira/promicro/config.h168
-rw-r--r--keyboards/meira/promicro/promicro.c2
-rw-r--r--keyboards/meira/promicro/promicro.h10
-rw-r--r--keyboards/meira/promicro/rules.mk2
-rw-r--r--keyboards/meira/readme.md28
-rw-r--r--keyboards/meira/rules.mk84
23 files changed, 2186 insertions, 0 deletions
diff --git a/keyboards/meira/TWIlib.c b/keyboards/meira/TWIlib.c
new file mode 100755
index 000000000..8e0c97438
--- /dev/null
+++ b/keyboards/meira/TWIlib.c
@@ -0,0 +1,287 @@
1/*
2 * TWIlib.c
3 *
4 * Created: 6/01/2014 10:41:33 PM
5 * Author: Chris Herring
6 */
7
8#include <avr/io.h>
9#include <avr/interrupt.h>
10#include "TWIlib.h"
11#include "util/delay.h"
12#include "print.h"
13
14void TWIInit()
15{
16 TWIInfo.mode = Ready;
17 TWIInfo.errorCode = 0xFF;
18 TWIInfo.repStart = 0;
19 // Set pre-scalers (no pre-scaling)
20 TWSR = 0;
21 // Set bit rate
22 TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
23 // Enable TWI and interrupt
24 TWCR = (1 << TWIE) | (1 << TWEN);
25}
26
27uint8_t isTWIReady()
28{
29 if ( (TWIInfo.mode == Ready) | (TWIInfo.mode == RepeatedStartSent) )
30 {
31
32// xprintf("i2c ready\n");
33 return 1;
34 }
35 else
36 {
37 if(TWIInfo.mode == Initializing){
38 switch(TWIInfo.errorCode){
39 case TWI_SUCCESS:
40 break;
41 case TWI_NO_RELEVANT_INFO:
42
43 break;
44 case TWI_LOST_ARBIT:
45 case TWI_MT_DATA_NACK:
46 // Some kind of I2C error, reset and re-init
47 xprintf("I2C init error: %d\n", TWIInfo.errorCode);
48 TWCR = (1 << TWINT)|(1 << TWSTO);
49 TWIInit();
50 break;
51 default:
52 xprintf("Other i2c init error: %d\n", TWIInfo.errorCode);
53 }
54 }
55 return 0;
56 }
57}
58
59
60void TWITransmitData(void *const TXdata, uint8_t dataLen, uint8_t repStart, uint8_t blocking)
61{
62 // Wait until ready
63 while (!isTWIReady()) {_delay_us(1);}
64 // Reset the I2C stuff
65 TWCR = (1 << TWINT)|(1 << TWSTO);
66 TWIInit();
67 // Set repeated start mode
68 TWIInfo.repStart = repStart;
69 // Copy transmit info to global variables
70 TWITransmitBuffer = (uint8_t *)TXdata;
71 TXBuffLen = dataLen;
72 TXBuffIndex = 0;
73
74 // If a repeated start has been sent, then devices are already listening for an address
75 // and another start does not need to be sent.
76 if (TWIInfo.mode == RepeatedStartSent)
77 {
78 TWIInfo.mode = Initializing;
79 TWDR = TWITransmitBuffer[TXBuffIndex++]; // Load data to transmit buffer
80 TWISendTransmit(); // Send the data
81 }
82 else // Otherwise, just send the normal start signal to begin transmission.
83 {
84 TWIInfo.mode = Initializing;
85 TWISendStart();
86 }
87 if(blocking){
88 // Wait until ready
89 while (!isTWIReady()){_delay_us(1);}
90 }
91}
92
93
94// uint8_t TWITransmitData(void *const TXdata, uint8_t dataLen, uint8_t repStart)
95// {
96// if (dataLen <= TXMAXBUFLEN)
97// {
98// // Wait until ready
99// while (!isTWIReady()) {_delay_us(1);}
100// // Set repeated start mode
101// TWIInfo.repStart = repStart;
102// // Copy data into the transmit buffer
103// uint8_t *data = (uint8_t *)TXdata;
104// for (int i = 0; i < dataLen; i++)
105// {
106// TWITransmitBuffer[i] = data[i];
107// }
108// // Copy transmit info to global variables
109// TXBuffLen = dataLen;
110// TXBuffIndex = 0;
111
112// // If a repeated start has been sent, then devices are already listening for an address
113// // and another start does not need to be sent.
114// if (TWIInfo.mode == RepeatedStartSent)
115// {
116// TWIInfo.mode = Initializing;
117// TWDR = TWITransmitBuffer[TXBuffIndex++]; // Load data to transmit buffer
118// TWISendTransmit(); // Send the data
119// }
120// else // Otherwise, just send the normal start signal to begin transmission.
121// {
122// TWIInfo.mode = Initializing;
123// TWISendStart();
124// }
125
126// }
127// else
128// {
129// return 1; // return an error if data length is longer than buffer
130// }
131// return 0;
132// }
133
134uint8_t TWIReadData(uint8_t TWIaddr, uint8_t bytesToRead, uint8_t repStart)
135{
136 // Check if number of bytes to read can fit in the RXbuffer
137 if (bytesToRead < RXMAXBUFLEN)
138 {
139 // Reset buffer index and set RXBuffLen to the number of bytes to read
140 RXBuffIndex = 0;
141 RXBuffLen = bytesToRead;
142 // Create the one value array for the address to be transmitted
143 uint8_t TXdata[1];
144 // Shift the address and AND a 1 into the read write bit (set to write mode)
145 TXdata[0] = (TWIaddr << 1) | 0x01;
146 // Use the TWITransmitData function to initialize the transfer and address the slave
147 TWITransmitData(TXdata, 1, repStart, 0);
148 }
149 else
150 {
151 return 0;
152 }
153 return 1;
154}
155
156ISR (TWI_vect)
157{
158 switch (TWI_STATUS)
159 {
160 // ----\/ ---- MASTER TRANSMITTER OR WRITING ADDRESS ----\/ ---- //
161 case TWI_MT_SLAW_ACK: // SLA+W transmitted and ACK received
162 // Set mode to Master Transmitter
163 TWIInfo.mode = MasterTransmitter;
164 case TWI_START_SENT: // Start condition has been transmitted
165 case TWI_MT_DATA_ACK: // Data byte has been transmitted, ACK received
166 if (TXBuffIndex < TXBuffLen) // If there is more data to send
167 {
168 TWDR = TWITransmitBuffer[TXBuffIndex++]; // Load data to transmit buffer
169 TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
170 TWISendTransmit(); // Send the data
171 }
172 // This transmission is complete however do not release bus yet
173 else if (TWIInfo.repStart)
174 {
175 TWIInfo.errorCode = 0xFF;
176 TWISendStart();
177 }
178 // All transmissions are complete, exit
179 else
180 {
181 TWIInfo.mode = Ready;
182 TWIInfo.errorCode = 0xFF;
183 TWISendStop();
184 }
185 break;
186
187 // ----\/ ---- MASTER RECEIVER ----\/ ---- //
188
189 case TWI_MR_SLAR_ACK: // SLA+R has been transmitted, ACK has been received
190 // Switch to Master Receiver mode
191 TWIInfo.mode = MasterReceiver;
192 // If there is more than one byte to be read, receive data byte and return an ACK
193 if (RXBuffIndex < RXBuffLen-1)
194 {
195 TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
196 TWISendACK();
197 }
198 // Otherwise when a data byte (the only data byte) is received, return NACK
199 else
200 {
201 TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
202 TWISendNACK();
203 }
204 break;
205
206 case TWI_MR_DATA_ACK: // Data has been received, ACK has been transmitted.
207
208 /// -- HANDLE DATA BYTE --- ///
209 TWIReceiveBuffer[RXBuffIndex++] = TWDR;
210 // If there is more than one byte to be read, receive data byte and return an ACK
211 if (RXBuffIndex < RXBuffLen-1)
212 {
213 TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
214 TWISendACK();
215 }
216 // Otherwise when a data byte (the only data byte) is received, return NACK
217 else
218 {
219 TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
220 TWISendNACK();
221 }
222 break;
223
224 case TWI_MR_DATA_NACK: // Data byte has been received, NACK has been transmitted. End of transmission.
225
226 /// -- HANDLE DATA BYTE --- ///
227 TWIReceiveBuffer[RXBuffIndex++] = TWDR;
228 // This transmission is complete however do not release bus yet
229 if (TWIInfo.repStart)
230 {
231 TWIInfo.errorCode = 0xFF;
232 TWISendStart();
233 }
234 // All transmissions are complete, exit
235 else
236 {
237 TWIInfo.mode = Ready;
238 TWIInfo.errorCode = 0xFF;
239 TWISendStop();
240 }
241 break;
242
243 // ----\/ ---- MT and MR common ----\/ ---- //
244
245 case TWI_MR_SLAR_NACK: // SLA+R transmitted, NACK received
246 case TWI_MT_SLAW_NACK: // SLA+W transmitted, NACK received
247 case TWI_MT_DATA_NACK: // Data byte has been transmitted, NACK received
248 case TWI_LOST_ARBIT: // Arbitration has been lost
249 // Return error and send stop and set mode to ready
250 if (TWIInfo.repStart)
251 {
252 TWIInfo.errorCode = TWI_STATUS;
253 TWISendStart();
254 }
255 // All transmissions are complete, exit
256 else
257 {
258 TWIInfo.mode = Ready;
259 TWIInfo.errorCode = TWI_STATUS;
260 TWISendStop();
261 }
262 break;
263 case TWI_REP_START_SENT: // Repeated start has been transmitted
264 // Set the mode but DO NOT clear TWINT as the next data is not yet ready
265 TWIInfo.mode = RepeatedStartSent;
266 break;
267
268 // ----\/ ---- SLAVE RECEIVER ----\/ ---- //
269
270 // TODO IMPLEMENT SLAVE RECEIVER FUNCTIONALITY
271
272 // ----\/ ---- SLAVE TRANSMITTER ----\/ ---- //
273
274 // TODO IMPLEMENT SLAVE TRANSMITTER FUNCTIONALITY
275
276 // ----\/ ---- MISCELLANEOUS STATES ----\/ ---- //
277 case TWI_NO_RELEVANT_INFO: // It is not really possible to get into this ISR on this condition
278 // Rather, it is there to be manually set between operations
279 break;
280 case TWI_ILLEGAL_START_STOP: // Illegal START/STOP, abort and return error
281 TWIInfo.errorCode = TWI_ILLEGAL_START_STOP;
282 TWIInfo.mode = Ready;
283 TWISendStop();
284 break;
285 }
286
287}
diff --git a/keyboards/meira/TWIlib.h b/keyboards/meira/TWIlib.h
new file mode 100755
index 000000000..6db3cc951
--- /dev/null
+++ b/keyboards/meira/TWIlib.h
@@ -0,0 +1,81 @@
1/*
2 * TWIlib.h
3 *
4 * Created: 6/01/2014 10:38:42 PM
5 * Author: Chris Herring
6 */
7
8
9#ifndef TWILIB_H_
10#define TWILIB_H_
11// TWI bit rate
12#define TWI_FREQ 400000
13// Get TWI status
14#define TWI_STATUS (TWSR & 0xF8)
15// Transmit buffer length
16#define TXMAXBUFLEN 20
17// Receive buffer length
18#define RXMAXBUFLEN 20
19// Global transmit buffer
20volatile uint8_t *TWITransmitBuffer;
21// Global receive buffer
22volatile uint8_t TWIReceiveBuffer[RXMAXBUFLEN];
23// Buffer indexes
24volatile int TXBuffIndex; // Index of the transmit buffer. Is volatile, can change at any time.
25int RXBuffIndex; // Current index in the receive buffer
26// Buffer lengths
27int TXBuffLen; // The total length of the transmit buffer
28int RXBuffLen; // The total number of bytes to read (should be less than RXMAXBUFFLEN)
29
30typedef enum {
31 Ready,
32 Initializing,
33 RepeatedStartSent,
34 MasterTransmitter,
35 MasterReceiver,
36 SlaceTransmitter,
37 SlaveReciever
38 } TWIMode;
39
40 typedef struct TWIInfoStruct{
41 TWIMode mode;
42 uint8_t errorCode;
43 uint8_t repStart;
44 }TWIInfoStruct;
45TWIInfoStruct TWIInfo;
46
47
48// TWI Status Codes
49#define TWI_START_SENT 0x08 // Start sent
50#define TWI_REP_START_SENT 0x10 // Repeated Start sent
51// Master Transmitter Mode
52#define TWI_MT_SLAW_ACK 0x18 // SLA+W sent and ACK received
53#define TWI_MT_SLAW_NACK 0x20 // SLA+W sent and NACK received
54#define TWI_MT_DATA_ACK 0x28 // DATA sent and ACK received
55#define TWI_MT_DATA_NACK 0x30 // DATA sent and NACK received
56// Master Receiver Mode
57#define TWI_MR_SLAR_ACK 0x40 // SLA+R sent, ACK received
58#define TWI_MR_SLAR_NACK 0x48 // SLA+R sent, NACK received
59#define TWI_MR_DATA_ACK 0x50 // Data received, ACK returned
60#define TWI_MR_DATA_NACK 0x58 // Data received, NACK returned
61
62// Miscellaneous States
63#define TWI_LOST_ARBIT 0x38 // Arbitration has been lost
64#define TWI_NO_RELEVANT_INFO 0xF8 // No relevant information available
65#define TWI_ILLEGAL_START_STOP 0x00 // Illegal START or STOP condition has been detected
66#define TWI_SUCCESS 0xFF // Successful transfer, this state is impossible from TWSR as bit2 is 0 and read only
67
68
69#define TWISendStart() (TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE)) // Send the START signal, enable interrupts and TWI, clear TWINT flag to resume transfer.
70#define TWISendStop() (TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN)|(1<<TWIE)) // Send the STOP signal, enable interrupts and TWI, clear TWINT flag.
71#define TWISendTransmit() (TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE)) // Used to resume a transfer, clear TWINT and ensure that TWI and interrupts are enabled.
72#define TWISendACK() (TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE)|(1<<TWEA)) // FOR MR mode. Resume a transfer, ensure that TWI and interrupts are enabled and respond with an ACK if the device is addressed as a slave or after it receives a byte.
73#define TWISendNACK() (TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE)) // FOR MR mode. Resume a transfer, ensure that TWI and interrupts are enabled but DO NOT respond with an ACK if the device is addressed as a slave or after it receives a byte.
74
75// Function declarations
76void TWITransmitData(void *const TXdata, uint8_t dataLen, uint8_t repStart, uint8_t blocking);
77void TWIInit(void);
78uint8_t TWIReadData(uint8_t TWIaddr, uint8_t bytesToRead, uint8_t repStart);
79uint8_t isTWIReady(void);
80
81#endif // TWICOMMS_H_ \ No newline at end of file
diff --git a/keyboards/meira/config.h b/keyboards/meira/config.h
new file mode 100644
index 000000000..e335db90f
--- /dev/null
+++ b/keyboards/meira/config.h
@@ -0,0 +1,53 @@
1/*
2Copyright 2017 Cole Markham
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#ifndef CONFIG_H
19#define CONFIG_H
20
21#include "config_common.h"
22
23/* USB Device descriptor parameter */
24#define VENDOR_ID 0xFEED
25#define PRODUCT_ID 0x6061
26#define DEVICE_VER 0x0001
27#define MANUFACTURER WoodKeys.click
28#define PRODUCT Meira
29#define DESCRIPTION Low-profile Ortholinear Compact keyboard
30
31/* key matrix size */
32#define MATRIX_ROWS 4
33#define MATRIX_COLS 12
34
35/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */
36#define DIODE_DIRECTION CUSTOM_MATRIX
37
38#define BACKLIGHT_LEVELS 10
39#define BACKLIGHT_PWM_MAP {2, 4, 8, 16, 40, 55, 70, 128, 200, 255}
40#define BACKLIGHT_BREATHING
41
42#define RGB_DI_PIN D3
43#define RGBLIGHT_TIMER
44#define RGBLED_NUM 15 // Number of LEDs
45
46#ifdef SUBPROJECT_promicro
47 #include "promicro/config.h"
48#endif
49#ifdef SUBPROJECT_featherble
50 #include "featherble/config.h"
51#endif
52
53#endif
diff --git a/keyboards/meira/featherble/config.h b/keyboards/meira/featherble/config.h
new file mode 100644
index 000000000..ade3b2d57
--- /dev/null
+++ b/keyboards/meira/featherble/config.h
@@ -0,0 +1,175 @@
1/*
2Copyright 2017 REPLACE_WITH_YOUR_NAME
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#ifndef FEATHERBLECONFIG_H
19#define FEATHERBLECONFIG_H
20
21#include "config_common.h"
22
23/*
24 * Keyboard Matrix Assignments
25 *
26 * Change this to how you wired your keyboard
27 * COLS: AVR pins used for columns, left to right
28 * ROWS: AVR pins used for rows, top to bottom
29 * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
30 * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
31 *
32*/
33#define MATRIX_ROW_PINS { F7, F6, F5, F4 }
34// Column pins to demux in LSB order
35#define MATRIX_COL_PINS { C7, B7, B6, C6 }
36#define LED_EN_PIN D2
37#define UNUSED_PINS
38
39#define CATERINA_BOOTLOADER
40
41
42// #define BACKLIGHT_PIN B7
43// #define BACKLIGHT_BREATHING
44//#define BACKLIGHT_LEVELS 3
45
46
47/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
48#define DEBOUNCING_DELAY 5
49
50/* define if matrix has ghost (lacks anti-ghosting diodes) */
51//#define MATRIX_HAS_GHOST
52
53/* number of backlight levels */
54
55/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
56#define LOCKING_SUPPORT_ENABLE
57/* Locking resynchronize hack */
58#define LOCKING_RESYNC_ENABLE
59
60/*
61 * Force NKRO
62 *
63 * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
64 * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
65 * makefile for this to work.)
66 *
67 * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
68 * until the next keyboard reset.
69 *
70 * NKRO may prevent your keystrokes from being detected in the BIOS, but it is
71 * fully operational during normal computer usage.
72 *
73 * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
74 * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
75 * bootmagic, NKRO mode will always be enabled until it is toggled again during a
76 * power-up.
77 *
78 */
79//#define FORCE_NKRO
80
81/*
82 * Magic Key Options
83 *
84 * Magic keys are hotkey commands that allow control over firmware functions of
85 * the keyboard. They are best used in combination with the HID Listen program,
86 * found here: https://www.pjrc.com/teensy/hid_listen.html
87 *
88 * The options below allow the magic key functionality to be changed. This is
89 * useful if your keyboard/keypad is missing keys and you want magic key support.
90 *
91 */
92
93/* key combination for magic key command */
94#define IS_COMMAND() ( \
95 keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
96)
97
98/* control how magic key switches layers */
99//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
100//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
101//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
102
103/* override magic key keymap */
104//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
105//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
106//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
107//#define MAGIC_KEY_HELP1 H
108//#define MAGIC_KEY_HELP2 SLASH
109//#define MAGIC_KEY_DEBUG D
110//#define MAGIC_KEY_DEBUG_MATRIX X
111//#define MAGIC_KEY_DEBUG_KBD K
112//#define MAGIC_KEY_DEBUG_MOUSE M
113//#define MAGIC_KEY_VERSION V
114//#define MAGIC_KEY_STATUS S
115//#define MAGIC_KEY_CONSOLE C
116//#define MAGIC_KEY_LAYER0_ALT1 ESC
117//#define MAGIC_KEY_LAYER0_ALT2 GRAVE
118//#define MAGIC_KEY_LAYER0 0
119//#define MAGIC_KEY_LAYER1 1
120//#define MAGIC_KEY_LAYER2 2
121//#define MAGIC_KEY_LAYER3 3
122//#define MAGIC_KEY_LAYER4 4
123//#define MAGIC_KEY_LAYER5 5
124//#define MAGIC_KEY_LAYER6 6
125//#define MAGIC_KEY_LAYER7 7
126//#define MAGIC_KEY_LAYER8 8
127//#define MAGIC_KEY_LAYER9 9
128//#define MAGIC_KEY_BOOTLOADER PAUSE
129//#define MAGIC_KEY_LOCK CAPS
130//#define MAGIC_KEY_EEPROM E
131//#define MAGIC_KEY_NKRO N
132//#define MAGIC_KEY_SLEEP_LED Z
133
134/*
135 * Feature disable options
136 * These options are also useful to firmware size reduction.
137 */
138
139/* disable debug print */
140//#define NO_DEBUG
141
142/* disable print */
143//#define NO_PRINT
144
145/* disable action features */
146//#define NO_ACTION_LAYER
147//#define NO_ACTION_TAPPING
148//#define NO_ACTION_ONESHOT
149//#define NO_ACTION_MACRO
150//#define NO_ACTION_FUNCTION
151
152/*
153 * MIDI options
154 */
155
156/* Prevent use of disabled MIDI features in the keymap */
157//#define MIDI_ENABLE_STRICT 1
158
159/* enable basic MIDI features:
160 - MIDI notes can be sent when in Music mode is on
161*/
162//#define MIDI_BASIC
163
164/* enable advanced MIDI features:
165 - MIDI notes can be added to the keymap
166 - Octave shift and transpose
167 - Virtual sustain, portamento, and modulation wheel
168 - etc.
169*/
170//#define MIDI_ADVANCED
171
172/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
173//#define MIDI_TONE_KEYCODE_OCTAVES 1
174
175#endif
diff --git a/keyboards/meira/featherble/featherble.c b/keyboards/meira/featherble/featherble.c
new file mode 100644
index 000000000..560f0db29
--- /dev/null
+++ b/keyboards/meira/featherble/featherble.c
@@ -0,0 +1 @@
#include "meira.h"
diff --git a/keyboards/meira/featherble/featherble.h b/keyboards/meira/featherble/featherble.h
new file mode 100644
index 000000000..b7599b994
--- /dev/null
+++ b/keyboards/meira/featherble/featherble.h
@@ -0,0 +1,9 @@
1#ifndef FEATHERBLE_H
2#define FEATHERBLE_H
3
4#include "../meira.h"
5
6#include "quantum.h"
7
8
9#endif
diff --git a/keyboards/meira/featherble/rules.mk b/keyboards/meira/featherble/rules.mk
new file mode 100644
index 000000000..47d0e5b89
--- /dev/null
+++ b/keyboards/meira/featherble/rules.mk
@@ -0,0 +1,4 @@
1BLUETOOTH_ENABLE = yes
2BACKLIGHT_ENABLE = yes
3F_CPU = 8000000
4
diff --git a/keyboards/meira/issi.c b/keyboards/meira/issi.c
new file mode 100755
index 000000000..600a465ba
--- /dev/null
+++ b/keyboards/meira/issi.c
@@ -0,0 +1,286 @@
1#ifdef ISSI_ENABLE
2
3#include <stdlib.h>
4#include <stdint.h>
5#include <util/delay.h>
6#include <avr/sfr_defs.h>
7#include <avr/io.h>
8#include <util/twi.h>
9#include "issi.h"
10#include "print.h"
11#include "TWIlib.h"
12
13#define ISSI_ADDR_DEFAULT 0xE8
14
15#define ISSI_REG_CONFIG 0x00
16#define ISSI_REG_CONFIG_PICTUREMODE 0x00
17#define ISSI_REG_CONFIG_AUTOPLAYMODE 0x08
18
19#define ISSI_CONF_PICTUREMODE 0x00
20#define ISSI_CONF_AUTOFRAMEMODE 0x04
21#define ISSI_CONF_AUDIOMODE 0x08
22
23#define ISSI_REG_PICTUREFRAME 0x01
24
25#define ISSI_REG_SHUTDOWN 0x0A
26#define ISSI_REG_AUDIOSYNC 0x06
27
28#define ISSI_COMMANDREGISTER 0xFD
29#define ISSI_BANK_FUNCTIONREG 0x0B // helpfully called 'page nine'
30uint8_t control[8][9] = {
31 {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0},
32 {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0},
33 {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0},
34 {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0},
35};
36ISSIDeviceStruct *issi_devices[4] = {0, 0, 0, 0};
37
38#ifndef cbi
39#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
40#endif
41
42#ifndef sbi
43#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
44#endif
45
46#define I2C_WRITE 0
47#define F_SCL 400000UL // SCL frequency
48#define Prescaler 1
49#define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16 ) / 2)
50
51uint8_t i2c_start(uint8_t address)
52{
53 // reset TWI control register
54 TWCR = 0;
55 // transmit START condition
56 TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
57 // wait for end of transmission
58 while( !(TWCR & (1<<TWINT)) );
59
60 // check if the start condition was successfully transmitted
61 if((TWSR & 0xF8) != TW_START){ return 1; }
62
63 // load slave address into data register
64 TWDR = address;
65 // start transmission of address
66 TWCR = (1<<TWINT) | (1<<TWEN);
67 // wait for end of transmission
68 while( !(TWCR & (1<<TWINT)) );
69
70 // check if the device has acknowledged the READ / WRITE mode
71 uint8_t twst = TW_STATUS & 0xF8;
72 if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
73
74 return 0;
75}
76
77uint8_t i2c_write(uint8_t data)
78{
79 // load data into data register
80 TWDR = data;
81 // start transmission of data
82 TWCR = (1 << TWINT) | (1 << TWEN);
83 // wait for end of transmission
84 while (!(TWCR & (1 << TWINT)))
85 ;
86
87 if ((TWSR & 0xF8) != TW_MT_DATA_ACK) {
88 return 1;
89 }
90 return 0;
91}
92
93uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length)
94{
95 TWBR = (uint8_t)TWBR_val;
96 if (i2c_start(address | I2C_WRITE))
97 return 1;
98 for (uint16_t i = 0; i < length; i++) {
99 if (i2c_write(data[i]))
100 return 1;
101 }
102 // transmit STOP condition
103 TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
104 return 0;
105}
106
107void setFrame(uint8_t device, uint8_t frame)
108{
109 static uint8_t current_frame = -1;
110 if(current_frame != frame){
111 uint8_t payload[] = {
112 ISSI_ADDR_DEFAULT | device << 1,
113 ISSI_COMMANDREGISTER,
114 frame
115 };
116 TWITransmitData(payload, sizeof(payload), 0, 1);
117 }
118 // static uint8_t current_frame = 0xFF;
119 // if(current_frame == frame){
120 // // return;
121 // }
122 // uint8_t payload[2] = { ISSI_COMMANDREGISTER, frame };
123 // i2c_transmit(ISSI_ADDR_DEFAULT | device << 1, payload, 2);
124 // current_frame = frame;
125}
126
127void writeRegister8(uint8_t device, uint8_t frame, uint8_t reg, uint8_t data)
128{
129 // Set the frame
130 setFrame(device, frame);
131
132 // Write to the register
133 uint8_t payload[] = {
134 ISSI_ADDR_DEFAULT | device << 1,
135 reg,
136 data
137 };
138 TWITransmitData(payload, sizeof(payload), 0, 1);
139}
140
141// void activateLED(uint8_t matrix, uint8_t cx, uint8_t cy, uint8_t pwm)
142// {
143// xprintf("activeLED: %02X %02X %02X %02X\n", matrix, cy, cx, pwm);
144// uint8_t x = cx - 1; // funciton takes 1 based counts, but we need 0...
145// uint8_t y = cy - 1; // creating them once for less confusion
146// if(pwm == 0){
147// cbi(control[matrix][y], x);
148// }else{
149// sbi(control[matrix][y], x);
150// }
151// uint8_t device = (matrix & 0x06) >> 1;
152// uint8_t control_reg = (y << 1) | (matrix & 0x01);
153// uint8_t pwm_reg = 0;
154// switch(matrix & 0x01){
155// case 0:
156// pwm_reg = 0x24;
157// break;
158// case 1:
159// pwm_reg = 0x2C;
160// break;
161// }
162// pwm_reg += (y << 4) + x;
163// xprintf(" device: %02X\n", device);
164// xprintf(" control: %02X %02X\n", control_reg, control[matrix][y]);
165// xprintf(" pwm: %02X %02X\n", pwm_reg, pwm);
166// writeRegister8(device, 0, control_reg, control[matrix][y]);
167// writeRegister8(device, 0, control_reg + 0x12, control[matrix][y]);
168// writeRegister8(device, 0, pwm_reg, pwm);
169// }
170
171void activateLED(uint8_t matrix, uint8_t cx, uint8_t cy, uint8_t pwm)
172{
173 uint8_t device_addr = (matrix & 0x06) >> 1;
174 ISSIDeviceStruct *device = issi_devices[device_addr];
175 if(device == 0){
176 return;
177 }
178 // xprintf("activeLED: %02X %02X %02X %02X\n", matrix, cy, cx, pwm);
179 uint8_t x = cx - 1; // funciton takes 1 based counts, but we need 0...
180 uint8_t y = cy - 1; // creating them once for less confusion
181 uint8_t control_reg = (y << 1) | (matrix & 0x01);
182 if(pwm == 0){
183 cbi(device->led_ctrl[control_reg], x);
184 cbi(device->led_blink_ctrl[control_reg], x);
185 }else{
186 sbi(device->led_ctrl[control_reg], x);
187 sbi(device->led_blink_ctrl[control_reg], x);
188 }
189 uint8_t pwm_reg = 0;
190 switch(matrix & 0x01){
191 case 0:
192 pwm_reg = 0x00;
193 break;
194 case 1:
195 pwm_reg = 0x08;
196 break;
197 }
198 pwm_reg += (y << 4) + x;
199 // xprintf(" device_addr: %02X\n", device_addr);
200 // xprintf(" control: %02X %02X\n", control_reg, control[matrix][y]);
201 // xprintf(" pwm: %02X %02X\n", pwm_reg, pwm);
202 // writeRegister8(device_addr, 0, control_reg, control[matrix][y]);
203 device->led_pwm[pwm_reg] = pwm;
204 device->led_dirty = 1;
205
206 // writeRegister8(device_addr, 0, control_reg + 0x12, control[matrix][y]);
207 // writeRegister8(device_addr, 0, pwm_reg, pwm);
208}
209
210void update_issi(uint8_t device_addr, uint8_t blocking)
211{
212 // This seems to take about 6ms
213 ISSIDeviceStruct *device = issi_devices[device_addr];
214 if(device != 0){
215 if(device->fn_dirty){
216 device->fn_dirty = 0;
217 setFrame(device_addr, ISSI_BANK_FUNCTIONREG);
218 TWITransmitData(&device->fn_device_addr, sizeof(device->fn_registers) + 2, 0, 1);
219 }
220 if(device->led_dirty){
221 device->led_dirty = 0;
222 setFrame(device_addr, 0);
223 TWITransmitData(&device->led_device_addr, 0xB6, 0, blocking);
224 }
225 }
226}
227
228void issi_init(void)
229{
230 // Set LED_EN/SDB high to enable the chip
231 xprintf("Enabing SDB on pin: %d\n", LED_EN_PIN);
232 _SFR_IO8((LED_EN_PIN >> 4) + 1) &= ~_BV(LED_EN_PIN & 0xF); // IN
233 _SFR_IO8((LED_EN_PIN >> 4) + 2) |= _BV(LED_EN_PIN & 0xF); // HI
234 TWIInit();
235 for(uint8_t device_addr = 0; device_addr < 4; device_addr++){
236 xprintf("ISSI Init device: %d\n", device_addr);
237 // If this device has been previously allocated, free it
238 if(issi_devices[device_addr] != 0){
239 free(issi_devices[device_addr]);
240 }
241 // Try to shutdown the device, if this fails skip this device
242 writeRegister8(device_addr, ISSI_BANK_FUNCTIONREG, ISSI_REG_SHUTDOWN, 0x00);
243 while (!isTWIReady()){_delay_us(1);}
244 if(TWIInfo.errorCode != 0xFF){
245 xprintf("ISSI init failed %d %02X %02X\n", device_addr, TWIInfo.mode, TWIInfo.errorCode);
246 continue;
247 }
248 // Allocate the device structure - calloc zeros it for us
249 ISSIDeviceStruct *device = (ISSIDeviceStruct *)calloc(sizeof(ISSIDeviceStruct) * 2, 1);
250 issi_devices[device_addr] = device;
251 device->fn_device_addr = ISSI_ADDR_DEFAULT | device_addr << 1;
252 device->fn_register_addr = 0;
253 device->led_device_addr = ISSI_ADDR_DEFAULT | device_addr << 1;
254 device->led_register_addr = 0;
255 // set dirty bits so that all of the buffered data is written out
256 device->fn_dirty = 1;
257 device->led_dirty = 1;
258 update_issi(device_addr, 1);
259 // Set the function register to picture mode
260 // device->fn_reg[ISSI_REG_CONFIG] = ISSI_REG_CONFIG_PICTUREMODE;
261 writeRegister8(device_addr, ISSI_BANK_FUNCTIONREG, ISSI_REG_SHUTDOWN, 0x01);
262 }
263
264 // Shutdown and set all registers to 0
265 // writeRegister8(device_addr, ISSI_BANK_FUNCTIONREG, ISSI_REG_SHUTDOWN, 0x00);
266 // for(uint8_t bank = 0; bank <= 7; bank++){
267 // for (uint8_t reg = 0x00; reg <= 0xB3; reg++) {
268 // writeRegister8(device_addr, bank, reg, 0x00);
269 // }
270 // }
271 // for (uint8_t reg = 0; reg <= 0x0C; reg++) {
272 // writeRegister8(device_addr, ISSI_BANK_FUNCTIONREG, reg, 0x00);
273 // }
274 // writeRegister8(device_addr, ISSI_BANK_FUNCTIONREG, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE);
275 // writeRegister8(device_addr, ISSI_BANK_FUNCTIONREG, ISSI_REG_SHUTDOWN, 0x01);
276 // picture mode
277 // writeRegister8(ISSI_BANK_FUNCTIONREG, 0x01, 0x01);
278
279 //Enable blink
280 // writeRegister8(ISSI_BANK_FUNCTIONREG, 0x05, 0x48B);
281
282 //Enable Breath
283
284}
285
286#endif
diff --git a/keyboards/meira/issi.h b/keyboards/meira/issi.h
new file mode 100755
index 000000000..51777f6ee
--- /dev/null
+++ b/keyboards/meira/issi.h
@@ -0,0 +1,40 @@
1#ifdef ISSI_ENABLE
2#ifndef ISSI_H
3#define ISSI_H
4
5typedef struct ISSIDeviceStruct{
6 uint8_t fn_dirty; // function registers need to be resent
7 uint8_t fn_device_addr;
8 uint8_t fn_register_addr;
9 uint8_t fn_registers[13];
10 uint8_t led_dirty; // LED data has changed and needs to be resent
11 uint8_t led_device_addr;
12 uint8_t led_register_addr;
13 uint8_t led_ctrl[18];
14 uint8_t led_blink_ctrl[18];
15 uint8_t led_pwm[144];
16}ISSIDeviceStruct;
17
18extern ISSIDeviceStruct *issi_devices[];
19
20// Low level commands- 'device' is the 2-bit i2c id.
21void issi_init(void);
22void set_shutdown(uint8_t device, uint8_t shutdown);
23void writeRegister8(uint8_t device, uint8_t frame, uint8_t reg, uint8_t data);
24
25// Higher level, no device is given, but it is calculated from 'matrix'
26// Each device has 2 blocks, max of 4 devices:
27// Device | Block = Matrix
28// 0 A 0
29// 0 B 1
30// 1 A 2
31// 1 B 3
32// 2 A 4
33// 2 B 5
34// 3 A 6
35// 3 B 7
36void activateLED(uint8_t matrix, uint8_t cx, uint8_t cy, uint8_t pwm);
37void update_issi(uint8_t device_addr, uint8_t blocking);
38
39#endif
40#endif \ No newline at end of file
diff --git a/keyboards/meira/keymaps/default/config.h b/keyboards/meira/keymaps/default/config.h
new file mode 100644
index 000000000..f52a97bbc
--- /dev/null
+++ b/keyboards/meira/keymaps/default/config.h
@@ -0,0 +1,24 @@
1/* Copyright 2017 REPLACE_WITH_YOUR_NAME
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#ifndef CONFIG_USER_H
18#define CONFIG_USER_H
19
20#include "../../config.h"
21
22// place overrides here
23
24#endif
diff --git a/keyboards/meira/keymaps/default/keymap.c b/keyboards/meira/keymaps/default/keymap.c
new file mode 100644
index 000000000..acde30afc
--- /dev/null
+++ b/keyboards/meira/keymaps/default/keymap.c
@@ -0,0 +1,320 @@
1/* Copyright 2017 Cole Markham
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#include "meira.h"
17#include "issi.h"
18#include "lighting.h"
19
20#ifdef RGBLIGHT_ENABLE
21//Following line allows macro to read current RGB settings
22extern rgblight_config_t rgblight_config;
23#endif
24
25#define _QWERTY 0
26#define _COLEMAK 1
27#define _DVORAK 2
28#define _LOWER 3
29#define _RAISE 4
30#define _ADJUST 16
31
32enum custom_keycodes {
33 QWERTY = SAFE_RANGE,
34 COLEMAK,
35 DVORAK,
36 LOWER,
37 RAISE,
38 ADJUST,
39};
40
41// define variables for reactive RGB
42bool TOG_STATUS = false;
43int RGB_current_mode;
44
45const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
46 /* Qwerty
47 * ,-----------------------------------------------------------------------------------.
48 * | Esc | Q | W | E | R | T | Y | U | I | O | P | Bksp |
49 * |------+------+------+------+------+-------------+------+------+------+------+------|
50 * | Tab | A | S | D | F | G | H | J | K | L | ; | ' |
51 * |------+------+------+------+------+------|------+------+------+------+------+------|
52 * | Shift| Z | X | C | V | B | N | M | , | . | / |Enter |
53 * |------+------+------+------+------+------+------+------+------+------+------+------|
54 * |Adjust| Ctrl | Ctrl | Alt |Lower | Cmd |Space |Raise | Left | Down | Up |Right |
55 * `-----------------------------------------------------------------------------------'
56 */
57 [_QWERTY] = KEYMAP( \
58 KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, \
59 KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, \
60 KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT, \
61 ADJUST, KC_LCTL, KC_LALT, KC_LALT, LOWER, KC_LGUI, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \
62 ),
63
64 /* Colemak
65 * ,-----------------------------------------------------------------------------------.
66 * | Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp |
67 * |------+------+------+------+------+-------------+------+------+------+------+------|
68 * | Esc | A | R | S | T | D | H | N | E | I | O | " |
69 * |------+------+------+------+------+------|------+------+------+------+------+------|
70 * | Shift| Z | X | C | V | B | K | M | , | . | / |Enter |
71 * |------+------+------+------+------+------+------+------+------+------+------+------|
72 * |Adjust| Ctrl | Alt | GUI |Lower |Space |Space |Raise | Left | Down | Up |Right |
73 * `-----------------------------------------------------------------------------------'
74 */
75 [_COLEMAK] = KEYMAP( \
76 KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC, \
77 KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT, \
78 KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT , \
79 ADJUST, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \
80 ),
81
82 /* Dvorak
83 * ,-----------------------------------------------------------------------------------.
84 * | Tab | " | , | . | P | Y | F | G | C | R | L | Bksp |
85 * |------+------+------+------+------+-------------+------+------+------+------+------|
86 * | Esc | A | O | E | U | I | D | H | T | N | S | / |
87 * |------+------+------+------+------+------|------+------+------+------+------+------|
88 * | Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter |
89 * |------+------+------+------+------+------+------+------+------+------+------+------|
90 * |Adjust| Ctrl | Alt | GUI |Lower |Space |Space |Raise | Left | Down | Up |Right |
91 * `-----------------------------------------------------------------------------------'
92 */
93 [_DVORAK] = KEYMAP( \
94 KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC, \
95 KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH, \
96 KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_ENT , \
97 ADJUST, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \
98 ),
99
100 /* Lower
101 * ,-----------------------------------------------------------------------------------.
102 * | | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp |
103 * |------+------+------+------+------+-------------+------+------+------+------+------|
104 * | ~ | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | | \ | | |
105 * |------+------+------+------+------+------|------+------+------+------+------+------|
106 * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | | |Enter |
107 * |------+------+------+------+------+------+------+------+------+------+------+------|
108 * | | | | | | | | Next | Vol- | Vol+ | Play |
109 * `-----------------------------------------------------------------------------------'
110 */
111 [_LOWER] = KEYMAP( \
112 _______, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL, \
113 KC_TILD, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, \
114 _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,S(KC_NUHS),S(KC_NUBS),_______, _______, KC_QUOT, \
115 _______, _______, _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END \
116 ),
117
118 /* Raise
119 * ,-----------------------------------------------------------------------------------.
120 * | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
121 * |------+------+------+------+------+-------------+------+------+------+------+------|
122 * | ` | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ |
123 * |------+------+------+------+------+------|------+------+------+------+------+------|
124 * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO # |ISO / | | |Enter |
125 * |------+------+------+------+------+------+------+------+------+------+------+------|
126 * | | | | | | | | Home | PgUp | PgDn | End |
127 * `-----------------------------------------------------------------------------------'
128 */
129 [_RAISE] = KEYMAP( \
130 _______, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL, \
131 KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, \
132 _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, _______, _______, _______, \
133 _______, _______, _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END \
134 ),
135
136 /* Adjust (Lower + Raise)
137 * ,-----------------------------------------------------------------------------------.
138 * | | Reset| | | | | | | | | | Del |
139 * |------+------+------+------+------+-------------+------+------+------+------+------|
140 * | | | |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak| | |
141 * |------+------+------+------+------+------|------+------+------+------+------+------|
142 * | | | | | | | | | | | | |
143 * |------+------+------+------+------+------+------+------+------+------+------+------|
144 * | | | | | | | | | | | |
145 * `-----------------------------------------------------------------------------------'
146 */
147 [_ADJUST] = KEYMAP( \
148 BL_TOGG, RESET, _______, KC_MRWD, KC_MPLY, KC_MFFD, KC_PSCR, _______, KC_MUTE, KC_VOLD, KC_VOLU, KC_DEL, \
149 BL_STEP, RGB_MOD, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______, \
150 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
151 _______, KC_PSCR, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
152 )
153};
154
155const uint16_t PROGMEM fn_actions[] = {
156
157};
158
159// Setting ADJUST layer RGB back to default
160void update_tri_layer_RGB(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
161 if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
162#ifdef RGBLIGHT_ENABLE
163 rgblight_mode(RGB_current_mode);
164#endif
165 layer_on(layer3);
166 } else {
167 layer_off(layer3);
168 }
169}
170
171const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
172{
173 // MACRODOWN only works in this function
174 switch(id) {
175 case 0:
176 if (record->event.pressed) {
177 register_code(KC_RSFT);
178 } else {
179 unregister_code(KC_RSFT);
180 }
181 break;
182 }
183 return MACRO_NONE;
184};
185
186
187void matrix_init_user(void) {
188
189}
190
191void matrix_scan_user(void) {
192
193}
194
195bool process_record_user(uint16_t keycode, keyrecord_t *record) {
196 switch (keycode) {
197 case QWERTY:
198 if (record->event.pressed) {
199 #ifdef AUDIO_ENABLE
200 PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
201 #endif
202// persistent_default_layer_set(1UL<<_QWERTY);
203 }
204 return false;
205 break;
206 case COLEMAK:
207 if (record->event.pressed) {
208 #ifdef AUDIO_ENABLE
209 PLAY_NOTE_ARRAY(tone_colemak, false, 0);
210 #endif
211// persistent_default_layer_set(1UL<<_COLEMAK);
212 }
213 return false;
214 break;
215 case DVORAK:
216 if (record->event.pressed) {
217 #ifdef AUDIO_ENABLE
218 PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
219 #endif
220// persistent_default_layer_set(1UL<<_DVORAK);
221 }
222 return false;
223 break;
224 case LOWER:
225 if (record->event.pressed) {
226 //not sure how to have keyboard check mode and set it to a variable, so my work around
227 //uses another variable that would be set to true after the first time a reactive key is pressed.
228 if (TOG_STATUS) { //TOG_STATUS checks is another reactive key currently pressed, only changes RGB mode if returns false
229 } else {
230 TOG_STATUS = !TOG_STATUS;
231#ifdef RGBLIGHT_ENABLE
232 rgblight_mode(16);
233#endif
234 }
235 layer_on(_LOWER);
236 update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
237 } else {
238#ifdef RGBLIGHT_ENABLE
239 rgblight_mode(RGB_current_mode); // revert RGB to initial mode prior to RGB mode change
240#endif
241 TOG_STATUS = false;
242 layer_off(_LOWER);
243 update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
244 }
245 return false;
246 break;
247 case RAISE:
248 if (record->event.pressed) {
249 //not sure how to have keyboard check mode and set it to a variable, so my work around
250 //uses another variable that would be set to true after the first time a reactive key is pressed.
251 if (TOG_STATUS) { //TOG_STATUS checks is another reactive key currently pressed, only changes RGB mode if returns false
252 } else {
253 TOG_STATUS = !TOG_STATUS;
254#ifdef RGBLIGHT_ENABLE
255 rgblight_mode(15);
256#endif
257 }
258 layer_on(_RAISE);
259 update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
260 } else {
261#ifdef RGBLIGHT_ENABLE
262 rgblight_mode(RGB_current_mode); // revert RGB to initial mode prior to RGB mode change
263#endif
264 layer_off(_RAISE);
265 TOG_STATUS = false;
266 update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
267 }
268 return false;
269 break;
270 case ADJUST:
271 // FIXME add RGB feedback
272 if (record->event.pressed) {
273 layer_on(_ADJUST);
274 } else {
275 layer_off(_ADJUST);
276 }
277 return false;
278 break;
279 case BL_TOGG:
280#ifdef ISSI_ENABLE
281 if (record->event.pressed) {
282 print("Enabling backlight\n");
283 issi_init();
284 }
285#endif
286 return false;
287 break;
288 case BL_STEP:
289 if (record->event.pressed) {
290 print("Stepping backlight\n");
291#ifdef BACKLIGHT_ENABLE
292 print("Really stepping backlight\n");
293 backlight_step();
294#endif
295
296 }
297 return false;
298 break;
299 //led operations - RGB mode change now updates the RGB_current_mode to allow the right RGB mode to be set after reactive keys are released
300#ifdef RGBLIGHT_ENABLE
301 case RGB_MOD:
302 if (record->event.pressed) {
303 rgblight_mode(RGB_current_mode);
304 rgblight_step();
305 RGB_current_mode = rgblight_config.mode;
306 }
307 return false;
308 break;
309#endif
310// case BL_INC:
311// meira_inc_backlight_level();
312// return false;
313// break;
314 }
315 return true;
316}
317
318void led_set_user(uint8_t usb_led) {
319
320}
diff --git a/keyboards/meira/keymaps/default/readme.md b/keyboards/meira/keymaps/default/readme.md
new file mode 100644
index 000000000..be8404881
--- /dev/null
+++ b/keyboards/meira/keymaps/default/readme.md
@@ -0,0 +1 @@
# The default keymap for meira
diff --git a/keyboards/meira/lighting.c b/keyboards/meira/lighting.c
new file mode 100755
index 000000000..fee70a32b
--- /dev/null
+++ b/keyboards/meira/lighting.c
@@ -0,0 +1,95 @@
1#ifdef ISSI_ENABLE
2
3
4#include <avr/sfr_defs.h>
5#include <avr/timer_avr.h>
6#include <avr/wdt.h>
7#include "meira.h"
8#include "issi.h"
9#include "TWIlib.h"
10#include "lighting.h"
11#include "debug.h"
12#include "audio/audio.h"
13
14
15const uint8_t backlight_pwm_map[BACKLIGHT_LEVELS] = BACKLIGHT_PWM_MAP;
16
17 const uint8_t switch_matrices[] = {0, 1};
18
19 // Maps switch LEDs from Row/Col to ISSI matrix.
20 // Value breakdown:
21 // Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
22 // | | ISSI Col | ISSI Row |
23 // / |
24 // Device
25// const uint8_t switch_leds[MATRIX_ROWS][MATRIX_COLS] =
26// KEYMAP(
27// 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0xA9, 0xA8, 0xA7, 0xA6, 0xA5,
28// 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0xB9, 0xB8, 0xB7, 0xB6, 0xB5,
29// 0x49, 0x48, 0x47, 0x45, 0x44, 0x43, 0x42, 0x41, 0xC9, 0xC8, 0xC7, 0xC6,
30// 0x59, 0x58, 0x57, 0x56, 0x55, 0x51, 0xD6, 0xE5, 0xE4, 0xE3, 0xE2);
31
32void backlight_set(uint8_t level){
33#ifdef BACKLIGHT_ENABLE
34 uint8_t pwm_value = 0;
35 if(level >= BACKLIGHT_LEVELS){
36 level = BACKLIGHT_LEVELS;
37 }
38 if(level > 0){
39 pwm_value = backlight_pwm_map[level-1];
40 }
41 xprintf("BACKLIGHT_LEVELS: %d\n", BACKLIGHT_LEVELS);
42 xprintf("backlight_set level: %d pwm: %d\n", level, pwm_value);
43 for(int x = 1; x <= 9; x++){
44 for(int y = 1; y <= 9; y++){
45 activateLED(switch_matrices[0], x, y, pwm_value);
46 activateLED(switch_matrices[1], x, y, pwm_value);
47 }
48 }
49#endif
50}
51
52void set_backlight_by_keymap(uint8_t col, uint8_t row){
53// dprintf("LED: %02X, %d %d %d\n", lookup_value, matrix, led_col, led_row);
54// activateLED(matrix, led_col, led_row, 255);
55}
56
57void force_issi_refresh(){
58 issi_devices[0]->led_dirty = true;
59 update_issi(0, true);
60 issi_devices[3]->led_dirty = true;
61 update_issi(3, true);
62}
63
64void led_test(){
65#ifdef WATCHDOG_ENABLE
66 // This test take a long time to run, disable the WTD until its complete
67 wdt_disable();
68#endif
69 backlight_set(0);
70 force_issi_refresh();
71// for(uint8_t x = 0; x < sizeof(rgb_sequence); x++){
72// set_rgb(rgb_sequence[x], 255, 0, 0);
73// force_issi_refresh();
74// _delay_ms(250);
75// set_rgb(rgb_sequence[x], 0, 255, 0);
76// force_issi_refresh();
77// _delay_ms(250);
78// set_rgb(rgb_sequence[x], 0, 0, 255);
79// force_issi_refresh();
80// _delay_ms(250);
81// set_rgb(rgb_sequence[x], 0, 0, 0);
82// force_issi_refresh();
83// }
84#ifdef WATCHDOG_ENABLE
85 wdt_enable(WDTO_250MS);
86#endif
87}
88
89void backlight_init_ports(void){
90 xprintf("backlight_init_ports\n");
91 issi_init();
92}
93
94#endif
95
diff --git a/keyboards/meira/lighting.h b/keyboards/meira/lighting.h
new file mode 100755
index 000000000..dc55b70ef
--- /dev/null
+++ b/keyboards/meira/lighting.h
@@ -0,0 +1,9 @@
1#ifndef LIGHTING_H
2#define LIGHTING_H
3
4void led_test(void);
5void force_issi_refresh(void);
6void set_backlight(uint8_t level);
7void set_backlight_by_keymap(uint8_t col, uint8_t row);
8
9#endif
diff --git a/keyboards/meira/matrix.c b/keyboards/meira/matrix.c
new file mode 100644
index 000000000..a4d8ec247
--- /dev/null
+++ b/keyboards/meira/matrix.c
@@ -0,0 +1,314 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3Copyright 2017 Cole Markham <cole@ccmcomputing.net>
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/*
20 * scan matrix
21 */
22#include <stdint.h>
23#include <stdbool.h>
24#if defined(__AVR__)
25#include <avr/io.h>
26#endif
27#include "meira.h"
28#include "wait.h"
29#include "print.h"
30#include "debug.h"
31#include "util.h"
32#include "matrix.h"
33#include "config.h"
34#include "timer.h"
35
36#ifndef DEBOUNCING_DELAY
37# define DEBOUNCING_DELAY 5
38#endif
39
40#if (DEBOUNCING_DELAY > 0)
41 static uint16_t debouncing_time;
42 static bool debouncing = false;
43#endif
44
45#if (MATRIX_COLS <= 8)
46# define print_matrix_header() print("\nr/c 01234567\n")
47# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
48# define matrix_bitpop(i) bitpop(matrix[i])
49# define ROW_SHIFTER ((uint8_t)1)
50#elif (MATRIX_COLS <= 16)
51# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
52# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
53# define matrix_bitpop(i) bitpop16(matrix[i])
54# define ROW_SHIFTER ((uint16_t)1)
55#elif (MATRIX_COLS <= 32)
56# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
57# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
58# define matrix_bitpop(i) bitpop32(matrix[i])
59# define ROW_SHIFTER ((uint32_t)1)
60#endif
61
62static matrix_row_t matrix_debouncing[MATRIX_ROWS];
63
64static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
65static const uint8_t col_pins[4] = MATRIX_COL_PINS;
66//static const uint8_t lrow_pins[MATRIX_ROWS] = LED_ROW_PINS;
67//static const uint8_t lcol_pins[4] = LED_COL_PINS;
68
69/* matrix state(1:on, 0:off) */
70static matrix_row_t matrix[MATRIX_ROWS];
71static matrix_row_t matrix_debouncing[MATRIX_ROWS];
72static void init_rows(void);
73//static void init_lcols(void);
74static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col);
75static void unselect_cols(void);
76static void select_col(uint8_t col);
77
78__attribute__ ((weak))
79void matrix_init_quantum(void) {
80 matrix_init_kb();
81}
82
83__attribute__ ((weak))
84void matrix_scan_quantum(void) {
85 matrix_scan_kb();
86}
87
88__attribute__ ((weak))
89void matrix_init_kb(void) {
90 matrix_init_user();
91}
92
93__attribute__ ((weak))
94void matrix_scan_kb(void) {
95 matrix_scan_user();
96}
97
98__attribute__ ((weak))
99void matrix_init_user(void) {
100}
101
102__attribute__ ((weak))
103void matrix_scan_user(void) {
104}
105
106inline
107uint8_t matrix_rows(void)
108{
109 return MATRIX_ROWS;
110}
111
112inline
113uint8_t matrix_cols(void)
114{
115 return MATRIX_COLS;
116}
117
118void matrix_init(void)
119{
120 debug_enable = true;
121 debug_matrix = true;
122 debug_mouse = true;
123 // initialize row and col
124 unselect_cols();
125 init_rows();
126// init_lcols();
127
128// TX_RX_LED_INIT;
129
130 // initialize matrix state: all keys off
131 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
132 matrix[i] = 0;
133 matrix_debouncing[i] = 0;
134 }
135
136 matrix_init_quantum();
137
138}
139
140uint8_t _matrix_scan(void)
141{
142 // Set col, read rows
143 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
144# if (DEBOUNCING_DELAY > 0)
145 bool matrix_changed = read_rows_on_col(matrix_debouncing, current_col);
146 if (matrix_changed) {
147 debouncing = true;
148 debouncing_time = timer_read();
149 }
150# else
151 read_rows_on_col(matrix, current_col);
152# endif
153
154 }
155
156# if (DEBOUNCING_DELAY > 0)
157 if (debouncing && (timer_elapsed(debouncing_time) > DEBOUNCING_DELAY)) {
158 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
159 matrix[i] = matrix_debouncing[i];
160 }
161 debouncing = false;
162 }
163# endif
164
165 return 1;
166}
167
168uint8_t matrix_scan(void)
169{
170 uint8_t ret = _matrix_scan();
171 matrix_scan_quantum();
172// // HACK backlighting
173// for (uint8_t t = 0; t < meira_get_backlight_level(); t++) {
174// for (uint8_t x = 0; x < 13; x++) {
175// for (uint8_t y = 0; y < 4; y++) {
176// uint8_t pin = lcol_pins[y];
177// if ((x >> y) & 1) {
178// _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
179// } else {
180// _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LO
181// }
182// }
183// }
184// }
185 return ret;
186}
187
188bool matrix_is_modified(void)
189{
190 if (debouncing) return false;
191 return true;
192}
193
194inline
195bool matrix_is_on(uint8_t row, uint8_t col)
196{
197 return (matrix[row] & ((matrix_row_t)1<<col));
198}
199
200inline
201matrix_row_t matrix_get_row(uint8_t row)
202{
203 return matrix[row];
204}
205
206void matrix_print(void)
207{
208 print("\nr/c 0123456789ABCDEF\n");
209 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
210 phex(row); print(": ");
211 pbin_reverse16(matrix_get_row(row));
212 print("\n");
213 }
214}
215
216uint8_t matrix_key_count(void)
217{
218 uint8_t count = 0;
219 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
220 count += bitpop16(matrix[i]);
221 }
222 return count;
223}
224
225
226static void init_rows(void)
227{
228 for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
229 uint8_t pin = row_pins[x];
230 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
231 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
232// // HACK backlighting
233// uint8_t lpin = lrow_pins[x];
234// _SFR_IO8((lpin >> 4) + 1) |= _BV(lpin & 0xF); // OUT
235// _SFR_IO8((lpin >> 4) + 2) |= _BV(lpin & 0xF); // HI
236 }
237}
238
239//static void init_lcols(void)
240//{
241// for (uint8_t x = 0; x < 4; x++) {
242// uint8_t pin = lcol_pins[x];
243// _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT
244// _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HIGH
245// }
246//}
247
248static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
249{
250 bool matrix_changed = false;
251
252 // Select col and wait for col selection to stabilize
253 select_col(current_col);
254 wait_us(30);
255
256 // For each row...
257 for(uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++)
258 {
259
260 // Store last value of row prior to reading
261 matrix_row_t last_row_value = current_matrix[row_index];
262
263 // Check row pin state
264 if ((_SFR_IO8(row_pins[row_index] >> 4) & _BV(row_pins[row_index] & 0xF)) == 0)
265 {
266 // Pin LO, set col bit
267 current_matrix[row_index] |= (ROW_SHIFTER << current_col);
268 }
269 else
270 {
271 // Pin HI, clear col bit
272 current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
273 }
274
275 // Determine if the matrix changed state
276 if ((last_row_value != current_matrix[row_index]) && !(matrix_changed))
277 {
278 matrix_changed = true;
279 }
280 }
281
282 // Unselect col
283 unselect_cols();
284
285 return matrix_changed;
286}
287
288static void select_col(uint8_t col)
289{
290#ifdef FLIPPED_BOARD
291 col = MATRIX_COLS - col - 1;
292#endif
293 for(uint8_t x = 0; x < 4; x++) {
294 uint8_t pin = col_pins[x];
295 _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT
296 if (((col >> x) & 0x1) == 1){
297 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HIGH
298 } else {
299 _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
300 }
301 }
302}
303
304static void unselect_cols(void)
305{
306 // FIXME This really needs to use the global enable on the decoder, because currently this sets the value to col1
307 for(uint8_t x = 0; x < 4; x++) {
308 uint8_t pin = col_pins[x];
309 _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT
310 _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
311 }
312}
313
314
diff --git a/keyboards/meira/meira.c b/keyboards/meira/meira.c
new file mode 100644
index 000000000..823415920
--- /dev/null
+++ b/keyboards/meira/meira.c
@@ -0,0 +1,145 @@
1/* Copyright 2017 REPLACE_WITH_YOUR_NAME
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#include "meira.h"
17#include "issi.h"
18#include "TWIlib.h"
19#include "lighting.h"
20#include "quantum.h"
21#define BACKLIGHT_BREATHING
22
23#ifdef AUDIO_ENABLE
24 float tone_startup[][2] = SONG(STARTUP_SOUND);
25 float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
26#endif
27
28
29void shutdown_user(void) {
30 #ifdef AUDIO_ENABLE
31 PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
32 _delay_ms(150);
33 stop_all_notes();
34 #endif
35}
36
37
38void matrix_init_kb(void)
39{
40 debug_enable=true;
41 print("meira matrix_init_kb\n");
42#ifdef AUDIO_ENABLE
43 _delay_ms(20); // gets rid of tick
44 PLAY_NOTE_ARRAY(tone_startup, false, 0);
45#endif
46
47
48#ifdef ISSI_ENABLE
49 issi_init();
50#endif
51 backlight_set(5);
52#ifdef WATCHDOG_ENABLE
53 // This is done after turning the layer LED red, if we're caught in a loop
54 // we should get a flashing red light
55 wdt_enable(WDTO_500MS);
56#endif
57
58
59 // put your keyboard start-up code here
60 // runs once when the firmware starts up
61 matrix_init_user();
62}
63
64void matrix_scan_kb(void)
65{
66#ifdef WATCHDOG_ENABLE
67 wdt_reset();
68#endif
69#ifdef ISSI_ENABLE
70 // switch/underglow lighting update
71 static uint32_t issi_device = 0;
72 static uint32_t twi_last_ready = 0;
73 if(twi_last_ready > 1000){
74 // Its been way too long since the last ISSI update, reset the I2C bus and start again
75 xprintf("TWI failed to recover, TWI re-init\n");
76 twi_last_ready = 0;
77 TWIInit();
78 force_issi_refresh();
79 }
80 if(isTWIReady()){
81 twi_last_ready = 0;
82 // If the i2c bus is available, kick off the issi update, alternate between devices
83 update_issi(issi_device, issi_device);
84 if(issi_device){
85 issi_device = 0;
86 }else{
87 issi_device = 3;
88 }
89 }else{
90 twi_last_ready++;
91 }
92#endif
93 matrix_scan_user();
94}
95
96bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
97 // Test code that turns on the switch led for the key that is pressed
98 // set_backlight_by_keymap(record->event.key.col, record->event.key.row);
99 if (keycode == RESET) {
100 reset_keyboard_kb();
101 } else {
102 }
103 return process_record_user(keycode, record);
104}
105
106void led_set_kb(uint8_t usb_led) {
107 // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here
108 led_set_user(usb_led);
109}
110
111//void action_function(keyrecord_t *event, uint8_t id, uint8_t opt)
112//{
113//#ifdef AUDIO_ENABLE
114// int8_t sign = 1;
115//#endif
116// if(id == LFK_ESC_TILDE){
117// // Send ~ on shift-esc
118// void (*method)(uint8_t) = (event->event.pressed) ? &add_key : &del_key;
119// uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT));
120// method(shifted ? KC_GRAVE : KC_ESCAPE);
121// send_keyboard_report();
122// }else if(event->event.pressed){
123// switch(id){
124// case LFK_CLEAR:
125// // Go back to default layer
126// layer_clear();
127// break;
128//#ifdef ISSI_ENABLE
129// case LFK_LED_TEST:
130// led_test();
131// break;
132//#endif
133// }
134// }
135//}
136
137void reset_keyboard_kb(){
138#ifdef WATCHDOG_ENABLE
139 MCUSR = 0;
140 wdt_disable();
141 wdt_reset();
142#endif
143 xprintf("programming!\n");
144 reset_keyboard();
145}
diff --git a/keyboards/meira/meira.h b/keyboards/meira/meira.h
new file mode 100644
index 000000000..db84f7221
--- /dev/null
+++ b/keyboards/meira/meira.h
@@ -0,0 +1,48 @@
1/* Copyright 2017 Cole Markham
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#ifndef MEIRA_H
17#define MEIRA_H
18
19
20#ifdef SUBPROJECT_featherble
21 #include "featherble.h"
22#endif
23#ifdef SUBPROJECT_promicro
24 #include "promicro.h"
25#endif
26
27#include "quantum.h"
28
29void reset_keyboard_kb(void);
30
31// This a shortcut to help you visually see your layout.
32// The following is an example using the Planck MIT layout
33// The first section contains all of the arguments
34// The second converts the arguments into a two-dimensional array
35#define KEYMAP( \
36 k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \
37 k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \
38 k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, \
39 k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b \
40) \
41{ \
42 { k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b }, \
43 { k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b }, \
44 { k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b }, \
45 { k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b } \
46}
47
48#endif
diff --git a/keyboards/meira/promicro/config.h b/keyboards/meira/promicro/config.h
new file mode 100644
index 000000000..403a4e047
--- /dev/null
+++ b/keyboards/meira/promicro/config.h
@@ -0,0 +1,168 @@
1/*
2Copyright 2017 REPLACE_WITH_YOUR_NAME
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#ifndef PROMICROCONFIG_H
19#define PROMICROCONFIG_H
20
21#include "config_common.h"
22
23
24/*
25 * Keyboard Matrix Assignments
26 *
27 * Change this to how you wired your keyboard
28 * COLS: AVR pins used for columns, left to right
29 * ROWS: AVR pins used for rows, top to bottom
30 * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
31 * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
32 *
33*/
34#define MATRIX_ROW_PINS { F7, F6, F5, F4 }
35// Column pins to demux in LSB order
36#define MATRIX_COL_PINS { B1, B3, B2, B6 }
37#define LED_EN_PIN D2
38#define UNUSED_PINS
39
40#define CATERINA_BOOTLOADER
41
42/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
43#define DEBOUNCING_DELAY 5
44
45/* define if matrix has ghost (lacks anti-ghosting diodes) */
46//#define MATRIX_HAS_GHOST
47
48/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
49//#define LOCKING_SUPPORT_ENABLE
50/* Locking resynchronize hack */
51//#define LOCKING_RESYNC_ENABLE
52
53/*
54 * Force NKRO
55 *
56 * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
57 * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
58 * makefile for this to work.)
59 *
60 * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
61 * until the next keyboard reset.
62 *
63 * NKRO may prevent your keystrokes from being detected in the BIOS, but it is
64 * fully operational during normal computer usage.
65 *
66 * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
67 * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
68 * bootmagic, NKRO mode will always be enabled until it is toggled again during a
69 * power-up.
70 *
71 */
72//#define FORCE_NKRO
73
74/*
75 * Magic Key Options
76 *
77 * Magic keys are hotkey commands that allow control over firmware functions of
78 * the keyboard. They are best used in combination with the HID Listen program,
79 * found here: https://www.pjrc.com/teensy/hid_listen.html
80 *
81 * The options below allow the magic key functionality to be changed. This is
82 * useful if your keyboard/keypad is missing keys and you want magic key support.
83 *
84 */
85
86/* key combination for magic key command */
87#define IS_COMMAND() ( \
88 keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
89)
90
91/* control how magic key switches layers */
92//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
93//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
94//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
95
96/* override magic key keymap */
97//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
98//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
99//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
100//#define MAGIC_KEY_HELP1 H
101//#define MAGIC_KEY_HELP2 SLASH
102//#define MAGIC_KEY_DEBUG D
103//#define MAGIC_KEY_DEBUG_MATRIX X
104//#define MAGIC_KEY_DEBUG_KBD K
105//#define MAGIC_KEY_DEBUG_MOUSE M
106//#define MAGIC_KEY_VERSION V
107//#define MAGIC_KEY_STATUS S
108//#define MAGIC_KEY_CONSOLE C
109//#define MAGIC_KEY_LAYER0_ALT1 ESC
110//#define MAGIC_KEY_LAYER0_ALT2 GRAVE
111//#define MAGIC_KEY_LAYER0 0
112//#define MAGIC_KEY_LAYER1 1
113//#define MAGIC_KEY_LAYER2 2
114//#define MAGIC_KEY_LAYER3 3
115//#define MAGIC_KEY_LAYER4 4
116//#define MAGIC_KEY_LAYER5 5
117//#define MAGIC_KEY_LAYER6 6
118//#define MAGIC_KEY_LAYER7 7
119//#define MAGIC_KEY_LAYER8 8
120//#define MAGIC_KEY_LAYER9 9
121//#define MAGIC_KEY_BOOTLOADER PAUSE
122//#define MAGIC_KEY_LOCK CAPS
123//#define MAGIC_KEY_EEPROM E
124//#define MAGIC_KEY_NKRO N
125//#define MAGIC_KEY_SLEEP_LED Z
126
127/*
128 * Feature disable options
129 * These options are also useful to firmware size reduction.
130 */
131
132/* disable debug print */
133//#define NO_DEBUG
134
135/* disable print */
136//#define NO_PRINT
137
138/* disable action features */
139//#define NO_ACTION_LAYER
140//#define NO_ACTION_TAPPING
141//#define NO_ACTION_ONESHOT
142//#define NO_ACTION_MACRO
143//#define NO_ACTION_FUNCTION
144
145/*
146 * MIDI options
147 */
148
149/* Prevent use of disabled MIDI features in the keymap */
150//#define MIDI_ENABLE_STRICT 1
151
152/* enable basic MIDI features:
153 - MIDI notes can be sent when in Music mode is on
154*/
155//#define MIDI_BASIC
156
157/* enable advanced MIDI features:
158 - MIDI notes can be added to the keymap
159 - Octave shift and transpose
160 - Virtual sustain, portamento, and modulation wheel
161 - etc.
162*/
163//#define MIDI_ADVANCED
164
165/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
166//#define MIDI_TONE_KEYCODE_OCTAVES 1
167
168#endif
diff --git a/keyboards/meira/promicro/promicro.c b/keyboards/meira/promicro/promicro.c
new file mode 100644
index 000000000..cf579c89b
--- /dev/null
+++ b/keyboards/meira/promicro/promicro.c
@@ -0,0 +1,2 @@
1#include "meira.h"
2
diff --git a/keyboards/meira/promicro/promicro.h b/keyboards/meira/promicro/promicro.h
new file mode 100644
index 000000000..8e7525eab
--- /dev/null
+++ b/keyboards/meira/promicro/promicro.h
@@ -0,0 +1,10 @@
1#ifndef FEATHERBLE_H
2#define FEATHERBLE_H
3
4#include "../meira.h"
5
6#include "quantum.h"
7
8#include "pro_micro.h"
9
10#endif
diff --git a/keyboards/meira/promicro/rules.mk b/keyboards/meira/promicro/rules.mk
new file mode 100644
index 000000000..8d6c4e168
--- /dev/null
+++ b/keyboards/meira/promicro/rules.mk
@@ -0,0 +1,2 @@
1BLUETOOTH_ENABLE = no
2BACKLIGHT_ENABLE = yes
diff --git a/keyboards/meira/readme.md b/keyboards/meira/readme.md
new file mode 100644
index 000000000..ef69b1a80
--- /dev/null
+++ b/keyboards/meira/readme.md
@@ -0,0 +1,28 @@
1meira keyboard firmware
2======================
3
4## Quantum MK Firmware
5
6For the full Quantum feature list, see [the parent readme](/).
7
8## Building
9
10Download or clone the whole firmware and navigate to the keyboards/meira folder. Once your dev env is setup, you'll be able to type `make` to generate your .hex - you can then use the Teensy Loader to program your .hex file.
11
12Depending on which keymap you would like to use, you will have to compile slightly differently.
13
14### Default
15
16To build with the default keymap, simply run `make default`.
17
18### Other Keymaps
19
20Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create a folder with the name of your keymap in the keymaps folder, and see keymap documentation (you can find in top readme.md) and existant keymap files.
21
22To build the firmware binary hex file with a keymap just do `make` with a keymap like this:
23
24```
25$ make [default|jack|<name>]
26```
27
28Keymaps follow the format **__\<name\>.c__** and are stored in the `keymaps` folder.
diff --git a/keyboards/meira/rules.mk b/keyboards/meira/rules.mk
new file mode 100644
index 000000000..fa80ca9d4
--- /dev/null
+++ b/keyboards/meira/rules.mk
@@ -0,0 +1,84 @@
1SRC += matrix.c TWIlib.c issi.c lighting.c
2
3# MCU name
4#MCU = at90usb1286
5MCU = atmega32u4
6
7# Processor frequency.
8# This will define a symbol, F_CPU, in all source code files equal to the
9# processor frequency in Hz. You can then use this symbol in your source code to
10# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
11# automatically to create a 32-bit value in your source code.
12#
13# This will be an integer division of F_USB below, as it is sourced by
14# F_USB after it has run through any CPU prescalers. Note that this value
15# does not *change* the processor frequency - it should merely be updated to
16# reflect the processor speed set externally so that the code can use accurate
17# software delays.
18F_CPU = 16000000
19
20
21#
22# LUFA specific
23#
24# Target architecture (see library "Board Types" documentation).
25ARCH = AVR8
26
27# Input clock frequency.
28# This will define a symbol, F_USB, in all source code files equal to the
29# input clock frequency (before any prescaling is performed) in Hz. This value may
30# differ from F_CPU if prescaling is used on the latter, and is required as the
31# raw input clock is fed directly to the PLL sections of the AVR for high speed
32# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
33# at the end, this will be done automatically to create a 32-bit value in your
34# source code.
35#
36# If no clock division is performed on the input clock inside the AVR (via the
37# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
38F_USB = $(F_CPU)
39
40# Interrupt driven control endpoint task(+60)
41OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
42
43
44# Boot Section Size in *bytes*
45# Teensy halfKay 512
46# Teensy++ halfKay 1024
47# Atmel DFU loader 4096
48# LUFA bootloader 4096
49# USBaspLoader 2048
50OPT_DEFS += -DBOOTLOADER_SIZE=512
51
52
53# Build Options
54# change yes to no to disable
55#
56BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
57MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
58EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
59CONSOLE_ENABLE ?= yes # Console for debug(+400)
60COMMAND_ENABLE ?= yes # Commands for debug and configuration
61# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
62SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
63# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
64NKRO_ENABLE ?= no # USB Nkey Rollover
65BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality on B7 by default
66MIDI_ENABLE ?= no # MIDI support (+2400 to 4200, depending on config)
67UNICODE_ENABLE ?= no # Unicode
68BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
69AUDIO_ENABLE ?= no # Audio output on port C6
70RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
71FAUXCLICKY_ENABLE ?= no # Use buzzer to emulate clicky switches
72
73ISSI_ENABLE = yes # If the I2C pullup resistors aren't install this must be disabled
74#WATCHDOG_ENABLE = yes # Resets keyboard if matrix_scan isn't run every 250ms
75
76CUSTOM_MATRIX = yes
77
78ifeq ($(strip $(ISSI_ENABLE)), yes)
79 TMK_COMMON_DEFS += -DISSI_ENABLE
80endif
81
82ifeq ($(strip $(WATCHDOG_ENABLE)), yes)
83 TMK_COMMON_DEFS += -DWATCHDOG_ENABLE
84endif