Increase the size of one of the look up tables. Fixes 'burst of static' in some files...
[kugel-rb.git] / apps / plugin.c
bloba7baa6d314d22ff6a1f4a597c494a7fe9a491987
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_framebuffer[0][0],
95 lcd_update_rect,
96 lcd_set_drawmode,
97 lcd_get_drawmode,
98 lcd_setfont,
99 lcd_drawpixel,
100 lcd_drawline,
101 lcd_hline,
102 lcd_vline,
103 lcd_drawrect,
104 lcd_fillrect,
105 lcd_mono_bitmap_part,
106 lcd_mono_bitmap,
107 #if LCD_DEPTH > 1
108 lcd_set_foreground,
109 lcd_get_foreground,
110 lcd_set_background,
111 lcd_get_background,
112 lcd_bitmap_part,
113 lcd_bitmap,
114 lcd_get_backdrop,
115 lcd_set_backdrop,
116 #endif
117 #if LCD_DEPTH == 16
118 lcd_bitmap_transparent_part,
119 lcd_bitmap_transparent,
120 lcd_blit_yuv,
121 #if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200) || defined(SANSA_C200) \
122 || defined (IRIVER_H10)
123 lcd_yuv_set_options,
124 #endif
125 #elif (LCD_DEPTH < 4) && !defined(SIMULATOR)
126 lcd_blit_mono,
127 lcd_blit_grey_phase,
128 #endif /* LCD_DEPTH */
129 lcd_puts_style,
130 lcd_puts_scroll_style,
131 bidi_l2v,
132 font_get_bits,
133 font_load,
134 font_get,
135 font_getstringsize,
136 font_get_width,
137 screen_clear_area,
138 gui_scrollbar_draw,
139 #endif
141 backlight_on,
142 backlight_off,
143 backlight_set_timeout,
144 #if CONFIG_CHARGING
145 backlight_set_timeout_plugged,
146 #endif
147 is_backlight_on,
148 gui_syncsplash,
150 #ifdef HAVE_REMOTE_LCD
151 /* remote lcd */
152 lcd_remote_set_contrast,
153 lcd_remote_clear_display,
154 lcd_remote_setmargins,
155 lcd_remote_puts,
156 lcd_remote_puts_scroll,
157 lcd_remote_stop_scroll,
158 lcd_remote_set_drawmode,
159 lcd_remote_get_drawmode,
160 lcd_remote_setfont,
161 lcd_remote_getstringsize,
162 lcd_remote_drawpixel,
163 lcd_remote_drawline,
164 lcd_remote_hline,
165 lcd_remote_vline,
166 lcd_remote_drawrect,
167 lcd_remote_fillrect,
168 lcd_remote_mono_bitmap_part,
169 lcd_remote_mono_bitmap,
170 lcd_remote_putsxy,
171 lcd_remote_puts_style,
172 lcd_remote_puts_scroll_style,
173 &lcd_remote_framebuffer[0][0],
174 lcd_remote_update,
175 lcd_remote_update_rect,
177 remote_backlight_on,
178 remote_backlight_off,
179 remote_backlight_set_timeout,
180 #if CONFIG_CHARGING
181 remote_backlight_set_timeout_plugged,
182 #endif
183 #endif /* HAVE_REMOTE_LCD */
184 #if NB_SCREENS == 2
185 {&screens[SCREEN_MAIN], &screens[SCREEN_REMOTE]},
186 #else
187 {&screens[SCREEN_MAIN]},
188 #endif
189 #if defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
190 lcd_remote_set_foreground,
191 lcd_remote_get_foreground,
192 lcd_remote_set_background,
193 lcd_remote_get_background,
194 lcd_remote_bitmap_part,
195 lcd_remote_bitmap,
196 #endif
197 viewport_set_defaults,
199 /* list */
200 gui_synclist_init,
201 gui_synclist_set_nb_items,
202 gui_synclist_set_icon_callback,
203 gui_synclist_get_nb_items,
204 gui_synclist_get_sel_pos,
205 gui_synclist_draw,
206 gui_synclist_select_item,
207 gui_synclist_add_item,
208 gui_synclist_del_item,
209 gui_synclist_limit_scroll,
210 gui_synclist_do_button,
211 gui_synclist_set_title,
213 /* button */
214 button_get,
215 button_get_w_tmo,
216 button_status,
217 button_clear_queue,
218 button_queue_count,
219 #ifdef HAS_BUTTON_HOLD
220 button_hold,
221 #endif
223 /* file */
224 (open_func)PREFIX(open),
225 PREFIX(close),
226 (read_func)PREFIX(read),
227 PREFIX(lseek),
228 (creat_func)PREFIX(creat),
229 (write_func)PREFIX(write),
230 PREFIX(remove),
231 PREFIX(rename),
232 PREFIX(ftruncate),
233 PREFIX(filesize),
234 fdprintf,
235 read_line,
236 settings_parseline,
237 ata_sleep,
238 #ifndef SIMULATOR
239 ata_disk_is_active,
240 #endif
241 ata_spin,
242 ata_spindown,
243 reload_directory,
244 create_numbered_filename,
245 file_exists,
247 /* dir */
248 opendir,
249 closedir,
250 readdir,
251 mkdir,
252 rmdir,
253 dir_exists,
255 /* kernel/ system */
256 PREFIX(sleep),
257 yield,
258 &current_tick,
259 default_event_handler,
260 default_event_handler_ex,
261 threads,
262 create_thread,
263 thread_exit,
264 thread_wait,
265 #if (CONFIG_CODEC == SWCODEC)
266 mutex_init,
267 mutex_lock,
268 mutex_unlock,
269 align_buffer,
270 #endif
272 reset_poweroff_timer,
273 #ifndef SIMULATOR
274 system_memory_guard,
275 &cpu_frequency,
277 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
278 #ifdef CPU_BOOST_LOGGING
279 cpu_boost_,
280 #else
281 cpu_boost,
282 #endif
283 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
284 #endif /* !SIMULATOR */
285 #ifdef HAVE_SCHEDULER_BOOSTCTRL
286 trigger_cpu_boost,
287 cancel_cpu_boost,
288 #endif
289 #ifdef CACHE_FUNCTIONS_AS_CALL
290 flush_icache,
291 invalidate_icache,
292 #endif
293 timer_register,
294 timer_unregister,
295 timer_set_period,
297 queue_init,
298 queue_delete,
299 queue_post,
300 queue_wait_w_tmo,
301 #if CONFIG_CODEC == SWCODEC
302 queue_enable_queue_send,
303 queue_empty,
304 queue_wait,
305 queue_send,
306 queue_reply,
307 #endif
308 usb_acknowledge,
309 #ifdef RB_PROFILE
310 profile_thread,
311 profstop,
312 profile_func_enter,
313 profile_func_exit,
314 #endif
316 #ifdef SIMULATOR
317 /* special simulator hooks */
318 #if defined(HAVE_LCD_BITMAP) && LCD_DEPTH < 8
319 sim_lcd_ex_init,
320 sim_lcd_ex_update_rect,
321 #endif
322 #endif
324 /* strings and memory */
325 snprintf,
326 vsnprintf,
327 strcpy,
328 strncpy,
329 strlen,
330 strrchr,
331 strcmp,
332 strncmp,
333 strcasecmp,
334 strncasecmp,
335 memset,
336 memcpy,
337 memmove,
338 _ctype_,
339 atoi,
340 strchr,
341 strcat,
342 memchr,
343 memcmp,
344 strcasestr,
345 strtok_r,
346 /* unicode stuff */
347 utf8decode,
348 iso_decode,
349 utf16LEdecode,
350 utf16BEdecode,
351 utf8encode,
352 utf8length,
353 utf8seek,
355 /* sound */
356 sound_set,
357 sound_default,
358 sound_min,
359 sound_max,
360 sound_unit,
361 sound_val2phys,
362 #ifndef SIMULATOR
363 mp3_play_data,
364 mp3_play_pause,
365 mp3_play_stop,
366 mp3_is_playing,
367 #if CONFIG_CODEC != SWCODEC
368 bitswap,
369 #endif
370 #endif
371 #if CONFIG_CODEC == SWCODEC
372 &audio_master_sampr_list[0],
373 &hw_freq_sampr[0],
374 pcm_apply_settings,
375 pcm_play_data,
376 pcm_play_stop,
377 pcm_set_frequency,
378 pcm_is_playing,
379 pcm_is_paused,
380 pcm_play_pause,
381 pcm_get_bytes_waiting,
382 pcm_calculate_peaks,
383 pcm_play_lock,
384 pcm_play_unlock,
385 #ifdef HAVE_RECORDING
386 &rec_freq_sampr[0],
387 pcm_init_recording,
388 pcm_close_recording,
389 pcm_record_data,
390 pcm_record_more,
391 pcm_stop_recording,
392 pcm_calculate_rec_peaks,
393 audio_set_recording_gain,
394 #endif /* HAVE_RECORDING */
395 #if INPUT_SRC_CAPS != 0
396 audio_set_output_source,
397 audio_set_input_source,
398 #endif
399 dsp_set_crossfeed,
400 dsp_set_eq,
401 dsp_dither_enable,
402 dsp_configure,
403 dsp_process,
404 #endif /* CONFIG_CODEC == SWCODEC */
406 /* playback control */
407 playlist_amount,
408 playlist_resume,
409 playlist_start,
410 PREFIX(audio_play),
411 audio_stop,
412 audio_pause,
413 audio_resume,
414 audio_next,
415 audio_prev,
416 audio_ff_rewind,
417 audio_next_track,
418 audio_status,
419 audio_has_changed_track,
420 audio_current_track,
421 audio_flush_and_reload_tracks,
422 audio_get_file_pos,
423 #if !defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
424 mpeg_get_last_header,
425 #endif
426 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) || \
427 (CONFIG_CODEC == SWCODEC)
428 sound_set_pitch,
429 #endif
431 #if !defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
432 /* MAS communication */
433 mas_readmem,
434 mas_writemem,
435 mas_readreg,
436 mas_writereg,
437 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
438 mas_codec_writereg,
439 mas_codec_readreg,
440 i2c_begin,
441 i2c_end,
442 i2c_write,
443 #endif
444 #endif /* !SIMULATOR && CONFIG_CODEC != SWCODEC */
446 /* menu */
447 do_menu,
448 /* statusbars */
449 &statusbars,
450 gui_syncstatusbar_draw,
451 /* options */
452 find_setting,
453 option_screen,
454 set_option,
455 set_bool_options,
456 set_int,
457 set_bool,
458 #ifdef HAVE_LCD_COLOR
459 set_color,
460 #endif
462 /* action handling */
463 get_custom_action,
464 get_action,
465 action_userabort,
467 /* power */
468 battery_level,
469 battery_level_safe,
470 battery_time,
471 #ifndef SIMULATOR
472 battery_voltage,
473 #endif
474 #if CONFIG_CHARGING
475 charger_inserted,
476 # if CONFIG_CHARGING == CHARGING_MONITOR
477 charging_state,
478 # endif
479 #endif
480 #ifdef HAVE_USB_POWER
481 usb_powered,
482 #endif
484 /* misc */
485 srand,
486 rand,
487 (qsort_func)qsort,
488 kbd_input,
489 get_time,
490 set_time,
491 #if CONFIG_RTC
492 mktime,
493 #endif
494 plugin_get_buffer,
495 plugin_get_audio_buffer,
496 plugin_tsr,
497 plugin_get_current_filename,
498 #ifdef PLUGIN_USE_IRAM
499 plugin_iram_init,
500 #endif
501 #if defined(DEBUG) || defined(SIMULATOR)
502 debugf,
503 #endif
504 #ifdef ROCKBOX_HAS_LOGF
505 _logf,
506 #endif
507 &global_settings,
508 &global_status,
509 talk_disable,
510 #if CONFIG_CODEC == SWCODEC
511 codec_load_file,
512 get_codec_filename,
513 get_metadata,
514 #endif
515 mp3info,
516 count_mp3_frames,
517 create_xing_header,
518 find_next_frame,
519 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
520 peak_meter_scale_value,
521 peak_meter_set_use_dbfs,
522 peak_meter_get_use_dbfs,
523 #endif
524 #ifdef HAVE_LCD_BITMAP
525 read_bmp_file,
526 screen_dump_set_hook,
527 #endif
528 show_logo,
529 tree_get_context,
530 set_current_file,
531 set_dirfilter,
533 #ifdef HAVE_WHEEL_POSITION
534 wheel_status,
535 wheel_send_events,
536 #endif
538 #ifdef IRIVER_H100_SERIES
539 /* Routines for the iriver_flash -plugin. */
540 detect_original_firmware,
541 detect_flashed_ramimage,
542 detect_flashed_romimage,
543 #endif
544 led,
545 #if (CONFIG_CODEC == SWCODEC)
546 bufopen,
547 bufalloc,
548 bufclose,
549 bufseek,
550 bufadvance,
551 bufread,
552 bufgetdata,
553 bufgettail,
554 bufcuttail,
556 buf_get_offset,
557 buf_handle_offset,
558 buf_request_buffer_handle,
559 buf_set_base_handle,
560 buf_used,
561 #endif
563 #ifdef HAVE_TAGCACHE
564 tagcache_search,
565 tagcache_search_set_uniqbuf,
566 tagcache_search_add_filter,
567 tagcache_get_next,
568 tagcache_retrieve,
569 tagcache_search_finish,
570 #endif
572 #ifdef HAVE_ALBUMART
573 find_albumart,
574 search_albumart_files,
575 #endif
577 /* new stuff at the end, sort into place next time
578 the API gets incompatible */
582 int plugin_load(const char* plugin, void* parameter)
584 int rc;
585 struct plugin_header *hdr;
586 #ifdef SIMULATOR
587 void *pd;
588 #else /* !SIMULATOR */
589 int fd;
590 ssize_t readsize;
591 #if NUM_CORES > 1
592 unsigned my_core;
593 #endif
594 #endif /* !SIMULATOR */
595 int xm, ym;
596 #ifdef HAVE_REMOTE_LCD
597 int rxm, rym;
598 #endif
600 #if LCD_DEPTH > 1
601 fb_data* old_backdrop;
602 #endif
604 if (pfn_tsr_exit != NULL) /* if we have a resident old plugin: */
606 if (pfn_tsr_exit(!strcmp(current_plugin, plugin)) == false )
608 /* not allowing another plugin to load */
609 return PLUGIN_OK;
611 pfn_tsr_exit = NULL;
612 plugin_loaded = false;
615 gui_syncsplash(0, ID2P(LANG_WAIT));
616 strcpy(current_plugin, plugin);
618 #ifdef SIMULATOR
619 hdr = sim_plugin_load((char *)plugin, &pd);
620 if (pd == NULL) {
621 gui_syncsplash(HZ*2, str(LANG_PLUGIN_CANT_OPEN), plugin);
622 return -1;
624 if (hdr == NULL
625 || hdr->magic != PLUGIN_MAGIC
626 || hdr->target_id != TARGET_ID) {
627 sim_plugin_close(pd);
628 gui_syncsplash(HZ*2, str(LANG_PLUGIN_WRONG_MODEL));
629 return -1;
631 if (hdr->api_version > PLUGIN_API_VERSION
632 || hdr->api_version < PLUGIN_MIN_API_VERSION) {
633 sim_plugin_close(pd);
634 gui_syncsplash(HZ*2, str(LANG_PLUGIN_WRONG_VERSION));
635 return -1;
637 #else
638 fd = open(plugin, O_RDONLY);
639 if (fd < 0) {
640 gui_syncsplash(HZ*2, str(LANG_PLUGIN_CANT_OPEN), plugin);
641 return fd;
643 #if NUM_CORES > 1
644 /* Make sure COP cache is flushed and invalidated before loading */
645 my_core = switch_core(CURRENT_CORE ^ 1);
646 invalidate_icache();
647 switch_core(my_core);
648 #endif
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;