aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Wilson <scott.t.wilson@gmail.com>2017-12-03 10:32:07 -0500
committerJack Humbert <jack.humb@gmail.com>2017-12-09 00:01:58 -0500
commitc51dfef958bce4a792b66db337d5c7cdf0956fc4 (patch)
treeb51a3d2a95c5ba47416e2964bc98c9ad329cf168
parent8b1862330a960b0413046ed6fdba78d2570e7988 (diff)
downloadqmk_firmware-c51dfef958bce4a792b66db337d5c7cdf0956fc4.tar.gz
qmk_firmware-c51dfef958bce4a792b66db337d5c7cdf0956fc4.zip
Add support for LFKeyboard products: LFK78, LFK87 and SMK65
-rw-r--r--keyboards/lfkeyboards/TWIlib.c283
-rw-r--r--keyboards/lfkeyboards/TWIlib.h81
-rw-r--r--keyboards/lfkeyboards/issi.c244
-rw-r--r--keyboards/lfkeyboards/issi.h40
-rw-r--r--keyboards/lfkeyboards/lfk78/config.h172
-rw-r--r--keyboards/lfkeyboards/lfk78/keymaps/default/config.h8
-rw-r--r--keyboards/lfkeyboards/lfk78/keymaps/default/keymap.c123
-rw-r--r--keyboards/lfkeyboards/lfk78/keymaps/default/readme.md1
-rw-r--r--keyboards/lfkeyboards/lfk78/keymaps/default/rules.mk42
-rw-r--r--keyboards/lfkeyboards/lfk78/lfk78.c225
-rw-r--r--keyboards/lfkeyboards/lfk78/lfk78.h155
-rw-r--r--keyboards/lfkeyboards/lfk78/readme.md14
-rw-r--r--keyboards/lfkeyboards/lfk78/rules.mk34
-rw-r--r--keyboards/lfkeyboards/lfk87/config.h173
-rw-r--r--keyboards/lfkeyboards/lfk87/keymaps/default/config.h8
-rw-r--r--keyboards/lfkeyboards/lfk87/keymaps/default/keymap.c133
-rw-r--r--keyboards/lfkeyboards/lfk87/keymaps/default/rules.mk54
-rw-r--r--keyboards/lfkeyboards/lfk87/keymaps/iso/config.h8
-rw-r--r--keyboards/lfkeyboards/lfk87/keymaps/iso/keymap.c137
-rw-r--r--keyboards/lfkeyboards/lfk87/keymaps/iso/rules.mk53
-rw-r--r--keyboards/lfkeyboards/lfk87/lfk87.c215
-rw-r--r--keyboards/lfkeyboards/lfk87/lfk87.h139
-rw-r--r--keyboards/lfkeyboards/lfk87/readme.md14
-rw-r--r--keyboards/lfkeyboards/lfk87/rules.mk31
-rw-r--r--keyboards/lfkeyboards/lfkeyboards.c0
-rw-r--r--keyboards/lfkeyboards/lfkeyboards.h0
-rw-r--r--keyboards/lfkeyboards/lighting.c157
-rw-r--r--keyboards/lfkeyboards/lighting.h53
-rw-r--r--keyboards/lfkeyboards/rules.mk1
-rw-r--r--keyboards/lfkeyboards/smk65/config.h168
-rw-r--r--keyboards/lfkeyboards/smk65/keymaps/default/config.h8
-rw-r--r--keyboards/lfkeyboards/smk65/keymaps/default/keymap.c85
-rw-r--r--keyboards/lfkeyboards/smk65/keymaps/default/rules.mk36
-rw-r--r--keyboards/lfkeyboards/smk65/readme.md14
-rw-r--r--keyboards/lfkeyboards/smk65/rules.mk17
-rw-r--r--keyboards/lfkeyboards/smk65/smk65.c164
-rw-r--r--keyboards/lfkeyboards/smk65/smk65.h90
37 files changed, 3180 insertions, 0 deletions
diff --git a/keyboards/lfkeyboards/TWIlib.c b/keyboards/lfkeyboards/TWIlib.c
new file mode 100644
index 000000000..abb12cc87
--- /dev/null
+++ b/keyboards/lfkeyboards/TWIlib.c
@@ -0,0 +1,283 @@
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 return 1;
32 }
33 else
34 {
35 if(TWIInfo.mode == Initializing){
36 switch(TWIInfo.errorCode){
37 case TWI_SUCCESS:
38 case TWI_NO_RELEVANT_INFO:
39 break;
40 case TWI_LOST_ARBIT:
41 case TWI_MT_DATA_NACK:
42 // Some kind of I2C error, reset and re-init
43 xprintf("I2C init error: %d\n", TWIInfo.errorCode);
44 TWCR = (1 << TWINT)|(1 << TWSTO);
45 TWIInit();
46 break;
47 default:
48 xprintf("Other i2c init error: %d\n", TWIInfo.errorCode);
49 }
50 }
51 return 0;
52 }
53}
54
55
56void TWITransmitData(void *const TXdata, uint8_t dataLen, uint8_t repStart, uint8_t blocking)
57{
58 // Wait until ready
59 while (!isTWIReady()) {_delay_us(1);}
60 // Reset the I2C stuff
61 TWCR = (1 << TWINT)|(1 << TWSTO);
62 TWIInit();
63 // Set repeated start mode
64 TWIInfo.repStart = repStart;
65 // Copy transmit info to global variables
66 TWITransmitBuffer = (uint8_t *)TXdata;
67 TXBuffLen = dataLen;
68 TXBuffIndex = 0;
69
70 // If a repeated start has been sent, then devices are already listening for an address
71 // and another start does not need to be sent.
72 if (TWIInfo.mode == RepeatedStartSent)
73 {
74 TWIInfo.mode = Initializing;
75 TWDR = TWITransmitBuffer[TXBuffIndex++]; // Load data to transmit buffer
76 TWISendTransmit(); // Send the data
77 }
78 else // Otherwise, just send the normal start signal to begin transmission.
79 {
80 TWIInfo.mode = Initializing;
81 TWISendStart();
82 }
83 if(blocking){
84 // Wait until ready
85 while (!isTWIReady()){_delay_us(1);}
86 }
87}
88
89
90// uint8_t TWITransmitData(void *const TXdata, uint8_t dataLen, uint8_t repStart)
91// {
92// if (dataLen <= TXMAXBUFLEN)
93// {
94// // Wait until ready
95// while (!isTWIReady()) {_delay_us(1);}
96// // Set repeated start mode
97// TWIInfo.repStart = repStart;
98// // Copy data into the transmit buffer
99// uint8_t *data = (uint8_t *)TXdata;
100// for (int i = 0; i < dataLen; i++)
101// {
102// TWITransmitBuffer[i] = data[i];
103// }
104// // Copy transmit info to global variables
105// TXBuffLen = dataLen;
106// TXBuffIndex = 0;
107
108// // If a repeated start has been sent, then devices are already listening for an address
109// // and another start does not need to be sent.
110// if (TWIInfo.mode == RepeatedStartSent)
111// {
112// TWIInfo.mode = Initializing;
113// TWDR = TWITransmitBuffer[TXBuffIndex++]; // Load data to transmit buffer
114// TWISendTransmit(); // Send the data
115// }
116// else // Otherwise, just send the normal start signal to begin transmission.
117// {
118// TWIInfo.mode = Initializing;
119// TWISendStart();
120// }
121
122// }
123// else
124// {
125// return 1; // return an error if data length is longer than buffer
126// }
127// return 0;
128// }
129
130uint8_t TWIReadData(uint8_t TWIaddr, uint8_t bytesToRead, uint8_t repStart)
131{
132 // Check if number of bytes to read can fit in the RXbuffer
133 if (bytesToRead < RXMAXBUFLEN)
134 {
135 // Reset buffer index and set RXBuffLen to the number of bytes to read
136 RXBuffIndex = 0;
137 RXBuffLen = bytesToRead;
138 // Create the one value array for the address to be transmitted
139 uint8_t TXdata[1];
140 // Shift the address and AND a 1 into the read write bit (set to write mode)
141 TXdata[0] = (TWIaddr << 1) | 0x01;
142 // Use the TWITransmitData function to initialize the transfer and address the slave
143 TWITransmitData(TXdata, 1, repStart, 0);
144 }
145 else
146 {
147 return 0;
148 }
149 return 1;
150}
151
152ISR (TWI_vect)
153{
154 switch (TWI_STATUS)
155 {
156 // ----\/ ---- MASTER TRANSMITTER OR WRITING ADDRESS ----\/ ---- //
157 case TWI_MT_SLAW_ACK: // SLA+W transmitted and ACK received
158 // Set mode to Master Transmitter
159 TWIInfo.mode = MasterTransmitter;
160 case TWI_START_SENT: // Start condition has been transmitted
161 case TWI_MT_DATA_ACK: // Data byte has been transmitted, ACK received
162 if (TXBuffIndex < TXBuffLen) // If there is more data to send
163 {
164 TWDR = TWITransmitBuffer[TXBuffIndex++]; // Load data to transmit buffer
165 TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
166 TWISendTransmit(); // Send the data
167 }
168 // This transmission is complete however do not release bus yet
169 else if (TWIInfo.repStart)
170 {
171 TWIInfo.errorCode = 0xFF;
172 TWISendStart();
173 }
174 // All transmissions are complete, exit
175 else
176 {
177 TWIInfo.mode = Ready;
178 TWIInfo.errorCode = 0xFF;
179 TWISendStop();
180 }
181 break;
182
183 // ----\/ ---- MASTER RECEIVER ----\/ ---- //
184
185 case TWI_MR_SLAR_ACK: // SLA+R has been transmitted, ACK has been received
186 // Switch to Master Receiver mode
187 TWIInfo.mode = MasterReceiver;
188 // If there is more than one byte to be read, receive data byte and return an ACK
189 if (RXBuffIndex < RXBuffLen-1)
190 {
191 TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
192 TWISendACK();
193 }
194 // Otherwise when a data byte (the only data byte) is received, return NACK
195 else
196 {
197 TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
198 TWISendNACK();
199 }
200 break;
201
202 case TWI_MR_DATA_ACK: // Data has been received, ACK has been transmitted.
203
204 /// -- HANDLE DATA BYTE --- ///
205 TWIReceiveBuffer[RXBuffIndex++] = TWDR;
206 // If there is more than one byte to be read, receive data byte and return an ACK
207 if (RXBuffIndex < RXBuffLen-1)
208 {
209 TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
210 TWISendACK();
211 }
212 // Otherwise when a data byte (the only data byte) is received, return NACK
213 else
214 {
215 TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
216 TWISendNACK();
217 }
218 break;
219
220 case TWI_MR_DATA_NACK: // Data byte has been received, NACK has been transmitted. End of transmission.
221
222 /// -- HANDLE DATA BYTE --- ///
223 TWIReceiveBuffer[RXBuffIndex++] = TWDR;
224 // This transmission is complete however do not release bus yet
225 if (TWIInfo.repStart)
226 {
227 TWIInfo.errorCode = 0xFF;
228 TWISendStart();
229 }
230 // All transmissions are complete, exit
231 else
232 {
233 TWIInfo.mode = Ready;
234 TWIInfo.errorCode = 0xFF;
235 TWISendStop();
236 }
237 break;
238
239 // ----\/ ---- MT and MR common ----\/ ---- //
240
241 case TWI_MR_SLAR_NACK: // SLA+R transmitted, NACK received
242 case TWI_MT_SLAW_NACK: // SLA+W transmitted, NACK received
243 case TWI_MT_DATA_NACK: // Data byte has been transmitted, NACK received
244 case TWI_LOST_ARBIT: // Arbitration has been lost
245 // Return error and send stop and set mode to ready
246 if (TWIInfo.repStart)
247 {
248 TWIInfo.errorCode = TWI_STATUS;
249 TWISendStart();
250 }
251 // All transmissions are complete, exit
252 else
253 {
254 TWIInfo.mode = Ready;
255 TWIInfo.errorCode = TWI_STATUS;
256 TWISendStop();
257 }
258 break;
259 case TWI_REP_START_SENT: // Repeated start has been transmitted
260 // Set the mode but DO NOT clear TWINT as the next data is not yet ready
261 TWIInfo.mode = RepeatedStartSent;
262 break;
263
264 // ----\/ ---- SLAVE RECEIVER ----\/ ---- //
265
266 // TODO IMPLEMENT SLAVE RECEIVER FUNCTIONALITY
267
268 // ----\/ ---- SLAVE TRANSMITTER ----\/ ---- //
269
270 // TODO IMPLEMENT SLAVE TRANSMITTER FUNCTIONALITY
271
272 // ----\/ ---- MISCELLANEOUS STATES ----\/ ---- //
273 case TWI_NO_RELEVANT_INFO: // It is not really possible to get into this ISR on this condition
274 // Rather, it is there to be manually set between operations
275 break;
276 case TWI_ILLEGAL_START_STOP: // Illegal START/STOP, abort and return error
277 TWIInfo.errorCode = TWI_ILLEGAL_START_STOP;
278 TWIInfo.mode = Ready;
279 TWISendStop();
280 break;
281 }
282
283}
diff --git a/keyboards/lfkeyboards/TWIlib.h b/keyboards/lfkeyboards/TWIlib.h
new file mode 100644
index 000000000..6db3cc951
--- /dev/null
+++ b/keyboards/lfkeyboards/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/lfkeyboards/issi.c b/keyboards/lfkeyboards/issi.c
new file mode 100644
index 000000000..e675a5986
--- /dev/null
+++ b/keyboards/lfkeyboards/issi.c
@@ -0,0 +1,244 @@
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
141void activateLED(uint8_t matrix, uint8_t cx, uint8_t cy, uint8_t pwm)
142{
143 uint8_t device_addr = (matrix & 0x06) >> 1;
144 ISSIDeviceStruct *device = issi_devices[device_addr];
145 if(device == 0){
146 return;
147 }
148 // xprintf("activeLED: %02X %02X %02X %02X\n", matrix, cy, cx, pwm);
149 uint8_t x = cx - 1; // funciton takes 1 based counts, but we need 0...
150 uint8_t y = cy - 1; // creating them once for less confusion
151 uint8_t control_reg = (y << 1) | (matrix & 0x01);
152 if(pwm == 0){
153 cbi(device->led_ctrl[control_reg], x);
154 cbi(device->led_blink_ctrl[control_reg], x);
155 }else{
156 sbi(device->led_ctrl[control_reg], x);
157 sbi(device->led_blink_ctrl[control_reg], x);
158 }
159 uint8_t pwm_reg = 0;
160 switch(matrix & 0x01){
161 case 0:
162 pwm_reg = 0x00;
163 break;
164 case 1:
165 pwm_reg = 0x08;
166 break;
167 }
168 pwm_reg += (y << 4) + x;
169 device->led_pwm[pwm_reg] = pwm;
170 device->led_dirty = 1;
171}
172
173void update_issi(uint8_t device_addr, uint8_t blocking)
174{
175 // This seems to take about 6ms
176 ISSIDeviceStruct *device = issi_devices[device_addr];
177 if(device != 0){
178 if(device->fn_dirty){
179 device->fn_dirty = 0;
180 setFrame(device_addr, ISSI_BANK_FUNCTIONREG);
181 TWITransmitData(&device->fn_device_addr, sizeof(device->fn_registers) + 2, 0, 1);
182 }
183 if(device->led_dirty){
184 device->led_dirty = 0;
185 setFrame(device_addr, 0);
186 TWITransmitData(&device->led_device_addr, 0xB6, 0, blocking);
187 }
188 }
189}
190
191void issi_init(void)
192{
193 TWIInit();
194 for(uint8_t device_addr = 0; device_addr < 4; device_addr++){
195 // If this device has been previously allocated, free it
196 if(issi_devices[device_addr] != 0){
197 free(issi_devices[device_addr]);
198 }
199 // Try to shutdown the device, if this fails skip this device
200 writeRegister8(device_addr, ISSI_BANK_FUNCTIONREG, ISSI_REG_SHUTDOWN, 0x00);
201 while (!isTWIReady()){_delay_us(1);}
202 if(TWIInfo.errorCode != 0xFF){
203 xprintf("ISSI init failed %d %02X %02X\n", device_addr, TWIInfo.mode, TWIInfo.errorCode);
204 continue;
205 }
206 // Allocate the device structure - calloc zeros it for us
207 ISSIDeviceStruct *device = (ISSIDeviceStruct *)calloc(sizeof(ISSIDeviceStruct) * 2, 1);
208 issi_devices[device_addr] = device;
209 device->fn_device_addr = ISSI_ADDR_DEFAULT | device_addr << 1;
210 device->fn_register_addr = 0;
211 device->led_device_addr = ISSI_ADDR_DEFAULT | device_addr << 1;
212 device->led_register_addr = 0;
213 // set dirty bits so that all of the buffered data is written out
214 device->fn_dirty = 1;
215 device->led_dirty = 1;
216 update_issi(device_addr, 1);
217 // Set the function register to picture mode
218 // device->fn_reg[ISSI_REG_CONFIG] = ISSI_REG_CONFIG_PICTUREMODE;
219 writeRegister8(device_addr, ISSI_BANK_FUNCTIONREG, ISSI_REG_SHUTDOWN, 0x01);
220 }
221
222 // Shutdown and set all registers to 0
223 // writeRegister8(device_addr, ISSI_BANK_FUNCTIONREG, ISSI_REG_SHUTDOWN, 0x00);
224 // for(uint8_t bank = 0; bank <= 7; bank++){
225 // for (uint8_t reg = 0x00; reg <= 0xB3; reg++) {
226 // writeRegister8(device_addr, bank, reg, 0x00);
227 // }
228 // }
229 // for (uint8_t reg = 0; reg <= 0x0C; reg++) {
230 // writeRegister8(device_addr, ISSI_BANK_FUNCTIONREG, reg, 0x00);
231 // }
232 // writeRegister8(device_addr, ISSI_BANK_FUNCTIONREG, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE);
233 // writeRegister8(device_addr, ISSI_BANK_FUNCTIONREG, ISSI_REG_SHUTDOWN, 0x01);
234 // picture mode
235 // writeRegister8(ISSI_BANK_FUNCTIONREG, 0x01, 0x01);
236
237 //Enable blink
238 // writeRegister8(ISSI_BANK_FUNCTIONREG, 0x05, 0x48B);
239
240 //Enable Breath
241
242}
243
244#endif \ No newline at end of file
diff --git a/keyboards/lfkeyboards/issi.h b/keyboards/lfkeyboards/issi.h
new file mode 100644
index 000000000..51777f6ee
--- /dev/null
+++ b/keyboards/lfkeyboards/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/lfkeyboards/lfk78/config.h b/keyboards/lfkeyboards/lfk78/config.h
new file mode 100644
index 000000000..32f4455da
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk78/config.h
@@ -0,0 +1,172 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#ifndef CONFIG_H
19#define CONFIG_H
20
21#include "config_common.h"
22
23#define VENDOR_ID 0xFEED
24#define PRODUCT_ID 0x6060
25#define DEVICE_VER 0x0001
26#define MANUFACTURER LFKeyboards
27#define PRODUCT LFK78
28#define DESCRIPTION QMK keyboard firmware for LFK78 LFK_REV_STRING
29
30#ifdef LFK_REV_B
31/* RevB Matrix config */
32 #define DIODE_DIRECTION COL2ROW
33 #define MATRIX_ROWS 10
34 #define MATRIX_COLS 8
35 #define MATRIX_ROW_PINS { B0, B1, B2, B3, B4, F0, F1, F4, F5, F6}
36 #define MATRIX_COL_PINS { E6, F7, D2, D3, D4, D5, D6, D7 }
37 #define UNUSED_PINS { C7 }
38 #define RGBLED_NUM 31 // Number of LEDs
39#else
40/* RevC/D Matrix config */
41 #define DIODE_DIRECTION COL2ROW
42 #define MATRIX_ROWS 5
43 #define MATRIX_COLS 18
44 #define MATRIX_ROW_PINS {D2, D3, D4, D5, D6 }
45 #define MATRIX_COL_PINS {A0, A1, A2, A3, A4, A5, A6, A7, E6, E7,\
46 F0, F1, F2, F3, C0, C1, C2, C3 }
47 #define UNUSED_PINS {B0, B1, B2, B3, B4, B4, B5, B6, B7, C4, C5, C6, C7,\
48 D0, D1, D7, E0, E1, E2, E3, E4, D5, F4, F5, F6, F7,\
49 E6, E7, F0, F1, F2, F3, C0, C1, C2, C3}
50 #define RGBLED_NUM 27 // Number of LEDs
51#endif
52
53#define AUDIO_VOICES
54#define C6_AUDIO
55
56#define BACKLIGHT_LEVELS 8
57#define BACKLIGHT_PWM_MAP {8, 16, 40, 55, 70, 128, 200, 255}
58
59#define RGB_DI_PIN C7 // Have to set it to something to get the ws2812 code to compile
60#define RGBLIGHT_ANIMATIONS
61#define RGBLIGHT_HUE_STEP 10
62#define RGBLIGHT_SAT_STEP 17
63#define RGBLIGHT_VAL_STEP 17
64
65#define TAPPING_TERM 200
66
67/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
68#define DEBOUNCING_DELAY 5
69
70/* define if matrix has ghost (lacks anti-ghosting diodes) */
71//#define MATRIX_HAS_GHOST
72
73/* number of backlight levels */
74
75/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
76#define LOCKING_SUPPORT_ENABLE
77/* Locking resynchronize hack */
78#define LOCKING_RESYNC_ENABLE
79
80/*
81 * Force NKRO
82 *
83 * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
84 * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
85 * makefile for this to work.)
86 *
87 * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
88 * until the next keyboard reset.
89 *
90 * NKRO may prevent your keystrokes from being detected in the BIOS, but it is
91 * fully operational during normal computer usage.
92 *
93 * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
94 * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
95 * bootmagic, NKRO mode will always be enabled until it is toggled again during a
96 * power-up.
97 *
98 */
99//#define FORCE_NKRO
100
101/*
102 * Magic Key Options
103 *
104 * Magic keys are hotkey commands that allow control over firmware functions of
105 * the keyboard. They are best used in combination with the HID Listen program,
106 * found here: https://www.pjrc.com/teensy/hid_listen.html
107 *
108 * The options below allow the magic key functionality to be changed. This is
109 * useful if your keyboard/keypad is missing keys and you want magic key support.
110 *
111 */
112
113/* key combination for magic key command */
114#define IS_COMMAND() ( \
115 keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
116)
117
118/* control how magic key switches layers */
119//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
120//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
121//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
122
123/* override magic key keymap */
124//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
125//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
126//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
127//#define MAGIC_KEY_HELP1 H
128//#define MAGIC_KEY_HELP2 SLASH
129//#define MAGIC_KEY_DEBUG D
130//#define MAGIC_KEY_DEBUG_MATRIX X
131//#define MAGIC_KEY_DEBUG_KBD K
132//#define MAGIC_KEY_DEBUG_MOUSE M
133//#define MAGIC_KEY_VERSION V
134//#define MAGIC_KEY_STATUS S
135//#define MAGIC_KEY_CONSOLE C
136//#define MAGIC_KEY_LAYER0_ALT1 ESC
137//#define MAGIC_KEY_LAYER0_ALT2 GRAVE
138//#define MAGIC_KEY_LAYER0 0
139//#define MAGIC_KEY_LAYER1 1
140//#define MAGIC_KEY_LAYER2 2
141//#define MAGIC_KEY_LAYER3 3
142//#define MAGIC_KEY_LAYER4 4
143//#define MAGIC_KEY_LAYER5 5
144//#define MAGIC_KEY_LAYER6 6
145//#define MAGIC_KEY_LAYER7 7
146//#define MAGIC_KEY_LAYER8 8
147//#define MAGIC_KEY_LAYER9 9
148//#define MAGIC_KEY_BOOTLOADER PAUSE
149//#define MAGIC_KEY_LOCK CAPS
150//#define MAGIC_KEY_EEPROM E
151//#define MAGIC_KEY_NKRO N
152//#define MAGIC_KEY_SLEEP_LED Z
153
154/*
155 * Feature disable options
156 * These options are also useful to firmware size reduction.
157 */
158
159/* disable debug print */
160//#define NO_DEBUG
161
162/* disable print */
163//#define NO_PRINT
164
165/* disable action features */
166//#define NO_ACTION_LAYER
167//#define NO_ACTION_TAPPING
168//#define NO_ACTION_ONESHOT
169//#define NO_ACTION_MACRO
170//#define NO_ACTION_FUNCTION
171
172#endif
diff --git a/keyboards/lfkeyboards/lfk78/keymaps/default/config.h b/keyboards/lfkeyboards/lfk78/keymaps/default/config.h
new file mode 100644
index 000000000..8893d122e
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk78/keymaps/default/config.h
@@ -0,0 +1,8 @@
1#ifndef CONFIG_USER_H
2#define CONFIG_USER_H
3
4#include "../../config.h"
5
6// place overrides here
7
8#endif
diff --git a/keyboards/lfkeyboards/lfk78/keymaps/default/keymap.c b/keyboards/lfkeyboards/lfk78/keymaps/default/keymap.c
new file mode 100644
index 000000000..613213f06
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk78/keymaps/default/keymap.c
@@ -0,0 +1,123 @@
1#include "lfk78.h"
2#include "issi.h"
3#include "lighting.h"
4#include "action_layer.h"
5
6//Define a shorter 'transparent' key code to make the keymaps more compact
7#define KC_TR KC_TRNS
8
9enum keymap_layout {
10 VANILLA = 0, // matches MF68 layout
11 FUNC, // 0x02
12 SETTINGS, // 0x04
13};
14
15// Colors of the layer indicator LED
16// This list needs to define layer 0xFFFFFFFF, it is the end of the list, and the unknown layer
17const Layer_Info layer_info[] = {
18 // Layer Mask Red Green Blue
19 {0x00000000, 0xFFFFFFFF, {0x0000, 0x0FFF, 0x0000}}, // base layer - green
20 {0x00000002, 0xFFFFFFFE, {0x0000, 0x0000, 0x0FFF}}, // function layer - blue
21 {0x00000004, 0xFFFFFFFC, {0x0FFF, 0x0000, 0x0FFF}}, // settings layer - magenta
22 {0xFFFFFFFF, 0xFFFFFFFF, {0x0FFF, 0x0FFF, 0x0FFF}}, // unknown layer - REQUIRED - white
23};
24
25
26
27const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
28[VANILLA] = KEYMAP(
29 /* Keymap VANILLA: (Base Layer) Default Layer
30 * ,---------. ,------------------------------------------------------------. ,---------.
31 * | F1 | F2 | |Esc~| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0| - | = |Backspa| | Ins|PgUp|
32 * |---------| |------------------------------------------------------------| |---------|
33 * | F3 | F4 | |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | Del|PgDn|
34 * |---------| |------------------------------------------------------------| `---------'
35 * | F5 | F6 | |CAPS | A| S| D| F| G| H| J| K| L| ;| '|Return |
36 * |---------| |------------------------------------------------------------| ,----.
37 * | F7 | F8 | |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift | | Up |
38 * |---------| |-------------------------------------------------------------------------.
39 * | F9 | F10| |Ctrl|Win |Alt | Space |Alt |Ctrl|Func | |Lft| Dn |Rig |
40 * `---------' `------------------------------------------------------' `-------------'
41 */
42 KC_F1, KC_F2, KC_GESC,KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_PGUP,
43 KC_F3, KC_F4, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_PGDN,
44 KC_F5, KC_F6, KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
45 KC_F7, KC_F8, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
46 KC_F9, KC_F10, KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RCTL, MO(FUNC), KC_LEFT, KC_DOWN, KC_RGHT),
47 /* Keymap FUNCTION: Function Layer
48 * ,---------. ,-------------------------------------------------------------. ,---------.
49 * | | | | ` |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12|Delete | | Ins|Home|
50 * |---------| |-------------------------------------------------------------| |---------|
51 * | | | |Tab |Hom| Up|End|PgU| | | | | | | | | | | Del|End |
52 * |---------| |-------------------------------------------------------------| `---------'
53 * | | | |MO(FUNC)|Lft|Dn |Rig|PgD| |Lft|Dwn| Up|Rgt| | | |
54 * |---------| |-------------------------------------------------------------| ,----.
55 * | | | |Shift | | | | | | |Mute|V- |V+ | |TG(SETTINGS)| | Up |
56 * |---------| |--------------------------------------------------------------------------.
57 * | | | |Ctrl|Win |Alt | Enter |Alt |Func |CTRL | |Lft| Dn |Rig |
58 * `---------' `------------------------------------------------------' `-------------'
59 */
60[FUNC] = KEYMAP(
61 KC_TR, KC_TR, KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_TR, KC_HOME,
62 KC_TR, KC_TR, KC_NO,KC_HOME, KC_UP, KC_END, KC_PGUP, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TR, KC_END,
63 KC_TR, KC_TR, KC_TR, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGDN, KC_NO, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_NO, KC_NO, KC_NO,
64 KC_TR, KC_TR, KC_TR, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_MUTE, KC_VOLD, KC_VOLU, KC_NO, TG(SETTINGS), KC_TR,
65 KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_ENT, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR),
66
67 /* Keymap SETTINGS: Settings Layer
68 * ,---------. ,-------------------------------------------------------------. ,-------------.
69 * | | | |LayClr| | | | | | | | | | |BL-|BL+|BL Togl| |RGB Tog |Val+|
70 * |---------| |-------------------------------------------------------------| |-------------|
71 * | | | |MuMode | | | | | | | | | | | | |LEDTst| |RGB Mode|Val-|
72 * |---------| |-------------------------------------------------------------| `-------------'
73 * | | | |AudTgl |Hz+|MS+| | | | | | | | | | RST |
74 * |---------| |-------------------------------------------------------------| ,----.
75 * | | | |ClickTgl |Hz-|MS-| | | | |MuTgl| | | |Layer Clr | |Hue+|
76 * |---------| |-------------------------------------------------------------------------.
77 * | | | | | | | | | | | |Sat-|Hue-|Sat+|
78 * `---------' `--------------------------------------------------------' `--------------'
79 */
80[SETTINGS] = KEYMAP(
81 KC_NO, KC_NO, KC_FN0,KC_NO,KC_NO,KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, BL_DEC, BL_INC, BL_TOGG, RGB_TOG, RGB_VAI,
82 KC_NO, KC_NO, MU_MOD, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, RGB_MOD, RGB_VAD,
83 KC_NO, KC_NO, AU_TOG, KC_FN1,KC_FN3, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, RESET,
84 KC_NO, KC_NO, KC_FN5, KC_FN2,KC_FN4, KC_NO, KC_NO, KC_NO, KC_NO, MU_TOG, KC_NO, KC_NO, KC_NO, KC_NO, RGB_HUI,
85 KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, RGB_SAD, RGB_HUD, RGB_SAI),
86};
87
88const uint16_t PROGMEM fn_actions[] = {
89 ACTION_FUNCTION(LFK_CLEAR), // FN0 - reset layers
90 ACTION_FUNCTION(LFK_CLICK_FREQ_HIGHER), // FN1 - Increase Freq of audio click
91 ACTION_FUNCTION(LFK_CLICK_FREQ_LOWER), // FN2 - Decrease Freq of audio click
92 ACTION_FUNCTION(LFK_CLICK_TIME_LONGER), // FN3 - Increase length of audio click
93 ACTION_FUNCTION(LFK_CLICK_TIME_SHORTER), // FN4 - Decrease length of audio click
94 ACTION_FUNCTION(LFK_CLICK_TOGGLE), // FN5 - Toggle audio click
95 };
96
97
98const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
99{
100 // MACRODOWN only works in this function
101 switch(id) {
102 }
103 return MACRO_NONE;
104};
105
106
107void matrix_init_user(void) {
108 // This keymap only has a single base layer, so reset the default if needed
109 if(eeconfig_read_default_layer() > 1){
110 eeconfig_update_default_layer(1);
111 default_layer_set(1);
112 }
113}
114
115void matrix_scan_user(void) {
116}
117
118bool process_record_user(uint16_t keycode, keyrecord_t *record) {
119 return true;
120}
121
122void led_set_user(uint8_t usb_led) {
123}
diff --git a/keyboards/lfkeyboards/lfk78/keymaps/default/readme.md b/keyboards/lfkeyboards/lfk78/keymaps/default/readme.md
new file mode 100644
index 000000000..8321adeb7
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk78/keymaps/default/readme.md
@@ -0,0 +1 @@
# The default keymap for LFK78
diff --git a/keyboards/lfkeyboards/lfk78/keymaps/default/rules.mk b/keyboards/lfkeyboards/lfk78/keymaps/default/rules.mk
new file mode 100644
index 000000000..dd973eac3
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk78/keymaps/default/rules.mk
@@ -0,0 +1,42 @@
1# Build Options
2# change to "no" to disable the options, or define them in the Makefile in
3# the appropriate keymap folder that will get included automatically
4#
5
6BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
7MOUSEKEY_ENABLE = no # Mouse keys(+4700)
8EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
9CONSOLE_ENABLE = no # Console for debug(+400)
10COMMAND_ENABLE = no # Commands for debug and configuration
11NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
12BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
13MIDI_ENABLE = no # MIDI controls
14AUDIO_ENABLE = yes # Audio output on port C6
15UNICODE_ENABLE = no # Unicode
16BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
17RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
18RGBLIGHT_CUSTOM_DRIVER = yes # RGB code is implemented in lefkeyboards, not qmk base
19SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
20TAP_DANCE_ENABLE = no
21
22ISSI_ENABLE = yes # If the I2C pullup resistors aren't install this must be disabled
23WATCHDOG_ENABLE = no # Resets keyboard if matrix_scan isn't run every 250ms
24
25ifndef QUANTUM_DIR
26 include ../../../../Makefile
27endif
28
29ifeq ($(strip $(ISSI_ENABLE)), yes)
30 TMK_COMMON_DEFS += -DISSI_ENABLE
31endif
32
33ifeq ($(strip $(WATCHDOG_ENABLE)), yes)
34 TMK_COMMON_DEFS += -DWATCHDOG_ENABLE
35endif
36
37# Override the LFK78 hardware version:
38#
39# B - first public release, uses atmega32u4, has audio, ISSI matrix split between RGB and backlight
40# C-H - at90usb1286, no audio, ISSI device 0 is backlight, 4 is RGB
41# J - at90usb646, C6 audio, ISSI device 0 is backlight, 4 is RGB
42# LFK_REV = J
diff --git a/keyboards/lfkeyboards/lfk78/lfk78.c b/keyboards/lfkeyboards/lfk78/lfk78.c
new file mode 100644
index 000000000..e4393327f
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk78/lfk78.c
@@ -0,0 +1,225 @@
1#include <avr/sfr_defs.h>
2#include <avr/timer_avr.h>
3#include <avr/wdt.h>
4#include "lfk78.h"
5#include "keymap.h"
6#include "issi.h"
7#include "TWIlib.h"
8#include "lighting.h"
9#include "debug.h"
10#include <audio/audio.h>
11
12uint16_t click_hz = CLICK_HZ;
13uint16_t click_time = CLICK_MS;
14uint8_t click_toggle = CLICK_ENABLED;
15
16void matrix_init_kb(void)
17{
18 matrix_init_user();
19
20 // Configure the Layer LED
21 // Set up 16 bit PWM: Fast PWM, mode 15, inverted
22 TCCR1A = 0b11111110;
23 TCCR1B = 0b00011001;
24 ICR1 = 0xFFFF;
25 // PWM values - 0xFFFF = off, 0x0000 = max
26 OCR1C = 0x0000; // B7 - Blue
27 OCR1B = 0x0000; // B6 - Green
28 OCR1A = 0x0FFF; // B5 - Red
29 // Set as output
30 DDRB |= 0b11100000;
31
32#ifndef AUDIO_ENABLE
33 // If we're not using the audio pin, drive it low
34 sbi(DDRC, 6);
35 cbi(PORTC, 6);
36#endif
37
38#ifdef ISSI_ENABLE
39 issi_init();
40#endif
41#ifdef WATCHDOG_ENABLE
42 // This is done after turning the layer LED red, if we're caught in a loop
43 // we should get a flashing red light
44 wdt_enable(WDTO_500MS);
45#endif
46
47}
48
49void matrix_scan_kb(void)
50{
51#ifdef WATCHDOG_ENABLE
52 wdt_reset();
53#endif
54#ifdef ISSI_ENABLE
55 // switch/underglow lighting update
56 static uint32_t issi_device = 0;
57 static uint32_t twi_last_ready = 0;
58 if(twi_last_ready > 1000){
59 // Its been way too long since the last ISSI update, reset the I2C bus and start again
60 dprintf("TWI failed to recover, TWI re-init\n");
61 twi_last_ready = 0;
62 TWIInit();
63 force_issi_refresh();
64 }
65 if(isTWIReady()){
66 twi_last_ready = 0;
67 // If the i2c bus is available, kick off the issi update, alternate between devices
68 update_issi(issi_device, issi_device);
69 if(issi_device){
70 issi_device = 0;
71 }else{
72 issi_device = 3;
73 }
74 }else{
75 twi_last_ready++;
76 }
77#endif
78 // Update layer indicator LED
79 //
80 // Not sure how else to reliably do this... TMK has the 'hook_layer_change'
81 // but can't find QMK equiv
82 static uint32_t layer_indicator = -1;
83 if(layer_indicator != layer_state){
84 for(uint32_t i=0;; i++){
85 // the layer_info list should end with layer 0xFFFFFFFF
86 // it will break this out of the loop and define the unknown layer color
87 if((layer_info[i].layer == (layer_state & layer_info[i].mask)) || (layer_info[i].layer == 0xFFFFFFFF)){
88 OCR1A = layer_info[i].color.red;
89 OCR1B = layer_info[i].color.green;
90 OCR1C = layer_info[i].color.blue;
91 layer_indicator = layer_state;
92 break;
93 }
94 }
95 }
96 matrix_scan_user();
97}
98
99void click(uint16_t freq, uint16_t duration){
100#ifdef AUDIO_ENABLE
101 if(freq >= 100 && freq <= 20000 && duration < 100){
102 play_note(freq, 10);
103 for (uint16_t i = 0; i < duration; i++){
104 _delay_ms(1);
105 }
106 stop_all_notes();
107 }
108#endif
109}
110
111bool process_record_kb(uint16_t keycode, keyrecord_t* record)
112{
113 if (click_toggle && record->event.pressed){
114 click(click_hz, click_time);
115 }
116 if (keycode == RESET) {
117 reset_keyboard_kb();
118 } else {
119 }
120 return process_record_user(keycode, record);
121}
122
123void action_function(keyrecord_t *event, uint8_t id, uint8_t opt)
124{
125#ifdef AUDIO_ENABLE
126 int8_t sign = 1;
127#endif
128 if(id == LFK_ESC_TILDE){
129 // Send ~ on shift-esc
130 void (*method)(uint8_t) = (event->event.pressed) ? &add_key : &del_key;
131 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT));
132 if(layer_state == 0){
133 method(shifted ? KC_GRAVE : KC_ESCAPE);
134 }else{
135 method(shifted ? KC_ESCAPE : KC_GRAVE);
136 }
137 send_keyboard_report();
138 }else if(event->event.pressed){
139 switch(id){
140 case LFK_SET_DEFAULT_LAYER:
141 // set/save the current base layer to eeprom, falls through to LFK_CLEAR
142 eeconfig_update_default_layer(1UL << opt);
143 default_layer_set(1UL << opt);
144 case LFK_CLEAR:
145 // Go back to default layer
146 layer_clear();
147 break;
148#ifdef ISSI_ENABLE
149 case LFK_LED_TEST:
150 led_test();
151 break;
152#endif
153#ifdef AUDIO_ENABLE
154 case LFK_CLICK_FREQ_LOWER:
155 sign = -1; // continue to next statement
156 case LFK_CLICK_FREQ_HIGHER:
157 click_hz += sign * 100;
158 click(click_hz, click_time);
159 break;
160 case LFK_CLICK_TOGGLE:
161 if(click_toggle){
162 click_toggle = 0;
163 click(4000, 100);
164 click(1000, 100);
165 }else{
166 click_toggle = 1;
167 click(1000, 100);
168 click(4000, 100);
169 }
170 break;
171 case LFK_CLICK_TIME_SHORTER:
172 sign = -1; // continue to next statement
173 case LFK_CLICK_TIME_LONGER:
174 click_time += sign;
175 click(click_hz, click_time);
176 break;
177#endif
178 case LFK_DEBUG_SETTINGS:
179 dprintf("Click:\n");
180 dprintf(" toggle: %d\n", click_toggle);
181 dprintf(" freq(hz): %d\n", click_hz);
182 dprintf(" duration(ms): %d\n", click_time);
183 break;
184 }
185 }
186}
187
188void reset_keyboard_kb(){
189#ifdef WATCHDOG_ENABLE
190 MCUSR = 0;
191 wdt_disable();
192 wdt_reset();
193#endif
194 OCR1A = 0x0000; // B5 - Red
195 OCR1B = 0x0FFF; // B6 - Green
196 OCR1C = 0x0FFF; // B7 - Blue
197 reset_keyboard();
198}
199
200void led_set_kb(uint8_t usb_led)
201{
202 // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here
203
204 led_set_user(usb_led);
205}
206
207// LFK lighting info
208const uint8_t switch_matrices[] = {0, 1};
209const uint8_t rgb_matrices[] = {6, 7};
210const uint8_t rgb_sequence[] = {
211 12, 11, 10, 9, 16, 32, 31, 30, 28, 25, 24, 22, 21,
212 20, 19, 18, 17, 1, 2, 3, 4, 5, 6, 7, 8, 14, 13
213};
214// Maps switch LEDs from Row/Col to ISSI matrix.
215// Value breakdown:
216// Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
217// / \ ISSI Col | ISSI Row |
218// matrix idx
219const uint8_t switch_leds[MATRIX_ROWS][MATRIX_COLS] =
220KEYMAP(
221 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91,
222 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0xA9, 0xA8, 0xA7, 0xA6, 0xA5, 0xA4, 0xA3, 0xA2, 0xA1,
223 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0xB9, 0xB8, 0xB7, 0xB6, 0xB5, 0xB3,
224 0x49, 0x48, 0x47, 0x45, 0x44, 0x43, 0x42, 0x41, 0xC9, 0xC8, 0xC7, 0xC6, 0xC5, 0xC4, 0xC2,
225 0x59, 0x58, 0x57, 0x56, 0x55, 0x51, 0xD6, 0xE5, 0xE4, 0xE3, 0xE2, 0xE1);
diff --git a/keyboards/lfkeyboards/lfk78/lfk78.h b/keyboards/lfkeyboards/lfk78/lfk78.h
new file mode 100644
index 000000000..47ad74531
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk78/lfk78.h
@@ -0,0 +1,155 @@
1#ifndef LFK78_H
2#define LFK78_H
3
4/* if the kb.h file exists (because we're running from qmkbuilder) include it */
5#if __has_include("kb.h")
6#include "kb.h"
7#endif
8
9#include "quantum.h"
10#include "matrix.h"
11#include <avr/sfr_defs.h>
12
13#ifndef cbi
14#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
15#endif
16
17#ifndef sbi
18#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
19#endif
20
21
22typedef struct RGB_Color {
23 uint16_t red;
24 uint16_t green;
25 uint16_t blue;
26} RGB_Color;
27
28typedef struct Layer_Info {
29 uint32_t layer;
30 uint32_t mask;
31 RGB_Color color;
32} Layer_Info;
33
34extern const uint32_t layer_count;
35extern const Layer_Info layer_info[];
36
37enum action_functions {
38 LFK_CLEAR = 0, // Resets all layers
39 LFK_ESC_TILDE, // esc+lshift = ~
40 LFK_SET_DEFAULT_LAYER, // changes and saves current base layer to eeprom
41 LFK_CLICK_TOGGLE, // Adjusts click duration
42 LFK_CLICK_FREQ_HIGHER, // Adjusts click frequency
43 LFK_CLICK_FREQ_LOWER, // Adjusts click frequency
44 LFK_CLICK_TIME_LONGER, // Adjusts click duration
45 LFK_CLICK_TIME_SHORTER, // Adjusts click duration
46 LFK_DEBUG_SETTINGS, // prints LED and click settings to HID
47 LFK_LED_TEST // cycles through switch and RGB LEDs
48};
49
50#define CLICK_HZ 500
51#define CLICK_MS 2
52#define CLICK_ENABLED 0
53
54void reset_keyboard_kb(void);
55void click(uint16_t freq, uint16_t duration);
56
57#ifdef LFK_REV_B
58 /* RevB Keymap */
59 // This a shortcut to help you visually see your layout.
60 /*
61 * ,---------. ,-----------------------------------------------------------------------. ,---------.
62 * | 0 | 1 | | 2 | 3 | 4 | 5 | 6 | 7 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | | 94 | 95 |
63 * |---------| |-----------------------------------------------------------------------| |---------|
64 * | 10 | 11 | | 12 | 13 | 14 | 15 | 16 | 17 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | | 96 | 97 |
65 * |---------| |-----------------------------------------------------------------------| `---------'
66 * | 20 | 21 | | 22 | 23 | 24 | 25 | 26 | 27 | 70 | 71 | 72 | 73 | 74 | 75 | 76 |
67 * |---------| |-----------------------------------------------------------------------| ,----.
68 * | 30 | 31 | | 32 | 33 | 34 | 35 | 36 | 37 | 80 | 81 | 82 | 83 | 84 | 85 | | 86 |
69 * |---------| |-------------------------------------------------------------------------------------.
70 * | 40 | 41 | | 42 | 43 | 44 | 45 | 46 | 47 | 90 | | 91 | 92 | 93 |
71 * `---------' `--------------------------------------------------------------------' `--------------'
72 */
73 // The first section contains all of the arguements
74 // The second converts the arguments into a two-dimensional array
75 #define KEYMAP( \
76 k00, k01, k02, k03, k04, k05, k06, k07, k50, k51, k52, k53, k54, k55, k56, k57, k94, k95, \
77 k10, k11, k12, k13, k14, k15, k16, k17, k60, k61, k62, k63, k64, k65, k66, k67, k96, k97, \
78 k20, k21, k22, k23, k24, k25, k26, k27, k70, k71, k72, k73, k74, k75, k76, \
79 k30, k31, k32, k33, k34, k35, k36, k37, k80, k81, k82, k83, k84, k85, k86, \
80 k40, k41, k42, k43, k44, k45, k46, k47, k90, k91, k92, k93 \
81 ) { \
82 { k00, k01, k02, k03, k04, k05, k06, k07, }, \
83 { k10, k11, k12, k13, k14, k15, k16, k17, }, \
84 { k20, k21, k22, k23, k24, k25, k26, k27, }, \
85 { k30, k31, k32, k33, k34, k35, k36, k37, }, \
86 { k40, k41, k42, k43, k44, k45, k46, k47, }, \
87 { k50, k51, k52, k53, k54, k55, k56, k57, }, \
88 { k60, k61, k62, k63, k64, k65, k66, k67, }, \
89 { k70, k71, k72, k73, k74, k75, k76, KC_NO,}, \
90 { k80, k81, k82, k83, k84, k85, k86, KC_NO,}, \
91 { k90, k91, k92, k93, k94, k95, k96, k97, }, \
92 }
93#else
94 /* RevC/D Keymap */
95 // This a shortcut to help you visually see your layout.
96 /*
97 * ,---------. ,-----------------------------------------------------------------------. ,---------.
98 * | 11 | 12 | | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 1A | 1B | 1C | 1D | 1E | 1F | 1G | | 1H | 1I |
99 * |---------| |-----------------------------------------------------------------------| |---------|
100 * | 21 | 22 | | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 2A | 2B | 2C | 2D | 2E | 2F | 2G | | 2H | 2I |
101 * |---------| |-----------------------------------------------------------------------| `---------'
102 * | 31 | 32 | | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 3A | 3B | 3C | 3D | 3E | 3F |
103 * |---------| |-----------------------------------------------------------------------| ,----.
104 * | 41 | 42 | | 43 | 45 | 46 | 47 | 48 | 49 | 4A | 4B | 4C | 4D | 4E | 4F | | 4H |
105 * |---------| |-------------------------------------------------------------------------------------.
106 * | 51 | 52 | | 53 | 54 | 55 | 59 | 5D | 5E | 5F | | 5G | 5H | 5I |
107 * `---------' `--------------------------------------------------------------------' `--------------'
108 */
109 // The first section contains all of the arguements
110 // The second converts the arguments into a two-dimensional array
111 #define KEYMAP( \
112 k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, k1F, k1G, k1H, k1I, \
113 k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E, k2F, k2G, k2H, k2I, \
114 k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, k3E, k3F, \
115 k41, k42, k43, k45, k46, k47, k48, k49, k4A, k4B, k4C, k4D, k4E, k4F, k4H, \
116 k51, k52, k53, k54, k55, k59, k5D, k5E, k5F, k5G, k5H, k5I \
117 ) { \
118 {k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, k1F, k1G, k1H, k1I}, \
119 {k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E, k2F, k2G, k2H, k2I}, \
120 {k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, k3E, k3F, KC_NO, KC_NO, KC_NO}, \
121 {k41, k42, k43, KC_NO, k45, k46, k47, k48, k49, k4A, k4B, k4C, k4D, k4E, k4F, KC_NO, k4H, KC_NO}, \
122 {k51, k52, k53, k54, k55, KC_NO, KC_NO, KC_NO, k59, KC_NO, KC_NO, KC_NO, k5D, k5E, k5F, k5G, k5H, k5I} \
123 }
124
125 #define SPLIT_SHIFT_KEYMAP( \
126 k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, k1F, k1G, k1H, k1I, \
127 k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E, k2F, k2G, k2H, k2I, \
128 k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, k3E, k3F, \
129 k41, k42, k43, k45, k46, k47, k48, k49, k4A, k4B, k4C, k4D, k4E, k4F, k4G, k4H, \
130 k51, k52, k53, k54, k55, k59, k5D, k5E, k5F, k5G, k5H, k5I \
131 ) { \
132 {k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, k1F, k1G, k1H, k1I}, \
133 {k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E, k2F, k2G, k2H, k2I}, \
134 {k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, k3E, k3F, KC_NO, KC_NO, KC_NO}, \
135 {k41, k42, k43, KC_NO, k45, k46, k47, k48, k49, k4A, k4B, k4C, k4D, k4E, k4F, k4G, k4H, KC_NO}, \
136 {k51, k52, k53, k54, k55, KC_NO, KC_NO, KC_NO, k59, KC_NO, KC_NO, KC_NO, k5D, k5E, k5F, k5G, k5H, k5I} \
137 }
138
139 #define ISO_KEYMAP( \
140 k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, k1F, k1G, k1H, k1I, \
141 k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E, k2F, k2G, k2H, k2I, \
142 k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, k3E, k3F, \
143 k41, k42, k43, k44, k45, k46, k47, k48, k49, k4A, k4B, k4C, k4D, k4E, k4F, k4H, \
144 k51, k52, k53, k54, k55, k59, k5D, k5E, k5F, k5G, k5H, k5I \
145 ) { \
146 {k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, k1F, k1G, k1H, k1I}, \
147 {k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E, k2F, k2G, k2H, k2I}, \
148 {k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, k3E, k3F, KC_NO, KC_NO, KC_NO}, \
149 {k41, k42, k43, k44, k45, k46, k47, k48, k49, k4A, k4B, k4C, k4D, k4E, k4F, KC_NO, k4H, KC_NO}, \
150 {k51, k52, k53, k54, k55, KC_NO, KC_NO, KC_NO, k59, KC_NO, KC_NO, KC_NO, k5D, k5E, k5F, k5G, k5H, k5I} \
151 }
152
153#endif //LFK_REV_B
154
155#endif //LFK78_H
diff --git a/keyboards/lfkeyboards/lfk78/readme.md b/keyboards/lfkeyboards/lfk78/readme.md
new file mode 100644
index 000000000..e05390f9c
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk78/readme.md
@@ -0,0 +1,14 @@
1LFK78/68
2===
3
4A 65% keyboard similar to the MagicForce68 or VA68M. Optional fuction key block on left side.
5
6Keyboard Maintainer: [LFKeyboards](https://github.com/lfkeyboards)
7Hardware Supported: LFK78/68 RevB - RevJ, SMK78/68
8Hardware Availability: [LFKeyboards.com](https://www.lfkeyboards.com/)
9
10Make example for this keyboard (after setting up your build environment):
11
12 make lfkeyboards/lfk78:default
13
14See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information. \ No newline at end of file
diff --git a/keyboards/lfkeyboards/lfk78/rules.mk b/keyboards/lfkeyboards/lfk78/rules.mk
new file mode 100644
index 000000000..091cd7755
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk78/rules.mk
@@ -0,0 +1,34 @@
1# Set the LFK78 hardware version.
2#
3# B - first public release, uses atmega32u4, has audio, ISSI matrix split between RGB and backlight
4# C-H - at90usb1286, no audio, ISSI device 0 is backlight, 4 is RGB
5# J - at90usb646, C6 audio, ISSI device 0 is backlight, 4 is RGB
6LFK_REV = J
7
8ifeq ($(LFK_REV), B)
9 MCU = atmega32u4
10 OPT_DEFS += -DBOOTLOADER_SIZE=4096
11else ifeq ($(LFK_REV), J)
12 MCU = at90usb646
13 OPT_DEFS += -DBOOTLOADER_SIZE=4096
14else
15 MCU = at90usb1286
16 OPT_DEFS += -DBOOTLOADER_SIZE=8192
17endif
18OPT_DEFS += -DLFK_REV_$(LFK_REV)
19OPT_DEFS += -DLFK_REV_STRING=\"Rev$(LFK_REV)\"
20
21# Extra source files for IS3731 lighting
22SRC = TWIlib.c issi.c lighting.c
23
24# Processor frequency.
25F_CPU = 16000000
26
27# Target architecture (see library "Board Types" documentation).
28ARCH = AVR8
29
30# Input clock frequency.
31F_USB = $(F_CPU)
32
33# Interrupt driven control endpoint task(+60)
34OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
diff --git a/keyboards/lfkeyboards/lfk87/config.h b/keyboards/lfkeyboards/lfk87/config.h
new file mode 100644
index 000000000..84357450b
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk87/config.h
@@ -0,0 +1,173 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#ifndef CONFIG_H
19#define CONFIG_H
20
21#include "config_common.h"
22
23#define VENDOR_ID 0xFEED
24#define PRODUCT_ID 0x6060
25#define DEVICE_VER 0x0001
26#define MANUFACTURER LFKeyboards
27#define PRODUCT LFK87
28#define DESCRIPTION QMK keyboard firmware for LFK87
29
30#define DIODE_DIRECTION COL2ROW
31
32
33#ifdef LFK_TKL_REV_A
34/* RevB Matrix config */
35 #define MATRIX_ROWS 6
36 #define MATRIX_COLS 17
37 #define MATRIX_ROW_PINS {D2, D3, D4, D5, D6, D7 }
38 #define MATRIX_COL_PINS {A0, A1, A2, A3, A4, A5, A6, A7, E6, E7,\
39 F0, F1, F2, F3, C0, C1, C2 }
40 #define UNUSED_PINS {B0, B1, B2, B3, B4, B4, B5, B6, B7, C4, C5, C6, C7,\
41 D0, D1, E0, E1, E2, E3, E4, F4, F5, F6, F7}
42 #define RGBLED_NUM 25 // Number of LEDs
43#else
44/* RevC/D Matrix config */
45 #define MATRIX_ROWS 7
46 #define MATRIX_COLS 16
47 #define MATRIX_ROW_PINS {F2, D7, D6, D5, D4, D3, F3}
48 #define MATRIX_COL_PINS {A0, A1, A2, A3, A4, A5, A6, A7, C7, C1, C0, E1, E0, C2, C3, C4}
49 #define UNUSED_PINS {B0, B1, B2, B3, B4, B4, B5, B6, B7, C5, C6, D2, E3, E4, E5, E6, E7, \
50 F0, F1, F4, F5, F6, F7}
51 #define RGBLED_NUM 24 // Number of LEDs
52#endif
53
54#define AUDIO_VOICES
55#define C6_AUDIO
56
57#define BACKLIGHT_LEVELS 10
58#define BACKLIGHT_PWM_MAP {2, 4, 8, 16, 40, 55, 70, 128, 200, 255}
59
60#define RGB_DI_PIN F4 // Have to set it to something to get the ws2812 code to compile
61#define RGBLIGHT_ANIMATIONS
62#define RGBLIGHT_HUE_STEP 10
63#define RGBLIGHT_SAT_STEP 17
64#define RGBLIGHT_VAL_STEP 17
65
66#define TAPPING_TERM 200
67
68/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
69#define DEBOUNCING_DELAY 5
70
71/* define if matrix has ghost (lacks anti-ghosting diodes) */
72//#define MATRIX_HAS_GHOST
73
74/* number of backlight levels */
75
76/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
77#define LOCKING_SUPPORT_ENABLE
78/* Locking resynchronize hack */
79#define LOCKING_RESYNC_ENABLE
80
81/*
82 * Force NKRO
83 *
84 * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
85 * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
86 * makefile for this to work.)
87 *
88 * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
89 * until the next keyboard reset.
90 *
91 * NKRO may prevent your keystrokes from being detected in the BIOS, but it is
92 * fully operational during normal computer usage.
93 *
94 * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
95 * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
96 * bootmagic, NKRO mode will always be enabled until it is toggled again during a
97 * power-up.
98 *
99 */
100//#define FORCE_NKRO
101
102/*
103 * Magic Key Options
104 *
105 * Magic keys are hotkey commands that allow control over firmware functions of
106 * the keyboard. They are best used in combination with the HID Listen program,
107 * found here: https://www.pjrc.com/teensy/hid_listen.html
108 *
109 * The options below allow the magic key functionality to be changed. This is
110 * useful if your keyboard/keypad is missing keys and you want magic key support.
111 *
112 */
113
114/* key combination for magic key command */
115#define IS_COMMAND() ( \
116 keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
117)
118
119/* control how magic key switches layers */
120//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
121//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
122//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
123
124/* override magic key keymap */
125//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
126//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
127//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
128//#define MAGIC_KEY_HELP1 H
129//#define MAGIC_KEY_HELP2 SLASH
130//#define MAGIC_KEY_DEBUG D
131//#define MAGIC_KEY_DEBUG_MATRIX X
132//#define MAGIC_KEY_DEBUG_KBD K
133//#define MAGIC_KEY_DEBUG_MOUSE M
134//#define MAGIC_KEY_VERSION V
135//#define MAGIC_KEY_STATUS S
136//#define MAGIC_KEY_CONSOLE C
137//#define MAGIC_KEY_LAYER0_ALT1 ESC
138//#define MAGIC_KEY_LAYER0_ALT2 GRAVE
139//#define MAGIC_KEY_LAYER0 0
140//#define MAGIC_KEY_LAYER1 1
141//#define MAGIC_KEY_LAYER2 2
142//#define MAGIC_KEY_LAYER3 3
143//#define MAGIC_KEY_LAYER4 4
144//#define MAGIC_KEY_LAYER5 5
145//#define MAGIC_KEY_LAYER6 6
146//#define MAGIC_KEY_LAYER7 7
147//#define MAGIC_KEY_LAYER8 8
148//#define MAGIC_KEY_LAYER9 9
149//#define MAGIC_KEY_BOOTLOADER PAUSE
150//#define MAGIC_KEY_LOCK CAPS
151//#define MAGIC_KEY_EEPROM E
152//#define MAGIC_KEY_NKRO N
153//#define MAGIC_KEY_SLEEP_LED Z
154
155/*
156 * Feature disable options
157 * These options are also useful to firmware size reduction.
158 */
159
160/* disable debug print */
161//#define NO_DEBUG
162
163/* disable print */
164//#define NO_PRINT
165
166/* disable action features */
167//#define NO_ACTION_LAYER
168//#define NO_ACTION_TAPPING
169//#define NO_ACTION_ONESHOT
170//#define NO_ACTION_MACRO
171//#define NO_ACTION_FUNCTION
172
173#endif
diff --git a/keyboards/lfkeyboards/lfk87/keymaps/default/config.h b/keyboards/lfkeyboards/lfk87/keymaps/default/config.h
new file mode 100644
index 000000000..8893d122e
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk87/keymaps/default/config.h
@@ -0,0 +1,8 @@
1#ifndef CONFIG_USER_H
2#define CONFIG_USER_H
3
4#include "../../config.h"
5
6// place overrides here
7
8#endif
diff --git a/keyboards/lfkeyboards/lfk87/keymaps/default/keymap.c b/keyboards/lfkeyboards/lfk87/keymaps/default/keymap.c
new file mode 100644
index 000000000..79affb51c
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk87/keymaps/default/keymap.c
@@ -0,0 +1,133 @@
1#include "lfk87.h"
2#include "issi.h"
3#include "lighting.h"
4#include "action_layer.h"
5
6//Define a shorter 'transparent' key code to make the keymaps more compact
7#define KC_TR KC_TRNS
8
9enum keymap_layout {
10 VANILLA = 0, // matches MF68 layout
11 FUNC, // 0x08
12 SETTINGS, // 0x10
13};
14
15// Colors of the layer indicator LED
16// This list needs to define layer 0xFFFFFFFF, it is the end of the list, and the unknown layer
17const Layer_Info layer_info[] = {
18 // Layer Mask Red Green Blue
19 {0x00000000, 0xFFFFFFFF, {0x00, 0xFF, 0x00}}, // base layers - green
20 {0x00000002, 0xFFFFFFFE, {0x00, 0x00, 0xFF}}, // function layer - blue
21 {0x00000004, 0xFFFFFFFC, {0xFF, 0x00, 0xFF}}, // settings layer - magenta
22 {0xFFFFFFFF, 0xFFFFFFFF, {0xFF, 0xFF, 0xFF}}, // unknown layer - REQUIRED - white
23};
24
25
26const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
27[VANILLA] = KEYMAP(
28 /* Keymap VANILLA: (Base Layer) Default Layer
29 * ,-----------------------------------------------------------------------------.
30 * |Esc |f1| f2| f3| f4| | f5| f6| f7| f8| | f9|f10|f11|f12| |Prnt|ScLk|Paus|
31 * |-----------------------------------------------------------| |--------------|
32 * | ~ | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0| - | = |Backsp | | Ins|Home|PgUp|
33 * |-----------------------------------------------------------| |--------------|
34 * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | Del| End|PgDn|
35 * |-----------------------------------------------------------| `--------------'
36 * |CAPS | A| S| D| F| G| H| J| K| L| ;| '|Return |
37 * |-----------------------------------------------------------| ,----.
38 * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift | | Up |
39 * |-----------------------------------------------------------| ,-------------.
40 * |Ctrl|Gui |Alt | Space |ALT |GUI |Func|CTRL | |Lft| Dn |Rig |
41 * `-----------------------------------------------------------' `-------------'
42 */
43 KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SLCK, KC_PAUS, \
44 KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP, \
45 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DELETE, KC_END, KC_PGDN, \
46 KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \
47 KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, \
48 KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, MO(FUNC), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
49 /* Keymap FUNCTION: Function Layer
50 * ,-------------------------------------------------------------. ,--------------.
51 * |Esc |f1| f2| f3| f4| | f5| f6| f7| f8| | f9|f10|f11|f12 | |Prnt|ScLk|Paus|
52 * |-------------------------------------------------------------| |--------------|
53 * | ` |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12|Delete | | | | |
54 * |-------------------------------------------------------------| |--------------|
55 * |Tab | |PgU| | | | | | Up| | | | | | | | | |
56 * |-------------------------------------------------------------| `--------------'
57 * |Control|Hme|PgD|End| | | |Lft|Dwn|Rgt| | | |
58 * |-------------------------------------------------------------| ,----.
59 * |Shift | |Del| | | | |Mute|V- |V+ | |TG(SETTINGS)| | Up |
60 * |-------------------------------------------------------------' ,-------------.
61 * |Func|Win |Alt | PgD |Alt |Ctrl |Func | |Lft| Dn |Rig |
62 * `------------------------------------------------------' `-------------'
63 */
64[FUNC] = KEYMAP(
65 KC_ESC, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_PSCR, KC_SLCK, KC_PAUS, \
66 KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_DEL, KC_TR, KC_TR, KC_TR, \
67 KC_NO,KC_NO, KC_PGUP, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_UP, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TR, KC_TR, KC_TR, \
68 KC_TR, KC_HOME, KC_PGDN, KC_END, KC_NO, KC_NO, KC_NO, KC_LEFT, KC_DOWN, KC_RGHT, KC_NO, KC_NO, KC_NO, \
69 KC_TR, KC_NO, KC_DEL, KC_NO, KC_NO, KC_NO, KC_NO, KC_MUTE, KC_VOLD, KC_VOLU, KC_NO, TG(SETTINGS), KC_TR, \
70 KC_TR, KC_TR, KC_TR, KC_PGDN, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR),
71
72 /* Keymap SETTINGS: Settings Layer
73 * ,-----------------------------------------------------------. ,-------------.
74 * |Esc |f1| f2| f3| f4| | f5| f6| f7| f8| | f9|f10|f11|f12 | |Prnt|ScLk|Paus|
75 * |-------------------------------------------------------------| |--------------|
76 * |FN0 | | | | | | | | | | |BL-|BL+|BL Togl| |RGB Tog |Val+|
77 * |-----------------------------------------------------------| |-------------|
78 * |MuMode| | | | | | | | | | | | |LEDTst| |RGB Mode|Val-|
79 * |-----------------------------------------------------------| `-------------'
80 * |AudTgl |Hz+|MS+| | | | | | | | | | RST |
81 * |-----------------------------------------------------------| ,----.
82 * |ClickTgl|Hz-|MS-| | | | | | | | |Layer Clr | |Hue+|
83 * |--------------------------------------------------------------------------.
84 * | | | | | | | | | |Sat-|Hue-|Sat+|
85 * `----------------------------------------------------------------------------'
86 */
87[SETTINGS] = KEYMAP(
88 KC_FN0, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, BL_DEC, KC_NO, KC_NO, KC_NO,
89 KC_FN0,KC_NO,KC_NO,KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, BL_DEC, BL_INC, BL_TOGG, RGB_TOG, RGB_VAI, KC_NO,
90 MU_MOD, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_FN2, RGB_MOD, RGB_VAD, KC_NO,
91 AU_TOG, KC_F1,KC_FN3, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, RESET,
92 KC_FN5, KC_FN2,KC_FN4, KC_NO, KC_NO, KC_NO, KC_NO, MU_TOG, KC_NO, KC_NO, KC_NO, KC_NO, RGB_HUI,
93 KC_NO, KC_NO, KC_NO, KC_FN12, KC_NO, KC_NO, KC_NO, KC_TR, RGB_SAD, RGB_HUD, RGB_SAI),
94};
95
96const uint16_t PROGMEM fn_actions[] = {
97 ACTION_FUNCTION(LFK_CLEAR), // FN0 - reset layers
98 ACTION_FUNCTION(LFK_CLICK_FREQ_HIGHER), // FN1 - Increase Freq of audio click
99 ACTION_FUNCTION(LFK_CLICK_FREQ_LOWER), // FN2 - Decrease Freq of audio click
100 ACTION_FUNCTION(LFK_CLICK_TIME_LONGER), // FN3 - Increase length of audio click
101 ACTION_FUNCTION(LFK_CLICK_TIME_SHORTER), // FN4 - Decrease length of audio click
102 ACTION_FUNCTION(LFK_CLICK_TOGGLE), // FN5 - Toggle audio click
103 };
104
105
106const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
107{
108 // MACRODOWN only works in this function
109 switch(id) {
110 }
111 return MACRO_NONE;
112};
113
114
115void matrix_init_user(void) {
116 // This keymap only has a single base layer, so reset the default if needed
117 if(eeconfig_read_default_layer() > 1){
118 eeconfig_update_default_layer(1);
119 default_layer_set(1);
120 }
121}
122
123void matrix_scan_user(void) {
124
125}
126
127bool process_record_user(uint16_t keycode, keyrecord_t *record) {
128 return true;
129}
130
131void led_set_user(uint8_t usb_led) {
132
133}
diff --git a/keyboards/lfkeyboards/lfk87/keymaps/default/rules.mk b/keyboards/lfkeyboards/lfk87/keymaps/default/rules.mk
new file mode 100644
index 000000000..c1f1070fd
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk87/keymaps/default/rules.mk
@@ -0,0 +1,54 @@
1# Build Options
2# change to "no" to disable the options, or define them in the Makefile in
3# the appropriate keymap folder that will get included automatically
4#
5
6BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
7MOUSEKEY_ENABLE = no # Mouse keys(+4700)
8EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
9CONSOLE_ENABLE = no # Console for debug(+400)
10COMMAND_ENABLE = no # Commands for debug and configuration
11NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
12BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
13MIDI_ENABLE = no # MIDI controls
14AUDIO_ENABLE = yes # Audio output on port C6
15UNICODE_ENABLE = no # Unicode
16BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
17RGBLIGHT_ENABLE = yes # Enable RGB underlight
18RGBLIGHT_CUSTOM_DRIVER = yes # RGB code is implemented in lefkeyboards, not WS2812
19SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
20TAP_DANCE_ENABLE = no
21
22ISSI_ENABLE = yes # If the I2C pullup resistors aren't install this must be disabled
23WATCHDOG_ENABLE = no # Resets keyboard if matrix_scan isn't run every 250ms
24
25
26ifndef QUANTUM_DIR
27 include ../../../../Makefile
28endif
29
30ifeq ($(strip $(ISSI_ENABLE)), yes)
31 TMK_COMMON_DEFS += -DISSI_ENABLE
32endif
33
34ifeq ($(strip $(WATCHDOG_ENABLE)), yes)
35 TMK_COMMON_DEFS += -DWATCHDOG_ENABLE
36endif
37
38
39# Override the LFK87 hardware version.
40#
41# A - Green PCB. at90usb1286 Only 3 exist
42# B - We don't talk about RevB
43# C-D - Black PCB. at90usb646 First public release
44#
45# LFK_REV = C
46
47# ifeq ($(LFK_REV), A)
48# MCU = at90usb1286
49# OPT_DEFS += -DBOOTLOADER_SIZE=8192
50# else
51# MCU = at90usb646
52# OPT_DEFS += -DBOOTLOADER_SIZE=4096
53# endif
54# OPT_DEFS += -DLFK_TKL_REV_$(LFK_REV)
diff --git a/keyboards/lfkeyboards/lfk87/keymaps/iso/config.h b/keyboards/lfkeyboards/lfk87/keymaps/iso/config.h
new file mode 100644
index 000000000..8893d122e
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk87/keymaps/iso/config.h
@@ -0,0 +1,8 @@
1#ifndef CONFIG_USER_H
2#define CONFIG_USER_H
3
4#include "../../config.h"
5
6// place overrides here
7
8#endif
diff --git a/keyboards/lfkeyboards/lfk87/keymaps/iso/keymap.c b/keyboards/lfkeyboards/lfk87/keymaps/iso/keymap.c
new file mode 100644
index 000000000..10248e08c
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk87/keymaps/iso/keymap.c
@@ -0,0 +1,137 @@
1#include "lfk87.h"
2#include "issi.h"
3#include "lighting.h"
4#include "action_layer.h"
5
6//Define a shorter 'transparent' key code to make the keymaps more compact
7#define KC_TR KC_TRNS
8
9enum keymap_layout {
10 VANILLA = 0,
11 FUNC, // 0x02
12 SETTINGS, // 0x04
13};
14
15// Colors of the layer indicator LED
16// This list needs to define layer 0xFFFFFFFF, it is the end of the list, and the unknown layer
17const Layer_Info layer_info[] = {
18 // Layer Mask Red Green Blue
19 {0x00000000, 0xFFFFFFFF, {0x00, 0x00, 0x00}}, // base layer - off
20 {0x00000002, 0xFFFFFFFE, {0x00, 0x00, 0x7F}}, // function layer - blue
21 {0x00000004, 0xFFFFFFFC, {0x7F, 0x00, 0x00}}, // settings layer - red
22 {0xFFFFFFFF, 0xFFFFFFFF, {0x0F, 0x0F, 0x0F}}, // unknown layer - REQUIRED - white
23};
24
25
26const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
27[VANILLA] = ISO_KEYMAP(
28 /* Keymap VANILLA: (Base Layer) Default Layer
29 * ,-----------------------------------------------------------------------------.
30 * |Esc |f1| f2| f3| f4| | f5| f6| f7| f8| | f9|f10|f11|f12| |Prnt|ScLk|Paus|
31 * |-----------------------------------------------------------| |--------------|
32 * | ~ | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0| - | = |Backsp | | Ins|Home|PgUp|
33 * |-----------------------------------------------------------| |--------------|
34 * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| Ret| | Del| End|PgDn|
35 * |--------------------------------------------------------. | `--------------'
36 * |CAPS | A| S| D| F| G| H| J| K| L| ;| '| # | |
37 * |-----------------------------------------------------------| ,----.
38 * |Shft| \ | Z| X| C| V| B| N| M| ,| .| /|Shift | | Up |
39 * |-----------------------------------------------------------| ,-------------.
40 * |Ctrl|Gui |Alt | Space |ALT |GUI | Func|CTRL| |Lft| Dn |Rig |
41 * `-----------------------------------------------------------' `-------------'
42 */
43 KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_LSCR, KC_PAUS, \
44 KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP, \
45 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_ENT, KC_DELETE, KC_END, KC_PGDN, \
46 KC_LCAP, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, \
47 KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, \
48 KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, MO(FUNC), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
49 /* Keymap FUNCTION: Function Layer
50 * ,-------------------------------------------------------------. ,--------------.
51 * | |f1| f2| f3| f4| | f5| f6| f7| f8| | f9|f10|f11|f12 | |Prnt|ScLk|Paus|
52 * |-------------------------------------------------------------| |--------------|
53 * | |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12|Delete | | | | |
54 * |-------------------------------------------------------------| |--------------|
55 * |Tab | |PgU| | | | | | Up| | | | | | | | | | |
56 * |---------------------------------------------------------. | `--------------'
57 * |Control|Hme|PgD|End| | | |Lft|Dwn|Rgt| | | | |
58 * |-------------------------------------------------------------| ,----.
59 * |Shift| | |Del| | | | |Mute|V- |V+ | |TG(SETTINGS)| | Up |
60 * |-------------------------------------------------------------' ,-------------.
61 * |Func|Win |Alt | PgD |ALT |GUI | Func|CTRL| |Lft| Dn |Rig |
62 * `-------------------------------------------------------------' `-------------'
63 */
64[FUNC] = ISO_KEYMAP(
65 KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_PSCR, KC_SLCK, KC_PAUS, \
66 KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_DEL, KC_TR, KC_TR, KC_TR, \
67 KC_NO,KC_NO, KC_PGUP, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_UP, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TR, KC_TR, KC_TR, \
68 KC_TR, KC_HOME, KC_PGDN, KC_END, KC_NO, KC_NO, KC_NO, KC_LEFT, KC_DOWN, KC_RGHT, KC_NO, KC_NO, KC_NO, \
69 KC_TR,KC_NO, KC_NO, KC_DEL, KC_NO, KC_NO, KC_NO, KC_NO, KC_MUTE, KC_VOLD, KC_VOLU, KC_NO, TG(SETTINGS), KC_TR, \
70 KC_TR, KC_TR, KC_TR, KC_PGDN, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR),
71
72 /* Keymap SETTINGS: Settings Layer
73 * ,-----------------------------------------------------------. ,-------------.
74 * |Esc |f1| f2| f3| f4| | f5| f6| f7| f8| | f9|f10|f11|f12 | |Prnt|ScLk|Paus|
75 * |-------------------------------------------------------------| |--------------|
76 * |FN3 |BL0|BL1|BL2|BL3| | | | | | |BL-|BL+|BL Togl| |RGB Tog |Val+|
77 * |-----------------------------------------------------------| |-------------|
78 * |Debug| | | | | | | | | | | | | RST | |RGB Mode|Val-|
79 * |--------------------------------------------------------. | `-------------'
80 * |LayrClr|Hz+|MS+| | | | | | | | | | | |
81 * |-----------------------------------------------------------| ,----.
82 * |ClickTgl|Hz-|MS-| | | | | | | | |Layer Clr | |Hue+|
83 * |------------------------------------------------------------------------.
84 * | | | | | | | | |Sat-|Hue-|Sat+|
85 * `------------------------------------------------------' `--------------'
86 */
87[SETTINGS] = ISO_KEYMAP(
88 KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, BL_DEC, KC_NO, KC_NO, KC_NO,
89 KC_FN0,KC_FN3,KC_FN4,KC_FN5, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, BL_DEC, BL_INC, BL_TOGG, RGB_TOG, RGB_VAI, KC_NO,
90 MU_MOD, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, RESET, RGB_MOD, RGB_VAD, KC_NO,
91 AU_TOG, KC_FN3,KC_FN5, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
92 KC_FN7, KC_NO, KC_FN4, KC_FN6, KC_NO, KC_NO, KC_NO, KC_NO, MU_TOG, KC_NO, KC_NO, KC_NO, KC_FN0, RGB_HUI,
93 KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_FN0, RGB_SAD, RGB_HUD, RGB_SAI),
94};
95
96const uint16_t PROGMEM fn_actions[] = {
97 ACTION_FUNCTION(LFK_CLEAR), // FN0 - reset layers
98 ACTION_FUNCTION(LFK_ESC_TILDE), // FN1 - esc+shift = ~, else escape
99 ACTION_FUNCTION(LFK_LED_TEST), // FN2 - cycle through LEDs for testing
100 ACTION_FUNCTION(LFK_CLICK_FREQ_HIGHER), // FN3 - Increase Freq of audio click
101 ACTION_FUNCTION(LFK_CLICK_FREQ_LOWER), // FN4 - Decrease Freq of audio click
102 ACTION_FUNCTION(LFK_CLICK_TIME_LONGER), // FN5 - Increase length of audio click
103 ACTION_FUNCTION(LFK_CLICK_TIME_SHORTER), // FN6 - Decrease length of audio click
104 ACTION_FUNCTION(LFK_CLICK_TOGGLE), // FN7 - Toggle audio click
105 ACTION_FUNCTION(LFK_LED_TEST), // FN8 - cycle through LEDs for testing
106 ACTION_FUNCTION(LFK_DEBUG_SETTINGS), // FN9 - prints LED and click settings to HID
107 };
108
109
110const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
111{
112 // MACRODOWN only works in this function
113 switch(id) {
114 }
115 return MACRO_NONE;
116};
117
118
119void matrix_init_user(void) {
120 // This keymap only has a single base layer, so reset the default if needed
121 if(eeconfig_read_default_layer() > 1){
122 eeconfig_update_default_layer(1);
123 default_layer_set(1);
124 }
125}
126
127void matrix_scan_user(void) {
128
129}
130
131bool process_record_user(uint16_t keycode, keyrecord_t *record) {
132 return true;
133}
134
135void led_set_user(uint8_t usb_led) {
136
137}
diff --git a/keyboards/lfkeyboards/lfk87/keymaps/iso/rules.mk b/keyboards/lfkeyboards/lfk87/keymaps/iso/rules.mk
new file mode 100644
index 000000000..68e200a5d
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk87/keymaps/iso/rules.mk
@@ -0,0 +1,53 @@
1# Build Options
2# change to "no" to disable the options, or define them in the Makefile in
3# the appropriate keymap folder that will get included automatically
4#
5
6BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
7MOUSEKEY_ENABLE = no # Mouse keys(+4700)
8EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
9CONSOLE_ENABLE = no # Console for debug(+400)
10COMMAND_ENABLE = no # Commands for debug and configuration
11NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
12BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
13MIDI_ENABLE = no # MIDI controls
14AUDIO_ENABLE = yes # Audio output on port C6
15UNICODE_ENABLE = no # Unicode
16BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
17RGBLIGHT_ENABLE = yes # Enable RGB underlight
18RGBLIGHT_CUSTOM_DRIVER = yes # RGB code is implemented in lefkeyboards, not WS2812
19SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
20TAP_DANCE_ENABLE = no
21
22ISSI_ENABLE = yes # If the I2C pullup resistors aren't install this must be disabled
23WATCHDOG_ENABLE = no # Resets keyboard if matrix_scan isn't run every 250ms
24
25
26ifndef QUANTUM_DIR
27 include ../../../../Makefile
28endif
29
30ifeq ($(strip $(ISSI_ENABLE)), yes)
31 TMK_COMMON_DEFS += -DISSI_ENABLE
32endif
33
34ifeq ($(strip $(WATCHDOG_ENABLE)), yes)
35 TMK_COMMON_DEFS += -DWATCHDOG_ENABLE
36endif
37
38
39# # Set the LFK78 hardware version. This is defined in rules.mk, but can be overidden here if desired
40# #
41# # RevB - first public release, uses atmega32u4, has audio, ISSI matrix split between RGB and backlight
42# # RevC/D - at90usb1286, no audio, ISSI device 0 is backlight, 4 is RGB
43# #
44# # Set to B, C or D
45# LFK_REV = D
46
47# ifeq ($(LFK_REV), B)
48# MCU = atmega32u4
49# else
50# MCU = at90usb1286
51# endif
52# OPT_DEFS += -DLFK_REV_$(LFK_REV)
53# OPT_DEFS += -DUSB_PRODUCT=\"LFK_Rev$(LFK_REV)\"
diff --git a/keyboards/lfkeyboards/lfk87/lfk87.c b/keyboards/lfkeyboards/lfk87/lfk87.c
new file mode 100644
index 000000000..831d9d281
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk87/lfk87.c
@@ -0,0 +1,215 @@
1
2#include <avr/sfr_defs.h>
3#include <avr/timer_avr.h>
4#include <avr/wdt.h>
5#include "lfk87.h"
6#include "keymap.h"
7#include "issi.h"
8#include "TWIlib.h"
9#include "lighting.h"
10#include "debug.h"
11#include "quantum.h"
12
13uint16_t click_hz = CLICK_HZ;
14uint16_t click_time = CLICK_MS;
15uint8_t click_toggle = CLICK_ENABLED;
16
17void matrix_init_kb(void)
18{
19 // put your keyboard start-up code here
20 // runs once when the firmware starts up
21 matrix_init_user();
22 set_rgb(31, 0x00, 0x00, 0x00); // Caps lock
23 set_rgb(32, 0xFF, 0x00, 0x00); // Layer indicator, start red
24#ifndef AUDIO_ENABLE
25 // If we're not using the audio pin, drive it low
26 sbi(DDRC, 6);
27 cbi(PORTC, 6);
28#endif
29#ifdef ISSI_ENABLE
30 issi_init();
31#endif
32#ifdef WATCHDOG_ENABLE
33 // This is done after turning the layer LED red, if we're caught in a loop
34 // we should get a flashing red light
35 wdt_enable(WDTO_500MS);
36#endif
37}
38
39void matrix_scan_kb(void)
40{
41#ifdef WATCHDOG_ENABLE
42 wdt_reset();
43#endif
44#ifdef ISSI_ENABLE
45 // switch/underglow lighting update
46 static uint32_t issi_device = 0;
47 static uint32_t twi_last_ready = 0;
48 if(twi_last_ready > 1000){
49 // Its been way too long since the last ISSI update, reset the I2C bus and start again
50 twi_last_ready = 0;
51 TWIInit();
52 force_issi_refresh();
53 }
54 if(isTWIReady()){
55 twi_last_ready = 0;
56 // If the i2c bus is available, kick off the issi update, alternate between devices
57 update_issi(issi_device, issi_device);
58 if(issi_device){
59 issi_device = 0;
60 }else{
61 issi_device = 3;
62 }
63 }else{
64 twi_last_ready++;
65 }
66#endif
67 // Update layer indicator LED
68 //
69 // Not sure how else to reliably do this... TMK has the 'hook_layer_change'
70 // but can't find QMK equiv
71 static uint32_t layer_indicator = -1;
72 if(layer_indicator != layer_state){
73 for(uint32_t i=0;; i++){
74 // the layer_info list should end with layer 0xFFFF
75 // it will break this out of the loop and define the unknown layer color
76 if((layer_info[i].layer == (layer_state & layer_info[i].mask)) || (layer_info[i].layer == 0xFFFFFFFF)){
77 set_rgb(32, layer_info[i].color.red, layer_info[i].color.green, layer_info[i].color.blue);
78 layer_indicator = layer_state;
79 break;
80 }
81 }
82 }
83 matrix_scan_user();
84}
85
86void click(uint16_t freq, uint16_t duration){
87#ifdef AUDIO_ENABLE
88 if(freq >= 100 && freq <= 20000 && duration < 100){
89 play_note(freq, 10);
90 for (uint16_t i = 0; i < duration; i++){
91 _delay_ms(1);
92 }
93 stop_all_notes();
94 }
95#endif
96}
97
98bool process_record_kb(uint16_t keycode, keyrecord_t* record)
99{
100 if (click_toggle && record->event.pressed){
101 click(click_hz, click_time);
102 }
103 if (keycode == RESET) {
104 reset_keyboard_kb();
105 } else {
106 }
107 return process_record_user(keycode, record);
108}
109
110void action_function(keyrecord_t *event, uint8_t id, uint8_t opt)
111{
112#ifdef AUDIO_ENABLE
113 int8_t sign = 1;
114#endif
115 if(id == LFK_ESC_TILDE){
116 // Send ~ on shift-esc
117 void (*method)(uint8_t) = (event->event.pressed) ? &add_key : &del_key;
118 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT));
119 method(shifted ? KC_GRAVE : KC_ESCAPE);
120 send_keyboard_report();
121 }else if(event->event.pressed){
122 switch(id){
123 case LFK_SET_DEFAULT_LAYER:
124 // set/save the current base layer to eeprom, falls through to LFK_CLEAR
125 eeconfig_update_default_layer(1UL << opt);
126 default_layer_set(1UL << opt);
127 case LFK_CLEAR:
128 // Go back to default layer
129 layer_clear();
130 break;
131#ifdef ISSI_ENABLE
132 case LFK_LED_TEST:
133 led_test();
134 break;
135#endif
136#ifdef AUDIO_ENABLE
137 case LFK_CLICK_FREQ_LOWER:
138 sign = -1; // continue to next statement
139 case LFK_CLICK_FREQ_HIGHER:
140 click_hz += sign * 100;
141 click(click_hz, click_time);
142 break;
143 case LFK_CLICK_TOGGLE:
144 if(click_toggle){
145 click_toggle = 0;
146 click(4000, 100);
147 click(1000, 100);
148 }else{
149 click_toggle = 1;
150 click(1000, 100);
151 click(4000, 100);
152 }
153 break;
154 case LFK_CLICK_TIME_SHORTER:
155 sign = -1; // continue to next statement
156 case LFK_CLICK_TIME_LONGER:
157 click_time += sign;
158 click(click_hz, click_time);
159 break;
160#endif
161 }
162 }
163}
164
165void reset_keyboard_kb(){
166#ifdef WATCHDOG_ENABLE
167 MCUSR = 0;
168 wdt_disable();
169 wdt_reset();
170#endif
171 set_rgb(31, 0x00, 0xFF, 0xFF);
172 set_rgb(32, 0x00, 0xFF, 0xFF);
173 force_issi_refresh();
174 reset_keyboard();
175}
176
177void led_set_kb(uint8_t usb_led)
178{
179 // Set capslock LED to Blue
180 if (usb_led & (1 << USB_LED_CAPS_LOCK)) {
181 set_rgb(31, 0x00, 0x00, 0x7F);
182 }else{
183 set_rgb(31, 0x00, 0x00, 0x00);
184 }
185 led_set_user(usb_led);
186}
187
188// Lighting info, see lighting.h for details
189const uint8_t switch_matrices[] = {0, 1};
190const uint8_t rgb_matrices[] = {6, 7};
191
192// RGB Map:
193// 27 29 10 9 8 7 6
194// 26 5
195// 25 4
196// 24 3
197// 23 22 21 20 14 15 11 1 2
198const uint8_t rgb_sequence[] = {
199 27, 29, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 11, 15, 14, 20, 21, 22, 23, 24, 25, 26
200};
201
202// Maps switch LEDs from Row/Col to ISSI matrix.
203// Value breakdown:
204// Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
205// | | ISSI Col | ISSI Row |
206// / |
207// Device
208const uint8_t switch_leds[MATRIX_ROWS][MATRIX_COLS] =
209KEYMAP(
210 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91,
211 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0xA9, 0xA8, 0xA7, 0xA6, 0xA5, 0xA4, 0xA3, 0xA2, 0xA1,
212 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0xB9, 0xB8, 0xB7, 0xB6, 0xB5, 0xB3,
213 0x49, 0x48, 0x47, 0x45, 0x44, 0x43, 0x42, 0x41, 0xC9, 0xC8, 0xC7, 0xC6, 0xC5, 0xC4, 0xC2,
214 0x59, 0x58, 0x57, 0x56, 0x55, 0x51, 0xD6, 0xE5, 0xE4, 0xE3, 0xE2, 0xE1,
215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
diff --git a/keyboards/lfkeyboards/lfk87/lfk87.h b/keyboards/lfkeyboards/lfk87/lfk87.h
new file mode 100644
index 000000000..cf16c8e2f
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk87/lfk87.h
@@ -0,0 +1,139 @@
1#ifndef LFK87_H
2#define LFK87_H
3
4/* if the kb.h file exists (because we're running from qmkbuilder) include it */
5#if __has_include("kb.h")
6#include "kb.h"
7#endif
8
9#include "quantum.h"
10#include "matrix.h"
11#include <avr/sfr_defs.h>
12
13#ifndef cbi
14#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
15#endif
16
17#ifndef sbi
18#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
19#endif
20
21
22typedef struct RGB_Color {
23 uint16_t red;
24 uint16_t green;
25 uint16_t blue;
26} RGB_Color;
27
28typedef struct Layer_Info {
29 uint32_t layer;
30 uint32_t mask;
31 RGB_Color color;
32} Layer_Info;
33
34extern const uint32_t layer_count;
35extern const Layer_Info layer_info[];
36
37enum action_functions {
38 LFK_CLEAR = 0, // Resets all layers
39 LFK_ESC_TILDE, // esc+lshift = ~
40 LFK_SET_DEFAULT_LAYER, // changes and saves current base layer to eeprom
41 LFK_CLICK_TOGGLE, // Adjusts click duration
42 LFK_CLICK_FREQ_HIGHER, // Adjusts click frequency
43 LFK_CLICK_FREQ_LOWER, // Adjusts click frequency
44 LFK_CLICK_TIME_LONGER, // Adjusts click duration
45 LFK_CLICK_TIME_SHORTER, // Adjusts click duration
46 LFK_DEBUG_SETTINGS, // prints LED and click settings to HID
47 LFK_LED_TEST, // cycles through switch and RGB LEDs
48 LFK_PLAY_ONEUP
49};
50
51#define CLICK_HZ 500
52#define CLICK_MS 2
53#define CLICK_ENABLED 0
54
55void reset_keyboard_kb(void);
56void click(uint16_t freq, uint16_t duration);
57
58#define k00 KC_NO
59#ifdef LFK_TKL_REV_A
60 #ifndef KEYMAP
61 #define KEYMAP( \
62 k11, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d, k1e, k1f, k1g, k1h, \
63 k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k2d, k2e, k2f, k2g, k2h, \
64 k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d, k3e, k3f, k3g, k3h, \
65 k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c, k4d, \
66 k51, k53, k54, k55, k56, k57, k58, k59, k5a, k5b, k5c, k5d, k5g, \
67 k61, k62, k63, k67, k6b, k6c, k6d, k6e, k6f, k6g, k6h \
68 ) \
69 { \
70 {k11, k00, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d, k1e, k1f, k1g, k1h}, \
71 {k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k2d, k2e, k2f, k2g, k2h}, \
72 {k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d, k3e, k3f, k3g, k3h}, \
73 {k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c, k4d, k00, k00, k00, k00}, \
74 {k51, k00, k53, k54, k55, k56, k57, k58, k59, k5a, k5b, k5c, k5d, k00, k00, k5g, k00}, \
75 {k61, k62, k63, k00, k00, k00, k67, k00, k00, k00, k6b, k6c, k6d, k6e, k6f, k6g, k6h}, \
76 }
77
78 #endif //!KEYMAP#endif
79 #ifndef ISO_KEYMAP
80 #define ISO_KEYMAP( \
81 k11, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d, k1e, k1f, k1g, k1h, \
82 k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k2d, k2e, k2f, k2g, k2h, \
83 k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d, k3e, k3f, k3g, k3h, \
84 k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c, k4d, \
85 k51, k52, k53, k54, k55, k56, k57, k58, k59, k5a, k5b, k5c, k5d, k5g, \
86 k61, k62, k63, k67, k6b, k6c, k6d, k6e, k6f, k6g, k6h \
87 ) \
88 { \
89 {k11, k00, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d, k1e, k1f, k1g, k1h}, \
90 {k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k2d, k2e, k2f, k2g, k2h}, \
91 {k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d, k3e, k3f, k3g, k3h}, \
92 {k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c, k4d, k00, k00, k00, k00}, \
93 {k51, k52, k53, k54, k55, k56, k57, k58, k59, k5a, k5b, k5c, k5d, k00, k00, k5g, k00}, \
94 {k61, k62, k63, k00, k00, k00, k67, k00, k00, k00, k6b, k6c, k6d, k6e, k6f, k6g, k6h}, \
95 }
96 #endif //!ISO_KEYMAP
97#else // RevC+ keymaps
98 #ifndef KEYMAP
99 #define KEYMAP( \
100 k71, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1e, k1f, k1g, \
101 k72, k73, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k2e, k2f, k2g, \
102 k74, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d, k3e, k3f, k3g, \
103 k61, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c, \
104 k62, k52, k53, k54, k55, k56, k57, k58, k59, k5a, k5b, k5c, k5f, \
105 k63, k64, k65, k67, k6a, k6b, k6c, k6d, k6e, k6f, k6g \
106 ) \
107 { \
108 {k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k00, k1e, k1f, k1g}, \
109 {k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k00, k2e, k2f, k2g}, \
110 {k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d, k3e, k3f, k3g}, \
111 {k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c, k00, k00, k00, k00}, \
112 {k00, k52, k53, k54, k55, k56, k57, k58, k59, k5a, k5b, k5c, k00, k00, k5f, k00}, \
113 {k61, k62, k63, k64, k65, k00, k67, k00, k00, k6a, k6b, k6c, k6d, k6e, k6f, k6g}, \
114 {k71, k72, k73, k74, k00, k00, k00, k00, k00, k00, k00, k00, k00, k00, k00, k00}, \
115 }
116
117 #endif //!KEYMAP#endif
118 #ifndef ISO_KEYMAP
119 #define ISO_KEYMAP( \
120 k71, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1e, k1f, k1g, \
121 k72, k73, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k2e, k2f, k2g, \
122 k74, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d, k3e, k3f, k3g, \
123 k61, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c, \
124 k62, k51, k52, k53, k54, k55, k56, k57, k58, k59, k5a, k5b, k5c, k5f, \
125 k63, k64, k65, k67, k6a, k6b, k6c, k6d, k6e, k6f, k6g \
126 ) \
127 { \
128 {k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k00, k1e, k1f, k1g}, \
129 {k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k00, k2e, k2f, k2g}, \
130 {k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d, k3e, k3f, k3g}, \
131 {k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c, k00, k00, k00, k00}, \
132 {k51, k52, k53, k54, k55, k56, k57, k58, k59, k5a, k5b, k5c, k00, k00, k5f, k00}, \
133 {k61, k62, k63, k64, k65, k00, k67, k00, k00, k6a, k6b, k6c, k6d, k6e, k6f, k6g}, \
134 {k71, k72, k73, k74, k00, k00, k00, k00, k00, k00, k00, k00, k00, k00, k00, k00}, \
135 }
136 #endif //!ISO_KEYMAP
137#endif //Rev
138
139#endif //LFK87_H
diff --git a/keyboards/lfkeyboards/lfk87/readme.md b/keyboards/lfkeyboards/lfk87/readme.md
new file mode 100644
index 000000000..15e551710
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk87/readme.md
@@ -0,0 +1,14 @@
1LFK87
2===
3
4A standard TKL with RGB underglow, in switch backlighting and audio support.
5
6Keyboard Maintainer: [LFKeyboards](https://github.com/lfkeyboards)
7Hardware Supported: LFK87, SMK87
8Hardware Availability: [LFKeyboards.com](https://www.lfkeyboards.com/)
9
10Make example for this keyboard (after setting up your build environment):
11
12 make lfkeyboards/lfk87:default
13
14See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information. \ No newline at end of file
diff --git a/keyboards/lfkeyboards/lfk87/rules.mk b/keyboards/lfkeyboards/lfk87/rules.mk
new file mode 100644
index 000000000..ec550d275
--- /dev/null
+++ b/keyboards/lfkeyboards/lfk87/rules.mk
@@ -0,0 +1,31 @@
1# Set the LFK87 hardware version.
2#
3# A - Green PCB. at90usb1286 Only 3 exist
4# B - We don't talk about RevB
5# C-D - Black PCB. at90usb646 First public release
6#
7LFK_REV = C
8
9ifeq ($(LFK_REV), A)
10 MCU = at90usb1286
11 OPT_DEFS += -DBOOTLOADER_SIZE=8192
12else
13 MCU = at90usb646
14 OPT_DEFS += -DBOOTLOADER_SIZE=4096
15endif
16OPT_DEFS += -DLFK_TKL_REV_$(LFK_REV)
17
18# Extra source files for IS3731 lighting
19SRC = TWIlib.c issi.c lighting.c
20
21# Processor frequency.
22F_CPU = 16000000
23
24# Target architecture (see library "Board Types" documentation).
25ARCH = AVR8
26
27# Input clock frequency.
28F_USB = $(F_CPU)
29
30# Interrupt driven control endpoint task(+60)
31OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
diff --git a/keyboards/lfkeyboards/lfkeyboards.c b/keyboards/lfkeyboards/lfkeyboards.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/keyboards/lfkeyboards/lfkeyboards.c
diff --git a/keyboards/lfkeyboards/lfkeyboards.h b/keyboards/lfkeyboards/lfkeyboards.h
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/keyboards/lfkeyboards/lfkeyboards.h
diff --git a/keyboards/lfkeyboards/lighting.c b/keyboards/lfkeyboards/lighting.c
new file mode 100644
index 000000000..42d247ae7
--- /dev/null
+++ b/keyboards/lfkeyboards/lighting.c
@@ -0,0 +1,157 @@
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 "quantum.h"
8// #include "lfk87.h"
9#include "issi.h"
10#include "TWIlib.h"
11#include "lighting.h"
12#include "debug.h"
13#include "rgblight.h"
14#include "audio/audio.h"
15
16
17extern rgblight_config_t rgblight_config; // Declared in rgblight.c
18
19const uint8_t backlight_pwm_map[BACKLIGHT_LEVELS] = BACKLIGHT_PWM_MAP;
20
21// RGB# to ISSI matrix, this is the same across all revisions
22const uint8_t rgb_leds[][3][2] = {
23 {{0, 0}, {0, 0}, {0, 0}},
24 {{1, 1}, {2, 3}, {2, 4}}, // RGB1/RGB17
25 {{2, 1}, {2, 2}, {3, 4}}, // RGB2/RGB18
26 {{3, 1}, {3, 2}, {3, 3}}, // RGB3/RGB19
27 {{4, 1}, {4, 2}, {4, 3}}, // RGB4/RGB20
28 {{5, 1}, {5, 2}, {5, 3}}, // RGB5/RGB21
29 {{6, 1}, {6, 2}, {6, 3}}, // RGB6/RGB22
30 {{7, 1}, {7, 2}, {7, 3}}, // RGB6/RGB23
31 {{8, 1}, {8, 2}, {8, 3}}, // RGB8/RGB24
32 {{1, 9}, {1, 8}, {1, 7}}, // RGB9/RGB25
33 {{2, 9}, {2, 8}, {2, 7}}, // RGB10/RGB26
34 {{3, 9}, {3, 8}, {3, 7}}, // RGB11/RGB27
35 {{4, 9}, {4, 8}, {4, 7}}, // RGB12/RGB28
36 {{5, 9}, {5, 8}, {5, 7}}, // RGB13/RGB29
37 {{6, 9}, {6, 8}, {6, 7}}, // RGB14/RGB30
38 {{7, 9}, {7, 8}, {6, 6}}, // RGB15/RGB31
39 {{8, 9}, {7, 7}, {7, 6}} // RGB16/RGB32
40 };
41
42void set_rgb(uint8_t rgb_led, uint8_t red, uint8_t green, uint8_t blue){
43#ifdef RGBLIGHT_ENABLE
44 uint8_t matrix = rgb_matrices[0];
45 if(rgb_led >= 17){
46 matrix = rgb_matrices[1];
47 rgb_led -= 16;
48 }
49 if(rgb_leds[rgb_led][0][1] != 0){
50 activateLED(matrix, rgb_leds[rgb_led][0][0], rgb_leds[rgb_led][0][1], red);
51 }
52 if(rgb_leds[rgb_led][1][1] != 0){
53 activateLED(matrix, rgb_leds[rgb_led][1][0], rgb_leds[rgb_led][1][1], green);
54 }
55 if(rgb_leds[rgb_led][2][1] != 0){
56 activateLED(matrix, rgb_leds[rgb_led][2][0], rgb_leds[rgb_led][2][1], blue);
57 }
58#endif
59}
60
61void backlight_set(uint8_t level){
62#ifdef BACKLIGHT_ENABLE
63 uint8_t pwm_value = 0;
64 if(level >= BACKLIGHT_LEVELS){
65 level = BACKLIGHT_LEVELS;
66 }
67 if(level > 0){
68 pwm_value = backlight_pwm_map[level-1];
69 }
70 for(int x = 1; x <= 9; x++){
71 for(int y = 1; y <= 9; y++){
72 activateLED(switch_matrices[0], x, y, pwm_value);
73 activateLED(switch_matrices[1], x, y, pwm_value);
74 }
75 }
76#endif
77}
78
79void set_underglow(uint8_t red, uint8_t green, uint8_t blue){
80#ifdef RGBLIGHT_ENABLE
81 for(uint8_t x = 1; x <= 32; x++){
82 set_rgb(x, red, green, blue);
83 }
84#endif
85}
86
87
88void rgblight_set(void) {
89#ifdef RGBLIGHT_ENABLE
90 for(uint8_t i = 0; (i < sizeof(rgb_sequence)) && (i < RGBLED_NUM); i++){
91 if(rgblight_config.enable){
92 set_rgb(rgb_sequence[i], led[i].r, led[i].g, led[i].b);
93 }else{
94 set_rgb(rgb_sequence[i], 0, 0, 0);
95 }
96 }
97#endif
98}
99
100void set_backlight_by_keymap(uint8_t col, uint8_t row){
101#ifdef RGBLIGHT_ENABLE
102 uint8_t lookup_value = switch_leds[row][col];
103 uint8_t matrix = switch_matrices[0];
104 if(lookup_value & 0x80){
105 matrix = switch_matrices[1];
106 }
107 issi_devices[0]->led_dirty = 1;
108 uint8_t led_col = (lookup_value & 0x70) >> 4;
109 uint8_t led_row = lookup_value & 0x0F;
110 activateLED(matrix, led_col, led_row, 255);
111#endif
112}
113
114void force_issi_refresh(){
115#ifdef ISSI_ENABLE
116 issi_devices[0]->led_dirty = true;
117 update_issi(0, true);
118 issi_devices[3]->led_dirty = true;
119 update_issi(3, true);
120#endif
121}
122
123void led_test(){
124#ifdef ISSI_ENABLE
125#ifdef WATCHDOG_ENABLE
126 // This test take a long time to run, disable the WTD until its complete
127 wdt_disable();
128#endif
129 backlight_set(0);
130 set_underglow(0, 0, 0);
131 force_issi_refresh();
132 set_underglow(0, 0, 0);
133 for(uint8_t x = 0; x < sizeof(rgb_sequence); x++){
134 set_rgb(rgb_sequence[x], 255, 0, 0);
135 force_issi_refresh();
136 _delay_ms(250);
137 set_rgb(rgb_sequence[x], 0, 255, 0);
138 force_issi_refresh();
139 _delay_ms(250);
140 set_rgb(rgb_sequence[x], 0, 0, 255);
141 force_issi_refresh();
142 _delay_ms(250);
143 set_rgb(rgb_sequence[x], 0, 0, 0);
144 force_issi_refresh();
145 }
146#ifdef WATCHDOG_ENABLE
147 wdt_enable(WDTO_250MS);
148#endif
149#endif
150}
151
152void backlight_init_ports(void){
153 issi_init();
154}
155
156#endif
157
diff --git a/keyboards/lfkeyboards/lighting.h b/keyboards/lfkeyboards/lighting.h
new file mode 100644
index 000000000..69e63268d
--- /dev/null
+++ b/keyboards/lfkeyboards/lighting.h
@@ -0,0 +1,53 @@
1#ifndef LIGHTING_H
2#define LIGHTING_H
3
4
5// rgb_sequence[RGBLED_NUM]
6//
7// Array used for sequential lighting effects.
8//
9// Example LFK78 RevC+ RGB Map:
10// 27 29 10 9 8 7 6
11// 26 5
12// 25 4
13// 24 3
14// 23 22 21 20 14 15 11 1 2
15//
16// const uint8_t rgb_sequence[] = {
17// 27, 29, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
18// 11, 15, 14, 20, 21, 22, 23, 24, 25, 26
19// };
20extern const uint8_t rgb_sequence[RGBLED_NUM];
21
22// switch_matrices[]
23//
24// The ISSI matrices for switch backlighting
25//
26// Example LFK78 RevC+ - ISSI Device 0, banks 0 and 1:
27// switch_matrices[] = {0, 1};
28extern const uint8_t switch_matrices[];
29
30// rgb_matrices[]
31// The ISSI matrices for RGB Underglow
32//
33// Example LFK78 RevC+ - ISSI Device 3, banks 0 and 1:
34// rgb_matrices[] = {6, 7};
35extern const uint8_t rgb_matrices[];
36
37// switch_leds[MATRIX_ROWS][MATRIX_COLS]
38// Maps switch LEDs from Row/Col to ISSI matrix.
39// Value breakdown:
40// Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
41// | | ISSI Col | ISSI Row |
42// | |
43// Device
44extern const uint8_t switch_leds[MATRIX_ROWS][MATRIX_COLS];
45
46void led_test(void);
47void force_issi_refresh(void);
48void set_backlight(uint8_t level);
49void set_underglow(uint8_t red, uint8_t green, uint8_t blue);
50void set_rgb(uint8_t rgb_led, uint8_t red, uint8_t green, uint8_t blue);
51void set_backlight_by_keymap(uint8_t col, uint8_t row);
52
53#endif \ No newline at end of file
diff --git a/keyboards/lfkeyboards/rules.mk b/keyboards/lfkeyboards/rules.mk
new file mode 100644
index 000000000..5cf759a2f
--- /dev/null
+++ b/keyboards/lfkeyboards/rules.mk
@@ -0,0 +1 @@
SRC = TWIlib.c issi.c lighting.c
diff --git a/keyboards/lfkeyboards/smk65/config.h b/keyboards/lfkeyboards/smk65/config.h
new file mode 100644
index 000000000..78626416c
--- /dev/null
+++ b/keyboards/lfkeyboards/smk65/config.h
@@ -0,0 +1,168 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#ifndef CONFIG_H
19#define CONFIG_H
20
21#include "config_common.h"
22
23#define VENDOR_ID 0xFEED
24#define PRODUCT_ID 0x6062
25#define DEVICE_VER 0x0001
26#define MANUFACTURER LFKeyboards
27#define PRODUCT SMK65v2
28#define DESCRIPTION QMK keyboard firmware for SMK65
29
30// RevA
31// #define DIODE_DIRECTION COL2ROW
32// #define MATRIX_ROWS 5
33// #define MATRIX_COLS 16
34// #define MATRIX_ROW_PINS {B7, F7, F6, F5, F4}
35// #define MATRIX_COL_PINS {F0, F1, D2, D3, D5, D4, D6, D7, B4, B5, B6, C7, B3, B2, B1, B0}
36// #define UNUSED_PINS {}
37
38// RevB
39#define DIODE_DIRECTION COL2ROW
40#define MATRIX_ROWS 5
41#define MATRIX_COLS 16
42#define MATRIX_ROW_PINS {D6, D7, E0, C3, C4}
43#define MATRIX_COL_PINS {F2, C5, E5, E4, B7, B6, B5, B4, B3, B2, B1, B0, E1, C0, C1, C2}
44#define UNUSED_PINS {}
45#define RGBLED_NUM 20 // Number of LEDs
46
47//RevB only:
48
49#define AUDIO_VOICES
50#define C6_AUDIO
51// #define B5_AUDIO
52
53#define BACKLIGHT_LEVELS 8
54#define BACKLIGHT_PWM_MAP {8, 16, 40, 55, 70, 128, 200, 255}
55
56#define RGB_DI_PIN C7 // Have to set it to something to get the ws2812 code to compile
57#define RGBLED_NUM 20 // Number of LEDs
58#define RGBLIGHT_ANIMATIONS
59#define RGBLIGHT_HUE_STEP 10
60#define RGBLIGHT_SAT_STEP 17
61#define RGBLIGHT_VAL_STEP 17
62
63/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
64#define DEBOUNCING_DELAY 5
65
66/* define if matrix has ghost (lacks anti-ghosting diodes) */
67//#define MATRIX_HAS_GHOST
68
69/* number of backlight levels */
70
71/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
72#define LOCKING_SUPPORT_ENABLE
73/* Locking resynchronize hack */
74#define LOCKING_RESYNC_ENABLE
75
76/*
77 * Force NKRO
78 *
79 * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
80 * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
81 * makefile for this to work.)
82 *
83 * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
84 * until the next keyboard reset.
85 *
86 * NKRO may prevent your keystrokes from being detected in the BIOS, but it is
87 * fully operational during normal computer usage.
88 *
89 * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
90 * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
91 * bootmagic, NKRO mode will always be enabled until it is toggled again during a
92 * power-up.
93 *
94 */
95//#define FORCE_NKRO
96
97/*
98 * Magic Key Options
99 *
100 * Magic keys are hotkey commands that allow control over firmware functions of
101 * the keyboard. They are best used in combination with the HID Listen program,
102 * found here: https://www.pjrc.com/teensy/hid_listen.html
103 *
104 * The options below allow the magic key functionality to be changed. This is
105 * useful if your keyboard/keypad is missing keys and you want magic key support.
106 *
107 */
108
109/* key combination for magic key command */
110#define IS_COMMAND() ( \
111 keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
112)
113
114/* control how magic key switches layers */
115//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
116//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
117//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
118
119/* override magic key keymap */
120//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
121//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
122//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
123//#define MAGIC_KEY_HELP1 H
124//#define MAGIC_KEY_HELP2 SLASH
125//#define MAGIC_KEY_DEBUG D
126//#define MAGIC_KEY_DEBUG_MATRIX X
127//#define MAGIC_KEY_DEBUG_KBD K
128//#define MAGIC_KEY_DEBUG_MOUSE M
129//#define MAGIC_KEY_VERSION V
130//#define MAGIC_KEY_STATUS S
131//#define MAGIC_KEY_CONSOLE C
132//#define MAGIC_KEY_LAYER0_ALT1 ESC
133//#define MAGIC_KEY_LAYER0_ALT2 GRAVE
134//#define MAGIC_KEY_LAYER0 0
135//#define MAGIC_KEY_LAYER1 1
136//#define MAGIC_KEY_LAYER2 2
137//#define MAGIC_KEY_LAYER3 3
138//#define MAGIC_KEY_LAYER4 4
139//#define MAGIC_KEY_LAYER5 5
140//#define MAGIC_KEY_LAYER6 6
141//#define MAGIC_KEY_LAYER7 7
142//#define MAGIC_KEY_LAYER8 8
143//#define MAGIC_KEY_LAYER9 9
144//#define MAGIC_KEY_BOOTLOADER PAUSE
145//#define MAGIC_KEY_LOCK CAPS
146//#define MAGIC_KEY_EEPROM E
147//#define MAGIC_KEY_NKRO N
148//#define MAGIC_KEY_SLEEP_LED Z
149
150/*
151 * Feature disable options
152 * These options are also useful to firmware size reduction.
153 */
154
155/* disable debug print */
156//#define NO_DEBUG
157
158/* disable print */
159//#define NO_PRINT
160
161/* disable action features */
162//#define NO_ACTION_LAYER
163//#define NO_ACTION_TAPPING
164//#define NO_ACTION_ONESHOT
165//#define NO_ACTION_MACRO
166//#define NO_ACTION_FUNCTION
167
168#endif
diff --git a/keyboards/lfkeyboards/smk65/keymaps/default/config.h b/keyboards/lfkeyboards/smk65/keymaps/default/config.h
new file mode 100644
index 000000000..8893d122e
--- /dev/null
+++ b/keyboards/lfkeyboards/smk65/keymaps/default/config.h
@@ -0,0 +1,8 @@
1#ifndef CONFIG_USER_H
2#define CONFIG_USER_H
3
4#include "../../config.h"
5
6// place overrides here
7
8#endif
diff --git a/keyboards/lfkeyboards/smk65/keymaps/default/keymap.c b/keyboards/lfkeyboards/smk65/keymaps/default/keymap.c
new file mode 100644
index 000000000..97ca543b5
--- /dev/null
+++ b/keyboards/lfkeyboards/smk65/keymaps/default/keymap.c
@@ -0,0 +1,85 @@
1#include "smk65.h"
2#include "action_layer.h"
3
4//Define a shorter 'transparent' key code to make the keymaps more compact
5#define KC_TR KC_TRNS
6
7enum keymap_layout {
8 VANILLA = 0,
9 FUNC,
10 SETTINGS,
11};
12
13
14const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
15[VANILLA] = KEYMAP(
16 /* Keymap VANILLA: (Base Layer) Default Layer
17 * ,------------------------------------------------------------.----.
18 * |Esc~| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0| - | = |Backspa| Ins|
19 * |------------------------------------------------------------|----|
20 * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| Del|
21 * |------------------------------------------------------------|----|
22 * |CAPS | A| S| D| F| G| H| J| K| L| ;| '|Return |PgUp|
23 * |------------------------------------------------------------|----|
24 * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |Up |PgDn|
25 * |-----------------------------------------------------------------|
26 * |Ctrl|Win |Alt | Space |Alt |Ctrl|Func|Lft| Dn |Rig |
27 * `-----------------------------------------------------------------'
28 */
29 KC_GESC,KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS,
30 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL,
31 KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP,
32 KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN,
33 KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RCTL, MO(FUNC), KC_LEFT, KC_DOWN, KC_RGHT),
34
35[FUNC] = KEYMAP(
36 /* Keymap VANILLA: Function Layer
37 * ,------------------------------------------------------------.----.
38 * |Esc~| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0| - | = |Backspa| Ins|
39 * |------------------------------------------------------------|----|
40 * |AudTgl| Q| W| E| R| T| Y| U| I| O| P| [| ]| \| Del|
41 * |------------------------------------------------------------|----|
42 * |CAPS | A| S| D| F| G| H| J| K| L| ;| '|Return |PgUp|
43 * |------------------------------------------------------------|----|
44 * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |Up |PgDn|
45 * |-----------------------------------------------------------------|
46 * |Ctrl|Win |Alt | Space |Alt |Ctrl|Func|Lft| Dn |Rig |
47 * `-----------------------------------------------------------------'
48 */
49 KC_GRV,KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_F13, KC_F14,
50 AU_TOG, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR,
51 KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR,
52 KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR,
53 KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR, KC_TR),
54};
55
56const uint16_t PROGMEM fn_actions[] = {
57 ACTION_FUNCTION(LFK_CLEAR), // FN0 - reset layers
58 ACTION_FUNCTION(LFK_ESC_TILDE), // FN1 - esc+shift = ~, else escape
59 };
60
61
62const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
63{
64 // MACRODOWN only works in this function
65 switch(id) {
66 }
67 return MACRO_NONE;
68};
69
70
71void matrix_init_user(void) {
72
73}
74
75void matrix_scan_user(void) {
76
77}
78
79bool process_record_user(uint16_t keycode, keyrecord_t *record) {
80 return true;
81}
82
83void led_set_user(uint8_t usb_led) {
84
85}
diff --git a/keyboards/lfkeyboards/smk65/keymaps/default/rules.mk b/keyboards/lfkeyboards/smk65/keymaps/default/rules.mk
new file mode 100644
index 000000000..14ceebb77
--- /dev/null
+++ b/keyboards/lfkeyboards/smk65/keymaps/default/rules.mk
@@ -0,0 +1,36 @@
1# Build Options
2# change to "no" to disable the options, or define them in the Makefile in
3# the appropriate keymap folder that will get included automatically
4#
5
6BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
7MOUSEKEY_ENABLE = no # Mouse keys(+4700)
8EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
9CONSOLE_ENABLE = no # Console for debug(+400)
10COMMAND_ENABLE = no # Commands for debug and configuration
11NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
12BACKLIGHT_ENABLE = no # Disable keyboard backlight functionality
13MIDI_ENABLE = no # MIDI controls
14AUDIO_ENABLE = yes # Audio output on port C6
15UNICODE_ENABLE = no # Unicode
16BLUETOOTH_ENABLE = no # Disable Bluetooth with the Adafruit EZ-Key HID
17RGBLIGHT_ENABLE = yes # Disable RGB underlight
18RGBLIGHT_CUSTOM_DRIVER = yes # RGB code is implemented in lefkeyboards, not WS2812
19SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
20TAP_DANCE_ENABLE = no
21
22ISSI_ENABLE = yes # If the I2C pullup resistors aren't install this must be disabled
23WATCHDOG_ENABLE = no # Resets keyboard if matrix_scan isn't run every 250ms
24
25
26ifndef QUANTUM_DIR
27 include ../../../../Makefile
28endif
29
30ifeq ($(strip $(ISSI_ENABLE)), yes)
31 TMK_COMMON_DEFS += -DISSI_ENABLE
32endif
33
34ifeq ($(strip $(WATCHDOG_ENABLE)), yes)
35 TMK_COMMON_DEFS += -DWATCHDOG_ENABLE
36endif
diff --git a/keyboards/lfkeyboards/smk65/readme.md b/keyboards/lfkeyboards/smk65/readme.md
new file mode 100644
index 000000000..8265e36e6
--- /dev/null
+++ b/keyboards/lfkeyboards/smk65/readme.md
@@ -0,0 +1,14 @@
1SMK65
2===
3
465% layout based on Mat3o's Whitefox, but with support for SMK switches.
5
6Keyboard Maintainer: [LFKeyboards](https://github.com/lfkeyboards)
7Hardware Supported: SMK65
8Hardware Availability: [LFKeyboards.com](https://www.lfkeyboards.com/)
9
10Make example for this keyboard (after setting up your build environment):
11
12 make lfkeyboards/smk65:default
13
14See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information. \ No newline at end of file
diff --git a/keyboards/lfkeyboards/smk65/rules.mk b/keyboards/lfkeyboards/smk65/rules.mk
new file mode 100644
index 000000000..b7f94154a
--- /dev/null
+++ b/keyboards/lfkeyboards/smk65/rules.mk
@@ -0,0 +1,17 @@
1MCU = at90usb646
2OPT_DEFS += -DBOOTLOADER_SIZE=4096
3
4# Extra source files for IS3731 lighting
5SRC = TWIlib.c issi.c lighting.c
6
7# Processor frequency.
8F_CPU = 16000000
9
10# Target architecture (see library "Board Types" documentation).
11ARCH = AVR8
12
13# Input clock frequency.
14F_USB = $(F_CPU)
15
16# Interrupt driven control endpoint task(+60)
17OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
diff --git a/keyboards/lfkeyboards/smk65/smk65.c b/keyboards/lfkeyboards/smk65/smk65.c
new file mode 100644
index 000000000..d3654b880
--- /dev/null
+++ b/keyboards/lfkeyboards/smk65/smk65.c
@@ -0,0 +1,164 @@
1#include <avr/sfr_defs.h>
2#include <avr/timer_avr.h>
3#include <avr/wdt.h>
4#include "smk65.h"
5#include "keymap.h"
6#include "debug.h"
7#include "issi.h"
8#include "TWIlib.h"
9#include "lighting.h"
10
11uint16_t click_hz = CLICK_HZ;
12uint16_t click_time = CLICK_MS;
13uint8_t click_toggle = CLICK_ENABLED;
14
15
16void matrix_init_kb(void)
17{
18 matrix_init_user();
19
20#ifdef AUDIO_ENABLE
21 // audio_init() sets PB5 to output and drives it low, which breaks our matrix
22 // so reset PB5 to input
23 cbi(DDRB, 5);
24 sbi(PORTB, 5);
25#else
26 // If we're not using the audio pin, drive it low
27 sbi(DDRC, 6);
28 cbi(PORTC, 6);
29#endif
30
31#ifdef ISSI_ENABLE
32 issi_init();
33#endif
34}
35
36void matrix_scan_kb(void)
37{
38#ifdef WATCHDOG_ENABLE
39 wdt_reset();
40#endif
41 matrix_scan_user();
42}
43
44void click(uint16_t freq, uint16_t duration){
45#ifdef AUDIO_ENABLE
46 if(freq >= 100 && freq <= 20000 && duration < 100){
47 play_note(freq, 10);
48 for (uint16_t i = 0; i < duration; i++){
49 _delay_ms(1);
50 }
51 stop_all_notes();
52 }
53#endif
54}
55
56bool process_record_kb(uint16_t keycode, keyrecord_t* record)
57{
58 // Test code that turns on the switch led for the key that is pressed
59 // set_backlight_by_keymap(record->event.key.col, record->event.key.row);
60 if (click_toggle && record->event.pressed){
61 click(click_hz, click_time);
62 }
63 if (keycode == RESET) {
64 reset_keyboard_kb();
65 } else {
66 }
67 return process_record_user(keycode, record);
68}
69
70void action_function(keyrecord_t *event, uint8_t id, uint8_t opt)
71{
72#ifdef AUDIO_ENABLE
73 int8_t sign = 1;
74#endif
75 if(id == LFK_ESC_TILDE){
76 // Send ~ on shift-esc
77 void (*method)(uint8_t) = (event->event.pressed) ? &add_key : &del_key;
78 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT));
79 method(shifted ? KC_GRAVE : KC_ESCAPE);
80 send_keyboard_report();
81 }else if(event->event.pressed){
82 switch(id){
83 case LFK_SET_DEFAULT_LAYER:
84 // set/save the current base layer to eeprom, falls through to LFK_CLEAR
85 eeconfig_update_default_layer(1UL << opt);
86 default_layer_set(1UL << opt);
87 case LFK_CLEAR:
88 // Go back to default layer
89 layer_clear();
90 break;
91#ifdef AUDIO_ENABLE
92 case LFK_CLICK_FREQ_LOWER:
93 sign = -1; // continue to next statement
94 case LFK_CLICK_FREQ_HIGHER:
95 click_hz += sign * 100;
96 click(click_hz, click_time);
97 break;
98 case LFK_CLICK_TOGGLE:
99 if(click_toggle){
100 click_toggle = 0;
101 click(4000, 100);
102 click(1000, 100);
103 }else{
104 click_toggle = 1;
105 click(1000, 100);
106 click(4000, 100);
107 }
108 break;
109 case LFK_CLICK_TIME_SHORTER:
110 sign = -1; // continue to next statement
111 case LFK_CLICK_TIME_LONGER:
112 click_time += sign;
113 click(click_hz, click_time);
114 break;
115#endif
116 case LFK_DEBUG_SETTINGS:
117 dprintf("Click:\n");
118 dprintf(" toggle: %d\n", click_toggle);
119 dprintf(" freq(hz): %d\n", click_hz);
120 dprintf(" duration(ms): %d\n", click_time);
121 break;
122 }
123 }
124}
125
126void reset_keyboard_kb(){
127#ifdef WATCHDOG_ENABLE
128 MCUSR = 0;
129 wdt_disable();
130 wdt_reset();
131#endif
132 reset_keyboard();
133}
134
135void led_set_kb(uint8_t usb_led)
136{
137 // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here
138
139 led_set_user(usb_led);
140}
141
142// LFK lighting info
143const uint8_t switch_matrices[] = {0, 1};
144const uint8_t rgb_matrices[] = {6, 7};
145// const uint8_t rgb_sequence[] = {
146// 14, 24, 23, 22, 21, 20, 19, 18, 26, 25, 28, 29,
147// 30, 31, 32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
148// };
149const uint8_t rgb_sequence[] = {
150 25, 28, 29,
151 30, 31, 32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
152};
153// Maps switch LEDs from Row/Col to ISSI matrix.
154// Value breakdown:
155// Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
156// / \ ISSI Col | ISSI Row |
157// matrix idx
158// const uint8_t switch_leds[MATRIX_ROWS][MATRIX_COLS] =
159// KEYMAP(
160// 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91,
161// 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0xA9, 0xA8, 0xA7, 0xA6, 0xA5, 0xA4, 0xA3, 0xA2, 0xA1,
162// 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0xB9, 0xB8, 0xB7, 0xB6, 0xB5, 0xB3,
163// 0x49, 0x48, 0x47, 0x45, 0x44, 0x43, 0x42, 0x41, 0xC9, 0xC8, 0xC7, 0xC6, 0xC5, 0xC4, 0xC2,
164// 0x59, 0x58, 0x57, 0x56, 0x55, 0x51, 0xD6, 0xE5, 0xE4, 0xE3, 0xE2, 0xE1);
diff --git a/keyboards/lfkeyboards/smk65/smk65.h b/keyboards/lfkeyboards/smk65/smk65.h
new file mode 100644
index 000000000..cb39a6c11
--- /dev/null
+++ b/keyboards/lfkeyboards/smk65/smk65.h
@@ -0,0 +1,90 @@
1#ifndef SMK65_H
2#define SMK65_H
3
4/* if the kb.h file exists (because we're running from qmkbuilder) include it */
5#ifdef __has_include
6#if __has_include("kb.h")
7#include "kb.h"
8#endif
9#endif
10
11#include "quantum.h"
12#include "matrix.h"
13#include <avr/sfr_defs.h>
14
15#ifndef cbi
16#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
17#endif
18
19#ifndef sbi
20#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
21#endif
22
23
24typedef struct RGB_Color {
25 uint16_t red;
26 uint16_t green;
27 uint16_t blue;
28} RGB_Color;
29
30typedef struct Layer_Info {
31 uint32_t layer;
32 uint32_t mask;
33 RGB_Color color;
34} Layer_Info;
35
36extern const uint32_t layer_count;
37extern const Layer_Info layer_info[];
38
39enum action_functions {
40 LFK_CLEAR = 0, // Resets all layers
41 LFK_ESC_TILDE, // esc+lshift = ~
42 LFK_SET_DEFAULT_LAYER, // changes and saves current base layer to eeprom
43 LFK_CLICK_TOGGLE, // Adjusts click duration
44 LFK_CLICK_FREQ_HIGHER, // Adjusts click frequency
45 LFK_CLICK_FREQ_LOWER, // Adjusts click frequency
46 LFK_CLICK_TIME_LONGER, // Adjusts click duration
47 LFK_CLICK_TIME_SHORTER, // Adjusts click duration
48 LFK_DEBUG_SETTINGS, // prints LED and click settings to HID
49 LFK_LED_TEST // cycles through switch and RGB LEDs
50};
51
52#define CLICK_HZ 500
53#define CLICK_MS 2
54#define CLICK_ENABLED 0
55
56void reset_keyboard_kb(void);
57void click(uint16_t freq, uint16_t duration);
58
59/* Vanilla Keymap */
60// This a shortcut to help you visually see your layout.
61/*
62* ,-------------------------------------------------------------------------------.
63* | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 1A | 1B | 1C | 1D | 1E | 1G |
64* |-------------------------------------------------------------------------------|
65* | 21 | 22 |23 | 24 | 25 | 26 | 27 | 28 | 29 | 2A | 2B | 2C | 2D | 2F | 2G |
66* |-------------------------------------------------------------------------------|
67* | 31 | 32 |33 | 34 | 35 | 36 | 37 | 38 | 39 | 3A | 3B | 3C | 3F | 3G |
68* |-------------------------------------------------------------------------------|
69* | 41 | 42 |43 | 45 | 46 | 47 | 48 | 49 | 4A | 4B | 4C | 4D | 4F | 4G |
70* |-------------------------------------------------------------------------------|
71* | 51 | 52 | 53 | 57 | 5A | 5B | 5C | 5D | 5E | 3E | 4E |
72* `-------------------------------------------------------------------------------'
73*/
74// The first section contains all of the arguements
75// The second converts the arguments into a two-dimensional array
76#define KEYMAP( \
77 k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1F, k1G, \
78 k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2F, k2G, \
79 k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3F, k3G, \
80 k41, k43, k44, k45, k46, k47, k48, k49, k4A, k4B, k4C, k4D, k4F, k4G, \
81 k51, k52, k53, k57, k5B, k5C, k5D, k5E, k3E, k4E \
82) { \
83 {k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, KC_NO, k1F, k1G}, \
84 {k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, KC_NO, k2F, k2G}, \
85 {k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, KC_NO, k3E, k3F, k3G}, \
86 {k41, KC_NO, k43, k44, k45, k46, k47, k48, k49, k4A, k4B, k4C, k4D, k4E, k4F, k4G}, \
87 {k51, k52, k53, KC_NO, KC_NO, KC_NO, k57, KC_NO, KC_NO, KC_NO, k5B, k5C, k5D, k5E, KC_NO, KC_NO}, \
88}
89
90#endif //SMK65_H