mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-09 21:22:39 -05:00
New feature for units that can be powered or charged from USB (Recorder fm/v2, Ondios): USB power mode, based on patch #1110332 by Pieter Bos. This way you can save battery power or even charge the battery (fm/v2) while using your unit near a PC. Hold MODE (Ondio) or F1 (fm/v2) while plugging USB to enter that mode. A tiny USB plug icon will be displayed is the status bar (overridden by the regular power plug icon in case of fm/v2 when the charger is connected).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6836 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
6e0436f65c
commit
97a8049389
12 changed files with 109 additions and 48 deletions
|
|
@ -230,6 +230,10 @@ void init(void)
|
||||||
usb_screen();
|
usb_screen();
|
||||||
mounted = true; /* mounting done @ end of USB mode */
|
mounted = true; /* mounting done @ end of USB mode */
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_USB_POWER
|
||||||
|
if (usb_powered()) /* avoid deadlock */
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mounted)
|
if (!mounted)
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ const unsigned char bitmap_icons_6x8[LastIcon][6] =
|
||||||
const unsigned char bitmap_icons_7x8[][7] =
|
const unsigned char bitmap_icons_7x8[][7] =
|
||||||
{
|
{
|
||||||
{0x08,0x1c,0x3e,0x3e,0x3e,0x14,0x14}, /* Power plug */
|
{0x08,0x1c,0x3e,0x3e,0x3e,0x14,0x14}, /* Power plug */
|
||||||
|
{0x1c,0x14,0x3e,0x2a,0x22,0x1c,0x08}, /* USB plug */
|
||||||
{0x00,0x1c,0x1c,0x3e,0x7f,0x00,0x00}, /* Speaker */
|
{0x00,0x1c,0x1c,0x3e,0x7f,0x00,0x00}, /* Speaker */
|
||||||
{0x01,0x1e,0x1c,0x3e,0x7f,0x20,0x40}, /* Speaker mute */
|
{0x01,0x1e,0x1c,0x3e,0x7f,0x20,0x40}, /* Speaker mute */
|
||||||
{0x00,0x7f,0x7f,0x3e,0x1c,0x08,0x00}, /* Play */
|
{0x00,0x7f,0x7f,0x3e,0x1c,0x08,0x00}, /* Play */
|
||||||
|
|
@ -239,7 +240,7 @@ const unsigned char rockbox160x53[] = {
|
||||||
/*
|
/*
|
||||||
* Print battery icon to status bar
|
* Print battery icon to status bar
|
||||||
*/
|
*/
|
||||||
void statusbar_icon_battery(int percent, bool charging)
|
void statusbar_icon_battery(int percent)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int fill;
|
int fill;
|
||||||
|
|
@ -292,11 +293,6 @@ void statusbar_icon_battery(int percent, bool charging)
|
||||||
STATUSBAR_Y_POS, "?");
|
STATUSBAR_Y_POS, "?");
|
||||||
lcd_setfont(FONT_UI);
|
lcd_setfont(FONT_UI);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* draw power plug if charging */
|
|
||||||
if (charging)
|
|
||||||
lcd_bitmap(bitmap_icons_7x8[Icon_Plug], ICON_PLUG_X_POS,
|
|
||||||
STATUSBAR_Y_POS, ICON_PLUG_WIDTH, STATUSBAR_HEIGHT, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ enum icons_5x8 {
|
||||||
|
|
||||||
enum icons_7x8 {
|
enum icons_7x8 {
|
||||||
Icon_Plug,
|
Icon_Plug,
|
||||||
|
Icon_USBPlug,
|
||||||
Icon_Speaker,
|
Icon_Speaker,
|
||||||
Icon_Mute,
|
Icon_Mute,
|
||||||
Icon_Play,
|
Icon_Play,
|
||||||
|
|
@ -97,7 +98,7 @@ extern const unsigned char rockbox160x53[];
|
||||||
#define TIME_X_END STATUSBAR_WIDTH-1
|
#define TIME_X_END STATUSBAR_WIDTH-1
|
||||||
|
|
||||||
extern void statusbar_wipe(void);
|
extern void statusbar_wipe(void);
|
||||||
extern void statusbar_icon_battery(int percent, bool charging);
|
extern void statusbar_icon_battery(int percent);
|
||||||
extern bool statusbar_icon_volume(int percent);
|
extern bool statusbar_icon_volume(int percent);
|
||||||
extern void statusbar_icon_play_state(int state);
|
extern void statusbar_icon_play_state(int state);
|
||||||
extern void statusbar_icon_play_mode(int mode);
|
extern void statusbar_icon_play_mode(int mode);
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,15 @@
|
||||||
#if CONFIG_KEYPAD == IRIVER_H100_PAD
|
#if CONFIG_KEYPAD == IRIVER_H100_PAD
|
||||||
#include "button.h"
|
#include "button.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "usb.h"
|
||||||
|
|
||||||
static enum playmode ff_mode;
|
static enum playmode ff_mode;
|
||||||
|
|
||||||
static long switch_tick;
|
static long switch_tick;
|
||||||
static int battery_charge_step = 0;
|
|
||||||
static bool plug_state;
|
|
||||||
static bool battery_state = true;
|
static bool battery_state = true;
|
||||||
|
#ifdef HAVE_CHARGING
|
||||||
|
static int battery_charge_step = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct status_info {
|
struct status_info {
|
||||||
int battlevel;
|
int battlevel;
|
||||||
|
|
@ -63,6 +65,10 @@ struct status_info {
|
||||||
#if CONFIG_LED == LED_VIRTUAL
|
#if CONFIG_LED == LED_VIRTUAL
|
||||||
bool led; /* disk LED simulation in the status bar */
|
bool led; /* disk LED simulation in the status bar */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_USB_POWER
|
||||||
|
bool usb_power;
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void status_init(void)
|
void status_init(void)
|
||||||
|
|
@ -170,6 +176,9 @@ void status_draw(bool force_redraw)
|
||||||
#if CONFIG_LED == LED_VIRTUAL
|
#if CONFIG_LED == LED_VIRTUAL
|
||||||
info.led = led_read(HZ/2); /* delay should match polling interval */
|
info.led = led_read(HZ/2); /* delay should match polling interval */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_USB_POWER
|
||||||
|
info.usb_power = usb_powered();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* only redraw if forced to, or info has changed */
|
/* only redraw if forced to, or info has changed */
|
||||||
if (force_redraw ||
|
if (force_redraw ||
|
||||||
|
|
@ -183,10 +192,10 @@ void status_draw(bool force_redraw)
|
||||||
/* players always "redraw" */
|
/* players always "redraw" */
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARGING
|
||||||
if (info.inserted) {
|
if (info.inserted) {
|
||||||
battery_state = true;
|
battery_state = true;
|
||||||
plug_state = true;
|
|
||||||
#if defined(HAVE_CHARGE_CTRL) || CONFIG_BATTERY == BATT_LIION2200
|
#if defined(HAVE_CHARGE_CTRL) || CONFIG_BATTERY == BATT_LIION2200
|
||||||
/* zero battery run time if charging */
|
/* zero battery run time if charging */
|
||||||
if (charge_state > 0) {
|
if (charge_state > 0) {
|
||||||
|
|
@ -212,8 +221,9 @@ void status_draw(bool force_redraw)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
plug_state=false;
|
#endif /* HAVE_CHARGING */
|
||||||
|
{
|
||||||
if (info.battery_safe)
|
if (info.battery_safe)
|
||||||
battery_state = true;
|
battery_state = true;
|
||||||
else {
|
else {
|
||||||
|
|
@ -228,8 +238,18 @@ void status_draw(bool force_redraw)
|
||||||
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
if (battery_state)
|
if (battery_state)
|
||||||
statusbar_icon_battery(info.battlevel, plug_state);
|
statusbar_icon_battery(info.battlevel);
|
||||||
|
|
||||||
|
/* draw power plug if charging */
|
||||||
|
if (info.inserted)
|
||||||
|
lcd_bitmap(bitmap_icons_7x8[Icon_Plug], ICON_PLUG_X_POS,
|
||||||
|
STATUSBAR_Y_POS, ICON_PLUG_WIDTH, STATUSBAR_HEIGHT, false);
|
||||||
|
#ifdef HAVE_USB_POWER
|
||||||
|
else if (info.usb_power)
|
||||||
|
lcd_bitmap(bitmap_icons_7x8[Icon_USBPlug], ICON_PLUG_X_POS,
|
||||||
|
STATUSBAR_Y_POS, ICON_PLUG_WIDTH, STATUSBAR_HEIGHT, false);
|
||||||
|
#endif
|
||||||
|
|
||||||
info.redraw_volume = statusbar_icon_volume(info.volume);
|
info.redraw_volume = statusbar_icon_volume(info.volume);
|
||||||
statusbar_icon_play_state(current_playmode() + Icon_Play);
|
statusbar_icon_play_state(current_playmode() + Icon_Play);
|
||||||
switch (info.repeat) {
|
switch (info.repeat) {
|
||||||
|
|
|
||||||
|
|
@ -119,3 +119,4 @@ Alexander Spyridakis
|
||||||
Pedro Baltazar Vasconcelos
|
Pedro Baltazar Vasconcelos
|
||||||
Ray Lambert
|
Ray Lambert
|
||||||
Dave Wiard
|
Dave Wiard
|
||||||
|
Pieter Bos
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,9 @@
|
||||||
/* Define this for LCD backlight available */
|
/* Define this for LCD backlight available */
|
||||||
#define CONFIG_BACKLIGHT BL_RTC /* on I2C controlled RTC port */
|
#define CONFIG_BACKLIGHT BL_RTC /* on I2C controlled RTC port */
|
||||||
|
|
||||||
|
/* define this if the unit can be powered or charged via USB */
|
||||||
|
#define HAVE_USB_POWER
|
||||||
|
|
||||||
#define CONFIG_LCD LCD_SSD1815
|
#define CONFIG_LCD LCD_SSD1815
|
||||||
|
|
||||||
#define BOOTFILE_EXT ".ajz"
|
#define BOOTFILE_EXT ".ajz"
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,9 @@
|
||||||
|
|
||||||
#define CONFIG_LCD LCD_SSD1815
|
#define CONFIG_LCD LCD_SSD1815
|
||||||
|
|
||||||
|
/* define this if the unit can be powered or charged via USB */
|
||||||
|
#define HAVE_USB_POWER
|
||||||
|
|
||||||
#define BOOTFILE_EXT ".ajz"
|
#define BOOTFILE_EXT ".ajz"
|
||||||
#define BOOTFILE "ajbrec" BOOTFILE_EXT
|
#define BOOTFILE "ajbrec" BOOTFILE_EXT
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,9 @@
|
||||||
|
|
||||||
#define CONFIG_LCD LCD_SSD1815
|
#define CONFIG_LCD LCD_SSD1815
|
||||||
|
|
||||||
|
/* define this if the unit can be powered or charged via USB */
|
||||||
|
#define HAVE_USB_POWER
|
||||||
|
|
||||||
#define BOOTFILE_EXT ".ajz"
|
#define BOOTFILE_EXT ".ajz"
|
||||||
#define BOOTFILE "ajbrec" BOOTFILE_EXT
|
#define BOOTFILE "ajbrec" BOOTFILE_EXT
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,9 @@
|
||||||
/* Define this for LCD backlight available */
|
/* Define this for LCD backlight available */
|
||||||
#define CONFIG_BACKLIGHT BL_RTC /* on I2C controlled RTC port */
|
#define CONFIG_BACKLIGHT BL_RTC /* on I2C controlled RTC port */
|
||||||
|
|
||||||
|
/* define this if the unit can be powered or charged via USB */
|
||||||
|
#define HAVE_USB_POWER
|
||||||
|
|
||||||
#define CONFIG_LCD LCD_SSD1815
|
#define CONFIG_LCD LCD_SSD1815
|
||||||
|
|
||||||
#define BOOTFILE_EXT ".ajz"
|
#define BOOTFILE_EXT ".ajz"
|
||||||
|
|
|
||||||
|
|
@ -28,5 +28,8 @@ void usb_wait_for_disconnect(struct event_queue *q);
|
||||||
int usb_wait_for_disconnect_w_tmo(struct event_queue *q, int ticks);
|
int usb_wait_for_disconnect_w_tmo(struct event_queue *q, int ticks);
|
||||||
bool usb_inserted(void); /* return the official value, what's been reported to the threads */
|
bool usb_inserted(void); /* return the official value, what's been reported to the threads */
|
||||||
bool usb_detect(void); /* return the raw hardware value */
|
bool usb_detect(void); /* return the raw hardware value */
|
||||||
|
#ifdef HAVE_USB_POWER
|
||||||
|
bool usb_powered(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -437,7 +437,12 @@ static int runcurrent(void)
|
||||||
current = CURRENT_NORMAL;
|
current = CURRENT_NORMAL;
|
||||||
#endif /* MEM == 8 */
|
#endif /* MEM == 8 */
|
||||||
|
|
||||||
if(usb_inserted()) {
|
if(usb_inserted()
|
||||||
|
#ifdef HAVE_USB_POWER
|
||||||
|
|| usb_powered()
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
current = CURRENT_USB;
|
current = CURRENT_USB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,18 +47,21 @@ void screen_dump(void); /* Nasty again. Defined in apps/ too */
|
||||||
|
|
||||||
#if !defined(SIMULATOR) && !defined(USB_NONE)
|
#if !defined(SIMULATOR) && !defined(USB_NONE)
|
||||||
|
|
||||||
/* Messages from usb_tick */
|
/* Messages from usb_tick and thread states */
|
||||||
#define USB_INSERTED 1
|
#define USB_INSERTED 1
|
||||||
#define USB_EXTRACTED 2
|
#define USB_EXTRACTED 2
|
||||||
#ifdef HAVE_MMC
|
#ifdef HAVE_MMC
|
||||||
#define USB_REENABLE 3
|
#define USB_REENABLE 3
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_USB_POWER
|
||||||
|
#define USB_POWERED 4
|
||||||
|
|
||||||
/* Thread states */
|
#if CONFIG_KEYPAD == RECORDER_PAD
|
||||||
#define EXTRACTING 1
|
#define USBPOWER_BUTTON BUTTON_F1
|
||||||
#define EXTRACTED 2
|
#elif CONFIG_KEYPAD == ONDIO_PAD
|
||||||
#define INSERTED 3
|
#define USBPOWER_BUTTON BUTTON_MENU
|
||||||
#define INSERTING 4
|
#endif
|
||||||
|
#endif /* HAVE_USB_POWER */
|
||||||
|
|
||||||
/* The ADC tick reads one channel per tick, and we want to check 3 successive
|
/* The ADC tick reads one channel per tick, and we want to check 3 successive
|
||||||
readings on the USB voltage channel. This doesn't apply to the Player, but
|
readings on the USB voltage channel. This doesn't apply to the Player, but
|
||||||
|
|
@ -221,8 +224,15 @@ static void usb_thread(void)
|
||||||
screen_dump();
|
screen_dump();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_USB_POWER
|
||||||
|
if(button_status() == USBPOWER_BUTTON)
|
||||||
|
{
|
||||||
|
usb_state = USB_POWERED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
/* Tell all threads that they have to back off the ATA.
|
/* Tell all threads that they have to back off the ATA.
|
||||||
We subtract one for our own thread. */
|
We subtract one for our own thread. */
|
||||||
num_acks_to_expect =
|
num_acks_to_expect =
|
||||||
|
|
@ -230,11 +240,9 @@ static void usb_thread(void)
|
||||||
waiting_for_ack = true;
|
waiting_for_ack = true;
|
||||||
DEBUGF("USB inserted. Waiting for ack from %d threads...\n",
|
DEBUGF("USB inserted. Waiting for ack from %d threads...\n",
|
||||||
num_acks_to_expect);
|
num_acks_to_expect);
|
||||||
#ifdef HAVE_LCD_BITMAP
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SYS_USB_CONNECTED_ACK:
|
case SYS_USB_CONNECTED_ACK:
|
||||||
if(waiting_for_ack)
|
if(waiting_for_ack)
|
||||||
{
|
{
|
||||||
|
|
@ -259,33 +267,37 @@ static void usb_thread(void)
|
||||||
|
|
||||||
case USB_EXTRACTED:
|
case USB_EXTRACTED:
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
if(!do_screendump_instead_of_usb)
|
if(do_screendump_instead_of_usb)
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_USB_POWER
|
||||||
|
if(usb_state == USB_POWERED)
|
||||||
{
|
{
|
||||||
#endif
|
|
||||||
if(usb_state == USB_INSERTED)
|
|
||||||
{
|
|
||||||
/* Only disable the USB mode if we really have enabled it
|
|
||||||
some threads might not have acknowledged the
|
|
||||||
insertion */
|
|
||||||
usb_slave_mode(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
usb_state = USB_EXTRACTED;
|
usb_state = USB_EXTRACTED;
|
||||||
|
break;
|
||||||
/* Tell all threads that we are back in business */
|
|
||||||
num_acks_to_expect =
|
|
||||||
queue_broadcast(SYS_USB_DISCONNECTED, NULL) - 1;
|
|
||||||
waiting_for_ack = true;
|
|
||||||
DEBUGF("USB extracted. Waiting for ack from %d threads...\n",
|
|
||||||
num_acks_to_expect);
|
|
||||||
#ifdef HAVE_LCD_CHARCELLS
|
|
||||||
lcd_icon(ICON_USB, false);
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_LCD_BITMAP
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
if(usb_state == USB_INSERTED)
|
||||||
|
{
|
||||||
|
/* Only disable the USB mode if we really have enabled it
|
||||||
|
some threads might not have acknowledged the
|
||||||
|
insertion */
|
||||||
|
usb_slave_mode(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
usb_state = USB_EXTRACTED;
|
||||||
|
|
||||||
|
/* Tell all threads that we are back in business */
|
||||||
|
num_acks_to_expect =
|
||||||
|
queue_broadcast(SYS_USB_DISCONNECTED, NULL) - 1;
|
||||||
|
waiting_for_ack = true;
|
||||||
|
DEBUGF("USB extracted. Waiting for ack from %d threads...\n",
|
||||||
|
num_acks_to_expect);
|
||||||
|
#ifdef HAVE_LCD_CHARCELLS
|
||||||
|
lcd_icon(ICON_USB, false);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SYS_USB_DISCONNECTED_ACK:
|
case SYS_USB_DISCONNECTED_ACK:
|
||||||
if(waiting_for_ack)
|
if(waiting_for_ack)
|
||||||
{
|
{
|
||||||
|
|
@ -475,6 +487,13 @@ bool usb_inserted(void)
|
||||||
return usb_state == USB_INSERTED;
|
return usb_state == USB_INSERTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_USB_POWER
|
||||||
|
bool usb_powered(void)
|
||||||
|
{
|
||||||
|
return usb_state == USB_POWERED;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifdef USB_NONE
|
#ifdef USB_NONE
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue