Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/usb hid multiple report fix #1091

Merged
merged 2 commits into from Aug 27, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 11 additions & 1 deletion hal/inc/hal_dynalib_usb.h
Expand Up @@ -88,10 +88,20 @@ DYNALIB_FN(BASE_IDX2 + 0, hal_usb, HAL_USB_Set_Vendor_Request_Callback, void(HAL
#define BASE_IDX4 (BASE_IDX3 + 4)
#endif


#ifdef USB_HID_ENABLE
DYNALIB_FN(BASE_IDX4 + 0, hal_usb, HAL_USB_HID_Status, int32_t(uint8_t, void*))
# define BASE_IDX5 (BASE_IDX4 + 1)
#else
# define BASE_IDX5 BASE_IDX4
#endif

DYNALIB_END(hal_usb)

#undef BASE_IDX
#undef BASE_IDX1
#undef BASE_IDX2
#undef BASE_IDX3
#undef BASE_IDX4
#undef BASE_IDX5

#endif /* HAL_DYNALIB_USB_H */
1 change: 1 addition & 0 deletions hal/inc/usb_hal.h
Expand Up @@ -186,6 +186,7 @@ int32_t HAL_USB_USART_LineCoding_BitRate_Handler(void (*handler)(uint32_t bitRat
void HAL_USB_HID_Init(uint8_t reserved, void* reserved1);
void HAL_USB_HID_Begin(uint8_t reserved, void* reserved1);
void HAL_USB_HID_Send_Report(uint8_t reserved, void *pHIDReport, uint16_t reportSize, void* reserved1);
int32_t HAL_USB_HID_Status(uint8_t reserved, void* reserved1);
void HAL_USB_HID_End(uint8_t reserved);
#endif

Expand Down
6 changes: 6 additions & 0 deletions hal/src/stm32f2xx/usb_hal.c
Expand Up @@ -532,6 +532,12 @@ void HAL_USB_HID_Send_Report(uint8_t reserved, void *pHIDReport, uint16_t report
{
USBD_MHID_SendReport(&USB_OTG_dev, NULL, pHIDReport, reportSize);
}

int32_t HAL_USB_HID_Status(uint8_t reserved, void* reserved1)
{
return USBD_MHID_Transfer_Status(&USB_OTG_dev, NULL);
}

#endif


Expand Down
3 changes: 3 additions & 0 deletions platform/MCU/STM32F2xx/SPARK_Firmware_Driver/inc/usbd_mhid.h
Expand Up @@ -38,8 +38,11 @@ typedef struct USBD_MHID_Instance_Data {
// Temporary aligned buffer
__ALIGN_BEGIN uint8_t descriptor[USBD_MHID_DESC_SIZE] __ALIGN_END;
#endif

volatile uint8_t intransfer;
} USBD_MHID_Instance_Data;

uint8_t USBD_MHID_SendReport (USB_OTG_CORE_HANDLE* pdev, USBD_MHID_Instance_Data* priv, uint8_t* report, uint16_t len);
int32_t USBD_MHID_Transfer_Status(void* pdev, USBD_Composite_Class_Data* cls);

#endif /* USBD_MHID_H_ */
9 changes: 9 additions & 0 deletions platform/MCU/STM32F2xx/SPARK_Firmware_Driver/src/usbd_mhid.c
Expand Up @@ -179,6 +179,7 @@ static uint8_t USBD_MHID_Init(void* pdev, USBD_Composite_Class_Data* cls, uint8_
// HID_OUT_PACKET,
// USB_OTG_EP_INT);

priv->intransfer = 0;
priv->configured = 1;

return USBD_OK;
Expand Down Expand Up @@ -279,6 +280,7 @@ uint8_t USBD_MHID_SendReport (USB_OTG_CORE_HANDLE* pdev, USBD_MHID_Instance_Data

if (pdev->dev.device_status == USB_OTG_CONFIGURED && priv->configured)
{
priv->intransfer = 1;
DCD_EP_Tx (pdev, priv->ep_in, report, len);
}
return USBD_OK;
Expand Down Expand Up @@ -312,6 +314,7 @@ static uint8_t USBD_MHID_DataIn(void* pdev, USBD_Composite_Class_Data* cls, uint
return USBD_FAIL;

DCD_EP_Flush(pdev, priv->ep_in);
priv->intransfer = 0;
return USBD_OK;
}

Expand All @@ -324,3 +327,9 @@ uint8_t* USBD_MHID_GetUsrStrDescriptor(uint8_t speed, USBD_Composite_Class_Data*
*length = 0;
return NULL;
}

int32_t USBD_MHID_Transfer_Status(void* pdev, USBD_Composite_Class_Data* cls)
{
USBD_MHID_Instance_Data* priv = &USBD_MHID_Instance; /* (USBD_MHID_Instance_Data*)cls->priv; */
return priv->intransfer && (((USB_OTG_CORE_HANDLE*)pdev)->dev.device_status == USB_OTG_CONFIGURED && priv->configured);
}
6 changes: 6 additions & 0 deletions user/tests/wiring/usbhid/application.cpp
@@ -0,0 +1,6 @@
#include "application.h"
#include "unit-test/unit-test.h"

UNIT_TEST_APP();

SYSTEM_MODE(SEMI_AUTOMATIC);
66 changes: 66 additions & 0 deletions user/tests/wiring/usbhid/usbhid.cpp
@@ -0,0 +1,66 @@
#include "application.h"
#include "unit-test/unit-test.h"

void startup();
STARTUP(startup());

void startup()
{
Keyboard.begin();
Mouse.begin();
}

int randomString(char *buf, int len) {
for (int i = 0; i < len; i++) {
uint8_t d = random(0, 15);
char c = d + 48;
if (57 < c)
c += 7;
buf[i] = c;
}

return len;
}

void consume(Stream& serial)
{
while (serial.available() > 0) {
(void)serial.read();
}
}

test(0_USBHID_MultipleConsecutiveReportsAreSuccessfullyDelivered) {
Serial.println("Please keep the terminal window in focus");
delay(5000);
srand(millis());

assertEqual(Serial.available(), 0);

char randStr[65];
char message[128];
memset(randStr, 0, sizeof(randStr));
memset(message, 0, sizeof(message));
randomString(randStr, sizeof(randStr) - 1);
Serial.println(randStr);

Keyboard.println(randStr);

serialReadLine(&Serial, message, sizeof(message) - 1, 10000); //10 sec timeout
assertTrue(strncmp(randStr, message, sizeof(randStr) - 1) == 0);
Serial.println();

randomString(randStr, sizeof(randStr) - 1);
Serial.println(randStr);
memset(message, 0, sizeof(message));
consume(Serial);

for (int i = 0; i < sizeof(randStr) - 1; i++) {
Keyboard.print(randStr[i]);
Mouse.move(5, 0, 0);
}
Keyboard.println();

serialReadLine(&Serial, message, sizeof(message) - 1, 10000); //10 sec timeout
assertTrue(strncmp(randStr, message, sizeof(randStr) - 1) == 0);
Serial.println();
}
3 changes: 3 additions & 0 deletions wiring/inc/spark_wiring_usbkeyboard.h
Expand Up @@ -93,6 +93,9 @@ class USBKeyboard : public Print
virtual size_t press(uint16_t k);
virtual size_t release(uint16_t k);
virtual void releaseAll(void);

private:
void sendReport();
};

extern USBKeyboard Keyboard;
Expand Down
3 changes: 3 additions & 0 deletions wiring/inc/spark_wiring_usbmouse.h
Expand Up @@ -61,6 +61,9 @@ class USBMouse
void press(uint8_t button = MOUSE_LEFT); // press LEFT by default
void release(uint8_t button = MOUSE_LEFT); // release LEFT by default
bool isPressed(uint8_t button = MOUSE_LEFT); // check LEFT by default

private:
void sendReport();
};

extern USBMouse Mouse;
Expand Down
28 changes: 23 additions & 5 deletions wiring/src/spark_wiring_usbkeyboard.cpp
Expand Up @@ -167,6 +167,7 @@ const uint8_t asciimap[128] =
//
USBKeyboard::USBKeyboard(void)
{
memset((void*)&keyReport, 0, sizeof(keyReport));
keyReport.reportId = 0x02;
HAL_USB_HID_Init(0, NULL);
}
Expand Down Expand Up @@ -238,7 +239,7 @@ size_t USBKeyboard::press(uint16_t key)
}
}

HAL_USB_HID_Send_Report(0, &keyReport, sizeof(keyReport), NULL);
sendReport();
return 1;
}

Expand Down Expand Up @@ -285,7 +286,7 @@ size_t USBKeyboard::release(uint16_t key)
}
}

