1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Oscilloscope, with the thought-to-be impossible horizontal aspect!
12 * Copyright (C) 2004 Jens Arnold
14 * All files in this archive are subject to the GNU General Public License.
15 * See the file COPYING in the source tree root for full license agreement.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #ifndef SIMULATOR /* not for simulator by now */
25 #ifdef HAVE_LCD_BITMAP /* and also not for the Player */
27 /* The different drawing modes */
28 #define DRAW_MODE_FILLED 0
29 #define DRAW_MODE_OUTLINE 1
30 #define DRAW_MODE_PIXEL 2
31 #define DRAW_MODE_COUNT 3
33 #define MAX_PEAK 0x8000
35 /* variable button definitions */
36 #if CONFIG_KEYPAD == RECORDER_PAD
37 #define OSCILLOSCOPE_QUIT BUTTON_OFF
38 #define OSCILLOSCOPE_SCROLL BUTTON_F1
39 #define OSCILLOSCOPE_MODE BUTTON_F2
40 #define OSCILLOSCOPE_PAUSE BUTTON_PLAY
41 #define OSCILLOSCOPE_VOL_UP BUTTON_UP
42 #define OSCILLOSCOPE_VOL_DOWN BUTTON_DOWN
44 #elif CONFIG_KEYPAD == ONDIO_PAD
45 #define OSCILLOSCOPE_QUIT BUTTON_OFF
46 #define OSCILLOSCOPE_SCROLL BUTTON_RIGHT
47 #define OSCILLOSCOPE_MODE BUTTON_MENU
48 #define OSCILLOSCOPE_PAUSE BUTTON_LEFT
49 #define OSCILLOSCOPE_VOL_UP BUTTON_UP
50 #define OSCILLOSCOPE_VOL_DOWN BUTTON_DOWN
54 /* unsigned 16 bit multiplication (a single instruction on the SH) */
55 #define MULU16(a, b) ((unsigned long) \
56 (((unsigned short) (a)) * ((unsigned short) (b))))
58 /* global variables */
60 struct plugin_api
* rb
; /* global api struct pointer */
62 int draw_mode
= DRAW_MODE_FILLED
;
70 void lcd_scroll_left(int count
, bool black_border
);
72 void cleanup(void *parameter
);
73 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
);
77 void lcd_scroll_left(int count
, bool black_border
)
83 if ((unsigned) count
>= LCD_WIDTH
)
86 filler
= black_border
? 0xFF : 0;
88 for (by
= 0; by
< (LCD_HEIGHT
/8); by
++)
90 ptr
= rb
->lcd_framebuffer
+ MULU16(LCD_WIDTH
, by
);
92 "mov %0,r1 \n" /* check if both source... */
93 "or %2,r1 \n" /* ...and offset are even */
94 "shlr r1 \n" /* -> lsb = 0 */
95 "bf .sl_start2 \n" /* -> copy word-wise */
97 "add #-1,%2 \n" /* copy byte-wise */
100 "mov.b r1,@(%2,%0) \n"
107 ".sl_start2: \n" /* copy word-wise */
111 "mov.w r1,@(%2,%0) \n"
118 /* %0 */ "r"(ptr
+ count
),
119 /* %1 */ "r"(ptr
+ LCD_WIDTH
),
125 rb
->memset(ptr
+ LCD_WIDTH
- count
, filler
, count
);
131 static int last_left
, last_right
;
132 bool full_update
= false;
136 if ((unsigned)x
>= LCD_WIDTH
)
140 lcd_scroll_left(1, false);
148 rb
->lcd_clearline(x
, 0, x
, LCD_HEIGHT
-1);
152 case DRAW_MODE_FILLED
:
153 rb
->lcd_drawline(x
, LCD_HEIGHT
/2+1,
154 x
, LCD_HEIGHT
/2+1 + left_val
);
155 rb
->lcd_drawline(x
, LCD_HEIGHT
/2-1,
156 x
, LCD_HEIGHT
/2-1 - right_val
);
159 case DRAW_MODE_OUTLINE
:
162 rb
->lcd_drawline(x
- 1, LCD_HEIGHT
/2+1 + last_left
,
163 x
, LCD_HEIGHT
/2+1 + left_val
);
164 rb
->lcd_drawline(x
- 1, LCD_HEIGHT
/2-1 - last_right
,
165 x
, LCD_HEIGHT
/2-1 - right_val
);
168 /* else fall through */
170 case DRAW_MODE_PIXEL
:
171 rb
->lcd_drawpixel(x
, LCD_HEIGHT
/2+1 + left_val
);
172 rb
->lcd_drawpixel(x
, LCD_HEIGHT
/2-1 - right_val
);
179 rb
->lcd_update_rect(MAX(x
- 1, 0), 0, 2, LCD_HEIGHT
);
181 last_left
= left_val
;
182 last_right
= right_val
;
188 void cleanup(void *parameter
)
192 rb
->plugin_unregister_timer();
195 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
201 TEST_PLUGIN_API(api
);
205 rb
->plugin_register_timer(FREQ
/ 67, 1, timer_isr
);
211 /* read the volume info from MAS */
212 left_val
= rb
->mas_codec_readreg(0xC) / (MAX_PEAK
/ (LCD_HEIGHT
/2-2));
213 right_val
= rb
->mas_codec_readreg(0xD) / (MAX_PEAK
/ (LCD_HEIGHT
/2-2));
218 button
= rb
->button_get(paused
);
221 case OSCILLOSCOPE_QUIT
:
225 case OSCILLOSCOPE_SCROLL
:
229 case OSCILLOSCOPE_MODE
:
231 draw_mode
= draw_mode
% DRAW_MODE_COUNT
;
234 case OSCILLOSCOPE_PAUSE
:
238 case OSCILLOSCOPE_VOL_UP
:
239 case OSCILLOSCOPE_VOL_UP
| BUTTON_REPEAT
:
240 vol
= rb
->global_settings
->volume
;
244 rb
->mpeg_sound_set(SOUND_VOLUME
, vol
);
245 rb
->global_settings
->volume
= vol
;
249 case OSCILLOSCOPE_VOL_DOWN
:
250 case OSCILLOSCOPE_VOL_DOWN
| BUTTON_REPEAT
:
251 vol
= rb
->global_settings
->volume
;
255 rb
->mpeg_sound_set(SOUND_VOLUME
, vol
);
256 rb
->global_settings
->volume
= vol
;
261 if (rb
->default_event_handler_ex(button
, cleanup
, NULL
)
262 == SYS_USB_CONNECTED
)
263 return PLUGIN_USB_CONNECTED
;