mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-28 20:43: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
|
- multi-getkey repeats (if possible, which doesn't seem likely)
|
||||||
- timer
|
- getkey() may unwantedly repeat a key if it was triggered for multigetkey()
|
||||||
- gray engine
|
|
||||||
|
- write and test gray engine
|
||||||
- full rtc driver (time)
|
- full rtc driver (time)
|
||||||
|
- callbacks and complete user API
|
||||||
|
|
||||||
_ 7305.h
|
_ 7305.h
|
||||||
_ libc
|
_ libc
|
||||||
|
|
124
ginttest.c
124
ginttest.c
|
@ -3,11 +3,26 @@
|
||||||
#include <mpu.h>
|
#include <mpu.h>
|
||||||
#include <keyboard.h>
|
#include <keyboard.h>
|
||||||
#include <display.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 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)
|
void print_hex(unsigned int n, int x, int y)
|
||||||
{
|
{
|
||||||
char ch[11] = "0x";
|
char ch[11] = "0x";
|
||||||
|
@ -19,7 +34,7 @@ void print_hex(unsigned int n, int x, int y)
|
||||||
n >>= 4;
|
n >>= 4;
|
||||||
}
|
}
|
||||||
ch[10] = 0;
|
ch[10] = 0;
|
||||||
print(ch, x, y);
|
__Print(ch, x, y);
|
||||||
}
|
}
|
||||||
void print_bin(unsigned char n, int x, int 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;
|
n >>= 1;
|
||||||
}
|
}
|
||||||
ch[8] = 0;
|
ch[8] = 0;
|
||||||
print(ch, x, y);
|
__Print(ch, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_hexa(unsigned int n, int digits, int x, int y)
|
void print_hexa(unsigned int n, int digits, int x, int y)
|
||||||
{
|
{
|
||||||
char ch[20];
|
char ch[20];
|
||||||
|
@ -47,29 +61,35 @@ void print_hexa(unsigned int n, int digits, int x, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch[digits] = 0;
|
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)
|
void keyboard_test(void)
|
||||||
{
|
{
|
||||||
const char *names[] = {
|
/*
|
||||||
"MPU_Unkown",
|
print_bin(keyboard_state[0], 0, 2);
|
||||||
"MPU_SH7337",
|
print_bin(keyboard_state[1], 0, 3);
|
||||||
"MPU_SH7355",
|
print_bin(keyboard_state[2], 0, 4);
|
||||||
"MPU_SH7305",
|
print_bin(keyboard_state[3], 0, 5);
|
||||||
"MPU_SH7724",
|
print_bin(keyboard_state[4], 0, 6);
|
||||||
"Error"
|
|
||||||
};
|
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;
|
int x = 0;
|
||||||
char str[3];
|
char str[3];
|
||||||
int keys[4] = { 0 };
|
int keys[4] = { 0 };
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
print(names[MPU_CURRENT < 5 ? MPU_CURRENT : 5], 0, 0);
|
print_clear();
|
||||||
|
|
||||||
print("gint size:", 0, 1);
|
|
||||||
print_hex(&egint - &bgint, 11, 1);
|
|
||||||
|
|
||||||
while(1)
|
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_symbol_start;
|
||||||
extern Image binary_symbol2_start;
|
extern Image binary_symbol2_start;
|
||||||
|
@ -307,5 +327,69 @@ int main(void)
|
||||||
dupdate();
|
dupdate();
|
||||||
|
|
||||||
while(getkey() != KEY_EXE);
|
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;
|
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);
|
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"),
|
section(".gint.int.entry"),
|
||||||
interrupt_handler
|
interrupt_handler
|
||||||
));
|
));
|
||||||
void gint_7705(void) __attribute__((section(".gint.int")));
|
void gint_7705(void) __attribute__((section(".gint.int")));
|
||||||
void gint_7305(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_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_KEY 8
|
||||||
|
#define GINT_INTP_TIMER 10
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -83,42 +83,24 @@
|
||||||
// Keyboard configuration.
|
// 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()
|
keyboard_setFrequency()
|
||||||
Sets the keyboard frequency. Does nothing when the argument is not a
|
Sets the keyboard frequency. The default frequency is 32 Hz. Very few
|
||||||
valid KeyboardFrequency value.
|
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()
|
keyboard_setRepeatRate()
|
||||||
Sets the default repeat rate for key events. The unit for the argument
|
Sets the default repeat rate for key events. The unit for the argument
|
||||||
is the keyboard period.
|
is the keyboard period. For example at 32 Hz, values of (20, 4) will
|
||||||
For example at 16 Hz, values of (10, 2) will imitate the system
|
imitate the system default.
|
||||||
default.
|
|
||||||
Set to 0 to disable repetition. If first = 0, no repetition will be
|
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. If first != 0 and next = 0, only one repetition will be
|
||||||
allowed.
|
allowed.
|
||||||
|
@ -170,6 +152,19 @@ enum GetkeyOpt
|
||||||
*/
|
*/
|
||||||
int keylast(int *repeat_count);
|
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()
|
getkey()
|
||||||
Blocking function with auto-repeat and SHIFT modifying functionalities.
|
Blocking function with auto-repeat and SHIFT modifying functionalities.
|
||||||
|
@ -251,4 +246,41 @@ int keychar(int key);
|
||||||
*/
|
*/
|
||||||
enum KeyType keytype(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
|
#endif // _KEYBOARD_H
|
||||||
|
|
|
@ -13,9 +13,9 @@
|
||||||
#define TIMER_2 2
|
#define TIMER_2 2
|
||||||
#define TIMER_TMU2 TIMER_2
|
#define TIMER_TMU2 TIMER_2
|
||||||
// Timer function identifiers.
|
// Timer function identifiers.
|
||||||
#define TIMER_GRAY TIMER_TMU0
|
#define TIMER_KEYBOARD TIMER_TMU0
|
||||||
#define TIMER_USER1 TIMER_TMU1
|
#define TIMER_GRAY TIMER_TMU1
|
||||||
#define TIMER_USER2 TIMER_TMU2
|
#define TIMER_USER TIMER_TMU2
|
||||||
|
|
||||||
// Timer prescalers.
|
// Timer prescalers.
|
||||||
#define TIMER_Po_4 0
|
#define TIMER_Po_4 0
|
||||||
|
@ -31,11 +31,12 @@
|
||||||
//---
|
//---
|
||||||
|
|
||||||
/*
|
/*
|
||||||
timer_set()
|
timer_start()
|
||||||
Configures and starts a timer.
|
Configures and starts a timer.
|
||||||
|
|
||||||
@arg timer Timer identifier. Use only TIMER_USER1 and
|
@arg timer Timer name. Use only TIMER_USER. You may use
|
||||||
TIMER_USER2.
|
TIMER_GRAY, if you're not running the gray
|
||||||
|
engine.
|
||||||
@arg delay Delay before expiration, in clock counts.
|
@arg delay Delay before expiration, in clock counts.
|
||||||
@arg prescaler Clock prescaler value. Possible values are
|
@arg prescaler Clock prescaler value. Possible values are
|
||||||
TIMER_Po_4, TIMER_Po_16, TIMER_Po_64,
|
TIMER_Po_4, TIMER_Po_16, TIMER_Po_64,
|
||||||
|
@ -43,7 +44,7 @@
|
||||||
@arg callback Callback function.
|
@arg callback Callback function.
|
||||||
@arg repetitions Number of repetitions, 0 for infinite.
|
@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);
|
int repetitions);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -68,6 +69,6 @@ void timer_stop(int timer);
|
||||||
|
|
||||||
@timer Timer that generated the interrupt.
|
@timer Timer that generated the interrupt.
|
||||||
*/
|
*/
|
||||||
void timer_interrupt(int timer);
|
void timer_interrupt(int timer) __attribute__((section(".gint.int")));
|
||||||
|
|
||||||
#endif // _TIMER_H
|
#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 <gint.h>
|
||||||
|
#include <timer.h>
|
||||||
|
#include <keyboard.h>
|
||||||
#include <7305.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.
|
// Interrupt codes.
|
||||||
//---
|
//---
|
||||||
|
|
||||||
#define IC_RTC_PRI 0xaa0
|
#define IC_RTC_PRI 0xaa0
|
||||||
#define IC_KEYSC 0xbe0
|
#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.
|
// Keyboard management.
|
||||||
//---
|
//---
|
||||||
|
|
||||||
extern volatile unsigned char keyboard_state[10];
|
|
||||||
extern void keyboard_interrupt(void);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
kdelay()
|
kdelay()
|
||||||
Should sleep during a few milliseconds. Well...
|
Should sleep during a few milliseconds. Well...
|
||||||
|
@ -143,16 +140,14 @@ static int krow(int row)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
kstate()
|
keyboard_updateState()
|
||||||
Updates the keyboard state.
|
Updates the keyboard state.
|
||||||
*/
|
*/
|
||||||
static void kstate(void)
|
void keyboard_updateState_7305(volatile unsigned char *keyboard_state)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < 10; i++) keyboard_state[i] = krow(i);
|
for(i = 0; i < 10; i++) keyboard_state[i] = krow(i);
|
||||||
|
|
||||||
keyboard_interrupt();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -169,23 +164,19 @@ void gint_7305(void)
|
||||||
switch(code)
|
switch(code)
|
||||||
{
|
{
|
||||||
case IC_RTC_PRI:
|
case IC_RTC_PRI:
|
||||||
// Clearing the interrupt flag.
|
|
||||||
RTC.RCR2.PEF = 0;
|
RTC.RCR2.PEF = 0;
|
||||||
// Updating the keyboard state.
|
break;
|
||||||
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);
|
|
||||||
|
|
||||||
print_bin(keyboard_state[5], 9, 2);
|
case IC_TMU0_TUNI0:
|
||||||
print_bin(keyboard_state[6], 9, 3);
|
timer_interrupt(TIMER_TMU0);
|
||||||
print_bin(keyboard_state[7], 9, 4);
|
break;
|
||||||
print_bin(keyboard_state[8], 9, 5);
|
|
||||||
print_bin(keyboard_state[9], 9, 6);
|
case IC_TMU0_TUNI1:
|
||||||
*/
|
timer_interrupt(TIMER_TMU1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IC_TMU0_TUNI2:
|
||||||
|
timer_interrupt(TIMER_TMU2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,7 +236,10 @@ static void gint_priority_lock_7305(void)
|
||||||
// Allowing RTC. Keyboard analysis is done regularly using a RTC
|
// Allowing RTC. Keyboard analysis is done regularly using a RTC
|
||||||
// because SH7305's special KEYSC interface does not allow us to clear
|
// because SH7305's special KEYSC interface does not allow us to clear
|
||||||
// the keyboard interrupt flags.
|
// 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)
|
static void gint_priority_unlock_7305(void)
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
#include <gint.h>
|
#include <gint.h>
|
||||||
|
#include <timer.h>
|
||||||
|
#include <keyboard.h>
|
||||||
#include <7705.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.
|
// Interrupt codes.
|
||||||
//---
|
//---
|
||||||
|
|
||||||
#define IC_RTC_PRI 0x4a0
|
#define IC_RTC_PRI 0x4a0
|
||||||
#define IC_PINT07 0x700
|
#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.
|
// Keyboard management.
|
||||||
//---
|
//---
|
||||||
|
|
||||||
extern volatile unsigned char keyboard_state[10];
|
|
||||||
extern void keyboard_interrupt(void);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
kdelay()
|
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)
|
static void kdelay(void)
|
||||||
{
|
{
|
||||||
|
@ -39,7 +38,7 @@ static void kdelay(void)
|
||||||
|
|
||||||
#undef r4
|
#undef r4
|
||||||
|
|
||||||
/*
|
/* Watchdog version.
|
||||||
const int delay = 0xf4;
|
const int delay = 0xf4;
|
||||||
|
|
||||||
// Disabling the watchdog timer interrupt and resetting the
|
// Disabling the watchdog timer interrupt and resetting the
|
||||||
|
@ -64,7 +63,7 @@ static void kdelay(void)
|
||||||
|
|
||||||
// Enabling back the watchdog timer interrupt.
|
// Enabling back the watchdog timer interrupt.
|
||||||
INTC.IPRB.BIT._WDT = GINT_INTP_WDT;
|
INTC.IPRB.BIT._WDT = GINT_INTP_WDT;
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -134,16 +133,14 @@ static int krow(int row)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
kstate()
|
keyboard_updateState()
|
||||||
Updates the keyboard state.
|
Updates the keyboard state.
|
||||||
*/
|
*/
|
||||||
static void kstate(void)
|
void keyboard_updateState_7705(volatile unsigned char *keyboard_state)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < 10; i++) keyboard_state[i] = krow(i);
|
for(i = 0; i < 10; i++) keyboard_state[i] = krow(i);
|
||||||
|
|
||||||
keyboard_interrupt();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,23 +157,19 @@ void gint_7705(void)
|
||||||
switch(code)
|
switch(code)
|
||||||
{
|
{
|
||||||
case IC_RTC_PRI:
|
case IC_RTC_PRI:
|
||||||
// Clearing the interrupt flag.
|
|
||||||
RTC.RCR2.BIT.PEF = 0;
|
RTC.RCR2.BIT.PEF = 0;
|
||||||
// Updating the keyboard state.
|
break;
|
||||||
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);
|
|
||||||
|
|
||||||
print_bin(keyboard_state[5], 9, 2);
|
case IC_TMU0_TUNI0:
|
||||||
print_bin(keyboard_state[6], 9, 3);
|
timer_interrupt(TIMER_TMU0);
|
||||||
print_bin(keyboard_state[7], 9, 4);
|
break;
|
||||||
print_bin(keyboard_state[8], 9, 5);
|
|
||||||
print_bin(keyboard_state[9], 9, 6);
|
case IC_TMU1_TUNI1:
|
||||||
*/
|
timer_interrupt(TIMER_TMU1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IC_TMU2_TUNI2:
|
||||||
|
timer_interrupt(TIMER_TMU2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,7 +207,10 @@ static void gint_priority_lock_7705(void)
|
||||||
INTX.IPRH.WORD = 0x0000;
|
INTX.IPRH.WORD = 0x0000;
|
||||||
|
|
||||||
// Allowing RTC, which handles keyboard.
|
// 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)
|
static void gint_priority_unlock_7705(void)
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
#include <keyboard.h>
|
#include <keyboard.h>
|
||||||
|
#include <timer.h>
|
||||||
#include <mpu.h>
|
#include <mpu.h>
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Keyboard variables.
|
// 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 repeat_first = 10, repeat_next = 2;
|
||||||
static int last_key = KEY_NONE, last_repeats = 0, last_events = 0;
|
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()
|
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__
|
__asm__
|
||||||
(
|
(
|
||||||
|
@ -34,7 +38,7 @@ void sleep(void)
|
||||||
|
|
||||||
@return A pressed key.
|
@return A pressed key.
|
||||||
*/
|
*/
|
||||||
int getPressedKey(void)
|
static int getPressedKey(void)
|
||||||
{
|
{
|
||||||
int row = 1, column = 0;
|
int row = 1, column = 0;
|
||||||
int state;
|
int state;
|
||||||
|
@ -62,7 +66,7 @@ int getPressedKey(void)
|
||||||
|
|
||||||
@return Number of actual pressed keys found.
|
@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 row = 1, column;
|
||||||
int found = 0, actually_pressed;
|
int found = 0, actually_pressed;
|
||||||
|
@ -109,16 +113,46 @@ int getPressedKeys(int *keys, int count)
|
||||||
return actually_pressed;
|
return actually_pressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Interrupt management.
|
||||||
|
//---
|
||||||
|
|
||||||
/*
|
/*
|
||||||
keyboard_interrupt()
|
keyboard_interrupt()
|
||||||
Callback for keyboard update. Allows keyboard analysis functions to
|
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)
|
void keyboard_interrupt(void)
|
||||||
{
|
{
|
||||||
|
if(isSH3())
|
||||||
|
keyboard_updateState_7705(keyboard_state);
|
||||||
|
else
|
||||||
|
keyboard_updateState_7305(keyboard_state);
|
||||||
|
|
||||||
interrupt_flag = 1;
|
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()
|
keyboard_setFrequency()
|
||||||
Sets the keyboard frequency. Does nothing when the argument is not a
|
Sets the keyboard frequency.
|
||||||
valid KeyboardFrequency value.
|
|
||||||
|
|
||||||
@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()
|
getkey()
|
||||||
Blocking function with auto-repeat and SHIFT modifying functionalities.
|
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--;
|
if(max_cycles > 0) max_cycles--;
|
||||||
|
|
||||||
number = getPressedKeys(keys, count);
|
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;
|
if(number) return;
|
||||||
|
|
||||||
// Handle key repetitions.
|
// 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.
|
Configures and starts a timer.
|
||||||
|
|
||||||
@arg timer Timer identifier.
|
@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 callback Callback function.
|
||||||
@arg repetitions Number of repetitions, 0 for infinite.
|
@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)
|
int repetitions)
|
||||||
{
|
{
|
||||||
// Getting the timer address. Using a byte to alter TSTR.
|
// Getting the timer address. Using a byte to alter TSTR.
|
||||||
|
|
Loading…
Reference in a new issue