diff options
-rw-r--r-- | keyboards/infinity60/config.h | 2 | ||||
-rw-r--r-- | keyboards/infinity60/halconf.h | 4 | ||||
-rw-r--r-- | keyboards/infinity60/keymaps/jpetermans/Makefile | 6 | ||||
-rw-r--r-- | keyboards/infinity60/keymaps/jpetermans/config.h | 11 | ||||
-rw-r--r-- | keyboards/infinity60/keymaps/jpetermans/keymap.c | 142 | ||||
-rw-r--r-- | keyboards/infinity60/led.c | 28 | ||||
-rw-r--r-- | keyboards/infinity60/led_controller.c | 361 | ||||
-rw-r--r-- | keyboards/infinity60/led_controller.h | 101 | ||||
-rw-r--r-- | keyboards/infinity60/mcuconf.h | 11 | ||||
-rw-r--r-- | keyboards/infinity60/rules.mk | 5 |
10 files changed, 661 insertions, 10 deletions
diff --git a/keyboards/infinity60/config.h b/keyboards/infinity60/config.h index f8346fe165..83930901cb 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 46b37a4f46..f89dfc2e1e 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 0000000000..225e4cad40 --- /dev/null +++ b/keyboards/infinity60/keymaps/jpetermans/Makefile @@ -0,0 +1,6 @@ +#BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality +#BOOTMAGIC_ENABLE = yes + +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 0000000000..72a2ed0810 --- /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 0000000000..d6c2b7bb5e --- /dev/null +++ b/keyboards/infinity60/keymaps/jpetermans/keymap.c @@ -0,0 +1,142 @@ +#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 + +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, \ + 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,_______,_______ \ + ), + + /* 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), _______,_______,_______,_______ \ + ), + + /* 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, \ + _______,_______,_______, 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 +}; + +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) +}; + +/* custom action function */ +void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { + (void)opt; + switch(id) { + case ACTION_LEDS_ALL: + if(record->event.pressed) { + // signal the LED controller thread + chMBPost(&led_mailbox, LED_MSG_GAME_TOGGLE, 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); + } + 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; +}; + + +// Runs just one time when the keyboard initializes. +void matrix_init_user(void) { + led_controller_init(); +}; + +// Runs constantly in the background, in a loop. +void matrix_scan_user(void) { + +}; + diff --git a/keyboards/infinity60/led.c b/keyboards/infinity60/led.c index aed66c7c03..e17a5dd0d3 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,32 @@ 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) { +/* + // 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); + } else { + GPIOA->PCOR |= (1<<5); + } + */ + if (usb_led & (1<<USB_LED_CAPS_LOCK)) { + // signal the LED control thread + chSysUnconditionalLock(); + chMBPostI(&led_mailbox, LED_MSG_CAPS_ON); + chSysUnconditionalUnlock(); + } else { + // signal the LED control thread + chSysUnconditionalLock(); + chMBPostI(&led_mailbox, LED_MSG_CAPS_OFF); + chSysUnconditionalUnlock(); + } } diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c new file mode 100644 index 0000000000..c5303a3e70 --- /dev/null +++ b/keyboards/infinity60/led_controller.c @@ -0,0 +1,361 @@ +/* +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 + * WF uses 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_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 + * The usual Caps Lock position is C4-6, so the address is + * 0x24 + (4-1)*0x10 + (8-1) = 0x59 */ +#if !defined(CAPS_LOCK_LED_ADDRESS) +#define CAPS_LOCK_LED_ADDRESS 0x59 +#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) +// 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] = { + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, + 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x7F, 0x00, 0x00, 0x00 +}; + +/* ============================ + * 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 b, uint8_t reg, uint8_t *result) { + is31_select_page(b); + + 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); + // 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); + // 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 temp; + uint8_t save_page, save_breath1, save_breath2; + msg_t msg, retval; + + 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); + + // 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); + 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); + 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); + break; + case LED_MSG_SLEEP_LED_OFF: + // should not get here; wakeup should be received in the branch above + 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); + } else { + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 2); + } + 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_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0); + } else { + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 1); + } + 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, +}; + +/* 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, +}; + +/* ============= + * hook into TMK + * ============= */ +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 + 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(); + + /* enable LEDs on all pages */ + full_page[0] = 0; + __builtin_memcpy(full_page+1, is31_ic60_leds_mask, 0x12); + for(i=0; i<8; i++) { + is31_write_data(i, full_page, 1+0x12); + } + + /* 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); + + /* 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 new file mode 100644 index 0000000000..7db02389f8 --- /dev/null +++ b/keyboards/infinity60/led_controller.h @@ -0,0 +1,101 @@ +/* +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 + * ========================= */ + +void led_controller_init(void); + +/* ============================= + * 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 0x8 +// 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 definitions + * ============================== */ + +extern mailbox_t led_mailbox; + +// 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 +}; + +#endif /* _LED_CONTROLLER_H_ */ diff --git a/keyboards/infinity60/mcuconf.h b/keyboards/infinity60/mcuconf.h index f453304b75..6af85d0796 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 56d6470b59..f58bb26420 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 |