From af13e9a12d64f74873e5bf429fdedcda37b3036a Mon Sep 17 00:00:00 2001 From: jpetermans Date: Thu, 6 Apr 2017 16:27:51 -0700 Subject: [PATCH 01/24] Moved led page arrays to keymap.c and added keymap header to define individual led addresses --- .../infinity60/keymaps/jpetermans/keymap.c | 80 +++++++++++++++++-- .../keymaps/jpetermans/keymap_jpetermans.h | 78 ++++++++++++++++++ keyboards/infinity60/led_controller.c | 51 +----------- 3 files changed, 152 insertions(+), 57 deletions(-) create mode 100644 keyboards/infinity60/keymaps/jpetermans/keymap_jpetermans.h diff --git a/keyboards/infinity60/keymaps/jpetermans/keymap.c b/keyboards/infinity60/keymaps/jpetermans/keymap.c index 2c38068fef..7b90bc8ede 100644 --- a/keyboards/infinity60/keymaps/jpetermans/keymap.c +++ b/keyboards/infinity60/keymaps/jpetermans/keymap.c @@ -1,5 +1,6 @@ #include "infinity60.h" #include "led_controller.h" +#include "keymap_jpetermans.h" //Helpful Defines #define _______ KC_TRNS @@ -86,6 +87,66 @@ enum function_id { enum macro_id { ACTION_LEDS_ALL, ACTION_LEDS_GAME +//TODO: ACTION_LED_LAYER which reads current layer and turns on appropriate LED +}; + +/* + Configuring led control can be done + 1. full keyboard at a time - define led array, or + 2. individual - send specific led address (defined in keymap.h) + + The arrays relate to the mcu's LED pages (8 available) desribed in led_controller.c + 0x24 (pcb row 1) is first byte of PWM portion of LED page + 0x34 (pcb row 2) is 17th byte of PWM portion of LED page + array translates to row and column positions + + + 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 +*/ + +//"WASD" +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, +}; + +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, }; const uint16_t fn_actions[] = { @@ -94,13 +155,6 @@ const uint16_t fn_actions[] = { [2] = ACTION_FUNCTION(ACTION_LEDS_ALL), [3] = ACTION_FUNCTION(ACTION_LEDS_GAME) -/* [1] = ACTION_FUNCTION(ACTION_LEDS_GAME), - - [4] = ACTION_USAGE_CONSUMER(0x1B4), - [5] = ACTION_USAGE_CONSUMER(0x196), - [6] = ACTION_USAGE_CONSUMER(0x1A6), - [7] = ACTION_USAGE_CONSUMER(0x1A0) -*/ }; /* custom action function */ @@ -140,7 +194,19 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) // Runs just one time when the keyboard initializes. void matrix_init_user(void) { + uint8_t j; + led_controller_init(); + +//TODO: do pages need to be written at init or ok on demand? + /* Write pages */ + for(j=0; j<8; j++) { + is31_write_data(1,(uint8_t *)(led_game+(9*j)),9); + chThdSleepMilliseconds(5); + is31_write_data(2,(uint8_t *)(led_all+(9*j)),9); + chThdSleepMilliseconds(5); + } + }; // Runs constantly in the background, in a loop. diff --git a/keyboards/infinity60/keymaps/jpetermans/keymap_jpetermans.h b/keyboards/infinity60/keymaps/jpetermans/keymap_jpetermans.h new file mode 100644 index 0000000000..240374423c --- /dev/null +++ b/keyboards/infinity60/keymaps/jpetermans/keymap_jpetermans.h @@ -0,0 +1,78 @@ +/* LED layout mainly based on default Standard configuration + * ,-----------------------------------------------------------. + * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \ | ` | + * |-----------------------------------------------------------| + * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| Bksp| + * |-----------------------------------------------------------| + * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Enter | + * |-----------------------------------------------------------| + * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |Fn0| + * |-----------------------------------------------------------' + * | LCtl|LGui|LAlt | Space | RAlt|RGui|RMenu|RCtl| + * `-----------------------------------------------------------' +*/ + + +#define ADDR_LED_ESC 0x24 +#define ADDR_LED_1 0x25 +#define ADDR_LED_2 0x26 +#define ADDR_LED_3 0x27 +#define ADDR_LED_4 0x28 +#define ADDR_LED_5 0x29 +#define ADDR_LED_6 0x2A +#define ADDR_LED_7 0x2B +#define ADDR_LED_8 0x34 +#define ADDR_LED_9 0x35 +#define ADDR_LED_0 0x36 +#define ADDR_LED_MINS 0x37 +#define ADDR_LED_EQL 0x38 +#define ADDR_LED_BSLS 0x39 +//#define ADDR_LED_GRV 0x3A //not used by Alphabet layout +#define ADDR_LED_TAB 0x3B +#define ADDR_LED_Q 0x44 +#define ADDR_LED_W 0x45 +#define ADDR_LED_E 0x46 +#define ADDR_LED_R 0x47 +#define ADDR_LED_T 0x48 +#define ADDR_LED_Y 0x49 +#define ADDR_LED_U 0x4A +#define ADDR_LED_I 0x4B +#define ADDR_LED_O 0x54 +#define ADDR_LED_P 0x55 +#define ADDR_LED_LBRC 0x56 +#define ADDR_LED_RBRC 0x57 +#define ADDR_LED_BSPC 0x58 +#define ADDR_LED_CAPS 0x59 +#define ADDR_LED_A 0x5A +#define ADDR_LED_S 0x5B +#define ADDR_LED_D 0x64 +#define ADDR_LED_F 0x65 +#define ADDR_LED_G 0x66 +#define ADDR_LED_H 0x67 +#define ADDR_LED_J 0x68 +#define ADDR_LED_K 0x69 +#define ADDR_LED_L 0x6A +#define ADDR_LED_SCLN 0x6B +#define ADDR_LED_QUOT 0x74 +#define ADDR_LED_ENT 0x75 +#define ADDR_LED_LSFT 0x76 +#define ADDR_LED_Z 0x77 +#define ADDR_LED_X 0x78 +#define ADDR_LED_C 0x79 +#define ADDR_LED_V 0x7A +#define ADDR_LED_B 0x7B +#define ADDR_LED_N 0x84 +#define ADDR_LED_M 0x85 +#define ADDR_LED_COMM 0x86 +#define ADDR_LED_DOT 0x87 +#define ADDR_LED_SLSH 0x88 +#define ADDR_LED_RSFT 0x89 +//#define ADDR_LED_FN0 0x8A //not used by Alphabet layout +#define ADDR_LED_LCTL 0x8B +#define ADDR_LED_LGUI 0x94 +#define ADDR_LED_LALT 0x95 +#define ADDR_LED_SPC 0x96 +#define ADDR_LED_RALT 0x97 +#define ADDR_LED_RGUI 0x98 +#define ADDR_LED_MENU 0x99 +#define ADDR_LED_RCTL 0x9A diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c index c5303a3e70..9579bc08b4 100644 --- a/keyboards/infinity60/led_controller.c +++ b/keyboards/infinity60/led_controller.c @@ -171,6 +171,7 @@ static THD_FUNCTION(LEDthread, arg) { // process 'msg' here switch(msg) { +//TODO: make this generic and able to turn on/off any address and loop through all(or current) pages case LED_MSG_CAPS_ON: // turn caps on on pages 1 and 2 is31_write_register(0, CAPS_LOCK_LED_ADDRESS, 0xFF); @@ -238,48 +239,6 @@ static THD_FUNCTION(LEDthread, arg) { } } -//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 * ============= */ @@ -315,14 +274,6 @@ 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); From a2ac8837790030b771744402aac8d8ab0e1967aa Mon Sep 17 00:00:00 2001 From: jpetermans Date: Fri, 7 Apr 2017 15:58:17 -0700 Subject: [PATCH 02/24] add ability to toggle individual led by address --- .../infinity60/keymaps/jpetermans/keymap.c | 78 +++++---- keyboards/infinity60/led.c | 3 + keyboards/infinity60/led_controller.c | 148 +++++++++--------- 3 files changed, 128 insertions(+), 101 deletions(-) diff --git a/keyboards/infinity60/keymaps/jpetermans/keymap.c b/keyboards/infinity60/keymaps/jpetermans/keymap.c index 7b90bc8ede..c7145ed78e 100644 --- a/keyboards/infinity60/keymaps/jpetermans/keymap.c +++ b/keyboards/infinity60/keymaps/jpetermans/keymap.c @@ -12,6 +12,10 @@ #define _MEDIA 3 #define _TILDE 4 +/* ================================== + * KEYMAPS + * ==================================*/ + const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /* Layer 0: Default Layer * ,-----------------------------------------------------------. @@ -58,7 +62,7 @@ const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = { _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,KC_MUTE, KC_VOLD, KC_VOLU,_______,KC_NO,\ _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______,_______,\ _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______, \ - _______,_______,F(2),F(3),_______,_______,_______, _______, KC_MPRV, KC_MNXT,KC_MSTP, _______,KC_NO, \ + _______,_______,F(2),F(3),F(4),_______,_______, _______, KC_MPRV, KC_MNXT,KC_MSTP, _______,KC_NO, \ _______,_______,_______, KC_MPLY, _______,_______, _______,_______ \ ), /* ~ */ @@ -86,28 +90,35 @@ enum function_id { enum macro_id { ACTION_LEDS_ALL, - ACTION_LEDS_GAME -//TODO: ACTION_LED_LAYER which reads current layer and turns on appropriate LED + ACTION_LEDS_GAME, + ACTION_LED_1 }; + +/* ================================== + * LED MAPPING + * ==================================*/ + +//TODO: ACTION_LED_LAYER which reads current layer and turns on appropriate LED /* - Configuring led control can be done + Configuring led control can be done as 1. full keyboard at a time - define led array, or - 2. individual - send specific led address (defined in keymap.h) - - The arrays relate to the mcu's LED pages (8 available) desribed in led_controller.c + 2. individual led - send specific led address (defined in keymap.h) + + 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 + + The full keyboard arrays map to the mcu's LED pages + (8 available) desribed in led_controller.c + 0x24 (pcb row 1) is first byte of PWM portion of LED page 0x34 (pcb row 2) is 17th byte of PWM portion of LED page array translates to row and column positions - - - 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 */ //"WASD" @@ -153,7 +164,8 @@ 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) + [3] = ACTION_FUNCTION(ACTION_LEDS_GAME), + [4] = ACTION_FUNCTION(ACTION_LED_1) }; @@ -162,15 +174,21 @@ 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); - } + if(record->event.pressed) { + // signal the LED controller thread + chMBPost(&led_mailbox, 1, 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); + chMBPost(&led_mailbox, 2, TIME_IMMEDIATE); + } + break; + case ACTION_LED_1: + if(record->event.pressed) { + // signal the LED controller thread + chMBPost(&led_mailbox, ADDR_LED_1, TIME_IMMEDIATE); } break; } @@ -179,14 +197,14 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { 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; + case 0: + if (record->event.pressed) { + } + break; + case 1: + if (record->event.pressed) { + } + break; } return MACRO_NONE; }; diff --git a/keyboards/infinity60/led.c b/keyboards/infinity60/led.c index e17a5dd0d3..815a529fc8 100644 --- a/keyboards/infinity60/led.c +++ b/keyboards/infinity60/led.c @@ -36,6 +36,9 @@ void led_set(uint8_t usb_led) { GPIOA->PCOR |= (1<<5); } */ +//TODO: How does this test if led is set +//usb_led --> led_set(usb_led) <-- chibios/host_keyboard_leds <-- keyboard_leds from usbSetupTransfer +//keyboard_leds is enum'd in chibios/main.c if (usb_led & (1<= 0x24) { + xprintf("Power pre-read\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm); + is31_read_register(0, msg, &temp); + chThdSleepMilliseconds(10); + xprintf("Post-read\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm); + chThdSleepMilliseconds(10); + pwm = (temp > 0x00 ? 0x00 : 0xFF); + xprintf("pwm after: %X\n", pwm); + chThdSleepMilliseconds(10); + for(i=0; i<8; i++) { + is31_write_register(i, msg, pwm); + } + xprintf("Power post-change\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm); + chThdSleepMilliseconds(10); + } + break; + } } + xprintf("--------------------\n"); } } - -/* ============= - * hook into TMK - * ============= */ +/* ===================== + * hook into user keymap + * ===================== */ void led_controller_init(void) { uint8_t i; From dda858c437e2fd0336f070ccb5d1f6e412815d9a Mon Sep 17 00:00:00 2001 From: jpetermans Date: Mon, 10 Apr 2017 17:36:47 -0700 Subject: [PATCH 03/24] revised led controller code to allow for more options unable to switch picture displays --- .../infinity60/keymaps/jpetermans/keymap.c | 103 +++--- keyboards/infinity60/led.c | 4 +- keyboards/infinity60/led_controller.c | 333 ++++++++++++++---- keyboards/infinity60/led_controller.h | 33 +- 4 files changed, 340 insertions(+), 133 deletions(-) diff --git a/keyboards/infinity60/keymaps/jpetermans/keymap.c b/keyboards/infinity60/keymaps/jpetermans/keymap.c index c7145ed78e..cfc2889162 100644 --- a/keyboards/infinity60/keymaps/jpetermans/keymap.c +++ b/keyboards/infinity60/keymaps/jpetermans/keymap.c @@ -98,8 +98,6 @@ enum macro_id { * LED MAPPING * ==================================*/ -//TODO: ACTION_LED_LAYER which reads current layer and turns on appropriate LED - /* Configuring led control can be done as 1. full keyboard at a time - define led array, or @@ -121,43 +119,50 @@ enum macro_id { array translates to row and column positions */ -//"WASD" -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 Layer indicator (1 per layer 3-7) +const uint8_t led_single_layer[5] = { + 12,13,14,15,16 }; - -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, +//LED Page 1 - All off +//LED Page 2 - All on +//LED Page 3 - _Nav +const uint8_t led_nav[33] = { + 11,12,13,14,15,16,17,18,21,22,23,24,25, + 28, 37,38,41,42,45, + 46,47,48, 54,55,56,57,58, + 64,65,66, 71, + 84,85 +}; +//LED Page 4 - _Numpad +const uint8_t led_numpad[17] = { + 18,21,22,23, + 37,38,41,42, + 55,56,57,58, + 72,73,74,75, + 85 +}; +//LED Page 5 - _Media +const uint8_t led_media[12] = { + 23,24,25, + 38, + 55,56,57, + 73,74,75, + 83, 86 +}; +//LED Page 6 - _Game +const uint8_t led_game[5] = { + //row 1 + 11, + //row 2 + //row 3 + 32, + //row 4 + 47, 48, + //row 5 + 51 + //row 6 + //row 7 + //row 8 }; const uint16_t fn_actions[] = { @@ -172,17 +177,20 @@ const uint16_t fn_actions[] = { /* 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, 1, TIME_IMMEDIATE); + msg=(TOGGLE_LED << 8) | 12; + chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } break; case ACTION_LEDS_GAME: if(record->event.pressed) { // signal the LED controller thread - chMBPost(&led_mailbox, 2, TIME_IMMEDIATE); + msg=(TOGGLE_LAYER_LEDS << 8) | 5; + chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } break; case ACTION_LED_1: @@ -212,19 +220,22 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) // Runs just one time when the keyboard initializes. void matrix_init_user(void) { - uint8_t j; led_controller_init(); //TODO: do pages need to be written at init or ok on demand? - /* Write pages */ - for(j=0; j<8; j++) { - is31_write_data(1,(uint8_t *)(led_game+(9*j)),9); +/* Write pages */ + write_led_page(3, led_nav, 33); chThdSleepMilliseconds(5); - is31_write_data(2,(uint8_t *)(led_all+(9*j)),9); + + write_led_page(4, led_numpad, 17); chThdSleepMilliseconds(5); - } + write_led_page(5, led_media, 12); + chThdSleepMilliseconds(5); + + write_led_page(6, led_game, 5); + chThdSleepMilliseconds(5); }; // Runs constantly in the background, in a loop. diff --git a/keyboards/infinity60/led.c b/keyboards/infinity60/led.c index 815a529fc8..d2f554549a 100644 --- a/keyboards/infinity60/led.c +++ b/keyboards/infinity60/led.c @@ -42,12 +42,12 @@ void led_set(uint8_t usb_led) { if (usb_led & (1<. * 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 +#define CAPS_LOCK_LED_ADDRESS 0x46 +#endif + +#if !defined(NUM_LOCK_LED_ADDRESS) +#define NUM_LOCK_LED_ADDRESS 0x85 #endif /* Which LED should breathe during sleep */ @@ -85,12 +89,21 @@ 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 +// Each byte is a control pin for 8 leds ordered 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 }; +// 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_reg_array[9] = {0}; + + /* ============================ * communication functions * ============================ */ @@ -109,6 +122,7 @@ msg_t is31_write_register(uint8_t page, uint8_t reg, uint8_t data) { is31_select_page(page); tx[0] = reg; tx[1] = data; + xprintf("page display: %X\n", page); return i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, tx, 2, NULL, 0, US2ST(IS31_TIMEOUT)); } @@ -160,98 +174,267 @@ static THD_FUNCTION(LEDthread, arg) { (void)arg; chRegSetThreadName("LEDthread"); - uint8_t i; - uint8_t temp, pwm; - uint8_t save_page, save_breath1, save_breath2; + uint8_t i, page; + + //persistent status variables + uint8_t backlight_status, lock_status, led_step, active_layer; + uint8_t led_control_reg[0x13] = {0};//led control register start address + 0x12 bytes + + //mailbox variables + uint8_t temp, msg_type, msg_led; + msg_t msg; + +/* //control register variables + uint8_t page, save_page, save_breath1, save_breath2; msg_t msg, retval; +*/ + +// initialize persistent variables +backlight_status = 0; +lock_status = 0;//TODO: does keyboard remember locks? +led_step = 4; //full brightness +active_layer = 0; 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_type = (msg >> 8) & 0xFF; //first byte is msg type + msg_led = (msg) & 0xFF; //second byte is action information - // process 'msg' here - // if msg between 0-7, then process as page#, otherwise a specific LED address xprintf("--------------------\n"); - xprintf("mailbox fetch\ntemp: %X - msg: %X\n", temp, msg); - if (msg < 8) { - - // read current page into 'temp' - is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); - chThdSleepMilliseconds(1); - // If page is already in layer, switch off (layer 0) - xprintf("Layer: post-read\ntemp: %X\n", temp); - if(temp == msg) { - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0); - } else { - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, msg); - } - xprintf("Layer: post-change\ntemp: %X\n", temp); - - } else { - - switch(msg) { -//TODO: make this generic and able to turn on/off any address and loop through all(or current) pages -//TODO: set number of layers somewhere and loop through all when setting specific led - 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)); + xprintf("mailbox fetch\nmsg: %X\n", msg); + xprintf("type: %X - led: %X\n", msg_type, msg_led); //test if msg_type is 1 or 2 bytes after mask + switch (msg_type){ + case KEY_LIGHT: + //TODO: lighting key led on keypress + break; + + case TOGGLE_LED: + //TODO: toggle existing indicator off, or let user do this, but write frame 7 for every led change + //turn on single led, msg_led = row/col of led + set_led_bit(led_control_reg, msg_led, 1); + + is31_write_data (7, led_control_reg, 0x12+1); + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); + active_layer = 7; + is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); + xprintf("page display: %X\n", temp); + break; + + case TOGGLE_ALL: + xprintf("TOGGLE_ALL\n"); + //msg_led = unused, TODO: consider using msg_led to toggle layer display + is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); + + xprintf("temp: %X\n", temp); + //if LED_ALL is on then toggle off, any other layer, turn on LED_ALL + if(temp == 1) { + xprintf("page display true: %X\n", temp); + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0); + } else { + xprintf("page display false: %X\n", temp); + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 1); + } + is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); + xprintf("page display: %X\n", temp); + break; + + case TOGGLE_BACKLIGHT: + //msg_led = unused + backlight_status ^= 1; + is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); + active_layer = temp; + + page = backlight_status == 0 ? 0 : active_layer; + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, page); + break; + + case TOGGLE_LAYER_LEDS://show layer indicator or full map of layer keys. + //TODO: change so user can flag which they want, indiv or full map in fn_actions + //msg_led = layer to toggle on + is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); + + if(temp == msg_led) { + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); + active_layer = 7; + } else { + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, msg_led); + active_layer = msg_led; + } + break; + + case TOGGLE_LOCK_LED: + //msg_led = 0-3 for lock flags + lock_status ^= msg_led; //TODO: confirm toggling works and doesn't get out of sync + set_lock_leds(led_control_reg, lock_status); + break; + + case MODE_BREATH: + break; + case STEP_BRIGHTNESS: + //pwm_levels[] bounds checking, loop through array + //TODO: find a cleaner way to walk through this logic + if (msg_led == 0) { + if (led_step == 0) { + led_step = 4; + } else { + led_step--; } - // 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; - break; - default: - if(msg >= 0x24) { - xprintf("Power pre-read\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm); + } else { + if (led_step == 4) { + led_step = 0; + } else { + led_step++; + } + } + + //TODO: this seems a messy way to populate the pwm register + //populate the 9 byte rows to be written to each pin, first byte is register (pin) address + for(i=1; i<9; i++) { + pwm_reg_array[i]=pwm_levels[led_step]; + } + for(i=0; i<8; i++) { + pwm_reg_array[0] = 0x24 + (i * 0x10);//first byte of 9 bytes must be register address + is31_write_data(0, pwm_reg_array, 9); + chThdSleepMilliseconds(5); + } + 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; + break; + default: + //TODO: individual led state unchanged if page arrays are selected in code above + //avoidable if full pages are written on the fly + //or use pg8 for individual leds, have pointer to currently on led address for toggling + if (msg == 0x59 || msg == 0x84) { + //toggle lock keys on all layers + for (i=0,i<8,i++) { is31_read_register(0, msg, &temp); - chThdSleepMilliseconds(10); - xprintf("Post-read\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm); - chThdSleepMilliseconds(10); pwm = (temp > 0x00 ? 0x00 : 0xFF); - xprintf("pwm after: %X\n", pwm); - chThdSleepMilliseconds(10); - for(i=0; i<8; i++) { - is31_write_register(i, msg, pwm); - } - xprintf("Power post-change\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm); - chThdSleepMilliseconds(10); + is31_write_register(i,msg,pwm); + } + + } else if(msg >= 0x24) { + xprintf("Power pre-read\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm); + is31_read_register(7, msg, &temp); + xprintf("Post-read\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm); + if (msg == active_led) { + //toggle led power + pwm = (temp > 0x00 ? 0x00 : 0xFF); + + //Use 8th led page for individual led indicators + is31_write_register(7, msg, pwm); + } else { + is31_write_register(7, active_led, 0x00); + is31_write_register(7, msg, 0xFF); + } + xprintf("Power post-change\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm); + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); } break; - } +*/ } xprintf("--------------------\n"); } } + + +/* ======================== + * led bit processing + * ======================== */ +void set_led_bit (uint8_t *led_control_reg, uint8_t msg_led, uint8_t toggle_on) { + uint8_t row_byte, column_bit; + //msg_led tens column is pin#, A-control register is every other 8 bits + //ones column is bit position in 8-bit mask + //control register will be one bit shifted into position along register's full 0x12 bytes + ////first byte is register address 0x00 + row_byte = ((msg_led / 10) % 10 - 1 ) * 2 + 1; + column_bit = 1<<(msg_led % 10 - 1); + + if (toggle_on) { + led_control_reg[row_byte] |= 1<<(column_bit); + } else { + led_control_reg[row_byte] &= ~1<<(column_bit); + } +} + +void set_lock_leds(uint8_t *led_control_reg, uint8_t lock_status) { + uint8_t i; + + switch (lock_status) { + case 1: + set_led_bit(led_control_reg, CAPS_LOCK_LED_ADDRESS, 1);//TODO: define lock addresses by matrix#, and loop for all frames + set_led_bit(led_control_reg, NUM_LOCK_LED_ADDRESS, 0); + break; + case 2: + set_led_bit(led_control_reg, CAPS_LOCK_LED_ADDRESS, 0); + set_led_bit(led_control_reg, NUM_LOCK_LED_ADDRESS, 1); + break; + case 3: + set_led_bit(led_control_reg, NUM_LOCK_LED_ADDRESS, 1); + set_led_bit(led_control_reg, CAPS_LOCK_LED_ADDRESS, 1); + break; + } + + for(i=1; i<8; i++) { //keep LED_OFF layer all off, including locks + is31_write_data (i, led_control_reg, 0x12+1); + chThdSleepMilliseconds(5); + } +} + +void write_led_page (uint8_t page, const uint8_t *led_array, uint8_t led_count) { +//TODO: init function that accepts array of led addresses and sets them by row + uint8_t i; + uint8_t row, col; + uint8_t temp_control_reg[0x13] = {0};//led control register start address + 0x12 bytes + xprintf("-------------\n"); + xprintf("write page %X\n", page); + + for(i=0;i Date: Mon, 10 Apr 2017 22:23:45 -0700 Subject: [PATCH 04/24] led init code missing pwm writes for Frame 1 --- .../infinity60/keymaps/jpetermans/keymap.c | 32 ++++++++++++++----- keyboards/infinity60/led_controller.c | 23 +++++++++---- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/keyboards/infinity60/keymaps/jpetermans/keymap.c b/keyboards/infinity60/keymaps/jpetermans/keymap.c index cfc2889162..87a1afc3e5 100644 --- a/keyboards/infinity60/keymaps/jpetermans/keymap.c +++ b/keyboards/infinity60/keymaps/jpetermans/keymap.c @@ -62,7 +62,7 @@ const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = { _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,KC_MUTE, KC_VOLD, KC_VOLU,_______,KC_NO,\ _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______,_______,\ _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______, \ - _______,_______,F(2),F(3),F(4),_______,_______, _______, KC_MPRV, KC_MNXT,KC_MSTP, _______,KC_NO, \ + _______,_______,F(2),F(3),F(4),F(5),F(6),F(7), KC_MPRV, KC_MNXT,KC_MSTP, _______,KC_NO, \ _______,_______,_______, KC_MPLY, _______,_______, _______,_______ \ ), /* ~ */ @@ -91,7 +91,9 @@ enum function_id { enum macro_id { ACTION_LEDS_ALL, ACTION_LEDS_GAME, - ACTION_LED_1 + ACTION_LEDS_NAV, + ACTION_LEDS_MEDIA, + ACTION_LEDS_NUMPAD }; /* ================================== @@ -170,7 +172,9 @@ const uint16_t fn_actions[] = { [1] = ACTION_LAYER_MODS(_TILDE, MOD_LSFT), [2] = ACTION_FUNCTION(ACTION_LEDS_ALL), [3] = ACTION_FUNCTION(ACTION_LEDS_GAME), - [4] = ACTION_FUNCTION(ACTION_LED_1) + [4] = ACTION_FUNCTION(ACTION_LEDS_MEDIA), + [5] = ACTION_FUNCTION(ACTION_LEDS_NAV), + [6] = ACTION_FUNCTION(ACTION_LEDS_NUMPAD) }; @@ -182,23 +186,35 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { case ACTION_LEDS_ALL: if(record->event.pressed) { // signal the LED controller thread - msg=(TOGGLE_LED << 8) | 12; + msg=(TOGGLE_ALL << 8) | 0; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } break; case ACTION_LEDS_GAME: if(record->event.pressed) { // signal the LED controller thread - msg=(TOGGLE_LAYER_LEDS << 8) | 5; + msg=(TOGGLE_LED << 8) | 11; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } break; - case ACTION_LED_1: + case ACTION_LEDS_NAV: if(record->event.pressed) { // signal the LED controller thread - chMBPost(&led_mailbox, ADDR_LED_1, TIME_IMMEDIATE); + msg=(TOGGLE_LAYER_LEDS << 8) | 3; + chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); + } + case ACTION_LEDS_NUMPAD: + if(record->event.pressed) { + // signal the LED controller thread + msg=(TOGGLE_LAYER_LEDS << 8) | 4; + chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); + } + case ACTION_LEDS_MEDIA: + if(record->event.pressed) { + // signal the LED controller thread + msg=(TOGGLE_LAYER_LEDS << 8) | 5; + chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } - break; } } diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c index 03f061a20e..2a7431a4cd 100644 --- a/keyboards/infinity60/led_controller.c +++ b/keyboards/infinity60/led_controller.c @@ -122,7 +122,6 @@ msg_t is31_write_register(uint8_t page, uint8_t reg, uint8_t data) { is31_select_page(page); tx[0] = reg; tx[1] = data; - xprintf("page display: %X\n", page); return i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, tx, 2, NULL, 0, US2ST(IS31_TIMEOUT)); } @@ -379,6 +378,8 @@ void set_led_bit (uint8_t *led_control_reg, uint8_t msg_led, uint8_t toggle_on) ////first byte is register address 0x00 row_byte = ((msg_led / 10) % 10 - 1 ) * 2 + 1; column_bit = 1<<(msg_led % 10 - 1); + xprintf("row %X\n", row_byte); + xprintf("col %X\n", column_bit); if (toggle_on) { led_control_reg[row_byte] |= 1<<(column_bit); @@ -451,15 +452,23 @@ 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 Frame 1 + is31_write_register(IS31_FUNCTIONREG, IS31_REG_DISPLAYOPT, IS31_REG_DISPLAYOPT_INTENSITY_SAME); + + /* set full pwm on Frame 1 */ + for(i=1; i<9; i++) { + pwm_reg_array[i]=0xFF; + } for(i=0; i<8; i++) { - is31_write_data(i, full_page, 1+0x12); + pwm_reg_array[0] = 0x24 + (i * 0x10);//first byte of 9 bytes must be register address + is31_write_data(0, pwm_reg_array, 9); + chThdSleepMilliseconds(5); } - //set Display Option Register so all pwm intensity is controlled from Frame 1 - is31_write_register(IS31_FUNCTIONREG, IS31_REG_DISPLAYOPT, IS31_REG_DISPLAYOPT_INTENSITY_SAME); + //set all led bits on for Frame 2 LEDS_ALL + full_page[0] = 0; + __builtin_memcpy(full_page+1, is31_ic60_leds_mask, 0x12); + is31_write_data(1, full_page, 1+0x12); /* enable breathing when the displayed page changes */ // Fade-in Fade-out, time = 26ms * 2^N, N=3 From 0881f2dbfa6887347afad577def01c246050df61 Mon Sep 17 00:00:00 2001 From: jpetermans Date: Tue, 11 Apr 2017 23:33:48 -0700 Subject: [PATCH 05/24] fixed write_led_page col shift, added option for lock led display --- .../infinity60/keymaps/jpetermans/keymap.c | 24 +++- keyboards/infinity60/led_controller.c | 109 ++++++------------ keyboards/infinity60/led_controller.h | 1 + 3 files changed, 53 insertions(+), 81 deletions(-) diff --git a/keyboards/infinity60/keymaps/jpetermans/keymap.c b/keyboards/infinity60/keymaps/jpetermans/keymap.c index 87a1afc3e5..2eb66b506f 100644 --- a/keyboards/infinity60/keymaps/jpetermans/keymap.c +++ b/keyboards/infinity60/keymaps/jpetermans/keymap.c @@ -93,7 +93,8 @@ enum macro_id { ACTION_LEDS_GAME, ACTION_LEDS_NAV, ACTION_LEDS_MEDIA, - ACTION_LEDS_NUMPAD + ACTION_LEDS_NUMPAD, + ACTION_LEDS_TEST }; /* ================================== @@ -174,7 +175,9 @@ const uint16_t fn_actions[] = { [3] = ACTION_FUNCTION(ACTION_LEDS_GAME), [4] = ACTION_FUNCTION(ACTION_LEDS_MEDIA), [5] = ACTION_FUNCTION(ACTION_LEDS_NAV), - [6] = ACTION_FUNCTION(ACTION_LEDS_NUMPAD) + [6] = ACTION_FUNCTION(ACTION_LEDS_NUMPAD), + [7] = ACTION_FUNCTION(ACTION_LEDS_TEST) + }; @@ -193,7 +196,14 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { case ACTION_LEDS_GAME: if(record->event.pressed) { // signal the LED controller thread - msg=(TOGGLE_LED << 8) | 11; + msg=(TOGGLE_LAYER_LEDS << 8) | 6; + chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); + } + break; + case ACTION_LEDS_MEDIA: + if(record->event.pressed) { + // signal the LED controller thread + msg=(TOGGLE_LAYER_LEDS << 8) | 5; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } break; @@ -203,18 +213,21 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { msg=(TOGGLE_LAYER_LEDS << 8) | 3; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } + break; case ACTION_LEDS_NUMPAD: if(record->event.pressed) { // signal the LED controller thread msg=(TOGGLE_LAYER_LEDS << 8) | 4; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } - case ACTION_LEDS_MEDIA: + break; + case ACTION_LEDS_TEST: if(record->event.pressed) { // signal the LED controller thread - msg=(TOGGLE_LAYER_LEDS << 8) | 5; + msg=(TOGGLE_LED << 8) | 12; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } + break; } } @@ -236,6 +249,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) // Runs just one time when the keyboard initializes. void matrix_init_user(void) { + xprintf("init start"); led_controller_init(); diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c index 2a7431a4cd..89c477ee75 100644 --- a/keyboards/infinity60/led_controller.c +++ b/keyboards/infinity60/led_controller.c @@ -101,7 +101,7 @@ const uint8_t pwm_levels[5] = { }; // array to write to pwm register -uint8_t pwm_reg_array[9] = {0}; +uint8_t pwm_register_array[9] = {0}; /* ============================ @@ -147,10 +147,6 @@ void is31_init(void) { // software shutdown is31_write_register(IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, 0); chThdSleepMilliseconds(10); - // TODO: This already done above, remove? - // 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); @@ -176,7 +172,7 @@ static THD_FUNCTION(LEDthread, arg) { uint8_t i, page; //persistent status variables - uint8_t backlight_status, lock_status, led_step, active_layer; + uint8_t backlight_status, lock_status, led_step_status, layer_status; uint8_t led_control_reg[0x13] = {0};//led control register start address + 0x12 bytes //mailbox variables @@ -191,8 +187,8 @@ static THD_FUNCTION(LEDthread, arg) { // initialize persistent variables backlight_status = 0; lock_status = 0;//TODO: does keyboard remember locks? -led_step = 4; //full brightness -active_layer = 0; +led_step_status = 4; //full brightness +layer_status = 0; while(true) { // wait for a message (asynchronous) @@ -213,13 +209,13 @@ active_layer = 0; case TOGGLE_LED: //TODO: toggle existing indicator off, or let user do this, but write frame 7 for every led change //turn on single led, msg_led = row/col of led + xprintf("TOGGLE_LED\n"); set_led_bit(led_control_reg, msg_led, 1); is31_write_data (7, led_control_reg, 0x12+1); is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); - active_layer = 7; + layer_status = 7; is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); - xprintf("page display: %X\n", temp); break; case TOGGLE_ALL: @@ -227,40 +223,39 @@ active_layer = 0; //msg_led = unused, TODO: consider using msg_led to toggle layer display is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); - xprintf("temp: %X\n", temp); //if LED_ALL is on then toggle off, any other layer, turn on LED_ALL if(temp == 1) { - xprintf("page display true: %X\n", temp); is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0); } else { - xprintf("page display false: %X\n", temp); is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 1); } is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); - xprintf("page display: %X\n", temp); break; case TOGGLE_BACKLIGHT: //msg_led = unused + //TODO: consider Frame 0 as on/off layer and toggle led control register here + xprintf("TOGGLE_BACKLIGHT\n"); backlight_status ^= 1; is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); - active_layer = temp; + layer_status = temp; - page = backlight_status == 0 ? 0 : active_layer; + page = backlight_status == 0 ? 0 : layer_status; is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, page); break; case TOGGLE_LAYER_LEDS://show layer indicator or full map of layer keys. //TODO: change so user can flag which they want, indiv or full map in fn_actions //msg_led = layer to toggle on + xprintf("TOGGLE_LAYER_LEDS\n"); is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); if(temp == msg_led) { is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); - active_layer = 7; + layer_status = 7; } else { is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, msg_led); - active_layer = msg_led; + layer_status = msg_led; } break; @@ -275,29 +270,27 @@ active_layer = 0; case STEP_BRIGHTNESS: //pwm_levels[] bounds checking, loop through array //TODO: find a cleaner way to walk through this logic - if (msg_led == 0) { - if (led_step == 0) { - led_step = 4; - } else { - led_step--; - } + if (msg_led == 0 && led_step_status == 0) { + led_step_status = 4; } else { - if (led_step == 4) { - led_step = 0; - } else { - led_step++; - } + led_step_status--; + } + + if (msg_led == 1 && led_step_status == 4) { + led_step_status = 0; + } else { + led_step_status++; } //TODO: this seems a messy way to populate the pwm register + //mimic whitefox init which uses memcpy //populate the 9 byte rows to be written to each pin, first byte is register (pin) address for(i=1; i<9; i++) { - pwm_reg_array[i]=pwm_levels[led_step]; + pwm_register_array[i]=pwm_levels[led_step_status]; } for(i=0; i<8; i++) { - pwm_reg_array[0] = 0x24 + (i * 0x10);//first byte of 9 bytes must be register address - is31_write_data(0, pwm_reg_array, 9); - chThdSleepMilliseconds(5); + pwm_register_array[0] = 0x24 + (i * 0x10);//first byte of 9 bytes must be register address + is31_write_data(0, pwm_register_array, 9);//first page controls pwm in all pages (init Display Option register) } break; @@ -330,36 +323,6 @@ active_layer = 0; case LED_MSG_SLEEP_LED_OFF: // should not get here; wakeup should be received in the branch above break; break; - default: - //TODO: individual led state unchanged if page arrays are selected in code above - //avoidable if full pages are written on the fly - //or use pg8 for individual leds, have pointer to currently on led address for toggling - if (msg == 0x59 || msg == 0x84) { - //toggle lock keys on all layers - for (i=0,i<8,i++) { - is31_read_register(0, msg, &temp); - pwm = (temp > 0x00 ? 0x00 : 0xFF); - is31_write_register(i,msg,pwm); - } - - } else if(msg >= 0x24) { - xprintf("Power pre-read\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm); - is31_read_register(7, msg, &temp); - xprintf("Post-read\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm); - if (msg == active_led) { - //toggle led power - pwm = (temp > 0x00 ? 0x00 : 0xFF); - - //Use 8th led page for individual led indicators - is31_write_register(7, msg, pwm); - } else { - is31_write_register(7, active_led, 0x00); - is31_write_register(7, msg, 0xFF); - } - xprintf("Power post-change\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm); - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); - } - break; */ } xprintf("--------------------\n"); @@ -378,8 +341,6 @@ void set_led_bit (uint8_t *led_control_reg, uint8_t msg_led, uint8_t toggle_on) ////first byte is register address 0x00 row_byte = ((msg_led / 10) % 10 - 1 ) * 2 + 1; column_bit = 1<<(msg_led % 10 - 1); - xprintf("row %X\n", row_byte); - xprintf("col %X\n", column_bit); if (toggle_on) { led_control_reg[row_byte] |= 1<<(column_bit); @@ -393,7 +354,7 @@ void set_lock_leds(uint8_t *led_control_reg, uint8_t lock_status) { switch (lock_status) { case 1: - set_led_bit(led_control_reg, CAPS_LOCK_LED_ADDRESS, 1);//TODO: define lock addresses by matrix#, and loop for all frames + set_led_bit(led_control_reg, CAPS_LOCK_LED_ADDRESS, 1); set_led_bit(led_control_reg, NUM_LOCK_LED_ADDRESS, 0); break; case 2: @@ -406,9 +367,8 @@ void set_lock_leds(uint8_t *led_control_reg, uint8_t lock_status) { break; } - for(i=1; i<8; i++) { //keep LED_OFF layer all off, including locks + for(i=BACKLIGHT_OFF_LOCK_LED_OFF; i<8; i++) { //set in led_controller.h is31_write_data (i, led_control_reg, 0x12+1); - chThdSleepMilliseconds(5); } } @@ -417,18 +377,15 @@ void write_led_page (uint8_t page, const uint8_t *led_array, uint8_t led_count) uint8_t i; uint8_t row, col; uint8_t temp_control_reg[0x13] = {0};//led control register start address + 0x12 bytes - xprintf("-------------\n"); - xprintf("write page %X\n", page); for(i=0;i Date: Wed, 12 Apr 2017 23:32:38 -0700 Subject: [PATCH 06/24] Updated lock led init --- keyboards/infinity60/led.c | 26 +++++-- keyboards/infinity60/led_controller.c | 104 +++++++++++++++++--------- keyboards/infinity60/led_controller.h | 11 +-- 3 files changed, 96 insertions(+), 45 deletions(-) diff --git a/keyboards/infinity60/led.c b/keyboards/infinity60/led.c index d2f554549a..c78e2d1195 100644 --- a/keyboards/infinity60/led.c +++ b/keyboards/infinity60/led.c @@ -16,6 +16,7 @@ along with this program. If not, see . */ #include "hal.h" +#include "print.h" #include "led.h" @@ -26,6 +27,7 @@ along with this program. If not, see . * In particular, I2C functions (interrupt-driven) should NOT be called from here. */ void led_set(uint8_t usb_led) { + msg_t msg; /* // PTA5: LED (1:on/0:off) GPIOA->PDDR |= (1<<1); @@ -36,18 +38,32 @@ void led_set(uint8_t usb_led) { GPIOA->PCOR |= (1<<5); } */ -//TODO: How does this test if led is set -//usb_led --> led_set(usb_led) <-- chibios/host_keyboard_leds <-- keyboard_leds from usbSetupTransfer -//keyboard_leds is enum'd in chibios/main.c + if (usb_led & (1<. #include "ch.h" #include "hal.h" #include "print.h" +#include "led.h" #include "led_controller.h" @@ -57,11 +58,11 @@ along with this program. If not, see . * 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 0x46 +#define CAPS_LOCK_LED_ADDRESS 46 #endif #if !defined(NUM_LOCK_LED_ADDRESS) -#define NUM_LOCK_LED_ADDRESS 0x85 +#define NUM_LOCK_LED_ADDRESS 85 #endif /* Which LED should breathe during sleep */ @@ -215,7 +216,6 @@ layer_status = 0; is31_write_data (7, led_control_reg, 0x12+1); is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); layer_status = 7; - is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); break; case TOGGLE_ALL: @@ -259,12 +259,18 @@ layer_status = 0; } break; - case TOGGLE_LOCK_LED: - //msg_led = 0-3 for lock flags - lock_status ^= msg_led; //TODO: confirm toggling works and doesn't get out of sync - set_lock_leds(led_control_reg, lock_status); + case TOGGLE_NUM_LOCK: + //msg_led = 0 or 1, off/on + //TODO: confirm toggling works and doesn't get out of sync + set_lock_leds(USB_LED_NUM_LOCK, msg_led); break; + case TOGGLE_CAPS_LOCK: + //msg_led = 0 or 1, off/on + //TODO: confirm toggling works and doesn't get out of sync + set_lock_leds(USB_LED_CAPS_LOCK, msg_led); + break; + case MODE_BREATH: break; case STEP_BRIGHTNESS: @@ -335,11 +341,10 @@ layer_status = 0; * ======================== */ void set_led_bit (uint8_t *led_control_reg, uint8_t msg_led, uint8_t toggle_on) { uint8_t row_byte, column_bit; - //msg_led tens column is pin#, A-control register is every other 8 bits + //msg_led tens column is pin# //ones column is bit position in 8-bit mask - //control register will be one bit shifted into position along register's full 0x12 bytes - ////first byte is register address 0x00 - row_byte = ((msg_led / 10) % 10 - 1 ) * 2 + 1; + //first byte is register address 0x00 + row_byte = ((msg_led / 10) % 10 - 1 ) * 2 + 1;// A register is every other 8 bits column_bit = 1<<(msg_led % 10 - 1); if (toggle_on) { @@ -349,31 +354,61 @@ void set_led_bit (uint8_t *led_control_reg, uint8_t msg_led, uint8_t toggle_on) } } -void set_lock_leds(uint8_t *led_control_reg, uint8_t lock_status) { - uint8_t i; - - switch (lock_status) { - case 1: - set_led_bit(led_control_reg, CAPS_LOCK_LED_ADDRESS, 1); - set_led_bit(led_control_reg, NUM_LOCK_LED_ADDRESS, 0); - break; - case 2: - set_led_bit(led_control_reg, CAPS_LOCK_LED_ADDRESS, 0); - set_led_bit(led_control_reg, NUM_LOCK_LED_ADDRESS, 1); - break; - case 3: - set_led_bit(led_control_reg, NUM_LOCK_LED_ADDRESS, 1); - set_led_bit(led_control_reg, CAPS_LOCK_LED_ADDRESS, 1); - break; - } - - for(i=BACKLIGHT_OFF_LOCK_LED_OFF; i<8; i++) { //set in led_controller.h - is31_write_data (i, led_control_reg, 0x12+1); +//TODO: not toggling off correctly +//TODO: confirm led_off page still has FF pwm for all +void set_lock_leds(uint8_t lock_type, uint8_t lock_status) { + uint8_t page; + uint8_t led_addr, temp; + uint8_t control_reg[2] = {0};//register address and led bits + + switch(lock_type) { + case USB_LED_NUM_LOCK: + led_addr = NUM_LOCK_LED_ADDRESS; + break; + case USB_LED_CAPS_LOCK: + led_addr = CAPS_LOCK_LED_ADDRESS; + break; + #ifdef SCROLL_LOCK_LED_ADDRESS + case USB_LED_SCROLL_LOCK: + led_addr = SCROLL_LOCK_LED_ADDRESS; + break; + #endif + #ifdef COMPOSE_LED_ADDRESS + case USB_LED_COMPOSE: + led_addr = COMPOSE_LED_ADDRESS; + break; + #endif + #ifdef SCROLL_LOCK_LED_ADDRESS + case USB_LED_KANA: + led_addr = KANA_LED_ADDRESS; + break; + #endif + } + xprintf("led_addr: %X\n", led_addr); + chThdSleepMilliseconds(30); + control_reg[0] = ((led_addr / 10) % 10 - 1 ) * 0x02;// A-register is every other byte + xprintf("control_reg: %X\n", control_reg[0]); + chThdSleepMilliseconds(30); + + for(page=BACKLIGHT_OFF_LOCK_LED_OFF; page<8; page++) { //set in led_controller.h + is31_read_register(page,control_reg[0],&temp);//need to maintain status of leds in this row (1 byte) + chThdSleepMilliseconds(30); + xprintf("1lock byte: %X\n", temp); + chThdSleepMilliseconds(30); + if (lock_status) { + temp |= 1<<(led_addr % 10 - 1); + } else { + temp &= ~1<<(led_addr % 10 - 1); + } + chThdSleepMilliseconds(30); + xprintf("2lock byte: %X\n", temp); + chThdSleepMilliseconds(30); + control_reg[1] = temp; + is31_write_data (page, control_reg, 0x02); } } void write_led_page (uint8_t page, const uint8_t *led_array, uint8_t led_count) { -//TODO: init function that accepts array of led addresses and sets them by row uint8_t i; uint8_t row, col; uint8_t temp_control_reg[0x13] = {0};//led control register start address + 0x12 bytes @@ -433,9 +468,8 @@ void led_controller_init(void) { is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, IS31_REG_BREATHCTRL2_ENABLE|3); // clean up the lock LEDs - //TODO: adjust for new addressing and additional frames - //is31_write_register(1, CAPS_LOCK_LED_ADDRESS, 0); - //is31_write_register(2, CAPS_LOCK_LED_ADDRESS, 0); + set_lock_leds(USB_LED_NUM_LOCK, 0); + set_lock_leds(USB_LED_CAPS_LOCK, 0); /* more time consuming LED processing should be offloaded into * a thread, with asynchronous messaging. */ diff --git a/keyboards/infinity60/led_controller.h b/keyboards/infinity60/led_controller.h index e9d897303b..7408620182 100644 --- a/keyboards/infinity60/led_controller.h +++ b/keyboards/infinity60/led_controller.h @@ -32,9 +32,9 @@ msg_t is31_read_register(uint8_t page, uint8_t reg, uint8_t *result); void led_controller_init(void); -#define CAPS_LOCK_LED_ADDRESS 0x46 -#define NUM_LOCK_LED_ADDRESS 0x85 -#define BACKLIGHT_OFF_LOCK_LED_OFF 1 //set to 0 to show lock leds even if backlight off +#define CAPS_LOCK_LED_ADDRESS 46 +#define NUM_LOCK_LED_ADDRESS 85 +#define BACKLIGHT_OFF_LOCK_LED_OFF 0 //set to 0 to show lock leds even if backlight off /* ============================= * IS31 chip related definitions @@ -93,7 +93,7 @@ void led_controller_init(void); extern mailbox_t led_mailbox; void set_led_bit (uint8_t *led_control_reg, uint8_t led_msg, uint8_t toggle_on); -void set_lock_leds (uint8_t *led_control_reg, uint8_t lock_status); +void set_lock_leds (uint8_t lock_type, uint8_t lock_status); void write_led_page (uint8_t page, const uint8_t *led_array, uint8_t led_count); // constants for signaling the LED controller thread @@ -103,7 +103,8 @@ enum led_msg_t { TOGGLE_ALL, TOGGLE_BACKLIGHT, TOGGLE_LAYER_LEDS, - TOGGLE_LOCK_LED, + TOGGLE_NUM_LOCK, + TOGGLE_CAPS_LOCK, MODE_BREATH, STEP_BRIGHTNESS }; From 1b1adf35bb746a875c2b846e1b1b405075c94847 Mon Sep 17 00:00:00 2001 From: jpetermans Date: Thu, 13 Apr 2017 17:15:24 -0700 Subject: [PATCH 07/24] more flexible led processing functions, all and on/off/toggle functioning --- .../infinity60/keymaps/jpetermans/keymap.c | 4 +- keyboards/infinity60/led.c | 14 +- keyboards/infinity60/led_controller.c | 147 +++++++++++------- keyboards/infinity60/led_controller.h | 10 +- 4 files changed, 97 insertions(+), 78 deletions(-) diff --git a/keyboards/infinity60/keymaps/jpetermans/keymap.c b/keyboards/infinity60/keymaps/jpetermans/keymap.c index 2eb66b506f..6f14b66cba 100644 --- a/keyboards/infinity60/keymaps/jpetermans/keymap.c +++ b/keyboards/infinity60/keymaps/jpetermans/keymap.c @@ -210,14 +210,14 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { case ACTION_LEDS_NAV: if(record->event.pressed) { // signal the LED controller thread - msg=(TOGGLE_LAYER_LEDS << 8) | 3; + msg=(OFF_LED << 8) | 12; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } break; case ACTION_LEDS_NUMPAD: if(record->event.pressed) { // signal the LED controller thread - msg=(TOGGLE_LAYER_LEDS << 8) | 4; + msg=(ON_LED << 8) | 12; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } break; diff --git a/keyboards/infinity60/led.c b/keyboards/infinity60/led.c index c78e2d1195..92069dc593 100644 --- a/keyboards/infinity60/led.c +++ b/keyboards/infinity60/led.c @@ -16,7 +16,6 @@ along with this program. If not, see . */ #include "hal.h" -#include "print.h" #include "led.h" @@ -28,16 +27,7 @@ along with this program. If not, see . */ void led_set(uint8_t usb_led) { msg_t msg; -/* - // PTA5: LED (1:on/0:off) - GPIOA->PDDR |= (1<<1); - PORTA->PCR[5] |= PORTx_PCRn_DSE | PORTx_PCRn_MUX(1); - if (usb_led & (1<PSOR |= (1<<5); - } else { - GPIOA->PCOR |= (1<<5); - } - */ + if (usb_led & (1< 0) {//check current led page to prevent double blink + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); + } + layer_status = 7; + break; + case ON_LED: + xprintf("ON_LED\n"); + set_led_bit(7, control_register_word, msg_led, 1); + is31_write_data (7, control_register_word, 0x02); + if (layer_status > 7) { + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); + } + layer_status = 7; + break; case TOGGLE_LED: - //TODO: toggle existing indicator off, or let user do this, but write frame 7 for every led change - //turn on single led, msg_led = row/col of led xprintf("TOGGLE_LED\n"); - set_led_bit(led_control_reg, msg_led, 1); + set_led_bit(7, control_register_word, msg_led, 2); - is31_write_data (7, led_control_reg, 0x12+1); - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); + is31_write_data (7, control_register_word, 0x02); + if (layer_status > 7) { + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); + } layer_status = 7; break; case TOGGLE_ALL: xprintf("TOGGLE_ALL\n"); //msg_led = unused, TODO: consider using msg_led to toggle layer display - is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); - //if LED_ALL is on then toggle off, any other layer, turn on LED_ALL - if(temp == 1) { - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0); + is31_read_register(0, 0x00, &temp);//if first byte is on, then toggle frame 1 off + + led_control_reg[0] = 0; + if (temp==0) { + xprintf("all leds on"); + __builtin_memcpy(led_control_reg+1, all_on_leds_mask, 0x12); } else { - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 1); + xprintf("all leds off"); + __builtin_memset(led_control_reg+1, 0, 0x12); } - is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); + + is31_write_data(0, led_control_reg, 0x13); + if (layer_status > 0) { + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0); + } + layer_status=0; + //TODO: Double blink when all on break; case TOGGLE_BACKLIGHT: //msg_led = unused //TODO: consider Frame 0 as on/off layer and toggle led control register here + //TODO: need to test tracking of active layer with layer_state from qmk xprintf("TOGGLE_BACKLIGHT\n"); backlight_status ^= 1; is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); @@ -274,6 +303,7 @@ layer_status = 0; case MODE_BREATH: break; case STEP_BRIGHTNESS: + //TEST: Step brightness code //pwm_levels[] bounds checking, loop through array //TODO: find a cleaner way to walk through this logic if (msg_led == 0 && led_step_status == 0) { @@ -336,30 +366,42 @@ layer_status = 0; } -/* ======================== - * led bit processing - * ======================== */ -void set_led_bit (uint8_t *led_control_reg, uint8_t msg_led, uint8_t toggle_on) { - uint8_t row_byte, column_bit; - //msg_led tens column is pin# - //ones column is bit position in 8-bit mask - //first byte is register address 0x00 - row_byte = ((msg_led / 10) % 10 - 1 ) * 2 + 1;// A register is every other 8 bits - column_bit = 1<<(msg_led % 10 - 1); - - if (toggle_on) { - led_control_reg[row_byte] |= 1<<(column_bit); - } else { - led_control_reg[row_byte] &= ~1<<(column_bit); +/* ============================== + * 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 mask to write + + uint8_t control_reg_addr, column_bit, column_byte, temp; + //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 + column_bit = 1<<(led_addr % 10 - 1); + + is31_read_register(page,control_reg_addr,&temp);//need to maintain status of leds in this row (1 byte) + column_byte = temp; + + switch(action) { + case 0: + column_byte &= ~1<<(column_bit); + break; + case 1: + column_byte |= 1<<(column_bit); + break; + case 2: + column_byte ^= 1<<(column_bit); + break; } + + led_control_reg[0] = control_reg_addr; + led_control_reg[1] = column_byte; } -//TODO: not toggling off correctly -//TODO: confirm led_off page still has FF pwm for all -void set_lock_leds(uint8_t lock_type, uint8_t lock_status) { - uint8_t page; - uint8_t led_addr, temp; - uint8_t control_reg[2] = {0};//register address and led bits +void set_lock_leds(uint8_t lock_type, uint8_t led_on) { + uint8_t page, led_addr; + uint8_t led_control_write[2] = {0}; + //TODO: consolidate control register to top level array vs. three scattered around switch(lock_type) { case USB_LED_NUM_LOCK: @@ -384,44 +426,30 @@ void set_lock_leds(uint8_t lock_type, uint8_t lock_status) { break; #endif } - xprintf("led_addr: %X\n", led_addr); - chThdSleepMilliseconds(30); - control_reg[0] = ((led_addr / 10) % 10 - 1 ) * 0x02;// A-register is every other byte - xprintf("control_reg: %X\n", control_reg[0]); - chThdSleepMilliseconds(30); for(page=BACKLIGHT_OFF_LOCK_LED_OFF; page<8; page++) { //set in led_controller.h - is31_read_register(page,control_reg[0],&temp);//need to maintain status of leds in this row (1 byte) - chThdSleepMilliseconds(30); - xprintf("1lock byte: %X\n", temp); - chThdSleepMilliseconds(30); - if (lock_status) { - temp |= 1<<(led_addr % 10 - 1); - } else { - temp &= ~1<<(led_addr % 10 - 1); - } - chThdSleepMilliseconds(30); - xprintf("2lock byte: %X\n", temp); - chThdSleepMilliseconds(30); - control_reg[1] = temp; - is31_write_data (page, control_reg, 0x02); + //TODO: check if frame2 (or frame1, first byte all on), and ignore if true + //also if BACKLIGHT_OFF_LOCK_LED_OFF set + set_led_bit(page,led_control_write,led_addr,led_on); + is31_write_data (page, led_control_write, 0x02); } } void write_led_page (uint8_t page, const uint8_t *led_array, uint8_t led_count) { uint8_t i; uint8_t row, col; - uint8_t temp_control_reg[0x13] = {0};//led control register start address + 0x12 bytes + uint8_t led_control_register[0x13] = {0};//led control register start address + 0x12 bytes for(i=0;i Date: Thu, 13 Apr 2017 17:51:37 -0700 Subject: [PATCH 08/24] fixed bit shift in led_set_bit --- keyboards/infinity60/led_controller.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c index eb3ccafc11..e98d8de505 100644 --- a/keyboards/infinity60/led_controller.c +++ b/keyboards/infinity60/led_controller.c @@ -376,26 +376,40 @@ void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint uint8_t control_reg_addr, column_bit, column_byte, temp; //first byte is led control register address 0x00 //msg_led tens column is pin#, ones column is bit position in 8-bit mask + chThdSleepMilliseconds(10); + xprintf("led_addr: %d ", led_addr); control_reg_addr = ((led_addr / 10) % 10 - 1 ) * 0x02;// A-register is every other byte column_bit = 1<<(led_addr % 10 - 1); is31_read_register(page,control_reg_addr,&temp);//need to maintain status of leds in this row (1 byte) + chThdSleepMilliseconds(10); + xprintf("col_bit: %X ", column_bit); column_byte = temp; + chThdSleepMilliseconds(10); + xprintf("action: %X ", action); switch(action) { case 0: - column_byte &= ~1<<(column_bit); + xprintf("off-"); + chThdSleepMilliseconds(10); + column_byte &= ~column_bit; break; case 1: - column_byte |= 1<<(column_bit); + xprintf("on-"); + chThdSleepMilliseconds(10); + column_byte |= column_bit; break; case 2: - column_byte ^= 1<<(column_bit); + xprintf("toggle-"); + chThdSleepMilliseconds(10); + column_byte ^= column_bit; break; } led_control_reg[0] = control_reg_addr; led_control_reg[1] = column_byte; + chThdSleepMilliseconds(10); + xprintf("set_bit row: %X set_bit col: %X\n", led_control_reg[0], led_control_reg[1]); } void set_lock_leds(uint8_t lock_type, uint8_t led_on) { @@ -427,11 +441,13 @@ void set_lock_leds(uint8_t lock_type, uint8_t led_on) { #endif } - for(page=BACKLIGHT_OFF_LOCK_LED_OFF; page<8; page++) { //set in led_controller.h + for(page=0; page<8; page++) { //set in led_controller.h //TODO: check if frame2 (or frame1, first byte all on), and ignore if true //also if BACKLIGHT_OFF_LOCK_LED_OFF set set_led_bit(page,led_control_write,led_addr,led_on); - is31_write_data (page, led_control_write, 0x02); + xprintf("lock_led row: %X lock_led col%X\n", led_control_write[0], led_control_write[1]); + is31_write_data(page, led_control_write, 0x02); + chThdSleepMilliseconds(10); } } From c0ec1756afda7a49848faff23781bf54cd9fa3c3 Mon Sep 17 00:00:00 2001 From: jpetermans Date: Fri, 14 Apr 2017 18:20:12 -0700 Subject: [PATCH 09/24] Added backlight step functionality --- keyboards/infinity60/led_controller.c | 322 +++++++++++++------------- keyboards/infinity60/led_controller.h | 2 +- 2 files changed, 160 insertions(+), 164 deletions(-) diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c index e98d8de505..cb91f9f351 100644 --- a/keyboards/infinity60/led_controller.c +++ b/keyboards/infinity60/led_controller.c @@ -170,12 +170,12 @@ static THD_FUNCTION(LEDthread, arg) { (void)arg; chRegSetThreadName("LEDthread"); - uint8_t i, page; - uint8_t control_register_word[2] = {0}; + uint8_t i, j, page; + uint8_t control_register_word[2] = {0};//register address - byte to write uint8_t led_control_reg[0x13] = {0};//led control register start address + 0x12 bytes //persistent status variables - uint8_t backlight_status, led_step_status, layer_status; + uint8_t backlight_status, pwm_step_status, layer_status; //mailbox variables uint8_t temp, msg_type, msg_led; @@ -187,9 +187,9 @@ static THD_FUNCTION(LEDthread, arg) { */ // initialize persistent variables -backlight_status = 0; -led_step_status = 4; //full brightness -layer_status = 0; +backlight_status = 0; //start backlight off +pwm_step_status = 4; //full brightness +layer_status = 0; //start frame 0 (all off/on) while(true) { // wait for a message (asynchronous) @@ -202,170 +202,172 @@ layer_status = 0; xprintf("--------------------\n"); xprintf("mailbox fetch\nmsg: %X\n", msg); xprintf("type: %X - led: %X\n", msg_type, msg_led); //test if msg_type is 1 or 2 bytes after mask - switch (msg_type){ - case KEY_LIGHT: - //TODO: lighting key led on keypress - break; - - //turn on/off/toggle single led, msg_led = row/col of led - case OFF_LED: - xprintf("OFF_LED\n"); - set_led_bit(7, control_register_word, msg_led, 0); - is31_write_data (7, control_register_word, 0x02); - if (layer_status > 0) {//check current led page to prevent double blink - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); - } - layer_status = 7; - break; - case ON_LED: - xprintf("ON_LED\n"); - set_led_bit(7, control_register_word, msg_led, 1); - is31_write_data (7, control_register_word, 0x02); - if (layer_status > 7) { - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); - } - layer_status = 7; - break; - case TOGGLE_LED: - xprintf("TOGGLE_LED\n"); - set_led_bit(7, control_register_word, msg_led, 2); - is31_write_data (7, control_register_word, 0x02); - if (layer_status > 7) { - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); - } - layer_status = 7; + switch (msg_type){ + case KEY_LIGHT: + //TODO: lighting key led on keypress break; + + //turn on/off/toggle single led, msg_led = row/col of led + case OFF_LED: + xprintf("OFF_LED\n"); + set_led_bit(7, control_register_word, msg_led, 0); + is31_write_data (7, control_register_word, 0x02); + if (layer_status > 0) {//check current led page to prevent double blink + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); + } + layer_status = 7; + break; + case ON_LED: + xprintf("ON_LED\n"); + set_led_bit(7, control_register_word, msg_led, 1); + is31_write_data (7, control_register_word, 0x02); + if (layer_status > 7) { + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); + } + layer_status = 7; + break; + case TOGGLE_LED: + xprintf("TOGGLE_LED\n"); + set_led_bit(7, control_register_word, msg_led, 2); - case TOGGLE_ALL: - xprintf("TOGGLE_ALL\n"); - //msg_led = unused, TODO: consider using msg_led to toggle layer display + is31_write_data (7, control_register_word, 0x02); + if (layer_status > 7) { + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); + } + layer_status = 7; + break; - is31_read_register(0, 0x00, &temp);//if first byte is on, then toggle frame 1 off + case TOGGLE_ALL: + xprintf("TOGGLE_ALL\n"); + //msg_led = unused - led_control_reg[0] = 0; - if (temp==0) { - xprintf("all leds on"); - __builtin_memcpy(led_control_reg+1, all_on_leds_mask, 0x12); - } else { - xprintf("all leds off"); - __builtin_memset(led_control_reg+1, 0, 0x12); - } + is31_read_register(0, 0x00, &temp);//if first byte is on, then toggle frame 1 off - is31_write_data(0, led_control_reg, 0x13); - if (layer_status > 0) { - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0); - } - layer_status=0; - //TODO: Double blink when all on - break; + led_control_reg[0] = 0; + if (temp==0) { + xprintf("all leds on"); + __builtin_memcpy(led_control_reg+1, all_on_leds_mask, 0x12); + } else { + xprintf("all leds off"); + __builtin_memset(led_control_reg+1, 0, 0x12); + } - case TOGGLE_BACKLIGHT: - //msg_led = unused - //TODO: consider Frame 0 as on/off layer and toggle led control register here - //TODO: need to test tracking of active layer with layer_state from qmk - xprintf("TOGGLE_BACKLIGHT\n"); - backlight_status ^= 1; - is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); - layer_status = temp; - - page = backlight_status == 0 ? 0 : layer_status; - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, page); - break; + is31_write_data(0, led_control_reg, 0x13); + if (layer_status > 0) { + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0); + } + layer_status=0; + break; - case TOGGLE_LAYER_LEDS://show layer indicator or full map of layer keys. - //TODO: change so user can flag which they want, indiv or full map in fn_actions - //msg_led = layer to toggle on - xprintf("TOGGLE_LAYER_LEDS\n"); - is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); + case TOGGLE_BACKLIGHT: + //msg_led = unused + //TODO: need to test tracking of active layer with layer_state from qmk + xprintf("TOGGLE_BACKLIGHT\n"); + backlight_status ^= 1; + is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); + layer_status = temp; - if(temp == msg_led) { - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); - layer_status = 7; - } else { - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, msg_led); - layer_status = msg_led; - } - break; - - case TOGGLE_NUM_LOCK: - //msg_led = 0 or 1, off/on - //TODO: confirm toggling works and doesn't get out of sync - set_lock_leds(USB_LED_NUM_LOCK, msg_led); - break; - - case TOGGLE_CAPS_LOCK: - //msg_led = 0 or 1, off/on - //TODO: confirm toggling works and doesn't get out of sync - set_lock_leds(USB_LED_CAPS_LOCK, msg_led); - break; + page = backlight_status == 0 ? 0 : layer_status; + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, page); + break; - case MODE_BREATH: - break; - case STEP_BRIGHTNESS: - //TEST: Step brightness code - //pwm_levels[] bounds checking, loop through array - //TODO: find a cleaner way to walk through this logic - if (msg_led == 0 && led_step_status == 0) { - led_step_status = 4; - } else { - led_step_status--; - } + case TOGGLE_PAGE_LEDS://show single layer indicator or full map of layer + //msg_led = page to toggle on + xprintf("TOGGLE_LAYER_LEDS\n"); + is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); + + if(temp == msg_led) { + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); + layer_status = 7; + } else { + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, msg_led); + layer_status = msg_led; + } + break; + + case TOGGLE_NUM_LOCK: + //msg_led = 0 or 1, off/on + set_lock_leds(USB_LED_NUM_LOCK, msg_led); + break; - if (msg_led == 1 && led_step_status == 4) { - led_step_status = 0; - } else { - led_step_status++; - } + case TOGGLE_CAPS_LOCK: + //msg_led = 0 or 1, off/on + set_lock_leds(USB_LED_CAPS_LOCK, msg_led); + break; - //TODO: this seems a messy way to populate the pwm register - //mimic whitefox init which uses memcpy - //populate the 9 byte rows to be written to each pin, first byte is register (pin) address - for(i=1; i<9; i++) { - pwm_register_array[i]=pwm_levels[led_step_status]; - } - 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);//first page controls pwm in all pages (init Display Option register) + case MODE_BREATH: + break; + case STEP_BRIGHTNESS: + xprintf("TOGGLE_BACKLIGHT\n"); + //led_msg = step pwm up or down + //TODO: test step brightness code + //pwm_levels[] bounds checking, loop through array + 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; } - 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)); + //populate the 9 byte rows to be written to each pin, first byte is register (pin) address + __builtin_memset(pwm_register_array+1, pwm_levels[pwm_step_status], 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); + for(j=0; j<9; j++) { + } + is31_write_data(0,pwm_register_array,9); } - // 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; - break; -*/ + 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; + break; +*/ + xprintf("--------------------\n"); } - xprintf("--------------------\n"); } } - /* ============================== * led processing functions * ============================== */ @@ -451,14 +453,14 @@ void set_lock_leds(uint8_t lock_type, uint8_t led_on) { } } -void write_led_page (uint8_t page, const uint8_t *led_array, uint8_t led_count) { +void write_led_page (uint8_t page, const uint8_t *user_led_array, uint8_t led_count) { uint8_t i; uint8_t row, col; uint8_t led_control_register[0x13] = {0};//led control register start address + 0x12 bytes for(i=0;i Date: Sat, 15 Apr 2017 14:37:55 -0700 Subject: [PATCH 10/24] more stable lock led process, added debugging code --- keyboards/infinity60/led_controller.c | 117 +++++++++++++++----------- 1 file changed, 70 insertions(+), 47 deletions(-) diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c index cb91f9f351..d88ae14b15 100644 --- a/keyboards/infinity60/led_controller.c +++ b/keyboards/infinity60/led_controller.c @@ -70,6 +70,8 @@ along with this program. If not, see . #define BREATHE_LED_ADDRESS CAPS_LOCK_LED_ADDRESS #endif +#define DEBUG_ENABLED 1 + /* ================= * ChibiOS I2C setup * ================= */ @@ -171,11 +173,11 @@ static THD_FUNCTION(LEDthread, arg) { chRegSetThreadName("LEDthread"); uint8_t i, j, page; - uint8_t control_register_word[2] = {0};//register address - byte to write + 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 backlight_status, pwm_step_status, layer_status; + uint8_t backlight_status, pwm_step_status, page_status; //mailbox variables uint8_t temp, msg_type, msg_led; @@ -189,7 +191,7 @@ static THD_FUNCTION(LEDthread, arg) { // initialize persistent variables backlight_status = 0; //start backlight off pwm_step_status = 4; //full brightness -layer_status = 0; //start frame 0 (all off/on) +page_status = 0; //start frame 0 (all off/on) while(true) { // wait for a message (asynchronous) @@ -201,74 +203,89 @@ layer_status = 0; //start frame 0 (all off/on) xprintf("--------------------\n"); xprintf("mailbox fetch\nmsg: %X\n", msg); - xprintf("type: %X - led: %X\n", msg_type, msg_led); //test if msg_type is 1 or 2 bytes after mask + xprintf("type: %X - led: %X\n", msg_type, msg_led); switch (msg_type){ case KEY_LIGHT: //TODO: lighting key led on keypress break; - //turn on/off/toggle single led, msg_led = row/col of led case OFF_LED: + //on/off/toggle single led, msg_led = row/col of led xprintf("OFF_LED\n"); set_led_bit(7, control_register_word, msg_led, 0); is31_write_data (7, control_register_word, 0x02); - if (layer_status > 0) {//check current led page to prevent double blink + + if (page_status < 7) { is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); } - layer_status = 7; + page_status = 7; break; + case ON_LED: xprintf("ON_LED\n"); set_led_bit(7, control_register_word, msg_led, 1); is31_write_data (7, control_register_word, 0x02); - if (layer_status > 7) { + + if (page_status < 7) {//check current led page to prevent double blink is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); } - layer_status = 7; + page_status = 7; break; + case TOGGLE_LED: xprintf("TOGGLE_LED\n"); set_led_bit(7, control_register_word, msg_led, 2); is31_write_data (7, control_register_word, 0x02); - if (layer_status > 7) { + if (page_status > 7) { is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); } - layer_status = 7; + page_status = 7; break; case TOGGLE_ALL: xprintf("TOGGLE_ALL\n"); //msg_led = unused - is31_read_register(0, 0x00, &temp);//if first byte is on, then toggle frame 1 off + is31_read_register(0, 0x00, &temp);//if first byte is on, then toggle frame 0 off led_control_reg[0] = 0; - if (temp==0) { - xprintf("all leds on"); + if (temp==0 || page_status > 0) { + xprintf("all leds on"); __builtin_memcpy(led_control_reg+1, all_on_leds_mask, 0x12); } else { - xprintf("all leds off"); + xprintf("all leds off"); __builtin_memset(led_control_reg+1, 0, 0x12); } is31_write_data(0, led_control_reg, 0x13); - if (layer_status > 0) { + if (page_status > 0) { is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0); } - layer_status=0; + + //maintain lock leds + if (host_keyboard_leds() & (1<0 || BACKLIGHT_OFF_LOCK_LED_OFF) ? 1 : 0; + + for(page=start; page<8; page++) { set_led_bit(page,led_control_write,led_addr,led_on); - xprintf("lock_led row: %X lock_led col%X\n", led_control_write[0], led_control_write[1]); is31_write_data(page, led_control_write, 0x02); - chThdSleepMilliseconds(10); } } @@ -458,8 +479,10 @@ void write_led_page (uint8_t page, const uint8_t *user_led_array, uint8_t led_co uint8_t row, col; uint8_t led_control_register[0x13] = {0};//led control register start address + 0x12 bytes + __builtin_memset(led_control_register,0,13); + for(i=0;i Date: Wed, 26 Apr 2017 23:12:25 -0700 Subject: [PATCH 11/24] Simplified processing in led_controller; more control at user level. --- keyboards/infinity60/led_controller.c | 214 +++++++++++++++----------- keyboards/infinity60/led_controller.h | 5 +- 2 files changed, 123 insertions(+), 96 deletions(-) diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c index d88ae14b15..4dc9b92342 100644 --- a/keyboards/infinity60/led_controller.c +++ b/keyboards/infinity60/led_controller.c @@ -25,6 +25,8 @@ along with this program. If not, see . #include "hal.h" #include "print.h" #include "led.h" +#include "action_layer.h" +#include "host.h" #include "led_controller.h" @@ -70,7 +72,7 @@ along with this program. If not, see . #define BREATHE_LED_ADDRESS CAPS_LOCK_LED_ADDRESS #endif -#define DEBUG_ENABLED 1 +#define DEBUG_ENABLED 0 /* ================= * ChibiOS I2C setup @@ -172,12 +174,12 @@ static THD_FUNCTION(LEDthread, arg) { (void)arg; chRegSetThreadName("LEDthread"); - uint8_t i, j, page; + 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 backlight_status, pwm_step_status, page_status; + uint8_t pwm_step_status, page_status; //mailbox variables uint8_t temp, msg_type, msg_led; @@ -189,7 +191,6 @@ static THD_FUNCTION(LEDthread, arg) { */ // initialize persistent variables -backlight_status = 0; //start backlight off pwm_step_status = 4; //full brightness page_status = 0; //start frame 0 (all off/on) @@ -202,68 +203,63 @@ page_status = 0; //start frame 0 (all off/on) msg_led = (msg) & 0xFF; //second byte is action information xprintf("--------------------\n"); + chThdSleepMilliseconds(10); xprintf("mailbox fetch\nmsg: %X\n", msg); + chThdSleepMilliseconds(10); xprintf("type: %X - led: %X\n", msg_type, msg_led); + chThdSleepMilliseconds(10); switch (msg_type){ case KEY_LIGHT: //TODO: lighting key led on keypress break; + //TODO: custom page that is written using keypresses + //TODO: BLINK_ON/OFF_LED + case OFF_LED: //on/off/toggle single led, msg_led = row/col of led xprintf("OFF_LED\n"); + chThdSleepMilliseconds(10); set_led_bit(7, control_register_word, msg_led, 0); is31_write_data (7, control_register_word, 0x02); - - if (page_status < 7) { - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); - } - page_status = 7; break; case ON_LED: xprintf("ON_LED\n"); + chThdSleepMilliseconds(10); set_led_bit(7, control_register_word, msg_led, 1); is31_write_data (7, control_register_word, 0x02); - - if (page_status < 7) {//check current led page to prevent double blink - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); - } - page_status = 7; break; case TOGGLE_LED: xprintf("TOGGLE_LED\n"); + chThdSleepMilliseconds(10); set_led_bit(7, control_register_word, msg_led, 2); - is31_write_data (7, control_register_word, 0x02); - if (page_status > 7) { - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); - } - page_status = 7; break; case TOGGLE_ALL: xprintf("TOGGLE_ALL\n"); + chThdSleepMilliseconds(10); //msg_led = unused - is31_read_register(0, 0x00, &temp);//if first byte is on, then toggle frame 0 off - led_control_reg[0] = 0; if (temp==0 || page_status > 0) { xprintf("all leds on"); + chThdSleepMilliseconds(10); __builtin_memcpy(led_control_reg+1, all_on_leds_mask, 0x12); } else { xprintf("all leds off"); + chThdSleepMilliseconds(10); __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); } - + //maintain lock leds if (host_keyboard_leds() & (1< 90 || led_addr % 10 > 8) { + xprintf("Invalid address: %d\n", led_addr); + return; + } + //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 column_bit = 1<<(led_addr % 10 - 1); - is31_read_register(page,control_reg_addr,&temp);//need to maintain status of leds in this row (1 byte) + is31_read_register(page, control_reg_addr, &temp);//maintain status of leds on this byte column_byte = temp; switch(action) { @@ -437,9 +460,11 @@ void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint void set_lock_leds(uint8_t lock_type, uint8_t led_on) { uint8_t page, led_addr, start, temp; - uint8_t led_control_write[2] = {0}; - //TODO: consolidate control register to top level array vs. three scattered around + uint8_t led_control_word[2] = {0}; + //TODO: this function call could send led address vs lock_type. + //however, the switch/case allows for additional steps, like audio, depending on type + led_addr = 0; switch(lock_type) { case USB_LED_NUM_LOCK: led_addr = NUM_LOCK_LED_ADDRESS; @@ -465,16 +490,18 @@ void set_lock_leds(uint8_t lock_type, uint8_t led_on) { } //ignore frame0 if all leds are on or if option set in led_controller.h + //TODO: blink of all leds are on, clear blink register if not is31_read_register(0, 0x00, &temp); - start = (temp>0 || BACKLIGHT_OFF_LOCK_LED_OFF) ? 1 : 0; + led_addr += temp == 0 ? 0 : 0x12;//send bit to blink register instead + start = BACKLIGHT_OFF_LOCK_LED_OFF ? 1 : 0; for(page=start; page<8; page++) { - set_led_bit(page,led_control_write,led_addr,led_on); - is31_write_data(page, led_control_write, 0x02); + set_led_bit(page,led_control_word,led_addr,led_on); + is31_write_data(page, led_control_word, 0x02); } } -void write_led_page (uint8_t page, const uint8_t *user_led_array, uint8_t led_count) { +void write_led_page (uint8_t page, uint8_t *user_led_array, uint8_t led_count) { uint8_t i; uint8_t row, col; uint8_t led_control_register[0x13] = {0};//led control register start address + 0x12 bytes @@ -516,7 +543,6 @@ void led_controller_init(void) { //set Display Option Register so all pwm intensity is controlled from Frame 0 is31_write_register(IS31_FUNCTIONREG, IS31_REG_DISPLAYOPT, IS31_REG_DISPLAYOPT_INTENSITY_SAME); - //TODO: test new init pwm loop /* set full pwm on Frame 1 */ pwm_register_array[0] = 0; __builtin_memset(pwm_register_array+1, 0xFF, 8); diff --git a/keyboards/infinity60/led_controller.h b/keyboards/infinity60/led_controller.h index 1511004714..b06113b077 100644 --- a/keyboards/infinity60/led_controller.h +++ b/keyboards/infinity60/led_controller.h @@ -94,7 +94,7 @@ 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 lock_type, uint8_t led_on); -void write_led_page (uint8_t page, const uint8_t *led_array, uint8_t led_count); +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 { @@ -104,7 +104,8 @@ enum led_msg_t { TOGGLE_LED, TOGGLE_ALL, TOGGLE_BACKLIGHT, - TOGGLE_PAGE_LEDS, + DISPLAY_PAGE, + RESET_PAGE, TOGGLE_NUM_LOCK, TOGGLE_CAPS_LOCK, MODE_BREATH, From ff6beeb7a313953c589defb6af1f9ae461cba03a Mon Sep 17 00:00:00 2001 From: jpetermans Date: Sat, 29 Apr 2017 09:22:40 -0700 Subject: [PATCH 12/24] simplified lock led function --- keyboards/infinity60/led_controller.c | 57 ++++++++------------------- keyboards/infinity60/led_controller.h | 2 +- 2 files changed, 17 insertions(+), 42 deletions(-) diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c index 4dc9b92342..707b4e0df6 100644 --- a/keyboards/infinity60/led_controller.c +++ b/keyboards/infinity60/led_controller.c @@ -262,10 +262,10 @@ page_status = 0; //start frame 0 (all off/on) //maintain lock leds if (host_keyboard_leds() & (1< Date: Sun, 30 Apr 2017 16:27:46 -0700 Subject: [PATCH 13/24] Testing initial blink support --- keyboards/infinity60/led_controller.c | 254 ++++++++++++++++++-------- keyboards/infinity60/led_controller.h | 7 +- 2 files changed, 180 insertions(+), 81 deletions(-) diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c index 4dc9b92342..59ca833b65 100644 --- a/keyboards/infinity60/led_controller.c +++ b/keyboards/infinity60/led_controller.c @@ -72,7 +72,7 @@ along with this program. If not, see . #define BREATHE_LED_ADDRESS CAPS_LOCK_LED_ADDRESS #endif -#define DEBUG_ENABLED 0 +#define DEBUG_ENABLED 1 /* ================= * ChibiOS I2C setup @@ -214,44 +214,58 @@ page_status = 0; //start frame 0 (all off/on) //TODO: lighting key led on keypress break; - //TODO: custom page that is written using keypresses //TODO: BLINK_ON/OFF_LED + break; case OFF_LED: //on/off/toggle single led, msg_led = row/col of led - xprintf("OFF_LED\n"); + xprintf("OFF_LED: %d\n", msg_led); chThdSleepMilliseconds(10); set_led_bit(7, control_register_word, msg_led, 0); is31_write_data (7, control_register_word, 0x02); break; - case ON_LED: - xprintf("ON_LED\n"); + xprintf("ON_LED: %d\n", msg_led); chThdSleepMilliseconds(10); set_led_bit(7, control_register_word, msg_led, 1); is31_write_data (7, control_register_word, 0x02); break; - case TOGGLE_LED: - xprintf("TOGGLE_LED\n"); + xprintf("TOGGLE_LED: %d\n", msg_led); chThdSleepMilliseconds(10); 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 + xprintf("BLINK_ON: %d\n", msg_led); + chThdSleepMilliseconds(10); + set_led_bit(7, control_register_word, msg_led, 4); + is31_write_data (7, control_register_word, 0x02); + break; + case BLINK_ON_LED: + xprintf("BLINK_OFF: %d\n", msg_led); + chThdSleepMilliseconds(10); + set_led_bit(7, control_register_word, msg_led, 5); + is31_write_data (7, control_register_word, 0x02); + break; + case BLINK_TOGGLE_LED: + xprintf("BLINK_TOGGLE: %d\n", msg_led); + chThdSleepMilliseconds(10); + set_led_bit(7, control_register_word, msg_led, 6); + is31_write_data (7, control_register_word, 0x02); + case TOGGLE_ALL: - xprintf("TOGGLE_ALL\n"); + xprintf("TOGGLE_ALL: %d\n", msg_led); chThdSleepMilliseconds(10); //msg_led = unused is31_read_register(0, 0x00, &temp);//if first byte is on, then toggle frame 0 off led_control_reg[0] = 0; + if (temp==0 || page_status > 0) { - xprintf("all leds on"); - chThdSleepMilliseconds(10); __builtin_memcpy(led_control_reg+1, all_on_leds_mask, 0x12); } else { - xprintf("all leds off"); - chThdSleepMilliseconds(10); __builtin_memset(led_control_reg+1, 0, 0x12); } is31_write_data(0, led_control_reg, 0x13); @@ -292,15 +306,19 @@ page_status = 0; //start frame 0 (all off/on) case DISPLAY_PAGE://show single layer indicator or full map of layer //msg_led = page to toggle on - xprintf("DISPLAY_PAGE\n"); + xprintf("DISPLAY_PAGE"); chThdSleepMilliseconds(10); if (page_status != msg_led) { + xprintf(" - new page\n"); + chThdSleepMilliseconds(10); is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, msg_led); } page_status = msg_led; break; case RESET_PAGE: + xprintf("RESET_PAGE\n"); + chThdSleepMilliseconds(10); //led_msg = page to reset led_control_reg[0] = 0; __builtin_memset(led_control_reg+1, 0, 0x12); @@ -317,19 +335,23 @@ page_status = 0; //start frame 0 (all off/on) case TOGGLE_NUM_LOCK: //msg_led = 0 or 1, off/on - set_lock_leds(USB_LED_NUM_LOCK, msg_led); + xprintf("NUMLOCK: %d\n", msg_led); + chThdSleepMilliseconds(10); + set_lock_leds(NUM_LOCK_LED_ADDRESS, msg_led); break; case TOGGLE_CAPS_LOCK: + xprintf("CAPSLOCK: %d\n", msg_led); + chThdSleepMilliseconds(10); //msg_led = 0 or 1, off/on - set_lock_leds(USB_LED_CAPS_LOCK, msg_led); + set_lock_leds(CAPS_LOCK_LED_ADDRESS, msg_led); break; //TODO: MODE_BREATH case MODE_BREATH: break; case STEP_BRIGHTNESS: - xprintf("TOGGLE_BACKLIGHT\n"); + xprintf("STEP_BACKLIGHT\n"); chThdSleepMilliseconds(10); //led_msg = step pwm up or down switch (msg_led) { @@ -394,27 +416,101 @@ page_status = 0; //start frame 0 (all off/on) chThdSleepMilliseconds(10); } #if DEBUG_ENABLED - uint8_t j, page; + uint8_t j; + uint8_t pages[3]={0x00, 0x07}; //debugging code - print full led/blink/pwm registers on each frame xprintf("----layer state----: %X\n", layer_state); - for(i=0;i<8;i++) { - xprintf("page: %d", i); - chThdSleepMilliseconds(2); - for(j=0;j<0xB4;j++){ - is31_read_register(i,j,&temp); + for(i=0;i<2;i++) { + xprintf("page: %d\n", pages[i]); chThdSleepMilliseconds(2); - xprintf("%02X, ", temp); - if(j % 9 == 0){ + for(j=0;j<0x24;j++){ + if(j > 0 && j % 9 == 0){ xprintf("\n"); - if(j % 18 ==0){ - xprintf("register"); - xprintf("\n"); - } + } + switch (j) { + case 0: + xprintf("\n--on-off--\n"); + chThdSleepMilliseconds(2); + break; + case 0x12: + xprintf("\n--blink--\n"); + chThdSleepMilliseconds(2); + break; } - chThdSleepMilliseconds(1); + is31_read_register(pages[i],j,&temp); + xprintf("%02X, ", temp); + chThdSleepMilliseconds(2); } + + xprintf("\n--pwm--\n"); + chThdSleepMilliseconds(2); + for(j=0x24;j<0xB4;j++) { + is31_read_register(pages[i],j,&temp); + xprintf("%02X, ", temp); + chThdSleepMilliseconds(2); + if(j > 0x24 && (j-4) % 8 == 0){ xprintf("\n"); + } + } + xprintf("\n"); + } + + //Function Register + xprintf("\n--FUNCTION--\n"); + chThdSleepMilliseconds(2); + for(j=0;j<0x0D;j++) { + is31_read_register(0x0B,j,&temp); + switch(j) { + case 0: + xprintf("Config %02X", temp); + chThdSleepMilliseconds(2); + break; + case 1: + xprintf(" - Pict %02X\n", temp); + chThdSleepMilliseconds(2); + break; + case 2: + xprintf("Auto1 %02X", temp); + chThdSleepMilliseconds(2); + break; + case 3: + xprintf(" - Auto2 %02X\n", temp); + chThdSleepMilliseconds(2); + break; + case 5: + xprintf("Disp %02X", temp); + chThdSleepMilliseconds(2); + break; + case 6: + xprintf(" - Audio %02X\n", temp); + chThdSleepMilliseconds(2); + break; + case 7: + xprintf("Frame %02X", temp); + chThdSleepMilliseconds(2); + break; + case 8: + xprintf(" - Breath1 %02X\n", temp); + chThdSleepMilliseconds(2); + break; + case 9: + xprintf("Breath2 %02X - ", temp); + chThdSleepMilliseconds(2); + break; + case 10: + xprintf(" - Shut %02X\n", temp); + chThdSleepMilliseconds(2); + break; + case 11: + xprintf("AGC %02X", temp); + chThdSleepMilliseconds(2); + break; + case 12: + xprintf(" - ADC %02X\n", temp); + chThdSleepMilliseconds(2); + break; } + } #endif } } @@ -425,22 +521,39 @@ page_status = 0; //start frame 0 (all off/on) 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, temp, blink_on; - uint8_t control_reg_addr, column_bit, column_byte, temp; //check for valid led address - if (led_addr < 0 || led_addr > 90 || led_addr % 10 > 8) { + if (led_addr < 0 || led_addr > 87 || led_addr % 10 > 8) { xprintf("Invalid address: %d\n", led_addr); return; } + xprintf("set_led_bit: %d\n", led_addr); + xprintf("action: %d\n", action); + chThdSleepMilliseconds(10); + //check 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 + xprintf("pre-reg_addr: %X\n", control_reg_addr); + chThdSleepMilliseconds(10); + control_reg_addr += blink_on == 1 ? 0x12 : 0x00;//shift 12 bytes to blink register + xprintf("blink-reg_addr: %X\n", control_reg_addr); + chThdSleepMilliseconds(10); + column_bit = 1<<(led_addr % 10 - 1); is31_read_register(page, control_reg_addr, &temp);//maintain status of leds on this byte column_byte = temp; + xprintf("column_byte read: %X\n", column_byte); + chThdSleepMilliseconds(10); switch(action) { case 0: column_byte &= ~column_bit; @@ -452,72 +565,58 @@ void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint column_byte ^= column_bit; break; } + xprintf("column_byte write: %X\n", column_byte); + chThdSleepMilliseconds(10); //return word to be written in register led_control_reg[0] = control_reg_addr; led_control_reg[1] = column_byte; } -void set_lock_leds(uint8_t lock_type, uint8_t led_on) { - uint8_t page, led_addr, start, temp; - uint8_t led_control_word[2] = {0}; - //TODO: this function call could send led address vs lock_type. - //however, the switch/case allows for additional steps, like audio, depending on type +void write_led_byte (uint8_t page, uint8_t row, uint8_t led_byte) { + uint8_t led_control_word[2] = {0};//register address and led on/off mask - led_addr = 0; - switch(lock_type) { - case USB_LED_NUM_LOCK: - led_addr = NUM_LOCK_LED_ADDRESS; - break; - case USB_LED_CAPS_LOCK: - led_addr = CAPS_LOCK_LED_ADDRESS; - break; - #ifdef SCROLL_LOCK_LED_ADDRESS - case USB_LED_SCROLL_LOCK: - led_addr = SCROLL_LOCK_LED_ADDRESS; - break; - #endif - #ifdef COMPOSE_LED_ADDRESS - case USB_LED_COMPOSE: - led_addr = COMPOSE_LED_ADDRESS; - break; - #endif - #ifdef SCROLL_LOCK_LED_ADDRESS - case USB_LED_KANA: - led_addr = KANA_LED_ADDRESS; - break; - #endif - } - - //ignore frame0 if all leds are on or if option set in led_controller.h - //TODO: blink of all leds are on, clear blink register if not - is31_read_register(0, 0x00, &temp); - led_addr += temp == 0 ? 0 : 0x12;//send bit to blink register instead - start = BACKLIGHT_OFF_LOCK_LED_OFF ? 1 : 0; - - for(page=start; page<8; page++) { - set_led_bit(page,led_control_word,led_addr,led_on); - is31_write_data(page, led_control_word, 0x02); - } + led_control_word[0] = (row - 1 ) * 0x02;// A-register is every other byte + led_control_word[1] = led_byte;// A-register is every other byte + is31_write_data(page, led_control_word, 0x13); } void write_led_page (uint8_t page, uint8_t *user_led_array, uint8_t led_count) { uint8_t i; - uint8_t row, col; + uint8_t pin, col; uint8_t led_control_register[0x13] = {0};//led control register start address + 0x12 bytes __builtin_memset(led_control_register,0,13); for(i=0;i Date: Mon, 8 May 2017 11:57:40 -0700 Subject: [PATCH 14/24] small code cleanup --- keyboards/infinity60/MEMO.txt | 385 -------------------------- keyboards/infinity60/led_controller.c | 385 ++++++++++++++------------ keyboards/infinity60/led_controller.h | 16 +- 3 files changed, 210 insertions(+), 576 deletions(-) delete mode 100644 keyboards/infinity60/MEMO.txt diff --git a/keyboards/infinity60/MEMO.txt b/keyboards/infinity60/MEMO.txt deleted file mode 100644 index e2886aa002..0000000000 --- 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 --------- - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = KINETIS - MCU_SERIES = KL2x - - # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ - # or /ld/ - MCU_LDSCRIPT = MKL26Z64 - - # - it should exist in /os/common/ports/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP = kl2x - - # Board: it should exist either in /os/hal/boards/ - # or /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/led_controller.c b/keyboards/infinity60/led_controller.c index 59ca833b65..c162e9a8f0 100644 --- a/keyboards/infinity60/led_controller.c +++ b/keyboards/infinity60/led_controller.c @@ -72,8 +72,6 @@ along with this program. If not, see . #define BREATHE_LED_ADDRESS CAPS_LOCK_LED_ADDRESS #endif -#define DEBUG_ENABLED 1 - /* ================= * ChibiOS I2C setup * ================= */ @@ -145,7 +143,6 @@ 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); @@ -182,7 +179,7 @@ static THD_FUNCTION(LEDthread, arg) { uint8_t pwm_step_status, page_status; //mailbox variables - uint8_t temp, msg_type, msg_led; + uint8_t temp, msg_type, msg_pin, msg_col, msg_led; msg_t msg; /* //control register variables @@ -199,14 +196,17 @@ page_status = 0; //start frame 0 (all off/on) // (messages are queued (up to LED_MAILBOX_NUM_MSGS) if they can't // be processed right away) chMBFetch(&led_mailbox, &msg, TIME_INFINITE); - msg_type = (msg >> 8) & 0xFF; //first byte is msg type - msg_led = (msg) & 0xFF; //second byte is action information + msg_col = (msg >> 24) & 0xFF;//if needed + msg_pin = (msg >> 16) & 0XFF;//if needed (SET_FULL_ROW) + msg_type = (msg >> 8) & 0xFF; //second byte is msg type + msg_led = (msg) & 0xFF; //first byte is action information xprintf("--------------------\n"); - chThdSleepMilliseconds(10); xprintf("mailbox fetch\nmsg: %X\n", msg); - chThdSleepMilliseconds(10); - xprintf("type: %X - led: %X\n", msg_type, msg_led); + chThdSleepMilliseconds(20); + xprintf("type: %X - pin: %X\n", msg_type, msg_pin); + chThdSleepMilliseconds(20); + xprintf("col: %X - led: %X\n", msg_col, msg_led); chThdSleepMilliseconds(10); switch (msg_type){ @@ -214,8 +214,12 @@ page_status = 0; //start frame 0 (all off/on) //TODO: lighting key led on keypress break; - //TODO: BLINK_ON/OFF_LED - break; + case SET_FULL_ROW: + //write full byte to pin address, msg_pin = pin #, msg_led = byte to write + //writes only to current page + xprintf("SET_FULL_ROW\n"); + write_led_byte(page_status,msg_pin,msg_led); + break; case OFF_LED: //on/off/toggle single led, msg_led = row/col of led @@ -255,6 +259,7 @@ page_status = 0; //start frame 0 (all off/on) chThdSleepMilliseconds(10); set_led_bit(7, control_register_word, msg_led, 6); is31_write_data (7, control_register_word, 0x02); + break; case TOGGLE_ALL: xprintf("TOGGLE_ALL: %d\n", msg_led); @@ -272,17 +277,12 @@ page_status = 0; //start frame 0 (all off/on) if (page_status > 0) { is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0); - } - //maintain lock leds - if (host_keyboard_leds() & (1< 0 && j % 9 == 0){ - xprintf("\n"); - } - switch (j) { - case 0: - xprintf("\n--on-off--\n"); - chThdSleepMilliseconds(2); - break; - case 0x12: - xprintf("\n--blink--\n"); - chThdSleepMilliseconds(2); - break; - } - is31_read_register(pages[i],j,&temp); - xprintf("%02X, ", temp); - chThdSleepMilliseconds(2); - } + } +} - xprintf("\n--pwm--\n"); - chThdSleepMilliseconds(2); - for(j=0x24;j<0xB4;j++) { - is31_read_register(pages[i],j,&temp); - xprintf("%02X, ", temp); - chThdSleepMilliseconds(2); - if(j > 0x24 && (j-4) % 8 == 0){ - xprintf("\n"); - } - } - xprintf("\n"); +/* ============================== + * debug function + * ============================== */ +void print_debug(uint8_t page) { + uint8_t j, debug_temp; + //debugging code - print full led/blink/pwm registers on each frame + xprintf("----layer state----: %X\n", layer_state); + xprintf("page: %d\n", page); + chThdSleepMilliseconds(10); + for(j=0;j<0x24;j++){ + if(j > 0 && j % 9 == 0){ + xprintf("\n"); + } + switch (j) { + case 0: + xprintf("\n--on-off--\n"); + chThdSleepMilliseconds(10); + break; + case 0x12: + xprintf("\n--blink--\n"); + chThdSleepMilliseconds(10); + break; } + is31_read_register(page,j,&debug_temp); + xprintf("%02X, ", debug_temp); + chThdSleepMilliseconds(10); + } - //Function Register - xprintf("\n--FUNCTION--\n"); - chThdSleepMilliseconds(2); - for(j=0;j<0x0D;j++) { - is31_read_register(0x0B,j,&temp); - switch(j) { - case 0: - xprintf("Config %02X", temp); - chThdSleepMilliseconds(2); - break; - case 1: - xprintf(" - Pict %02X\n", temp); - chThdSleepMilliseconds(2); - break; - case 2: - xprintf("Auto1 %02X", temp); - chThdSleepMilliseconds(2); - break; - case 3: - xprintf(" - Auto2 %02X\n", temp); - chThdSleepMilliseconds(2); - break; - case 5: - xprintf("Disp %02X", temp); - chThdSleepMilliseconds(2); - break; - case 6: - xprintf(" - Audio %02X\n", temp); - chThdSleepMilliseconds(2); - break; - case 7: - xprintf("Frame %02X", temp); - chThdSleepMilliseconds(2); - break; - case 8: - xprintf(" - Breath1 %02X\n", temp); - chThdSleepMilliseconds(2); - break; - case 9: - xprintf("Breath2 %02X - ", temp); - chThdSleepMilliseconds(2); - break; - case 10: - xprintf(" - Shut %02X\n", temp); - chThdSleepMilliseconds(2); - break; - case 11: - xprintf("AGC %02X", temp); - chThdSleepMilliseconds(2); - break; - case 12: - xprintf(" - ADC %02X\n", temp); - chThdSleepMilliseconds(2); - break; - } + xprintf("\n--pwm--\n"); + chThdSleepMilliseconds(10); + for(j=0x24;j<0xB4;j++) { + is31_read_register(page,j,&debug_temp); + xprintf("%02X, ", debug_temp); + chThdSleepMilliseconds(10); + if(j > 0x24 && (j-3) % 8 == 0){ + xprintf("\n"); + } + } + xprintf("\n"); + + //Function Register + xprintf("\n--FUNCTION--\n"); + chThdSleepMilliseconds(10); + for(j=0;j<0x0D;j++) { + is31_read_register(0x0B,j,&debug_temp); + switch(j) { + case 0: + xprintf("Config %02X", debug_temp); + chThdSleepMilliseconds(2); + break; + case 1: + xprintf(" - Pict %02X\n", debug_temp); + chThdSleepMilliseconds(2); + break; + case 2: + xprintf("Auto1 %02X", debug_temp); + chThdSleepMilliseconds(2); + break; + case 3: + xprintf(" - Auto2 %02X\n", debug_temp); + chThdSleepMilliseconds(2); + break; + case 5: + xprintf("Disp %02X", debug_temp); + chThdSleepMilliseconds(2); + break; + case 6: + xprintf(" - Audio %02X\n", debug_temp); + chThdSleepMilliseconds(2); + break; + case 7: + xprintf("Frame %02X", debug_temp); + chThdSleepMilliseconds(2); + break; + case 8: + xprintf(" - Breath1 %02X\n", debug_temp); + chThdSleepMilliseconds(2); + break; + case 9: + xprintf("Breath2 %02X - ", debug_temp); + chThdSleepMilliseconds(2); + break; + case 10: + xprintf(" - Shut %02X\n", debug_temp); + chThdSleepMilliseconds(2); + break; + case 11: + xprintf("AGC %02X", debug_temp); + chThdSleepMilliseconds(2); + break; + case 12: + xprintf(" - ADC %02X\n", debug_temp); + chThdSleepMilliseconds(2); + break; } -#endif } } @@ -523,7 +518,7 @@ void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint //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, temp, blink_on; + 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) { @@ -541,18 +536,28 @@ void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint //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 - xprintf("pre-reg_addr: %X\n", control_reg_addr); + xprintf("pre-reg_addr: %2X\n", control_reg_addr); chThdSleepMilliseconds(10); control_reg_addr += blink_on == 1 ? 0x12 : 0x00;//shift 12 bytes to blink register - xprintf("blink-reg_addr: %X\n", control_reg_addr); + xprintf("blink-reg_addr: %2X\n", control_reg_addr); + chThdSleepMilliseconds(10); + xprintf("page: %2X\n", page); chThdSleepMilliseconds(10); - column_bit = 1<<(led_addr % 10 - 1); - is31_read_register(page, control_reg_addr, &temp);//maintain status of leds on this byte - column_byte = temp; + is31_read_register(page, 0x06, &bit_temp);//maintain status of leds on this byte + xprintf("reg 06: %2X\n", bit_temp); + is31_read_register(page, 0x17, &bit_temp);//maintain status of leds on this byte + xprintf("reg 17: %2X\n", bit_temp); + is31_read_register(page, 0x18, &bit_temp);//maintain status of leds on this byte + xprintf("reg 18: %2X\n", bit_temp); + is31_read_register(page, 0x19, &bit_temp);//maintain status of leds on this byte + xprintf("reg 19: %2X\n", bit_temp); + 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; - xprintf("column_byte read: %X\n", column_byte); + xprintf("column_byte read: %2X\n", column_byte); chThdSleepMilliseconds(10); switch(action) { case 0: @@ -565,7 +570,7 @@ void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint column_byte ^= column_bit; break; } - xprintf("column_byte write: %X\n", column_byte); + xprintf("column_byte write: %2X\n", column_byte); chThdSleepMilliseconds(10); //return word to be written in register @@ -574,47 +579,59 @@ void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint } void write_led_byte (uint8_t page, uint8_t row, uint8_t led_byte) { - uint8_t led_control_word[2] = {0};//register address and led on/off mask + 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;// A-register is every other byte - is31_write_data(page, led_control_word, 0x13); + 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};//led control register start address + 0x12 bytes + uint8_t led_control_register[0x13] = {0};//control register start address + 0x12 bytes __builtin_memset(led_control_register,0,13); for(i=0;i Date: Mon, 8 May 2017 14:35:08 -0700 Subject: [PATCH 15/24] CLeaned out debug code --- keyboards/infinity60/led.c | 4 - keyboards/infinity60/led_controller.c | 275 ++------------------------ keyboards/infinity60/led_controller.h | 1 - 3 files changed, 14 insertions(+), 266 deletions(-) diff --git a/keyboards/infinity60/led.c b/keyboards/infinity60/led.c index 92069dc593..d60c76fd8c 100644 --- a/keyboards/infinity60/led.c +++ b/keyboards/infinity60/led.c @@ -29,26 +29,22 @@ void led_set(uint8_t usb_led) { msg_t msg; if (usb_led & (1<. /* * 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 */ @@ -56,9 +56,7 @@ along with this program. If not, see . 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 46 #endif @@ -90,7 +88,6 @@ 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 ordered 8-1 const uint8_t all_on_leds_mask[0x12] = { @@ -182,11 +179,6 @@ static THD_FUNCTION(LEDthread, arg) { uint8_t temp, msg_type, msg_pin, msg_col, msg_led; msg_t msg; -/* //control register variables - uint8_t page, save_page, save_breath1, save_breath2; - msg_t msg, retval; -*/ - // initialize persistent variables pwm_step_status = 4; //full brightness page_status = 0; //start frame 0 (all off/on) @@ -197,77 +189,51 @@ page_status = 0; //start frame 0 (all off/on) // be processed right away) chMBFetch(&led_mailbox, &msg, TIME_INFINITE); msg_col = (msg >> 24) & 0xFF;//if needed - msg_pin = (msg >> 16) & 0XFF;//if needed (SET_FULL_ROW) + 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 - xprintf("--------------------\n"); - xprintf("mailbox fetch\nmsg: %X\n", msg); - chThdSleepMilliseconds(20); - xprintf("type: %X - pin: %X\n", msg_type, msg_pin); - chThdSleepMilliseconds(20); - xprintf("col: %X - led: %X\n", msg_col, msg_led); - chThdSleepMilliseconds(10); - switch (msg_type){ - case KEY_LIGHT: - //TODO: lighting key led on keypress - break; - case SET_FULL_ROW: //write full byte to pin address, msg_pin = pin #, msg_led = byte to write //writes only to current page - xprintf("SET_FULL_ROW\n"); write_led_byte(page_status,msg_pin,msg_led); break; case OFF_LED: //on/off/toggle single led, msg_led = row/col of led - xprintf("OFF_LED: %d\n", msg_led); - chThdSleepMilliseconds(10); set_led_bit(7, control_register_word, msg_led, 0); is31_write_data (7, control_register_word, 0x02); break; case ON_LED: - xprintf("ON_LED: %d\n", msg_led); - chThdSleepMilliseconds(10); set_led_bit(7, control_register_word, msg_led, 1); is31_write_data (7, control_register_word, 0x02); break; case TOGGLE_LED: - xprintf("TOGGLE_LED: %d\n", msg_led); - chThdSleepMilliseconds(10); 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 - xprintf("BLINK_ON: %d\n", msg_led); - chThdSleepMilliseconds(10); set_led_bit(7, control_register_word, msg_led, 4); is31_write_data (7, control_register_word, 0x02); break; case BLINK_ON_LED: - xprintf("BLINK_OFF: %d\n", msg_led); - chThdSleepMilliseconds(10); set_led_bit(7, control_register_word, msg_led, 5); is31_write_data (7, control_register_word, 0x02); break; case BLINK_TOGGLE_LED: - xprintf("BLINK_TOGGLE: %d\n", msg_led); - chThdSleepMilliseconds(10); set_led_bit(7, control_register_word, msg_led, 6); is31_write_data (7, control_register_word, 0x02); break; case TOGGLE_ALL: - xprintf("TOGGLE_ALL: %d\n", msg_led); - chThdSleepMilliseconds(10); //msg_led = unused - is31_read_register(0, 0x00, &temp);//if first byte is on, then toggle frame 0 off + 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 { @@ -287,8 +253,6 @@ page_status = 0; //start frame 0 (all off/on) case TOGGLE_BACKLIGHT: //msg_led = on/off - xprintf("TOGGLE_BACKLIGHT\n"); - chThdSleepMilliseconds(10); //populate the 9 byte rows to be written to each pin, first byte is register (pin) address if (msg_led == 1) { @@ -304,13 +268,9 @@ page_status = 0; //start frame 0 (all off/on) } break; - case DISPLAY_PAGE://show single layer indicator or full map of layer - //msg_led = page to toggle on - xprintf("DISPLAY_PAGE\n"); - chThdSleepMilliseconds(10); + case DISPLAY_PAGE: + //msg_led = page to toggle on if (page_status != msg_led) { - xprintf(" - new page\n"); - chThdSleepMilliseconds(10); is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, msg_led); page_status = msg_led; @@ -321,33 +281,22 @@ page_status = 0; //start frame 0 (all off/on) case RESET_PAGE: //led_msg = page to reset - xprintf("RESET_PAGE\n"); - chThdSleepMilliseconds(10); 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 - xprintf("NUMLOCK: %d\n", msg_led); - chThdSleepMilliseconds(10); + //msg_led = 0 or 1, off/on set_lock_leds(NUM_LOCK_LED_ADDRESS, msg_led, page_status); break; - case TOGGLE_CAPS_LOCK: - xprintf("CAPSLOCK: %d\n", msg_led); - chThdSleepMilliseconds(10); - //msg_led = 0 or 1, off/on + //msg_led = 0 or 1, off/on set_lock_leds(CAPS_LOCK_LED_ADDRESS, msg_led, page_status); break; - //TODO: MODE_BREATH - case STEP_BRIGHTNESS: - xprintf("STEP_BACKLIGHT\n"); - chThdSleepMilliseconds(10); - //led_msg = step pwm up or down + //led_msg = step pwm up or down switch (msg_led) { case 0: if (pwm_step_status == 0) { @@ -375,137 +324,6 @@ page_status = 0; //start frame 0 (all off/on) is31_write_data(0,pwm_register_array,9); } 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; - break; -*/ - xprintf("--------------------\n"); - chThdSleepMilliseconds(10); - } - } -} - -/* ============================== - * debug function - * ============================== */ -void print_debug(uint8_t page) { - uint8_t j, debug_temp; - //debugging code - print full led/blink/pwm registers on each frame - xprintf("----layer state----: %X\n", layer_state); - xprintf("page: %d\n", page); - chThdSleepMilliseconds(10); - for(j=0;j<0x24;j++){ - if(j > 0 && j % 9 == 0){ - xprintf("\n"); - } - switch (j) { - case 0: - xprintf("\n--on-off--\n"); - chThdSleepMilliseconds(10); - break; - case 0x12: - xprintf("\n--blink--\n"); - chThdSleepMilliseconds(10); - break; - } - is31_read_register(page,j,&debug_temp); - xprintf("%02X, ", debug_temp); - chThdSleepMilliseconds(10); - } - - xprintf("\n--pwm--\n"); - chThdSleepMilliseconds(10); - for(j=0x24;j<0xB4;j++) { - is31_read_register(page,j,&debug_temp); - xprintf("%02X, ", debug_temp); - chThdSleepMilliseconds(10); - if(j > 0x24 && (j-3) % 8 == 0){ - xprintf("\n"); - } - } - xprintf("\n"); - - //Function Register - xprintf("\n--FUNCTION--\n"); - chThdSleepMilliseconds(10); - for(j=0;j<0x0D;j++) { - is31_read_register(0x0B,j,&debug_temp); - switch(j) { - case 0: - xprintf("Config %02X", debug_temp); - chThdSleepMilliseconds(2); - break; - case 1: - xprintf(" - Pict %02X\n", debug_temp); - chThdSleepMilliseconds(2); - break; - case 2: - xprintf("Auto1 %02X", debug_temp); - chThdSleepMilliseconds(2); - break; - case 3: - xprintf(" - Auto2 %02X\n", debug_temp); - chThdSleepMilliseconds(2); - break; - case 5: - xprintf("Disp %02X", debug_temp); - chThdSleepMilliseconds(2); - break; - case 6: - xprintf(" - Audio %02X\n", debug_temp); - chThdSleepMilliseconds(2); - break; - case 7: - xprintf("Frame %02X", debug_temp); - chThdSleepMilliseconds(2); - break; - case 8: - xprintf(" - Breath1 %02X\n", debug_temp); - chThdSleepMilliseconds(2); - break; - case 9: - xprintf("Breath2 %02X - ", debug_temp); - chThdSleepMilliseconds(2); - break; - case 10: - xprintf(" - Shut %02X\n", debug_temp); - chThdSleepMilliseconds(2); - break; - case 11: - xprintf("AGC %02X", debug_temp); - chThdSleepMilliseconds(2); - break; - case 12: - xprintf(" - ADC %02X\n", debug_temp); - chThdSleepMilliseconds(2); - break; } } } @@ -515,50 +333,29 @@ void print_debug(uint8_t page) { * ============================== */ 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 + //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) { - xprintf("Invalid address: %d\n", led_addr); return; } - xprintf("set_led_bit: %d\n", led_addr); - xprintf("action: %d\n", action); - chThdSleepMilliseconds(10); - //check blink bit + //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 - xprintf("pre-reg_addr: %2X\n", control_reg_addr); - chThdSleepMilliseconds(10); control_reg_addr += blink_on == 1 ? 0x12 : 0x00;//shift 12 bytes to blink register - xprintf("blink-reg_addr: %2X\n", control_reg_addr); - chThdSleepMilliseconds(10); - xprintf("page: %2X\n", page); - chThdSleepMilliseconds(10); - - - is31_read_register(page, 0x06, &bit_temp);//maintain status of leds on this byte - xprintf("reg 06: %2X\n", bit_temp); - is31_read_register(page, 0x17, &bit_temp);//maintain status of leds on this byte - xprintf("reg 17: %2X\n", bit_temp); - is31_read_register(page, 0x18, &bit_temp);//maintain status of leds on this byte - xprintf("reg 18: %2X\n", bit_temp); - is31_read_register(page, 0x19, &bit_temp);//maintain status of leds on this byte - xprintf("reg 19: %2X\n", bit_temp); + 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; - xprintf("column_byte read: %2X\n", column_byte); - chThdSleepMilliseconds(10); switch(action) { case 0: column_byte &= ~column_bit; @@ -570,8 +367,6 @@ void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint column_byte ^= column_bit; break; } - xprintf("column_byte write: %2X\n", column_byte); - chThdSleepMilliseconds(10); //return word to be written in register led_control_reg[0] = control_reg_addr; @@ -589,7 +384,7 @@ void write_led_byte (uint8_t page, uint8_t row, uint8_t led_byte) { 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};//control register start address + 0x12 bytes + uint8_t led_control_register[0x13] = {0}; __builtin_memset(led_control_register,0,13); @@ -607,30 +402,15 @@ 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}; - xprintf("---set lock---\n"); - chThdSleepMilliseconds(10); - //blink if all leds are on if (page == 0) { is31_read_register(0, 0x00, &lock_temp); - xprintf("AllOnReg: %2X\n", lock_temp); - chThdSleepMilliseconds(10); if (lock_temp == 0xFF) { - xprintf("AllOntrue\n"); - chThdSleepMilliseconds(10); led_action |= (1<<2); //set blink bit - } else { - xprintf("AllOnfalse\n"); - chThdSleepMilliseconds(10); } } set_led_bit(page,led_control_word,led_addr,led_action); - - xprintf("led_word: %2X", led_control_word[0]); - xprintf("%X\n", led_control_word[1]); - chThdSleepMilliseconds(10); - is31_write_data(page, led_control_word, 0x02); } @@ -679,30 +459,3 @@ void led_controller_init(void) { 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 7bdef7ae63..457b21a925 100644 --- a/keyboards/infinity60/led_controller.h +++ b/keyboards/infinity60/led_controller.h @@ -31,7 +31,6 @@ msg_t is31_read_register(uint8_t page, uint8_t reg, uint8_t *result); * ============================*/ void led_controller_init(void); -void print_debug (uint8_t page); #define CAPS_LOCK_LED_ADDRESS 46 //pin matrix location #define NUM_LOCK_LED_ADDRESS 85 From f1d81d2cc6f257925d8582da630aadf5170bd878 Mon Sep 17 00:00:00 2001 From: jpetermans Date: Mon, 8 May 2017 14:55:57 -0700 Subject: [PATCH 16/24] minor change on lock leds --- keyboards/infinity60/led_controller.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c index 707b4e0df6..75806d54b5 100644 --- a/keyboards/infinity60/led_controller.c +++ b/keyboards/infinity60/led_controller.c @@ -317,19 +317,19 @@ page_status = 0; //start frame 0 (all off/on) case TOGGLE_NUM_LOCK: //msg_led = 0 or 1, off/on - set_lock_leds(NUM_LOCK_LED_ADDRESS, msg_led); + set_lock_leds(NUM_LOCK_LED_ADDRESS, 1); break; case TOGGLE_CAPS_LOCK: //msg_led = 0 or 1, off/on - set_lock_leds(CAPS_LOCK_LED_ADDRESS, msg_led); + set_lock_leds(CAPS_LOCK_LED_ADDRESS, 1); break; //TODO: MODE_BREATH case MODE_BREATH: break; case STEP_BRIGHTNESS: - xprintf("STEP_BACKLIGHT\n"); + xprintf("TOGGLE_BACKLIGHT\n"); chThdSleepMilliseconds(10); //led_msg = step pwm up or down switch (msg_led) { @@ -459,10 +459,8 @@ void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint } void set_lock_leds(uint8_t led_addr, uint8_t led_action) { - uint8_t page, temp; + uint8_t page; uint8_t led_control_word[2] = {0}; - //TODO: this function call could send led address vs lock_type. - //however, the switch/case allows for additional steps, like audio, depending on type //ignore frame0 if all leds are on or if option set in led_controller.h //TODO: blink of all leds are on, clear blink register if not From 5df74f3ba73f18f6bbd13b82a3a960c86fa592e1 Mon Sep 17 00:00:00 2001 From: jpetermans Date: Mon, 8 May 2017 15:13:02 -0700 Subject: [PATCH 17/24] updated keymap for new led functions --- .../infinity60/keymaps/jpetermans/Makefile | 2 - .../infinity60/keymaps/jpetermans/keymap.c | 280 ++++++++++-------- .../keymaps/jpetermans/keymap_jpetermans.h | 78 ----- .../infinity60/keymaps/jpetermans/readme.md | 79 +++++ 4 files changed, 240 insertions(+), 199 deletions(-) delete mode 100644 keyboards/infinity60/keymaps/jpetermans/keymap_jpetermans.h create mode 100644 keyboards/infinity60/keymaps/jpetermans/readme.md diff --git a/keyboards/infinity60/keymaps/jpetermans/Makefile b/keyboards/infinity60/keymaps/jpetermans/Makefile index 225e4cad40..df3d1e952f 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 6f14b66cba..1afb7c067f 100644 --- a/keyboards/infinity60/keymaps/jpetermans/keymap.c +++ b/keyboards/infinity60/keymaps/jpetermans/keymap.c @@ -1,6 +1,5 @@ #include "infinity60.h" #include "led_controller.h" -#include "keymap_jpetermans.h" //Helpful Defines #define _______ KC_TRNS @@ -12,8 +11,33 @@ #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 + * KEYMAPS * ==================================*/ const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = { @@ -35,19 +59,10 @@ 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_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 \ ), - /* 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,\ @@ -57,12 +72,21 @@ const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = { _______,_______,_______, 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( \ - _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,KC_MUTE, KC_VOLD, KC_VOLU,_______,KC_NO,\ + _______,F(MODE_SINGLE),F(MODE_PAGE),F(MODE_FLASH),_______,_______,_______, _______, _______, _______,KC_MUTE, KC_VOLD, KC_VOLU,_______,KC_NO,\ _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______,_______,\ - _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______, \ - _______,_______,F(2),F(3),F(4),F(5),F(6),F(7), KC_MPRV, KC_MNXT,KC_MSTP, _______,KC_NO, \ + _______,_______,_______,_______,_______,F(GAME),_______, _______, _______, _______,_______, _______,_______, \ + _______,_______,F(ALL) ,F(BRIGHT),F(DIM),F(BACKLIGHT),_______, _______, KC_MPRV, KC_MNXT,KC_MSTP, _______,KC_NO, \ _______,_______,_______, KC_MPLY, _______,_______, _______,_______ \ ), /* ~ */ @@ -91,21 +115,20 @@ enum function_id { enum macro_id { ACTION_LEDS_ALL, ACTION_LEDS_GAME, - ACTION_LEDS_NAV, - ACTION_LEDS_MEDIA, - ACTION_LEDS_NUMPAD, - ACTION_LEDS_TEST + ACTION_LEDS_BACKLIGHT, + ACTION_LEDS_BRIGHT, + ACTION_LEDS_DIM, + ACTION_LEDS_BREATH, + ACTION_LEDS_SINGLE, + ACTION_LEDS_PAGE, + ACTION_LEDS_FLASH, }; - + /* ================================== - * LED MAPPING + * LED MAPPING * ==================================*/ /* - Configuring led control can be done as - 1. full keyboard at a time - define led array, or - 2. individual led - send specific led address (defined in keymap.h) - 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 @@ -113,163 +136,182 @@ enum macro_id { 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 full keyboard arrays map to the mcu's LED pages - (8 available) desribed in led_controller.c - - 0x24 (pcb row 1) is first byte of PWM portion of LED page - 0x34 (pcb row 2) is 17th byte of PWM portion of LED page - array translates to row and column positions */ -//LED Layer indicator (1 per layer 3-7) -const uint8_t led_single_layer[5] = { - 12,13,14,15,16 -}; -//LED Page 1 - All off -//LED Page 2 - All on -//LED Page 3 - _Nav -const uint8_t led_nav[33] = { - 11,12,13,14,15,16,17,18,21,22,23,24,25, - 28, 37,38,41,42,45, - 46,47,48, 54,55,56,57,58, - 64,65,66, 71, - 84,85 -}; -//LED Page 4 - _Numpad -const uint8_t led_numpad[17] = { +//======== 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, - 85 + 72,73,74,75 }; -//LED Page 5 - _Media -const uint8_t led_media[12] = { - 23,24,25, - 38, - 55,56,57, - 73,74,75, - 83, 86 +//LED Page 2 - _Nav +uint8_t led_nav[12] = { + 38, + 47,48, 55,56,57, + 64,65,66 }; -//LED Page 6 - _Game -const uint8_t led_game[5] = { - //row 1 +//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, - //row 2 - //row 3 - 32, - //row 4 - 47, 48, - //row 5 - 51 - //row 6 - //row 7 - //row 8 + 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), - [4] = ACTION_FUNCTION(ACTION_LEDS_MEDIA), - [5] = ACTION_FUNCTION(ACTION_LEDS_NAV), - [6] = ACTION_FUNCTION(ACTION_LEDS_NUMPAD), - [7] = ACTION_FUNCTION(ACTION_LEDS_TEST) - - + [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) { - (void)opt; msg_t msg; + switch(id) { case ACTION_LEDS_ALL: if(record->event.pressed) { - // signal the LED controller thread + 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_GAME: + + case ACTION_LEDS_BACKLIGHT: if(record->event.pressed) { - // signal the LED controller thread - msg=(TOGGLE_LAYER_LEDS << 8) | 6; + backlight_status_global ^= 1; + msg=(TOGGLE_BACKLIGHT << 8) | (backlight_status_global); chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } break; - case ACTION_LEDS_MEDIA: + + case ACTION_LEDS_GAME: if(record->event.pressed) { - // signal the LED controller thread - msg=(TOGGLE_LAYER_LEDS << 8) | 5; + 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_NAV: + + case ACTION_LEDS_BRIGHT: if(record->event.pressed) { - // signal the LED controller thread - msg=(OFF_LED << 8) | 12; + msg=(STEP_BRIGHTNESS << 8) | 1; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } break; - case ACTION_LEDS_NUMPAD: + + case ACTION_LEDS_DIM: if(record->event.pressed) { - // signal the LED controller thread - msg=(ON_LED << 8) | 12; + msg=(STEP_BRIGHTNESS << 8) | 0; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } break; - case ACTION_LEDS_TEST: + + case ACTION_LEDS_BREATH: if(record->event.pressed) { - // signal the LED controller thread - msg=(TOGGLE_LED << 8) | 12; + 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) { - 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(); -//TODO: do pages need to be written at init or ok on demand? -/* Write pages */ - write_led_page(3, led_nav, 33); - chThdSleepMilliseconds(5); + // Write predefined led pages. + write_led_page(_NUMPAD, led_numpad, 16); + chThdSleepMilliseconds(10); - write_led_page(4, led_numpad, 17); - chThdSleepMilliseconds(5); + write_led_page(_FNAV, led_nav, 12); + chThdSleepMilliseconds(10); - write_led_page(5, led_media, 12); - chThdSleepMilliseconds(5); + write_led_page(_MEDIA, led_media, 15); + chThdSleepMilliseconds(10); - write_led_page(6, led_game, 5); - chThdSleepMilliseconds(5); + 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=(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/keymap_jpetermans.h b/keyboards/infinity60/keymaps/jpetermans/keymap_jpetermans.h deleted file mode 100644 index 240374423c..0000000000 --- a/keyboards/infinity60/keymaps/jpetermans/keymap_jpetermans.h +++ /dev/null @@ -1,78 +0,0 @@ -/* LED layout mainly based on default Standard configuration - * ,-----------------------------------------------------------. - * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \ | ` | - * |-----------------------------------------------------------| - * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| Bksp| - * |-----------------------------------------------------------| - * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Enter | - * |-----------------------------------------------------------| - * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |Fn0| - * |-----------------------------------------------------------' - * | LCtl|LGui|LAlt | Space | RAlt|RGui|RMenu|RCtl| - * `-----------------------------------------------------------' -*/ - - -#define ADDR_LED_ESC 0x24 -#define ADDR_LED_1 0x25 -#define ADDR_LED_2 0x26 -#define ADDR_LED_3 0x27 -#define ADDR_LED_4 0x28 -#define ADDR_LED_5 0x29 -#define ADDR_LED_6 0x2A -#define ADDR_LED_7 0x2B -#define ADDR_LED_8 0x34 -#define ADDR_LED_9 0x35 -#define ADDR_LED_0 0x36 -#define ADDR_LED_MINS 0x37 -#define ADDR_LED_EQL 0x38 -#define ADDR_LED_BSLS 0x39 -//#define ADDR_LED_GRV 0x3A //not used by Alphabet layout -#define ADDR_LED_TAB 0x3B -#define ADDR_LED_Q 0x44 -#define ADDR_LED_W 0x45 -#define ADDR_LED_E 0x46 -#define ADDR_LED_R 0x47 -#define ADDR_LED_T 0x48 -#define ADDR_LED_Y 0x49 -#define ADDR_LED_U 0x4A -#define ADDR_LED_I 0x4B -#define ADDR_LED_O 0x54 -#define ADDR_LED_P 0x55 -#define ADDR_LED_LBRC 0x56 -#define ADDR_LED_RBRC 0x57 -#define ADDR_LED_BSPC 0x58 -#define ADDR_LED_CAPS 0x59 -#define ADDR_LED_A 0x5A -#define ADDR_LED_S 0x5B -#define ADDR_LED_D 0x64 -#define ADDR_LED_F 0x65 -#define ADDR_LED_G 0x66 -#define ADDR_LED_H 0x67 -#define ADDR_LED_J 0x68 -#define ADDR_LED_K 0x69 -#define ADDR_LED_L 0x6A -#define ADDR_LED_SCLN 0x6B -#define ADDR_LED_QUOT 0x74 -#define ADDR_LED_ENT 0x75 -#define ADDR_LED_LSFT 0x76 -#define ADDR_LED_Z 0x77 -#define ADDR_LED_X 0x78 -#define ADDR_LED_C 0x79 -#define ADDR_LED_V 0x7A -#define ADDR_LED_B 0x7B -#define ADDR_LED_N 0x84 -#define ADDR_LED_M 0x85 -#define ADDR_LED_COMM 0x86 -#define ADDR_LED_DOT 0x87 -#define ADDR_LED_SLSH 0x88 -#define ADDR_LED_RSFT 0x89 -//#define ADDR_LED_FN0 0x8A //not used by Alphabet layout -#define ADDR_LED_LCTL 0x8B -#define ADDR_LED_LGUI 0x94 -#define ADDR_LED_LALT 0x95 -#define ADDR_LED_SPC 0x96 -#define ADDR_LED_RALT 0x97 -#define ADDR_LED_RGUI 0x98 -#define ADDR_LED_MENU 0x99 -#define ADDR_LED_RCTL 0x9A diff --git a/keyboards/infinity60/keymaps/jpetermans/readme.md b/keyboards/infinity60/keymaps/jpetermans/readme.md new file mode 100644 index 0000000000..9c5b89173c --- /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);` From 821f72eae94ce4f1b93bab1376b2187698206b65 Mon Sep 17 00:00:00 2001 From: jpetermans Date: Mon, 8 May 2017 16:15:20 -0700 Subject: [PATCH 18/24] documentation cleanup --- .../infinity60/keymaps/jpetermans/readme.md | 69 ++++++++++--------- keyboards/infinity60/led_controller.c | 6 +- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/keyboards/infinity60/keymaps/jpetermans/readme.md b/keyboards/infinity60/keymaps/jpetermans/readme.md index 9c5b89173c..fcad4b140a 100644 --- a/keyboards/infinity60/keymaps/jpetermans/readme.md +++ b/keyboards/infinity60/keymaps/jpetermans/readme.md @@ -3,10 +3,10 @@ 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. +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 C4-5 in the IS31 datasheet, 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 @@ -17,19 +17,26 @@ digits mean "row" and "col", i.e. 45 means C4-5 in the IS31 datasheet, matrix A *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. +- **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, every 8 *bytes* (not bits) 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" +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 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: +One function is available to directly set leds without the mailbox: ``` 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: -``` +```c uint8_t led_numpad[16] = { 18,21,22,23, 37,38,41,42, @@ -39,24 +46,24 @@ uint8_t led_numpad[16] = { 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. +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. +Sending an action to the led mailbox is done using chMBPost: ``` chMBPost(&led_mailbox, message, timeout); ``` @@ -66,14 +73,14 @@ chMBPost(&led_mailbox, message, timeout); 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;` + *`msg=(ON_LED << 8) | 42;` 2. send msg to the led mailbox -`chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);` + *`chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);` Another: -`msg=(BLINK_TOGGLE_LED << 8) | 46;` -`chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);` + *`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);` + *`msg=(row<<16) | (SET_FULL_ROW << 8) | (led_pin_byte);` + *`chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);` diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c index d4ad0559b7..d776b4fcf1 100644 --- a/keyboards/infinity60/led_controller.c +++ b/keyboards/infinity60/led_controller.c @@ -186,7 +186,7 @@ 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_col = (msg >> 24) & 0xFF;//if needed msg_pin = (msg >> 16) & 0XFF;//if needed (e.g. SET_FULL_ROW) @@ -229,7 +229,7 @@ page_status = 0; //start frame 0 (all off/on) break; case TOGGLE_ALL: - //msg_led = unused + //msg_led = unused is31_read_register(0, 0x00, &temp); led_control_reg[0] = 0; @@ -315,7 +315,7 @@ page_status = 0; //start frame 0 (all off/on) break; } - //populate 8 byte rows to write on each pin + //populate 8 byte arrays 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); From d1ff2bb9db68b899dbd02d1cdf036551b38dccdc Mon Sep 17 00:00:00 2001 From: jpetermans Date: Mon, 8 May 2017 16:17:40 -0700 Subject: [PATCH 19/24] readme fix --- keyboards/infinity60/keymaps/jpetermans/readme.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/keyboards/infinity60/keymaps/jpetermans/readme.md b/keyboards/infinity60/keymaps/jpetermans/readme.md index fcad4b140a..4657a84c07 100644 --- a/keyboards/infinity60/keymaps/jpetermans/readme.md +++ b/keyboards/infinity60/keymaps/jpetermans/readme.md @@ -73,14 +73,14 @@ chMBPost(&led_mailbox, message, timeout); 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;` + * `msg=(ON_LED << 8) | 42;` 2. send msg to the led mailbox - *`chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);` + * `chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);` Another: - *`msg=(BLINK_TOGGLE_LED << 8) | 46;` - *`chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);` + * `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);` + * `msg=(row<<16) | (SET_FULL_ROW << 8) | (led_pin_byte);` + * `chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);` From 5fc5661147e4e8bec8a52a8691ac1df2fedd3558 Mon Sep 17 00:00:00 2001 From: jpetermans Date: Mon, 8 May 2017 16:19:11 -0700 Subject: [PATCH 20/24] third readme fix attempt --- keyboards/infinity60/keymaps/jpetermans/readme.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/keyboards/infinity60/keymaps/jpetermans/readme.md b/keyboards/infinity60/keymaps/jpetermans/readme.md index 4657a84c07..2e0edeacd4 100644 --- a/keyboards/infinity60/keymaps/jpetermans/readme.md +++ b/keyboards/infinity60/keymaps/jpetermans/readme.md @@ -78,9 +78,9 @@ An example: * `chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);` Another: - * `msg=(BLINK_TOGGLE_LED << 8) | 46;` - * `chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);` +- `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);` +- `msg=(row<<16) | (SET_FULL_ROW << 8) | (led_pin_byte);` +- `chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);` From 16774333ad47ada2367b5ca283d0af5060ff8415 Mon Sep 17 00:00:00 2001 From: jpetermans Date: Mon, 8 May 2017 16:28:04 -0700 Subject: [PATCH 21/24] last readme fix --- keyboards/infinity60/keymaps/jpetermans/readme.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/keyboards/infinity60/keymaps/jpetermans/readme.md b/keyboards/infinity60/keymaps/jpetermans/readme.md index 2e0edeacd4..7e60a7f0da 100644 --- a/keyboards/infinity60/keymaps/jpetermans/readme.md +++ b/keyboards/infinity60/keymaps/jpetermans/readme.md @@ -78,9 +78,13 @@ An example: * `chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);` Another: -- `msg=(BLINK_TOGGLE_LED << 8) | 46;` -- `chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);` +```c +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);` +```c +msg=(row<<16) | (SET_FULL_ROW << 8) | (led_pin_byte); +chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); +``` From a144968807f5bf98b2c41cfe153f3df780ed4eaa Mon Sep 17 00:00:00 2001 From: jpetermans Date: Mon, 8 May 2017 16:38:44 -0700 Subject: [PATCH 22/24] remove breath functions from keymap --- keyboards/infinity60/keymaps/jpetermans/keymap.c | 10 ---------- keyboards/infinity60/keymaps/jpetermans/readme.md | 11 +++++++---- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/keyboards/infinity60/keymaps/jpetermans/keymap.c b/keyboards/infinity60/keymaps/jpetermans/keymap.c index 1afb7c067f..630105017d 100644 --- a/keyboards/infinity60/keymaps/jpetermans/keymap.c +++ b/keyboards/infinity60/keymaps/jpetermans/keymap.c @@ -23,7 +23,6 @@ enum ic60_keycodes { BACKLIGHT, BRIGHT, DIM, - BREATH, ALL, GAME, MODE_SINGLE, @@ -118,7 +117,6 @@ enum macro_id { ACTION_LEDS_BACKLIGHT, ACTION_LEDS_BRIGHT, ACTION_LEDS_DIM, - ACTION_LEDS_BREATH, ACTION_LEDS_SINGLE, ACTION_LEDS_PAGE, ACTION_LEDS_FLASH, @@ -175,7 +173,6 @@ const uint16_t fn_actions[] = { [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), @@ -225,13 +222,6 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { } 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; diff --git a/keyboards/infinity60/keymaps/jpetermans/readme.md b/keyboards/infinity60/keymaps/jpetermans/readme.md index 7e60a7f0da..f50bee6172 100644 --- a/keyboards/infinity60/keymaps/jpetermans/readme.md +++ b/keyboards/infinity60/keymaps/jpetermans/readme.md @@ -72,10 +72,13 @@ chMBPost(&led_mailbox, message, timeout); -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);` +```c +//set the message to be sent. First byte (LSB) is the led address, and second is the message type +msg=(ON_LED << 8) | 42; + +//send msg to the led mailbox +chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); +``` Another: ```c From 164a6c994b797b66634f7a1c12fcaffd0ffd7506 Mon Sep 17 00:00:00 2001 From: jpetermans Date: Wed, 10 May 2017 15:53:59 -0700 Subject: [PATCH 23/24] reorder mailbox msg data; formatting --- .../infinity60/keymaps/jpetermans/keymap.c | 28 ++-- .../infinity60/keymaps/jpetermans/readme.md | 38 ++--- keyboards/infinity60/led.c | 8 +- keyboards/infinity60/led_controller.c | 138 +++++++++--------- 4 files changed, 101 insertions(+), 111 deletions(-) diff --git a/keyboards/infinity60/keymaps/jpetermans/keymap.c b/keyboards/infinity60/keymaps/jpetermans/keymap.c index 630105017d..8d19834b2f 100644 --- a/keyboards/infinity60/keymaps/jpetermans/keymap.c +++ b/keyboards/infinity60/keymaps/jpetermans/keymap.c @@ -12,7 +12,7 @@ #define _TILDE 4 //IS31 chip has 8 available led pages, using 0 for all leds and 7 for single toggles -#define max_pages 6 +#define max_pages 6 enum ic60_keycodes { NUMPAD, @@ -75,7 +75,7 @@ const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_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_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,_______,_______ \ ), @@ -119,7 +119,7 @@ enum macro_id { ACTION_LEDS_DIM, ACTION_LEDS_SINGLE, ACTION_LEDS_PAGE, - ACTION_LEDS_FLASH, + ACTION_LEDS_FLASH }; /* ================================== @@ -137,9 +137,8 @@ enum macro_id { */ //======== 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] = { +uint8_t led_numpad[16] = { 18,21,22,23, 37,38,41,42, 55,56,57,58, @@ -186,7 +185,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { case ACTION_LEDS_ALL: if(record->event.pressed) { led_mode_global = led_mode_global == ALL ? MODE_SINGLE : ALL; - msg=(TOGGLE_ALL << 8) | 0; + msg=TOGGLE_ALL; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } break; @@ -194,7 +193,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { case ACTION_LEDS_BACKLIGHT: if(record->event.pressed) { backlight_status_global ^= 1; - msg=(TOGGLE_BACKLIGHT << 8) | (backlight_status_global); + msg=(backlight_status_global << 8) | TOGGLE_BACKLIGHT; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } break; @@ -203,21 +202,21 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { if(record->event.pressed) { led_mode_global = led_mode_global == GAME ? MODE_SINGLE : GAME; - msg=(DISPLAY_PAGE << 8) | 4; + msg=(4 << 8) | DISPLAY_PAGE; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } break; case ACTION_LEDS_BRIGHT: if(record->event.pressed) { - msg=(STEP_BRIGHTNESS << 8) | 1; + msg=(1 << 8) | STEP_BRIGHTNESS; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } break; case ACTION_LEDS_DIM: if(record->event.pressed) { - msg=(STEP_BRIGHTNESS << 8) | 0; + msg=(0 << 8) | STEP_BRIGHTNESS; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } break; @@ -282,26 +281,25 @@ void matrix_scan_user(void) { 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); + 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=(DISPLAY_PAGE << 8) | 7; + msg=(7 << 8) | DISPLAY_PAGE; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); - msg=(1<<16) | (SET_FULL_ROW << 8) | (led_pin_byte); + 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=(DISPLAY_PAGE << 8) | (page); + 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 index f50bee6172..63fd88ec22 100644 --- a/keyboards/infinity60/keymaps/jpetermans/readme.md +++ b/keyboards/infinity60/keymaps/jpetermans/readme.md @@ -16,26 +16,24 @@ digits mean "row" and "col", i.e. 45 means pin 4, column 5 in the IS31 datasheet ``` *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, ..). +The IS31 includes 8 pages (or frames) 0-7 and each page consists of 144 bytes +- **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. +- **bytes 8 - 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. +- **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 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" +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 leds in array) ``` -This function saves a full page using a supplied array of led locations such as: +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, @@ -48,13 +46,9 @@ 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. +- **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. @@ -68,13 +62,13 @@ 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 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 +- 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=(ON_LED << 8) | 42; +msg=(42 << 8) | ON_LED //send msg to the led mailbox chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); @@ -82,12 +76,12 @@ chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); Another: ```c -msg=(BLINK_TOGGLE_LED << 8) | 46; +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) | (SET_FULL_ROW << 8) | (led_pin_byte); +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 d60c76fd8c..53147a78a5 100644 --- a/keyboards/infinity60/led.c +++ b/keyboards/infinity60/led.c @@ -30,23 +30,23 @@ void led_set(uint8_t usb_led) { if (usb_led & (1<> 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 + 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_pin = pin #, msg_led = byte to write - //writes only to current page - write_led_byte(page_status,msg_pin,msg_led); - break; + //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; - 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); + case 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], 0); + is31_write_data (msg_args[1], 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); + case ON_LED: + set_led_bit(msg_args[1], control_register_word, msg_args[0], 1); + is31_write_data (msg_args[1], 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); + case TOGGLE_LED: + set_led_bit(msg_args[1], control_register_word, msg_args[0], 2); + is31_write_data (msg_args[1], 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); + 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); + is31_write_data (msg_args[1], 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); + case BLINK_ON_LED: + set_led_bit(msg_args[1], control_register_word, msg_args[0], 5); + is31_write_data (msg_args[1], 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); + case BLINK_TOGGLE_LED: + set_led_bit(msg_args[1], control_register_word, msg_args[0], 6); + is31_write_data (msg_args[1], control_register_word, 0x02); break; case TOGGLE_ALL: - //msg_led = unused + //turn on/off all leds, msg_args = unused is31_read_register(0, 0x00, &temp); led_control_reg[0] = 0; - //if first byte is on, then toggle frame 0 off + //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 { @@ -252,27 +250,27 @@ page_status = 0; //start frame 0 (all off/on) break; case TOGGLE_BACKLIGHT: - //msg_led = on/off + //msg_args[0] = on/off - //populate the 9 byte rows to be written to each pin, first byte is register (pin) address - if (msg_led == 1) { + //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 { __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 + //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_led = page to toggle on - if (page_status != msg_led) { - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, msg_led); - page_status = msg_led; + //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()); @@ -280,24 +278,24 @@ page_status = 0; //start frame 0 (all off/on) break; case RESET_PAGE: - //led_msg = page to reset + //led_args[0] = 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); + is31_write_data(msg_args[0], 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); + //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_led = 0 or 1, off/on - set_lock_leds(CAPS_LOCK_LED_ADDRESS, msg_led, page_status); + //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_msg = step pwm up or down - switch (msg_led) { + //led_args[0] = step up (1) or down (0) + switch (msg_args[0]) { case 0: if (pwm_step_status == 0) { pwm_step_status = 4; @@ -305,7 +303,7 @@ page_status = 0; //start frame 0 (all off/on) pwm_step_status--; } break; - + case 1: if (pwm_step_status == 4) { pwm_step_status = 0; @@ -316,7 +314,7 @@ page_status = 0; //start frame 0 (all off/on) } //populate 8 byte arrays to write on each pin - //first byte is register address, every 0x10 9 bytes are A-register pwm pins + //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++) { @@ -334,9 +332,9 @@ page_status = 0; //start frame 0 (all off/on) 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 + //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, bit_temp, blink_on; + 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) { @@ -344,17 +342,17 @@ void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint } //check for blink bit - blink_on = action>>2; + blink_bit = 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 + //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, &bit_temp);//maintain status of leds on this byte + is31_read_register(page, control_reg_addr, &temp);//maintain status of leds on this byte column_bit = 1<<(led_addr % 10 - 1); - column_byte = bit_temp; + column_byte = temp; switch(action) { case 0: @@ -376,7 +374,7 @@ void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint 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[0] = (row - 1 ) * 0x02;// A-matrix is every other byte led_control_word[1] = led_byte; is31_write_data(page, led_control_word, 0x02); } @@ -389,7 +387,7 @@ void write_led_page (uint8_t page, uint8_t *user_led_array, uint8_t led_count) { __builtin_memset(led_control_register,0,13); for(i=0;i Date: Wed, 24 May 2017 11:20:50 -0700 Subject: [PATCH 24/24] keymap example update and tweak to set_led_bit function --- .../infinity60/keymaps/jpetermans/keymap.c | 6 ++--- .../infinity60/keymaps/jpetermans/readme.md | 12 ++++----- keyboards/infinity60/led_controller.c | 27 +++++++++---------- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/keyboards/infinity60/keymaps/jpetermans/keymap.c b/keyboards/infinity60/keymaps/jpetermans/keymap.c index 8d19834b2f..cc4633b1b4 100644 --- a/keyboards/infinity60/keymaps/jpetermans/keymap.c +++ b/keyboards/infinity60/keymaps/jpetermans/keymap.c @@ -59,7 +59,7 @@ const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 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 \ + KC_LCTL, KC_LGUI,KC_LALT, LT(_FNAV, KC_SPC), KC_RALT,TG(_NUMPAD),MO(_MEDIA), KC_RCTL \ ), /* numpad */ @@ -68,7 +68,7 @@ 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 */ @@ -290,7 +290,7 @@ void matrix_scan_user(void) { 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; + msg=(1 << 16) | (led_pin_byte << 8) | SET_FULL_ROW; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); break; diff --git a/keyboards/infinity60/keymaps/jpetermans/readme.md b/keyboards/infinity60/keymaps/jpetermans/readme.md index 63fd88ec22..b83057ea7b 100644 --- a/keyboards/infinity60/keymaps/jpetermans/readme.md +++ b/keyboards/infinity60/keymaps/jpetermans/readme.md @@ -16,9 +16,9 @@ digits mean "row" and "col", i.e. 45 means pin 4, column 5 in the IS31 datasheet ``` *Unused in Alphabet Layout -The IS31 includes 8 pages (or frames) 0-7 and each page consists of 144 bytes +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 (CA1, CB1, CA2, CB2, ..). + * 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. @@ -31,7 +31,7 @@ In the Infinity60 project folder, led_controller.c sets up ability to write led One function is available to directly set leds without the mailbox: ``` -write_led_page(page#, array of leds by address, # of leds in array) +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 @@ -45,7 +45,7 @@ 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. +- **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. @@ -68,7 +68,7 @@ chMBPost(&led_mailbox, message, timeout); 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 +msg=(42 << 8) | ON_LED; //send msg to the led mailbox chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); @@ -76,7 +76,7 @@ chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); Another: ```c -msg=(46 << 8) | BLINK_TOGGLE_LED +msg=(46 << 8) | BLINK_TOGGLE_LED; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); ``` diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c index a66edb9277..04793cc01f 100644 --- a/keyboards/infinity60/led_controller.c +++ b/keyboards/infinity60/led_controller.c @@ -25,7 +25,6 @@ along with this program. If not, see . #include "hal.h" #include "print.h" #include "led.h" -#include "action_layer.h" #include "host.h" #include "led_controller.h" @@ -199,31 +198,25 @@ static THD_FUNCTION(LEDthread, arg) { break; case OFF_LED: - //on/off/toggle single led, msg_args[0] = row/col of 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); - is31_write_data (msg_args[1], control_register_word, 0x02); break; case ON_LED: set_led_bit(msg_args[1], control_register_word, msg_args[0], 1); - is31_write_data (msg_args[1], control_register_word, 0x02); break; case TOGGLE_LED: set_led_bit(msg_args[1], control_register_word, msg_args[0], 2); - is31_write_data (msg_args[1], control_register_word, 0x02); break; 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); - is31_write_data (msg_args[1], control_register_word, 0x02); break; case BLINK_ON_LED: set_led_bit(msg_args[1], control_register_word, msg_args[0], 5); - is31_write_data (msg_args[1], control_register_word, 0x02); break; case BLINK_TOGGLE_LED: set_led_bit(msg_args[1], control_register_word, msg_args[0], 6); - is31_write_data (msg_args[1], control_register_word, 0x02); break; case TOGGLE_ALL: @@ -282,6 +275,10 @@ static THD_FUNCTION(LEDthread, arg) { 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: @@ -330,7 +327,7 @@ static THD_FUNCTION(LEDthread, arg) { * led processing functions * ============================== */ -void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint8_t action) { +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 @@ -341,11 +338,9 @@ void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint return; } - //check for blink bit - blink_bit = action>>2; + blink_bit = action>>2;//check for blink bit action &= ~(1<<2); //strip blink bit - //first byte is led control register address 0x00 //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 @@ -367,8 +362,9 @@ void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint } //return word to be written in register - led_control_reg[0] = control_reg_addr; - led_control_reg[1] = column_byte; + 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) { @@ -403,13 +399,14 @@ void set_lock_leds(uint8_t led_addr, uint8_t led_action, uint8_t page) { //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); - is31_write_data(page, led_control_word, 0x02); } /* =====================