OK, so I got this working on XP. User error I am afraid, slight wiring error. So the next step in my development is to get this working in Linux. You mention in the description that libusb would be the way to go. By the way I am using the PIC18F2550 which I understand is a direct replacement for the 4550.
So I plug in the board and it is recognised by the OS:
Code:
pete@box1:~$ lsusb
Bus 003 Device 045: ID 04d8:0042 Microchip Technology, Inc.
and dmesg
Code:
pete@box1:~ dmesg
[291909.390015] usb 3-1: new full speed USB device using uhci_hcd and address 45
[291909.585099] usb 3-1: configuration #1 chosen from 1 choice
[291909.588017] usbip 3-1:1.0: this device 3-1 is not in match_busid table. skip!
[291909.592086] generic-usb 0003:04D8:0042.000E: hiddev96,hidraw1: USB HID v1.11 Device [Microchip Technology Inc. WFF Generic HID demo] on usb-0000:00:1a.0-1/input0
All good so far
So the next step, actualy communicating with the board. I found a libusb based c code to test this out.
Code:
#include <stdio.h>
#include <usb.h>
#include <string.h>
#include <usb.h>
#include <assert.h>
#include <math.h>
#define VID 0x04d8
#define PID 0x0042
#define STR_BUFF 256
#define ERROR -1
#define USB_TIMEOUT 20
#define PACKET_LEN 8
#define CMD_RESET 0x00
#define MAX_DEV 4
#define USB_OUT_EP 0x01 /* USB output endpoint */
#define USB_INP_EP 0x81 /* USB Input endpoint */
/* set debug to 0 to not print excess info */
int DEBUG = 1;
long BoardAddress = 0;
/* globals for datatransfer */
struct My_dev {
unsigned char data_in[PACKET_LEN+1];
unsigned char data_out[PACKET_LEN+1];
struct usb_dev_handle *device_handle;
int DevNo;
};
static struct My_dev F2550[MAX_DEV];
static struct My_dev *CurrDev;
/*functions*/
static int takeover_device(usb_dev_handle * udev, int interface);
static int WriteData(unsigned char cmd);
static int ReadData(void);
long SetCurrentDevice(long deviceno);
/* Keep these globals for now */
unsigned char *data_in, *data_out;
int main(void)
{
struct usb_bus *bus;
struct usb_device *dev;
struct usb_dev_handle *udev;
//static struct usb_device *dev;
//struct usb_dev_handle *device_handle;
int i;
i = 0;
usb_init();
usb_find_busses();
usb_find_devices();
/*
for (bus = busses; bus; bus = bus->next)
{
for (dev = bus->devices; dev; dev = dev->next)
{
if ((dev->descriptor.idVendor == VID) &&
(dev->descriptor.idProduct == ipid))
{
CurrDev = &F2550[BoardAddress];
CurrDev->device_handle = usb_open(dev);
if (DEBUG)
*/
printf("Detection of the board :\n\r");
for (bus = usb_busses; bus; bus = bus->next)
{
for (dev = bus->devices; dev; dev = dev->next)
{
if ((dev->descriptor.idVendor == VID) && (dev->descriptor.idProduct == PID))
{
printf("Board is found\n\r");
CurrDev = &F2550[BoardAddress];
CurrDev->device_handle = usb_open(dev);
udev = usb_open(dev);
if (takeover_device(CurrDev->device_handle, 0) < 0)
{
fprintf(stderr,
"Can not take over the device from the OS driver\n");
usb_close(CurrDev->device_handle); /* close usb if we fail */
return ERROR; /* throw ERROR to show that OpenDevice failed */
}
CurrDev->DevNo = BoardAddress + 1; /* Mark as open and valid */
SetCurrentDevice(BoardAddress);
unsigned char buffer[8];
memset(CurrDev->data_out,0,PACKET_LEN); /* Write cmd 0, read data */
WriteData(CMD_RESET);
if (ReadData() == 0)
return BoardAddress; /* This function should return board address */
else
return ERROR;
usb_bulk_write(CurrDev->device_handle, 1, "N", 1, 1000);
usb_close(CurrDev->device_handle);
// }
}
}
}
}
/* If device is owned by some kernel driver, try to disconnect it and claim the device*/
static int takeover_device(usb_dev_handle * udev, int interface)
{
char driver_name[STR_BUFF];
memset(driver_name, 0, STR_BUFF);
int ret = ERROR;
assert(udev != NULL);
ret = usb_get_driver_np(udev, interface, driver_name, sizeof(driver_name));
//if(DEBUG) printf("ret = %d\n",ret);
if (ret == 0)
{
if (DEBUG)
fprintf(stderr, "Got driver name: %s\n", driver_name);
if (0 > usb_detach_kernel_driver_np(udev, interface))
{
if (DEBUG)
fprintf(stderr, "Disconnect OS driver: %s\n", usb_strerror());
}
else if (DEBUG)
fprintf(stderr, "Disconnected OS driver: %s\n", usb_strerror());
}
else if (DEBUG)
fprintf(stderr, "Get driver name: - %s\n", usb_strerror());
/* claim interface */
if (usb_claim_interface(udev, interface) < 0)
{
if (DEBUG)
fprintf(stderr, "Claim interface error: %s\n", usb_strerror());
return ERROR;
}
else
usb_set_altinterface(udev, interface);
usb_set_configuration(udev, 1);
if (DEBUG)
{
fprintf(stderr, "Found interface %d\n", interface);
fprintf(stderr, "Took over the device\n");
}
return 0;
}
/* Actual write of data to the device endpont, retry 3 times if not reponding correctly */
static int WriteData(unsigned char cmd)
{
int write_status = 0, i = 0;
if (CurrDev->DevNo == 0) return ERROR;
CurrDev->data_out[0] = cmd;
for(i=0; i < 3; i++)
{
write_status = usb_interrupt_write(CurrDev->device_handle, USB_OUT_EP, (char *)CurrDev->data_out, PACKET_LEN, USB_TIMEOUT);
if (write_status == PACKET_LEN) {
printf("USB interrupt write, Write status: %d. Packet Length: %d. Data out %d \n", write_status, PACKET_LEN, (char *)CurrDev->data_out);
return 0;
}
if (DEBUG)
fprintf(stderr, "Write retry\n");
}
return ERROR;
}
/* should return deviceno if OK */
long SetCurrentDevice(long deviceno)
{
if (deviceno >= 0 && deviceno < MAX_DEV)
{
if (F2550[deviceno].DevNo != 0)
{
CurrDev = &F2550[deviceno];
data_in = CurrDev->data_in;
data_out = CurrDev->data_out;
return deviceno;
}
}
return ERROR;
}
/* Actual read of data from the device endpoint, retry 3 times if not responding ok */
static int ReadData(void)
{
int read_status = 0, i = 0;
if (CurrDev->DevNo == 0) return ERROR;
for(i=0; i < 3; i++)
{
//read_status = usb_interrupt_read(CurrDev->device_handle, USB_INP_EP, (char *)CurrDev->data_in, PACKET_LEN, USB_TIMEOUT);
//printf("%d \n",(char *)CurrDev->data_in);
read_status = usb_interrupt_read(CurrDev->device_handle, USB_INP_EP, (char *)CurrDev->data_in, PACKET_LEN, USB_TIMEOUT);
printf("USB interrupt read, read status: %d. Packet Length: %d. Data in: %d\n",read_status,PACKET_LEN, (char *)CurrDev->data_in );
if ((read_status == PACKET_LEN) && (CurrDev->data_in[1] == CurrDev->DevNo )) return 0;
if (DEBUG)
fprintf(stderr, "Read retry\n");
}
return ERROR;
}
But when I run this it seems to recognise the board ok but fails on the read interrupt.
Code:
Detection of the board :
Board is found
Get driver name: - could not get bound driver: No data available
Found interface 0
Took over the device
USB interrupt write, Write status: 8. Packet Length: 8. Data out 6299913
USB interrupt read, read status: -110. Packet Length: 8. Data in: 6299904
Read retry
USB interrupt read, read status: -110. Packet Length: 8. Data in: 6299904
Read retry
USB interrupt read, read status: -110. Packet Length: 8. Data in: 6299904
Read retry
In know you developed this for windows but any advice trying to get his to work on linux would be great. I am new to pic development so if there is anything you see in the code or the output that does not look right or can suggest anything else to try that would be great.
Pete.