From e977311a20cf5863e747f99e47c9326c5e763ac0 Mon Sep 17 00:00:00 2001 From: Lars Weber Date: Fri, 7 Sep 2018 07:30:15 +0200 Subject: [PATCH 1/8] Added support for 413d:2107 TEMPerGold_V3.1 --- libtempered/temper_type.c | 52 +++++++++++++++++++++++++++++++++++ libtempered/type_hid/simple.c | 30 ++++++++++++++++++++ libtempered/type_hid/simple.h | 13 +++++++++ 3 files changed, 95 insertions(+) create mode 100644 libtempered/type_hid/simple.c create mode 100644 libtempered/type_hid/simple.h diff --git a/libtempered/temper_type.c b/libtempered/temper_type.c index 1b00b20..3072f1c 100644 --- a/libtempered/temper_type.c +++ b/libtempered/temper_type.c @@ -10,6 +10,7 @@ #include "type_hid/sht1x.h" #include "type_hid/ntc.h" #include "type_hid/si7005.h" +#include "type_hid/simple.h" // This is an array of known TEMPer types. struct temper_type known_temper_types[]={ @@ -407,6 +408,57 @@ struct temper_type known_temper_types[]={ NULL // List terminator for subtypes } }, + { + .name="TEMPerGold_V3.1", + .vendor_id=0x413d, + .product_id=0x2107, + .interface_number=1, + .open = tempered_type_hid_open, + .close = tempered_type_hid_close, + .get_subtype_id = tempered_type_hid_get_subtype_id_from_string, + .get_subtype_data = &(struct tempered_type_hid_subtype_from_string_data) + { + .query = { + .length = 9, + .data = (unsigned char[]){ 0, 1, 0x86, 0xFF, 1, 0, 0, 0, 0 } + }, + .response_count = 2, + .subtype_strings = (char *[]){ + "TEMPerGold_V3.1 ", + NULL + } + }, + .subtypes = (struct temper_subtype*[]){ + (struct temper_subtype*)&(struct temper_subtype_hid){ + .base = { + .id = 0, + .name = "TEMPerGold_V3.1", + .open = tempered_type_hid_subtype_open, + .read_sensors = tempered_type_hid_read_sensors, + .get_temperature = tempered_type_hid_get_temperature + }, + .sensor_group_count = 1, + .sensor_groups = (struct tempered_type_hid_sensor_group[]){ + { + .query = { + .length = 9, + .data = (unsigned char[]){ 0, 1, 0x80, 0x33, 1, 0, 0, 0, 0 } + }, + .read_sensors = tempered_type_hid_read_sensor_group, + .sensor_count = 1, + .sensors = (struct tempered_type_hid_sensor[]){ + { + .get_temperature = tempered_type_hid_get_temperature_simple, + .temperature_high_byte_offset = 2, + .temperature_low_byte_offset = 3 + } + } + } + } + }, + NULL // List terminator for subtypes + } + }, { .name=NULL } // List terminator for temper types }; diff --git a/libtempered/type_hid/simple.c b/libtempered/type_hid/simple.c new file mode 100644 index 0000000..7620660 --- /dev/null +++ b/libtempered/type_hid/simple.c @@ -0,0 +1,30 @@ +#include +#include + +#include "type-info.h" +#include "../tempered-internal.h" + +bool tempered_type_hid_get_temperature_simple( + tempered_device *device, struct tempered_type_hid_sensor *sensor, + struct tempered_type_hid_query_result *group_data, float *tempC +) { + if ( + group_data->length <= sensor->temperature_high_byte_offset || + group_data->length <= sensor->temperature_low_byte_offset + ) { + tempered_set_error( + device, strdup( "Not enough data was read from the sensor." ) + ); + return false; + } + + int low_byte_offset = sensor->temperature_low_byte_offset; + int high_byte_offset = sensor->temperature_high_byte_offset; + int temp = ( group_data->data[low_byte_offset] & 0xFF ) + + ( (signed char)group_data->data[high_byte_offset] << 8 ) + ; + + *tempC = temp / 100.0; + + return true; +} diff --git a/libtempered/type_hid/simple.h b/libtempered/type_hid/simple.h new file mode 100644 index 0000000..7d0b5ad --- /dev/null +++ b/libtempered/type_hid/simple.h @@ -0,0 +1,13 @@ +#ifndef TEMPERED__TYPE_HID__SIMPLE_H +#define TEMPERED__TYPE_HID__SIMPLE_H + +#include + +#include "type-info.h" + +bool tempered_type_hid_get_temperature_simple( + tempered_device *device, struct tempered_type_hid_sensor *sensor, + struct tempered_type_hid_query_result *group_data, float *tempC +); + +#endif From dec07e881d22e7ac3ff1a9dcf9152fe071ee7572 Mon Sep 17 00:00:00 2001 From: Stefan Schoenberger Date: Tue, 30 Jul 2019 20:41:14 +0200 Subject: [PATCH 2/8] Temperature support for TEMPerX_V3.3 --- libtempered/temper_type.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/libtempered/temper_type.c b/libtempered/temper_type.c index 3072f1c..6147a0c 100644 --- a/libtempered/temper_type.c +++ b/libtempered/temper_type.c @@ -409,7 +409,7 @@ struct temper_type known_temper_types[]={ } }, { - .name="TEMPerGold_V3.1", + .name="TEMPer2V3.1 or TEMPer2V3.3", .vendor_id=0x413d, .product_id=0x2107, .interface_number=1, @@ -425,6 +425,7 @@ struct temper_type known_temper_types[]={ .response_count = 2, .subtype_strings = (char *[]){ "TEMPerGold_V3.1 ", + "TEMPerX_V3.3 ", NULL } }, @@ -456,6 +457,33 @@ struct temper_type known_temper_types[]={ } } }, + (struct temper_subtype*)&(struct temper_subtype_hid){ + .base = { + .id = 1, + .name = "TEMPerX_V3.3", + .open = tempered_type_hid_subtype_open, + .read_sensors = tempered_type_hid_read_sensors, + .get_temperature = tempered_type_hid_get_temperature + }, + .sensor_group_count = 1, + .sensor_groups = (struct tempered_type_hid_sensor_group[]){ + { + .query = { + .length = 9, + .data = (unsigned char[]){ 0, 1, 0x80, 0x33, 1, 0, 0, 0, 0 } + }, + .read_sensors = tempered_type_hid_read_sensor_group, + .sensor_count = 1, + .sensors = (struct tempered_type_hid_sensor[]){ + { + .get_temperature = tempered_type_hid_get_temperature_simple, + .temperature_high_byte_offset = 2, + .temperature_low_byte_offset = 3 + } + } + } + } + }, NULL // List terminator for subtypes } }, From 48fee9db73042579686002386d58ab541e5b23f6 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Wed, 21 Sep 2016 09:54:28 -0400 Subject: [PATCH 3/8] Fix missing links to dependencies of libtempered --- libtempered/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libtempered/CMakeLists.txt b/libtempered/CMakeLists.txt index b989315..34b4120 100644 --- a/libtempered/CMakeLists.txt +++ b/libtempered/CMakeLists.txt @@ -8,6 +8,7 @@ endif() if (BUILD_SHARED_LIB) add_library(tempered-shared SHARED ${libtempered_FILES}) + target_link_libraries(tempered-shared ${HIDAPI_LINK_LIBS}) set_target_properties(tempered-shared PROPERTIES OUTPUT_NAME tempered SOVERSION 0 @@ -22,6 +23,7 @@ endif() if (BUILD_STATIC_LIB) add_library(tempered-static STATIC ${libtempered_FILES}) + target_link_libraries(tempered-static ${HIDAPI_LINK_LIBS}) set_target_properties(tempered-static PROPERTIES OUTPUT_NAME tempered ) From a81398a877acfc8299a72485d02f3cf4f935489c Mon Sep 17 00:00:00 2001 From: mwerezak Date: Fri, 23 Sep 2016 11:22:08 -0400 Subject: [PATCH 4/8] Fixes tempered.h includes So that it can actually be used in other projects --- libtempered/tempered.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libtempered/tempered.h b/libtempered/tempered.h index 0ba3338..233038d 100644 --- a/libtempered/tempered.h +++ b/libtempered/tempered.h @@ -5,6 +5,7 @@ extern "C" { #endif +#include #include /** This file contains the headers that comprise the public API of the TEMPered From c0b7530c74c6948d7699c8c261c88c3f3b4340c4 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Wed, 21 Sep 2016 13:12:07 -0400 Subject: [PATCH 5/8] Fixes libtempered passing pointers to allocated strings A library should NEVER ask an application to free dynamically allocated memory. Unless the library is statically linked to the application, there is no guarantee that a free() in the application will line up with a malloc() in the library. --- examples/enumerate.c | 11 ++++------ examples/read-all.c | 11 ++++------ examples/read-repeat.c | 14 +++++------- libtempered/core.c | 50 +++++++++++++++++++++++++++++++++++++----- libtempered/tempered.h | 27 +++++++++++++---------- utils/tempered.c | 11 ++++------ 6 files changed, 77 insertions(+), 47 deletions(-) diff --git a/examples/enumerate.c b/examples/enumerate.c index dc00c2a..358bd9b 100644 --- a/examples/enumerate.c +++ b/examples/enumerate.c @@ -8,19 +8,17 @@ This example shows how to enumerate the attached devices. int main( void ) { - char *error = NULL; - if ( !tempered_init( &error ) ) + char error[256]; + if ( !tempered_init( error, sizeof(error) ) ) { fprintf( stderr, "%s\n", error ); - free( error ); return 1; } - struct tempered_device_list *list = tempered_enumerate( &error ); + struct tempered_device_list *list = tempered_enumerate( error, sizeof(error) ); if ( list == NULL ) { fprintf( stderr, "%s\n", error ); - free( error ); } else { @@ -39,10 +37,9 @@ int main( void ) tempered_free_device_list( list ); } - if ( !tempered_exit( &error ) ) + if ( !tempered_exit( error, sizeof(error) ) ) { fprintf( stderr, "%s\n", error ); - free( error ); return 1; } return 0; diff --git a/examples/read-all.c b/examples/read-all.c index 2069df4..bfd2baf 100644 --- a/examples/read-all.c +++ b/examples/read-all.c @@ -96,15 +96,14 @@ void read_device( struct tempered_device_list *dev ) int main( void ) { - char *error = NULL; - if ( !tempered_init( &error ) ) + char error[256]; + if ( !tempered_init( error, sizeof(error) ) ) { fprintf( stderr, "Failed to initialize libtempered: %s\n", error ); - free( error ); return 1; } - struct tempered_device_list *list = tempered_enumerate( &error ); + struct tempered_device_list *list = tempered_enumerate( error, sizeof(error) ); if ( list == NULL ) { if ( error == NULL ) @@ -114,7 +113,6 @@ int main( void ) else { fprintf( stderr, "Failed to enumerate devices: %s\n", error ); - free( error ); } } else @@ -127,10 +125,9 @@ int main( void ) tempered_free_device_list( list ); } - if ( !tempered_exit( &error ) ) + if ( !tempered_exit( error, sizeof(error) ) ) { fprintf( stderr, "Failed to shut down libtempered: %s\n", error ); - free( error ); return 1; } return 0; diff --git a/examples/read-repeat.c b/examples/read-repeat.c index 8fb404f..3a9fcac 100644 --- a/examples/read-repeat.c +++ b/examples/read-repeat.c @@ -55,11 +55,11 @@ void read_device_sensor( tempered_device *device, int sensor ) void read_repeatedly( tempered_device *device ) { int i; - for ( i = 0; i < 10; i++ ) + for ( i = 0; i < 500; i++ ) { if ( i > 0 ) { - sleep( 5 ); + sleep( 1 ); } if ( !tempered_read_sensors( device ) ) { @@ -83,7 +83,7 @@ void read_repeatedly( tempered_device *device ) tempered_device* open_device( char *dev_path ) { char *error = NULL; - struct tempered_device_list *list = tempered_enumerate( &error ); + struct tempered_device_list *list = tempered_enumerate( error, sizeof(error) ); if ( list == NULL ) { if ( error == NULL ) @@ -135,11 +135,10 @@ int main( int argc, char *argv[] ) fprintf( stderr, "Usage: read-repeat \n" ); return 1; } - char *error = NULL; - if ( !tempered_init( &error ) ) + char error[256]; + if ( !tempered_init( error, sizeof(error) ) ) { fprintf( stderr, "Failed to initialize libtempered: %s\n", error ); - free( error ); return 1; } @@ -150,10 +149,9 @@ int main( int argc, char *argv[] ) tempered_close( device ); } - if ( !tempered_exit( &error ) ) + if ( !tempered_exit( error, sizeof(error) ) ) { fprintf( stderr, "Failed to shut down libtempered: %s\n", error ); - free( error ); return 1; } return 0; diff --git a/libtempered/core.c b/libtempered/core.c index 73ad0b0..ae54bb3 100644 --- a/libtempered/core.c +++ b/libtempered/core.c @@ -23,21 +23,59 @@ void tempered_set_error( tempered_device *device, char *error ) } /** Initialize the TEMPered library. */ -bool tempered_init( char **error ) +bool tempered_init( char *error, size_t err_size ) { - return temper_type_init( error ); + if ( error == NULL ) //don't need to handle error messages + { + return temper_type_init( NULL ); + } + + char *err; + if ( !temper_type_init( &err ) ) + { + snprintf(error, err_size, "%s", err); + free(err); //free the damn thing + + return false; + } + return true; } /** Finalize the TEMPered library. */ -bool tempered_exit( char **error ) +bool tempered_exit( char *error, size_t err_size ) { - return temper_type_exit( error ); + if ( error == NULL ) //don't need to handle error messages + { + return temper_type_init( NULL ); + } + + char *err; + if ( !temper_type_exit( &err ) ) + { + snprintf(error, err_size, "%s", err); + free(err); //free the damn thing + + return false; + } + return true; } /** Enumerate the TEMPer devices. */ -struct tempered_device_list* tempered_enumerate( char **error ) +struct tempered_device_list* tempered_enumerate( char *error, size_t err_size ) { - return temper_type_enumerate( error ); + if ( error == NULL ) //don't need to handle error messages + { + return temper_type_enumerate( NULL ); + } + + char *err; + struct tempered_device_list *list = temper_type_enumerate( &err ); + if ( list == NULL ) + { + snprintf(error, err_size, "%s", err); + free(err); //free the damn thing + } + return list; } /** Free the memory used by the given device list. */ diff --git a/libtempered/tempered.h b/libtempered/tempered.h index 233038d..1adf2ff 100644 --- a/libtempered/tempered.h +++ b/libtempered/tempered.h @@ -70,37 +70,40 @@ typedef struct tempered_device_ tempered_device; * necessary, as it will be called automatically when needed, but should be * called at the start of execution if there's a chance the library will be * used by multiple threads simultaneously. - * @param error If an error occurs and this is not NULL, it will be set to the - * error message. The returned string is dynamically allocated, and should be - * freed when you're done with it. + * @param error If an error occurs and this is not NULL, the error message will + * be written to the given buffer. + * @param err_size If the buffer is too small for the error message it will be + * truncated. * @return true on success, false on error. */ -bool tempered_init( char **error ); +bool tempered_init( char *error, size_t err_size ); /** Finalize the TEMPered library. * * This function should be called at the end of execution to avoid memory leaks. - * @param error If an error occurs and this is not NULL, it will be set to the - * error message. The returned string is dynamically allocated, and should be - * freed when you're done with it. + * @param error If an error occurs and this is not NULL, the error message will + * be written to the given buffer. + * @param err_size If the buffer is too small for the error message it will be + * truncated. * @return true on success, false on error. */ -bool tempered_exit( char **error ); +bool tempered_exit( char *error, size_t err_size ); /** Enumerate the TEMPer devices. * * This function returns a linked list of all the recognized TEMPer devices * attached to the system (excluding the ones that are ignored). * - * @param error If an error occurs and this is not NULL, it will be set to the - * error message. The returned string is dynamically allocated, and should be - * freed when you're done with it. + * @param error If an error occurs and this is not NULL, the error message will + * be written to the given buffer. + * @param err_size If the buffer is too small for the error message it will be + * truncated. * @return A pointer to the first device in the enumerated list, or NULL on * error. This list should be freed with tempered_free_device_list when you * are done with it. * If no devices were found, NULL is returned and the error remains unset. */ -struct tempered_device_list* tempered_enumerate( char **error ); +struct tempered_device_list* tempered_enumerate( char *error, size_t err_size ); /** Free the memory used by the given device list. * diff --git a/utils/tempered.c b/utils/tempered.c index 65b72c5..6c50edd 100644 --- a/utils/tempered.c +++ b/utils/tempered.c @@ -282,20 +282,18 @@ int main( int argc, char *argv[] ) { return 1; } - char *error = NULL; - if ( !tempered_init( &error ) ) + char error[256]; + if ( !tempered_init( error, sizeof(error) ) ) { fprintf( stderr, "Failed to initialize libtempered: %s\n", error ); - free( error ); free_options( options ); return 1; } - struct tempered_device_list *list = tempered_enumerate( &error ); + struct tempered_device_list *list = tempered_enumerate( error, sizeof(error) ); if ( list == NULL ) { fprintf( stderr, "Failed to enumerate devices: %s\n", error ); - free( error ); } else { @@ -337,10 +335,9 @@ int main( int argc, char *argv[] ) tempered_free_device_list( list ); } - if ( !tempered_exit( &error ) ) + if ( !tempered_exit( error, sizeof(error) ) ) { fprintf( stderr, "%s\n", error ); - free( error ); free_options( options ); return 1; } From 1478618578430fa1191448c09f824f8b01e9d2fd Mon Sep 17 00:00:00 2001 From: mwerezak Date: Wed, 21 Sep 2016 16:01:25 -0400 Subject: [PATCH 6/8] Fixes error string handling in tempered_open() --- examples/read-all.c | 5 ++--- examples/read-repeat.c | 15 +++------------ libtempered/core.c | 28 +++++++++++++++++----------- libtempered/tempered.h | 9 +++++---- utils/tempered.c | 5 ++--- 5 files changed, 29 insertions(+), 33 deletions(-) diff --git a/examples/read-all.c b/examples/read-all.c index bfd2baf..2a1964f 100644 --- a/examples/read-all.c +++ b/examples/read-all.c @@ -60,12 +60,11 @@ void read_device( struct tempered_device_list *dev ) dev->interface_number, dev->type_name ); - char *error = NULL; - tempered_device *device = tempered_open( dev, &error ); + char error[256]; + tempered_device *device = tempered_open( dev, error, sizeof(error) ); if ( device == NULL ) { printf( "\tOpen failed, error: %s\n", error ); - free( error ); return; } printf( diff --git a/examples/read-repeat.c b/examples/read-repeat.c index 3a9fcac..21630ac 100644 --- a/examples/read-repeat.c +++ b/examples/read-repeat.c @@ -82,19 +82,11 @@ void read_repeatedly( tempered_device *device ) /** Open the device with the given device path. */ tempered_device* open_device( char *dev_path ) { - char *error = NULL; + char error[256]; struct tempered_device_list *list = tempered_enumerate( error, sizeof(error) ); if ( list == NULL ) { - if ( error == NULL ) - { - printf( "No devices were found.\n" ); - } - else - { - fprintf( stderr, "Failed to enumerate devices: %s\n", error ); - free( error ); - } + fprintf( stderr, "Failed to enumerate devices: %s\n", error ); return NULL; } tempered_device *device = NULL; @@ -105,7 +97,7 @@ tempered_device* open_device( char *dev_path ) if ( strcmp( dev->path, dev_path ) == 0 ) { found = true; - device = tempered_open( dev, &error ); + device = tempered_open( dev, error, sizeof(error) ); break; } } @@ -118,7 +110,6 @@ tempered_device* open_device( char *dev_path ) stderr, "Opening %s failed, error: %s\n", dev_path, error ); - free( error ); } else { diff --git a/libtempered/core.c b/libtempered/core.c index ae54bb3..783a80b 100644 --- a/libtempered/core.c +++ b/libtempered/core.c @@ -133,13 +133,13 @@ static bool tempered_open__find_subtype( tempered_device *device ) } /** Open a given device from the list. */ -tempered_device* tempered_open( struct tempered_device_list *list, char **error ) +tempered_device* tempered_open( struct tempered_device_list *list, char *error, size_t err_size ) { if ( list == NULL ) { if ( error != NULL ) { - *error = strdup( "Invalid device given." ); + snprintf( error, err_size, "Invalid device given." ); } return NULL; } @@ -150,7 +150,7 @@ tempered_device* tempered_open( struct tempered_device_list *list, char **error { if ( error != NULL ) { - *error = strdup( "Invalid device given (type not found)." ); + snprintf( error, err_size, "Invalid device given (type not found)." ); } return NULL; } @@ -158,7 +158,7 @@ tempered_device* tempered_open( struct tempered_device_list *list, char **error { if ( error != NULL ) { - *error = strdup( "Device type has no open method." ); + snprintf( error, err_size, "Device type has no open method." ); } return NULL; } @@ -167,7 +167,7 @@ tempered_device* tempered_open( struct tempered_device_list *list, char **error { if ( error != NULL ) { - *error = strdup( "Could not allocate memory for the device." ); + snprintf( error, err_size, "Could not allocate memory for the device." ); } return NULL; } @@ -180,7 +180,7 @@ tempered_device* tempered_open( struct tempered_device_list *list, char **error { if ( error != NULL ) { - *error = strdup( "Could not allocate memory for the path." ); + snprintf( error, err_size, "Could not allocate memory for the path." ); } free( device ); return NULL; @@ -191,11 +191,13 @@ tempered_device* tempered_open( struct tempered_device_list *list, char **error { if ( device->error != NULL ) { - *error = device->error; + snprintf( error, err_size, + "Type-specific device open failed with error: %s", device->error + ); } else { - *error = strdup( + snprintf( error, err_size, "Type-specific device open failed with no error message." ); } @@ -212,7 +214,8 @@ tempered_device* tempered_open( struct tempered_device_list *list, char **error { if ( error != NULL ) { - *error = device->error; + snprintf( error, err_size, "%s", device->error ); + free( device->error ); device->error = NULL; } tempered_close( device ); @@ -226,12 +229,15 @@ tempered_device* tempered_open( struct tempered_device_list *list, char **error { if ( device->error != NULL ) { - *error = device->error; + snprintf( error, err_size, + "Type-specific device open failed with error: %s", device->error + ); + free( device->error ); device->error = NULL; } else { - *error = strdup( + snprintf( error, err_size, "Type-specific device open failed with no error message." ); } diff --git a/libtempered/tempered.h b/libtempered/tempered.h index 1adf2ff..cb33442 100644 --- a/libtempered/tempered.h +++ b/libtempered/tempered.h @@ -119,14 +119,15 @@ void tempered_free_device_list( struct tempered_device_list *list ); * The returned handle should be closed with tempered_close() when you are done * using the device. * @param list The device list entry that should be opened. - * @param error If an error occurs and this is not NULL, it will be set to the - * error message. The returned string is dynamically allocated, and should be - * freed when you're done with it. + * @param error If an error occurs and this is not NULL, the error message will + * be written to the given buffer. + * @param err_size If the buffer is too small for the error message it will be + * truncated. * @return The opened device, or NULL on error. * @see tempered_close() * @see tempered_enumerate() */ -tempered_device* tempered_open( struct tempered_device_list *list, char **error ); +tempered_device* tempered_open( struct tempered_device_list *list, char *error, size_t err_size ); /** Close an open device. * diff --git a/utils/tempered.c b/utils/tempered.c index 6c50edd..689a4c8 100644 --- a/utils/tempered.c +++ b/utils/tempered.c @@ -245,15 +245,14 @@ void print_device( ); return; } - char *error = NULL; - tempered_device *device = tempered_open( dev, &error ); + char error[256]; + tempered_device *device = tempered_open( dev, error, sizeof(error) ); if ( device == NULL ) { fprintf( stderr, "%s: Could not open device: %s\n", dev->path, error ); - free( error ); return; } if ( !tempered_read_sensors( device ) ) From 88bce610cde097e1c8ecf8fbc5a1ef68c0844c0f Mon Sep 17 00:00:00 2001 From: Forrest Voight Date: Mon, 29 Sep 2014 17:41:02 -0400 Subject: [PATCH 7/8] Added support for the 0C45:7402 TEMPerHumM12V1.2, which uses a Si7021 sensor. --- libtempered/temper_type.c | 33 +++++++++++++++++ libtempered/type_hid/si7021.c | 69 +++++++++++++++++++++++++++++++++++ libtempered/type_hid/si7021.h | 20 ++++++++++ 3 files changed, 122 insertions(+) create mode 100644 libtempered/type_hid/si7021.c create mode 100644 libtempered/type_hid/si7021.h diff --git a/libtempered/temper_type.c b/libtempered/temper_type.c index 6147a0c..5c42bc2 100644 --- a/libtempered/temper_type.c +++ b/libtempered/temper_type.c @@ -10,6 +10,7 @@ #include "type_hid/sht1x.h" #include "type_hid/ntc.h" #include "type_hid/si7005.h" +#include "type_hid/si7021.h" #include "type_hid/simple.h" // This is an array of known TEMPer types. @@ -38,6 +39,7 @@ struct temper_type known_temper_types[]={ .subtype_strings = (char *[]){ "TEMPerHumV1.0rHu", "TEMPerHumM12V1.0", + "TEMPerHumM12V1.2", NULL } }, @@ -104,6 +106,37 @@ struct temper_type known_temper_types[]={ } } }, + (struct temper_subtype*)&(struct temper_subtype_hid){ + .base = { + .id = 2, + .name = "TEMPerHumM12V1.2", + .open = tempered_type_hid_subtype_open, + .read_sensors = tempered_type_hid_read_sensors, + .get_temperature = tempered_type_hid_get_temperature, + .get_humidity = tempered_type_hid_get_humidity + }, + .sensor_group_count = 1, + .sensor_groups = (struct tempered_type_hid_sensor_group[]){ + { + .query = { + .length = 9, + .data = (unsigned char[]){ 0, 1, 0x80, 0x33, 1, 0, 0, 0, 0 } + }, + .read_sensors = tempered_type_hid_read_sensor_group, + .sensor_count = 1, + .sensors = (struct tempered_type_hid_sensor[]){ + { + .get_temperature = tempered_type_hid_get_temperature_si7021, + .get_humidity = tempered_type_hid_get_humidity_si7021, + .temperature_high_byte_offset = 2, + .temperature_low_byte_offset = 3, + .humidity_high_byte_offset = 4, + .humidity_low_byte_offset = 5 + } + } + } + } + }, NULL // List terminator for subtypes } }, diff --git a/libtempered/type_hid/si7021.c b/libtempered/type_hid/si7021.c new file mode 100644 index 0000000..0bf1506 --- /dev/null +++ b/libtempered/type_hid/si7021.c @@ -0,0 +1,69 @@ +#include +#include + +#include "type-info.h" +#include "../tempered-internal.h" + +bool tempered_type_hid_get_temperature_si7021( + tempered_device *device, struct tempered_type_hid_sensor *sensor, + struct tempered_type_hid_query_result *group_data, float *tempC +) { + if ( + group_data->length <= sensor->temperature_high_byte_offset || + group_data->length <= sensor->temperature_low_byte_offset + ) { + tempered_set_error( + device, strdup( "Not enough data was read from the sensor." ) + ); + return false; + } + + // Convert from two separate data bytes to a single integer. + // The result should be an unsigned int between 0x0000 and 0xFFFF. + int low_byte_offset = sensor->temperature_low_byte_offset; + int high_byte_offset = sensor->temperature_high_byte_offset; + int temp = ( group_data->data[low_byte_offset] & 0xFF ) + + ( ( group_data->data[high_byte_offset] & 0xFF ) << 8 ) + ; + + // These formulas and values are based on the Silicon Labs Si7021 datasheet + *tempC = 175.72*temp/65536 - 46.85; + + return true; +} + +bool tempered_type_hid_get_humidity_si7021( + tempered_device *device, struct tempered_type_hid_sensor *sensor, + struct tempered_type_hid_query_result *group_data, float *rel_hum +) { + float tempC; + if ( + !tempered_type_hid_get_temperature_si7021( + device, sensor, group_data, &tempC + ) + ) { + return false; + } + + if ( + group_data->length <= sensor->humidity_high_byte_offset || + group_data->length <= sensor->humidity_low_byte_offset + ) + { + tempered_set_error( + device, strdup( "Not enough data was read from the sensor." ) + ); + return false; + } + + int low_byte_offset = sensor->humidity_low_byte_offset; + int high_byte_offset = sensor->humidity_high_byte_offset; + int rh = ( group_data->data[low_byte_offset] & 0xFF ) + + ( ( group_data->data[high_byte_offset] & 0xFF ) << 8 ) + ; + + // These formulas and values are based on the Silicon Labs Si7021 datasheet + *rel_hum = 125.*rh/65536 - 6; + + return true; +} diff --git a/libtempered/type_hid/si7021.h b/libtempered/type_hid/si7021.h new file mode 100644 index 0000000..7b5de85 --- /dev/null +++ b/libtempered/type_hid/si7021.h @@ -0,0 +1,20 @@ +#ifndef TEMPERED__TYPE_HID__SI7021_H +#define TEMPERED__TYPE_HID__SI7021_H + +#include + +#include "type-info.h" + +// These methods are for the Silicon Labs Si7021 chip. + +bool tempered_type_hid_get_temperature_si7021( + tempered_device *device, struct tempered_type_hid_sensor *sensor, + struct tempered_type_hid_query_result *group_data, float *tempC +); + +bool tempered_type_hid_get_humidity_si7021( + tempered_device *device, struct tempered_type_hid_sensor *sensor, + struct tempered_type_hid_query_result *group_data, float *rel_hum +); + +#endif From 53347000bc9f9e9821ae51ec68214b5b5d67215b Mon Sep 17 00:00:00 2001 From: Dave T Date: Sat, 19 Mar 2016 11:25:32 -0500 Subject: [PATCH 8/8] Add support for 0C45:7402 TEMPerHumM12V1.3, which uses a si7021 IC Added support for "TEMPerHumM12V1.3" devices which use the si7021 IC Signed-off-by: Dave T --- libtempered/temper_type.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/libtempered/temper_type.c b/libtempered/temper_type.c index 5c42bc2..7bbe47e 100644 --- a/libtempered/temper_type.c +++ b/libtempered/temper_type.c @@ -40,6 +40,7 @@ struct temper_type known_temper_types[]={ "TEMPerHumV1.0rHu", "TEMPerHumM12V1.0", "TEMPerHumM12V1.2", + "TEMPerHumM12V1.3", NULL } }, @@ -137,6 +138,37 @@ struct temper_type known_temper_types[]={ } } }, + (struct temper_subtype*)&(struct temper_subtype_hid){ + .base = { + .id = 3, + .name = "TEMPerHumM12V1.3", + .open = tempered_type_hid_subtype_open, + .read_sensors = tempered_type_hid_read_sensors, + .get_temperature = tempered_type_hid_get_temperature, + .get_humidity = tempered_type_hid_get_humidity + }, + .sensor_group_count = 1, + .sensor_groups = (struct tempered_type_hid_sensor_group[]){ + { + .query = { + .length = 9, + .data = (unsigned char[]){ 0, 1, 0x80, 0x33, 1, 0, 0, 0, 0 } + }, + .read_sensors = tempered_type_hid_read_sensor_group, + .sensor_count = 1, + .sensors = (struct tempered_type_hid_sensor[]){ + { + .get_temperature = tempered_type_hid_get_temperature_si7021, + .get_humidity = tempered_type_hid_get_humidity_si7021, + .temperature_high_byte_offset = 2, + .temperature_low_byte_offset = 3, + .humidity_high_byte_offset = 4, + .humidity_low_byte_offset = 5 + } + } + } + } + }, NULL // List terminator for subtypes } },