Library for the use of the atmospheric pressure sensor SCP1000
Diff: SCP1000.cpp
- Revision:
- 0:a224293d7af4
- Child:
- 1:1b2027cbe629
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SCP1000.cpp Tue Sep 16 13:07:04 2014 +0000 @@ -0,0 +1,200 @@ +/* Copyright (c) 2014 Shigenori Inoue, MIT License + * + * 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 "SCP1000.h" + +/* Constructor */ +SCP1000::SCP1000(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName trig, PinName drdy) : + _s(mosi, miso, sclk), _cs(cs), _trig(trig), _drdy(drdy) +{ + init(); +} + +/* Destructor */ +SCP1000::~SCP1000() {} + +/* Write an 8-bit data to an address in the SCP1000 via SPI */ +void SCP1000::write(int addr, int data) +{ + uint8_t f_addr; + uint8_t f_data; + + /* Creating the address frame, adding the WRITE bit */ + f_addr = ( static_cast<uint8_t>(addr << 2) | 0x02); + + /* Creating the data frame */ + f_data = static_cast<uint8_t>(data); + + _cs = 0; + _s.write(f_addr); + _s.write(f_data); + _cs = 1; +} + +/* Read an 8-bit data from an address in the SCP1000 via SPI */ +int SCP1000::read8(int addr) +{ + uint8_t f_addr; + uint8_t f_data; + + /* Creating the address frame, adding the WRITE bit */ + f_addr = static_cast<uint8_t>(addr << 2); + + _cs = 0; + _s.write(f_addr); + f_data = _s.write(0x00); + _cs = 1; + + return static_cast<int>(f_data); +} + +/* Read a 16-bit data from an address in the SCP1000 via SPI */ +int SCP1000::read16(int addr) +{ + uint8_t f_addr; + uint8_t f_data_h; + uint8_t f_data_l; + + /* Creating the address frame, adding the WRITE bit */ + f_addr = static_cast<uint8_t>(addr << 2); + + _cs = 0; + _s.write(f_addr); + f_data_h = _s.write(0x00); + f_data_l = _s.write(0x00); + _cs = 1; + + return (static_cast<int>(f_data_h) << 8) + static_cast<int>(f_data_l); +} + +/* Initialize the SCP1000 */ +int SCP1000::init(void) +{ + int d_read; + int cnt = 0; + _cs = 1; + _trig = 0; + + /* SPI setting */ + _s.format(8, 0); + _s.frequency(1000000); + + /* Software reset of SCP1000 */ + write(RSTR, 0x01); + + /* Waiting for 60 ms as in the datasheet */ + wait_ms(60); + + /* Reading STATUS registor until its LSB = 0 */ + do { + d_read = read8(STATUS); + if ((d_read & 0x01) == 0) { + break; + } else { + cnt++; + wait_ms(10); + } + + if (cnt > 100) { + return ERR; + } + } while (true); + + /* Reading DATARD8 registor to check its LSB = 1 */ + d_read = read8(DATARD8); + if ((d_read & 0x01) == 0) { + return ERR; + } else { + return OK; + } +} + +/* Set the measurement mode of the SCP1000 */ +void SCP1000::setMode(int mode) +{ + write(OPERATIONS, 0x00); + wait_ms(50); + switch(mode) { + case HIGH_RESOLUTION: + write(OPERATIONS, 0x0A); + break; + case HIGH_SPEED: + write(OPERATIONS, 0x09); + break; + case ULTRA_LOW_POWER: + write(OPERATIONS, 0x0B); + break; + case LOW_POWER_17BIT: + write(ADDPTR, 0x00); + write(DATAWR, 0x05); + write(OPERATIONS, 0x02); + write(OPERATIONS, 0x0C); + break; + case LOW_POWER_15BIT: + write(ADDPTR, 0x00); + write(DATAWR, 0x0D); + write(OPERATIONS, 0x02); + write(OPERATIONS, 0x0C); + break; + default: /* High resolution mode by default */ + write(OPERATIONS, 0x0A); + break; + } +} + +/* Trigger the measurement by TRIG wire in Low Power Mode */ +void SCP1000::triggerHard(void) +{ + _trig = 1; + wait_us(1); + _trig = 0; +} + +/* Trigger the measurement by register writing in Low Power Mode */ +void SCP1000::triggerSoft(void) +{ + write(OPERATIONS, 0x0C); +} + +/* Check the data readiness */ +bool SCP1000::IsReady(void) +{ + if (_drdy == 1) { + return true; + } else { + return false; + } +} + +/* Read temperature measurement result in degrees Celcius */ +float SCP1000::readTemperature(void) +{ + int temp_raw; + temp_raw = read16(TEMPOUT); + return static_cast<float>(temp_raw) * 0.05; +} + +/* Read atmospheric pressure measurement result in hectopascal */ +float SCP1000::readPressure(void) +{ + int press_raw_h; + int press_raw_l; + press_raw_h = read8(DATARD8); + press_raw_l = read16(DATARD16); + return static_cast<float>((press_raw_h << 16) + press_raw_l) * 0.0025; +} \ No newline at end of file