From 51115a97853a71d36aeea6e51d375b97fb56b0a1 Mon Sep 17 00:00:00 2001 From: profi200 Date: Tue, 5 May 2020 23:27:34 +0200 Subject: [PATCH] =?UTF-8?q?Added=20Circle-Pad=20controls.=20Costs=20about?= =?UTF-8?q?=2030=20=C2=B5s=20frame=20time.=20Note:=20No=20calibration=20su?= =?UTF-8?q?pport=20yet.=20If=20your=20Circle-Pad=20is=20in=20bad=20shape?= =?UTF-8?q?=20or=20came=20out=20of=20the=20factory=20with=20drift=20this?= =?UTF-8?q?=20will=20certainly=20break.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/arm11/hardware/codec.h | 15 ++++++- include/arm11/hardware/hid.h | 9 ++++- source/arm11/hardware/codec.c | 17 +++++--- source/arm11/hardware/hid.c | 74 +++++++++++++++++----------------- source/arm11/hardware/lgy.c | 11 +++++ source/arm11/main.c | 8 ++-- 6 files changed, 85 insertions(+), 49 deletions(-) diff --git a/include/arm11/hardware/codec.h b/include/arm11/hardware/codec.h index 59a4aa5..d061820 100644 --- a/include/arm11/hardware/codec.h +++ b/include/arm11/hardware/codec.h @@ -21,6 +21,15 @@ #include "types.h" +typedef struct +{ + u16 touchX[5]; + u16 touchY[5]; + u16 cpadY[8]; + u16 cpadX[8]; +} CdcAdcData; + + /** * @brief Initialize CODEC for Circle-Pad/Touchscreen/Sound. @@ -40,6 +49,8 @@ void CODEC_wakeup(void); /** * @brief Get raw ADC data for Circle-Pad/Touchscreen. * - * @param[in] buf The buffer to write the data to. + * @param data The output data pointer. Must be 4 bytes aligned. + * + * @return Returns true if data was available and false otherwise. */ -void CODEC_getRawAdcData(u32 buf[13]); +bool CODEC_getRawAdcData(CdcAdcData *data); diff --git a/include/arm11/hardware/hid.h b/include/arm11/hardware/hid.h index c6f29c8..4caa1d1 100644 --- a/include/arm11/hardware/hid.h +++ b/include/arm11/hardware/hid.h @@ -64,6 +64,11 @@ enum KEY_DOWN = KEY_DDOWN | KEY_CPAD_DOWN, // D-Pad Down or Circle Pad Down KEY_LEFT = KEY_DLEFT | KEY_CPAD_LEFT, // D-Pad Left or Circle Pad Left KEY_RIGHT = KEY_DRIGHT | KEY_CPAD_RIGHT, // D-Pad Right or Circle Pad Right + + // Masks + KEY_DPAD = KEY_DDOWN | KEY_DUP | KEY_DLEFT | KEY_DRIGHT, + KEY_CSTICK = KEY_CSTICK_DOWN | KEY_CSTICK_UP | KEY_CSTICK_LEFT | KEY_CSTICK_RIGHT, + KEY_CPAD = KEY_CPAD_DOWN | KEY_CPAD_UP | KEY_CPAD_LEFT | KEY_CPAD_RIGHT }; // Extra keys use with hidGetExtraKeys() @@ -97,6 +102,6 @@ void hidScanInput(void); u32 hidKeysHeld(void); u32 hidKeysDown(void); u32 hidKeysUp(void); -//const TouchPos* hidGetTouchPosPtr(void); -//const CpadPos* hidGetCpadPosPtr(void); +const TouchPos* hidGetTouchPosPtr(void); +const CpadPos* hidGetCpadPosPtr(void); u32 hidGetExtraKeys(u32 clearMask); diff --git a/source/arm11/hardware/codec.c b/source/arm11/hardware/codec.c index 7666b5b..e60b981 100644 --- a/source/arm11/hardware/codec.c +++ b/source/arm11/hardware/codec.c @@ -19,6 +19,7 @@ // Based on code from https://github.com/xerpi/linux_3ds/blob/master/drivers/input/misc/nintendo3ds_codec_hid.c #include "types.h" +#include "arm11/hardware/codec.h" #include "arm11/hardware/spi.h" #include "arm11/hardware/timer.h" #include "arm11/hardware/gpio.h" @@ -440,11 +441,17 @@ void CODEC_wakeup(void) TIMER_sleepMs(18); // Fixed 18 ms delay when unsetting this GPIO. } -void CODEC_getRawAdcData(u32 buf[13]) +bool CODEC_getRawAdcData(CdcAdcData *data) { - //codecSwitchBank(0x67); - // This reg read seems useless and doesn't affect funtionality. - //codecReadReg(0x26); + if((codecReadReg(0x67, 0x26) & 2u) == 0) + { + codecReadRegBuf(0xFB, 1, (u32*)data, sizeof(CdcAdcData)); - codecReadRegBuf(0xFB, 1, buf, 52); + return true; + } + + // Codec module does this when data is unavailable. Why? + //codecSwitchBank(0); + + return false; } diff --git a/source/arm11/hardware/hid.c b/source/arm11/hardware/hid.c index 234450e..eb0cb0a 100644 --- a/source/arm11/hardware/hid.c +++ b/source/arm11/hardware/hid.c @@ -32,10 +32,10 @@ #define CPAD_THRESHOLD (400) -static u32 kHeld, kDown, kUp; -static u32 extraKeys; -//TouchPos tPos; -//CpadPos cPos; +static u32 g_kHeld = 0, g_kDown = 0, g_kUp = 0; +static u32 g_extraKeys = 0; +TouchPos tPos = {0}; +CpadPos cPos = {0}; @@ -45,17 +45,15 @@ void hidInit(void) if(inited) return; inited = true; - kUp = kDown = kHeld = 0; - MCU_init(); u8 state = MCU_getExternalHwState(); u32 tmp = ~state<<3 & KEY_SHELL; // Current shell state. Bit is inverted. tmp |= state<<1 & KEY_BAT_CHARGING; // Current battery charging state state = MCU_getHidHeld(); tmp |= ~state<<1 & KEY_HOME; // Current HOME button state - extraKeys = tmp; + g_extraKeys = tmp; - //CODEC_init(); + CODEC_init(); } static void updateMcuHidState(void) @@ -63,7 +61,7 @@ static void updateMcuHidState(void) const u32 state = MCU_getEvents(0x40C07F); if(state == 0) return; - u32 tmp = extraKeys; + u32 tmp = g_extraKeys; tmp |= state & (KEY_POWER | KEY_POWER_HELD | KEY_HOME); // Power button pressed/held, HOME button pressed if(state & 1u<<3) tmp &= ~KEY_HOME; // HOME released tmp |= state>>1 & (KEY_WIFI | KEY_SHELL); // WiFi switch, shell closed @@ -71,64 +69,68 @@ static void updateMcuHidState(void) tmp |= state>>10 & KEY_BAT_CHARGING; // Battery started charging if(state & 1u<<14) tmp &= ~KEY_BAT_CHARGING; // Battery stopped charging tmp |= state>>16 & KEY_VOL_SLIDER; // Volume slider update - extraKeys = tmp; + g_extraKeys = tmp; } -/*static u32 rawCodec2Hid(void) +static u32 rawCodec2Hid(void) { - alignas(4) u8 buf[13 * 4]; - - CODEC_getRawAdcData((u32*)buf); + static u32 fakeKeysCache = 0; + alignas(4) CdcAdcData adc; + if(!CODEC_getRawAdcData(&adc)) return fakeKeysCache; // Touchscreen - u32 emuButtons = !(buf[0] & 1u<<4)<<20; // KEY_TOUCH - tPos.x = (buf[0]<<8 | buf[1]) * 320u / 4096u; // TODO: Calibration - tPos.y = (buf[10]<<8 | buf[11]) * 240u / 4096u; + // TODO: Calibration + const u16 tx = __builtin_bswap16(adc.touchX[0]); + u32 fakeKeys = (~tx & 1u<<12)<<8; // KEY_TOUCH + tPos.x = tx * 320u / 4096u; + tPos.y = __builtin_bswap16(adc.touchY[0]) * 240u / 4096u; // Circle-Pad - cPos.x = -(((buf[36]<<8 | buf[37]) & 0xFFFu) - 2048u); // X axis is inverted - cPos.y = ((buf[20]<<8 | buf[21]) & 0xFFFu) - 2048u; + // TODO: Calibration + cPos.y = (__builtin_bswap16(adc.cpadY[0]) & 0xFFFu) - 2048u; + cPos.x = -((__builtin_bswap16(adc.cpadX[0]) & 0xFFFu) - 2048u); // X axis is inverted. if((cPos.x >= 0 ? cPos.x : -cPos.x) > CPAD_THRESHOLD) { - if(cPos.x >= 0) emuButtons |= KEY_CPAD_RIGHT; - else emuButtons |= KEY_CPAD_LEFT; + if(cPos.x >= 0) fakeKeys |= KEY_CPAD_RIGHT; + else fakeKeys |= KEY_CPAD_LEFT; } if((cPos.y >= 0 ? cPos.y : -cPos.y) > CPAD_THRESHOLD) { - if(cPos.y >= 0) emuButtons |= KEY_CPAD_UP; - else emuButtons |= KEY_CPAD_DOWN; + if(cPos.y >= 0) fakeKeys |= KEY_CPAD_UP; + else fakeKeys |= KEY_CPAD_DOWN; } - return emuButtons; -}*/ + fakeKeysCache = fakeKeys; + return fakeKeys; +} void hidScanInput(void) { updateMcuHidState(); - const u32 kOld = kHeld; - kHeld = /*rawCodec2Hid() |*/ REG_HID_PAD; - kDown = (~kOld) & kHeld; - kUp = kOld & (~kHeld); + const u32 kOld = g_kHeld; + g_kHeld = rawCodec2Hid() | REG_HID_PAD; + g_kDown = (~kOld) & g_kHeld; + g_kUp = kOld & (~g_kHeld); } u32 hidKeysHeld(void) { - return kHeld; + return g_kHeld; } u32 hidKeysDown(void) { - return kDown; + return g_kDown; } u32 hidKeysUp(void) { - return kUp; + return g_kUp; } -/*const TouchPos* hidGetTouchPosPtr(void) +const TouchPos* hidGetTouchPosPtr(void) { return &tPos; } @@ -136,12 +138,12 @@ u32 hidKeysUp(void) const CpadPos* hidGetCpadPosPtr(void) { return &cPos; -}*/ +} u32 hidGetExtraKeys(u32 clearMask) { - const u32 tmp = extraKeys; - extraKeys &= ~clearMask; + const u32 tmp = g_extraKeys; + g_extraKeys &= ~clearMask; return tmp; } diff --git a/source/arm11/hardware/lgy.c b/source/arm11/hardware/lgy.c index 8aadfa5..891d6e8 100644 --- a/source/arm11/hardware/lgy.c +++ b/source/arm11/hardware/lgy.c @@ -67,6 +67,17 @@ void LGY_switchMode(void) void LGY_handleEvents(void) { + // Override D-Pad if Circle-Pad is used. + const u32 kHeld = hidKeysHeld(); + u16 padSel; + if(kHeld & KEY_CPAD) + { + REG_LGY_PAD_VAL = (kHeld>>24) ^ KEY_DPAD; + padSel = KEY_DPAD; + } + else padSel = 0; + REG_LGY_PAD_SEL = padSel; + LGYFB_processFrame(); // Bit 0 triggers wakeup. Bit 1 sleep state/ack sleep end. Bit 2 unk. Bit 15 IRQ enable (triggers IRQ 89). diff --git a/source/arm11/main.c b/source/arm11/main.c index 145530b..646c952 100644 --- a/source/arm11/main.c +++ b/source/arm11/main.c @@ -49,7 +49,7 @@ int main(void) GFX_setBrightness(0x30, 0x30); GFX_gpuInit(); consoleInit(SCREEN_BOT, NULL, false); - CODEC_init(); + //CODEC_init(); ee_puts("Prepare legacy mode..."); updateScreens(); @@ -62,12 +62,12 @@ int main(void) do { - __wfi(); + hidScanInput(); + if(hidGetExtraKeys(KEY_POWER) & KEY_POWER) break; LGY_handleEvents(); - hidScanInput(); - if(hidGetExtraKeys(KEY_POWER) & KEY_POWER) break; + __wfi(); } while(1); LGY_deinit();