felis / USB_Host_Shield_2.0

Revision 2.0 of USB Host Library for Arduino.
https://chome.nerpa.tech
1.8k stars 779 forks source link

Reset required on arduino in order to load device driver for newly attached device #452

Open Vamshi253 opened 5 years ago

Vamshi253 commented 5 years ago

The state of MAX3421E is not changing when I insert a different USB device. Currently , I am using the soft reset function on arduino such that whenever a device descriptor parameter is changed, reset function is executed and arduino loads the specific driver for the newly attached device.

But now I need to implement multitasking phenomena on arduino so that I can't use reset function any more.

Can any one of you please suggest me a hint on how to achieve this without using reset function?

Thank You.

Vamshi253 commented 5 years ago

Hi Guys,

What I have observed is whenever there is a usb device insertion or removal, the "usb_task_state" parameter is changing (value 0 for no usb device and 144 for any usb device), but the device descriptor parameter is not changing.

Ryzee119 commented 5 years ago

Could try adding Usb.busprobe() to the main loop

Vamshi253 commented 5 years ago

Hi Ryzee,

Thank you, I added it. But still it's not working. Do you have any idea of how descriptor parameters are related to usb_task_state?

Ryzee119 commented 5 years ago

I may be wrong here, but usb_task_state tracks the state machine for device enumeration/cleanup. The USB device descriptor is gathered when task state= USB_STATE_CONFIGURING, (0x80)

Vamshi253 commented 5 years ago

Update:

What I have found is, in "uint8_t MAX3421e< SPI_SS, INTR >::Task(void)" function of usbhost.h file the variable "pinvalue" is not updating during the usb device removal.

Vamshi253 commented 5 years ago

-PIN- register status is not changing (corresponding to the interrupt signal generation whenever USB device is attached or removed). In my case, it's Arduino Mega ADK. The pin PE6 has used for interrupt based services. There must be either no interrupt signal whenever the usb device is removed or might be hardware related problem. I am not sure of this.

jwyse commented 4 years ago

I think I'm seeing the same issue. I'm testing with an ESP32 devkit, using the pin connections listed in the README. I have to (re)boot the microcontroller with the USB device connected in order to get anything to work. Plugging in the USB device after initial boot, or unplugging+plugging after the initial boot will not detect the device.

The following code works, as an inelegant brute-force workaround. When in the detached/waiting for device state, I'm calling Usb.Init() every 3 seconds.

Aside: How often is too often to call Usb.Init()? I'm still trying to read and understand the underlying code; on the surface, it appears that Init() just resets one variable, but surely it does more than that?

uint64_t nextinit = 0;

loop() {
  Usb.Task();
  if (Usb.getUsbTaskState() == USB_STATE_RUNNING) {
    // Great! Do some stuff.
  }
  else {

    // Call Usb.Init() every 3 seconds while waiting for a device
    if (Usb.getUsbTaskState() == USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE
        && millis() >= nextInit)
    {
      Usb.Init();
      nextInit = millis() + 3000;
    }

  }
}
HungYn commented 4 years ago

include //USB Keyboard

include //Mini USB Host

include

String Barcode; //條碼字串變數 uint16_t nextInit = 0;

class KbdRptParser : public KeyboardReportParser //定義一個類別叫KbdRptParser 設定public區域和 KeyboardReportParser 成員 { protected: //繼承類別准許存取protected成員→OnKeyDown void OnKeyDown (uint8_t mod, uint8_t key); };

void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key) { uint8_t c = OemToAscii(mod, key); // if (c) Barcode = Barcode + (char) c; // Serial.println(Barcode.length()); if (c == 19) { //一般條碼機最後會送出Enter for (byte i = 0; i < Barcode.length() - 1; i++) { //Enter不要算進去所以減一 Serial.print(Barcode[i]); } Serial.println(); Barcode = ""; } }

USB Usb; //USBHub Hub(&Usb); HIDBoot HidKeyboard(&Usb);

KbdRptParser Prs;

void setup() { Serial.begin( 115200 );

if !defined(MIPSEL)

while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection

endif

Serial.println("Start"); if (Usb.Init() == -1) Serial.println("OSC did not start."); delay( 200 ); HidKeyboard.SetReportParser(0, &Prs); }

void loop() { Usb.Task(); if (Usb.getUsbTaskState() == USB_STATE_RUNNING) {

} else {

//等待設備時每3秒調用一次Usb.Init()
if (Usb.getUsbTaskState() == USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE && millis() >= nextInit)
{
  Usb.Init();
  nextInit = millis() + 3000;
  Serial.println("等待設備連接");
}

} }