Browse Source

stmhal: Implement SNAK/CNAK mechanism for USB HID receive.

This implements flow control in case user does not call recv method often
enough (it tells host side to stop sending more data).
pull/2631/head
Pavol Rusnak 8 years ago
committed by Damien George
parent
commit
0883a7e72f
  1. 6
      stmhal/usbd_hid_interface.c
  2. 2
      stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h
  3. 18
      stmhal/usbdev/class/src/usbd_cdc_msc_hid.c

6
stmhal/usbd_hid_interface.c

@ -89,7 +89,8 @@ static int8_t HID_Itf_Receive(uint8_t* Buf, uint32_t Len) {
// initiate next USB packet transfer, to append to existing data in buffer
USBD_HID_SetRxBuffer(&hUSBDDevice, buffer[current_write_buffer]);
USBD_HID_ReceivePacket(&hUSBDDevice);
// Set NAK to indicate we need to process read buffer
USBD_HID_SetNAK(&hUSBDDevice);
return USBD_OK;
}
@ -125,6 +126,9 @@ int USBD_HID_Rx(uint8_t *buf, uint32_t len, uint32_t timeout) {
memcpy(buf, buffer[current_read_buffer], last_read_len);
current_read_buffer = !current_read_buffer;
// Clear NAK to indicate we are ready to read more data
USBD_HID_ClearNAK(&hUSBDDevice);
// Success, return number of bytes read
return last_read_len;
}

2
stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h

@ -116,5 +116,7 @@ uint8_t USBD_HID_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
uint8_t USBD_HID_ReceivePacket(USBD_HandleTypeDef *pdev);
int USBD_HID_CanSendReport(USBD_HandleTypeDef *pdev);
uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
uint8_t USBD_HID_SetNAK(USBD_HandleTypeDef *pdev);
uint8_t USBD_HID_ClearNAK(USBD_HandleTypeDef *pdev);
#endif // _USB_CDC_MSC_CORE_H_

18
stmhal/usbdev/class/src/usbd_cdc_msc_hid.c

@ -1093,6 +1093,24 @@ uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t
return USBD_OK;
}
uint8_t USBD_HID_SetNAK(USBD_HandleTypeDef *pdev) {
// get USBx object from pdev (needed for USBx_OUTEP macro below)
PCD_HandleTypeDef *hpcd = pdev->pData;
USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
// set NAK on HID OUT endpoint
USBx_OUTEP(HID_OUT_EP_WITH_CDC)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
return USBD_OK;
}
uint8_t USBD_HID_ClearNAK(USBD_HandleTypeDef *pdev) {
// get USBx object from pdev (needed for USBx_OUTEP macro below)
PCD_HandleTypeDef *hpcd = pdev->pData;
USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
// clear NAK on HID OUT endpoint
USBx_OUTEP(HID_OUT_EP_WITH_CDC)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
return USBD_OK;
}
// CDC/MSC/HID interface class callback structure
USBD_ClassTypeDef USBD_CDC_MSC_HID = {
USBD_CDC_MSC_HID_Init,

Loading…
Cancel
Save