Driver for the NXP PCT2075 digital temperature sensor and thermal watchdog
Embed:
(wiki syntax)
Show/hide line numbers
PCT2075.cpp
00001 #include "PCT2075.h" 00002 00003 // R/W - Configuration register: contains a single 8-bit data byte to set the 00004 // device operating condition; default = 0 00005 static const char configuration_register = 0x01; 00006 // Read only - Temperature register: contains two 8-bit data bytes to store the 00007 // measured Temp data 00008 static const char temperature_register = 0x00; 00009 // R/W - Overtemperature shutdown threshold register: contains two 8-bit data 00010 // bytes to store the overtemperature shutdown T ots limit; default = 80 °C 00011 static const char os_temperature_register = 0x03; 00012 // R/W - Hysteresis register: contains two 8-bit data bytes to store the 00013 // hysteresis T hys limit; default = 75 °C 00014 static const char hyst_temperature_register = 0x02; 00015 // R/W - Temperature conversion cycle; default = 100 ms 00016 static const char idle_time_register = 0x04; 00017 00018 PCT2075::PCT2075 (I2C &i2c_obj, uint8_t address) : i2c( i2c_obj ) { 00019 // I2C uses 7 bit addresses, so the address is left shifted by 1 and added 00020 // with the R/W bit before using it 00021 address_write = (address << 1)|0; 00022 address_read = (address << 1)|1; 00023 } 00024 00025 PCT2075::~PCT2075 () { 00026 ; 00027 } 00028 00029 static PCT2075::OSFaultQue parse_os_fault_que(char config_byte) { 00030 switch ((config_byte >> 3) & 0x03) { 00031 case 0: 00032 return PCT2075::OS_FAULT_QUE_1; 00033 case 1: 00034 return PCT2075::OS_FAULT_QUE_2; 00035 case 2: 00036 return PCT2075::OS_FAULT_QUE_4; 00037 case 3: 00038 return PCT2075::OS_FAULT_QUE_6; 00039 } 00040 00041 return PCT2075::OS_FAULT_QUE_1; 00042 } 00043 00044 PCT2075::Configuration PCT2075::get_configuration() { 00045 char data; 00046 00047 i2c.write( address_write, &configuration_register, 1, true); 00048 i2c.read( address_read, &data, 1 ); 00049 00050 PCT2075::Configuration config = { 00051 parse_os_fault_que(data), 00052 ((data >> 2) & 0x01) == 0x00 ? OS_ACTIVE_LOW : OS_ACTIVE_HIGH, 00053 ((data >> 1) & 0x01) == 0x00 ? OS_MODE_COMP : OS_MODE_INTERRUPT, 00054 (data & 0x01) == 0x00 ? DEVICE_MODE_NORMAL : DEVICE_MODE_SHUTDOWN 00055 }; 00056 00057 return config; 00058 } 00059 00060 void PCT2075::set_configuration(Configuration& config) { 00061 char command[2] = {configuration_register, 2}; 00062 00063 switch (config.os_fault_que) { 00064 case OS_FAULT_QUE_1: 00065 break; 00066 case OS_FAULT_QUE_2: 00067 command[1] |= 1 << 3; 00068 break; 00069 case OS_FAULT_QUE_4: 00070 command[1] |= 2 << 3; 00071 break; 00072 case OS_FAULT_QUE_6: 00073 command[1] |= 3 << 3; 00074 break; 00075 } 00076 00077 if (config.os_polarity == OS_ACTIVE_HIGH) 00078 command[1] |= 1 << 2; 00079 if (config.os_mode == OS_MODE_INTERRUPT) 00080 command[1] |= 1 << 1; 00081 if (config.device_mode == DEVICE_MODE_SHUTDOWN) 00082 command[1] |= 1; 00083 00084 i2c.write(address_write, command, 2); 00085 } 00086 00087 void PCT2075::set_os_fault_queue(PCT2075::OSFaultQue fault_que) { 00088 Configuration conf = get_configuration(); 00089 conf.os_fault_que = fault_que; 00090 set_configuration(conf); 00091 } 00092 00093 void PCT2075::set_os_polarity(PCT2075::OSPolarity polarity) { 00094 Configuration conf = get_configuration(); 00095 conf.os_polarity = polarity; 00096 set_configuration(conf); 00097 } 00098 00099 void PCT2075::set_os_mode(PCT2075::OSMode os_mode) { 00100 Configuration conf = get_configuration(); 00101 conf.os_mode = os_mode; 00102 set_configuration(conf); 00103 } 00104 00105 void PCT2075::set_device_mode(PCT2075::DeviceMode device_mode) { 00106 Configuration conf = get_configuration(); 00107 conf.device_mode = device_mode; 00108 set_configuration(conf); 00109 } 00110 00111 void PCT2075::shutdown_mode() { 00112 set_device_mode(DEVICE_MODE_SHUTDOWN); 00113 } 00114 00115 void PCT2075::normal_mode() { 00116 set_device_mode(DEVICE_MODE_NORMAL); 00117 } 00118 00119 int16_t PCT2075::read_temperature() { 00120 char data[2]; 00121 00122 i2c.write(address_write, &temperature_register, 1, true); 00123 i2c.read(address_read, data, 2); 00124 00125 int16_t temperature = (data[0] << 8) | data[1]; 00126 temperature = temperature >> 5; 00127 00128 // temperature should not overflow since 0x3FF * 25 < MaxInt16 00129 // and 0x4FF * 25 < MaxUint16 00130 return (temperature*25) / 2; // = temperature / 8 * 100 00131 } 00132 00133 int16_t PCT2075::get_os_temperature() { 00134 char data[2]; 00135 00136 i2c.write(address_write, &os_temperature_register, 1, true); 00137 i2c.read(address_read, data, 2); 00138 00139 int16_t temperature = (data[0] << 8) | data[1]; 00140 temperature = temperature >> 7; 00141 00142 return temperature * 50; // = temperature / 2 * 100 00143 } 00144 00145 void PCT2075::set_os_temperature(int16_t temperature) { 00146 char command[3]; 00147 00148 if( temperature > TEMP_MAX ) { 00149 temperature = TEMP_MAX; 00150 } else if (temperature < TEMP_MIN) { 00151 temperature = TEMP_MIN; 00152 } 00153 00154 temperature = temperature / 50; // = temperature / 100 * 2 00155 command[0] = os_temperature_register; 00156 command[1] = (char)(temperature >> 1); // = << 7 and >> 8 00157 command[2] = (char)((temperature << 7) & 0x80); 00158 00159 i2c.write(address_write, command, 3); 00160 } 00161 00162 int16_t PCT2075::get_hyst_temperature() { 00163 char data[2]; 00164 00165 i2c.write(address_write, &hyst_temperature_register, 1, true); 00166 i2c.read(address_read, data, 2); 00167 00168 int16_t temperature = (data[0] << 8) | data[1]; 00169 temperature = temperature >> 7; 00170 00171 return temperature * 50; // = temperature / 2 * 100 00172 } 00173 00174 void PCT2075::set_hyst_temperature (int16_t temperature) { 00175 char command[3]; 00176 00177 if( temperature > TEMP_MAX ) { 00178 temperature = TEMP_MAX; 00179 } else if ( temperature < TEMP_MIN ) { 00180 temperature = TEMP_MIN; 00181 } 00182 00183 temperature = temperature / 50; // = temperature / 100 * 2 00184 command[0] = hyst_temperature_register; 00185 command[1] = (char)(temperature >> 1); // = << 7 and >> 8 00186 command[2] = (char)((temperature << 7) & 0x80); 00187 00188 i2c.write(address_write, command, 2); 00189 } 00190 00191 uint16_t PCT2075::get_idle_time() { 00192 char data[2]; 00193 00194 i2c.write(address_write, &idle_time_register, 1, true); 00195 i2c.read(address_read, data, 1); 00196 00197 uint16_t time = (uint16_t)data[0]; 00198 return time * 100; 00199 } 00200 00201 void PCT2075::set_idle_time(uint16_t time) { 00202 char command[2]; 00203 00204 if( time > TIDLE_MAX) { 00205 time = TIDLE_MAX; 00206 } else if( time < TIDLE_MIN ) { 00207 time = TIDLE_MIN; 00208 } 00209 00210 command[0] = idle_time_register; 00211 command[1] = (char)(time / 100); 00212 00213 i2c.write(address_write, command, 2); 00214 }
Generated on Thu Jul 21 2022 09:31:43 by 1.7.2