ms5803: initial implementation; C, C++; FTI + examples

Signed-off-by: Jon Trulson <jtrulson@ics.com>
This commit is contained in:
Jon Trulson
2016-11-11 17:41:28 -07:00
parent 7bc9ef0150
commit 803f9a9838
20 changed files with 1645 additions and 0 deletions

View File

@ -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)

View File

@ -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);
}
}
%}

12
src/ms5803/jsupm_ms5803.i Normal file
View File

@ -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"
%}

504
src/ms5803/ms5803.c Normal file
View File

@ -0,0 +1,504 @@
/*
* 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 <unistd.h>
#include <string.h>
#include <assert.h>
#include "ms5803.h"
#include <upm_math.h>
#include <upm_platform.h>
#include <upm_utilities.h>
// 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; i<MS5803_MAX_COEFFICIENTS; i++)
{
uint8_t cmd = MS5803_CMD_PROM_READ | ((i & 7) << 1);
if (ms5803_bus_read(dev, cmd, buffer, 2))
{
printf("%s: ms5802_bus_read() failed.\n", __FUNCTION__);
return UPM_ERROR_OPERATION_FAILED;
}
dev->C[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; i<len; i++)
data[i] = sbuf[i + 1];
}
else
{
// I2C
if (mraa_i2c_read_bytes_data(dev->i2c, 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; i<len; i++)
sbuf[i + 1] = data[i];
}
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);
}
else
{
// I2C...
uint8_t buffer[len + 1];
buffer[0] = cmd;
if (data && len)
{
for (int i=0; i<len; i++)
buffer[i+1] = data[i];
}
mraa_result_t rv = mraa_i2c_write(dev->i2c, 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;
}

118
src/ms5803/ms5803.cxx Normal file
View File

@ -0,0 +1,118 @@
/*
* 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 <unistd.h>
#include <iostream>
#include <stdexcept>
#include <string>
#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");
}

205
src/ms5803/ms5803.h Normal file
View File

@ -0,0 +1,205 @@
/*
* 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.
*/
#pragma once
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <upm.h>
#include <mraa/i2c.h>
#include <mraa/spi.h>
#include <mraa/gpio.h>
#include <ms5803_defs.h>
#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

183
src/ms5803/ms5803.hpp Normal file
View File

@ -0,0 +1,183 @@
/*
* 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.
*/
#pragma once
#include <string>
#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:
};
}

77
src/ms5803/ms5803_defs.h Normal file
View File

@ -0,0 +1,77 @@
/*
* 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.
*/
#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

125
src/ms5803/ms5803_fti.c Normal file
View File

@ -0,0 +1,125 @@
/*
* 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 "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;
}

18
src/ms5803/pyupm_ms5803.i Normal file
View File

@ -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"
%}