2012-11-30 06:31 AM
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 STM32F 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... I've tried with an external pull up without further success). 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, PLLDIV3 thus SYSCLK = 32MHz), RTX SYSTICK_TIMER @ 32MHz. To be sure, I used MCO to display the SYSCLK frequency and it matched my expectations. The system_stm32l1xx.c has been generated through the xls provided by ST. I started without defining anything for GPIO PA11 et PA12 (as it was the case for STM32F), but then I also tried in ''alternate function'' which I believe should be more appropriate for USB. Still, in this mode, the two data lines stay very close to 0V and hardly raise, as an output forced to low, so I keep the following setting... Here, at last, D+ and D- are moving ! 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);
GPIO_PinAFConfig(GPIOA, GPIO_Pin_11, GPIO_AF_USB);//alternate function in USB mode)
GPIO_PinAFConfig(GPIOA, GPIO_Pin_12, GPIO_AF_USB);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12; //D+ and D- of USB
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //and not Mode_AF ??
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;//PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz; //Maximum speed
GPIO_Init(GPIOA, &GPIO_InitStructure);
os_tsk_prio_self(100); // Set task priority to medium
NVIC->ISER[((uint32_t)(USB_LP_IRQn) >> 5)] = (1 << ((uint32_t)(USB_LP_IRQn) & 0x1F));
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.
I place a breakpoint in the USB_LP_IRQ handler, and it appears my interrupt never raises...
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 (this, at least, seems to work correctly), 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 ?
I now suspect an issue with pin configuration / switch in USB mode... Maybe with interrupt management ?
Some of you may have seen this on keil discussion board, but I believe it's more a device issue so I try here...
Thanks in advance for your help.
Regards,
#usb-reenumeration-enumeration #usb-cdc-stm32l
2012-12-06 06:01 AM
I'm still struggling to get my device recognized by the PC... Can anybody post here a basic USB example code that actually work on STM32L ?
Thanks2012-12-06 09:09 AM
Can anybody post here a basic USB example code that actually work on STM32L ?
Doesn't STM32_USB-FS-Device_Lib_V3.4.0 contain projects/examples for the STM32L152-EVAL and STM32L152D-EVAL boards? STM32_USB-FS-Device_Lib_V3.4.0\Utilities\STM32_EVAL\STM32L152_EVAL
I can't attest to their functionality as these boards/chips are not the ones I'm invested in, but it's where I'd start looking for code examples.
2012-12-07 06:38 AM
Thank you for your answer.
I've already looked in these projects, hoping I could find some clue... In these, it seems there is no special configuration for the USB pins, as far as I can see.I tried to modify the soft to directly call the USB functions (it seems it's triggered through actions on the lcd screen menus), and program it on my stm32l-discovery board, but it didn't show much improvments. My PC keep on ignoring the device I plug. (''unknown device detected'')In fact, I find it quite difficult to extract the few lines I need for USB management among a single project composed of thousands of features interacting with each others... It's so weighty I'm sure to forget something. That's why I was begging for a ''basic USB example code''.But I will definitly take a closer look to that, thanks !2013-05-08 11:12 AM
Even the example projects don't work. It is clear that STM32L is an afterthought for ST's MCD team, in terms of USB functionality.
I've struggled for a long time, using variants of the FS lib and example project, with no success. On the F series devices, yes, it works beautifully. I suspect a major problem is the internal pullup. I have not tried using an external pullup at this point. I suspect another major problem is the place in the USB routine where the ALT USB configuration should occur. It is not anywhere in the example code or in documentation, so to debug it is like fighting in the dark.Tremendously annoying.2013-05-08 01:45 PM
Are you working on STM32L-DISCOVERY or 32L152CDISCOVERY board ?
These dev boards don't mount any crystal, though the boards have pads for crystal (and associated capacitors and a resistor) The examples in STM32_USB-FS-Device_Lib_V4.0.0 (STSW-STM32081) expect a 8MHz crystal for USB operation. In the Keil forum, I posted a port of KEIL RL-USB HID to STM32L-DISCOVERY board, the source and brief porting notes. http://www.keil.com/forum/22234/ 4-Feb-2013 22:45 GMT See the notes on above post in Keil forum. Tsuneo2013-05-08 09:46 PM
I'm using the IKRv001 board, which is an ST product using an STM32L152VBT6. It includes an 8MHz crystal. Like the topic-starter, I have no problem generating the 96 MHz PLL signal. I've actually generated that in a variety of ways, but this board does it the same way as the normal STM32L kits do.
Also like the topic starter, the USB LP interrupt doesn't usually work. It will indeed be invoked following USB_Init() as long as the USB D+/- pins are set to floating inputs, with multiple interrupt bits high -- both suspend and CTR. Suspend has higher-priority. I've turned-off the Suspend feature itself, so the part goes into ''Resume Later.'' It doesn't.I expect that, at some point, the ALT setting of the USB pins needs to occur. If it is done at startup, then nothing works. The LP interrupt never occurs.Anyway, I will tinker around over the next several weeks. I will also refer to the Keil implementation. ST's implementation needs an overhaul, though.2013-05-09 07:59 AM
It looks like you are using an RTOS. I once had issues with the USB enumeration because the thread could not satisfy the very strict enumeration timing. You might want to try to handle the enumeration before you start up the RTOS.
2013-05-09 03:44 PM
My RTOS is asynchronous, and the USB driver itself runs outside the thread that manages communication processing and timeouts.
But that is not really important, because in the testing I am doing, all of the enumeration occurs before the scheduler is even initialized (like you suggest).2013-05-09 11:54 PM
norair.jp
> I've turned-off the Suspend feature itself, so the part goes into ''Resume Later.'' It doesn't. Did you disable Suspend on usb_conf.h ? To disable Suspend/Resume behavior completely on this stack, drop CNTR_SUSPM and CNTR_ESOFM from IMR_MSK() definition.
STM32_USB-FS-Device_Lib_V4.0.0/Projects/Virtual_COM_Port/inc/usb_conf.h
/* IMR_MSK */
/* mask defining which events has to be handled */
/* by the device application software */
// #define IMR_MSK (CNTR_CTRM | CNTR_WKUPM | CNTR_SUSPM | CNTR_ERRM | CNTR_SOFM \
// | CNTR_ESOFM | CNTR_RESETM )
// Disable Suspend/Resume response completely
#define IMR_MSK (CNTR_CTRM | CNTR_WKUPM | CNTR_ERRM | CNTR_SOFM | CNTR_RESETM )
The Suspend() code (in usb_pwr.c) of this stack drops the entire system into STOP mode. By this code, the device stays in STOP mode, while USB is not plugged in, and until bus reset occurs on USB after plug in.
This stack behavior should be ''unexpected'' for self-powered devices ;)
I ran Virtual_COM_Port example of STM32_USB-FS-Device_Lib_V4.0.0 on my STM32L-DISCOVERY (with 8MHz crystal). The example was built on Keil under STM32L152-EVAL configuration without any other change. At USB plug in, it enumerated without any trouble (confirmed on a hardware bus analyzer), except the debugger terminated unexpectedly. When I applied above Suspend modification, the debugger survived.
A jumper across PA2-PA3 (USART2 TX/RX) was placed for loopback, but I didn't see any character on TeraTerm, when a key was typed in. On debugger, EP3_OUT_Callback() certainly put the byte to USART2 by calling USART_SendData(). But breakpoint on EVAL_COM1_IRQHandler() didn't fire. There seem to be a trouble on USART setting, but sorry, my free time has expired today ;)
Update:
STM32L152-EVAL configuration assigns PD5/PD6 for USART2 TX/RX. But STM32L-DISCOVERY doesn't have these ports. After modifying USART2 port assignment, above loopback test works as expected.
Tsuneo