summaryrefslogtreecommitdiff
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)
230 usb_screen(); 230 usb_screen();
231 mounted = true; /* mounting done @ end of USB mode */ 231 mounted = true; /* mounting done @ end of USB mode */
232 } 232 }
233#ifdef HAVE_USB_POWER
234 if (usb_powered()) /* avoid deadlock */
235 break;
236#endif
233 } 237 }
234 238
235 if (!mounted) 239 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] =
58const unsigned char bitmap_icons_7x8[][7] = 58const unsigned char bitmap_icons_7x8[][7] =
59{ 59{
60 {0x08,0x1c,0x3e,0x3e,0x3e,0x14,0x14}, /* Power plug */ 60 {0x08,0x1c,0x3e,0x3e,0x3e,0x14,0x14}, /* Power plug */
61 {0x1c,0x14,0x3e,0x2a,0x22,0x1c,0x08}, /* USB plug */
61 {0x00,0x1c,0x1c,0x3e,0x7f,0x00,0x00}, /* Speaker */ 62 {0x00,0x1c,0x1c,0x3e,0x7f,0x00,0x00}, /* Speaker */
62 {0x01,0x1e,0x1c,0x3e,0x7f,0x20,0x40}, /* Speaker mute */ 63 {0x01,0x1e,0x1c,0x3e,0x7f,0x20,0x40}, /* Speaker mute */
63 {0x00,0x7f,0x7f,0x3e,0x1c,0x08,0x00}, /* Play */ 64 {0x00,0x7f,0x7f,0x3e,0x1c,0x08,0x00}, /* Play */
@@ -239,7 +240,7 @@ const unsigned char rockbox160x53[] = {
239/* 240/*
240 * Print battery icon to status bar 241 * Print battery icon to status bar
241 */ 242 */
242void statusbar_icon_battery(int percent, bool charging) 243void statusbar_icon_battery(int percent)
243{ 244{
244 int i; 245 int i;
245 int fill; 246 int fill;
@@ -292,11 +293,6 @@ void statusbar_icon_battery(int percent, bool charging)
292 STATUSBAR_Y_POS, "?"); 293 STATUSBAR_Y_POS, "?");
293 lcd_setfont(FONT_UI); 294 lcd_setfont(FONT_UI);
294 } 295 }
295
296 /* draw power plug if charging */
297 if (charging)
298 lcd_bitmap(bitmap_icons_7x8[Icon_Plug], ICON_PLUG_X_POS,
299 STATUSBAR_Y_POS, ICON_PLUG_WIDTH, STATUSBAR_HEIGHT, false);
300} 296}
301 297
302/* 298/*
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 {
43 43
44enum icons_7x8 { 44enum icons_7x8 {
45 Icon_Plug, 45 Icon_Plug,
46 Icon_USBPlug,
46 Icon_Speaker, 47 Icon_Speaker,
47 Icon_Mute, 48 Icon_Mute,
48 Icon_Play, 49 Icon_Play,
@@ -97,7 +98,7 @@ extern const unsigned char rockbox160x53[];
97#define TIME_X_END STATUSBAR_WIDTH-1 98#define TIME_X_END STATUSBAR_WIDTH-1
98 99
99extern void statusbar_wipe(void); 100extern void statusbar_wipe(void);
100extern void statusbar_icon_battery(int percent, bool charging); 101extern void statusbar_icon_battery(int percent);
101extern bool statusbar_icon_volume(int percent); 102extern bool statusbar_icon_volume(int percent);
102extern void statusbar_icon_play_state(int state); 103extern void statusbar_icon_play_state(int state);
103extern void statusbar_icon_play_mode(int mode); 104extern 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 @@
40#if CONFIG_KEYPAD == IRIVER_H100_PAD 40#if CONFIG_KEYPAD == IRIVER_H100_PAD
41#include "button.h" 41#include "button.h"
42#endif 42#endif
43#include "usb.h"
43 44
44static enum playmode ff_mode; 45static enum playmode ff_mode;
45 46
46static long switch_tick; 47static long switch_tick;
47static int battery_charge_step = 0;
48static bool plug_state;
49static bool battery_state = true; 48static bool battery_state = true;
49#ifdef HAVE_CHARGING
50static int battery_charge_step = 0;
51#endif
50 52
51struct status_info { 53struct status_info {
52 int battlevel; 54 int battlevel;
@@ -63,6 +65,10 @@ struct status_info {
63#if CONFIG_LED == LED_VIRTUAL 65#if CONFIG_LED == LED_VIRTUAL
64 bool led; /* disk LED simulation in the status bar */ 66 bool led; /* disk LED simulation in the status bar */
65#endif 67#endif
68#ifdef HAVE_USB_POWER
69 bool usb_power;
70#endif
71
66}; 72};
67 73
68void status_init(void) 74void status_init(void)
@@ -170,6 +176,9 @@ void status_draw(bool force_redraw)
170#if CONFIG_LED == LED_VIRTUAL 176#if CONFIG_LED == LED_VIRTUAL
171 info.led = led_read(HZ/2); /* delay should match polling interval */ 177 info.led = led_read(HZ/2); /* delay should match polling interval */
172#endif 178#endif
179#ifdef HAVE_USB_POWER
180 info.usb_power = usb_powered();
181#endif
173 182
174 /* only redraw if forced to, or info has changed */ 183 /* only redraw if forced to, or info has changed */
175 if (force_redraw || 184 if (force_redraw ||
@@ -183,10 +192,10 @@ void status_draw(bool force_redraw)
183 /* players always "redraw" */ 192 /* players always "redraw" */
184 { 193 {
185#endif 194#endif
186 195
196#ifdef HAVE_CHARGING
187 if (info.inserted) { 197 if (info.inserted) {
188 battery_state = true; 198 battery_state = true;
189 plug_state = true;
190#if defined(HAVE_CHARGE_CTRL) || CONFIG_BATTERY == BATT_LIION2200 199#if defined(HAVE_CHARGE_CTRL) || CONFIG_BATTERY == BATT_LIION2200
191 /* zero battery run time if charging */ 200 /* zero battery run time if charging */
192 if (charge_state > 0) { 201 if (charge_state > 0) {
@@ -212,8 +221,9 @@ void status_draw(bool force_redraw)
212 } 221 }
213 } 222 }
214 } 223 }
215 else { 224 else
216 plug_state=false; 225#endif /* HAVE_CHARGING */
226 {
217 if (info.battery_safe) 227 if (info.battery_safe)
218 battery_state = true; 228 battery_state = true;
219 else { 229 else {
@@ -228,8 +238,18 @@ void status_draw(bool force_redraw)
228 238
229#ifdef HAVE_LCD_BITMAP 239#ifdef HAVE_LCD_BITMAP
230 if (battery_state) 240 if (battery_state)
231 statusbar_icon_battery(info.battlevel, plug_state); 241 statusbar_icon_battery(info.battlevel);
232 242
243 /* draw power plug if charging */
244 if (info.inserted)
245 lcd_bitmap(bitmap_icons_7x8[Icon_Plug], ICON_PLUG_X_POS,
246 STATUSBAR_Y_POS, ICON_PLUG_WIDTH, STATUSBAR_HEIGHT, false);
247#ifdef HAVE_USB_POWER
248 else if (info.usb_power)
249 lcd_bitmap(bitmap_icons_7x8[Icon_USBPlug], ICON_PLUG_X_POS,
250 STATUSBAR_Y_POS, ICON_PLUG_WIDTH, STATUSBAR_HEIGHT, false);
251#endif
252
233 info.redraw_volume = statusbar_icon_volume(info.volume); 253 info.redraw_volume = statusbar_icon_volume(info.volume);
234 statusbar_icon_play_state(current_playmode() + Icon_Play); 254 statusbar_icon_play_state(current_playmode() + Icon_Play);
235 switch (info.repeat) { 255 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
119Pedro Baltazar Vasconcelos 119Pedro Baltazar Vasconcelos
120Ray Lambert 120Ray Lambert
121Dave Wiard 121Dave Wiard
122Pieter 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 @@
76/* Define this for LCD backlight available */ 76/* Define this for LCD backlight available */
77#define CONFIG_BACKLIGHT BL_RTC /* on I2C controlled RTC port */ 77#define CONFIG_BACKLIGHT BL_RTC /* on I2C controlled RTC port */
78 78
79/* define this if the unit can be powered or charged via USB */
80#define HAVE_USB_POWER
81
79#define CONFIG_LCD LCD_SSD1815 82#define CONFIG_LCD LCD_SSD1815
80 83
81#define BOOTFILE_EXT ".ajz" 84#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 @@
90 90
91#define CONFIG_LCD LCD_SSD1815 91#define CONFIG_LCD LCD_SSD1815
92 92
93/* define this if the unit can be powered or charged via USB */
94#define HAVE_USB_POWER
95
93#define BOOTFILE_EXT ".ajz" 96#define BOOTFILE_EXT ".ajz"
94#define BOOTFILE "ajbrec" BOOTFILE_EXT 97#define BOOTFILE "ajbrec" BOOTFILE_EXT
95 98
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 @@
78 78
79#define CONFIG_LCD LCD_SSD1815 79#define CONFIG_LCD LCD_SSD1815
80 80
81/* define this if the unit can be powered or charged via USB */
82#define HAVE_USB_POWER
83
81#define BOOTFILE_EXT ".ajz" 84#define BOOTFILE_EXT ".ajz"
82#define BOOTFILE "ajbrec" BOOTFILE_EXT 85#define BOOTFILE "ajbrec" BOOTFILE_EXT
83 86
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 @@
76/* Define this for LCD backlight available */ 76/* Define this for LCD backlight available */
77#define CONFIG_BACKLIGHT BL_RTC /* on I2C controlled RTC port */ 77#define CONFIG_BACKLIGHT BL_RTC /* on I2C controlled RTC port */
78 78
79/* define this if the unit can be powered or charged via USB */
80#define HAVE_USB_POWER
81
79#define CONFIG_LCD LCD_SSD1815 82#define CONFIG_LCD LCD_SSD1815
80 83
81#define BOOTFILE_EXT ".ajz" 84#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);
28int usb_wait_for_disconnect_w_tmo(struct event_queue *q, int ticks); 28int usb_wait_for_disconnect_w_tmo(struct event_queue *q, int ticks);
29bool usb_inserted(void); /* return the official value, what's been reported to the threads */ 29bool usb_inserted(void); /* return the official value, what's been reported to the threads */
30bool usb_detect(void); /* return the raw hardware value */ 30bool usb_detect(void); /* return the raw hardware value */
31#ifdef HAVE_USB_POWER
32bool usb_powered(void);
33#endif
31 34
32#endif 35#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)
437 current = CURRENT_NORMAL; 437 current = CURRENT_NORMAL;
438#endif /* MEM == 8 */ 438#endif /* MEM == 8 */
439 439
440 if(usb_inserted()) { 440 if(usb_inserted()
441#ifdef HAVE_USB_POWER
442 || usb_powered()
443#endif
444 )
445 {
441 current = CURRENT_USB; 446 current = CURRENT_USB;
442 } 447 }
443 448
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 */
47 47
48#if !defined(SIMULATOR) && !defined(USB_NONE) 48#if !defined(SIMULATOR) && !defined(USB_NONE)
49 49
50/* Messages from usb_tick */ 50/* Messages from usb_tick and thread states */
51#define USB_INSERTED 1 51#define USB_INSERTED 1
52#define USB_EXTRACTED 2 52#define USB_EXTRACTED 2
53#ifdef HAVE_MMC 53#ifdef HAVE_MMC
54#define USB_REENABLE 3 54#define USB_REENABLE 3
55#endif 55#endif
56#ifdef HAVE_USB_POWER
57#define USB_POWERED 4
56 58
57/* Thread states */ 59#if CONFIG_KEYPAD == RECORDER_PAD
58#define EXTRACTING 1 60#define USBPOWER_BUTTON BUTTON_F1
59#define EXTRACTED 2 61#elif CONFIG_KEYPAD == ONDIO_PAD
60#define INSERTED 3 62#define USBPOWER_BUTTON BUTTON_MENU
61#define INSERTING 4 63#endif
64#endif /* HAVE_USB_POWER */
62 65
63/* The ADC tick reads one channel per tick, and we want to check 3 successive 66/* The ADC tick reads one channel per tick, and we want to check 3 successive
64 readings on the USB voltage channel. This doesn't apply to the Player, but 67 readings on the USB voltage channel. This doesn't apply to the Player, but
@@ -221,8 +224,15 @@ static void usb_thread(void)
221 screen_dump(); 224 screen_dump();
222 } 225 }
223 else 226 else
227#endif
228#ifdef HAVE_USB_POWER
229 if(button_status() == USBPOWER_BUTTON)
224 { 230 {
231 usb_state = USB_POWERED;
232 }
233 else
225#endif 234#endif
235 {
226 /* Tell all threads that they have to back off the ATA. 236 /* Tell all threads that they have to back off the ATA.
227 We subtract one for our own thread. */ 237 We subtract one for our own thread. */
228 num_acks_to_expect = 238 num_acks_to_expect =
@@ -230,11 +240,9 @@ static void usb_thread(void)
230 waiting_for_ack = true; 240 waiting_for_ack = true;
231 DEBUGF("USB inserted. Waiting for ack from %d threads...\n", 241 DEBUGF("USB inserted. Waiting for ack from %d threads...\n",
232 num_acks_to_expect); 242 num_acks_to_expect);
233#ifdef HAVE_LCD_BITMAP
234 } 243 }
235#endif
236 break; 244 break;
237 245
238 case SYS_USB_CONNECTED_ACK: 246 case SYS_USB_CONNECTED_ACK:
239 if(waiting_for_ack) 247 if(waiting_for_ack)
240 { 248 {
@@ -259,33 +267,37 @@ static void usb_thread(void)
259 267
260 case USB_EXTRACTED: 268 case USB_EXTRACTED:
261#ifdef HAVE_LCD_BITMAP 269#ifdef HAVE_LCD_BITMAP
262 if(!do_screendump_instead_of_usb) 270 if(do_screendump_instead_of_usb)
263 { 271 break;
264#endif 272#endif
265 if(usb_state == USB_INSERTED) 273#ifdef HAVE_USB_POWER
266 { 274 if(usb_state == USB_POWERED)
267 /* Only disable the USB mode if we really have enabled it 275 {
268 some threads might not have acknowledged the
269 insertion */
270 usb_slave_mode(false);
271 }
272
273 usb_state = USB_EXTRACTED; 276 usb_state = USB_EXTRACTED;
274 277 break;
275 /* Tell all threads that we are back in business */ 278 }
276 num_acks_to_expect =
277 queue_broadcast(SYS_USB_DISCONNECTED, NULL) - 1;
278 waiting_for_ack = true;
279 DEBUGF("USB extracted. Waiting for ack from %d threads...\n",
280 num_acks_to_expect);
281#ifdef HAVE_LCD_CHARCELLS
282 lcd_icon(ICON_USB, false);
283#endif 279#endif
284#ifdef HAVE_LCD_BITMAP 280 if(usb_state == USB_INSERTED)
281 {
282 /* Only disable the USB mode if we really have enabled it
283 some threads might not have acknowledged the
284 insertion */
285 usb_slave_mode(false);
285 } 286 }
287
288 usb_state = USB_EXTRACTED;
289
290 /* Tell all threads that we are back in business */
291 num_acks_to_expect =
292 queue_broadcast(SYS_USB_DISCONNECTED, NULL) - 1;
293 waiting_for_ack = true;
294 DEBUGF("USB extracted. Waiting for ack from %d threads...\n",
295 num_acks_to_expect);
296#ifdef HAVE_LCD_CHARCELLS
297 lcd_icon(ICON_USB, false);
286#endif 298#endif
287 break; 299 break;
288 300
289 case SYS_USB_DISCONNECTED_ACK: 301 case SYS_USB_DISCONNECTED_ACK:
290 if(waiting_for_ack) 302 if(waiting_for_ack)
291 { 303 {
@@ -475,6 +487,13 @@ bool usb_inserted(void)
475 return usb_state == USB_INSERTED; 487 return usb_state == USB_INSERTED;
476} 488}
477 489
490#ifdef HAVE_USB_POWER
491bool usb_powered(void)
492{
493 return usb_state == USB_POWERED;
494}
495#endif
496
478#else 497#else
479 498
480#ifdef USB_NONE 499#ifdef USB_NONE