source: thomson/elec/CrO2/software/powerSwitch.c@ 0da6f01

main
Last change on this file since 0da6f01 was 0da6f01, checked in by Adrien Destugues <pulkomandy@…>, 12 years ago

Add host software for CrO2 (WIP)

git-svn-id: svn://localhost/thomson@6 85ae3b6b-dc8f-4344-a89d-598714f2e4e5

  • Property mode set to 100644
File size: 6.7 KB
RevLine 
[0da6f01]1/* Name: powerSwitch.c
2 * Project: PowerSwitch based on AVR USB driver
3 * Author: Christian Starkjohann
4 * Creation Date: 2005-01-16
5 * Tabsize: 4
6 * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
7 * License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
8 * This Revision: $Id: powerSwitch.c 472 2008-01-21 18:21:59Z cs $
9 */
10
11/*
12General Description:
13This program controls the PowerSwitch USB device from the command line.
14It must be linked with libusb, a library for accessing the USB bus from
15Linux, FreeBSD, Mac OS X and other Unix operating systems. Libusb can be
16obtained from http://libusb.sourceforge.net/.
17*/
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22#include <lusb0_usb.h> /* this is libusb, see http://libusb.sourceforge.net/ */
23
24#define USBDEV_SHARED_VENDOR 0x16C0 /* VOTI */
25#define USBDEV_SHARED_PRODUCT 0x05DC /* Obdev's free shared PID */
26/* Use obdev's generic shared VID/PID pair and follow the rules outlined
27 * in firmware/usbdrv/USBID-License.txt.
28 */
29
30#define VENDORSTRING "pulkomandy.ath.cx"
31#define PRODUCTSTRING "CrO2"
32
33#define PSCMD_CONFIG 0
34#define PSCMD_GET 1
35#define PSCMD_PUT 2
36/* These are the vendor specific SETUP commands implemented by our USB device */
37
38static void usage(char *name)
39{
40 fprintf(stderr, "usage:\n");
41 fprintf(stderr, " %s status\n", name);
42 fprintf(stderr, " %s on <port> [<duration>]\n", name);
43 fprintf(stderr, " %s off <port> [<duration>]\n", name);
44 fprintf(stderr, " %s test\n\n", name);
45 fprintf(stderr, "Ports are single digits in the range 0...7\n");
46 fprintf(stderr, "The pulse duration for switching temporarily is given in seconds.\n");
47}
48
49
50static int usbGetStringAscii(usb_dev_handle *dev, int index, int langid, char *buf, int buflen)
51{
52char buffer[256];
53int rval, i;
54
55 if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, langid, buffer, sizeof(buffer), 1000)) < 0)
56 return rval;
57 if(buffer[1] != USB_DT_STRING)
58 return 0;
59 if((unsigned char)buffer[0] < rval)
60 rval = (unsigned char)buffer[0];
61 rval /= 2;
62 /* lossy conversion to ISO Latin1 */
63 for(i=1;i<rval;i++){
64 if(i > buflen) /* destination buffer overflow */
65 break;
66 buf[i-1] = buffer[2 * i];
67 if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */
68 buf[i-1] = '?';
69 }
70 buf[i-1] = 0;
71 return i-1;
72}
73
74
75/* PowerSwitch uses the free shared default VID/PID. If you want to see an
76 * example device lookup where an individually reserved PID is used, see our
77 * RemoteSensor reference implementation.
78 */
79
80#define USB_ERROR_NOTFOUND 1
81#define USB_ERROR_ACCESS 2
82#define USB_ERROR_IO 3
83
84static int usbOpenDevice(usb_dev_handle **device, int vendor, char *vendorName, int product, char *productName)
85{
86struct usb_bus *bus;
87struct usb_device *dev;
88usb_dev_handle *handle = NULL;
89int errorCode = USB_ERROR_NOTFOUND;
90static int didUsbInit = 0;
91
92 if(!didUsbInit){
93 didUsbInit = 1;
94 usb_init();
95 }
96 usb_find_busses();
97 usb_find_devices();
98 for(bus=usb_get_busses(); bus; bus=bus->next){
99 for(dev=bus->devices; dev; dev=dev->next){
100 if(dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product){
101 char string[256];
102 int len;
103 handle = usb_open(dev); /* we need to open the device in order to query strings */
104 if(!handle){
105 errorCode = USB_ERROR_ACCESS;
106 fprintf(stderr, "Warning: cannot open USB device: %s\n", usb_strerror());
107 continue;
108 }
109 if(vendorName == NULL && productName == NULL){ /* name does not matter */
110 break;
111 }
112 /* now check whether the names match: */
113 len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, 0x0409, string, sizeof(string));
114 if(len < 0){
115 errorCode = USB_ERROR_IO;
116 fprintf(stderr, "Warning: cannot query manufacturer for device: %s\n", usb_strerror());
117 }else{
118 errorCode = USB_ERROR_NOTFOUND;
119 /* fprintf(stderr, "seen device from vendor ->%s<-\n", string); */
120 if(strcmp(string, vendorName) == 0){
121 len = usbGetStringAscii(handle, dev->descriptor.iProduct, 0x0409, string, sizeof(string));
122 if(len < 0){
123 errorCode = USB_ERROR_IO;
124 fprintf(stderr, "Warning: cannot query product for device: %s\n", usb_strerror());
125 }else{
126 errorCode = USB_ERROR_NOTFOUND;
127 /* fprintf(stderr, "seen product ->%s<-\n", string); */
128 if(strcmp(string, productName) == 0)
129 break;
130 }
131 }
132 }
133 usb_close(handle);
134 handle = NULL;
135 }
136 }
137 if(handle)
138 break;
139 }
140 if(handle != NULL){
141 errorCode = 0;
142 *device = handle;
143 }
144 return errorCode;
145}
146
147void hexdump(unsigned char* bytes, int len)
148{
149 for(int i = 0; i <len; i++)
150 printf("%X ",bytes[i]);
151 puts("");
152}
153
154int main(int argc, char **argv)
155{
156usb_dev_handle *handle = NULL;
157unsigned char buffer[275];
158int nBytes;
159
160 if(argc < 2){
161 usage(argv[0]);
162 exit(1);
163 }
164 usb_init();
165 if(usbOpenDevice(&handle, USBDEV_SHARED_VENDOR, VENDORSTRING, USBDEV_SHARED_PRODUCT, PRODUCTSTRING) != 0){
166 fprintf(stderr, "Could not find USB device \""PRODUCTSTRING"\" with vid=0x%x pid=0x%x\n", USBDEV_SHARED_VENDOR, USBDEV_SHARED_PRODUCT);
167 exit(1);
168 }
169/* We have searched all devices on all busses for our USB device above. Now
170 * try to open it and perform the vendor specific control operations for the
171 * function requested by the user.
172 */
173 if(strcmp(argv[1], "get") == 0){
174 memset(buffer, 0, 275);
175 nBytes = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, PSCMD_GET, 0,0, (char*)buffer, 200, 5000);
176 hexdump(buffer, sizeof(buffer));
177 }else if(strcmp(argv[1], "put") == 0){
178 hexdump(buffer, sizeof(buffer));
179 nBytes = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, PSCMD_PUT, 0,0, (char*)buffer, 200, 5000);
180 }else{
181 fprintf(stderr,"Unknown command: %s.\n", argv[1]);
182 usage(argv[0]);
183 nBytes = 0;
184 // TODO manage return code
185 }
186
187 if (nBytes < 0) fprintf(stderr, "USB error %s\n", usb_strerror());
188
189 usb_close(handle);
190 return 0;
191}
192
Note: See TracBrowser for help on using the repository browser.