linux ARM 上带有 libusb 的状态热敏打印机

Status thermal printer with libusb on linux ARM

我知道有很多关于状态打印机的问题...

我有一台 Citizen CT-S310 II,我已经管理了 USB 中写入字符的所有代码,libusb_bulk_transfer(文本、粗体、居中、CR、CUT_PAPER 等)没有问题:

#define ENDPOINT_OUT    0x02
#define ENDPOINT_IN     0x81

struct libusb_device_handle *_handle;

[detach kernel driver...]
[claim interface...]
[etc ...]

r = libusb_bulk_transfer(device_handle, ENDPOINT_OUT, Mydata, out_len, &transferred, 1000);

现在,我需要从打印机接收数据以检查状态,我的第一个想法是使用与文档相同的 "bulk_transfer" 发送 POS 命令:

1D (hexa) 72 (hexa) n n => 1(发送纸张传感器状态)

并通过 "bulk_transfer" 检索值,终点 "ENDPOINT_IN" 文档说有 8 个字节要接收:

bit 0,1 => paper found by paper near-end sensor 00H
bit 0,1 => paper not found by paper near-end sensor 03H
bit 1,2 => paper found by paper-end sensor 00H
bit 1,2 => paper not found by paper-end sensor 0CH
[...]

所以两个 "bulk_transfer",一个用于发送命令状态 (ENDPOINT_OUT),一个用于接收结果 (ENDPOINT_IN),但我总是遇到 USB 错误 ("bulk_transfer" 阅读 = -1)

也许 USB 不是这样工作的?所以我的第二个想法是使用命令 "control_transfer" :

在 PrinterClass USB 中实现的功能
int r = 0;
    int out_len = 1;
    unsigned char* _udata = NULL;

    uint8_t bmRequestType = LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE;
    uint8_t bRequest = LIBUSB_REQUEST_GET_STATUS;
    uint16_t wValue = 0; // the value field for the setup packet (?????)
    uint16_t wIndex = 0; // N° interface printer (the index field for the setup packet)

    r = libusb_control_transfer(device_handle, bmRequestType,bRequest,wValue, wIndex,_udata,out_len, USB_TIMEOUT);

我不知道如何填写所有参数,我知道这取决于我的设备,但 libsub 的文档不是很明确。

"wValue" 到底是什么?

"wIndex" 到底是什么?接口号??

参数 LIBUSB_ENDPOINT_IN 默认为 0x80,但我的打印机使用 0x81,我必须更改此默认端点吗?

Bus 001 Device 004: ID 1d90:2060
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x1d90
  idProduct          0x2060
  bcdDevice            0.02
  iManufacturer           1 CITIZEN
  iProduct                2 Thermal Printer
  iSerial                 3 00000000
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           32
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0xc0
      Self Powered
    MaxPower                0mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         7 Printer
      bInterfaceSubClass      1 Printer
      bInterfaceProtocol      2 Bidirectional
      iInterface              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
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
Device Status:     0x0001
  Self Powered

在我的例子中,"control_transfer" 的响应总是 0 :( 用纸或 without.How 发送一个好的 "control_transfer" 请求我的打印机状态 ??

欢迎大家帮助解决我的问题!!!

终于解决了!

LIBUSB_REQUEST_GET_STATUS 的值为 0x00,但对于打印机,请求状态为 0x01。

使用 libusb-1.0 检查打印机状态:

uint8_t bmRequestType = LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE;
    uint8_t bRequest = 0x01; // Here not LIBUSB_REQUEST_GET_STATUS
    uint16_t wValue = 0;
    uint16_t wIndex = 0;

    r = libusb_control_transfer(device_handle, bmRequestType,bRequest,wValue, wIndex,&_udata,out_len, USB_TIMEOUT);