-
Notifications
You must be signed in to change notification settings - Fork 39
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
HID Discuss #5
Comments
I can't see a hook for the parser - where is it?
|
The info comes from the host. As far as parsing the HID data, that has to be done yet. |
Do we need vidpid?
|
Yes, to trump "basic" drivers to specifically crafted ones. |
Oh and don't worry, once the information is used, it will be thrown away. it is only very basic at this point. Much of this information can be reduced to a newer struct that contains only the bare minimums to work. |
all looks good to me |
What is the purpose of UHS_BT_HOST_BASE? |
Same thing, it is a base class. |
Hello, I tried the 2.0 library with the shield MAX3421E + Mega2560 and it worked (HID mouse/keyboard and pendrive). Outputs occur on the serial monitor. But I could not get any output on the serial monitor with library 3.0, just start message. What must I do to get results? The MAX3421E RESET pin is connected directly to the Arduino Reset pin, does it have any influence? Where are the pin definitions? In which file? |
There are a couple of ways. Here is how I do this. Then create a global pointer to the host object, parser(s), and to the drivers that you will be using.
In setup do ONE of the following: Then allocate the drivers:
Note that what happens in the parser should happen as quickly as possible. It is best to just do what you need to do on the parser "event". If you want to pass some kind of result back to loop(), you MUST use volatile objects and variables, you MUST also implement locking too, which is fine if you are advanced enough. Does this help you? |
See also README.md, which includes specific AVR information!!! |
Thanks, I hadn't noticed the instruction to redirect the interrupt signal (maybe it's the heat, lots of sunshine here these days). It worked with Mega2560. Thank you. |
"When all else fails, read the instructions." :-) |
Should it also work when using a HUB? The HID device works without the HUB. But the HUB is recognized. Is it possible to use HID and Pendrive with only one MAX3421E? |
hub right now is broken, needs work.
…On Tue, Nov 5, 2019 at 11:54 AM rtek1000 ***@***.***> wrote:
Should it also work when using a HUB? The HID device works without the
HUB. But the HUB is recognized. Is it possible to use HID and Pendrive with
only one MAX3421E?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#5?email_source=notifications&email_token=AA5SJTBZEE7KXZYVWAIW4CTQSGQLTA5CNFSM4BRZTSSKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEDDNRBI#issuecomment-549902469>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AA5SJTDHFT2XWMZXRTLKG2DQSGQLTANCNFSM4BRZTSSA>
.
--
Visit my github for awesome Arduino code @ https://github.com/xxxajk
|
Hi @xxxajk , To help monitor and control the state of keyboard LED's, I added these routines below, but it would be really nice to have GetReport() working, I tried to create this function, but did not work, the returned value is always 0x00.
UHS_HID_RAW.ino (modified): // Load the USB Host System core
#define LOAD_USB_HOST_SYSTEM
// Load USB Host Shield
#define LOAD_USB_HOST_SHIELD
// Use USB hub, you might want this for multiple devices.
#define LOAD_UHS_HUB
// Patch printf so we can use it.
#define LOAD_UHS_PRINTF_HELPER
#define DEBUG_PRINTF_EXTRA_HUGE 0
#define DEBUG_PRINTF_EXTRA_HUGE_USB_HID 1
#define LOAD_UHS_HID
#include <Arduino.h>
#ifdef true
#undef true
#endif
#ifdef false
#undef false
#endif
#include "UHS_host.h"
volatile bool NumLock = true;
volatile bool CapsLock = false;
volatile bool ScrollLock = false;
volatile uint8_t led_states = 0b1;
volatile uint8_t led_states_prev = 0;
uint8_t led_states_prev2 = 0;
UHS_HID_base *dev_kb0;
unsigned millis0;
class myHID_processor : public UHS_HID_PROCESSOR {
public:
myHID_processor(void) {}
void onRelease(UHS_HID_base *d) {
printf_P(PSTR("HID driver type %d no longer available.\r\n"), d->driver);
}
void onStart(UHS_HID_base *d) {
printf_P(PSTR("HID driver type %d started, Subclass %02x, Protocol %02x\r\n"), d->driver, d->parent->bSubClass, d->parent->bProtocol);
}
void onPoll(UHS_HID_base *d, uint8_t *data, uint16_t length) {
switch (d->driver) {
case UHS_HID_raw:
printf_P(PSTR("RAW input %d bytes interface %d, Subclass %02x, Protocol %02x Data:"), length, d->parent->bIface, d->parent->bSubClass, d->parent->bProtocol);
for (int i = 0; i < length; i++) {
printf_P(PSTR(" %02x"), data[i]);
}
if (d->parent->bProtocol == 1) {
dev_kb0 = d;
if ((length == 8) && (data[0] == 0) && (data[1] == 0) && (data[3] == 0) && (data[4] == 0) && (data[5] == 0) && (data[6] == 0) && (data[7] == 0)) {
if (data[2] == 0x53) {
if (NumLock == false) {
led_states |= 0b1;
NumLock = true;
} else {
led_states &= ~0b1;
NumLock = false;
}
} else if (data[2] == 0x39) {
if (CapsLock == false) {
led_states |= 0b10;
CapsLock = true;
} else {
led_states &= ~0b10;
CapsLock = false;
}
} else if (data[2] == 0x47) {
if (ScrollLock == false) {
led_states |= 0b100;
ScrollLock = true;
} else {
led_states &= ~0b100;
ScrollLock = false;
}
}
}
if (led_states_prev != led_states) {
led_states_prev = led_states;
uint8_t rv;
d->parent->pUsb->DisablePoll();
rv = d->parent->SetReport(d->parent->bIface, 2, 0, 1, &led_states);
d->parent->pUsb->EnablePoll();
}
printf_P(PSTR(" %02x"), led_states);
}
printf_P(PSTR("\r\n"));
break;
default:
break;
}
}
};
myHID_processor HID_processor1;
myHID_processor HID_processor2;
MAX3421E_HOST UHS_Usb;
UHS_USBHub hub_1(&UHS_Usb);
UHS_HID hid1(&UHS_Usb, &HID_processor1);
UHS_HID hid2(&UHS_Usb, &HID_processor2);
void setup() {
USB_HOST_SERIAL.begin(115200);
while (UHS_Usb.Init(1000) != 0)
;
printf_P(PSTR("\r\nHID RAW demo Begin.\r\n"));
}
void loop() {
if ((millis() - millis0) > 500) {
millis0 = millis();
if (dev_kb0->parent->bProtocol == 1) {
uint8_t rv;
dev_kb0->parent->pUsb->DisablePoll();
rv = dev_kb0->parent->SetReport(dev_kb0->parent->bIface, 2, 0, 1, &led_states);
dev_kb0->parent->pUsb->EnablePoll();
// uint8_t led_tmp;
// dev_kb0->parent->pUsb->DisablePoll();
// rv = dev_kb0->parent->GetReport(dev_kb0->parent->bIface, 2, 0, 1, &led_tmp);
// dev_kb0->parent->pUsb->EnablePoll();
//
// printf_P(PSTR("GetReport Data: %02x\r\n"), led_tmp);
}
}
delay(1);
}
/*
SerialEvent occurs whenever a new data comes in the hardware serial RX. This
routine is run between each time loop() runs, so using delay inside loop can
delay response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
if ((inChar >= '0') && (inChar <= '7')) {
led_states = (inChar - 48) & 0b111;
NumLock = led_states & 1;
CapsLock = (led_states >> 1) & 1;
ScrollLock = (led_states >> 2) & 1;
}
}
}
GetReport is basically SetReport and the value 0x01 instead of 0x09:
https://github.com/STMicroelectronics/stm32_mw_usb_host/blob/master/Class/HID/Inc/usbh_hid.h /**
* @brief USBH_HID_GetReport
* retrieve Set Report
* @param phost: Host handle
* @param reportType : Report type to be sent
* @param reportId : Targeted report ID for Set Report request
* @param reportBuff : Report Buffer
* @param reportLen : Length of data report to be send
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_HID_GetReport(USBH_HandleTypeDef *phost,
uint8_t reportType,
uint8_t reportId,
uint8_t *reportBuff,
uint8_t reportLen)
{
phost->Control.setup.b.bmRequestType = USB_D2H | USB_REQ_RECIPIENT_INTERFACE | \
USB_REQ_TYPE_CLASS;
phost->Control.setup.b.bRequest = USB_HID_GET_REPORT;
phost->Control.setup.b.wValue.w = (uint16_t)(((uint32_t)reportType << 8U) | (uint32_t)reportId);
phost->Control.setup.b.wIndex.w = 0U;
phost->Control.setup.b.wLength.w = reportLen;
return USBH_CtlReq(phost, reportBuff, (uint16_t)reportLen);
} /**
* @brief USBH_HID_Set_Report
* Issues Set Report
* @param phost: Host handle
* @param reportType : Report type to be sent
* @param reportId : Targeted report ID for Set Report request
* @param reportBuff : Report Buffer
* @param reportLen : Length of data report to be send
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_HID_SetReport(USBH_HandleTypeDef *phost,
uint8_t reportType,
uint8_t reportId,
uint8_t *reportBuff,
uint8_t reportLen)
{
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE | \
USB_REQ_TYPE_CLASS;
phost->Control.setup.b.bRequest = USB_HID_SET_REPORT;
phost->Control.setup.b.wValue.w = (uint16_t)(((uint32_t)reportType << 8U) | (uint32_t)reportId);
phost->Control.setup.b.wIndex.w = 0U;
phost->Control.setup.b.wLength.w = reportLen;
return USBH_CtlReq(phost, reportBuff, (uint16_t)reportLen);
} https://github.com/STMicroelectronics/stm32_mw_usb_host/blob/master/Class/HID/Src/usbh_hid.c uint8_t UHS_NI UHS_HID::SetReport(uint8_t iface, uint8_t report_type, uint8_t report_id, uint16_t nbytes, uint8_t* dataptr) {
uint8_t rv;
pUsb->DisablePoll();
rv = pUsb->ctrlReq(bAddress, mkSETUP_PKT8(0x21U, 0x09U, report_id, report_type, iface, nbytes), nbytes, dataptr);
pUsb->EnablePoll();
return rv;
}
uint8_t UHS_NI UHS_HID::GetReport(uint8_t iface, uint8_t report_type, uint8_t report_id, uint16_t nbytes, uint8_t* dataptr) {
uint8_t rv;
pUsb->DisablePoll();
rv = pUsb->ctrlReq(bAddress, mkSETUP_PKT8(0x21U, 0x01U, report_id, report_type, iface, nbytes), nbytes, dataptr);
pUsb->EnablePoll();
return rv;
} |
Still on AVR or something better? If on AVR, using ram expansion? |
This was tested on a UNO board and USB Host Shield (of this type) with no memory expansion.
|
UNO won't be able to do much because of limitations. The only AVRs I would recommend are the ones that can be RAM extended. You really need about 32K RAM just for this stack to do anything useful. More is better, of course. RAM extending AVR's include the ATMEGA 1280,2560,1286 and 2566, however it is less expensive to just use an MCU with the required amount of RAM, e.g. ARM or MIPS based MCUs. |
It would be interesting if UHS30 could work with STM32 or ESP32 maybe. I tried to make some adaptations but I still couldn't get it to compile in ESP32 or STM32. |
ESP32 isn't (currently) supported because of the RTOS. i.MX chip native EHCI should be supported, don't even need an extra USB shield! You can get that here: https://www.pjrc.com/store/teensy41.html MIPS native (Digilent boards) was started, but there was no interest, however it should be able to use the stack with the additional USB host shield. I have not tested it in a very long time, it required board-level modifications due to how they designed the board, and the boards are not offered any longer. :-( |
Interesting, why is it necessary to use RTOS on ESP32, if on Arduino UNO it is possible to compile without RTOS? Or is Arduino UNO using RTOS? These Teensy boards are very expensive. |
Espressif uses an RTOS because they are basically lazy (but that's my opinion). The Teensy boards might seem expensive, however, you should consider what you are getting... |
Yes, I saw that the board has good features, yet many people have been looking for cheaper boards like ESP32 or RP2040. Maybe in a next project I'll try to use Teensy, if that much resource is needed. I made a data logger with STM32 and since then I've been struggling with the USB port. But now, after years, I'm managing to get around the software and hardware limitations, today I would choose an NXP over STM. |
Hi, can you tell if the error control of packets received by the Arduino, are performed by IC MAX3421 (via hardware) or are performed by Arduino (via software)? I tested a gamepad with Arduino and it works fine, but in STM32 it is generating incorrect data, it seems to me to be a lack of error control of the packets. STM32 is using internal PHY and CubeMX libraries. I made a post on the ST forum, with more details: |
It looks like the error handling is done by IC MAX3421e, I found a PDF of application notes: |
Yeah, you need to process depending on the result of the transfer. |
Thank you for commenting on the Package vs Pipe, I added your comment there on the ST forum, maybe someone else might be interested in this UHS3 library. |
Please review the UHS_HID_interface struct.
Lets make sure it covers most of what we will need to pass onto a hid USB driver.
One thing at a time here too. We can add stuff later on for BT.
https://github.com/felis/UHS30/blob/master/libraries/UHS_HID/UHS_HID.h
The text was updated successfully, but these errors were encountered: