A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 211 lines 5.6 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2007 by Michael Sevakis 11 * 12 * LCD scrolling thread and scheduler 13 * 14 * Much collected and combined from the various Rockbox LCD drivers. 15 * 16 * This program is free software; you can redistribute it and/or 17 * modify it under the terms of the GNU General Public License 18 * as published by the Free Software Foundation; either version 2 19 * of the License, or (at your option) any later version. 20 * 21 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 22 * KIND, either express or implied. 23 * 24 ****************************************************************************/ 25 26#include <stdio.h> 27#include "config.h" 28#include "gcc_extensions.h" 29#include "cpu.h" 30#include "kernel.h" 31#include "thread.h" 32#include "usb.h" 33#include "lcd.h" 34#include "font.h" 35#if !defined(BOOTLOADER) 36#include "misc.h" 37#include "settings.h" 38#endif 39#ifdef HAVE_REMOTE_LCD 40#include "lcd-remote.h" 41#endif 42#include "scroll_engine.h" 43 44#if !defined(BOOTLOADER) 45static const char scroll_tick_table[18] = { 46 /* Hz values [f(x)=100.8/(x+.048)]: 47 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33, 49.2, 96.2 */ 48 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3, 2, 1 49}; 50#endif 51 52#include "drivers/lcd-scroll.c" 53 54#ifdef HAVE_REMOTE_LCD 55/* copied from lcd-remote-1bit.c */ 56/* Compile 1 bit vertical packing LCD driver for remote LCD */ 57#undef LCDFN 58#define LCDFN(fn) lcd_remote_ ## fn 59#undef LCDM 60#define LCDM(ma) LCD_REMOTE_ ## ma 61 62#include "drivers/lcd-scroll.c" 63#endif /* HAVE_REMOTE_LCD */ 64 65#if defined(HAVE_REMOTE_LCD) && !defined(BOOTLOADER) 66static struct event_queue scroll_queue SHAREDBSS_ATTR; 67 68static void sync_display_ticks(void) 69{ 70 lcd_scroll_info.last_scroll = 71 lcd_remote_scroll_info.last_scroll = current_tick; 72} 73 74static bool scroll_process_message(int delay) 75{ 76 struct queue_event ev; 77 78 /* just poll once for negative delays */ 79 if (delay < 0) 80 delay = TIMEOUT_NOBLOCK; 81 82 do 83 { 84 long tick = current_tick; 85 queue_wait_w_tmo(&scroll_queue, &ev, delay); 86 87 switch (ev.id) 88 { 89 case SYS_TIMEOUT: 90 return false; 91 case SYS_USB_CONNECTED: 92 usb_acknowledge(SYS_USB_CONNECTED_ACK); 93 usb_wait_for_disconnect(&scroll_queue); 94 sync_display_ticks(); 95 return true; 96#if (CONFIG_PLATFORM & PLATFORM_NATIVE) 97 case SYS_REMOTE_PLUGGED: 98 if (!remote_initialized) 99 sync_display_ticks(); 100#endif 101 } 102 103 delay -= current_tick - tick; 104 } 105 while (delay > 0); 106 107 return false; 108} 109#endif /* HAVE_REMOTE_LCD && !BOOTLOADER */ 110 111#if !defined(BOOTLOADER) 112static void scroll_thread(void); 113static const char scroll_name[] = "scroll"; 114static void scroll_thread(void) NORETURN_ATTR; 115 116#ifdef HAVE_REMOTE_LCD 117static void scroll_thread(void) 118{ 119 enum 120 { 121 SCROLL_LCD = 0x1, 122 SCROLL_LCD_REMOTE = 0x2, 123 }; 124 125 sync_display_ticks(); 126 127 while ( 1 ) 128 { 129 long delay; 130 int scroll; 131 long tick_lcd, tick_remote; 132 133 tick_lcd = lcd_scroll_info.last_scroll + lcd_scroll_info.ticks; 134 delay = current_tick; 135 136 if ( 137#if (CONFIG_PLATFORM & PLATFORM_NATIVE) 138 !remote_initialized || 139#endif 140 (tick_remote = lcd_remote_scroll_info.last_scroll + 141 lcd_remote_scroll_info.ticks, 142 TIME_BEFORE(tick_lcd, tick_remote))) 143 { 144 scroll = SCROLL_LCD; 145 delay = tick_lcd - delay; 146 } 147 /* TIME_BEFORE(tick_remote, tick_lcd) */ 148 else if (tick_lcd != tick_remote) 149 { 150 scroll = SCROLL_LCD_REMOTE; 151 delay = tick_remote - delay; 152 } 153 else 154 { 155 scroll = SCROLL_LCD | SCROLL_LCD_REMOTE; 156 delay = tick_lcd - delay; 157 } 158 159 if (scroll_process_message(delay)) 160 continue; 161 162 if (scroll & SCROLL_LCD) 163 { 164#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) 165 if (lcd_active()) 166#endif 167 lcd_scroll_worker(); 168 lcd_scroll_info.last_scroll = current_tick; 169 } 170 171 if (scroll == (SCROLL_LCD | SCROLL_LCD_REMOTE)) 172 yield(); 173 174 if (scroll & SCROLL_LCD_REMOTE) 175 { 176 lcd_remote_scroll_worker(); 177 lcd_remote_scroll_info.last_scroll = current_tick; 178 } 179 } 180} 181#else /* !HAVE_REMOTE_LCD */ 182static void scroll_thread(void) 183{ 184 while (1) 185 { 186 sleep(lcd_scroll_info.ticks); 187#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) 188 if (lcd_active()) 189#endif 190 lcd_scroll_worker(); 191 } 192} 193#endif /* !HAVE_REMOTE_LCD */ 194 195void scroll_init(void) 196{ 197 static long scroll_stack[(DEFAULT_STACK_SIZE*3)/sizeof(long)]; 198#ifdef HAVE_REMOTE_LCD 199 queue_init(&scroll_queue, true); 200#endif 201 create_thread(scroll_thread, scroll_stack, 202 sizeof(scroll_stack), 0, scroll_name 203 IF_PRIO(, PRIORITY_USER_INTERFACE) 204 IF_COP(, CPU)); 205} 206#else /* BOOTLOADER */ 207void scroll_init(void) 208{ 209 /* DUMMY */ 210} 211#endif /* BOOTLOADER*/