Add battery info. Move network info into system OSD page.

This commit is contained in:
sorgelig
2018-02-11 08:29:08 +08:00
parent 1cc907c276
commit 45b54b1933
6 changed files with 366 additions and 48 deletions

View File

@@ -40,6 +40,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="archie.c" />
<ClCompile Include="battery.c" />
<ClCompile Include="brightness.c" />
<ClCompile Include="cfg.c" />
<ClCompile Include="DiskImage.cpp" />
@@ -64,6 +65,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="archie.h" />
<ClInclude Include="battery.h" />
<ClInclude Include="brightness.h" />
<ClInclude Include="cfg.h" />
<ClInclude Include="charrom.h" />

View File

@@ -77,6 +77,9 @@
<ClCompile Include="brightness.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="battery.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="archie.h">
@@ -169,6 +172,9 @@
<ClInclude Include="brightness.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="battery.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="build.sh" />

212
battery.c Normal file
View File

@@ -0,0 +1,212 @@
/*
* battery.c
* display pi-top battery status
*
* Copyright 2016, 2017 rricharz
* MiSTer port. Copyright 2018 Sorgelig
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*
*/
#include <time.h>
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include "battery.h"
#define MAX_COUNT 20 // Maximum number of trials
#define SLEEP_TIME 500 // time between two i2cget in microsec
///////////////////////////////////////////////////////////////////////
// I2C definitions
#define I2C_SLAVE 0x0703
#define I2C_SMBUS 0x0720 /* SMBus-level access */
#define I2C_SMBUS_READ 1
#define I2C_SMBUS_WRITE 0
// SMBus transaction types
#define I2C_SMBUS_QUICK 0
#define I2C_SMBUS_BYTE 1
#define I2C_SMBUS_BYTE_DATA 2
#define I2C_SMBUS_WORD_DATA 3
#define I2C_SMBUS_PROC_CALL 4
#define I2C_SMBUS_BLOCK_DATA 5
#define I2C_SMBUS_I2C_BLOCK_BROKEN 6
#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */
#define I2C_SMBUS_I2C_BLOCK_DATA 8
// SMBus messages
#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */
#define I2C_SMBUS_I2C_BLOCK_MAX 32 /* Not specified but we use same structure */
// Structures used in the ioctl() calls
union i2c_smbus_data
{
uint8_t byte;
int8_t sbyte;
uint16_t word;
int16_t sword;
uint8_t block [I2C_SMBUS_BLOCK_MAX + 2]; // block [0] is used for length + one more for PEC
};
struct i2c_smbus_ioctl_data
{
char read_write;
uint8_t command;
int size;
union i2c_smbus_data *data;
};
static int i2c_smbus_access (int fd, char rw, uint8_t command, int size, union i2c_smbus_data *data)
{
struct i2c_smbus_ioctl_data args;
args.read_write = rw;
args.command = command;
args.size = size;
args.data = data;
return ioctl (fd, I2C_SMBUS, &args);
}
static int i2c_smbus_write_quick(int fd, uint8_t value)
{
return i2c_smbus_access(fd, value, 0, I2C_SMBUS_QUICK, NULL);
}
///////////////////////////////////////////////////////////////////////
static int i2c_handle = -1;
static int smbus_open(int dev_address)
{
// re-entry compatible
if(i2c_handle < 0)
{
int fd;
if ((fd = open ("/dev/i2c-1", O_RDWR)) < 0)
{
printf("Unable to open I2C device: %s\n", strerror(errno));
return 0;
}
if (ioctl (fd, I2C_SLAVE, dev_address) < 0)
{
printf("Unable to select I2C device: %s\n", strerror (errno));
close(fd);
return 0;
}
if (i2c_smbus_write_quick(fd, I2C_SMBUS_WRITE) < 0)
{
printf("Unable to detect SMBUS device: %s\n", strerror(errno));
close(fd);
return 0;
}
i2c_handle = fd;
}
return 1;
}
static void smbus_close()
{
if(i2c_handle > 0) close(i2c_handle);
i2c_handle = -1;
}
static int smbus_get(int address, short *data)
{
union i2c_smbus_data smbus_data;
if (i2c_smbus_access (i2c_handle, I2C_SMBUS_READ, address, I2C_SMBUS_WORD_DATA, &smbus_data)) return 0;
*data = smbus_data.sword;
return 1;
}
static int getReg(int reg, int min, int max)
{
int count = 0;
short value = -1;
while ((value == -1) && (count++ < MAX_COUNT))
{
if (smbus_get(reg, &value))
{
if ((value > max) || (value < min)) value = -1; // out of limits
}
usleep(SLEEP_TIME);
}
return value;
}
int getBattery(int quick, struct battery_data_t *data)
{
/*
data->capacity = 80;
data->load_current = -520;
data->time = 312;
data->current = 2510;
data->voltage = 16200;
data->cell[0] = 4101;
data->cell[1] = 4102;
data->cell[2] = 4103;
data->cell[3] = 4104;
return 1;
*/
// don't try to check if no battery device is present
if (i2c_handle == -2) return 0;
if (!smbus_open(0x0b))
{
printf("No battery found.\n");
i2c_handle = -2;
return 0;
}
data->capacity = getReg(0x0D, 0, 100);
data->load_current = getReg(0x0A, -5000, 5000);
if (quick) return 1;
data->time = 0;
if (data->load_current > 0) data->time = getReg(0x13, 1, 999);
if (data->load_current < -1) data->time = getReg(0x12, 1, 960);
data->current = getReg(0x0F, 0, 5000);
data->voltage = getReg(0x09, 5000, 20000);
/*
data->cell[0] = getReg(0x3F, 1000, 5000);
data->cell[1] = getReg(0x3E, 1000, 5000);
data->cell[2] = getReg(0x3D, 1000, 5000);
data->cell[3] = getReg(0x3C, 1000, 5000);
*/
return 1;
}

