diff --git a/include/arm11/hardware/timer.h b/include/arm11/hardware/timer.h index a7338cd..dccd092 100644 --- a/include/arm11/hardware/timer.h +++ b/include/arm11/hardware/timer.h @@ -29,7 +29,7 @@ #define TIMER_IRQ_ENABLE (1u<<2) // p is the prescaler value and n the frequence -#define TIMER_FREQ(p, n) (TIMER_BASE_FREQ / 2 / ((p) + 1) / (n)) +#define TIMER_FREQ(p, n) (TIMER_BASE_FREQ / 2 / (p) / (n)) diff --git a/include/arm11/menu/battery.h b/include/arm11/menu/battery.h new file mode 100644 index 0000000..ddb915f --- /dev/null +++ b/include/arm11/menu/battery.h @@ -0,0 +1,32 @@ +#pragma once + +/* + * This file is part of fastboot 3DS + * Copyright (C) 2017 derrek, profi200, d0k3 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "types.h" + + /** + * @brief Battery state description struct. + */ +typedef struct { + u32 percent; ///< Current percent. + bool charging; ///< True if charging. +} BatteryState; + +void getBatteryState(BatteryState *battery); diff --git a/source/arm11/hardware/timer.c b/source/arm11/hardware/timer.c index 2d21495..b5a5445 100644 --- a/source/arm11/hardware/timer.c +++ b/source/arm11/hardware/timer.c @@ -20,6 +20,7 @@ #include "mem_map.h" #include "arm11/hardware/timer.h" #include "arm11/hardware/interrupt.h" +#include "fb_assert.h" #include "arm11/event.h" @@ -41,8 +42,10 @@ void TIMER_start(u8 prescaler, u32 ticks, bool autoReload, bool enableIrq) { + fb_assert(prescaler > 0); + REG_TIMER_LOAD = ticks; - REG_TIMER_CNT = prescaler<<8 | (enableIrq ? TIMER_IRQ_ENABLE : 0) | + REG_TIMER_CNT = (prescaler - 1)<<8 | (enableIrq ? TIMER_IRQ_ENABLE : 0) | (autoReload ? TIMER_AUTO_RELOAD : TIMER_SINGLE_SHOT) | TIMER_ENABLE; } @@ -60,7 +63,7 @@ void TIMER_sleepTicks(u32 ticks) { REG_TIMER_LOAD = ticks; - REG_TIMER_CNT = 0u<<8 | TIMER_IRQ_ENABLE | TIMER_SINGLE_SHOT | TIMER_ENABLE; + REG_TIMER_CNT = TIMER_IRQ_ENABLE | TIMER_SINGLE_SHOT | TIMER_ENABLE; while(REG_TIMER_COUNTER) __wfe(); diff --git a/source/arm11/menu/battery.c b/source/arm11/menu/battery.c new file mode 100644 index 0000000..ce2c6c0 --- /dev/null +++ b/source/arm11/menu/battery.c @@ -0,0 +1,29 @@ +#pragma once + +/* + * This file is part of fastboot 3DS + * Copyright (C) 2017 derrek, profi200, d0k3 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "arm11/hardware/i2c.h" +#include "arm11/menu/battery.h" + +void getBatteryState(BatteryState *battery) +{ + battery->percent = I2C_readReg(I2C_DEV_MCU, 0x0B); + battery->charging = (I2C_readReg(I2C_DEV_MCU, 0x0F) & (1<<4)); +} diff --git a/source/arm11/menu/menu.c b/source/arm11/menu/menu.c index ca09a4f..9e03eeb 100644 --- a/source/arm11/menu/menu.c +++ b/source/arm11/menu/menu.c @@ -21,6 +21,7 @@ #include #include #include "types.h" +#include "arm11/menu/battery.h" #include "arm11/menu/bootinfo.h" #include "arm11/menu/bootslot.h" #include "arm11/menu/menu.h" @@ -35,7 +36,7 @@ #include "hardware/gfx.h" #include "fs.h" // for drive names - +static BatteryState battery; void menuBuildDescString(char* desc, u32 flags, u32 index, const char* desc_raw) { @@ -124,7 +125,10 @@ // print bootinfo consoleSetCursor(desc_con, 0, 4); ee_printf(" Model: %s\n", bootinfo.model); - ee_printf(" %s\n\n", bootinfo.bootEnv); + ee_printf(" %s\n", bootinfo.bootEnv); + ee_printf(" Battery: %s%lu%s %%" ESC_RESET "\n\n", + ((battery.percent <= 20) && !battery.charging) ? ESC_SCHEME_BAD : ESC_SCHEME_GOOD, + battery.percent, (battery.charging) ? "+" : ""); for (u32 i = 0; i < sizeof(mount_paths) / sizeof(const char*); i++) { ee_printf(" " ESC_SCHEME_WEAK "%s" ESC_RESET " %s\n", mount_paths[i], @@ -297,6 +301,9 @@ u32 index = 0; u32 last_index = (u32) -1; + u64 n_vblanks = 0; + getBatteryState(&battery); + // main menu processing loop while (!g_startFirmLaunch) { @@ -304,8 +311,12 @@ if(hidGetPowerButton(false)) break; // deinits & poweroff outside of this function + // handle battery state + if ((++n_vblanks % 250) == 0) + getBatteryState(&battery); + // update menu and description (on demand) - if ((index != last_index) || (curr_menu != last_menu)) { + if ((index != last_index) || (curr_menu != last_menu) || (n_vblanks % 250 == 0)) { menuDraw(curr_menu, menu_con, index); menuShowDesc(curr_menu, desc_con, index); last_index = index; diff --git a/source/arm11/menu/menu_func.c b/source/arm11/menu/menu_func.c index fda5523..f637873 100644 --- a/source/arm11/menu/menu_func.c +++ b/source/arm11/menu/menu_func.c @@ -25,6 +25,7 @@ #include "firmwriter.h" #include "fs.h" #include "fsutils.h" +#include "arm11/menu/battery.h" #include "arm11/menu/bootslot.h" #include "arm11/menu/menu_color.h" #include "arm11/menu/menu_fsel.h" @@ -477,6 +478,14 @@ goto fail; } + // check battery + BatteryState battery; + getBatteryState(&battery); + if ((battery.percent <= 20) && !battery.charging) { + ee_printf("Battery below 20% and not charging.\nPlug in the charger and retry.\n"); + goto fail; + } + // ensure SD mounted if (!fsEnsureMounted("sdmc:")) {