cancel
Showing results for 
Search instead for 
Did you mean: 

STM32Cube CDC - problems and a possible bug

matteo
Associate II
Posted on March 22, 2014 at 01:39

Hello.

I am currently trying to build a project using the STM32F429 iDisco. The toolchain I am using is the arm embedded gcc, under Eclipse IDE. I am trying to use STM32Cube to write the initialization part for me. Initially I want to use CDC to loopback data sent from a pc (host) to the board (device). Later I want to implement communication between pc and board to control sensors. I'm fiddling with the various callbacks that Cube puts in usbd_conf.c. Since my first problem is the fact that the host pc cannot recognize the connected board (Windows has stopped this device because it has reported problems. (Code 43)A request for the USB device descriptor failed.) I am playing with HAL_PCD_ConnectCallback, but I am not sure what I should be doing there. I tried opening a bunch of endpoints (with HAL_PCD_EP_Open()), but to no avail. Using the board's LEDs to give me output depending on the device state, tells me that after initialization the device is in USBD_STATE_DEFAULT, but after a while (as soon as Windows enumerates it and cannot find its descriptor) it goes in USB_STATE_SUSPENDED. While playing around with my code I also found something that looked kinda odd. In stm32f4xx_hal_pcd.c, in the functionHAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd), from line 163:

for (i = 0; i < 
15
; i++)
{
hpcd->OUT_ep[i].is_in = 0;
hpcd->OUT_ep[i].num = i;
hpcd->IN_ep[i].tx_fifo_num = i; //<<< 
THIS
LOOKS ODD
/* Control until ep is activated */
hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
hpcd->OUT_ep[i].maxpacket = 0;
hpcd->OUT_ep[i].xfer_buff = 0;
hpcd->OUT_ep[i].xfer_len = 0;
hpcd->Instance->DIEPTXF[i] = 0;
}

Line 167 (the third instruction in the for loop) looks out of place to me. Can anyone tell me what should I write, and where, to implement this loopback? Ideally, the result of this step in my project would be that the board can receive data from a terminal and loop it back, like I did with a VCP code I downloaded recently. Also, can anyone confirm that that line is correct as it is? Thanks, Matteo #stm32cubemx #stm32f429 #discovery
9 REPLIES 9
matteo
Associate II
Posted on March 22, 2014 at 01:53

Just a quick thing.

Since the device enters theUSBD_STATE_SUSPENDED state, it means that the HAL_PCD_SuspendCallback is called correctly. Also, I noticed that in usbd_core.c, the function for the connection event does nothing:

USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev)
{
return USBD_OK;
}

In the old libraries it was different

static uint8_t USBD_DevConnected(USB_OTG_CORE_HANDLE *pdev)
{
pdev->dev.usr_cb->DeviceConnected();
pdev->dev.connection_status = 1; 
return USBD_OK;
}

I thing this may be why my host does not receive any descriptor? I will play with it tomorrow, or later tonight. Best, Matteo
matteo
Associate II
Posted on March 23, 2014 at 02:40 Further update. There are a lot more differences between old std periphery library and current hal library. Since the host pc cannot get a descriptor from the board I was looking into USBD_GetDescriptor The older libraries had more checks on most cases, for example on the value of the length parameter. For example:

/*FROM THE HAL LIBRARY*/
case USB_DESC_TYPE_DEVICE:
pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len);
break;
/*FROM THE OLDER LIBRARY*/
case USB_DESC_TYPE_DEVICE:
pbuf = pdev->dev.usr_device->GetDeviceDescriptor(pdev->cfg.speed, &len);
if ((req->wLength == 64) ||( pdev->dev.device_status == USB_OTG_DEFAULT)) 
{ 
len = 8;
}
break;

Can anyone confirm that these differences are ok? I am assuming that the difference in the structs is correct, but what about those checks? At this moment I don't have access to the board to try and change that code to see what happens. Best, Matteo
stm32cube-t
Senior III
Posted on March 26, 2014 at 15:59

Hello Matteo,

If the answer below is not sufficient, please send us your STM32CubeMX project file (.ioc extension).

To enumerate in CDC class, the STM32F4 device requires minimum heap and stack sizes. Please modify the stack and heap sizes in the stm32f4xxx_startup.s file as shown in red in the snapshot below:

