cleanup a bit, put keyboard init & reading things into a semi-nicer API
still pretty low-level. will be fleshing this out more soon. :-)
This commit is contained in:
parent
d3a8c22b67
commit
7429c134f8
|
@ -8,7 +8,7 @@ project(${PROJECT_NAME} C ASM)
|
|||
set(CMAKE_VERBOSE_MAKEFILE OFF)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
|
||||
add_executable(${PROJECT_NAME}.elf src/main.c)
|
||||
add_executable(${PROJECT_NAME}.elf src/main.c src/gckeybrd.c)
|
||||
|
||||
target_link_directories(${PROJECT_NAME}.elf PRIVATE ${DEVKITPRO}/libogc/lib/wii)
|
||||
target_link_libraries(${PROJECT_NAME}.elf PRIVATE db wiiuse bte ogc m)
|
||||
|
|
83
src/gckeybrd.c
Normal file
83
src/gckeybrd.c
Normal file
|
@ -0,0 +1,83 @@
|
|||
#include <gccore.h>
|
||||
|
||||
#if defined(HW_DOL)
|
||||
#define SI_REG_BASE 0xCC006400
|
||||
#elif defined(HW_RVL)
|
||||
#define SI_REG_BASE 0xCD006400
|
||||
#else
|
||||
#error Hardware model unknown? Missing a preprocessor definition somewhere...
|
||||
#endif
|
||||
|
||||
#define SIREG(n) ((vu32*)(SI_REG_BASE + (n)))
|
||||
|
||||
#define SICOUTBUF(n) (SIREG(0x00 + (n)*12)) /* SI Channel n Output Buffer (Joy-channel n Command) (4 bytes) */
|
||||
#define SICINBUFH(i) (SIREG(0x04 + (i)*12)) /* SI Channel n Input Buffer High (Joy-channel n Buttons 1) (4 bytes) */
|
||||
#define SICINBUFL(i) (SIREG(0x08 + (i)*12)) /* SI Channel n Input Buffer Low (Joy-channel n Buttons 2) (4 bytes) */
|
||||
#define SIPOLL (SIREG(0x30)) /* SI Poll Register (4 bytes) */
|
||||
#define SICOMCSR (SIREG(0x34)) /* SI Communication Control Status Register (command) (4 bytes) */
|
||||
#define SISR (SIREG(0x38)) /* SI Status Register (4 bytes) */
|
||||
#define SIIOBUF (SIREG(0x80)) /* SI I/O buffer (access by word) (128 bytes) */
|
||||
|
||||
#define PAD_ENABLEDMASK(chan) (0x80000000 >> chan)
|
||||
|
||||
static void SI_AwaitPendingCommands(void) {
|
||||
while(*SICOMCSR & 0x1);
|
||||
}
|
||||
|
||||
int GCKB_Detect(void) {
|
||||
SI_AwaitPendingCommands();
|
||||
|
||||
u32 buf[2];
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
SI_GetResponse(i, buf);
|
||||
SI_SetCommand(i, 0x00400300);
|
||||
SI_EnablePolling(PAD_ENABLEDMASK(i));
|
||||
}
|
||||
SI_AwaitPendingCommands();
|
||||
|
||||
int keyboardChan = -1;
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
u32 type = SI_DecodeType(SI_GetType(i));
|
||||
if (type == SI_GC_KEYBOARD)
|
||||
keyboardChan = i;
|
||||
}
|
||||
|
||||
return keyboardChan;
|
||||
}
|
||||
|
||||
int GCKB_Init(int chan) {
|
||||
if (chan == -1)
|
||||
return 0;
|
||||
|
||||
u32 buf[2];
|
||||
|
||||
SI_GetResponse(chan, buf);
|
||||
SI_SetCommand(chan, 0x00540000);
|
||||
SI_EnablePolling(PAD_ENABLEDMASK(chan));
|
||||
SI_TransferCommands();
|
||||
SI_AwaitPendingCommands();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int GCKB_ReadKeys(int chan, u8 *pressedKeys) {
|
||||
if (chan == -1)
|
||||
return 0;
|
||||
if (!pressedKeys)
|
||||
return 0;
|
||||
|
||||
u32 buffer[2];
|
||||
if (SI_GetResponse(chan, buffer)) {
|
||||
pressedKeys[0] = buffer[1] >> 24;
|
||||
pressedKeys[1] = (buffer[1] >> 16) & 0xff;
|
||||
pressedKeys[2] = (buffer[1] >> 8) & 0xff;
|
||||
return 1;
|
||||
} else {
|
||||
pressedKeys[0] = 0;
|
||||
pressedKeys[1] = 0;
|
||||
pressedKeys[2] = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
29
src/gckeybrd.h
Normal file
29
src/gckeybrd.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef GCKEYBRD_H_INCLUDED
|
||||
#define GCKEYBRD_H_INCLUDED
|
||||
|
||||
#include <gctypes.h>
|
||||
|
||||
/**
|
||||
* Attempts to detect the presence of a GC Keyboard Controller connected to any of the controller ports.
|
||||
* Returns the SI channel of the found keyboard controller, or -1 if one could not be found.
|
||||
*/
|
||||
int GCKB_Detect(void);
|
||||
|
||||
/**
|
||||
* Initializes the keyboard controller, previously detected on the given SI channel. This must be called before
|
||||
* key press information can be read. Returns 1 on success, 0 on failure.
|
||||
*/
|
||||
int GCKB_Init(int chan);
|
||||
|
||||
/**
|
||||
* Reads current key press information from the previously initialized keyboard controller, located on the given
|
||||
* SI channel. Returns 1 if key press data has been returned, or 0 on failure.
|
||||
*
|
||||
* The pressedKeys buffer passed in should be large enough to hold 3 bytes. Each byte will correspond to one key
|
||||
* pressed. The keyboard controller can only recognize 3 simultaneous key presses at a time (and, depending on the
|
||||
* specific keys, probably only 2 at a time). If too many keys are held down, all of the values returned will be 0x02.
|
||||
* A value of 0x00 indicates no key press.
|
||||
*/
|
||||
int GCKB_ReadKeys(int chan, u8 *pressedKeys);
|
||||
|
||||
#endif
|
99
src/main.c
99
src/main.c
|
@ -3,72 +3,11 @@
|
|||
#include <gccore.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "gckeybrd.h"
|
||||
|
||||
static void *xfb = NULL;
|
||||
static GXRModeObj *rmode = NULL;
|
||||
|
||||
#if defined(HW_DOL)
|
||||
#define SI_REG_BASE 0xCC006400
|
||||
#elif defined(HW_RVL)
|
||||
#define SI_REG_BASE 0xCD006400
|
||||
#else
|
||||
#error HW model unknown.
|
||||
#endif
|
||||
|
||||
#define SIREG(n) ((vu32*)(SI_REG_BASE + (n)))
|
||||
|
||||
#define SICOUTBUF(n) (SIREG(0x00 + (n)*12)) /* SI Channel n Output Buffer (Joy-channel n Command) (4 bytes) */
|
||||
#define SICINBUFH(i) (SIREG(0x04 + (i)*12)) /* SI Channel n Input Buffer High (Joy-channel n Buttons 1) (4 bytes) */
|
||||
#define SICINBUFL(i) (SIREG(0x08 + (i)*12)) /* SI Channel n Input Buffer Low (Joy-channel n Buttons 2) (4 bytes) */
|
||||
#define SIPOLL (SIREG(0x30)) /* SI Poll Register (4 bytes) */
|
||||
#define SICOMCSR (SIREG(0x34)) /* SI Communication Control Status Register (command) (4 bytes) */
|
||||
#define SISR (SIREG(0x38)) /* SI Status Register (4 bytes) */
|
||||
#define SIIOBUF (SIREG(0x80)) /* SI I/O buffer (access by word) (128 bytes) */
|
||||
|
||||
#define PAD_ENABLEDMASK(chan) (0x80000000 >> chan)
|
||||
|
||||
|
||||
|
||||
static void SI_AwaitPendingCommands(void) {
|
||||
while(*SICOMCSR & 0x1);
|
||||
}
|
||||
|
||||
static int SI_DetectGCKeyboard(void) {
|
||||
SI_AwaitPendingCommands();
|
||||
|
||||
u32 buf[2];
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
SI_GetResponse(i, buf);
|
||||
SI_SetCommand(i, 0x00400300);
|
||||
SI_EnablePolling(PAD_ENABLEDMASK(i));
|
||||
}
|
||||
SI_AwaitPendingCommands();
|
||||
|
||||
int keyboardChan = -1;
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
u32 type = SI_DecodeType(SI_GetType(i));
|
||||
if (type == SI_GC_KEYBOARD)
|
||||
keyboardChan = i;
|
||||
}
|
||||
|
||||
return keyboardChan;
|
||||
}
|
||||
|
||||
static int SI_InitGCKeyboard(int chan) {
|
||||
if (chan == -1)
|
||||
return 0;
|
||||
|
||||
u32 buf[2];
|
||||
|
||||
SI_GetResponse(chan, buf);
|
||||
SI_SetCommand(chan, 0x00540000);
|
||||
SI_EnablePolling(PAD_ENABLEDMASK(chan));
|
||||
SI_TransferCommands();
|
||||
SI_AwaitPendingCommands();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
VIDEO_Init();
|
||||
|
@ -87,31 +26,27 @@ int main(int argc, char **argv) {
|
|||
|
||||
printf("\n\nHello ...\n");
|
||||
|
||||
DEBUG_Init(GDBSTUB_DEVICE_USB,1);
|
||||
printf("Waiting for debugger ...\n");
|
||||
_break();
|
||||
printf("debugger connected ...\n");
|
||||
//DEBUG_Init(GDBSTUB_DEVICE_USB,1);
|
||||
//printf("Waiting for debugger ...\n");
|
||||
//_break();
|
||||
//printf("debugger connected ...\n");
|
||||
|
||||
PAD_Init();
|
||||
|
||||
int keyboardChan = SI_DetectGCKeyboard();
|
||||
printf("Keyboard located at chan %d\n", keyboardChan);
|
||||
int keyboardChan = GCKB_Detect();
|
||||
printf("GC Keyboard located at chan %d\n", keyboardChan);
|
||||
|
||||
int keyboardEnabled = SI_InitGCKeyboard(keyboardChan);
|
||||
int keyboardEnabled = GCKB_Init(keyboardChan);
|
||||
if (keyboardEnabled)
|
||||
printf("keyboard initialized on chan %d\n", keyboardChan);
|
||||
printf("GC Keyboard initialized on chan %d\n", keyboardChan);
|
||||
|
||||
printf("start of main loop ...\n");
|
||||
printf("Start of main loop.\nPress Start on the controller plugged into slot 1 to exit ...\n");
|
||||
while(1) {
|
||||
if (keyboardEnabled) {
|
||||
u32 buf[2];
|
||||
if (SI_GetResponse(keyboardChan, buf)) {
|
||||
u8 key1 = buf[1] >> 24;
|
||||
u8 key2 = (buf[1] >> 16) & 0xff;
|
||||
u8 key3 = (buf[1] >> 8) & 0xff;
|
||||
if (key1 | key2 | key3)
|
||||
printf("keyboard data - raw: 0x%08x 0x%08x - keys: 0x%02x, 0x%02x, 0x%02x\n",
|
||||
buf[0], buf[1], key1, key2, key3);
|
||||
u8 keys[3];
|
||||
if (GCKB_ReadKeys(keyboardChan, keys)) {
|
||||
if (keys[0] | keys[1] | keys[2])
|
||||
printf("keys pressed: 0x%02x, 0x%02x, 0x%02x\n", keys[0], keys[1], keys[2]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,10 +59,6 @@ int main(int argc, char **argv) {
|
|||
printf("exiting ...\n");
|
||||
exit(0);
|
||||
}
|
||||
if (pressed & PAD_BUTTON_A) {
|
||||
_break();
|
||||
printf("A pressed\n");
|
||||
}
|
||||
|
||||
VIDEO_WaitVSync();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue