From f2b8921f1e227f5de9011d05f83005db50d15a4c Mon Sep 17 00:00:00 2001 From: Henry Bruce Date: Wed, 6 Jan 2016 15:31:46 -0800 Subject: [PATCH] t6713: Initial Implementation Amphenol Telaire 6713 Series CO2 sensor Signed-off-by: Henry Bruce Signed-off-by: Abhishek Malik --- src/t6713/CMakeLists.txt | 5 + src/t6713/jsupm_t6713.i | 9 ++ src/t6713/pyupm_t6713.i | 10 ++ src/t6713/t6713.cxx | 283 +++++++++++++++++++++++++++++++++++++++ src/t6713/t6713.h | 153 +++++++++++++++++++++ 5 files changed, 460 insertions(+) create mode 100644 src/t6713/CMakeLists.txt create mode 100644 src/t6713/jsupm_t6713.i create mode 100644 src/t6713/pyupm_t6713.i create mode 100644 src/t6713/t6713.cxx create mode 100644 src/t6713/t6713.h diff --git a/src/t6713/CMakeLists.txt b/src/t6713/CMakeLists.txt new file mode 100644 index 00000000..83149760 --- /dev/null +++ b/src/t6713/CMakeLists.txt @@ -0,0 +1,5 @@ +set (libname "t6713") +set (libdescription "upm Amphenol Telaire 6713 Series CO2 Module") +set (module_src ${libname}.cxx) +set (module_h ${libname}.h) +upm_module_init() diff --git a/src/t6713/jsupm_t6713.i b/src/t6713/jsupm_t6713.i new file mode 100644 index 00000000..35572d78 --- /dev/null +++ b/src/t6713/jsupm_t6713.i @@ -0,0 +1,9 @@ +%module jsupm_t6713 +%include "../upm.i" +%include "../carrays_uint16_t.i" + +%{ + #include "t6713.h" +%} + +%include "t6713.h" diff --git a/src/t6713/pyupm_t6713.i b/src/t6713/pyupm_t6713.i new file mode 100644 index 00000000..ad1c338b --- /dev/null +++ b/src/t6713/pyupm_t6713.i @@ -0,0 +1,10 @@ +%module pyupm_t6713 +%include "../upm.i" +%include "stdint.i" + +%feature("autodoc", "3"); + +%include "t6713.h" +%{ + #include "t6713.h" +%} diff --git a/src/t6713/t6713.cxx b/src/t6713/t6713.cxx new file mode 100644 index 00000000..81e534da --- /dev/null +++ b/src/t6713/t6713.cxx @@ -0,0 +1,283 @@ +/* + * Author: HCL + * Copyright (c) 2015 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 +#include +#include +#include +#include +#include + +#define T6713_ADDR 0x15 + +/* REGISTER ADDRESSES */ +#define T6713_REG_FIRMWARE_REVISION 0x1389 + +#define T6713_REG_STATUS 0x138A + +#define T6713_REG_GAS_PPM 0x138B + +#define T6713_REG_RESET_DEVICE 0x03E8 + +#define T6713_REG_START_SINGLE_POINT_CAL 0x03EC + +#define T6713_REG_CHANGE_SLAVE_ADDRESS 0x0FA5 + +#define T6713_REG_ABC_LOGIC_ENABLE_DISABLE 0x03EE + +using namespace upm; +using namespace upm::t6713_co2; + +T6713::T6713 (int bus) +{ + i2c = new mraa::I2c(bus); + status = i2c->address(T6713_ADDR); + uint16_t firmwareRevision = getFirmwareRevision(); + if (!isConfigured()) + UPM_THROW("config failure"); +} + +T6713::~T6713() +{ + delete i2c; +} + +bool T6713::isConfigured() +{ + return status == mraa::SUCCESS; +} + +const char* T6713::getModuleName() +{ + return "t6713"; +} + +uint16_t T6713::getFirmwareRevision() +{ + return(getSensorData(T6713_COMMAND_GET_FIRMWARE_REVISION)); +} + +uint16_t T6713::getPpm () +{ + return(getSensorData(T6713_COMMAND_GET_GAS_PPM)); +} + +uint16_t T6713::getSensorData (MODBUS_COMMANDS cmd) +{ + uint16_t data ,readBytes ; + STATUS currStatus ; + switch(currStatus = getStatus()) /* handle error conditions */ + { + case ERROR_CONDITION: + UPM_THROW ("error condition"); + break; + case FLASH_ERROR: + UPM_THROW ("flash error"); + break; + case CALIBRATION_ERROR: + UPM_THROW ("calibration error"); + break; + case WARMUP_MODE: + //UPM_THROW ("warmup mode"); + break; + case RS232: + //printf("\nRS232 mode set\n "); + break; + case RS485: + //printf("\nRS485 mode set\n "); + break; + case I2C: + //printf("\nI2C mode set\n"); + data = 0; + runCommand(cmd); + mraa::Result ret = i2c->address(T6713_ADDR); + if (ret != mraa::SUCCESS) + { + UPM_THROW ("I2C error setting slave address"); + // TODO: need to handle this + } + RESPONSE * response = new RESPONSE ; + if(readBytes = i2c->read((uint8_t*)(response), sizeof(RESPONSE) ) != sizeof(RESPONSE)) + { + UPM_THROW("I2C read failed"); + // TODO + } + if(response->function_code == READ_INPUT_REGISTERS) + { + if(response->byte_count == 2) + { + data = (response->status_msb << 8 | response->status_lsb); + } + } + delete(response); response=NULL; + return(data); + break; + } + return 0; + +} + + +mraa::Result T6713::runCommand(MODBUS_COMMANDS cmd) +{ + + COMMAND * cmdPacket = new COMMAND ; + mraa::Result ret; + + switch(cmd) + { + case T6713_COMMAND_RESET: + cmdPacket->function_code = WRITE_SINGLE_COIL; + cmdPacket->register_address_msb = (T6713_REG_RESET_DEVICE >> 8); + cmdPacket->register_address_lsb = (T6713_REG_RESET_DEVICE & 0xff); + cmdPacket->input_registers_to_read_msb = 0xff; + cmdPacket->input_registers_to_read_lsb = 0x00; + ret = i2c->write((const uint8_t*) (cmdPacket), sizeof(COMMAND)); + /*no response from the slave */ + break; + case T6713_COMMAND_STATUS: + /*created the modbus status command packet*/ + cmdPacket->function_code = READ_INPUT_REGISTERS; + cmdPacket->register_address_msb = (T6713_REG_STATUS >> 8); + cmdPacket->register_address_lsb = (T6713_REG_STATUS & 0xff); + cmdPacket->input_registers_to_read_msb = 0; + cmdPacket->input_registers_to_read_lsb = 1; + ret = i2c->address(T6713_ADDR); + if (ret != mraa::SUCCESS) + { + UPM_THROW ("I2C error setting slave address"); + } + + if((ret = i2c->write((const uint8_t*) (cmdPacket), sizeof(COMMAND))) != mraa::SUCCESS) + { + UPM_THROW("I2C write failed"); + } + + + break; + case T6713_COMMAND_GET_FIRMWARE_REVISION: + cmdPacket->function_code = READ_INPUT_REGISTERS; + cmdPacket->register_address_msb = (T6713_REG_FIRMWARE_REVISION >> 8); + cmdPacket->register_address_lsb = (T6713_REG_FIRMWARE_REVISION & 0xff); + cmdPacket->input_registers_to_read_msb = 0; + cmdPacket->input_registers_to_read_lsb = 1; + ret = i2c->write((const uint8_t*) (cmdPacket), sizeof(COMMAND)); + break; + case T6713_COMMAND_GET_GAS_PPM: + cmdPacket->function_code = READ_INPUT_REGISTERS; + cmdPacket->register_address_msb = (T6713_REG_GAS_PPM >> 8); + cmdPacket->register_address_lsb = (T6713_REG_GAS_PPM & 0xff); + + cmdPacket->input_registers_to_read_msb = 0; + cmdPacket->input_registers_to_read_lsb = 1; + ret = i2c->address(T6713_ADDR); + if (ret != mraa::SUCCESS) + { + UPM_THROW ("I2C error setting slave address"); + //need to handle this + } + + + if((ret = i2c->write((const uint8_t*) (cmdPacket), sizeof(COMMAND))) != mraa::SUCCESS) + { + UPM_THROW("I2C write failed"); + } + + break; + } + delete cmdPacket; cmdPacket=NULL; + + return ret; +} + + +STATUS T6713::getStatus() +{ + uint16_t responseStatus = 0, readBytes = 0; + RESPONSE * response = new RESPONSE ; + runCommand(T6713_COMMAND_STATUS); + mraa::Result ret = i2c->address(T6713_ADDR); + if (ret != mraa::SUCCESS) + { + UPM_THROW ("I2C error setting slave address"); + //need to handle tnis + } + if(readBytes = i2c->read((uint8_t*) (response), sizeof(RESPONSE)) != sizeof(RESPONSE)) + { + UPM_THROW("I2C read failed"); + + } + if(response->function_code == READ_INPUT_REGISTERS) + { + if(response->byte_count == 2) + { + responseStatus = (response->status_msb << 8 | response->status_lsb); + } + else + { + UPM_THROW("I2C read failed"); + + } + } + else + { + UPM_THROW("MODBUS function code failed"); + } + + delete(response); + + if(responseStatus & 0x0001) + { + return ERROR_CONDITION; + } + if(responseStatus & 0x0002) + { + return FLASH_ERROR; + } + if(responseStatus & 0x0004) + { + return CALIBRATION_ERROR; + } + if(responseStatus & 0x0800) + { + return WARMUP_MODE; + } + if(responseStatus & 0x8000) + { + return SINGLE_POINT_CALIBRATION; + } + if(responseStatus & 0x0100) + { + return RS232; + } + if(responseStatus & 0x0400) + { + return RS485; + } + else + { + return I2C; + } +} + diff --git a/src/t6713/t6713.h b/src/t6713/t6713.h new file mode 100644 index 00000000..795e55d9 --- /dev/null +++ b/src/t6713/t6713.h @@ -0,0 +1,153 @@ +/* + * Author: HCL + * Copyright (c) 2015 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 "mraa/i2c.hpp" +#include "upm/iCO2Sensor.h" + +namespace upm { + +/** + * @brief Amphenol Telaire 6713 Series CO2 Module + * @defgroup t6713 libupm-t6713 + * @ingroup i2c telaire gas ico2sensor + */ + +/** + * @brief C++ API for Amphenol Telaire 6713 Series CO2 Module + * + * The Telaire 6713 Series CO2 Module + * [6713](http://amphenol-sensors.com/en/products/co2/co2-modules/3215-t6700#specifications-t6713) + * is a CO2 Module sensor. + * + * @library t6713 + * @sensor t6713 + * @comname Telaire 6713 Series CO2 Module + * @altname T6713 + * @type gaseous + * @man amphenol + * @con i2c + * @if ic02sensor + + */ +namespace t6713_co2 +{ + /* COMMAND VALUES */ + typedef enum + { + T6713_COMMAND_RESET, + T6713_COMMAND_STATUS, + T6713_COMMAND_GET_FIRMWARE_REVISION, + T6713_COMMAND_GET_GAS_PPM + }MODBUS_COMMANDS; + + + + typedef enum + { + ERROR_CONDITION, + FLASH_ERROR, + CALIBRATION_ERROR, + WARMUP_MODE, + SINGLE_POINT_CALIBRATION, + RS232, + I2C, + RS485 + }STATUS; + + typedef struct + { + uint8_t function_code; + uint8_t register_address_msb; + uint8_t register_address_lsb; + uint8_t input_registers_to_read_msb; + uint8_t input_registers_to_read_lsb; + + }COMMAND; + + typedef struct + { + uint8_t function_code; + uint8_t byte_count; + uint8_t status_msb; + uint8_t status_lsb; + + }RESPONSE; + + + typedef enum + { + READ_INPUT_REGISTERS = 4, + WRITE_SINGLE_COIL, + WRITE_SINGLE_HOLDING_REGISTER + }FUNCTION_CODES; +}//namespace t6713_co2 + + +class T6713 : public ICO2Sensor { + public: + /** + * Instantiates a T6713 object + * + * @param bus number of used bus + */ + T6713 (int bus); + + /** + * SI7005 object destructor. + */ + ~T6713 (); + + /** + * Returns whether the sensor is configured. + */ + bool isConfigured(); + + /** + * Returns sensor module name + */ + const char* getModuleName(); + + /** + * Get relative humidity measurement. + */ + uint16_t getPpm (); + /** + * Get the firmware version + */ + uint16_t getFirmwareRevision(); + + + private: + mraa::Result runCommand(t6713_co2::MODBUS_COMMANDS command); + uint16_t getSensorData (t6713_co2::MODBUS_COMMANDS cmd); + t6713_co2::STATUS getStatus(); + + int bus; + mraa::I2c* i2c; + mraa::Result status; +}; + + +}//namespace upm