From 1672350378c1eb218db319e35e7bf8fa457b1142 Mon Sep 17 00:00:00 2001 From: Dave Chapman Date: Tue, 4 Sep 2007 08:03:07 +0000 Subject: FS #7691 - improved USB detection on PP devices. This patch modifies the target-tree function usb_detect() on all targets from bool to int, returning USB_INSERTED or USB_EXTRACTED instead of true or false. This was done to enable the PP usb_detect() to check for USB_POWER (either a connection to a USB wall charger, or the user holding "charge mode" button) and return that as a third value. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14600 a1c6a512-1295-4272-9138-f99709370657 --- apps/main.c | 2 +- bootloader/gigabeat.c | 4 +- bootloader/iriver_h300.c | 11 +-- bootloader/main-pp.c | 2 +- bootloader/main.c | 10 +-- firmware/export/usb.h | 37 ++++++++- .../target/arm/pnx0101/iriver-ifp7xx/usb-ifp7xx.c | 4 +- .../target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c | 8 +- .../target/arm/s3c2440/gigabeat-fx/usb-target.h | 1 - firmware/target/arm/usb-fw-pp5002.c | 6 +- firmware/target/arm/usb-fw-pp502x.c | 88 ++++++++++++++++------ firmware/target/coldfire/iaudio/usb-iaudio.c | 5 +- firmware/target/coldfire/iriver/h100/usb-h100.c | 5 +- firmware/target/coldfire/iriver/h300/usb-h300.c | 5 +- firmware/target/sh/archos/fm_v2/usb-fm_v2.c | 5 +- firmware/target/sh/archos/ondio/usb-ondio.c | 5 +- firmware/target/sh/archos/player/usb-player.c | 5 +- firmware/target/sh/archos/recorder/usb-recorder.c | 5 +- firmware/usb.c | 51 +++---------- 19 files changed, 160 insertions(+), 99 deletions(-) diff --git a/apps/main.c b/apps/main.c index 3d419407f4..86f651f775 100644 --- a/apps/main.c +++ b/apps/main.c @@ -444,7 +444,7 @@ static void init(void) #endif usb_start_monitoring(); - while (usb_detect()) + while (usb_detect() == USB_INSERTED) { #ifdef HAVE_EEPROM_SETTINGS firmware_settings.disk_clean = false; diff --git a/bootloader/gigabeat.c b/bootloader/gigabeat.c index e482c70d16..704548b65a 100644 --- a/bootloader/gigabeat.c +++ b/bootloader/gigabeat.c @@ -66,7 +66,7 @@ void main(void) usb_init(); /* Enter USB mode without USB thread */ - if(usb_detect()) + if(usb_detect() == USB_INSERTED) { const char msg[] = "Bootloader USB mode"; reset_screen(); @@ -78,7 +78,7 @@ void main(void) sleep(HZ/20); usb_enable(true); - while (usb_detect()) + while (usb_detect() == USB_INSERTED) sleep(HZ); usb_enable(false); diff --git a/bootloader/iriver_h300.c b/bootloader/iriver_h300.c index dce178fcec..a3a15bd4b5 100644 --- a/bootloader/iriver_h300.c +++ b/bootloader/iriver_h300.c @@ -169,7 +169,7 @@ void main(void) /* Turn off if we believe the start was accidental */ if(!(rtc_alarm || on_button || rc_on_button || - usb_detect() || charger_inserted())) { + (usb_detect() == USB_INSERTED) || charger_inserted())) { __reset_cookie(); power_off(); } @@ -222,7 +222,8 @@ void main(void) { hold_status = true; } - if (hold_status && !rtc_alarm && !usb_detect() && !charger_inserted()) + if (hold_status && !rtc_alarm && (usb_detect() != USB_INSERTED) && + !charger_inserted()) { if (detect_original_firmware()) { @@ -282,7 +283,7 @@ void main(void) break; } - if(usb_detect()) + if(usb_detect() == USB_INSERTED) request_start = true; } if(!request_start) @@ -297,7 +298,7 @@ void main(void) usb_init(); /* A hack to enter USB mode without using the USB thread */ - if(usb_detect()) + if(usb_detect() == USB_INSERTED) { const char msg[] = "Bootloader USB mode"; int w, h; @@ -314,7 +315,7 @@ void main(void) sleep(HZ/20); usb_enable(true); cpu_idle_mode(true); - while (usb_detect()) + while (usb_detect() == USB_INSERTED) { /* Print the battery status. */ line = 0; diff --git a/bootloader/main-pp.c b/bootloader/main-pp.c index 0d377fd798..8b851394ac 100644 --- a/bootloader/main-pp.c +++ b/bootloader/main-pp.c @@ -464,7 +464,7 @@ void* main(void) { usb_retry++; sleep(HZ/4); - usb = usb_detect(); + usb = (usb_detect() == USB_INSERTED); } if (usb) btn |= BOOTLOADER_BOOT_OF; diff --git a/bootloader/main.c b/bootloader/main.c index 0306eea5dc..e60799fa65 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -388,7 +388,7 @@ void main(void) power_init(); /* Turn off if neither ON button is pressed */ - if(!(on_button || rc_on_button || usb_detect())) + if(!(on_button || rc_on_button || (usb_detect() == USB_INSERTED))) { __reset_cookie(); power_off(); @@ -439,7 +439,7 @@ void main(void) } # ifdef EEPROM_SETTINGS - if (!hold_status && !usb_detect() && !recovery_mode) + if (!hold_status && (usb_detect() != USB_INSERTED) && !recovery_mode) try_flashboot(); # endif @@ -467,7 +467,7 @@ void main(void) /* Don't start if the Hold button is active on the device you are starting with */ - if (!usb_detect() && (hold_status + if ((usb_detect() != USB_INSERTED) && (hold_status #ifdef HAVE_EEPROM_SETTINGS || recovery_mode #endif @@ -494,7 +494,7 @@ void main(void) usb_init(); /* A hack to enter USB mode without using the USB thread */ - if(usb_detect()) + if(usb_detect() == USB_INSERTED) { const char msg[] = "Bootloader USB mode"; int w, h; @@ -520,7 +520,7 @@ void main(void) sleep(HZ/20); usb_enable(true); cpu_idle_mode(true); - while (usb_detect()) + while (usb_detect() == USB_INSERTED) { /* Print the battery status. */ line = 0; diff --git a/firmware/export/usb.h b/firmware/export/usb.h index 622db35543..82b9d36d4a 100644 --- a/firmware/export/usb.h +++ b/firmware/export/usb.h @@ -20,6 +20,41 @@ #define _USB_H_ #include "kernel.h" +#include "button.h" + +/* 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 + +#if CONFIG_KEYPAD == RECORDER_PAD +#define USBPOWER_BUTTON BUTTON_F1 +#define USBPOWER_BTN_IGNORE BUTTON_ON +#elif CONFIG_KEYPAD == ONDIO_PAD +#define USBPOWER_BUTTON BUTTON_MENU +#define USBPOWER_BTN_IGNORE BUTTON_OFF +#elif (CONFIG_KEYPAD == IPOD_4G_PAD) +#define USBPOWER_BUTTON BUTTON_MENU +#define USBPOWER_BTN_IGNORE BUTTON_PLAY +#elif CONFIG_KEYPAD == IRIVER_H300_PAD +#define USBPOWER_BUTTON BUTTON_REC +#define USBPOWER_BTN_IGNORE BUTTON_ON +#elif CONFIG_KEYPAD == GIGABEAT_PAD +#define USBPOWER_BUTTON BUTTON_MENU +#define USBPOWER_BTN_IGNORE BUTTON_POWER +#elif CONFIG_KEYPAD == IRIVER_H10_PAD +#define USBPOWER_BUTTON BUTTON_NONE +#define USBPOWER_BTN_IGNORE BUTTON_POWER +#elif CONFIG_KEYPAD == SANSA_E200_PAD +#define USBPOWER_BUTTON BUTTON_SELECT +#define USBPOWER_BTN_IGNORE BUTTON_POWER +#endif +#endif /* HAVE_USB_POWER */ void usb_init(void); void usb_enable(bool on); @@ -28,7 +63,7 @@ void usb_acknowledge(long id); 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 */ +int usb_detect(void); /* return the raw hardware value - nothing/pc/charger */ #ifdef HAVE_USB_POWER bool usb_powered(void); #ifdef CONFIG_CHARGING diff --git a/firmware/target/arm/pnx0101/iriver-ifp7xx/usb-ifp7xx.c b/firmware/target/arm/pnx0101/iriver-ifp7xx/usb-ifp7xx.c index a22a227b15..3761c84a50 100644 --- a/firmware/target/arm/pnx0101/iriver-ifp7xx/usb-ifp7xx.c +++ b/firmware/target/arm/pnx0101/iriver-ifp7xx/usb-ifp7xx.c @@ -37,10 +37,10 @@ void usb_init_device(void) { } -bool usb_detect(void) +int usb_detect(void) { /* TODO: Implement USB_ISP1582 */ - return false; + return USB_EXTRACTED; } void usb_enable(bool on) diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c index 566d25eecb..217a7d3cef 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c @@ -21,6 +21,7 @@ #include "system.h" #include "kernel.h" #include "ata.h" +#include "usb.h" #define USB_RST_ASSERT GPBDAT &= ~(1 << 4) #define USB_RST_DEASSERT GPBDAT |= (1 << 4) @@ -35,9 +36,12 @@ #define USB_CRADLE_BUS_DISABLE GPHDAT &= ~(1 << 8) /* The usb detect is one pin to the cpu active low */ -inline bool usb_detect(void) +int usb_detect(void) { - return USB_UNIT_IS_PRESENT | USB_CRADLE_IS_PRESENT; + if (USB_UNIT_IS_PRESENT | USB_CRADLE_IS_PRESENT) + return USB_INSERTED; + else + return USB_EXTRACTED; } void usb_init_device(void) diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/usb-target.h b/firmware/target/arm/s3c2440/gigabeat-fx/usb-target.h index baeb539b38..65690dc86b 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/usb-target.h +++ b/firmware/target/arm/s3c2440/gigabeat-fx/usb-target.h @@ -20,7 +20,6 @@ #define USB_TARGET_H bool usb_init_device(void); -bool usb_detect(void); void usb_enable(bool on); #endif diff --git a/firmware/target/arm/usb-fw-pp5002.c b/firmware/target/arm/usb-fw-pp5002.c index e64d4f8f81..2a216c4d9b 100644 --- a/firmware/target/arm/usb-fw-pp5002.c +++ b/firmware/target/arm/usb-fw-pp5002.c @@ -56,15 +56,15 @@ void usb_enable(bool on) } } -bool usb_detect(void) +int usb_detect(void) { #if defined(IPOD_1G2G) || defined(IPOD_3G) /* GPIO C bit 7 is firewire detect */ if (!(GPIOC_INPUT_VAL & 0x80)) - return true; + return USB_INSERTED; #endif /* TODO: add USB detection for iPod 3rd gen */ - return false; + return USB_EXTRACTED; } diff --git a/firmware/target/arm/usb-fw-pp502x.c b/firmware/target/arm/usb-fw-pp502x.c index 76bd7281f5..ad2a10599f 100644 --- a/firmware/target/arm/usb-fw-pp502x.c +++ b/firmware/target/arm/usb-fw-pp502x.c @@ -92,7 +92,7 @@ void usb_init_device(void) void usb_enable(bool on) { #ifdef HAVE_USBSTACK - (void)on; + (void)on; #else /* This device specific code will eventually give way to proper USB handling, which should be the same for all PP502x targets. */ @@ -124,18 +124,42 @@ void usb_enable(bool on) #endif /* !HAVE_USBSTACK */ } -bool usb_detect(void) +int usb_detect(void) { + static int countdown = 0; + static int status = USB_EXTRACTED; static bool prev_usbstatus1 = false; - bool usbstatus1,usbstatus2; + bool usbstatus1, usbstatus2; #if defined(IPOD_COLOR) || defined(IPOD_4G) \ || defined(IPOD_MINI) || defined(IPOD_MINI2G) /* GPIO C bit 1 is firewire detect */ if (!(GPIOC_INPUT_VAL & 0x02)) - return true; + return USB_INSERTED; #endif + if (countdown > 0) + { + countdown--; + + usbstatus2 = (UDC_PORTSC1 & PORTSCX_CURRENT_CONNECT_STATUS) ? true : false; + if ((countdown == 0) || usbstatus2) + { + countdown = 0; + status = usbstatus2 ? USB_INSERTED : USB_POWERED; + dr_controller_stop(); + +#ifdef HAVE_USBSTACK + /* TODO: Move this call - it shouldn't be done in this function */ + if (status == USB_INSERTED) + { + usb_stack_start(); + } +#endif + } + return status; + } + /* UDC_ID should have the bit format: [31:24] = 0x0 [23:16] = 0x22 (Revision number) @@ -144,29 +168,51 @@ bool usb_detect(void) [7:6] = 0x0 (Reserved) [5:0] = 0x05 (ID) */ if (UDC_ID != 0x22FA05) { - return false; + /* This should never occur - do we even need to test? */ + return USB_EXTRACTED; } usbstatus1 = (UDC_OTGSC & 0x800) ? true : false; + + if (usbstatus1 == prev_usbstatus1) + { + /* Nothing has changed, so just return previous status */ + return status; + } + prev_usbstatus1 = usbstatus1; + + if (!usbstatus1) + { /* We have just been disconnected */ + status = USB_EXTRACTED; #ifdef HAVE_USBSTACK - if ((usbstatus1 == true) && (prev_usbstatus1 == false)) { - usb_stack_start(); - } else if ((usbstatus1 == false) && (prev_usbstatus1 == true)) { + /* TODO: Move this call - it shouldn't be done in this function */ usb_stack_stop(); - } -#else - if ((usbstatus1 == true) && (prev_usbstatus1 == false)) { - dr_controller_run(); - } else if ((usbstatus1 == false) && (prev_usbstatus1 == true)) { - dr_controller_stop(); - } #endif - prev_usbstatus1 = usbstatus1; - usbstatus2 = (UDC_PORTSC1 & PORTSCX_CURRENT_CONNECT_STATUS) ? true : false; + return status; + } + + /* We now know that we have just been connected to either a charger + or a computer */ - if (usbstatus1 && usbstatus2) { - return true; - } else { - return false; + if((button_status() & ~USBPOWER_BTN_IGNORE) == USBPOWER_BUTTON) + { + /* The user wants to charge, so it doesn't matter what we are + connected to. */ + + status = USB_POWERED; + return status; } + + /* Run the USB controller for long enough to detect if we're connected + to a computer, then stop it again. */ + + dr_controller_run(); + + /* Wait for 50 ticks (500ms) before deciding there is no computer + attached. The required value varied a lot between different users + when this feature was being tested. */ + + countdown = 50; + + return status; } diff --git a/firmware/target/coldfire/iaudio/usb-iaudio.c b/firmware/target/coldfire/iaudio/usb-iaudio.c index 3bd1a7a458..21d69611b7 100644 --- a/firmware/target/coldfire/iaudio/usb-iaudio.c +++ b/firmware/target/coldfire/iaudio/usb-iaudio.c @@ -20,6 +20,7 @@ #include #include "cpu.h" #include "system.h" +#include "usb.h" void usb_init_device(void) { @@ -30,9 +31,9 @@ void usb_init_device(void) or_l(0x00800000, &GPIO1_FUNCTION); /* USB detect */ } -bool usb_detect(void) +int usb_detect(void) { - return (GPIO1_READ & 0x00800000)?true:false; + return (GPIO1_READ & 0x00800000) ? USB_INSERTED : USB_EXTRACTED; } void usb_enable(bool on) diff --git a/firmware/target/coldfire/iriver/h100/usb-h100.c b/firmware/target/coldfire/iriver/h100/usb-h100.c index 3b00e967da..5a2f7f500b 100644 --- a/firmware/target/coldfire/iriver/h100/usb-h100.c +++ b/firmware/target/coldfire/iriver/h100/usb-h100.c @@ -21,6 +21,7 @@ #include "cpu.h" #include "system.h" #include "kernel.h" +#include "usb.h" void usb_init_device(void) { @@ -30,9 +31,9 @@ void usb_init_device(void) or_l(0x01000040, &GPIO_FUNCTION); } -bool usb_detect(void) +int usb_detect(void) { - return (GPIO1_READ & 0x80)?true:false; + return (GPIO1_READ & 0x80) ? USB_INSERTED : USB_EXTRACTED; } void usb_enable(bool on) diff --git a/firmware/target/coldfire/iriver/h300/usb-h300.c b/firmware/target/coldfire/iriver/h300/usb-h300.c index d08cc24dba..d50b7bc808 100644 --- a/firmware/target/coldfire/iriver/h300/usb-h300.c +++ b/firmware/target/coldfire/iriver/h300/usb-h300.c @@ -21,6 +21,7 @@ #include "cpu.h" #include "system.h" #include "kernel.h" +#include "usb.h" void usb_init_device(void) { @@ -35,9 +36,9 @@ void usb_init_device(void) or_l(0x03000000, &GPIO_FUNCTION); } -bool usb_detect(void) +int usb_detect(void) { - return (GPIO1_READ & 0x80)?true:false; + return (GPIO1_READ & 0x80) ? USB_INSERTED : USB_EXTRACTED; } void usb_enable(bool on) diff --git a/firmware/target/sh/archos/fm_v2/usb-fm_v2.c b/firmware/target/sh/archos/fm_v2/usb-fm_v2.c index 3dcc3559a3..9c641b925a 100644 --- a/firmware/target/sh/archos/fm_v2/usb-fm_v2.c +++ b/firmware/target/sh/archos/fm_v2/usb-fm_v2.c @@ -22,10 +22,11 @@ #include "cpu.h" #include "hwcompat.h" #include "system.h" +#include "usb.h" -bool usb_detect(void) +int usb_detect(void) { - return (adc_read(ADC_USB_POWER) <= 512) ? true : false; + return (adc_read(ADC_USB_POWER) <= 512) ? USB_INSERTED : USB_EXTRACTED; } void usb_enable(bool on) diff --git a/firmware/target/sh/archos/ondio/usb-ondio.c b/firmware/target/sh/archos/ondio/usb-ondio.c index c856f3ae2c..b370fec3d9 100644 --- a/firmware/target/sh/archos/ondio/usb-ondio.c +++ b/firmware/target/sh/archos/ondio/usb-ondio.c @@ -23,10 +23,11 @@ #include "cpu.h" #include "hwcompat.h" #include "system.h" +#include "usb.h" -bool usb_detect(void) +int usb_detect(void) { - return (adc_read(ADC_USB_POWER) <= 512) ? true : false; + return (adc_read(ADC_USB_POWER) <= 512) ? USB_INSERTED : USB_EXTRACTED; } void usb_enable(bool on) diff --git a/firmware/target/sh/archos/player/usb-player.c b/firmware/target/sh/archos/player/usb-player.c index c10e222f0a..e86003f2c2 100644 --- a/firmware/target/sh/archos/player/usb-player.c +++ b/firmware/target/sh/archos/player/usb-player.c @@ -20,10 +20,11 @@ #include #include "cpu.h" #include "system.h" +#include "usb.h" -bool usb_detect(void) +int usb_detect(void) { - return (PADR & 0x8000) ? false : true; + return (PADR & 0x8000) ? USB_INSERTED : USB_EXTRACTED; } void usb_enable(bool on) diff --git a/firmware/target/sh/archos/recorder/usb-recorder.c b/firmware/target/sh/archos/recorder/usb-recorder.c index 7ed237068e..dfa8462203 100644 --- a/firmware/target/sh/archos/recorder/usb-recorder.c +++ b/firmware/target/sh/archos/recorder/usb-recorder.c @@ -22,10 +22,11 @@ #include "cpu.h" #include "hwcompat.h" #include "system.h" +#include "usb.h" -bool usb_detect(void) +int usb_detect(void) { - return (adc_read(ADC_USB_POWER) > 500) ? true : false; + return (adc_read(ADC_USB_POWER) > 500) ? USB_INSERTED : USB_EXTRACTED; } void usb_enable(bool on) diff --git a/firmware/usb.c b/firmware/usb.c index 9e9cb77919..876a5e4ec2 100644 --- a/firmware/usb.c +++ b/firmware/usb.c @@ -51,39 +51,6 @@ void screen_dump(void); /* Nasty again. Defined in apps/ too */ #if !defined(SIMULATOR) && !defined(USB_NONE) -/* 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 - -#if CONFIG_KEYPAD == RECORDER_PAD -#define USBPOWER_BUTTON BUTTON_F1 -#define USBPOWER_BTN_IGNORE BUTTON_ON -#elif CONFIG_KEYPAD == ONDIO_PAD -#define USBPOWER_BUTTON BUTTON_MENU -#define USBPOWER_BTN_IGNORE BUTTON_OFF -#elif (CONFIG_KEYPAD == IPOD_4G_PAD) -#define USBPOWER_BUTTON BUTTON_MENU -#define USBPOWER_BTN_IGNORE BUTTON_PLAY -#elif CONFIG_KEYPAD == IRIVER_H300_PAD -#define USBPOWER_BUTTON BUTTON_REC -#define USBPOWER_BTN_IGNORE BUTTON_ON -#elif CONFIG_KEYPAD == GIGABEAT_PAD -#define USBPOWER_BUTTON BUTTON_MENU -#define USBPOWER_BTN_IGNORE BUTTON_POWER -#elif CONFIG_KEYPAD == IRIVER_H10_PAD -#define USBPOWER_BUTTON BUTTON_NONE -#define USBPOWER_BTN_IGNORE BUTTON_POWER -#elif CONFIG_KEYPAD == SANSA_E200_PAD -#define USBPOWER_BUTTON BUTTON_SELECT -#define USBPOWER_BTN_IGNORE BUTTON_POWER -#endif -#endif /* HAVE_USB_POWER */ - #define NUM_POLL_READINGS (HZ/5) static int countdown; @@ -100,7 +67,7 @@ static long usb_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)]; static const char usb_thread_name[] = "usb"; #endif static struct event_queue usb_queue; -static bool last_usb_status; +static int last_usb_status; static bool usb_monitor_enabled; @@ -161,6 +128,11 @@ static void usb_thread(void) queue_wait(&usb_queue, &ev); switch(ev.id) { +#ifdef HAVE_USB_POWER + case USB_POWERED: + usb_state = USB_POWERED; + break; +#endif case USB_INSERTED: #ifdef HAVE_LCD_BITMAP if(do_screendump_instead_of_usb) @@ -278,7 +250,7 @@ static void usb_thread(void) #ifndef BOOTLOADER static void usb_tick(void) { - bool current_status; + int current_status; if(usb_monitor_enabled) { @@ -300,10 +272,7 @@ static void usb_tick(void) readings in a row */ if(countdown == 0) { - if(current_status) - queue_post(&usb_queue, USB_INSERTED, 0); - else - queue_post(&usb_queue, USB_EXTRACTED, 0); + queue_post(&usb_queue, current_status, 0); } } } @@ -463,9 +432,9 @@ void usb_start_monitoring(void) { } -bool usb_detect(void) +int usb_detect(void) { - return false; + return USB_EXTRACTED; } void usb_wait_for_disconnect(struct event_queue *q) -- cgit v1.2.3