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
- Committer:
- Seppe Stas
- Date:
- 2016-09-23
- Revision:
- 1:a2b7889eb4e9
File content as of revision 1:a2b7889eb4e9:
#include "PCT2075.h" // R/W - Configuration register: contains a single 8-bit data byte to set the // device operating condition; default = 0 static const char configuration_register = 0x01; // Read only - Temperature register: contains two 8-bit data bytes to store the // measured Temp data static const char temperature_register = 0x00; // R/W - Overtemperature shutdown threshold register: contains two 8-bit data // bytes to store the overtemperature shutdown T ots limit; default = 80 °C static const char os_temperature_register = 0x03; // R/W - Hysteresis register: contains two 8-bit data bytes to store the // hysteresis T hys limit; default = 75 °C static const char hyst_temperature_register = 0x02; // R/W - Temperature conversion cycle; default = 100 ms static const char idle_time_register = 0x04; PCT2075::PCT2075 (I2C &i2c_obj, uint8_t address) : i2c( i2c_obj ) { // I2C uses 7 bit addresses, so the address is left shifted by 1 and added // with the R/W bit before using it address_write = (address << 1)|0; address_read = (address << 1)|1; } PCT2075::~PCT2075 () { ; } static PCT2075::OSFaultQue parse_os_fault_que(char config_byte) { switch ((config_byte >> 3) & 0x03) { case 0: return PCT2075::OS_FAULT_QUE_1; case 1: return PCT2075::OS_FAULT_QUE_2; case 2: return PCT2075::OS_FAULT_QUE_4; case 3: return PCT2075::OS_FAULT_QUE_6; } return PCT2075::OS_FAULT_QUE_1; } PCT2075::Configuration PCT2075::get_configuration() { char data; i2c.write( address_write, &configuration_register, 1, true); i2c.read( address_read, &data, 1 ); PCT2075::Configuration config = { parse_os_fault_que(data), ((data >> 2) & 0x01) == 0x00 ? OS_ACTIVE_LOW : OS_ACTIVE_HIGH, ((data >> 1) & 0x01) == 0x00 ? OS_MODE_COMP : OS_MODE_INTERRUPT, (data & 0x01) == 0x00 ? DEVICE_MODE_NORMAL : DEVICE_MODE_SHUTDOWN }; return config; } void PCT2075::set_configuration(Configuration& config) { char command[2] = {configuration_register, 2}; switch (config.os_fault_que) { case OS_FAULT_QUE_1: break; case OS_FAULT_QUE_2: command[1] |= 1 << 3; break; case OS_FAULT_QUE_4: command[1] |= 2 << 3; break; case OS_FAULT_QUE_6: command[1] |= 3 << 3; break; } if (config.os_polarity == OS_ACTIVE_HIGH) command[1] |= 1 << 2; if (config.os_mode == OS_MODE_INTERRUPT) command[1] |= 1 << 1; if (config.device_mode == DEVICE_MODE_SHUTDOWN) command[1] |= 1; i2c.write(address_write, command, 2); } void PCT2075::set_os_fault_queue(PCT2075::OSFaultQue fault_que) { Configuration conf = get_configuration(); conf.os_fault_que = fault_que; set_configuration(conf); } void PCT2075::set_os_polarity(PCT2075::OSPolarity polarity) { Configuration conf = get_configuration(); conf.os_polarity = polarity; set_configuration(conf); } void PCT2075::set_os_mode(PCT2075::OSMode os_mode) { Configuration conf = get_configuration(); conf.os_mode = os_mode; set_configuration(conf); } void PCT2075::set_device_mode(PCT2075::DeviceMode device_mode) { Configuration conf = get_configuration(); conf.device_mode = device_mode; set_configuration(conf); } void PCT2075::shutdown_mode() { set_device_mode(DEVICE_MODE_SHUTDOWN); } void PCT2075::normal_mode() { set_device_mode(DEVICE_MODE_NORMAL); } int16_t PCT2075::read_temperature() { char data[2]; i2c.write(address_write, &temperature_register, 1, true); i2c.read(address_read, data, 2); int16_t temperature = (data[0] << 8) | data[1]; temperature = temperature >> 5; // temperature should not overflow since 0x3FF * 25 < MaxInt16 // and 0x4FF * 25 < MaxUint16 return (temperature*25) / 2; // = temperature / 8 * 100 } int16_t PCT2075::get_os_temperature() { char data[2]; i2c.write(address_write, &os_temperature_register, 1, true); i2c.read(address_read, data, 2); int16_t temperature = (data[0] << 8) | data[1]; temperature = temperature >> 7; return temperature * 50; // = temperature / 2 * 100 } void PCT2075::set_os_temperature(int16_t temperature) { char command[3]; if( temperature > TEMP_MAX ) { temperature = TEMP_MAX; } else if (temperature < TEMP_MIN) { temperature = TEMP_MIN; } temperature = temperature / 50; // = temperature / 100 * 2 command[0] = os_temperature_register; command[1] = (char)(temperature >> 1); // = << 7 and >> 8 command[2] = (char)((temperature << 7) & 0x80); i2c.write(address_write, command, 3); } int16_t PCT2075::get_hyst_temperature() { char data[2]; i2c.write(address_write, &hyst_temperature_register, 1, true); i2c.read(address_read, data, 2); int16_t temperature = (data[0] << 8) | data[1]; temperature = temperature >> 7; return temperature * 50; // = temperature / 2 * 100 } void PCT2075::set_hyst_temperature (int16_t temperature) { char command[3]; if( temperature > TEMP_MAX ) { temperature = TEMP_MAX; } else if ( temperature < TEMP_MIN ) { temperature = TEMP_MIN; } temperature = temperature / 50; // = temperature / 100 * 2 command[0] = hyst_temperature_register; command[1] = (char)(temperature >> 1); // = << 7 and >> 8 command[2] = (char)((temperature << 7) & 0x80); i2c.write(address_write, command, 2); } uint16_t PCT2075::get_idle_time() { char data[2]; i2c.write(address_write, &idle_time_register, 1, true); i2c.read(address_read, data, 1); uint16_t time = (uint16_t)data[0]; return time * 100; } void PCT2075::set_idle_time(uint16_t time) { char command[2]; if( time > TIDLE_MAX) { time = TIDLE_MAX; } else if( time < TIDLE_MIN ) { time = TIDLE_MIN; } command[0] = idle_time_register; command[1] = (char)(time / 100); i2c.write(address_write, command, 2); }