diff options
| author | Jörg Hohensohn <hohensoh@rockbox.org> | 2004-04-30 20:37:11 +0000 |
|---|---|---|
| committer | Jörg Hohensohn <hohensoh@rockbox.org> | 2004-04-30 20:37:11 +0000 |
| commit | 68002763a788e7b56904c658e73a78d4d7b1e6ab (patch) | |
| tree | ee6d22c0572f38e78619813e20c4954e177ae002 /apps/plugin.c | |
| parent | 7bd007a597a15cd5fcb4f9c7d20f4309e2cbe1e3 (diff) | |
| download | rockbox-68002763a788e7b56904c658e73a78d4d7b1e6ab.zip rockbox-68002763a788e7b56904c658e73a78d4d7b1e6ab.tar.gz rockbox-68002763a788e7b56904c658e73a78d4d7b1e6ab.tar.bz2 rockbox-68002763a788e7b56904c658e73a78d4d7b1e6ab.tar.xz | |
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
Diffstat (limited to 'apps/plugin.c')
| -rw-r--r-- | apps/plugin.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/apps/plugin.c b/apps/plugin.c index 3258dad..e92a9a4 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -68,6 +68,8 @@ extern void bitswap(unsigned char *data, int length); static bool plugin_loaded = false; static int plugin_size = 0; +static void (*pfn_timer)(void) = NULL; /* user timer handler */ +static void (*pfn_tsr_exit)(void) = NULL; /* TSR exit callback */ static int plugin_test(int api_version, int model, int memsize); @@ -188,6 +190,24 @@ static struct plugin_api rockbox_api = { #ifdef HAVE_LCD_BITMAP checkbox, #endif +#ifndef SIMULATOR + plugin_register_timer, + plugin_unregister_timer, +#endif + plugin_tsr, + create_thread, + remove_thread, + lcd_set_contrast, + mpeg_play, + mpeg_stop, + mpeg_pause, + mpeg_resume, + mpeg_next, + mpeg_prev, + mpeg_ff_rewind, + mpeg_next_track, + mpeg_has_changed_track, + mpeg_status, }; int plugin_load(char* plugin, void* parameter) @@ -202,6 +222,12 @@ int plugin_load(char* plugin, void* parameter) int fd; #endif + if (pfn_tsr_exit != NULL) /* if we have a resident old plugin: */ + { + pfn_tsr_exit(); /* force it to exit now */ + pfn_tsr_exit = NULL; + } + #ifdef HAVE_LCD_BITMAP int xm,ym; lcd_clear_display(); @@ -335,6 +361,67 @@ void* plugin_get_mp3_buffer(int* buffer_size) #endif } +#ifndef SIMULATOR +/* Register a periodic time callback, called every "cycles" CPU clocks. + Note that this function will be called in interrupt context! */ +int plugin_register_timer(int cycles, int prio, void (*timer_callback)(void)) +{ + int phi = 0; /* bits for the prescaler */ + int prescale = 1; + + while (cycles > 0x10000) + { /* work out the smallest prescaler that makes it fit */ + phi++; + prescale *= 2; + cycles /= 2; + } + + if (prescale > 8 || cycles == 0 || prio < 1 || prio > 15) + return 0; /* error, we can't do such period, bad argument */ + + and_b(~0x10, &TSTR); /* Stop the timer 4 */ + and_b(~0x10, &TSNC); /* No synchronization */ + and_b(~0x10, &TMDR); /* Operate normally */ + + pfn_timer = timer_callback; /* install 2nd level ISR */ + + TSR4 &= ~0x01; + TIER4 = 0xF9; /* Enable GRA match interrupt */ + + GRA4 = (unsigned short)(cycles - 1); + TCR4 = 0x20 | phi; /* clear at GRA match, set prescaler */ + IPRD = (IPRD & 0xFF0F) | prio << 4; /* interrupt priority */ + or_b(0x10, &TSTR); /* start timer 4 */ + + return cycles * prescale; /* return the actual period, in CPU clocks */ +} + +/* disable the user timer */ +void plugin_unregister_timer(void) +{ + and_b(~0x10, &TSTR); /* stop the timer 4 */ + IPRD = (IPRD & 0xFF0F); /* disable interrupt */ + pfn_timer = NULL; +} + +/* interrupt handler for user timer */ +#pragma interrupt +void IMIA4(void) +{ + if (pfn_timer != NULL) + pfn_timer(); /* call the user timer function */ +} +#endif /* #ifndef SIMULATOR */ + +/* The plugin wants to stay resident after leaving its main function, e.g. + runs from timer or own thread. The callback is registered to later + instruct it to free its resources before a new plugin gets loaded. */ +void plugin_tsr(void (*exit_callback)(void)) +{ + pfn_tsr_exit = exit_callback; /* remember the callback for later */ +} + + static int plugin_test(int api_version, int model, int memsize) { if (api_version < PLUGIN_MIN_API_VERSION || |