Merge branch 'muon_light' of github.com:qmk/qmk_firmware into keymap_folders
This commit is contained in:
		
						commit
						e54159d9e8
					
				
					 28 changed files with 421 additions and 236 deletions
				
			
		| 
						 | 
				
			
			@ -124,7 +124,7 @@ endif
 | 
			
		|||
ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
 | 
			
		||||
    OPT_DEFS += -DRGB_MATRIX_ENABLE
 | 
			
		||||
    SRC += is31fl3731.c
 | 
			
		||||
    SRC += twi2c.c
 | 
			
		||||
    I2C_ENABLE = yes
 | 
			
		||||
    SRC += $(QUANTUM_DIR)/color.c
 | 
			
		||||
    SRC += $(QUANTUM_DIR)/rgb_matrix.c
 | 
			
		||||
    CIE1931_CURVE = yes
 | 
			
		||||
| 
						 | 
				
			
			@ -205,7 +205,7 @@ ifeq ($(strip $(USB_HID_ENABLE)), yes)
 | 
			
		|||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(strip $(I2C_SLAVE_ENABLE)), yes)
 | 
			
		||||
    SRC += twi2c.c
 | 
			
		||||
    I2C_ENABLE = yes
 | 
			
		||||
    OPT_DEFS += -DI2C_SLAVE_ENABLE
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -214,6 +214,14 @@ ifeq ($(strip $(ENCODER_ENABLE)), yes)
 | 
			
		|||
    SRC += $(QUANTUM_DIR)/encoder.c
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(strip $(QWIIC_KEYBOARD_ENABLE)), yes)
 | 
			
		||||
    SRC += qwiic/qwiic_keyboard.c
 | 
			
		||||
    OPT_DEFS += -DQWIIC_KEYBOARD_ENABLE
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(strip $(I2C_ENABLE)), yes)
 | 
			
		||||
    SRC += twi2c.c
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
QUANTUM_SRC:= \
 | 
			
		||||
    $(QUANTUM_DIR)/quantum.c \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,10 +20,6 @@
 | 
			
		|||
#include "chprintf.h"
 | 
			
		||||
#include "memstreams.h"
 | 
			
		||||
#include "printf.h"
 | 
			
		||||
#include "matrix.h"
 | 
			
		||||
 | 
			
		||||
#ifdef I2C_SLAVE_ENABLE
 | 
			
		||||
 | 
			
		||||
#include "hal_i2cslave.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -40,9 +36,8 @@
 | 
			
		|||
//   400000
 | 
			
		||||
// };
 | 
			
		||||
 | 
			
		||||
I2CSlaveMsgCB twi2c_slave_message_process, catchError, clearAfterSend;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
I2CSlaveMsgCB twi2c_incoming_message_process, twi2c_catch_error, twi2c_clear_after_send;
 | 
			
		||||
twi2c_message_received twi2c_message_received_callback;
 | 
			
		||||
 | 
			
		||||
