Compare commits
95 Commits
0.6.41
...
muon_light
| Author | SHA1 | Date | |
|---|---|---|---|
| 47c27bb6b9 | |||
| 19e0bc852f | |||
| 32028cfc43 | |||
| 9ddb678fd0 | |||
| 6c68cccd90 | |||
| f9c61b1bbe | |||
| c11c7948e6 | |||
| 3775c92ff8 | |||
| d01f40edbf | |||
| 13f49ad8d9 | |||
| 0f89d7efed | |||
| 2fccc1a064 | |||
| 53c518f7d4 | |||
| 459dfa510e | |||
| 5bb1e7869c | |||
| 58c4ba096a | |||
| c8cc9c6aab | |||
| c53a8ead93 | |||
| a6afb16c90 | |||
| 21665df8eb | |||
| ff4a1ae5d2 | |||
| 018a0142d2 | |||
| c1f6f1308b | |||
| 274283420d | |||
| 874f5a5c07 | |||
| 161c68b48a | |||
| 5fad8d774d | |||
| 4fdc9badd3 | |||
| 835431330c | |||
| a75bd221f2 | |||
| 805b42275b | |||
| 7f5361aedb | |||
| 434a450be1 | |||
| 4bd64227fd | |||
| 8a9c19ee93 | |||
| 751719e6cb | |||
| 034a25aedf | |||
| eb8388b31e | |||
| edb149fb5a | |||
| 0f99562992 | |||
| eed6ef0999 | |||
| a87b36d791 | |||
| 6009ca2d4a | |||
| dfa7a708fe | |||
| 2b677ddac9 | |||
| 8ddebce2d7 | |||
| a677d8a00d | |||
| 3b1ddd12a5 | |||
| 716877b40a | |||
| 28525ab461 | |||
| 504ce1b4bc | |||
| 357d9f4772 | |||
| 6e867a7ecc | |||
| af6107bee8 | |||
| d233737c95 | |||
| 3e282ab203 | |||
| 1c0d85c143 | |||
| 7c19e9fa04 | |||
| 9fccfc8dd5 | |||
| 1cb72a9c59 | |||
| 82146ecfc0 | |||
| 4a1984d33e | |||
| 676080372c | |||
| 0af7415981 | |||
| df371458b3 | |||
| e0e5efbead | |||
| edb4460e64 | |||
| fe72bfa070 | |||
| 25642c8840 | |||
| 03b1904b2e | |||
| bb71a988c2 | |||
| ddee61c9ba | |||
| 91efe74365 | |||
| 12a64ff24b | |||
| b034896cd3 | |||
| 2bd625b754 | |||
| da32068f48 | |||
| b308d6709e | |||
| 123ad0de95 | |||
| 00fc38435f | |||
| 8b5b41bb47 | |||
| 4bdde668e1 | |||
| 3c0d86eb47 | |||
| f60166c1a1 | |||
| 7d59f83b2e | |||
| be81cd8c98 | |||
| b075df1c87 | |||
| 8a91aa5e6c | |||
| fae437cfad | |||
| fc91bf4a65 | |||
| 78ea99d154 | |||
| 2165f9d654 | |||
| 31df12c84f | |||
| d09d9f32bd | |||
| 690a08cbbb |
@@ -1,6 +1,7 @@
|
||||
[submodule "lib/chibios"]
|
||||
path = lib/chibios
|
||||
url = https://github.com/qmk/ChibiOS
|
||||
branch = handwire
|
||||
[submodule "lib/chibios-contrib"]
|
||||
path = lib/chibios-contrib
|
||||
url = https://github.com/qmk/ChibiOS-Contrib
|
||||
|
||||
@@ -3,16 +3,16 @@ include message.mk
|
||||
# Directory common source files exist
|
||||
TOP_DIR = .
|
||||
TMK_DIR = tmk_core
|
||||
TMK_PATH = $(TOP_DIR)/$(TMK_DIR)
|
||||
LIB_PATH = $(TOP_DIR)/lib
|
||||
TMK_PATH = $(TMK_DIR)
|
||||
LIB_PATH = lib
|
||||
|
||||
QUANTUM_DIR = quantum
|
||||
QUANTUM_PATH = $(TOP_DIR)/$(QUANTUM_DIR)
|
||||
QUANTUM_PATH = $(QUANTUM_DIR)
|
||||
|
||||
DRIVER_DIR = drivers
|
||||
DRIVER_PATH = $(TOP_DIR)/$(DRIVER_DIR)
|
||||
DRIVER_PATH = $(DRIVER_DIR)
|
||||
|
||||
BUILD_DIR := $(TOP_DIR)/.build
|
||||
BUILD_DIR := .build
|
||||
|
||||
COMMON_VPATH := $(TOP_DIR)
|
||||
COMMON_VPATH += $(TMK_PATH)
|
||||
@@ -21,4 +21,4 @@ COMMON_VPATH += $(QUANTUM_PATH)/keymap_extras
|
||||
COMMON_VPATH += $(QUANTUM_PATH)/audio
|
||||
COMMON_VPATH += $(QUANTUM_PATH)/process_keycode
|
||||
COMMON_VPATH += $(QUANTUM_PATH)/api
|
||||
COMMON_VPATH += $(DRIVER_PATH)
|
||||
COMMON_VPATH += $(DRIVER_PATH)
|
||||
|
||||
+27
-1
@@ -20,6 +20,13 @@ SERIAL_SRC += $(wildcard $(SERIAL_PATH)/system/*.c)
|
||||
SERIAL_DEFS += -DSERIAL_LINK_ENABLE
|
||||
COMMON_VPATH += $(SERIAL_PATH)
|
||||
|
||||
COMMON_VPATH += $(DRIVER_PATH)
|
||||
ifeq ($(PLATFORM),AVR)
|
||||
COMMON_VPATH += $(DRIVER_PATH)/avr
|
||||
else
|
||||
COMMON_VPATH += $(DRIVER_PATH)/arm
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(API_SYSEX_ENABLE)), yes)
|
||||
OPT_DEFS += -DAPI_SYSEX_ENABLE
|
||||
SRC += $(QUANTUM_DIR)/api/api_sysex.c
|
||||
@@ -117,7 +124,7 @@ endif
|
||||
ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
|
||||
OPT_DEFS += -DRGB_MATRIX_ENABLE
|
||||
SRC += is31fl3731.c
|
||||
SRC += i2c_master.c
|
||||
I2C_ENABLE = yes
|
||||
SRC += $(QUANTUM_DIR)/color.c
|
||||
SRC += $(QUANTUM_DIR)/rgb_matrix.c
|
||||
CIE1931_CURVE = yes
|
||||
@@ -197,6 +204,25 @@ ifeq ($(strip $(USB_HID_ENABLE)), yes)
|
||||
include $(TMK_DIR)/protocol/usb_hid.mk
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(I2C_SLAVE_ENABLE)), yes)
|
||||
I2C_ENABLE = yes
|
||||
OPT_DEFS += -DI2C_SLAVE_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(ENCODER_ENABLE)), yes)
|
||||
OPT_DEFS += -DENCODER_ENABLE
|
||||
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 \
|
||||
$(QUANTUM_DIR)/keymap_common.c \
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
* [Bootmagic](feature_bootmagic.md)
|
||||
* [Command](feature_command.md)
|
||||
* [Dynamic Macros](feature_dynamic_macros.md)
|
||||
* [Encoders](feature_encoders.md)
|
||||
* [Grave Escape](feature_grave_esc.md)
|
||||
* [Key Lock](feature_key_lock.md)
|
||||
* [Layouts](feature_layouts.md)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# Encoders
|
||||
|
||||
Basic encoders are supported by adding this to your `rules.mk`:
|
||||
|
||||
ENCODER_ENABLE = yes
|
||||
|
||||
and this to your `config.h`:
|
||||
|
||||
#define NUMBER_OF_ENCODERS 1
|
||||
#define ENCODERS_PAD_A { B12 }
|
||||
#define ENCODERS_PAD_B { B13 }
|
||||
|
||||
Each PAD_A/B variable defines an array so multiple encoders can be defined, e.g.:
|
||||
|
||||
#define ENCODERS_PAD_A { encoder1a, encoder2a }
|
||||
#define ENCODERS_PAD_B { encoder1a, encoder2b }
|
||||
|
||||
If your encoder's clockwise directions are incorrect, you can swap the A & B pad definitions.
|
||||
|
||||
Additionally, the resolution can be specified in the same file (the default & suggested is 4):
|
||||
|
||||
#define ENCODER_RESOLUTION 4
|
||||
|
||||
## Callbacks
|
||||
|
||||
The callback functions can be inserted into your `<keyboard>.c`:
|
||||
|
||||
void encoder_update_kb(uint8_t index, bool clockwise) {
|
||||
encoder_update_user(index, clockwise);
|
||||
}
|
||||
|
||||
or `keymap.c`:
|
||||
|
||||
void encoder_update_user(uint8_t index, bool clockwise) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
## Hardware
|
||||
|
||||
The A an B lines of the encoders should be wired directly to the MCU, and the C/common lines should be wired to ground.
|
||||
@@ -17,14 +17,16 @@ void matrix_scan_user(void) {
|
||||
leader_end();
|
||||
|
||||
SEQ_ONE_KEY(KC_F) {
|
||||
register_code(KC_S);
|
||||
unregister_code(KC_S);
|
||||
// Anything you can do in a macro.
|
||||
SEND_STRING("QMK is awesome.");
|
||||
}
|
||||
SEQ_TWO_KEYS(KC_D, KC_D) {
|
||||
SEND_STRING(SS_LCTRL("a")SS_LCTRL("c"));
|
||||
}
|
||||
SEQ_THREE_KEYS(KC_D, KC_D, KC_S) {
|
||||
SEND_STRING("https://start.duckduckgo.com"SS_TAP(X_ENTER));
|
||||
}
|
||||
SEQ_TWO_KEYS(KC_A, KC_S) {
|
||||
register_code(KC_H);
|
||||
unregister_code(KC_H);
|
||||
}
|
||||
SEQ_THREE_KEYS(KC_A, KC_S, KC_D) {
|
||||
register_code(KC_LGUI);
|
||||
register_code(KC_S);
|
||||
unregister_code(KC_S);
|
||||
@@ -34,4 +36,6 @@ void matrix_scan_user(void) {
|
||||
}
|
||||
```
|
||||
|
||||
As you can see, you have three function. you can use - `SEQ_ONE_KEY` for single-key sequences (Leader followed by just one key), and `SEQ_TWO_KEYS` and `SEQ_THREE_KEYS` for longer sequences. Each of these accepts one or more keycodes as arguments. This is an important point: You can use keycodes from **any layer on your keyboard**. That layer would need to be active for the leader macro to fire, obviously.
|
||||
As you can see, you have a few function. You can use `SEQ_ONE_KEY` for single-key sequences (Leader followed by just one key), and `SEQ_TWO_KEYS`, `SEQ_THREE_KEYS` up to `SEQ_FIVE_KEYS` for longer sequences.
|
||||
|
||||
Each of these accepts one or more keycodes as arguments. This is an important point: You can use keycodes from **any layer on your keyboard**. That layer would need to be active for the leader macro to fire, obviously.
|
||||
|
||||
@@ -88,11 +88,36 @@ const uint16_t RGBLED_GRADIENT_RANGES[] PROGMEM = {360, 240, 180, 120, 90};
|
||||
Look in `rgblights.h` for all available functions, but if you want to control all or some LEDs your goto functions are:
|
||||
|
||||
```c
|
||||
rgblight_disable(); // turn all lights off
|
||||
rgblight_enable(); // turn lights on, based on their previous state (stored in EEPROM)
|
||||
// turn all lights off (stored in EEPROM)
|
||||
rgblight_disable();
|
||||
// turn lights on, based on their previous state (stored in EEPROM)
|
||||
rgblight_enable();
|
||||
|
||||
// turn all lights off (not stored in EEPROM)
|
||||
rgblight_disable_noeeprom();
|
||||
// turn lights on, based on their previous state (not stored in EEPROM)
|
||||
rgblight_enable_noeeprom();
|
||||
|
||||
// where r/g/b is a number from 0..255. Turns all the LEDs to this color (ignores mode, not stored in EEPROM).
|
||||
rgblight_setrgb(r, g, b);
|
||||
// HSV color control - h is a value from 0..360 and s/v is a value from 0..255 (stored in EEPROM)
|
||||
rgblight_sethsv(h, s, v);
|
||||
// HSV color control - h is a value from 0..360 and s/v is a value from 0..255 (not stored in EEPROM)
|
||||
rgblight_sethsv_noeeprom(h, s, v);
|
||||
|
||||
// Sets the mode, if rgb animations are enabled (stored in eeprom)
|
||||
rgblight_mode(x);
|
||||
// Sets the mode, if rgb animations are enabled (not stored in eeprom)
|
||||
rgblight_mode_noeeprom(x);
|
||||
// MODE 1, solid color
|
||||
// MODE 2-5, breathing
|
||||
// MODE 6-8, rainbow mood
|
||||
// MODE 9-14, rainbow swirl
|
||||
// MODE 15-20, snake
|
||||
// MODE 21-23, knight
|
||||
// MODE 24, xmas
|
||||
// MODE 25-34, static rainbow
|
||||
|
||||
rgblight_setrgb(r, g, b); // where r/g/b is a number from 0..255. Turns all the LEDs to this color
|
||||
rgblight_sethsv(h, s, v); // HSV color control - h is a value from 0..360 and s/v is a value from 0..255
|
||||
rgblight_setrgb_at(r,g,b, LED); // control a single LED. 0 <= LED < RGBLED_NUM
|
||||
rgblight_sethsv_at(h,s,v, LED); // control a single LED. 0 <= LED < RGBLED_NUM
|
||||
```
|
||||
@@ -126,7 +151,7 @@ note: for backwards compatibility, `RGB_SMOD` is an alias for `RGB_MOD`.
|
||||
|
||||
## Hardware Modification
|
||||
|
||||

|
||||

|
||||
|
||||
Here is a quick demo on Youtube (with NPKC KC60) (https://www.youtube.com/watch?v=VKrpPAHlisY).
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@ Hit the semicolon key once, send a semicolon. Hit it twice, rapidly -- send a co
|
||||
|
||||
With this feature one can specify keys that behave differently, based on the amount of times they have been tapped, and when interrupted, they get handled before the interrupter.
|
||||
|
||||
To make it clear how this is different from `ACTION_FUNCTION_TAP`, lets explore a certain setup! We want one key to send `Space` on single tap, but `Enter` on double-tap.
|
||||
To make it clear how this is different from `ACTION_FUNCTION_TAP`, let's explore a certain setup! We want one key to send `Space` on single tap, but `Enter` on double-tap.
|
||||
|
||||
With `ACTION_FUNCTION_TAP`, it is quite a rain-dance to set this up, and has the problem that when the sequence is interrupted, the interrupting key will be send first. Thus, `SPC a` will result in `a SPC` being sent, if they are typed within `TAPPING_TERM`. With the tap dance feature, that'll come out as `SPC a`, correctly.
|
||||
With `ACTION_FUNCTION_TAP`, it is quite a rain-dance to set this up, and has the problem that when the sequence is interrupted, the interrupting key will be sent first. Thus, `SPC a` will result in `a SPC` being sent, if they are typed within `TAPPING_TERM`. With the tap dance feature, that'll come out as `SPC a`, correctly.
|
||||
|
||||
The implementation hooks into two parts of the system, to achieve this: into `process_record_quantum()`, and the matrix scan. We need the latter to be able to time out a tap sequence even when a key is not being pressed, so `SPC` alone will time out and register after `TAPPING_TERM` time.
|
||||
|
||||
@@ -16,13 +16,13 @@ But lets start with how to use it, first!
|
||||
|
||||
First, you will need `TAP_DANCE_ENABLE=yes` in your `rules.mk`, because the feature is disabled by default. This adds a little less than 1k to the firmware size. Next, you will want to define some tap-dance keys, which is easiest to do with the `TD()` macro, that - similar to `F()`, takes a number, which will later be used as an index into the `tap_dance_actions` array.
|
||||
|
||||
This array specifies what actions shall be taken when a tap-dance key is in action. Currently, there are three possible options:
|
||||
This array specifies what actions shall be taken when a tap-dance key is in action. Currently, there are five possible options:
|
||||
|
||||
* `ACTION_TAP_DANCE_DOUBLE(kc1, kc2)`: Sends the `kc1` keycode when tapped once, `kc2` otherwise. When the key is held, the appropriate keycode is registered: `kc1` when pressed and held, `kc2` when tapped once, then pressed and held.
|
||||
* `ACTION_TAP_DANCE_DUAL_ROLE(kc, layer)`: Sends the `kc` keycode when tapped once, or moves to `layer`. (this functions like the `TO` layer keycode).
|
||||
* `ACTION_TAP_DANCE_FN(fn)`: Calls the specified function - defined in the user keymap - with the final tap count of the tap dance action.
|
||||
* `ACTION_TAP_DANCE_FN_ADVANCED(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn)`: Calls the first specified function - defined in the user keymap - on every tap, the second function on when the dance action finishes (like the previous option), and the last function when the tap dance action resets.
|
||||
** `ACTION_TAP_DANCE_FN_ADVANCED_TIME(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn, tap_specific_tapping_term)`: This functions identically to the `ACTION_TAP_DANCE_FN_ADVANCED` function, but uses a custom tapping term for it, instead of the predefined `TAPPING_TERM`.
|
||||
* `ACTION_TAP_DANCE_FN_ADVANCED(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn)`: Calls the first specified function - defined in the user keymap - on every tap, the second function when the dance action finishes (like the previous option), and the last function when the tap dance action resets.
|
||||
* `ACTION_TAP_DANCE_FN_ADVANCED_TIME(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn, tap_specific_tapping_term)`: This functions identically to the `ACTION_TAP_DANCE_FN_ADVANCED` function, but uses a custom tapping term for it, instead of the predefined `TAPPING_TERM`.
|
||||
|
||||
The first option is enough for a lot of cases, that just want dual roles. For example, `ACTION_TAP_DANCE_DOUBLE(KC_SPC, KC_ENT)` will result in `Space` being sent on single-tap, `Enter` otherwise.
|
||||
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
/* 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 "twi2c.h"
|
||||
#include <string.h>
|
||||
#include <hal.h>
|
||||
#include "chprintf.h"
|
||||
#include "memstreams.h"
|
||||
#include "printf.h"
|
||||
#include "hal_i2cslave.h"
|
||||
|
||||
/**
|
||||
* I2C slave test routine.
|
||||
*
|
||||
* To use: Add file to a project, call startComms() with the address of a serial stream
|
||||
*
|
||||
* There are two different responses:
|
||||
* a) A read-only transaction - returns the "Initial Reply" message
|
||||
* b) A write then read transaction - calls a message processor and returns the generated reply.
|
||||
* Stretches clock until reply available.
|
||||
*/
|
||||
// static const I2CConfig masterI2CConfig = {
|
||||
// 400000
|
||||
// };
|
||||
|
||||
I2CSlaveMsgCB twi2c_incoming_message_process, twi2c_catch_error, twi2c_clear_after_send;
|
||||
twi2c_message_received twi2c_message_received_callback;
|
||||
|
||||
static uint8_t twi2c_address;
|
||||
|
||||
static const I2CConfig i2cconfig = {
|
||||
STM32_TIMINGR_PRESC(15U) |
|
||||
STM32_TIMINGR_SCLDEL(4U) | STM32_TIMINGR_SDADEL(2U) |
|
||||
STM32_TIMINGR_SCLH(15U) | STM32_TIMINGR_SCLL(21U),
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
/**
|
||||
* Track I2C errors
|
||||
*/
|
||||
uint8_t gotI2cError = 0;
|
||||
uint32_t lastI2cErrorFlags = 0;
|
||||
|
||||
// Called from ISR to log error
|
||||
void noteI2cError(uint32_t flags)
|
||||
{
|
||||
lastI2cErrorFlags = flags;
|
||||
gotI2cError = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic error handler
|
||||
*
|
||||
* Called in interrupt context, so need to watch what we do
|
||||
*/
|
||||
void twi2c_catch_error(I2CDriver *i2cp)
|
||||
{
|
||||
noteI2cError(i2cp->errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback after sending of response complete - restores default reply in case polled
|
||||
*/
|
||||
void twi2c_clear_after_send(I2CDriver *i2cp)
|
||||
{
|
||||
// echoReply.size = 0; // Clear receive message
|
||||
// i2cSlaveReplyI(i2cp, &initialReply);
|
||||
}
|
||||
|
||||
uint8_t twi2c_start(void) {
|
||||
i2cStart(&I2C_DRIVER, &i2cconfig);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void twi2c_init(void) {
|
||||
palSetGroupMode(GPIOB,6,7, PAL_MODE_INPUT); // Try releasing special pins for a short time
|
||||
chThdSleepMilliseconds(10);
|
||||
|
||||
palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP);
|
||||
palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP);
|
||||
|
||||
// try high drive (from kiibohd)
|
||||
// I2C_DRIVER.i2c->C2 |= I2Cx_C2_HDRS;
|
||||
// try glitch fixing (from kiibohd)
|
||||
// I2C_DRIVER.i2c->FLT = 4;
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/* 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 TWI2C_H
|
||||
#define TWI2C_H
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#ifndef I2C_DRIVER
|
||||
#define I2C_DRIVER I2CD1
|
||||
#endif
|
||||
|
||||
#define slaveI2Caddress 0x30 /* Address in our terms - halved by later code */
|
||||
//#define myOtherI2Caddress 0x19
|
||||
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(void);
|
||||
uint8_t twi2c_write(uint8_t data);
|
||||
uint8_t twi2c_read_ack(void);
|
||||
uint8_t twi2c_read_nack(void);
|
||||
uint8_t twi2c_transmit(uint8_t address, uint8_t* data, uint16_t length);
|
||||
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
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* LEDDriver.c
|
||||
*
|
||||
* Created on: Aug 26, 2013
|
||||
* Author: Omri Iluz
|
||||
*/
|
||||
|
||||
#include "ws2812.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
static uint8_t *fb;
|
||||
static int sLeds;
|
||||
static stm32_gpio_t *sPort;
|
||||
static uint32_t sMask;
|
||||
uint8_t* dma_source;
|
||||
|
||||
void setColor(uint8_t color, uint8_t *buf,uint32_t mask){
|
||||
int i;
|
||||
for (i=0;i<8;i++){
|
||||
buf[i]=((color<<i)&0b10000000?0x0:mask);
|
||||
}
|
||||
}
|
||||
|
||||
void setColorRGB(Color c, uint8_t *buf, uint32_t mask){
|
||||
setColor(c.G,buf, mask);
|
||||
setColor(c.R,buf+8, mask);
|
||||
setColor(c.B,buf+16, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize Led Driver
|
||||
* @details Initialize the Led Driver based on parameters.
|
||||
* Following initialization, the frame buffer would automatically be
|
||||
* exported to the supplied port and pins in the right timing to drive
|
||||
* a chain of WS2812B controllers
|
||||
* @note The function assumes the controller is running at 72Mhz
|
||||
* @note Timing is critical for WS2812. While all timing is done in hardware
|
||||
* need to verify memory bandwidth is not exhausted to avoid DMA delays
|
||||
*
|
||||
* @param[in] leds length of the LED chain controlled by each pin
|
||||
* @param[in] port which port would be used for output
|
||||
* @param[in] mask Which pins would be used for output, each pin is a full chain
|
||||
* @param[out] o_fb initialized frame buffer
|
||||
*
|
||||
*/
|
||||
void ledDriverInit(int leds, stm32_gpio_t *port, uint32_t mask, uint8_t **o_fb) {
|
||||
sLeds=leds;
|
||||
sPort=port;
|
||||
sMask=mask;
|
||||
palSetGroupMode(port, sMask, 0, PAL_MODE_OUTPUT_PUSHPULL|PAL_STM32_OSPEED_HIGHEST|PAL_STM32_PUPDR_FLOATING);
|
||||
|
||||
// configure pwm timers -
|
||||
// timer 2 as master, active for data transmission and inactive to disable transmission during reset period (50uS)
|
||||
// timer 3 as slave, during active time creates a 1.25 uS signal, with duty cycle controlled by frame buffer values
|
||||
static PWMConfig pwmc2 = {72000000 / 90, /* 800Khz PWM clock frequency. 1/90 of PWMC3 */
|
||||
(72000000 / 90) * 0.05, /*Total period is 50ms (20FPS), including sLeds cycles + reset length for ws2812b and FB writes */
|
||||
NULL,
|
||||
{ {PWM_OUTPUT_ACTIVE_HIGH, NULL},
|
||||
{PWM_OUTPUT_DISABLED, NULL},
|
||||
{PWM_OUTPUT_DISABLED, NULL},
|
||||
{PWM_OUTPUT_DISABLED, NULL}},
|
||||
TIM_CR2_MMS_2, /* master mode selection */
|
||||
0, };
|
||||
/* master mode selection */
|
||||
static PWMConfig pwmc3 = {72000000,/* 72Mhz PWM clock frequency. */
|
||||
90, /* 90 cycles period (1.25 uS per period @72Mhz */
|
||||
NULL,
|
||||
{ {PWM_OUTPUT_ACTIVE_HIGH, NULL},
|
||||
{PWM_OUTPUT_ACTIVE_HIGH, NULL},
|
||||
{PWM_OUTPUT_ACTIVE_HIGH, NULL},
|
||||
{PWM_OUTPUT_ACTIVE_HIGH, NULL}},
|
||||
0,
|
||||
0,
|
||||
};
|
||||
dma_source = chHeapAlloc(NULL, 1);
|
||||
fb = chHeapAlloc(NULL, ((sLeds) * 24)+10);
|
||||
*o_fb=fb;
|
||||
int j;
|
||||
for (j = 0; j < (sLeds) * 24; j++) fb[j] = 0;
|
||||
dma_source[0] = sMask;
|
||||
// DMA stream 2, triggered by channel3 pwm signal. if FB indicates, reset output value early to indicate "0" bit to ws2812
|
||||
dmaStreamAllocate(STM32_DMA1_STREAM2, 10, NULL, NULL);
|
||||
dmaStreamSetPeripheral(STM32_DMA1_STREAM2, &(sPort->BSRR.H.clear));
|
||||
dmaStreamSetMemory0(STM32_DMA1_STREAM2, fb);
|
||||
dmaStreamSetTransactionSize(STM32_DMA1_STREAM2, (sLeds) * 24);
|
||||
dmaStreamSetMode(
|
||||
STM32_DMA1_STREAM2,
|
||||
STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_MINC | STM32_DMA_CR_PSIZE_BYTE
|
||||
| STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_CIRC | STM32_DMA_CR_PL(2));
|
||||
// DMA stream 3, triggered by pwm update event. output high at beginning of signal
|
||||
dmaStreamAllocate(STM32_DMA1_STREAM3, 10, NULL, NULL);
|
||||
dmaStreamSetPeripheral(STM32_DMA1_STREAM3, &(sPort->BSRR.H.set));
|
||||
dmaStreamSetMemory0(STM32_DMA1_STREAM3, dma_source);
|
||||
dmaStreamSetTransactionSize(STM32_DMA1_STREAM3, 1);
|
||||
dmaStreamSetMode(
|
||||
STM32_DMA1_STREAM3, STM32_DMA_CR_TEIE |
|
||||
STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE
|
||||
| STM32_DMA_CR_CIRC | STM32_DMA_CR_PL(3));
|
||||
// DMA stream 6, triggered by channel1 update event. reset output value late to indicate "1" bit to ws2812.
|
||||
// always triggers but no affect if dma stream 2 already change output value to 0
|
||||
dmaStreamAllocate(STM32_DMA1_STREAM6, 10, NULL, NULL);
|
||||
dmaStreamSetPeripheral(STM32_DMA1_STREAM6, &(sPort->BSRR.H.clear));
|
||||
dmaStreamSetMemory0(STM32_DMA1_STREAM6, dma_source);
|
||||
dmaStreamSetTransactionSize(STM32_DMA1_STREAM6, 1);
|
||||
dmaStreamSetMode(
|
||||
STM32_DMA1_STREAM6,
|
||||
STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE
|
||||
| STM32_DMA_CR_CIRC | STM32_DMA_CR_PL(3));
|
||||
pwmStart(&PWMD2, &pwmc2);
|
||||
pwmStart(&PWMD3, &pwmc3);
|
||||
// set pwm3 as slave, triggerd by pwm2 oc1 event. disables pwmd2 for synchronization.
|
||||
PWMD3.tim->SMCR |= TIM_SMCR_SMS_0 | TIM_SMCR_SMS_2 | TIM_SMCR_TS_0;
|
||||
PWMD2.tim->CR1 &= ~TIM_CR1_CEN;
|
||||
// set pwm values.
|
||||
// 28 (duty in ticks) / 90 (period in ticks) * 1.25uS (period in S) = 0.39 uS
|
||||
pwmEnableChannel(&PWMD3, 2, 28);
|
||||
// 58 (duty in ticks) / 90 (period in ticks) * 1.25uS (period in S) = 0.806 uS
|
||||
pwmEnableChannel(&PWMD3, 0, 58);
|
||||
// active during transfer of 90 cycles * sLeds * 24 bytes * 1/90 multiplier
|
||||
pwmEnableChannel(&PWMD2, 0, 90 * sLeds * 24 / 90);
|
||||
// stop and reset counters for synchronization
|
||||
PWMD2.tim->CNT = 0;
|
||||
// Slave (TIM3) needs to "update" immediately after master (TIM2) start in order to start in sync.
|
||||
// this initial sync is crucial for the stability of the run
|
||||
PWMD3.tim->CNT = 89;
|
||||
PWMD3.tim->DIER |= TIM_DIER_CC3DE | TIM_DIER_CC1DE | TIM_DIER_UDE;
|
||||
dmaStreamEnable(STM32_DMA1_STREAM3);
|
||||
dmaStreamEnable(STM32_DMA1_STREAM6);
|
||||
dmaStreamEnable(STM32_DMA1_STREAM2);
|
||||
// all systems go! both timers and all channels are configured to resonate
|
||||
// in complete sync without any need for CPU cycles (only DMA and timers)
|
||||
// start pwm2 for system to start resonating
|
||||
PWMD2.tim->CR1 |= TIM_CR1_CEN;
|
||||
}
|
||||
|
||||
void ledDriverWaitCycle(void){
|
||||
while (PWMD2.tim->CNT < 90 * sLeds * 24 / 90){chThdSleepMicroseconds(1);};
|
||||
}
|
||||
|
||||
void testPatternFB(uint8_t *fb){
|
||||
int i;
|
||||
Color tmpC = {rand()%256, rand()%256, rand()%256};
|
||||
for (i=0;i<sLeds;i++){
|
||||
setColorRGB(tmpC,fb+24*i, sMask);
|
||||
}
|
||||
}
|
||||
|
||||
void ws2812_setleds(LED_TYPE *ledarray, uint16_t number_of_leds) {
|
||||
// uint8_t i = 0;
|
||||
// while (i < number_of_leds) {
|
||||
// ws2812_write_led(i, ledarray[i].r, ledarray[i].g, ledarray[i].b);
|
||||
// i++;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
void ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t number_of_leds) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* LEDDriver.h
|
||||
*
|
||||
* Created on: Aug 26, 2013
|
||||
* Author: Omri Iluz
|
||||
*/
|
||||
|
||||
#ifndef WS2812_H_
|
||||
#define WS2812_H_
|
||||
|
||||
#include "hal.h"
|
||||
#include "rgblight_types.h"
|
||||
|
||||
#define sign(x) (( x > 0 ) - ( x < 0 ))
|
||||
|
||||
typedef struct Color Color;
|
||||
struct Color {
|
||||
uint8_t R;
|
||||
uint8_t G;
|
||||
uint8_t B;
|
||||
};
|
||||
|
||||
void ledDriverInit(int leds, stm32_gpio_t *port, uint32_t mask, uint8_t **o_fb);
|
||||
void setColorRGB(Color c, uint8_t *buf, uint32_t mask);
|
||||
void testPatternFB(uint8_t *fb);
|
||||
void ledDriverWaitCycle(void);
|
||||
|
||||
void ws2812_setleds(LED_TYPE *ledarray, uint16_t number_of_leds);
|
||||
void ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t number_of_leds);
|
||||
|
||||
#endif /* LEDDRIVER_H_ */
|
||||
@@ -1,22 +0,0 @@
|
||||
/* Library made by: g4lvanix
|
||||
* Github repository: https://github.com/g4lvanix/I2C-master-lib
|
||||
*/
|
||||
|
||||
#ifndef I2C_MASTER_H
|
||||
#define I2C_MASTER_H
|
||||
|
||||
#define I2C_READ 0x01
|
||||
#define I2C_WRITE 0x00
|
||||
|
||||
void i2c_init(void);
|
||||
uint8_t i2c_start(uint8_t address);
|
||||
uint8_t i2c_write(uint8_t data);
|
||||
uint8_t i2c_read_ack(void);
|
||||
uint8_t i2c_read_nack(void);
|
||||
uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length);
|
||||
uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length);
|
||||
uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length);
|
||||
uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length);
|
||||
void i2c_stop(void);
|
||||
|
||||
#endif // I2C_MASTER_H
|
||||
@@ -1,244 +0,0 @@
|
||||
/* Copyright 2017 Jason Williams
|
||||
* 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 "is31fl3731.h"
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include <string.h>
|
||||
#include "i2c_master.h"
|
||||
#include "progmem.h"
|
||||
|
||||
// This is a 7-bit address, that gets left-shifted and bit 0
|
||||
// set to 0 for write, 1 for read (as per I2C protocol)
|
||||
// The address will vary depending on your wiring:
|
||||
// 0b1110100 AD <-> GND
|
||||
// 0b1110111 AD <-> VCC
|
||||
// 0b1110101 AD <-> SCL
|
||||
// 0b1110110 AD <-> SDA
|
||||
#define ISSI_ADDR_DEFAULT 0x74
|
||||
|
||||
#define ISSI_REG_CONFIG 0x00
|
||||
#define ISSI_REG_CONFIG_PICTUREMODE 0x00
|
||||
#define ISSI_REG_CONFIG_AUTOPLAYMODE 0x08
|
||||
#define ISSI_REG_CONFIG_AUDIOPLAYMODE 0x18
|
||||
|
||||
#define ISSI_CONF_PICTUREMODE 0x00
|
||||
#define ISSI_CONF_AUTOFRAMEMODE 0x04
|
||||
#define ISSI_CONF_AUDIOMODE 0x08
|
||||
|
||||
#define ISSI_REG_PICTUREFRAME 0x01
|
||||
|
||||
#define ISSI_REG_SHUTDOWN 0x0A
|
||||
#define ISSI_REG_AUDIOSYNC 0x06
|
||||
|
||||
#define ISSI_COMMANDREGISTER 0xFD
|
||||
#define ISSI_BANK_FUNCTIONREG 0x0B // helpfully called 'page nine'
|
||||
|
||||
// Transfer buffer for TWITransmitData()
|
||||
uint8_t g_twi_transfer_buffer[20];
|
||||
|
||||
// These buffers match the IS31FL3731 PWM registers 0x24-0xB3.
|
||||
// Storing them like this is optimal for I2C transfers to the registers.
|
||||
// We could optimize this and take out the unused registers from these
|
||||
// buffers and the transfers in IS31FL3731_write_pwm_buffer() but it's
|
||||
// probably not worth the extra complexity.
|
||||
uint8_t g_pwm_buffer[DRIVER_COUNT][144];
|
||||
bool g_pwm_buffer_update_required = false;
|
||||
|
||||
uint8_t g_led_control_registers[DRIVER_COUNT][18] = { { 0 }, { 0 } };
|
||||
bool g_led_control_registers_update_required = false;
|
||||
|
||||
// This is the bit pattern in the LED control registers
|
||||
// (for matrix A, add one to register for matrix B)
|
||||
//
|
||||
// reg - b7 b6 b5 b4 b3 b2 b1 b0
|
||||
// 0x00 - R08,R07,R06,R05,R04,R03,R02,R01
|
||||
// 0x02 - G08,G07,G06,G05,G04,G03,G02,R00
|
||||
// 0x04 - B08,B07,B06,B05,B04,B03,G01,G00
|
||||
// 0x06 - - , - , - , - , - ,B02,B01,B00
|
||||
// 0x08 - - , - , - , - , - , - , - , -
|
||||
// 0x0A - B17,B16,B15, - , - , - , - , -
|
||||
// 0x0C - G17,G16,B14,B13,B12,B11,B10,B09
|
||||
// 0x0E - R17,G15,G14,G13,G12,G11,G10,G09
|
||||
// 0x10 - R16,R15,R14,R13,R12,R11,R10,R09
|
||||
|
||||
|
||||
void IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data )
|
||||
{
|
||||
g_twi_transfer_buffer[0] = reg;
|
||||
g_twi_transfer_buffer[1] = data;
|
||||
|
||||
//Transmit data until succesful
|
||||
while(i2c_transmit(addr << 1, g_twi_transfer_buffer,2) != 0);
|
||||
}
|
||||
|
||||
void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer )
|
||||
{
|
||||
// assumes bank is already selected
|
||||
|
||||
// transmit PWM registers in 9 transfers of 16 bytes
|
||||
// g_twi_transfer_buffer[] is 20 bytes
|
||||
|
||||
// iterate over the pwm_buffer contents at 16 byte intervals
|
||||
for ( int i = 0; i < 144; i += 16 )
|
||||
{
|
||||
// set the first register, e.g. 0x24, 0x34, 0x44, etc.
|
||||
g_twi_transfer_buffer[0] = 0x24 + i;
|
||||
// copy the data from i to i+15
|
||||
// device will auto-increment register for data after the first byte
|
||||
// thus this sets registers 0x24-0x33, 0x34-0x43, etc. in one transfer
|
||||
for ( int j = 0; j < 16; j++ )
|
||||
{
|
||||
g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j];
|
||||
}
|
||||
|
||||
//Transmit buffer until succesful
|
||||
while(i2c_transmit(addr << 1, g_twi_transfer_buffer,17) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL3731_init( uint8_t addr )
|
||||
{
|
||||
// In order to avoid the LEDs being driven with garbage data
|
||||
// in the LED driver's PWM registers, first enable software shutdown,
|
||||
// then set up the mode and other settings, clear the PWM registers,
|
||||
// then disable software shutdown.
|
||||
|
||||
// select "function register" bank
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG );
|
||||
|
||||
// enable software shutdown
|
||||
IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x00 );
|
||||
// this delay was copied from other drivers, might not be needed
|
||||
_delay_ms( 10 );
|
||||
|
||||
// picture mode
|
||||
IS31FL3731_write_register( addr, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE );
|
||||
// display frame 0
|
||||
IS31FL3731_write_register( addr, ISSI_REG_PICTUREFRAME, 0x00 );
|
||||
// audio sync off
|
||||
IS31FL3731_write_register( addr, ISSI_REG_AUDIOSYNC, 0x00 );
|
||||
|
||||
// select bank 0
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 );
|
||||
|
||||
// turn off all LEDs in the LED control register
|
||||
for ( int i = 0x00; i <= 0x11; i++ )
|
||||
{
|
||||
IS31FL3731_write_register( addr, i, 0x00 );
|
||||
}
|
||||
|
||||
// turn off all LEDs in the blink control register (not really needed)
|
||||
for ( int i = 0x12; i <= 0x23; i++ )
|
||||
{
|
||||
IS31FL3731_write_register( addr, i, 0x00 );
|
||||
}
|
||||
|
||||
// set PWM on all LEDs to 0
|
||||
for ( int i = 0x24; i <= 0xB3; i++ )
|
||||
{
|
||||
IS31FL3731_write_register( addr, i, 0x00 );
|
||||
}
|
||||
|
||||
// select "function register" bank
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG );
|
||||
|
||||
// disable software shutdown
|
||||
IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x01 );
|
||||
|
||||
// select bank 0 and leave it selected.
|
||||
// most usage after initialization is just writing PWM buffers in bank 0
|
||||
// as there's not much point in double-buffering
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 );
|
||||
}
|
||||
|
||||
void IS31FL3731_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
|
||||
{
|
||||
if ( index >= 0 && index < DRIVER_LED_TOTAL ) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
|
||||
// Subtract 0x24 to get the second index of g_pwm_buffer
|
||||
g_pwm_buffer[led.driver][led.r - 0x24] = red;
|
||||
g_pwm_buffer[led.driver][led.g - 0x24] = green;
|
||||
g_pwm_buffer[led.driver][led.b - 0x24] = blue;
|
||||
g_pwm_buffer_update_required = true;
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL3731_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
|
||||
{
|
||||
for ( int i = 0; i < DRIVER_LED_TOTAL; i++ )
|
||||
{
|
||||
IS31FL3731_set_color( i, red, green, blue );
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL3731_set_led_control_register( uint8_t index, bool red, bool green, bool blue )
|
||||
{
|
||||
is31_led led = g_is31_leds[index];
|
||||
|
||||
uint8_t control_register_r = (led.r - 0x24) / 8;
|
||||
uint8_t control_register_g = (led.g - 0x24) / 8;
|
||||
uint8_t control_register_b = (led.b - 0x24) / 8;
|
||||
uint8_t bit_r = (led.r - 0x24) % 8;
|
||||
uint8_t bit_g = (led.g - 0x24) % 8;
|
||||
uint8_t bit_b = (led.b - 0x24) % 8;
|
||||
|
||||
if ( red ) {
|
||||
g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r);
|
||||
} else {
|
||||
g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r);
|
||||
}
|
||||
if ( green ) {
|
||||
g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g);
|
||||
} else {
|
||||
g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g);
|
||||
}
|
||||
if ( blue ) {
|
||||
g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b);
|
||||
} else {
|
||||
g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b);
|
||||
}
|
||||
|
||||
g_led_control_registers_update_required = true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void IS31FL3731_update_pwm_buffers( uint8_t addr1, uint8_t addr2 )
|
||||
{
|
||||
if ( g_pwm_buffer_update_required )
|
||||
{
|
||||
IS31FL3731_write_pwm_buffer( addr1, g_pwm_buffer[0] );
|
||||
IS31FL3731_write_pwm_buffer( addr2, g_pwm_buffer[1] );
|
||||
}
|
||||
g_pwm_buffer_update_required = false;
|
||||
}
|
||||
|
||||
void IS31FL3731_update_led_control_registers( uint8_t addr1, uint8_t addr2 )
|
||||
{
|
||||
if ( g_led_control_registers_update_required )
|
||||
{
|
||||
for ( int i=0; i<18; i++ )
|
||||
{
|
||||
IS31FL3731_write_register(addr1, i, g_led_control_registers[0][i] );
|
||||
IS31FL3731_write_register(addr2, i, g_led_control_registers[1][i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Executable → Regular
+61
-61
@@ -5,44 +5,44 @@
|
||||
#include <avr/io.h>
|
||||
#include <util/twi.h>
|
||||
|
||||
#include "i2c_master.h"
|
||||
#include "twi2c.h"
|
||||
|
||||
#define F_SCL 400000UL // SCL frequency
|
||||
#define Prescaler 1
|
||||
#define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16 ) / 2)
|
||||
|
||||
void i2c_init(void)
|
||||
void twi2c_init(void)
|
||||
{
|
||||
TWBR = (uint8_t)TWBR_val;
|
||||
}
|
||||
|
||||
uint8_t i2c_start(uint8_t address)
|
||||
uint8_t twi2c_start(uint8_t address)
|
||||
{
|
||||
// reset TWI control register
|
||||
TWCR = 0;
|
||||
// transmit START condition
|
||||
// transmit START condition
|
||||
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
|
||||
// wait for end of transmission
|
||||
while( !(TWCR & (1<<TWINT)) );
|
||||
|
||||
|
||||
// check if the start condition was successfully transmitted
|
||||
if((TWSR & 0xF8) != TW_START){ return 1; }
|
||||
|
||||
|
||||
// load slave address into data register
|
||||
TWDR = address;
|
||||
// start transmission of address
|
||||
TWCR = (1<<TWINT) | (1<<TWEN);
|
||||
// wait for end of transmission
|
||||
while( !(TWCR & (1<<TWINT)) );
|
||||
|
||||
|
||||
// check if the device has acknowledged the READ / WRITE mode
|
||||
uint8_t twst = TW_STATUS & 0xF8;
|
||||
if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t i2c_write(uint8_t data)
|
||||
uint8_t twi2c_write(uint8_t data)
|
||||
{
|
||||
// load data into data register
|
||||
TWDR = data;
|
||||
@@ -50,26 +50,26 @@ uint8_t i2c_write(uint8_t data)
|
||||
TWCR = (1<<TWINT) | (1<<TWEN);
|
||||
// wait for end of transmission
|
||||
while( !(TWCR & (1<<TWINT)) );
|
||||
|
||||
|
||||
if( (TWSR & 0xF8) != TW_MT_DATA_ACK ){ return 1; }
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t i2c_read_ack(void)
|
||||
uint8_t twi2c_read_ack(void)
|
||||
{
|
||||
|
||||
|
||||
// start TWI module and acknowledge data after reception
|
||||
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
|
||||
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
|
||||
// wait for end of transmission
|
||||
while( !(TWCR & (1<<TWINT)) );
|
||||
// return received data from TWDR
|
||||
return TWDR;
|
||||
}
|
||||
|
||||
uint8_t i2c_read_nack(void)
|
||||
uint8_t twi2c_read_nack(void)
|
||||
{
|
||||
|
||||
|
||||
// start receiving without acknowledging reception
|
||||
TWCR = (1<<TWINT) | (1<<TWEN);
|
||||
// wait for end of transmission
|
||||
@@ -78,71 +78,71 @@ uint8_t i2c_read_nack(void)
|
||||
return TWDR;
|
||||
}
|
||||
|
||||
uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length)
|
||||
uint8_t twi2c_transmit(uint8_t address, uint8_t* data, uint16_t length)
|
||||
{
|
||||
if (i2c_start(address | I2C_WRITE)) return 1;
|
||||
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
if (i2c_write(data[i])) return 1;
|
||||
}
|
||||
|
||||
i2c_stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length)
|
||||
{
|
||||
if (i2c_start(address | I2C_READ)) return 1;
|
||||
|
||||
for (uint16_t i = 0; i < (length-1); i++)
|
||||
{
|
||||
data[i] = i2c_read_ack();
|
||||
}
|
||||
data[(length-1)] = i2c_read_nack();
|
||||
|
||||
i2c_stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)
|
||||
{
|
||||
if (i2c_start(devaddr | 0x00)) return 1;
|
||||
|
||||
i2c_write(regaddr);
|
||||
if (twi2c_start(address | I2C_WRITE)) return 1;
|
||||
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
if (i2c_write(data[i])) return 1;
|
||||
if (twi2c_write(data[i])) return 1;
|
||||
}
|
||||
|
||||
i2c_stop();
|
||||
twi2c_stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)
|
||||
uint8_t twi2c_receive(uint8_t address, uint8_t* data, uint16_t length)
|
||||
{
|
||||
if (i2c_start(devaddr)) return 1;
|
||||
|
||||
i2c_write(regaddr);
|
||||
|
||||
if (i2c_start(devaddr | 0x01)) return 1;
|
||||
if (twi2c_start(address | I2C_READ)) return 1;
|
||||
|
||||
for (uint16_t i = 0; i < (length-1); i++)
|
||||
{
|
||||
data[i] = i2c_read_ack();
|
||||
data[i] = twi2c_read_ack();
|
||||
}
|
||||
data[(length-1)] = i2c_read_nack();
|
||||
data[(length-1)] = twi2c_read_nack();
|
||||
|
||||
i2c_stop();
|
||||
twi2c_stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void i2c_stop(void)
|
||||
uint8_t twi2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)
|
||||
{
|
||||
if (twi2c_start(devaddr | 0x00)) return 1;
|
||||
|
||||
twi2c_write(regaddr);
|
||||
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
if (twi2c_write(data[i])) return 1;
|
||||
}
|
||||
|
||||
twi2c_stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t twi2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)
|
||||
{
|
||||
if (twi2c_start(devaddr)) return 1;
|
||||
|
||||
twi2c_write(regaddr);
|
||||
|
||||
if (twi2c_start(devaddr | 0x01)) return 1;
|
||||
|
||||
for (uint16_t i = 0; i < (length-1); i++)
|
||||
{
|
||||
data[i] = twi2c_read_ack();
|
||||
}
|
||||
data[(length-1)] = twi2c_read_nack();
|
||||
|
||||
twi2c_stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void twi2c_stop(void)
|
||||
{
|
||||
// transmit STOP condition
|
||||
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
|
||||
@@ -0,0 +1,22 @@
|
||||
/* Library made by: g4lvanix
|
||||
* Github repository: https://github.com/g4lvanix/I2C-master-lib
|
||||
*/
|
||||
|
||||
#ifndef TWI2C_H
|
||||
#define TWI2C_H
|
||||
|
||||
#define I2C_READ 0x01
|
||||
#define I2C_WRITE 0x00
|
||||
|
||||
void twi2c_init(void);
|
||||
uint8_t twi2c_start(uint8_t address);
|
||||
uint8_t twi2c_write(uint8_t data);
|
||||
uint8_t twi2c_read_ack(void);
|
||||
uint8_t twi2c_read_nack(void);
|
||||
uint8_t twi2c_transmit(uint8_t address, uint8_t* data, uint16_t length);
|
||||
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);
|
||||
|
||||
#endif // I2C_MASTER_H
|
||||
@@ -0,0 +1,244 @@
|
||||
/* Copyright 2017 Jason Williams
|
||||
* 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 "is31fl3731.h"
|
||||
#include "wait.h"
|
||||
#include <string.h>
|
||||
#include "twi2c.h"
|
||||
#include "progmem.h"
|
||||
|
||||
// This is a 7-bit address, that gets left-shifted and bit 0
|
||||
// set to 0 for write, 1 for read (as per I2C protocol)
|
||||
// The address will vary depending on your wiring:
|
||||
// 0b1110100 AD <-> GND
|
||||
// 0b1110111 AD <-> VCC
|
||||
// 0b1110101 AD <-> SCL
|
||||
// 0b1110110 AD <-> SDA
|
||||
#define ISSI_ADDR_DEFAULT 0x74
|
||||
|
||||
#define ISSI_REG_CONFIG 0x00
|
||||
#define ISSI_REG_CONFIG_PICTUREMODE 0x00
|
||||
#define ISSI_REG_CONFIG_AUTOPLAYMODE 0x08
|
||||
#define ISSI_REG_CONFIG_AUDIOPLAYMODE 0x18
|
||||
|
||||
#define ISSI_CONF_PICTUREMODE 0x00
|
||||
#define ISSI_CONF_AUTOFRAMEMODE 0x04
|
||||
#define ISSI_CONF_AUDIOMODE 0x08
|
||||
|
||||
#define ISSI_REG_PICTUREFRAME 0x01
|
||||
|
||||
#define ISSI_REG_SHUTDOWN 0x0A
|
||||
#define ISSI_REG_AUDIOSYNC 0x06
|
||||
|
||||
#define ISSI_COMMANDREGISTER 0xFD
|
||||
#define ISSI_BANK_FUNCTIONREG 0x0B // helpfully called 'page nine'
|
||||
|
||||
// Transfer buffer for TWITransmitData()
|
||||
uint8_t g_twi_transfer_buffer[20];
|
||||
|
||||
// These buffers match the IS31FL3731 PWM registers 0x24-0xB3.
|
||||
// Storing them like this is optimal for I2C transfers to the registers.
|
||||
// We could optimize this and take out the unused registers from these
|
||||
// buffers and the transfers in IS31FL3731_write_pwm_buffer() but it's
|
||||
// probably not worth the extra complexity.
|
||||
uint8_t g_pwm_buffer[DRIVER_COUNT][144];
|
||||
bool g_pwm_buffer_update_required = false;
|
||||
|
||||
uint8_t g_led_control_registers[DRIVER_COUNT][18] = { { 0 }, { 0 } };
|
||||
bool g_led_control_registers_update_required = false;
|
||||
|
||||
// This is the bit pattern in the LED control registers
|
||||
// (for matrix A, add one to register for matrix B)
|
||||
//
|
||||
// reg - b7 b6 b5 b4 b3 b2 b1 b0
|
||||
// 0x00 - R08,R07,R06,R05,R04,R03,R02,R01
|
||||
// 0x02 - G08,G07,G06,G05,G04,G03,G02,R00
|
||||
// 0x04 - B08,B07,B06,B05,B04,B03,G01,G00
|
||||
// 0x06 - - , - , - , - , - ,B02,B01,B00
|
||||
// 0x08 - - , - , - , - , - , - , - , -
|
||||
// 0x0A - B17,B16,B15, - , - , - , - , -
|
||||
// 0x0C - G17,G16,B14,B13,B12,B11,B10,B09
|
||||
// 0x0E - R17,G15,G14,G13,G12,G11,G10,G09
|
||||
// 0x10 - R16,R15,R14,R13,R12,R11,R10,R09
|
||||
|
||||
|
||||
void IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data )
|
||||
{
|
||||
g_twi_transfer_buffer[0] = reg;
|
||||
g_twi_transfer_buffer[1] = data;
|
||||
|
||||
//Transmit data until succesful
|
||||
//while(twi2c_transmit(addr << 1, g_twi_transfer_buffer,2) != 0);
|
||||
twi2c_transmit(addr << 1, g_twi_transfer_buffer,2);
|
||||
}
|
||||
|
||||
void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer )
|
||||
{
|
||||
// assumes bank is already selected
|
||||
|
||||
// transmit PWM registers in 9 transfers of 16 bytes
|
||||
// g_twi_transfer_buffer[] is 20 bytes
|
||||
|
||||
// iterate over the pwm_buffer contents at 16 byte intervals
|
||||
for ( int i = 0; i < 144; i += 16 )
|
||||
{
|
||||
// set the first register, e.g. 0x24, 0x34, 0x44, etc.
|
||||
g_twi_transfer_buffer[0] = 0x24 + i;
|
||||
// copy the data from i to i+15
|
||||
// device will auto-increment register for data after the first byte
|
||||
// thus this sets registers 0x24-0x33, 0x34-0x43, etc. in one transfer
|
||||
for ( int j = 0; j < 16; j++ )
|
||||
{
|
||||
g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j];
|
||||
}
|
||||
|
||||
//Transmit buffer until succesful
|
||||
//while(twi2c_transmit(addr << 1, g_twi_transfer_buffer,17) != 0);
|
||||
twi2c_transmit(addr << 1, g_twi_transfer_buffer,17);
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL3731_init( uint8_t addr )
|
||||
{
|
||||
// In order to avoid the LEDs being driven with garbage data
|
||||
// in the LED driver's PWM registers, first enable software shutdown,
|
||||
// then set up the mode and other settings, clear the PWM registers,
|
||||
// then disable software shutdown.
|
||||
|
||||
// select "function register" bank
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG );
|
||||
|
||||
// enable software shutdown
|
||||
IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x00 );
|
||||
// this delay was copied from other drivers, might not be needed
|
||||
wait_ms( 10 );
|
||||
|
||||
// picture mode
|
||||
IS31FL3731_write_register( addr, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE );
|
||||
// display frame 0
|
||||
IS31FL3731_write_register( addr, ISSI_REG_PICTUREFRAME, 0x00 );
|
||||
// audio sync off
|
||||
IS31FL3731_write_register( addr, ISSI_REG_AUDIOSYNC, 0x00 );
|
||||
|
||||
// select bank 0
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 );
|
||||
|
||||
// turn off all LEDs in the LED control register
|
||||
for ( int i = 0x00; i <= 0x11; i++ )
|
||||
{
|
||||
IS31FL3731_write_register( addr, i, 0x00 );
|
||||
}
|
||||
|
||||
// turn off all LEDs in the blink control register (not really needed)
|
||||
for ( int i = 0x12; i <= 0x23; i++ )
|
||||
{
|
||||
IS31FL3731_write_register( addr, i, 0x00 );
|
||||
}
|
||||
|
||||
// set PWM on all LEDs to 0
|
||||
for ( int i = 0x24; i <= 0xB3; i++ )
|
||||
{
|
||||
IS31FL3731_write_register( addr, i, 0x00 );
|
||||
}
|
||||
|
||||
// select "function register" bank
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG );
|
||||
|
||||
// disable software shutdown
|
||||
IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x01 );
|
||||
|
||||
// select bank 0 and leave it selected.
|
||||
// most usage after initialization is just writing PWM buffers in bank 0
|
||||
// as there's not much point in double-buffering
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 );
|
||||
}
|
||||
|
||||
void IS31FL3731_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
|
||||
{
|
||||
if ( index >= 0 && index < DRIVER_LED_TOTAL ) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
|
||||
// Subtract 0x24 to get the second index of g_pwm_buffer
|
||||
g_pwm_buffer[led.driver][led.r - 0x24] = red;
|
||||
g_pwm_buffer[led.driver][led.g - 0x24] = green;
|
||||
g_pwm_buffer[led.driver][led.b - 0x24] = blue;
|
||||
g_pwm_buffer_update_required = true;
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL3731_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
|
||||
{
|
||||
for ( int i = 0; i < DRIVER_LED_TOTAL; i++ )
|
||||
{
|
||||
IS31FL3731_set_color( i, red, green, blue );
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL3731_set_led_control_register( uint8_t index, bool red, bool green, bool blue )
|
||||
{
|
||||
is31_led led = g_is31_leds[index];
|
||||
|
||||
uint8_t control_register_r = (led.r - 0x24) / 8;
|
||||
uint8_t control_register_g = (led.g - 0x24) / 8;
|
||||
uint8_t control_register_b = (led.b - 0x24) / 8;
|
||||
uint8_t bit_r = (led.r - 0x24) % 8;
|
||||
uint8_t bit_g = (led.g - 0x24) % 8;
|
||||
uint8_t bit_b = (led.b - 0x24) % 8;
|
||||
|
||||
if ( red ) {
|
||||
g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r);
|
||||
} else {
|
||||
g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r);
|
||||
}
|
||||
if ( green ) {
|
||||
g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g);
|
||||
} else {
|
||||
g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g);
|
||||
}
|
||||
if ( blue ) {
|
||||
g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b);
|
||||
} else {
|
||||
g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b);
|
||||
}
|
||||
|
||||
g_led_control_registers_update_required = true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void IS31FL3731_update_pwm_buffers( uint8_t addr1, uint8_t addr2 )
|
||||
{
|
||||
if ( g_pwm_buffer_update_required )
|
||||
{
|
||||
IS31FL3731_write_pwm_buffer( addr1, g_pwm_buffer[0] );
|
||||
IS31FL3731_write_pwm_buffer( addr2, g_pwm_buffer[1] );
|
||||
}
|
||||
g_pwm_buffer_update_required = false;
|
||||
}
|
||||
|
||||
void IS31FL3731_update_led_control_registers( uint8_t addr1, uint8_t addr2 )
|
||||
{
|
||||
if ( g_led_control_registers_update_required )
|
||||
{
|
||||
for ( int i=0; i<18; i++ )
|
||||
{
|
||||
IS31FL3731_write_register(addr1, i, g_led_control_registers[0][i] );
|
||||
IS31FL3731_write_register(addr2, i, g_led_control_registers[1][i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct is31_led {
|
||||
uint8_t driver:2;
|
||||
uint8_t driver:2;
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
@@ -0,0 +1,189 @@
|
||||
/* 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);
|
||||
|
||||
static bool qwiic_keyboard_master = false;
|
||||
static bool qwiic_keyboard_connected = false;
|
||||
static uint8_t qwiic_keyboard_handshake_message[QWIIC_KEYBOARD_HANDSHAKE_MESSAGE_SIZE] = {0};
|
||||
static uint8_t qwiic_keyboard_matrix_message[QWIIC_KEYBOARD_ROWS] = {0};
|
||||
static qwiic_matrix_t matrix_prev[QWIIC_KEYBOARD_ROWS] = {0};
|
||||
static twi2c_message_received qwiic_keyboard_message_received_ptr = qwiic_keyboard_message_received;
|
||||
|
||||
static uint16_t qwiic_keyboard_keymap[QWIIC_KEYBOARD_LAYERS][QWIIC_KEYBOARD_ROWS][QWIIC_KEYBOARD_COLS] = {{{0}}};
|
||||
static uint8_t qwiic_keyboard_listening_address = QWIIC_KEYBOARD_LISTENING_ADDRESS_START;
|
||||
|
||||
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
|
||||
)) {
|
||||
// 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++) << 8);
|
||||
keycode |= (*pointer++);
|
||||
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, keymatrix_t key) {
|
||||
if (key.matrix == 0) {
|
||||
// Read entire word (16bits)
|
||||
return pgm_read_word(&keymaps[(layer)][(key.pos.row)][(key.pos.col)]);
|
||||
} else {
|
||||
return qwiic_keyboard_keymap[(layer)][(key.pos.row)][(key.pos.col)];
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t multimatrix_get_num_matrices(void) {
|
||||
return qwiic_keyboard_connected ? 1 : 0;
|
||||
}
|
||||
|
||||
uint8_t multimatrix_get_num_cols(uint8_t matrix) {
|
||||
return QWIIC_KEYBOARD_COLS;
|
||||
}
|
||||
|
||||
uint8_t multimatrix_get_num_rows(uint8_t matrix) {
|
||||
return QWIIC_KEYBOARD_ROWS;
|
||||
}
|
||||
|
||||
uint32_t multimatrix_get_row(uint8_t matrix, uint8_t row) {
|
||||
return qwiic_keyboard_matrix_message[row];
|
||||
}
|
||||
|
||||
uint32_t multimatrix_get_row_cache(uint8_t matrix, uint8_t row) {
|
||||
return matrix_prev[row];
|
||||
}
|
||||
|
||||
void multimatrix_set_row_cache(uint8_t matrix, uint8_t row, uint32_t value) {
|
||||
matrix_prev[row] = value;
|
||||
}
|
||||
|
||||
uint8_t* multimatrix_get_source_layers_cache(uint8_t matrix) {
|
||||
static uint8_t source_layers_cache[(QWIIC_KEYBOARD_ROWS * QWIIC_KEYBOARD_COLS * MAX_LAYER_BITS + 7) / 8] = {0};
|
||||
return source_layers_cache;
|
||||
}
|
||||
@@ -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
|
||||
@@ -19,7 +19,7 @@
|
||||
* | 40 | 41 | 42 | 45 | 4a | 4b | 4c | 4d |
|
||||
* `-----------------------------------------------------------'
|
||||
*/
|
||||
#define KEYMAP( \
|
||||
#define LAYOUT( \
|
||||
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, k0d, k49,\
|
||||
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d, \
|
||||
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k2d, \
|
||||
@@ -48,7 +48,7 @@
|
||||
* | 40 | 41 | 42 | 45 | 4a | 4b | 4c | 4d |
|
||||
* `-----------------------------------------------------------'
|
||||
*/
|
||||
#define KEYMAP_ANSI( \
|
||||
#define LAYOUT_60_ansi( \
|
||||
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, k0d, \
|
||||
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d, \
|
||||
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2d, \
|
||||
@@ -63,8 +63,6 @@
|
||||
{k40, k41, k42, XXX, XXX, k45, XXX, XXX, XXX, XXX, k4a, k4b, k4c, k4d} \
|
||||
}
|
||||
|
||||
#define LAYOUT_60_ansi KEYMAP_ANSI
|
||||
|
||||
/* AMJ60 HHKB matrix layout
|
||||
* ,------------------------------------------------------------.
|
||||
* | 00 |01| 02| 03| 04| 05| 06| 07| 08| 09| 0a| 0b| 0c| 0d| 49 |
|
||||
@@ -79,7 +77,7 @@
|
||||
* `------------------------------------------------------------'
|
||||
*/
|
||||
|
||||
#define KEYMAP_HHKB( \
|
||||
#define LAYOUT_hhkb( \
|
||||
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, k0d, k49, \
|
||||
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d, \
|
||||
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2d, \
|
||||
@@ -107,7 +105,7 @@
|
||||
* | 40 | 41 | 42 | 45 | 4a | 4b | 4c | 4d |
|
||||
* `-----------------------------------------------------------'
|
||||
*/
|
||||
#define KEYMAP_ISO( \
|
||||
#define LAYOUT_iso( \
|
||||
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, k0d, \
|
||||
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d, \
|
||||
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k2d, \
|
||||
@@ -135,7 +133,7 @@
|
||||
* | 40 | 41 | 42 | 45 | 4a | 4b | 4c | 4d |
|
||||
* `-----------------------------------------------------------'
|
||||
*/
|
||||
#define KEYMAP_ISO_SPLITRSHIFT( \
|
||||
#define LAYOUT_iso_splitrshift( \
|
||||
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, k0d, \
|
||||
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d, \
|
||||
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k2d, \
|
||||
@@ -150,7 +148,7 @@
|
||||
{k40, k41, k42, XXX, XXX, k45, XXX, XXX, XXX, XXX, k4a, k4b, k4c, k4d} \
|
||||
}
|
||||
|
||||
#define KEYMAP_MAX( \
|
||||
#define LAYOUT_max( \
|
||||
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, k0d, k49,\
|
||||
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d, \
|
||||
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2d, \
|
||||
|
||||
@@ -5,8 +5,23 @@
|
||||
"width": 15,
|
||||
"height": 5,
|
||||
"layouts": {
|
||||
"LAYOUT": {
|
||||
"layout": [{"label":"k00", "x":0, "y":0}, {"label":"k01", "x":1, "y":0}, {"label":"k02", "x":2, "y":0}, {"label":"k03", "x":3, "y":0}, {"label":"k04", "x":4, "y":0}, {"label":"k05", "x":5, "y":0}, {"label":"k06", "x":6, "y":0}, {"label":"k07", "x":7, "y":0}, {"label":"k08", "x":8, "y":0}, {"label":"k09", "x":9, "y":0}, {"label":"k0a", "x":10, "y":0}, {"label":"k0b", "x":11, "y":0}, {"label":"k0c", "x":12, "y":0}, {"label":"k0d", "x":13, "y":0}, {"label":"k49", "x":14, "y":0}, {"label":"k10", "x":0, "y":1, "w":1.5}, {"label":"k11", "x":1.5, "y":1}, {"label":"k12", "x":2.5, "y":1}, {"label":"k13", "x":3.5, "y":1}, {"label":"k14", "x":4.5, "y":1}, {"label":"k15", "x":5.5, "y":1}, {"label":"k16", "x":6.5, "y":1}, {"label":"k17", "x":7.5, "y":1}, {"label":"k18", "x":8.5, "y":1}, {"label":"k19", "x":9.5, "y":1}, {"label":"k1a", "x":10.5, "y":1}, {"label":"k1b", "x":11.5, "y":1}, {"label":"k1c", "x":12.5, "y":1}, {"label":"k1d", "x":13.5, "y":1, "w":1.5}, {"label":"k20", "x":0, "y":2, "w":1.75}, {"label":"k21", "x":1.75, "y":2}, {"label":"k22", "x":2.75, "y":2}, {"label":"k23", "x":3.75, "y":2}, {"label":"k24", "x":4.75, "y":2}, {"label":"k25", "x":5.75, "y":2}, {"label":"k26", "x":6.75, "y":2}, {"label":"k27", "x":7.75, "y":2}, {"label":"k28", "x":8.75, "y":2}, {"label":"k29", "x":9.75, "y":2}, {"label":"k2a", "x":10.75, "y":2}, {"label":"k2b", "x":11.75, "y":2}, {"label":"k2c", "x":12.75, "y":2}, {"label":"k2d", "x":13.75, "y":2, "w":1.25}, {"label":"k30", "x":0, "y":3, "w":1.25}, {"label":"k31", "x":1.25, "y":3}, {"label":"k32", "x":2.25, "y":3}, {"label":"k33", "x":3.25, "y":3}, {"label":"k34", "x":4.25, "y":3}, {"label":"k35", "x":5.25, "y":3}, {"label":"k36", "x":6.25, "y":3}, {"label":"k37", "x":7.25, "y":3}, {"label":"k38", "x":8.25, "y":3}, {"label":"k39", "x":9.25, "y":3}, {"label":"k3a", "x":10.25, "y":3}, {"label":"k3b", "x":11.25, "y":3}, {"label":"k3c", "x":12.25, "y":3, "w":1.75}, {"label":"k3d", "x":14, "y":3}, {"label":"k40", "x":0, "y":4, "w":1.25}, {"label":"k41", "x":1.25, "y":4, "w":1.25}, {"label":"k42", "x":2.5, "y":4, "w":1.25}, {"label":"k45", "x":3.75, "y":4, "w":6.25}, {"label":"k4a", "x":10, "y":4, "w":1.25}, {"label":"k4b", "x":11.25, "y":4, "w":1.25}, {"label":"k4c", "x":12.5, "y":4, "w":1.25}, {"label":"k4d", "x":13.75, "y":4, "w":1.25}]
|
||||
},
|
||||
"LAYOUT_60_ansi": {
|
||||
"layout": [{"label":"k00", "x":0, "y":0}, {"label":"k01", "x":1, "y":0}, {"label":"k02", "x":2, "y":0}, {"label":"k03", "x":3, "y":0}, {"label":"k04", "x":4, "y":0}, {"label":"k05", "x":5, "y":0}, {"label":"k06", "x":6, "y":0}, {"label":"k07", "x":7, "y":0}, {"label":"k08", "x":8, "y":0}, {"label":"k09", "x":9, "y":0}, {"label":"k0a", "x":10, "y":0}, {"label":"k0b", "x":11, "y":0}, {"label":"k0c", "x":12, "y":0}, {"label":"k0d", "x":13, "y":0, "w":2}, {"label":"k10", "x":0, "y":1, "w":1.5}, {"label":"k11", "x":1.5, "y":1}, {"label":"k12", "x":2.5, "y":1}, {"label":"k13", "x":3.5, "y":1}, {"label":"k14", "x":4.5, "y":1}, {"label":"k15", "x":5.5, "y":1}, {"label":"k16", "x":6.5, "y":1}, {"label":"k17", "x":7.5, "y":1}, {"label":"k18", "x":8.5, "y":1}, {"label":"k19", "x":9.5, "y":1}, {"label":"k1a", "x":10.5, "y":1}, {"label":"k1b", "x":11.5, "y":1}, {"label":"k1c", "x":12.5, "y":1}, {"label":"k1d", "x":13.5, "y":1, "w":1.5}, {"label":"k20", "x":0, "y":2, "w":1.75}, {"label":"k21", "x":1.75, "y":2}, {"label":"k22", "x":2.75, "y":2}, {"label":"k23", "x":3.75, "y":2}, {"label":"k24", "x":4.75, "y":2}, {"label":"k25", "x":5.75, "y":2}, {"label":"k26", "x":6.75, "y":2}, {"label":"k27", "x":7.75, "y":2}, {"label":"k28", "x":8.75, "y":2}, {"label":"k29", "x":9.75, "y":2}, {"label":"k2a", "x":10.75, "y":2}, {"label":"k2b", "x":11.75, "y":2}, {"label":"k2d", "x":12.75, "y":2, "w":2.25}, {"label":"k30", "x":0, "y":3, "w":2.25}, {"label":"k32", "x":2.25, "y":3}, {"label":"k33", "x":3.25, "y":3}, {"label":"k34", "x":4.25, "y":3}, {"label":"k35", "x":5.25, "y":3}, {"label":"k36", "x":6.25, "y":3}, {"label":"k37", "x":7.25, "y":3}, {"label":"k38", "x":8.25, "y":3}, {"label":"k39", "x":9.25, "y":3}, {"label":"k3a", "x":10.25, "y":3}, {"label":"k3b", "x":11.25, "y":3}, {"label":"k3d", "x":12.25, "y":3, "w":2.75}, {"label":"k40", "x":0, "y":4, "w":1.25}, {"label":"k41", "x":1.25, "y":4, "w":1.25}, {"label":"k42", "x":2.5, "y":4, "w":1.25}, {"label":"k45", "x":3.75, "y":4, "w":6.25}, {"label":"k4a", "x":10, "y":4, "w":1.25}, {"label":"k4b", "x":11.25, "y":4, "w":1.25}, {"label":"k4c", "x":12.5, "y":4, "w":1.25}, {"label":"k4d", "x":13.75, "y":4, "w":1.25}]
|
||||
},
|
||||
"LAYOUT_hhkb": {
|
||||
"layout": [{"label":"k00", "x":0, "y":0}, {"label":"k01", "x":1, "y":0}, {"label":"k02", "x":2, "y":0}, {"label":"k03", "x":3, "y":0}, {"label":"k04", "x":4, "y":0}, {"label":"k05", "x":5, "y":0}, {"label":"k06", "x":6, "y":0}, {"label":"k07", "x":7, "y":0}, {"label":"k08", "x":8, "y":0}, {"label":"k09", "x":9, "y":0}, {"label":"k0a", "x":10, "y":0}, {"label":"k0b", "x":11, "y":0}, {"label":"k0c", "x":12, "y":0}, {"label":"k0d", "x":13, "y":0}, {"label":"k49", "x":14, "y":0}, {"label":"k10", "x":0, "y":1, "w":1.5}, {"label":"k11", "x":1.5, "y":1}, {"label":"k12", "x":2.5, "y":1}, {"label":"k13", "x":3.5, "y":1}, {"label":"k14", "x":4.5, "y":1}, {"label":"k15", "x":5.5, "y":1}, {"label":"k16", "x":6.5, "y":1}, {"label":"k17", "x":7.5, "y":1}, {"label":"k18", "x":8.5, "y":1}, {"label":"k19", "x":9.5, "y":1}, {"label":"k1a", "x":10.5, "y":1}, {"label":"k1b", "x":11.5, "y":1}, {"label":"k1c", "x":12.5, "y":1}, {"label":"k1d", "x":13.5, "y":1, "w":1.5}, {"label":"k20", "x":0, "y":2, "w":1.75}, {"label":"k21", "x":1.75, "y":2}, {"label":"k22", "x":2.75, "y":2}, {"label":"k23", "x":3.75, "y":2}, {"label":"k24", "x":4.75, "y":2}, {"label":"k25", "x":5.75, "y":2}, {"label":"k26", "x":6.75, "y":2}, {"label":"k27", "x":7.75, "y":2}, {"label":"k28", "x":8.75, "y":2}, {"label":"k29", "x":9.75, "y":2}, {"label":"k2a", "x":10.75, "y":2}, {"label":"k2b", "x":11.75, "y":2}, {"label":"k2d", "x":12.75, "y":2, "w":2.25}, {"label":"k30", "x":0, "y":3, "w":2.25}, {"label":"k32", "x":2.25, "y":3}, {"label":"k33", "x":3.25, "y":3}, {"label":"k34", "x":4.25, "y":3}, {"label":"k35", "x":5.25, "y":3}, {"label":"k36", "x":6.25, "y":3}, {"label":"k37", "x":7.25, "y":3}, {"label":"k38", "x":8.25, "y":3}, {"label":"k39", "x":9.25, "y":3}, {"label":"k3a", "x":10.25, "y":3}, {"label":"k3b", "x":11.25, "y":3}, {"label":"k3d", "x":12.25, "y":3, "w":1.75}, {"label":"k3c", "x":14, "y":3}, {"label":"k40", "x":0, "y":4, "w":1.25}, {"label":"k41", "x":1.25, "y":4, "w":1.25}, {"label":"k42", "x":2.5, "y":4, "w":1.25}, {"label":"k45", "x":3.75, "y":4, "w":6.25}, {"label":"k4a", "x":10, "y":4, "w":1.25}, {"label":"k4b", "x":11.25, "y":4, "w":1.25}, {"label":"k4c", "x":12.5, "y":4, "w":1.25}, {"label":"k4d", "x":13.75, "y":4, "w":1.25}]
|
||||
},
|
||||
"LAYOUT_iso": {
|
||||
"layout": [{"label":"k00", "x":0, "y":0}, {"label":"k01", "x":1, "y":0}, {"label":"k02", "x":2, "y":0}, {"label":"k03", "x":3, "y":0}, {"label":"k04", "x":4, "y":0}, {"label":"k05", "x":5, "y":0}, {"label":"k06", "x":6, "y":0}, {"label":"k07", "x":7, "y":0}, {"label":"k08", "x":8, "y":0}, {"label":"k09", "x":9, "y":0}, {"label":"k0a", "x":10, "y":0}, {"label":"k0b", "x":11, "y":0}, {"label":"k0c", "x":12, "y":0}, {"label":"k0d", "x":13, "y":0, "w":2}, {"label":"k10", "x":0, "y":1, "w":1.5}, {"label":"k11", "x":1.5, "y":1}, {"label":"k12", "x":2.5, "y":1}, {"label":"k13", "x":3.5, "y":1}, {"label":"k14", "x":4.5, "y":1}, {"label":"k15", "x":5.5, "y":1}, {"label":"k16", "x":6.5, "y":1}, {"label":"k17", "x":7.5, "y":1}, {"label":"k18", "x":8.5, "y":1}, {"label":"k19", "x":9.5, "y":1}, {"label":"k1a", "x":10.5, "y":1}, {"label":"k1b", "x":11.5, "y":1}, {"label":"k1c", "x":12.5, "y":1}, {"label":"k1d", "x":13.5, "y":1, "w":1.5}, {"label":"k20", "x":0, "y":2, "w":1.75}, {"label":"k21", "x":1.75, "y":2}, {"label":"k22", "x":2.75, "y":2}, {"label":"k23", "x":3.75, "y":2}, {"label":"k24", "x":4.75, "y":2}, {"label":"k25", "x":5.75, "y":2}, {"label":"k26", "x":6.75, "y":2}, {"label":"k27", "x":7.75, "y":2}, {"label":"k28", "x":8.75, "y":2}, {"label":"k29", "x":9.75, "y":2}, {"label":"k2a", "x":10.75, "y":2}, {"label":"k2b", "x":11.75, "y":2}, {"label":"k2c", "x":12.75, "y":2}, {"label":"k2d", "x":13.75, "y":2, "w":1.25}, {"label":"k30", "x":0, "y":3, "w":1.25}, {"label":"k31", "x":1.25, "y":3}, {"label":"k32", "x":2.25, "y":3}, {"label":"k33", "x":3.25, "y":3}, {"label":"k34", "x":4.25, "y":3}, {"label":"k35", "x":5.25, "y":3}, {"label":"k36", "x":6.25, "y":3}, {"label":"k37", "x":7.25, "y":3}, {"label":"k38", "x":8.25, "y":3}, {"label":"k39", "x":9.25, "y":3}, {"label":"k3a", "x":10.25, "y":3}, {"label":"k3b", "x":11.25, "y":3}, {"label":"k3d", "x":12.25, "y":3, "w":2.75}, {"label":"k40", "x":0, "y":4, "w":1.25}, {"label":"k41", "x":1.25, "y":4, "w":1.25}, {"label":"k42", "x":2.5, "y":4, "w":1.25}, {"label":"k45", "x":3.75, "y":4, "w":6.25}, {"label":"k4a", "x":10, "y":4, "w":1.25}, {"label":"k4b", "x":11.25, "y":4, "w":1.25}, {"label":"k4c", "x":12.5, "y":4, "w":1.25}, {"label":"k4d", "x":13.75, "y":4, "w":1.25}]
|
||||
},
|
||||
"LAYOUT_iso_splitrshift": {
|
||||
"layout": [{"label":"k00", "x":0, "y":0}, {"label":"k01", "x":1, "y":0}, {"label":"k02", "x":2, "y":0}, {"label":"k03", "x":3, "y":0}, {"label":"k04", "x":4, "y":0}, {"label":"k05", "x":5, "y":0}, {"label":"k06", "x":6, "y":0}, {"label":"k07", "x":7, "y":0}, {"label":"k08", "x":8, "y":0}, {"label":"k09", "x":9, "y":0}, {"label":"k0a", "x":10, "y":0}, {"label":"k0b", "x":11, "y":0}, {"label":"k0c", "x":12, "y":0}, {"label":"k0d", "x":13, "y":0, "w":2}, {"label":"k10", "x":0, "y":1, "w":1.5}, {"label":"k11", "x":1.5, "y":1}, {"label":"k12", "x":2.5, "y":1}, {"label":"k13", "x":3.5, "y":1}, {"label":"k14", "x":4.5, "y":1}, {"label":"k15", "x":5.5, "y":1}, {"label":"k16", "x":6.5, "y":1}, {"label":"k17", "x":7.5, "y":1}, {"label":"k18", "x":8.5, "y":1}, {"label":"k19", "x":9.5, "y":1}, {"label":"k1a", "x":10.5, "y":1}, {"label":"k1b", "x":11.5, "y":1}, {"label":"k1c", "x":12.5, "y":1}, {"label":"k1d", "x":13.5, "y":1, "w":1.5}, {"label":"k20", "x":0, "y":2, "w":1.75}, {"label":"k21", "x":1.75, "y":2}, {"label":"k22", "x":2.75, "y":2}, {"label":"k23", "x":3.75, "y":2}, {"label":"k24", "x":4.75, "y":2}, {"label":"k25", "x":5.75, "y":2}, {"label":"k26", "x":6.75, "y":2}, {"label":"k27", "x":7.75, "y":2}, {"label":"k28", "x":8.75, "y":2}, {"label":"k29", "x":9.75, "y":2}, {"label":"k2a", "x":10.75, "y":2}, {"label":"k2b", "x":11.75, "y":2}, {"label":"k2c", "x":12.75, "y":2}, {"label":"k2d", "x":13.75, "y":2, "w":1.25}, {"label":"k30", "x":0, "y":3, "w":1.25}, {"label":"k31", "x":1.25, "y":3}, {"label":"k32", "x":2.25, "y":3}, {"label":"k33", "x":3.25, "y":3}, {"label":"k34", "x":4.25, "y":3}, {"label":"k35", "x":5.25, "y":3}, {"label":"k36", "x":6.25, "y":3}, {"label":"k37", "x":7.25, "y":3}, {"label":"k38", "x":8.25, "y":3}, {"label":"k39", "x":9.25, "y":3}, {"label":"k3a", "x":10.25, "y":3}, {"label":"k3b", "x":11.25, "y":3}, {"label":"k3d", "x":12.25, "y":3, "w":1.75}, {"label":"k3c", "x":14, "y":3}, {"label":"k40", "x":0, "y":4, "w":1.25}, {"label":"k41", "x":1.25, "y":4, "w":1.25}, {"label":"k42", "x":2.5, "y":4, "w":1.25}, {"label":"k45", "x":3.75, "y":4, "w":6.25}, {"label":"k4a", "x":10, "y":4, "w":1.25}, {"label":"k4b", "x":11.25, "y":4, "w":1.25}, {"label":"k4c", "x":12.5, "y":4, "w":1.25}, {"label":"k4d", "x":13.75, "y":4, "w":1.25}]
|
||||
},
|
||||
"LAYOUT_max": {
|
||||
"layout": [{"label":"k00", "x":0, "y":0}, {"label":"k01", "x":1, "y":0}, {"label":"k02", "x":2, "y":0}, {"label":"k03", "x":3, "y":0}, {"label":"k04", "x":4, "y":0}, {"label":"k05", "x":5, "y":0}, {"label":"k06", "x":6, "y":0}, {"label":"k07", "x":7, "y":0}, {"label":"k08", "x":8, "y":0}, {"label":"k09", "x":9, "y":0}, {"label":"k0a", "x":10, "y":0}, {"label":"k0b", "x":11, "y":0}, {"label":"k0c", "x":12, "y":0}, {"label":"k0d", "x":13, "y":0}, {"label":"k49", "x":14, "y":0}, {"label":"k10", "x":0, "y":1, "w":1.5}, {"label":"k11", "x":1.5, "y":1}, {"label":"k12", "x":2.5, "y":1}, {"label":"k13", "x":3.5, "y":1}, {"label":"k14", "x":4.5, "y":1}, {"label":"k15", "x":5.5, "y":1}, {"label":"k16", "x":6.5, "y":1}, {"label":"k17", "x":7.5, "y":1}, {"label":"k18", "x":8.5, "y":1}, {"label":"k19", "x":9.5, "y":1}, {"label":"k1a", "x":10.5, "y":1}, {"label":"k1b", "x":11.5, "y":1}, {"label":"k1c", "x":12.5, "y":1}, {"label":"k1d", "x":13.5, "y":1, "w":1.5}, {"label":"k20", "x":0, "y":2, "w":1.75}, {"label":"k21", "x":1.75, "y":2}, {"label":"k22", "x":2.75, "y":2}, {"label":"k23", "x":3.75, "y":2}, {"label":"k24", "x":4.75, "y":2}, {"label":"k25", "x":5.75, "y":2}, {"label":"k26", "x":6.75, "y":2}, {"label":"k27", "x":7.75, "y":2}, {"label":"k28", "x":8.75, "y":2}, {"label":"k29", "x":9.75, "y":2}, {"label":"k2a", "x":10.75, "y":2}, {"label":"k2b", "x":11.75, "y":2}, {"label":"k2d", "x":12.75, "y":2, "w":2.25}, {"label":"k30", "x":0, "y":3, "w":1.25}, {"label":"k31", "x":1.25, "y":3}, {"label":"k32", "x":2.25, "y":3}, {"label":"k33", "x":3.25, "y":3}, {"label":"k34", "x":4.25, "y":3}, {"label":"k35", "x":5.25, "y":3}, {"label":"k36", "x":6.25, "y":3}, {"label":"k37", "x":7.25, "y":3}, {"label":"k38", "x":8.25, "y":3}, {"label":"k39", "x":9.25, "y":3}, {"label":"k3a", "x":10.25, "y":3}, {"label":"k3b", "x":11.25, "y":3}, {"label":"k3d", "x":12.25, "y":3, "w":1.75}, {"label":"k3c", "x":14, "y":3}, {"label":"k40", "x":0, "y":4, "w":1.25}, {"label":"k41", "x":1.25, "y":4, "w":1.25}, {"label":"k42", "x":2.5, "y":4, "w":1.25}, {"label":"k45", "x":3.75, "y":4, "w":6.25}, {"label":"k4a", "x":10, "y":4, "w":1.25}, {"label":"k4b", "x":11.25, "y":4, "w":1.25}, {"label":"k4c", "x":12.5, "y":4, "w":1.25}, {"label":"k4d", "x":13.75, "y":4, "w":1.25}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
#include "amj60.h"
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
// Each layer gets a name for readability, which is then used in the keymap matrix below.
|
||||
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
|
||||
@@ -29,7 +29,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
* |Ctrl|Win |Alt | Space/Fn0 |Alt |Win |Menu|RCtl|
|
||||
* `-----------------------------------------------------------'
|
||||
*/
|
||||
[_DEF] = KEYMAP_MAX(
|
||||
[_DEF] = LAYOUT_max(
|
||||
KC_ESC, 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_BSLS, KC_GRV, \
|
||||
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_BSPC, \
|
||||
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, \
|
||||
@@ -49,7 +49,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
* | | | | |Alt |Prev|Vol-|Next|
|
||||
* `-----------------------------------------------------------'
|
||||
*/
|
||||
[_SPC] = KEYMAP_MAX(
|
||||
[_SPC] = LAYOUT_max(
|
||||
KC_PSCR, 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_PAUS, KC_UP, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL, \
|
||||
_______, KC_LEFT, KC_DOWN, KC_RIGHT, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______, _______, KC_MPLY, \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
#include "amj60.h"
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
// Each layer gets a name for readability, which is then used in the keymap matrix below.
|
||||
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
|
||||
@@ -48,7 +48,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
* |Ctrl|Win |Alt | Space/Fn0 |Alt |Win |Menu|RCtl| Gui Menu, RCtrl is
|
||||
* `-----------------------------------------------------------' LEFT DWN RIGHT
|
||||
*/
|
||||
[_DEF] = KEYMAP_ISO_SPLITRSHIFT(
|
||||
[_DEF] = LAYOUT_iso_splitrshift(
|
||||
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, \
|
||||
TABDUAL, 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, \
|
||||
CAPSDUAL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, ENTERDUAL, \
|
||||
@@ -68,7 +68,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
* | | | | |Alt |Prev|Vol-|Next|
|
||||
* `-----------------------------------------------------------'
|
||||
*/
|
||||
[_SPC] = KEYMAP_ISO_SPLITRSHIFT(
|
||||
[_SPC] = LAYOUT_iso_splitrshift(
|
||||
KC_PSCR, 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_PAUS, KC_UP, GER_BRC_L, GER_BRC_R, _______, _______, GER_PAR_L, GER_PAR_R, _______, _______, _______, _______, _______, \
|
||||
_______, KC_LEFT, KC_DOWN, KC_RIGHT, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______, _______, _______, KC_MPLY, \
|
||||
@@ -88,7 +88,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
* | | | | |Alt |Pos1|PgDn|End |
|
||||
* `-----------------------------------------------------------'
|
||||
*/
|
||||
[_TAB] = KEYMAP_ISO_SPLITRSHIFT(
|
||||
[_TAB] = LAYOUT_iso_splitrshift(
|
||||
KC_WAKE, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_INS, \
|
||||
_______, _______, _______, _______, _______, _______, _______, GER_CUR_L, GER_CUR_R, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END, _______, _______, _______, KC_ENT, \
|
||||
@@ -108,7 +108,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
* |Ctrl|Win |Alt | |Alt |Left|Down|Right|
|
||||
* `-----------------------------------------------------------'
|
||||
*/
|
||||
[_SFX] = KEYMAP_ISO_SPLITRSHIFT(
|
||||
[_SFX] = LAYOUT_iso_splitrshift(
|
||||
RESET, _______, _______, _______, _______, _______, _______, KC_7, KC_8, KC_9, _______, _______, _______, KC_BSPC, \
|
||||
_______, _______, _______, _______, _______, _______, _______, KC_4, KC_5, KC_6, _______, _______, _______, KC_BSLS, \
|
||||
_______, F(2), F(3), _______, _______, _______, _______, KC_1, KC_2, KC_3, _______, _______, XXXXXXX, KC_ENT, \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
#include "amj60.h"
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
// Each layer gets a name for readability, which is then used in the keymap matrix below.
|
||||
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
|
||||
@@ -29,7 +29,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
* |Ctrl|Win |Alt | Space/Fn0 |Alt |Win |Menu|RCtl|
|
||||
* `-----------------------------------------------------------'
|
||||
*/
|
||||
[_DEF] = KEYMAP_MAX(
|
||||
[_DEF] = LAYOUT_max(
|
||||
KC_ESC, 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_BSLS, KC_GRV, \
|
||||
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_BSPC, \
|
||||
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, \
|
||||
@@ -49,7 +49,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
* | | | | |Alt |Prev|Vol-|Next|
|
||||
* `-----------------------------------------------------------'
|
||||
*/
|
||||
[_SPC] = KEYMAP_MAX(
|
||||
[_SPC] = LAYOUT_max(
|
||||
KC_PSCR, 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_PAUS, KC_UP, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL, \
|
||||
_______, KC_LEFT, KC_DOWN, KC_RIGHT, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______, _______, KC_MPLY, \
|
||||
|
||||
+28
-26
@@ -23,38 +23,40 @@
|
||||
*/
|
||||
// The first section contains all of the arguments
|
||||
// The second converts the arguments into a two-dimensional array
|
||||
#define KEYMAP( \
|
||||
k00, k01, k02, k03, \
|
||||
k10, k11, k12, k13, \
|
||||
k20, k21, k22, k23, \
|
||||
k30, k31, k32, \
|
||||
k40, k41, k42, k43, \
|
||||
k50, k52 \
|
||||
#define LAYOUT_numpad_6x4( \
|
||||
k00, k01, k02, k03, \
|
||||
k10, k11, k12, k13, \
|
||||
k20, k21, k22, \
|
||||
k30, k31, k32, k23, \
|
||||
k40, k41, k42, \
|
||||
k50, k52, k43 \
|
||||
) \
|
||||
{ \
|
||||
{k00, k01, k02, k03}, \
|
||||
{k10, k11, k12, k13}, \
|
||||
{k20, k21, k22, k23}, \
|
||||
{k30, k31, k32, XXX}, \
|
||||
{k40, k41, k42, k43}, \
|
||||
{k50, XXX, k52, XXX} \
|
||||
{k00, k01, k02, k03}, \
|
||||
{k10, k11, k12, k13}, \
|
||||
{k20, k21, k22, k23}, \
|
||||
{k30, k31, k32, XXX}, \
|
||||
{k40, k41, k42, k43}, \
|
||||
{k50, XXX, k52, XXX} \
|
||||
}
|
||||
#define MAXKEYMAP( \
|
||||
k00, k01, k02, k03, \
|
||||
k10, k11, k12, k13, \
|
||||
k20, k21, k22, k23, \
|
||||
k30, k31, k32, k33, \
|
||||
k40, k41, k42, k43, \
|
||||
k50, k51, k52, k53\
|
||||
|
||||
#define LAYOUT_ortho_6x4( \
|
||||
k00, k01, k02, k03, \
|
||||
k10, k11, k12, k13, \
|
||||
k20, k21, k22, k23, \
|
||||
k30, k31, k32, k33, \
|
||||
k40, k41, k42, k43, \
|
||||
k50, k51, k52, k53 \
|
||||
) \
|
||||
{ \
|
||||
{k00, k01, k02, k03}, \
|
||||
{k10, k11, k12, k13}, \
|
||||
{k20, k21, k22, k23}, \
|
||||
{k30, k31, k32, k33}, \
|
||||
{k40, k41, k42, k43}, \
|
||||
{k50, k51, k52, k53} \
|
||||
{k00, k01, k02, k03}, \
|
||||
{k10, k11, k12, k13}, \
|
||||
{k20, k21, k22, k23}, \
|
||||
{k30, k31, k32, k33}, \
|
||||
{k40, k41, k42, k43}, \
|
||||
{k50, k51, k52, k53} \
|
||||
}
|
||||
|
||||
void matrix_init_user(void);
|
||||
void matrix_scan_user(void);
|
||||
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
{
|
||||
"keyboard_name": "AMJ Pad",
|
||||
"url": "",
|
||||
"maintainer": "qmk",
|
||||
"bootloader": "",
|
||||
"width": 4,
|
||||
"height": 6,
|
||||
"keyboard_name": "AMJ Pad",
|
||||
"url": "",
|
||||
"maintainer": "qmk",
|
||||
"width": 4,
|
||||
"height": 6,
|
||||
"layouts": {
|
||||
"LAYOUT": {
|
||||
"key_count": 21,
|
||||
"layout": [{"x":0, "y":0}, {"x":1, "y":0}, {"x":2, "y":0}, {"x":3, "y":0}, {"x":0, "y":1}, {"x":1, "y":1}, {"x":2, "y":1}, {"x":3, "y":1}, {"x":0, "y":2}, {"x":1, "y":2}, {"x":2, "y":2}, {"x":3, "y":2, "h":2}, {"x":0, "y":3}, {"x":1, "y":3}, {"x":2, "y":3}, {"x":0, "y":4}, {"x":1, "y":4}, {"x":2, "y":4}, {"x":3, "y":4, "h":2}, {"x":0, "y":5, "w":2}, {"x":2, "y":5}]
|
||||
},
|
||||
"LAYOUT_all": {
|
||||
"key_count": 24,
|
||||
"layout": [{"label":"k00", "x":0, "y":0}, {"label":"k01", "x":1, "y":0}, {"label":"k02", "x":2, "y":0}, {"label":"k03", "x":3, "y":0}, {"label":"k10", "x":0, "y":1}, {"label":"k11", "x":1, "y":1}, {"label":"k12", "x":2, "y":1}, {"label":"k13", "x":3, "y":1}, {"label":"k20", "x":0, "y":2}, {"label":"k21", "x":1, "y":2}, {"label":"k22", "x":2, "y":2}, {"label":"k23", "x":3, "y":2}, {"label":"k30", "x":0, "y":3}, {"label":"k31", "x":1, "y":3}, {"label":"k32", "x":2, "y":3}, {"label":"k33", "x":3, "y":3}, {"label":"k40", "x":0, "y":4}, {"label":"k41", "x":1, "y":4}, {"label":"k42", "x":2, "y":4}, {"label":"k43", "x":3, "y":4}, {"label":"k50", "x":0, "y":5}, {"label":"k51", "x":1, "y":5}, {"label":"k52", "x":2, "y":5}, {"label":"k53", "x":3, "y":5}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "amjpad.h"
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
#include "rgblight.h"
|
||||
@@ -33,13 +33,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
* `-------------------'
|
||||
*/
|
||||
|
||||
[_BL] = KEYMAP(
|
||||
KC_ESC,KC_TAB,KC_BSPC,KC_PEQL, \
|
||||
KC_NLCK,KC_PSLS,KC_PAST,KC_PMNS, \
|
||||
KC_P7, KC_P8, KC_P9, KC_PPLS, \
|
||||
KC_P4, KC_P5, KC_P6, \
|
||||
KC_P1, KC_P2, KC_P3, KC_PENT, \
|
||||
KC_P0, LT(_FL,KC_PDOT)),
|
||||
[_BL] = LAYOUT_numpad_6x4(
|
||||
KC_ESC, KC_TAB, KC_BSPC, KC_PEQL, \
|
||||
KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS, \
|
||||
KC_P7, KC_P8, KC_P9, \
|
||||
KC_P4, KC_P5, KC_P6, KC_PPLS, \
|
||||
KC_P1, KC_P2, KC_P3, \
|
||||
KC_P0, LT(_FL,KC_PDOT), KC_PENT \
|
||||
),
|
||||
|
||||
/* Keymap _FL: Function Layer
|
||||
* ,-------------------.
|
||||
@@ -56,14 +57,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
* | 0 |./FN| |
|
||||
* `-------------------'
|
||||
*/
|
||||
[_FL] = KEYMAP(
|
||||
|
||||
KC_ESC,KC_TAB,KC_BSPC,KC_PEQL, \
|
||||
KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS, \
|
||||
KC_P7, KC_P8, KC_P9, RESET, \
|
||||
KC_P4, KC_P5, KC_P6, \
|
||||
KC_P1, KC_P2, KC_P3, KC_PENT, \
|
||||
KC_P0, LT(_FL,KC_PDOT)),
|
||||
[_FL] = LAYOUT_numpad_6x4(
|
||||
KC_ESC, KC_TAB, KC_BSPC, KC_PEQL, \
|
||||
KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS, \
|
||||
KC_P7, KC_P8, KC_P9, \
|
||||
KC_P4, KC_P5, KC_P6, RESET, \
|
||||
KC_P1, KC_P2, KC_P3, \
|
||||
KC_P0, LT(_FL,KC_PDOT), KC_PENT \
|
||||
),
|
||||
};
|
||||
|
||||
enum function_id {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "amjpad.h"
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
#include "rgblight.h"
|
||||
@@ -33,14 +33,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
* `-------------------'
|
||||
*/
|
||||
|
||||
[_BL] = MAXKEYMAP(
|
||||
|
||||
KC_ESC, KC_TAB, KC_MINS,KC_EQL, \
|
||||
KC_F1, KC_F2, KC_F3, KC_F4, \
|
||||
KC_P7, KC_P8, KC_P9, KC_PMNS, \
|
||||
KC_P4, KC_P5, KC_P6, KC_PENT, \
|
||||
KC_P1, KC_P2, KC_P3, KC_BSLS, \
|
||||
KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT),
|
||||
[_BL] = LAYOUT_ortho_6x4(
|
||||
KC_ESC, KC_TAB, KC_MINS,KC_EQL, \
|
||||
KC_F1, KC_F2, KC_F3, KC_F4, \
|
||||
KC_P7, KC_P8, KC_P9, KC_PMNS, \
|
||||
KC_P4, KC_P5, KC_P6, KC_PENT, \
|
||||
KC_P1, KC_P2, KC_P3, KC_BSLS, \
|
||||
KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT
|
||||
),
|
||||
|
||||
/* Keymap _FL: Function Layer
|
||||
* ,-------------------.
|
||||
@@ -57,14 +57,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
* | 0 |./FN| |
|
||||
* `-------------------'
|
||||
*/
|
||||
[_FL] = MAXKEYMAP(
|
||||
|
||||
KC_ESC,KC_TAB,KC_BSPC,KC_PEQL, \
|
||||
KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS, \
|
||||
KC_P7, KC_P8, KC_P9, RESET, \
|
||||
KC_P4, KC_P5, KC_P6, KC_PENT, \
|
||||
KC_P1, KC_P2, KC_P3, KC_PENT, \
|
||||
KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT),
|
||||
[_FL] = LAYOUT_ortho_6x4(
|
||||
KC_ESC, KC_TAB, KC_BSPC, KC_PEQL, \
|
||||
KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS, \
|
||||
KC_P7, KC_P8, KC_P9, RESET, \
|
||||
KC_P4, KC_P5, KC_P6, KC_PENT, \
|
||||
KC_P1, KC_P2, KC_P3, KC_PENT, \
|
||||
KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT
|
||||
),
|
||||
};
|
||||
|
||||
enum function_id {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "amjpad.h"
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
#include "rgblight.h"
|
||||
@@ -30,14 +30,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
* `-------------------'
|
||||
*/
|
||||
|
||||
[_BL] = MAXKEYMAP(
|
||||
|
||||
KC_T, KC_G, KC_B, KC_SPACE,\
|
||||
KC_R, KC_F, KC_V, MO(1), \
|
||||
KC_E, KC_D, KC_C, KC_LGUI, \
|
||||
KC_W, KC_S, KC_X, KC_LALT, \
|
||||
KC_Q, KC_A, KC_Z, KC_LCTL, \
|
||||
KC_TAB, KC_ESC, KC_LSHIFT, MO(1)),
|
||||
[_BL] = LAYOUT_ortho_6x4(
|
||||
KC_T, KC_G, KC_B, KC_SPACE,\
|
||||
KC_R, KC_F, KC_V, MO(1), \
|
||||
KC_E, KC_D, KC_C, KC_LGUI, \
|
||||
KC_W, KC_S, KC_X, KC_LALT, \
|
||||
KC_Q, KC_A, KC_Z, KC_LCTL, \
|
||||
KC_TAB, KC_ESC, KC_LSHIFT, MO(1)
|
||||
),
|
||||
|
||||
/* Keymap _FL: Function Layer
|
||||
* ,-------------------.
|
||||
@@ -54,12 +54,12 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
* | ` | Del|Shft| |
|
||||
* `-------------------'
|
||||
*/
|
||||
[_FL] = MAXKEYMAP(
|
||||
|
||||
KC_5, KC_F5, KC_F11, _______, \
|
||||
KC_4, KC_F4, KC_F10, _______, \
|
||||
KC_3, KC_F3, KC_F9, _______, \
|
||||
KC_2, KC_F2, KC_F8, _______, \
|
||||
KC_1, KC_F1, KC_F7, _______, \
|
||||
KC_GRV,KC_DEL, _______, _______),
|
||||
[_FL] = LAYOUT_ortho_6x4(
|
||||
KC_5, KC_F5, KC_F11, _______, \
|
||||
KC_4, KC_F4, KC_F10, _______, \
|
||||
KC_3, KC_F3, KC_F9, _______, \
|
||||
KC_2, KC_F2, KC_F8, _______, \
|
||||
KC_1, KC_F1, KC_F7, _______, \
|
||||
KC_GRV,KC_DEL, _______, _______
|
||||
),
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user