2014-12-16 06:15 AM
2014-12-16 11:05 AM
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
2014-12-18 12:40 AM
Thanks @chinzei.tsuneo
The following did the trick:Fixing the Report DescriptorCalling SetEPTxCount() and SetEPRxCount() with parameter '64' (it was 2)usb_conf.h was already OK