summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjpetermans <tibcmhhm@gmail.com>2017-05-24 21:07:18 +0200
committerjpetermans <tibcmhhm@gmail.com>2017-05-24 21:07:18 +0200
commite6c9b07e1c9f508c8a2a4d5e920816c34c6a21f4 (patch)
treeef5775c79867a9e33f4233faf5139439ef23f014
parent2dcd6c38fa478b40a973c9411c3f5b4c87ae0ba7 (diff)
parentf54b4771eb23027be1bd66a6fe1300713b593d58 (diff)
downloadqmk_firmware-e6c9b07e1c9f508c8a2a4d5e920816c34c6a21f4.tar.gz
qmk_firmware-e6c9b07e1c9f508c8a2a4d5e920816c34c6a21f4.tar.xz
Merge branch 'user_led_configuration' into infinity60
Conflicts: keyboards/infinity60/keymaps/jpetermans/keymap.c
-rw-r--r--keyboards/infinity60/MEMO.txt385
-rw-r--r--keyboards/infinity60/keymaps/jpetermans/Makefile2
-rw-r--r--keyboards/infinity60/keymaps/jpetermans/keymap.c243
-rw-r--r--keyboards/infinity60/keymaps/jpetermans/readme.md87
-rw-r--r--keyboards/infinity60/led.c27
-rw-r--r--keyboards/infinity60/led_controller.c423
-rw-r--r--keyboards/infinity60/led_controller.h44
7 files changed, 595 insertions, 616 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/keymaps/jpetermans/Makefile b/keyboards/infinity60/keymaps/jpetermans/Makefile
index 225e4cad4..df3d1e952 100644
--- a/keyboards/infinity60/keymaps/jpetermans/Makefile
+++ b/keyboards/infinity60/keymaps/jpetermans/Makefile
@@ -1,5 +1,3 @@
-#BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
-#BOOTMAGIC_ENABLE = yes
ifndef QUANTUM_DIR
include ../../../../Makefile
diff --git a/keyboards/infinity60/keymaps/jpetermans/keymap.c b/keyboards/infinity60/keymaps/jpetermans/keymap.c
index d6c2b7bb5..cc4633b1b 100644
--- a/keyboards/infinity60/keymaps/jpetermans/keymap.c
+++ b/keyboards/infinity60/keymaps/jpetermans/keymap.c
@@ -11,6 +11,34 @@
#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,
+ 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
* ,-----------------------------------------------------------.
@@ -30,17 +58,8 @@ const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
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, \
- F(1), KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH,KC_RSFT,KC_NO, \
- KC_LCTL, KC_LGUI,KC_LALT, KC_SPC, KC_RALT,TG(_NUMPAD),MO(_MEDIA), KC_RCTL \
- ),
-
- /* 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(0),KC_NLCK,_______,_______ \
+ 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, LT(_FNAV, KC_SPC), KC_RALT,TG(_NUMPAD),MO(_MEDIA), KC_RCTL \
),
/* numpad */
@@ -49,15 +68,24 @@ const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______,_______,_______,_______,_______,_______,_______, 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), _______,_______,_______,_______ \
+ _______,_______,_______, TO(_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, \
+ _______,_______,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( \
- _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,KC_MUTE, KC_VOLD, KC_VOLU,_______,KC_NO,\
- _______,_______,_______,_______,_______,_______,_______, _______, KC_UP, _______,_______, _______,_______,_______,\
- _______,_______,_______,_______,_______,_______,_______, KC_LEFT, KC_DOWN, KC_RGHT,_______, _______,_______, \
- _______,_______,F(2),F(3),_______,_______,_______, _______, KC_MPRV, KC_MNXT,KC_MSTP, _______,KC_NO, \
+ _______,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, _______,_______, _______,_______ \
),
/* ~ */
@@ -85,58 +113,193 @@ enum function_id {
enum macro_id {
ACTION_LEDS_ALL,
- ACTION_LEDS_GAME
+ ACTION_LEDS_GAME,
+ ACTION_LEDS_BACKLIGHT,
+ ACTION_LEDS_BRIGHT,
+ ACTION_LEDS_DIM,
+ 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 =========
+//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[] = {
- [0] = ACTION_KEY(LALT(LCTL(KC_DEL))),
- [1] = ACTION_LAYER_MODS(_TILDE, MOD_LSFT),
- [2] = ACTION_FUNCTION(ACTION_LEDS_ALL),
- [3] = ACTION_FUNCTION(ACTION_LEDS_GAME)
+ [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),
+ [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) {
- (void)opt;
+ msg_t msg;
+
switch(id) {
case ACTION_LEDS_ALL:
- if(record->event.pressed) {
- // signal the LED controller thread
- chMBPost(&led_mailbox, LED_MSG_GAME_TOGGLE, TIME_IMMEDIATE);
- }
+ if(record->event.pressed) {
+ led_mode_global = led_mode_global == ALL ? MODE_SINGLE : ALL;
+ msg=TOGGLE_ALL;
+ chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
+ }
break;
+
+ case ACTION_LEDS_BACKLIGHT:
+ if(record->event.pressed) {
+ backlight_status_global ^= 1;
+ msg=(backlight_status_global << 8) | TOGGLE_BACKLIGHT;
+ chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
+ }
+ break;
+
case ACTION_LEDS_GAME:
if(record->event.pressed) {
- // signal the LED controller thread
- chMBPost(&led_mailbox, LED_MSG_ALL_TOGGLE, TIME_IMMEDIATE);
+ led_mode_global = led_mode_global == GAME ? MODE_SINGLE : GAME;
+
+ msg=(4 << 8) | DISPLAY_PAGE;
+ chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
+ }
+ break;
+
+ case ACTION_LEDS_BRIGHT:
+ if(record->event.pressed) {
+ msg=(1 << 8) | STEP_BRIGHTNESS;
+ chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
}
break;
+
+ case ACTION_LEDS_DIM:
+ if(record->event.pressed) {
+ msg=(0 << 8) | STEP_BRIGHTNESS;
+ 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)
{
- switch(id) {
- case 0:
- if (record->event.pressed) {
- }
- break;
- case 1:
- if (record->event.pressed) {
- }
- break;
- }
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);
};
-// Runs constantly in the background, in a loop.
+// 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=(page << 8) | DISPLAY_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=(7 << 8) | DISPLAY_PAGE;
+ chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
+ msg=(1 << 16) | (led_pin_byte << 8) | SET_FULL_ROW;
+ 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=(page << 8) | DISPLAY_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..b83057ea7
--- /dev/null
+++ b/keyboards/infinity60/keymaps/jpetermans/readme.md
@@ -0,0 +1,87 @@
+Backlight for Infinity60
+========================
+
+## Led Controller Specs
+
+The Infinity60 (revision 1.1a) 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 pin 4, column 5 in the IS31 datasheet
+```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 led pages (or frames) 0-7 than can be displayed, and each page consists of 144 bytes.
+- **bytes 0 - 17** - LED control (on/off).
+ * 18 pins which alternate between A and B matrices (A1, B1, A2, B2, ..).
+ * Each byte controls the 8 leds on that pin with bits (8 to 1).
+- **bytes 8 - 35** - Blink control.
+ * Same as LED control above, but sets blink on/off.
+- **bytes 36 - 143** - PWM control.
+ * One byte per LED, sets PWM from 0 to 255.
+ * Same as above, the register alternates, every 8 *bytes* (not bits) between the A & B matrices.
+
+## Led Controller Code
+In the Infinity60 project folder, 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. The remaining 7 pages (1-7) are free for preset led maps or single led actions 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". This code is based on work matt3o and flabbergast did for tmk firmware on the [whitefox](https://github.com/tmk/whitefox).
+
+One function is available to directly set leds without the mailbox:
+```
+write_led_page(page#, array of leds by address, # of addresses in array)
+```
+This function saves a full page to the controller using a supplied array of led locations such as:
+```c
+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) - message type, 8-bit mask, and row#. Sets all leds on one pin per the bit mask.
+- **OFF_LED, ON_LED, TOGGLE_LED** (3 bytes) - message type, led address, and page#. Off/on/toggle specific led.
+- **BLINK_OFF_LED, BLINK_ON_LED, BLINK_OFF_LED** (3 bytes) - message type, led address, and page#. Set blink Off/on/toggle for specific led.
+- **TOGGLE_ALL** (1 byte) - 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:
+```
+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 type, the remaining three bytes are the message to process.
+- timeout is TIME_IMMEDIATE
+
+An example:
+```c
+//set the message to be sent. First byte (LSB) is the led address, and second is the message type
+msg=(42 << 8) | ON_LED;
+
+//send msg to the led mailbox
+chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
+```
+
+Another:
+```c
+msg=(46 << 8) | BLINK_TOGGLE_LED;
+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:
+```c
+msg=(row<<16) | (led_pin_byte << 8) | SET_FULL_ROW;
+chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
+```
diff --git a/keyboards/infinity60/led.c b/keyboards/infinity60/led.c
index e17a5dd0d..53147a78a 100644
--- a/keyboards/infinity60/led.c
+++ b/keyboards/infinity60/led.c
@@ -26,25 +26,28 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* In particular, I2C functions (interrupt-driven) should NOT be called from here.
*/
void led_set(uint8_t usb_led) {
-/*
- // PTA5: LED (1:on/0:off)
- GPIOA->PDDR |= (1<<1);
- PORTA->PCR[5] |= PORTx_PCRn_DSE | PORTx_PCRn_MUX(1);
- if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
- GPIOA->PSOR |= (1<<5);
+ msg_t msg;
+
+ if (usb_led & (1<<USB_LED_NUM_LOCK)) {
+ chSysUnconditionalLock();
+ msg=(1 << 8) | TOGGLE_NUM_LOCK;
+ chMBPostI(&led_mailbox, msg);
+ chSysUnconditionalUnlock();
} else {
- GPIOA->PCOR |= (1<<5);
+ chSysUnconditionalLock();
+ msg=(0 << 8) | TOGGLE_NUM_LOCK;
+ chMBPostI(&led_mailbox, msg);
+ chSysUnconditionalUnlock();
}
- */
if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
- // signal the LED control thread
chSysUnconditionalLock();
- chMBPostI(&led_mailbox, LED_MSG_CAPS_ON);
+ msg=(1 << 8) | TOGGLE_CAPS_LOCK;
+ chMBPostI(&led_mailbox, msg);
chSysUnconditionalUnlock();
} else {
- // signal the LED control thread
chSysUnconditionalLock();
- chMBPostI(&led_mailbox, LED_MSG_CAPS_OFF);
+ msg=(0 << 8) | TOGGLE_CAPS_LOCK;
+ chMBPostI(&led_mailbox, msg);
chSysUnconditionalUnlock();
}
}
diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c
index c5303a3e7..04793cc01 100644
--- a/keyboards/infinity60/led_controller.c
+++ b/keyboards/infinity60/led_controller.c
@@ -17,13 +17,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/*
* LED controller code
- * WF uses IS31FL3731C matrix LED driver from ISSI
+ * 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 "host.h"
#include "led_controller.h"
@@ -53,11 +55,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
order same as above (CA 1st row (8bytes), CB 1st row (8bytes), ...)
*/
-/* Which LED should be used for CAPS LOCK indicator
- * The usual Caps Lock position is C4-6, so the address is
- * 0x24 + (4-1)*0x10 + (8-1) = 0x59 */
+// Which LED should be used for CAPS LOCK indicator
#if !defined(CAPS_LOCK_LED_ADDRESS)
-#define CAPS_LOCK_LED_ADDRESS 0x59
+#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 */
@@ -83,14 +87,22 @@ uint8_t rx[1] __attribute__((aligned(2)));
uint8_t full_page[0xB4+1] = {0};
// LED mask (which LEDs are present, selected by bits)
-// See page comment above, control alternates CA matrix/CB matrix
// IC60 pcb uses only CA matrix.
-// Each byte is a control pin for 8 leds 8-1
-const uint8_t is31_ic60_leds_mask[0x12] = {
+// 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
* ============================ */
@@ -112,8 +124,8 @@ msg_t is31_write_register(uint8_t page, uint8_t reg, uint8_t data) {
return i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, tx, 2, NULL, 0, US2ST(IS31_TIMEOUT));
}
-msg_t is31_read_register(uint8_t b, uint8_t reg, uint8_t *result) {
- is31_select_page(b);
+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));
@@ -127,16 +139,9 @@ void is31_init(void) {
__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);
- // disable hardware shutdown
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);
- // zero function page, all registers
- is31_write_data(IS31_FUNCTIONREG, full_page, 0xD + 1);
- chThdSleepMilliseconds(10);
// software shutdown disable (i.e. turn stuff on)
is31_write_register(IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_ON);
chThdSleepMilliseconds(10);
@@ -144,7 +149,7 @@ void is31_init(void) {
uint8_t i;
for(i=0; i<8; i++) {
is31_write_data(i, full_page, 0xB4 + 1);
- chThdSleepMilliseconds(1);
+ chThdSleepMilliseconds(5);
}
}
@@ -159,134 +164,257 @@ static THD_FUNCTION(LEDthread, arg) {
(void)arg;
chRegSetThreadName("LEDthread");
- uint8_t temp;
- uint8_t save_page, save_breath1, save_breath2;
- msg_t msg, retval;
+ 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;
+ uint8_t msg_args[3];
+ 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)
+ // be processed right away
chMBFetch(&led_mailbox, &msg, TIME_INFINITE);
+ msg_type = msg & 0xFF; //first byte is action information
+ msg_args[0] = (msg >> 8) & 0xFF;
+ msg_args[1] = (msg >> 16) & 0XFF;
+ msg_args[2] = (msg >> 24) & 0xFF;
+
+ switch (msg_type){
+ case SET_FULL_ROW:
+ //write full byte to pin address, msg_args[1] = pin #, msg_args[0] = 8 bits to write
+ //writes only to currently displayed page
+ write_led_byte(page_status, msg_args[1], msg_args[0]);
+ break;
- // process 'msg' here
- switch(msg) {
- case LED_MSG_CAPS_ON:
- // turn caps on on pages 1 and 2
- is31_write_register(0, CAPS_LOCK_LED_ADDRESS, 0xFF);
- is31_write_register(1, CAPS_LOCK_LED_ADDRESS, 0xFF);
- is31_write_register(2, CAPS_LOCK_LED_ADDRESS, 0xFF);
+ case OFF_LED:
+ //on/off/toggle single led, msg_args[0] = row/col of led, msg_args[1] = page
+ set_led_bit(msg_args[1], control_register_word, msg_args[0], 0);
break;
- case LED_MSG_CAPS_OFF:
- // turn caps off on pages 1 and 2
- is31_write_register(0, CAPS_LOCK_LED_ADDRESS, 0);
- is31_write_register(1, CAPS_LOCK_LED_ADDRESS, 0);
- is31_write_register(2, CAPS_LOCK_LED_ADDRESS, 0);
+ case ON_LED:
+ set_led_bit(msg_args[1], control_register_word, msg_args[0], 1);
break;
- case LED_MSG_SLEEP_LED_ON:
- // save current settings
- is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &save_page);
- is31_read_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, &save_breath1);
- is31_read_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, &save_breath2);
- // use pages 7 and 8 for (hardware) breathing (assuming they're empty)
- is31_write_register(6, BREATHE_LED_ADDRESS, 0xFF);
- is31_write_register(7, BREATHE_LED_ADDRESS, 0x00);
- is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, (6<<4)|6);
- is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, IS31_REG_BREATHCTRL2_ENABLE|3);
- retval = MSG_TIMEOUT;
- temp = 6;
- while(retval == MSG_TIMEOUT) {
- // switch to the other page
- is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, temp);
- temp = (temp == 6 ? 7 : 6);
- // the times should be sufficiently long for IS31 to finish switching pages
- retval = chMBFetch(&led_mailbox, &msg, MS2ST(temp == 6 ? 4000 : 6000));
- }
- // received a message (should be a wakeup), so restore previous state
- chThdSleepMilliseconds(3000); // need to wait until the page change finishes
- // note: any other messages are queued
- is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, save_breath1);
- is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, save_breath2);
- is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, save_page);
+ case TOGGLE_LED:
+ set_led_bit(msg_args[1], control_register_word, msg_args[0], 2);
break;
- case LED_MSG_SLEEP_LED_OFF:
- // should not get here; wakeup should be received in the branch above
+
+ case BLINK_OFF_LED:
+ //on/off/toggle single led, msg_args[0] = row/col of led
+ set_led_bit(msg_args[1], control_register_word, msg_args[0], 4);
break;
- case LED_MSG_ALL_TOGGLE:
- // read current page into 'temp'
- is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp);
- chThdSleepMilliseconds(1);
- // switch to 'the other' page
- if(temp==2) {
- is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0);
+ case BLINK_ON_LED:
+ set_led_bit(msg_args[1], control_register_word, msg_args[0], 5);
+ break;
+ case BLINK_TOGGLE_LED:
+ set_led_bit(msg_args[1], control_register_word, msg_args[0], 6);
+ break;
+
+ case TOGGLE_ALL:
+ //turn on/off all leds, msg_args = unused
+ is31_read_register(0, 0x00, &temp);
+ led_control_reg[0] = 0;
+
+ //if first leds are already on, toggle frame 0 off
+ if (temp==0 || page_status > 0) {
+ __builtin_memcpy(led_control_reg+1, all_on_leds_mask, 0x12);
} else {
- is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 2);
+ __builtin_memset(led_control_reg+1, 0, 0x12);
}
- break;
- case LED_MSG_GAME_TOGGLE:
- // read current page into 'temp'
- is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp);
- chThdSleepMilliseconds(1);
- // switch to 'the other' page
- if(temp==1) {
+ 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_args[0] = on/off
+
+ //populate 9 byte rows to be written to each pin, first byte is register (pin) address
+ if (msg_args[0] == 1) {
+ __builtin_memset(pwm_register_array+1, pwm_levels[pwm_step_status], 8);
} else {
- is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 1);
+ __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-matrix pwm pins
+ pwm_register_array[0] = 0x24 + (i * 0x10);
+ is31_write_data(0,pwm_register_array,9);
+ }
+ break;
+
+ case DISPLAY_PAGE:
+ //msg_args[0] = page to toggle on
+ if (page_status != msg_args[0]) {
+ is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, msg_args[0]);
+ page_status = msg_args[0];
+
+ //maintain lock leds
+ led_set(host_keyboard_leds());
+ }
+ break;
+
+ case RESET_PAGE:
+ //led_args[0] = page to reset
+ led_control_reg[0] = 0;
+ __builtin_memset(led_control_reg+1, 0, 0x12);
+ is31_write_data(msg_args[0], led_control_reg, 0x13);
+
+ //repeat for blink register
+ led_control_reg[0] = 0x12;
+ is31_write_data(msg_args[0], led_control_reg, 0x13);
+ break;
+
+ case TOGGLE_NUM_LOCK:
+ //msg_args[0] = 0 or 1, off/on
+ set_lock_leds(NUM_LOCK_LED_ADDRESS, msg_args[0], page_status);
+ break;
+ case TOGGLE_CAPS_LOCK:
+ //msg_args[0] = 0 or 1, off/on
+ set_lock_leds(CAPS_LOCK_LED_ADDRESS, msg_args[0], page_status);
+ break;
+
+ case STEP_BRIGHTNESS:
+ //led_args[0] = step up (1) or down (0)
+ switch (msg_args[0]) {
+ 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 arrays to write on each pin
+ //first byte is register address, every 0x10 9 bytes are A-matrix 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;
}
}
}
-//These relate to the LED map above, row and column
-//0x24 = first byte (CA1) of PWM page, 0x34 is 17th byte (CA2)
-/* LED game mode */
-const uint8_t led_game[72] = {
- 0x24,
- 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x44,
- 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x54,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
- 0x64,
- 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x74,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x84,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x94,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
+/* ==============================
+ * led processing functions
+ * ============================== */
-/* ALL LEDs */
-const uint8_t led_all[72] = {
- 0x24,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0x34,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-0x44,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0x54,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0x64,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0x74,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0x84,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0x94,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-};
+void set_led_bit (uint8_t page, uint8_t *led_control_word, uint8_t led_addr, uint8_t action) {
+ //returns 2 bytes: led control register address and byte to write
+ //action: 0 - off, 1 - on, 2 - toggle, 4 - blink on, 5 - blink off, 6 - toggle blink
+
+ uint8_t control_reg_addr, column_bit, column_byte, temp, blink_bit;
+
+ //check for valid led address
+ if (led_addr < 0 || led_addr > 87 || led_addr % 10 > 8) {
+ return;
+ }
+
+ blink_bit = action>>2;//check for blink bit
+ action &= ~(1<<2); //strip blink bit
+
+ //led_addr tens column is pin#, ones column is bit position in 8-bit mask
+ control_reg_addr = ((led_addr / 10) % 10 - 1 ) * 0x02;// A-matrix is every other byte
+ control_reg_addr += blink_bit == 1 ? 0x12 : 0x00;//if blink_bit, shift 12 bytes to blink register
+
+ is31_read_register(page, control_reg_addr, &temp);//maintain status of leds on this byte
+ column_bit = 1<<(led_addr % 10 - 1);
+ column_byte = 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_word[0] = control_reg_addr;
+ led_control_word[1] = column_byte;
+ is31_write_data (page, led_control_word, 0x02);
+}
+
+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-matrix 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);
-/* =============
- * hook into TMK
- * ============= */
+ for(i=0;i<led_count;i++){
+ //shift pin by 1 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 temp;
+ uint8_t led_control_word[2] = {0};
+
+ //blink if all leds are on
+ if (page == 0) {
+ is31_read_register(0, 0x00, &temp);
+ chThdSleepMilliseconds(10);
+
+ if (temp == 0xFF) {
+ led_action |= (1<<2); //set blink bit
+ }
+ }
+
+ set_led_bit(page,led_control_word,led_addr,led_action);
+}
+
+/* =====================
+ * hook into user keymap
+ * ===================== */
void led_controller_init(void) {
uint8_t i;
- xprintf("led_controller_init");
/* initialise I2C */
/* I2C pins */
palSetPadMode(GPIOB, 0, PAL_MODE_ALTERNATIVE_2); // PTB0/I2C0/SCL
@@ -303,11 +431,17 @@ void led_controller_init(void) {
/* initialise IS31 chip */
is31_init();
- /* enable LEDs on all pages */
- full_page[0] = 0;
- __builtin_memcpy(full_page+1, is31_ic60_leds_mask, 0x12);
+ //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++) {
- is31_write_data(i, full_page, 1+0x12);
+ 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 */
@@ -315,47 +449,8 @@ void led_controller_init(void) {
is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, (3<<4)|3);
is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, IS31_REG_BREATHCTRL2_ENABLE|3);
- /* Write pages */
- for(i=0; i<8; i++) {
- is31_write_data(1,(uint8_t *)(led_game+(9*i)),9);
- chThdSleepMilliseconds(5);
- is31_write_data(2,(uint8_t *)(led_all+(9*i)),9);
- chThdSleepMilliseconds(5);
- }
-
- // clean up the capslock LED
- is31_write_register(1, CAPS_LOCK_LED_ADDRESS, 0);
- is31_write_register(2, CAPS_LOCK_LED_ADDRESS, 0);
-
/* 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);
}
-
-//TODO: Don't know equivalent QMK hooks for these
-//
-//void hook_usb_suspend_entry(void) {
-//#ifdef SLEEP_LED_ENABLE
-// chSysLockFromISR();
-// chMBPostI(&led_mailbox, LED_MSG_SLEEP_LED_ON);
-// chSysUnlockFromISR();
-//#endif /* SLEEP_LED_ENABLE */
-//}
-//
-//void hook_usb_suspend_loop(void) {
-// chThdSleepMilliseconds(100);
-// /* Remote wakeup */
-// if((USB_DRIVER.status & 2) && suspend_wakeup_condition()) {
-// send_remote_wakeup(&USB_DRIVER);
-// }
-//}
-//
-//void hook_usb_wakeup(void) {
-//#ifdef SLEEP_LED_ENABLE
-// chSysLockFromISR();
-// chMBPostI(&led_mailbox, LED_MSG_SLEEP_LED_OFF);
-// chSysUnlockFromISR();
-//#endif /* SLEEP_LED_ENABLE */
-//}
-//*/
diff --git a/keyboards/infinity60/led_controller.h b/keyboards/infinity60/led_controller.h
index 7db02389f..457b21a92 100644
--- a/keyboards/infinity60/led_controller.h
+++ b/keyboards/infinity60/led_controller.h
@@ -26,12 +26,15 @@ 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
- * ========================= */
+/* ============================
+ * 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
* ============================= */
@@ -55,7 +58,7 @@ void led_controller_init(void);
#define IS31_REG_DISPLAYOPT 0x05
#define IS31_REG_DISPLAYOPT_INTENSITY_SAME 0x20 // same intensity for all frames
-#define IS31_REG_DISPLAYOPT_BLINK_ENABLE 0x8
+#define IS31_REG_DISPLAYOPT_BLINK_ENABLE 0x08
// D2:D0 bits blink period time (*0.27s)
#define IS31_REG_AUDIOSYNC 0x06
@@ -82,20 +85,35 @@ void led_controller_init(void);
#define IS31_TIMEOUT 10000 // needs to be long enough to write a whole page
-/* ==============================
- * LED Thread related definitions
- * ============================== */
+/* ========================================
+ * 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 {
- LED_MSG_CAPS_ON,
- LED_MSG_CAPS_OFF,
- LED_MSG_SLEEP_LED_ON,
- LED_MSG_SLEEP_LED_OFF,
- LED_MSG_ALL_TOGGLE,
- LED_MSG_GAME_TOGGLE
+ 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_ */