Driver for the NXP PCT2075 digital temperature sensor and thermal watchdog

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PCT2075.cpp Source File

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 }