From 4da04f3bf37cadb7ec59d32573b68c9f50ace950 Mon Sep 17 00:00:00 2001 From: Björn Stenberg Date: Thu, 19 Sep 2002 10:28:10 +0000 Subject: Added Philipp Pertermanns oscillograph demo git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2334 a1c6a512-1295-4272-9138-f99709370657 --- apps/demo_menu.c | 4 + apps/recorder/oscillograph.c | 201 +++++++++++++++++++++++++++++++++++++++++++ firmware/drivers/lcd.c | 17 ++++ firmware/drivers/lcd.h | 1 + 4 files changed, 223 insertions(+) create mode 100644 apps/recorder/oscillograph.c diff --git a/apps/demo_menu.c b/apps/demo_menu.c index de625c5821..23cd7d1cb5 100644 --- a/apps/demo_menu.c +++ b/apps/demo_menu.c @@ -35,6 +35,7 @@ extern Menu bounce(void); extern Menu snow(void); +extern Menu oscillograph(void); Menu demo_menu(void) { @@ -44,6 +45,9 @@ Menu demo_menu(void) struct menu_items items[] = { { str(LANG_BOUNCE), bounce }, { str(LANG_SNOW), snow }, +#ifndef SIMULATOR + { "Oscillograph", oscillograph }, +#endif }; m=menu_init( items, sizeof items / sizeof(struct menu_items) ); diff --git a/apps/recorder/oscillograph.c b/apps/recorder/oscillograph.c new file mode 100644 index 0000000000..c3b76c4626 --- /dev/null +++ b/apps/recorder/oscillograph.c @@ -0,0 +1,201 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 Philipp Pertermann + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include +#include "menu.h" +#include "lcd.h" +#include "button.h" +#include "mas.h" +#include "system.h" + +/* The different drawing modes */ +#define DRAW_MODE_FILLED 0 +#define DRAW_MODE_OUTLINE 1 +#define DRAW_MODE_PIXEL 2 +#define DRAW_MODE_COUNT 3 + +#define MAX_PEAK 0x8000 + +/* number of ticks between two volume samples */ +static int speed = 1; +/* roll == true -> lcd rolls */ +static bool roll = true; +/* see DRAW_MODE_XXX constants for valid values */ +static int drawMode = DRAW_MODE_FILLED; + +/** + * Displays a vertically scrolling oscillosgraph using + * hardware scrolling of the display. The user can change + * speed + */ +Menu oscillograph(void) +{ + /* stores current volume value left */ + int left; + /* stores current volume value right */ + int right; + /* specifies the current position on the lcd */ + int y = LCD_WIDTH - 1; + + /* only needed when drawing lines */ + int lastLeft = 0; + int lastRight = 0; + int lasty = 0; + + bool exit = false; + + /* the main loop */ + while (!exit) { + + /* read the volume info from MAS */ + left = mas_codec_readreg(0xC) / (MAX_PEAK / (LCD_WIDTH / 2 - 2)); + right = mas_codec_readreg(0xD) / (MAX_PEAK / (LCD_WIDTH / 2 - 2)); + + /* delete current line */ + lcd_clearline(0, y, LCD_WIDTH-1, y); + + switch (drawMode) { + case DRAW_MODE_FILLED: + lcd_drawline(LCD_WIDTH / 2 + 1 , y, + LCD_WIDTH / 2 + 1 + right, y); + lcd_drawline(LCD_WIDTH / 2 - 1 , y, + LCD_WIDTH / 2 - 1 -left , y); + break; + + case DRAW_MODE_OUTLINE: + /* last position needed for lines */ + lasty = MAX(y-1, 0); + + /* Here real lines were neccessary because + anything else was ugly. */ + lcd_drawline(LCD_WIDTH / 2 + right , y, + LCD_WIDTH / 2 + lastRight , lasty); + lcd_drawline(LCD_WIDTH / 2 - left , y, + LCD_WIDTH / 2 - lastLeft, lasty); + + /* have to store the old values for drawing lines + the next time */ + lastRight = right; + lastLeft = left; + break; + + case DRAW_MODE_PIXEL: + /* straight and simple */ + lcd_drawpixel(LCD_WIDTH / 2 + right, y); + lcd_drawpixel(LCD_WIDTH / 2 - left, y); + break; + } + + + /* increment and adjust the drawing position */ + y++; + if (y >= LCD_HEIGHT) + y = 0; + + /* I roll before update because otherwise the new + line would appear at the wrong end of the display */ + if (roll) + lcd_roll(y); + + /* now finally make the new sample visible */ + lcd_update_rect(0, MAX(y-1, 0), LCD_WIDTH, 2); + + /* There are two mechanisms to alter speed: + 1.) slowing down is achieved by increasing + the time waiting for user input. This + mechanism uses positive values. + 2.) speeding up is achieved by leaving out + the user input check for (-speed) volume + samples. For this mechanism negative values + are used. + */ + + if (speed >= 0 || ((speed < 0) && (y % (-speed) == 0))) { + bool draw = false; + + /* speed values > 0 slow the oszi down. By user input + speed might become < 1. If a value < 1 was + passed user input would be disabled. Thus + it must be ensured that at least 1 is passed. */ + + /* react to user input */ + switch (button_get_w_tmo(MAX(speed, 1))) { + case BUTTON_UP: + speed++; + draw = true; + break; + + case BUTTON_DOWN: + speed--; + draw = true; + break; + + case BUTTON_PLAY: + /* pause the demo */ + button_get(true); + break; + + case BUTTON_F1: + /* toggle rolling */ + roll = !roll; + break; + + case BUTTON_F2: + /* step through the display modes */ + drawMode ++; + drawMode = drawMode % DRAW_MODE_COUNT; + + /* lcd buffer might be rolled so that + the transition from LCD_HEIGHT to 0 + takes place in the middle of the screen. + That produces ugly results in DRAW_MODE_OUTLINE + mode. If rolling is enabled this change will + be reverted before the next update anyway.*/ + lcd_roll(0); + break; + + case BUTTON_F3: + speed = 1; + draw = true; + break; + + case BUTTON_OFF: + exit = true; + break; + } + + if (draw) { + char buf[16]; + snprintf(buf, sizeof buf, "Speed: %d", -speed); + lcd_putsxy(0, (y + LCD_HEIGHT - 8) % LCD_HEIGHT, buf, 0); + lcd_update_rect(0, (y + LCD_HEIGHT - 8) % LCD_HEIGHT, + LCD_WIDTH, 8); + } + } + } + + /* restore to default roll position. + Looks funny if you forget to do this... */ + lcd_roll(0); + lcd_update(); + + /* standard return */ + return MENU_OK; +} diff --git a/firmware/drivers/lcd.c b/firmware/drivers/lcd.c index 5240dfda42..8abc638175 100644 --- a/firmware/drivers/lcd.c +++ b/firmware/drivers/lcd.c @@ -1163,6 +1163,23 @@ static void scroll_thread(void) } } +#ifndef SIMULATOR +#ifdef HAVE_LCD_BITMAP +/** + * Rolls up the lcd display by the specified amount of lines. + * Lines that are rolled out over the top of the screen are + * rolled in from the bottom again. This is a hardware + * remapping only and all operations on the lcd are affected. + * -> + * @param int lines - The number of lines that are rolled. + * The value must be 0 <= pixels < LCD_HEIGHT. + */ +void lcd_roll(int lines) +{ + lcd_write(true, LCD_SET_DISPLAY_START_LINE | (lines & (LCD_HEIGHT-1))); +} +#endif +#endif /* ----------------------------------------------------------------- * local variables: diff --git a/firmware/drivers/lcd.h b/firmware/drivers/lcd.h index 23b3d75e76..8c89d4c057 100644 --- a/firmware/drivers/lcd.h +++ b/firmware/drivers/lcd.h @@ -116,6 +116,7 @@ extern void lcd_clearline( int x1, int y1, int x2, int y2 ); extern void lcd_drawpixel(int x, int y); extern void lcd_clearpixel(int x, int y); extern void lcd_invertpixel(int x, int y); +extern void lcd_roll(int pixels); #endif /* CHARCELLS / BITMAP */ -- cgit v1.2.3