AS7265x functions for setting integration time, LEDs, collecting/reading data

Dependents:   IntegratingSphereController LaunchDay

AS7265xfunctions.cpp

Committer:
nthompson22
Date:
2019-01-24
Revision:
0:3699cacb5a93
Child:
1:4d4e07dcc694

File content as of revision 0:3699cacb5a93:

#include "AS7265xfunctions.h"
#define REG_ADDR_STATUS 0x00
#define REG_ADDR_WRITE  0x01
#define REG_ADDR_READ   0x02
#define STATUS_TX_VALID 0x02
#define STATUS_RX_VALID 0x01
#define REG_DEV_SEL     0x4F
#define REG_LED_CONFIG  0x07
#define REG_INTEG_TIME  0x05

AS7265x::AS7265x(I2C i2c, int addr) : _i2c(i2c) {
  _addr = addr;
}

void AS7265x::collectData(void){
    int k;
    for (int i = 0; i < 3; i++) { //goes through all 3 sensors
        selectDevice(i);
        for (int j = 0; j < 6; j++) { //goes through all 6 channels on each sensor
            uint16_t data = getData(j);
            k = 6*i + j; //gives the channel currently being read for data out of all 18 channels
            switch (k) { //assigns values to the array of data for all 18 channels
                case 0: _channels[8] = data; break;
                case 1: _channels[10] = data; break;
                case 2: _channels[12] = data; break;
                case 3: _channels[13] = data; break;
                case 4: _channels[14] = data; break;
                case 5: _channels [15] = data; break;
                case 6: _channels [6] = data; break;
                case 7: _channels [7] = data; break;
                case 8: _channels [9] = data; break;
                case 9: _channels [11] = data; break;
                case 10: _channels [16] = data; break;
                case 11: _channels [17] = data; break;
                case 12: _channels [0] = data; break;
                case 13: _channels [1] = data; break;
                case 14: _channels [2] = data; break;
                case 15: _channels [3] = data; break;
                case 16: _channels [4] = data; break;
                case 17: _channels [5] = data; break;
                default: _channels [0] = 0;
            }
        }
    }
}

uint16_t AS7265x::readData(int i) {
    i--; //so that the user can put in a number 1 to 18 for which channel they want, but the readData function reads from channels 0 to 17
    return _channels[i];
}

void AS7265x::regWrite(char reg, char data) {
    char status;
    char buff[3];
    bool writeBuffReady = false;
    while (!writeBuffReady) {
        // Read slave I²C status to see if the write buffer is ready.
        buff[0] = REG_ADDR_STATUS;
        _i2c.write(_addr, buff, 1, true); //true at the end to not send a stop signal before the next start signal because our sensor doesn't need it
        _i2c.read(_addr, buff, 1);
        status = buff[0];
        if ((status & STATUS_TX_VALID) == 0)
            // No inbound TX pending at slave. Okay to write now.
            writeBuffReady = true;
            
    }
    // Send the virtual register address (enabling bit 7 to indicate a write).
    buff[0] = REG_ADDR_WRITE;
    buff[1] = reg | 0x80;
    _i2c.write(_addr, buff, 2);
    writeBuffReady = false;
    while (!writeBuffReady) {
        // Read the slave I²C status to see if the write buffer is ready.
        buff [0] = REG_ADDR_STATUS;
        _i2c.write(_addr, buff, 1, true);
        _i2c.read(_addr, buff, 1);
        status = buff[0];
        if ((status & STATUS_TX_VALID) == 0)
            // No inbound TX pending at slave. Okay to write data now.
            writeBuffReady = true;
    }
    // Send the data to complete the operation.
    buff [0] = REG_ADDR_WRITE;
    buff [1] = data;
    _i2c.write(_addr, buff, 2);
}

char AS7265x::regRead(char reg) {
    char buff [3];
    char status;
    bool writeBuffReady = false;
    while (!writeBuffReady) {
        // Read slave I²C status to see if the read buffer is ready.
        buff [0] = REG_ADDR_STATUS;
        _i2c.write(_addr, buff, 1, true);
        _i2c.read(_addr, buff, 1);
        status = buff[0];
        if ((status & STATUS_TX_VALID) == 0)
            // No inbound TX pending at slave. Okay to write now.
            writeBuffReady = true;
    }
    // Send the virtual register address (disabling bit 7 to indicate a read).
    buff [0] = REG_ADDR_WRITE;
    buff [1] = reg;
    _i2c.write(_addr, buff, 2);
    bool readBuffReady = false;
    while (!readBuffReady) {
        // Read the slave I²C status to see if our read data is available.
        buff [0] = REG_ADDR_STATUS;
        _i2c.write(_addr, buff, 1, true);
        _i2c.read(_addr, buff, 1);
        status = buff[0];
        if ((status & STATUS_RX_VALID) != 0)
            // Read data is ready.
            readBuffReady = true;
    }
    // Read the data to complete the operation.
    buff [0] = REG_ADDR_READ;
    _i2c.write(_addr, buff, 1, true);
    _i2c.read(_addr, buff, 1) ;
    return buff[0];
} 

uint16_t AS7265x::getData(int channel){
    int channel_addr;
    uint16_t high, low;
    switch(channel) { //based on the channel number put into the function, converts to the address of that channel
        case 0: channel_addr = 0x08; break;
        case 1: channel_addr = 0x0A; break;
        case 2: channel_addr = 0x0C; break;
        case 3: channel_addr = 0x0E; break;
        case 4: channel_addr = 0x10; break;
        case 5: channel_addr = 0x12; break;
        default: channel_addr = 0x08;
    }
    high = regRead(channel_addr)<<8; //reads the highest 8 bits of data, and shifts them over by 8, leaving 8 zeroes
    low = regRead(channel_addr + 1); //reads the lowest 8 bits of data
    return high | low; //lowest 8 bits of data fill in the 8 zeroes left by the highest 8 bits being shifted, created a 16 bit number

}

void AS7265x::selectDevice(int dev) {
    switch(dev) { //based on the value put into the function, converts to the address of the corresponding sensor and selects it
        case 0: regWrite(REG_DEV_SEL, 0x00); break;
        case 1: regWrite(REG_DEV_SEL, 0x01); break;
        case 2: regWrite(REG_DEV_SEL, 0x02); break;
        default: regWrite(REG_DEV_SEL, 0x00);
    }
}

void AS7265x::ledSwitch(int dev, int set) {
    char setting;
    selectDevice(dev);
    setting = regRead(REG_LED_CONFIG); //configures the bits necessary to control the LED, now bit 3 will turn it on or off
    if(set) {
        setting = setting | 0x08; //turns bit 3 on
    }
    else {
        setting = setting & (0xFF - 0x08); //turns bit 3 off
    }
    regWrite(REG_LED_CONFIG, setting);
}

void AS7265x::setAllLeds(int set) {
    for (int i = 0; i < 3; i++) {
        ledSwitch(i, set); //goes through every sensor, turning the corresponding LED on or off one at a time
    }
}

char AS7265x::getDeviceType() {
  return regRead(0x00);
}

char AS7265x::getHardwareVersion() {
  return regRead(0x01);
}

void AS7265x::setIntegTime(int integTime) {
    char setting;
    setting = integTime/2.8;
    /* divides by 2.8 because the sensor takes the value put into the function and multiplies it by 2.8 to get the integration
    time in ms. This way, the user can input how many ms they want the integration time to be */
    regWrite(REG_INTEG_TIME, setting);
}