My solution?
The realization that the external pin ALONE does not produce enough current to drive the USB D+ pin high. So my work around was to take a 3 position jumper and tie all three leads together - and plug it into J6 effectively driving D+ to vcc by DEFAULT.
Then connect one of the jumper positions to pin PA0. Now when the software loads it calls stm32_usb_disconnect_pullup() which sets PA0 as an output and pulls it down to ground (0). then later when the user presses "c" on the terminal I call stm32_usb_connect_pullup() which sets PA0 as in input and floating - which drives D+ back up to VCC. This results seen on my Total Phase USB Sniffer is as I expected!!!
Clever?
Yeah ... thats me
/*
**********************************************************************
*description: setup particular portA pin to an input, so its no
* longer driving the pin
*input: unsigned int wdPin = PAx pin number to use. it must be
* portA block pins ONLY
*note: this should be called inside the usb isr on RESET flag
*implemented: using three position jumper pin with all three wire
* wrapped linked - and a jumper from PAx to one of the
* positions
**********************************************************************
*/
void stm32_usb_connect_pullup(unsigned int wdPin)
{
volatile unsigned int wdTemp, wdMask;
wdTemp = (*PTR_STM32_GPIO_A_CRL);
wdTemp &= ~(0x0f << (wdPin << 2));
wdMask = ((STM32_GPIO_CNF_IN_FLOATING << 2) | \
STM32_GPIO_MODE_INPUT_MODE) << (wdPin << 2);
(*PTR_STM32_GPIO_A_CRL) = (wdMask | wdTemp);
}
/*
**********************************************************************
*description: I am using PAX (external wire to Dplus pin on J6 facing
* the USB connector) to pull up the line to trigger the
* USB HOST enumeration.
* setup PAX to generic output. pull it high
*input: unsigned int wdPin = PAx pin number to use. it must be
* portA block pins ONLY
**********************************************************************
*/
void stm32_usb_disconnect_pullup(unsigned int wdPin)
{
volatile unsigned int wdTemp, wdMask;
(*PTR_STM32_GPIO_A_BSRR) = ((1 << wdPin) << 16);
wdTemp = (*PTR_STM32_GPIO_A_CRL);
wdTemp &= ~(0x0f << (wdPin << 2));
wdMask = ((STM32_GPIO_CNF_OUT_GEN_PUSH_PULL << 2) | \
STM32_GPIO_MODE_OUTPUT_2MHZ) << (wdPin << 2);
(*PTR_STM32_GPIO_A_CRL) = (wdMask | wdTemp);
}

No comments:
Post a Comment