Implement HID for Windows.
This commit is contained in:
parent
2658ffff80
commit
f6dd16d0c2
@ -6,7 +6,7 @@ CFLAGS = -g -O -Wall -Werror -DVERSION='"$(VERSION).$(GITCOUNT)"'
|
|||||||
LDFLAGS = -g -s
|
LDFLAGS = -g -s
|
||||||
|
|
||||||
OBJS = main.o util.o radio.o dfu-windows.o uv380.o md380.o rd5r.o hid-windows.o
|
OBJS = main.o util.o radio.o dfu-windows.o uv380.o md380.o rd5r.o hid-windows.o
|
||||||
LIBS = -lsetupapi
|
LIBS = -lhid -lsetupapi
|
||||||
|
|
||||||
# Compiling Windows binary from Linux
|
# Compiling Windows binary from Linux
|
||||||
ifeq (/usr/bin/i586-mingw32msvc-gcc,$(wildcard /usr/bin/i586-mingw32msvc-gcc))
|
ifeq (/usr/bin/i586-mingw32msvc-gcc,$(wildcard /usr/bin/i586-mingw32msvc-gcc))
|
||||||
|
@ -399,8 +399,10 @@ const char *dfu_init(unsigned vid, unsigned pid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!path) {
|
if (!path) {
|
||||||
fprintf(stderr, "Cannot find USB device %04x:%04x\n", vid, pid);
|
if (trace_flag) {
|
||||||
exit(-1);
|
fprintf(stderr, "Cannot find DFU device %04x:%04x\n", vid, pid);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open the device.
|
// Open the device.
|
||||||
|
@ -98,10 +98,10 @@ static int write_read(const unsigned char *data, unsigned length, unsigned char
|
|||||||
if (! transfer) {
|
if (! transfer) {
|
||||||
// Allocate transfer descriptor on first invocation.
|
// Allocate transfer descriptor on first invocation.
|
||||||
transfer = libusb_alloc_transfer(0);
|
transfer = libusb_alloc_transfer(0);
|
||||||
|
}
|
||||||
libusb_fill_interrupt_transfer(transfer, dev,
|
libusb_fill_interrupt_transfer(transfer, dev,
|
||||||
LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN,
|
LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN,
|
||||||
reply, rlength, read_callback, 0, TIMEOUT_MSEC);
|
reply, rlength, read_callback, 0, TIMEOUT_MSEC);
|
||||||
}
|
|
||||||
again:
|
again:
|
||||||
nbytes_received = 0;
|
nbytes_received = 0;
|
||||||
libusb_submit_transfer(transfer);
|
libusb_submit_transfer(transfer);
|
||||||
|
109
hid-windows.c
109
hid-windows.c
@ -25,6 +25,9 @@
|
|||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
#include <windows.h>
|
||||||
|
#include <setupapi.h>
|
||||||
|
#include <hidsdi.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -42,8 +45,8 @@ static const unsigned char CMD_ENDW[] = "ENDW";
|
|||||||
static const unsigned char CMD_CWB0[] = "CWB\4\0\0\0\0";
|
static const unsigned char CMD_CWB0[] = "CWB\4\0\0\0\0";
|
||||||
static const unsigned char CMD_CWB1[] = "CWB\4\0\1\0\0";
|
static const unsigned char CMD_CWB1[] = "CWB\4\0\1\0\0";
|
||||||
|
|
||||||
|
HANDLE dev = INVALID_HANDLE_VALUE;; // HID device
|
||||||
static unsigned char receive_buf[42]; // receive buffer
|
static unsigned char receive_buf[42]; // receive buffer
|
||||||
static volatile int nbytes_received = 0; // receive result
|
|
||||||
static unsigned offset = 0; // CWD offset
|
static unsigned offset = 0; // CWD offset
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -55,6 +58,7 @@ void hid_send_recv(const unsigned char *data, unsigned nbytes, unsigned char *rd
|
|||||||
{
|
{
|
||||||
unsigned char buf[42];
|
unsigned char buf[42];
|
||||||
unsigned k;
|
unsigned k;
|
||||||
|
DWORD nbytes_received;
|
||||||
|
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
buf[0] = 1;
|
buf[0] = 1;
|
||||||
@ -76,30 +80,22 @@ void hid_send_recv(const unsigned char *data, unsigned nbytes, unsigned char *rd
|
|||||||
}
|
}
|
||||||
nbytes_received = 0;
|
nbytes_received = 0;
|
||||||
memset(receive_buf, 0, sizeof(receive_buf));
|
memset(receive_buf, 0, sizeof(receive_buf));
|
||||||
#if 0
|
|
||||||
//TODO
|
|
||||||
// Write to HID device.
|
// Write to HID device.
|
||||||
IOReturn result = IOHIDDeviceSetReport(dev, kIOHIDReportTypeOutput, 0, buf, sizeof(buf));
|
if (!WriteFile(dev, buf, sizeof(buf), NULL, NULL)) {
|
||||||
if (result != kIOReturnSuccess) {
|
fprintf(stderr, "Error %#lx sending to HID device!\n", GetLastError());
|
||||||
fprintf(stderr, "HID output error: %d!\n", result);
|
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run main application loop until reply received.
|
// Receive reply.
|
||||||
for (k=0; ; k++) {
|
if (!ReadFile(dev, receive_buf, sizeof(receive_buf), &nbytes_received, NULL)) {
|
||||||
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, 0);
|
fprintf(stderr, "Error %#lx receiving from HID device!\n", GetLastError());
|
||||||
if (nbytes_received > 0)
|
|
||||||
break;
|
|
||||||
if (k >= 5) {
|
|
||||||
fprintf(stderr, "HID device stopped responding!\n");
|
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
usleep(10000);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (nbytes_received != sizeof(receive_buf)) {
|
if (nbytes_received != sizeof(receive_buf)) {
|
||||||
fprintf(stderr, "Short read: %d bytes instead of %d!\n",
|
fprintf(stderr, "Short read: %u bytes instead of %u!\n",
|
||||||
nbytes_received, (int)sizeof(receive_buf));
|
(unsigned)nbytes_received, (unsigned)sizeof(receive_buf));
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
if (trace_flag > 0) {
|
if (trace_flag > 0) {
|
||||||
@ -124,15 +120,81 @@ void hid_send_recv(const unsigned char *data, unsigned nbytes, unsigned char *rd
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Launch the IOHIDManager.
|
// Find a HID device with given GUID, vendor ID and product ID.
|
||||||
|
// Return an opened file descriptor.
|
||||||
|
//
|
||||||
|
HANDLE find_hid_device(int vid, int pid)
|
||||||
|
{
|
||||||
|
static GUID guid = { 0x4d1e55b2, 0xf16f, 0x11cf, { 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };
|
||||||
|
HANDLE h = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
|
HDEVINFO devinfo = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
|
||||||
|
if (devinfo == INVALID_HANDLE_VALUE) {
|
||||||
|
printf("Cannot get devinfo!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through available devices with a given GUID.
|
||||||
|
int index;
|
||||||
|
SP_INTERFACE_DEVICE_DATA iface;
|
||||||
|
iface.cbSize = sizeof(iface);
|
||||||
|
for (index=0; SetupDiEnumDeviceInterfaces(devinfo, NULL, &guid, index, &iface); ++index) {
|
||||||
|
|
||||||
|
// Obtain a required size of device detail structure.
|
||||||
|
DWORD needed;
|
||||||
|
SetupDiGetDeviceInterfaceDetail(devinfo, &iface, NULL, 0, &needed, NULL);
|
||||||
|
|
||||||
|
// Allocate the device detail structure.
|
||||||
|
PSP_INTERFACE_DEVICE_DETAIL_DATA detail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)alloca(needed);
|
||||||
|
detail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
|
||||||
|
SP_DEVINFO_DATA did = { sizeof(SP_DEVINFO_DATA) };
|
||||||
|
|
||||||
|
// Get device information.
|
||||||
|
if (!SetupDiGetDeviceInterfaceDetail(devinfo, &iface, detail, needed, NULL, &did)) {
|
||||||
|
printf("Device %d: cannot get path!\n", index);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf("Device %d: path %s\n", index, detail->DevicePath);
|
||||||
|
|
||||||
|
h = CreateFile(detail->DevicePath, GENERIC_WRITE | GENERIC_READ,
|
||||||
|
0, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
if (h == INVALID_HANDLE_VALUE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the Vendor ID and Product ID for this device.
|
||||||
|
HIDD_ATTRIBUTES attrib;
|
||||||
|
attrib.Size = sizeof(HIDD_ATTRIBUTES);
|
||||||
|
HidD_GetAttributes(h, &attrib);
|
||||||
|
printf("Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID);
|
||||||
|
|
||||||
|
// Check the VID/PID.
|
||||||
|
if (attrib.VendorID != vid || attrib.ProductID != pid) {
|
||||||
|
CloseHandle(h);
|
||||||
|
h = INVALID_HANDLE_VALUE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required device found.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SetupDiDestroyDeviceInfoList(devinfo);
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Open the radio in programming mode.
|
||||||
//
|
//
|
||||||
const char *hid_init(int vid, int pid)
|
const char *hid_init(int vid, int pid)
|
||||||
{
|
{
|
||||||
//TODO
|
// Find HID device.
|
||||||
|
dev = find_hid_device(vid, pid);
|
||||||
|
if (dev == INVALID_HANDLE_VALUE) {
|
||||||
if (trace_flag) {
|
if (trace_flag) {
|
||||||
fprintf(stderr, "Cannot find USB device %04x:%04x\n", vid, pid);
|
fprintf(stderr, "Cannot find HID device %04x:%04x\n", vid, pid);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned char reply[38];
|
static unsigned char reply[38];
|
||||||
unsigned char ack;
|
unsigned char ack;
|
||||||
@ -169,7 +231,10 @@ const char *hid_init(int vid, int pid)
|
|||||||
//
|
//
|
||||||
void hid_close()
|
void hid_close()
|
||||||
{
|
{
|
||||||
//TODO
|
if (dev != INVALID_HANDLE_VALUE) {
|
||||||
|
CloseHandle(dev);
|
||||||
|
dev = INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hid_read_block(int bno, uint8_t *data, int nbytes)
|
void hid_read_block(int bno, uint8_t *data, int nbytes)
|
||||||
|
Loading…
Reference in New Issue
Block a user