Updated lock led init

example_keyboards
jpetermans 8 years ago
parent 0881f2dbfa
commit 15635817b5

@ -16,6 +16,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "hal.h" #include "hal.h"
#include "print.h"
#include "led.h" #include "led.h"
@ -26,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* In particular, I2C functions (interrupt-driven) should NOT be called from here. * In particular, I2C functions (interrupt-driven) should NOT be called from here.
*/ */
void led_set(uint8_t usb_led) { void led_set(uint8_t usb_led) {
msg_t msg;
/* /*
// PTA5: LED (1:on/0:off) // PTA5: LED (1:on/0:off)
GPIOA->PDDR |= (1<<1); GPIOA->PDDR |= (1<<1);
@ -36,18 +38,32 @@ void led_set(uint8_t usb_led) {
GPIOA->PCOR |= (1<<5); GPIOA->PCOR |= (1<<5);
} }
*/ */
//TODO: How does this test if led is set if (usb_led & (1<<USB_LED_NUM_LOCK)) {
//usb_led --> led_set(usb_led) <-- chibios/host_keyboard_leds <-- keyboard_leds from usbSetupTransfer // signal the LED control thread
//keyboard_leds is enum'd in chibios/main.c chSysUnconditionalLock();
msg=(TOGGLE_NUM_LOCK << 8) | 1;
chMBPostI(&led_mailbox, msg);
chSysUnconditionalUnlock();
} else {
// signal the LED control thread
xprintf("NUMLOCK OFF\n");
chSysUnconditionalLock();
msg=(TOGGLE_NUM_LOCK << 8) | 0;
chMBPostI(&led_mailbox, msg);
chSysUnconditionalUnlock();
}
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
xprintf("CAPSLOCK ON\n");
chSysUnconditionalLock(); chSysUnconditionalLock();
chMBPostI(&led_mailbox, 0x59); msg=(TOGGLE_CAPS_LOCK << 8) | 1;
chMBPostI(&led_mailbox, msg);
chSysUnconditionalUnlock(); chSysUnconditionalUnlock();
} else { } else {
// signal the LED control thread // signal the LED control thread
chSysUnconditionalLock(); chSysUnconditionalLock();
chMBPostI(&led_mailbox, 0x59); msg=(TOGGLE_CAPS_LOCK << 8) | 0;
chMBPostI(&led_mailbox, msg);
chSysUnconditionalUnlock(); chSysUnconditionalUnlock();
} }
} }

