Add the viewport functions to the screens API, including a new getfont() function...
[Rockbox.git] / apps / plugin.c
blob2149fdaee885c6d21aacaddd0625519182859c1b
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Björn Stenberg
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include "plugin.h"
20 #include <ctype.h>
21 #include <string.h>
22 #include <sprintf.h>
23 #include <atoi.h>
24 #include "debug.h"
25 #include "i2c.h"
26 #include "lang.h"
27 #include "led.h"
28 #include "keyboard.h"
29 #include "buffer.h"
30 #include "backlight.h"
31 #include "sound_menu.h"
32 #include "mp3data.h"
33 #include "powermgmt.h"
34 #include "splash.h"
35 #include "logf.h"
36 #include "option_select.h"
37 #include "talk.h"
39 #if CONFIG_CHARGING
40 #include "power.h"
41 #endif
43 #ifdef HAVE_LCD_BITMAP
44 #include "scrollbar.h"
45 #include "peakmeter.h"
46 #include "bmp.h"
47 #include "bidi.h"
48 #endif
50 #ifdef SIMULATOR
51 static unsigned char pluginbuf[PLUGIN_BUFFER_SIZE];
52 void *sim_plugin_load(char *plugin, void **pd);
53 void sim_plugin_close(void *pd);
54 void sim_lcd_ex_init(int shades, unsigned long (*getpixel)(int, int));
55 void sim_lcd_ex_update_rect(int x, int y, int width, int height);
56 #else
57 #define sim_plugin_close(x)
58 extern unsigned char pluginbuf[];
59 #include "bitswap.h"
60 #endif
62 /* for actual plugins only, not for codecs */
63 static bool plugin_loaded = false;
64 static int plugin_size = 0;
65 static bool (*pfn_tsr_exit)(bool reenter) = NULL; /* TSR exit callback */
66 static char current_plugin[MAX_PATH];
68 char *plugin_get_current_filename(void);
70 extern struct thread_entry threads[MAXTHREADS];
72 static const struct plugin_api rockbox_api = {
74 /* lcd */
75 lcd_set_contrast,
76 lcd_update,
77 lcd_clear_display,
78 lcd_setmargins,
79 lcd_getstringsize,
80 lcd_putsxy,
81 lcd_puts,
82 lcd_puts_scroll,
83 lcd_stop_scroll,
84 #ifdef HAVE_LCD_CHARCELLS
85 lcd_define_pattern,
86 lcd_get_locked_pattern,
87 lcd_unlock_pattern,
88 lcd_putc,
89 lcd_put_cursor,
90 lcd_remove_cursor,
91 lcd_icon,
92 lcd_double_height,
93 #else
94 lcd_set_drawmode,
95 lcd_get_drawmode,
96 lcd_setfont,
97 lcd_drawpixel,
98 lcd_drawline,
99 lcd_hline,
100 lcd_vline,
101 lcd_drawrect,
102 lcd_fillrect,
103 lcd_mono_bitmap_part,
104 lcd_mono_bitmap,
105 #if LCD_DEPTH > 1
106 lcd_set_foreground,
107 lcd_get_foreground,
108 lcd_set_background,
109 lcd_get_background,
110 lcd_bitmap_part,
111 lcd_bitmap,
112 lcd_get_backdrop,
113 lcd_set_backdrop,
114 #endif
115 #if LCD_DEPTH == 16
116 lcd_bitmap_transparent_part,
117 lcd_bitmap_transparent,
118 #endif
119 bidi_l2v,
120 font_get_bits,
121 font_load,
122 lcd_puts_style,
123 lcd_puts_scroll_style,
124 &lcd_framebuffer[0][0],
125 lcd_blit,
126 lcd_update_rect,
127 gui_scrollbar_draw,
128 font_get,
129 font_getstringsize,
130 font_get_width,
131 screen_clear_area,
132 #endif
133 backlight_on,
134 backlight_off,
135 backlight_set_timeout,
136 #if CONFIG_CHARGING
137 backlight_set_timeout_plugged,
138 #endif
139 gui_syncsplash,
140 #ifdef HAVE_REMOTE_LCD
141 /* remote lcd */
142 lcd_remote_set_contrast,
143 lcd_remote_clear_display,
144 lcd_remote_setmargins,
145 lcd_remote_puts,
146 lcd_remote_puts_scroll,
147 lcd_remote_stop_scroll,
148 lcd_remote_set_drawmode,
149 lcd_remote_get_drawmode,
150 lcd_remote_setfont,
151 lcd_remote_getstringsize,
152 lcd_remote_drawpixel,
153 lcd_remote_drawline,
154 lcd_remote_hline,
155 lcd_remote_vline,
156 lcd_remote_drawrect,
157 lcd_remote_fillrect,
158 lcd_remote_mono_bitmap_part,
159 lcd_remote_mono_bitmap,
160 lcd_remote_putsxy,
161 lcd_remote_puts_style,
162 lcd_remote_puts_scroll_style,
163 &lcd_remote_framebuffer[0][0],
164 lcd_remote_update,
165 lcd_remote_update_rect,
167 remote_backlight_on,
168 remote_backlight_off,
169 #endif
170 #if NB_SCREENS == 2
171 {&screens[SCREEN_MAIN], &screens[SCREEN_REMOTE]},
172 #else
173 {&screens[SCREEN_MAIN]},
174 #endif
175 #if defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
176 lcd_remote_set_foreground,
177 lcd_remote_get_foreground,
178 lcd_remote_set_background,
179 lcd_remote_get_background,
180 lcd_remote_bitmap_part,
181 lcd_remote_bitmap,
182 #endif
184 #if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4) && !defined(SIMULATOR)
185 lcd_grey_phase_blit,
186 #endif
187 #if defined(HAVE_LCD_COLOR)
188 lcd_yuv_blit,
189 #endif
190 #if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200) || defined(SANSA_C200)
191 lcd_yuv_set_options,
192 #endif
193 /* list */
194 gui_synclist_init,
195 gui_synclist_set_nb_items,
196 gui_synclist_set_icon_callback,
197 gui_synclist_get_nb_items,
198 gui_synclist_get_sel_pos,
199 gui_synclist_draw,
200 gui_synclist_select_item,
201 gui_synclist_add_item,
202 gui_synclist_del_item,
203 gui_synclist_limit_scroll,
204 gui_synclist_do_button,
205 gui_synclist_set_title,
207 /* button */
208 button_get,
209 button_get_w_tmo,
210 button_status,
211 button_clear_queue,
212 button_queue_count,
213 #ifdef HAS_BUTTON_HOLD
214 button_hold,
215 #endif
217 /* file */
218 (open_func)PREFIX(open),
219 PREFIX(close),
220 (read_func)PREFIX(read),
221 PREFIX(lseek),
222 (creat_func)PREFIX(creat),
223 (write_func)PREFIX(write),
224 PREFIX(remove),
225 PREFIX(rename),
226 PREFIX(ftruncate),
227 PREFIX(filesize),
228 fdprintf,
229 read_line,
230 settings_parseline,
231 #ifndef SIMULATOR
232 ata_sleep,
233 ata_disk_is_active,
234 #endif
235 ata_spindown,
236 reload_directory,
237 create_numbered_filename,
239 /* dir */
240 opendir,
241 closedir,
242 readdir,
243 mkdir,
244 rmdir,
246 /* kernel/ system */
247 PREFIX(sleep),
248 yield,
249 #ifdef HAVE_PRIORITY_SCHEDULING
250 priority_yield,
251 #endif
252 &current_tick,
253 default_event_handler,
254 default_event_handler_ex,
255 threads,
256 create_thread,
257 remove_thread,
258 reset_poweroff_timer,
259 #ifndef SIMULATOR
260 system_memory_guard,
261 &cpu_frequency,
263 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
264 #ifdef CPU_BOOST_LOGGING
265 cpu_boost_,
266 #else
267 cpu_boost,
268 #endif
269 #endif
270 #endif
271 timer_register,
272 timer_unregister,
273 timer_set_period,
275 queue_init,
276 queue_delete,
277 queue_post,
278 queue_wait_w_tmo,
279 usb_acknowledge,
280 #ifdef RB_PROFILE
281 profile_thread,
282 profstop,
283 profile_func_enter,
284 profile_func_exit,
285 #endif
287 #ifdef SIMULATOR
288 /* special simulator hooks */
289 #if defined(HAVE_LCD_BITMAP) && LCD_DEPTH < 8
290 sim_lcd_ex_init,
291 sim_lcd_ex_update_rect,
292 #endif
293 #endif
295 /* strings and memory */
296 snprintf,
297 vsnprintf,
298 strcpy,
299 strncpy,
300 strlen,
301 strrchr,
302 strcmp,
303 strncmp,
304 strcasecmp,
305 strncasecmp,
306 memset,
307 memcpy,
308 memmove,
309 _ctype_,
310 atoi,
311 strchr,
312 strcat,
313 memchr,
314 memcmp,
315 strcasestr,
316 strtok_r,
317 /* unicode stuff */
318 utf8decode,
319 iso_decode,
320 utf16LEdecode,
321 utf16BEdecode,
322 utf8encode,
323 utf8length,
324 utf8seek,
326 /* sound */
327 #if CONFIG_CODEC == SWCODEC
328 sound_default,
329 #endif
330 sound_set,
332 sound_min,
333 sound_max,
334 #ifndef SIMULATOR
335 mp3_play_data,
336 mp3_play_pause,
337 mp3_play_stop,
338 mp3_is_playing,
339 #if CONFIG_CODEC != SWCODEC
340 bitswap,
341 #endif
342 #endif
343 #if CONFIG_CODEC == SWCODEC
344 &audio_master_sampr_list[0],
345 &hw_freq_sampr[0],
346 pcm_apply_settings,
347 pcm_play_data,
348 pcm_play_stop,
349 pcm_set_frequency,
350 pcm_is_playing,
351 pcm_is_paused,
352 pcm_play_pause,
353 pcm_get_bytes_waiting,
354 pcm_calculate_peaks,
355 #ifdef HAVE_RECORDING
356 &rec_freq_sampr[0],
357 pcm_init_recording,
358 pcm_close_recording,
359 pcm_record_data,
360 pcm_record_more,
361 pcm_stop_recording,
362 pcm_calculate_rec_peaks,
363 audio_set_recording_gain,
364 #endif /* HAVE_RECORDING */
365 #if INPUT_SRC_CAPS != 0
366 audio_set_output_source,
367 audio_set_input_source,
368 #endif
369 #endif /* CONFIG_CODEC == SWCODEC */
371 /* playback control */
372 playlist_amount,
373 playlist_resume,
374 playlist_start,
375 PREFIX(audio_play),
376 audio_stop,
377 audio_pause,
378 audio_resume,
379 audio_next,
380 audio_prev,
381 audio_ff_rewind,
382 audio_next_track,
383 audio_status,
384 audio_has_changed_track,
385 audio_current_track,
386 audio_flush_and_reload_tracks,
387 audio_get_file_pos,
388 #if !defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
389 mpeg_get_last_header,
390 #endif
391 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) || \
392 (CONFIG_CODEC == SWCODEC)
393 sound_set_pitch,
394 #endif
396 #if !defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
397 /* MAS communication */
398 mas_readmem,
399 mas_writemem,
400 mas_readreg,
401 mas_writereg,
402 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
403 mas_codec_writereg,
404 mas_codec_readreg,
405 i2c_begin,
406 i2c_end,
407 i2c_write,
408 #endif
409 #endif /* !SIMULATOR && CONFIG_CODEC != SWCODEC */
411 /* menu */
412 do_menu,
413 /* statusbars */
414 &statusbars,
415 gui_syncstatusbar_draw,
416 /* options */
417 find_setting,
418 option_screen,
419 set_option,
420 set_bool_options,
421 set_int,
422 set_bool,
423 #ifdef HAVE_LCD_COLOR
424 set_color,
425 #endif
427 /* action handling */
428 get_custom_action,
429 get_action,
430 action_userabort,
432 /* power */
433 battery_level,
434 battery_level_safe,
435 battery_time,
436 #ifndef SIMULATOR
437 battery_voltage,
438 #endif
439 #if CONFIG_CHARGING
440 charger_inserted,
441 # if CONFIG_CHARGING == CHARGING_MONITOR
442 charging_state,
443 # endif
444 #endif
445 #ifdef HAVE_USB_POWER
446 usb_powered,
447 #endif
449 /* misc */
450 srand,
451 rand,
452 (qsort_func)qsort,
453 kbd_input,
454 get_time,
455 set_time,
456 #if CONFIG_RTC
457 mktime,
458 #endif
459 plugin_get_buffer,
460 plugin_get_audio_buffer,
461 plugin_tsr,
462 plugin_get_current_filename,
463 #ifdef PLUGIN_USE_IRAM
464 plugin_iram_init,
465 #endif
466 #if defined(DEBUG) || defined(SIMULATOR)
467 debugf,
468 #endif
469 #ifdef ROCKBOX_HAS_LOGF
470 _logf,
471 #endif
472 &global_settings,
473 &global_status,
474 talk_disable,
475 #if CONFIG_CODEC == SWCODEC
476 codec_load_file,
477 get_codec_filename,
478 get_metadata,
479 #endif
480 mp3info,
481 count_mp3_frames,
482 create_xing_header,
483 find_next_frame,
484 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
485 peak_meter_scale_value,
486 peak_meter_set_use_dbfs,
487 peak_meter_get_use_dbfs,
488 #endif
489 #ifdef HAVE_LCD_BITMAP
490 read_bmp_file,
491 screen_dump_set_hook,
492 #endif
493 show_logo,
494 tree_get_context,
495 set_current_file,
496 set_dirfilter,
498 #ifdef HAVE_WHEEL_POSITION
499 wheel_status,
500 wheel_send_events,
501 #endif
503 #ifdef IRIVER_H100_SERIES
504 /* Routines for the iriver_flash -plugin. */
505 detect_original_firmware,
506 detect_flashed_ramimage,
507 detect_flashed_romimage,
508 #endif
509 led,
510 #ifdef CACHE_FUNCTIONS_AS_CALL
511 flush_icache,
512 invalidate_icache,
513 #endif
514 /* new stuff at the end, sort into place next time
515 the API gets incompatible */
517 #if (CONFIG_CODEC == SWCODEC)
518 mutex_init,
519 mutex_lock,
520 mutex_unlock,
521 #endif
523 thread_wait,
525 #if (CONFIG_CODEC == SWCODEC)
526 align_buffer,
527 #endif
529 file_exists,
530 dir_exists,
532 #ifdef HAVE_REMOTE_LCD
533 remote_backlight_set_timeout,
534 #if CONFIG_CHARGING
535 remote_backlight_set_timeout_plugged,
536 #endif
537 #endif /* HAVE_REMOTE_LCD */
539 #if (CONFIG_CODEC == SWCODEC)
540 bufopen,
541 bufalloc,
542 bufclose,
543 bufseek,
544 bufadvance,
545 bufread,
546 bufgetdata,
547 bufgettail,
548 bufcuttail,
550 buf_get_offset,
551 buf_handle_offset,
552 buf_request_buffer_handle,
553 buf_set_base_handle,
554 buf_used,
555 #endif
557 #ifdef HAVE_TAGCACHE
558 tagcache_search,
559 tagcache_search_set_uniqbuf,
560 tagcache_search_add_filter,
561 tagcache_get_next,
562 tagcache_retrieve,
563 tagcache_search_finish,
564 #endif
566 #ifdef HAVE_ALBUMART
567 find_albumart,
568 search_albumart_files,
569 #endif
571 #if CONFIG_CODEC == SWCODEC
572 pcm_play_lock,
573 pcm_play_unlock,
574 queue_enable_queue_send,
575 queue_empty,
576 queue_wait,
577 queue_send,
578 queue_reply,
579 #ifndef HAVE_FLASH_STORAGE
580 ata_spin,
581 #endif
582 #ifdef HAVE_SCHEDULER_BOOSTCTRL
583 trigger_cpu_boost,
584 cancel_cpu_boost,
585 #endif
586 sound_unit,
587 sound_val2phys,
588 #endif /* CONFIG_CODEC == SWCODEC */
591 int plugin_load(const char* plugin, void* parameter)
593 int rc;
594 struct plugin_header *hdr;
595 #ifdef SIMULATOR
596 void *pd;
597 #else
598 int fd;
599 ssize_t readsize;
600 #endif
601 int xm, ym;
602 #ifdef HAVE_REMOTE_LCD
603 int rxm, rym;
604 #endif
606 #if LCD_DEPTH > 1
607 fb_data* old_backdrop;
608 #endif
610 if (pfn_tsr_exit != NULL) /* if we have a resident old plugin: */
612 if (pfn_tsr_exit(!strcmp(current_plugin, plugin)) == false )
614 /* not allowing another plugin to load */
615 return PLUGIN_OK;
617 pfn_tsr_exit = NULL;
618 plugin_loaded = false;
621 gui_syncsplash(0, ID2P(LANG_WAIT));
622 strcpy(current_plugin, plugin);
624 #ifdef SIMULATOR
625 hdr = sim_plugin_load((char *)plugin, &pd);
626 if (pd == NULL) {
627 gui_syncsplash(HZ*2, str(LANG_PLUGIN_CANT_OPEN), plugin);
628 return -1;
630 if (hdr == NULL
631 || hdr->magic != PLUGIN_MAGIC
632 || hdr->target_id != TARGET_ID) {
633 sim_plugin_close(pd);
634 gui_syncsplash(HZ*2, str(LANG_PLUGIN_WRONG_MODEL));
635 return -1;
637 if (hdr->api_version > PLUGIN_API_VERSION
638 || hdr->api_version < PLUGIN_MIN_API_VERSION) {
639 sim_plugin_close(pd);
640 gui_syncsplash(HZ*2, str(LANG_PLUGIN_WRONG_VERSION));
641 return -1;
643 #else
644 fd = open(plugin, O_RDONLY);
645 if (fd < 0) {
646 gui_syncsplash(HZ*2, str(LANG_PLUGIN_CANT_OPEN), plugin);
647 return fd;
650 readsize = read(fd, pluginbuf, PLUGIN_BUFFER_SIZE);
651 close(fd);
653 if (readsize < 0) {
654 gui_syncsplash(HZ*2, str(LANG_READ_FAILED), plugin);
655 return -1;
657 hdr = (struct plugin_header *)pluginbuf;
659 if ((unsigned)readsize <= sizeof(struct plugin_header)
660 || hdr->magic != PLUGIN_MAGIC
661 || hdr->target_id != TARGET_ID
662 || hdr->load_addr != pluginbuf
663 || hdr->end_addr > pluginbuf + PLUGIN_BUFFER_SIZE) {
664 gui_syncsplash(HZ*2, str(LANG_PLUGIN_WRONG_MODEL));
665 return -1;
667 if (hdr->api_version > PLUGIN_API_VERSION
668 || hdr->api_version < PLUGIN_MIN_API_VERSION) {
669 gui_syncsplash(HZ*2, str(LANG_PLUGIN_WRONG_VERSION));
670 return -1;
672 plugin_size = hdr->end_addr - pluginbuf;
674 /* zero out bss area only, above guards end of pluginbuf */
675 if (plugin_size > readsize)
676 memset(pluginbuf + readsize, 0, plugin_size - readsize);
677 #endif
679 plugin_loaded = true;
681 xm = lcd_getxmargin();
682 ym = lcd_getymargin();
683 lcd_setmargins(0,0);
685 #if defined HAVE_LCD_BITMAP && LCD_DEPTH > 1
686 old_backdrop = lcd_get_backdrop();
687 #endif
688 lcd_clear_display();
689 lcd_update();
691 #ifdef HAVE_REMOTE_LCD
692 rxm = lcd_remote_getxmargin();
693 rym = lcd_remote_getymargin();
694 lcd_remote_setmargins(0, 0);
695 lcd_remote_clear_display();
696 lcd_remote_update();
697 #endif
699 invalidate_icache();
701 rc = hdr->entry_point((struct plugin_api*) &rockbox_api, parameter);
702 /* explicitly casting the pointer here to avoid touching every plugin. */
704 button_clear_queue();
706 #ifdef HAVE_LCD_BITMAP
707 #if LCD_DEPTH > 1
708 lcd_set_backdrop(old_backdrop);
709 #ifdef HAVE_LCD_COLOR
710 lcd_set_drawinfo(DRMODE_SOLID, global_settings.fg_color,
711 global_settings.bg_color);
712 #else
713 lcd_set_drawinfo(DRMODE_SOLID, LCD_DEFAULT_FG, LCD_DEFAULT_BG);
714 #endif
715 #else /* LCD_DEPTH == 1 */
716 lcd_set_drawmode(DRMODE_SOLID);
717 #endif /* LCD_DEPTH */
718 #endif /* HAVE_LCD_BITMAP */
720 /* restore margins */
721 lcd_setmargins(xm,ym);
722 lcd_clear_display();
723 lcd_update();
725 #ifdef HAVE_REMOTE_LCD
726 #if LCD_REMOTE_DEPTH > 1
727 lcd_remote_set_drawinfo(DRMODE_SOLID, LCD_REMOTE_DEFAULT_FG,
728 LCD_REMOTE_DEFAULT_BG);
729 #else
730 lcd_remote_set_drawmode(DRMODE_SOLID);
731 #endif
732 lcd_remote_setmargins(rxm, rym);
733 lcd_remote_clear_display();
736 lcd_remote_update();
739 #endif
741 if (pfn_tsr_exit == NULL)
742 plugin_loaded = false;
744 sim_plugin_close(pd);
746 switch (rc) {
747 case PLUGIN_OK:
748 break;
750 case PLUGIN_USB_CONNECTED:
751 return PLUGIN_USB_CONNECTED;
753 default:
754 gui_syncsplash(HZ*2, str(LANG_PLUGIN_ERROR));
755 break;
757 return PLUGIN_OK;
760 /* Returns a pointer to the portion of the plugin buffer that is not already
761 being used. If no plugin is loaded, returns the entire plugin buffer */
762 void* plugin_get_buffer(size_t *buffer_size)
764 int buffer_pos;
766 if (plugin_loaded)
768 if (plugin_size >= PLUGIN_BUFFER_SIZE)
769 return NULL;
771 *buffer_size = PLUGIN_BUFFER_SIZE-plugin_size;
772 buffer_pos = plugin_size;
774 else
776 *buffer_size = PLUGIN_BUFFER_SIZE;
777 buffer_pos = 0;
780 return &pluginbuf[buffer_pos];
783 /* Returns a pointer to the mp3 buffer.
784 Playback gets stopped, to avoid conflicts.
785 Talk buffer is stolen as well.
787 void* plugin_get_audio_buffer(size_t *buffer_size)
789 #if CONFIG_CODEC == SWCODEC
790 return audio_get_buffer(true, buffer_size);
791 #else
792 audio_stop();
793 talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
794 *buffer_size = audiobufend - audiobuf;
795 return audiobuf;
796 #endif
799 #ifdef PLUGIN_USE_IRAM
800 /* Initializes plugin IRAM */
801 void plugin_iram_init(char *iramstart, char *iramcopy, size_t iram_size,
802 char *iedata, size_t iedata_size)
804 /* We need to stop audio playback in order to use codec IRAM */
805 audio_hard_stop();
806 memcpy(iramstart, iramcopy, iram_size);
807 memset(iedata, 0, iedata_size);
808 memset(iramcopy, 0, iram_size);
809 #if NUM_CORES > 1
810 /* writeback cleared iedata and iramcopy areas */
811 flush_icache();
812 #endif
814 #endif /* PLUGIN_USE_IRAM */
816 /* The plugin wants to stay resident after leaving its main function, e.g.
817 runs from timer or own thread. The callback is registered to later
818 instruct it to free its resources before a new plugin gets loaded. */
819 void plugin_tsr(bool (*exit_callback)(bool))
821 pfn_tsr_exit = exit_callback; /* remember the callback for later */
824 char *plugin_get_current_filename(void)
826 return current_plugin;