blob: fcd75222c51c14b57ecde83e702f6c2f2a4f28bf [file] [log] [blame]
/*
* Copyright (C) 2014 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.araploxio;
import android.content.Context;
import android.hardware.I2cManager;
import android.hardware.I2cTransaction;
import android.os.Handler;
import android.os.Message;
import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Sensor {
// The 7-bit slave address
private static final int address = (0x50 >> 1);
private static final String bus = "/dev/i2c-4";
private Context context;
private I2cManager i2c;
private Handler handler;
private ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
private static I2cTransaction WriteReg(int reg, int b1, int b2, int b3) {
return I2cTransaction.newWrite(0x01, reg, b1, b2, b3);
}
private static final I2cTransaction[] setupTxns = {
WriteReg(0x00, 0x00, 0x00, 0x08), //AFE4400_CONTROL0
WriteReg(0x01, 0x00, 0x17, 0xD4), //AFE4400_LED2STC
WriteReg(0x02, 0x00, 0x1D, 0xAE), //AFE4400_LED2ENDC
WriteReg(0x03, 0x00, 0x17, 0x70), //AFE4400_LED2LEDSTC
WriteReg(0x04, 0x00, 0x1D, 0xAF), //AFE4400_LED2LEDENDC
WriteReg(0x05, 0x00, 0x00, 0x00), //AFE4400_ALED2STC
WriteReg(0x06, 0x00, 0x06, 0x3E), //AFE4400_ALED2ENDC
WriteReg(0x07, 0x00, 0x08, 0x34), //AFE4400_LED1STC
WriteReg(0x08, 0x00, 0x0E, 0x0E), //AFE4400_LED1ENDC
WriteReg(0x09, 0x00, 0x07, 0xD0), //AFE4400_LED1LEDSTC
WriteReg(0x0A, 0x00, 0x0E, 0x0F), //AFE4400_LED1LEDENDC
WriteReg(0x0B, 0x00, 0x0F, 0xA0), //AFE4400_ALED1STC
WriteReg(0x0C, 0x00, 0x15, 0xDE), //AFE4400_ALED1ENDC
WriteReg(0x0D, 0x00, 0x00, 0x02), //AFE4400_LED2CONVST
WriteReg(0x0E, 0x00, 0x07, 0xCF), //AFE4400_LED2CONVEND
WriteReg(0x0F, 0x00, 0x07, 0xD2), //AFE4400_ALED2CONVST
WriteReg(0x10, 0x00, 0x0F, 0x9F), //AFE4400_ALED2CONVEND
WriteReg(0x11, 0x00, 0x0F, 0xA2), //AFE4400_LED1CONVST
WriteReg(0x12, 0x00, 0x17, 0x6F), //AFE4400_LED1CONVEND
WriteReg(0x13, 0x00, 0x17, 0x72), //AFE4400_ALED1CONVST
WriteReg(0x14, 0x00, 0x1F, 0x3F), //AFE4400_ALED1CONVEND
WriteReg(0x15, 0x00, 0x00, 0x00), //AFE4400_ADCRSTSTCT0
WriteReg(0x16, 0x00, 0x00, 0x00), //AFE4400_ADCRSTENDCT0
WriteReg(0x17, 0x00, 0x07, 0xD0), //AFE4400_ADCRSTSTCT1
WriteReg(0x18, 0x00, 0x07, 0xD0), //AFE4400_ADCRSTENDCT1
WriteReg(0x19, 0x00, 0x0F, 0xA0), //AFE4400_ADCRSTSTCT2
WriteReg(0x1A, 0x00, 0x0F, 0xA0), //AFE4400_ADCRSTENDCT2
WriteReg(0x1B, 0x00, 0x17, 0x70), //AFE4400_ADCRSTSTCT3
WriteReg(0x1C, 0x00, 0x17, 0x70), //AFE4400_ADCRSTENDCT3
WriteReg(0x1D, 0x00, 0x1F, 0x3F), //AFE4400_PRPCOUNT
WriteReg(0x1E, 0x00, 0x01, 0x01), //AFE4400_CONTROL1
WriteReg(0x20, 0x00, 0x00, 0x00), //AFE4400_TIAGAIN
// Rf=100k Cf=50pF gain=0dB stage2=bypass ambdac=0µA
WriteReg(0x21, 0x00, 0x00, 0x3A), //AFE4400_TIA_AMB_GAIN
//WriteReg(0x22, 0x01, 0x14, 0x29), //AFE4400_LEDCNTRL
WriteReg(0x22, 0x01, 0x4f, 0x4f), //AFE4400_LEDCNTRL
WriteReg(0x23, 0x02, 0x01, 0x00), //AFE4400_CONTROL2
WriteReg(0x29, 0x00, 0x00, 0x00), //AFE4400_ALARM
// Setup SPI_READ
WriteReg(0x00, 0x00, 0x00, 0x01), //AFE4400_CONTROL0
};
private static final I2cTransaction[] led2Read = {
WriteReg(0x2e, // LED2-ALED2VAL
0xff, 0xff, 0xff), // 3 dummy bytes
I2cTransaction.newRead(4),
};
private static final I2cTransaction[] led1Read = {
WriteReg(0x2f, // LED1-ALED1VAL
0xff, 0xff, 0xff), // 3 dummy bytes
I2cTransaction.newRead(4),
};
private static final I2cTransaction[] resetTxns = {
WriteReg(0x00, 0x00, 0x00, 0x08), //AFE4400_CONTROL0
};
public Sensor(Context context, Handler handler) {
this.context = context;
this.i2c = (I2cManager)context.getSystemService(Context.I2C_SERVICE);
this.handler = handler;
}
private I2cTransaction[] execute(I2cTransaction[] txns) {
I2cTransaction[] results;
try {
results = null;
for (I2cTransaction txn: txns)
results = i2c.performTransactions(bus, address, txn);
} catch (IOException e) {
throw new RuntimeException("I2C error: " + e);
}
return results;
}
public void start() {
execute(setupTxns);
executor.scheduleAtFixedRate(collector, 20, 20, TimeUnit.MILLISECONDS);
}
public void stop() {
executor.shutdown();
try {
executor.awaitTermination(20, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
assert false;
}
execute(resetTxns);
}
private final Runnable collector = new Runnable() {
public void run() {
I2cTransaction[] results;
byte[] data;
int LED1VAL;
int LED2VAL;
results = execute(led2Read);
data = results[0].data;
LED2VAL = (((int)data[1] & 0xFF) << 16) |
(((int)data[2] & 0xFF) << 8) |
(((int)data[3] & 0xFF) << 0);
if (LED2VAL >= 0x800000 && LED2VAL < 0x1000000)
LED2VAL -= 0x1000000;
results = execute(led1Read);
data = results[0].data;
LED1VAL = (((int)data[1] & 0xFF) << 16) |
(((int)data[2] & 0xFF) << 8) |
(((int)data[3] & 0xFF) << 0);
if (LED1VAL >= 0x800000 && LED1VAL < 0x1000000)
LED1VAL -= 0x1000000;
handler.obtainMessage(0, LED1VAL, LED2VAL).sendToTarget();
}
};
}