summaryrefslogtreecommitdiff
path: root/apps/plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugin.c')
-rw-r--r--apps/plugin.c87
1 files changed, 87 insertions, 0 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 ||