Class which provides functions to control a TAOS TCS3472 Color Light-to-Digital Converter with IR Filter via I2C. (Tidied up)

Dependents:   openwear-lifelogger-example

Fork of TCS3472_I2C by Karl Maxwell

Files at this revision

API Documentation at this revision

Comitter:
karlmaxwell67
Date:
Thu Mar 20 16:56:56 2014 +0000
Parent:
2:38d5187a4e7b
Child:
4:5d1f8d7d81ff
Commit message:
Added more functions to increase the functionality of the class.

Changed in this revision

TCS3472_I2C.cpp Show annotated file Show diff for this revision Revisions of this file
TCS3472_I2C.h Show annotated file Show diff for this revision Revisions of this file
--- a/TCS3472_I2C.cpp	Wed Mar 19 18:48:12 2014 +0000
+++ b/TCS3472_I2C.cpp	Thu Mar 20 16:56:56 2014 +0000
@@ -1,40 +1,41 @@
 #include "TCS3472_I2C.h"
 
-TCS3472_I2C::TCS3472_I2C( PinName sda, PinName scl ) : i2c_( sda, scl ){   
-    i2c_.frequency(400000);
-    enableRGBC();
+TCS3472_I2C::TCS3472_I2C( PinName sda, PinName scl ) : i2c( sda, scl ){   
+    i2c.frequency(400000);
+    enablePowerAndRGBC();
 }
 
 int TCS3472_I2C::writeSingleRegister( char address, char data ){
     char tx[2] = { address | 160, data }; //0d160 = 0b10100000
-    int ack = i2c_.write( SLAVE_ADDRESS << 1 , tx, 2 );
+    int ack = i2c.write( SLAVE_ADDRESS << 1, tx, 2 );
+    return ack;
+}
+
+int TCS3472_I2C::writeMultipleRegisters( char address, char* data, int quantity ){
+    char tx[ quantity + 1 ];
+    tx[0] = address | 160;
+    for ( int i = 1; i <= quantity; i++ ){
+        tx[ i ] = data[ i - 1 ];
+    }
+    int ack = i2c.write( SLAVE_ADDRESS << 1, tx, quantity + 1 );
     return ack;
 }
 
 char TCS3472_I2C::readSingleRegister( char address ){
     char output = 255;
     char command = address | 160; //0d160 = 0b10100000
-    i2c_.write( SLAVE_ADDRESS << 1, &command, 1, true );
-    i2c_.read( SLAVE_ADDRESS << 1, &output, 1 );
+    i2c.write( SLAVE_ADDRESS << 1, &command, 1, true );
+    i2c.read( SLAVE_ADDRESS << 1, &output, 1 );
     return output;
 }
 
 int TCS3472_I2C::readMultipleRegisters( char address, char* output, int quantity ){
     char command = address | 160; //0d160 = 0b10100000
-    i2c_.write( SLAVE_ADDRESS << 1, &command, 1, true );
-    int ack = i2c_.read( SLAVE_ADDRESS << 1, output, quantity );
+    i2c.write( SLAVE_ADDRESS << 1, &command, 1, true );
+    int ack = i2c.read( SLAVE_ADDRESS << 1, output, quantity );
     return ack;
 }
 
-int TCS3472_I2C::enableRGBC(){
-    int ack = writeSingleRegister( ENABLE_REGISTER, 3 );
-    return ack;
-}
-
-char TCS3472_I2C::readEnableRegister(){
-    return readSingleRegister( ENABLE_REGISTER );
-}
-
 int TCS3472_I2C::getAllColours( int* readings ){
     char buffer[8] = { 0 };
 
@@ -76,37 +77,79 @@
     return reading;
 }
 
-int TCS3472_I2C::setIntegrationTime( const float itime ){
-    char atime = 256 - itime / 2.4;
-    int ack = writeSingleRegister( ATIME, atime );
+int TCS3472_I2C::enablePower(){
+    char enable_old = readSingleRegister( ENABLE );
+    char enable_new = enable_old | 1; // sets PON (bit 0) to 1
+    int ack = writeSingleRegister( ENABLE, enable_new );
+    return ack;
+}
+
+int TCS3472_I2C::disablePower(){
+    char enable_old = readSingleRegister( ENABLE );
+    char enable_new = enable_old & 254; // sets PON (bit 0) to 0
+    int ack = writeSingleRegister( ENABLE, enable_new );
+    return ack;
+}
+
+int TCS3472_I2C::enableRGBC(){
+    char enable_old = readSingleRegister( ENABLE );
+    char enable_new = enable_old | 2; // sets AEN (bit 1) to 1
+    int ack = writeSingleRegister( ENABLE, enable_new );
+    return ack;
+}
+
+int TCS3472_I2C::disableRGBC(){
+    char enable_old = readSingleRegister( ENABLE );
+    char enable_new = enable_old & 253; // sets AEN (bit 1) to 0
+    int ack = writeSingleRegister( ENABLE, enable_new );
+    return ack;
+}
+
+int TCS3472_I2C::enablePowerAndRGBC(){
+    char enable_old = readSingleRegister( ENABLE );
+    char enable_new = enable_old | 3; // sets PON (bit 0) and AEN (bit 1) to 1
+    int ack = writeSingleRegister( ENABLE, enable_new );
+    return ack;
+}
+
+int TCS3472_I2C::disablePowerAndRGBC(){
+    char enable_old = readSingleRegister( ENABLE );
+    char enable_new = enable_old | 252; // sets PON (bit 0) and AEN (bit 1) to 0
+    int ack = writeSingleRegister( ENABLE, enable_new );
     return ack;
 }
 
 int TCS3472_I2C::enableWait(){
-    char enable_old = readSingleRegister( ENABLE_REGISTER );
+    char enable_old = readSingleRegister( ENABLE );
     char enable_new = enable_old | 8; // sets WEN (bit 4) to 1
-    int ack = writeSingleRegister( ENABLE_REGISTER, enable_new );
+    int ack = writeSingleRegister( ENABLE, enable_new );
     return ack;
 }
 
 int TCS3472_I2C::disableWait(){
-    char enable_old = readSingleRegister( ENABLE_REGISTER );
+    char enable_old = readSingleRegister( ENABLE );
     char enable_new = enable_old & 247; // sets WEN (bit 4) to 0
-    int ack = writeSingleRegister( ENABLE_REGISTER, enable_new );
+    int ack = writeSingleRegister( ENABLE, enable_new );
     return ack;
 }
 
 int TCS3472_I2C::enableInterrupt(){
-    char enable_old = readSingleRegister( ENABLE_REGISTER );
+    char enable_old = readSingleRegister( ENABLE );
     char enable_new = enable_old | 16; // sets AIEN (bit 5) to 1
-    int ack = writeSingleRegister( ENABLE_REGISTER, enable_new );
+    int ack = writeSingleRegister( ENABLE, enable_new );
     return ack;
 }
 
 int TCS3472_I2C::disableInterrupt(){
-    char enable_old = readSingleRegister( ENABLE_REGISTER );
+    char enable_old = readSingleRegister( ENABLE );
     char enable_new = enable_old & 239; // sets AIEN (bit 5) to 0
-    int ack = writeSingleRegister( ENABLE_REGISTER, enable_new );
+    int ack = writeSingleRegister( ENABLE, enable_new );
+    return ack;
+}
+
+int TCS3472_I2C::setIntegrationTime( const float itime ){
+    char atime = 256 - itime / 2.4;
+    int ack = writeSingleRegister( ATIME, atime );
     return ack;
 }
 
@@ -114,13 +157,232 @@
     int ack = 1;
     char wtime = 0;
     if ( time >= 2.4 && time <= 614.4 ){
-        ack = writeSingleRegister( CONFIGURATION_REGISTER, 0 ); // sets WLONG to 0
+        ack = writeSingleRegister( CONFIG, 0 ); // sets WLONG to 0
         wtime = 256 - time / 2.4;
     }
     else if ( time > 614.4 && time <= 7400 ){
-        ack = writeSingleRegister( CONFIGURATION_REGISTER, 2 ); // sets WLONG to 1
+        ack = writeSingleRegister( CONFIG, 2 ); // sets WLONG to 1
         wtime = 256 - ( time / 12 ) / 2.4;
     } 
     ack = ack || writeSingleRegister( WTIME, wtime );
     return ack;
+}
+
+char TCS3472_I2C::readEnableRegister(){
+    return readSingleRegister( ENABLE );
+}
+
+int TCS3472_I2C::readLowInterruptThreshold(){
+    char buffer[2] = { 0 };
+    readMultipleRegisters( AILTL, buffer, 2 );
+    int reading = (int)buffer[1] << 8 | (int)buffer[0];
+    return reading;
+}
+
+int TCS3472_I2C::readHighInterruptThreshold(){
+    char buffer[2] = { 0 };
+    readMultipleRegisters( AIHTL, buffer, 2 );
+    int reading = (int)buffer[1] << 8 | (int)buffer[0];
+    return reading;
+}
+
+int TCS3472_I2C::setLowInterruptThreshold( const int threshold ){
+    char threshold_bytes[2];
+    threshold_bytes[0] = threshold; // take lowest 8 bits of threshold
+    threshold_bytes[1] = threshold >> 8; // take highest 8 bits of threshold
+    int ack = writeMultipleRegisters( AILTL, threshold_bytes, 2 );
+    return ack;
+}
+
+int TCS3472_I2C::setHighInterruptThreshold( const int threshold ){
+    char threshold_bytes[2];
+    threshold_bytes[0] = threshold;
+    threshold_bytes[1] = threshold >> 8;
+    int ack = writeMultipleRegisters( AIHTL, threshold_bytes, 2 );
+    return ack;
+}
+
+int TCS3472_I2C::readInterruptPersistence(){
+    char pers = readSingleRegister( PERS );
+    char persistence_bits = ( pers << 4 ) >> 4; // discard bits 4 to 7, keep only bits 0 to 3
+    int persistence = -1;
+    switch (persistence_bits){
+        case 0:
+            persistence = 0;
+            break;
+        case 1:
+            persistence = 1;
+            break;
+        case 2:
+            persistence = 2;
+            break;
+        case 3:
+            persistence = 3;
+            break;
+        case 4:
+            persistence = 5;
+            break;
+        case 5:
+            persistence = 10;
+            break;
+        case 6:
+            persistence = 15;
+            break;
+        case 7:
+            persistence = 20;
+            break;
+        case 8:
+            persistence = 25;
+            break;
+        case 9:
+            persistence = 30;
+            break;
+        case 10:
+            persistence = 35;
+            break;
+        case 11:
+            persistence = 40;
+            break;
+        case 12:
+            persistence = 45;
+            break;
+        case 13:
+            persistence = 50;
+            break;
+        case 14:
+            persistence = 55;
+            break;
+        case 15:
+            persistence = 60;
+            break;
+        default:
+            break;
+    }
+    return persistence;
+}
+
+int TCS3472_I2C::setInterruptPersistence( const int persistence ){
+    char pers_byte;
+    int ack = 0;
+    switch (persistence){
+        case 0:
+            pers_byte = 0;
+            break;
+        case 1:
+            pers_byte = 1;
+            break;
+        case 2:
+            pers_byte = 2;
+            break;
+        case 3:
+            pers_byte = 3;
+            break;
+        case 5:
+            pers_byte = 4;
+            break;
+        case 10:
+            pers_byte = 5;
+            break;
+        case 15:
+            pers_byte = 6;
+            break;
+        case 20:
+            pers_byte = 7;
+            break;
+        case 25:
+            pers_byte = 8;
+            break;
+        case 30:
+            pers_byte = 9;
+            break;
+        case 35:
+            pers_byte = 10;
+            break;
+        case 40:
+            pers_byte = 11;
+            break;
+        case 45:
+            pers_byte = 12;
+            break;
+        case 50:
+            pers_byte = 13;
+            break;
+        case 55:
+            pers_byte = 14;
+            break;
+        case 60:
+            pers_byte = 15;
+            break;
+        default:
+            ack = 2; // 2 used to indicate invalid entry
+            break;
+    }
+    if ( ack != 2 ){
+        ack = writeSingleRegister( PERS, pers_byte );
+    }
+    return ack;
+}
+
+int TCS3472_I2C::clearInterrupt(){
+    char tx = 230;
+    int ack = i2c.write( SLAVE_ADDRESS << 1, &tx, 1 );
+    return ack;
+}
+
+int TCS3472_I2C::readRGBCGain(){
+    char control = readSingleRegister( CONTROL );
+    char gain_bits = ( control << 6 ) >> 6; // discard  bits 2 to 7, keep only bits 0 & 1
+    int gain;
+    switch (gain_bits) {
+        case 0:
+            gain = 1;
+            break;
+        case 1:
+            gain = 4;
+            break;
+        case 2:
+            gain = 16;
+            break;
+        case 3:
+            gain = 60;
+            break;
+        default:
+            gain = 0;
+            break;
+    }
+    return gain;
+}
+
+int TCS3472_I2C::setRGBCGain( const int gain ){
+    char control;
+    int ack = 0;
+    switch (gain){
+        case 1:
+            control = 0;
+            break;
+        case 4:
+            control = 1;
+            break;
+        case 16:
+            control = 2;
+            break;
+        case 60:
+            control = 3;
+            break;
+        default:
+            ack = 2; // 2 used to indicate invalid entry
+            break;
+    }
+    if ( ack != 2 ){
+        ack = writeSingleRegister( CONTROL, control );
+    }
+    return ack;
+}
+
+char TCS3472_I2C::getDeviceID(){
+    return readSingleRegister( ID );
+}
+
+char TCS3472_I2C::readStatusRegister(){
+    return readSingleRegister( STATUS );
 }
\ No newline at end of file
--- a/TCS3472_I2C.h	Wed Mar 19 18:48:12 2014 +0000
+++ b/TCS3472_I2C.h	Thu Mar 20 16:56:56 2014 +0000
@@ -5,10 +5,16 @@
 //Defines 
 #define SLAVE_ADDRESS           0x29
 
-#define ENABLE_REGISTER         0x00
+#define ENABLE                  0x00
 #define ATIME                   0x01
 #define WTIME                   0x03
-#define CONFIGURATION_REGISTER  0x0D
+#define AILTL                   0x04
+#define AIHTL                   0x06
+#define PERS                    0x0C
+#define CONFIG                  0x0D
+#define CONTROL                 0x0F
+#define ID                      0x12
+#define STATUS                  0x13
 #define CDATA                   0x14
 #define RDATA                   0x16
 #define GDATA                   0x18
@@ -23,20 +29,38 @@
     int getRedData();
     int getGreenData();
     int getBlueData();
-    
-    int setIntegrationTime( const float itime ); // itime (in ms) should be in the range 2.4 - 614.4ms.
+   
+    int enablePower();
+    int disablePower();
+    int enableRGBC();
+    int disableRGBC();
+    int enablePowerAndRGBC();
+    int disablePowerAndRGBC();
     int enableWait();
     int disableWait();
     int enableInterrupt();
     int disableInterrupt();
     int setWaitTime( const float wtime ); // wtime (in ms) should be in the range 2.4 - 7400ms.
+    int setIntegrationTime( const float itime ); // itime (in ms) should be in the range 2.4 - 614.4ms.
+    
+    char readEnableRegister();
+    int readLowInterruptThreshold();
+    int readHighInterruptThreshold();
+    int setLowInterruptThreshold( const int threshold );
+    int setHighInterruptThreshold( const int threshold );
+    int readInterruptPersistence();
+    int setInterruptPersistence( const int persistence ); // persistence must be 0, 1, 2, 3, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55 or 60
+    int clearInterrupt();
+    int readRGBCGain();
+    int setRGBCGain( const int gain ); // gain must be 1, 4, 16 or 60
+    char getDeviceID();
+    char readStatusRegister();
 
 private:
-    I2C i2c_;
+    I2C i2c;
     
-    int enableRGBC();
-    char readEnableRegister();
     int writeSingleRegister( char address, char data );
+    int writeMultipleRegisters( char address, char* data, int quantity );
     char readSingleRegister( char address );
     int readMultipleRegisters( char address, char* output, int quantity );
 };