From 803f9a9838c5ab10548fc2406ce0de4702938fdc Mon Sep 17 00:00:00 2001 From: Jon Trulson Date: Fri, 11 Nov 2016 17:41:28 -0700 Subject: [PATCH] ms5803: initial implementation; C, C++; FTI + examples Signed-off-by: Jon Trulson --- examples/c++/CMakeLists.txt | 1 + examples/c++/ms5803.cxx | 78 +++++ examples/c/CMakeLists.txt | 1 + examples/c/ms5803.c | 79 +++++ examples/java/CMakeLists.txt | 1 + examples/java/MS5803_Example.java | 56 ++++ examples/javascript/ms5803.js | 53 ++++ examples/python/ms5803.py | 58 ++++ include/fti/upm_pressure.h | 42 +++ include/upm_fti.h | 1 + src/ms5803/CMakeLists.txt | 9 + src/ms5803/javaupm_ms5803.i | 24 ++ src/ms5803/jsupm_ms5803.i | 12 + src/ms5803/ms5803.c | 504 ++++++++++++++++++++++++++++++ src/ms5803/ms5803.cxx | 118 +++++++ src/ms5803/ms5803.h | 205 ++++++++++++ src/ms5803/ms5803.hpp | 183 +++++++++++ src/ms5803/ms5803_defs.h | 77 +++++ src/ms5803/ms5803_fti.c | 125 ++++++++ src/ms5803/pyupm_ms5803.i | 18 ++ 20 files changed, 1645 insertions(+) create mode 100644 examples/c++/ms5803.cxx create mode 100644 examples/c/ms5803.c create mode 100644 examples/java/MS5803_Example.java create mode 100644 examples/javascript/ms5803.js create mode 100755 examples/python/ms5803.py create mode 100644 include/fti/upm_pressure.h create mode 100644 src/ms5803/CMakeLists.txt create mode 100644 src/ms5803/javaupm_ms5803.i create mode 100644 src/ms5803/jsupm_ms5803.i create mode 100644 src/ms5803/ms5803.c create mode 100644 src/ms5803/ms5803.cxx create mode 100644 src/ms5803/ms5803.h create mode 100644 src/ms5803/ms5803.hpp create mode 100644 src/ms5803/ms5803_defs.h create mode 100644 src/ms5803/ms5803_fti.c create mode 100644 src/ms5803/pyupm_ms5803.i diff --git a/examples/c++/CMakeLists.txt b/examples/c++/CMakeLists.txt index d240f284..9d44cef3 100644 --- a/examples/c++/CMakeLists.txt +++ b/examples/c++/CMakeLists.txt @@ -321,6 +321,7 @@ add_example (hka5) add_example (dfrorp) add_example (dfrec) add_example (sht1x) +add_example (ms5803) # These are special cases where you specify example binary, source file and module(s) include_directories (${PROJECT_SOURCE_DIR}/src) diff --git a/examples/c++/ms5803.cxx b/examples/c++/ms5803.cxx new file mode 100644 index 00000000..f06ae5b9 --- /dev/null +++ b/examples/c++/ms5803.cxx @@ -0,0 +1,78 @@ +/* + * Author: Jon Trulson + * 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 +#include +#include + +#include "ms5803.hpp" + +using namespace std; +using namespace upm; + +int shouldRun = true; + +void sig_handler(int signo) +{ + if (signo == SIGINT) + shouldRun = false; +} + + +int main(int argc, char **argv) +{ + signal(SIGINT, sig_handler); +//! [Interesting] + + // Instantiate a MS5803 instance using i2c bus 0 and default address + upm::MS5803 *sensor = new upm::MS5803(0); + + // For SPI, bus 0, you would pass -1 as the address, and a valid + // pin for CS (or -1 if you are using a hw pin you have no control + // over, like edison): + // MS5803(0, -1, 9); + + while (shouldRun) + { + // update our values from the sensor + sensor->update(); + + cout << "Temperature: " + << sensor->getTemperature() + << " C, " + << "Pressure: " + << sensor->getPressure() + << " mbar" + << endl; + + sleep(1); + } +//! [Interesting] + + cout << "Exiting..." << endl; + + delete sensor; + + return 0; +} diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt index 756de1b4..bfd4a2b7 100644 --- a/examples/c/CMakeLists.txt +++ b/examples/c/CMakeLists.txt @@ -138,6 +138,7 @@ add_example (otp538u) add_example (button) add_example (button_intr) add_example (my9221) +add_example (ms5803) # Custom examples add_custom_example (nmea_gps_i2c-example-c nmea_gps_i2c.c nmea_gps) diff --git a/examples/c/ms5803.c b/examples/c/ms5803.c new file mode 100644 index 00000000..dfdc56d0 --- /dev/null +++ b/examples/c/ms5803.c @@ -0,0 +1,79 @@ +/* + * Author: Jon Trulson + * 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 +#include +#include + +#include "ms5803.h" +#include "upm_utilities.h" + +bool shouldRun = true; + +void sig_handler(int signo) +{ + if (signo == SIGINT) + shouldRun = false; +} + +int main() +{ + signal(SIGINT, sig_handler); + +//! [Interesting] + + // Instantiate a MS5803 on analog I2C bus 0, at the default address + ms5803_context sensor = ms5803_init(0, MS5803_DEFAULT_I2C_ADDR, -1); + + if (!sensor) + { + printf("ms5803_init() failed\n"); + return 1; + } + + // Every second, sample the sensor and output the pressure and + // temperature + + while (shouldRun) + { + if (ms5803_update(sensor)) + { + printf("ms5803_update() failed\n"); + } + + printf("Temperature: %f C, Pressure = %f mbar\n", + ms5803_get_temperature(sensor), + ms5803_get_pressure(sensor)); + + upm_delay(1); + } + +//! [Interesting] + + printf("Exiting\n"); + + ms5803_close(sensor); + + return 0; +} diff --git a/examples/java/CMakeLists.txt b/examples/java/CMakeLists.txt index 9bf6c386..cd0f2833 100644 --- a/examples/java/CMakeLists.txt +++ b/examples/java/CMakeLists.txt @@ -156,6 +156,7 @@ add_example(HKA5_Example hka5) add_example(DFRORP_Example dfrorp) add_example(DFREC_Example dfrec) add_example(SHT1X_Example sht1x) +add_example(MS5803_Example ms5803) add_example_with_path(Jhd1313m1_lcdSample lcd i2clcd) add_example_with_path(Jhd1313m1Sample lcd i2clcd) diff --git a/examples/java/MS5803_Example.java b/examples/java/MS5803_Example.java new file mode 100644 index 00000000..ef0afca1 --- /dev/null +++ b/examples/java/MS5803_Example.java @@ -0,0 +1,56 @@ +/* + * Author: Jon Trulson + * 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. + */ + +import upm_ms5803.MS5803; + +public class MS5803_Example +{ + public static void main(String[] args) throws InterruptedException + { +// ! [Interesting] + + // Instantiate a MS5803 instance using bus 0 and default i2c address + MS5803 sensor = new MS5803(0); + + // For SPI, bus 0, you would pass -1 as the address, and a + // valid pin for CS: + // MS5803(0, -1, 10); + + while (true) + { + // update our values from the sensor + sensor.update(); + + System.out.println("Temperature: " + + sensor.getTemperature() + + " C, Pressure: " + + sensor.getPressure() + + " mbar"); + + Thread.sleep(1000); + } + +// ! [Interesting] + } +} diff --git a/examples/javascript/ms5803.js b/examples/javascript/ms5803.js new file mode 100644 index 00000000..aed38c50 --- /dev/null +++ b/examples/javascript/ms5803.js @@ -0,0 +1,53 @@ +/* + * Author: Jon Trulson + * 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. + */ + +var sensorObj = require('jsupm_ms5803'); + +// Instantiate a MS5803 instance using bus 0 and default i2c address +var sensor = new sensorObj.MS5803(0); + +// For SPI, bus 0, you would pass -1 as the address, and a valid pin for CS: +// MS5803(0, -1, 10); + +setInterval(function() +{ + // update our values from the sensor + sensor.update(); + + console.log("Temperature: " + + sensor.getTemperature() + + " C, Pressure: " + + sensor.getPressure() + + " mbar"); +}, 1000); + +// exit on ^C +process.on('SIGINT', function() +{ + sensor = null; + sensorObj.cleanUp(); + sensorObj = null; + console.log("Exiting."); + process.exit(0); +}); diff --git a/examples/python/ms5803.py b/examples/python/ms5803.py new file mode 100755 index 00000000..7ba1acb5 --- /dev/null +++ b/examples/python/ms5803.py @@ -0,0 +1,58 @@ +#!/usr/bin/python +# Author: Jon Trulson +# 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. + +from __future__ import print_function +import time, sys, signal, atexit +from upm import pyupm_ms5803 as sensorObj + +def main(): + # Instantiate a MS5803 instance using bus 0 and default i2c address + sensor = sensorObj.MS5803(0) + + # For SPI, bus 0, you would pass -1 as the address, and a valid pin for CS: + # MS5803(0, -1, 10); + + ## Exit handlers ## + # This function stops python from printing a stacktrace when you + # hit control-C + def SIGINTHandler(signum, frame): + raise SystemExit + + # This function lets you run code on exit + def exitHandler(): + print("Exiting") + sys.exit(0) + + # Register exit handlers + atexit.register(exitHandler) + signal.signal(signal.SIGINT, SIGINTHandler) + + while (1): + sensor.update() + + print("Temperature:", sensor.getTemperature(), "C,", end=' ') + print("Pressure: ", sensor.getPressure(), "mbar") + time.sleep(1) + +if __name__ == '__main__': + main() diff --git a/include/fti/upm_pressure.h b/include/fti/upm_pressure.h new file mode 100644 index 00000000..5dcf2527 --- /dev/null +++ b/include/fti/upm_pressure.h @@ -0,0 +1,42 @@ +/* + * Authors: Jon Trulson + * 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. + */ +#ifndef UPM_PRESSURE_H_ +#define UPM_PRESSURE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// Pressure function table +typedef struct _upm_pressure_ft { + upm_result_t (*upm_pressure_set_scale) (void* dev, float scale); + upm_result_t (*upm_pressure_set_offset) (void* dev, float offset); + upm_result_t (*upm_pressure_get_value) (void* dev, float* value); +} upm_pressure_ft; + +#ifdef __cplusplus +} +#endif + +#endif /* UPM_PRESSURE_H_ */ diff --git a/include/upm_fti.h b/include/upm_fti.h index e7a5b8b0..9b34506c 100644 --- a/include/upm_fti.h +++ b/include/upm_fti.h @@ -124,6 +124,7 @@ typedef struct _upm_sensor_ft* (*func_get_upm_sensor_ft)(upm_sensor_t sensor_typ #include #include #include +#include #ifdef __cplusplus } diff --git a/src/ms5803/CMakeLists.txt b/src/ms5803/CMakeLists.txt new file mode 100644 index 00000000..d9b611d2 --- /dev/null +++ b/src/ms5803/CMakeLists.txt @@ -0,0 +1,9 @@ +upm_mixed_module_init (NAME ms5803 + DESCRIPTION "MS5803 Pressure and temperature sensor" + C_HDR ms5803.h ms5803_defs.h + C_SRC ms5803.c + CPP_HDR ms5803.hpp + CPP_SRC ms5803.cxx + FTI_SRC ms5803_fti.c + CPP_WRAPS_C + REQUIRES mraa) diff --git a/src/ms5803/javaupm_ms5803.i b/src/ms5803/javaupm_ms5803.i new file mode 100644 index 00000000..1bc6aa73 --- /dev/null +++ b/src/ms5803/javaupm_ms5803.i @@ -0,0 +1,24 @@ +%module javaupm_ms5803 +%include "../upm.i" +%include "typemaps.i" +%include "arrays_java.i" +%include "../java_buffer.i" +%include "std_string.i" + +%include "ms5803_defs.h" +%include "ms5803.hpp" +%{ + #include "ms5803.hpp" +%} + + +%pragma(java) jniclasscode=%{ + static { + try { + System.loadLibrary("javaupm_ms5803"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. \n" + e); + System.exit(1); + } + } +%} diff --git a/src/ms5803/jsupm_ms5803.i b/src/ms5803/jsupm_ms5803.i new file mode 100644 index 00000000..7828af88 --- /dev/null +++ b/src/ms5803/jsupm_ms5803.i @@ -0,0 +1,12 @@ +%module jsupm_ms5803 +%include "../upm.i" +%include "cpointer.i" +%include "std_string.i" + +%pointer_functions(float, floatp); + +%include "ms5803_defs.h" +%include "ms5803.hpp" +%{ + #include "ms5803.hpp" +%} diff --git a/src/ms5803/ms5803.c b/src/ms5803/ms5803.c new file mode 100644 index 00000000..f0189cdd --- /dev/null +++ b/src/ms5803/ms5803.c @@ -0,0 +1,504 @@ +/* + * Author: Jon Trulson + * 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 +#include +#include + +#include "ms5803.h" + +#include +#include +#include + +// quick binary power of 2 function +#define POWB(type, exp) ((type)1 << exp) + +// For SPI, these are our CS on/off functions, if needed +static void ms5803_cs_on(const ms5803_context dev) +{ + assert(dev != NULL); + + if (dev->gpio) + mraa_gpio_write(dev->gpio, 0); +} + +static void ms5803_cs_off(const ms5803_context dev) +{ + assert(dev != NULL); + + if (dev->gpio) + mraa_gpio_write(dev->gpio, 1); +} + +static upm_result_t ms5803_get_adc_value(const ms5803_context dev, + MS5803_CMD_T cmd, + MS5803_OSR_T dly, + uint32_t *value) +{ + assert(dev != NULL); + + uint8_t buf[3]; + + if (ms5803_bus_write(dev, cmd, NULL, 0)) + { + printf("%s: ms5802_bus_write() failed.\n", __FUNCTION__); + return UPM_ERROR_OPERATION_FAILED; + } + + // need to delay for the appropriate time + upm_delay_ms(dly); + + // now, get the 3 byte sample + if (ms5803_bus_read(dev, MS5803_CMD_ADC_READ, buf, 3)) + { + printf("%s: ms5802_bus_read() failed.\n", __FUNCTION__); + return UPM_ERROR_OPERATION_FAILED; + } + + *value = ((buf[0] << 16) | (buf[1] << 8) | buf[2]); + + return UPM_SUCCESS; +} + +ms5803_context ms5803_init(unsigned int bus, int address, int cs_pin) +{ + ms5803_context dev = + (ms5803_context)malloc(sizeof(struct _ms5803_context)); + + if (!dev) + return NULL; + + // zero out context + memset((void *)dev, 0, sizeof(struct _ms5803_context)); + + // make sure MRAA is initialized + int mraa_rv; + if ((mraa_rv = mraa_init()) != MRAA_SUCCESS) + { + printf("%s: mraa_init() failed (%d).\n", __FUNCTION__, mraa_rv); + ms5803_close(dev); + return NULL; + } + + if (address > 0) + { + // we are doing I2C + dev->isSPI = false; + + if (!(dev->i2c = mraa_i2c_init(bus))) + { + printf("%s: mraa_i2c_init() failed.\n", __FUNCTION__); + ms5803_close(dev); + return NULL; + } + + if (mraa_i2c_address(dev->i2c, address) != MRAA_SUCCESS) + { + printf("%s: mraa_i2c_address() failed.\n", __FUNCTION__); + ms5803_close(dev); + return NULL; + } + +#if defined(UPM_PLATFORM_ZEPHYR) + // we seem to need to stick qith 100khz for some reason with + // this device on Zephyr. Even at 100Khz, while calibration + // data is now read correctly, there are other issues yet to + // be determined. But as a first step, 100Khz is a + // requirement for this driver on Zephyr. + if (mraa_i2c_frequency(dev->i2c, MRAA_I2C_STD)) + { + printf("%s: mraa_i2c_frequency() failed.\n", __FUNCTION__); + ms5803_close(dev); + return NULL; + } +#endif // UPM_PLATFORM_ZEPHYR + + } + else + { + // we are doing SPI + dev->isSPI = true; + + if (!(dev->spi = mraa_spi_init(bus))) + { + printf("%s: mraa_spi_init() failed.\n", __FUNCTION__); + ms5803_close(dev); + return NULL; + } + + // Only create cs context if we are actually using a valid pin. + // A hardware controlled pin should specify cs as -1. + if (cs_pin >= 0) + { + if (!(dev->gpio = mraa_gpio_init(cs_pin))) + { + printf("%s: mraa_gpio_init() failed.\n", __FUNCTION__); + ms5803_close(dev); + return NULL; + } + + mraa_gpio_dir(dev->gpio, MRAA_GPIO_OUT); + ms5803_cs_off(dev); + } + + if (mraa_spi_mode(dev->spi, MRAA_SPI_MODE0)) + { + printf("%s: mraa_spi_mode() failed.\n", __FUNCTION__); + ms5803_close(dev); + return NULL; + } + + if (mraa_spi_frequency(dev->spi, 10000000)) + { + printf("%s: mraa_spi_frequency() failed.\n", __FUNCTION__); + ms5803_close(dev); + return NULL; + } + } + + // read factory coefficients + if (ms5803_load_coefficients(dev)) + { + printf("%s: ms5803_load_coefficients() failed.\n", __FUNCTION__); + ms5803_close(dev); + return NULL; + } + + // set the default OSR to the highest resolution + ms5803_set_temperature_osr(dev, MS5803_OSR_4096); + ms5803_set_pressure_osr(dev, MS5803_OSR_4096); + + return dev; +} + +void ms5803_close(ms5803_context dev) +{ + assert(dev != NULL); + + if (dev->i2c) + mraa_i2c_stop(dev->i2c); + + if (dev->spi) + mraa_spi_stop(dev->spi); + + if (dev->gpio) + mraa_gpio_close(dev->gpio); + + free(dev); +} + +upm_result_t ms5803_update(const ms5803_context dev) +{ + assert(dev != NULL); + + // start by getting temperature and then pressure + + uint32_t rawTemperature; + uint32_t rawPressure; + + // temperature + if (ms5803_get_adc_value(dev, dev->temperatureCmd, dev->temperatureDelay, + &rawTemperature)) + { + printf("%s: ms5803_get_adc_value() failed.\n", __FUNCTION__); + return UPM_ERROR_OPERATION_FAILED; + } + + // pressure + if (ms5803_get_adc_value(dev, dev->pressureCmd, dev->pressureDelay, + &rawPressure)) + { + printf("%s: ms5803_get_adc_value() failed.\n", __FUNCTION__); + return UPM_ERROR_OPERATION_FAILED; + } + +// printf("raw T = %u P = %u\n", rawTemperature, rawPressure); + + // This algorithm comes from the datasheet. + + // calc 1st order compensated temperature + int32_t dT = rawTemperature - dev->C[5] * POWB(int32_t, 8); + int32_t TEMP = 2000 + (int64_t)dT * dev->C[6] / POWB(int32_t, 23); + + // calc compensated temp and pressure + int64_t OFF, SENS; + int32_t P = 0; + + // first order compensation + OFF = dev->C[2] * POWB(int64_t, 16) + (dev->C[4] * dT)/POWB(int64_t, 7); + SENS = dev->C[1] * POWB(int64_t, 15) + (dev->C[3] * dT)/POWB(int64_t, 8); + + // second order compensation + int64_t T2 = 0, OFF2 = 0, SENS2 = 0; + if (TEMP >= 2000) + { + // >=20C + T2 = 7 * (((uint64_t)dT * dT) / POWB(int64_t, 37)); + OFF2 = ((TEMP - 2000) * (TEMP - 2000)) / POWB(int64_t, 4); + SENS2 = 0; + } + else + { + T2 = 3 * (((uint64_t)dT * dT) / POWB(int64_t, 33)); + OFF2 = 3 * ((TEMP - 2000) * (TEMP - 2000)) / POWB(int64_t, 1); + SENS2 = 5 * ((TEMP - 2000) * (TEMP - 2000)) / POWB(int64_t, 3); + + // further compensation for very low temps + if (TEMP < 1500) + { + // <15C + OFF2 = OFF2 + 7 * ((TEMP + 1500) * (TEMP + 1500)); + SENS2 = SENS2 + 4 * ((TEMP + 1500) * (TEMP + 1500)); + } + } + + // final caculation + TEMP = TEMP - T2; + OFF = OFF - OFF2; + SENS = SENS - SENS2; + P = (rawPressure * SENS/POWB(int64_t, 21) - OFF)/POWB(int64_t, 15); + + dev->temperature = (float)TEMP / 100.0; + dev->pressure = (float)P/10.0; + + return UPM_SUCCESS; +} + +upm_result_t ms5803_load_coefficients(const ms5803_context dev) +{ + assert(dev != NULL); + + // we will load them all, even though only 6 of them are of use to us + uint8_t buffer[2]; + + for (int i=0; iC[i] = (buffer[0] << 8) | buffer[1]; +// printf("C[%d] = %u\n", i, dev->C[i]); + } + + return UPM_SUCCESS; +} + +// i2c bus read and write functions +upm_result_t ms5803_bus_read(const ms5803_context dev, uint8_t cmd, + uint8_t *data, uint8_t len) +{ + assert(dev != NULL); + + if (dev->isSPI) + { + // SPI + + uint8_t sbuf[len + 1]; + memset((void *)sbuf, 0, len + 1); + sbuf[0] = cmd; + + ms5803_cs_on(dev); + + if (mraa_spi_transfer_buf(dev->spi, sbuf, sbuf, len + 1)) + { + ms5803_cs_off(dev); + printf("%s: mraa_spi_transfer_buf() failed.\n", __FUNCTION__); + return UPM_ERROR_OPERATION_FAILED; + } + ms5803_cs_off(dev); + + // now copy it into user buffer + for (int i=0; ii2c, cmd, data, len) < 0) + { + printf("%s: mraa_i2c_read_bytes() failed.\n", __FUNCTION__); + return UPM_ERROR_OPERATION_FAILED; + } + } + + return UPM_SUCCESS; +} + +upm_result_t ms5803_bus_write(const ms5803_context dev, uint8_t cmd, + uint8_t *data, uint8_t len) +{ + assert(dev != NULL); + + if (dev->isSPI) + { + // SPI + + uint8_t sbuf[len + 1]; + memset((void *)sbuf, 0, len + 1); + sbuf[0] = cmd; + + // copy in the data to write... + if (data && len) + { + for (int i=0; ispi, sbuf, sbuf, len + 1)) + { + ms5803_cs_off(dev); + printf("%s: mraa_spi_transfer_buf() failed.\n", __FUNCTION__); + return UPM_ERROR_OPERATION_FAILED; + } + ms5803_cs_off(dev); + } + else + { + // I2C... + + uint8_t buffer[len + 1]; + + buffer[0] = cmd; + + if (data && len) + { + for (int i=0; ii2c, buffer, len+1); + + if (rv != MRAA_SUCCESS) + { + printf("%s: mraa_i2c_write() failed.\n", __FUNCTION__); + return UPM_ERROR_OPERATION_FAILED; + } + } + + return UPM_SUCCESS; +} + +void ms5803_set_temperature_osr(const ms5803_context dev, MS5803_OSR_T osr) +{ + assert(dev != NULL); + + switch(osr) + { + case MS5803_OSR_256: + dev->temperatureCmd = MS5803_CMD_CONVERT_D2_OSR_256; + break; + + case MS5803_OSR_512: + dev->temperatureCmd = MS5803_CMD_CONVERT_D2_OSR_512; + break; + + case MS5803_OSR_1024: + dev->temperatureCmd = MS5803_CMD_CONVERT_D2_OSR_1024; + break; + + case MS5803_OSR_2048: + dev->temperatureCmd = MS5803_CMD_CONVERT_D2_OSR_2048; + break; + + case MS5803_OSR_4096: + dev->temperatureCmd = MS5803_CMD_CONVERT_D2_OSR_4096; + break; + + default: + // can't happen in this universe + printf("%s: Internal error, invalid osr value %d\n", __FUNCTION__, + (int)osr); + return; + } + + dev->temperatureDelay = osr; +} + +void ms5803_set_pressure_osr(const ms5803_context dev, MS5803_OSR_T osr) +{ + assert(dev != NULL); + + switch(osr) + { + case MS5803_OSR_256: + dev->pressureCmd = MS5803_CMD_CONVERT_D1_OSR_256; + break; + + case MS5803_OSR_512: + dev->pressureCmd = MS5803_CMD_CONVERT_D1_OSR_512; + break; + + case MS5803_OSR_1024: + dev->pressureCmd = MS5803_CMD_CONVERT_D1_OSR_1024; + break; + + case MS5803_OSR_2048: + dev->pressureCmd = MS5803_CMD_CONVERT_D1_OSR_2048; + break; + + case MS5803_OSR_4096: + dev->pressureCmd = MS5803_CMD_CONVERT_D1_OSR_4096; + break; + + default: + // can't happen in this universe + printf("%s: Internal error, invalid osr value %d\n", __FUNCTION__, + (int)osr); + return; + } + + dev->pressureDelay = osr; +} + +upm_result_t ms5803_reset(const ms5803_context dev) +{ + assert(dev != NULL); + + upm_result_t rv = ms5803_bus_write(dev, MS5803_CMD_RESET, NULL, 0); + upm_delay_ms(5); + + return rv; +} + +float ms5803_get_temperature(const ms5803_context dev) +{ + assert(dev != NULL); + + return dev->temperature; +} + +float ms5803_get_pressure(const ms5803_context dev) +{ + assert(dev != NULL); + + return dev->pressure; +} diff --git a/src/ms5803/ms5803.cxx b/src/ms5803/ms5803.cxx new file mode 100644 index 00000000..6cefa088 --- /dev/null +++ b/src/ms5803/ms5803.cxx @@ -0,0 +1,118 @@ +/* + * Author: Jon Trulson + * 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 +#include +#include +#include + +#include "ms5803.hpp" + +using namespace upm; +using namespace std; + +MS5803::MS5803(int bus, int address, int csPin) : + m_ms5803(ms5803_init(bus, address, csPin)) +{ + if (!m_ms5803) + throw std::runtime_error(string(__FUNCTION__) + + ": ms5803_init() failed"); +} + +MS5803::~MS5803() +{ + ms5803_close(m_ms5803); +} + +void MS5803::update() +{ + if (ms5803_update(m_ms5803)) + throw std::runtime_error(string(__FUNCTION__) + + ": ms5803_update() failed"); +} + +void MS5803::reset() +{ + if (ms5803_reset(m_ms5803)) + throw std::runtime_error(string(__FUNCTION__) + + ": ms5803_reset() failed"); +} + +void MS5803::setTemperatureOSR(MS5803_OSR_T osr) +{ + ms5803_set_temperature_osr(m_ms5803, osr); +} + +void MS5803::setPressureOSR(MS5803_OSR_T osr) +{ + ms5803_set_pressure_osr(m_ms5803, osr); +} + + +float MS5803::getTemperature() +{ + return ms5803_get_temperature(m_ms5803); +} + +float MS5803::getPressure() +{ + return ms5803_get_pressure(m_ms5803); +} + +void MS5803::loadCoefficients() +{ + if (ms5803_load_coefficients(m_ms5803)) + throw std::runtime_error(string(__FUNCTION__) + + ": ms5803_load_coefficients() failed"); +} + +string MS5803::busRead(int cmd, int len) +{ + uint8_t ucmd = (uint8_t)(cmd & 0xff); + uint8_t ulen = (uint8_t)(len & 0xff); + + uint8_t *data = new uint8_t[ulen]; + + if (ms5803_bus_read(m_ms5803, ucmd, data, ulen)) + { + delete [] data; + throw std::runtime_error(string(__FUNCTION__) + + ": ms5803_bus_read() failed"); + } + + string dataStr((char *)data, ulen); + delete [] data; + + return dataStr; +} + +void MS5803::busWrite(int cmd, string data) +{ + uint8_t ucmd = (uint8_t)(cmd & 0xff); + + if (ms5803_bus_write(m_ms5803, ucmd, (uint8_t *)data.data(), + (uint8_t)data.size())) + throw std::runtime_error(string(__FUNCTION__) + + ": ms5803_bus_write() failed"); +} diff --git a/src/ms5803/ms5803.h b/src/ms5803/ms5803.h new file mode 100644 index 00000000..dd68e5da --- /dev/null +++ b/src/ms5803/ms5803.h @@ -0,0 +1,205 @@ +/* + * Author: Jon Trulson + * 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. + */ +#pragma once + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * @file ms5803 + * @library ms5803 + * @brief C API for the MS5803 Pressure and Temperature sensor + * + * @include ms5803.c + */ + + /** + * Device context + */ + typedef struct _ms5803_context { + mraa_i2c_context i2c; + mraa_spi_context spi; + // CS pin, if we are using one + mraa_gpio_context gpio; + + // whether we are doing I2C or SPI + bool isSPI; + + // stored calibration coefficients + uint16_t C[MS5803_MAX_COEFFICIENTS]; + + // the command sent to chip depending on OSR configuration for + // temperature and pressure measurement. + MS5803_CMD_T temperatureCmd; + MS5803_OSR_T temperatureDelay; + + MS5803_CMD_T pressureCmd; + MS5803_OSR_T pressureDelay; + + // compensated temperature in C + float temperature; + // compensated pressure in millibars + float pressure; + } *ms5803_context; + + /** + * MS5803 initializer + * + * @param bus i2c/spi bus to use + * @param address The address for this device if using I2C. If + * using SPI, supply -1 for this parameter. + * @param cs_pin The GPIO pin to use for Chip Select (CS). This is + * only needed for SPI, and only if your SPI implementation + * requires it. Otherwise, just pass -1 if not using SPI, or your + * CS is handled automatically by your SPI implementation. + * @return an initialized device context on success, NULL on error. + */ + ms5803_context ms5803_init(unsigned int bus, int address, int cs_pin); + + /** + * MS5803 close + * + * @param dev Device context. + */ + void ms5803_close(ms5803_context dev); + + /** + * Reset the device. + * + * @param dev Device context. + * @return UPM Status. + */ + upm_result_t ms5803_reset(const ms5803_context dev); + + /** + * Take measurements and store the current sensor values + * internally. This function must be called prior to retrieving + * any sensor values, for example ms5803_get_temperature(). + * + * @param dev Device context. + */ + upm_result_t ms5803_update(const ms5803_context dev); + + /** + * Set the output sampling resolution of the temperature + * measurement. Higher values provide a more precise value. In + * addition, more precise values require more time to measure. + * The default set at device intialization is the highest + * precision supported: MS5803_OSR_4096 + * + * @param dev Device context. + * @param dev One of the MS5803_OSR_T values. + */ + void ms5803_set_temperature_osr(const ms5803_context dev, + MS5803_OSR_T osr); + + /** + * Set the output sampling resolution of the pressure + * measurement. Higher values provide a more precise value. In + * addition, more precise values require more time to measure. + * The default set at device intialization is the highest + * precision supported: MS5803_OSR_4096 + * + * @param dev Device context. + * @param dev One of the MS5803_OSR_T values. + */ + void ms5803_set_pressure_osr(const ms5803_context dev, + MS5803_OSR_T osr); + + /** + * Return the latest measured temperature. ms5803_update() must + * have been called prior to calling this function. The returned + * value is in degrees Celsius. + * + * @param dev Device context. + * @return Temperature in degrees C + */ + float ms5803_get_temperature(const ms5803_context dev); + + /** + * Return the latest measured pressure. ms5803_update() must have + * been called prior to calling this function. The returned value + * is in millibars. + * + * @param dev Device context. + * @return Pressure in mbar + */ + float ms5803_get_pressure(const ms5803_context dev); + + /** + * Load a series of factory installed compensation coefficients. + * This function is called during ms5803_init(), so it should + * never need to be called again. It is provided here anyway + * "just in case". + * + * @param dev Device context. + * @return UPM Status. + */ + upm_result_t ms5803_load_coefficients(const ms5803_context dev); + + /** + * Perform a bus read. This function is bus agnostic. It is + * exposed here for those users wishing to perform their own low + * level accesses. This is a low level function, and should not + * be used unless you know what you are doing. + * + * @param dev Device context + * @param cmd The command to send. + * @param data A pointer to a buffer in which data will be read into. + * @param len The number of bytes to read. + * @return UPM Status + */ + upm_result_t ms5803_bus_read(const ms5803_context dev, uint8_t cmd, + uint8_t *data, uint8_t len); + + /** + * Perform a bus write. This function is bus agnostic. It is + * exposed here for those users wishing to perform their own low + * level accesses. This is a low level function, and should not + * be used unless you know what you are doing. + * + * @param dev Device context + * @param cmd The command to send. + * @param data A pointer to a buffer containing data to write. + * @param len The number of bytes to write. + * @return UPM Status + */ + upm_result_t ms5803_bus_write(const ms5803_context dev, uint8_t cmd, + uint8_t *data, uint8_t len); + +#ifdef __cplusplus +} +#endif diff --git a/src/ms5803/ms5803.hpp b/src/ms5803/ms5803.hpp new file mode 100644 index 00000000..82966284 --- /dev/null +++ b/src/ms5803/ms5803.hpp @@ -0,0 +1,183 @@ +/* + * Author: Jon Trulson + * 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. + */ +#pragma once + +#include + +#include "ms5803.h" + +namespace upm { + + /** + * @brief MS5803 Pressure and Temperature sensor + * @defgroup ms5803 libupm-ms5803 + * @ingroup i2c spi gpio temperature pressure + */ + + /** + * @library ms5803 + * @sensor ms5803 + * @comname MS5803 Pressure and Temperature sensor + * @type temperature pressure + * @man sparkfun + * @con i2c spi + * @web https://www.sparkfun.com/products/12909 + * + * @brief UPM API for the MS5803 Pressure and Temperature sensor + * + * The MS5803-14BA is a new generation of high resolution pressure + * sensors with SPI and I2C bus interface. It is optimized for + * depth measurement systems with a water depth resolution of 1cm + * and below. The sensor module includes a high linear pressure + * sensor and an ultra low power 24 bit ΔΣ ADC with internal + * factory calibrated coefficients. It provides a precise digital + * 24 Bit pressure and temperature value and different operation + * modes that allow the user to optimize for conversion speed and + * current consumption. A high resolution temperature output + * allows the implementation of a depth measurement systems and + * thermometer function without any additional sensor. + * + * The device is driven at 3.3vdc, and has a pressure range of + * between 0 and 14 Bar, and a temperature range fo between -40 + * and +85C. + * + * @snippet ms5803.cxx Interesting + */ + class MS5803 { + public: + + /** + * MS5803 constructor. The default arguments inititialize I2C + * operation and the default I2C address. + * + * @param bus i2c/spi bus to use + * @param address The address for this device if using I2C. If + * using SPI, supply -1 for this parameter. + * @param csPin The GPIO pin to use for Chip Select (CS). This is + * only needed for SPI, and only if your SPI implementation + * requires it. Otherwise, just pass -1 if not using SPI, or your + * CS is handled automatically by your SPI implementation. + */ + MS5803(int bus, int address=MS5803_DEFAULT_I2C_ADDR, + int csPin=-1); + + /** + * MS5803 Destructor + */ + ~MS5803(); + + /** + * Reset the device. + * + */ + void reset(); + + /** + * Take a measurement and store the current sensor values + * internally. This function must be called prior to retrieving + * any sensor values, for example getTemperature(). + * + */ + void update(); + + /** + * Set the output sampling resolution of the temperature + * measurement. Higher values provide a more precise value. In + * addition, more precise values require more time to measure. + * The default set at device intialization is the highest + * precision supported: MS5803_OSR_4096 + * + * @param dev One of the MS5803_OSR_T values. + */ + void setTemperatureOSR(MS5803_OSR_T osr); + + /** + * Set the output sampling resolution of the pressure + * measurement. Higher values provide a more precise value. In + * addition, more precise values require more time to measure. + * The default set at device intialization is the highest + * precision supported: MS5803_OSR_4096 + * + * @param dev One of the MS5803_OSR_T values. + */ + void setPressureOSR(MS5803_OSR_T osr); + + /** + * Return the latest measured temperature. update() must have + * been called prior to calling this function. The returned + * value is in degrees Celsius. + * + * @return Temperature in degrees C + */ + float getTemperature(); + + /** + * Return the latest measured pressure. update() must have + * been called prior to calling this function. The returned + * value is in millibars. + * + * @return Pressure in mbar + */ + float getPressure(); + + protected: + ms5803_context m_ms5803; + + /** + * Load a series of factory installed compensation coefficients. + * This function is called during ms5803_init(), so it should + * never need to be called again. It is provided here anyway + * "just in case". + * + * @param dev Device context. + * @return UPM Status. + */ + void loadCoefficients(); + + /** + * Perform a bus read. This function is bus agnostic. It is + * exposed here for those users wishing to perform their own low + * level accesses. This is a low level function, and should not + * be used unless you know what you are doing. + * + * @param cmd The command or register to access. + * @param cnt The number of bytes to read. + * @return The data read + */ + std::string busRead(int cmd, int len); + + /** + * Perform a bus write. This function is bus agnostic. It is + * exposed here for those users wishing to perform their own low + * level accesses. This is a low level function, and should not + * be used unless you know what you are doing. + * + * @param cmd The command or register to access. + * @param data The string containing the data to write + */ + void busWrite(int cmd, std::string data); + + private: + }; +} diff --git a/src/ms5803/ms5803_defs.h b/src/ms5803/ms5803_defs.h new file mode 100644 index 00000000..825fce4e --- /dev/null +++ b/src/ms5803/ms5803_defs.h @@ -0,0 +1,77 @@ +/* + * Author: Jon Trulson + * 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. + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +// default I2C address +#define MS5803_DEFAULT_I2C_ADDR 0x76 + +#define MS5803_MAX_COEFFICIENTS (8) + + // valid commands + typedef enum { + MS5803_CMD_RESET = 0x1e, + + // D1 = pressure + MS5803_CMD_CONVERT_D1_OSR_256 = 0x40, + MS5803_CMD_CONVERT_D1_OSR_512 = 0x42, + MS5803_CMD_CONVERT_D1_OSR_1024 = 0x44, + MS5803_CMD_CONVERT_D1_OSR_2048 = 0x46, + MS5803_CMD_CONVERT_D1_OSR_4096 = 0x48, + + // D2 = temperature + MS5803_CMD_CONVERT_D2_OSR_256 = 0x50, + MS5803_CMD_CONVERT_D2_OSR_512 = 0x52, + MS5803_CMD_CONVERT_D2_OSR_1024 = 0x54, + MS5803_CMD_CONVERT_D2_OSR_2048 = 0x56, + MS5803_CMD_CONVERT_D2_OSR_4096 = 0x58, + + // ADC read + MS5803_CMD_ADC_READ = 0x00, + + // PROM read. Bits 1, 2, and 3 indicate the address. Bit 0 is + // always 0 (in all commands). There are 7 PROM locations, + // each 2 bytes in length. These locations store factory + // loaded compensation coefficients. + MS5803_CMD_PROM_READ = 0xa0 + } MS5803_CMD_T; + + // output sampling resolution for temperature and pressure. We + // set the numeric values here to indicate the required wait time + // for each in milliseconds (rounded up from the datasheet + // maximums), so do not change these numbers. + typedef enum { + MS5803_OSR_256 = 1, // 1ms + MS5803_OSR_512 = 2, + MS5803_OSR_1024 = 3, + MS5803_OSR_2048 = 5, + MS5803_OSR_4096 = 10 + } MS5803_OSR_T; + +#ifdef __cplusplus +} +#endif diff --git a/src/ms5803/ms5803_fti.c b/src/ms5803/ms5803_fti.c new file mode 100644 index 00000000..6d6d6a27 --- /dev/null +++ b/src/ms5803/ms5803_fti.c @@ -0,0 +1,125 @@ +/* + * Author: Jon Trulson + * 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 "ms5803.h" +#include "upm_fti.h" + +/** + * This file implements the Function Table Interface (FTI) for this sensor + */ + +const char upm_ms5803_name[] = "MS5803"; +const char upm_ms5803_description[] = "MS5803 Pressure and Temperature Sensor"; +const upm_protocol_t upm_ms5803_protocol[] = {UPM_SPI, UPM_I2C, UPM_GPIO}; +const upm_sensor_t upm_ms5803_category[] = {UPM_TEMPERATURE, UPM_PRESSURE}; + +// forward declarations +const void* upm_ms5803_get_ft(upm_sensor_t sensor_type); +void* upm_ms5803_init_name(); +void upm_ms5803_close(void *dev); +upm_result_t upm_ms5803_get_pressure(void *dev, float *value); +upm_result_t upm_ms5803_get_temperature(void *dev, float *value, + upm_temperature_u unit); + +static const upm_sensor_ft ft = +{ + .upm_sensor_init_name = upm_ms5803_init_name, + .upm_sensor_close = upm_ms5803_close, +}; + +static const upm_temperature_ft tft = +{ + .upm_temperature_get_value = upm_ms5803_get_temperature, +}; + +static const upm_pressure_ft pft = +{ + .upm_pressure_get_value = upm_ms5803_get_pressure, +}; + +const void* upm_ms5803_get_ft(upm_sensor_t sensor_type) +{ + switch(sensor_type) + { + case UPM_SENSOR: + return &ft; + case UPM_PRESSURE: + return &pft; + case UPM_TEMPERATURE: + return &tft; + default: + return NULL; + } +} + +void* upm_ms5803_init_name() +{ + return NULL; +} + +void upm_ms5803_close(void *dev) +{ + ms5803_close((ms5803_context)dev); +} + +upm_result_t upm_ms5803_get_pressure(void *dev, float *value) +{ + upm_result_t rv; + + if ((rv = ms5803_update((ms5803_context)dev))) + return rv; + + *value = ms5803_get_pressure((ms5803_context)dev); + + return UPM_SUCCESS; +} + +upm_result_t upm_ms5803_get_temperature(void *dev, float *value, + upm_temperature_u unit) +{ + upm_result_t rv; + + if ((rv = ms5803_update((ms5803_context)dev))) + return rv; + + // always in C + float temp = ms5803_get_temperature((ms5803_context)dev); + + switch (unit) + { + case CELSIUS: + *value = temp; + return UPM_SUCCESS; + + case KELVIN: + *value = temp + 273.15; + return UPM_SUCCESS; + + case FAHRENHEIT: + *value = temp * (9.0/5.0) + 32.0; + return UPM_SUCCESS; + } + + return UPM_SUCCESS; +} diff --git a/src/ms5803/pyupm_ms5803.i b/src/ms5803/pyupm_ms5803.i new file mode 100644 index 00000000..91370e2c --- /dev/null +++ b/src/ms5803/pyupm_ms5803.i @@ -0,0 +1,18 @@ +// Include doxygen-generated documentation +%include "pyupm_doxy2swig.i" +%module pyupm_ms5803 +%include "../upm.i" +%include "cpointer.i" +%include "std_string.i" + +%include "stdint.i" + +%feature("autodoc", "3"); + +%pointer_functions(float, floatp); + +%include "ms5803_defs.h" +%include "ms5803.hpp" +%{ + #include "ms5803.hpp" +%}