1 |
/* |
1 |
/* |
2 |
* i2c_usb.c - test application for the i2c-tiby-usb interface |
2 |
* i2c_usb.c - test application for the i2c-tiby-usb interface |
3 |
* http://www.harbaum.org/till/i2c_tiny_usb |
3 |
* http://www.harbaum.org/till/i2c_tiny_usb |
4 |
* |
4 |
* |
5 |
* $Id: i2c_usb.c,v 1.5 2007/01/05 19:30:43 harbaum Exp $ |
5 |
* $Id: i2c_usb.c,v 1.5 2007/01/05 19:30:43 harbaum Exp $ |
6 |
*/ |
6 |
*/ |
7 |
|
7 |
|
8 |
#include <stdio.h> |
8 |
#include <stdio.h> |
9 |
#include <stdlib.h> |
9 |
#include <stdlib.h> |
10 |
#include <string.h> |
10 |
#include <string.h> |
11 |
#include <usb.h> |
11 |
#include <usb.h> |
12 |
|
12 |
|
13 |
/* ds1621 chip address (A0-A2 tied low) */ |
13 |
/* ds1621 chip address (A0-A2 tied low) */ |
14 |
#define DS1621_ADDR 0x48 |
14 |
#define DS1621_ADDR 0x48 |
15 |
|
15 |
|
16 |
/* pcf8574 chip address (A0-A2 tied low) */ |
16 |
/* pcf8574 chip address (A0-A2 tied low) */ |
17 |
#define PCF8574_ADDR 0x20 |
17 |
#define PCF8574_ADDR 0x20 |
18 |
|
18 |
|
19 |
#define LOOPS 100 |
19 |
#define LOOPS 100 |
20 |
|
20 |
|
21 |
#define USB_CTRL_IN (USB_TYPE_CLASS | USB_ENDPOINT_IN) |
21 |
#define USB_CTRL_IN (USB_TYPE_CLASS | USB_ENDPOINT_IN) |
22 |
#define USB_CTRL_OUT (USB_TYPE_CLASS) |
22 |
#define USB_CTRL_OUT (USB_TYPE_CLASS) |
23 |
|
23 |
|
24 |
/* the vendor and product id was donated by ftdi ... many thanks!*/ |
24 |
/* the vendor and product id was donated by ftdi ... many thanks!*/ |
25 |
#define I2C_TINY_USB_VID 0x0403 |
25 |
#define I2C_TINY_USB_VID 0x0403 |
26 |
#define I2C_TINY_USB_PID 0xc631 |
26 |
#define I2C_TINY_USB_PID 0xc631 |
27 |
|
27 |
|
28 |
#ifdef WIN |
28 |
#ifdef WIN |
29 |
#include <windows.h> |
29 |
#include <windows.h> |
30 |
#include <winbase.h> |
30 |
#include <winbase.h> |
31 |
#define usleep(t) Sleep((t) / 1000) |
31 |
#define usleep(t) Sleep((t) / 1000) |
32 |
#endif |
32 |
#endif |
33 |
|
33 |
|
34 |
#define I2C_M_RD 0x01 |
34 |
#define I2C_M_RD 0x01 |
35 |
|
35 |
|
36 |
/* commands via USB, must e.g. match command ids firmware */ |
36 |
/* commands via USB, must e.g. match command ids firmware */ |
37 |
#define CMD_ECHO 0 |
37 |
#define CMD_ECHO 0 |
38 |
#define CMD_GET_FUNC 1 |
38 |
#define CMD_GET_FUNC 1 |
39 |
#define CMD_SET_DELAY 2 |
39 |
#define CMD_SET_DELAY 2 |
40 |
#define CMD_GET_STATUS 3 |
40 |
#define CMD_GET_STATUS 3 |
41 |
#define CMD_I2C_IO 4 |
41 |
#define CMD_I2C_IO 4 |
42 |
#define CMD_I2C_BEGIN 1 // flag to I2C_IO |
42 |
#define CMD_I2C_BEGIN 1 // flag to I2C_IO |
43 |
#define CMD_I2C_END 2 // flag to I2C_IO |
43 |
#define CMD_I2C_END 2 // flag to I2C_IO |
44 |
|
44 |
|
45 |
#define STATUS_IDLE 0 |
45 |
#define STATUS_IDLE 0 |
46 |
#define STATUS_ADDRESS_ACK 1 |
46 |
#define STATUS_ADDRESS_ACK 1 |
47 |
#define STATUS_ADDRESS_NAK 2 |
47 |
#define STATUS_ADDRESS_NAK 2 |
48 |
|
48 |
|
49 |
usb_dev_handle *handle = NULL; |
49 |
usb_dev_handle *handle = NULL; |
50 |
|
50 |
|
51 |
/* write a set of bytes to the i2c_tiny_usb device */ |
51 |
/* write a set of bytes to the i2c_tiny_usb device */ |
52 |
int i2c_tiny_usb_write(int request, int value, int index){ |
52 |
int i2c_tiny_usb_write(int request, int value, int index){ |
53 |
|
53 |
|
54 |
if(usb_control_msg(handle, USB_CTRL_OUT, request, |
54 |
if(usb_control_msg(handle, USB_CTRL_OUT, request, |
55 |
value, index, NULL, 0, 1000) < 0) { |
55 |
value, index, NULL, 0, 1000) < 0) { |
56 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
56 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
57 |
return -1; |
57 |
return -1; |
58 |
} |
58 |
} |
59 |
return 1; |
59 |
return 1; |
60 |
} |
60 |
} |
61 |
|
61 |
|
62 |
/* read a set of bytes from the i2c_tiny_usb device */ |
62 |
/* read a set of bytes from the i2c_tiny_usb device */ |
63 |
int i2c_tiny_usb_read(unsigned char cmd, void *data, int len) { |
63 |
int i2c_tiny_usb_read(unsigned char cmd, void *data, int len) { |
64 |
int nBytes; |
64 |
int nBytes; |
65 |
|
65 |
|
66 |
/* send control request and accept return value */ |
66 |
/* send control request and accept return value */ |
67 |
nBytes = usb_control_msg(handle,USB_CTRL_IN, cmd, 0, 0, &data, len, 1000); |
67 |
nBytes = usb_control_msg(handle,USB_CTRL_IN, cmd, 0, 0, &data, len, 1000); |
68 |
|
68 |
|
69 |
if(nBytes < 0) { |
69 |
if(nBytes < 0) { |
70 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
70 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
71 |
return nBytes; |
71 |
return nBytes; |
72 |
} |
72 |
} |
73 |
|
73 |
|
74 |
return 0; |
74 |
return 0; |
75 |
} |
75 |
} |
76 |
|
76 |
|
77 |
/* get i2c usb interface test */ |
77 |
/* get i2c usb interface test */ |
78 |
void i2c_tiny_usb_test(void) { |
78 |
void i2c_tiny_usb_test(void) { |
79 |
unsigned long func; |
79 |
unsigned long func; |
80 |
|
80 |
|
81 |
if(i2c_tiny_usb_read(CMD_ECHO, &func, sizeof(func)) == 0) |
81 |
if(i2c_tiny_usb_read(CMD_ECHO, &func, sizeof(func)) == 0) |
82 |
printf("Functionality = %lx\n", func); |
82 |
printf("Functionality = %lx\n", func); |
83 |
} |
83 |
} |
84 |
|
84 |
|
85 |
|
85 |
|
86 |
/* get i2c usb interface firmware version */ |
86 |
/* get i2c usb interface firmware version */ |
87 |
void i2c_tiny_usb_get_func(void) { |
87 |
void i2c_tiny_usb_get_func(void) { |
88 |
unsigned long func; |
88 |
unsigned long func; |
89 |
|
89 |
|
90 |
if(i2c_tiny_usb_read(CMD_GET_FUNC, &func, sizeof(func)) == 0) |
90 |
if(i2c_tiny_usb_read(CMD_GET_FUNC, &func, sizeof(func)) == 0) |
91 |
printf("Functionality = %lx\n", func); |
91 |
printf("Functionality = %lx\n", func); |
92 |
} |
92 |
} |
93 |
|
93 |
|
94 |
/* set a value in the I2C_USB interface */ |
94 |
/* set a value in the I2C_USB interface */ |
95 |
void i2c_tiny_usb_set(unsigned char cmd, int value) { |
95 |
void i2c_tiny_usb_set(unsigned char cmd, int value) { |
96 |
if(usb_control_msg(handle, |
96 |
if(usb_control_msg(handle, |
97 |
USB_TYPE_VENDOR, cmd, value, 0, |
97 |
USB_TYPE_VENDOR, cmd, value, 0, |
98 |
NULL, 0, 1000) < 0) { |
98 |
NULL, 0, 1000) < 0) { |
99 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
99 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
100 |
} |
100 |
} |
101 |
} |
101 |
} |
102 |
|
102 |
|
103 |
/* get the current transaction status from the i2c_tiny_usb interface */ |
103 |
/* get the current transaction status from the i2c_tiny_usb interface */ |
104 |
int i2c_tiny_usb_get_status(void) { |
104 |
int i2c_tiny_usb_get_status(void) { |
105 |
int i; |
105 |
int i; |
106 |
unsigned char status; |
106 |
unsigned char status; |
107 |
|
107 |
|
108 |
if((i=i2c_tiny_usb_read(CMD_GET_STATUS, &status, sizeof(status))) < 0) { |
108 |
if((i=i2c_tiny_usb_read(CMD_GET_STATUS, &status, sizeof(status))) < 0) { |
109 |
fprintf(stderr, "Error reading status\n"); |
109 |
fprintf(stderr, "Error reading status\n"); |
110 |
return i; |
110 |
return i; |
111 |
} |
111 |
} |
112 |
|
112 |
|
113 |
return status; |
113 |
return status; |
114 |
} |
114 |
} |
115 |
|
115 |
|
116 |
/* write command and read an 8 or 16 bit value from the given chip */ |
116 |
/* write command and read an 8 or 16 bit value from the given chip */ |
117 |
int i2c_read_with_cmd(unsigned char addr, char cmd, int length) { |
117 |
int i2c_read_with_cmd(unsigned char addr, char cmd, int length) { |
118 |
unsigned char result[2]; |
118 |
unsigned char result[2]; |
119 |
|
119 |
|
120 |
if((length < 0) || (length > sizeof(result))) { |
120 |
if((length < 0) || (length > sizeof(result))) { |
121 |
fprintf(stderr, "request exceeds %lu bytes\n", sizeof(result)); |
121 |
fprintf(stderr, "request exceeds %lu bytes\n", sizeof(result)); |
122 |
return -1; |
122 |
return -1; |
123 |
} |
123 |
} |
124 |
|
124 |
|
125 |
/* write one byte register address to chip */ |
125 |
/* write one byte register address to chip */ |
126 |
if(usb_control_msg(handle, USB_CTRL_OUT, |
126 |
if(usb_control_msg(handle, USB_CTRL_OUT, |
127 |
CMD_I2C_IO + CMD_I2C_BEGIN |
127 |
CMD_I2C_IO + CMD_I2C_BEGIN |
128 |
+ ((!length)?CMD_I2C_END:0), |
128 |
+ ((!length)?CMD_I2C_END:0), |
129 |
0, addr, &cmd, 1, |
129 |
0, addr, &cmd, 1, |
130 |
1000) < 1) { |
130 |
1000) < 1) { |
131 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
131 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
132 |
return -1; |
132 |
return -1; |
133 |
} |
133 |
} |
134 |
|
134 |
|
135 |
if(i2c_tiny_usb_get_status() != STATUS_ADDRESS_ACK) { |
135 |
if(i2c_tiny_usb_get_status() != STATUS_ADDRESS_ACK) { |
136 |
fprintf(stderr, "write command status failed\n"); |
136 |
fprintf(stderr, "write command status failed\n"); |
137 |
return -1; |
137 |
return -1; |
138 |
} |
138 |
} |
139 |
|
139 |
|
140 |
// just a test? return ok |
140 |
// just a test? return ok |
141 |
if(!length) return 0; |
141 |
if(!length) return 0; |
142 |
|
142 |
|
143 |
if(usb_control_msg(handle, |
143 |
if(usb_control_msg(handle, |
144 |
USB_CTRL_IN, |
144 |
USB_CTRL_IN, |
145 |
CMD_I2C_IO + CMD_I2C_END, |
145 |
CMD_I2C_IO + CMD_I2C_END, |
146 |
I2C_M_RD, addr, (char*)result, length, |
146 |
I2C_M_RD, addr, (char*)result, length, |
147 |
1000) < 1) { |
147 |
1000) < 1) { |
148 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
148 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
149 |
return -1; |
149 |
return -1; |
150 |
} |
150 |
} |
151 |
|
151 |
|
152 |
if(i2c_tiny_usb_get_status() != STATUS_ADDRESS_ACK) { |
152 |
if(i2c_tiny_usb_get_status() != STATUS_ADDRESS_ACK) { |
153 |
fprintf(stderr, "read data status failed\n"); |
153 |
fprintf(stderr, "read data status failed\n"); |
154 |
return -1; |
154 |
return -1; |
155 |
} |
155 |
} |
156 |
|
156 |
|
157 |
// return 16 bit result |
157 |
// return 16 bit result |
158 |
if(length == 2) |
158 |
if(length == 2) |
159 |
return 256*result[0] + result[1]; |
159 |
return 256*result[0] + result[1]; |
160 |
|
160 |
|
161 |
// return 8 bit result |
161 |
// return 8 bit result |
162 |
return result[0]; |
162 |
return result[0]; |
163 |
} |
163 |
} |
164 |
|
164 |
|
165 |
/* write a single byte to the i2c client */ |
165 |
/* write a single byte to the i2c client */ |
166 |
int i2c_write_byte(unsigned char addr, char data) { |
166 |
int i2c_write_byte(unsigned char addr, char data) { |
167 |
|
167 |
|
168 |
/* write one byte register address to chip */ |
168 |
/* write one byte register address to chip */ |
169 |
if(usb_control_msg(handle, USB_CTRL_OUT, |
169 |
if(usb_control_msg(handle, USB_CTRL_OUT, |
170 |
CMD_I2C_IO + CMD_I2C_BEGIN + CMD_I2C_END, |
170 |
CMD_I2C_IO + CMD_I2C_BEGIN + CMD_I2C_END, |
171 |
0, addr, &data, 1, |
171 |
0, addr, &data, 1, |
172 |
1000) < 1) { |
172 |
1000) < 1) { |
173 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
173 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
174 |
return -1; |
174 |
return -1; |
175 |
} |
175 |
} |
176 |
|
176 |
|
177 |
if(i2c_tiny_usb_get_status() != STATUS_ADDRESS_ACK) { |
177 |
if(i2c_tiny_usb_get_status() != STATUS_ADDRESS_ACK) { |
178 |
fprintf(stderr, "write command status failed\n"); |
178 |
fprintf(stderr, "write command status failed\n"); |
179 |
return -1; |
179 |
return -1; |
180 |
} |
180 |
} |
181 |
|
181 |
|
182 |
return 0; |
182 |
return 0; |
183 |
} |
183 |
} |
184 |
|
184 |
|
185 |
/* write a command byte and a single byte to the i2c client */ |
185 |
/* write a command byte and a single byte to the i2c client */ |
186 |
int i2c_write_cmd_and_byte(unsigned char addr, char cmd, char data) { |
186 |
int i2c_write_cmd_and_byte(unsigned char addr, char cmd, char data) { |
187 |
char msg[2]; |
187 |
char msg[2]; |
188 |
|
188 |
|
189 |
msg[0] = cmd; |
189 |
msg[0] = cmd; |
190 |
msg[1] = data; |
190 |
msg[1] = data; |
191 |
|
191 |
|
192 |
/* write one byte register address to chip */ |
192 |
/* write one byte register address to chip */ |
193 |
if(usb_control_msg(handle, USB_CTRL_OUT, |
193 |
if(usb_control_msg(handle, USB_CTRL_OUT, |
194 |
CMD_I2C_IO + CMD_I2C_BEGIN + CMD_I2C_END, |
194 |
CMD_I2C_IO + CMD_I2C_BEGIN + CMD_I2C_END, |
195 |
0, addr, msg, 2, |
195 |
0, addr, msg, 2, |
196 |
1000) < 1) { |
196 |
1000) < 1) { |
197 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
197 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
198 |
return -1; |
198 |
return -1; |
199 |
} |
199 |
} |
200 |
|
200 |
|
201 |
if(i2c_tiny_usb_get_status() != STATUS_ADDRESS_ACK) { |
201 |
if(i2c_tiny_usb_get_status() != STATUS_ADDRESS_ACK) { |
202 |
fprintf(stderr, "write command status failed\n"); |
202 |
fprintf(stderr, "write command status failed\n"); |
203 |
return -1; |
203 |
return -1; |
204 |
} |
204 |
} |
205 |
|
205 |
|
206 |
return 0; |
206 |
return 0; |
207 |
} |
207 |
} |
208 |
|
208 |
|
209 |
/* write a command byte and a 16 bit value to the i2c client */ |
209 |
/* write a command byte and a 16 bit value to the i2c client */ |
210 |
int i2c_write_cmd_and_word(unsigned char addr, char cmd, int data) { |
210 |
int i2c_write_cmd_and_word(unsigned char addr, char cmd, int data) { |
211 |
char msg[3]; |
211 |
char msg[3]; |
212 |
|
212 |
|
213 |
msg[0] = cmd; |
213 |
msg[0] = cmd; |
214 |
msg[1] = data >> 8; |
214 |
msg[1] = data >> 8; |
215 |
msg[2] = data & 0xff; |
215 |
msg[2] = data & 0xff; |
216 |
|
216 |
|
217 |
/* write one byte register address to chip */ |
217 |
/* write one byte register address to chip */ |
218 |
if(usb_control_msg(handle, USB_CTRL_OUT, |
218 |
if(usb_control_msg(handle, USB_CTRL_OUT, |
219 |
CMD_I2C_IO + CMD_I2C_BEGIN + CMD_I2C_END, |
219 |
CMD_I2C_IO + CMD_I2C_BEGIN + CMD_I2C_END, |
220 |
0, addr, msg, 3, |
220 |
0, addr, msg, 3, |
221 |
1000) < 1) { |
221 |
1000) < 1) { |
222 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
222 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
223 |
return -1; |
223 |
return -1; |
224 |
} |
224 |
} |
225 |
|
225 |
|
226 |
if(i2c_tiny_usb_get_status() != STATUS_ADDRESS_ACK) { |
226 |
if(i2c_tiny_usb_get_status() != STATUS_ADDRESS_ACK) { |
227 |
fprintf(stderr, "write command status failed\n"); |
227 |
fprintf(stderr, "write command status failed\n"); |
228 |
return -1; |
228 |
return -1; |
229 |
} |
229 |
} |
230 |
|
230 |
|
231 |
return 0; |
231 |
return 0; |
232 |
} |
232 |
} |
233 |
|
233 |
|
234 |
/* read ds1621 control register */ |
234 |
/* read ds1621 control register */ |
235 |
void ds1621_read_control(void) { |
235 |
void ds1621_read_control(void) { |
236 |
int result; |
236 |
int result; |
237 |
|
237 |
|
238 |
do { |
238 |
do { |
239 |
result = i2c_read_with_cmd(DS1621_ADDR, 0xac, 1); |
239 |
result = i2c_read_with_cmd(DS1621_ADDR, 0xac, 1); |
240 |
} while(!(result & 0x80)); |
240 |
} while(!(result & 0x80)); |
241 |
} |
241 |
} |
242 |
|
242 |
|
243 |
|
243 |
|
244 |
|
244 |
|
245 |
/* main program process */ |
245 |
/* main program process */ |
246 |
|
246 |
|
247 |
|
247 |
|
248 |
int main(int argc, char *argv[]) { |
248 |
int main(int argc, char *argv[]) { |
249 |
struct usb_bus *bus; |
249 |
struct usb_bus *bus; |
250 |
struct usb_device *dev; |
250 |
struct usb_device *dev; |
251 |
int i; |
251 |
int i; |
252 |
#ifndef WIN |
252 |
#ifndef WIN |
253 |
int ret; |
253 |
int ret; |
254 |
#endif |
254 |
#endif |
255 |
|
255 |
|
256 |
printf("-- i2c-tiny-usb test application --\n"); |
256 |
printf("-- i2c-tiny-usb test application --\n"); |
257 |
printf("-- (c) 2006 by Till Harbaum --\n"); |
257 |
printf("-- (c) 2006 by Till Harbaum --\n"); |
258 |
printf("-- http://www.harbaum.org/till/i2c_tiny_usb --\n"); |
258 |
printf("-- http://www.harbaum.org/till/i2c_tiny_usb --\n"); |
259 |
|
259 |
|
260 |
usb_init(); |
260 |
usb_init(); |
261 |
|
261 |
|
262 |
usb_find_busses(); |
262 |
usb_find_busses(); |
263 |
usb_find_devices(); |
263 |
usb_find_devices(); |
264 |
|
264 |
|
265 |
for(bus = usb_get_busses(); bus; bus = bus->next) { |
265 |
for(bus = usb_get_busses(); bus; bus = bus->next) { |
266 |
for(dev = bus->devices; dev; dev = dev->next) { |
266 |
for(dev = bus->devices; dev; dev = dev->next) { |
267 |
if((dev->descriptor.idVendor == I2C_TINY_USB_VID) && |
267 |
if((dev->descriptor.idVendor == I2C_TINY_USB_VID) && |
268 |
(dev->descriptor.idProduct == I2C_TINY_USB_PID)) { |
268 |
(dev->descriptor.idProduct == I2C_TINY_USB_PID)) { |
269 |
|
269 |
|
270 |
printf("Found i2c_tiny_usb device on bus %s device %s.\n", |
270 |
printf("Found i2c_tiny_usb device on bus %s device %s.\n", |
271 |
bus->dirname, dev->filename); |
271 |
bus->dirname, dev->filename); |
272 |
|
272 |
|
273 |
/* open device */ |
273 |
/* open device */ |
274 |
if(!(handle = usb_open(dev))) |
274 |
if(!(handle = usb_open(dev))) |
275 |
fprintf(stderr, "Error: Cannot open the device: %s\n", |
275 |
fprintf(stderr, "Error: Cannot open the device: %s\n", |
276 |
usb_strerror()); |
276 |
usb_strerror()); |
277 |
|
277 |
|
278 |
break; |
278 |
break; |
279 |
} |
279 |
} |
280 |
} |
280 |
} |
281 |
} |
281 |
} |
282 |
|
282 |
|
283 |
if(!handle) { |
283 |
if(!handle) { |
284 |
fprintf(stderr, "Error: Could not find i2c_tiny_usb device\n"); |
284 |
fprintf(stderr, "Error: Could not find i2c_tiny_usb device\n"); |
285 |
|
285 |
|
286 |
#ifdef WIN |
286 |
#ifdef WIN |
287 |
printf("Press return to quit\n"); |
287 |
printf("Press return to quit\n"); |
288 |
getchar(); |
288 |
getchar(); |
289 |
#endif |
289 |
#endif |
290 |
|
290 |
|
291 |
exit(-1); |
291 |
exit(-1); |
292 |
} |
292 |
} |
293 |
|
293 |
|
294 |
#ifndef WIN |
294 |
#ifndef WIN |
295 |
/* Get exclusive access to interface 0. Does not work under windows. */ |
295 |
/* Get exclusive access to interface 0. Does not work under windows. */ |
296 |
ret = usb_claim_interface(handle, 0); |
296 |
ret = usb_claim_interface(handle, 0); |
297 |
if (ret != 0) { |
297 |
if (ret != 0) { |
298 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
298 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
299 |
|
299 |
|
300 |
exit(1); |
300 |
exit(1); |
301 |
} |
301 |
} |
302 |
#endif |
302 |
#endif |
303 |
|
303 |
|
304 |
printf("writing to adapter"); |
304 |
printf("writing to adapter"); |
305 |
i2c_tiny_usb_write(0,0,0); |
305 |
i2c_tiny_usb_write(0,0,0); |
306 |
|
306 |
|
307 |
/* do some testing */ |
307 |
/* do some testing */ |
308 |
printf("Getting adapter functionalities"); |
308 |
printf("Getting adapter functionalities"); |
309 |
i2c_tiny_usb_get_func(); |
309 |
i2c_tiny_usb_get_func(); |
310 |
|
310 |
|
311 |
/* try to set i2c clock to 100kHz (10us), will actually result in ~50kHz */ |
311 |
/* try to set i2c clock to 100kHz (10us), will actually result in ~50kHz */ |
312 |
/* since the software generated i2c clock isn't too exact. in fact setting */ |
312 |
/* since the software generated i2c clock isn't too exact. in fact setting */ |
313 |
/* it to 10us doesn't do anything at all since this already is the default */ |
313 |
/* it to 10us doesn't do anything at all since this already is the default */ |
314 |
printf("Reseting I2C clock to 100 kHz"); |
314 |
printf("Reseting I2C clock to 100 kHz"); |
315 |
i2c_tiny_usb_set(CMD_SET_DELAY, 10); |
315 |
i2c_tiny_usb_set(CMD_SET_DELAY, 10); |
316 |
|
316 |
|
317 |
/* -------- begin of ds1621 client processing --------- */ |
317 |
/* -------- begin of ds1621 client processing --------- */ |
318 |
printf("Probing for DS1621 ... "); |
318 |
printf("Probing for DS1621 ... "); |
319 |
|
319 |
|
320 |
/* try to access ds1621 at address DS1621_ADDR */ |
320 |
/* try to access ds1621 at address DS1621_ADDR */ |
321 |
if(usb_control_msg(handle, USB_CTRL_IN, |
321 |
if(usb_control_msg(handle, USB_CTRL_IN, |
322 |
CMD_I2C_IO + CMD_I2C_BEGIN + CMD_I2C_END, |
322 |
CMD_I2C_IO + CMD_I2C_BEGIN + CMD_I2C_END, |
323 |
0, DS1621_ADDR, NULL, 0, |
323 |
0, DS1621_ADDR, NULL, 0, |
324 |
1000) < 0) { |
324 |
1000) < 0) { |
325 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
325 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
326 |
goto quit; |
326 |
goto quit; |
327 |
} |
327 |
} |
328 |
|
328 |
|
329 |
if(i2c_tiny_usb_get_status() == STATUS_ADDRESS_ACK) { |
329 |
if(i2c_tiny_usb_get_status() == STATUS_ADDRESS_ACK) { |
330 |
int temp; |
330 |
int temp; |
331 |
|
331 |
|
332 |
printf("success at address 0x%02x\n", DS1621_ADDR); |
332 |
printf("success at address 0x%02x\n", DS1621_ADDR); |
333 |
|
333 |
|
334 |
/* activate one shot mode */ |
334 |
/* activate one shot mode */ |
335 |
if(i2c_write_cmd_and_byte(DS1621_ADDR, 0xac, 0x01) < 0) |
335 |
if(i2c_write_cmd_and_byte(DS1621_ADDR, 0xac, 0x01) < 0) |
336 |
goto quit; |
336 |
goto quit; |
337 |
|
337 |
|
338 |
/* wait 10ms */ |
338 |
/* wait 10ms */ |
339 |
usleep(10000); |
339 |
usleep(10000); |
340 |
|
340 |
|
341 |
#if 0 |
341 |
#if 0 |
342 |
/* write default limits */ |
342 |
/* write default limits */ |
343 |
/* high threshold: +15 deg celsius */ |
343 |
/* high threshold: +15 deg celsius */ |
344 |
i2c_write_cmd_and_word(DS1621_ADDR, 0xa1, 0x0f00); /* 15 deg celsius */ |
344 |
i2c_write_cmd_and_word(DS1621_ADDR, 0xa1, 0x0f00); /* 15 deg celsius */ |
345 |
usleep(10000); |
345 |
usleep(10000); |
346 |
/* low threshold: +10 deg celsius */ |
346 |
/* low threshold: +10 deg celsius */ |
347 |
i2c_write_cmd_and_word(DS1621_ADDR, 0xa2, 0x0a00); |
347 |
i2c_write_cmd_and_word(DS1621_ADDR, 0xa2, 0x0a00); |
348 |
usleep(10000); |
348 |
usleep(10000); |
349 |
#endif |
349 |
#endif |
350 |
|
350 |
|
351 |
/* display limits */ |
351 |
/* display limits */ |
352 |
temp = i2c_read_with_cmd(DS1621_ADDR, 0xa1, 2); |
352 |
temp = i2c_read_with_cmd(DS1621_ADDR, 0xa1, 2); |
353 |
printf("high temperature threshold = %d.%03d\n", |
353 |
printf("high temperature threshold = %d.%03d\n", |
354 |
temp>>8, 1000 * (temp & 0xff) / 256); |
354 |
temp>>8, 1000 * (temp & 0xff) / 256); |
355 |
temp = i2c_read_with_cmd(DS1621_ADDR, 0xa2, 2); |
355 |
temp = i2c_read_with_cmd(DS1621_ADDR, 0xa2, 2); |
356 |
printf("low temperature threshold = %d.%03d\n", |
356 |
printf("low temperature threshold = %d.%03d\n", |
357 |
temp>>8, 1000 * (temp & 0xff) / 256); |
357 |
temp>>8, 1000 * (temp & 0xff) / 256); |
358 |
|
358 |
|
359 |
printf("Getting %d temperature readings:\n", LOOPS); |
359 |
printf("Getting %d temperature readings:\n", LOOPS); |
360 |
for(i=0;i<LOOPS;i++) { |
360 |
for(i=0;i<LOOPS;i++) { |
361 |
int temp; |
361 |
int temp; |
362 |
int counter, slope; |
362 |
int counter, slope; |
363 |
|
363 |
|
364 |
/* just write command 0xee to start conversion */ |
364 |
/* just write command 0xee to start conversion */ |
365 |
if(i2c_read_with_cmd(DS1621_ADDR, 0xee, 0) < 0) |
365 |
if(i2c_read_with_cmd(DS1621_ADDR, 0xee, 0) < 0) |
366 |
goto quit; |
366 |
goto quit; |
367 |
|
367 |
|
368 |
ds1621_read_control(); |
368 |
ds1621_read_control(); |
369 |
|
369 |
|
370 |
temp = i2c_read_with_cmd(DS1621_ADDR, 0xaa, 2); |
370 |
temp = i2c_read_with_cmd(DS1621_ADDR, 0xaa, 2); |
371 |
if(temp < 0) |
371 |
if(temp < 0) |
372 |
goto quit; |
372 |
goto quit; |
373 |
|
373 |
|
374 |
/* read counter and slope values */ |
374 |
/* read counter and slope values */ |
375 |
counter = i2c_read_with_cmd(DS1621_ADDR, 0xa8, 1); |
375 |
counter = i2c_read_with_cmd(DS1621_ADDR, 0xa8, 1); |
376 |
slope = i2c_read_with_cmd(DS1621_ADDR, 0xa9, 1); |
376 |
slope = i2c_read_with_cmd(DS1621_ADDR, 0xa9, 1); |
377 |
|
377 |
|
378 |
/* use counter and slope to adjust temperature (see ds1621 datasheet) */ |
378 |
/* use counter and slope to adjust temperature (see ds1621 datasheet) */ |
379 |
temp = (temp & 0xff00) - 256/4; |
379 |
temp = (temp & 0xff00) - 256/4; |
380 |
temp += 256 * (slope - counter) / slope; |
380 |
temp += 256 * (slope - counter) / slope; |
381 |
|
381 |
|
382 |
printf("temp = %d.%03d\n", temp>>8, 1000 * (temp & 0xff) / 256); |
382 |
printf("temp = %d.%03d\n", temp>>8, 1000 * (temp & 0xff) / 256); |
383 |
} |
383 |
} |
384 |
} else |
384 |
} else |
385 |
printf("failed\n"); |
385 |
printf("failed\n"); |
386 |
/* -------- end of ds1621 client processing --------- */ |
386 |
/* -------- end of ds1621 client processing --------- */ |
387 |
|
387 |
|
388 |
/* -------- begin of pcf8574 client processing --------- */ |
388 |
/* -------- begin of pcf8574 client processing --------- */ |
389 |
printf("Probing for PCF8574 ... "); |
389 |
printf("Probing for PCF8574 ... "); |
390 |
|
390 |
|
391 |
/* try to access pcf8574 at address PCF8574_ADDR */ |
391 |
/* try to access pcf8574 at address PCF8574_ADDR */ |
392 |
if(usb_control_msg(handle, USB_CTRL_IN, |
392 |
if(usb_control_msg(handle, USB_CTRL_IN, |
393 |
CMD_I2C_IO + CMD_I2C_BEGIN + CMD_I2C_END, |
393 |
CMD_I2C_IO + CMD_I2C_BEGIN + CMD_I2C_END, |
394 |
0, PCF8574_ADDR, NULL, 0, |
394 |
0, PCF8574_ADDR, NULL, 0, |
395 |
1000) < 0) { |
395 |
1000) < 0) { |
396 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
396 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
397 |
goto quit; |
397 |
goto quit; |
398 |
} |
398 |
} |
399 |
|
399 |
|
400 |
if(i2c_tiny_usb_get_status() == STATUS_ADDRESS_ACK) { |
400 |
if(i2c_tiny_usb_get_status() == STATUS_ADDRESS_ACK) { |
401 |
unsigned char bit_mask = 0xfe; |
401 |
unsigned char bit_mask = 0xfe; |
402 |
|
402 |
|
403 |
printf("success at address 0x%02x\n", PCF8574_ADDR); |
403 |
printf("success at address 0x%02x\n", PCF8574_ADDR); |
404 |
|
404 |
|
405 |
printf("Cycling 0 bit %d times.\n", LOOPS); |
405 |
printf("Cycling 0 bit %d times.\n", LOOPS); |
406 |
/* just rotate a single 0 bit through the outputs */ |
406 |
/* just rotate a single 0 bit through the outputs */ |
407 |
|
407 |
|
408 |
for(i=0;i<LOOPS;i++) { |
408 |
for(i=0;i<LOOPS;i++) { |
409 |
if(i2c_write_byte(PCF8574_ADDR, bit_mask) < 0) |
409 |
if(i2c_write_byte(PCF8574_ADDR, bit_mask) < 0) |
410 |
goto quit; |
410 |
goto quit; |
411 |
|
411 |
|
412 |
/* rotate the byte */ |
412 |
/* rotate the byte */ |
413 |
bit_mask = (bit_mask << 1) | 1; |
413 |
bit_mask = (bit_mask << 1) | 1; |
414 |
if(bit_mask == 0xff) |
414 |
if(bit_mask == 0xff) |
415 |
bit_mask = 0xfe; |
415 |
bit_mask = 0xfe; |
416 |
|
416 |
|
417 |
usleep(100000); |
417 |
usleep(100000); |
418 |
} |
418 |
} |
419 |
} else |
419 |
} else |
420 |
printf("failed\n"); |
420 |
printf("failed\n"); |
421 |
/* -------- end of pcf8574 client processing --------- */ |
421 |
/* -------- end of pcf8574 client processing --------- */ |
422 |
|
422 |
|
423 |
quit: |
423 |
quit: |
424 |
#ifndef WIN |
424 |
#ifndef WIN |
425 |
ret = usb_release_interface(handle, 0); |
425 |
ret = usb_release_interface(handle, 0); |
426 |
if (ret) |
426 |
if (ret) |
427 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
427 |
fprintf(stderr, "USB error: %s\n", usb_strerror()); |
428 |
#endif |
428 |
#endif |
429 |
|
429 |
|
430 |
usb_close(handle); |
430 |
usb_close(handle); |
431 |
|
431 |
|
432 |
#ifdef WIN |
432 |
#ifdef WIN |
433 |
printf("Press return to quit\n"); |
433 |
printf("Press return to quit\n"); |
434 |
getchar(); |
434 |
getchar(); |
435 |
#endif |
435 |
#endif |
436 |
|
436 |
|
437 |
return 0; |
437 |
return 0; |
438 |
} |
438 |
} |