diff options
Diffstat (limited to 'firmware')
25 files changed, 1236 insertions, 19 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index d8cfadef11..4092f71e04 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -1698,3 +1698,14 @@ target/coldfire/mpio/fmradio_i2c-mpio.c #endif /* BOOTLOADER */ #endif /* SIMULATOR */ #endif + + +#if (CONFIG_PLATFORM & PLATFORM_ANDROID) +target/hosted/android/lcd-android.c +target/hosted/android/button-android.c +target/hosted/android/kernel-android.c +target/hosted/android/pcm-android.c +target/hosted/android/system-android.c +drivers/audio/android.c +thread.c +#endif diff --git a/firmware/common/rbpaths.c b/firmware/common/rbpaths.c index 69bc1387ef..b63586c9f4 100644 --- a/firmware/common/rbpaths.c +++ b/firmware/common/rbpaths.c @@ -33,9 +33,13 @@ void paths_init(void) { /* make sure $HOME/.config/rockbox.org exists, it's needed for config.cfg */ +#if (CONFIG_PLATFORM & PLATFORM_ANDROID) + mkdir("/sdcard/rockbox"); +#else char home_path[MAX_PATH]; snprintf(home_path, sizeof(home_path), "%s/.config/rockbox.org", getenv("HOME")); mkdir(home_path); +#endif } const char* get_user_file_path(const char *path, @@ -50,7 +54,11 @@ const char* get_user_file_path(const char *path, pos += ROCKBOX_DIR_LEN; if (*pos == '/') pos += 1; +#if (CONFIG_PLATFORM & PLATFORM_ANDROID) + if (snprintf(buf, bufsize, "/sdcard/rockbox/%s", pos) +#else if (snprintf(buf, bufsize, "%s/.config/rockbox.org/%s", getenv("HOME"), pos) +#endif >= (int)bufsize) return NULL; diff --git a/firmware/drivers/audio/android.c b/firmware/drivers/audio/android.c new file mode 100644 index 0000000000..300bb08482 --- /dev/null +++ b/firmware/drivers/audio/android.c @@ -0,0 +1,61 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright © 2010 Thomas Martitz + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#include "config.h" +#include "audiohw.h" + +const struct sound_settings_info audiohw_settings[] = { + [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN / 10, VOLUME_MAX / 10, -25}, +/* Bass and treble tone controls */ +#ifdef AUDIOHW_HAVE_BASS + [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, +#endif +#ifdef AUDIOHW_HAVE_TREBLE + [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, +#endif + [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, + [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, + [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, +#if defined(HAVE_RECORDING) + [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0}, + [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0}, + [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16}, +#endif +#if defined(AUDIOHW_HAVE_BASS_CUTOFF) + [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1}, +#endif +#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) + [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1}, +#endif +}; + + +void audiohw_set_volume(int volume) +{ + extern void pcm_set_mixer_volume(int); + pcm_set_mixer_volume(volume); +} + +void audiohw_set_balance(int balance) +{ + (void)balance; +} diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h index d4861aac5a..658dd1301c 100644 --- a/firmware/export/audiohw.h +++ b/firmware/export/audiohw.h @@ -66,7 +66,7 @@ #elif defined(HAVE_AK4537) #include "ak4537.h" #endif -#if defined(HAVE_SDL_AUDIO) +#if (CONFIG_PLATFORM & PLATFORM_HOSTED) /* #include <SDL_audio.h> gives errors in other code areas, * we don't really need it here, so don't. but it should maybe be fixed */ #ifndef SIMULATOR /* simulator gets values from the target .h files */ diff --git a/firmware/export/config.h b/firmware/export/config.h index 1b8a782f39..3b59004549 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -78,8 +78,10 @@ * bit fields to allow PLATFORM_HOSTED to be OR'ed e.g. with a * possible future PLATFORM_ANDROID (some OSes might need totally different * handling to run on them than a stand-alone application) */ -#define PLATFORM_NATIVE (1<<0) -#define PLATFORM_HOSTED (1<<1) +#define PLATFORM_NATIVE (1<<0) +#define PLATFORM_HOSTED (1<<1) +#define PLATFORM_ANDROID (1<<2) +#define PLATFORM_SDL (1<<3) /* CONFIG_KEYPAD */ #define PLAYER_PAD 1 @@ -427,6 +429,8 @@ Lyre prototype 1 */ #elif defined(APPLICATION) #include "config/application.h" +#define CONFIG_CPU 0 +#define CONFIG_STORAGE 0 #else /* no known platform */ #endif @@ -689,11 +693,17 @@ Lyre prototype 1 */ #define HAVE_EXTENDED_MESSAGING_AND_NAME #define HAVE_WAKEUP_EXT_CB + +#if (CONFIG_PLATFORM & PLATFORM_ANDROID) +#define HAVE_PRIORITY_SCHEDULING +#endif + #if (CONFIG_PLATFORM & PLATFORM_NATIVE) #define HAVE_PRIORITY_SCHEDULING #define HAVE_SCHEDULER_BOOSTCTRL #endif /* PLATFORM_NATIVE */ + #define HAVE_SEMAPHORE_OBJECTS #if defined(HAVE_USBSTACK) && CONFIG_USBOTG == USBOTG_ARC diff --git a/firmware/export/config/application.h b/firmware/export/config/application.h index a5583ded75..988f0d51ac 100644 --- a/firmware/export/config/application.h +++ b/firmware/export/config/application.h @@ -4,11 +4,13 @@ #define TARGET_TREE /* this target is using the target tree system */ /* We don't run on hardware directly */ -#define CONFIG_PLATFORM PLATFORM_HOSTED +#ifdef ANDROID +#define CONFIG_PLATFORM (PLATFORM_HOSTED|PLATFORM_ANDROID) +#else +#define CONFIG_PLATFORM (PLATFORM_HOSTED|PLATFORM_SDL) +#endif /* For Rolo and boot loader */ -/* -#define MODEL_NUMBER 24 -*/ +#define MODEL_NUMBER 100 #define MODEL_NAME "Rockbox" @@ -37,9 +39,17 @@ /* define this if you would like tagcache to build on this target */ #define HAVE_TAGCACHE -/* LCD dimensions */ +/* LCD dimensions + * + * overriden by configure for application builds */ +#ifndef LCD_WIDTH #define LCD_WIDTH 320 -#define LCD_HEIGHT 240 +#endif + +#ifndef LCD_HEIGHT +#define LCD_HEIGHT 480 +#endif + #define LCD_DEPTH 16 #define LCD_PIXELFORMAT 565 @@ -62,10 +72,10 @@ #define CONFIG_CODEC SWCODEC #define CONFIG_KEYPAD COWON_D2_PAD + +#if (CONFIG_PLATFORM & PLATFORM_SDL) /* Use SDL audio/pcm in a SDL app build */ #define HAVE_SDL - -#ifdef HAVE_SDL #define HAVE_SDL_AUDIO #endif @@ -92,3 +102,5 @@ /* Define this if a programmable hotkey is mapped */ //#define HAVE_HOTKEY + +#define BOOTDIR "/.rockbox" diff --git a/firmware/export/config/sim.h b/firmware/export/config/sim.h index 5dcb4f6f2d..066201ad08 100644 --- a/firmware/export/config/sim.h +++ b/firmware/export/config/sim.h @@ -99,7 +99,8 @@ #define DEFAULT_BRIGHTNESS_SETTING MAX_BRIGHTNESS_SETTING #endif +#define CONFIG_PLATFORM (PLATFORM_HOSTED|PLATFORM_SDL) #define HAVE_SDL #define HAVE_SDL_AUDIO -#define CONFIG_PLATFORM PLATFORM_HOSTED + #define _ISOC99_SOURCE 1 diff --git a/firmware/export/debug.h b/firmware/export/debug.h index f7f0f32426..f19a96c526 100644 --- a/firmware/export/debug.h +++ b/firmware/export/debug.h @@ -21,6 +21,7 @@ #ifndef DEBUG_H #define DEBUG_H +#include "config.h" #include "gcc_extensions.h" extern void debug_init(void); @@ -34,7 +35,11 @@ extern void ldebugf(const char* file, int line, const char *fmt, ...) /* */ #if defined(SIMULATOR) && !defined(__PCTOOL__) #define DEBUGF debugf -#define LDEBUGF(...) ldebugf(__FILE__, __LINE__, __VA_ARGS__) +#define LDEBUGF(...) ldebugf(__FILE__, __LINE__, __VA_ARGS__) && defined(DEBUG) +#elif (CONFIG_PLATFORM & PLATFORM_ANDROID) +#include "system-target.h" +#define DEBUGF LOG +#define LDEBUGF(...) #else #if defined(DEBUG) diff --git a/firmware/export/thread.h b/firmware/export/thread.h index c4b7d1fa22..2853c0b121 100644 --- a/firmware/export/thread.h +++ b/firmware/export/thread.h @@ -79,9 +79,19 @@ #define MAXTHREADS (BASETHREADS+TARGET_EXTRA_THREADS) +/* + * We need more stack when we run under a host + * maybe more expensive C lib functions? + * + * simulator doesn't simulate stack usage anyway but well ... */ +#if ((CONFIG_PLATFORM & PLATFORM_NATIVE) || defined(SIMULATOR)) #define DEFAULT_STACK_SIZE 0x400 /* Bytes */ +#else +#define DEFAULT_STACK_SIZE 0x1000 /* Bytes */ +#endif + -#if (CONFIG_PLATFORM & PLATFORM_NATIVE) +#if (CONFIG_PLATFORM & (PLATFORM_NATIVE|PLATFORM_ANDROID)) /* Need to keep structures inside the header file because debug_menu * needs them. */ #ifdef CPU_COLDFIRE @@ -101,7 +111,7 @@ struct regs uint32_t pr; /* 32 - Procedure register */ uint32_t start; /* 36 - Thread start address, or NULL when started */ }; -#elif defined(CPU_ARM) +#elif defined(CPU_ARM) || (CONFIG_PLATFORM & PLATFORM_ANDROID) struct regs { uint32_t r[8]; /* 0-28 - Registers r4-r11 */ diff --git a/firmware/sound.c b/firmware/sound.c index 76f1dd0df6..4cc63f4583 100644 --- a/firmware/sound.c +++ b/firmware/sound.c @@ -273,7 +273,7 @@ static void set_prescaled_volume(void) #elif defined(HAVE_TLV320) || defined(HAVE_WM8978) || defined(HAVE_WM8985) audiohw_set_headphone_vol(tenthdb2master(l), tenthdb2master(r)); -#elif defined(HAVE_JZ4740_CODEC) || defined(HAVE_SDL_AUDIO) +#elif defined(HAVE_JZ4740_CODEC) || defined(HAVE_SDL_AUDIO) || defined(ANDROID) audiohw_set_volume(current_volume); #endif #else /* HAVE_SDL_AUDIO */ diff --git a/firmware/target/hosted/android/app/adc-target.h b/firmware/target/hosted/android/app/adc-target.h new file mode 100644 index 0000000000..f8069be6f5 --- /dev/null +++ b/firmware/target/hosted/android/app/adc-target.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 by Thomas Martitz + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __ADC_TARGET_H__ +#define __ADC_TARGET_H__ + +#endif /* __ADC_TARGET_H__ */ diff --git a/firmware/target/hosted/android/app/backlight-target.h b/firmware/target/hosted/android/app/backlight-target.h new file mode 100644 index 0000000000..f753e7c1dd --- /dev/null +++ b/firmware/target/hosted/android/app/backlight-target.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 by Thomas Martitz + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __BACKLIGHT_TARGET_H__ +#define __BACKLIGHT_TARGET_H__ + +#endif /* __BACKLIGHT_TARGET_H__ */ diff --git a/firmware/target/hosted/android/app/button-application.c b/firmware/target/hosted/android/app/button-application.c new file mode 100644 index 0000000000..a27f769718 --- /dev/null +++ b/firmware/target/hosted/android/app/button-application.c @@ -0,0 +1,29 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Thomas Martitz + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************9*************************/ + + +#include "button.h" + +int key_to_button(int keyboard_key) +{ + (void)keyboard_key; + return BUTTON_NONE; +} diff --git a/firmware/target/hosted/android/app/button-target.h b/firmware/target/hosted/android/app/button-target.h new file mode 100644 index 0000000000..329ed651af --- /dev/null +++ b/firmware/target/hosted/android/app/button-target.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by Rob Purchase + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef _BUTTON_TARGET_H_ +#define _BUTTON_TARGET_H_ + +#include <stdbool.h> +#include "config.h" + +#undef button_init_device +void button_init_device(void); +int button_read_device(int *data); + +/* Main unit's buttons */ +#define BUTTON_POWER 0x00000001 +#define BUTTON_PLUS 0x00000002 +#define BUTTON_MINUS 0x00000004 +#define BUTTON_MENU 0x00000008 + +/* Compatibility hacks for flipping. Needs a somewhat better fix. */ +#define BUTTON_LEFT BUTTON_MIDLEFT +#define BUTTON_RIGHT BUTTON_MIDRIGHT +#define BUTTON_UP BUTTON_TOPMIDDLE +#define BUTTON_DOWN BUTTON_BOTTOMMIDDLE + +/* Touch Screen Area Buttons */ +#define BUTTON_TOPLEFT 0x00000010 +#define BUTTON_TOPMIDDLE 0x00000020 +#define BUTTON_TOPRIGHT 0x00000040 +#define BUTTON_MIDLEFT 0x00000080 +#define BUTTON_CENTER 0x00000100 +#define BUTTON_MIDRIGHT 0x00000200 +#define BUTTON_BOTTOMLEFT 0x00000400 +#define BUTTON_BOTTOMMIDDLE 0x00000800 +#define BUTTON_BOTTOMRIGHT 0x00001000 + +#define BUTTON_MAIN 0x1FFF + +/* No remote */ +#define BUTTON_REMOTE 0 + +/* Software power-off */ +#define POWEROFF_BUTTON BUTTON_POWER +#define POWEROFF_COUNT 10 + +#endif /* _BUTTON_TARGET_H_ */ diff --git a/firmware/target/hosted/android/app/i2c-target.h b/firmware/target/hosted/android/app/i2c-target.h new file mode 100644 index 0000000000..89f0436b9e --- /dev/null +++ b/firmware/target/hosted/android/app/i2c-target.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 by Thomas Martitz + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __I2C_TARGET_H__ +#define __I2C_TARGET_H__ + +#endif /* __I2C_TARGET_H__ */ diff --git a/firmware/target/hosted/android/app/usb-target.h b/firmware/target/hosted/android/app/usb-target.h new file mode 100644 index 0000000000..10e04677f9 --- /dev/null +++ b/firmware/target/hosted/android/app/usb-target.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 by Thomas Martitz + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __USB_TARGET_H__ +#define __USB_TARGET_H__ + +#endif /* __USB_TARGET_H__ */ diff --git a/firmware/target/hosted/android/button-android.c b/firmware/target/hosted/android/button-android.c new file mode 100644 index 0000000000..67e8ca1f89 --- /dev/null +++ b/firmware/target/hosted/android/button-android.c @@ -0,0 +1,87 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (c) 2010 Thomas Martitz + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#include <jni.h> +#include <stdbool.h> +#include "config.h" +#include "kernel.h" +#include "system.h" +#include "touchscreen.h" + +static long last_touch; +static int last_y, last_x; + +static enum { + STATE_UNKNOWN, + STATE_UP, + STATE_DOWN, +} last_state = STATE_UNKNOWN; + + +/* + * this writes in an interrupt-like fashion the last pixel coordinates + * that the user pressed on the screen */ +JNIEXPORT void JNICALL +Java_org_rockbox_RockboxFramebuffer_pixelHandler(JNIEnv*env, jobject this, + int x, int y) +{ + (void)env; + (void)this; + last_x = x; + last_y = y; + last_touch = current_tick; +} + +/* + * this notifies us in an interrupt-like fashion whether the user just + * began or stopped the touch action */ +JNIEXPORT void JNICALL +Java_org_rockbox_RockboxFramebuffer_touchHandler(JNIEnv*env, jobject this, + int down) +{ + (void)env; + (void)this; + if (down) + last_state = STATE_DOWN; + else + last_state = STATE_UP; +} + +void button_init_device(void) +{ + last_touch = current_tick; +} + +int button_read_device(int *data) +{ + /* get grid button/coordinates based on the current touchscreen mode */ + int btn = touchscreen_to_pixels(last_x, last_y, data); + if (last_state == STATE_DOWN) + { + return btn; + } + else + { + *data = last_x = last_y = 0; + return 0; + } +} diff --git a/firmware/target/hosted/android/buttonmap.h b/firmware/target/hosted/android/buttonmap.h new file mode 100644 index 0000000000..e90b8a40d4 --- /dev/null +++ b/firmware/target/hosted/android/buttonmap.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 by Fred Bauer + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef __BUTTONMAP_H__ +#define __BUTTONMAP_H__ +/* Button maps: simulated key, x, y, radius, name */ +/* Run sim with --mapping to get coordinates */ +/* or --debugbuttons to check */ +/* The First matching button is returned */ +struct button_map { + int button, x, y, radius; + char *description; +}; + +extern struct button_map bm[]; + +int xy2button( int x, int y); + +/* for the sim, these function is implemented in uisimulator/buttonmap/ *.c */ +int key_to_button(int keyboard_button); +#ifdef HAVE_TOUCHSCREEN +int key_to_touch(int keyboard_button, unsigned int mouse_coords); +#endif + +#endif /* __BUTTONMAP_H__ */ diff --git a/firmware/target/hosted/android/kernel-android.c b/firmware/target/hosted/android/kernel-android.c new file mode 100644 index 0000000000..9594516460 --- /dev/null +++ b/firmware/target/hosted/android/kernel-android.c @@ -0,0 +1,106 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (c) 2010 Thomas Martitz + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#include <jni.h> +#include "config.h" +#include "system.h" + +extern JNIEnv *env_ptr; +extern jclass RockboxActivity_class; +extern jobject RockboxActivity_instance; + +static jclass RockboxTimer_class; +static jobject RockboxTimer_instance; +static jmethodID java_wait_for_interrupt; +static bool initialized = false; + +/* + * This is called from the separate Timer java thread. I have not added any + * interrupt simulation to it (like the sdl counterpart does), + * I think this is probably not needed, unless code calls disable_interrupt() + * in order to be protected from tick tasks, but I can't remember a place right + * now. + * + * No synchronisation mechanism either. This could possibly be problematic, + * but we'll see :) + */ +JNIEXPORT void JNICALL +Java_org_rockbox_RockboxTimer_timerTask(JNIEnv *env, jobject this) +{ + (void)env; + (void)this; + call_tick_tasks(); +} + +void tick_start(unsigned int interval_in_ms) +{ + JNIEnv e = *env_ptr; + /* first, create a new Timer instance */ + RockboxTimer_class = e->FindClass(env_ptr, "org/rockbox/RockboxTimer"); + jmethodID constructor = e->GetMethodID(env_ptr, + RockboxTimer_class, + "<init>", + "(J)V"); + /* the constructor will do the tick_start */ + RockboxTimer_instance = e->NewObject(env_ptr, + RockboxTimer_class, + constructor, + (jlong)interval_in_ms); + + /* get our wfi func also */ + java_wait_for_interrupt = e->GetMethodID(env_ptr, + RockboxTimer_class, + "java_wait_for_interrupt", + "()V"); + /* it's now safe to call java_wait_for_interrupt */ + initialized = true; +} + +void wait_for_interrupt(void) +{ + if (LIKELY(initialized)) + { + (*env_ptr)->CallVoidMethod(env_ptr, + RockboxTimer_instance, + java_wait_for_interrupt); + } +} + +bool timer_register(int reg_prio, void (*unregister_callback)(void), + long cycles, void (*timer_callback)(void)) +{ + (void)reg_prio; + (void)unregister_callback; + (void)cycles; + (void)timer_callback; + return false; +} + +bool timer_set_period(long cycles) +{ + (void)cycles; + return false; +} + +void timer_unregister(void) +{ +} diff --git a/firmware/target/hosted/android/lcd-android.c b/firmware/target/hosted/android/lcd-android.c new file mode 100644 index 0000000000..ef4004ef2a --- /dev/null +++ b/firmware/target/hosted/android/lcd-android.c @@ -0,0 +1,291 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (c) 2010 Thomas Martitz + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#include <jni.h> +#include "config.h" +#include "system.h" +#include "lcd.h" + +extern JNIEnv *env_ptr; +extern jclass RockboxActivity_class; +extern jobject RockboxActivity_instance; + +static jobject Framebuffer_instance; +static jmethodID java_lcd_update; + +void lcd_init_device(void) +{ + /* get the RockboxFramebuffer instance allocated by the activity */ + jfieldID id = (*env_ptr)->GetFieldID(env_ptr, + RockboxActivity_class, + "fb", + "Lorg/rockbox/RockboxFramebuffer;"); + + Framebuffer_instance = (*env_ptr)->GetObjectField(env_ptr, + RockboxActivity_instance, + id); + + jclass Framebuffer_class = (*env_ptr)->GetObjectClass(env_ptr, + Framebuffer_instance); + + /* get the java init function and call it. it'll set up a bitmap + * based on LCD_WIDTH, LCD_HEIGHT and the ByteBuffer which directly maps + * our framebuffer */ + + jmethodID java_init_lcd = (*env_ptr)->GetMethodID(env_ptr, + Framebuffer_class, + "java_lcd_init", + "(IILjava/nio/ByteBuffer;)V"); + java_lcd_update = (*env_ptr)->GetMethodID(env_ptr, + Framebuffer_class, + "java_lcd_update", + "()V"); + + /* map the framebuffer to a ByteBuffer, this way lcd updates will + * be directly feched from the framebuffer */ + jobject buf = (*env_ptr)->NewDirectByteBuffer(env_ptr, + lcd_framebuffer, + sizeof(lcd_framebuffer)); + + (*env_ptr)->CallVoidMethod(env_ptr, + Framebuffer_instance, + java_init_lcd, + LCD_WIDTH, LCD_HEIGHT, buf); +} + +void lcd_update() +{ + /* tell the system we're ready for drawing */ + (*env_ptr)->CallVoidMethod(env_ptr, Framebuffer_instance, java_lcd_update); +} + +void lcd_update_rect(int x, int y, int height, int width) +{ + /* can't do partial updates yet */ + (void)x; (void)y; (void)height; (void)width; + lcd_update(); +} + +/* below is a plain copy from lcd-sdl.c */ + +/** + * |R| |1.000000 -0.000001 1.402000| |Y'| + * |G| = |1.000000 -0.334136 -0.714136| |Pb| + * |B| |1.000000 1.772000 0.000000| |Pr| + * Scaled, normalized, rounded and tweaked to yield RGB 565: + * |R| |74 0 101| |Y' - 16| >> 9 + * |G| = |74 -24 -51| |Cb - 128| >> 8 + * |B| |74 128 0| |Cr - 128| >> 9 + */ +#define YFAC (74) +#define RVFAC (101) +#define GUFAC (-24) +#define GVFAC (-51) +#define BUFAC (128) + +static inline int clamp(int val, int min, int max) +{ + if (val < min) + val = min; + else if (val > max) + val = max; + return val; +} + +void lcd_yuv_set_options(unsigned options) +{ + (void)options; +} + +/* Draw a partial YUV colour bitmap - similiar behavior to lcd_blit_yuv + in the core */ +void lcd_blit_yuv(unsigned char * const src[3], + int src_x, int src_y, int stride, + int x, int y, int width, int height) +{ + const unsigned char *ysrc, *usrc, *vsrc; + int linecounter; + fb_data *dst, *row_end; + long z; + + /* width and height must be >= 2 and an even number */ + width &= ~1; + linecounter = height >> 1; + +#if LCD_WIDTH >= LCD_HEIGHT + dst = &lcd_framebuffer[y][x]; + row_end = dst + width; +#else + dst = &lcd_framebuffer[x][LCD_WIDTH - y - 1]; + row_end = dst + LCD_WIDTH * width; +#endif + + z = stride * src_y; + ysrc = src[0] + z + src_x; + usrc = src[1] + (z >> 2) + (src_x >> 1); + vsrc = src[2] + (usrc - src[1]); + + /* stride => amount to jump from end of last row to start of next */ + stride -= width; + + /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */ + + do + { + do + { + int y, cb, cr, rv, guv, bu, r, g, b; + + y = YFAC*(*ysrc++ - 16); + cb = *usrc++ - 128; + cr = *vsrc++ - 128; + + rv = RVFAC*cr; + guv = GUFAC*cb + GVFAC*cr; + bu = BUFAC*cb; + + r = y + rv; + g = y + guv; + b = y + bu; + + if ((unsigned)(r | g | b) > 64*256-1) + { + r = clamp(r, 0, 64*256-1); + g = clamp(g, 0, 64*256-1); + b = clamp(b, 0, 64*256-1); + } + + *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); + +#if LCD_WIDTH >= LCD_HEIGHT + dst++; +#else + dst += LCD_WIDTH; +#endif + + y = YFAC*(*ysrc++ - 16); + r = y + rv; + g = y + guv; + b = y + bu; + + if ((unsigned)(r | g | b) > 64*256-1) + { + r = clamp(r, 0, 64*256-1); + g = clamp(g, 0, 64*256-1); + b = clamp(b, 0, 64*256-1); + } + + *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); + +#if LCD_WIDTH >= LCD_HEIGHT + dst++; +#else + dst += LCD_WIDTH; +#endif + } + while (dst < row_end); + + ysrc += stride; + usrc -= width >> 1; + vsrc -= width >> 1; + +#if LCD_WIDTH >= LCD_HEIGHT + row_end += LCD_WIDTH; + dst += LCD_WIDTH - width; +#else + row_end -= 1; + dst -= LCD_WIDTH*width + 1; +#endif + + do + { + int y, cb, cr, rv, guv, bu, r, g, b; + + y = YFAC*(*ysrc++ - 16); + cb = *usrc++ - 128; + cr = *vsrc++ - 128; + + rv = RVFAC*cr; + guv = GUFAC*cb + GVFAC*cr; + bu = BUFAC*cb; + + r = y + rv; + g = y + guv; + b = y + bu; + + if ((unsigned)(r | g | b) > 64*256-1) + { + r = clamp(r, 0, 64*256-1); + g = clamp(g, 0, 64*256-1); + b = clamp(b, 0, 64*256-1); + } + + *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); + +#if LCD_WIDTH >= LCD_HEIGHT + dst++; +#else + dst += LCD_WIDTH; +#endif + + y = YFAC*(*ysrc++ - 16); + r = y + rv; + g = y + guv; + b = y + bu; + + if ((unsigned)(r | g | b) > 64*256-1) + { + r = clamp(r, 0, 64*256-1); + g = clamp(g, 0, 64*256-1); + b = clamp(b, 0, 64*256-1); + } + + *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); + +#if LCD_WIDTH >= LCD_HEIGHT + dst++; +#else + dst += LCD_WIDTH; +#endif + } + while (dst < row_end); + + ysrc += stride; + usrc += stride >> 1; + vsrc += stride >> 1; + +#if LCD_WIDTH >= LCD_HEIGHT + row_end += LCD_WIDTH; + dst += LCD_WIDTH - width; +#else + row_end -= 1; + dst -= LCD_WIDTH*width + 1; +#endif + } + while (--linecounter > 0); + +#if LCD_WIDTH >= LCD_HEIGHT + lcd_update_rect(x, y, width, height); +#else + lcd_update_rect(LCD_WIDTH - y - height, x, height, width); +#endif +} diff --git a/firmware/target/hosted/android/pcm-android.c b/firmware/target/hosted/android/pcm-android.c new file mode 100644 index 0000000000..91978f422b --- /dev/null +++ b/firmware/target/hosted/android/pcm-android.c @@ -0,0 +1,174 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (c) 2010 Thomas Martitz + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include <jni.h> +#include <stdbool.h> +#include <system.h> +#include "pcm.h" + +extern JNIEnv *env_ptr; +extern jclass RockboxActivity_class; +extern jobject RockboxActivity_instance; + +/* infos about our pcm chunks */ +static size_t pcm_data_size; +static char *pcm_data_start; + +/* cache frequently called methods */ +static jmethodID play_pause_method; +static jmethodID stop_method; +static jmethodID set_volume_method; +static jclass RockboxPCM_class; +static jobject RockboxPCM_instance; + + +/* + * transfer our raw data into a java array + * + * a bit of a monster functions, but it should cover all cases to overcome + * the issue that the chunk size of the java layer and our pcm chunks are + * differently sized + * + * afterall, it only copies the raw pcm data from pcm_data_start to + * the passed byte[]-array + * + * it is called from the PositionMarker callback of AudioTrack + **/ +JNIEXPORT void JNICALL +Java_org_rockbox_RockboxPCM_pcmSamplesToByteArray(JNIEnv *env, + jobject this, + jbyteArray arr) +{ + (void)this; + size_t len; + size_t array_size = (*env)->GetArrayLength(env, arr); + if (array_size > pcm_data_size) + len = pcm_data_size; + else + len = array_size; + + (*env)->SetByteArrayRegion(env, arr, 0, len, pcm_data_start); + + if (array_size > pcm_data_size) + { /* didn't have enough data for the array ? */ + size_t remaining = array_size - pcm_data_size; + size_t offset = len; + retry: + pcm_play_get_more_callback((void**)&pcm_data_start, &pcm_data_size); + if (pcm_data_size == 0) + return; + if (remaining > pcm_data_size) + { /* got too little data, get more ... */ + (*env)->SetByteArrayRegion(env, arr, offset, pcm_data_size, pcm_data_start); + /* advance in the java array by the amount we copied */ + offset += pcm_data_size; + /* we copied at least a bit */ + remaining -= pcm_data_size; + /* let's get another buch of data and try again */ + goto retry; + } + else + (*env)->SetByteArrayRegion(env, arr, offset, remaining, pcm_data_start); + len = remaining; + } + pcm_data_start += len; + pcm_data_size -= len; +} + +void pcm_play_lock(void) +{ +} + +void pcm_play_unlock(void) +{ +} + +void pcm_dma_apply_settings(void) +{ +} + +void pcm_play_dma_start(const void *addr, size_t size) +{ + pcm_data_start = (char*)addr; + pcm_data_size = size; + + pcm_play_dma_pause(false); +} + +void pcm_play_dma_stop(void) +{ + (*env_ptr)->CallVoidMethod(env_ptr, + RockboxPCM_instance, + stop_method); +} + +void pcm_play_dma_pause(bool pause) +{ + (*env_ptr)->CallVoidMethod(env_ptr, + RockboxPCM_instance, + play_pause_method, + (int)pause); +} + +size_t pcm_get_bytes_waiting(void) +{ + return pcm_data_size; +} + +const void * pcm_play_dma_get_peak_buffer(int *count) +{ + uintptr_t addr = (uintptr_t)pcm_data_start; + *count = pcm_data_size / 4; + return (void *)((addr + 3) & ~3); +} + +void pcm_play_dma_init(void) +{ + /* in order to have background music playing after leaving the activity, + * we need to allocate the PCM object from the Rockbox thread (the Activity + * runs in a separate thread because it would otherwise kill us when + * stopping it) + * + * Luckily we only reference the PCM object from here, so it's safe (and + * clean) to allocate it here + **/ + JNIEnv e = *env_ptr; + /* get the class and its constructor */ + RockboxPCM_class = e->FindClass(env_ptr, "org/rockbox/RockboxPCM"); + jmethodID constructor = e->GetMethodID(env_ptr, RockboxPCM_class, "<init>", "()V"); + /* instance = new RockboxPCM() */ + RockboxPCM_instance = e->NewObject(env_ptr, RockboxPCM_class, constructor); + /* cache needed methods */ + play_pause_method = e->GetMethodID(env_ptr, RockboxPCM_class, "play_pause", "(Z)V"); + set_volume_method = e->GetMethodID(env_ptr, RockboxPCM_class, "set_volume", "(I)V"); + stop_method = e->GetMethodID(env_ptr, RockboxPCM_class, "stop", "()V"); + /* get initial pcm data, if any */ + pcm_play_get_more_callback((void*)&pcm_data_start, &pcm_data_size); +} + +void pcm_postinit(void) +{ +} + +void pcm_set_mixer_volume(int volume) +{ + (*env_ptr)->CallVoidMethod(env_ptr, RockboxPCM_instance, set_volume_method, volume); +} diff --git a/firmware/target/hosted/android/system-android.c b/firmware/target/hosted/android/system-android.c new file mode 100644 index 0000000000..07dff2ed56 --- /dev/null +++ b/firmware/target/hosted/android/system-android.c @@ -0,0 +1,59 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (c) 2010 Thomas Martitz + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#include <jni.h> +#include "config.h" +#include "system.h" + +void system_exception_wait(void) { } +void system_reboot(void) { } +void power_off(void) { } +void system_init(void) { } + + +/* global fields for use with various JNI calls */ +JNIEnv *env_ptr; +jobject RockboxActivity_instance; +jclass RockboxActivity_class; + +uintptr_t *stackbegin; +uintptr_t *stackend; + +extern int main(void); +/* this is the entry point of the android app initially called by jni */ +JNIEXPORT void JNICALL +Java_org_rockbox_RockboxActivity_main(JNIEnv *env, jobject this) +{ + /* hack!!! we can't have a valid stack pointer otherwise. + * but we don't really need it anyway, thread.c only needs it + * for overflow detection which doesn't apply for the main thread + * (it's managed by the OS) */ + + (void)env; + (void)this; + volatile uintptr_t stack = 0; + stackbegin = stackend = &stack; + env_ptr = env; + RockboxActivity_instance = this; + RockboxActivity_class = (*env)->GetObjectClass(env, this); + main(); +} diff --git a/firmware/target/hosted/android/system-target.h b/firmware/target/hosted/android/system-target.h new file mode 100644 index 0000000000..210d191d6c --- /dev/null +++ b/firmware/target/hosted/android/system-target.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 by Thomas Martitz + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef __SYSTEM_TARGET_H__ +#define __SYSTEM_TARGET_H__ + +#define disable_irq() +#define enable_irq() +#define disable_irq_save() 0 +#define restore_irq(level) (void)level + +void power_off(void); + +#include <android/log.h> +#define LOG_TAG "Rockbox" +#define LOG(args...) \ + __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, ##args); + +#endif /* __SYSTEM_TARGET_H__ */ + +#define NEED_GENERIC_BYTESWAPS + diff --git a/firmware/target/hosted/android/thread-android-arm.c b/firmware/target/hosted/android/thread-android-arm.c new file mode 100644 index 0000000000..baf8b84b65 --- /dev/null +++ b/firmware/target/hosted/android/thread-android-arm.c @@ -0,0 +1,98 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2005 by Thom Johansen + * Copyright (C) 2010 by Thomas Martitz (Android-suitable core_sleep()) + * + * Generic ARM threading support + * + * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include <jni.h> +/*--------------------------------------------------------------------------- + * Start the thread running and terminate it if it returns + *--------------------------------------------------------------------------- + */ +static void __attribute__((naked,used)) start_thread(void) +{ + /* r0 = context */ + asm volatile ( + "ldr sp, [r0, #32] \n" /* Load initial sp */ + "ldr r4, [r0, #40] \n" /* start in r4 since it's non-volatile */ + "mov r1, #0 \n" /* Mark thread as running */ + "str r1, [r0, #40] \n" + "mov lr, pc \n" /* Call thread function */ + "bx r4 \n" + ); /* No clobber list - new thread doesn't care */ + thread_exit(); +} + +/* For startup, place context pointer in r4 slot, start_thread pointer in r5 + * slot, and thread function pointer in context.start. See load_context for + * what happens when thread is initially going to run. */ +#define THREAD_STARTUP_INIT(core, thread, function) \ + ({ (thread)->context.r[0] = (uint32_t)&(thread)->context, \ + (thread)->context.r[1] = (uint32_t)start_thread, \ + (thread)->context.start = (uint32_t)function; }) + + +/*--------------------------------------------------------------------------- + * Store non-volatile context. + *--------------------------------------------------------------------------- + */ +static inline void store_context(void* addr) +{ + asm volatile( + "stmia %0, { r4-r11, sp, lr } \n" + : : "r" (addr) + ); +} + +/*--------------------------------------------------------------------------- + * Load non-volatile context. + *--------------------------------------------------------------------------- + */ +static inline void load_context(const void* addr) +{ + asm volatile( + "ldr r0, [%0, #40] \n" /* Load start pointer */ + "cmp r0, #0 \n" /* Check for NULL */ + + /* If not already running, jump to start */ + "ldmneia %0, { r0, pc } \n" + "ldmia %0, { r4-r11, sp, lr } \n" /* Load regs r4 to r14 from context */ + : : "r" (addr) : "r0" /* only! */ + ); +} + +/* + * this core sleep suspends the OS thread rockbox runs under, which greatly + * reduces cpu usage (~100% to <10%) + * + * it returns when the RockboxTimer notified us, i.e. at each tick + * (after it called the tick tasks) + * + * wait_for_interrupt is implemented in kernel-android.c + **/ + +extern void wait_for_interrupt(void); +static inline void core_sleep(void) +{ + wait_for_interrupt(); +} + + diff --git a/firmware/thread.c b/firmware/thread.c index c00fc36e3f..b3d8ec3970 100644 --- a/firmware/thread.c +++ b/firmware/thread.c @@ -123,8 +123,13 @@ static struct core_entry cores[NUM_CORES] IBSS_ATTR; struct thread_entry threads[MAXTHREADS] IBSS_ATTR; static const char main_thread_name[] = "main"; +#if (CONFIG_PLATFORM & PLATFORM_NATIVE) extern uintptr_t stackbegin[]; extern uintptr_t stackend[]; +#else +extern uintptr_t *stackbegin; +extern uintptr_t *stackend; +#endif static inline void core_sleep(IF_COP_VOID(unsigned int core)) __attribute__((always_inline)); @@ -170,7 +175,9 @@ void switch_thread(void) /**************************************************************************** * Processor-specific section - include necessary core support */ -#if defined(CPU_ARM) +#if defined(ANDROID) +#include "thread-android-arm.c" +#elif defined(CPU_ARM) #include "thread-arm.c" #if defined (CPU_PP) #include "thread-pp.c" @@ -1150,7 +1157,7 @@ void switch_thread(void) store_context(&thread->context); /* Check if the current thread stack is overflown */ - if (UNLIKELY(thread->stack[0] != DEADBEEF)) + if (UNLIKELY(thread->stack[0] != DEADBEEF) && thread->stack_size > 0) thread_stkov(thread); #if NUM_CORES > 1 @@ -2319,7 +2326,9 @@ static int stack_usage(uintptr_t *stackptr, size_t stack_size) */ int thread_stack_usage(const struct thread_entry *thread) { - return stack_usage(thread->stack, thread->stack_size); + if (LIKELY(thread->stack_size > 0)) + return stack_usage(thread->stack, thread->stack_size); + return 0; } #if NUM_CORES > 1 |