A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 218 lines 4.8 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2016 by Roman Stolyarov 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 2 15 * of the License, or (at your option) any later version. 16 * 17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 * KIND, either express or implied. 19 * 20 ****************************************************************************/ 21 22#include "config.h" 23#include "jz4760b.h" 24#include "../kernel-internal.h" 25#include "backlight.h" 26#include "font.h" 27#include "lcd.h" 28#include "file.h" 29#ifdef HAVE_BOOTLOADER_USB_MODE 30#include "usb.h" 31#endif 32#include "system.h" 33#include "button.h" 34#include "common.h" 35#include "rb-loader.h" 36#include "loader_strerror.h" 37#include "storage.h" 38#include "file_internal.h" 39#include "disk.h" 40#include "string.h" 41#include "adc.h" 42#include "version.h" 43 44#include "xdebug.h" 45 46#define SHOW_LOGO 47 48extern void show_logo(void); 49extern void power_off(void); 50 51static int lcd_inited = 0; 52void init_lcd(void) 53{ 54 if(lcd_inited) 55 return; 56 57 lcd_init(); 58 font_init(); 59 lcd_setfont(FONT_SYSFIXED); 60 61 lcd_clear_display(); 62 lcd_update(); 63 64 backlight_init(); 65 66 lcd_inited = true; 67} 68 69#ifdef HAVE_BOOTLOADER_USB_MODE 70static void show_splash(int timeout, const char *msg) 71{ 72 init_lcd(); 73 reset_screen(); 74 lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2, 75 (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg); 76 lcd_update(); 77 78 sleep(timeout); 79} 80 81static int usb_inited = 0; 82 83static void usb_mode(void) 84{ 85 int button = 0; 86 87 /* Init USB, but only once */ 88 if (!usb_inited) { 89 usb_init(); 90 usb_start_monitoring(); 91 usb_inited = 1; 92 } 93 94 init_lcd(); 95 reset_screen(); 96 97 /* Wait for USB */ 98 show_splash(0, "Waiting for USB"); 99 while(1) { 100 button = button_get_w_tmo(HZ/2); 101 if (button == BUTTON_POWER) 102 return; 103 if (button == SYS_USB_CONNECTED) 104 break; /* Hit */ 105 } 106 107 /* Got the message - wait for disconnect */ 108 show_splash(0, "Bootloader USB mode"); 109 110 usb_acknowledge(SYS_USB_CONNECTED_ACK); 111 112 while(1) { 113 button = button_get_w_tmo(HZ/2); 114 if (button == SYS_USB_DISCONNECTED) 115 break; 116 } 117 118 show_splash(HZ*2, "USB disconnected"); 119} 120#endif 121 122/* Jump to loaded binary */ 123void exec(void* addr) __attribute__((noinline, noreturn, section(".icode"))); 124 125void exec(void* addr) 126{ 127 commit_discard_idcache(); 128 typedef void(*entry_fn)(void) __attribute__((noreturn)); 129 entry_fn fn = (entry_fn)addr; 130 fn(); 131} 132 133static int boot_rockbox(void) 134{ 135 int rc; 136 137 printf("Mounting disk..."); 138 139 while((rc = disk_mount_all()) <= 0) { 140 verbose = true; 141#ifdef HAVE_BOOTLOADER_USB_MODE 142 error(EDISK, rc, false); 143 usb_mode(); 144#else 145 error(EDISK, rc, true); 146#endif 147 } 148 149 printf("Loading firmware..."); 150 rc = load_firmware((unsigned char *)CONFIG_SDRAM_START, BOOTFILE, 0x400000); 151 if(rc <= EFILE_EMPTY) { 152 printf("!! " BOOTFILE); 153 return rc; 154 } else { 155 printf("Starting Rockbox..."); 156 adc_close(); /* Disable SADC, seems to fix the re-init Rockbox does */ 157 disable_interrupt(); 158 exec((void*) CONFIG_SDRAM_START); 159 return 0; /* Shouldn't happen */ 160 } 161} 162 163int main(void) 164{ 165 int rc; 166 167 serial_puts("\n\nSPL Stage 2\n\n"); 168 169 system_init(); 170 kernel_init(); 171 172 init_lcd(); 173#ifdef SHOW_LOGO 174 show_logo(); 175#endif 176 177 button_init(); 178 enable_irq(); 179 180 int btn = button_read_device(); 181 if(btn & BUTTON_POWER) { 182 verbose = true; 183 } 184 185 rc = storage_init(); 186 if(rc) { 187 verbose = true; 188 error(EATA, rc, true); 189 } 190 191 filesystem_init(); 192 193#ifdef HAVE_BOOTLOADER_USB_MODE 194 /* Enter USB mode if USB is plugged and POWER button is pressed */ 195 if (btn & BUTTON_POWER) { 196 usb_mode(); 197 reset_screen(); 198 } 199#endif /* HAVE_BOOTLOADER_USB_MODE */ 200 201#ifndef SHOW_LOGO 202 printf(MODEL_NAME" Rockbox Bootloader"); 203 printf("Version %s", rbversion); 204#endif 205 206 rc = boot_rockbox(); 207 208 if(rc <= EFILE_EMPTY) { 209 verbose = true; 210 printf("Error: %s", loader_strerror(rc)); 211 } 212 213 /* Power off */ 214 sleep(5*HZ); 215 power_off(); 216 217 return 0; 218}