Menu App to select highram images from phone's flash memory

This commit is contained in:
Andreas Eversberg 2013-09-26 09:40:23 +02:00
parent f2ab5e1496
commit 46188c726b
2 changed files with 355 additions and 1 deletions

View File

@ -84,11 +84,12 @@ BOARD_se_j100_ENVIRONMENTS=$(compal_COMMON_ENVIRONMENTS)
#
# List of all applications (meant to be overridden on command line)
APPLICATIONS?=hello_world compal_dsp_dump layer1 loader rssi
APPLICATIONS?=hello_world compal_dsp_dump layer1 loader rssi menu
# Applications specific env requirements
APP_loader_ENVIRONMENTS=compalram highram
APP_rssi_ENVIRONMENTS=* -compalram
APP_menu_ENVIRONMENTS=* -highram
# Various objects that are currently linked into all applications
FLASH_OBJS=flash/cfi_flash.o

View File

@ -0,0 +1,353 @@
/* Menu for Calypso Phone to load applicatios from flash */
/* (C) 2013 by Andreas Eversberg <jolly@eversberg.eu>
*
* All Rights Reserved
*
* 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 <stdint.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <debug.h>
#include <memory.h>
#include <delay.h>
#include <byteorder.h>
#include <rffe.h>
#include <keypad.h>
#include <board.h>
#include <abb/twl3025.h>
#include <rf/trf6151.h>
#include <calypso/clock.h>
#include <calypso/tpu.h>
#include <calypso/tsp.h>
#include <calypso/dsp.h>
#include <calypso/irq.h>
#include <calypso/misc.h>
#include <calypso/timer.h>
#include <comm/sercomm.h>
#include <comm/timer.h>
#include <uart.h>
#include <fb/framebuffer.h>
#include <battery/battery.h>
#include <asm/system.h>
#define RAM 0x00820000
#define MAGIC 0x0083ff00
enum key_codes key_code = KEY_INV;
static volatile enum key_states key_state;
int cursor = 0, scroll_apps = 0;
struct apps {
char name[16];
void *start;
int len;
} apps[32];
int _memcmp(char *s1, char *s2, int size)
{
int i;
for (i = 0; i < size; i++) {
if (*s1 < *s2)
return -1;
if (*s1 > *s2)
return 1;
s1++;
s2++;
}
return 0;
}
static void locate_apps(void)
{
int i, j, k;
char *p;
memset(apps, 0, sizeof(apps));
for (j = 0, i = 0x010000; i < 0x200000; i += 0x10000) {
p = (char *)i;
/* check for highram header: "highram:" */
if (!!_memcmp(p, "highram:", 8))
continue;
p += 8;
/* check for app name after header: "highram:<name>\n" */
printf("found highram image at flash mem address 0x%p\n",
(char *)i);
for (k = 0; k < (int)sizeof(apps[j].name) - 1; k++) {
if (p[k] == '\n')
break;
}
if (k == sizeof(apps[j].name) - 3) {
printf("skipping: corrupt highram header, no '\\n' "
"after image name or name more larger than %d "
"digits\n", (int)sizeof(apps[j].name) - 3);
continue;
}
if (j < 9)
apps[j].name[0] = '1' + j;
else if (j == 9)
apps[j].name[0] = '0';
else
apps[j].name[0] = ' ';
apps[j].name[1] = ' ';
memcpy(apps[j].name + 2, p, k);
apps[j].len = 0x20000;
p += k + 1;
/* p points to highram image after header */
apps[j].start = p;
j++;
}
}
static void wait_key_release(void)
{
/* wait for key release */
while (key_state == PRESSED) {
delay_ms(10);
keypad_poll();
}
}
static void load_app(void)
{
static int i;
static void (*f) (void) = (void (*)(void))RAM;
wait_key_release();
local_irq_disable();
for (i = 0; i < apps[cursor].len; i++)
((unsigned char *)RAM)[i] = ((unsigned char *)apps[cursor].start)[i];
f();
}
/* UI */
static void refresh_display(void)
{
#if 0
char text[16];
int bat = battery_info.battery_percent;
#endif
int i;
fb_clear();
/* header */
fb_setbg(FB_COLOR_WHITE);
if (1) {
fb_setfg(FB_COLOR_BLUE);
fb_setfont(FB_FONT_HELVR08);
fb_gotoxy(0, 7);
fb_putstr("Osmocom Menu", -1);
fb_setfg(FB_COLOR_RGB(0xc0, 0xc0, 0x00));
fb_setfont(FB_FONT_SYMBOLS);
#if 0
fb_gotoxy(framebuffer->width - 15, 8);
if (bat >= 100 && (battery_info.flags & BATTERY_CHG_ENABLED)
&& !(battery_info.flags & BATTERY_CHARGING))
fb_putstr("@HHBC", framebuffer->width);
else {
sprintf(text, "@%c%c%cC", (bat >= 30) ? 'B':'A',
(bat >= 60) ? 'B':'A', (bat >= 90) ? 'B':'A');
fb_putstr(text, framebuffer->width);
}
#endif
fb_gotoxy(0, 8);
fb_putstr("GGEGG", framebuffer->width);
fb_setfg(FB_COLOR_GREEN);
fb_gotoxy(0, 10);
fb_boxto(framebuffer->width - 1, 10);
}
fb_setfg(FB_COLOR_BLACK);
fb_setfont(FB_FONT_C64);
for (i = 0; i < 5; i++) {
if (!apps[scroll_apps + i].name)
break;
if (scroll_apps + i == cursor) {
fb_setfg(FB_COLOR_WHITE);
fb_setbg(FB_COLOR_BLUE);
}
fb_gotoxy(0, 20 + i * 10);
fb_putstr(apps[scroll_apps + i].name,
framebuffer->width);
if (scroll_apps + i == cursor) {
fb_setfg(FB_COLOR_BLACK);
fb_setbg(FB_COLOR_WHITE);
}
}
if (i == 0) {
fb_gotoxy(0, 50);
fb_putstr("No apps!", -1);
}
fb_flush();
}
static void handle_key_code()
{
if (key_code == KEY_INV)
return;
switch (key_code) {
case KEY_1:
case KEY_2:
case KEY_3:
case KEY_4:
case KEY_5:
case KEY_6:
case KEY_7:
case KEY_8:
case KEY_9:
if (apps[key_code - KEY_1].len) {
cursor = key_code - KEY_1;
load_app();
}
break;
case KEY_0:
if (apps[9].len) {
cursor = 9;
load_app();
}
break;
case KEY_UP:
if (cursor == 0)
return;
cursor--;
if (cursor < scroll_apps)
scroll_apps = cursor;
refresh_display();
break;
case KEY_DOWN:
if (!apps[cursor + 1].name[0])
return;
cursor++;
if (cursor >= scroll_apps + 5)
scroll_apps = cursor - 4;
refresh_display();
break;
case KEY_OK:
if (apps[cursor].len)
load_app();
break;
case KEY_POWER:
wait_key_release();
twl3025_power_off();
break;
default:
break;
}
key_code = KEY_INV;
}
/* Main Program */
const char *hr = "======================================================================\n";
static void key_handler(enum key_codes code, enum key_states state)
{
key_state = state;
if (state != PRESSED)
return;
key_code = code;
}
extern void putchar_asm(uint32_t c);
static const uint8_t phone_ack[] = { 0x1b, 0xf6, 0x02, 0x00, 0x41, 0x03, 0x42 };
int main(void)
{
int i;
/* Simulate a compal loader saying "ACK" */
for (i = 0; i < (int)sizeof(phone_ack); i++) {
putchar_asm(phone_ack[i]);
}
board_init(0);
puts("\n\nOsmocomBB Menu (revision " GIT_REVISION ")\n");
puts(hr);
fb_clear();
fb_setfg(FB_COLOR_BLACK);
fb_setbg(FB_COLOR_WHITE);
fb_setfont(FB_FONT_HELVB14);
fb_gotoxy(2,20);
fb_putstr("menu",framebuffer->width-4);
fb_setfg(FB_COLOR_RED);
fb_setbg(FB_COLOR_BLUE);
fb_gotoxy(2,25);
fb_boxto(framebuffer->width-3,38);
fb_setfg(FB_COLOR_WHITE);
fb_setfont(FB_FONT_HELVR08);
fb_gotoxy(8,33);
fb_putstr("osmocom-bb",framebuffer->width-4);
fb_flush();
/* Dump device identification */
dump_dev_id();
puts(hr);
/* Dump clock config before PLL set */
calypso_clk_dump();
puts(hr);
keypad_set_handler(&key_handler);
/* Dump clock config after PLL set */
calypso_clk_dump();
puts(hr);
// display_unset_attr(DISP_ATTR_INVERT);
locate_apps();
while (1) {
for (i = 0; i < 50; i++) {
keypad_poll();
delay_ms(10);
osmo_timers_update();
handle_key_code();
}
refresh_display();
}
/* NOT REACHED */
twl3025_power_off();
}