source: thomson/elec/CrO2/software/powerSwitch.c@ 88642a4

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

Add motor on detection.

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

  • Property mode set to 100644
File size: 7.6 KB
Line 
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 <stdint.h>
23#include <unistd.h>
24
25#include <lusb0_usb.h> /* this is libusb, see http://libusb.sourceforge.net/ */
26
27#define USBDEV_SHARED_VENDOR 0x16C0 /* VOTI */
28#define USBDEV_SHARED_PRODUCT 0x05DC /* Obdev's free shared PID */
29/* Use obdev's generic shared VID/PID pair and follow the rules outlined
30 * in firmware/usbdrv/USBID-License.txt.
31 */
32
33#define VENDORSTRING "pulkomandy.ath.cx"
34#define PRODUCTSTRING "CrO2"
35
36/* These are the vendor specific SETUP commands implemented by our USB device */
37#define PSCMD_CONFIG 0
38#define PSCMD_GET 1
39#define PSCMD_PUT 2
40#define PSCMD_STATUS 3
41
42static void usage(char *name)
43{
44 fprintf(stderr, "usage:\n");
45 fprintf(stderr, " %s status\n", name);
46 fprintf(stderr, " %s on <port> [<duration>]\n", name);
47 fprintf(stderr, " %s off <port> [<duration>]\n", name);
48 fprintf(stderr, " %s test\n\n", name);
49 fprintf(stderr, "Ports are single digits in the range 0...7\n");
50 fprintf(stderr, "The pulse duration for switching temporarily is given in seconds.\n");
51}
52
53
54static int usbGetStringAscii(usb_dev_handle *dev, int index, int langid, char *buf, int buflen)
55{
56char buffer[256];
57int rval, i;
58
59 if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, langid, buffer, sizeof(buffer), 1000)) < 0)
60 return rval;
61 if(buffer[1] != USB_DT_STRING)
62 return 0;
63 if((unsigned char)buffer[0] < rval)
64 rval = (unsigned char)buffer[0];
65 rval /= 2;
66 /* lossy conversion to ISO Latin1 */
67 for(i=1;i<rval;i++){
68 if(i > buflen) /* destination buffer overflow */
69 break;
70 buf[i-1] = buffer[2 * i];
71 if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */
72 buf[i-1] = '?';
73 }
74 buf[i-1] = 0;
75 return i-1;
76}
77
78
79/* PowerSwitch uses the free shared default VID/PID. If you want to see an
80 * example device lookup where an individually reserved PID is used, see our
81 * RemoteSensor reference implementation.
82 */
83
84#define USB_ERROR_NOTFOUND 1
85#define USB_ERROR_ACCESS 2
86#define USB_ERROR_IO 3
87
88static int usbOpenDevice(usb_dev_handle **device, int vendor, char *vendorName, int product, char *productName)
89{
90struct usb_bus *bus;
91struct usb_device *dev;
92usb_dev_handle *handle = NULL;
93int errorCode = USB_ERROR_NOTFOUND;
94static int didUsbInit = 0;
95
96 if(!didUsbInit){
97 didUsbInit = 1;
98 usb_init();
99 }
100 usb_find_busses();
101 usb_find_devices();
102 for(bus=usb_get_busses(); bus; bus=bus->next){
103 for(dev=bus->devices; dev; dev=dev->next){
104 if(dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product){
105 char string[256];
106 int len;
107 handle = usb_open(dev); /* we need to open the device in order to query strings */
108 if(!handle){
109 errorCode = USB_ERROR_ACCESS;
110 fprintf(stderr, "Warning: cannot open USB device: %s\n", usb_strerror());
111 continue;
112 }
113 if(vendorName == NULL && productName == NULL){ /* name does not matter */
114 break;
115 }
116 /* now check whether the names match: */
117 len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, 0x0409, string, sizeof(string));
118 if(len < 0){
119 errorCode = USB_ERROR_IO;
120 fprintf(stderr, "Warning: cannot query manufacturer for device: %s\n", usb_strerror());
121 }else{
122 errorCode = USB_ERROR_NOTFOUND;
123 /* fprintf(stderr, "seen device from vendor ->%s<-\n", string); */
124 if(strcmp(string, vendorName) == 0){
125 len = usbGetStringAscii(handle, dev->descriptor.iProduct, 0x0409, string, sizeof(string));
126 if(len < 0){
127 errorCode = USB_ERROR_IO;
128 fprintf(stderr, "Warning: cannot query product for device: %s\n", usb_strerror());
129 }else{
130 errorCode = USB_ERROR_NOTFOUND;
131 /* fprintf(stderr, "seen product ->%s<-\n", string); */
132 if(strcmp(string, productName) == 0)
133 break;
134 }
135 }
136 }
137 usb_close(handle);
138 handle = NULL;
139 }
140 }
141 if(handle)
142 break;
143 }
144 if(handle != NULL){
145 errorCode = 0;
146 *device = handle;
147 }
148 return errorCode;
149}
150
151void hexdump(unsigned char* bytes, int len)
152{
153 for(int i = 0; i <len; i++)
154 printf("%X ",bytes[i]);
155 puts("");
156}
157
158int main(int argc, char **argv)
159{
160usb_dev_handle *handle = NULL;
161unsigned char buffer[275];
162int nBytes;
163
164 if(argc < 2){
165 usage(argv[0]);
166 exit(1);
167 }
168 usb_init();
169 if(usbOpenDevice(&handle, USBDEV_SHARED_VENDOR, VENDORSTRING, USBDEV_SHARED_PRODUCT, PRODUCTSTRING) != 0){
170 fprintf(stderr, "Could not find USB device \""PRODUCTSTRING"\" with vid=0x%x pid=0x%x\n", USBDEV_SHARED_VENDOR, USBDEV_SHARED_PRODUCT);
171 exit(1);
172 }
173/* We have searched all devices on all busses for our USB device above. Now
174 * try to open it and perform the vendor specific control operations for the
175 * function requested by the user.
176 */
177 if(strcmp(argv[1], "get") == 0){
178 memset(buffer, 0, 275);
179 nBytes = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, PSCMD_GET, 0,0, (char*)buffer, 200, 5000);
180 hexdump(buffer, sizeof(buffer));
181 }else if(strcmp(argv[1], "put") == 0){
182
183 do
184 {
185 // Wait for motor on
186 nBytes = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, PSCMD_STATUS, 0,0, (char*)buffer, 1, 5000);
187 usleep(1000000);
188 } while (buffer[0] & 8);
189
190
191 FILE* fptr = fopen(argv[2], "rb");
192 int blockid;
193 uint8_t blktype, blksize;
194 sscanf(argv[3], "%d", &blockid);
195
196 do
197 {
198 do
199 {
200 fread(&blktype, 1, 1, fptr);
201 if (feof(fptr))
202 {
203 fprintf(stderr, "end of file.\n");
204 fclose(fptr);
205 usb_close(handle);
206 exit(0);
207 }
208 }
209 while(blktype != 0x5A); // skip sync header
210
211 fread(&blktype, 1, 1, fptr);
212 fread(&blksize, 1, 1, fptr);
213 blksize -= 2;
214 fread(buffer, 1, blksize + 1, fptr);
215 if (blktype == 0)
216 {
217 // new file
218 printf("%.11s\n",buffer);
219 }
220 }
221 while (blockid --);
222
223 fclose(fptr);
224
225 hexdump(buffer, blksize);
226 int rqtype = (blksize == 0) ? USB_ENDPOINT_IN:USB_ENDPOINT_OUT;
227 nBytes = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | rqtype, PSCMD_PUT, blktype,0 /*checksum*/, (char*)buffer, blksize, 5000);
228 }else{
229 fprintf(stderr,"Unknown command: %s.\n", argv[1]);
230 usage(argv[0]);
231 nBytes = 0;
232 // TODO manage return code
233 }
234
235 if (nBytes < 0) fprintf(stderr, "USB error %s\n", usb_strerror());
236 usb_close(handle);
237 return 0;
238}
239
Note: See TracBrowser for help on using the repository browser.