cancel
Showing results for 
Search instead for 
Did you mean: 

stdio via USB virtual COM port

lanchon
Associate III
Posted on April 04, 2009 at 17:08

stdio via USB virtual COM port

48 REPLIES 48
niksa
Associate II
Posted on May 17, 2011 at 12:28

Thanks mvi for your quick reply.

I was wondering, is there a way to emulate pullup behavior in software? I tried manually setting pin PA12 as output and setting it to high using the following code:

GPIO_WriteBit(GPIOA, GPIO_Pin_12, SET);

USB_SetClock();

USB_SetPullUp();

USB_SetInterrupt();

USB_Init();

but nothing is changed. However, if I replace that code with

GPIO_WriteBit(GPIOA, GPIO_Pin_12, SET);

while(1);

then the host device (my PC) will notify me that an unknown USB device was plugged in.

So maybe this is the way to go?

The PA12 was initialized as:

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOA, &GPIO_InitStructure);

Regards,

Niksa

lanchon
Associate III
Posted on May 17, 2011 at 12:28

hi Niksa,

these are suppositions, I don't really know about USB.

two issues:

1)

> On the custom design we don't have a USB pullup pin

you're not being clear enough, your text only says that you're not using a gated pullup. the USB pullup can either be software controlled or active all the time, but you *must* have a pullup.

if you haven't got a of pullup, don't try strange hacks, they won't work and might kill your STM32. you need to add an appropriate pullup, read USB specs or copy from other people's designs.

2) however, if you implement a non-gated pullup, the code I posted might not work: there could be bugs in the USB library (and in the VCOM sample) that might prevent proper enumeration and startup. (or it could work just fine.)

if you reach this stage, I could give you some pointers to help you start debugging the issue.

mvi
Associate II
Posted on May 17, 2011 at 12:28

Also the USB spec is specific about a 1.5k pullup. The STM32 has ''weak'' pullups so you might need to double check this.

The pullup needs to be connected to the D+ line.

http://www.beyondlogic.org/usbnutshell/usb2.htm

niksa
Associate II
Posted on May 17, 2011 at 12:28

lanchon, mvi,

thanks for your replies - they were very helpful. It seems that USB controllers that we worked with in the past had pullup resistor and logic integrated and there was no need for external pullup control.

Thanks,

Niksa

trevor1
Associate II
Posted on May 17, 2011 at 12:28

Firstly, thanks to Lanchon for making the code available.

I can't get it to work so I hope someone can help.

Setup

ST dev board (STM32F10x-EVAL)

Rowley CrossWorks for ARM compiler (GCC based)

Windows XP

Changes To Original VCOM code (V0.9.1):

Changed USB pull up control to use PD9

Changed the following code in Set_USBInterrupt (main.c)

--------------

extern void (* const __cs3_interrupt_vector[])(void);

SCB->VTOR = (u32) __cs3_interrupt_vector;

--------------

To be this (I don't have a __cs3_interrupt_vector defined in Rowley)

--------------

#ifdef VECT_TAB_RAM

/* Set the Vector Table base location at 0x20000000 */

NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

#else /* VECT_TAB_FLASH */

/* Set the Vector Table base location at 0x08000000 */

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

#endif

--------------

With jumper J1 inserted so that the USB 1k5 pull up is always enabled the code gets stuck at

--------------

while (((volatile DEVICE_INFO*) pInformation)->Current_Configuration == 0);

--------------

If the jumper is set so that PD9 is in control of the pull up then the code gets stuck at

--------------

void HardFaultException(void)

{

DEFAULT_EXCEPTION_HANDLER(HardFaultException, ''Hard Fault'', 3, 0x0C);

}

--------------

Any ideas?

Regards

Trevor

[ This message was edited by: trevor on 17-05-2008 01:54 ]

lanchon
Associate III
Posted on May 17, 2011 at 12:28

hi trevor,

> With jumper J1 inserted so that the USB 1k5 pull up is always enabled the code gets stuck at

>

> --------------

> while (((volatile DEVICE_INFO*) pInformation)->Current_Configuration == 0);

> --------------

I strongly suspect that's a bug in the USB lib, but it could also be a bug in the way ST's VCOM sample uses the lib (read the previous posts). I use this lib only for debugging and works fine for me, I've no intention of fixing the usb lib bugs.

a ''fix'' (right!) might be to just delete that line. that line simply makes the USB init routing wait until the peripheral is enumerated by the host. (that non-optional waiting is bad library design anyway.) concerned parties might give this a try.

the correct way is to handle initialization in a proper thread safe manner. this could be as simple as delaying the enabling of USB macrocell reception and interrupts until the usb lib and macrocell are correctly initialized (and doing this with a little bit of care, such as by clearing pending interrupts before enabling reception if necessary, etc).

> If the jumper is set so that PD9 is in control of the pull up then the code gets stuck at

>

> --------------

> void HardFaultException(void)

> {

> DEFAULT_EXCEPTION_HANDLER(HardFaultException, ''Hard Fault'', 3, 0x0C);

> }

> --------------

that might be an issue with rowley. I invite you to install codesourcery arm-none-eabi, make with cs-make, and try the code. I'm afraid I can't help you with Rowley CrossWorks since it's proprietary or proprietarized code.

however I see that in your port to rowley you've included stm32exceptions.c, a file from my build environment that's not part of the app. I guess the simplest way to distinguish between what makes the app and what doesn't is to compare it with a virgin build environment that you can download from here:

http://www.st.com/mcu/forums-cat-6445-23.html

best,

lanchon

trevor1
Associate II
Posted on May 17, 2011 at 12:28

Yes, I did this last night and it works. I added this check at the top of Virtual_Com_Port_Receive_Non_Blocking and Virtual_Com_Port_Transmit_Non_Blocking.

e.g.

Code:

u32 Virtual_Com_Port_Receive_Non_Blocking(u8* data, u32 length)

{

u32 l;

if (((volatile DEVICE_INFO*) pInformation)->Current_Configuration == 0)

return 0;

.

.

Not sure if I need this -- just trying to prevent running code that assumes the interface is configured.

In terms of re-connecting:-

If I disconnect and then re-connect the USB cable and then close and open again the virtual com port on the PC then it works again (most of the time :( ). The problem then is how does the PC end ''know'' that it needs to re-connect the virtual com port when the USB cable is removed?

Regards

Trevor

trevor1
Associate II
Posted on May 17, 2011 at 12:28

Thanks for you response Lanchon.

After much hair pulling the problem was the stack size. In the Rowley project settings I changed the stack size from 128 (default) to 512 and it sprang to life........ahhhhhhhh....should have spotted this before now. The EVAL board jumper (J1) is set to its default position (2,3) so that PD9 controls the USB pull up.

Now to figure out how to make it so I can plug in and out the USB cable when ever I like and also not have to wait at start-up for USB to connect. What I'm trying to achieve is to provide access to a command line. I already have the command line working on serial ports so I just need to make my USB interface look like a serial port -- with circular buffers etc. (I'm running an OS).

I'll report back anything that might be useful to others. All suggestions welcome.

Regards

Trevor

lanchon
Associate III
Posted on May 17, 2011 at 12:28

> not have to wait at start-up for USB to connect

start by removing this line

while (((volatile DEVICE_INFO*) pInformation)->Current_Configuration == 0);

and tell us.

lanchon
Associate III
Posted on May 17, 2011 at 12:28

> The problem then is how does the PC end

this is a windows issue. if a virtual COM is disconnected by unplugging the USB, the windows virtual COM interface to the virtual COM remains in a emulated ''valid but dead'' state until the terminal closes it. if it doesn't and you reconnect, windows will not rehook the COM interface to the COM.

either make your own terminal to detect and rehook or use a better OS.