cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 USB configuration problem

rafflex290
Associate II
Posted on September 26, 2014 at 11:18

Hi Guys,

Im currently try to implement a USB. The programm is

derived

from the CDC example. It is already working with 3 enpoint like in the CDC example. But I want only to work with 2 endpoint but when I configured it I get always a set configuration error when a want to communicate with the stm here a the configuration with 3 endpoints: usb_desc.c

const
uint8_t Virtual_Com_Port_DeviceDescriptor[] =
{
0x12, 
/* bLength */
USB_DEVICE_DESCRIPTOR_TYPE, 
/* bDescriptorType */
0x00,
0x02, 
/* bcdUSB = 2.00 */
0xff, 
/* Class: Vendor specific */
0x00, 
/* bDeviceSubClass */
0x00, 
/* bDeviceProtocol */
0x40, 
/* bMaxPacketSize0 */
0x83,
0x04, 
/* idVendor = 0x0483 */
0x01,
0xf0, 
/* idProduct = 0xf001 */
0x00,
0x01, 
/* bcdDevice = 2.00 */
1, 
/* Index of string descriptor describing manufacturer */
2, 
/* Index of string descriptor describing product */
3, 
/* Index of string descriptor describing the device's serial number */
0x01 
/* bNumConfigurations */
};
const
uint8_t Virtual_Com_Port_ConfigDescriptor[] =
{
/*Configuation Descriptor*/
0x09, 
/* bLength: Configuation Descriptor size */
USB_CONFIGURATION_DESCRIPTOR_TYPE, 
/* bDescriptorType: Configuration */
VIRTUAL_COM_PORT_SIZ_CONFIG_DESC, 
/* wTotalLength:no of returned bytes */
0x00,
0x01, 
/* bNumInterfaces: 1 interface */
0x01, 
/* bConfigurationValue: Configuration value */
0x00, 
/* iConfiguration: Index of string descriptor describing the configuration */
0x80, 
/* bmAttributes: Bus powered */
500/2, 
/* MaxPower 0 mA */
/*Data class interface descriptor*/
0x09, 
/* bLength: Endpoint Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, 
/* bDescriptorType: */
0x00, 
/* bInterfaceNumber: Number of Interface */
0x00, 
/* bAlternateSetting: Alternate setting */
0x03, 
/* bNumEndpoints: 3 endpoints used */
0xff, 
/* bInterfaceClass: ??? */
0x00, 
/* bInterfaceSubClass: */
0x00, 
/* bInterfaceProtocol: */
0x00, 
/* iInterface: */
/*Endpoint 1 Descriptor*/
0x07, 
/* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, 
/* bDescriptorType: Endpoint */
0x81, 
/* bEndpointAddress: (IN1) */
0x02, 
/* bmAttributes: Bulk */
VIRTUAL_COM_PORT_DATA_SIZE, 
/* wMaxPacketSize: */
0x00,
0x00, 
/* bInterval */
/*Endpoint 2 Descriptor*/
0x07, 
/* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, 
/* bDescriptorType: Endpoint */
0x02, 
/* bEndpointAddress: (OUT2) */
0x02, 
/* bmAttributes: Bulk */
VIRTUAL_COM_PORT_DATA_SIZE, 
/* wMaxPacketSize: */
0x00,
0x00, 
/* bInterval: ignore for Bulk transfer */
/*Endpoint32 Descriptor*/
0x07, 
/* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, 
/* bDescriptorType: Endpoint */
0x03, 
/* bEndpointAddress: (OUT3) */
0x02, 
/* bmAttributes: Bulk */
VIRTUAL_COM_PORT_DATA_SIZE, 
/* wMaxPacketSize: */
0x00,
0x00 
/* bInterval: ignore for Bulk transfer */
};

usb_config.h

#define EP_NUM (4) //+EP0
 /*-------------------------------------------------------------*/
 /* -------------- Buffer Description Table -----------------*/
 /*-------------------------------------------------------------*/
 /* buffer table base address */
 /* buffer table base address */
 #define BTABLE_ADDRESS (0x00)
 /* EP0 */
 /* rx/tx buffer base address */
 #define ENDP0_RXADDR (0x40)
 #define ENDP0_TXADDR (0x80)
 /* EP1 */
 /* tx buffer base address */
 #define ENDP1_TXADDR (0xC0)
 #define ENDP2_RXADDR (0x100) 

usb_prop.c