@ -24,6 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "ch.h" #include "ch.h"
#include "hal.h" #include "hal.h"
#include "print.h" #include "print.h"
#include "led.h"
#include "led_controller.h" #include "led_controller.h"
@ -57,11 +58,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* The usual Caps Lock position is C4-6, so the address is * The usual Caps Lock position is C4-6, so the address is
* 0x24 + (4-1)*0x10 + (8-1) = 0x59 */ * 0x24 + (4-1)*0x10 + (8-1) = 0x59 */
#if !defined(CAPS_LOCK_LED_ADDRESS) #if !defined(CAPS_LOCK_LED_ADDRESS)
#define CAPS_LOCK_LED_ADDRESS 0x46 #define CAPS_LOCK_LED_ADDRESS 46
#endif #endif
#if !defined(NUM_LOCK_LED_ADDRESS) #if !defined(NUM_LOCK_LED_ADDRESS)
#define NUM_LOCK_LED_ADDRESS 0x85 #define NUM_LOCK_LED_ADDRESS 85
#endif #endif
/* Which LED should breathe during sleep */ /* Which LED should breathe during sleep */
@ -215,7 +216,6 @@ layer_status = 0;
is31_write_data (7, led_control_reg, 0x12+1); is31_write_data (7, led_control_reg, 0x12+1);
is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7);
layer_status = 7; layer_status = 7;
is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp);
break; break;
case TOGGLE_ALL: case TOGGLE_ALL:
@ -259,10 +259,16 @@ layer_status = 0;
} }
break; break;
case TOGGLE_LOCK_LED: case TOGGLE_NUM_LOCK:
//msg_led = 0-3 for lock flags //msg_led = 0 or 1, off/on
lock_status ^= msg_led; //TODO: confirm toggling works and doesn't get out of sync //TODO: confirm toggling works and doesn't get out of sync
set_lock_leds(led_control_reg, lock_status); 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; break;
case MODE_BREATH: case MODE_BREATH:
@ -335,11 +341,10 @@ layer_status = 0;
* ======================== */ * ======================== */
void set_led_bit (uint8_t *led_control_reg, uint8_t msg_led, uint8_t toggle_on) { void set_led_bit (uint8_t *led_control_reg, uint8_t msg_led, uint8_t toggle_on) {
uint8_t row_byte, column_bit; 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 //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
////first byte is register address 0x00 row_byte = ((msg_led / 10) % 10 - 1 ) * 2 + 1;// A register is every other 8 bits
row_byte = ((msg_led / 10) % 10 - 1 ) * 2 + 1;
column_bit = 1<<(msg_led % 10 - 1); column_bit = 1<<(msg_led % 10 - 1);
if (toggle_on) { 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) { //TODO: not toggling off correctly
uint8_t i; //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_status) { switch(lock_type) {
case 1: case USB_LED_NUM_LOCK:
set_led_bit(led_control_reg, CAPS_LOCK_LED_ADDRESS, 1); led_addr = NUM_LOCK_LED_ADDRESS;
set_led_bit(led_control_reg, NUM_LOCK_LED_ADDRESS, 0); break;
case USB_LED_CAPS_LOCK:
led_addr = CAPS_LOCK_LED_ADDRESS;
break; break;
case 2: #ifdef SCROLL_LOCK_LED_ADDRESS
set_led_bit(led_control_reg, CAPS_LOCK_LED_ADDRESS, 0); case USB_LED_SCROLL_LOCK:
set_led_bit(led_control_reg, NUM_LOCK_LED_ADDRESS, 1); led_addr = SCROLL_LOCK_LED_ADDRESS;
break; break;
case 3: #endif
set_led_bit(led_control_reg, NUM_LOCK_LED_ADDRESS, 1); #ifdef COMPOSE_LED_ADDRESS
set_led_bit(led_control_reg, CAPS_LOCK_LED_ADDRESS, 1); case USB_LED_COMPOSE:
led_addr = COMPOSE_LED_ADDRESS;
break; 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);
for(i=BACKLIGHT_OFF_LOCK_LED_OFF; i<8; i++) { //set in led_controller.h chThdSleepMilliseconds(30);
is31_write_data (i, led_control_reg, 0x12+1); 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) { 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 i;
uint8_t row, col; uint8_t row, col;
uint8_t temp_control_reg[0x13] = {0};//led control register start address + 0x12 bytes 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); is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, IS31_REG_BREATHCTRL2_ENABLE|3);
// clean up the lock LEDs // clean up the lock LEDs
//TODO: adjust for new addressing and additional frames set_lock_leds(USB_LED_NUM_LOCK, 0);
//is31_write_register(1, CAPS_LOCK_LED_ADDRESS, 0); set_lock_leds(USB_LED_CAPS_LOCK, 0);
//is31_write_register(2, CAPS_LOCK_LED_ADDRESS, 0);
/* more time consuming LED processing should be offloaded into /* more time consuming LED processing should be offloaded into
* a thread, with asynchronous messaging. */ * a thread, with asynchronous messaging. */

@ -32,9 +32,9 @@ msg_t is31_read_register(uint8_t page, uint8_t reg, uint8_t *result);
void led_controller_init(void); void led_controller_init(void);
#define CAPS_LOCK_LED_ADDRESS 0x46 #define CAPS_LOCK_LED_ADDRESS 46
#define NUM_LOCK_LED_ADDRESS 0x85 #define NUM_LOCK_LED_ADDRESS 85
#define BACKLIGHT_OFF_LOCK_LED_OFF 1 //set to 0 to show lock leds even if backlight off #define BACKLIGHT_OFF_LOCK_LED_OFF 0 //set to 0 to show lock leds even if backlight off
/* ============================= /* =============================
* IS31 chip related definitions * IS31 chip related definitions
@ -93,7 +93,7 @@ void led_controller_init(void);
extern mailbox_t led_mailbox; extern mailbox_t led_mailbox;
void set_led_bit (uint8_t *led_control_reg, uint8_t led_msg, uint8_t toggle_on); 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); void write_led_page (uint8_t page, const uint8_t *led_array, uint8_t led_count);
// constants for signaling the LED controller thread // constants for signaling the LED controller thread
@ -103,7 +103,8 @@ enum led_msg_t {
TOGGLE_ALL, TOGGLE_ALL,
TOGGLE_BACKLIGHT, TOGGLE_BACKLIGHT,
TOGGLE_LAYER_LEDS, TOGGLE_LAYER_LEDS,
TOGGLE_LOCK_LED, TOGGLE_NUM_LOCK,
TOGGLE_CAPS_LOCK,
MODE_BREATH, MODE_BREATH,
STEP_BRIGHTNESS STEP_BRIGHTNESS
}; };

Loading…
Cancel
Save