Driver for the NXP PCT2075 digital temperature sensor and thermal watchdog
NXP PCT2075 temperature sensor driver for mbed
This library is a driver for the [NXP PCT2075](http://www.nxp.com/products/sensors/i2c-temperature-voltage-monitors/ic-bus-fm-plus-1-degree-c-accuracy-digital-temperature-sensor-and-thermal-watchdog:PCT2075). It only handles the I2C communication with the sensor, it does not handle the OS interrupt line. The [mbed InterruptIn](https://developer.mbed.org/handbook/InterruptIn) library can be used for this.
example usage
#include <mbed.h> #include <PCT2075.h> Serial s(USBTX, USBRX); // tx, rx InterruptIn TempPinInt(PC4); LowPowerTicker ticker; static volatile bool temp_int = false; static volatile bool tick_int = false; int main( void ) { TempPinInt.mode(PullUp); PCT2075::Configuration config = { PCT2075::OS_FAULT_QUE_1, PCT2075::OS_ACTIVE_LOW, PCT2075::OS_MODE_INTERRUPT, PCT2075::DEVICE_MODE_SHUTDOWN }; temp_sensor.set_configuration(config); temp_sensor.set_idle_time(PCT2075::TIDLE_MAX); temp_sensor.set_hyst_temperature(2000); temp_sensor.set_os_temperature(2500); TempPinInt.fall(&on_fall); ticker.attach(&tick, 2.0); while(true) { sleep(); // wait to be woken up by ticker or temp sensor if (tick_int) { s.printf("Tick\r\n"); config.device_mode = PCT2075::DEVICE_MODE_NORMAL; temp_sensor.set_configuration(config); tick_int = false; } if (temp_int) { config.device_mode = PCT2075::DEVICE_MODE_SHUTDOWN; temp_sensor.set_configuration(config); uint16_t t = temp_sensor.read_temperature(); s.printf("Temperature: %d\r\n", t); temp_int = false; } } }
PCT2075.cpp@1:a2b7889eb4e9, 2016-09-23 (annotated)
- Committer:
- Seppe Stas
- Date:
- Fri Sep 23 15:38:34 2016 +0200
- Revision:
- 1:a2b7889eb4e9
Added library files
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Seppe Stas |
1:a2b7889eb4e9 | 1 | #include "PCT2075.h" |
Seppe Stas |
1:a2b7889eb4e9 | 2 | |
Seppe Stas |
1:a2b7889eb4e9 | 3 | // R/W - Configuration register: contains a single 8-bit data byte to set the |
Seppe Stas |
1:a2b7889eb4e9 | 4 | // device operating condition; default = 0 |
Seppe Stas |
1:a2b7889eb4e9 | 5 | static const char configuration_register = 0x01; |
Seppe Stas |
1:a2b7889eb4e9 | 6 | // Read only - Temperature register: contains two 8-bit data bytes to store the |
Seppe Stas |
1:a2b7889eb4e9 | 7 | // measured Temp data |
Seppe Stas |
1:a2b7889eb4e9 | 8 | static const char temperature_register = 0x00; |
Seppe Stas |
1:a2b7889eb4e9 | 9 | // R/W - Overtemperature shutdown threshold register: contains two 8-bit data |
Seppe Stas |
1:a2b7889eb4e9 | 10 | // bytes to store the overtemperature shutdown T ots limit; default = 80 °C |
Seppe Stas |
1:a2b7889eb4e9 | 11 | static const char os_temperature_register = 0x03; |
Seppe Stas |
1:a2b7889eb4e9 | 12 | // R/W - Hysteresis register: contains two 8-bit data bytes to store the |
Seppe Stas |
1:a2b7889eb4e9 | 13 | // hysteresis T hys limit; default = 75 °C |
Seppe Stas |
1:a2b7889eb4e9 | 14 | static const char hyst_temperature_register = 0x02; |
Seppe Stas |
1:a2b7889eb4e9 | 15 | // R/W - Temperature conversion cycle; default = 100 ms |
Seppe Stas |
1:a2b7889eb4e9 | 16 | static const char idle_time_register = 0x04; |
Seppe Stas |
1:a2b7889eb4e9 | 17 | |
Seppe Stas |
1:a2b7889eb4e9 | 18 | PCT2075::PCT2075 (I2C &i2c_obj, uint8_t address) : i2c( i2c_obj ) { |
Seppe Stas |
1:a2b7889eb4e9 | 19 | // I2C uses 7 bit addresses, so the address is left shifted by 1 and added |
Seppe Stas |
1:a2b7889eb4e9 | 20 | // with the R/W bit before using it |
Seppe Stas |
1:a2b7889eb4e9 | 21 | address_write = (address << 1)|0; |
Seppe Stas |
1:a2b7889eb4e9 | 22 | address_read = (address << 1)|1; |
Seppe Stas |
1:a2b7889eb4e9 | 23 | } |
Seppe Stas |
1:a2b7889eb4e9 | 24 | |
Seppe Stas |
1:a2b7889eb4e9 | 25 | PCT2075::~PCT2075 () { |
Seppe Stas |
1:a2b7889eb4e9 | 26 | ; |
Seppe Stas |
1:a2b7889eb4e9 | 27 | } |
Seppe Stas |
1:a2b7889eb4e9 | 28 | |
Seppe Stas |
1:a2b7889eb4e9 | 29 | static PCT2075::OSFaultQue parse_os_fault_que(char config_byte) { |
Seppe Stas |
1:a2b7889eb4e9 | 30 | switch ((config_byte >> 3) & 0x03) { |
Seppe Stas |
1:a2b7889eb4e9 | 31 | case 0: |
Seppe Stas |
1:a2b7889eb4e9 | 32 | return PCT2075::OS_FAULT_QUE_1; |
Seppe Stas |
1:a2b7889eb4e9 | 33 | case 1: |
Seppe Stas |
1:a2b7889eb4e9 | 34 | return PCT2075::OS_FAULT_QUE_2; |
Seppe Stas |
1:a2b7889eb4e9 | 35 | case 2: |
Seppe Stas |
1:a2b7889eb4e9 | 36 | return PCT2075::OS_FAULT_QUE_4; |
Seppe Stas |
1:a2b7889eb4e9 | 37 | case 3: |
Seppe Stas |
1:a2b7889eb4e9 | 38 | return PCT2075::OS_FAULT_QUE_6; |
Seppe Stas |
1:a2b7889eb4e9 | 39 | } |
Seppe Stas |
1:a2b7889eb4e9 | 40 | |
Seppe Stas |
1:a2b7889eb4e9 | 41 | return PCT2075::OS_FAULT_QUE_1; |
Seppe Stas |
1:a2b7889eb4e9 | 42 | } |
Seppe Stas |
1:a2b7889eb4e9 | 43 | |
Seppe Stas |
1:a2b7889eb4e9 | 44 | PCT2075::Configuration PCT2075::get_configuration() { |
Seppe Stas |
1:a2b7889eb4e9 | 45 | char data; |
Seppe Stas |
1:a2b7889eb4e9 | 46 | |
Seppe Stas |
1:a2b7889eb4e9 | 47 | i2c.write( address_write, &configuration_register, 1, true); |
Seppe Stas |
1:a2b7889eb4e9 | 48 | i2c.read( address_read, &data, 1 ); |
Seppe Stas |
1:a2b7889eb4e9 | 49 | |
Seppe Stas |
1:a2b7889eb4e9 | 50 | PCT2075::Configuration config = { |
Seppe Stas |
1:a2b7889eb4e9 | 51 | parse_os_fault_que(data), |
Seppe Stas |
1:a2b7889eb4e9 | 52 | ((data >> 2) & 0x01) == 0x00 ? OS_ACTIVE_LOW : OS_ACTIVE_HIGH, |
Seppe Stas |
1:a2b7889eb4e9 | 53 | ((data >> 1) & 0x01) == 0x00 ? OS_MODE_COMP : OS_MODE_INTERRUPT, |
Seppe Stas |
1:a2b7889eb4e9 | 54 | (data & 0x01) == 0x00 ? DEVICE_MODE_NORMAL : DEVICE_MODE_SHUTDOWN |
Seppe Stas |
1:a2b7889eb4e9 | 55 | }; |
Seppe Stas |
1:a2b7889eb4e9 | 56 | |
Seppe Stas |
1:a2b7889eb4e9 | 57 | return config; |
Seppe Stas |
1:a2b7889eb4e9 | 58 | } |
Seppe Stas |
1:a2b7889eb4e9 | 59 | |
Seppe Stas |
1:a2b7889eb4e9 | 60 | void PCT2075::set_configuration(Configuration& config) { |
Seppe Stas |
1:a2b7889eb4e9 | 61 | char command[2] = {configuration_register, 2}; |
Seppe Stas |
1:a2b7889eb4e9 | 62 | |
Seppe Stas |
1:a2b7889eb4e9 | 63 | switch (config.os_fault_que) { |
Seppe Stas |
1:a2b7889eb4e9 | 64 | case OS_FAULT_QUE_1: |
Seppe Stas |
1:a2b7889eb4e9 | 65 | break; |
Seppe Stas |
1:a2b7889eb4e9 | 66 | case OS_FAULT_QUE_2: |
Seppe Stas |
1:a2b7889eb4e9 | 67 | command[1] |= 1 << 3; |
Seppe Stas |
1:a2b7889eb4e9 | 68 | break; |
Seppe Stas |
1:a2b7889eb4e9 | 69 | case OS_FAULT_QUE_4: |
Seppe Stas |
1:a2b7889eb4e9 | 70 | command[1] |= 2 << 3; |
Seppe Stas |
1:a2b7889eb4e9 | 71 | break; |
Seppe Stas |
1:a2b7889eb4e9 | 72 | case OS_FAULT_QUE_6: |
Seppe Stas |
1:a2b7889eb4e9 | 73 | command[1] |= 3 << 3; |
Seppe Stas |
1:a2b7889eb4e9 | 74 | break; |
Seppe Stas |
1:a2b7889eb4e9 | 75 | } |
Seppe Stas |
1:a2b7889eb4e9 | 76 | |
Seppe Stas |
1:a2b7889eb4e9 | 77 | if (config.os_polarity == OS_ACTIVE_HIGH) |
Seppe Stas |
1:a2b7889eb4e9 | 78 | command[1] |= 1 << 2; |
Seppe Stas |
1:a2b7889eb4e9 | 79 | if (config.os_mode == OS_MODE_INTERRUPT) |
Seppe Stas |
1:a2b7889eb4e9 | 80 | command[1] |= 1 << 1; |
Seppe Stas |
1:a2b7889eb4e9 | 81 | if (config.device_mode == DEVICE_MODE_SHUTDOWN) |
Seppe Stas |
1:a2b7889eb4e9 | 82 | command[1] |= 1; |
Seppe Stas |
1:a2b7889eb4e9 | 83 | |
Seppe Stas |
1:a2b7889eb4e9 | 84 | i2c.write(address_write, command, 2); |
Seppe Stas |
1:a2b7889eb4e9 | 85 | } |
Seppe Stas |
1:a2b7889eb4e9 | 86 | |
Seppe Stas |
1:a2b7889eb4e9 | 87 | void PCT2075::set_os_fault_queue(PCT2075::OSFaultQue fault_que) { |
Seppe Stas |
1:a2b7889eb4e9 | 88 | Configuration conf = get_configuration(); |
Seppe Stas |
1:a2b7889eb4e9 | 89 | conf.os_fault_que = fault_que; |
Seppe Stas |
1:a2b7889eb4e9 | 90 | set_configuration(conf); |
Seppe Stas |
1:a2b7889eb4e9 | 91 | } |
Seppe Stas |
1:a2b7889eb4e9 | 92 | |
Seppe Stas |
1:a2b7889eb4e9 | 93 | void PCT2075::set_os_polarity(PCT2075::OSPolarity polarity) { |
Seppe Stas |
1:a2b7889eb4e9 | 94 | Configuration conf = get_configuration(); |
Seppe Stas |
1:a2b7889eb4e9 | 95 | conf.os_polarity = polarity; |
Seppe Stas |
1:a2b7889eb4e9 | 96 | set_configuration(conf); |
Seppe Stas |
1:a2b7889eb4e9 | 97 | } |
Seppe Stas |
1:a2b7889eb4e9 | 98 | |
Seppe Stas |
1:a2b7889eb4e9 | 99 | void PCT2075::set_os_mode(PCT2075::OSMode os_mode) { |
Seppe Stas |
1:a2b7889eb4e9 | 100 | Configuration conf = get_configuration(); |
Seppe Stas |
1:a2b7889eb4e9 | 101 | conf.os_mode = os_mode; |
Seppe Stas |
1:a2b7889eb4e9 | 102 | set_configuration(conf); |
Seppe Stas |
1:a2b7889eb4e9 | 103 | } |
Seppe Stas |
1:a2b7889eb4e9 | 104 | |
Seppe Stas |
1:a2b7889eb4e9 | 105 | void PCT2075::set_device_mode(PCT2075::DeviceMode device_mode) { |
Seppe Stas |
1:a2b7889eb4e9 | 106 | Configuration conf = get_configuration(); |
Seppe Stas |
1:a2b7889eb4e9 | 107 | conf.device_mode = device_mode; |
Seppe Stas |
1:a2b7889eb4e9 | 108 | set_configuration(conf); |
Seppe Stas |
1:a2b7889eb4e9 | 109 | } |
Seppe Stas |
1:a2b7889eb4e9 | 110 | |
Seppe Stas |
1:a2b7889eb4e9 | 111 | void PCT2075::shutdown_mode() { |
Seppe Stas |
1:a2b7889eb4e9 | 112 | set_device_mode(DEVICE_MODE_SHUTDOWN); |
Seppe Stas |
1:a2b7889eb4e9 | 113 | } |
Seppe Stas |
1:a2b7889eb4e9 | 114 | |
Seppe Stas |
1:a2b7889eb4e9 | 115 | void PCT2075::normal_mode() { |
Seppe Stas |
1:a2b7889eb4e9 | 116 | set_device_mode(DEVICE_MODE_NORMAL); |
Seppe Stas |
1:a2b7889eb4e9 | 117 | } |
Seppe Stas |
1:a2b7889eb4e9 | 118 | |
Seppe Stas |
1:a2b7889eb4e9 | 119 | int16_t PCT2075::read_temperature() { |
Seppe Stas |
1:a2b7889eb4e9 | 120 | char data[2]; |
Seppe Stas |
1:a2b7889eb4e9 | 121 | |
Seppe Stas |
1:a2b7889eb4e9 | 122 | i2c.write(address_write, &temperature_register, 1, true); |
Seppe Stas |
1:a2b7889eb4e9 | 123 | i2c.read(address_read, data, 2); |
Seppe Stas |
1:a2b7889eb4e9 | 124 | |
Seppe Stas |
1:a2b7889eb4e9 | 125 | int16_t temperature = (data[0] << 8) | data[1]; |
Seppe Stas |
1:a2b7889eb4e9 | 126 | temperature = temperature >> 5; |
Seppe Stas |
1:a2b7889eb4e9 | 127 | |
Seppe Stas |
1:a2b7889eb4e9 | 128 | // temperature should not overflow since 0x3FF * 25 < MaxInt16 |
Seppe Stas |
1:a2b7889eb4e9 | 129 | // and 0x4FF * 25 < MaxUint16 |
Seppe Stas |
1:a2b7889eb4e9 | 130 | return (temperature*25) / 2; // = temperature / 8 * 100 |
Seppe Stas |
1:a2b7889eb4e9 | 131 | } |
Seppe Stas |
1:a2b7889eb4e9 | 132 | |
Seppe Stas |
1:a2b7889eb4e9 | 133 | int16_t PCT2075::get_os_temperature() { |
Seppe Stas |
1:a2b7889eb4e9 | 134 | char data[2]; |
Seppe Stas |
1:a2b7889eb4e9 | 135 | |
Seppe Stas |
1:a2b7889eb4e9 | 136 | i2c.write(address_write, &os_temperature_register, 1, true); |
Seppe Stas |
1:a2b7889eb4e9 | 137 | i2c.read(address_read, data, 2); |
Seppe Stas |
1:a2b7889eb4e9 | 138 | |
Seppe Stas |
1:a2b7889eb4e9 | 139 | int16_t temperature = (data[0] << 8) | data[1]; |
Seppe Stas |
1:a2b7889eb4e9 | 140 | temperature = temperature >> 7; |
Seppe Stas |
1:a2b7889eb4e9 | 141 | |
Seppe Stas |
1:a2b7889eb4e9 | 142 | return temperature * 50; // = temperature / 2 * 100 |
Seppe Stas |
1:a2b7889eb4e9 | 143 | } |
Seppe Stas |
1:a2b7889eb4e9 | 144 | |
Seppe Stas |
1:a2b7889eb4e9 | 145 | void PCT2075::set_os_temperature(int16_t temperature) { |
Seppe Stas |
1:a2b7889eb4e9 | 146 | char command[3]; |
Seppe Stas |
1:a2b7889eb4e9 | 147 | |
Seppe Stas |
1:a2b7889eb4e9 | 148 | if( temperature > TEMP_MAX ) { |
Seppe Stas |
1:a2b7889eb4e9 | 149 | temperature = TEMP_MAX; |
Seppe Stas |
1:a2b7889eb4e9 | 150 | } else if (temperature < TEMP_MIN) { |
Seppe Stas |
1:a2b7889eb4e9 | 151 | temperature = TEMP_MIN; |
Seppe Stas |
1:a2b7889eb4e9 | 152 | } |
Seppe Stas |
1:a2b7889eb4e9 | 153 | |
Seppe Stas |
1:a2b7889eb4e9 | 154 | temperature = temperature / 50; // = temperature / 100 * 2 |
Seppe Stas |
1:a2b7889eb4e9 | 155 | command[0] = os_temperature_register; |
Seppe Stas |
1:a2b7889eb4e9 | 156 | command[1] = (char)(temperature >> 1); // = << 7 and >> 8 |
Seppe Stas |
1:a2b7889eb4e9 | 157 | command[2] = (char)((temperature << 7) & 0x80); |
Seppe Stas |
1:a2b7889eb4e9 | 158 | |
Seppe Stas |
1:a2b7889eb4e9 | 159 | i2c.write(address_write, command, 3); |
Seppe Stas |
1:a2b7889eb4e9 | 160 | } |
Seppe Stas |
1:a2b7889eb4e9 | 161 | |
Seppe Stas |
1:a2b7889eb4e9 | 162 | int16_t PCT2075::get_hyst_temperature() { |
Seppe Stas |
1:a2b7889eb4e9 | 163 | char data[2]; |
Seppe Stas |
1:a2b7889eb4e9 | 164 | |
Seppe Stas |
1:a2b7889eb4e9 | 165 | i2c.write(address_write, &hyst_temperature_register, 1, true); |
Seppe Stas |
1:a2b7889eb4e9 | 166 | i2c.read(address_read, data, 2); |
Seppe Stas |
1:a2b7889eb4e9 | 167 | |
Seppe Stas |
1:a2b7889eb4e9 | 168 | int16_t temperature = (data[0] << 8) | data[1]; |
Seppe Stas |
1:a2b7889eb4e9 | 169 | temperature = temperature >> 7; |
Seppe Stas |
1:a2b7889eb4e9 | 170 | |
Seppe Stas |
1:a2b7889eb4e9 | 171 | return temperature * 50; // = temperature / 2 * 100 |
Seppe Stas |
1:a2b7889eb4e9 | 172 | } |
Seppe Stas |
1:a2b7889eb4e9 | 173 | |
Seppe Stas |
1:a2b7889eb4e9 | 174 | void PCT2075::set_hyst_temperature (int16_t temperature) { |
Seppe Stas |
1:a2b7889eb4e9 | 175 | char command[3]; |
Seppe Stas |
1:a2b7889eb4e9 | 176 | |
Seppe Stas |
1:a2b7889eb4e9 | 177 | if( temperature > TEMP_MAX ) { |
Seppe Stas |
1:a2b7889eb4e9 | 178 | temperature = TEMP_MAX; |
Seppe Stas |
1:a2b7889eb4e9 | 179 | } else if ( temperature < TEMP_MIN ) { |
Seppe Stas |
1:a2b7889eb4e9 | 180 | temperature = TEMP_MIN; |
Seppe Stas |
1:a2b7889eb4e9 | 181 | } |
Seppe Stas |
1:a2b7889eb4e9 | 182 | |
Seppe Stas |
1:a2b7889eb4e9 | 183 | temperature = temperature / 50; // = temperature / 100 * 2 |
Seppe Stas |
1:a2b7889eb4e9 | 184 | command[0] = hyst_temperature_register; |
Seppe Stas |
1:a2b7889eb4e9 | 185 | command[1] = (char)(temperature >> 1); // = << 7 and >> 8 |
Seppe Stas |
1:a2b7889eb4e9 | 186 | command[2] = (char)((temperature << 7) & 0x80); |
Seppe Stas |
1:a2b7889eb4e9 | 187 | |
Seppe Stas |
1:a2b7889eb4e9 | 188 | i2c.write(address_write, command, 2); |
Seppe Stas |
1:a2b7889eb4e9 | 189 | } |
Seppe Stas |
1:a2b7889eb4e9 | 190 | |
Seppe Stas |
1:a2b7889eb4e9 | 191 | uint16_t PCT2075::get_idle_time() { |
Seppe Stas |
1:a2b7889eb4e9 | 192 | char data[2]; |
Seppe Stas |
1:a2b7889eb4e9 | 193 | |
Seppe Stas |
1:a2b7889eb4e9 | 194 | i2c.write(address_write, &idle_time_register, 1, true); |
Seppe Stas |
1:a2b7889eb4e9 | 195 | i2c.read(address_read, data, 1); |
Seppe Stas |
1:a2b7889eb4e9 | 196 | |
Seppe Stas |
1:a2b7889eb4e9 | 197 | uint16_t time = (uint16_t)data[0]; |
Seppe Stas |
1:a2b7889eb4e9 | 198 | return time * 100; |
Seppe Stas |
1:a2b7889eb4e9 | 199 | } |
Seppe Stas |
1:a2b7889eb4e9 | 200 | |
Seppe Stas |
1:a2b7889eb4e9 | 201 | void PCT2075::set_idle_time(uint16_t time) { |
Seppe Stas |
1:a2b7889eb4e9 | 202 | char command[2]; |
Seppe Stas |
1:a2b7889eb4e9 | 203 | |
Seppe Stas |
1:a2b7889eb4e9 | 204 | if( time > TIDLE_MAX) { |
Seppe Stas |
1:a2b7889eb4e9 | 205 | time = TIDLE_MAX; |
Seppe Stas |
1:a2b7889eb4e9 | 206 | } else if( time < TIDLE_MIN ) { |
Seppe Stas |
1:a2b7889eb4e9 | 207 | time = TIDLE_MIN; |
Seppe Stas |
1:a2b7889eb4e9 | 208 | } |
Seppe Stas |
1:a2b7889eb4e9 | 209 | |
Seppe Stas |
1:a2b7889eb4e9 | 210 | command[0] = idle_time_register; |
Seppe Stas |
1:a2b7889eb4e9 | 211 | command[1] = (char)(time / 100); |
Seppe Stas |
1:a2b7889eb4e9 | 212 | |
Seppe Stas |
1:a2b7889eb4e9 | 213 | i2c.write(address_write, command, 2); |
Seppe Stas |
1:a2b7889eb4e9 | 214 | } |