void
Virtual_Com_Port_Reset(
void
)
{
/* Set Virtual_Com_Port DEVICE as not configured */
pInformation->Current_Configuration = 0;
/* Current Feature initialization */
pInformation->Current_Feature = Virtual_Com_Port_ConfigDescriptor[7];
/* Set Virtual_Com_Port DEVICE with the default Interface*/
pInformation->Current_Interface = 0;
SetBTABLE(BTABLE_ADDRESS);
/* Initialize Endpoint 0 */
SetEPType(ENDP0, EP_CONTROL);
SetEPTxStatus(ENDP0, EP_TX_STALL);
SetEPRxAddr(ENDP0, ENDP0_RXADDR);
SetEPTxAddr(ENDP0, ENDP0_TXADDR);
Clear_Status_Out(ENDP0);
SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
SetEPRxValid(ENDP0);
/* Initialize Endpoint 1 */
SetEPType(ENDP1, EP_BULK);
SetEPTxAddr(ENDP1, ENDP1_TXADDR);
SetEPTxStatus(ENDP1, EP_TX_NAK);
SetEPRxStatus(ENDP1, EP_RX_DIS);
/* pre-fill a packet. */
USB_SIL_Write(ENDP1,(uint8_t *)
''TEST''
, 4);
SetEPTxValid(ENDP1);
/* Initialize Endpoint 2 */
SetEPType(ENDP2, EP_BULK);
SetEPRxAddr(ENDP2, ENDP2_RXADDR);
SetEPTxStatus(ENDP2, EP_TX_DIS);
SetEPRxStatus(ENDP2, EP_RX_VALID);
SetEPRxCount(ENDP2, VIRTUAL_COM_PORT_DATA_SIZE);
/* Set this device to response on default address */
SetDeviceAddress(0);
bDeviceState = ATTACHED;
}

usb_endp.c

/*******************************************************************************
* Function Name : EP1_IN_Callback
* Description :
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void
EP1_IN_Callback (
void
)
{
SetEPTxValid(ENDP1);
}
/*******************************************************************************
* Function Name : EP2_OUT_Callback
* Description :
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void
EP2_OUT_Callback(
void
)
{
packet_receive = 1;
Receive_length = GetEPRxCount(ENDP2);
PMAToUserBufferCopy((unsigned 
char
*)Receive_Buffer, ENDP2_RXADDR, Receive_length);
SetEPRxValid(ENDP2);
}

and the 2 endpoint config I just modify usb_desc.c and usb_conf.h usb_desc.c

const
uint8_t Virtual_Com_Port_ConfigDescriptor[] =
{
/*Configuation Descriptor*/
0x09, 
/* bLength: Configuation Descriptor size */
USB_CONFIGURATION_DESCRIPTOR_TYPE, 
/* bDescriptorType: Configuration */
VIRTUAL_COM_PORT_SIZ_CONFIG_DESC, 
/* wTotalLength:no of returned bytes */
0x00,
0x01, 
/* bNumInterfaces: 1 interface */
0x01, 
/* bConfigurationValue: Configuration value */
0x00, 
/* iConfiguration: Index of string descriptor describing the configuration */
0x80, 
/* bmAttributes: Bus powered */
500/2, 
/* MaxPower 0 mA */
/*Data class interface descriptor*/
0x09, 
/* bLength: Endpoint Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, 
/* bDescriptorType: */
0x00, 
/* bInterfaceNumber: Number of Interface */
0x00, 
/* bAlternateSetting: Alternate setting */
0x02, 
/* bNumEndpoints: 3 endpoints used */
0xff, 
/* bInterfaceClass: ??? */
0x00, 
/* bInterfaceSubClass: */
0x00, 
/* bInterfaceProtocol: */
0x00, 
/* iInterface: */
/*Endpoint 1 Descriptor*/
0x07, 
/* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, 
/* bDescriptorType: Endpoint */
0x81, 
/* bEndpointAddress: (IN1) */
0x02, 
/* bmAttributes: Bulk */
VIRTUAL_COM_PORT_DATA_SIZE, 
/* wMaxPacketSize: */
0x00,
0x00, 
/* bInterval */
/*Endpoint 2 Descriptor*/
0x07, 
/* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, 
/* bDescriptorType: Endpoint */
0x02, 
/* bEndpointAddress: (OUT2) */
0x02, 
/* bmAttributes: Bulk */
VIRTUAL_COM_PORT_DATA_SIZE, 
/* wMaxPacketSize: */
0x00,
0x00 
/* bInterval: ignore for Bulk transfer */
};

usb_conf.h

#define EP_NUM (3) //+EP0

Does anybody know how to solve the problem so I can just use 2 endpoint or anybody knows why this error happend? Thanks in advance
10 REPLIES 10
rafflex290
Associate II
Posted on October 01, 2014 at 09:33

no one has

an idea?

chen
Associate II
Posted on October 01, 2014 at 11:46

Hi

''

no one has

an idea?

''

''Im currently try to implement a generic USB.''

This statement is non nonsensical. There is no such thing as a 'generic USB'.

You must define a USB device of some kind.

The number of end points then can depend or be defined by the USB device type.

 

rafflex290
Associate II
Posted on October 01, 2014 at 13:18

