simple CCS811 driver

Dependencies:   AMS_ENS210_temp_humid_sensor

Dependents:   TBSense2_Sensor_Demo

Fork of AMS_CCS811_gas_sensor by Marcus Lee

Revision:
5:41e97348e9e7
Parent:
4:a6b8881eae87
Child:
6:22c0a7f2ece2
--- a/AMS_CCS811.h	Thu Jan 19 14:27:44 2017 +0000
+++ b/AMS_CCS811.h	Fri Jan 20 14:34:41 2017 +0000
@@ -10,26 +10,64 @@
 
 #include "mbed.h"
 
+#include "serialBuffer.h"
+using utils::SerialBuffer;
+extern SerialBuffer USBserialComms;
+
 /* Library defaults */
-#define CONFIG_OP_MODE      TEN_SECOND              // Every 10 seconds
-#define CONFIG_INTR         0                       // Interupt off
-#define CONFIG_ADDR_DIR     0                       // ADDR n_wake_pin pulled low
-#define CONFIG_ENS210_POLL  3000                    // ENS210 is polled every 3 seconds
+#define CONFIG_OP_MODE              TEN_SECOND              // Every 10 seconds
+#define CONFIG_INTR                 0                       // Interupt off
+#define CONFIG_ADDR_DIR             0                       // ADDR n_wake_pin pulled low
+#define CONFIG_ENS210_POLL          3000                    // ENS210 is polled every 3 seconds
 
 /* Library Constants */
-#define SLAVE_ADDR_RAW_H    0x5B
-#define SLAVE_ADDR_RAW_L    0x5A
-#define SLAVE_ADDR_RAW      slave_addr
-#define SLAVE_ADDR          SLAVE_ADDR_RAW << 1     // 0x86
-#define SLAVE_ADDR_W        SLAVE_ADDR
-#define SLAVE_ADDR_R        SLAVE_ADDR | 1          // 0x87
+#define CCS811_SLAVE_ADDR_RAW_H     0x5B
+#define CCS811_SLAVE_ADDR_RAW_L     0x5A
+#define CCS811_SLAVE_ADDR_RAW       _slave_addr
+#define CCS811_SLAVE_ADDR           CCS811_SLAVE_ADDR_RAW << 1     
+#define CCS811_SLAVE_ADDR_W         CCS811_SLAVE_ADDR
+#define CCS811_SLAVE_ADDR_R         CCS811_SLAVE_ADDR | 1          
+
+#define MEAS_MODE                   0x01
+#define STATUS                      0x00
+
+#define ALG_RESULT_DATA             0x02
+#define ENV_DATA                    0x05
+#define ERROR_ID                    0xE0
+
+#define APP_START                   0xF4
+
+#define CCS811_T_AWAKE              55                      // us - time taken for sensor I2C to become active
+#define CCS811_T_DWAKE              25                      // us - time taken for sensor I2C to become inactive
 
-#define SYS_MODE            0x01
-#define SYS_STATUS          0x00
+/* Error Codes */
+#define CCS811_NO_ERROR             "No Error";
+/* Sensor Errors */
+#define CCS811_ERR_NUM              8
+#define CCS811_WRITE_REG_INVALID    "The CCS811 received an I2C write request addressed to this station but with invalid register address ID"
+#define CCS811_READ_REG_INVALID     "The CCS811 received an I2C read request to a mailbox ID that is invalid"
+#define CCS811_MEASMODE_INVALID     "The CCS811 received an I2C request to write an unsupported mode to MEAS_MODE"
+#define CCS811_MAX_RESISTANCE       "The sensor resistance measurement has reached or exceeded the maximum range"
+#define CCS811_HEATER_FAULT         "The Heater current in the CCS811 is not in range"
+#define CCS811_HEATER_SUPPLY        "The Heater voltage is not being applied correctly"
+#define CCS811_RESERVED             "Reserved for Future Use"
+/* Library Errors */
+#define CCS811_LIB_ERR_NUM          6
+#define CCS811_LIB_N_WAKE_ID        0
+#define CCS811_LIB_N_WAKE           "nWAKE pin not set"
+#define CCS811_LIB_I2C_ID           1
+#define CCS811_LIB_I2C              "I2C interface is NULL"
+#define CCS811_LIB_SLAVE_W_ID       2
+#define CCS811_LIB_SLAVE_W          "Invaid slave write address"
+#define CCS811_LIB_REG_ADDR_ID      3
+#define CCS811_LIB_REG_ADDR         "Failed to write register address"
+#define CCS811_LIB_I2CWRITE_ID      4
+#define CCS811_LIB_I2CWRITE         "Failed to write byte"
+#define CCS811_LIB_SLAVE_R_ID       5
+#define CCS811_LIB_SLAVE_R          "Invaid slave read address"
 