static uint8_t twi2c_address;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -54,62 +49,6 @@ static const I2CConfig i2cconfig = {
 | 
			
		|||
  0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
char initialReplyBody[50] = "Initial reply";        // 'Status' response if read without preceding write
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t messageCounter = 0;                /* Counts number of messages received to return as part of response */
 | 
			
		||||
 | 
			
		||||
uint8_t  rxBody[2];                       /* stores last message master sent us (intentionally a few bytes smaller than txBody) */
 | 
			
		||||
uint8_t  txBody[MATRIX_ROWS/2];                       /* Return message buffer for computed replies */
 | 
			
		||||
 | 
			
		||||
BaseSequentialStream *chp = NULL;           // Used for serial logging
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef I2C_SLAVE_ENABLE
 | 
			
		||||
 | 
			
		||||
// Handler when something sent to us
 | 
			
		||||
const I2CSlaveMsg echoRx =
 | 
			
		||||
{
 | 
			
		||||
  sizeof(rxBody),       /* max sizeof received msg body */
 | 
			
		||||
  rxBody,               /* body of received msg */
 | 
			
		||||
  NULL,                 /* do nothing on address match */
 | 
			
		||||
  twi2c_slave_message_process,     /* Routine to process received messages */
 | 
			
		||||
  catchError            /* Error hook */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// // 'Empty' reply when nothing to say, and no message received. In RAM, to allow update
 | 
			
		||||
I2CSlaveMsg initialReply =
 | 
			
		||||
{
 | 
			
		||||
  sizeof(initialReplyBody),   /* trailing zero byte will be repeated as needed */
 | 
			
		||||
  (uint8_t *)initialReplyBody,
 | 
			
		||||
  NULL,                 /* do nothing on address match */
 | 
			
		||||
  NULL,                 /* do nothing after reply sent */
 | 
			
		||||
  catchError            /* Error hook */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// // 'Empty' reply when nothing to say, and no message received. In RAM, to allow update
 | 
			
		||||
// I2CSlaveMsg initialReply =
 | 
			
		||||
// {
 | 
			
		||||
//   0,  /* trailing zero byte will be repeated as needed */
 | 
			
		||||
//   NULL,
 | 
			
		||||
//   NULL,                 /* do nothing on address match */
 | 
			
		||||
//   NULL,                 /* do nothing after reply sent */
 | 
			
		||||
//   catchError            /* Error hook */
 | 
			
		||||
// };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Response to received messages
 | 
			
		||||
I2CSlaveMsg echoReply = {  /* this is in RAM so size may be updated */
 | 
			
		||||
  MATRIX_ROWS / 2,                    /* filled in with the length of the message to send */
 | 
			
		||||
  txBody,               /* Response message */
 | 
			
		||||
  NULL,                 /* do nothing special on address match */
 | 
			
		||||
  clearAfterSend,       /* Clear receive buffer once replied */
 | 
			
		||||
  catchError            /* Error hook */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Track I2C errors
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -123,95 +62,26 @@ void noteI2cError(uint32_t flags)
 | 
			
		|||
  gotI2cError = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generic error handler
 | 
			
		||||
 *
 | 
			
		||||
 * Called in interrupt context, so need to watch what we do
 | 
			
		||||
 */
 | 
			
		||||
void catchError(I2CDriver *i2cp)
 | 
			
		||||
void twi2c_catch_error(I2CDriver *i2cp)
 | 
			
		||||
{
 | 
			
		||||
  noteI2cError(i2cp->errors);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern void matrix_copy(matrix_row_t * copy);
 | 
			
		||||
 | 
			
		||||
const char hexString[16] = "0123456789abcdef";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *  Message processor - looks at received message, determines reply as quickly as possible
 | 
			
		||||
 *
 | 
			
		||||
 *  Responds with the value of the messageCounter (in hex), followed by the received message in [..]
 | 
			
		||||
 *
 | 
			
		||||
 *  Note: Called in interrupt context, so need to be quick!
 | 
			
		||||
 */
 | 
			
		||||
void twi2c_slave_message_process(I2CDriver *i2cp) {
 | 
			
		||||
 | 
			
		||||
  // size_t len = i2cSlaveBytes(i2cp);         // Number of bytes received
 | 
			
		||||
 | 
			
		||||
  // memset(txBody, 0, MATRIX_ROWS / 2 * sizeof(matrix_row_t));
 | 
			
		||||
  matrix_copy(txBody);
 | 
			
		||||
 | 
			
		||||
  echoReply.size =  MATRIX_ROWS / 2;
 | 
			
		||||
  i2cSlaveReplyI(i2cp, &echoReply);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Callback after sending of response complete - restores default reply in case polled
 | 
			
		||||
 */
 | 
			
		||||
void clearAfterSend(I2CDriver *i2cp)
 | 
			
		||||
void twi2c_clear_after_send(I2CDriver *i2cp)
 | 
			
		||||
{
 | 
			
		||||
  // echoReply.size = 0;               // Clear receive message
 | 
			
		||||
  // i2cSlaveReplyI(i2cp, &initialReply);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Start the I2C Slave port to accept comms from master CPU
 | 
			
		||||
 *
 | 
			
		||||
 * We then go into a loop checking for errors, and never return
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
void twi2c_slave_init(void) {
 | 
			
		||||
 | 
			
		||||
  twi2c_init();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  i2cStart(&I2C_DRIVER, &i2cconfig);
 | 
			
		||||
#if HAL_USE_I2C_SLAVE
 | 
			
		||||
  I2C_DRIVER.slaveTimeout = MS2ST(100);       // Time for complete message
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  // i2cSlaveConfigure(&I2C_DRIVER, &echoRx, &initialReply);
 | 
			
		||||
 | 
			
		||||
  memset(txBody, 0, MATRIX_ROWS / 2 * sizeof(matrix_row_t));
 | 
			
		||||
 | 
			
		||||
  i2cSlaveConfigure(&I2C_DRIVER, &echoRx, &echoReply);
 | 
			
		||||
 | 
			
		||||
  // Enable match address after everything else set up
 | 
			
		||||
  i2cMatchAddress(&I2C_DRIVER, slaveI2Caddress/2);
 | 
			
		||||
//  i2cMatchAddress(&I2C_DRIVER, myOtherI2Caddress/2);
 | 
			
		||||
 // i2cMatchAddress(&I2C_DRIVER, 0);  /* "all call" */
 | 
			
		||||
 | 
			
		||||
  printf("Slave I2C started\n\r");
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void twi2c_slave_task(void) {
 | 
			
		||||
    if (gotI2cError) {
 | 
			
		||||
      gotI2cError = 0;
 | 
			
		||||
        printf("I2cError: %04x\r\n", lastI2cErrorFlags);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
uint8_t twi2c_start(uint8_t address) {
 | 
			
		||||
  twi2c_address = address;
 | 
			
		||||
uint8_t twi2c_start(void) {
 | 
			
		||||
  i2cStart(&I2C_DRIVER, &i2cconfig);
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -233,8 +103,66 @@ uint8_t twi2c_write(uint8_t data) {
 | 
			
		|||
  return i2cMasterTransmitTimeout(&I2C_DRIVER, twi2c_address/2, &data, 1, 0, 0, MS2ST(100));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t twi2c_transmit(uint8_t address, uint8_t* data, uint16_t length) {
 | 
			
		||||
  twi2c_address = address;
 | 
			
		||||
  i2cStart(&I2C_DRIVER, &i2cconfig);
 | 
			
		||||
  return i2cMasterTransmitTimeout(&I2C_DRIVER, twi2c_address/2, data, length, 0, 0, MS2ST(100));
 | 
			
		||||
uint8_t twi2c_transmit(uint8_t address, uint8_t * data, uint16_t length) {
 | 
			
		||||
  return i2cMasterTransmitTimeout(&I2C_DRIVER, address/2, data, length, 0, 0, MS2ST(100));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t twi2c_receive(uint8_t address, uint8_t * data, uint16_t length) {
 | 
			
		||||
  return i2cMasterReceiveTimeout(&I2C_DRIVER, address/2, data, length, MS2ST(100));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint8_t twi2c_incoming_body[50];
 | 
			
		||||
uint8_t twi2c_outgoing_body[1024];
 | 
			
		||||
 | 
			
		||||
// Response to received messages
 | 
			
		||||
I2CSlaveMsg twi2c_incoming_message = {
 | 
			
		||||
  sizeof(twi2c_incoming_body),
 | 
			
		||||
  twi2c_incoming_body,
 | 
			
		||||
  NULL,
 | 
			
		||||
  twi2c_incoming_message_process,
 | 
			
		||||
  twi2c_catch_error                   /* Error hook */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void twi2c_incoming_message_process(I2CDriver * i2cp) {
 | 
			
		||||
  size_t len = i2cSlaveBytes(i2cp);
 | 
			
		||||
  (*twi2c_message_received_callback)(i2cp, twi2c_incoming_body, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Response to received messages
 | 
			
		||||
I2CSlaveMsg twi2c_outgoing_message = {
 | 
			
		||||
  sizeof(twi2c_outgoing_body),
 | 
			
		||||
  twi2c_outgoing_body,
 | 
			
		||||
  NULL,
 | 
			
		||||
  twi2c_clear_after_send,
 | 
			
		||||
  twi2c_catch_error
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
uint8_t twi2c_reply(I2CDriver * i2cp, uint8_t * data, uint16_t length) {
 | 
			
		||||
  memcpy(twi2c_outgoing_body, data, length);
 | 
			
		||||
  twi2c_outgoing_message.size = length;
 | 
			
		||||
  i2cSlaveReplyI(i2cp, &twi2c_outgoing_message);
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t twi2c_transmit_receive(uint8_t address, uint8_t * tx_body, uint16_t tx_length, uint8_t * rx_body, uint16_t rx_length) {
 | 
			
		||||
  return i2cMasterTransmitTimeout(&I2C_DRIVER, address/2, tx_body, tx_length, rx_body, rx_length, MS2ST(100));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t twi2c_start_listening(uint8_t address, twi2c_message_received callback) {
 | 
			
		||||
  twi2c_message_received_callback = callback;
 | 
			
		||||
  I2C_DRIVER.slaveTimeout = MS2ST(100);
 | 
			
		||||
  i2cSlaveConfigure(&I2C_DRIVER, &twi2c_incoming_message, &twi2c_outgoing_message);
 | 
			
		||||
  i2cMatchAddress(&I2C_DRIVER, address/2);
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t twi2c_restart_listening(uint8_t address) {
 | 
			
		||||
  i2cMatchAddress(&I2C_DRIVER, address/2);
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void twi2c_stop(void) {
 | 
			
		||||
  i2cUnmatchAll(&I2C_DRIVER);
 | 
			
		||||
  i2cStop(&I2C_DRIVER);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,9 @@
 | 
			
		|||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef TWI2C_H
 | 
			
		||||
#define TWI2C_H
 | 
			
		||||
 | 
			
		||||
#include "ch.h"
 | 
			
		||||
#include "hal.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -23,17 +26,11 @@
 | 
			
		|||
 | 
			
		||||
#define slaveI2Caddress  0x30       /* Address in our terms - halved by later code */
 | 
			
		||||
//#define myOtherI2Caddress 0x19
 | 
			
		||||
 | 
			
		||||
#ifdef I2C_SLAVE_ENABLE
 | 
			
		||||
 | 
			
		||||
I2CSlaveMsgCB twi2c_slave_message_process, catchError, clearAfterSend;
 | 
			
		||||
 | 
			
		||||
void twi2c_slave_init(void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
I2CSlaveMsgCB twi2c_incoming_message_process, twi2c_catch_error, twi2c_clear_after_send;
 | 
			
		||||
typedef void (*twi2c_message_received)(I2CDriver *, uint8_t *, uint16_t);
 | 
			
		||||
 | 
			
		||||
void twi2c_init(void);
 | 
			
		||||
uint8_t twi2c_start(uint8_t address);
 | 
			
		||||
uint8_t twi2c_start(void);
 | 
			
		||||
uint8_t twi2c_write(uint8_t data);
 | 
			
		||||
uint8_t twi2c_read_ack(void);
 | 
			
		||||
uint8_t twi2c_read_nack(void);
 | 
			
		||||
| 
						 | 
				
			
			@ -42,3 +39,10 @@ uint8_t twi2c_receive(uint8_t address, uint8_t* data, uint16_t length);
 | 
			
		|||
uint8_t twi2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length);
 | 
			
		||||
uint8_t twi2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length);
 | 
			
		||||
void twi2c_stop(void);
 | 
			
		||||
 | 
			
		||||
uint8_t twi2c_reply(I2CDriver * i2cp, uint8_t * data, uint16_t length);
 | 
			
		||||
uint8_t twi2c_transmit_receive(uint8_t address, uint8_t * tx_body, uint16_t tx_length, uint8_t * rx_body, uint16_t rx_length);
 | 
			
		||||
uint8_t twi2c_start_listening(uint8_t address, twi2c_message_received callback);
 | 
			
		||||
uint8_t twi2c_restart_listening(uint8_t address);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										199
									
								
								drivers/qwiic/qwiic_keyboard.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								drivers/qwiic/qwiic_keyboard.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,199 @@
 | 
			
		|||
/* Copyright 2018 Jack Humbert
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "qwiic_keyboard.h"
 | 
			
		||||
#include "keymap.h"
 | 
			
		||||
#include "matrix.h"
 | 
			
		||||
#include "keyboard.h"
 | 
			
		||||
#include "twi2c.h"
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "usb_main.h"
 | 
			
		||||
#include "usb_driver.h"
 | 
			
		||||
 | 
			
		||||
#define QWIIC_KEYBOARD_LAYERS 16
 | 
			
		||||
#define QWIIC_KEYBOARD_ROWS 8
 | 
			
		||||
#define QWIIC_KEYBOARD_COLS 8
 | 
			
		||||
 | 
			
		||||
#define qwiic_matrix_t uint8_t
 | 
			
		||||
 | 
			
		||||
#define QWIIC_KEYBOARD_HANDSHAKE_ADDRESS       0b01010100
 | 
			
		||||
#define QWIIC_KEYBOARD_LISTENING_ADDRESS_START 0b01010110
 | 
			
		||||
#define QWIIC_KEYBOARD_HANDSHAKE_MESSAGE_SIZE  (QWIIC_KEYBOARD_LAYERS * QWIIC_KEYBOARD_ROWS * QWIIC_KEYBOARD_COLS)
 | 
			
		||||
#define QWIIC_KEYBOARD_MATRIX_MESSAGE_SIZE     MATRIX_ROWS
 | 
			
		||||
 | 
			
		||||
void qwiic_keyboard_write_keymap(uint8_t * pointer);
 | 
			
		||||
void qwiic_keyboard_read_keymap(uint8_t * pointer);
 | 
			
		||||
 | 
			
		||||
bool qwiic_keyboard_master = false;
 | 
			
		||||
bool qwiic_keyboard_connected = false;
 | 
			
		||||
uint8_t qwiic_keyboard_handshake_message[QWIIC_KEYBOARD_HANDSHAKE_MESSAGE_SIZE] = {0};
 | 
			
		||||
uint8_t qwiic_keyboard_matrix_message[QWIIC_KEYBOARD_ROWS] = {0};
 | 
			
		||||
twi2c_message_received qwiic_keyboard_message_received_ptr = qwiic_keyboard_message_received;
 | 
			
		||||
 | 
			
		||||
uint16_t qwiic_keyboard_keymap[QWIIC_KEYBOARD_LAYERS][QWIIC_KEYBOARD_ROWS][QWIIC_KEYBOARD_COLS] = {0};
 | 
			
		||||
uint8_t qwiic_keyboard_listening_address = QWIIC_KEYBOARD_LISTENING_ADDRESS_START;
 | 
			
		||||
uint8_t qwiic_keyboard_processing_slave = false;
 | 
			
		||||
 | 
			
		||||
void qwiic_keyboard_init(void) {
 | 
			
		||||
  twi2c_init();
 | 
			
		||||
  twi2c_start();
 | 
			
		||||
  twi2c_start_listening(QWIIC_KEYBOARD_HANDSHAKE_ADDRESS, qwiic_keyboard_message_received_ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qwiic_keyboard_set_master(void) {
 | 
			
		||||
  twi2c_stop();
 | 
			
		||||
  twi2c_start();
 | 
			
		||||
  qwiic_keyboard_master = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t command[1] = { 0x00 };
 | 
			
		||||
 | 
			
		||||
void qwiic_keyboard_task(void) {
 | 
			
		||||
  if (USB_DRIVER.state == USB_ACTIVE)
 | 
			
		||||
    qwiic_keyboard_master = true;
 | 
			
		||||
  else
 | 
			
		||||
    qwiic_keyboard_master = false;
 | 
			
		||||
  if (qwiic_keyboard_master) {
 | 
			
		||||
    if (qwiic_keyboard_connected) {
 | 
			
		||||
      // send empty message, expecting matrix info
 | 
			
		||||
      if (MSG_OK == twi2c_transmit_receive(qwiic_keyboard_listening_address,
 | 
			
		||||
        command, 1,
 | 
			
		||||
        qwiic_keyboard_matrix_message, QWIIC_KEYBOARD_MATRIX_MESSAGE_SIZE
 | 
			
		||||
      )) {
 | 
			
		||||
        // majority of this is pulled from keyboard.c:keyboard_task()
 | 
			
		||||
        static qwiic_matrix_t matrix_prev[QWIIC_KEYBOARD_ROWS];
 | 
			
		||||
        qwiic_matrix_t matrix_row = 0;
 | 
			
		||||
        qwiic_matrix_t matrix_change = 0;
 | 
			
		||||
        qwiic_keyboard_processing_slave = true;
 | 
			
		||||
        for (uint8_t r = 0; r < QWIIC_KEYBOARD_ROWS; r++) {
 | 
			
		||||
          matrix_row = qwiic_keyboard_matrix_message[r];
 | 
			
		||||
          matrix_change = matrix_row ^ matrix_prev[r];
 | 
			
		||||
          if (matrix_change) {
 | 
			
		||||
            for (uint8_t c = 0; c < QWIIC_KEYBOARD_COLS; c++) {
 | 
			
		||||
              if (matrix_change & ((qwiic_matrix_t)1<<c)) {
 | 
			
		||||
                action_exec((keyevent_t){
 | 
			
		||||
                  .key = (keypos_t){ .row = r, .col = c },
 | 
			
		||||
                  .pressed = (matrix_row & ((qwiic_matrix_t)1<<c)),
 | 
			
		||||
                  .time = (timer_read() | 1) /* time should not be 0 */
 | 
			
		||||
                });
 | 
			
		||||
                // record a processed key
 | 
			
		||||
                matrix_prev[r] ^= ((qwiic_matrix_t)1<<c);
 | 
			
		||||
                #ifdef QMK_KEYS_PER_SCAN
 | 
			
		||||
                  // only jump out if we have processed "enough" keys.
 | 
			
		||||
                  if (++keys_processed >= QMK_KEYS_PER_SCAN)
 | 
			
		||||
                #endif
 | 
			
		||||
                // process a key per task call
 | 
			
		||||
                //goto MATRIX_LOOP_END;
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        // call with pseudo tick event when no real key event.
 | 
			
		||||
        #ifdef QMK_KEYS_PER_SCAN
 | 
			
		||||
          // we can get here with some keys processed now.
 | 
			
		||||
          if (!keys_processed)
 | 
			
		||||
        #endif
 | 
			
		||||
        action_exec(TICK);
 | 
			
		||||
        //MATRIX_LOOP_END:
 | 
			
		||||
        qwiic_keyboard_processing_slave = false;
 | 
			
		||||
      } else {
 | 
			
		||||
        // disconnect
 | 
			
		||||
        // qwiic_keyboard_connected = false;
 | 
			
		||||
      }
 | 
			
		||||
    } else { // if not connected
 | 
			
		||||
      // send new address to listen on, expect back keymap
 | 
			
		||||
      if (MSG_OK == twi2c_transmit_receive(QWIIC_KEYBOARD_HANDSHAKE_ADDRESS,
 | 
			
		||||
        &qwiic_keyboard_listening_address, 1,
 | 
			
		||||
        qwiic_keyboard_handshake_message, QWIIC_KEYBOARD_HANDSHAKE_MESSAGE_SIZE
 | 
			
		||||
      )) {
 | 
			
		||||
        qwiic_keyboard_connected = true;
 | 
			
		||||
        // load keymap into memory
 | 
			
		||||
        qwiic_keyboard_read_keymap(qwiic_keyboard_handshake_message);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float song_one_up[][2]  = SONG(ONE_UP_SOUND);
 | 
			
		||||
bool first_message = true;
 | 
			
		||||
 | 
			
		||||
void qwiic_keyboard_message_received(I2CDriver *i2cp, uint8_t * body, uint16_t size) {
 | 
			
		||||
  if (qwiic_keyboard_connected) {
 | 
			
		||||
    for (uint8_t row = 0; row < QWIIC_KEYBOARD_ROWS; row++) {
 | 
			
		||||
      if (row < MATRIX_ROWS) {
 | 
			
		||||
        qwiic_keyboard_matrix_message[row] = matrix_get_row(row);
 | 
			
		||||
      } else {
 | 
			
		||||
        qwiic_keyboard_matrix_message[row] = 0;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    twi2c_reply(i2cp, qwiic_keyboard_matrix_message, QWIIC_KEYBOARD_MATRIX_MESSAGE_SIZE);
 | 
			
		||||
    if (first_message) {
 | 
			
		||||
      PLAY_SONG(song_one_up);
 | 
			
		||||
      first_message = false;
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    qwiic_keyboard_connected = true;
 | 
			
		||||
    qwiic_keyboard_master = false;
 | 
			
		||||
    qwiic_keyboard_listening_address = body[0];
 | 
			
		||||
    twi2c_restart_listening(qwiic_keyboard_listening_address);
 | 
			
		||||
    qwiic_keyboard_write_keymap(qwiic_keyboard_handshake_message);
 | 
			
		||||
    twi2c_reply(i2cp, qwiic_keyboard_handshake_message, QWIIC_KEYBOARD_HANDSHAKE_MESSAGE_SIZE);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// qwiic_keyboard_message_received_ptr = qwiic_keyboard_message_received;
 | 
			
		||||
 | 
			
		||||
__attribute__((optimize("O0")))
 | 
			
		||||
void qwiic_keyboard_write_keymap(uint8_t * pointer) {
 | 
			
		||||
  for (uint8_t layer = 0; layer < QWIIC_KEYBOARD_LAYERS; layer++) {
 | 
			
		||||
    for (uint8_t row = 0; row < QWIIC_KEYBOARD_ROWS; row++) {
 | 
			
		||||
      for (uint8_t col = 0; col < QWIIC_KEYBOARD_COLS; col++) {
 | 
			
		||||
        uint16_t keycode = pgm_read_word(&keymaps[layer][row][col]);
 | 
			
		||||
        *pointer++ = (keycode >> 8);
 | 
			
		||||
        *pointer++ = (keycode & 0xFF);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qwiic_keyboard_read_keymap(uint8_t * pointer) {
 | 
			
		||||
  for (uint8_t layer = 0; layer < QWIIC_KEYBOARD_LAYERS; layer++) {
 | 
			
		||||
    for (uint8_t row = 0; row < QWIIC_KEYBOARD_ROWS; row++) {
 | 
			
		||||
      for (uint8_t col = 0; col < QWIIC_KEYBOARD_COLS; col++) {
 | 
			
		||||
        uint16_t keycode = *pointer++;
 | 
			
		||||
        keycode |= ((*pointer++) << 8);
 | 
			
		||||
        qwiic_keyboard_keymap[layer][row][col] = keycode;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// overwrite the built-in function - slaves don't need to process keycodes
 | 
			
		||||
bool is_keyboard_master(void) {
 | 
			
		||||
  return qwiic_keyboard_master;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// overwrite the built-in function
 | 
			
		||||
uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) {
 | 
			
		||||
  if (qwiic_keyboard_processing_slave) {
 | 
			
		||||
    // trick the built-in handling to accept our replacement keymap
 | 
			
		||||
    //return qwiic_keyboard_keymap[(layer)][(key.row)][(key.col)];
 | 
			
		||||
    return KC_A;
 | 
			
		||||
  } else {
 | 
			
		||||
    // Read entire word (16bits)
 | 
			
		||||
    return pgm_read_word(&keymaps[(layer)][(key.row)][(key.col)]);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								drivers/qwiic/qwiic_keyboard.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								drivers/qwiic/qwiic_keyboard.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
/* Copyright 2018 Jack Humbert
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef QWIIC_KEYBOARD_H
 | 
			
		||||
#define QWIIC_KEYBOARD_H
 | 
			
		||||
 | 
			
		||||
#include "quantum.h"
 | 
			
		||||
 | 
			
		||||
void qwiic_keyboard_init(void);
 | 
			
		||||
void qwiic_keyboard_task(void);
 | 
			
		||||
void qwiic_keyboard_message_received(I2CDriver *i2cp, uint8_t * body, uint16_t size);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
# The default keymap for clueboard 60%
 | 
			
		||||
| 
						 | 
				
			
			@ -149,4 +149,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#define DRIVER_2_LED_TOTAL 24
 | 
			
		||||
#define DRIVER_LED_TOTAL DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL
 | 
			
		||||
 | 
			
		||||
#define NO_USB_STARTUP_CHECK
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,6 +79,13 @@
 | 
			
		|||
#define HAL_USE_I2C                 TRUE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief   Enables the I2C Slave subsystem.
 | 
			
		||||
 */
 | 
			
		||||
#if !defined(HAL_USE_I2C_SLAVE) || defined(__DOXYGEN__)
 | 
			
		||||
#define HAL_USE_I2C_SLAVE           TRUE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief   Enables the I2S subsystem.
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,13 +28,13 @@ void matrix_scan_kb(void) {
 | 
			
		|||
  matrix_scan_user();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void suspend_power_down_kb(void) {
 | 
			
		||||
  rgb_matrix_set_suspend_state(true);
 | 
			
		||||
}
 | 
			
		||||
// void suspend_power_down_kb(void) {
 | 
			
		||||
//   rgb_matrix_set_suspend_state(true);
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
void suspend_wakeup_init_kb(void) {
 | 
			
		||||
  rgb_matrix_set_suspend_state(false);
 | 
			
		||||
}
 | 
			
		||||
// void suspend_wakeup_init_kb(void) {
 | 
			
		||||
//   rgb_matrix_set_suspend_state(false);
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
const uint8_t music_map[MATRIX_ROWS][MATRIX_COLS] = LAYOUT_ortho_4x6(
 | 
			
		||||
  18, 19, 20, 21, 22, 23,
 | 
			
		||||
| 
						 | 
				
			
			@ -43,73 +43,73 @@ const uint8_t music_map[MATRIX_ROWS][MATRIX_COLS] = LAYOUT_ortho_4x6(
 | 
			
		|||
  0,  1,  2,  3,  4,  5
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
 | 
			
		||||
/* Refer to IS31 manual for these locations
 | 
			
		||||
 *   driver
 | 
			
		||||
 *   |  R location
 | 
			
		||||
 *   |  |      G location
 | 
			
		||||
 *   |  |      |      B location
 | 
			
		||||
 *   |  |      |      | */
 | 
			
		||||
    {0, C1_3,  C2_3,  C3_3},
 | 
			
		||||
    {0, C1_4,  C2_4,  C3_4},
 | 
			
		||||
    {0, C1_5,  C2_5,  C3_5},
 | 
			
		||||
    {0, C1_11, C2_11, C3_11},
 | 
			
		||||
    {0, C1_12, C2_12, C3_12},
 | 
			
		||||
    {0, C1_13, C2_13, C3_13},
 | 
			
		||||
// const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
 | 
			
		||||
// /* Refer to IS31 manual for these locations
 | 
			
		||||
//  *   driver
 | 
			
		||||
//  *   |  R location
 | 
			
		||||
//  *   |  |      G location
 | 
			
		||||
//  *   |  |      |      B location
 | 
			
		||||
//  *   |  |      |      | */
 | 
			
		||||
//     {0, C1_3,  C2_3,  C3_3},
 | 
			
		||||
//     {0, C1_4,  C2_4,  C3_4},
 | 
			
		||||
//     {0, C1_5,  C2_5,  C3_5},
 | 
			
		||||
//     {0, C1_11, C2_11, C3_11},
 | 
			
		||||
//     {0, C1_12, C2_12, C3_12},
 | 
			
		||||
//     {0, C1_13, C2_13, C3_13},
 | 
			
		||||
 | 
			
		||||
    {0, C1_6,  C2_6,  C3_6},
 | 
			
		||||
    {0, C1_7,  C2_7,  C3_7},
 | 
			
		||||
    {0, C1_8,  C2_8,  C3_8},
 | 
			
		||||
    {0, C1_14, C2_14, C3_14},
 | 
			
		||||
    {0, C1_15, C2_15, C3_15},
 | 
			
		||||
    {0, C1_16, C2_16, C3_16},
 | 
			
		||||
//     {0, C1_6,  C2_6,  C3_6},
 | 
			
		||||
//     {0, C1_7,  C2_7,  C3_7},
 | 
			
		||||
//     {0, C1_8,  C2_8,  C3_8},
 | 
			
		||||
//     {0, C1_14, C2_14, C3_14},
 | 
			
		||||
//     {0, C1_15, C2_15, C3_15},
 | 
			
		||||
//     {0, C1_16, C2_16, C3_16},
 | 
			
		||||
 | 
			
		||||
    {0, C9_1,  C8_1,  C7_1},
 | 
			
		||||
    {0, C9_2,  C8_2,  C7_2},
 | 
			
		||||
    {0, C9_3,  C8_3,  C7_3},
 | 
			
		||||
    {0, C9_9,  C8_9,  C7_9},
 | 
			
		||||
    {0, C9_10, C8_10, C7_10},
 | 
			
		||||
    {0, C9_11, C8_11, C7_11},
 | 
			
		||||
//     {0, C9_1,  C8_1,  C7_1},
 | 
			
		||||
//     {0, C9_2,  C8_2,  C7_2},
 | 
			
		||||
//     {0, C9_3,  C8_3,  C7_3},
 | 
			
		||||
//     {0, C9_9,  C8_9,  C7_9},
 | 
			
		||||
//     {0, C9_10, C8_10, C7_10},
 | 
			
		||||
//     {0, C9_11, C8_11, C7_11},
 | 
			
		||||
 | 
			
		||||
    {0, C9_4,  C8_4,  C7_4},
 | 
			
		||||
    {0, C9_5,  C8_5,  C7_5},
 | 
			
		||||
    {0, C9_6,  C8_6,  C7_6},
 | 
			
		||||
    {0, C9_12, C8_12, C7_12},
 | 
			
		||||
    {0, C9_13, C8_13, C7_13},
 | 
			
		||||
    {0, C9_14, C8_14, C7_14}
 | 
			
		||||
};
 | 
			
		||||
//     {0, C9_4,  C8_4,  C7_4},
 | 
			
		||||
//     {0, C9_5,  C8_5,  C7_5},
 | 
			
		||||
//     {0, C9_6,  C8_6,  C7_6},
 | 
			
		||||
//     {0, C9_12, C8_12, C7_12},
 | 
			
		||||
//     {0, C9_13, C8_13, C7_13},
 | 
			
		||||
//     {0, C9_14, C8_14, C7_14}
 | 
			
		||||
// };
 | 
			
		||||
 | 
			
		||||
const rgb_led g_rgb_leds[DRIVER_LED_TOTAL] = {
 | 
			
		||||
// const rgb_led g_rgb_leds[DRIVER_LED_TOTAL] = {
 | 
			
		||||
 | 
			
		||||
    /*{row | col << 4}
 | 
			
		||||
      |             {x=0..224, y=0..64}
 | 
			
		||||
      |              |                 modifier
 | 
			
		||||
      |              |                 | */
 | 
			
		||||
    {{0|(0<<4)},   {20.36*0, 21.33*0}, 1},
 | 
			
		||||
    {{0|(1<<4)},   {20.36*1, 21.33*0}, 0},
 | 
			
		||||
    {{0|(2<<4)},   {20.36*2, 21.33*0}, 0},
 | 
			
		||||
    {{0|(3<<4)},   {20.36*3, 21.33*0}, 0},
 | 
			
		||||
    {{0|(4<<4)},   {20.36*4, 21.33*0}, 0},
 | 
			
		||||
    {{0|(5<<4)},   {20.36*5, 21.33*0}, 0},
 | 
			
		||||
//     {row | col << 4}
 | 
			
		||||
//       |             {x=0..224, y=0..64}
 | 
			
		||||
//       |              |                 modifier
 | 
			
		||||
//       |              |                 |
 | 
			
		||||
//     {{0|(0<<4)},   {20.36*0, 21.33*0}, 1},
 | 
			
		||||
//     {{0|(1<<4)},   {20.36*1, 21.33*0}, 0},
 | 
			
		||||
//     {{0|(2<<4)},   {20.36*2, 21.33*0}, 0},
 | 
			
		||||
//     {{0|(3<<4)},   {20.36*3, 21.33*0}, 0},
 | 
			
		||||
//     {{0|(4<<4)},   {20.36*4, 21.33*0}, 0},
 | 
			
		||||
//     {{0|(5<<4)},   {20.36*5, 21.33*0}, 0},
 | 
			
		||||
 | 
			
		||||
    {{1|(0<<4)},   {20.36*0, 21.33*1}, 1},
 | 
			
		||||
    {{1|(1<<4)},   {20.36*1, 21.33*1}, 0},
 | 
			
		||||
    {{1|(2<<4)},   {20.36*2, 21.33*1}, 0},
 | 
			
		||||
    {{1|(3<<4)},   {20.36*3, 21.33*1}, 0},
 | 
			
		||||
    {{1|(4<<4)},   {20.36*4, 21.33*1}, 0},
 | 
			
		||||
    {{1|(5<<4)},   {20.36*5, 21.33*1}, 0},
 | 
			
		||||
//     {{1|(0<<4)},   {20.36*0, 21.33*1}, 1},
 | 
			
		||||
//     {{1|(1<<4)},   {20.36*1, 21.33*1}, 0},
 | 
			
		||||
//     {{1|(2<<4)},   {20.36*2, 21.33*1}, 0},
 | 
			
		||||
//     {{1|(3<<4)},   {20.36*3, 21.33*1}, 0},
 | 
			
		||||
//     {{1|(4<<4)},   {20.36*4, 21.33*1}, 0},
 | 
			
		||||
//     {{1|(5<<4)},   {20.36*5, 21.33*1}, 0},
 | 
			
		||||
 | 
			
		||||
    {{2|(0<<4)},   {20.36*0, 21.33*2}, 1},
 | 
			
		||||
    {{2|(1<<4)},   {20.36*1, 21.33*2}, 0},
 | 
			
		||||
    {{2|(2<<4)},   {20.36*2, 21.33*2}, 0},
 | 
			
		||||
    {{2|(3<<4)},   {20.36*3, 21.33*2}, 0},
 | 
			
		||||
    {{2|(4<<4)},   {20.36*4, 21.33*2}, 0},
 | 
			
		||||
    {{2|(5<<4)},   {20.36*5, 21.33*2}, 0},
 | 
			
		||||
//     {{2|(0<<4)},   {20.36*0, 21.33*2}, 1},
 | 
			
		||||
//     {{2|(1<<4)},   {20.36*1, 21.33*2}, 0},
 | 
			
		||||
//     {{2|(2<<4)},   {20.36*2, 21.33*2}, 0},
 | 
			
		||||
//     {{2|(3<<4)},   {20.36*3, 21.33*2}, 0},
 | 
			
		||||
//     {{2|(4<<4)},   {20.36*4, 21.33*2}, 0},
 | 
			
		||||
//     {{2|(5<<4)},   {20.36*5, 21.33*2}, 0},
 | 
			
		||||
 | 
			
		||||
    {{3|(0<<4)},   {20.36*0, 21.33*3}, 1},
 | 
			
		||||
    {{3|(1<<4)},   {20.36*1, 21.33*3}, 1},
 | 
			
		||||
    {{3|(2<<4)},   {20.36*2, 21.33*3}, 1},
 | 
			
		||||
    {{3|(3<<4)},   {20.36*3, 21.33*3}, 1},
 | 
			
		||||
    {{3|(4<<4)},   {20.36*4, 21.33*3}, 1},
 | 
			
		||||
    {{3|(5<<4)},   {20.36*5, 21.33*3}, 0}
 | 
			
		||||
};
 | 
			
		||||
//     {{3|(0<<4)},   {20.36*0, 21.33*3}, 1},
 | 
			
		||||
//     {{3|(1<<4)},   {20.36*1, 21.33*3}, 1},
 | 
			
		||||
//     {{3|(2<<4)},   {20.36*2, 21.33*3}, 1},
 | 
			
		||||
//     {{3|(3<<4)},   {20.36*3, 21.33*3}, 1},
 | 
			
		||||
//     {{3|(4<<4)},   {20.36*4, 21.33*3}, 1},
 | 
			
		||||
//     {{3|(5<<4)},   {20.36*5, 21.33*3}, 0}
 | 
			
		||||
// };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,12 +51,13 @@ COMMAND_ENABLE = yes    # Commands for debug and configuration
 | 
			
		|||
NKRO_ENABLE = yes     # USB Nkey Rollover
 | 
			
		||||
CUSTOM_MATRIX = yes # Custom matrix file
 | 
			
		||||
AUDIO_ENABLE = yes
 | 
			
		||||
RGB_MATRIX_ENABLE = yes
 | 
			
		||||
ENCODER_ENABLE = yes
 | 
			
		||||
# RGB_MATRIX_ENABLE = yes
 | 
			
		||||
# ENCODER_ENABLE = yes
 | 
			
		||||
# SERIAL_LINK_ENABLE = yes
 | 
			
		||||
I2C_SLAVE_ENABLE = yes
 | 
			
		||||
QWIIC_KEYBOARD_ENABLE = yes
 | 
			
		||||
 | 
			
		||||
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
 | 
			
		||||
SLEEP_LED_ENABLE = no    # Breathing sleep LED during USB suspend
 | 
			
		||||
 | 
			
		||||
LAYOUTS = ortho_4x6
 | 
			
		||||
LAYOUTS_HAS_RGB = no
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,8 +23,8 @@
 | 
			
		|||
#define PRODUCT_ID      0x1770
 | 
			
		||||
#define DEVICE_VER      0x0001
 | 
			
		||||
#define MANUFACTURER    QMK
 | 
			
		||||
#define PRODUCT         Handwire
 | 
			
		||||
#define DESCRIPTION     "Handwire protoboard"
 | 
			
		||||
#define PRODUCT         Proton C
 | 
			
		||||
#define DESCRIPTION     "Proton C protoboard"
 | 
			
		||||
 | 
			
		||||
/* key matrix size */
 | 
			
		||||
#define MATRIX_ROWS 12
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
#include "_qmk_handwire.h"
 | 
			
		||||
#include QMK_KEYBOARD_H
 | 
			
		||||
 | 
			
		||||
#define _______ KC_TRNS
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								keyboards/proton_c/keymaps/default/readme.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								keyboards/proton_c/keymaps/default/readme.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
# The default keymap for the Proton C
 | 
			
		||||
| 
						 | 
				
			
			@ -14,7 +14,7 @@
 | 
			
		|||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
#include "_qmk_handwire.h"
 | 
			
		||||
#include "proton_c.h"
 | 
			
		||||
 | 
			
		||||
void matrix_init_kb(void) {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -14,15 +14,15 @@
 | 
			
		|||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef QMK_HANDWIRE_H
 | 
			
		||||
#define QMK_HANDWIRE_H
 | 
			
		||||
#ifndef PROTON_C_H
 | 
			
		||||
#define PROTON_C_H
 | 
			
		||||
 | 
			
		||||
#include "quantum.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * These are shortcuts to help you work with the various layout options. If your 
 | 
			
		||||
 * These are shortcuts to help you work with the various layout options. If your
 | 
			
		||||
 * keymap works with one of the LAYOUT_...() macros you are encouraged to use that
 | 
			
		||||
 * and to contribute your keymap to the corresponding layout in 
 | 
			
		||||
 * and to contribute your keymap to the corresponding layout in
 | 
			
		||||
 * `qmk_firmware/layouts/community`.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -56,4 +56,4 @@
 | 
			
		|||
    { k50, k51, k52, 0,   0,   0,   0   } \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,14 +1,14 @@
 | 
			
		|||
# QMK Handwire
 | 
			
		||||
# Proton C
 | 
			
		||||
 | 
			
		||||
An Arm-based handwire board.
 | 
			
		||||
 | 
			
		||||
* Keyboard Maintainer: [Jack Humbert](https://github.com/jackhumbert)
 | 
			
		||||
* Hardware Supported: QMK Handwire
 | 
			
		||||
* Hardware Supported: QMK Proton C
 | 
			
		||||
  * rev1 (1.0)
 | 
			
		||||
* Hardware Availability: [qmk.fm](https://qmk.fm/)
 | 
			
		||||
 | 
			
		||||
Make example for this keyboard (after setting up your build environment):
 | 
			
		||||
 | 
			
		||||
    make _qmk_handwire:default
 | 
			
		||||
    make proton_c:default
 | 
			
		||||
 | 
			
		||||
See [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.
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +1 @@
 | 
			
		|||
Subproject commit 587968d6cbc2b0e1c7147540872f2a67e59ca18b
 | 
			
		||||
Subproject commit c846437e39423ef9394aecd3a96393db24c51ebf
 | 
			
		||||
| 
						 | 
				
			
			@ -69,6 +69,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#ifdef MIDI_ENABLE
 | 
			
		||||
#   include "process_midi.h"
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef QWIIC_KEYBOARD_ENABLE
 | 
			
		||||
#   include "qwiic/qwiic_keyboard.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MATRIX_HAS_GHOST
 | 
			
		||||
extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
 | 
			
		||||
| 
						 | 
				
			
			@ -181,11 +184,14 @@ void keyboard_init(void) {
 | 
			
		|||
#if defined(NKRO_ENABLE) && defined(FORCE_NKRO)
 | 
			
		||||
    keymap_config.nkro = 1;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef QWIIC_KEYBOARD_ENABLE
 | 
			
		||||
    qwiic_keyboard_init();
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** \brief Keyboard task: Do keyboard routine jobs
 | 
			
		||||
 *
 | 
			
		||||
 * Do routine keyboard jobs: 
 | 
			
		||||
 * Do routine keyboard jobs:
 | 
			
		||||
 *
 | 
			
		||||
 * * scan matrix
 | 
			
		||||
 * * handle mouse movements
 | 
			
		||||
| 
						 | 
				
			
			@ -291,6 +297,10 @@ MATRIX_LOOP_END:
 | 
			
		|||
    midi_task();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef QWIIC_KEYBOARD_ENABLE
 | 
			
		||||
    qwiic_keyboard_task();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // update LED
 | 
			
		||||
    if (led_status != host_keyboard_leds()) {
 | 
			
		||||
        led_status = host_keyboard_leds();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue