Skip to main content
lanchon
Associate III
April 4, 2009
Question

stdio via USB virtual COM port

  • April 4, 2009
  • 48 replies
  • 8644 views
Posted on April 04, 2009 at 17:08

stdio via USB virtual COM port

    This topic has been closed for replies.

    48 replies

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

    here's a simple library to route stdio over USB using serial port emulation. it's very easy to integrate into non USB-enabled projects, take a look at main.c. it implements bidirectional blocking I/O (flow control on the PC should be set to none). hopefully all data races in the virtual COM port sample app were solved. (less than 10KB.)

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

    small changes to clean up interface and allow reading of tx/rx buffer availability, see usb_endp.h.

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

    I forgot to mention that you can't type into the virtual COM using HyperTerminal, but you *can* paste into it; go figure!

    I imagine it has to do with the VCOM code not implementing the RS-232 handshake signals, an issue of ST's VCOM implementation.

    PuTTY works fine but sends '\r' as line terminator and can't be made to send '\n' (or I'm dumb). Termite works ok but only transmits complete lines.

    paul
    Associate
    May 17, 2011
    Posted on May 17, 2011 at 12:28

    I should have read the documentation before asking.

    On page 14/46 in the STM32-Eval board the J1 needs to be placed on pins 1-2, the default was pins 2-3 and simulated USB disconnect mode.

    Thanks for the code lanchon.

    paul
    Associate
    May 17, 2011
    Posted on May 17, 2011 at 12:28

    lanchon,

    I am using the STM32-EVAL board. I have compiled your code using arm-none-eabi-gcc. During startup I just hang in Virtual_Com_Port_Init(), specifically at line 124: while (((volatile DEVICE_INFO*) pInformation)->Current_Configuration == 0);

    Is there something that I need to press/configure on the EVAL board to get the board to boot?

    Regards Paul

    paul
    Associate
    May 17, 2011
    Posted on May 17, 2011 at 12:28

    I am not getting stuck in the USB_LP_CAN_RX0_IRQHandler(). This is due to wInterrupt_Mask not being set before the first interrupts come in. Then the board is continuously in the ISR as the interrupt is never cleared. I tried setting wInterrupt_Mask to 0xF00, this just caused a BusFault.

    I am not experienced at all with USB so a little help to get up and running would be great.

    Regards Paul

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

    Hi,

    first thanks for the great library. I was using it on Olimex prototype board and it works great.

    However, recently I switched to a custom-designed hardware. On the custom design we don't have a USB pullup pin as the device is powered through USB and USB is constantly connected. So defines as USB_PULLUP_GPIO_PORT are not used.

    My startup code gets stuck in the same place as described: it freezes in USB_Init() -> Virtual_Com_Port_Init() -> PowerOn(), on the last instruction:

    _SetCNTR(wInterrupt_Mask);

    Although, after the freeze, I do get one

    USB_LP_CAN_RX0_IRQHandler interrupt that is handled by USB_Istr(), in the first IF statement:

    if (wIstr & ISTR_RESET & wInterrupt_Mask)

    Why does the code block when there is no pullup pin? When we designed the custom hardware it seemed we don't need it for our application. But now, I am not sure. I wouldn't like to go through one more hardware revision.

    I am using STM32F103T8U6 chip.

    Best regards,

    Niksa

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

    > During startup I just hang in Virtual_Com_Port_Init()

    > in the STM32-Eval board the J1 needs to be placed on pins 1-2, the default was pins 2-3 and simulated USB disconnect mode.

    in main.c there are a few macros named USB_PULLUP_* or something like that define which pin is used for controlled USB pullup (simulated USB disconnect). you need to set these for your board (I think it's PD9 on your case, but check). that's all the configuration necessary.

    > wInterrupt_Mask not being set before the first interrupts come in. Then the board is continuously in the ISR as the interrupt is never cleared.

    there might be race conditions in the USB lib during startup and shutdown. if I had to guess, I'd say that the cause of the problem might be that some conditions arise as a result of having the USB pullup fixed as active by the jumper, that trigger the interrupt before the library is initialized (maybe an RX event or an overrun or whatever, I know very little about the USB macrocell). if this is true then fixing the USB_PULLUP_* macros would also solve this problem.

    lanchon
    lanchonAuthor
    Associate III
    May 17, 2011
    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.

    niksa
    Associate II
    May 17, 2011
    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