cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F3 discovery board - unable to receive USB HID data

boaz
Associate II
Posted on December 16, 2014 at 15:15

The original post was too long to process during our migration. Please click on the attachment to read the original post.
2 REPLIES 2
tsuneo
Senior
Posted on December 16, 2014 at 20:05

I don’t find any severe error on your descriptors, except for a minor mistake on the report descriptor (**1).

Maybe, you are starting from a ST HID example, and adding the interrupt OUT endpoint. Did you enable (open) / prime the OUT endpoint? A) For STM32F3-Discovery_FW_V1.1.0 (STSW-STM32118)

usb_conf.h
/* EP1 */
/* tx buffer base address */
#define ENDP1_RXADDR (0xC0)
#define ENDP1_TXADDR (0x100)
usb_prop.c
void Joystick_Reset(void)
{
..
/* Initialize Endpoint 1 */
SetEPType(ENDP1, EP_INTERRUPT);
SetEPTxAddr(ENDP1, ENDP1_TXADDR);
SetEPRxAddr(ENDP1, ENDP1_RXADDR); // assign EP buffer
SetEPTxCount(ENDP1, 64);
SetEPRxCount(ENDP1, 64); // prime Rx (OUT) endpoint
SetEPTxStatus(ENDP1, EP_TX_NAK);
SetEPRxStatus(ENDP1, EP_RX_VALID); // enable Rx (OUT) endpoint
usb_conf.h
//#define EP1_OUT_Callback NOP_Process // <------ comment this line
Add your custom void EP1_OUT_Callback(void) routine to usb_endp.c
usb_endp.c
void EP1_OUT_Callback(void)
{
uint16_t USB_Rx_Cnt;
// read out a packet from the EP buffer
USB_Rx_Cnt = USB_SIL_Read(EP1_OUT, USB_Rx_Buffer);
// process data on the USB_Rx_Buffer, here
// Prime the OUT EP1 for the next packet
SetEPRxValid(ENDP1);
}

B) for STM32Cube_FW_F3_V1.1.0

usbd_conf.c
USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
{ 
..
..
/* Initialize LL Driver */
HAL_PCD_Init(pdev->pData);
HAL_PCDEx_PMAConfig(pdev->pData , 0x00 , PCD_SNG_BUF, 0x18);
HAL_PCDEx_PMAConfig(pdev->pData , 0x80 , PCD_SNG_BUF, 0x58);
HAL_PCDEx_PMAConfig(pdev->pData , 0x01 , PCD_SNG_BUF, 0xC0); // <------ add this line
HAL_PCDEx_PMAConfig(pdev->pData , 0x81 , PCD_SNG_BUF, 0x100); 
usbd_hid.h
#define HID_EPOUT_ADDR 0x01
#define HID_EPIN_ADDR 0x81
#define HID_EPOUT_SIZE 0x40
#define HID_EPIN_SIZE 0x40
#define USB_HID_CONFIG_DESC_SIZ 41
#define USB_HID_DESC_SIZ 9
#define HID_MOUSE_REPORT_DESC_SIZE 34
usbd_hid.c
static uint8_t USBD_HID_DataOut (USBD_HandleTypeDef *pdev, 
uint8_t epnum);
USBD_ClassTypeDef USBD_HID = 
{
USBD_HID_Init,
USBD_HID_DeInit,
USBD_HID_Setup,
NULL, /*EP0_TxSent*/ 
NULL, /*EP0_RxReady*/
USBD_HID_DataIn, /*DataIn*/
USBD_HID_DataOut, /*DataOut*/ // <-------- register OUT EP callback
NULL, /*SOF */
NULL,
NULL, 
USBD_HID_GetCfgDesc,
USBD_HID_GetCfgDesc, 
USBD_HID_GetCfgDesc,
USBD_HID_GetDeviceQualifierDesc,
};
static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev, 
uint8_t cfgidx)
{
uint8_t ret = 0;
USBD_HID_HandleTypeDef *hhid = pdev->pClassData;
/* Open EP IN */
USBD_LL_OpenEP(pdev,
HID_EPIN_ADDR,
USBD_EP_TYPE_INTR,
HID_EPIN_SIZE); 
// Open EP OUT
USBD_LL_OpenEP(pdev,
HID_EPOUT_ADDR,
USBD_EP_TYPE_INTR,
HID_EPOUT_SIZE); 
USBD_LL_PrepareReceive(pdev,
HID_EPOUT_ADDR,
hhid->RxBuffer,
HID_EPOUT_SIZE);
..
static uint8_t USBD_HID_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum)
{ 
USBD_HID_HandleTypeDef *hhid = pdev->pClassData;
/* Get the received data length */
hhid->RxLength = USBD_LL_GetRxDataSize (pdev, epnum);
if(pdev->pClassData != NULL)
{
((USBD_HID_ItfTypeDef *)pdev->pUserData)->Receive(hhid->RxBuffer, &hhid->RxLength);
return USBD_OK;
}
else
{
return USBD_FAIL;
}
}

(**1) In your report descriptor, the Input/Output takes ''Array'' property, but it should be ''Var(iable)'' 0x81, 0x02, // Input (Data, Var, Abs) .. 0x91, 0x02, // Output (Data, Var, Abs) ''Array'' stands for ''Usage array'' To apply this property, you have to define an array (list) of Usages before Input/Output, using a couple of Usages or Usage Min/Max. For example of HID 101-keyboard, Usage Page (Key Codes), Usage Minimum (0), // no event Usage Maximum (101), // Keyboard ''Application'' key Input (Data, Array, Abs), The value of the Input/Output(Array) field is an index on the Usage array. Tsuneo
boaz
Associate II
Posted on December 18, 2014 at 09:40

Thanks @chinzei.tsuneo

The following did the trick:

Fixing the Report Descriptor

Calling SetEPTxCount() and SetEPRxCount() with parameter '64' (it was 2)

usb_conf.h was already OK