mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-05-23 20:15:10 +02:00
add a dynamic setting for keyboard scan frequency
The repeat delays of getkey() are adjusted automatically, however a repeat that is currently going on might be affected. Also, repeat delays are always approximated as a whole number of keyboard scans so an increase in scan frequency can impact the speed at which repeats are emitted.
This commit is contained in:
parent
6440527527
commit
ee7b4f27b8
5 changed files with 93 additions and 20 deletions
|
@ -64,7 +64,7 @@ void hw_detect(void);
|
|||
#define HWURAM 6 /* Userspace RAM */
|
||||
#define HWETMU 7 /* Extra Timer Units */
|
||||
#define HWKBD 8 /* Keyboard */
|
||||
#define HWKBDSF 9 /* Keyboard Scan Frequency (set iff HWKBD is loaded) */
|
||||
#define HWKBDSF /* Deprecated: use keysc_scan_frequency() */
|
||||
#define HWDD 10 /* Display Driver */
|
||||
|
||||
/*
|
||||
|
|
|
@ -120,12 +120,28 @@ enum
|
|||
#define KEYBOARD_QUEUE_SIZE 32
|
||||
#endif
|
||||
|
||||
/* Keyboard frequency analysis, must be at least 64 for the keyboard to work,
|
||||
and at most 32768 for the extra timer to support it. Better if a power of 2.
|
||||
TODO: Add a runtime setting for KEYBOARD_SCAN_FREQUENCY */
|
||||
#ifndef KEYBOARD_SCAN_FREQUENCY
|
||||
#define KEYBOARD_SCAN_FREQUENCY 128
|
||||
#endif
|
||||
/* Keyboard frequency analysis is a runtime setting since gint 2.4. This macro
|
||||
is preserved for compatibility until gint 3. */
|
||||
#define KEYBOARD_SCAN_FREQUENCY keysc_scan_frequency()
|
||||
|
||||
//---
|
||||
// Scan frequency settings
|
||||
//---
|
||||
|
||||
/* keysc_scan_frequency(): Get the current keyboard scan frequency in Hertz */
|
||||
int keysc_scan_frequency(void);
|
||||
|
||||
/* keysc_scan_frequency_us(): Get keyboard scan delay in microseconds */
|
||||
uint32_t keysc_scan_frequency_us(void);
|
||||
|
||||
/* keysc_set_scan_frequency(): Set the keyboard scan frequency in Hertz
|
||||
|
||||
The new frequency must be at least 64 for the keyboard to work reliably, and
|
||||
at most 32768 for the underlying ETMU to support it. Out-of-range values are
|
||||
forced to the closest valid value.
|
||||
|
||||
@freq New scan frequency, in Hertz */
|
||||
void keysc_set_scan_frequency(int freq);
|
||||
|
||||
//---
|
||||
// Event-level functions
|
||||
|
|
|
@ -5,15 +5,18 @@
|
|||
#include <gint/keyboard.h>
|
||||
#include <gint/gint.h>
|
||||
#include <gint/defs/types.h>
|
||||
#include "getkey.h"
|
||||
|
||||
#ifdef FX9860G
|
||||
#include <gint/drivers/t6k11.h>
|
||||
#endif
|
||||
|
||||
/* Delay between a key press and the first repeat, in scan intervals */
|
||||
static int rep_first = 64;
|
||||
static int rep_first = 51;
|
||||
/* Delay between subsequent repeats, in scan intervals */
|
||||
static int rep_next = 8;
|
||||
static int rep_next = 5;
|
||||
/* Same in milliseconds (values supplied by the user */
|
||||
static int rep_first_ms = 400, rep_next_ms = 40;
|
||||
|
||||
/* Repeat filter function */
|
||||
static int (*filter_function)(int key, int duration, int count) = NULL;
|
||||
|
@ -132,7 +135,7 @@ key_event_t getkey_opt(int opt, volatile int *timeout)
|
|||
/* Delay repeat by set amount */
|
||||
if(s > 0)
|
||||
{
|
||||
s = (s * KEYBOARD_SCAN_FREQUENCY) / 1000;
|
||||
s = (s * keysc_scan_frequency()) / 1000;
|
||||
rep_delay += s;
|
||||
break;
|
||||
}
|
||||
|
@ -165,8 +168,11 @@ key_event_t getkey_opt(int opt, volatile int *timeout)
|
|||
/* getkey_repeat(): Set repeat delays for getkey() */
|
||||
void getkey_repeat(int first, int next)
|
||||
{
|
||||
rep_first = (first * KEYBOARD_SCAN_FREQUENCY) / 1000;
|
||||
rep_next = (next * KEYBOARD_SCAN_FREQUENCY) / 1000;
|
||||
rep_first_ms = first;
|
||||
rep_next_ms = next;
|
||||
|
||||
rep_first = (first * keysc_scan_frequency()) / 1000;
|
||||
rep_next = (next * keysc_scan_frequency()) / 1000;
|
||||
}
|
||||
|
||||
/* getkey_repeat_filter(): Set the repeat filter function */
|
||||
|
@ -174,3 +180,9 @@ void getkey_repeat_filter(int (*filter)(int key, int duration, int count))
|
|||
{
|
||||
filter_function = filter;
|
||||
}
|
||||
|
||||
/* Refresh repeat delays after a change in keyboard scan frequency */
|
||||
void getkey_refresh_delays(void)
|
||||
{
|
||||
getkey_repeat(rep_first_ms, rep_next_ms);
|
||||
}
|
||||
|
|
11
src/keysc/getkey.h
Normal file
11
src/keysc/getkey.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
//---
|
||||
// gint:keysc:getkey - Internal interface to getkey()
|
||||
//---
|
||||
|
||||
#ifndef GINT_KEYSC_GETKEY
|
||||
#define GINT_KEYSC_GETKEY
|
||||
|
||||
/* Refresh repeat delays after a change in keyboard scan frequency */
|
||||
void getkey_refresh_delays(void);
|
||||
|
||||
#endif /* GINT_KEYSC_GETKEY */
|
|
@ -13,8 +13,16 @@
|
|||
#include <gint/drivers/iokbd.h>
|
||||
#include <gint/hardware.h>
|
||||
|
||||
#include "getkey.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
/* Keyboard scan frequency in Hertz. Start with 128 Hz, this frequency *must
|
||||
be high* for the keyboard to work! */
|
||||
static int scan_frequency = 128;
|
||||
/* Keyboard scanner timer */
|
||||
static int keysc_tid = -1;
|
||||
|
||||
//---
|
||||
// Keyboard buffer
|
||||
//---
|
||||
|
@ -78,6 +86,38 @@ static int buffer_poll(driver_event_t *ev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//---
|
||||
// Keyboard scanning
|
||||
//---
|
||||
|
||||
/* keysc_scan_frequency(): Get the current keyboard scan frequency in Hertz */
|
||||
int keysc_scan_frequency(void)
|
||||
{
|
||||
return scan_frequency;
|
||||
}
|
||||
|
||||
/* keysc_scan_frequency_us(): Get keyboard scan delay in microseconds */
|
||||
uint32_t keysc_scan_frequency_us(void)
|
||||
{
|
||||
int delay = 1000000 / scan_frequency;
|
||||
if(delay == 0) delay = 1;
|
||||
return delay;
|
||||
}
|
||||
|
||||
/* keysc_set_scan_frequency(): Set the keyboard scan frequency in Hertz */
|
||||
void keysc_set_scan_frequency(int freq)
|
||||
{
|
||||
if(freq < 64) freq = 64;
|
||||
if(freq > 32768) freq = 32768;
|
||||
scan_frequency = freq;
|
||||
|
||||
if(keysc_tid < 0) return;
|
||||
uint32_t TCOR = timer_delay(keysc_tid, keysc_scan_frequency_us(), 0);
|
||||
timer_reload(keysc_tid, TCOR);
|
||||
|
||||
getkey_refresh_delays();
|
||||
}
|
||||
|
||||
/* keysc_frame(): Generate driver events from KEYSC state */
|
||||
static void keysc_frame(void)
|
||||
{
|
||||
|
@ -258,20 +298,14 @@ static int callback(void)
|
|||
/* init() - setup the support timer */
|
||||
static void init(void)
|
||||
{
|
||||
/* Configure the timer to do 128 keyboard scans per second. This
|
||||
frequency *must* be high for the KEYSC interface to work! */
|
||||
int delay = 1000000 / KEYBOARD_SCAN_FREQUENCY;
|
||||
if(!delay) delay = 1;
|
||||
|
||||
/* Set the default repeat times (milliseconds) */
|
||||
getkey_repeat(400, 40);
|
||||
|
||||
/* The timer will be stopped when the timer driver is unloaded */
|
||||
int tid = timer_setup(TIMER_ANY, delay, callback);
|
||||
if(tid >= 0) timer_start(tid);
|
||||
keysc_tid = timer_setup(TIMER_ANY,keysc_scan_frequency_us(),callback);
|
||||
if(keysc_tid >= 0) timer_start(keysc_tid);
|
||||
|
||||
gint[HWKBD] = HW_LOADED | (isSH3() ? HWKBD_IO : HWKBD_KSI);
|
||||
gint[HWKBDSF] = KEYBOARD_SCAN_FREQUENCY;
|
||||
}
|
||||
|
||||
//---
|
||||
|
|
Loading…
Add table
Reference in a new issue