0690X000006058yQAA.png

Be warned that those settings will be overwritten upon next code generation. This issue should be fixed in a future release.

schauer
Associate II
Posted on March 26, 2014 at 17:12

Matteo,

your issue has (most likely) nothing todo with stack/heap size(s). The STM32Cube utility with the Firmware (also v.1.1.0) has several bugs in. First: in function SystemClock_Config check that the line

HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_x);

is configured so, that it meets the requirements (User Manual!) according to supply voltage and clock frequency of your stm The generator in my case always write FLASH_LATENCY_0 instead of FLASH_LATENCY_5. Second: in file stm32f4xx_hal_pcd.c find the block (around line 464):

if
(hpcd->Init.use_dedicated_ep1)
{
USBx_DEVICE->DOUTEP1MSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM); 
USBx_DEVICE->DINEP1MSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM); 
}
else
{
USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
}

and change them to:

if
(hpcd->Init.use_dedicated_ep1)
{
USBx_DEVICE->DOUTEP1MSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM); 
USBx_DEVICE->DINEP1MSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM); 
}
USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);

originally (before change): when using dedicated EP1, only EP1 interrupt mask gets configured, but not the register required for all other EP's. In that case: you might be able to transfer data via EP1 but you can't enumerate as EP0 is not working. I think the HAL firmware was not tested. In my case the device enumerated afterwards and it was possible to work with it.
matteo
Associate II
Posted on March 26, 2014 at 17:55

Thank you both for pitching in.

I tried both solutions (each by itself and both together) to no avail. The device initially goes into the USBD_STATE_ADDRESSED. Then it switches to the USBD_STATE_DEFAULT. Then the host pc throws the ''Device descriptor request failed'' error, and the board goes into the USBD_STATE_SUSPENDED.

A note to farfalle:

I do not have the file you mentioned anywhere. The only startup assembly file I have is startup_stm32f429xx.S, which does not include the lines you mention. I changed the minimum stack and heap sizes from my linker script.

A note to bs:

In my SystemClock_Config() the line you mention is as follows:

HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3);

That looks right to me, even though Eclipse sometimes tells me it cannot resolve FLASH_LATENCY_3.

Cheers,

Matteo

matteo
Associate II
Posted on March 26, 2014 at 18:21

Hello,

As found on another thread on the forums, once I disabled the ''Dedicated endpoint 1 interrupt'' (for whose setting there was the check in bs' snippet) the device is recognized as a ST VCP.

ref:

https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Java/Flat.aspx?RootFolder=%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fSTM32Java%2fSTM32CubeF4%20Usb%20documentation&FolderCTID=0x01200200770978C69A1141439FE559EB459D758000F9A0E3A95BA69146A17C2E80209ADC21&currentviews=189

stm32cube-t
Senior III
Posted on March 27, 2014 at 10:54

Hello Matteo,

All 3 points mentionned above are correct:

- stack/heap size (note: if using IAR toolchain you should specify them in the .icf file, if using Keil, in startup.s).

- Flash latency: this is an issue being looked into.

- ''Dedicated endpoint 1 interrupt'' must be disabled: the underlying STM32CubeF4 firmware current version does not support enabling this interrupt. Next STM32CubeMX version will be fixed to show accordingly, i.e. that it can not be enabled. 

stm32cube-t
Senior III
Posted on March 27, 2014 at 14:45

Regarding Flash latency (wait state value) issue, this will be fixed in next official STM32CubeMX release 4.1.

For workarounds in STM32CubeMX 4.0, see following post:

[DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32Java/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Java/Bug%20in%20STM32Cube%20for%20STM32F417&FolderCTID=0x01200200770978C69A1141439FE559EB459D758000F9A0E3A95BA69146A17C2E80209ADC21&TopicsView=https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Java/AllItems.aspx&currentviews=19]Bug in STM32Cube for STM32F417

schauer
Associate II
Posted on March 27, 2014 at 15:56

In my case EP 1 dedicated interrupt must be enabled to transfer data with the device. If not, it gets enumerated but its not possible to send data.

The EP1 ISR's are never called anyway...