aboutsummaryrefslogtreecommitdiffstats
path: root/keyboards
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards')
-rw-r--r--keyboards/infinity60/MEMO.txt385
-rw-r--r--keyboards/infinity60/config.h2
-rw-r--r--keyboards/infinity60/halconf.h4
-rw-r--r--keyboards/infinity60/keymaps/jpetermans/Makefile4
-rw-r--r--keyboards/infinity60/keymaps/jpetermans/config.h11
-rw-r--r--keyboards/infinity60/keymaps/jpetermans/keymap.c317
-rw-r--r--keyboards/infinity60/keymaps/jpetermans/readme.md79
-rw-r--r--keyboards/infinity60/led.c31
-rw-r--r--keyboards/infinity60/led_controller.c461
-rw-r--r--keyboards/infinity60/led_controller.h119
-rw-r--r--keyboards/infinity60/mcuconf.h11
-rw-r--r--keyboards/infinity60/rules.mk5
12 files changed, 1034 insertions, 395 deletions
diff --git a/keyboards/infinity60/MEMO.txt b/keyboards/infinity60/MEMO.txt
deleted file mode 100644
index e2886aa00..000000000
--- a/keyboards/infinity60/MEMO.txt
+++ /dev/null
@@ -1,385 +0,0 @@
-flabbergast's TMK/ChibiOS port
-==============================
-2015/10/16
-
-
-Build
------
-$ git clone -b chibios https://github.com/flabbergast/tmk_keyboard.git
-
-$ cd tmk_keyboard
-$ git submodule add -f -b kinetis https://github.com/flabbergast/ChibiOS.git tmk_core/tool/chibios/chibios
-or
-$ cd tmk_keyboard/tmk_core/tool/chibios
-$ git clone -b kinetis https://github.com/flabbergast/ChibiOS.git tmk_core/tool/chibios/chibios
-
-$ cd tmk_keyboard/keyboard/infinity_chibios
-$ make
-
-
-
-
-Chibios Configuration
----------------------
-halconf.h: for HAL configuration
- placed in project directory
- read in chibios/os/hal/hal.mk
- included in chibios/os/hal/include/hal.h
-mcuconf.h: for MCU configuration
- placed in project directory
- included in halconf.h
-
-
-Chibios Term
-------------
-PAL = Port Abstraction Layer
- palWritePad
- palReadPad
- palSetPad
- chibios/os/hal/include/pal.h
-
-LLD = Low Level Driver
-
-
-Makefile
---------
- # <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
- MCU_FAMILY = KINETIS
- MCU_SERIES = KL2x
-
- # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
- # or <this_dir>/ld/
- MCU_LDSCRIPT = MKL26Z64
-
- # - it should exist in <chibios>/os/common/ports/ARMCMx/compilers/GCC/mk/
- MCU_STARTUP = kl2x
-
- # Board: it should exist either in <chibios>/os/hal/boards/
- # or <this_dir>/boards
- BOARD = PJRC_TEENSY_LC
-
- MCU = cortex-m0
-
- # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
- ARMV = 6
-
-
-halconf.h
----------
-
-
-mcuconf.h
----------
-
-
-chconf.h
---------
-
-
-ld script
----------
---- ../../tmk_core/tool/chibios/chibios/os/common/ports/ARMCMx/compilers/GCC/ld/MKL26Z64.ld 2015-10-15 09:08:58.732904304 +0900
-+++ ld/MKL26Z64.ld 2015-10-15 08:48:06.430215496 +0900
-@@ -27,7 +27,8 @@
- {
- flash0 : org = 0x00000000, len = 0xc0
- flashcfg : org = 0x00000400, len = 0x10
-- flash : org = 0x00000410, len = 64k - 0x410
-+ flash : org = 0x00000410, len = 62k - 0x410
-+ eeprom_emu : org = 0x0000F800, len = 2k
- ram : org = 0x1FFFF800, len = 8k
- }
-
-@@ -35,6 +36,10 @@
- __ram_size__ = LENGTH(ram);
- __ram_end__ = __ram_start__ + __ram_size__;
-
-+__eeprom_workarea_start__ = ORIGIN(eeprom_emu);
-+__eeprom_workarea_size__ = LENGTH(eeprom_emu);
-+__eeprom_workarea_end__ = __eeprom_workarea_start__ + __eeprom_workarea_size__;
-+
- SECTIONS
- {
- . = 0;
-
-
-
-Configuration/Startup for Infinity 60%
---------------------------------------
-Configuration:
-
-
-Clock:
-Inifinity
- FEI(FLL Engaged Internal) mode with core clock:48MHz, bus clock:48MHz, flash clock:24MHz
- Clock dividor:
- SIM_CLKDIV1[OUTDIV1] = 0 divide-by-1 for core clock
- SIM_CLKDIV1[OUTDIV2] = 0 divide-by-1 for bus clock
- SIM_CLKDIV1[OUTDIV4] = 1 divide-by-2 for flash clock
- Internal reference clock:
- MCG_C1[IREFS] = 1 Internal Reference Select for clock source for FLL
- MCG_C1[IRCLKEN] = 1 Internal Reference Clock Enable
- FLL multipilication:
- MCG_C4[DMX32] = 1
- MCG_C4[DRST_DRS] = 01 FLL factor 1464 * 32.768kHz = 48MHz
-
-chibios/os/hal/ports/KINETIS/K20x/hal_lld.c
- k20x_clock_init(): called in __early_init() defined in board.c
- disable watchdog and configure clock
-
- configurable macros:
- KINETIS_NO_INIT: whether init or not
- KINETIS_MCG_MODE: clock mode
- KINETIS_MCG_MODE_FEI
- KINETIS_MCG_MODE_PEE
- hal/ports/KINETIS/K20x/hal_lld.h
-
-
-chibios/os/hal/boards/FREESCALE_FREEDOM_K20D50M/board.h
- PALConfig pal_default_config
- boardInit()
- __early_init()
- macro definitions for board infos, freq and mcu type
-
-chibios/os/hal/boards/FREESCALE_FREEDOM_K20D50M/board.c
-
-USB
-
-
-Startup
--------
- common/ports/ARMCMx/GCC/crt0_v[67]m.s
- Reset_Handler: startup code
- common/ports/ARMCMx/GCC/crt1.c
- __core_init(): weak
- __early_init(): weak
- __late_init(): weak
- __default_exit(): weak
- called from Reset_Handler of crt0
- common/ports/ARMCMx/GCC/vector.c
- common/ports/ARMCMx/GCC/ld/*.ld
-
-chibios/os/common/ports/ARMCMx/compilers/GCC/
-├── crt0_v6m.s
-├── crt0_v7m.s
-├── crt1.c
-├── ld
-│   ├── MK20DX128BLDR3.ld
-│   ├── MK20DX128BLDR4.ld
-│   ├── MK20DX128.ld
-│   ├── MK20DX256.ld
-│   ├── MKL25Z128.ld
-│   ├── MKL26Z128.ld
-│   ├── MKL26Z64.ld
-│   └── STM32L476xG.ld
-├── mk
-│   ├── startup_k20x5.mk
-│   ├── startup_k20x7.mk
-│   ├── startup_k20x.mk
-│   ├── startup_kl2x.mk
-│   └── startup_stm32l4xx.mk
-├── rules.ld
-├── rules.mk
-└── vectors.c
-
-chibios/os/hal/
-├── boards
-│   ├── FREESCALE_FREEDOM_K20D50M
-│   │   ├── board.c
-│   │   ├── board.h
-│   │   └── board.mk
-│   ├── MCHCK_K20
-│   │   ├── board.c
-│   │   ├── board.h
-│   │   └── board.mk
-│   ├── PJRC_TEENSY_3
-│   │   ├── board.c
-│   │   ├── board.h
-│   │   └── board.mk
-│   ├── PJRC_TEENSY_3_1
-│   │   ├── board.c
-│   │   ├── board.h
-│   │   └── board.mk
-│   ├── PJRC_TEENSY_LC
-│   │   ├── board.c
-│   │   ├── board.h
-│   │   └── board.mk
-│   ├── readme.txt
-│   ├── simulator
-│   │   ├── board.c
-│   │   ├── board.h
-│   │   └── board.mk
-│   ├── ST_NUCLEO_F030R8
-│   │   ├── board.c
-│   │   ├── board.h
-│   │   ├── board.mk
-│   │   └── cfg
-│   │   └── board.chcfg
-├── hal.mk
-├── include
-│   ├── adc.h
-│   ├── can.h
-│   ├── dac.h
-│   ├── ext.h
-│   ├── gpt.h
-│   ├── hal_channels.h
-│   ├── hal_files.h
-│   ├── hal.h
-│   ├── hal_ioblock.h
-│   ├── hal_mmcsd.h
-│   ├── hal_queues.h
-│   ├── hal_streams.h
-│   ├── i2c.h
-│   ├── i2s.h
-│   ├── icu.h
-│   ├── mac.h
-│   ├── mii.h
-│   ├── mmc_spi.h
-│   ├── pal.h
-│   ├── pwm.h
-│   ├── rtc.h
-│   ├── sdc.h
-│   ├── serial.h
-│   ├── serial_usb.h
-│   ├── spi.h
-│   ├── st.h
-│   ├── uart.h
-│   └── usb.h
-├── lib
-│   └── streams
-│   ├── chprintf.c
-│   ├── chprintf.h
-│   ├── memstreams.c
-│   ├── memstreams.h
-│   ├── nullstreams.c
-│   └── nullstreams.h
-├── osal
-│   ├── nil
-│   │   ├── osal.c
-│   │   ├── osal.h
-│   │   └── osal.mk
-│   ├── os-less
-│   │   └── ARMCMx
-│   │   ├── osal.c
-│   │   ├── osal.h
-│   │   └── osal.mk
-│   └── rt
-│   ├── osal.c
-│   ├── osal.h
-│   └── osal.mk
-├── ports
-│   ├── AVR
-│   ├── common
-│   │   └── ARMCMx
-│   │   ├── mpu.h
-│   │   ├── nvic.c
-│   │   └── nvic.h
-│   ├── KINETIS
-│   │   ├── K20x
-│   │   │   ├── hal_lld.c
-│   │   │   ├── hal_lld.h
-│   │   │   ├── kinetis_registry.h
-│   │   │   ├── platform.dox
-│   │   │   ├── platform.mk
-│   │   │   ├── pwm_lld.c
-│   │   │   ├── pwm_lld.h
-│   │   │   ├── spi_lld.c
-│   │   │   └── spi_lld.h
-│   │   ├── KL2x
-│   │   │   ├── hal_lld.c
-│   │   │   ├── hal_lld.h
-│   │   │   ├── kinetis_registry.h
-│   │   │   ├── platform.mk
-│   │   │   ├── pwm_lld.c
-│   │   │   └── pwm_lld.h
-│   │   ├── LLD
-│   │   │   ├── adc_lld.c
-│   │   │   ├── adc_lld.h
-│   │   │   ├── ext_lld.c
-│   │   │   ├── ext_lld.h
-│   │   │   ├── gpt_lld.c
-│   │   │   ├── gpt_lld.h
-│   │   │   ├── i2c_lld.c
-│   │   │   ├── i2c_lld.h
-│   │   │   ├── pal_lld.c
-│   │   │   ├── pal_lld.h
-│   │   │   ├── serial_lld.c
-│   │   │   ├── serial_lld.h
-│   │   │   ├── st_lld.c
-│   │   │   ├── st_lld.h
-│   │   │   ├── usb_lld.c
-│   │   │   └── usb_lld.h
-│   │   └── README.md
-│   ├── LPC
-│   ├── simulator
-│   └── STM32
-├── src
-│   ├── adc.c
-│   ├── can.c
-│   ├── dac.c
-│   ├── ext.c
-│   ├── gpt.c
-│   ├── hal.c
-│   ├── hal_mmcsd.c
-│   ├── hal_queues.c
-│   ├── i2c.c
-│   ├── i2s.c
-│   ├── icu.c
-│   ├── mac.c
-│   ├── mmc_spi.c
-│   ├── pal.c
-│   ├── pwm.c
-│   ├── rtc.c
-│   ├── sdc.c
-│   ├── serial.c
-│   ├── serial_usb.c
-│   ├── spi.c
-│   ├── st.c
-│   ├── uart.c
-│   └── usb.c
-└── templates
- ├── adc_lld.c
- ├── adc_lld.h
- ├── can_lld.c
- ├── can_lld.h
- ├── dac_lld.c
- ├── dac_lld.h
- ├── ext_lld.c
- ├── ext_lld.h
- ├── gpt_lld.c
- ├── gpt_lld.h
- ├── halconf.h
- ├── hal_lld.c
- ├── hal_lld.h
- ├── i2c_lld.c
- ├── i2c_lld.h
- ├── i2s_lld.c
- ├── i2s_lld.h
- ├── icu_lld.c
- ├── icu_lld.h
- ├── mac_lld.c
- ├── mac_lld.h
- ├── mcuconf.h
- ├── osal
- │   ├── osal.c
- │   ├── osal.h
- │   └── osal.mk
- ├── pal_lld.c
- ├── pal_lld.h
- ├── platform.mk
- ├── pwm_lld.c
- ├── pwm_lld.h
- ├── rtc_lld.c
- ├── rtc_lld.h
- ├── sdc_lld.c
- ├── sdc_lld.h
- ├── serial_lld.c
- ├── serial_lld.h
- ├── spi_lld.c
- ├── spi_lld.h
- ├── st_lld.c
- ├── st_lld.h
- ├── uart_lld.c
- ├── uart_lld.h
- ├── usb_lld.c
- └── usb_lld.h
diff --git a/keyboards/infinity60/config.h b/keyboards/infinity60/config.h
index f8346fe16..83930901c 100644
--- a/keyboards/infinity60/config.h
+++ b/keyboards/infinity60/config.h
@@ -54,7 +54,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
//#define INFINITY_PROTOTYPE
/* Keymap for Infinity 1.1a (first revision with LED support) */
-//#define INFINITY_LED
+#define INFINITY_LED
/*
* Feature disable options
diff --git a/keyboards/infinity60/halconf.h b/keyboards/infinity60/halconf.h
index 46b37a4f4..f89dfc2e1 100644
--- a/keyboards/infinity60/halconf.h
+++ b/keyboards/infinity60/halconf.h
@@ -76,7 +76,7 @@
* @brief Enables the I2C subsystem.
*/
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
-#define HAL_USE_I2C FALSE
+#define HAL_USE_I2C TRUE
#endif
/**
@@ -139,7 +139,7 @@
* @brief Enables the SERIAL over USB subsystem.
*/
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
-#define HAL_USE_SERIAL_USB TRUE
+#define HAL_USE_SERIAL_USB FALSE
#endif
/**
diff --git a/keyboards/infinity60/keymaps/jpetermans/Makefile b/keyboards/infinity60/keymaps/jpetermans/Makefile
new file mode 100644
index 000000000..df3d1e952
--- /dev/null
+++ b/keyboards/infinity60/keymaps/jpetermans/Makefile
@@ -0,0 +1,4 @@
+
+ifndef QUANTUM_DIR
+ include ../../../../Makefile
+endif
diff --git a/keyboards/infinity60/keymaps/jpetermans/config.h b/keyboards/infinity60/keymaps/jpetermans/config.h
new file mode 100644
index 000000000..72a2ed081
--- /dev/null
+++ b/keyboards/infinity60/keymaps/jpetermans/config.h
@@ -0,0 +1,11 @@
+#ifndef CONFIG_USER_H
+#define CONFIG_USER_H
+
+
+#include "../../config.h"
+
+//overrides
+#undef TAPPING_TOGGLE
+#define TAPPING_TOGGLE 2
+
+#endif
diff --git a/keyboards/infinity60/keymaps/jpetermans/keymap.c b/keyboards/infinity60/keymaps/jpetermans/keymap.c
new file mode 100644
index 000000000..1afb7c067
--- /dev/null
+++ b/keyboards/infinity60/keymaps/jpetermans/keymap.c
@@ -0,0 +1,317 @@
+#include "infinity60.h"
+#include "led_controller.h"
+
+//Helpful Defines
+#define _______ KC_TRNS
+
+//Define Layer Names
+#define _BASE 0
+#define _NUMPAD 1
+#define _FNAV 2
+#define _MEDIA 3
+#define _TILDE 4
+
+//IS31 chip has 8 available led pages, using 0 for all leds and 7 for single toggles
+#define max_pages 6
+
+enum ic60_keycodes {
+ NUMPAD,
+ FNAV,
+ MEDIA,
+ TILDE,
+ CTLALTDEL,
+ BACKLIGHT,
+ BRIGHT,
+ DIM,
+ BREATH,
+ ALL,
+ GAME,
+ MODE_SINGLE,
+ MODE_PAGE,
+ MODE_FLASH
+};
+
+uint8_t current_layer_global = 0;
+uint8_t led_mode_global = MODE_SINGLE;
+uint8_t backlight_status_global = 1; //init on/off state of backlight
+uint32_t led_layer_state = 0;
+
+/* ==================================
+ * KEYMAPS
+ * ==================================*/
+
+const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /* Layer 0: Default Layer
+ * ,-----------------------------------------------------------.
+ * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| Backs|
+ * |-----------------------------------------------------------|
+ * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \|
+ * |-----------------------------------------------------------|
+ * |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Enter |
+ * |-----------------------------------------------------------|
+ * |Shif| | Z| X| C| V| B| N| M| ,| .| /|Shift |
+ * |-----------------------------------------------------------|
+ * |Ctrl|Gui |Alt | Space |Alt |Gui | FN | Ctrl |
+ * `-----------------------------------------------------------'
+ */
+ /* default */
+ [_BASE] = KEYMAP( \
+ 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_NO,\
+ 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, \
+ TT(_FNAV), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN,KC_QUOT,KC_ENT, \
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH,F(TILDE),KC_NO, \
+ KC_LCTL, KC_LGUI,KC_LALT, KC_SPC, KC_RALT,TG(_NUMPAD),MO(_MEDIA), KC_RCTL \
+ ),
+
+ /* numpad */
+ [_NUMPAD] = KEYMAP( \
+ _______,_______,_______,_______,_______,_______,_______, KC_P7, KC_P8, KC_P9, KC_PSLS, _______,_______,_______,KC_NO,\
+ _______,_______,_______,_______,_______,_______,_______, KC_P4, KC_P5, KC_P6, KC_PAST, _______,_______,_______, \
+ MO(_FNAV),_______,_______,_______,_______,_______,_______, KC_P1, KC_P2, KC_P3, KC_PMNS, _______,_______, \
+ _______,_______,_______,_______,_______,_______,_______, KC_P0,KC_COMM,KC_PDOT,KC_PPLS, _______,KC_NO, \
+ _______,_______,_______, MO(_BASE), _______,_______,_______,_______ \
+ ),
+
+ /* F-, arrow, and media keys */
+ [_FNAV] = KEYMAP( \
+ KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______,KC_NO,\
+ KC_CAPS,_______,_______,_______,_______,_______,_______,KC_PGUP,KC_UP,KC_PGDN,KC_PSCR,_______,_______,KC_DEL, \
+ _______,M(0),KC_BTN2,_______,_______,_______,KC_HOME,KC_LEFT,KC_DOWN,KC_RGHT,KC_INS,_______,_______, \
+ _______,KC_APP,KC_BTN1,KC_CALC,_______,_______,KC_END,_______,_______,_______,_______,_______,KC_NO, \
+ _______,_______,_______, _______, F(CTLALTDEL),KC_NLCK,_______,_______ \
+ ),
+
+ /* media */
+ [_MEDIA] = KEYMAP( \
+ _______,F(MODE_SINGLE),F(MODE_PAGE),F(MODE_FLASH),_______,_______,_______, _______, _______, _______,KC_MUTE, KC_VOLD, KC_VOLU,_______,KC_NO,\
+ _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______,_______,\
+ _______,_______,_______,_______,_______,F(GAME),_______, _______, _______, _______,_______, _______,_______, \
+ _______,_______,F(ALL) ,F(BRIGHT),F(DIM),F(BACKLIGHT),_______, _______, KC_MPRV, KC_MNXT,KC_MSTP, _______,KC_NO, \
+ _______,_______,_______, KC_MPLY, _______,_______, _______,_______ \
+ ),
+ /* ~ */
+ [_TILDE] = KEYMAP( \
+ KC_GRV,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______,_______,KC_NO,\
+ _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______,_______,\
+ _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______, \
+ _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,KC_NO, \
+ _______,_______,_______, _______, _______,_______, _______,_______ \
+ ),
+ /* template */
+ [5] = KEYMAP( \
+ _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______,_______,KC_NO,\
+ _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______,_______,\
+ _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______, \
+ _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,KC_NO, \
+ _______,_______,_______, _______, _______,_______, _______,_______ \
+ ),
+};
+
+//id for user defined functions and macros
+enum function_id {
+ NONE,
+};
+
+enum macro_id {
+ ACTION_LEDS_ALL,
+ ACTION_LEDS_GAME,
+ ACTION_LEDS_BACKLIGHT,
+ ACTION_LEDS_BRIGHT,
+ ACTION_LEDS_DIM,
+ ACTION_LEDS_BREATH,
+ ACTION_LEDS_SINGLE,
+ ACTION_LEDS_PAGE,
+ ACTION_LEDS_FLASH,
+};
+
+/* ==================================
+ * LED MAPPING
+ * ==================================*/
+
+/*
+ Infinity60 LED MAP
+ 11 12 13 14 15 16 17 18 21 22 23 24 25 26 27*
+ 28 31 32 33 34 35 36 37 38 41 42 43 44 45
+ 46 47 48 51 52 53 54 55 56 57 58 61 62
+ 63 64 65 66 67 68 71 72 73 74 75 76 77*
+ 78 81 82 83 84 85 86 87
+ *Unused in Alphabet Layout
+*/
+
+//======== full page arrays =========
+//LED Page 1 - _Numpad
+//any change in array size needs to be mirrored in matrix_init_user
+uint8_t led_numpad[16] = {
+ 18,21,22,23,
+ 37,38,41,42,
+ 55,56,57,58,
+ 72,73,74,75
+};
+//LED Page 2 - _Nav
+uint8_t led_nav[12] = {
+ 38,
+ 47,48, 55,56,57,
+ 64,65,66
+};
+//LED Page 3 - _Media
+uint8_t led_media[15] = {
+ 12,13,14, 23,24,25,
+ 65,66,67,68, 73,74,75,
+ 83, 86
+};
+//LED Page 4 - _Game "WASD"
+uint8_t led_game[5] = {
+ 11,
+ 32,
+ 47,48,51
+};
+
+//======== qmk functions =========
+const uint16_t fn_actions[] = {
+ [CTLALTDEL] = ACTION_KEY(LALT(LCTL(KC_DEL))),
+ [TILDE] = ACTION_LAYER_MODS(_TILDE, MOD_LSFT),
+ [ALL] = ACTION_FUNCTION(ACTION_LEDS_ALL),
+ [GAME] = ACTION_FUNCTION(ACTION_LEDS_GAME),
+ [BACKLIGHT] = ACTION_FUNCTION(ACTION_LEDS_BACKLIGHT),
+ [BRIGHT] = ACTION_FUNCTION(ACTION_LEDS_BRIGHT),
+ [DIM] = ACTION_FUNCTION(ACTION_LEDS_DIM),
+ [BREATH] = ACTION_FUNCTION(ACTION_LEDS_BREATH),
+ [MODE_SINGLE] = ACTION_FUNCTION(ACTION_LEDS_SINGLE),
+ [MODE_PAGE] = ACTION_FUNCTION(ACTION_LEDS_PAGE),
+ [MODE_FLASH] = ACTION_FUNCTION(ACTION_LEDS_FLASH),
+};
+
+/* custom action function */
+void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
+ msg_t msg;
+
+ switch(id) {
+ case ACTION_LEDS_ALL:
+ if(record->event.pressed) {
+ led_mode_global = led_mode_global == ALL ? MODE_SINGLE : ALL;
+ msg=(TOGGLE_ALL << 8) | 0;
+ chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
+ }
+ break;
+
+ case ACTION_LEDS_BACKLIGHT:
+ if(record->event.pressed) {
+ backlight_status_global ^= 1;
+ msg=(TOGGLE_BACKLIGHT << 8) | (backlight_status_global);
+ chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
+ }
+ break;
+
+ case ACTION_LEDS_GAME:
+ if(record->event.pressed) {
+ led_mode_global = led_mode_global == GAME ? MODE_SINGLE : GAME;
+
+ msg=(DISPLAY_PAGE << 8) | 4;
+ chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
+ }
+ break;
+
+ case ACTION_LEDS_BRIGHT:
+ if(record->event.pressed) {
+ msg=(STEP_BRIGHTNESS << 8) | 1;
+ chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
+ }
+ break;
+
+ case ACTION_LEDS_DIM:
+ if(record->event.pressed) {
+ msg=(STEP_BRIGHTNESS << 8) | 0;
+ chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
+ }
+ break;
+
+ case ACTION_LEDS_BREATH:
+ if(record->event.pressed) {
+ msg=(TOGGLE_BREATH << 8) | 0;
+ chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
+ }
+ break;
+
+ //set led_mode for matrix_scan to toggle leds
+ case ACTION_LEDS_SINGLE:
+ led_mode_global = MODE_SINGLE;
+ break;
+ case ACTION_LEDS_PAGE:
+ led_mode_global = MODE_PAGE;
+ break;
+ case ACTION_LEDS_FLASH:
+ led_mode_global = MODE_FLASH;
+ break;
+
+ }
+}
+
+const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
+{
+ return MACRO_NONE;
+};
+
+
+bool process_record_user (uint16_t keycode, keyrecord_t *record) {
+ return true;
+}
+
+// Runs just one time when the keyboard initializes.
+void matrix_init_user(void) {
+ xprintf("init start");
+
+ led_controller_init();
+
+ // Write predefined led pages.
+ write_led_page(_NUMPAD, led_numpad, 16);
+ chThdSleepMilliseconds(10);
+
+ write_led_page(_FNAV, led_nav, 12);
+ chThdSleepMilliseconds(10);
+
+ write_led_page(_MEDIA, led_media, 15);
+ chThdSleepMilliseconds(10);
+
+ write_led_page(4, led_game, 5);
+ chThdSleepMilliseconds(1000);
+};
+
+// Loops constantly in the background.
+void matrix_scan_user(void) {
+ uint8_t page;
+ uint8_t led_pin_byte;
+ msg_t msg;
+
+ if (backlight_status_global == 0) {//backlight is off, skip the rest
+ return;
+ }
+
+ if (led_layer_state != layer_state && led_mode_global != GAME && led_mode_global != ALL) {
+ //check mode
+ //Turn on layer indicator or page depending on mode
+ switch(led_mode_global) {
+ case MODE_FLASH: //flash preset page leds then single indicator
+ page = biton32(layer_state) > max_pages ? 7 : biton32(layer_state);
+ msg=(DISPLAY_PAGE << 8) | (page);
+ chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
+ chThdSleepMilliseconds(500);
+ //flow to display single layer leds
+
+ case MODE_SINGLE: //light layer indicators for all active layers
+ led_pin_byte = layer_state & 0xFF;
+ msg=(DISPLAY_PAGE << 8) | 7;
+ chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
+ msg=(1<<16) | (SET_FULL_ROW << 8) | (led_pin_byte);
+ chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
+ break;
+
+ case MODE_PAGE: //display pre-defined led page
+ page = biton32(layer_state) > max_pages ? 7 : biton32(layer_state);
+ msg=(DISPLAY_PAGE << 8) | (page);
+ chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
+ break;
+ }
+ led_layer_state = layer_state;
+ }
+}
+
diff --git a/keyboards/infinity60/keymaps/jpetermans/readme.md b/keyboards/infinity60/keymaps/jpetermans/readme.md
new file mode 100644
index 000000000..9c5b89173
--- /dev/null
+++ b/keyboards/infinity60/keymaps/jpetermans/readme.md
@@ -0,0 +1,79 @@
+Backlight for Infinity60
+========================
+
+## Led Controller Specs
+
+The Infinity60 pcb uses the IS31FL3731C matrix LED driver from ISSI [datasheet](http://www.issi.com/WW/pdf/31FL3731C.pdf). The IS31 has the ability to control two led matrices (A & B), each matrix controlling 9 pins, each pin controlling 8 leds. The Infinity only utilizes matrix A.
+
+Infinity60 LED MAP:
+digits mean "row" and "col", i.e. 45 means C4-5 in the IS31 datasheet, matrix A
+```c
+ 11 12 13 14 15 16 17 18 21 22 23 24 25 26 27*
+ 28 31 32 33 34 35 36 37 38 41 42 43 44 45
+ 46 47 48 51 52 53 54 55 56 57 58 61 62
+ 63 64 65 66 67 68 71 72 73 74 75 76 77*
+ 78 81 82 83 84 85 86 87
+```
+*Unused in Alphabet Layout
+
+The IS31 includes 8 pages (or frames) 0-7 and each page consists of 0xB4 (144) bytes
+- **0 - 17** LED control (on/off). 18 pins which alternate between A and B matrices (CA1, CB1, CA2, CB2, ..). Each byte controls the 8 leds on that pin with bits (8 to 1).
+- **18 - 35** Blink control. Same as LED control above, but sets blink on/off.
+- **36 - 143** PWM control. One byte per LED, sets PWM from 0 to 255. Same as above, the register alternates bytes between the A & B matrices.
+
+## Led Controller Code
+led_controller.c sets up ability to write led layers at startup or control leds on demand as part of fn_actions. By default led_controller.c assumes page 0 will be used for full on/off and page 7 for controlling individual leds. The remaining 6 pages (1-6) are free to preset led maps at init or on demand. Communication with the IS31 is primarily done through the led_mailbox using chMBPost described further below under "Sending messages in Keymap.c"
+
+One function is available to directly control leds:
+```
+write_led_page(page#, array of leds by address, # of leds in array)
+```
+This function saves a full page using a supplied array of led locations such as:
+```
+uint8_t led_numpad[16] = {
+ 18,21,22,23,
+ 37,38,41,42,
+ 55,56,57,58,
+ 72,73,74,75
+}
+write_led_page(5, led_numpad, 16);
+```
+
+Remaining led control is done through the led mailbox using these message types.
+- **SET_FULL_ROW** - 3 bytes: row#, message type, 8-bit mask. Sets all leds on one pin per the bit mask.
+- **OFF_LED** - 2 bytes: message type, led address. Turn off specific led.
+- **ON_LED** - 2 bytes: message type, led address. Turn on specific led.
+- **TOGGLE_LED** - 2 bytes: message type, led address. Toggle specific led on/off.
+- **BLINK_OFF_LED** - 2 bytes: message type, led address. Set blink off for specific led.
+- **BLINK_ON_LED** - 2 bytes: message type, led address. Set blink on for specific led.
+- **BLINK_TOGGLE_LED** - 2 bytes: message type, led address. Toggle blink for specific led.
+- **TOGGLE_ALL** - 2 bytes: message type, not used. Turn on/off full backlight.
+- **TOGGLE_BACKLIGHT** - 2 bytes: message type, on/off. Sets backlight completely off, no leds will display.
+- **DISPLAY_PAGE** - 2 bytes: message type, page to display. Switch to specific pre-set page.
+- **RESET_PAGE** - 2 bytes: message type, page to reset. Reset/erase specific page.
+- **TOGGLE_NUM_LOCK** - 2 bytes: message type, on/off (NUM_LOCK_LED_ADDRESS). Toggle numlock on/off. Usually run with the `set_leds` function to check state of numlock or capslock. If all leds are on (e.i. TOGGLE_ALL) then this sets numlock to blink instead (this is still a little buggy if toggling on/off quickly).
+- **TOGGLE_CAPS_LOCK** - 2 bytes: message type, on/off (CAPS_LOCK_LED_ADDRESS). Same as numlock.
+- **STEP_BRIGHTNESS** - 2 bytes: message type, and step up (1) or step down (0). Increase or decrease led brightness.
+
+## Sending messages in Keymap.c
+Sending an action to the led mailbox is done using chMBPost with the following form.
+```
+chMBPost(&led_mailbox, message, timeout);
+```
+- &led_mailbox - pointer to led mailbox
+- message - up to 4 bytes but most messages use only 2. First byte (LSB) is the message to process, the second byte is type. The third is only used to pass row information in SET_FULL_ROW. The fourth byte is currently unused.
+-timeout is usually TIME_IMMEDIATE
+
+An example:
+1. set the message to be sent. First byte (LSB) is the led address, and second is the message type
+`msg=(ON_LED << 8) | 42;`
+2. send msg to the led mailbox
+`chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);`
+
+Another:
+`msg=(BLINK_TOGGLE_LED << 8) | 46;`
+`chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);`
+
+Finally, SET_FULL_ROW requires an extra byte with row information in the message so sending this message looks like:
+`msg=(row<<16) | (SET_FULL_ROW << 8) | (led_pin_byte);`
+`chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);`
diff --git a/keyboards/infinity60/led.c b/keyboards/infinity60/led.c
index aed66c7c0..d60c76fd8 100644
--- a/keyboards/infinity60/led.c
+++ b/keyboards/infinity60/led.c
@@ -1,5 +1,5 @@
/*
-Copyright 2012 Jun Wako <wakojun@gmail.com>
+Copyright 2015 Jun Wako <wakojun@gmail.com>
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
@@ -19,6 +19,35 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "led.h"
+#include "led_controller.h"
+/* WARNING! This function needs to be callable from
+ * both regular threads and ISRs, unlocked (during resume-from-sleep).
+ * In particular, I2C functions (interrupt-driven) should NOT be called from here.
+ */
void led_set(uint8_t usb_led) {
+ msg_t msg;
+
+ if (usb_led & (1<<USB_LED_NUM_LOCK)) {
+ chSysUnconditionalLock();
+ msg=(TOGGLE_NUM_LOCK << 8) | 1;
+ chMBPostI(&led_mailbox, msg);
+ chSysUnconditionalUnlock();
+ } else {
+ chSysUnconditionalLock();
+ msg=(TOGGLE_NUM_LOCK << 8) | 0;
+ chMBPostI(&led_mailbox, msg);
+ chSysUnconditionalUnlock();
+ }
+ if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
+ chSysUnconditionalLock();
+ msg=(TOGGLE_CAPS_LOCK << 8) | 1;
+ chMBPostI(&led_mailbox, msg);
+ chSysUnconditionalUnlock();
+ } else {
+ chSysUnconditionalLock();
+ msg=(TOGGLE_CAPS_LOCK << 8) | 0;
+ chMBPostI(&led_mailbox, msg);
+ chSysUnconditionalUnlock();
+ }
}
diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c
new file mode 100644
index 000000000..d4ad0559b
--- /dev/null
+++ b/keyboards/infinity60/led_controller.c
@@ -0,0 +1,461 @@
+/*
+Copyright 2016 flabbergast <s3+flabbergast@sdfeu.org>
+
+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/>.
+*/
+
+/*
+ * LED controller code
+ * IS31FL3731C matrix LED driver from ISSI
+ * datasheet: http://www.issi.com/WW/pdf/31FL3731C.pdf
+ */
+
+#include "ch.h"
+#include "hal.h"
+#include "print.h"
+#include "led.h"
+#include "action_layer.h"
+#include "host.h"
+
+#include "led_controller.h"
+
+#include "suspend.h"
+
+#include "usb_main.h"
+
+/* Infinity60 LED MAP
+ - digits mean "row" and "col", i.e. 45 means C4-5 in the IS31 datasheet, matrix A
+
+ 11 12 13 14 15 16 17 18 21 22 23 24 25 26 27*
+ 28 31 32 33 34 35 36 37 38 41 42 43 44 45
+ 46 47 48 51 52 53 54 55 56 57 58 61 62
+ 63 64 65 66 67 68 71 72 73 74 75 76 77*
+ 78 81 82 83 84 85 86 87
+
+*Unused in Alphabet Layout
+*/
+
+/*
+ each page has 0xB4 bytes
+ 0 - 0x11: LED control (on/off):
+ order: CA1, CB1, CA2, CB2, .... (CA - matrix A, CB - matrix B)
+ CAn controls Cn-8 .. Cn-1 (LSbit)
+ 0x12 - 0x23: blink control (like "LED control")
+ 0x24 - 0xB3: PWM control: byte per LED, 0xFF max on
+ order same as above (CA 1st row (8bytes), CB 1st row (8bytes), ...)
+*/
+
+// Which LED should be used for CAPS LOCK indicator
+#if !defined(CAPS_LOCK_LED_ADDRESS)
+#define CAPS_LOCK_LED_ADDRESS 46
+#endif
+
+#if !defined(NUM_LOCK_LED_ADDRESS)
+#define NUM_LOCK_LED_ADDRESS 85
+#endif
+
+/* Which LED should breathe during sleep */
+#if !defined(BREATHE_LED_ADDRESS)
+#define BREATHE_LED_ADDRESS CAPS_LOCK_LED_ADDRESS
+#endif
+
+/* =================
+ * ChibiOS I2C setup
+ * ================= */
+static const I2CConfig i2ccfg = {
+ 400000 // clock speed (Hz); 400kHz max for IS31
+};
+
+/* ==============
+ * variables
+ * ============== */
+// internal communication buffers
+uint8_t tx[2] __attribute__((aligned(2)));
+uint8_t rx[1] __attribute__((aligned(2)));
+
+// buffer for sending the whole page at once (used also as a temp buffer)
+uint8_t full_page[0xB4+1] = {0};
+
+// LED mask (which LEDs are present, selected by bits)
+// IC60 pcb uses only CA matrix.
+// Each byte is a control pin for 8 leds ordered 8-1
+const uint8_t all_on_leds_mask[0x12] = {
+ 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF,
+ 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x7F, 0x00, 0x00, 0x00
+};
+
+// array to hold brightness pwm steps
+const uint8_t pwm_levels[5] = {
+ 0x00, 0x16, 0x4E, 0xA1, 0xFF
+};
+
+// array to write to pwm register
+uint8_t pwm_register_array[9] = {0};
+
+
+/* ============================
+ * communication functions
+ * ============================ */
+msg_t is31_select_page(uint8_t page) {
+ tx[0] = IS31_COMMANDREGISTER;
+ tx[1] = page;
+ return i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, tx, 2, NULL, 0, US2ST(IS31_TIMEOUT));
+}
+
+msg_t is31_write_data(uint8_t page, uint8_t *buffer, uint8_t size) {
+ is31_select_page(page);
+ return i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, buffer, size, NULL, 0, US2ST(IS31_TIMEOUT));
+}
+
+msg_t is31_write_register(uint8_t page, uint8_t reg, uint8_t data) {
+ is31_select_page(page);
+ tx[0] = reg;
+ tx[1] = data;
+ return i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, tx, 2, NULL, 0, US2ST(IS31_TIMEOUT));
+}
+
+msg_t is31_read_register(uint8_t page, uint8_t reg, uint8_t *result) {
+ is31_select_page(page);
+
+ tx[0] = reg;
+ return i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, tx, 1, result, 1, US2ST(IS31_TIMEOUT));
+}
+
+/* ========================
+ * initialise the IS31 chip
+ * ======================== */
+void is31_init(void) {
+ // just to be sure that it's all zeroes
+ __builtin_memset(full_page,0,0xB4+1);
+ // zero function page, all registers (assuming full_page is all zeroes)
+ is31_write_data(IS31_FUNCTIONREG, full_page, 0xD + 1);
+ palSetPadMode(GPIOB, 16, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPad(GPIOB, 16);
+ chThdSleepMilliseconds(10);
+ // software shutdown
+ is31_write_register(IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, 0);
+ chThdSleepMilliseconds(10);
+ // software shutdown disable (i.e. turn stuff on)
+ is31_write_register(IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_ON);
+ chThdSleepMilliseconds(10);
+ // zero all LED registers on all 8 pages
+ uint8_t i;
+ for(i=0; i<8; i++) {
+ is31_write_data(i, full_page, 0xB4 + 1);
+ chThdSleepMilliseconds(1);
+ }
+}
+
+/* ==================
+ * LED control thread
+ * ================== */
+#define LED_MAILBOX_NUM_MSGS 5
+static msg_t led_mailbox_queue[LED_MAILBOX_NUM_MSGS];
+mailbox_t led_mailbox;
+static THD_WORKING_AREA(waLEDthread, 256);
+static THD_FUNCTION(LEDthread, arg) {
+ (void)arg;
+ chRegSetThreadName("LEDthread");
+
+ uint8_t i;
+ uint8_t control_register_word[2] = {0};//2 bytes: register address, byte to write
+ uint8_t led_control_reg[0x13] = {0};//led control register start address + 0x12 bytes
+
+ //persistent status variables
+ uint8_t pwm_step_status, page_status;
+
+ //mailbox variables
+ uint8_t temp, msg_type, msg_pin, msg_col, msg_led;
+ msg_t msg;
+
+// initialize persistent variables
+pwm_step_status = 4; //full brightness
+page_status = 0; //start frame 0 (all off/on)
+
+ while(true) {
+ // wait for a message (asynchronous)
+ // (messages are queued (up to LED_MAILBOX_NUM_MSGS) if they can't
+ // be processed right away)
+ chMBFetch(&led_mailbox, &msg, TIME_INFINITE);
+ msg_col = (msg >> 24) & 0xFF;//if needed
+ msg_pin = (msg >> 16) & 0XFF;//if needed (e.g. SET_FULL_ROW)
+ msg_type = (msg >> 8) & 0xFF; //second byte is msg type
+ msg_led = (msg) & 0xFF; //first byte is action information
+
+ switch (msg_type){
+ case SET_FULL_ROW:
+ //write full byte to pin address, msg_pin = pin #, msg_led = byte to write
+ //writes only to current page
+ write_led_byte(page_status,msg_pin,msg_led);
+ break;
+
+ case OFF_LED:
+ //on/off/toggle single led, msg_led = row/col of led
+ set_led_bit(7, control_register_word, msg_led, 0);
+ is31_write_data (7, control_register_word, 0x02);
+ break;
+ case ON_LED:
+ set_led_bit(7, control_register_word, msg_led, 1);
+ is31_write_data (7, control_register_word, 0x02);
+ break;
+ case TOGGLE_LED:
+ set_led_bit(7, control_register_word, msg_led, 2);
+ is31_write_data (7, control_register_word, 0x02);
+ break;
+
+ case BLINK_OFF_LED:
+ //on/off/toggle single led, msg_led = row/col of led
+ set_led_bit(7, control_register_word, msg_led, 4);
+ is31_write_data (7, control_register_word, 0x02);
+ break;
+ case BLINK_ON_LED:
+ set_led_bit(7, control_register_word, msg_led, 5);
+ is31_write_data (7, control_register_word, 0x02);
+ break;
+ case BLINK_TOGGLE_LED:
+ set_led_bit(7, control_register_word, msg_led, 6);
+ is31_write_data (7, control_register_word, 0x02);
+ break;
+
+ case TOGGLE_ALL:
+ //msg_led = unused
+ is31_read_register(0, 0x00, &temp);
+ led_control_reg[0] = 0;
+
+ //if first byte is on, then toggle frame 0 off
+ if (temp==0 || page_status > 0) {
+ __builtin_memcpy(led_control_reg+1, all_on_leds_mask, 0x12);
+ } else {
+ __builtin_memset(led_control_reg+1, 0, 0x12);
+ }
+ is31_write_data(0, led_control_reg, 0x13);
+
+ if (page_status > 0) {
+ is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0);
+
+ page_status=0;
+
+ //maintain lock leds
+ led_set(host_keyboard_leds());
+ }
+ break;
+
+ case TOGGLE_BACKLIGHT:
+ //msg_led = on/off
+
+ //populate the 9 byte rows to be written to each pin, first byte is register (pin) address
+ if (msg_led == 1) {
+ __builtin_memset(pwm_register_array+1, pwm_levels[pwm_step_status], 8);
+ } else {
+ __builtin_memset(pwm_register_array+1, 0, 8);
+ }
+
+ for(i=0; i<8; i++) {
+ //first byte is register address, every 0x10 9 bytes is A-register pwm pins
+ pwm_register_array[0] = 0x24 + (i * 0x10);
+ is31_write_data(0,pwm_register_array,9);
+ }
+ break;
+
+ case DISPLAY_PAGE:
+ //msg_led = page to toggle on
+ if (page_status != msg_led) {
+ is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, msg_led);
+ page_status = msg_led;
+
+ //maintain lock leds
+ led_set(host_keyboard_leds());
+ }
+ break;
+
+ case RESET_PAGE:
+ //led_msg = page to reset
+ led_control_reg[0] = 0;
+ __builtin_memset(led_control_reg+1, 0, 0x12);
+ is31_write_data(msg_led, led_control_reg, 0x13);
+ break;
+
+ case TOGGLE_NUM_LOCK:
+ //msg_led = 0 or 1, off/on
+ set_lock_leds(NUM_LOCK_LED_ADDRESS, msg_led, page_status);
+ break;
+ case TOGGLE_CAPS_LOCK:
+ //msg_led = 0 or 1, off/on
+ set_lock_leds(CAPS_LOCK_LED_ADDRESS, msg_led, page_status);
+ break;
+
+ case STEP_BRIGHTNESS:
+ //led_msg = step pwm up or down
+ switch (msg_led) {
+ case 0:
+ if (pwm_step_status == 0) {
+ pwm_step_status = 4;
+ } else {
+ pwm_step_status--;
+ }
+ break;
+
+ case 1:
+ if (pwm_step_status == 4) {
+ pwm_step_status = 0;
+ } else {
+ pwm_step_status++;
+ }
+ break;
+ }
+
+ //populate 8 byte rows to write on each pin
+ //first byte is register address, every 0x10 9 bytes are A-register pwm pins
+ __builtin_memset(pwm_register_array+1, pwm_levels[pwm_step_status], 8);
+
+ for(i=0; i<8; i++) {
+ pwm_register_array[0] = 0x24 + (i * 0x10);
+ is31_write_data(0,pwm_register_array,9);
+ }
+ break;
+ }
+ }
+}
+
+/* ==============================
+ * led processing functions
+ * ============================== */
+
+void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint8_t action) {
+ //returns 2 bytes: led control register address and byte to write
+ //0 - bit off, 1 - bit on, 2 - toggle bit
+
+ uint8_t control_reg_addr, column_bit, column_byte, bit_temp, blink_on;
+
+ //check for valid led address
+ if (led_addr < 0 || led_addr > 87 || led_addr % 10 > 8) {
+ return;
+ }
+
+ //check for blink bit
+ blink_on = action>>2;
+ action &= ~(1<<2); //strip blink bit
+
+ //first byte is led control register address 0x00
+ //msg_led tens column is pin#, ones column is bit position in 8-bit mask
+ control_reg_addr = ((led_addr / 10) % 10 - 1 ) * 0x02;// A-register is every other byte
+ control_reg_addr += blink_on == 1 ? 0x12 : 0x00;//shift 12 bytes to blink register
+
+ is31_read_register(page, control_reg_addr, &bit_temp);//maintain status of leds on this byte
+ column_bit = 1<<(led_addr % 10 - 1);
+ column_byte = bit_temp;
+
+ switch(action) {
+ case 0:
+ column_byte &= ~column_bit;
+ break;
+ case 1:
+ column_byte |= column_bit;
+ break;
+ case 2:
+ column_byte ^= column_bit;
+ break;
+ }
+
+ //return word to be written in register
+ led_control_reg[0] = control_reg_addr;
+ led_control_reg[1] = column_byte;
+}
+
+void write_led_byte (uint8_t page, uint8_t row, uint8_t led_byte) {
+ uint8_t led_control_word[2] = {0};//register address and on/off byte
+
+ led_control_word[0] = (row - 1 ) * 0x02;// A-register is every other byte
+ led_control_word[1] = led_byte;
+ is31_write_data(page, led_control_word, 0x02);
+}
+
+void write_led_page (uint8_t page, uint8_t *user_led_array, uint8_t led_count) {
+ uint8_t i;
+ uint8_t pin, col;
+ uint8_t led_control_register[0x13] = {0};
+
+ __builtin_memset(led_control_register,0,13);
+
+ for(i=0;i<led_count;i++){
+ // 1 byte shift for led register 0x00 address
+ pin = ((user_led_array[i] / 10) % 10 - 1 ) * 2 + 1;
+ col = user_led_array[i] % 10 - 1;
+ led_control_register[pin] |= 1<<(col);
+ }
+
+ is31_write_data(page, led_control_register, 0x13);
+}
+
+void set_lock_leds(uint8_t led_addr, uint8_t led_action, uint8_t page) {
+ uint8_t lock_temp;
+ uint8_t led_control_word[2] = {0};
+
+ //blink if all leds are on
+ if (page == 0) {
+ is31_read_register(0, 0x00, &lock_temp);
+ if (lock_temp == 0xFF) {
+ led_action |= (1<<2); //set blink bit
+ }
+ }
+
+ set_led_bit(page,led_control_word,led_addr,led_action);
+ is31_write_data(page, led_control_word, 0x02);
+}
+
+/* =====================
+ * hook into user keymap
+ * ===================== */
+void led_controller_init(void) {
+ uint8_t i;
+
+ /* initialise I2C */
+ /* I2C pins */
+ palSetPadMode(GPIOB, 0, PAL_MODE_ALTERNATIVE_2); // PTB0/I2C0/SCL
+ palSetPadMode(GPIOB, 1, PAL_MODE_ALTERNATIVE_2); // PTB1/I2C0/SDA
+ /* start I2C */
+ i2cStart(&I2CD1, &i2ccfg);
+ // try high drive (from kiibohd)
+ I2CD1.i2c->C2 |= I2Cx_C2_HDRS;
+ // try glitch fixing (from kiibohd)
+ I2CD1.i2c->FLT = 4;
+
+ chThdSleepMilliseconds(10);
+
+ /* initialise IS31 chip */
+ is31_init();
+
+ //set Display Option Register so all pwm intensity is controlled from page 0
+ //enable blink and set blink period to 0.27s x rate
+ is31_write_register(IS31_FUNCTIONREG, IS31_REG_DISPLAYOPT, IS31_REG_DISPLAYOPT_INTENSITY_SAME + IS31_REG_DISPLAYOPT_BLINK_ENABLE + 4);
+
+ /* set full pwm on page 1 */
+ pwm_register_array[0] = 0;
+ __builtin_memset(pwm_register_array+1, 0xFF, 8);
+ for(i=0; i<8; i++) {
+ pwm_register_array[0] = 0x24 + (i * 0x10);//first byte of 9 bytes must be register address
+ is31_write_data(0, pwm_register_array, 9);
+ chThdSleepMilliseconds(5);
+ }
+
+ /* enable breathing when the displayed page changes */
+ // Fade-in Fade-out, time = 26ms * 2^N, N=3
+ is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, (3<<4)|3);
+ is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, IS31_REG_BREATHCTRL2_ENABLE|3);
+
+ /* more time consuming LED processing should be offloaded into
+ * a thread, with asynchronous messaging. */
+ chMBObjectInit(&led_mailbox, led_mailbox_queue, LED_MAILBOX_NUM_MSGS);
+ chThdCreateStatic(waLEDthread, sizeof(waLEDthread), LOWPRIO, LEDthread, NULL);
+}
diff --git a/keyboards/infinity60/led_controller.h b/keyboards/infinity60/led_controller.h
new file mode 100644
index 000000000..457b21a92
--- /dev/null
+++ b/keyboards/infinity60/led_controller.h
@@ -0,0 +1,119 @@
+/*
+Copyright 2016 flabbergast <s3+flabbergast@sdfeu.org>
+
+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 _LED_CONTROLLER_H_
+#define _LED_CONTROLLER_H_
+
+/* =========================
+ * communication functions
+ * ========================= */
+
+msg_t is31_write_data(uint8_t page, uint8_t *buffer, uint8_t size);
+msg_t is31_write_register(uint8_t page, uint8_t reg, uint8_t data);
+msg_t is31_read_register(uint8_t page, uint8_t reg, uint8_t *result);
+
+/* ============================
+ * init functions/definitions
+ * ============================*/
+
+void led_controller_init(void);
+
+#define CAPS_LOCK_LED_ADDRESS 46 //pin matrix location
+#define NUM_LOCK_LED_ADDRESS 85
+
+/* =============================
+ * IS31 chip related definitions
+ * ============================= */
+
+#define IS31_ADDR_DEFAULT 0x74
+
+#define IS31_REG_CONFIG 0x00
+// bits in reg
+#define IS31_REG_CONFIG_PICTUREMODE 0x00
+#define IS31_REG_CONFIG_AUTOPLAYMODE 0x08
+#define IS31_REG_CONFIG_AUDIOPLAYMODE 0x18
+// D2:D0 bits are starting frame for autoplay mode
+
+#define IS31_REG_PICTDISP 0x01 // D2:D0 frame select for picture mode
+
+#define IS31_REG_AUTOPLAYCTRL1 0x02
+// D6:D4 number of loops (000=infty)
+// D2:D0 number of frames to be used
+
+#define IS31_REG_AUTOPLAYCTRL2 0x03 // D5:D0 delay time (*11ms)
+
+#define IS31_REG_DISPLAYOPT 0x05
+#define IS31_REG_DISPLAYOPT_INTENSITY_SAME 0x20 // same intensity for all frames
+#define IS31_REG_DISPLAYOPT_BLINK_ENABLE 0x08
+// D2:D0 bits blink period time (*0.27s)
+
+#define IS31_REG_AUDIOSYNC 0x06
+#define IS31_REG_AUDIOSYNC_ENABLE 0x1
+
+#define IS31_REG_FRAMESTATE 0x07
+
+#define IS31_REG_BREATHCTRL1 0x08
+// D6:D4 fade out time (26ms*2^i)
+// D2:D0 fade in time (26ms*2^i)
+
+#define IS31_REG_BREATHCTRL2 0x09
+#define IS31_REG_BREATHCTRL2_ENABLE 0x10
+// D2:D0 extinguish time (3.5ms*2^i)
+
+#define IS31_REG_SHUTDOWN 0x0A
+#define IS31_REG_SHUTDOWN_ON 0x1
+
+#define IS31_REG_AGCCTRL 0x0B
+#define IS31_REG_ADCRATE 0x0C
+
+#define IS31_COMMANDREGISTER 0xFD
+#define IS31_FUNCTIONREG 0x0B // helpfully called 'page nine'
+
+#define IS31_TIMEOUT 10000 // needs to be long enough to write a whole page
+
+/* ========================================
+ * LED Thread related items
+ * ========================================*/
+
+extern mailbox_t led_mailbox;
+
+void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint8_t action);
+void set_lock_leds (uint8_t led_addr, uint8_t led_action, uint8_t page);
+void write_led_byte (uint8_t page, uint8_t row, uint8_t led_byte);
+void write_led_page (uint8_t page, uint8_t *led_array, uint8_t led_count);
+
+// constants for signaling the LED controller thread
+enum led_msg_t {
+ KEY_LIGHT,
+ SET_FULL_ROW,
+ OFF_LED,
+ ON_LED,
+ TOGGLE_LED,
+ BLINK_OFF_LED,
+ BLINK_ON_LED,
+ BLINK_TOGGLE_LED,
+ TOGGLE_ALL,
+ TOGGLE_BACKLIGHT,
+ DISPLAY_PAGE,
+ RESET_PAGE,
+ TOGGLE_NUM_LOCK,
+ TOGGLE_CAPS_LOCK,
+ TOGGLE_BREATH,
+ STEP_BRIGHTNESS
+};
+
+#endif /* _LED_CONTROLLER_H_ */
diff --git a/keyboards/infinity60/mcuconf.h b/keyboards/infinity60/mcuconf.h
index f453304b7..6af85d079 100644
--- a/keyboards/infinity60/mcuconf.h
+++ b/keyboards/infinity60/mcuconf.h
@@ -47,9 +47,12 @@
* USB driver settings
*/
#define KINETIS_USB_USE_USB0 TRUE
-/* Need to redefine this, since the default is for K20x */
-/* This is for Teensy LC; you should comment it out (or change to 5)
- * for Teensy 3.x */
-#define KINETIS_USB_USB0_IRQ_PRIORITY 2
+#define KINETIS_USB_USB0_IRQ_PRIORITY 5
+
+/*
+ * I2C driver settings
+ */
+#define KINETIS_I2C_USE_I2C0 TRUE
+#define KINETIS_I2C_I2C0_PRIORITY 4
#endif /* _MCUCONF_H_ */
diff --git a/keyboards/infinity60/rules.mk b/keyboards/infinity60/rules.mk
index 56d6470b5..f58bb2642 100644
--- a/keyboards/infinity60/rules.mk
+++ b/keyboards/infinity60/rules.mk
@@ -1,6 +1,7 @@
# project specific files
SRC = matrix.c \
- led.c
+ led.c \
+ led_controller.c
## chip/board settings
# - the next two should match the directories in
@@ -63,4 +64,4 @@ CONSOLE_ENABLE ?= yes # Console for debug
COMMAND_ENABLE ?= yes # Commands for debug and configuration
SLEEP_LED_ENABLE ?= yes # Breathing sleep LED during USB suspend
NKRO_ENABLE ?= yes # USB Nkey Rollover
-CUSTOM_MATRIX ?= yes # Custom matrix file \ No newline at end of file
+CUSTOM_MATRIX ?= yes # Custom matrix file