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);
我知道有很多关于状态打印机的问题...
我有一台 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);