mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-05-24 04:25: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 HWURAM 6 /* Userspace RAM */
|
||||||
#define HWETMU 7 /* Extra Timer Units */
|
#define HWETMU 7 /* Extra Timer Units */
|
||||||
#define HWKBD 8 /* Keyboard */
|
#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 */
|
#define HWDD 10 /* Display Driver */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -120,12 +120,28 @@ enum
|
||||||
#define KEYBOARD_QUEUE_SIZE 32
|
#define KEYBOARD_QUEUE_SIZE 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Keyboard frequency analysis, must be at least 64 for the keyboard to work,
|
/* Keyboard frequency analysis is a runtime setting since gint 2.4. This macro
|
||||||
and at most 32768 for the extra timer to support it. Better if a power of 2.
|
is preserved for compatibility until gint 3. */
|
||||||
TODO: Add a runtime setting for KEYBOARD_SCAN_FREQUENCY */
|
#define KEYBOARD_SCAN_FREQUENCY keysc_scan_frequency()
|
||||||
#ifndef KEYBOARD_SCAN_FREQUENCY
|
|
||||||
#define KEYBOARD_SCAN_FREQUENCY 128
|
//---
|
||||||
#endif
|
// 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
|
// Event-level functions
|
||||||
|
|
|
@ -5,15 +5,18 @@
|
||||||
#include <gint/keyboard.h>
|
#include <gint/keyboard.h>
|
||||||
#include <gint/gint.h>
|
#include <gint/gint.h>
|
||||||
#include <gint/defs/types.h>
|
#include <gint/defs/types.h>
|
||||||
|
#include "getkey.h"
|
||||||
|
|
||||||
#ifdef FX9860G
|
#ifdef FX9860G
|
||||||
#include <gint/drivers/t6k11.h>
|
#include <gint/drivers/t6k11.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Delay between a key press and the first repeat, in scan intervals */
|
/* 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 */
|
/* 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 */
|
/* Repeat filter function */
|
||||||
static int (*filter_function)(int key, int duration, int count) = NULL;
|
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 */
|
/* Delay repeat by set amount */
|
||||||
if(s > 0)
|
if(s > 0)
|
||||||
{
|
{
|
||||||
s = (s * KEYBOARD_SCAN_FREQUENCY) / 1000;
|
s = (s * keysc_scan_frequency()) / 1000;
|
||||||
rep_delay += s;
|
rep_delay += s;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -165,8 +168,11 @@ key_event_t getkey_opt(int opt, volatile int *timeout)
|
||||||
/* getkey_repeat(): Set repeat delays for getkey() */
|
/* getkey_repeat(): Set repeat delays for getkey() */
|
||||||
void getkey_repeat(int first, int next)
|
void getkey_repeat(int first, int next)
|
||||||
{
|
{
|
||||||
rep_first = (first * KEYBOARD_SCAN_FREQUENCY) / 1000;
|
rep_first_ms = first;
|
||||||
rep_next = (next * KEYBOARD_SCAN_FREQUENCY) / 1000;
|
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 */
|
/* 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;
|
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/drivers/iokbd.h>
|
||||||
#include <gint/hardware.h>
|
#include <gint/hardware.h>
|
||||||
|
|
||||||
|
#include "getkey.h"
|
||||||
|
|
||||||
#include <stdarg.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
|
// Keyboard buffer
|
||||||
//---
|
//---
|
||||||
|
@ -78,6 +86,38 @@ static int buffer_poll(driver_event_t *ev)
|
||||||
return 0;
|
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 */
|
/* keysc_frame(): Generate driver events from KEYSC state */
|
||||||
static void keysc_frame(void)
|
static void keysc_frame(void)
|
||||||
{
|
{
|
||||||
|
@ -258,20 +298,14 @@ static int callback(void)
|
||||||
/* init() - setup the support timer */
|
/* init() - setup the support timer */
|
||||||
static void init(void)
|
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) */
|
/* Set the default repeat times (milliseconds) */
|
||||||
getkey_repeat(400, 40);
|
getkey_repeat(400, 40);
|
||||||
|
|
||||||
/* The timer will be stopped when the timer driver is unloaded */
|
/* The timer will be stopped when the timer driver is unloaded */
|
||||||
int tid = timer_setup(TIMER_ANY, delay, callback);
|
keysc_tid = timer_setup(TIMER_ANY,keysc_scan_frequency_us(),callback);
|
||||||
if(tid >= 0) timer_start(tid);
|
if(keysc_tid >= 0) timer_start(keysc_tid);
|
||||||
|
|
||||||
gint[HWKBD] = HW_LOADED | (isSH3() ? HWKBD_IO : HWKBD_KSI);
|
gint[HWKBD] = HW_LOADED | (isSH3() ? HWKBD_IO : HWKBD_KSI);
|
||||||
gint[HWKBDSF] = KEYBOARD_SCAN_FREQUENCY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---
|
//---
|
||||||
|
|
Loading…
Add table
Reference in a new issue