Library for the use of the atmospheric pressure sensor SCP1000

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