2

I need to read the response from a control unit of a motor. After the write of a command beginning with ?, the motor unit should respond with some text. I.e. on ?MSG it should report its status. But when I try to read the status the unit sends nothing and the request ends with a timeout.

The code is pretty straightforward and uses libusb. The program detaches all active drivers from the device, attaches itself to the device, transfers the command ?MSG and waits for response. After that it detaches and ends.

Why there is no response? Is there any error in code or is it an issue of the motor unit? I am sure that commands are sent and received by the unit as the motor moves, for example, on PSET1=4000

#include <assert.h>
#include <string.h>

#define VENDOR_ID     0x0483
#define PRODUCT_ID    0x5740
#define BULK_EP_IN      0x03
#define BULK_EP_OUT     0x81 // From computer to control unit
#define INTERFACE_IN       0
#define INTERFACE_OUT      1

#define BUF_SIZE    64

int main()
{
    libusb_context *ctx;
    libusb_device_handle *dev_handle;
    int r = 0;
    int actual, length, received;
    char cmd[] = "?MSG\r\n";
    char buffer[BUF_SIZE];
    length = strlen(cmd);
    r = libusb_init(&ctx);
    assert(r == 0);

    /* Set verbosity level to 3, as suggested in the documentation */
    libusb_set_debug(ctx, 3);

    /* Get device handle */
    dev_handle = libusb_open_device_with_vid_pid(ctx, VENDOR_ID, PRODUCT_ID);
    assert(dev_handle != NULL);

    /* Find out if kernel driver is attached on IN iface */
    if(libusb_kernel_driver_active(dev_handle, INTERFACE_IN) == 1) {
        printf("Kernel Driver Active\n");
        assert(libusb_detach_kernel_driver(dev_handle, INTERFACE_IN) == 0);
        printf("Kernel Driver Detached!\n");
    }
    if(libusb_kernel_driver_active(dev_handle, INTERFACE_OUT) == 1) {
        printf("Kernel Driver Active\n");
        assert(libusb_detach_kernel_driver(dev_handle, INTERFACE_OUT) == 0);
        printf("Kernel Driver Detached!\n");
    }

    /* Claim IN interface of device */
    r = libusb_claim_interface(dev_handle, INTERFACE_IN);
    assert(r >= 0);
    /* claim OUT interface of device */
    r = libusb_claim_interface(dev_handle, INTERFACE_OUT);
    assert(r >= 0);


    /* Transfer commands */
    r = libusb_bulk_transfer(dev_handle, BULK_EP_IN, (unsigned char *)cmd, length, &actual, 0);
    assert(r == 0 && actual > 0 && actual == length);
    printf("Written %s\n",cmd);

    /* Now read response */
    if (cmd[0] == '?') {
        char buffer[BUF_SIZE] = "";
        int received = 0;
        do {
            int i;
            r = libusb_bulk_transfer(dev_handle, BULK_EP_OUT, (unsigned char *)buffer, BUF_SIZE, &received, 1000);
            if(r == LIBUSB_ERROR_TIMEOUT) {
                printf("Timeout\n");
            } else {
                assert(r == 0);
            }
            for(i = 0; i<BUF_SIZE;i++)
                printf("%c",buffer[i]);
        } while (received != 0);
    }

    /* Release devices */
    r = libusb_release_interface(dev_handle, INTERFACE_IN);
    assert(r == 0);
    r = libusb_release_interface(dev_handle, INTERFACE_OUT);
    assert(r == 0);

    /* Clean */
    libusb_close(dev_handle);
    libusb_exit(ctx);
}

Here is a description of the device with sudo lsusb --verbose in case it's important:

Bus 003 Device 003: ID 0483:5740 STMicroelectronics STM32F407
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            2 Communications
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x0483 STMicroelectronics
  idProduct          0x5740 STM32F407
  bcdDevice            1.00
  iManufacturer           1 STMicroelectronics
  iProduct                2 STR75x Virtual COM Port
  iSerial                 3 Demo 1.000
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           67
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0xc0
      Self Powered
    MaxPower                0mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         2 Communications
      bInterfaceSubClass      2 Abstract (modem)
      bInterfaceProtocol      1 AT-commands (v.25ter)
      iInterface              0
      CDC Header:
        bcdCDC               1.10
      CDC Call Management:
        bmCapabilities       0x00
        bDataInterface          1
      CDC ACM:
        bmCapabilities       0x02
          line coding and serial state
      CDC Union:
        bMasterInterface        0
        bSlaveInterface         1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval             255
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0 Unused
      bInterfaceProtocol      0
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x03  EP 3 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
Device Status:     0x0001
  Self Powered
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kostrahb
  • 709
  • 1
  • 9
  • 21
  • From a very cursory reading, it really seems you've swapped your `OUT` and `IN` endpoint references. They are always from the host's (PC's, i.e. your) point of view, so you should write to `OUT` and read from `IN`. – unwind Jan 12 '17 at 14:23
  • It's definitely not swapped. If I change the endpoints, the program freezes on the first call of `libusb_bulk_transfer()`. This way I'm at least able to send the commands. – Kostrahb Jan 20 '17 at 11:04

1 Answers1

0

You can communicate with the device by the RS-232 protocol, because it provides a virtual COM port which is a CDC ACM class. The kernel driver is cdc_acm.

  iManufacturer           1 STMicroelectronics
  iProduct                2 STR75x Virtual COM Port
  bInterfaceClass         2 Communications
  bInterfaceSubClass      2 Abstract (modem)
  bInterfaceProtocol      1 AT-commands (v.25ter)
  iInterface              0
  CDC Header:
    bcdCDC               1.10
  CDC Call Management:
    bmCapabilities       0x00
    bDataInterface          1
  CDC ACM:
    bmCapabilities       0x02
      line coding and serial state
  CDC Union:
    bMasterInterface        0
    bSlaveInterface         1

So you can communicate with the device by sending RS-232 commands to /dev/ttyACMx (or /dev/ttyUSBx) (replace x with the number on your system)

To check this you can use a terminal program like PuTTY,... 5 Linux / Unix Commands For Connecting To The Serial Console. You have to figure out the correct COM port settings (baud rate, parity, start/stop bits, etc.)

There are several RS-232 libraries, see C: cross-platform RS-232 serial library?

Check the dmesg output after plugin in the device to see which driver is used.

Community
  • 1
  • 1
ralf htp
  • 9,149
  • 4
  • 22
  • 34