diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/plugin.c | 87 | ||||
-rw-r--r-- | apps/plugin.h | 28 |
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 | ||
69 | static bool plugin_loaded = false; | 69 | static bool plugin_loaded = false; |
70 | static int plugin_size = 0; | 70 | static int plugin_size = 0; |
71 | static void (*pfn_timer)(void) = NULL; /* user timer handler */ | ||
72 | static void (*pfn_tsr_exit)(void) = NULL; /* TSR exit callback */ | ||
71 | 73 | ||
72 | static int plugin_test(int api_version, int model, int memsize); | 74 | static 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 | ||
193 | int plugin_load(char* plugin, void* parameter) | 213 | int 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! */ | ||
367 | int 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 */ | ||
400 | void 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 | ||
409 | void 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. */ | ||
419 | void plugin_tsr(void (*exit_callback)(void)) | ||
420 | { | ||
421 | pfn_tsr_exit = exit_callback; /* remember the callback for later */ | ||
422 | } | ||
423 | |||
424 | |||
338 | static int plugin_test(int api_version, int model, int memsize) | 425 | static 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) */ |
216 | int plugin_load(char* plugin, void* parameter); | 237 | int plugin_load(char* plugin, void* parameter); |
217 | void* plugin_get_buffer(int *buffer_size); | 238 | void* plugin_get_buffer(int *buffer_size); |
218 | void* plugin_get_mp3_buffer(int *buffer_size); | 239 | void* plugin_get_mp3_buffer(int *buffer_size); |
240 | int plugin_register_timer(int cycles, int prio, void (*timer_callback)(void)); | ||
241 | void plugin_unregister_timer(void); | ||
242 | void plugin_tsr(void (*exit_callback)(void)); | ||
219 | 243 | ||
220 | /* defined by the plugin */ | 244 | /* defined by the plugin */ |
221 | enum plugin_status plugin_start(struct plugin_api* rockbox, void* parameter) | 245 | enum plugin_status plugin_start(struct plugin_api* rockbox, void* parameter) |