diff --git a/docs/images/lidarlitev3.jpg b/docs/images/lidarlitev3.jpg new file mode 100644 index 00000000..fa191692 Binary files /dev/null and b/docs/images/lidarlitev3.jpg differ diff --git a/examples/c++/lidarlitev3.cxx b/examples/c++/lidarlitev3.cxx new file mode 100644 index 00000000..f52548d7 --- /dev/null +++ b/examples/c++/lidarlitev3.cxx @@ -0,0 +1,64 @@ +/* + * Author: Saloni Jain + * Author: Niti Rohilla + * Copyright (c) 2014 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 "lidarlitev3.hpp" + +volatile int doWork = 0; + +void +sig_handler(int signo) +{ + if (signo == SIGINT) { + printf("\nCtrl-C received.\n"); + doWork = 1; + } +} + +int +main(int argc, char **argv) +{ + + // Register signal handler + signal(SIGINT, sig_handler); + + //! [Interesting] + upm::LIDARLITEV3 *sensor = new upm::LIDARLITEV3(0, ADDR); + + while (!doWork) { + std::cout << "Distance = " << sensor->getDistance () << std::endl; + usleep (50000); + } + + //! [Interesting] + + std::cout << "exiting application" << std::endl; + + delete sensor; + + return 0; +} diff --git a/src/lidarlitev3/CMakeLists.txt b/src/lidarlitev3/CMakeLists.txt new file mode 100644 index 00000000..08d92aa7 --- /dev/null +++ b/src/lidarlitev3/CMakeLists.txt @@ -0,0 +1,5 @@ +upm_mixed_module_init (NAME lidarlitev3 + DESCRIPTION "Optical Distance Measurement Sensor" + CPP_HDR lidarlitev3.hpp + CPP_SRC lidarlitev3.cxx + REQUIRES mraa) diff --git a/src/lidarlitev3/javaupm_lidarlitev3.i b/src/lidarlitev3/javaupm_lidarlitev3.i new file mode 100644 index 00000000..15157d8f --- /dev/null +++ b/src/lidarlitev3/javaupm_lidarlitev3.i @@ -0,0 +1,19 @@ +%module javaupm_lidarlitev3 +%include "../upm.i" + +%{ + #include "lidarlitev3.hpp" +%} + +%include "lidarlitev3.hpp" + +%pragma(java) jniclasscode=%{ + static { + try { + System.loadLibrary("javaupm_lidarlitev3"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. \n" + e); + System.exit(1); + } + } +%} diff --git a/src/lidarlitev3/jsupm_lidarlitev3.i b/src/lidarlitev3/jsupm_lidarlitev3.i new file mode 100644 index 00000000..f68e1c06 --- /dev/null +++ b/src/lidarlitev3/jsupm_lidarlitev3.i @@ -0,0 +1,8 @@ +%module jsupm_lidarlitev3 +%include "../upm.i" + +%{ + #include "lidarlitev3.hpp" +%} + +%include "lidarlitev3.hpp" diff --git a/src/lidarlitev3/lidarlitev3.cxx b/src/lidarlitev3/lidarlitev3.cxx new file mode 100644 index 00000000..681b6dcf --- /dev/null +++ b/src/lidarlitev3/lidarlitev3.cxx @@ -0,0 +1,139 @@ +/* + * Author: Saloni Jain + * Author: Niti Rohilla + * Copyright (c) 2014 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 "lidarlitev3.hpp" + +using namespace upm; + +LIDARLITEV3::LIDARLITEV3 (int bus, int devAddr) : m_i2ControlCtx(bus) { + m_name = "LIDARLITEV3"; + + m_controlAddr = devAddr; + m_bus = bus; + + mraa::Result ret = m_i2ControlCtx.address(m_controlAddr); + if (ret != mraa::SUCCESS) { + throw std::invalid_argument(std::string(__FUNCTION__) + + ": mraa_i2c_address() failed"); + } +} + +int +LIDARLITEV3::getDistance () { + + if(i2cWriteReg(ACQ_COMMAND, 0x04) < 0) + return -1; + + return read(0x8f,true); +} + +uint16_t +LIDARLITEV3::read(int reg, bool monitorBusyFlag) { + int busyFlag = 0; // busyFlag monitors when the device is done with a measurement + int busyCounter = 0; // busyCounter counts number of times busy flag is checked, for timeout + uint8_t data; + uint16_t distance; + + if(monitorBusyFlag) { + busyFlag = 1; // Begin read immediately if not monitoring busy flag + } + + while(busyFlag != 0) { // Loop until device is not busy + // Read status register to check busy flag + data = i2cReadReg_8 (0x01); // Read register 0x01 + busyFlag = data & 1; // Assign the LSB of the status register to busyFlag + + busyCounter++; // Increment busyCounter for timeout + + // Handle timeout condition, exit while loop and goto bailout + if(busyCounter > 9999) { + goto timeout; + } + } + + if (busyFlag == 0) { + // Read bytes to obtain 16-bit measured distance in centimeters + distance = i2cReadReg_16(0x8f); + } + + // timeout reports error + if(busyCounter > 9999) { + timeout: + busyCounter = 0; + throw std::invalid_argument(std::string(__FUNCTION__) + + ": Read timeout"); + } + return distance; +} + +uint16_t +LIDARLITEV3::i2cReadReg_16 (int reg) { + uint16_t data; + + m_i2ControlCtx.address(m_controlAddr); + m_i2ControlCtx.writeByte(reg); + + m_i2ControlCtx.address(m_controlAddr); + m_i2ControlCtx.read((uint8_t *)&data, 0x2); + + uint8_t high = (data & 0xFF00) >> 8; + data = (data << 8) & 0xFF00; + data |= high; + + return data; +} + +uint8_t +LIDARLITEV3::i2cReadReg_8 (int reg) { + uint8_t data; + + m_i2ControlCtx.address(m_controlAddr); + m_i2ControlCtx.writeByte(reg); + + m_i2ControlCtx.address(m_controlAddr); + m_i2ControlCtx.read(&data, 0x1); + + return data; +} + +mraa::Result +LIDARLITEV3::i2cWriteReg (uint8_t reg, uint8_t value) { + mraa::Result error = mraa::SUCCESS; + + uint8_t data[2] = { reg, value }; + error = m_i2ControlCtx.address (m_controlAddr); + error = m_i2ControlCtx.write (data, 2); + if ( error != mraa::SUCCESS) + throw std::invalid_argument(std::string(__FUNCTION__) + + ": mraa_i2c_write() failed"); + + return error; +} diff --git a/src/lidarlitev3/lidarlitev3.hpp b/src/lidarlitev3/lidarlitev3.hpp new file mode 100644 index 00000000..c17c56c4 --- /dev/null +++ b/src/lidarlitev3/lidarlitev3.hpp @@ -0,0 +1,162 @@ +/* + * Author: Saloni Jain + * Author: Niti Rohilla + * Copyright (c) 2014 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. + */ +#pragma once + +#include +#include + +#define ADDR 0x62 // device address + +// registers address +#define ACQ_COMMAND 0x00 // Device Command +#define STATUS 0x01 // System Status +#define SIG_COUNT_VAL 0x02 // Maximum Acquisition Count +#define ACQ_CONFIG_REG 0x04 // Acquisition Mode Control +#define VELOCITY 0x09 // Velocity measurement output +#define PEAK_CORR 0x0C // Peak value in correlation record +#define NOISE_PEAK 0x0D // Correaltion record noise floor +#define SIGNAL_STRENGTH 0x0E // Received signal strength +#define FULL_DELAY_HIGH 0x0F // Distance measurement high byte +#define FULL_DELAY_LOW 0x10 // Distance measurement low byte +#define OUTER_LOOP_COUNT 0x11 // Burst measurement count conttrol +#define REF_COUNT_VAL 0x12 // Reference acquisition count +#define LAST_DELAY_HIGH 0x14 // Previous distance measurement high byte +#define LAST_DELAY_LOW 0x15 // Previous distance measurement low byte +#define UNIT_ID_HIGH 0x16 // Serial number high byte +#define UNIT_ID_LOW 0x17 // Serial number low byte +#define I2C_ID_HIGH 0x18 // Write serial number high byte for I2C address unclock +#define I2C_ID_LOW 0x19 // Write serial number low byte for I2X address unlock +#define I2C_SEC_ADDR 0x1A // Write new I2C address after unlock +#define THRESHOLD_BYPASS 0x1C // Peak detection threshold bypass +#define I2C_CONFIG 0x1E // Default address response control +#define COMMAND 0x40 // State command +#define MEASURE_DELAY 0x45 // Delay between automatic measurements +#define PEAK_BCK 0x4C // Second largest peak value on correlation record +#define CORR_DATA 0x52 // Correlation record data lo byte +#define CORR_DATA_SIGN 0x53 // Correlation record data high byte +#define ACQ_SETTINGS 0x5D // Correaltion record memory bank select +#define POWER_CONTROL 0x65 // Power state control + +#define HIGH 1 +#define LOW 0 + +namespace upm { + +/** + * @brief LIDARLITEV3 Optical Distance Measurement Sensor library + * @defgroup lidarlitev3 libupm-lidarlitev3 + * @ingroup garmin i2c light + */ +/** + * @library lidarlightv3 + * @sensor lidarlightv3 + * @comname Optical Distance Measurement Sensor + * @type light + * @man garmin + * @con i2c + * @web https://www.sparkfun.com/products/14032 + * + * @brief API for the LIDARLITEV3 Optical Distance Measurement Sensor + * + * It is a compact, high-performance optical distance measurement + * sensor from Garmin. + * [LIDARLITEV3 Datasheet] + * http://static.garmin.com/pumac/LIDAR_Lite_v3_Operation_Manual_and_Technical_Specifications.pdf + * + * @snippet lidarlitev3.cxx Interesting + */ +class LIDARLITEV3 { + public: + /** + * Instantiates an LIDARLITEV3 object + * + * @param bus Number of the used bus + * @param devAddr Address of the used I2C device: 0x62 + */ + LIDARLITEV3 (int bus, int devAddr=ADDR); + + /** + * LIDARLITEV3 object destructor; basically, it closes the I2C connection. + * + *~LIDARLITEV3 (); + * no need for the destructor - the I2c connection will be closed when + * m_i2ControlCtx variable will be out of context + **/ + + /** + * Returns distance measurement on success + * Retruns -1 on failure. + */ + int getDistance (); + + /** + * Read + * Perform I2C read from device. + * + * @param reg register address to read from. + * @param monitorBusyFlag if true, the routine will repeatedly read the status + * register until the busy flag (LSB) is 0. + */ + uint16_t read(int reg, bool monitorBusyFlag); + + /** + * Returns the name of the component + */ + std::string name() + { + return m_name; + } + + /** + * Reads a one-byte register + * + * @param reg Address of the register + */ + uint8_t i2cReadReg_8 (int reg); + + /** + * Reads a two-byte register + * + * @param reg Address of the register + */ + uint16_t i2cReadReg_16 (int reg); + + /** + * Writes to a one-byte register + * + * @param reg Address of the register + * @param value Byte to be written + */ + mraa::Result i2cWriteReg (uint8_t reg, uint8_t value); + + private: + std::string m_name; + + int m_controlAddr; + int m_bus; + mraa::I2c m_i2ControlCtx; +}; + +} diff --git a/src/lidarlitev3/pyupm_lidarlitev3.i b/src/lidarlitev3/pyupm_lidarlitev3.i new file mode 100644 index 00000000..bdf5c9d6 --- /dev/null +++ b/src/lidarlitev3/pyupm_lidarlitev3.i @@ -0,0 +1,13 @@ +// Include doxygen-generated documentation +%include "pyupm_doxy2swig.i" +%module pyupm_lidarlitev3 +%include "../upm.i" + +%include "stdint.i" + +%feature("autodoc", "3"); + +%include "lidarlitev3.hpp" +%{ + #include "lidarlitev3.hpp" +%}