arduino-libraries / Arduino_USBHostMbed5

Apache License 2.0
4 stars 10 forks source link

GIGA R1: PL2303 USB Serial Adapter - faulting in USBDeviceConnected::getEndpoint #34

Closed KurtE closed 11 months ago

KurtE commented 11 months ago

Like #32. There is a lot more information in the forum posts: https://forum.arduino.cc/t/can-not-find-examples-for-usbhostserial/1182486/18?u=kurte

I am trying to get some USB to Serial adapters to work, that are not the CDC ACM devices (would like to get those to work as well).

So I started hacking up my own object. Currently doing it all within an Arduino sketch, where I have the .cpp and .h for the new object contained within the sketch.

In this case the device is a GPS unit has an PL2303 chipset in it:

My connect code:

bool USBHostFTDI::connect() {
  USB_INFO(" USBHostFTDI::connect() called\r\n");
  if (dev) {
    for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
      USBDeviceConnected* d = host->getDevice(i);
      if (dev == d)
        return true;
    }
    disconnect();
  }
  host = USBHost::getHostInst();
  for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
    USBDeviceConnected* d = host->getDevice(i);
    USB_DBG("\tDev: %p\r\n", d);
    if (d != NULL) {
      USB_INFO("Device:%p\r\n", d);
      if (host->enumerate(d, this) != USB_TYPE_OK) {
        USB_INFO("Enumerate returned status not OK");
        continue;  //break;  what if multiple devices?
      }

      printf("\tconnect hser_device_found\n\r");

      bulk_in = d->getEndpoint(intf_SerialDevice, BULK_ENDPOINT, IN);
      USB_INFO("bulk in:%p", bulk_in);

      bulk_out = d->getEndpoint(intf_SerialDevice, BULK_ENDPOINT, OUT);
      USB_INFO(" out:%p\r\n", bulk_out);

      printf("\tAfter get end points\n\r");
      if (bulk_in && bulk_out) {
        dev = d;
        dev_connected = true;
        //        USB_INFO("New hser device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, intf_SerialDevice);
        printf("New hser device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, intf_SerialDevice);
        dev->setName("Serial", intf_SerialDevice);
        host->registerDriver(dev, intf_SerialDevice, this, &USBHostFTDI::init);
        size_bulk_in = bulk_in->getSize();
        size_bulk_out = bulk_out->getSize();

        bulk_in->attach(this, &USBHostFTDI::rxHandler);
        bulk_out->attach(this, &USBHostFTDI::txHandler);
        host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
        printf("\n\r>>>>>>>>>>>>>> connected returning true <<<<<<<<<<<<<<<<<<<<\n\r");
        return true;
      }
    }
  }
  init();
  return false;
}

It is faulting on the call: bulk_in = d->getEndpoint(intf_SerialDevice, BULK_ENDPOINT, IN); Note: the useEndpoints code could be simplified:

/*virtual*/ bool USBHostFTDI::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir)  //Must return true if the endpoint will be used
{
  USB_INFO("USBHostFTDI::useEndpoint(%u, %u, %u\n\r", intf_nb, type, dir);
  printf("USBHostFTDI::useEndpoint(%u, %u, %u\n\r", intf_nb, type, dir);
  if (intf_nb == intf_SerialDevice) {
    //if (type == INTERRUPT_ENDPOINT && dir == IN) return true; // see if we can ignore it later

    if (type == BULK_ENDPOINT && dir == IN) {
      hser_device_found = true;
      return true;
    }
    if (type == BULK_ENDPOINT && dir == OUT) {
      hser_device_found = true;
      return true;
    }
  }
  return false;
}

Note: these devices as well as some other USB to Serial adapters, the interface has 3 endpoints, The first one typically being an Interrupt IN, which, I am saying NO to use. the second and third endpoints are BULK OUT and BULK IN which I am trying to use. This should work as it is how the devices are handled in some other code bases.

