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:"))
{