This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

USB CDC on STM32L device : unable to connect to host.

Hi all,

I try to make a device based on STM32L151 which will communicate through USB in CDC mode.

My software was initially developped on an STM32F4-discovery board, and it was working perfectly. It was also working on another board using a STM32F103. Then I switched to my own board and on STM32L-discovery and things started to go wrong...

If I compare stm32F and STM32L reference manuals, the only difference on the USB part is the internal pull up over D+ that you can manage via software (although it has been mentionned in an errata that the value was closer to 0.8kOhms than 1.5kOhms).

The electronic schematic of my board is pretty straightforward : D+ and D- of the STM32 are connected directly to a USB connector, no pullup. The entire board is USB powered.

I modified my working STM32F103 project for it fits the STM32L specs :
* USB_LP_CAN1_RX0_IRQn renamed in USB_LP_IRQn
* void USB_LP_CAN1_RX0_IRQHandler(void) in void USB_LP_IRQHandler(void) {

I use the same Keil RTX configuration on the other projects with USB working.

My clock settings are on HSE (driving an 8MHz quartz), with a PLL (PLLMUL12 thus PLLVCO @ 96MHz, PLLDIV2 thus SYSCLK = 48MHz), RTX SYSTICK_TIMER @ 72MHz. To be sure, I used MCO to display the SYSCLK frequency, divided by 2, and I measured 24MHz, which matched my expectations.

My main() starts a task that initialize I/O and USB as followed :

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//to manage internal usb pullup
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);


os_tsk_prio_self(100);   // Set task priority to medium
usbd_connect(__TRUE);    // USB Device Connect
usbd_init();             // USB Device Initialization
SYSCFG->PMC |= 1;     //Set USB pull up (STM32 internal pullup)
os_tsk_prio_self(1);     // Set task priority to the lowest
// Check if usb stack initialized and device connected to the host
do
{
Delay(100);
}while (!usbd_configured());

And my program is stuck in this loop.

On the PC side, my windows 7 see that some kind of USB device has been pluged as soon as the pull up is activated, but it prompts an error because it's unabled to retrieve VID and PID, so no driver assignation is possible.

I've worked with microchip PIC for a few years now, but I'm new to ST and Keil. Here I obviously miss something, but I can't simply put my finger on it.

Does somebody have any idea to make it work ?

Thanks in advance for your help.

Regards

Parents
  • Hi Tsuneo, thank you for your answer.

    As there's no USB connector on the STM32L-Discovery board, I cut a usb cable and plug the green wire to D+ (PA12) and the white one to D- (PA11). I double check with a multimeter and our previous designs using USB, as there is plenty of wrong schematics all over the internet... In doubt, I eventually swap the wire, to be sure, but no improvment.

    Still, I now suspect some issue with IO configuration for USB pins. It seems that the USB functionnality isn't the default configuration so I tried to add the following lines :

    //Set to AF configuration for USB, even if nobody seems to use it ?
    GPIO_PinAFConfig(GPIOA, GPIO_Pin_11, GPIO_AF_USB);
    GPIO_PinAFConfig(GPIOA, GPIO_Pin_12, GPIO_AF_USB);
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;                    //Draw d+ and d- lines to ground ! Host can manage it only if I set it on GPIO_Mode_IN instead
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;//PP;             //OD or PP : no improvment
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;                //default state anyway
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;               //maximum speed
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    

    And according to my scope (and as there's no detection on the PC side) GPIO_Mode_AF seems to force both USB lines to ground... The only way to let host send something over that bus is to configure it as GPIO_Mode_In, but of course, the STM32L raises no interrupt, since I guess it's not configured the right way.

    I certainly miss something here, but I've no idea.

Reply
  • Hi Tsuneo, thank you for your answer.

    As there's no USB connector on the STM32L-Discovery board, I cut a usb cable and plug the green wire to D+ (PA12) and the white one to D- (PA11). I double check with a multimeter and our previous designs using USB, as there is plenty of wrong schematics all over the internet... In doubt, I eventually swap the wire, to be sure, but no improvment.

    Still, I now suspect some issue with IO configuration for USB pins. It seems that the USB functionnality isn't the default configuration so I tried to add the following lines :

    //Set to AF configuration for USB, even if nobody seems to use it ?
    GPIO_PinAFConfig(GPIOA, GPIO_Pin_11, GPIO_AF_USB);
    GPIO_PinAFConfig(GPIOA, GPIO_Pin_12, GPIO_AF_USB);
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;                    //Draw d+ and d- lines to ground ! Host can manage it only if I set it on GPIO_Mode_IN instead
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;//PP;             //OD or PP : no improvment
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;                //default state anyway
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;               //maximum speed
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    

    And according to my scope (and as there's no detection on the PC side) GPIO_Mode_AF seems to force both USB lines to ground... The only way to let host send something over that bus is to configure it as GPIO_Mode_In, but of course, the STM32L raises no interrupt, since I guess it's not configured the right way.

    I certainly miss something here, but I've no idea.

Children
No data