mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-28 04:23:36 +01:00
Moved the keyboard to timers. Minor changes in multigetkey() to avoid unwanted event repeats. Beginning of a test application.
This commit is contained in:
parent
037382edb4
commit
9725c2819a
12 changed files with 320 additions and 141 deletions
8
TODO
8
TODO
|
@ -1,7 +1,9 @@
|
|||
- screen, display
|
||||
- timer
|
||||
- gray engine
|
||||
- multi-getkey repeats (if possible, which doesn't seem likely)
|
||||
- getkey() may unwantedly repeat a key if it was triggered for multigetkey()
|
||||
|
||||
- write and test gray engine
|
||||
- full rtc driver (time)
|
||||
- callbacks and complete user API
|
||||
|
||||
_ 7305.h
|
||||
_ libc
|
||||
|
|
124
ginttest.c
124
ginttest.c
|
@ -3,11 +3,26 @@
|
|||
#include <mpu.h>
|
||||
#include <keyboard.h>
|
||||
#include <display.h>
|
||||
#include <timer.h>
|
||||
|
||||
extern unsigned int gint_vbr, bgint, egint, gint_data;
|
||||
|
||||
/*
|
||||
A few procedures for displaying text in the system's vram.
|
||||
*/
|
||||
|
||||
extern void __Print(const char *msg, int x, int y);
|
||||
extern unsigned int gint_vbr, bgint, egint, gint_data;
|
||||
#define print __Print
|
||||
|
||||
void print_clear(void)
|
||||
{
|
||||
char *empty_line = " ";
|
||||
int i = 0;
|
||||
while(i < 8) print(empty_line, 0, i++);
|
||||
}
|
||||
void print(const char *str, int x, int y)
|
||||
{
|
||||
__Print(str, x, y);
|
||||
}
|
||||
void print_hex(unsigned int n, int x, int y)
|
||||
{
|
||||
char ch[11] = "0x";
|
||||
|
@ -19,7 +34,7 @@ void print_hex(unsigned int n, int x, int y)
|
|||
n >>= 4;
|
||||
}
|
||||
ch[10] = 0;
|
||||
print(ch, x, y);
|
||||
__Print(ch, x, y);
|
||||
}
|
||||
void print_bin(unsigned char n, int x, int y)
|
||||
{
|
||||
|
@ -32,9 +47,8 @@ void print_bin(unsigned char n, int x, int y)
|
|||
n >>= 1;
|
||||
}
|
||||
ch[8] = 0;
|
||||
print(ch, x, y);
|
||||
__Print(ch, x, y);
|
||||
}
|
||||
|
||||
void print_hexa(unsigned int n, int digits, int x, int y)
|
||||
{
|
||||
char ch[20];
|
||||
|
@ -47,29 +61,35 @@ void print_hexa(unsigned int n, int digits, int x, int y)
|
|||
}
|
||||
|
||||
ch[digits] = 0;
|
||||
print(ch, x, y);
|
||||
__Print(ch, x, y);
|
||||
}
|
||||
|
||||
// Don't forget to enable key state debugging in the interrupt handler.
|
||||
/*
|
||||
Keyboard tests.
|
||||
*/
|
||||
|
||||
void keyboard_test(void)
|
||||
{
|
||||
const char *names[] = {
|
||||
"MPU_Unkown",
|
||||
"MPU_SH7337",
|
||||
"MPU_SH7355",
|
||||
"MPU_SH7305",
|
||||
"MPU_SH7724",
|
||||
"Error"
|
||||
};
|
||||
/*
|
||||
print_bin(keyboard_state[0], 0, 2);
|
||||
print_bin(keyboard_state[1], 0, 3);
|
||||
print_bin(keyboard_state[2], 0, 4);
|
||||
print_bin(keyboard_state[3], 0, 5);
|
||||
print_bin(keyboard_state[4], 0, 6);
|
||||
|
||||
print_bin(keyboard_state[5], 9, 2);
|
||||
print_bin(keyboard_state[6], 9, 3);
|
||||
print_bin(keyboard_state[7], 9, 4);
|
||||
print_bin(keyboard_state[8], 9, 5);
|
||||
print_bin(keyboard_state[9], 9, 6);
|
||||
*/
|
||||
|
||||
int x = 0;
|
||||
char str[3];
|
||||
int keys[4] = { 0 };
|
||||
int i;
|
||||
|
||||
print(names[MPU_CURRENT < 5 ? MPU_CURRENT : 5], 0, 0);
|
||||
|
||||
print("gint size:", 0, 1);
|
||||
print_hex(&egint - &bgint, 11, 1);
|
||||
print_clear();
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
@ -251,7 +271,7 @@ void btest_gint_icon(void)
|
|||
}
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
void bitmap_test(void)
|
||||
{
|
||||
extern Image binary_symbol_start;
|
||||
extern Image binary_symbol2_start;
|
||||
|
@ -307,5 +327,69 @@ int main(void)
|
|||
dupdate();
|
||||
|
||||
while(getkey() != KEY_EXE);
|
||||
}
|
||||
|
||||
void test(void)
|
||||
{
|
||||
static int x = 0;
|
||||
x++;
|
||||
|
||||
print_hex(x, 0, 0);
|
||||
}
|
||||
|
||||
int main_menu(void)
|
||||
{
|
||||
/*
|
||||
Main menu.
|
||||
*/
|
||||
|
||||
const char *mpu_names[] = {
|
||||
"MPU_Unkown",
|
||||
"MPU_SH7337",
|
||||
"MPU_SH7355",
|
||||
"MPU_SH7305",
|
||||
"MPU_SH7724",
|
||||
"MPU Error !"
|
||||
};
|
||||
int key;
|
||||
|
||||
print_clear();
|
||||
|
||||
print("gint test application", 0, 0);
|
||||
print("---------------------", 0, 1);
|
||||
|
||||
print("[1] Keyboard test", 2, 3);
|
||||
print("[2] Drawing test", 2, 4);
|
||||
|
||||
print("mpu type:", 0, 6);
|
||||
print(mpu_names[MPU_CURRENT < 5 ? MPU_CURRENT : 5], 11, 6);
|
||||
print("gint size:", 0, 7);
|
||||
print_hex(&egint - &bgint, 11, 7);
|
||||
|
||||
while(1)
|
||||
{
|
||||
key = getkey();
|
||||
if(key == KEY_EXIT) return 0;
|
||||
|
||||
if(key == KEY_1) return 1;
|
||||
if(key == KEY_2) return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int app;
|
||||
|
||||
while(1)
|
||||
{
|
||||
app = main_menu();
|
||||
if(!app) break;
|
||||
|
||||
if(app == 1) keyboard_test();
|
||||
if(app == 2) bitmap_test();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
BIN
ginttest.g1a
BIN
ginttest.g1a
Binary file not shown.
|
@ -22,6 +22,20 @@ unsigned int gint_getVBR(void);
|
|||
*/
|
||||
unsigned int gint_systemVBR(void);
|
||||
|
||||
/*
|
||||
gint_setRTCCallback()
|
||||
Sets the callback function for the real-time clock interrupt. If
|
||||
frequency is non-NULL, the clock frequency is set to the given value.
|
||||
*/
|
||||
void gint_setRTCCallback(void (*callback)(void), enum GintFrequency frequency);
|
||||
|
||||
/*
|
||||
gint_getRTCCallback()
|
||||
Returns the callback function. If frequency is non-NULL, it is set to
|
||||
the current frequency value.
|
||||
*/
|
||||
void (*(gint_getRTCCallback)(void))(enum GintFrequency *frequency);
|
||||
|
||||
|
||||
|
||||
//---
|
||||
|
@ -79,8 +93,8 @@ void gint(void) __attribute__((
|
|||
section(".gint.int.entry"),
|
||||
interrupt_handler
|
||||
));
|
||||
void gint_7705(void) __attribute__((section(".gint.int")));
|
||||
void gint_7305(void) __attribute__((section(".gint.int")));
|
||||
void gint_7705(void) __attribute__((section(".gint.int")));
|
||||
void gint_7305(void) __attribute__((section(".gint.int")));
|
||||
|
||||
|
||||
|
||||
|
@ -89,8 +103,11 @@ void gint_7305(void) __attribute__((section(".gint.int")));
|
|||
//---
|
||||
|
||||
#define GINT_INTP_WDT 4
|
||||
#define GINT_INTP_RTC 9
|
||||
#define GINT_INTP_RTC 12
|
||||
|
||||
#define GINT_INTP_GRAY 15
|
||||
#define GINT_INTP_KEY 8
|
||||
#define GINT_INTP_TIMER 10
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -83,42 +83,24 @@
|
|||
// Keyboard configuration.
|
||||
//---
|
||||
|
||||
/*
|
||||
enum KeyboardFrequency
|
||||
Describes the various frequencies available for the keyboard analysis.
|
||||
Default frequency is 16 Hz (system frequency is about 40 Hz). Very few
|
||||
applications will need to change this setting.
|
||||
Be aware that you will miss key hits at low frequencies.
|
||||
At high frequencies, you will lose important execution power. Some
|
||||
loop-driven programs will freeze at 64 Hz because they will never
|
||||
leave the interrupt handling routine. SH3 also have difficulties with
|
||||
64 Hz.
|
||||
*/
|
||||
enum KeyboardFrequency {
|
||||
KeyFreq_500mHz = 7,
|
||||
KeyFreq_1Hz = 6,
|
||||
KeyFreq_2Hz = 5,
|
||||
KeyFreq_4Hz = 4,
|
||||
KeyFreq_16Hz = 3,
|
||||
KeyFreq_64Hz = 2,
|
||||
KeyFreq_256Hz = 1,
|
||||
};
|
||||
|
||||
/*
|
||||
keyboard_setFrequency()
|
||||
Sets the keyboard frequency. Does nothing when the argument is not a
|
||||
valid KeyboardFrequency value.
|
||||
Sets the keyboard frequency. The default frequency is 32 Hz. Very few
|
||||
Very few applications will need to change this setting.
|
||||
The actual frequency is guaranteed to be greater than the argument.
|
||||
Be aware that you will miss key hits at low frequencies. At higher
|
||||
frequencies, you will lose important execution power.
|
||||
|
||||
@arg frequency
|
||||
@arg frequency Frequency in Hz (1 Hz = 1 event / second).
|
||||
*/
|
||||
void keyboard_setFrequency(enum KeyboardFrequency frequency);
|
||||
// Currently not implemented.
|
||||
// void keyboard_setFrequency(int frequency);
|
||||
|
||||
/*
|
||||
keyboard_setRepeatRate()
|
||||
Sets the default repeat rate for key events. The unit for the argument
|
||||
is the keyboard period.
|
||||
For example at 16 Hz, values of (10, 2) will imitate the system
|
||||
default.
|
||||
is the keyboard period. For example at 32 Hz, values of (20, 4) will
|
||||
imitate the system default.
|
||||
Set to 0 to disable repetition. If first = 0, no repetition will be
|
||||
allowed. If first != 0 and next = 0, only one repetition will be
|
||||
allowed.
|
||||
|
@ -170,6 +152,19 @@ enum GetkeyOpt
|
|||
*/
|
||||
int keylast(int *repeat_count);
|
||||
|
||||
/*
|
||||
keystate()
|
||||
Returns the address of the keyboard state array. The keyboard state
|
||||
consists in 10 bytes, in which every key is represented as a bit.
|
||||
The returned address is the original buffer address. You should avoid
|
||||
editing the array. It wouldn't influence the behavior of the keyboard
|
||||
functions, but the buffer data is very volatile. Therefore, data
|
||||
written to the buffer could be replaced anytime.
|
||||
|
||||
@return 10-byte keyboard state buffer.
|
||||
*/
|
||||
volatile unsigned char *keystate(void);
|
||||
|
||||
/*
|
||||
getkey()
|
||||
Blocking function with auto-repeat and SHIFT modifying functionalities.
|
||||
|
@ -251,4 +246,41 @@ int keychar(int key);
|
|||
*/
|
||||
enum KeyType keytype(int key);
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Internal API.
|
||||
// Reference here for documentation purposes only. Do not call.
|
||||
//---
|
||||
|
||||
/*
|
||||
keyboard_interrupt()
|
||||
Notifies the keyboard module that an interrupt request has been issued,
|
||||
and updates the keyboard state.
|
||||
*/
|
||||
void keyboard_interrupt(void) __attribute__((section(".gint.int")));
|
||||
|
||||
/*
|
||||
keyboard_updateState()
|
||||
Updates the keyboard state.
|
||||
|
||||
@arg state 10-byte state buffer.
|
||||
*/
|
||||
void keyboard_updateState_7705(volatile unsigned char *state)
|
||||
__attribute__((section(".gint.int")));
|
||||
void keyboard_updateState_7305(volatile unsigned char *state)
|
||||
__attribute__((section(".gint.int")));
|
||||
|
||||
/*
|
||||
keyboard_init()
|
||||
Starts the keyboard timer.
|
||||
*/
|
||||
void keyboard_init(void) __attribute__((constructor));
|
||||
|
||||
/*
|
||||
keyboard_quit()
|
||||
Stops the keyboard timer.
|
||||
*/
|
||||
void keyboard_quit(void) __attribute__((destructor));
|
||||
|
||||
#endif // _KEYBOARD_H
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
#define TIMER_2 2
|
||||
#define TIMER_TMU2 TIMER_2
|
||||
// Timer function identifiers.
|
||||
#define TIMER_GRAY TIMER_TMU0
|
||||
#define TIMER_USER1 TIMER_TMU1
|
||||
#define TIMER_USER2 TIMER_TMU2
|
||||
#define TIMER_KEYBOARD TIMER_TMU0
|
||||
#define TIMER_GRAY TIMER_TMU1
|
||||
#define TIMER_USER TIMER_TMU2
|
||||
|
||||
// Timer prescalers.
|
||||
#define TIMER_Po_4 0
|
||||
|
@ -31,11 +31,12 @@
|
|||
//---
|
||||
|
||||
/*
|
||||
timer_set()
|
||||
timer_start()
|
||||
Configures and starts a timer.
|
||||
|
||||
@arg timer Timer identifier. Use only TIMER_USER1 and
|
||||
TIMER_USER2.
|
||||
@arg timer Timer name. Use only TIMER_USER. You may use
|
||||
TIMER_GRAY, if you're not running the gray
|
||||
engine.
|
||||
@arg delay Delay before expiration, in clock counts.
|
||||
@arg prescaler Clock prescaler value. Possible values are
|
||||
TIMER_Po_4, TIMER_Po_16, TIMER_Po_64,
|
||||
|
@ -43,7 +44,7 @@
|
|||
@arg callback Callback function.
|
||||
@arg repetitions Number of repetitions, 0 for infinite.
|
||||
*/
|
||||
void timer_set(int timer, int delay, int prescaler, void (*callback)(void),
|
||||
void timer_start(int timer, int delay, int prescaler, void (*callback)(void),
|
||||
int repetitions);
|
||||
|
||||
/*
|
||||
|
@ -68,6 +69,6 @@ void timer_stop(int timer);
|
|||
|
||||
@timer Timer that generated the interrupt.
|
||||
*/
|
||||
void timer_interrupt(int timer);
|
||||
void timer_interrupt(int timer) __attribute__((section(".gint.int")));
|
||||
|
||||
#endif // _TIMER_H
|
||||
|
|
BIN
libc.a
BIN
libc.a
Binary file not shown.
BIN
libgint.a
BIN
libgint.a
Binary file not shown.
|
@ -1,17 +1,17 @@
|
|||
#include <gint.h>
|
||||
#include <timer.h>
|
||||
#include <keyboard.h>
|
||||
#include <7305.h>
|
||||
|
||||
extern void print_hex(unsigned int value, int x, int y);
|
||||
extern void print_bin(unsigned char value, int x, int y);
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Interrupt codes.
|
||||
//---
|
||||
|
||||
#define IC_RTC_PRI 0xaa0
|
||||
#define IC_KEYSC 0xbe0
|
||||
#define IC_TMU0_TUNI0 0x400
|
||||
#define IC_TMU0_TUNI1 0x420
|
||||
#define IC_TMU0_TUNI2 0x440
|
||||
|
||||
|
||||
|
||||
|
@ -19,9 +19,6 @@ extern void print_bin(unsigned char value, int x, int y);
|
|||
// Keyboard management.
|
||||
//---
|
||||
|
||||
extern volatile unsigned char keyboard_state[10];
|
||||
extern void keyboard_interrupt(void);
|
||||
|
||||
/*
|
||||
kdelay()
|
||||
Should sleep during a few milliseconds. Well...
|
||||
|
@ -143,16 +140,14 @@ static int krow(int row)
|
|||
}
|
||||
|
||||
/*
|
||||
kstate()
|
||||
keyboard_updateState()
|
||||
Updates the keyboard state.
|
||||
*/
|
||||
static void kstate(void)
|
||||
void keyboard_updateState_7305(volatile unsigned char *keyboard_state)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 10; i++) keyboard_state[i] = krow(i);
|
||||
|
||||
keyboard_interrupt();
|
||||
}
|
||||
|
||||
|
||||
|
@ -169,23 +164,19 @@ void gint_7305(void)
|
|||
switch(code)
|
||||
{
|
||||
case IC_RTC_PRI:
|
||||
// Clearing the interrupt flag.
|
||||
RTC.RCR2.PEF = 0;
|
||||
// Updating the keyboard state.
|
||||
kstate();
|
||||
/*
|
||||
print_bin(keyboard_state[0], 0, 2);
|
||||
print_bin(keyboard_state[1], 0, 3);
|
||||
print_bin(keyboard_state[2], 0, 4);
|
||||
print_bin(keyboard_state[3], 0, 5);
|
||||
print_bin(keyboard_state[4], 0, 6);
|
||||
break;
|
||||
|
||||
print_bin(keyboard_state[5], 9, 2);
|
||||
print_bin(keyboard_state[6], 9, 3);
|
||||
print_bin(keyboard_state[7], 9, 4);
|
||||
print_bin(keyboard_state[8], 9, 5);
|
||||
print_bin(keyboard_state[9], 9, 6);
|
||||
*/
|
||||
case IC_TMU0_TUNI0:
|
||||
timer_interrupt(TIMER_TMU0);
|
||||
break;
|
||||
|
||||
case IC_TMU0_TUNI1:
|
||||
timer_interrupt(TIMER_TMU1);
|
||||
break;
|
||||
|
||||
case IC_TMU0_TUNI2:
|
||||
timer_interrupt(TIMER_TMU2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -245,7 +236,10 @@ static void gint_priority_lock_7305(void)
|
|||
// Allowing RTC. Keyboard analysis is done regularly using a RTC
|
||||
// because SH7305's special KEYSC interface does not allow us to clear
|
||||
// the keyboard interrupt flags.
|
||||
INTX.IPRK._RTC = GINT_INTP_RTC;
|
||||
INTX.IPRK._RTC = GINT_INTP_RTC;
|
||||
INTX.IPRA.TMU0_0 = GINT_INTP_KEY;
|
||||
INTX.IPRA.TMU0_1 = GINT_INTP_GRAY;
|
||||
INTX.IPRA.TMU0_2 = GINT_INTP_TIMER;
|
||||
}
|
||||
|
||||
static void gint_priority_unlock_7305(void)
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
#include <gint.h>
|
||||
#include <timer.h>
|
||||
#include <keyboard.h>
|
||||
#include <7705.h>
|
||||
|
||||
extern void print_hex(unsigned int value, int x, int y);
|
||||
extern void print_bin(unsigned char value, int x, int y);
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Interrupt codes.
|
||||
//---
|
||||
|
||||
#define IC_RTC_PRI 0x4a0
|
||||
#define IC_PINT07 0x700
|
||||
#define IC_TMU0_TUNI0 0x400
|
||||
#define IC_TMU1_TUNI1 0x420
|
||||
#define IC_TMU2_TUNI2 0x440
|
||||
|
||||
|
||||
|
||||
|
@ -19,12 +19,11 @@ extern void print_bin(unsigned char value, int x, int y);
|
|||
// Keyboard management.
|
||||
//---
|
||||
|
||||
extern volatile unsigned char keyboard_state[10];
|
||||
extern void keyboard_interrupt(void);
|
||||
|
||||
/*
|
||||
kdelay()
|
||||
Low-level sleep using the watchdog.
|
||||
Used to be a low-level sleep using the watchdog, as in the system. This
|
||||
way seems ok at least, and it doesn't create column effects as for
|
||||
SH7305.
|
||||
*/
|
||||
static void kdelay(void)
|
||||
{
|
||||
|
@ -39,7 +38,7 @@ static void kdelay(void)
|
|||
|
||||
#undef r4
|
||||
|
||||
/*
|
||||
/* Watchdog version.
|
||||
const int delay = 0xf4;
|
||||
|
||||
// Disabling the watchdog timer interrupt and resetting the
|
||||
|
@ -64,7 +63,7 @@ static void kdelay(void)
|
|||
|
||||
// Enabling back the watchdog timer interrupt.
|
||||
INTC.IPRB.BIT._WDT = GINT_INTP_WDT;
|
||||
*/
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -134,16 +133,14 @@ static int krow(int row)
|
|||
}
|
||||
|
||||
/*
|
||||
kstate()
|
||||
keyboard_updateState()
|
||||
Updates the keyboard state.
|
||||
*/
|
||||
static void kstate(void)
|
||||
void keyboard_updateState_7705(volatile unsigned char *keyboard_state)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 10; i++) keyboard_state[i] = krow(i);
|
||||
|
||||
keyboard_interrupt();
|
||||
}
|
||||
|
||||
|
||||
|
@ -160,23 +157,19 @@ void gint_7705(void)
|
|||
switch(code)
|
||||
{
|
||||
case IC_RTC_PRI:
|
||||
// Clearing the interrupt flag.
|
||||
RTC.RCR2.BIT.PEF = 0;
|
||||
// Updating the keyboard state.
|
||||
kstate();
|
||||
/*
|
||||
print_bin(keyboard_state[0], 0, 2);
|
||||
print_bin(keyboard_state[1], 0, 3);
|
||||
print_bin(keyboard_state[2], 0, 4);
|
||||
print_bin(keyboard_state[3], 0, 5);
|
||||
print_bin(keyboard_state[4], 0, 6);
|
||||
break;
|
||||
|
||||
print_bin(keyboard_state[5], 9, 2);
|
||||
print_bin(keyboard_state[6], 9, 3);
|
||||
print_bin(keyboard_state[7], 9, 4);
|
||||
print_bin(keyboard_state[8], 9, 5);
|
||||
print_bin(keyboard_state[9], 9, 6);
|
||||
*/
|
||||
case IC_TMU0_TUNI0:
|
||||
timer_interrupt(TIMER_TMU0);
|
||||
break;
|
||||
|
||||
case IC_TMU1_TUNI1:
|
||||
timer_interrupt(TIMER_TMU1);
|
||||
break;
|
||||
|
||||
case IC_TMU2_TUNI2:
|
||||
timer_interrupt(TIMER_TMU2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +207,10 @@ static void gint_priority_lock_7705(void)
|
|||
INTX.IPRH.WORD = 0x0000;
|
||||
|
||||
// Allowing RTC, which handles keyboard.
|
||||
INTC.IPRA.BIT._RTC = GINT_INTP_RTC;
|
||||
INTC.IPRA.BIT._RTC = GINT_INTP_RTC;
|
||||
INTC.IPRA.BIT._TMU0 = GINT_INTP_KEY;
|
||||
INTC.IPRA.BIT._TMU1 = GINT_INTP_GRAY;
|
||||
INTC.IPRA.BIT._TMU2 = GINT_INTP_TIMER;
|
||||
}
|
||||
|
||||
static void gint_priority_unlock_7705(void)
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
#include <keyboard.h>
|
||||
#include <timer.h>
|
||||
#include <mpu.h>
|
||||
|
||||
//---
|
||||
// Keyboard variables.
|
||||
//---
|
||||
|
||||
volatile unsigned char keyboard_state[10] = { 0 };
|
||||
// These ones get modified by interrupts.
|
||||
static volatile unsigned char keyboard_state[10] = { 0 };
|
||||
static volatile int interrupt_flag = 0;
|
||||
|
||||
// Key statistics.
|
||||
static int repeat_first = 10, repeat_next = 2;
|
||||
static int last_key = KEY_NONE, last_repeats = 0, last_events = 0;
|
||||
static volatile int interrupt_flag = 0;
|
||||
|
||||
|
||||
|
||||
|
@ -18,9 +22,9 @@ static volatile int interrupt_flag = 0;
|
|||
|
||||
/*
|
||||
sleep()
|
||||
Puts the CPU in sleep mode and waits for an interrupt to return.
|
||||
Puts the CPU to sleep and waits for an interrupt.
|
||||
*/
|
||||
void sleep(void)
|
||||
static void sleep(void)
|
||||
{
|
||||
__asm__
|
||||
(
|
||||
|
@ -34,7 +38,7 @@ void sleep(void)
|
|||
|
||||
@return A pressed key.
|
||||
*/
|
||||
int getPressedKey(void)
|
||||
static int getPressedKey(void)
|
||||
{
|
||||
int row = 1, column = 0;
|
||||
int state;
|
||||
|
@ -62,7 +66,7 @@ int getPressedKey(void)
|
|||
|
||||
@return Number of actual pressed keys found.
|
||||
*/
|
||||
int getPressedKeys(int *keys, int count)
|
||||
static int getPressedKeys(int *keys, int count)
|
||||
{
|
||||
int row = 1, column;
|
||||
int found = 0, actually_pressed;
|
||||
|
@ -109,16 +113,46 @@ int getPressedKeys(int *keys, int count)
|
|||
return actually_pressed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Interrupt management.
|
||||
//---
|
||||
|
||||
/*
|
||||
keyboard_interrupt()
|
||||
Callback for keyboard update. Allows keyboard analysis functions to
|
||||
wake only when RTC interrupts happen.
|
||||
wake only when keyboard interrupts happen.
|
||||
*/
|
||||
void keyboard_interrupt(void)
|
||||
{
|
||||
if(isSH3())
|
||||
keyboard_updateState_7705(keyboard_state);
|
||||
else
|
||||
keyboard_updateState_7305(keyboard_state);
|
||||
|
||||
interrupt_flag = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
keyboard_init()
|
||||
Starts the keyboard timer.
|
||||
*/
|
||||
void keyboard_init(void)
|
||||
{
|
||||
timer_start(TIMER_KEYBOARD, 1700, TIMER_Po_256, keyboard_interrupt,
|
||||
0);
|
||||
}
|
||||
|
||||
/*
|
||||
keyboard_quit()
|
||||
Stops the keyboard timer.
|
||||
*/
|
||||
void keyboard_quit(void)
|
||||
{
|
||||
timer_stop(TIMER_KEYBOARD);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---
|
||||
|
@ -127,20 +161,12 @@ void keyboard_interrupt(void)
|
|||
|
||||
/*
|
||||
keyboard_setFrequency()
|
||||
Sets the keyboard frequency. Does nothing when the argument is not a
|
||||
valid KeyboardFrequency value.
|
||||
Sets the keyboard frequency.
|
||||
|
||||
@arg frequency
|
||||
@arg frequency In Hz.
|
||||
*/
|
||||
void keyboard_setFrequency(enum KeyboardFrequency frequency)
|
||||
void keyboard_setFrequency(int frequency)
|
||||
{
|
||||
volatile unsigned char *rcr2;
|
||||
|
||||
if(frequency < 1 || frequency > 7) return;
|
||||
rcr2 = (unsigned char *)(isSH3() ? 0xfffffede : 0xa413fede);
|
||||
|
||||
frequency <<= 4;
|
||||
*rcr2 = (*rcr2 & 0x8f) | frequency;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -185,6 +211,21 @@ int keylast(int *repeat_count)
|
|||
|
||||
|
||||
|
||||
/*
|
||||
keystate()
|
||||
Returns the address of the keyboard state array. The returned address
|
||||
if the handler's buffer, therefore it contains volatile data.
|
||||
|
||||
@return 10-byte keyboard state buffer.
|
||||
*/
|
||||
volatile unsigned char *keystate(void)
|
||||
{
|
||||
return keyboard_state;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
getkey()
|
||||
Blocking function with auto-repeat and SHIFT modifying functionalities.
|
||||
|
@ -330,6 +371,18 @@ void multigetkey(int *keys, int count, int max_cycles)
|
|||
if(max_cycles > 0) max_cycles--;
|
||||
|
||||
number = getPressedKeys(keys, count);
|
||||
|
||||
// We need to update the last key data, in case multigetkey()
|
||||
// returns a single key, and getkey() is called a short time
|
||||
// after. Otherwise getkey() could re-send an event for this
|
||||
// key.
|
||||
if(number == 1)
|
||||
{
|
||||
last_key = keys[0];
|
||||
last_repeats = 0;
|
||||
last_events = 0;
|
||||
}
|
||||
|
||||
if(number) return;
|
||||
|
||||
// Handle key repetitions.
|
||||
|
|
|
@ -77,7 +77,7 @@ void timer_get(int timer, struct mod_tmu **tmu, unsigned char **tstr)
|
|||
}
|
||||
|
||||
/*
|
||||
timer_set()
|
||||
timer_start()
|
||||
Configures and starts a timer.
|
||||
|
||||
@arg timer Timer identifier.
|
||||
|
@ -86,7 +86,7 @@ void timer_get(int timer, struct mod_tmu **tmu, unsigned char **tstr)
|
|||
@arg callback Callback function.
|
||||
@arg repetitions Number of repetitions, 0 for infinite.
|
||||
*/
|
||||
void timer_set(int timer, int delay, int prescaler, void (*callback)(void),
|
||||
void timer_start(int timer, int delay, int prescaler, void (*callback)(void),
|
||||
int repetitions)
|
||||
{
|
||||
// Getting the timer address. Using a byte to alter TSTR.
|
||||
|
|
Loading…
Reference in a new issue