From 954611926eef2b429fafbe833bf291e7771eedaf Mon Sep 17 00:00:00 2001 From: sorgelig Date: Thu, 29 Dec 2016 08:33:47 +0800 Subject: [PATCH] Enable Keyboard LEDs (Caps Lock, Num Lock, Scroll Lock) control from FPGA. --- user_io.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++---- user_io.h | 14 ++++++++++++ 2 files changed, 77 insertions(+), 5 deletions(-) diff --git a/user_io.c b/user_io.c index ded4fe6..5130db0 100644 --- a/user_io.c +++ b/user_io.c @@ -66,6 +66,14 @@ static int16_t mouse_pos[2] = { 0, 0}; static uint8_t mouse_flags = 0; static unsigned long mouse_timer; +#define LED_FREQ 100 // 100 ms +static unsigned long led_timer; +char keyboard_leds = 0; +bool caps_status = 0; +bool num_status = 0; +bool scrl_status = 0; + + // set by OSD code to suppress forwarding of those keys to the core which // may be in use by an active OSD static char osd_is_visible = false; @@ -460,6 +468,17 @@ uint8_t user_io_sd_get_status(uint32_t *lba) { return c; } +// read 8 bit keyboard LEDs status from FPGA +uint8_t user_io_kbdled_get_status(void) { + uint8_t c; + + spi_uio_cmd_cont(UIO_GET_KBD_LED); + c = spi_in(); + DisableIO(); + + return c; +} + // read 32 bit ethernet status word from FPGA uint32_t user_io_eth_get_status(void) { uint32_t s; @@ -733,6 +752,27 @@ void user_io_send_buttons(char force) { } } +void set_kbd_led(unsigned char led, bool on) +{ + if(led & HID_LED_CAPS_LOCK) + { + if(!(keyboard_leds & KBD_LED_CAPS_CONTROL)) hid_set_kbd_led(led, on); + caps_status = on; + } + + if(led & HID_LED_NUM_LOCK) + { + if(!(keyboard_leds & KBD_LED_NUM_CONTROL)) hid_set_kbd_led(led, on); + num_status = on; + } + + if(led & HID_LED_SCROLL_LOCK) + { + if(!(keyboard_leds & KBD_LED_SCRL_CONTROL)) hid_set_kbd_led(led, on); + scrl_status = on; + } +} + void user_io_poll() { // check of core has changed from a good one to a not supported on @@ -1237,6 +1277,24 @@ void user_io_poll() { if(core_type == CORE_TYPE_ARCHIE) archie_poll(); + + if(CheckTimer(led_timer)) + { + led_timer = GetTimer(LED_FREQ); + uint8_t leds = user_io_kbdled_get_status(); + if((leds & KBD_LED_FLAG_MASK) != KBD_LED_FLAG_STATUS) leds = 0; + + if((keyboard_leds & KBD_LED_CAPS_MASK) != (leds & KBD_LED_CAPS_MASK)) + hid_set_kbd_led(HID_LED_CAPS_LOCK, (leds & KBD_LED_CAPS_CONTROL) ? leds & KBD_LED_CAPS_STATUS : caps_status); + + if((keyboard_leds & KBD_LED_NUM_MASK) != (leds & KBD_LED_NUM_MASK)) + hid_set_kbd_led(HID_LED_NUM_LOCK, (leds & KBD_LED_NUM_CONTROL) ? leds & KBD_LED_NUM_STATUS : num_status); + + if((keyboard_leds & KBD_LED_SCRL_MASK) != (leds & KBD_LED_SCRL_MASK)) + hid_set_kbd_led(HID_LED_SCROLL_LOCK, (leds & KBD_LED_SCRL_CONTROL) ? leds & KBD_LED_SCRL_STATUS : scrl_status); + + keyboard_leds = leds; + } } char user_io_dip_switch1() { @@ -1816,7 +1874,7 @@ void user_io_kbd(unsigned char m, unsigned char *k, uint8_t priority, unsigned s send_keycode((code & 0xff) | (caps_lock_toggle?BREAK:0)); caps_lock_toggle = !caps_lock_toggle; - hid_set_kbd_led(HID_LED_CAPS_LOCK, caps_lock_toggle); + set_kbd_led(HID_LED_CAPS_LOCK, caps_lock_toggle); } if(code & NUM_LOCK_TOGGLE) @@ -1830,11 +1888,11 @@ void user_io_kbd(unsigned char m, unsigned char *k, uint8_t priority, unsigned s if(emu_mode == EMU_MOUSE) emu_timer = GetTimer(EMU_MOUSE_FREQ); emu_mode = (emu_mode+1)&3; - if(emu_mode == EMU_MOUSE || emu_mode == EMU_JOY0) hid_set_kbd_led(HID_LED_NUM_LOCK, true); - else hid_set_kbd_led(HID_LED_NUM_LOCK, false); + if(emu_mode == EMU_MOUSE || emu_mode == EMU_JOY0) set_kbd_led(HID_LED_NUM_LOCK, true); + else set_kbd_led(HID_LED_NUM_LOCK, false); - if(emu_mode == EMU_MOUSE || emu_mode == EMU_JOY1) hid_set_kbd_led(HID_LED_SCROLL_LOCK, true); - else hid_set_kbd_led(HID_LED_SCROLL_LOCK, false); + if(emu_mode == EMU_MOUSE || emu_mode == EMU_JOY1) set_kbd_led(HID_LED_SCROLL_LOCK, true); + else set_kbd_led(HID_LED_SCROLL_LOCK, false); } } } diff --git a/user_io.h b/user_io.h index 194c990..eb9bc27 100644 --- a/user_io.h +++ b/user_io.h @@ -51,6 +51,7 @@ #define UIO_SET_SDSTAT 0x1c // set sd card status #define UIO_SET_SDINFO 0x1d // send info about mounted image #define UIO_SET_STATUS2 0x1e // 32bit status +#define UIO_GET_KBD_LED 0x1f // keyboard LEDs control // codes as used by 8bit (atari 800, zx81) via SS2 #define UIO_GET_STATUS 0x50 @@ -91,6 +92,19 @@ #define JOY_L3 0x4000 #define JOY_R3 0x8000 +// keyboard LEDs control +#define KBD_LED_CAPS_CONTROL 0x01 +#define KBD_LED_CAPS_STATUS 0x02 +#define KBD_LED_CAPS_MASK (KBD_LED_CAPS_CONTROL | KBD_LED_CAPS_STATUS) +#define KBD_LED_NUM_CONTROL 0x04 +#define KBD_LED_NUM_STATUS 0x08 +#define KBD_LED_NUM_MASK (KBD_LED_NUM_CONTROL | KBD_LED_NUM_STATUS) +#define KBD_LED_SCRL_CONTROL 0x10 +#define KBD_LED_SCRL_STATUS 0x20 +#define KBD_LED_SCRL_MASK (KBD_LED_SCRL_CONTROL | KBD_LED_SCRL_STATUS) +#define KBD_LED_FLAG_MASK 0xC0 +#define KBD_LED_FLAG_STATUS 0x40 + #define CONF_SCANDOUBLER_DISABLE 0x10 // core type value should be unlikely to be returned by broken cores