Here is debug output for a run I just did, which is now in the blinking red lights cycle...

Starting hser test...
[USB_INFO: C:\Users\kurte\Documents\Arduino\Arduino_GIGA\USBHost_FTDI_plus\USBHostFTDI.cpp:70] USBHostFTDI::connect() called

[USB_DBG: C:\Users\kurte\Documents\Arduino\Arduino_GIGA\USBHost_FTDI_plus\USBHostFTDI.cpp:82]   Dev: 0x2400c77c

[USB_INFO: C:\Users\kurte\Documents\Arduino\Arduino_GIGA\USBHost_FTDI_plus\USBHostFTDI.cpp:84]Device:0x2400c77c

[USB_DBG: c:\Users\kurte\Documents\Arduino\libraries\Arduino_USBHostMbed5\src\USBHost\USBHost.cpp:932]Enumerate dev: 0x2400c77c index: 0
[USB_DBG: c:\Users\kurte\Documents\Arduino\libraries\Arduino_USBHostMbed5\src\USBHost\USBHost.cpp:938]dev: 0x2400c77c nb_intf: 0
[USB_DBG: c:\Users\kurte\Documents\Arduino\libraries\Arduino_USBHostMbed5\src\USBHost\USBHost.cpp:939]dev: 0x2400c77c nb_intf_attached: 0
[USB_DBG: c:\Users\kurte\Documents\Arduino\libraries\Arduino_USBHostMbed5\src\USBHost\USBHost.cpp:945]Enumerate dev: 0x2400c77c
[USB_DBG: c:\Users\kurte\Documents\Arduino\libraries\Arduino_USBHostMbed5\src\USBHost\USBHost.cpp:957]DEVICE DESCRIPTOR(18):

12 01 10 01 00 00 00 40 7B 06 03 23 00 04 01 02 00 01 

[USB_DBG: c:\Users\kurte\Documents\Arduino\libraries\Arduino_USBHostMbed5\src\USBHost\USBHost.cpp:969]CLASS: 00      VID: 067B   PID: 2303
[USB_INFO: C:\Users\kurte\Documents\Arduino\Arduino_GIGA\USBHost_FTDI_plus\USBHostFTDI.cpp:142]VID: 67B, PID: 2303

VID: 67B, PID: 2303 PL2303

[USB_DBG: c:\Users\kurte\Documents\Arduino\libraries\Arduino_USBHostMbed5\src\USBHost\USBHost.cpp:876]TOTAL_LENGTH: 39   NUM_INTERF: 1
[USB_DBG: c:\Users\kurte\Documents\Arduino\libraries\Arduino_USBHostMbed5\src\USBHost\USBHost.cpp:979]CONFIGURATION DESCRIPTOR:

09 02 27 00 01 01 00 80 32 09 04 00 00 03 FF 00 00 00 07 05 81 03 0A 00 01 07 05 02 02 40 00 00 07 05 83 02 40 00 00 

[USB_DBG: c:\Users\kurte\Documents\Arduino\libraries\Arduino_USBHostMbed5\src\USBHost\USBHost.cpp:1031]dev: 0x2400c77c has 1 intf
[USB_INFO: C:\Users\kurte\Documents\Arduino\Arduino_GIGA\USBHost_FTDI_plus\USBHostFTDI.cpp:165]USBHostFTDI::parseInterface nb:0, cl:255 isub:0 iprot:0

USBHostFTDI::parseInterface nb:0, cl:255 isub:0 iprot:0

