Skip to content

Commit 0883a7e

Browse files
prusnakdpgeorge
authored andcommitted
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).
1 parent 6ace84b commit 0883a7e

3 files changed

Lines changed: 25 additions & 1 deletion

File tree

stmhal/usbd_hid_interface.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ static int8_t HID_Itf_Receive(uint8_t* Buf, uint32_t Len) {
8989
// initiate next USB packet transfer, to append to existing data in buffer
9090
USBD_HID_SetRxBuffer(&hUSBDDevice, buffer[current_write_buffer]);
9191
USBD_HID_ReceivePacket(&hUSBDDevice);
92-
92+
// Set NAK to indicate we need to process read buffer
93+
USBD_HID_SetNAK(&hUSBDDevice);
9394
return USBD_OK;
9495
}
9596

@@ -125,6 +126,9 @@ int USBD_HID_Rx(uint8_t *buf, uint32_t len, uint32_t timeout) {
125126
memcpy(buf, buffer[current_read_buffer], last_read_len);
126127
current_read_buffer = !current_read_buffer;
127128

129+
// Clear NAK to indicate we are ready to read more data
130+
USBD_HID_ClearNAK(&hUSBDDevice);
131+
128132
// Success, return number of bytes read
129133
return last_read_len;
130134
}

stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,5 +116,7 @@ uint8_t USBD_HID_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
116116
uint8_t USBD_HID_ReceivePacket(USBD_HandleTypeDef *pdev);
117117
int USBD_HID_CanSendReport(USBD_HandleTypeDef *pdev);
118118
uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
119+
uint8_t USBD_HID_SetNAK(USBD_HandleTypeDef *pdev);
120+
uint8_t USBD_HID_ClearNAK(USBD_HandleTypeDef *pdev);
119121

120122
#endif // _USB_CDC_MSC_CORE_H_

stmhal/usbdev/class/src/usbd_cdc_msc_hid.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,6 +1093,24 @@ uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t
10931093
return USBD_OK;
10941094
}
10951095

1096+
uint8_t USBD_HID_SetNAK(USBD_HandleTypeDef *pdev) {
1097+
// get USBx object from pdev (needed for USBx_OUTEP macro below)
1098+
PCD_HandleTypeDef *hpcd = pdev->pData;
1099+
USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1100+
// set NAK on HID OUT endpoint
1101+
USBx_OUTEP(HID_OUT_EP_WITH_CDC)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
1102+
return USBD_OK;
1103+
}
1104+
1105+
uint8_t USBD_HID_ClearNAK(USBD_HandleTypeDef *pdev) {
1106+
// get USBx object from pdev (needed for USBx_OUTEP macro below)
1107+
PCD_HandleTypeDef *hpcd = pdev->pData;
1108+
USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1109+
// clear NAK on HID OUT endpoint
1110+
USBx_OUTEP(HID_OUT_EP_WITH_CDC)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
1111+
return USBD_OK;
1112+
}
1113+
10961114
// CDC/MSC/HID interface class callback structure
10971115
USBD_ClassTypeDef USBD_CDC_MSC_HID = {
10981116
USBD_CDC_MSC_HID_Init,

0 commit comments

Comments
 (0)