add ability to toggle individual led by address

master
jpetermans 2017-04-07 15:58:17 -07:00
parent af13e9a12d
commit a2ac883779
3 changed files with 127 additions and 100 deletions

View File

@ -12,6 +12,10 @@
#define _MEDIA 3 #define _MEDIA 3
#define _TILDE 4 #define _TILDE 4
/* ==================================
* KEYMAPS
* ==================================*/
const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = { const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Layer 0: Default Layer /* Layer 0: Default Layer
* ,-----------------------------------------------------------. * ,-----------------------------------------------------------.
@ -58,7 +62,7 @@ const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______,_______,_______,_______,_______,_______,_______, _______, _______, _______,KC_MUTE, KC_VOLD, KC_VOLU,_______,KC_NO,\ _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,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, _______,_______, _______,_______ \ _______,_______,_______, KC_MPLY, _______,_______, _______,_______ \
), ),
/* ~ */ /* ~ */
@ -86,28 +90,35 @@ enum function_id {
enum macro_id { enum macro_id {
ACTION_LEDS_ALL, ACTION_LEDS_ALL,
ACTION_LEDS_GAME ACTION_LEDS_GAME,
//TODO: ACTION_LED_LAYER which reads current layer and turns on appropriate LED ACTION_LED_1
}; };
/* /* ==================================
Configuring led control can be done * LED MAPPING
1. full keyboard at a time - define led array, or * ==================================*/
2. individual - send specific led address (defined in keymap.h)
//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
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
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 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 0x34 (pcb row 2) is 17th byte of PWM portion of LED page
array translates to row and column positions 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" //"WASD"
@ -153,7 +164,8 @@ const uint16_t fn_actions[] = {
[0] = ACTION_KEY(LALT(LCTL(KC_DEL))), [0] = ACTION_KEY(LALT(LCTL(KC_DEL))),
[1] = ACTION_LAYER_MODS(_TILDE, MOD_LSFT), [1] = ACTION_LAYER_MODS(_TILDE, MOD_LSFT),
[2] = ACTION_FUNCTION(ACTION_LEDS_ALL), [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; (void)opt;
switch(id) { switch(id) {
case ACTION_LEDS_ALL: case ACTION_LEDS_ALL:
if(record->event.pressed) { if(record->event.pressed) {
// signal the LED controller thread // signal the LED controller thread
chMBPost(&led_mailbox, LED_MSG_GAME_TOGGLE, TIME_IMMEDIATE); chMBPost(&led_mailbox, 1, TIME_IMMEDIATE);
} }
break; break;
case ACTION_LEDS_GAME: case ACTION_LEDS_GAME:
if(record->event.pressed) { if(record->event.pressed) {
// signal the LED controller thread // 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; 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) const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{ {
switch(id) { switch(id) {
case 0: case 0:
if (record->event.pressed) { if (record->event.pressed) {
} }
break; break;
case 1: case 1:
if (record->event.pressed) { if (record->event.pressed) {
} }
break; break;
} }
return MACRO_NONE; return MACRO_NONE;
}; };

View File

@ -36,6 +36,9 @@ void led_set(uint8_t usb_led) {
GPIOA->PCOR |= (1<<5); 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<<USB_LED_CAPS_LOCK)) { if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
// signal the LED control thread // signal the LED control thread
chSysUnconditionalLock(); chSysUnconditionalLock();

View File

@ -112,8 +112,8 @@ msg_t is31_write_register(uint8_t page, uint8_t reg, uint8_t data) {
return i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, tx, 2, NULL, 0, US2ST(IS31_TIMEOUT)); return i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, tx, 2, NULL, 0, US2ST(IS31_TIMEOUT));
} }
msg_t is31_read_register(uint8_t b, uint8_t reg, uint8_t *result) { msg_t is31_read_register(uint8_t page, uint8_t reg, uint8_t *result) {
is31_select_page(b); is31_select_page(page);
tx[0] = reg; tx[0] = reg;
return i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, tx, 1, result, 1, US2ST(IS31_TIMEOUT)); return i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, tx, 1, result, 1, US2ST(IS31_TIMEOUT));
@ -134,6 +134,7 @@ void is31_init(void) {
// software shutdown // software shutdown
is31_write_register(IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, 0); is31_write_register(IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, 0);
chThdSleepMilliseconds(10); chThdSleepMilliseconds(10);
// TODO: This already done above, remove?
// zero function page, all registers // zero function page, all registers
is31_write_data(IS31_FUNCTIONREG, full_page, 0xD + 1); is31_write_data(IS31_FUNCTIONREG, full_page, 0xD + 1);
chThdSleepMilliseconds(10); chThdSleepMilliseconds(10);
@ -159,7 +160,8 @@ static THD_FUNCTION(LEDthread, arg) {
(void)arg; (void)arg;
chRegSetThreadName("LEDthread"); chRegSetThreadName("LEDthread");
uint8_t temp; uint8_t i;
uint8_t temp, pwm;
uint8_t save_page, save_breath1, save_breath2; uint8_t save_page, save_breath1, save_breath2;
msg_t msg, retval; msg_t msg, retval;
@ -170,78 +172,82 @@ static THD_FUNCTION(LEDthread, arg) {
chMBFetch(&led_mailbox, &msg, TIME_INFINITE); chMBFetch(&led_mailbox, &msg, TIME_INFINITE);
// process 'msg' here // process 'msg' here
switch(msg) { // 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: make this generic and able to turn on/off any address and loop through all(or current) pages
case LED_MSG_CAPS_ON: //TODO: set number of layers somewhere and loop through all when setting specific led
// turn caps on on pages 1 and 2 case LED_MSG_SLEEP_LED_ON:
is31_write_register(0, CAPS_LOCK_LED_ADDRESS, 0xFF); // save current settings
is31_write_register(1, CAPS_LOCK_LED_ADDRESS, 0xFF); is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &save_page);
is31_write_register(2, CAPS_LOCK_LED_ADDRESS, 0xFF); is31_read_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, &save_breath1);
break; is31_read_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, &save_breath2);
case LED_MSG_CAPS_OFF: // use pages 7 and 8 for (hardware) breathing (assuming they're empty)
// turn caps off on pages 1 and 2 is31_write_register(6, BREATHE_LED_ADDRESS, 0xFF);
is31_write_register(0, CAPS_LOCK_LED_ADDRESS, 0); is31_write_register(7, BREATHE_LED_ADDRESS, 0x00);
is31_write_register(1, CAPS_LOCK_LED_ADDRESS, 0); is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, (6<<4)|6);
is31_write_register(2, CAPS_LOCK_LED_ADDRESS, 0); is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, IS31_REG_BREATHCTRL2_ENABLE|3);
break; retval = MSG_TIMEOUT;
case LED_MSG_SLEEP_LED_ON: temp = 6;
// save current settings while(retval == MSG_TIMEOUT) {
is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &save_page); // switch to the other page
is31_read_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, &save_breath1); is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, temp);
is31_read_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, &save_breath2); temp = (temp == 6 ? 7 : 6);
// use pages 7 and 8 for (hardware) breathing (assuming they're empty) // the times should be sufficiently long for IS31 to finish switching pages
is31_write_register(6, BREATHE_LED_ADDRESS, 0xFF); retval = chMBFetch(&led_mailbox, &msg, MS2ST(temp == 6 ? 4000 : 6000));
is31_write_register(7, BREATHE_LED_ADDRESS, 0x00); }
is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, (6<<4)|6); // received a message (should be a wakeup), so restore previous state
is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, IS31_REG_BREATHCTRL2_ENABLE|3); chThdSleepMilliseconds(3000); // need to wait until the page change finishes
retval = MSG_TIMEOUT; // note: any other messages are queued
temp = 6; is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, save_breath1);
while(retval == MSG_TIMEOUT) { is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, save_breath2);
// switch to the other page is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, save_page);
is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, temp); break;
temp = (temp == 6 ? 7 : 6); case LED_MSG_SLEEP_LED_OFF:
// the times should be sufficiently long for IS31 to finish switching pages // should not get here; wakeup should be received in the branch above break;
retval = chMBFetch(&led_mailbox, &msg, MS2ST(temp == 6 ? 4000 : 6000)); break;
} default:
// received a message (should be a wakeup), so restore previous state if(msg >= 0x24) {
chThdSleepMilliseconds(3000); // need to wait until the page change finishes xprintf("Power pre-read\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm);
// note: any other messages are queued is31_read_register(0, msg, &temp);
is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, save_breath1); chThdSleepMilliseconds(10);
is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, save_breath2); xprintf("Post-read\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm);
is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, save_page); chThdSleepMilliseconds(10);
break; pwm = (temp > 0x00 ? 0x00 : 0xFF);
case LED_MSG_SLEEP_LED_OFF: xprintf("pwm after: %X\n", pwm);
// should not get here; wakeup should be received in the branch above chThdSleepMilliseconds(10);
break; for(i=0; i<8; i++) {
case LED_MSG_ALL_TOGGLE: is31_write_register(i, msg, pwm);
// read current page into 'temp' }
is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); xprintf("Power post-change\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm);
chThdSleepMilliseconds(1); chThdSleepMilliseconds(10);
// switch to 'the other' page }
if(temp==2) { break;
is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0); }
} else {
is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 2);
}
break;
case LED_MSG_GAME_TOGGLE:
// read current page into 'temp'
is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp);
chThdSleepMilliseconds(1);
// switch to 'the other' page
if(temp==1) {
is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0);
} else {
is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 1);
}
break;
} }
xprintf("--------------------\n");
} }
} }
/* =====================
/* ============= * hook into user keymap
* hook into TMK * ===================== */
* ============= */
void led_controller_init(void) { void led_controller_init(void) {
uint8_t i; uint8_t i;