summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2005-06-23 02:18:29 +0000
committerJens Arnold <amiconn@rockbox.org>2005-06-23 02:18:29 +0000
commit97a804938996d5bbc122128eb78a074491c4ad61 (patch)
tree8e5b58c663edc49bcbffd40c8237f259ca36309c
parent6e0436f65cd461bb2b21c9a0178dfa6978213d27 (diff)
downloadrockbox-97a804938996d5bbc122128eb78a074491c4ad61.tar.gz
rockbox-97a804938996d5bbc122128eb78a074491c4ad61.zip
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
-rw-r--r--apps/main.c4
-rw-r--r--apps/recorder/icons.c8
-rw-r--r--apps/recorder/icons.h3
-rw-r--r--apps/status.c36
-rw-r--r--docs/CREDITS1
-rw-r--r--firmware/export/config-fmrecorder.h3
-rw-r--r--firmware/export/config-ondiofm.h3
-rw-r--r--firmware/export/config-ondiosp.h3
-rw-r--r--firmware/export/config-recorderv2.h3
-rw-r--r--firmware/export/usb.h3
-rw-r--r--firmware/powermgmt.c7
-rw-r--r--firmware/usb.c79
12 files changed, 107 insertions, 46 deletions
diff --git a/apps/main.c b/apps/main.c
index 568a7efd09..9b9bae5098 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -230,6 +230,10 @@ void init(void)
usb_screen();
mounted = true; /* mounting done @ end of USB mode */
}
+#ifdef HAVE_USB_POWER
+ if (usb_powered()) /* avoid deadlock */
+ break;
+#endif
}
if (!mounted)
diff --git a/apps/recorder/icons.c b/apps/recorder/icons.c
index c77050e322..a10f2e1699 100644
--- a/apps/recorder/icons.c
+++ b/apps/recorder/icons.c
@@ -58,6 +58,7 @@ const unsigned char bitmap_icons_6x8[LastIcon][6] =
const unsigned char bitmap_icons_7x8[][7] =
{
{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 */
{0x01,0x1e,0x1c,0x3e,0x7f,0x20,0x40}, /* Speaker mute */
{0x00,0x7f,0x7f,0x3e,0x1c,0x08,0x00}, /* Play */
@@ -239,7 +240,7 @@ const unsigned char rockbox160x53[] = {
/*
* Print battery icon to status bar
*/
-void statusbar_icon_battery(int percent, bool charging)
+void statusbar_icon_battery(int percent)
{
int i;
int fill;
@@ -292,11 +293,6 @@ void statusbar_icon_battery(int percent, bool charging)
STATUSBAR_Y_POS, "?");
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);
}
/*
diff --git a/apps/recorder/icons.h b/apps/recorder/icons.h
index 77a310d053..b2900a1566 100644
--- a/apps/recorder/icons.h
+++ b/apps/recorder/icons.h
@@ -43,6 +43,7 @@ enum icons_5x8 {
enum icons_7x8 {
Icon_Plug,
+ Icon_USBPlug,
Icon_Speaker,
Icon_Mute,
Icon_Play,
@@ -97,7 +98,7 @@ extern const unsigned char rockbox160x53[];
#define TIME_X_END STATUSBAR_WIDTH-1
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 void statusbar_icon_play_state(int state);
extern void statusbar_icon_play_mode(int mode);
diff --git a/apps/status.c b/apps/status.c
index 8d3d1748cb..2218768451 100644
--- a/apps/status.c
+++ b/apps/status.c
@@ -40,13 +40,15 @@
#if CONFIG_KEYPAD == IRIVER_H100_PAD
#include "button.h"
#endif
+#include "usb.h"
static enum playmode ff_mode;
static long switch_tick;
-static int battery_charge_step = 0;
-static bool plug_state;
static bool battery_state = true;
+#ifdef HAVE_CHARGING
+static int battery_charge_step = 0;
+#endif
struct status_info {
int battlevel;
@@ -63,6 +65,10 @@ struct status_info {
#if CONFIG_LED == LED_VIRTUAL
bool led; /* disk LED simulation in the status bar */
#endif
+#ifdef HAVE_USB_POWER
+ bool usb_power;
+#endif
+
};
void status_init(void)
@@ -170,6 +176,9 @@ void status_draw(bool force_redraw)
#if CONFIG_LED == LED_VIRTUAL
info.led = led_read(HZ/2); /* delay should match polling interval */
#endif
+#ifdef HAVE_USB_POWER
+ info.usb_power = usb_powered();
+#endif
/* only redraw if forced to, or info has changed */
if (force_redraw ||
@@ -183,10 +192,10 @@ void status_draw(bool force_redraw)
/* players always "redraw" */
{
#endif
-
+
+#ifdef HAVE_CHARGING
if (info.inserted) {
battery_state = true;
- plug_state = true;
#if defined(HAVE_CHARGE_CTRL) || CONFIG_BATTERY == BATT_LIION2200
/* zero battery run time if charging */
if (charge_state > 0) {
@@ -212,8 +221,9 @@ void status_draw(bool force_redraw)
}
}
}
- else {
- plug_state=false;
+ else
+#endif /* HAVE_CHARGING */
+ {
if (info.battery_safe)
battery_state = true;
else {
@@ -228,8 +238,18 @@ void status_draw(bool force_redraw)
#ifdef HAVE_LCD_BITMAP
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);
statusbar_icon_play_state(current_playmode() + Icon_Play);
switch (info.repeat) {
diff --git a/docs/CREDITS b/docs/CREDITS
index de98748e85..93a2533191 100644
--- a/docs/CREDITS
+++ b/docs/CREDITS
@@ -119,3 +119,4 @@ Alexander Spyridakis
Pedro Baltazar Vasconcelos
Ray Lambert
Dave Wiard
+Pieter Bos
diff --git a/firmware/export/config-fmrecorder.h b/firmware/export/config-fmrecorder.h
index 914ef60f79..a3f2597d5d 100644
--- a/firmware/export/config-fmrecorder.h
+++ b/firmware/export/config-fmrecorder.h
@@ -76,6 +76,9 @@
/* Define this for LCD backlight available */
#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 BOOTFILE_EXT ".ajz"
diff --git a/firmware/export/config-ondiofm.h b/firmware/export/config-ondiofm.h
index b052832bbc..9436b86f1e 100644
--- a/firmware/export/config-ondiofm.h
+++ b/firmware/export/config-ondiofm.h
@@ -90,6 +90,9 @@
#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 "ajbrec" BOOTFILE_EXT
diff --git a/firmware/export/config-ondiosp.h b/firmware/export/config-ondiosp.h
index 6c800b3a53..fd79d19cb7 100644
--- a/firmware/export/config-ondiosp.h
+++ b/firmware/export/config-ondiosp.h
@@ -78,6 +78,9 @@
#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 "ajbrec" BOOTFILE_EXT
diff --git a/firmware/export/config-recorderv2.h b/firmware/export/config-recorderv2.h
index 450222dd38..c75f0e6f12 100644
--- a/firmware/export/config-recorderv2.h
+++ b/firmware/export/config-recorderv2.h
@@ -76,6 +76,9 @@
/* Define this for LCD backlight available */
#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 BOOTFILE_EXT ".ajz"
diff --git a/firmware/export/usb.h b/firmware/export/usb.h
index fc96c67166..e8602e7358 100644
--- a/firmware/export/usb.h
+++ b/firmware/export/usb.h
@@ -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);
bool usb_inserted(void); /* return the official value, what's been reported to the threads */
bool usb_detect(void); /* return the raw hardware value */
+#ifdef HAVE_USB_POWER
+bool usb_powered(void);
+#endif
#endif
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index bb2e6755cb..3eab4131d1 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -437,7 +437,12 @@ static int runcurrent(void)
current = CURRENT_NORMAL;
#endif /* MEM == 8 */
- if(usb_inserted()) {
+ if(usb_inserted()
+#ifdef HAVE_USB_POWER
+ || usb_powered()
+#endif
+ )
+ {
current = CURRENT_USB;
}
diff --git a/firmware/usb.c b/firmware/usb.c
index a514f8f0b4..866ca5319c 100644
--- a/firmware/usb.c
+++ b/firmware/usb.c
@@ -47,18 +47,21 @@ void screen_dump(void); /* Nasty again. Defined in apps/ too */
#if !defined(SIMULATOR) && !defined(USB_NONE)
-/* Messages from usb_tick */
+/* Messages from usb_tick and thread states */
#define USB_INSERTED 1
#define USB_EXTRACTED 2
#ifdef HAVE_MMC
#define USB_REENABLE 3
#endif
+#ifdef HAVE_USB_POWER
+#define USB_POWERED 4
-/* Thread states */
-#define EXTRACTING 1
-#define EXTRACTED 2
-#define INSERTED 3
-#define INSERTING 4
+#if CONFIG_KEYPAD == RECORDER_PAD
+#define USBPOWER_BUTTON BUTTON_F1
+#elif CONFIG_KEYPAD == ONDIO_PAD
+#define USBPOWER_BUTTON BUTTON_MENU
+#endif
+#endif /* HAVE_USB_POWER */
/* 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
@@ -221,8 +224,15 @@ static void usb_thread(void)
screen_dump();
}
else
+#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.
We subtract one for our own thread. */
num_acks_to_expect =
@@ -230,11 +240,9 @@ static void usb_thread(void)
waiting_for_ack = true;
DEBUGF("USB inserted. Waiting for ack from %d threads...\n",
num_acks_to_expect);
-#ifdef HAVE_LCD_BITMAP
}
-#endif
break;
-
+
case SYS_USB_CONNECTED_ACK:
if(waiting_for_ack)
{
@@ -259,33 +267,37 @@ static void usb_thread(void)
case USB_EXTRACTED:
#ifdef HAVE_LCD_BITMAP
- if(!do_screendump_instead_of_usb)
- {
+ if(do_screendump_instead_of_usb)
+ break;
#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);
- }
-
+#ifdef HAVE_USB_POWER
+ if(usb_state == USB_POWERED)
+ {
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);
+ break;
+ }
#endif
-#ifdef HAVE_LCD_BITMAP
+ 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
break;
-
+
case SYS_USB_DISCONNECTED_ACK:
if(waiting_for_ack)
{
@@ -475,6 +487,13 @@ bool usb_inserted(void)
return usb_state == USB_INSERTED;
}
+#ifdef HAVE_USB_POWER
+bool usb_powered(void)
+{
+ return usb_state == USB_POWERED;
+}
+#endif
+
#else
#ifdef USB_NONE