summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörg Hohensohn <hohensoh@rockbox.org>2004-04-30 20:37:11 +0000
committerJörg Hohensohn <hohensoh@rockbox.org>2004-04-30 20:37:11 +0000
commit68002763a788e7b56904c658e73a78d4d7b1e6ab (patch)
treeee6d22c0572f38e78619813e20c4954e177ae002
parent7bd007a597a15cd5fcb4f9c7d20f4309e2cbe1e3 (diff)
downloadrockbox-68002763a788e7b56904c658e73a78d4d7b1e6ab.tar.gz
rockbox-68002763a788e7b56904c658e73a78d4d7b1e6ab.zip
new plugin features for stuff I'm working on: user timer, TSR, threads, contrast, playback control
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4563 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugin.c87
-rw-r--r--apps/plugin.h28
2 files changed, 113 insertions, 2 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index 3258dadad2..e92a9a4d84 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -68,6 +68,8 @@ extern void bitswap(unsigned char *data, int length);
68 68
69static bool plugin_loaded = false; 69static bool plugin_loaded = false;
70static int plugin_size = 0; 70static int plugin_size = 0;
71static void (*pfn_timer)(void) = NULL; /* user timer handler */
72static void (*pfn_tsr_exit)(void) = NULL; /* TSR exit callback */
71 73
72static int plugin_test(int api_version, int model, int memsize); 74static int plugin_test(int api_version, int model, int memsize);
73 75
@@ -188,6 +190,24 @@ static struct plugin_api rockbox_api = {
188#ifdef HAVE_LCD_BITMAP 190#ifdef HAVE_LCD_BITMAP
189 checkbox, 191 checkbox,
190#endif 192#endif
193#ifndef SIMULATOR
194 plugin_register_timer,
195 plugin_unregister_timer,
196#endif
197 plugin_tsr,
198 create_thread,
199 remove_thread,
200 lcd_set_contrast,
201 mpeg_play,
202 mpeg_stop,
203 mpeg_pause,
204 mpeg_resume,
205 mpeg_next,
206 mpeg_prev,
207 mpeg_ff_rewind,
208 mpeg_next_track,
209 mpeg_has_changed_track,
210 mpeg_status,
191}; 211};
192 212
193int plugin_load(char* plugin, void* parameter) 213int plugin_load(char* plugin, void* parameter)
@@ -202,6 +222,12 @@ int plugin_load(char* plugin, void* parameter)
202 int fd; 222 int fd;
203#endif 223#endif
204 224
225 if (pfn_tsr_exit != NULL) /* if we have a resident old plugin: */
226 {
227 pfn_tsr_exit(); /* force it to exit now */
228 pfn_tsr_exit = NULL;
229 }
230
205#ifdef HAVE_LCD_BITMAP 231#ifdef HAVE_LCD_BITMAP
206 int xm,ym; 232 int xm,ym;
207 lcd_clear_display(); 233 lcd_clear_display();
@@ -335,6 +361,67 @@ void* plugin_get_mp3_buffer(int* buffer_size)
335#endif 361#endif
336} 362}
337 363
364#ifndef SIMULATOR
365/* Register a periodic time callback, called every "cycles" CPU clocks.
366 Note that this function will be called in interrupt context! */
367int plugin_register_timer(int cycles, int prio, void (*timer_callback)(void))
368{
369 int phi = 0; /* bits for the prescaler */
370 int prescale = 1;
371
372 while (cycles > 0x10000)
373 { /* work out the smallest prescaler that makes it fit */
374 phi++;
375 prescale *= 2;
376 cycles /= 2;
377 }
378
379 if (prescale > 8 || cycles == 0 || prio < 1 || prio > 15)
380 return 0; /* error, we can't do such period, bad argument */
381
382 and_b(~0x10, &TSTR); /* Stop the timer 4 */
383 and_b(~0x10, &TSNC); /* No synchronization */
384 and_b(~0x10, &TMDR); /* Operate normally */
385
386 pfn_timer = timer_callback; /* install 2nd level ISR */
387
388 TSR4 &= ~0x01;
389 TIER4 = 0xF9; /* Enable GRA match interrupt */
390
391 GRA4 = (unsigned short)(cycles - 1);
392 TCR4 = 0x20 | phi; /* clear at GRA match, set prescaler */
393 IPRD = (IPRD & 0xFF0F) | prio << 4; /* interrupt priority */
394 or_b(0x10, &TSTR); /* start timer 4 */
395
396 return cycles * prescale; /* return the actual period, in CPU clocks */
397}
398
399/* disable the user timer */
400void plugin_unregister_timer(void)
401{
402 and_b(~0x10, &TSTR); /* stop the timer 4 */
403 IPRD = (IPRD & 0xFF0F); /* disable interrupt */
404 pfn_timer = NULL;
405}
406
407/* interrupt handler for user timer */
408#pragma interrupt
409void IMIA4(void)
410{
411 if (pfn_timer != NULL)
412 pfn_timer(); /* call the user timer function */
413}
414#endif /* #ifndef SIMULATOR */
415
416/* The plugin wants to stay resident after leaving its main function, e.g.
417 runs from timer or own thread. The callback is registered to later
418 instruct it to free its resources before a new plugin gets loaded. */
419void plugin_tsr(void (*exit_callback)(void))
420{
421 pfn_tsr_exit = exit_callback; /* remember the callback for later */
422}
423
424
338static int plugin_test(int api_version, int model, int memsize) 425static int plugin_test(int api_version, int model, int memsize)
339{ 426{
340 if (api_version < PLUGIN_MIN_API_VERSION || 427 if (api_version < PLUGIN_MIN_API_VERSION ||
diff --git a/apps/plugin.h b/apps/plugin.h
index 720e4b20f3..2da469f004 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -43,9 +43,10 @@
43#include "mpeg.h" 43#include "mpeg.h"
44#include "mp3_playback.h" 44#include "mp3_playback.h"
45#include "settings.h" 45#include "settings.h"
46#include "thread.h"
46 47
47/* increase this every time the api struct changes */ 48/* increase this every time the api struct changes */
48#define PLUGIN_API_VERSION 11 49#define PLUGIN_API_VERSION 12
49 50
50/* update this to latest version if a change to the api struct breaks 51/* update this to latest version if a change to the api struct breaks
51 backwards compatibility (and please take the opportunity to sort in any 52 backwards compatibility (and please take the opportunity to sort in any
@@ -195,7 +196,7 @@ struct plugin_api {
195 void* (*plugin_get_mp3_buffer)(int* buffer_size); 196 void* (*plugin_get_mp3_buffer)(int* buffer_size);
196 void (*mpeg_sound_set)(int setting, int value); 197 void (*mpeg_sound_set)(int setting, int value);
197#ifndef SIMULATOR 198#ifndef SIMULATOR
198 void (*mp3_play_init)(void); 199 void (*mp3_play_init)(void); /* FIXME: remove this next time we break compatibility */
199 void (*mp3_play_data)(unsigned char* start, int size, void (*get_more)(unsigned char** start, int* size)); 200 void (*mp3_play_data)(unsigned char* start, int size, void (*get_more)(unsigned char** start, int* size));
200 void (*mp3_play_pause)(bool play); 201 void (*mp3_play_pause)(bool play);
201 void (*mp3_play_stop)(void); 202 void (*mp3_play_stop)(void);
@@ -210,12 +211,35 @@ struct plugin_api {
210#ifdef HAVE_LCD_BITMAP 211#ifdef HAVE_LCD_BITMAP
211 void (*checkbox)(int x, int y, int width, int height, bool checked); 212 void (*checkbox)(int x, int y, int width, int height, bool checked);
212#endif 213#endif
214#ifndef SIMULATOR
215 int (*plugin_register_timer)(int cycles, int prio, void (*timer_callback)(void));
216 void (*plugin_unregister_timer)(void);
217#endif
218 void (*plugin_tsr)(void (*exit_callback)(void));
219 int (*create_thread)(void* function, void* stack, int stack_size, char *name);
220 void (*remove_tread)(void);
221 void (*lcd_set_contrast)(int x);
222
223 /* playback control */
224 void (*mpeg_play)(int offset);
225 void (*mpeg_stop)(void);
226 void (*mpeg_pause)(void);
227 void (*mpeg_resume)(void);
228 void (*mpeg_next)(void);
229 void (*mpeg_prev)(void);
230 void (*mpeg_ff_rewind)(int newtime);
231 struct mp3entry* (*mpeg_next_track)(void);
232 bool (*mpeg_has_changed_track)(void);
233 int (*mpeg_status)(void);
213}; 234};
214 235
215/* defined by the plugin loader (plugin.c) */ 236/* defined by the plugin loader (plugin.c) */
216int plugin_load(char* plugin, void* parameter); 237int plugin_load(char* plugin, void* parameter);
217void* plugin_get_buffer(int *buffer_size); 238void* plugin_get_buffer(int *buffer_size);
218void* plugin_get_mp3_buffer(int *buffer_size); 239void* plugin_get_mp3_buffer(int *buffer_size);
240int plugin_register_timer(int cycles, int prio, void (*timer_callback)(void));
241void plugin_unregister_timer(void);
242void plugin_tsr(void (*exit_callback)(void));
219 243
220/* defined by the plugin */ 244/* defined by the plugin */
221enum plugin_status plugin_start(struct plugin_api* rockbox, void* parameter) 245enum plugin_status plugin_start(struct plugin_api* rockbox, void* parameter)