Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
e9c521c0e4 | |||
ed51155640 | |||
9d010120d5 | |||
5d15838757 |
201
Cargo.lock
generated
201
Cargo.lock
generated
@ -1,21 +1,126 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.169"
|
||||
version = "0.2.159"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
|
||||
|
||||
[[package]]
|
||||
name = "libusb-sys"
|
||||
version = "0.2.3"
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c53b6582563d64ad3e692f54ef95239c3ea8069e82c9eb70ca948869a7ad767"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -24,10 +129,88 @@ version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "sensor"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"cc",
|
||||
"libc",
|
||||
"libusb-sys",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||
|
11
Cargo.toml
11
Cargo.toml
@ -2,13 +2,12 @@
|
||||
name = "sensor"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
#build = "build.rs"
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
libusb-sys = "0.2"
|
||||
|
||||
#[build-dependencies]
|
||||
#cc = { version = "1.0", features = ["parallel"] }
|
||||
#bindgen = { version = "0.59", default-features = false}
|
||||
#pkg-config = "0.3"
|
||||
[build-dependencies]
|
||||
cc = { version = "1.1", features = ["parallel"] }
|
||||
bindgen = { version = "0.70", default-features = false }
|
||||
pkg-config = "0.3"
|
||||
|
61
README.md
61
README.md
@ -1,61 +0,0 @@
|
||||
# sensor
|
||||
|
||||
## Summary
|
||||
|
||||
PCSensor temper with Rust and C bindings
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
* libclang-dev
|
||||
* libusb-1.0-0-dev
|
||||
|
||||
## Howto
|
||||
|
||||
### Dev Run
|
||||
|
||||
```
|
||||
cargo r
|
||||
```
|
||||
|
||||
### Build
|
||||
|
||||
```bash
|
||||
cargo b -r
|
||||
```
|
||||
|
||||
|
||||
## TODO
|
||||
|
||||
|
||||
|
||||
## License
|
||||
|
||||
```text
|
||||
Copyright (c) 2022, 2023 PaulBSD
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of this project.
|
||||
```
|
@ -1,8 +1,8 @@
|
||||
extern crate bindgen;
|
||||
use cc;
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=src/pcsensor.c");
|
||||
@ -14,7 +14,7 @@ fn main() {
|
||||
fn bind() {
|
||||
let bindings = bindgen::Builder::default()
|
||||
.header("/usr/include/libusb-1.0/libusb.h")
|
||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
|
||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
|
||||
.generate()
|
||||
.expect("Unable to generate bindings");
|
||||
|
||||
@ -26,10 +26,10 @@ fn bind() {
|
||||
|
||||
fn compile_pcsensor() {
|
||||
cc::Build::new()
|
||||
.file("src/pcsensor.c")
|
||||
.shared_flag(true)
|
||||
.static_flag(true)
|
||||
.compile("pcsensor");
|
||||
.file("src/pcsensor.c")
|
||||
.shared_flag(true)
|
||||
.static_flag(true)
|
||||
.compile("pcsensor");
|
||||
}
|
||||
|
||||
fn link() {
|
@ -2,4 +2,4 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
//include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||
|
19
src/main.rs
19
src/main.rs
@ -1,14 +1,13 @@
|
||||
pub mod temp;
|
||||
use libc;
|
||||
|
||||
use temp::*;
|
||||
|
||||
//#[link(name = "pcsensor")]
|
||||
//#[link(name = "usb-1.0")]
|
||||
//extern "C" {
|
||||
// fn get_temp_c() -> libc::c_float;
|
||||
//}
|
||||
#[link(name = "pcsensor")]
|
||||
#[link(name = "usb-1.0")]
|
||||
extern "C" {
|
||||
fn get_temp_c() -> libc::c_float;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let temperature = get_temp_r();
|
||||
println!("{}", temperature);
|
||||
unsafe {
|
||||
println!("{}", get_temp_c());
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ typedef struct {
|
||||
const int has_sensor; // number of temperature sensor
|
||||
const int has_humid; // flag for humidity sensor
|
||||
void (*decode_func)();
|
||||
float divisor;
|
||||
} temper_type_t;
|
||||
|
||||
typedef struct {
|
||||
@ -29,15 +30,24 @@ typedef struct {
|
||||
temper_type_t *type;
|
||||
} temper_device_t;
|
||||
|
||||
void decode_answer_fm75();
|
||||
void decode_answer_sht1x();
|
||||
void decode_answer();
|
||||
|
||||
#define TEMPER_TYPES 4
|
||||
|
||||
const char GetFirmware[8] = { 0x01, 0x86, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00 };
|
||||
const char GetTemperature[8] = { 0x01, 0x80, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00 };
|
||||
//#define Temperature { 0x01, 0x82, 0x77, 0x01, 0x00, 0x00, 0x00, 0x00 }
|
||||
|
||||
//const char uTemperature1[8] = { 0x01, 0x80, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00 };
|
||||
//const char uTemperature2[8] = { 0x01, 0x82, 0x77, 0x01, 0x00, 0x00, 0x00, 0x00 };
|
||||
//const char uTemperature3[8] = { 0x01, 0x86, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
#define TEMPER_TYPES 3
|
||||
|
||||
temper_type_t tempers[TEMPER_TYPES] = {
|
||||
{0x0c45, 0x7401, "TEMPer2", 1, 2, 0, decode_answer_fm75}, // TEMPer2* eg. TEMPer2V1.3
|
||||
{0x0c45, 0x7401, "TEMPer1", 0, 1, 0, decode_answer_fm75}, // other 0c45:7401 eg. TEMPerV1.4
|
||||
{0x0c45, 0x7402, "TEMPerHUM", 0, 1, 1, decode_answer_sht1x},
|
||||
{0x1a86, 0xe025, "TEMPerGold", 1, 1, 0, decode_answer, 100.0},
|
||||
{0x0c45, 0x7401, "TEMPer2", 1, 2, 0, decode_answer, 256.0},
|
||||
{0x0c45, 0x7401, "TEMPer1", 0, 1, 0, decode_answer, 256.0},
|
||||
//{0x0c45, 0x7402, "TEMPerHUM", 0, 1, 1, decode_answer_sht1x, 100.0},
|
||||
};
|
||||
|
||||
/* memo: TEMPer2 cannot be distinguished with VID:PID,
|
||||
@ -51,12 +61,9 @@ temper_type_t tempers[TEMPER_TYPES] = {
|
||||
#define INTERFACE2 0x01
|
||||
|
||||
const int reqIntLen = 8;
|
||||
const int endpoint_Int_in = 0x82; /* endpoint 0x81 address for IN */
|
||||
const int timeout = 5000; /* timeout in ms */
|
||||
|
||||
const char uTemperature[] = {0x01, 0x80, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00};
|
||||
//const static char uIni1[] = { 0x01, 0x82, 0x77, 0x01, 0x00, 0x00, 0x00, 0x00 };
|
||||
//const static char uIni2[] = { 0x01, 0x86, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00 };
|
||||
const int endpoint_Int_out = 0x02;
|
||||
const int endpoint_Int_in = 0x82;
|
||||
const int timeout = 300; /* timeout in ms */
|
||||
|
||||
static int bsalir = 1;
|
||||
static int debug = 0;
|
||||
@ -156,7 +163,6 @@ int find_lvr_winusb(temper_device_t *devices) {
|
||||
}
|
||||
|
||||
int setup_libusb_access(temper_device_t *devices) {
|
||||
int i;
|
||||
int log_level = 0;
|
||||
int numdev;
|
||||
|
||||
@ -176,10 +182,10 @@ int setup_libusb_access(temper_device_t *devices) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < numdev; i++) {
|
||||
for (int i = 0; i < numdev; i++) {
|
||||
usb_detach(devices[i].handle, INTERFACE1);
|
||||
usb_detach(devices[i].handle, INTERFACE2);
|
||||
libusb_reset_device(devices[i].handle);
|
||||
//libusb_reset_device(devices[i].handle);
|
||||
|
||||
if (libusb_set_configuration(devices[i].handle, 0x01) < 0) {
|
||||
fprintf(stderr, "Could not set configuration 1\n");
|
||||
@ -201,25 +207,6 @@ int setup_libusb_access(temper_device_t *devices) {
|
||||
return numdev;
|
||||
}
|
||||
|
||||
void ini_control_transfer(libusb_device_handle *dev) {
|
||||
int r, i;
|
||||
|
||||
char question[reqIntLen];
|
||||
question[0] = 0x01;
|
||||
question[1] = 0x01;
|
||||
|
||||
r = libusb_control_transfer(dev, 0x21, 0x09, 0x0201, 0x00, (unsigned char *)question, 2, timeout);
|
||||
if (r < 0) {
|
||||
perror("USB control write");
|
||||
bad("USB write failed");
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
for (i = 0; i < reqIntLen; i++) fprintf(stderr, "%02x ", question[i] & 0xFF);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
void control_transfer(libusb_device_handle *dev, const char *pquestion) {
|
||||
int r, i;
|
||||
|
||||
@ -230,7 +217,7 @@ void control_transfer(libusb_device_handle *dev, const char *pquestion) {
|
||||
r = libusb_control_transfer(dev, 0x21, 0x09, 0x0200, 0x01, (unsigned char *)question, reqIntLen, timeout);
|
||||
if (r < 0) {
|
||||
perror("USB control write");
|
||||
bad("USB write failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
@ -240,15 +227,25 @@ void control_transfer(libusb_device_handle *dev, const char *pquestion) {
|
||||
}
|
||||
}
|
||||
|
||||
void interrupt_read(libusb_device_handle *dev, unsigned char *answer) {
|
||||
void interrupt_read(libusb_device_handle *dev, unsigned char *answer, const char *pquestion, const char *product_name) {
|
||||
int r, s, i;
|
||||
char question[reqIntLen];
|
||||
|
||||
memset(answer, 0, reqIntLen);
|
||||
memcpy(question, pquestion, sizeof question);
|
||||
|
||||
s = libusb_interrupt_transfer(dev, endpoint_Int_in, answer, reqIntLen, &r, timeout);
|
||||
if (r != reqIntLen) {
|
||||
fprintf(stderr, "USB read failed: %d\n", s);
|
||||
|
||||
if (strcmp(product_name, "TEMPerGold") == 0) {
|
||||
libusb_interrupt_transfer(dev, endpoint_Int_out, (unsigned char *)question, reqIntLen, &r, timeout);
|
||||
s = libusb_interrupt_transfer(dev, endpoint_Int_in, answer, reqIntLen, &r, timeout);
|
||||
}
|
||||
|
||||
if (s != 0) {
|
||||
fprintf(stderr, "USB read failed: %s\n", libusb_error_name(s));
|
||||
perror("USB interrupt read");
|
||||
bad("USB read failed");
|
||||
exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
@ -260,12 +257,13 @@ void interrupt_read(libusb_device_handle *dev, unsigned char *answer) {
|
||||
}
|
||||
|
||||
void cleanup_usb_devices(temper_device_t *devices, int numdev) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numdev; i++) {
|
||||
for (int i = 0; i < numdev; i++) {
|
||||
libusb_release_interface(devices[i].handle, INTERFACE1);
|
||||
libusb_release_interface(devices[i].handle, INTERFACE2);
|
||||
|
||||
libusb_attach_kernel_driver(devices[i].handle, INTERFACE1);
|
||||
libusb_attach_kernel_driver(devices[i].handle, INTERFACE2);
|
||||
|
||||
libusb_close(devices[i].handle);
|
||||
}
|
||||
|
||||
@ -278,24 +276,22 @@ void ex_program() {
|
||||
(void)signal(SIGINT, SIG_DFL);
|
||||
}
|
||||
|
||||
/* decode funcs */
|
||||
/* Thanks to https://github.com/edorfaus/TEMPered */
|
||||
|
||||
void decode_answer_fm75(unsigned char *answer, float *tempd, float *calibration) {
|
||||
void decode_answer(unsigned char *answer, float *divisor, float *tempd, float *calibration) {
|
||||
int buf;
|
||||
|
||||
// temp C internal
|
||||
buf = ((signed char)answer[2] << 8) + (answer[3] & 0xFF);
|
||||
tempd[0] = buf * (125.0 / 32000.0);
|
||||
tempd[0] = buf / *divisor;
|
||||
tempd[0] = tempd[0] * calibration[0] + calibration[1];
|
||||
|
||||
// temp C external
|
||||
buf = ((signed char)answer[4] << 8) + (answer[5] & 0xFF);
|
||||
tempd[1] = buf * (125.0 / 32000.0);
|
||||
tempd[1] = buf / *divisor;
|
||||
tempd[1] = tempd[1] * calibration[0] + calibration[1];
|
||||
}
|
||||
|
||||
void decode_answer_sht1x(unsigned char *answer, float *tempd, float *calibration) {
|
||||
/*
|
||||
void decode_answer_sht1x(unsigned char *answer, float *divisor, float *tempd, float *calibration) {
|
||||
int buf;
|
||||
|
||||
// temp C
|
||||
@ -307,13 +303,17 @@ void decode_answer_sht1x(unsigned char *answer, float *tempd, float *calibration
|
||||
buf = ((signed char)answer[4] << 8) + (answer[5] & 0xFF);
|
||||
tempd[1] = -2.0468 + 0.0367 * buf - 1.5955e-6 * buf * buf;
|
||||
tempd[1] = (tempd[0] - 25) * (0.01 + 0.00008 * buf) + tempd[1];
|
||||
if (tempd[1] < 0) tempd[1] = 0;
|
||||
if (tempd[1] > 99) tempd[1] = 100;
|
||||
if (tempd[1] < 0)
|
||||
tempd[1] = 0;
|
||||
if (tempd[1] > 99)
|
||||
tempd[1] = 100;
|
||||
}
|
||||
*/
|
||||
|
||||
float get_temp_c() {
|
||||
temper_device_t *devices;
|
||||
int numdev, i;
|
||||
int numdev;
|
||||
int i = 0;
|
||||
unsigned char *answer;
|
||||
float tempd[2];
|
||||
float calibration[2] = {1, 0};
|
||||
@ -327,10 +327,9 @@ float get_temp_c() {
|
||||
|
||||
answer = calloc(reqIntLen, sizeof(unsigned char));
|
||||
|
||||
i = 0;
|
||||
control_transfer(devices[i].handle, uTemperature);
|
||||
interrupt_read(devices[i].handle, answer);
|
||||
devices[i].type->decode_func(answer, tempd, calibration);
|
||||
control_transfer(devices[i].handle, GetTemperature);
|
||||
interrupt_read(devices[i].handle, answer, GetTemperature, devices[i].type->product_name);
|
||||
devices[i].type->decode_func(answer, &devices[i].type->divisor, tempd, calibration);
|
||||
|
||||
cleanup_usb_devices(devices, numdev);
|
||||
|
459
src/temp.rs
459
src/temp.rs
@ -1,459 +0,0 @@
|
||||
use std::ffi::CStr;
|
||||
use std::ptr::{null_mut, slice_from_raw_parts};
|
||||
|
||||
use libusb_sys::*;
|
||||
|
||||
const MAX_DEV: usize = 8;
|
||||
const INTERFACE1: i32 = 0x00;
|
||||
const INTERFACE2: i32 = 0x01;
|
||||
|
||||
const REQINTLEN: usize = 8;
|
||||
const ENDPOINT_INT_IN: u8 = 0x82;
|
||||
const TIMEOUT: u32 = 5000;
|
||||
|
||||
const UTEMPERATURE: &[u8; 8] = &[0x01, 0x80, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00];
|
||||
|
||||
static mut DEBUG: bool = false;
|
||||
|
||||
const TEMPER_TYPES: usize = 3;
|
||||
|
||||
const TEMPERS: [TemperType; TEMPER_TYPES] = [
|
||||
TemperType {
|
||||
vendor_id: 0x0c45,
|
||||
product_id: 0x7401,
|
||||
product_name: "TEMPer2",
|
||||
check_product_name: true,
|
||||
has_sensor: true,
|
||||
has_humid: false,
|
||||
}, // TEMPer2* eg. TEMPer2V1.3
|
||||
TemperType {
|
||||
vendor_id: 0x0c45,
|
||||
product_id: 0x7401,
|
||||
//product_name: "TEMPer1",
|
||||
product_name: "TEMPerV1.4",
|
||||
check_product_name: false,
|
||||
has_sensor: true,
|
||||
has_humid: false,
|
||||
}, // other 0c45:7401 eg. TEMPerV1.4
|
||||
TemperType {
|
||||
vendor_id: 0x0c45,
|
||||
product_id: 0x7402,
|
||||
product_name: "TEMPerHUM",
|
||||
check_product_name: false,
|
||||
has_sensor: true,
|
||||
has_humid: true,
|
||||
}, //decode_answer_sht1x},
|
||||
];
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TemperType {
|
||||
pub vendor_id: u16,
|
||||
pub product_id: u16,
|
||||
pub product_name: &'static str,
|
||||
pub check_product_name: bool,
|
||||
pub has_sensor: bool,
|
||||
pub has_humid: bool,
|
||||
}
|
||||
|
||||
impl TemperType {
|
||||
pub fn decode(&self, answer: &[u8; 100], tempd: &mut [f32; 2], calibration: &[f32; 2]) {
|
||||
match self.product_name {
|
||||
"TEMPer2" => self.decode_answer_fm75(answer, tempd, calibration),
|
||||
"TEMPerV1.4" => self.decode_answer_fm75(answer, tempd, calibration),
|
||||
_ => self.decode_answer_fm75(answer, tempd, calibration),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decode_answer_fm75(
|
||||
&self,
|
||||
answer: &[u8; 100],
|
||||
tempd: &mut [f32; 2],
|
||||
calibration: &[f32; 2],
|
||||
) {
|
||||
let mut buf: u16;
|
||||
|
||||
buf = ((answer[2] as u16) << 8) + ((answer[3] as u16) & 0xFF);
|
||||
tempd[0] = buf as f32 * (125.0 / 32000.0);
|
||||
tempd[0] = tempd[0] * calibration[0] + calibration[1];
|
||||
|
||||
buf = ((answer[4] as u16) << 8) as u16 + ((answer[5] as u16) & 0xFF) as u16;
|
||||
tempd[1] = buf as f32 * (125.0 / 32000.0);
|
||||
tempd[1] = tempd[1] * calibration[0] + calibration[1];
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for TemperType {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
vendor_id: 0,
|
||||
product_id: 0,
|
||||
product_name: "",
|
||||
check_product_name: true,
|
||||
has_sensor: false,
|
||||
has_humid: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Copy for TemperType {}
|
||||
|
||||
impl std::fmt::Display for TemperType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"vendor_id: {}, product_id: {}, product_name: {}",
|
||||
self.vendor_id, self.product_id, self.product_name
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TemperDevice {
|
||||
handle: *mut *mut libusb_device_handle,
|
||||
t: TemperType,
|
||||
}
|
||||
|
||||
impl Copy for TemperDevice {}
|
||||
|
||||
impl Default for TemperDevice {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
handle: null_mut(),
|
||||
t: TemperType::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for TemperDevice {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{}", self.t)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn usb_detach(lvr_winusb: *mut libusb_device_handle, i_interface: i32) {
|
||||
let ret;
|
||||
|
||||
unsafe {
|
||||
ret = libusb_detach_kernel_driver(lvr_winusb, i_interface);
|
||||
}
|
||||
if ret == LIBUSB_ERROR_NOT_FOUND {
|
||||
unsafe {
|
||||
if DEBUG {
|
||||
println!("Device already detached");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_lvr_winusb(ctx: *mut *mut libusb_context, devices: &mut Vec<TemperDevice>) -> isize {
|
||||
let mut devs_raw: *const *mut libusb_device = null_mut();
|
||||
let cnt: usize;
|
||||
|
||||
unsafe { cnt = libusb_get_device_list(*ctx, &mut devs_raw) as usize };
|
||||
if cnt < 1 {
|
||||
println!("Could not find USB device: {}", cnt);
|
||||
}
|
||||
|
||||
let mut i = 0usize;
|
||||
let mut numdev = 0;
|
||||
|
||||
let devs_tmp;
|
||||
unsafe {
|
||||
devs_tmp = &*slice_from_raw_parts(devs_raw, cnt);
|
||||
}
|
||||
let devs: &mut [*mut libusb_device; 16] = &mut [null_mut(); 16];
|
||||
for i in 0usize..cnt as usize {
|
||||
devs[i] = devs_tmp[i];
|
||||
}
|
||||
|
||||
while i < cnt && numdev < MAX_DEV {
|
||||
let mut desc: libusb_device_descriptor;
|
||||
/*let mut desc = libusb_device_descriptor {
|
||||
bLength: 0,
|
||||
bDescriptorType: 0,
|
||||
bcdUSB: 0,
|
||||
bDeviceClass: 0,
|
||||
bDeviceSubClass: 0,
|
||||
bDeviceProtocol: 0,
|
||||
bMaxPacketSize0: 0,
|
||||
idVendor: 0,
|
||||
idProduct: 0,
|
||||
bcdDevice: 0,
|
||||
iManufacturer: 0,
|
||||
iProduct: 0,
|
||||
iSerialNumber: 0,
|
||||
bNumConfigurations: 0,
|
||||
};*/
|
||||
|
||||
unsafe {
|
||||
desc = std::mem::zeroed();
|
||||
}
|
||||
|
||||
let s;
|
||||
unsafe {
|
||||
s = libusb_get_device_descriptor(
|
||||
devs[i],
|
||||
&mut desc as *mut _ as *mut libusb_device_descriptor,
|
||||
);
|
||||
}
|
||||
if s < 0 {
|
||||
println!("Could not get USB device descriptor: {}", s);
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
for temper in TEMPERS {
|
||||
if desc.idVendor == temper.vendor_id && desc.idProduct == temper.product_id {
|
||||
let bus: u8;
|
||||
let addr: u8;
|
||||
|
||||
let mut descmanu_b: [u8; 100] = [0; 100];
|
||||
let mut descprod_b: [u8; 100] = [0; 100];
|
||||
let mut descseri_b: [u8; 100] = [0; 100];
|
||||
|
||||
bus = libusb_get_bus_number(devs[i]);
|
||||
addr = libusb_get_device_address(devs[i]);
|
||||
|
||||
let mut handle: *mut libusb_device_handle = null_mut();
|
||||
let s = libusb_open(devs[i], &mut handle);
|
||||
if s != 0 {
|
||||
println!("error open {}", s);
|
||||
}
|
||||
|
||||
libusb_get_string_descriptor_ascii(
|
||||
handle,
|
||||
desc.iManufacturer,
|
||||
descmanu_b.as_mut_ptr(),
|
||||
256,
|
||||
);
|
||||
|
||||
libusb_get_string_descriptor_ascii(
|
||||
handle,
|
||||
desc.iProduct,
|
||||
descprod_b.as_mut_ptr(),
|
||||
256,
|
||||
);
|
||||
libusb_get_string_descriptor_ascii(
|
||||
handle,
|
||||
desc.iSerialNumber,
|
||||
descseri_b.as_mut_ptr(),
|
||||
256,
|
||||
);
|
||||
|
||||
let descmanu: &CStr = CStr::from_bytes_until_nul(&descmanu_b).unwrap();
|
||||
let descprod: &CStr = CStr::from_bytes_until_nul(&descprod_b).unwrap();
|
||||
let descseri: &CStr = CStr::from_bytes_until_nul(&descseri_b).unwrap();
|
||||
|
||||
let mut device = TemperDevice::default();
|
||||
|
||||
if temper.check_product_name {
|
||||
if descprod.to_str().unwrap() == temper.product_name {
|
||||
device.handle = &mut handle;
|
||||
device.t = temper;
|
||||
devices.push(device);
|
||||
} else {
|
||||
libusb_close(handle);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
device.handle = &mut handle;
|
||||
device.t = temper;
|
||||
devices.push(device);
|
||||
}
|
||||
|
||||
if DEBUG {
|
||||
println!(
|
||||
"{} {} {} {} {} {} {}",
|
||||
bus,
|
||||
addr,
|
||||
desc.idVendor,
|
||||
desc.idProduct,
|
||||
descmanu.to_str().unwrap(),
|
||||
descprod.to_str().unwrap(),
|
||||
descseri.to_str().unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
numdev += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
numdev as isize
|
||||
}
|
||||
|
||||
pub fn setup_libusb_access(
|
||||
ctx: &mut *mut libusb_context,
|
||||
devices: &mut Vec<TemperDevice>,
|
||||
) -> isize {
|
||||
let numdev;
|
||||
|
||||
unsafe {
|
||||
{
|
||||
let res = libusb_init(ctx);
|
||||
if res != 0 {
|
||||
println!("Error code {res}: failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
numdev = find_lvr_winusb(ctx, devices);
|
||||
}
|
||||
if numdev < 1 {
|
||||
println!("Couldn't find the USB device, Exiting: {}", numdev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for device in devices.iter() {
|
||||
let handle = device.handle;
|
||||
unsafe {
|
||||
usb_detach(*handle, INTERFACE1);
|
||||
usb_detach(*handle, INTERFACE2);
|
||||
}
|
||||
|
||||
let cfg;
|
||||
unsafe {
|
||||
libusb_reset_device(*device.handle);
|
||||
cfg = libusb_set_configuration(*device.handle, 0x01);
|
||||
}
|
||||
|
||||
if cfg < 0 {
|
||||
println!("Could not set configuration 1");
|
||||
return -1;
|
||||
}
|
||||
|
||||
let mut s;
|
||||
|
||||
unsafe { s = libusb_claim_interface(*device.handle, INTERFACE1) }
|
||||
if s < 0 {
|
||||
println!("Could not claim interface. Error: {}", s);
|
||||
return -1;
|
||||
}
|
||||
unsafe { s = libusb_claim_interface(*device.handle, INTERFACE2) }
|
||||
if s < 0 {
|
||||
println!("Could not claim interface. Error: {}", s);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
numdev as isize
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub fn ini_control_transfer(dev: &mut TemperDevice) {
|
||||
let r;
|
||||
|
||||
let mut question: [u8; REQINTLEN] = [0; REQINTLEN];
|
||||
question[0] = 0x01;
|
||||
question[1] = 0x01;
|
||||
|
||||
unsafe {
|
||||
r = libusb_control_transfer(
|
||||
*dev.handle,
|
||||
0x21,
|
||||
0x09,
|
||||
0x0201,
|
||||
0x00,
|
||||
question.as_mut_ptr(),
|
||||
REQINTLEN as u16,
|
||||
TIMEOUT,
|
||||
);
|
||||
}
|
||||
if r < 0 {
|
||||
println!("USB control write")
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub fn control_transfer(dev: &mut TemperDevice, pquestion: &[u8; 8]) {
|
||||
let r;
|
||||
let mut question = pquestion.clone();
|
||||
let question: *mut u8 = question.as_mut_ptr();
|
||||
|
||||
unsafe {
|
||||
r = libusb_control_transfer(
|
||||
*dev.handle,
|
||||
0x21,
|
||||
0x09,
|
||||
0x0200,
|
||||
0x01,
|
||||
question,
|
||||
REQINTLEN as u16,
|
||||
TIMEOUT,
|
||||
);
|
||||
}
|
||||
|
||||
if r < 0 {
|
||||
println!("USB control write")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn interrupt_read(dev: &mut TemperDevice, data: &mut [u8; 100]) {
|
||||
let (s, _i): (i32, i32);
|
||||
let mut transferred: i32 = 0i32;
|
||||
|
||||
unsafe {
|
||||
s = libusb_interrupt_transfer(
|
||||
*dev.handle,
|
||||
ENDPOINT_INT_IN,
|
||||
data.as_mut_ptr(),
|
||||
REQINTLEN as i32,
|
||||
&mut transferred,
|
||||
TIMEOUT,
|
||||
);
|
||||
}
|
||||
|
||||
if transferred != REQINTLEN as i32 {
|
||||
println!("USB read failed: {}", s);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cleanup_usb_devices(ctx: &mut *mut libusb_context, devices: &mut Vec<TemperDevice>) {
|
||||
for device in devices {
|
||||
unsafe {
|
||||
libusb_release_interface(*device.handle, INTERFACE1);
|
||||
libusb_release_interface(*device.handle, INTERFACE2);
|
||||
|
||||
libusb_close(*device.handle);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
libusb_exit(*ctx);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_temp_r() -> String {
|
||||
let mut ctx: libusb_context = unsafe { std::mem::zeroed() };
|
||||
let mut ctx = &mut ctx as *mut _ as *mut libusb_context;
|
||||
|
||||
let mut answer: &mut [u8; 100] = &mut [0; 100];
|
||||
let mut tempd: &mut [f32; 2] = &mut [0.; 2];
|
||||
let calibration: &[f32; 2] = &[1., 0.];
|
||||
|
||||
let mut results: Vec<String> = vec![];
|
||||
let output: String;
|
||||
|
||||
let mut devices: Vec<TemperDevice> = vec![];
|
||||
setup_libusb_access(&mut ctx, &mut devices);
|
||||
|
||||
for device in devices.iter_mut() {
|
||||
unsafe {
|
||||
if DEBUG {
|
||||
println!("{:?}", device.t);
|
||||
}
|
||||
}
|
||||
control_transfer(device, &UTEMPERATURE);
|
||||
interrupt_read(device, &mut answer);
|
||||
|
||||
device.t.decode(&answer, &mut tempd, calibration);
|
||||
results.push(format!("{}", tempd[0]));
|
||||
}
|
||||
|
||||
cleanup_usb_devices(&mut ctx, &mut devices);
|
||||
output = results.join(",");
|
||||
|
||||
return output;
|
||||
}
|
Loading…
Reference in New Issue
Block a user