#include #include #include #include //#usleep #include #include //# isdigit() #include "qmc5883.h" #include "deftypes.h" extern void bus_err(int ern); extern void print_help(void); extern uchar *xchg_data (uchar *buf, uint8 wrlen, uint8 waitlen, uint8 rdlen); unsigned char buf[32]; void qmc5883_print_all(const uchar *opts) { 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" "\n"); } void qmc5883_read_all(const uchar *opts) {} // void hmc5883_read_one(const uchar *opts) {} // void hmc5883_conf_set(const uchar *opts){} static float calc_field(char direction, float gain){ // Calculate temperature uint16 raw = 0; //# Signed by default // if(direction == 'x'){ // buf[0] = 0x03; //# Measurement in the REG[0] // } else if (direction == 'y'){ // buf[0] = 0x07; // } else if(direction == 'z'){ // buf[0] = 0x05; // } // buf[0] = 0x3d; // buf[0] = 0x00; // xchg_data(buf,1,0,3); // buf[0] = 0x3c; // for(int i=0; i<15; i++){ // buf[i] = 0xFF; // } // xchg_data(buf,14,0,14); // buf[0] = 0x01; // xchg_data(buf,1,0,1); buf[0] = 0x0A; buf[1] = 0b10000000; //soft reset to all xchg_data(buf,2,0,1); buf[0] = 0x09; buf[1] = 0x15; buf[2] = 0x0A; buf[3] = 0b00000000; buf[4] = 0x1b; buf[5] = 0x01; xchg_data(buf,6,2,1); buf[0] = 0x00; xchg_data(buf,1,0,14); // buf[0] = 0x3c; // buf[1] = 0x01; // buf[3] = 0xA0; // xchg_data(buf,3,0,1); // buf[0] = 0x3c; // buf[1] = 0x02; // buf[2] = 0x00; // xchg_data(buf,3,0,1); raw = buf[0] + buf[1]*256 ; //# /x*256 == x << 8/ (>> 5): Temp is 11bit data register // return(raw * 1.0); if((raw & 0x8000) == 0x8000){ //# check if the msb(bit11) is 1 (1024 = 0x400), 2'complement negative number raw = ~raw + 1; //# 2'complement data //raw = raw & 0xFFFF; //# Only the lowest 11bit needed return( -1 * raw * (1.0/3000.0)); } else { return(raw *(1.0/3000.0)); //# 11bit -> 0.125°C or 9bit -> 0.5°C } } static float read_tos(void){ // Over-Temperature Shutdown register uint16 rawtemp = 0; //# Int16 default signed buf[0] = 0x03; //# Tos = REG[2] xchg_data(buf,1,0,2); rawtemp = buf[0]*256 + buf[1]; // x*256 == x << 8 rawtemp = (rawtemp) >> 7; //# 9bit data 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 } } static uchar read_conf(void){ //Configuration register buf[0] = 0x01; 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", calc_temp(strtof(opts, NULL))); // // } else { // fprintf(stdout, "00:%f\n", calc_temp(0.0)); // // } // fprintf(stdout, "01:0x%x\n", read_conf()); // fprintf(stdout, "02:%f\n", read_thys()); // fprintf(stdout, "03:%f\n", read_tos()); // } void qmc5883_read_one(const uchar *opts){ // Prints the selected register's data uint16 id,i; uchar temp[256]; if(opts != NULL){ //# Search the comma: ...<01,-11.24> for(i = 0; i < strlen((char*)opts); i++){ if (*(opts+i) == ','){ break; } else { if( !isdigit(*(opts+i)) ){ //# Check the register string fprintf(stderr, "The Register address must be an integer!\n"); print_help(); qmc5883_print_all(NULL); exit (EXIT_FAILURE); } temp[i] = *(opts+i); //# copy register string temp[i+1] = '\0'; } } id = atoi((char*)temp); //# Convert register to number strncpy((char*)temp, (char*)opts+i+1, 255); //# Copy remain to temp switch (id) //# Which register is selected? { case 0x00: // for(uint32 i=0; i<0xFFFFFFFF; i++){ fprintf(stdout, "%f\n", calc_field(*temp, 0.73)); //# with the offset // usleep(100*1000); // } break; case 0x01: fprintf(stdout, "0x%x\n", read_conf()); break; case 0x02: break; case 0x03: fprintf(stdout, "%f\n", read_tos()); break; default: print_help(); } } } void qmc5883_conf_set(const uchar *opts){ // Prints the selected register's data uint16 i; uchar temp[256]; if(opts != NULL){ for(i = 0; i < strlen((char*)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 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 { qmc5883_print_all(NULL); 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 { qmc5883_print_all(NULL); 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 { qmc5883_print_all(NULL); 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 { qmc5883_print_all(NULL); 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"); print_help(); qmc5883_print_all(NULL); exit (EXIT_FAILURE); // } // } } } }