diff options
Diffstat (limited to 'peripheral/libupm/src/ds18b20/ds18b20.cxx')
-rw-r--r-- | peripheral/libupm/src/ds18b20/ds18b20.cxx | 298 |
1 files changed, 0 insertions, 298 deletions
diff --git a/peripheral/libupm/src/ds18b20/ds18b20.cxx b/peripheral/libupm/src/ds18b20/ds18b20.cxx deleted file mode 100644 index 0848fe3..0000000 --- a/peripheral/libupm/src/ds18b20/ds18b20.cxx +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Author: Jon Trulson <jtrulson@ics.com> - * Copyright (c) 2016 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include <iostream> -#include <time.h> -#include <stdexcept> - -#include "ds18b20.hpp" - -using namespace upm; -using namespace std; - -// conversion from celcius to fahrenheit -static float c2f(float c) -{ - return (c * (9.0 / 5.0) + 32.0); -} - -DS18B20::DS18B20(int uart) : - m_uart(uart) -{ - m_devicesFound = 0; - - // check basic access to the 1-wire bus (presence detect) - mraa::Result rv; - - if ((rv = m_uart.reset()) != mraa::SUCCESS) - { - throw std::runtime_error(std::string(__FUNCTION__) + - ": reset() failed, no devices on bus?"); - } -} - -DS18B20::~DS18B20() -{ -} - -void DS18B20::init() -{ - // iterate through the bus and build up a list of detected DS18B20 - // devices (only) - - // empty the map, in case this method has already been run once - // before - m_devicesFound = 0; - m_deviceMap.clear(); - - sensor_info_t sinfo; - - // defaults - sinfo.temperature = 0.0; - sinfo.resolution = RESOLUTION_12BITS; - - // start the search from scratch - string id = m_uart.search(true); - if (id.empty()) - { - throw std::runtime_error(std::string(__FUNCTION__) + - ": no devices detected on bus"); - } - - while (!id.empty()) - { - // The first byte (id[0]]) is the device type (family) code. We - // are only interested in the family code for these devices. - - if ((uint8_t)id[0] == DS18B20_FAMILY_CODE) - { - // we have a winner, add it to our map and continue searching - - sinfo.id = id; - m_deviceMap[m_devicesFound] = sinfo; - - m_devicesFound++; - } - - // continue search - id = m_uart.search(false); - } - - if (!m_devicesFound) - { - throw std::runtime_error(std::string(__FUNCTION__) + - ": no DS18B20 devices found on bus"); - } - - // iterate through the found devices and query their resolutions - for (int i=0; i<m_devicesFound; i++) - { - // read only the first 5 bytes of the scratchpad - static const int numScratch = 5; - uint8_t scratch[numScratch]; - - m_uart.command(CMD_READ_SCRATCHPAD, m_deviceMap[i].id); - for (int j=0; j<numScratch; j++) - scratch[j] = m_uart.readByte(); - - // config byte, shift the resolution to bit 0 - scratch[4] >>= _CFG_RESOLUTION_SHIFT; - - switch (scratch[4] & _CFG_RESOLUTION_MASK) - { - case 0: m_deviceMap[i].resolution = RESOLUTION_9BITS; break; - case 1: m_deviceMap[i].resolution = RESOLUTION_10BITS; break; - case 2: m_deviceMap[i].resolution = RESOLUTION_11BITS; break; - case 3: m_deviceMap[i].resolution = RESOLUTION_12BITS; break; - } - - // reset the bus - m_uart.reset(); - } -} - -void DS18B20::update(int index) -{ - if (index >= m_devicesFound) - { - throw std::out_of_range(std::string(__FUNCTION__) + - ": device index out of range"); - } - - // should we update all of them? - bool doAll = (index < 0) ? true : false; - - if (doAll) - { - // if we want to update all of them, we will first send the - // convert command to all of them, then wait. This will be - // faster, timey-wimey wise, then converting, sleeping, and - // reading each individual sensor. - - for (int i=0; i<m_devicesFound; i++) - m_uart.command(CMD_CONVERT, m_deviceMap[i].id); - } - else - m_uart.command(CMD_CONVERT, m_deviceMap[index].id); - - // wait for conversion(s) to finish - usleep(750000); // 750ms max - - if (doAll) - { - for (int i=0; i<m_devicesFound; i++) - m_deviceMap[i].temperature = readSingleTemp(i); - } - else - m_deviceMap[index].temperature = readSingleTemp(index); -} - -// utility function to read temp data from a single sensor -float DS18B20::readSingleTemp(int index) -{ - if (index < 0 || index >= m_devicesFound) - { - throw std::out_of_range(std::string(__FUNCTION__) + - ": device index out of range"); - } - - static const int numScratch = 9; - uint8_t scratch[numScratch]; - - // read the 9-byte scratchpad - m_uart.command(CMD_READ_SCRATCHPAD, m_deviceMap[index].id); - for (int i=0; i<numScratch; i++) - scratch[i] = m_uart.readByte(); - - // validate cksum -- if we get an error, we will warn and simply - // return the current (previously read) temperature - uint8_t crc = m_uart.crc8(scratch, 8); - - if (crc != scratch[8]) - { - cerr << __FUNCTION__ << ": crc check failed for device " - << index << ", returning previously measured temperature" << endl; - return m_deviceMap[index].temperature; - } - - // check the sign bit(s) - bool negative = (scratch[1] & 0x80) ? true : false; - - // shift everything into position - int16_t temp = (scratch[1] << 8) | scratch[0]; - - // grab the fractional - uint8_t frac = temp & 0x0f; - - // depending on the resolution, some frac bits should be ignored, so - // we mask them off. For 12bits, all bits are valid so we leve them - // alone. - - switch (m_deviceMap[index].resolution) - { - case RESOLUTION_9BITS: frac &= 0x08; break; - case RESOLUTION_10BITS: frac &= 0x0c; break; - case RESOLUTION_11BITS: frac &= 0x0e; break; - } - - // remove the fractional with extreme prejudice - temp >>= 4; - - // compensate for sign - if (negative) - temp -= 65536; // 2^^16 - - // convert - return ( float(temp) + (float(frac) * 0.0625) ); -} - -float DS18B20::getTemperature(int index, bool fahrenheit) -{ - if (index < 0 || index >= m_devicesFound) - { - throw std::out_of_range(std::string(__FUNCTION__) + - ": device index out of range"); - } - - if (fahrenheit) - return c2f(m_deviceMap[index].temperature); - else - return m_deviceMap[index].temperature; -} - -void DS18B20::setResolution(int index, RESOLUTIONS_T res) -{ - if (index < 0 || index >= m_devicesFound) - { - throw std::out_of_range(std::string(__FUNCTION__) + - ": device index out of range"); - } - - static const int numScratch = 9; - uint8_t scratch[numScratch]; - - // read the 9-byte scratchpad - m_uart.command(CMD_READ_SCRATCHPAD, m_deviceMap[index].id); - for (int i=0; i<numScratch; i++) - scratch[i] = m_uart.readByte(); - - // resolution is stored in byte 4 - scratch[4] = ((scratch[4] & ~(_CFG_RESOLUTION_MASK << _CFG_RESOLUTION_SHIFT)) - | (res << _CFG_RESOLUTION_SHIFT)); - - // now, write back, we only write 3 bytes (2-4), no cksum. - m_uart.command(CMD_WRITE_SCRATCHPAD, m_deviceMap[index].id); - for (int i=0; i<3; i++) - m_uart.writeByte(scratch[i+2]); -} - -void DS18B20::copyScratchPad(int index) -{ - if (index < 0 || index >= m_devicesFound) - { - throw std::out_of_range(std::string(__FUNCTION__) + - ": device index out of range"); - } - - // issue the command - m_uart.command(CMD_COPY_SCRATCHPAD, m_deviceMap[index].id); - - sleep(1); // to be safe... -} - -void DS18B20::recallEEPROM(int index) -{ - if (index < 0 || index >= m_devicesFound) - { - throw std::out_of_range(std::string(__FUNCTION__) + - ": device index out of range"); - } - - // issue the command - m_uart.command(CMD_RECALL_EEPROM, m_deviceMap[index].id); - - // issue read timeslots until a '1' is read back, indicating completion - while (!m_uart.writeBit(1)) - usleep(100); -} |