Thank you very much for the source. I purchased this device from OSR, and
have adapted your source code to use the libusb API (libusb.sourceforge.net), as the following (noticed it is much simpler):
/***********/
/ Define the vendor id and product id. /
/***********/
include <stdio.h>
include <string.h>
include <usb.h>
define VENDOR_ID 0x0547
define PRODUCT_ID 0x1002
/***********/
/ Define the vendor commands supported by OSR USB FX2 device. /
/***********/
define OSRFX2_READ_7SEGMENT_DISPLAY 0xD4
define OSRFX2_READ_SWITCHES 0xD6
define OSRFX2_READ_BARGRAPH_DISPLAY 0xD7
define OSRFX2_SET_BARGRAPH_DISPLAY 0xD8
define OSRFX2_IS_HIGH_SPEED 0xD9
define OSRFX2_REENUMERATE 0xDA
define OSRFX2_SET_7SEGMENT_DISPLAY 0xDB
define USB_CTRL_GET_TIMEOUT 1000
/***********/
/ BARGRAPH_STATE is a bit field structure with each bit corresponding /
/ to one on the bars on the bargraph LED of the OSR USB FX2 Learner Kit /
/ development board. /
/***********/
struct bargraph_state {
union {
struct {
/
* Individual bars (LEDs) starting from the top of the display.
* NOTE: The display has 10 LEDs, but the top two LEDs are not
* connected (don't light) and are not included here. /
unsigned char Bar4 : 1;
unsigned char Bar5 : 1;
unsigned char Bar6 : 1;
unsigned char Bar7 : 1;
unsigned char Bar8 : 1;
unsigned char Bar1 : 1;
unsigned char Bar2 : 1;
unsigned char Bar3 : 1;
};
/
* The state of all eight bars as a single octet.
*/
unsigned char BarsOctet;
};
} attribute ((packed));
/***********/
/ SEGMENT_STATE is a bit field structure with each bit corresponding /
/ to one on the segments on the 7-segment display of the OSR USB FX2 /
/ Learner Kit development board. /
/***********/
struct segment_state {
union {
struct {
/
* Individual segments. /
unsigned char Segment_top : 1; / 0x01 /
unsigned char Segment_upper_right : 1; / 0x02 /
unsigned char Segment_lower_right : 1; / 0x04 /
unsigned char Segment_dot : 1; / 0x08 /
unsigned char Segment_lower_left : 1; / 0x10 /
unsigned char Segment_middle : 1; / 0x20 /
unsigned char Segment_upper_left : 1; / 0x40 /
unsigned char Segment_bottom : 1; / 0x80 /
};
/
* The state of all the segments as a single octet. /
unsigned char SegmentsOctet;
};
} attribute ((packed));
/***********/
/ SWITCHES_STATE is a bit field structure with each bit corresponding /
/ to one of the DIP switches on the OSR USB FX2 Learner Kit development /
/ board. /
/***********/
struct switches_state {
union {
struct {
/
* Individual switches starting from the left /
unsigned char Switch8 : 1;
unsigned char Switch7 : 1;
unsigned char Switch6 : 1;
unsigned char Switch5 : 1;
unsigned char Switch4 : 1;
unsigned char Switch3 : 1;
unsigned char Switch2 : 1;
unsigned char Switch1 : 1;
};
/
* The state of all the switches as a single octet. /
unsigned char SwitchesOctet;
};
} attribute ((packed));
define TRUE 1
define FALSE 0
define EP1 1 / in / / out /
define EP2 2 / in /
define EP3 3
define EP4 4 / in /
define EP5 5
define EP6 6 / out /
define EP7 7
define EP8 8 / out /
int main(int argc, char argv[])
{
struct usb_bus bus;
char buffer[256];
usb_dev_handle udev;
struct usb_device dev;
int loop_count;
/***********/
/ This routine will retrieve the switches state, format it and return a /
/ representative string. /
//
/ Note the two different function defintions depending on kernel version. /
/***********/
int show_switches(struct usb_device * dev)
{
struct switches_state * packet;
int retval;
usb_dev_handle *udev;
/***********/
/ This macro creates an attribute under the sysfs directory /
/ --- /sys/bus/usb/devices/<root_hub>-<hub>:1.0/switches /
//
/ The DEVICE_ATTR() will create "dev_attr_switches" . /
/ "dev_attr_switches" is referenced in both probe and disconnect routines. /
//
/ Note that there is no "set" function for this attribute; therefore the /
/ S_IWUGO (write) flag is not included and the "set" routine point is set /
/ to NULL. /
/***********/
/static DEVICE_ATTR( switches, S_IRUGO, show_switches, NULL );/
/***********/
/ This routine will retrieve the bargraph LED state, format it and return a /
/ representative string. /
//
/ Note the two different function defintions depending on kernel version. /
/***********/
int show_bargraph(struct usb_device * dev)
{
struct bargraph_state * packet;
int retval;
usb_dev_handle *udev;
/***********/
/ This routine will set the bargraph LEDs. /
//
/ Note the two different function defintions depending on kernel version. /
/***********/
int set_bargraph(struct usb_device * dev, const char * buf)
{
struct bargraph_state * packet;
unsigned int value;
int retval;
char * end;
usb_dev_handle *udev;
udev = usb_open(dev);
usb_claim_interface(udev, 0);
packet = malloc(sizeof(*packet));
if (!packet) {
return FALSE;
}
packet->BarsOctet = 0;
value = (strtoul(buf, &end, 10) & 0xFF);
if (buf == end) {
value = 0;
}
packet->Bar1 = (value & 0x01) ? 1 : 0;
packet->Bar2 = (value & 0x02) ? 1 : 0;
packet->Bar3 = (value & 0x04) ? 1 : 0;
packet->Bar4 = (value & 0x08) ? 1 : 0;
packet->Bar5 = (value & 0x10) ? 1 : 0;
packet->Bar6 = (value & 0x20) ? 1 : 0;
packet->Bar7 = (value & 0x40) ? 1 : 0;
packet->Bar8 = (value & 0x80) ? 1 : 0;
retval = usb_control_msg(udev,
USB_ENDPOINT_OUT | USB_TYPE_VENDOR,
OSRFX2_SET_BARGRAPH_DISPLAY,
0,
0,
packet,
sizeof(*packet),
USB_CTRL_GET_TIMEOUT);
if (retval < 0) {
fprintf(stderr, "%s - retval=%d\n",
__FUNCTION__, retval);
}
free(packet);
usb_release_interface(udev, 0);
if (udev)
usb_close(udev);
return TRUE;
}
/***********/
/ This routine will show the 7-segment display value. /
//
/ The 7-segment display raw value is read and then looked-up in the /
/ mapping table, digit_to_segments. /
/ Any raw display value which is not mapped will be displayed as a ".". /
/ There are other special cases handles as well, e.g "H" for high-speed. /
//
/ Note the two different function defintions depending on kernel version. /
/***********/
int show_7segment(struct usb_device * dev)
{
struct segment_state * packet;
int retval;
int i;
usb_dev_handle *udev;
udev=usb_open(dev);usb_claim_interface(udev,0);packet=malloc(sizeof(*packet));if(!packet){returnFALSE;}packet->SegmentsOctet=nondisplayable;retval=usb_control_msg(udev,USB_ENDPOINT_IN|USB_TYPE_VENDOR,OSRFX2_READ_7SEGMENT_DISPLAY,0,0,packet,sizeof(*packet),USB_CTRL_GET_TIMEOUT);if(retval<0){fprintf(stderr,"Error:%s-retval=%d\n",__FUNCTION__,retval);free(packet);returnFALSE;}for(i=0;i<sizeof(digit_to_segments);i++){if(packet->SegmentsOctet==digit_to_segments[i]){break;}}if(i<sizeof(digit_to_segments)){printf("%d",i);}else{/* Check for special cases */printf("%s",(packet->SegmentsOctet==nondisplayable)?".":(packet->SegmentsOctet==high_speed)?"H":(packet->SegmentsOctet==power_active)?"A":"?");}free(packet);usb_release_interface(udev,0);if(udev)usb_close(udev);returnTRUE;
}
/***********/
/ This routine will set the 7-segment display. /
//
/ The input string (buf) is expected to be a numeric character between 0-9. /
/ Any ohter string values will be displayed on the 7-segment display by /
/ turning on the "dot" segment, thus indicating a "nondisplayable" value. /
//
/ Note the two different function defintions depending on kernel version. /
/***********/
int set_7segment(struct usb_device * dev, const char * buf)
{
struct segment_state * packet;
Thank you very much for the source. I purchased this device from OSR, and
have adapted your source code to use the libusb API (libusb.sourceforge.net), as the following (noticed it is much simpler):
/***********/
/ Define the vendor id and product id. /
/***********/
include <stdio.h>
include <string.h>
include <usb.h>
define VENDOR_ID 0x0547
define PRODUCT_ID 0x1002
/***********/
/ Define the vendor commands supported by OSR USB FX2 device. /
/***********/
define OSRFX2_READ_7SEGMENT_DISPLAY 0xD4
define OSRFX2_READ_SWITCHES 0xD6
define OSRFX2_READ_BARGRAPH_DISPLAY 0xD7
define OSRFX2_SET_BARGRAPH_DISPLAY 0xD8
define OSRFX2_IS_HIGH_SPEED 0xD9
define OSRFX2_REENUMERATE 0xDA
define OSRFX2_SET_7SEGMENT_DISPLAY 0xDB
define USB_CTRL_GET_TIMEOUT 1000
/***********/
/ BARGRAPH_STATE is a bit field structure with each bit corresponding /
/ to one on the bars on the bargraph LED of the OSR USB FX2 Learner Kit /
/ development board. /
/***********/
struct bargraph_state {
union {
struct {
/
* Individual bars (LEDs) starting from the top of the display.
* NOTE: The display has 10 LEDs, but the top two LEDs are not
* connected (don't light) and are not included here.
/
unsigned char Bar4 : 1;
unsigned char Bar5 : 1;
unsigned char Bar6 : 1;
unsigned char Bar7 : 1;
unsigned char Bar8 : 1;
unsigned char Bar1 : 1;
unsigned char Bar2 : 1;
unsigned char Bar3 : 1;
};
/
* The state of all eight bars as a single octet.
*/
unsigned char BarsOctet;
};
} attribute ((packed));
/***********/
/ SEGMENT_STATE is a bit field structure with each bit corresponding /
/ to one on the segments on the 7-segment display of the OSR USB FX2 /
/ Learner Kit development board. /
/***********/
struct segment_state {
union {
struct {
/
* Individual segments.
/
unsigned char Segment_top : 1; / 0x01 /
unsigned char Segment_upper_right : 1; / 0x02 /
unsigned char Segment_lower_right : 1; / 0x04 /
unsigned char Segment_dot : 1; / 0x08 /
unsigned char Segment_lower_left : 1; / 0x10 /
unsigned char Segment_middle : 1; / 0x20 /
unsigned char Segment_upper_left : 1; / 0x40 /
unsigned char Segment_bottom : 1; / 0x80 /
};
/
* The state of all the segments as a single octet.
/
unsigned char SegmentsOctet;
};
} attribute ((packed));
static const unsigned char digit_to_segments [10] = {
0xD7, / 0 /
0x06, / 1 /
0xB3, / 2 /
0xA7, / 3 /
0x66, / 4 /
0xE5, / 5 /
0xF5, / 6 /
0x07, / 7 /
0xF7, / 8 /
0x67 / 9 /
};
static const unsigned char nondisplayable = 0x08; / the "dot" segment /
static const unsigned char high_speed = 0x76; / high-speed "H" /
static const unsigned char power_active = 0x77; / PM active "A" /
static const unsigned char power_suspend = 0xE5; / PM suspend "S" /
/***********/
/ SWITCHES_STATE is a bit field structure with each bit corresponding /
/ to one of the DIP switches on the OSR USB FX2 Learner Kit development /
/ board. /
/***********/
struct switches_state {
union {
struct {
/
* Individual switches starting from the left
/
unsigned char Switch8 : 1;
unsigned char Switch7 : 1;
unsigned char Switch6 : 1;
unsigned char Switch5 : 1;
unsigned char Switch4 : 1;
unsigned char Switch3 : 1;
unsigned char Switch2 : 1;
unsigned char Switch1 : 1;
};
/
* The state of all the switches as a single octet.
/
unsigned char SwitchesOctet;
};
} attribute ((packed));
define TRUE 1
define FALSE 0
define EP1 1 / in / / out /
define EP2 2 / in /
define EP3 3
define EP4 4 / in /
define EP5 5
define EP6 6 / out /
define EP7 7
define EP8 8 / out /
int main(int argc, char argv[])
{
struct usb_bus bus;
char buffer[256];
usb_dev_handle udev;
struct usb_device dev;
int loop_count;
}
/***********/
/ This routine will retrieve the switches state, format it and return a /
/ representative string. /
/ /
/ Note the two different function defintions depending on kernel version. /
/***********/
int show_switches(struct usb_device * dev)
{
struct switches_state * packet;
int retval;
usb_dev_handle *udev;
}
/***********/
/ This macro creates an attribute under the sysfs directory /
/ --- /sys/bus/usb/devices/<root_hub>-<hub>:1.0/switches /
/ /
/ The DEVICE_ATTR() will create "dev_attr_switches" . /
/ "dev_attr_switches" is referenced in both probe and disconnect routines. /
/ /
/ Note that there is no "set" function for this attribute; therefore the /
/ S_IWUGO (write) flag is not included and the "set" routine point is set /
/ to NULL. /
/***********/
/static DEVICE_ATTR( switches, S_IRUGO, show_switches, NULL );/
/***********/
/ This routine will retrieve the bargraph LED state, format it and return a /
/ representative string. /
/ /
/ Note the two different function defintions depending on kernel version. /
/***********/
int show_bargraph(struct usb_device * dev)
{
struct bargraph_state * packet;
int retval;
usb_dev_handle *udev;
}
/***********/
/ This routine will set the bargraph LEDs. /
/ /
/ Note the two different function defintions depending on kernel version. /
/***********/
int set_bargraph(struct usb_device * dev, const char * buf)
{
struct bargraph_state * packet;
}
/***********/
/ This routine will show the 7-segment display value. /
/ /
/ The 7-segment display raw value is read and then looked-up in the /
/ mapping table, digit_to_segments. /
/ Any raw display value which is not mapped will be displayed as a ".". /
/ There are other special cases handles as well, e.g "H" for high-speed. /
/ /
/ Note the two different function defintions depending on kernel version. /
/***********/
int show_7segment(struct usb_device * dev)
{
struct segment_state * packet;
int retval;
int i;
usb_dev_handle *udev;
}
/***********/
/ This routine will set the 7-segment display. /
/ /
/ The input string (buf) is expected to be a numeric character between 0-9. /
/ Any ohter string values will be displayed on the 7-segment display by /
/ turning on the "dot" segment, thus indicating a "nondisplayable" value. /
/ /
/ Note the two different function defintions depending on kernel version. /
/***********/
int set_7segment(struct usb_device * dev, const char * buf)
{
struct segment_state * packet;
}