HAL_USB_HID_Send_Report(0, &keyReport, sizeof(keyReport), NULL);
sendReport();
return 1;
}

Expand All @@ -298,13 +299,12 @@ void USBKeyboard::releaseAll(void)
keyReport.keys[4] = 0;
keyReport.keys[5] = 0;
keyReport.modifiers = 0;
HAL_USB_HID_Send_Report(0, &keyReport, sizeof(keyReport), NULL);
sendReport();
}

size_t USBKeyboard::writeRaw(uint16_t key)
{
uint8_t p = press(136 + key); // Keydown
delay(100);
uint8_t r = release(136 + key); // Keyup
(void)r;
return (p); // just return the result of press() since release() almost always returns 1
Expand All @@ -313,12 +313,30 @@ size_t USBKeyboard::writeRaw(uint16_t key)
size_t USBKeyboard::write(uint8_t key)
{
uint8_t p = press(key); // Keydown
delay(100);
uint8_t r = release(key); // Keyup
(void)r;
return (p); // just return the result of press() since release() almost always returns 1
}

void USBKeyboard::sendReport()
{
uint32_t m = millis();
while(HAL_USB_HID_Status(0, nullptr)) {
// Wait 1 bInterval (1ms)
delay(1);
if ((millis() - m) >= 50)
return;
}
HAL_USB_HID_Send_Report(0, &keyReport, sizeof(keyReport), NULL);
m = millis();
while(HAL_USB_HID_Status(0, nullptr)) {
// Wait 1 bInterval (1ms)
delay(1);
if ((millis() - m) >= 50)
return;
}
}

//Preinstantiate Object
USBKeyboard Keyboard;
#endif
23 changes: 21 additions & 2 deletions wiring/src/spark_wiring_usbmouse.cpp
Expand Up @@ -33,6 +33,7 @@
//
USBMouse::USBMouse(void)
{
memset((void*)&mouseReport, 0, sizeof(mouseReport));
mouseReport.reportId = 0x01;
HAL_USB_HID_Init(0, NULL);
}
Expand Down Expand Up @@ -61,14 +62,13 @@ void USBMouse::move(int8_t x, int8_t y, int8_t wheel)
mouseReport.x = x;
mouseReport.y = y;
mouseReport.wheel = wheel;
HAL_USB_HID_Send_Report(0, &mouseReport, sizeof(mouseReport), NULL);
sendReport();
}

void USBMouse::click(uint8_t button)
{
mouseReport.buttons = button;
move(0,0,0);
delay(100);
mouseReport.buttons = 0;
move(0,0,0);
}
Expand All @@ -93,6 +93,25 @@ bool USBMouse::isPressed(uint8_t button)
return false;
}

void USBMouse::sendReport()
{
uint32_t m = millis();
while(HAL_USB_HID_Status(0, nullptr)) {
// Wait 1 bInterval (1ms)
delay(1);
if ((millis() - m) >= 50)
return;
}
HAL_USB_HID_Send_Report(0, &mouseReport, sizeof(mouseReport), NULL);
m = millis();
while(HAL_USB_HID_Status(0, nullptr)) {
// Wait 1 bInterval (1ms)
delay(1);
if ((millis() - m) >= 50)
return;
}
}

//Preinstantiate Object
USBMouse Mouse;
#endif