Library for Si114x optical sensors. Currently intended for the Si1146, although it will work also for the Si1145, and without full functionality for the Si1147
Dependents: Si114x_HelloWorld Hello-Uzuki-sensor-shield
Si114x.cpp
- Committer:
- Sissors
- Date:
- 2015-08-23
- Revision:
- 0:971d705818e7
File content as of revision 0:971d705818e7:
#include "Si114x.h" #include "Si114x_defs.h" #define PS_ADC_GAIN 0x02 Si114x::Si114x(PinName sda, PinName scl) : i2c(sda,scl) { //Wait startup time and enable the device i2c.frequency(400000); wait_ms(30); write_byte(REG_MEAS_RATE0, 0x00); write_byte(REG_MEAS_RATE1, 0x00); write_cmd(CMD_RESET); wait_ms(10); write_byte(REG_HW_KEY, 0x17); //Set UV coefficients write_byte(REG_UCOEF0, 0x29); write_byte(REG_UCOEF1, 0x89); write_byte(REG_UCOEF2, 0x02); write_byte(REG_UCOEF3, 0x00); //Set LED current (max, which apparantly is not going to destroy anything) write_byte(REG_PS_LED21, 0xFF); //Set default LED channels setPSLEDs(1, 0x01); setPSLEDs(2, 0x02); continious = false; } bool Si114x::verifyConnection(void) { uint8_t part_id = read_byte(REG_PART_ID); if ((part_id == 0x45) || (part_id == 0x46) || (part_id == 0x47)) return true; return false; } //-------------------Get light functions--------------------------- unsigned short Si114x::getVisibleLight(void) { if (continious == false) { //Enable visible light measurement, clear current interrupt, start conversion, wait until done write_byte(REG_IRQ_STATUS, 0x01); param_set(RAM_CHLIST, (1<<4)); write_cmd(CMD_ALS_FORCE); while(read_byte(REG_IRQ_STATUS) & 0x01 != 0x01); } return read_word(REG_ALS_VIS_DATA0); } unsigned short Si114x::getIRLight(void) { if (continious == false) { //Enable IR light measurement, clear current interrupt, start conversion, wait until done write_byte(REG_IRQ_STATUS, 0x01); param_set(RAM_CHLIST, (1<<5)); write_cmd(CMD_ALS_FORCE); while(read_byte(REG_IRQ_STATUS) & 0x01 != 0x01); } return read_word(REG_ALS_IR_DATA0); } unsigned short Si114x::getUVIndex(void) { if (continious == false) { //Enable IR light measurement, clear current interrupt, start conversion, wait until done write_byte(REG_IRQ_STATUS, 0x01); param_set(RAM_CHLIST, (1<<7)); write_cmd(CMD_ALS_FORCE); while(read_byte(REG_IRQ_STATUS) & 0x01 != 0x01); } return read_word(REG_UV_INDEX0); } //---------------------------------- Proximity ----------------------------------------------------- unsigned short Si114x::getProximity(char pschannel) { if (continious == false) { //Enable IR light measurement, clear current interrupt, start conversion, wait until done write_byte(REG_IRQ_STATUS, 0x04); param_set(RAM_CHLIST, (1<<(pschannel-1))); write_cmd(CMD_PS_FORCE); while(read_byte(REG_IRQ_STATUS) & 0x04 != 0x04); } return read_word(REG_PS1_DATA0 + (pschannel - 1)* 2); } void Si114x::setPSLEDs(char pschannel, char ledmask) { char psled12 = param_query(RAM_PSLED12_SELECT); if (pschannel == 1) { psled12 = (psled12 & ~0x0F) | ledmask; } else { psled12 = (psled12 & ~0xF0) | (ledmask << 4); } param_set(RAM_PSLED12_SELECT, psled12); } //---------------------------------- Read/Write functions --------------------------------------------- char Si114x::read_byte(const char reg) { char retval; i2c.write(SI114x_ADDRESS, ®, 1, true); i2c.read(SI114x_ADDRESS, &retval, 1); return retval; } unsigned short Si114x::read_word(const char reg) { unsigned short retval; i2c.write(SI114x_ADDRESS, ®, 1, true); i2c.read(SI114x_ADDRESS, (char*)&retval, 2); //This actually seems to put them in correct order return retval; } void Si114x::write_byte(const char reg, const char byte) { char data[] = {reg, byte}; i2c.write(SI114x_ADDRESS, data, 2); } void Si114x::param_set(const char param, const char value) { write_byte(REG_PARAM_WR, value); write_cmd(CMD_PARAM_SET | param); } char Si114x::param_query(const char param) { write_cmd(CMD_PARAM_QUERY | param); return read_byte(REG_PARAM_RD); } void Si114x::write_cmd(const char cmd) { uint8_t old_value = read_byte(REG_RESPONSE); write_byte(REG_COMMAND, cmd); if (cmd == CMD_RESET) { return; } char i = 0; while(read_byte(REG_RESPONSE) == old_value) { wait_ms(1); if (i > 25) { break; } i++; } }