-#define ALG_DATA            0x02
-#define ENV_DATA            0x05
-#define ERROR_ID            0xE0
+#define CCS811_TOTAL_ERR_NUM        CCS811_ERR_NUM+CCS811_LIB_ERR_NUM
+
 
 /** The AMS CCS811 class
  */
@@ -45,16 +83,17 @@
             TEN_SECOND,     /**< Measurement every 10 seconds */
             SIXTY_SECOND,   /**< Measurement every 60 seconds */
             CONSTANT,       /**< Measurement every 250ms - Only raw data available */
-            INVALID         /**< Invalid bit configuration */
+            INVALID         /**< Invalid bit configuration/Error Occured */
         };
     
-        /** Data collection status.
+        /** Holds error information.
          *
          */
-        enum DATA_STATUS {
-            DATA_NOT_READY, /**< No new data */
-            DATA_READY,     /**< New data */
-            ERROR,          /**< Error occurred */
+        struct ccs811_errors {
+            int count;                          /**< Number of total errors */
+            int codes[CCS811_TOTAL_ERR_NUM];    /**< Array of active error codes */
+            
+            ccs811_errors() : count(0) {}
         };
     
         /** Create an AMS_CCS811 instance
@@ -126,6 +165,12 @@
          * @return The poll interval in ms
          */
         int ens210_poll_interval();
+        
+        /** Get the current firmware mode
+         *
+         * @return 1 application mode, 0 for boot mode, -1 for error
+         */
+        int firmware_mode();
     
         /** Set the operation mode \n
          * Note: \n When a sensor operating mode is changed to a new mode with\n
@@ -199,9 +244,9 @@
         /** Get the sensor collection state
          *  Use when interupts are disabled
          *
-         * @return Current collection state
+         * @return Current collection state, 1 for new data ready, 0 for data not ready and -1 for error
          */
-        AMS_CCS811::DATA_STATUS has_new_data();
+        int has_new_data();
     
         /** Get the most recent CO2 measurement.
          *  Must call has_new_data() first when when interupts are disabled otherwise the same data will be returned
@@ -223,13 +268,26 @@
          * @return Most recent TVOC measurement in ppb
          */
         uint16_t raw_read();
-    
-        /** Get the last error.
-         *  Must call has_new_data() first when when interupts are disabled otherwise the same error will be returned
+        
+        /** Get current error status
+         *
+         * @return True when error has occured, false when no error has occured 
+         */
+        bool error_status();
+        
+        /** Get the latest errors.
          *
-         * @return Last error.
+         * @return Latest errors.
          */
-        const char * last_error();
+        ccs811_errors errors();
+    
+        /** Get the error string.
+         *
+         * @param err_code  Error code to be translated
+         *
+         * @return Error String.
+         */
+        const char * error_string(int err_code);
     
         /** Attach a function to be called when data is ready.
          *  Calling this method enables interupts
@@ -272,9 +330,9 @@
         /** Get whether the data ready interupt is enabled.
          * 
          *
-         * @return True for enabled, false for disabled
+         * @return 1 for enabled, 0 for disabled, -1 for error
          */
-        bool interupt_enabled();
+        int interupt_enabled();
         
         /** Set the nINT pin
          *
@@ -298,7 +356,7 @@
         I2C* _ens210_i2c;
         
         bool _addr_dir;
-        int slave_addr;
+        int _slave_addr;
         void update_slave_addr();
         
         bool _ens210_enabled;
@@ -309,12 +367,20 @@
         
         OP_MODES _mode;
         
-        bool set_defaults();
+        void set_defaults();
+        
+        bool _errors[CCS811_LIB_ERR_NUM];
+        int _error_count;
+        char _error_strings[CCS811_TOTAL_ERR_NUM][255];
+        void _init_errors();
+        void clear_errors();
+        void new_error(int error_id);
         
         DigitalOut *_n_wake_out;
         DigitalOut *_addr_out;
         
-    
+        char _alg_result_data[8];
+        
         FunctionPointer _isr_data_fp;
         bool _int_data_enabled;
         InterruptIn *_int_data;
@@ -322,12 +388,15 @@
     
         bool write_config();
         
-        struct read_config_result {
+        struct read_byte_result {
             bool success;
             uint8_t byte;
-            read_config_result() : success(false), byte(0) {}
+            read_byte_result() : success(false), byte(0) {}
         };
-        read_config_result read_config();
+        read_byte_result read_config();
+        read_byte_result read_status();
+        
+        bool boot_app_start();
         
         int i2c_read(char reg_addr, char* output, int len);
         int i2c_write(char reg_addr, char* input, int len);