-
Notifications
You must be signed in to change notification settings - Fork 2
/
lascar.c
141 lines (110 loc) · 3.6 KB
/
lascar.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include "lascar.h"
float get_temp(unsigned int t, int get_f) {
float rt = -200.0;
for(; t>0; t--) {
rt += STEPT;
}
if(get_f) {
rt = (rt * (9.0/5.0)) + 32;
}
return rt;
}
float get_hum(unsigned char h) {
float rh = 0;
for(; h>0x00; h--) {
rh+= STEPH;
}
return rh;
}
hid_return
get_reading(HIDInterface* hid, char* packet,
float* temp, float* hum, int get_f) {
return get_reading_r(hid, packet, temp, hum, get_f, 1);
}
hid_return
get_reading_r(HIDInterface* hid, char* packet,
float* temp, float* hum, int get_f, int retries) {
hid_return ret;
/*
* The temperature and humidity values are always sent one after the other,
* i.e. there is no way to request the same value back to back; you're
* going to get temp, hum, temp, hum, [...]. We know simply know if the
* data retrieved has 3 bytes it's temperature and if it has two bytes it's
* humidity.
*
* If we grab the temperature first and it fails, we can assume the device
* sent us humidity, so throw it out and re-request the data. If for some
* reason the subsequent request fails, then there is a problem and return
* an error.
*/
if((ret=read_device(hid, packet, TEMPERATURE)) != HID_RET_SUCCESS) {
if(ret == 21 && retries) {
/*fprintf(stderr, "Retrying on error 21\n");*/
return get_reading_r(hid, packet, temp, hum, get_f, --retries);
} else {
fprintf(stderr, "Unable to read temperature (%d)\n", TEMPERATURE);
return ret;
}
}
*temp = get_temp(pack((unsigned)packet[2], (unsigned)packet[1]), get_f);
if((ret=read_device(hid, packet, HUMIDITY)) != HID_RET_SUCCESS) {
fprintf(stderr, "Unable to read humidity (%d)\n", HUMIDITY);
return ret;
}
*hum = get_hum((unsigned)packet[1]);
/* check to make sure the values found are within spec, otherwise retry */
if(*temp >= -200.0 && *temp <= 200.0 && *hum >= 0.0 && *hum <= 100.0) {
return ret;
} else if(retries) {
/* if the values were bad, try another two times before giving up */
/*fprintf(stderr,
"Bad values for temp (%.1f) and hum (%.1f)\n", temp, hum);*/
return get_reading_r(hid, packet, temp, hum, get_f, 2);
} else {
return HID_RET_NOT_FOUND;
}
}
HIDInterface* init_termo(HIDInterface* hid) {
HIDInterfaceMatcher matcher = dev_id;
hid_return i;
i = hid_init();
if(i != HID_RET_SUCCESS) {
fprintf(stderr, "Could not init HID\n");
hid = NULL;
}
hid = hid_new_HIDInterface();
i = hid_force_open(hid, 0, &matcher, 3);
if(i != HID_RET_SUCCESS) {
fprintf(stderr, "Unable to open device\n");
hid = NULL;
}
return hid;
}
hid_return restore_termo(HIDInterface* hid) {
hid_return i;
i = hid_close(hid);
if(i != HID_RET_SUCCESS) {
fprintf(stderr, "hid_close failed with return code %d\n", i);
}
hid_delete_HIDInterface(&hid);
i = hid_cleanup();
if(i != HID_RET_SUCCESS) {
fprintf(stderr, "hid_cleanup failed with return code %d\n", i);
}
return i;
}
hid_return read_device(HIDInterface* hid, char* buf, int size) {
hid_return i;
i = hid_interrupt_read(hid, EP_HID_IN, buf, size, espera);
if(i != HID_RET_SUCCESS) {
fprintf(stderr, "hid_get_input_report failed with return code %d\n", i);
}
return i;
}
unsigned int pack(unsigned char a, unsigned char b) {
unsigned int packed;
packed = a;
packed <<= 8;
packed |= b;
return packed;
}