From 46188c726b70547e7eebcd386a72becfac300597 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Thu, 26 Sep 2013 09:40:23 +0200 Subject: Menu App to select highram images from phone's flash memory --- src/target/firmware/Makefile | 3 +- src/target/firmware/apps/menu/main.c | 353 +++++++++++++++++++++++++++++++++++ 2 files changed, 355 insertions(+), 1 deletion(-) create mode 100644 src/target/firmware/apps/menu/main.c diff --git a/src/target/firmware/Makefile b/src/target/firmware/Makefile index 42f7ad48..0f4120f9 100644 --- a/src/target/firmware/Makefile +++ b/src/target/firmware/Makefile @@ -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 diff --git a/src/target/firmware/apps/menu/main.c b/src/target/firmware/apps/menu/main.c new file mode 100644 index 00000000..47aadc4e --- /dev/null +++ b/src/target/firmware/apps/menu/main.c @@ -0,0 +1,353 @@ +/* Menu for Calypso Phone to load applicatios from flash */ + +/* (C) 2013 by Andreas Eversberg + * + * 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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:\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(); +} + -- cgit v1.2.3