From b508a3673b902369150535d7715139a5055e23b6 Mon Sep 17 00:00:00 2001 From: Chris Reed Date: Sat, 14 Oct 2017 14:53:43 -0500 Subject: [PATCH] K20 HIC waits until USB is configured to enable target power. - Interface main function calls gpio_set_board_power() when USB is connected (really configured) and disconnected. - The main task will wait ~2 seconds for USB to be configured. If this does not happen, it enables board power anyway. This is to support USB wall warts or similar power sources. - Added gpio_set_board_power() to gpio.h. - The K20 HIC implements this function to enable the target power switch only after high power has been negotiated with the USB host. - gpio_set_board_power() is stubbed out for all other HICs. --- source/daplink/interface/main.c | 25 +++++++++++++++++++--- source/hic_hal/atmel/sam3u2c/gpio.c | 8 +++++-- source/hic_hal/freescale/k20dx/gpio.c | 30 +++++++++++++++++---------- source/hic_hal/freescale/kl26z/gpio.c | 8 +++++-- source/hic_hal/gpio.h | 3 ++- source/hic_hal/nxp/lpc11u35/gpio.c | 6 +++++- source/hic_hal/nxp/lpc4322/gpio.c | 4 ++++ 7 files changed, 64 insertions(+), 20 deletions(-) diff --git a/source/daplink/interface/main.c b/source/daplink/interface/main.c index a03a7dfabc..508c6eb546 100644 --- a/source/daplink/interface/main.c +++ b/source/daplink/interface/main.c @@ -57,13 +57,17 @@ #define FLAGS_MAIN_CDC_EVENT (1 << 11) // Used by msd when flashing a new binary #define FLAGS_LED_BLINK_30MS (1 << 6) + // Timing constants (in 90mS ticks) -// USB busy time +// USB busy time (~3 sec) #define USB_BUSY_TIME (33) -// Delay before a USB device connect may occur +// Delay before a USB device connect may occur (~1 sec) #define USB_CONNECT_DELAY (11) +// Timeout for USB being configured (~2 sec) +#define USB_CONFIGURE_TIMEOUT (22) // Delay before target may be taken out of reset or reprogrammed after startup #define STARTUP_DELAY (1) + // Decrement to zero #define DECZERO(x) (x ? --x : 0) @@ -209,6 +213,7 @@ __task void main_task(void) gpio_led_state_t msc_led_value = GPIO_LED_OFF; // USB uint32_t usb_state_count = USB_BUSY_TIME; + uint32_t usb_no_config_count = USB_CONFIGURE_TIMEOUT; // thread running after usb connected started uint8_t thread_started = 0; // button state @@ -270,6 +275,8 @@ __task void main_task(void) if (flags & FLAGS_MAIN_POWERDOWN) { // Disable debug target_set_state(NO_DEBUG); + // Disable board power before USB is disconnected. + gpio_set_board_power(false); // Disconnect USB usbd_connect(0); // Turn off LED @@ -302,15 +309,18 @@ __task void main_task(void) switch (usb_state) { case USB_DISCONNECTING: usb_state = USB_DISCONNECTED; + // Disable board power before USB is disconnected. + gpio_set_board_power(false); usbd_connect(0); break; case USB_CONNECTING: - // Wait before connecting if (DECZERO(usb_state_count) == 0) { usbd_connect(1); usb_state = USB_CHECK_CONNECTED; + // Reset connect timeout + usb_no_config_count = USB_CONFIGURE_TIMEOUT; } break; @@ -322,8 +332,17 @@ __task void main_task(void) thread_started = 1; } + // Let the HIC enable power to the target now that high power has been negotiated. + gpio_set_board_power(true); + usb_state = USB_CONNECTED; } + else if (DECZERO(usb_no_config_count) == 0) { + // USB configuration timed out, which most likely indicates that the HIC is + // powered by a USB wall wart or similar power source. Go ahead and enable + // board power. + gpio_set_board_power(true); + } break; diff --git a/source/hic_hal/atmel/sam3u2c/gpio.c b/source/hic_hal/atmel/sam3u2c/gpio.c index 5ce9a4f08a..618a8ffacb 100644 --- a/source/hic_hal/atmel/sam3u2c/gpio.c +++ b/source/hic_hal/atmel/sam3u2c/gpio.c @@ -1,6 +1,6 @@ /** * @file gpio.c - * @brief + * @brief * * DAPLink Interface Firmware * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved @@ -36,7 +36,7 @@ void gpio_init(void) // Initially enable clock for GPIO and initialize LED ports as output with LED == off // PMC->PMC_PCER0 = (1 << 10) | (1 << 11) | (1 << 12); // Enable clock for all PIOs - + // DAP LED PIN_DAP_LED_PORT->PIO_PER = PIN_DAP_LED; PIN_DAP_LED_PORT->PIO_SODR = PIN_DAP_LED; @@ -106,3 +106,7 @@ uint8_t gpio_get_sw_reset() { return (PIN_RESET_IN_FWRD_PORT->PIO_PDSR & PIN_RESET_IN_FWRD) != 0; } + +void gpio_set_board_power(bool powerEnabled) +{ +} diff --git a/source/hic_hal/freescale/k20dx/gpio.c b/source/hic_hal/freescale/k20dx/gpio.c index c39da1f719..120f742aee 100644 --- a/source/hic_hal/freescale/k20dx/gpio.c +++ b/source/hic_hal/freescale/k20dx/gpio.c @@ -1,6 +1,6 @@ /** * @file gpio.c - * @brief + * @brief * * DAPLink Interface Firmware * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved @@ -57,16 +57,12 @@ void gpio_init(void) PIN_nRESET_GPIO->PDDR &= ~PIN_nRESET; PIN_nRESET_PORT->PCR[PIN_nRESET_BIT] = PORT_PCR_MUX(1); - // Keep powered off in bootloader mode - // to prevent the target from effecting the state - // of the reset line / reset button - if (!daplink_is_bootloader()) { - // configure pin as GPIO - PIN_POWER_EN_PORT->PCR[PIN_POWER_EN_BIT] = PORT_PCR_MUX(1); - // force always on logic 1 - PIN_POWER_EN_GPIO->PDOR |= 1UL << PIN_POWER_EN_BIT; - PIN_POWER_EN_GPIO->PDDR |= 1UL << PIN_POWER_EN_BIT; - } + // configure pin as GPIO + PIN_POWER_EN_PORT->PCR[PIN_POWER_EN_BIT] = PORT_PCR_MUX(1); + // set output to 0 + PIN_POWER_EN_GPIO->PCOR = PIN_POWER_EN; + // switch gpio to output + PIN_POWER_EN_GPIO->PDDR |= PIN_POWER_EN; // Let the voltage rails stabilize. This is especailly important // during software resets, since the target's 3.3v rail can take @@ -77,6 +73,18 @@ void gpio_init(void) busy_wait(1000000); } +void gpio_set_board_power(bool powerEnabled) +{ + if (powerEnabled) { + // enable power switch + PIN_POWER_EN_GPIO->PSOR = PIN_POWER_EN; + } + else { + // disable power switch + PIN_POWER_EN_GPIO->PCOR = PIN_POWER_EN; + } +} + void gpio_set_hid_led(gpio_led_state_t state) { if (state) { diff --git a/source/hic_hal/freescale/kl26z/gpio.c b/source/hic_hal/freescale/kl26z/gpio.c index e5067ede1b..4da4534593 100644 --- a/source/hic_hal/freescale/kl26z/gpio.c +++ b/source/hic_hal/freescale/kl26z/gpio.c @@ -1,6 +1,6 @@ /** * @file gpio.c - * @brief + * @brief * * DAPLink Interface Firmware * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved @@ -53,7 +53,7 @@ void gpio_init(void) PIN_POWER_EN_GPIO->PDDR |= PIN_POWER_EN; // set as input PIN_SW_RESET_GPIO->PDDR &= ~PIN_SW_RESET; - + // Let the voltage rails stabilize. This is especailly important // during software resets, since the target's 3.3v rail can take // 20-50ms to drain. During this time the target could be driving @@ -82,3 +82,7 @@ uint8_t gpio_get_sw_reset(void) { return (PIN_SW_RESET_GPIO->PDIR & PIN_SW_RESET) ? 1 : 0; } + +void gpio_set_board_power(bool powerEnabled) +{ +} diff --git a/source/hic_hal/gpio.h b/source/hic_hal/gpio.h index 9fd9001d4f..25a6cb76f3 100644 --- a/source/hic_hal/gpio.h +++ b/source/hic_hal/gpio.h @@ -1,6 +1,6 @@ /** * @file gpio.h - * @brief + * @brief * * DAPLink Interface Firmware * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved @@ -35,6 +35,7 @@ typedef enum led_state { } gpio_led_state_t; void gpio_init(void); +void gpio_set_board_power(bool powerEnabled); void gpio_set_hid_led(gpio_led_state_t state); void gpio_set_cdc_led(gpio_led_state_t state); void gpio_set_msc_led(gpio_led_state_t state); diff --git a/source/hic_hal/nxp/lpc11u35/gpio.c b/source/hic_hal/nxp/lpc11u35/gpio.c index e80d2a2832..ebb0028479 100644 --- a/source/hic_hal/nxp/lpc11u35/gpio.c +++ b/source/hic_hal/nxp/lpc11u35/gpio.c @@ -1,6 +1,6 @@ /** * @file gpio.c - * @brief + * @brief * * DAPLink Interface Firmware * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved @@ -171,3 +171,7 @@ void target_forward_reset(bool assert_reset) { // Do nothing - reset is forwarded in gpio_get_sw_reset } + +void gpio_set_board_power(bool powerEnabled) +{ +} diff --git a/source/hic_hal/nxp/lpc4322/gpio.c b/source/hic_hal/nxp/lpc4322/gpio.c index e368f2fb80..0643d60447 100644 --- a/source/hic_hal/nxp/lpc4322/gpio.c +++ b/source/hic_hal/nxp/lpc4322/gpio.c @@ -123,3 +123,7 @@ void target_forward_reset(bool assert_reset) { // Do nothing - reset is forwarded in gpio_get_sw_reset } + +void gpio_set_board_power(bool powerEnabled) +{ +}