A feature complete driver for the LM75B temperature sensor from NXP.

Fork of LM75B by Neil Thiessen

Committer:
neilt6
Date:
Fri May 30 19:04:36 2014 +0000
Revision:
16:7ac462ba84ac
Parent:
15:69991c038abe
Added MBED_OPERATORS check to implementation

Who changed what in which revision?

UserRevisionLine numberNew contents of line
neilt6 2:9ecc39b2ca70 1 /* LM75B Driver Library
neilt6 4:06676376766a 2 * Copyright (c) 2013 Neil Thiessen
neilt6 0:557a92280097 3 *
neilt6 3:9d68eed28bfb 4 * Licensed under the Apache License, Version 2.0 (the "License");
neilt6 3:9d68eed28bfb 5 * you may not use this file except in compliance with the License.
neilt6 3:9d68eed28bfb 6 * You may obtain a copy of the License at
neilt6 4:06676376766a 7 *
neilt6 4:06676376766a 8 * http://www.apache.org/licenses/LICENSE-2.0
neilt6 0:557a92280097 9 *
neilt6 3:9d68eed28bfb 10 * Unless required by applicable law or agreed to in writing, software
neilt6 3:9d68eed28bfb 11 * distributed under the License is distributed on an "AS IS" BASIS,
neilt6 3:9d68eed28bfb 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
neilt6 3:9d68eed28bfb 13 * See the License for the specific language governing permissions and
neilt6 3:9d68eed28bfb 14 * limitations under the License.
neilt6 0:557a92280097 15 */
neilt6 0:557a92280097 16
neilt6 0:557a92280097 17 #include "LM75B.h"
neilt6 0:557a92280097 18
neilt6 15:69991c038abe 19 LM75B::LM75B(PinName sda, PinName scl, Address addr, int hz) : m_I2C(sda, scl), m_ADDR((int)addr)
neilt6 0:557a92280097 20 {
neilt6 15:69991c038abe 21 //Set the I2C bus frequency
neilt6 15:69991c038abe 22 m_I2C.frequency(hz);
neilt6 0:557a92280097 23 }
neilt6 0:557a92280097 24
neilt6 13:27c19044ace6 25 bool LM75B::open()
neilt6 9:74b44a27fa40 26 {
neilt6 9:74b44a27fa40 27 //Probe for the LM75B using a Zero Length Transfer
neilt6 13:27c19044ace6 28 if (!m_I2C.write(m_ADDR, NULL, 0)) {
neilt6 9:74b44a27fa40 29 //Return success
neilt6 9:74b44a27fa40 30 return true;
neilt6 9:74b44a27fa40 31 } else {
neilt6 9:74b44a27fa40 32 //Return failure
neilt6 9:74b44a27fa40 33 return false;
neilt6 9:74b44a27fa40 34 }
neilt6 9:74b44a27fa40 35 }
neilt6 9:74b44a27fa40 36
neilt6 13:27c19044ace6 37 LM75B::PowerMode LM75B::powerMode()
neilt6 0:557a92280097 38 {
neilt6 0:557a92280097 39 //Read the 8-bit register value
neilt6 8:2b797c309258 40 char value = read8(REG_CONF);
neilt6 0:557a92280097 41
neilt6 0:557a92280097 42 //Return the status of the SHUTDOWN bit
neilt6 0:557a92280097 43 if (value & (1 << 0))
neilt6 2:9ecc39b2ca70 44 return POWER_SHUTDOWN;
neilt6 0:557a92280097 45 else
neilt6 2:9ecc39b2ca70 46 return POWER_NORMAL;
neilt6 0:557a92280097 47 }
neilt6 0:557a92280097 48
neilt6 8:2b797c309258 49 void LM75B::powerMode(PowerMode mode)
neilt6 0:557a92280097 50 {
neilt6 0:557a92280097 51 //Read the current 8-bit register value
neilt6 8:2b797c309258 52 char value = read8(REG_CONF);
neilt6 0:557a92280097 53
neilt6 0:557a92280097 54 //Set or clear the SHUTDOWN bit
neilt6 2:9ecc39b2ca70 55 if (mode == POWER_SHUTDOWN)
neilt6 0:557a92280097 56 value |= (1 << 0);
neilt6 0:557a92280097 57 else
neilt6 0:557a92280097 58 value &= ~(1 << 0);
neilt6 0:557a92280097 59
neilt6 0:557a92280097 60 //Write the value back out
neilt6 8:2b797c309258 61 write8(REG_CONF, value);
neilt6 0:557a92280097 62 }
neilt6 0:557a92280097 63
neilt6 13:27c19044ace6 64 LM75B::OSMode LM75B::osMode()
neilt6 0:557a92280097 65 {
neilt6 0:557a92280097 66 //Read the 8-bit register value
neilt6 8:2b797c309258 67 char value = read8(REG_CONF);
neilt6 0:557a92280097 68
neilt6 0:557a92280097 69 //Return the status of the OS_COMP_INT bit
neilt6 0:557a92280097 70 if (value & (1 << 1))
neilt6 2:9ecc39b2ca70 71 return OS_INTERRUPT;
neilt6 0:557a92280097 72 else
neilt6 2:9ecc39b2ca70 73 return OS_COMPARATOR;
neilt6 0:557a92280097 74 }
neilt6 0:557a92280097 75
neilt6 8:2b797c309258 76 void LM75B::osMode(OSMode mode)
neilt6 0:557a92280097 77 {
neilt6 0:557a92280097 78 //Read the current 8-bit register value
neilt6 8:2b797c309258 79 char value = read8(REG_CONF);
neilt6 0:557a92280097 80
neilt6 0:557a92280097 81 //Set or clear the OS_COMP_INT bit
neilt6 2:9ecc39b2ca70 82 if (mode == OS_INTERRUPT)
neilt6 0:557a92280097 83 value |= (1 << 1);
neilt6 0:557a92280097 84 else
neilt6 0:557a92280097 85 value &= ~(1 << 1);
neilt6 0:557a92280097 86
neilt6 0:557a92280097 87 //Write the value back out
neilt6 8:2b797c309258 88 write8(REG_CONF, value);
neilt6 0:557a92280097 89 }
neilt6 0:557a92280097 90
neilt6 13:27c19044ace6 91 LM75B::OSPolarity LM75B::osPolarity()
neilt6 0:557a92280097 92 {
neilt6 0:557a92280097 93 //Read the 8-bit register value
neilt6 8:2b797c309258 94 char value = read8(REG_CONF);
neilt6 0:557a92280097 95
neilt6 0:557a92280097 96 //Return the status of the OS_POL bit
neilt6 0:557a92280097 97 if (value & (1 << 2))
neilt6 2:9ecc39b2ca70 98 return OS_ACTIVE_HIGH;
neilt6 0:557a92280097 99 else
neilt6 2:9ecc39b2ca70 100 return OS_ACTIVE_LOW;
neilt6 0:557a92280097 101 }
neilt6 0:557a92280097 102
neilt6 8:2b797c309258 103 void LM75B::osPolarity(OSPolarity polarity)
neilt6 0:557a92280097 104 {
neilt6 0:557a92280097 105 //Read the current 8-bit register value
neilt6 8:2b797c309258 106 char value = read8(REG_CONF);
neilt6 0:557a92280097 107
neilt6 0:557a92280097 108 //Set or clear the OS_POL bit
neilt6 2:9ecc39b2ca70 109 if (polarity == OS_ACTIVE_HIGH)
neilt6 0:557a92280097 110 value |= (1 << 2);
neilt6 0:557a92280097 111 else
neilt6 0:557a92280097 112 value &= ~(1 << 2);
neilt6 0:557a92280097 113
neilt6 0:557a92280097 114 //Write the value back out
neilt6 8:2b797c309258 115 write8(REG_CONF, value);
neilt6 0:557a92280097 116 }
neilt6 0:557a92280097 117
neilt6 13:27c19044ace6 118 LM75B::OSFaultQueue LM75B::osFaultQueue()
neilt6 0:557a92280097 119 {
neilt6 0:557a92280097 120 //Read the 8-bit register value
neilt6 8:2b797c309258 121 char value = read8(REG_CONF);
neilt6 0:557a92280097 122
neilt6 0:557a92280097 123 //Return the status of the OS_F_QUE bits
neilt6 0:557a92280097 124 if ((value & (1 << 3)) && (value & (1 << 4)))
neilt6 2:9ecc39b2ca70 125 return OS_FAULT_QUEUE_6;
neilt6 0:557a92280097 126 else if (!(value & (1 << 3)) && (value & (1 << 4)))
neilt6 2:9ecc39b2ca70 127 return OS_FAULT_QUEUE_4;
neilt6 0:557a92280097 128 else if ((value & (1 << 3)) && !(value & (1 << 4)))
neilt6 2:9ecc39b2ca70 129 return OS_FAULT_QUEUE_2;
neilt6 0:557a92280097 130 else
neilt6 2:9ecc39b2ca70 131 return OS_FAULT_QUEUE_1;
neilt6 0:557a92280097 132 }
neilt6 0:557a92280097 133
neilt6 8:2b797c309258 134 void LM75B::osFaultQueue(OSFaultQueue queue)
neilt6 0:557a92280097 135 {
neilt6 0:557a92280097 136 //Read the current 8-bit register value
neilt6 8:2b797c309258 137 char value = read8(REG_CONF);
neilt6 0:557a92280097 138
neilt6 0:557a92280097 139 //Clear the old OS_F_QUE bits
neilt6 0:557a92280097 140 value &= ~(3 << 3);
neilt6 0:557a92280097 141
neilt6 0:557a92280097 142 //Set the new OS_F_QUE bits
neilt6 2:9ecc39b2ca70 143 if (queue == OS_FAULT_QUEUE_2)
neilt6 0:557a92280097 144 value |= (1 << 3);
neilt6 2:9ecc39b2ca70 145 else if (queue == OS_FAULT_QUEUE_4)
neilt6 0:557a92280097 146 value |= (2 << 3);
neilt6 2:9ecc39b2ca70 147 else if (queue == OS_FAULT_QUEUE_6)
neilt6 0:557a92280097 148 value |= (3 << 3);
neilt6 0:557a92280097 149
neilt6 0:557a92280097 150 //Write the value back out
neilt6 8:2b797c309258 151 write8(REG_CONF, value);
neilt6 0:557a92280097 152 }
neilt6 0:557a92280097 153
neilt6 13:27c19044ace6 154 float LM75B::alertTemp()
neilt6 0:557a92280097 155 {
neilt6 0:557a92280097 156 //Use the 9-bit helper to read the TOS register
neilt6 8:2b797c309258 157 return readAlertTempHelper(REG_TOS);
neilt6 0:557a92280097 158 }
neilt6 0:557a92280097 159
neilt6 8:2b797c309258 160 void LM75B::alertTemp(float temp)
neilt6 0:557a92280097 161 {
neilt6 0:557a92280097 162 //Use the 9-bit helper to write to the TOS register
neilt6 8:2b797c309258 163 return writeAlertTempHelper(REG_TOS, temp);
neilt6 0:557a92280097 164 }
neilt6 0:557a92280097 165
neilt6 13:27c19044ace6 166 float LM75B::alertHyst()
neilt6 0:557a92280097 167 {
neilt6 0:557a92280097 168 //Use the 9-bit helper to read the THYST register
neilt6 8:2b797c309258 169 return readAlertTempHelper(REG_THYST);
neilt6 0:557a92280097 170 }
neilt6 0:557a92280097 171
neilt6 8:2b797c309258 172 void LM75B::alertHyst(float temp)
neilt6 0:557a92280097 173 {
neilt6 0:557a92280097 174 //Use the 9-bit helper to write to the THYST register
neilt6 8:2b797c309258 175 return writeAlertTempHelper(REG_THYST, temp);
neilt6 0:557a92280097 176 }
neilt6 0:557a92280097 177
neilt6 13:27c19044ace6 178 float LM75B::temp()
neilt6 0:557a92280097 179 {
neilt6 0:557a92280097 180 //Signed return value
neilt6 0:557a92280097 181 short value;
neilt6 0:557a92280097 182
neilt6 0:557a92280097 183 //Read the 11-bit raw temperature value
neilt6 8:2b797c309258 184 value = read16(REG_TEMP) >> 5;
neilt6 0:557a92280097 185
neilt6 0:557a92280097 186 //Sign extend negative numbers
neilt6 0:557a92280097 187 if (value & (1 << 10))
neilt6 0:557a92280097 188 value |= 0xFC00;
neilt6 0:557a92280097 189
neilt6 0:557a92280097 190 //Return the temperature in °C
neilt6 0:557a92280097 191 return value * 0.125;
neilt6 0:557a92280097 192 }
neilt6 0:557a92280097 193
neilt6 16:7ac462ba84ac 194 #ifdef MBED_OPERATORS
neilt6 13:27c19044ace6 195 LM75B::operator float()
neilt6 13:27c19044ace6 196 {
neilt6 13:27c19044ace6 197 //Return the current temperature reading
neilt6 13:27c19044ace6 198 return temp();
neilt6 13:27c19044ace6 199 }
neilt6 16:7ac462ba84ac 200 #endif
neilt6 13:27c19044ace6 201
neilt6 8:2b797c309258 202 char LM75B::read8(char reg)
neilt6 0:557a92280097 203 {
neilt6 0:557a92280097 204 //Select the register
neilt6 13:27c19044ace6 205 m_I2C.write(m_ADDR, &reg, 1, true);
neilt6 0:557a92280097 206
neilt6 0:557a92280097 207 //Read the 8-bit register
neilt6 13:27c19044ace6 208 m_I2C.read(m_ADDR, &reg, 1);
neilt6 0:557a92280097 209
neilt6 0:557a92280097 210 //Return the byte
neilt6 0:557a92280097 211 return reg;
neilt6 0:557a92280097 212 }
neilt6 0:557a92280097 213
neilt6 8:2b797c309258 214 void LM75B::write8(char reg, char data)
neilt6 0:557a92280097 215 {
neilt6 0:557a92280097 216 //Create a temporary buffer
neilt6 0:557a92280097 217 char buff[2];
neilt6 0:557a92280097 218
neilt6 0:557a92280097 219 //Load the register address and 8-bit data
neilt6 0:557a92280097 220 buff[0] = reg;
neilt6 0:557a92280097 221 buff[1] = data;
neilt6 0:557a92280097 222
neilt6 0:557a92280097 223 //Write the data
neilt6 13:27c19044ace6 224 m_I2C.write(m_ADDR, buff, 2);
neilt6 0:557a92280097 225 }
neilt6 0:557a92280097 226
neilt6 8:2b797c309258 227 unsigned short LM75B::read16(char reg)
neilt6 0:557a92280097 228 {
neilt6 0:557a92280097 229 //Create a temporary buffer
neilt6 0:557a92280097 230 char buff[2];
neilt6 0:557a92280097 231
neilt6 0:557a92280097 232 //Select the register
neilt6 13:27c19044ace6 233 m_I2C.write(m_ADDR, &reg, 1, true);
neilt6 0:557a92280097 234
neilt6 0:557a92280097 235 //Read the 16-bit register
neilt6 13:27c19044ace6 236 m_I2C.read(m_ADDR, buff, 2);
neilt6 0:557a92280097 237
neilt6 0:557a92280097 238 //Return the combined 16-bit value
neilt6 0:557a92280097 239 return (buff[0] << 8) | buff[1];
neilt6 0:557a92280097 240 }
neilt6 0:557a92280097 241
neilt6 8:2b797c309258 242 void LM75B::write16(char reg, unsigned short data)
neilt6 0:557a92280097 243 {
neilt6 0:557a92280097 244 //Create a temporary buffer
neilt6 0:557a92280097 245 char buff[3];
neilt6 0:557a92280097 246
neilt6 0:557a92280097 247 //Load the register address and 16-bit data
neilt6 0:557a92280097 248 buff[0] = reg;
neilt6 0:557a92280097 249 buff[1] = data >> 8;
neilt6 0:557a92280097 250 buff[2] = data;
neilt6 0:557a92280097 251
neilt6 0:557a92280097 252 //Write the data
neilt6 13:27c19044ace6 253 m_I2C.write(m_ADDR, buff, 3);
neilt6 0:557a92280097 254 }
neilt6 0:557a92280097 255
neilt6 8:2b797c309258 256 float LM75B::readAlertTempHelper(char reg)
neilt6 0:557a92280097 257 {
neilt6 0:557a92280097 258 //Signed return value
neilt6 0:557a92280097 259 short value;
neilt6 0:557a92280097 260
neilt6 0:557a92280097 261 //Read the 9-bit raw temperature value
neilt6 8:2b797c309258 262 value = read16(reg) >> 7;
neilt6 0:557a92280097 263
neilt6 0:557a92280097 264 //Sign extend negative numbers
neilt6 0:557a92280097 265 if (value & (1 << 8))
neilt6 0:557a92280097 266 value |= 0xFF00;
neilt6 0:557a92280097 267
neilt6 0:557a92280097 268 //Return the temperature in °C
neilt6 0:557a92280097 269 return value * 0.5;
neilt6 0:557a92280097 270 }
neilt6 0:557a92280097 271
neilt6 8:2b797c309258 272 void LM75B::writeAlertTempHelper(char reg, float temp)
neilt6 0:557a92280097 273 {
neilt6 0:557a92280097 274 //Range limit temp
neilt6 0:557a92280097 275 if (temp < -55.0)
neilt6 0:557a92280097 276 temp = -55.0;
neilt6 0:557a92280097 277 else if (temp > 125.0)
neilt6 0:557a92280097 278 temp = 125.0;
neilt6 0:557a92280097 279
neilt6 0:557a92280097 280 //Extract and shift the signed integer
neilt6 0:557a92280097 281 short value = temp * 2;
neilt6 0:557a92280097 282 value <<= 7;
neilt6 0:557a92280097 283
neilt6 0:557a92280097 284 //Send the new value
neilt6 8:2b797c309258 285 write16(reg, value);
neilt6 0:557a92280097 286 }