From d6a628b7d3b37ef40f16c278d16c7ae38087b394 Mon Sep 17 00:00:00 2001 From: Kartik Date: Sat, 23 Sep 2017 19:33:37 +0530 Subject: [PATCH] Add mcu::HWC service (#373) --- libctru/include/3ds.h | 4 +- libctru/include/3ds/services/mcuhwc.h | 45 +++++++++++++ libctru/source/services/mcuhwc.c | 93 +++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 libctru/include/3ds/services/mcuhwc.h create mode 100644 libctru/source/services/mcuhwc.c diff --git a/libctru/include/3ds.h b/libctru/include/3ds.h index c5cea55..5244f28 100644 --- a/libctru/include/3ds.h +++ b/libctru/include/3ds.h @@ -65,6 +65,7 @@ extern "C" { #include <3ds/services/srvpm.h> #include <3ds/services/loader.h> #include <3ds/services/y2r.h> +#include <3ds/services/mcuhwc.h> #include <3ds/services/hb.h> #include <3ds/gpu/gx.h> @@ -77,8 +78,9 @@ extern "C" { #include <3ds/applets/swkbd.h> #include <3ds/applets/error.h> + #include <3ds/applets/miiselector.h> - + #include <3ds/sdmc.h> #include <3ds/romfs.h> #include <3ds/font.h> diff --git a/libctru/include/3ds/services/mcuhwc.h b/libctru/include/3ds/services/mcuhwc.h new file mode 100644 index 0000000..4f3f6d6 --- /dev/null +++ b/libctru/include/3ds/services/mcuhwc.h @@ -0,0 +1,45 @@ +/** + * @file mcuHwc.h + * @brief mcuHwc service. + */ +#pragma once + +/// Initializes mcuHwc. +Result mcuHwcInit(void); + +/// Exits mcuHwc. +void mcuHwcExit(void); + +/** + * @brief Reads data from a mcuHwc Register + * @param reg Register number. See https://www.3dbrew.org/wiki/I2C_Registers#Device_3 for more info + * @param data Pointer to write the data to. + * @param size Size of data to be read + */ +Result mcuHwcReadRegister(u8 reg, void *data, u32 size); + +/** + * @brief Writes data to a mcuHwc Register + * @param reg Register number. See https://www.3dbrew.org/wiki/I2C_Registers#Device_3 for more info + * @param data Pointer to write the data to. + * @param size Size of data to be written + */ +Result mcuHwcWriteRegister(u8 reg, const void *data, u32 size); + +/** + * @brief Gets the battery voltage + * @param voltage Pointer to write the battery voltage to. + */ +Result mcuHwcGetBatteryVoltage(u8 *voltage); + +/** + * @brief Gets the battery level + * @param level Pointer to write the current battery level to. + */ +Result mcuHwcGetBatteryLevel(u8 *level); + +/** + * @brief Gets the sound slider level + * @param level Pointer to write the slider level to. + */ +Result mcuHwcGetSoundSliderLevel(u8 *level); \ No newline at end of file diff --git a/libctru/source/services/mcuhwc.c b/libctru/source/services/mcuhwc.c new file mode 100644 index 0000000..dc7550f --- /dev/null +++ b/libctru/source/services/mcuhwc.c @@ -0,0 +1,93 @@ +#include <3ds.h> +#include <3ds/services/mcuhwc.h> + +static Handle mcuHwcHandle; +static int mcuHwcRefCount; + +Result mcuHwcInit(void) +{ + if (AtomicPostIncrement(&mcuHwcRefCount)) return 0; + Result res = srvGetServiceHandle(&mcuHwcHandle, "mcu::HWC"); + if (R_FAILED(res)) AtomicDecrement(&mcuHwcRefCount); + return res; +} + +void mcuHwcExit(void) +{ + if (AtomicDecrement(&mcuHwcRefCount)) return; + svcCloseHandle(mcuHwcHandle); +} + +Result mcuHwcReadRegister(u8 reg, void* data, u32 size) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x1,2,2); // 0x10082 + cmdbuf[1] = reg; + cmdbuf[2] = size; + cmdbuf[3] = IPC_Desc_Buffer (size, IPC_BUFFER_W); + cmdbuf[4] = (u32)data; + + if(R_FAILED(ret = svcSendSyncRequest(mcuHwcHandle)))return ret; + + return (Result)cmdbuf[1]; +} + +Result mcuHwcWriteRegister(u8 reg, const void *data, u32 size) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x2,2,2); // 0x20082 + cmdbuf[1] = reg; + cmdbuf[2] = size; + cmdbuf[3] = IPC_Desc_Buffer (size, IPC_BUFFER_R); + cmdbuf[4] = (u32)data; + + if(R_FAILED(ret = svcSendSyncRequest(mcuHwcHandle)))return ret; + + return (Result)cmdbuf[1]; +} + +Result mcuHwcGetBatteryVoltage(u8 *voltage) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x4,0,0); // 0x40000 + + if(R_FAILED(ret = svcSendSyncRequest(mcuHwcHandle)))return ret; + + *voltage = cmdbuf[2]; + + return (Result)cmdbuf[1]; +} + +Result mcuHwcGetBatteryLevel(u8 *level) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x5,0,0); // 0x50000 + + if(R_FAILED(ret = svcSendSyncRequest(mcuHwcHandle)))return ret; + + *level = cmdbuf[2]; + + return (Result)cmdbuf[1]; +} + +Result mcuHwcGetSoundSliderLevel(u8 *level) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0xB,0,0); // 0xB0000 + + if(R_FAILED(ret = svcSendSyncRequest(mcuHwcHandle)))return ret; + + *level = cmdbuf[2]; + + return (Result)cmdbuf[1]; +} \ No newline at end of file