diff options
author | Gergő J. Miklós | 2019-05-15 19:10:22 +0200 |
---|---|---|
committer | Gergő J. Miklós | 2019-05-15 19:10:22 +0200 |
commit | d150a9f31a81a7dc02f2359529a7351c743a0067 (patch) | |
tree | b678ba9988fea60fed794eac9fac1754a605a072 /src | |
parent | a55a3a855af46a8385c1bdcf4083f48a2b2490ba (diff) | |
download | i2sensors-d150a9f31a81a7dc02f2359529a7351c743a0067.tar.gz i2sensors-d150a9f31a81a7dc02f2359529a7351c743a0067.zip |
LM75 refactored and Working correctly
Diffstat (limited to 'src')
-rw-r--r-- | src/lm75.c | 258 | ||||
-rw-r--r-- | src/main.c | 4 |
2 files changed, 190 insertions, 72 deletions
@@ -4,7 +4,7 @@ #include <string.h> #include <unistd.h> #include <errno.h> -#include <ctype.h> //# isdigit +#include <ctype.h> //# isdigit() #include "lm75.h" @@ -22,10 +22,20 @@ uchar buf[32]; void lm75_print_all(void) { printf( - "00: Temperature data [°C] (reg: 0x00)\n" - "01: Configuration [hex] (reg: 0x01)\n" - "02: Tos (Overtemp) [°C] (reg: 0x03)\n" - "03: Thys (Hysteresis) [°C] (reg: 0x04)\n" + "============ LM75xx interface ===========\n" + "Registers:\n" + " 00: Temperature data [°C] (reg: 0x00)\n" + " 01: Configuration [hex] (reg: 0x01)\n" + " 02: Tos (Overtemp) [°C] (reg: 0x03)\n" + " 03: Thys (Hysteresis) [°C] (reg: 0x04)\n" + "Configuration:\n" + " tos: Over-Temperature register [-55°C...+125°C]\n" + " thys: Temperature-hysteresis register [-55°C...+125°C]\n" + " conf: Configuration register [hexadecimal]\n" + " sleep: Set idle mode [on/off]\n" + " mode: Comparator/Interrupt mode [comp/int]\n" + " tos_pol: Tos pin polarity (Low/High) [Al/Ah]\n" + " fault_q: Fault queue length [1/2/4]\n" "\n"); } @@ -44,51 +54,55 @@ uchar *xchg_data (uchar *buf, uint8 wrlen, uint8 waitlen, uint8 rdlen){ } - float calculate_temp(float offset){ // Calculate temperature - int16 rawtemp = 0; //# Signed by default + uint16 rawtemp = 0; //# Signed by default float temp; buf[0] = 0x00; //# Measurement in the REG[0] xchg_data(buf,1,0,2); //# Write: 1byte addr, Read: 2byte data, Wait:0, [buf] = 32 byte - - rawtemp = (buf[0]*256 + buf[1]) >> 5; // (buf[0] << 8), and (>> 5), Device with 11bit data, is also supported + rawtemp = (buf[0]*256 + buf[1]) >> 5; //# /x*256 == x << 8/ (>> 5): Temp is 11bit data register if((rawtemp & 0x400) == 0x400){ //# check if the msb(bit11) is 1 (1024 = 0x400), 2'complement negative number - rawtemp = rawtemp - 2048; //# 2^11 = 2048 - } - - temp = rawtemp * 0.125 ; //# 11bit -> 0.125°C or 9bit -> 0.5°C + rawtemp = ~rawtemp + 1; //# 2'complement data + rawtemp = rawtemp & 0x7ff; //# Only the lowest 11bit needed + temp = -1 * rawtemp * 0.125 ; + } else { + temp = rawtemp * 0.125 ; //# 11bit -> 0.125°C or 9bit -> 0.5°C + } return (temp + offset); } - float read_tos(void){ // Over-Temperature Shutdown register - int16 rawtemp = 0; //# Int16 default signed - buf[0] = 0x02; //# Tos = REG[2] + uint16 rawtemp = 0; //# Int16 default signed + buf[0] = 0x03; //# Tos = REG[2] xchg_data(buf,1,0,2); - rawtemp = buf[0]*256 + buf[1]; + rawtemp = buf[0]*256 + buf[1]; // x*256 == x << 8 rawtemp = (rawtemp) >> 7; //# 9bit data - if((rawtemp & 256) == 256){ //# check MSB if it's a 2'complement number - rawtemp = rawtemp - 512 ; //# 2^9 = 512; + if((rawtemp & 0x100) == 0x100){ //# check MSB if it's a 2'complement number + rawtemp = ~rawtemp + 1 ; //# 2'complement, 2^9 = 512; + rawtemp = rawtemp & 0x1FF; //# lowest 9 bit + return (-1 * rawtemp * 0.5); + } else { + return (rawtemp * 0.5); //# 9bit -> 0.5 celsius } - return (rawtemp * 0.5); //# 9bit -> 0.5 celsius } - float read_thys(void){ // Over-Temp Hysteresis Register - int16 rawtemp = 0; //# signed - buf[0] = 0x03; - xchg_data(buf,1,0,2); //# read from REG[3] + uint16 rawtemp = 0; //# signed + buf[0] = 0x02; + xchg_data(buf,1,0,2); //# read from REG[3] - rawtemp = buf[0]*256 + buf[1]; - rawtemp = (rawtemp) >> 7; //# 9bit data - if((rawtemp & 256) == 256){ - rawtemp = rawtemp - 512 ; //# 2^9 = 512; + rawtemp = (buf[0] << 8) + buf[1]; + rawtemp = (rawtemp) >> 7; //# 9bit data + + if((rawtemp & 256) == 256){ //# 256 = 0x100 + rawtemp = ~rawtemp + 1 ; //# 2'complement, 2^9 = 512; + rawtemp = rawtemp & 0x1FF; //# lowest 9 bit + return (-1 * rawtemp * 0.5); } return (rawtemp * 0.5); //# 9bit -> 0.5 celsius } @@ -96,28 +110,25 @@ float read_thys(void){ // Over-Temp Hysteresis Register uchar read_conf(void){ //Configuration register buf[0] = 0x01; - xchg_data(buf,1,0,2); + xchg_data(buf,1,0,1); return buf[0]; } - void lm75_read_all(const uchar *opts){ // Print out whole device's data // if(opts != NULL) // { // printf("00:%f\n", calculate_temp(strtof(opts, NULL))); - // } - // else - // { + // } else { printf("00:%f\n", calculate_temp(0.0)); // } printf("01:0x%x\n", read_conf()); - printf("02:%f\n", read_tos()); - printf("03:%f\n", read_thys()); + printf("02:%f\n", read_thys()); + printf("03:%f\n", read_tos()); + } - void lm75_read_one(const uchar *opts){ // Prints the selected register's data uint16 id,i; uchar temp[256]; @@ -151,10 +162,10 @@ void lm75_read_one(const uchar *opts){ // Prints the selected r printf("0x%x\n", read_conf()); break; case 0x02: - printf("%f\n", read_tos()); + printf("%f\n", read_thys()); break; case 0x03: - printf("%f\n", read_thys()); + printf("%f\n", read_tos()); break; default: print_help(); @@ -165,66 +176,169 @@ void lm75_read_one(const uchar *opts){ // Prints the selected r void lm75_conf_set(const uchar *opts){ // Prints the selected register's data - uint16 id,i,j; + uint16 i,j; uchar temp[256]; if(opts != NULL){ for(i = 0; i < strlen((char*)opts); i++, j++){ - if (*(opts+i) == ','){ + if (*(opts+i) == ','){ //# .... conf_set 0x49 thys,-10.5 break; } temp[i] = *(opts+i); temp[i+1] = '\0'; } - if(!strcmp("tos", (char*)temp)){ //# Set the Tos register value + + if(!strcmp("tos", (char*)temp)){ //# Set the Tos register value + float inp; + uint16 temp; + buf[0] = 0x03; + inp = atof( (char*)(opts+i+1)); + + if(inp < 0){ + temp = 0 - inp/0.5; + temp = ~temp +1; //# 2'complement + buf[1] = (temp >> 1) & 0xFF; //# (x << 7) and (x >> 8) ==> (x >> 1) + buf[2] = ((temp << 7) | 0x7F) & 0xFF; //# |d8,d7,d6,d5|d4,d3,d2,d1|d0,xx,xx,xx|xx,xx,xx,xx| + } else { + temp = inp/0.5; + buf[1] = (temp >> 1) & 0xFF; //# (x << 7) and (x >> 8) ==> (x >> 1) + buf[2] = (temp << 7) & 0xFF;; + } + xchg_data(buf,3,0,2); + }else if(!strcmp("thys", (char*)temp)){ //# Set the Thys reg + float inp; + uint16 temp; + buf[0] = 0x02; + inp = atof( (char*)(opts+i+1)); + + if(inp < 0){ + temp = 0 - inp/0.5; + temp = ~temp +1; //# 2'complement + buf[1] = (temp >> 1) & 0xFF; //# (x << 7) and (x >> 8) ==> (x >> 1) + buf[2] = ((temp << 7) | 0x7F) & 0xFF; //# |d8,d7,d6,d5|d4,d3,d2,d1|d0,xx,xx,xx|xx,xx,xx,xx| + } else { + temp = inp/0.5; + buf[1] = (temp >> 1) & 0xFF; //# (x << 7) and (x >> 8) ==> (x >> 1) + buf[2] = (temp << 7) & 0xFF;; + } + xchg_data(buf,3,0,2); + }else if(!strcmp("conf", (char*)temp)){ //# Set whole conf register + buf[0] = 0x01; + buf[1] = strtol((char*)(opts+i+1),NULL,0); + xchg_data(buf,2,0,1); + + }else if(!strcmp("sleep", (char*)temp)){ //# Send the sleep command + + buf[0] = 0x01; + xchg_data(buf,1,0,1); + if (!strcmp("on",(char*)opts+i+1)) + { + buf[1] = buf[0] | 0x01; + } + else if(!strcmp("off",(char*)opts+i+1)) + { + // buf[1] = ~buf[0]; //# XOR = NEG->OR->NEG + // buf[1] = buf[1] | 0b00000001; //# Invert->add->invert + // buf[1] = ~buf[1]; + buf[1] = buf[0] ^ 0b00000001; //# XOR to clear the bit + } + else + { + lm75_print_all(); + exit(EXIT_FAILURE); + } + buf[0] = 0x01; + xchg_data(buf,2,0,1); + }else if(!strcmp("mode", (char*)temp)){ //# Comparator/Interrupt mode + + buf[0] = 0x01; + xchg_data(buf,1,0,1); + if (!strcmp("comp",(char*)opts+i+1)) + { + buf[1] = buf[0] ^ 0b00000010; //# XOR to clear + } + else if(!strcmp("int",(char*)opts+i+1)) + { + buf[1] = buf[0] | 0b00000010; + } + else + { + lm75_print_all(); + exit(EXIT_FAILURE); + } + buf[0] = 0x01; + xchg_data(buf,2,0,1); + }else if(!strcmp("tos_pol", (char*)temp)){ //# Tos polarity + + buf[0] = 0x01; + xchg_data(buf,1,0,1); + if (!strcmp("Al",(char*)opts+i+1)) + { + buf[1] = buf[0] ^ 0b00000100; //# XOR to clear the bit + } + else if(!strcmp("Ah",(char*)opts+i+1)) + { + buf[1] = buf[0] | 0b00000100; + } + else + { + lm75_print_all(); + exit(EXIT_FAILURE); + } + buf[0] = 0x01; + xchg_data(buf,2,0,1); + }else if(!strcmp("fault_q", (char*)temp)){ //# Tos Fault Queue + + buf[0] = 0x01; + xchg_data(buf,1,0,1); + if (!strcmp("1",(char*)opts+i+1)) + { + buf[1] = buf[0] | 0b00011000; //# Add and clear whole section + buf[1] = buf[1] ^ 0b00011000; + } + else if(!strcmp("2",(char*)opts+i+1)) + { + buf[1] = buf[0] | 0b00011000; //# Clear first + buf[1] = buf[1] ^ 0b00011000; //# Clear first + buf[1] = buf[1] | 0b00001000; //# Set + } + else if(!strcmp("4",(char*)opts+i+1)) + { + buf[1] = buf[0] | 0b00011000; //# Clear first + buf[1] = buf[1] ^ 0b00011000; //# Clear first + buf[1] = buf[1] | 0b00010000; //# Set + } + else + { + lm75_print_all(); + exit(EXIT_FAILURE); + } + buf[0] = 0x01; + xchg_data(buf,2,0,1); + } else { - for(i = 0; i < strlen((char*)opts); i++ ){ - if( !isxdigit(*(opts+i)) || *(opts+i) !='x' || opts[i] != ','){ //# Check the register string - printf("The Register address, and value must be a hex, or an integer!\n"); + // for(i = 0; i < strlen((char*)opts); i++ ){ + // if( !isxdigit(*(opts+i)) || *(opts+i) !='x' || opts[i] != ','){ //# Check the register string + // printf("The Register address, and value must be a hex, or an integer!\n"); print_help(); + lm75_print_all(); exit (EXIT_FAILURE); - } - } + // } + // } } - - - - id = atoi((char*)temp); - strncpy((char*)temp, (char*)opts+i+1, 255); - // id = strtol (opts,&ptr,0); //all format allowed - // ptr++; //one separator allowed - - switch (id) - { - case 0x00: - printf("%f\n", calculate_temp(atof((char*)temp))); - break; - case 0x01: - printf("0x%x\n", read_conf()); - break; - case 0x02: - printf("%f\n", read_tos()); - break; - case 0x03: - printf("%f\n", read_thys()); - break; - default: - print_help(); - } - } }
\ No newline at end of file @@ -155,6 +155,10 @@ int main(int argc, char *argv[]) { read_one((uchar*)argv[5]); } + else if(!strcmp("conf_set",argv[1]) && conf_set != NULL && argc > 5) //# Prints out the selected register + { + conf_set((uchar*)argv[5]); + } else //# No other option { print_help(); |