16
battery.h Normal file
View File

@@ -0,0 +1,16 @@
#ifndef __BATTERY_H__
#define __BATTERY_H__
struct battery_data_t
{
short load_current;
short capacity;
short current;
short time;
short voltage;
short cell[4];
};
int getBattery(int quick, struct battery_data_t *data);
#endif

View File

@@ -38,7 +38,7 @@ Middle Dot
*/
// *character font
unsigned char charfont[128][8] =
unsigned char charfont[][8] =
{
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 0 [0x0]
{ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55 }, // 1 [0x1]
@@ -70,8 +70,8 @@ unsigned char charfont[128][8] =
{ 0x00,0x00,0x00,0x0c,0x0c,0x00,0x00,0x00 }, // 27 [0x1b] middle dot
{ 0x68,0x78,0x6b,0x0f,0x6b,0x78,0x68,0x00 }, // 28 [0x1c] ethernet
{ 0x02,0x09,0x25,0x95,0x95,0x25,0x09,0x02 }, // 29 [0x1d] wifi
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 30 [0x1e]
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 31 [0x1f]
{ 0x00,0x90,0xD8,0x7C,0x3E,0x1B,0x09,0x00 }, // 30 [0x1e] charge
{ 0x7E,0x72,0x73,0x73,0x73,0x72,0x7E,0x00 }, // 31 [0x1f] battery
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, // 32 [0x20]
{ 0x00,0x00,0x00,0x5F,0x5F,0x00,0x00,0x00 }, // 33 [0x21]
{ 0x00,0x03,0x03,0x00,0x03,0x03,0x00,0x00 }, // 34 [0x22]
@@ -167,7 +167,24 @@ unsigned char charfont[128][8] =
{ 0x00,0x00,0x00,0x7F,0x7F,0x00,0x00,0x00 }, // 124 [0x7c]
{ 0x00,0x41,0x41,0x77,0x3E,0x08,0x08,0x00 }, // 125 [0x7d]
{ 0x02,0x01,0x01,0x03,0x02,0x02,0x01,0x00 }, // 126 [0x7e]
{ 0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x00 } // 127 [0x7f]
{ 0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x00 }, // 127 [0x7f]
//dotted frame
{ 0x00,0x00,0x00,0xA8,0x00,0x08,0x00,0x08 }, // 128 [0x80] TL
{ 0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08 }, // 129 [0x81] T/B
{ 0x00,0x08,0x00,0xA8,0x00,0x00,0x00,0x00 }, // 130 [0x82] TR
{ 0x00,0x00,0x00,0xAA,0x00,0x00,0x00,0x00 }, // 131 [0x83] L/R
{ 0x00,0x08,0x00,0x0A,0x00,0x00,0x00,0x00 }, // 132 [0x84] BR
{ 0x00,0x00,0x00,0x0A,0x00,0x08,0x00,0x08 }, // 133 [0x85] BL
//solid frame
{ 0x00,0x00,0x00,0xF8,0x08,0x08,0x08,0x08 }, // 134 [0x86] TL
{ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08 }, // 135 [0x87] T/B
{ 0x08,0x08,0x08,0xF8,0x00,0x00,0x00,0x00 }, // 136 [0x88] TR
{ 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00 }, // 137 [0x89] L/R
{ 0x08,0x08,0x08,0x0F,0x00,0x00,0x00,0x00 }, // 138 [0x8A] BR
{ 0x00,0x00,0x00,0x0F,0x08,0x08,0x08,0x08 }, // 139 [0x8B] BL
};
#endif

