From c93bf7551d5d9731c7a8a81a94e45b38851ca72d Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Sun, 1 Aug 2010 20:05:58 +0200 Subject: [PATCH] Add target tree files (lcd, tick timer, pcm, buttons and stubs). --- firmware/target/hosted/android/app/adc-target.h | 25 ++ .../target/hosted/android/app/backlight-target.h | 25 ++ .../target/hosted/android/app/button-application.c | 29 ++ firmware/target/hosted/android/app/button-target.h | 64 +++++ firmware/target/hosted/android/app/i2c-target.h | 25 ++ firmware/target/hosted/android/app/usb-target.h | 25 ++ firmware/target/hosted/android/button-android.c | 82 ++++++ firmware/target/hosted/android/buttonmap.h | 43 +++ firmware/target/hosted/android/kernel-android.c | 87 ++++++ firmware/target/hosted/android/lcd-android.c | 291 +++++++++++++++++++++ firmware/target/hosted/android/pcm-android.c | 174 ++++++++++++ firmware/target/hosted/android/system-android.c | 58 ++++ firmware/target/hosted/android/system-target.h | 58 ++++ .../target/hosted/android/thread-android-arm.c | 108 ++++++++ 14 files changed, 1094 insertions(+) create mode 100644 firmware/target/hosted/android/app/adc-target.h create mode 100644 firmware/target/hosted/android/app/backlight-target.h create mode 100644 firmware/target/hosted/android/app/button-application.c create mode 100644 firmware/target/hosted/android/app/button-target.h create mode 100644 firmware/target/hosted/android/app/i2c-target.h create mode 100644 firmware/target/hosted/android/app/usb-target.h create mode 100644 firmware/target/hosted/android/button-android.c create mode 100644 firmware/target/hosted/android/buttonmap.h create mode 100644 firmware/target/hosted/android/kernel-android.c create mode 100644 firmware/target/hosted/android/lcd-android.c create mode 100644 firmware/target/hosted/android/pcm-android.c create mode 100644 firmware/target/hosted/android/system-android.c create mode 100644 firmware/target/hosted/android/system-target.h create mode 100644 firmware/target/hosted/android/thread-android-arm.c 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 000000000..f8069be6f --- /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 000000000..f753e7c1d --- /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 000000000..a27f76971 --- /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 000000000..329ed651a --- /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 +#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 000000000..89f0436b9 --- /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 000000000..10e04677f --- /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 000000000..0cac35fa2 --- /dev/null +++ b/firmware/target/hosted/android/button-android.c @@ -0,0 +1,82 @@ +/*************************************************************************** + * __________ __ ___. + * 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 +#include +#include "config.h" +#include "kernel.h" +#include "system.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) +{ + 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) +{ + 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 000000000..e90b8a40d --- /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 000000000..49d603b84 --- /dev/null +++ b/firmware/target/hosted/android/kernel-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 +#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; + +int set_irq_level(int level) +{ + (void)level; + return 0; +} + + +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) +{ + /* first, get the RockboxTimer instance allocated by RockboxActivity */ + jfieldID tim = (*env_ptr)->GetFieldID(env_ptr, + RockboxActivity_class, + "tim", + "Lcom/example/rbboot/RockboxTimer;"); + + RockboxTimer_instance = (*env_ptr)->GetObjectField(env_ptr, + RockboxActivity_instance, + tim); + RockboxTimer_class = (*env_ptr)->GetObjectClass(env_ptr, + RockboxTimer_instance); + + /* now find its tick start method and call it */ + jmethodID java_tick_start = (*env_ptr)->GetMethodID(env_ptr, + RockboxTimer_class, + "java_tick_start", + "(J)V"); + (*env_ptr)->CallVoidMethod(env_ptr, + RockboxTimer_instance, + java_tick_start, + (jlong)interval_in_ms); +} + +bool timer_register(int reg_prio, void (*unregister_callback)(void), + long cycles, void (*timer_callback)(void)) +{ + return false; +} + +bool timer_set_period(long 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 000000000..e970de5c8 --- /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 +#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", + "Lcom/example/rbboot/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 000000000..669c60667 --- /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 +#include +#include +#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) + * + * Luckly 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 it's constructor */ + RockboxPCM_class = e->FindClass(env_ptr, "org/rockbox/RockboxPCM"); + jmethodID constructor = e->GetMethodID(env_ptr, RockboxPCM_class, "", "()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_method", "(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 000000000..9b3bb6304 --- /dev/null +++ b/firmware/target/hosted/android/system-android.c @@ -0,0 +1,58 @@ +/*************************************************************************** + * __________ __ ___. + * 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 +#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; + +/* 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 000000000..4c10a0263 --- /dev/null +++ b/firmware/target/hosted/android/system-target.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by Michael Sevakis + * + * 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_SDL_H_ +#define _SYSTEM_SDL_H_ + +#include + +#define HIGHEST_IRQ_LEVEL 1 + +int set_irq_level(int level); + +#define disable_irq() \ + ((void)set_irq_level(HIGHEST_IRQ_LEVEL)) + +#define enable_irq() \ + ((void)set_irq_level(0)) + +#define disable_irq_save() \ + set_irq_level(HIGHEST_IRQ_LEVEL) + +#define restore_irq(level) \ + ((void)set_irq_level(level)) + +void sim_enter_irq_handler(void); +void sim_exit_irq_handler(void); +void sim_kernel_shutdown(void); +void sys_poweroff(void); +void sys_handle_argv(int argc, char *argv[]); +void gui_message_loop(void); +void sim_do_exit(void); + +#include +#define LOG_TAG "Rockbox" +#define LOG(args...) \ + __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, ##args); + +#endif /* _SYSTEM_SDL_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 000000000..312a32d74 --- /dev/null +++ b/firmware/target/hosted/android/thread-android-arm.c @@ -0,0 +1,108 @@ +/*************************************************************************** + * __________ __ ___. + * 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 +/*--------------------------------------------------------------------------- + * 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! */ + ); +} + +extern JNIEnv *env_ptr; +extern jclass RockboxActivity_class; +extern jobject RockboxActivity_instance; + +/* + * this core sleep suspends the thread rockbox runs under, which greatly + * reduces cpu usage (~100% to <10%) + * + * it returns when the RockboxTimer notified us, i.e. at each tick + **/ +static inline void core_sleep(void) +{ + static bool got_method_id = false; + static jmethodID java_core_sleep; + + if (UNLIKELY(!got_method_id)) + { /* cache method id */ + java_core_sleep = (*env_ptr)->GetMethodID(env_ptr, + RockboxActivity_class, + "java_core_sleep", + "()V"); + got_method_id = true; + } + (*env_ptr)->CallVoidMethod(env_ptr, RockboxActivity_instance, java_core_sleep); +} + + -- 2.11.4.GIT