Thanks for your reply!.

When I use the 0xFF( Class: vendor specific) in the Device Descriptor and the 0xFF (bInterfaceClass) in the Config Descriptor than it should be a complete vendor specific device arent it?

So the I can configure with the bNumEndpoints how many endpoint are used. But if I just modify this to two I get always an error when ii want to set configuration over PC with libusb but when I define three endpoint than everything is fine. Do I have to modify somewhere else the endpoints which I want to use except the EP_NUM in usb_config.h

chen
Associate II
Posted on October 01, 2014 at 13:34

''When I use the 0xFF( Class: vendor specific) in the Device Descriptor and the 0xFF (bInterfaceClass) in the Config Descriptor than it should be a complete vendor specific device arent it? ''

If you do this, then YOU must provide a matching driver for the host (PC) so that the host knows how to communicate with it (which will include how many end points are valid).

rafflex290
Associate II
Posted on October 01, 2014 at 14:40

ok thanks for the hint. So Im just started with usb stuff. I just followed the WIN USB Driver Installation which you can find on libusb.org (wiki).

http://www.libusb.org/wiki/winusb_driver_installation An the I used a simple python script with pyusb to communicate with the stm32

import usb.core
import usb.util
# find our device
dev = usb.core.find(idVendor=0x0483, idProduct=0xf001)
print dev
# was it found?
if dev is None:
raise ValueError('Device not found')
# set the active configuration. With no arguments, the first
# configuration will be the active one
dev.set_configuration()
# get an endpoint instance
cfg = dev.get_active_configuration()
intf = cfg[(0,0)]
ep_in = cfg[(0,0)][0]
ep_out = cfg[(0,0)][1]
print ep_out.write('test' )
print ep_in.read( 64, 500 )

This works well with the 3 endpoint setting but not with the 2 endpoint setting. Do I need to modify the WinUSB driver part much more to get it work with the 2 endpoints. Thanks for your help. I just want to learn how the hole usb stuff works but as you know this little bit confusing in the beginning
tsuneo
Senior
Posted on October 01, 2014 at 15:38

As of the Device descriptor, you should apply the device class triad of (0x00, 0x00, 0x00), in either case of 3 or 2 endpoints. This device triad means ''the USB class is determined by each interface''. (0xFF, 0x00, 0x00) may work, but (0x00, 0x00, 0x00) is better.

const uint8_t Virtual_Com_Port_DeviceDescriptor[] =
{
...
0xff, /* Class: Vendor specific */ <---- 0x00
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */

> but when I configured it I get always a set configuration error Did you change the value of VIRTUAL_COM_PORT_SIZ_CONFIG_DESC, which is used for wTotalLength field of the config descriptor ? For 3 endpoints, #define VIRTUAL_COM_PORT_SIZ_CONFIG_DESC (9 + 9 + 7 * 3) For 2 endpoints, #define VIRTUAL_COM_PORT_SIZ_CONFIG_DESC (9 + 9 + 7 * 2) Tsuneo
rafflex290
Associate II
Posted on October 01, 2014 at 15:53

chinzei.tsuneo you are genius

it was the #define VIRTUAL_COM_PORT_SIZ_CONFIG_DESC (9 + 9 + 7 * 2)

should the bInterfaceClass in the ConfigDescriptor also be 0x00 or 0xff vendor specific

thanks for the great help

chen
Associate II
Posted on October 01, 2014 at 16:02

Hi

''I just want to learn how the hole usb stuff works but as you know this little bit confusing in the beginning''

I'm running into the limits of my knowledge and understanding as well.

The end point handling code is in the USB device/core USB code.

If you are using one of the 'USB device types' that ST have provided examples for - you do not need to touch this code (unless you find a bug, of which there are lots).

Essentially, what you are doing is ignoring the hierarchical layers in the USB implementaion :

5 User USB implementation

4 USB Device type implementation

3 USB Core implementation

2 USB Peripheral HW (STM32 peripheral)

1 Physical USB (physical wires)

You are trying to handle 4 and 5 (and possibly 3) together.

As I said at the start - there is no such thing as 'Generic USB'

You started with a 'Generic USB CDC' - Communications Device Class and have mangled it into 'unknown'.

To understand - try playing with the CDC and MSC (Mass Storage Class) - ie only work at layer 5

HID (Human Interface Device - ie keyboard, mouse and joystick) is also very simple and easy to understand.

Once you understand the different device classes (and the code and APIs into the lower layer (4) ) then start to look at the next layer down.

As I said, Im running into the limits of my knowledge because I only look at the End Point handling code (layer 4) when Im debugging at layer 5 (and sometimes spot a bug in layer 4).

rafflex290
Associate II
Posted on October 01, 2014 at 16:14

But I

learned

alot from my ''stupid'' trials so I think thats good