153
menu.c
View File

@@ -52,6 +52,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "cfg.h"
#include "input.h"
#include "x86.h"
#include "battery.h"
/*menu states*/
enum MENU
@@ -524,6 +525,91 @@ char* getNet()
return ifa ? host : 0;
}
static long sysinfo_timer;
void infowrite(int pos, char* txt)
{
char str[40];
memset(str, 0x20, 29);
int len = strlen(txt);
if (len > 27) len = 27;
if(len) strncpy(str + 1+ ((27-len)/2), txt, len);
str[0] = 0x83;
str[28] = 0x83;
str[29] = 0;
OsdWrite(pos, str, 0, 0);
}
void printSysInfo()
{
if (!sysinfo_timer || CheckTimer(sysinfo_timer))
{
sysinfo_timer = GetTimer(2000);
struct battery_data_t bat;
int hasbat = getBattery(0, &bat);
int n = 9;
char str[40];
OsdWrite(n++, "\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", 0, 0);
if (!hasbat)
{
infowrite(n++, "");
}
memset(str, 0, sizeof(str));
char *net = getNet();
if (net)
{
str[strlen(str)] = 0x1b + netType;
strcat(str, " ");
}
strcat(str, net ? net : "No network");
infowrite(n++, str);
if (hasbat)
{
infowrite(n++, "");
sprintf(str, "\x1F ");
if (bat.capacity == -1) strcat(str, "n/a");
else sprintf(str + strlen(str), "%d%%", bat.capacity);
if (bat.current != -1) sprintf(str + strlen(str), " %dmAh", bat.current);
if (bat.voltage != -1) sprintf(str + strlen(str), " %d.%dV", bat.voltage / 1000, (bat.voltage / 100) % 10);
infowrite(n++, str);
str[0] = 0;
if (bat.load_current > 0)
{
sprintf(str + strlen(str), " \x12 %dmA", bat.load_current);
if (bat.time != -1)
{
if (bat.time < 90) sprintf(str + strlen(str), ", ETA: %dm", bat.time);
else sprintf(str + strlen(str), ", ETA: %dh%02dm", bat.time / 60, bat.time % 60);
}
}
else if (bat.load_current < -1)
{
sprintf(str + strlen(str), " \x13 %dmA", -bat.load_current);
if (bat.time != -1)
{
if (bat.time < 90) sprintf(str + strlen(str), ", ETA: %dm", bat.time);
else sprintf(str + strlen(str), ", ETA: %dh%02dm", bat.time / 60, bat.time % 60);
}
}
else
{
strcat(str, "Not charging");
}
infowrite(n++, str);
}
else
{
infowrite(n++, "");
infowrite(n++, "");
}
OsdWrite(n++, "\x85\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x84", 0, 0);
}
}
void HandleUI(void)
{
switch (user_io_core_type())
@@ -621,15 +707,6 @@ void HandleUI(void)
case KEY_MINUS: // -/_
minus = true;
break;
/*
case 0x01: // 1: 1280x720 mode
if (user_io_osd_is_visible) cfg.video_mode = 0;
break;
case 0x02: // 2: 1280x1024 mode
if (user_io_osd_is_visible) cfg.video_mode = 1;
break;
*/
}
if (menu || select || up || down || left || right)
@@ -1146,21 +1223,18 @@ void HandleUI(void)
parentstate = MENU_8BIT_SYSTEM1;
if (OsdIsBig) OsdWrite(0, "", 0, 0);
OsdWrite(OsdIsBig ? 1 : 0, " Firmware & Core \x16", menusub == 0, 0);
if(OsdIsBig) OsdWrite(2, "", 0, 0);
OsdWrite(OsdIsBig ? 3 : 1, " Define joystick buttons", menusub == 1, 0);
OsdWrite(OsdIsBig ? 4 : 2, "", 0, 0);
if (OsdIsBig) OsdWrite(5, "", 0, 0);
OsdWrite(OsdIsBig ? 6 : 3, m ? " Reset" : " Reset settings", menusub == 3, !has_menu());
OsdWrite(OsdIsBig ? 2 : 1, " Define joystick buttons \x16", menusub == 1, 0);
OsdWrite(OsdIsBig ? 3 : 2, "", 0, 0);
OsdWrite(OsdIsBig ? 4 : 3, m ? " Reset" : " Reset settings", menusub == 3, !has_menu());
if (m)
OsdWrite(OsdIsBig ? 7 : 4, "", 0, 0);
OsdWrite(OsdIsBig ? 5 : 4, "", 0, 0);
else
OsdWrite(OsdIsBig ? 7 : 4, " Save settings", menusub == 4, !has_menu()); // Minimig saves settings elsewhere
if (OsdIsBig) OsdWrite(8, "", 0, 0);
OsdWrite(OsdIsBig ? 9 : 5, " Cold reset", menusub == (5 - m), 0);
if (OsdIsBig) OsdWrite(10, "", 0, 0);
OsdWrite(OsdIsBig ? 11 : 6, " About", menusub == (6 - m), 0);
if(OsdIsBig) for (int i = 12; i < OsdGetSize() - 1; i++) OsdWrite(i, "", 0, 0);
OsdWrite(OsdIsBig ? 5 : 4, " Save settings", menusub == 4, !has_menu()); // Minimig saves settings elsewhere
if (OsdIsBig) OsdWrite(6, "", 0, 0);
OsdWrite(OsdIsBig ? 7 : 5, " Cold reset", menusub == (5 - m), 0);
OsdWrite(OsdIsBig ? 8 : 6, " About", menusub == (6 - m), 0);
OsdWrite(OsdGetSize() - 1, STD_EXIT, menusub == (7 - m), 0);
sysinfo_timer = 0;
break;
case MENU_8BIT_SYSTEM2:
@@ -1274,6 +1348,8 @@ void HandleUI(void)
}
}
}
if (OsdIsBig) printSysInfo();
break;
case MENU_JOYDIGMAP:
@@ -3011,16 +3087,12 @@ void HandleUI(void)
}
}
OsdWrite(5, "", 0, 0);
OsdWrite(6, " NOTE:", 0, 0);
OsdWrite(7, " USB storage takes longer", 0, 0);
OsdWrite(8, " time to initialize", 0, 0);
OsdWrite(9, " upon cold boot.", 0, 0);
OsdWrite(10, " Use OSD or USER button to", 0, 0);
OsdWrite(11, " cancel USB waiting.", 0, 0);
OsdWrite(12, "", 0, 0);
OsdWrite(13, "", 0, 0);
OsdWrite(14, " Remap keyboard", menusub == 1, 0);
OsdWrite(15, " Define joystick buttons", menusub == 2, 0);
OsdWrite(6, " Remap keyboard \x16", menusub == 1, 0);
OsdWrite(7, " Define joystick buttons \x16", menusub == 2, 0);
OsdWrite(8, "", 0, 0);
OsdWrite(15, "", 0, 0);
sysinfo_timer = 0;
menustate = MENU_STORAGE;
}
else
@@ -3096,6 +3168,7 @@ void HandleUI(void)
break;
}
}
printSysInfo();
break;
case MENU_KBDMAP:
@@ -3223,23 +3296,15 @@ void HandleUI(void)
rtc_timer = GetTimer(1000);
char str[64] = { 0 };
sprintf(str, " MiSTer ");
char *net = getNet();
if (menustate == MENU_STORAGE)
time_t t = time(NULL);
struct tm tm = *localtime(&t);
if (tm.tm_year >= 117)
{
strcat(str, net ? net : " no network");
}
else
{
time_t t = time(NULL);
struct tm tm = *localtime(&t);
if (tm.tm_year >= 117)
{
strftime(str + strlen(str), sizeof(str) - 1 - strlen(str), "%b %d %a %H:%M:%S", &tm);
}
strftime(str + strlen(str), sizeof(str) - 1 - strlen(str), "%b %d %a %H:%M:%S", &tm);
}
if (net) str[9] = 0x1b + netType;
if (getNet()) str[9] = 0x1b + netType;
OsdWrite(16, "", 1, 0);
OsdWrite(17, str, 1, 0);