[USB_DBG: c:\Users\kurte\Documents\Arduino\libraries\Arduino_USBHostMbed5\src\USBHost\USBHost.cpp:1040]ADD INTF 0 on device 0x2400c77c: class: 255, subclass: 0, proto: 0
[USB_INFO: C:\Users\kurte\Documents\Arduino\Arduino_GIGA\USBHost_FTDI_plus\USBHostFTDI.cpp:176]USBHostFTDI::useEndpoint(0, 3, 2

USBHostFTDI::useEndpoint(0, 3, 2

[USB_INFO: C:\Users\kurte\Documents\Arduino\Arduino_GIGA\USBHost_FTDI_plus\USBHostFTDI.cpp:176]USBHostFTDI::useEndpoint(0, 2, 1

USBHostFTDI::useEndpoint(0, 2, 1

[USB_DBG: c:\Users\kurte\Documents\Arduino\libraries\Arduino_USBHostMbed5\src\USBHost\USBHost.cpp:610]USBEndpoint created (0x2400c16c): type: 2, dir: 1, size: 64, addr: 2, state: USB_TYPE_IDLE
[USB_DBG: c:\Users\kurte\Documents\Arduino\libraries\Arduino_USBHostMbed5\src\USBHost\USBHost.cpp:1059]ADD USBEndpoint 0x2400c16c, on interf 0 on device 0x2400c77c
[USB_INFO: C:\Users\kurte\Documents\Arduino\Arduino_GIGA\USBHost_FTDI_plus\USBHostFTDI.cpp:176]USBHostFTDI::useEndpoint(0, 2, 2

USBHostFTDI::useEndpoint(0, 2, 2

[USB_DBG: c:\Users\kurte\Documents\Arduino\libraries\Arduino_USBHostMbed5\src\USBHost\USBHost.cpp:610]USBEndpoint created (0x2400c204): type: 2, dir: 2, size: 64, addr: 3, state: USB_TYPE_IDLE
[USB_DBG: c:\Users\kurte\Documents\Arduino\libraries\Arduino_USBHostMbed5\src\USBHost\USBHost.cpp:1059]ADD USBEndpoint 0x2400c204, on interf 0 on device 0x2400c77c
[USB_DBG: c:\Users\kurte\Documents\Arduino\libraries\Arduino_USBHostMbed5\src\USBHost\USBHost.cpp:992]Set configuration 1 on dev: 0x2400c77c
[USB_DBG: c:\Users\kurte\Documents\Arduino\libraries\Arduino_USBHostMbed5\src\USBHost\USBHost.cpp:1005]dev 0x2400c77c is enumerated

    connect hser_device_found

[USB_DBG: c:\Users\kurte\Documents\Arduino\libraries\Arduino_USBHostMbed5\src\USBHost\USBDeviceConnected.cpp:104]getEndpoint(0 2 2 0 0x2
[USB_DBG: c:\Users\kurte\Documents\Arduino\libraries\Arduino_USBHostMbed5\src\USBHost\USBDeviceConnected.cpp:109]index: 0 0xffff

Note the last two debug lines are from some debug information I added to the library code:

USBEndpoint * USBDeviceConnected::getEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint8_t index) {
    USB_DBG("getEndpoint(%u %u %u %u %p", intf_nb, type, dir, index);
    if (intf_nb >= MAX_INTF) {
        return NULL;
    }
    for (int i = 0; i < MAX_ENDPOINT_PER_INTERFACE; i++) {
        USB_DBG("index: %d %p", i, intf[intf_nb].ep[i]);
        if ( intf[intf_nb].ep[i] == nullptr) continue; // don't walk through NULL
        if ((intf[intf_nb].ep[i]->getType() == type) && (intf[intf_nb].ep[i]->getDir() == dir)) {
            if(index) {
                index--;
            } else {
                return intf[intf_nb].ep[i];
            }
        }
    }
    return NULL;
}

My first guess was the: intf[intf_nb].ep[i] value was probably going to be NULL, so I added test for it, which did not help.
Looks like the value is: 0xffff Which then trying to use that as an object pointer faulted. Not sure if that has special meaning here? Or the code is not handling the case where there are more end points than the library is configured to allow per interface? or?

KurtE commented 11 months ago

Looks like a problem that some test code I added caused...