diff --git a/examples/c++/CMakeLists.txt b/examples/c++/CMakeLists.txt index cd65ac9a..ae79dedf 100644 --- a/examples/c++/CMakeLists.txt +++ b/examples/c++/CMakeLists.txt @@ -342,6 +342,7 @@ add_example (hdc1000) add_example (bmg160) add_example (bma250e) add_example (bmm150) +add_example (rsc) # 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++/rsc.cxx b/examples/c++/rsc.cxx new file mode 100644 index 00000000..3b1fead7 --- /dev/null +++ b/examples/c++/rsc.cxx @@ -0,0 +1,64 @@ +/* + * Author: Abhishek Malik + * Copyright (c) 2017 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 "rsc.hpp" + +using namespace std; + +int shouldRun = true; + +void sig_handler(int signo) +{ + if (signo == SIGINT) + shouldRun = false; +} + + +int main () +{ + signal(SIGINT, sig_handler); + +//! [Interesting] + + upm::RSC* rsc = new upm::RSC(0, 9, 8); + + cout << "Sensor Name: " << rsc->getSensorName() << endl; + rsc->setMode(NORMAL_MODE); + rsc->setDataRate(N_DR_330_SPS); + while (shouldRun) { + cout << "inH2O pressure: " << rsc->getPressure() << endl; + cout << "Temp (C): " << rsc->getTemperature() << endl; + + sleep(1); + } +//! [Interesting] + + cout << "Exiting..." << endl; + + delete rsc; + return 0; +} diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt index 1be5d666..cc89dfa8 100644 --- a/examples/c/CMakeLists.txt +++ b/examples/c/CMakeLists.txt @@ -156,6 +156,7 @@ add_example (lcdks) add_example (bmg160) add_example (bma250e) add_example (bmm150) +add_example (rsc) # Custom examples add_custom_example (nmea_gps_i2c-example-c nmea_gps_i2c.c nmea_gps) diff --git a/examples/c/rsc.c b/examples/c/rsc.c new file mode 100644 index 00000000..eb8f832f --- /dev/null +++ b/examples/c/rsc.c @@ -0,0 +1,47 @@ +/* + * Author: Abhishek Malik + * Copyright (c) 2017 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 "upm_utilities.h" +#include "rsc.h" + +int main(void) { +//! [Interesting] + rsc_context dev = rsc_init(0, 9, 8); + + rsc_set_data_rate(dev, N_DR_330_SPS); + rsc_set_mode(dev, NORMAL_MODE); + + float pressure; + float temp; + while(1){ + pressure = rsc_get_pressure(dev); + printf("Retrieved pressure: %f %d\n", pressure, dev->unit); + temp = rsc_get_temperature(dev); + printf("Retieved temperature: %f C\n", temp); + upm_delay_ms(500); + } +//! [Interesting] + return 0; +} diff --git a/examples/javascript/rsc.js b/examples/javascript/rsc.js new file mode 100644 index 00000000..fdb1f2df --- /dev/null +++ b/examples/javascript/rsc.js @@ -0,0 +1,45 @@ +/* +* Author: Abhishek Malik +* Copyright (c) 2017 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 rsc = require("jsupm_rsc"); + +// Instantiate a Honeywell RSC Pressure Sensor at bus 0 +var rsc_sensor = new rsc.RSC(0, 9, 8); + +console.log("Sensor Name: " + rsc_sensor.getSensorName()); +console.log("Sensor Serial No.: " + rsc_sensor.getSensorSerialNumber()); + +var myInterval = setInterval(function() +{ + console.log("Pressure: " + rsc_sensor.getPressure() + " " + rsc_sensor.getPressureUnit()); + console.log("Temperature: " + rsc_sensor.getTemperature() + " C"); +}, 100); + +// When exiting: clear interval and print message +process.on('SIGINT', function() +{ + clearInterval(myInterval); + console.log("Exiting..."); + process.exit(0); +}); \ No newline at end of file diff --git a/examples/python/rsc.py b/examples/python/rsc.py new file mode 100644 index 00000000..9bee8075 --- /dev/null +++ b/examples/python/rsc.py @@ -0,0 +1,55 @@ +#!/usr/bin/python +# Author: Abhishek Malik +# Copyright (c) 2017 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_rsc as rsc + +def main(): + # Instantiate a Honeywell RSC Pressure sensor on the SPI bus 0 + rsc_sensor = rsc.RSC(0, 9, 8); + + ## 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, including functions from abpdrrt005pg2a5 + def exitHandler(): + print("Exiting") + sys.exit(0) + + # Register exit handlers + atexit.register(exitHandler) + signal.signal(signal.SIGINT, SIGINTHandler) + + # Read the value every second and detect the pressure + print("Sensor Name: {0}".format(rsc_sensor.getSensorName())) + print("Sensor Serial Number: {0}".format(rsc_sensor.getSensorSerialNumber())) + while(1): + print("Pressure {0}: {1}".format(rsc_sensor.getPressureUnit(), rsc_sensor.getPressure())) + print("Temperature C: {0}".format(rsc_sensor.getTemperature())) + time.sleep(1) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/src/rsc/CMakeLists.txt b/src/rsc/CMakeLists.txt new file mode 100644 index 00000000..cf090eb9 --- /dev/null +++ b/src/rsc/CMakeLists.txt @@ -0,0 +1,8 @@ +upm_mixed_module_init (NAME rsc + DESCRIPTION "Honeywell RSC TruStability Pressure and Temperature Sensor" + C_HDR rsc.h rsc_regs.h + C_SRC rsc.c + CPP_HDR rsc.hpp + CPP_SRC rsc.cxx + CPP_WRAPS_C + REQUIRES mraa) diff --git a/src/rsc/javaupm_rsc.i b/src/rsc/javaupm_rsc.i new file mode 100644 index 00000000..d474f0ae --- /dev/null +++ b/src/rsc/javaupm_rsc.i @@ -0,0 +1,19 @@ +%module javaupm_rsc +%include "../upm.i" + +%{ + #include "rsc.hpp" +%} + +%include "rsc.hpp" + +%pragma(java) jniclasscode=%{ + static { + try { + System.loadLibrary("javaupm_rsc"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. \n" + e); + System.exit(1); + } + } +%} \ No newline at end of file diff --git a/src/rsc/jsupm_rsc.i b/src/rsc/jsupm_rsc.i new file mode 100644 index 00000000..a3b91913 --- /dev/null +++ b/src/rsc/jsupm_rsc.i @@ -0,0 +1,8 @@ +%module jsupm_rsc +%include "../upm.i" + +%{ + #include "rsc.hpp" +%} + +%include "rsc.hpp" \ No newline at end of file diff --git a/src/rsc/pyupm_rsc.i b/src/rsc/pyupm_rsc.i new file mode 100644 index 00000000..e3f5edc9 --- /dev/null +++ b/src/rsc/pyupm_rsc.i @@ -0,0 +1,11 @@ +// Include doxygen-generated documentation +%include "pyupm_doxy2swig.i" +%module pyupm_rsc +%include "../upm.i" + +%feature("autodoc", "3"); + +%include "rsc.hpp" +%{ + #include "rsc.hpp" +%} \ No newline at end of file diff --git a/src/rsc/rsc.c b/src/rsc/rsc.c new file mode 100644 index 00000000..eab9d75e --- /dev/null +++ b/src/rsc/rsc.c @@ -0,0 +1,523 @@ +/* + * Author: Abhishek Malik + * Copyright (c) 2017 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 "rsc.h" + +upm_result_t rsc_eeprom_read(rsc_context dev, uint16_t address, uint8_t* buf, int len, uint8_t arglen); + +upm_result_t rsc_adc_write(rsc_context dev, uint8_t reg, uint8_t num_bytes, uint8_t* write_data); + +upm_result_t rsc_adc_read(rsc_context dev, READING_T type, uint8_t* data); + +upm_result_t rsc_add_dr_delay(rsc_context dev); + +void rsc_set_access_type(rsc_context dev, ACCESS_T type); + +rsc_context rsc_init(uint8_t bus, uint8_t cs_ee_pin, uint8_t cs_adc_pin) { + // 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); + return NULL; + } + + rsc_context dev = (rsc_context) malloc(sizeof(struct _rsc_context)); + if (!dev) { + return NULL; + } + + dev->spi_bus_number = bus; + + dev->spi = mraa_spi_init(dev->spi_bus_number); + if(dev->spi == NULL) + printf("RSC: SPI context not initialized\n"); + + // initializing the EEPROM chip select + dev->cs_ee = mraa_gpio_init(cs_ee_pin); + if(dev->cs_ee == NULL) + printf("RSC: EEPROM GPIO context not initialized\n"); + + if(mraa_gpio_dir(dev->cs_ee, MRAA_GPIO_OUT) != MRAA_SUCCESS) + printf("RSC: EEPROM GPIO direction could not be set\n"); + mraa_gpio_write(dev->cs_ee, 1); + + // initializing the ADC chip select + dev->cs_adc = mraa_gpio_init(cs_adc_pin); + if(dev->cs_adc == NULL) + printf("RSC: ADC GPIO context not initialized\n"); + + if(mraa_gpio_dir(dev->cs_adc, MRAA_GPIO_OUT) != MRAA_SUCCESS) + printf("RSC: ADC GPIO direction could not be set\n"); + mraa_gpio_write(dev->cs_adc, 1); + + // setting the frequency and spi mode + mraa_spi_frequency(dev->spi, 1250000); + //mraa_spi_mode(dev->spi, MRAA_SPI_MODE0); + //rsc_set_access_type(dev, EEPEROM); + + upm_delay_ms(100); + + uint8_t sensor_name[RSC_SENSOR_NAME_LEN]={0}; + rsc_get_sensor_name(dev, sensor_name); + //printf("sensor name: %s\n", sensor_name); + + upm_delay_ms(10); + uint8_t serial_number[RSC_SENSOR_NUMBER_LEN]={0}; + rsc_get_sensor_serial_number(dev, serial_number); + //printf("sensor serial number: %s\n", serial_number); + + upm_delay_ms(10); + float range = rsc_get_pressure_range(dev); + dev->pressure_range = range; + + upm_delay_ms(10); + float min_pressure = rsc_get_minimum_pressure(dev); + dev->min_pressure_val = min_pressure; + + upm_delay_ms(10); + rsc_get_pressure_unit(dev); + + upm_delay_ms(10); + rsc_get_pressure_type(dev); + + uint8_t adc_init_values[4]; + rsc_get_initial_adc_values(dev, adc_init_values); + + rsc_retrieve_coefficients(dev); + + //mraa_spi_frequency(dev->spi, 1250000); + //mraa_spi_mode(dev->spi, MRAA_SPI_MODE1); + //rsc_set_access_type(dev, ADC); + rsc_setup_adc(dev, adc_init_values); + + rsc_set_data_rate(dev, N_DR_20_SPS); + rsc_set_mode(dev, NORMAL_MODE); + + rsc_get_temperature(dev); + upm_delay_ms(50); + + return dev; +} + +upm_result_t rsc_close(rsc_context dev) { + free(dev); + return UPM_SUCCESS; +} + +void rsc_set_access_type(rsc_context dev, ACCESS_T type) { + switch(type) { + case EEPROM: + mraa_spi_mode(dev->spi, MRAA_SPI_MODE0); + break; + case ADC: + mraa_spi_mode(dev->spi, MRAA_SPI_MODE1); + break; + default: + // default mode is EEPROM + mraa_spi_mode(dev->spi, MRAA_SPI_MODE0); + } +} + +upm_result_t rsc_eeprom_read(rsc_context dev, uint16_t address, uint8_t* buf, int len, uint8_t arglen) { + uint8_t lbuf[len+arglen]; + lbuf[0] = RSC_READ_EEPROM_INSTRUCTION; + lbuf[1] = address & 0xff; + lbuf[0] = ((address & RSC_EEPROM_ADDRESS_9TH_BIT_MASK) >> 5) | lbuf[0]; + + mraa_gpio_write(dev->cs_ee, 0); + if(mraa_spi_transfer_buf(dev->spi, lbuf, lbuf, len+arglen) != MRAA_SUCCESS) { + printf("RSC: ISsues in SPI transfer\n"); + return UPM_ERROR_OPERATION_FAILED; + } + + mraa_gpio_write(dev->cs_ee, 1); + int i=0; + for(i=arglen;iunit = INH2O; + else if(pressure_unit[RSC_PRESSURE_UNIT_LEN-2] == 'a') + if(pressure_unit[RSC_PRESSURE_UNIT_LEN-4] == 'K') + dev->unit = KPASCAL; + else if (pressure_unit[RSC_PRESSURE_UNIT_LEN-4] == 'M') + dev->unit = MPASCAL; + else + dev->unit = PASCAL; + else if(pressure_unit[RSC_PRESSURE_UNIT_LEN-2] == 'r') + if(pressure_unit[RSC_PRESSURE_UNIT_LEN-5] == 'm') + dev->unit = mBAR; + else + dev->unit = BAR; + else if(pressure_unit[RSC_PRESSURE_UNIT_LEN-2] == 'i') + dev->unit = PSI; + + return dev->unit; +} + +PRESSURE_T rsc_get_pressure_type(rsc_context dev) { + uint8_t type; + + rsc_set_access_type(dev, EEPROM); + + rsc_eeprom_read(dev, RSC_PRESSURE_REFERENCE, &type, RSC_SENSOR_TYPE_LEN, RSC_EEPROM_STANDARD_ARGUMENT_LENGTH); + + switch (type) { + case 'D': + dev->type = DIFFERENTIAL; + break; + case 'A': + dev->type = ABSOLUTE; + break; + case 'G': + dev->type = GAUGE; + break; + default: + dev->type = DIFFERENTIAL; + } + + return dev->type; +} + +upm_result_t rsc_get_initial_adc_values(rsc_context dev, uint8_t* adc_init_values) { + rsc_set_access_type(dev, EEPROM); + + rsc_eeprom_read(dev, RSC_ADC_CONDIG_00, &adc_init_values[0], 1, RSC_EEPROM_STANDARD_ARGUMENT_LENGTH); + upm_delay_ms(2); + rsc_eeprom_read(dev, RSC_ADC_CONDIG_01, &adc_init_values[1], 1, RSC_EEPROM_STANDARD_ARGUMENT_LENGTH); + upm_delay_ms(2); + rsc_eeprom_read(dev, RSC_ADC_CONDIG_02, &adc_init_values[2], 1, RSC_EEPROM_STANDARD_ARGUMENT_LENGTH); + upm_delay_ms(2); + rsc_eeprom_read(dev, RSC_ADC_CONDIG_03, &adc_init_values[3], 1, RSC_EEPROM_STANDARD_ARGUMENT_LENGTH); + + return UPM_SUCCESS; +} + +upm_result_t rsc_retrieve_coefficients(rsc_context dev) { + int base_address = RSC_OFFSET_COEFFICIENT_0_LSB; + uint8_t l_coeffs[RSC_COEFF_ADDRESS_SPACE_SIZE]={0}; + int i,j = 0; + uint32_t temp; + + rsc_set_access_type(dev, EEPROM); + + for (i=0; icoeff_matrix[i][j] = *(float*)&temp; + } + } + + return UPM_SUCCESS; +} + +upm_result_t rsc_adc_write(rsc_context dev, uint8_t reg, uint8_t num_bytes, uint8_t* write_data) { + // The number of bytes to write has to be - 1,2,3,4 + if(num_bytes <= 0 || num_bytes >4) + return UPM_ERROR_UNSPECIFIED; + + // the ADC registers are 0,1,2,3 + if(reg < 0 || reg >3) + return UPM_ERROR_UNSPECIFIED; + + uint8_t tx[num_bytes+1]; + tx[0] = RSC_ADC_WREG|((reg<<2)&RSC_ADC_REG_MASK)|((num_bytes-1)&RSC_ADC_NUM_BYTES_MASK); + int cnt = 0; + for(cnt=0; cntcs_adc, 0); + if(mraa_spi_transfer_buf(dev->spi, tx, NULL, num_bytes+1) != MRAA_SUCCESS) { + printf("RSC: ISsues in SPI transfer\n"); + return UPM_ERROR_OPERATION_FAILED; + } + mraa_gpio_write(dev->cs_adc, 1); + return UPM_SUCCESS; +} + +upm_result_t rsc_set_data_rate(rsc_context dev, RSC_DATA_RATE dr) { + dev->data_rate = dr; + switch (dr) { + case N_DR_20_SPS: + case N_DR_45_SPS: + case N_DR_90_SPS: + case N_DR_175_SPS: + case N_DR_330_SPS: + case N_DR_600_SPS: + case N_DR_1000_SPS: + rsc_set_mode(dev, NORMAL_MODE); + break; + case F_DR_40_SPS: + case F_DR_90_SPS: + case F_DR_180_SPS: + case F_DR_350_SPS: + case F_DR_660_SPS: + case F_DR_1200_SPS: + case F_DR_2000_SPS: + rsc_set_mode(dev, FAST_MODE); + break; + default: + rsc_set_mode(dev, NA_MODE); + } + return UPM_SUCCESS; +} + +upm_result_t rsc_set_mode(rsc_context dev, RSC_MODE mode) { + RSC_MODE l_mode; + + switch(mode) { + case NORMAL_MODE: + if(dev->data_rate < N_DR_20_SPS || dev->data_rate > N_DR_1000_SPS) { + printf("RSC: Normal mode not supported with the current selection of data rate\n"); + printf("RSC: You will see erronous readings\n"); + l_mode = NA_MODE; + } else + l_mode = NORMAL_MODE; + break; + case FAST_MODE: + if(dev->data_rate < F_DR_40_SPS || dev->data_rate > F_DR_2000_SPS) { + printf("RSC: Fast mode not supported with the current selection of data rate\n"); + printf("RSC: You will see erronous readings\n"); + l_mode = NA_MODE; + } else + l_mode = FAST_MODE; + break; + default: + l_mode = NA_MODE; + } + dev->mode = l_mode; + + return UPM_SUCCESS; +} + +upm_result_t rsc_adc_read(rsc_context dev, READING_T type, uint8_t* data) { + uint8_t tx[2]={0}; + tx[0] = RSC_ADC_WREG|((1<<2)&RSC_ADC_REG_MASK); + + tx[1] = (((dev->data_rate << RSC_DATA_RATE_SHIFT)&RSC_DATA_RATE_MASK) | + ((dev->mode << RSC_OPERATING_MODE_SHIFT)&RSC_OPERATING_MODE_MASK) | + (((type&0x01)<<1)|RSC_SET_BITS_MASK)); + + mraa_gpio_write(dev->cs_adc, 0); + if(mraa_spi_transfer_buf(dev->spi, tx, NULL, 2) != MRAA_SUCCESS) { + printf("RSC: ISsues in SPI transfer\n"); + return UPM_ERROR_OPERATION_FAILED; + } + mraa_gpio_write(dev->cs_adc, 1); + + // delay would depend on data rate + rsc_add_dr_delay(dev); + uint8_t tx_1[4]={0x10, 0, 0, 0}; + mraa_gpio_write(dev->cs_adc, 0); + if(mraa_spi_transfer_buf(dev->spi, tx_1, data, 4) != MRAA_SUCCESS) { + printf("RSC: ISsues in SPI transfer\n"); + return UPM_ERROR_OPERATION_FAILED; + } + mraa_gpio_write(dev->cs_adc, 1); + + return UPM_SUCCESS; +} + +float rsc_get_temperature(rsc_context dev) { + uint8_t sec_arr[4]={0}; + float temp; + + rsc_set_access_type(dev, ADC); + + rsc_adc_read(dev, TEMPERATURE, sec_arr); + dev->t_raw = ((sec_arr[1]<<8) | sec_arr[2]) >> 2; + temp = dev->t_raw*0.03125; + + return temp; +} + +float rsc_get_pressure(rsc_context dev) { + uint8_t sec_arr[4]={0}; + + rsc_set_access_type(dev, ADC); + + rsc_adc_read(dev, PRESSURE, sec_arr); + + uint32_t p_raw = (sec_arr[1]<<16)|(sec_arr[2]<<8)|sec_arr[3]; + + uint32_t t_raw = dev->t_raw; + float x = (dev->coeff_matrix[0][3]*t_raw*t_raw*t_raw); + float y = (dev->coeff_matrix[0][2]*t_raw*t_raw); + float z = (dev->coeff_matrix[0][1]*t_raw); + float p_int1 = p_raw - (x + y + z + dev->coeff_matrix[0][0]); + + x = (dev->coeff_matrix[1][3]*t_raw*t_raw*t_raw); + y = (dev->coeff_matrix[1][2]*t_raw*t_raw); + z = (dev->coeff_matrix[1][1]*t_raw); + float p_int2 = p_int1/(x + y + z + dev->coeff_matrix[1][0]); + + x = (dev->coeff_matrix[2][3]*p_int2*p_int2*p_int2); + y = (dev->coeff_matrix[2][2]*p_int2*p_int2); + z = (dev->coeff_matrix[2][1]*p_int2); + float p_comp_fs = x + y + z + dev->coeff_matrix[2][0]; + + float p_comp = (p_comp_fs*dev->pressure_range) + dev->min_pressure_val; + + return p_comp; +} + +upm_result_t rsc_setup_adc(rsc_context dev, uint8_t* adc_init_values) { + uint8_t tx=RSC_ADC_RESET_COMMAND; + + rsc_set_access_type(dev, ADC); + + mraa_gpio_write(dev->cs_adc, 0); + if(mraa_spi_transfer_buf(dev->spi, &tx, NULL, 1) != MRAA_SUCCESS) { + printf("RSC: ISsues in SPI transfer\n"); + return UPM_ERROR_OPERATION_FAILED; + } + upm_delay_ms(5); + + uint8_t arr[4] = {adc_init_values[0], adc_init_values[1], adc_init_values[2], adc_init_values[3]}; + rsc_adc_write(dev, 0, 4, arr); + + mraa_gpio_write(dev->cs_adc, 1); + upm_delay_ms(5); + + return UPM_SUCCESS; +} + +upm_result_t rsc_add_dr_delay(rsc_context dev) { + float delay = 0; + switch(dev->data_rate){ + case N_DR_20_SPS: + delay = MSEC_PER_SEC/20; + break; + case N_DR_45_SPS: + delay = MSEC_PER_SEC/45; + break; + case N_DR_90_SPS: + delay = MSEC_PER_SEC/90; + break; + case N_DR_175_SPS: + delay = MSEC_PER_SEC/175; + break; + case N_DR_330_SPS: + delay = MSEC_PER_SEC/330; + break; + case N_DR_600_SPS: + delay = MSEC_PER_SEC/600; + break; + case N_DR_1000_SPS: + delay = MSEC_PER_SEC/1000; + break; + case F_DR_40_SPS: + delay = MSEC_PER_SEC/40; + break; + case F_DR_90_SPS: + delay = MSEC_PER_SEC/90; + break; + case F_DR_180_SPS: + delay = MSEC_PER_SEC/180; + break; + case F_DR_350_SPS: + delay = MSEC_PER_SEC/350; + break; + case F_DR_660_SPS: + delay = MSEC_PER_SEC/660; + break; + case F_DR_1200_SPS: + delay = MSEC_PER_SEC/1200; + break; + case F_DR_2000_SPS: + delay = MSEC_PER_SEC/2000; + break; + default: + delay = 50; + } + upm_delay_ms((int)delay + 2); + + return UPM_SUCCESS; +} diff --git a/src/rsc/rsc.cxx b/src/rsc/rsc.cxx new file mode 100644 index 00000000..f36902cb --- /dev/null +++ b/src/rsc/rsc.cxx @@ -0,0 +1,191 @@ +/* + * Author: Abhishek Malik + * Copyright (c) 2017 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 "rsc.hpp" + +using namespace upm; +using namespace std; + +RSC::RSC(uint8_t bus, uint8_t cs_ee_pin, uint8_t cs_adc_pin) : + m_rsc(rsc_init(bus, cs_ee_pin, cs_adc_pin)) +{ + if(!m_rsc) + throw std::runtime_error(std::string(__FUNCTION__) + + ": rsc_init failed"); +} + +RSC::~RSC() +{ + rsc_close(m_rsc); +} + +string RSC::getSensorName() +{ + uint8_t sensorName[RSC_SENSOR_NAME_LEN]={0}; + if(rsc_get_sensor_name(m_rsc, sensorName) != UPM_SUCCESS) { + throw std::runtime_error(std::string(__FUNCTION__) + + ": Unable to read the sensor name"); + } + std::string str((const char*)sensorName); + + return str; +} + +string RSC::getSensorSerialNumber() +{ + uint8_t serialNumber[RSC_SENSOR_NUMBER_LEN]={0}; + if(rsc_get_sensor_serial_number(m_rsc, serialNumber) != UPM_SUCCESS) { + throw std::runtime_error(std::string(__FUNCTION__) + + ": Unable to read the sensor serial number"); + } + std::string str((const char*)serialNumber); + + return str; +} + +float RSC::getPressureRange() +{ + return rsc_get_pressure_range(m_rsc); +} + +float RSC::getMinimumPressure() +{ + return rsc_get_minimum_pressure(m_rsc); +} + +string RSC::getPressureUnit() +{ + string s_unit; + PRESSURE_U unit = rsc_get_pressure_unit(m_rsc); + switch(unit){ + case PASCAL: + s_unit = "Pascal"; + break; + case KPASCAL: + s_unit = "Kilo Pascal"; + break; + case MPASCAL: + s_unit = "Mega Pascal"; + break; + case PSI: + s_unit = "PSI"; + break; + case INH2O: + s_unit = "inH2O"; + break; + case BAR: + s_unit = "Bar"; + break; + case mBAR: + s_unit = "milli Bar"; + break; + default: + throw std::runtime_error(std::string(__FUNCTION__) + + ": Unable to read the pressure unit from sensor"); + } + + return s_unit; +} + +string RSC::getPressureType() +{ + string s_type; + PRESSURE_T type = rsc_get_pressure_type(m_rsc); + switch(type){ + case DIFFERENTIAL: + s_type = "Differential"; + break; + case ABSOLUTE: + s_type = "Absolute"; + break; + case GAUGE: + s_type = "Gauge"; + break; + default: + throw std::runtime_error(std::string(__FUNCTION__) + + ": Unable to read the pressure type from sensor"); + } + + return s_type; +} + +uint8_t *RSC::getInitialADCState() +{ + uint8_t initialState[4]={0,0,0,0}; + if(rsc_get_initial_adc_values(m_rsc, initialState) != UPM_SUCCESS) { + throw std::runtime_error(std::string(__FUNCTION__) + + ": Unable to read the ADC state from the eeprom"); + } + int cnt = 0; + for (cnt = 0; cnt<4; cnt++) + m_adc_coeff[cnt]=initialState[cnt]; + + return m_adc_coeff; +} + +void RSC::updateCoefficients() +{ + if(rsc_retrieve_coefficients(m_rsc) != UPM_SUCCESS) { + throw std::runtime_error(std::string(__FUNCTION__) + + ": Unable to retrieve ADC Coefficients from the eeprom"); + } +} + +void RSC::setupADC(uint8_t* adc_init_values) +{ + if(rsc_setup_adc(m_rsc, adc_init_values) != UPM_SUCCESS) { + throw std::runtime_error(std::string(__FUNCTION__) + + ": Unable to setup the ADC"); + } +} + +float RSC::getTemperature() +{ + return rsc_get_temperature(m_rsc); +} + +float RSC::getPressure() +{ + return rsc_get_pressure(m_rsc); +} + +void RSC::setMode(RSC_MODE mode) +{ + if(rsc_set_mode(m_rsc, mode) != UPM_SUCCESS){ + throw std::runtime_error(std::string(__FUNCTION__) + + ": Unable to set the ADC mode"); + } +} + +void RSC::setDataRate(RSC_DATA_RATE dr) +{ + if(rsc_set_data_rate(m_rsc, dr) != UPM_SUCCESS) { + throw std::runtime_error(std::string(__FUNCTION__) + + ": Unable to set the ADC data rate"); + } +} diff --git a/src/rsc/rsc.h b/src/rsc/rsc.h new file mode 100644 index 00000000..4f8c0a32 --- /dev/null +++ b/src/rsc/rsc.h @@ -0,0 +1,219 @@ +/* + * Author: Abhishek Malik + * Copyright (c) 2017 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 "upm.h" +#include "mraa/spi.h" +#include "mraa/gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "rsc_regs.h" +/** + * @file rsc.h + * @library rsc + * @brief C API for the rsc driver + * + * @include rsc.c + */ + +/** + * Device context + */ +typedef struct _rsc_context { + mraa_spi_context spi; + mraa_gpio_context cs_ee; + mraa_gpio_context cs_adc; + uint8_t spi_bus_number; + float coeff_matrix[RSC_COEFF_T_ROW_NO][RSC_COEFF_T_COL_NO]; + PRESSURE_U unit; + PRESSURE_T type; + float pressure_range; + float min_pressure_val; + RSC_DATA_RATE data_rate; + RSC_MODE mode; + uint16_t t_raw; +} *rsc_context; + +/** + * RSC initialization. + * + * This device supports SPI. The sensor has two chip select + * pins since there are two ways to access content on the + * sensor - EEPROM/ADC. We will not be using the SPI CS here + * because that would work for all SPI operations. Hence, you are + * expected to initialize any 2 gpio pins for CS by providing the + * pin numbers. + * + * @param bus SPI bus to use. + * @param cs_ee_pin The CS pin for accessing the EEPROM + * @param cs_adc_pin The CS pin for accessing the ADC + * @return The device context, or NULL if an error occurred. + */ +rsc_context rsc_init(uint8_t bus, uint8_t cs_ee_pin, uint8_t cs_adc_pin); + +/** + * RSC Close function + * + * @param dev The device context + */ +upm_result_t rsc_close(rsc_context dev); + +/** + * This function fills up a character array provided to it with + * the sensor name that it reads from the EEPROM. + * NOTE: The length of the array will always have to be RSC_SENSOR_NAME_LEN + * + * @param dev The device context + * @param sensor_name Pointer to a uint8_t array with length + * RSC_SENSOR_NAME_LEN. This array will be filled up with the sensor name + * read from the EEPROM. + * @return UPM result. + */ +upm_result_t rsc_get_sensor_name(rsc_context dev, uint8_t* sensor_name); + +/** + * This function fills up a character array provided to it with + * the sensor serial number that it reads from the EEPROM. + * NOTE: The length of the array will always have to be RSC_SENSOR_NUMBER_LEN + * + * @param dev The device context + * @param sensor_name Pointer to a uint8_t array with length + * RSC_SENSOR_NUMBER_LEN. This array will be filled up with the serial number + * @return UPM result. + */ +upm_result_t rsc_get_sensor_serial_number(rsc_context dev, uint8_t* rsc_number); + +/** + * This function reads the EEPROM to retrieve the pressure range for the + * particular RSC device. + * + * @param dev The device context + * @return Sensor pressure range in float + */ +float rsc_get_pressure_range(rsc_context dev); + +/** + * This function reads the EEPROM to retrieve the minimum pressure that + * the sensor can read. + * + * @param dev The device context + * @return Minimum pressure sensor can read in float + */ +float rsc_get_minimum_pressure(rsc_context dev); + +/** + * This function reads the EEPROM to retrieve the pressure units that + * the pressure is read in + * + * @param dev The device context + * @return enum PRESSURE_U + */ +PRESSURE_U rsc_get_pressure_unit(rsc_context dev); + +/** + * This function reads the EEPROM to retrieve the sensor pressure type + * + * @param dev The device context + * @return enum PRESSURE_T + */ +PRESSURE_T rsc_get_pressure_type(rsc_context dev); + +/** + * This function reads the EEPROM to extract the values with which the + * ADC has to be initialized. + * NOTE: The length of the array will always be 4 + * + * @param dev The device context + * @param adc_init_values uint8_t pointer to an array containing the + * initial values for the ADC + * @return UPM result. + */ +upm_result_t rsc_get_initial_adc_values(rsc_context dev, uint8_t* adc_init_values); + +/** + * This function is used to retrieve the coefficients from the EEPROM. + * Once retrieved, the function updates a 2 dimensional array in the + * sensor context with the latest values. This function doesn't return + * the coefficient values. + * + * @param dev The device context + * @return UPM result. + */ +upm_result_t rsc_retrieve_coefficients(rsc_context dev); + +/** + * This function sets up the initial values in the ADC and also + * sets is to a default data rate - normal with 20 samples per second + * + * @param dev The device context + * @return UPM result. + */ +upm_result_t rsc_setup_adc(rsc_context dev, uint8_t* adc_init_values); + +/** + * Function to get the compensated temperature as read by the sensor. + * + * @param dev The device context + * @return float temperature in degree Celsius + */ +float rsc_get_temperature(rsc_context dev); + +/** + * Function to get the compensated pressure as read by the sensor. + * + * @param dev The device context + * @return float pressure (units inH2O) + */ +float rsc_get_pressure(rsc_context dev); + +/** + * Function to set the mode of the sensor. + * + * @param dev The device context + * @param mode mode of the sensor + * @return UPM result. + */ +upm_result_t rsc_set_mode(rsc_context dev, RSC_MODE mode); + +/** + * Function to set the data rate of the sensor. + * + * @param dev The device context + * @param dr data rate of the sensor + * @return UPM result. + */ +upm_result_t rsc_set_data_rate(rsc_context dev, RSC_DATA_RATE dr); + +#ifdef __cplusplus +} +#endif diff --git a/src/rsc/rsc.hpp b/src/rsc/rsc.hpp new file mode 100644 index 00000000..ff731c8f --- /dev/null +++ b/src/rsc/rsc.hpp @@ -0,0 +1,247 @@ +/* + * Author: Abhishek Malik + * Copyright (c) 2017 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 "rsc.h" + +namespace upm { + /** + * @brief Honeywell RSC TruStability Pressure and Temperature Sensors + * @defgroup rsc libupm-rsc + * @ingroup honeywell spi pressure temperature + */ + + /** + * @library rsc + * @sensor rsc + * @comname Honeywell TruStability Boardmount Pressure Sensors + * @altname TruStability Pressure and Temperature Sensors + * @type pressure temperature + * @man honeywell + * @con spi + * @web https://sensing.honeywell.com/honeywell-sensing-trustability-rsc-series-data-sheet-32321348-b-en.pdf + * + * @brief Description for the RSC TruStability line + * + * The RSC Series is a piezoresistive silicon pressure sensor + * offering a digital output for reading pressure over the specified + * full scale pressure span and temperature range. It is calibrated + * and temperature compensated for sensor offset, sensitivity, + * temperature effects, and non-linearity using a 24-bit analog-todigital + * converter with integrated EEPROM. Pressure data may + * be acquired at rates between 20 and 2000 samples per second + * over an SPI interface. It is intended for use with non-corrosive, + * non-ionic gases, such as air and other dry gases, designed and + * manufactured according to ISO 9001 standards, and is REACH + * and RoHS compliant. + * + * Most of the functionality available on this chip has been implemented. + * The driver calculates the compensated pressure and temperature values + * based on the information provided in the datasheet. The user must not mess + * around with the coefficient and adc init value readings from the EEPROM as + * these are used to calculate the compensated pressure and temperature values. + * + * In order to get the sensor to work properly on an Edison, you would need to + * turn off the Edison SPI power management, this can be done with the command: + * echo on > /sys/devices/pci0000\:00/0000\:00\:07.1/power/control + * + * You might have to use external pull up resistors on all the lines. + * More info about this has been provided in the datasheet with a table and + * a diagram. + * + */ + class RSC { + + public: + /** + * @brief Default constructor for rsc + * + * This device supports SPI. The sensor has two chip select + * pins since there are two ways to access content on the + * sensor - EEPROM/ADC. We will not be using the SPI CS here + * because that would work for all SPI operations. Hence, you are + * expected to initialize any 2 gpio pins for CS by providing the + * pin numbers. + * + * @param bus SPI bus to use. + * @param cs_ee_pin The CS pin for accessing the EEPROM + * @param cs_adc_pin The CS pin for accessing the ADC + */ + RSC(uint8_t bus, uint8_t cs_ee_pin, uint8_t cs_adc_pin); + + /** + * rsc destructor + */ + ~RSC(); + + /** + * This function provides the sensor name as a string to + * the user. + * + * @return std::string sensor name + */ + std::string getSensorName(); + + /** + * This function provides the sensor serial number as a + * string to the user. + * + * @return std::string sensor serial number + */ + std::string getSensorSerialNumber(); + + /** + * This function provides the pressure range which the + * sensor can read out. This will vary for the different + * kinds of RSC sensors. This value is read from the EEPROM + * + * @return float Total sensor pressure range + */ + float getPressureRange(); + + /** + * This function provides the minimum pressure which the + * sensor can read out. This will vary for the different + * kinds of RSC sensors. This value is read from the EEPROM + * + * @return float Sensor minimum pressure + */ + float getMinimumPressure(); + + /** + * This function gets the units that the particular RSC + * sensor being used reads out the pressure data in. + * Following are the possible units data can be read out + * in: + * 1. Pascal + * 2. Kilo Pascal + * 3. Mega Pascal + * 4. PSI + * 5. inH2O + * 6. Bar + * 7. milli Bar + * + * This info can be retrieved from the EEPROM + * + * @return std::string pressure units + */ + std::string getPressureUnit(); + + /** + * Function returns the type of RSC pressure sensor being + * used. This info is available in the EEPROM. + * Types: + * 1. Differential + * 2. Absolute + * 3. Gauge + * + * @return std::string sensor type + */ + std::string getPressureType(); + + /** + * Function returns the initial state that the ADC + * registers need to be set to. This info is retrieved + * from the EEPROM. + * + * @return std::string sensor type + */ + uint8_t *getInitialADCState(); + + /** + * Function used to update the coefficients. This function + * doesn't return the coefficent values. Intstead, it updates + * the 2-D array with the coefficient values read from the + * EEPROM. This function is mostly for internal use only. + */ + void updateCoefficients(); + + /** + * Function used to set up the ADC with the initial values + * of the ADC registers read from the EEPROM. + * + * @param adc_init_values pointer to uint8_t array containing + * the initial ADC values + */ + void setupADC(uint8_t* adc_init_values); + + /** + * Function to get the compensated temperature value. + * + * @return float compensated temperature value + */ + float getTemperature(); + + /** + * Function to get the compensated pressure value + * + * @return float compensated pressure value + */ + float getPressure(); + + /** + * Function to set the mode for the RSC sensor: + * There are 2 types of modes available: + * + * 1. Normal Mode - 256 KHz + * 2. Fast Mode - 512 KHz + * + * @return mode enum of type RSC_MODE + */ + void setMode(RSC_MODE mode); + + /** + * Function to set the data rate for the RSC sensor: + * Following are the different data rates available: + * + * In Normal Mode + * 1. 20 SPS + * 2. 45 SPS + * 3. 90 SPS + * 4. 175 SPS + * 5. 330 SPS + * 6. 600 SPS + * 7. 1000 SPS + * + * In Fast Mode + * 1. 40 SPS + * 2. 90 SPS + * 3. 180 SPS + * 4. 350 SPS + * 5. 660 SPS + * 6. 1200 SPS + * 7. 2000 SPS + * + * SPS - Samples per Second + * + * @return dr enum of type RSC_DATA_RATE + */ + void setDataRate(RSC_DATA_RATE dr); + + private: + rsc_context m_rsc; + uint8_t m_adc_coeff[4]; + }; +} diff --git a/src/rsc/rsc_regs.h b/src/rsc/rsc_regs.h new file mode 100644 index 00000000..e50914e7 --- /dev/null +++ b/src/rsc/rsc_regs.h @@ -0,0 +1,249 @@ +/* + * Author: Abhishek Malik + * Copyright (c) 2017 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 + +/* + * The following section lists the EEPROM Addresses + */ +/* + * RSC EEPROM Catalog listing + * This part in the EEPROM stores the ascii representation of the sensor chip + * number + */ +#define RSC_CATALOG_LISTING_MSB 0 +#define RSC_CATALOG_LISTING_LSB 15 + +/* + * RSC EEPROM Serial Number addresses + */ +#define RSC_SERIAL_NO_YYYY_MSB 16 +#define RSC_SERIAL_NO_YYYY_LSB 19 +#define RSC_SERIAL_NO_DDD_MSB 20 +#define RSC_SERIAL_NO_DDD_LSB 22 +#define RSC_SERIAL_NO_XXXX_MSB 23 +#define RSC_SERIAL_NO_XXXX_LSB 26 + +/* + * This area in the EEPROM contains the sensor's pressure range in float + */ +#define RSC_PRESSURE_RANGE_LSB 27 +#define RSC_PRESSURE_RANGE_MSB 30 + +/* + * This part in the EEPROM contains the lower pressure limit readable + * Value is stored float + */ +#define RSC_PRESSURE_MINIMUM_LSB 31 +#define RSC_PRESSURE_MINIMUM_MSB 34 + +/* + * Unit of measurement of pressure for this particular sensor + * Ex: Pascal, Bar, PSI, inH2O + */ +#define RSC_PRESSURE_UNIT_MSB 35 +#define RSC_PRESSURE_UNIT_LSB 39 + +/* + * Ex: Differential, Gauge, absolute + */ +#define RSC_PRESSURE_REFERENCE 40 + +/* + * ADC Configuration math + */ +#define RSC_ADC_CONDIG_00 61 +#define RSC_ADC_CONDIG_01 63 +#define RSC_ADC_CONDIG_02 65 +#define RSC_ADC_CONDIG_03 67 + +/* + * Offset Coefficient matrix + */ +#define RSC_OFFSET_COEFFICIENT_0_LSB 130 +#define RSC_OFFSET_COEFFICIENT_0_MSB 133 + +#define RSC_OFFSET_COEFFICIENT_1_LSB 134 +#define RSC_OFFSET_COEFFICIENT_1_MSB 137 + +#define RSC_OFFSET_COEFFICIENT_2_LSB 138 +#define RSC_OFFSET_COEFFICIENT_2_MSB 141 + +#define RSC_OFFSET_COEFFICIENT_3_LSB 142 +#define RSC_OFFSET_COEFFICIENT_3_MSB 145 + +/* + * Span Coefficient Matrix + */ +#define RSC_SPAN_COEFFICIENT_0_LSB 210 +#define RSC_SPAN_COEFFICIENT_0_MSB 213 + +#define RSC_SPAN_COEFFICIENT_1_LSB 214 +#define RSC_SPAN_COEFFICIENT_1_MSB 217 + +#define RSC_SPAN_COEFFICIENT_2_LSB 218 +#define RSC_SPAN_COEFFICIENT_2_MSB 221 + +#define RSC_SPAN_COEFFICIENT_3_LSB 222 +#define RSC_SPAN_COEFFICIENT_3_MSB 225 + +/* + * Shape Coefficient Matrix + */ +#define RSC_SHAPE_COEFFICIENT_0_LSB 290 +#define RSC_SHAPE_COEFFICIENT_0_MSB 293 + +#define RSC_SHAPE_COEFFICIENT_1_LSB 294 +#define RSC_SHAPE_COEFFICIENT_1_MSB 297 + +#define RSC_SHAPE_COEFFICIENT_2_LSB 298 +#define RSC_SHAPE_COEFFICIENT_2_MSB 301 + +#define RSC_SHAPE_COEFFICIENT_3_LSB 302 +#define RSC_SHAPE_COEFFICIENT_3_MSB 305 + +/* + * Checksum addresses + */ +#define RSC_CHECKSUM_LSB 450 +#define RSC_CHECKSUM_MSB 451 + +/* + * The following section contains a list of variations useful for EEPROM + * calculations and reads. + */ +#define RSC_EEPROM_ADDRESS_SPACE_SIZE 512 +#define RSC_EEPROM_STANDARD_ARGUMENT_LENGTH 2 +#define RSC_READ_EEPROM_INSTRUCTION 0x03 +#define RSC_EEPROM_ADDRESS_LOWER_BYTE_MASK 0xff +#define RSC_EEPROM_ADDRESS_9TH_BIT_MASK 0x100 +#define RSC_SENSOR_NAME_LEN 16 +#define RSC_SENSOR_NUMBER_LEN 12 +#define RSC_PRESSURE_RANGE_LEN 4 +#define RSC_PRESSURE_MINIMUM_LEN 4 +#define RSC_PRESSURE_UNIT_LEN 6 +#define RSC_SENSOR_TYPE_LEN 1 +// total types of coefficients +#define RSC_COEFF_T_ROW_NO 3 +// total no of coefficients in each type +#define RSC_COEFF_T_COL_NO 4 +// this can be calculated by using the LSB address of the 0th coefficient +// and the MSB of the 3rd coefficient +#define RSC_COEFF_ADDRESS_SPACE_SIZE 16 + +/* + * The following section lists ADC Commands/Registers + */ +#define RSC_ADC_RESET_COMMAND 0x06 +#define RSC_DATA_RATE_SHIFT 5 +#define RSC_DATA_RATE_MASK 0xe0 +#define RSC_ADC_REG_MASK 0x0C +#define RSC_ADC_NUM_BYTES_MASK 0x03 +#define RSC_OPERATING_MODE_MASK 0x18 +#define RSC_OPERATING_MODE_SHIFT 3 +#define RSC_SET_BITS_MASK 0x04 +#define RSC_ADC_WREG 0x40 +#define MSEC_PER_SEC 1000 +#define RSC_CREATE_WREG_COMMAND(x,y,z) (x|((y<<2)&RSC_ADC_REG_MASK)|(z&RSC_ADC_NUM_BYTES_MASK)) + +/* + * Read/Write Enum + */ +typedef enum { + READ = 0, + WRITE } RSC_ADC_TX; + +/* + * Enum for the datarates supported by the sensor + * N/F - Normal/Fast - 256 KHz/512 KHz + * DR - Data Rate + * SPS - Samples per second + */ +typedef enum { + N_DR_20_SPS = 0, + N_DR_45_SPS, + N_DR_90_SPS, + N_DR_175_SPS, + N_DR_330_SPS, + N_DR_600_SPS, + N_DR_1000_SPS, + N_DR_NA, + F_DR_40_SPS, + F_DR_90_SPS, + F_DR_180_SPS, + F_DR_350_SPS, + F_DR_660_SPS, + F_DR_1200_SPS, + F_DR_2000_SPS, + F_DR_NA } RSC_DATA_RATE; + +/* + * Enum for modes supported by the RSC sensor + */ +typedef enum { + NORMAL_MODE = 0, + NA_MODE, + FAST_MODE } RSC_MODE; + +/* + * Enum for the different pressure units supported by the rsc class of sensors + */ +typedef enum { + PASCAL = 0, + KPASCAL, + MPASCAL, + PSI, + INH2O, + BAR, + mBAR } PRESSURE_U; + +/* + * Enum for types of pressure that the rsc sensor class can calculate + */ +typedef enum { + DIFFERENTIAL = 0, + ABSOLUTE, + GAUGE } PRESSURE_T; + +/* + * Enum for types of coefficients available from the rsc sensors + */ +typedef enum { + OFFSET = 0, + SPAN, + SHAPE } COEFFICIENT_T; + +/* + * Enum for pressure/temperature reading + */ +typedef enum { + PRESSURE = 0, + TEMPERATURE } READING_T; + +/* + * Enum to access EEPROM/ADC + */ +typedef enum { + EEPROM = 0, + ADC } ACCESS_T; \ No newline at end of file