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
00001 #include "Si114x.h" 00002 #include "Si114x_defs.h" 00003 00004 #define PS_ADC_GAIN 0x02 00005 00006 00007 Si114x::Si114x(PinName sda, PinName scl) : i2c(sda,scl) { 00008 //Wait startup time and enable the device 00009 i2c.frequency(400000); 00010 wait_ms(30); 00011 write_byte(REG_MEAS_RATE0, 0x00); 00012 write_byte(REG_MEAS_RATE1, 0x00); 00013 00014 write_cmd(CMD_RESET); 00015 wait_ms(10); 00016 write_byte(REG_HW_KEY, 0x17); 00017 00018 //Set UV coefficients 00019 write_byte(REG_UCOEF0, 0x29); 00020 write_byte(REG_UCOEF1, 0x89); 00021 write_byte(REG_UCOEF2, 0x02); 00022 write_byte(REG_UCOEF3, 0x00); 00023 00024 //Set LED current (max, which apparantly is not going to destroy anything) 00025 write_byte(REG_PS_LED21, 0xFF); 00026 00027 //Set default LED channels 00028 setPSLEDs(1, 0x01); 00029 setPSLEDs(2, 0x02); 00030 00031 continious = false; 00032 00033 } 00034 00035 bool Si114x::verifyConnection(void) { 00036 uint8_t part_id = read_byte(REG_PART_ID); 00037 if ((part_id == 0x45) || (part_id == 0x46) || (part_id == 0x47)) 00038 return true; 00039 return false; 00040 } 00041 00042 //-------------------Get light functions--------------------------- 00043 00044 unsigned short Si114x::getVisibleLight(void) { 00045 if (continious == false) { 00046 //Enable visible light measurement, clear current interrupt, start conversion, wait until done 00047 write_byte(REG_IRQ_STATUS, 0x01); 00048 param_set(RAM_CHLIST, (1<<4)); 00049 write_cmd(CMD_ALS_FORCE); 00050 while(read_byte(REG_IRQ_STATUS) & 0x01 != 0x01); 00051 } 00052 return read_word(REG_ALS_VIS_DATA0); 00053 } 00054 00055 unsigned short Si114x::getIRLight(void) { 00056 if (continious == false) { 00057 //Enable IR light measurement, clear current interrupt, start conversion, wait until done 00058 write_byte(REG_IRQ_STATUS, 0x01); 00059 param_set(RAM_CHLIST, (1<<5)); 00060 write_cmd(CMD_ALS_FORCE); 00061 while(read_byte(REG_IRQ_STATUS) & 0x01 != 0x01); 00062 } 00063 return read_word(REG_ALS_IR_DATA0); 00064 } 00065 00066 unsigned short Si114x::getUVIndex(void) { 00067 if (continious == false) { 00068 //Enable IR light measurement, clear current interrupt, start conversion, wait until done 00069 write_byte(REG_IRQ_STATUS, 0x01); 00070 param_set(RAM_CHLIST, (1<<7)); 00071 write_cmd(CMD_ALS_FORCE); 00072 while(read_byte(REG_IRQ_STATUS) & 0x01 != 0x01); 00073 } 00074 return read_word(REG_UV_INDEX0); 00075 } 00076 00077 //---------------------------------- Proximity ----------------------------------------------------- 00078 unsigned short Si114x::getProximity(char pschannel) { 00079 if (continious == false) { 00080 //Enable IR light measurement, clear current interrupt, start conversion, wait until done 00081 write_byte(REG_IRQ_STATUS, 0x04); 00082 param_set(RAM_CHLIST, (1<<(pschannel-1))); 00083 write_cmd(CMD_PS_FORCE); 00084 while(read_byte(REG_IRQ_STATUS) & 0x04 != 0x04); 00085 } 00086 return read_word(REG_PS1_DATA0 + (pschannel - 1)* 2); 00087 } 00088 00089 void Si114x::setPSLEDs(char pschannel, char ledmask) { 00090 char psled12 = param_query(RAM_PSLED12_SELECT); 00091 if (pschannel == 1) { 00092 psled12 = (psled12 & ~0x0F) | ledmask; 00093 } 00094 else { 00095 psled12 = (psled12 & ~0xF0) | (ledmask << 4); 00096 } 00097 param_set(RAM_PSLED12_SELECT, psled12); 00098 } 00099 00100 00101 //---------------------------------- Read/Write functions --------------------------------------------- 00102 00103 char Si114x::read_byte(const char reg) { 00104 char retval; 00105 i2c.write(SI114x_ADDRESS, ®, 1, true); 00106 i2c.read(SI114x_ADDRESS, &retval, 1); 00107 return retval; 00108 } 00109 00110 unsigned short Si114x::read_word(const char reg) { 00111 unsigned short retval; 00112 i2c.write(SI114x_ADDRESS, ®, 1, true); 00113 i2c.read(SI114x_ADDRESS, (char*)&retval, 2); //This actually seems to put them in correct order 00114 return retval; 00115 } 00116 00117 void Si114x::write_byte(const char reg, const char byte) { 00118 char data[] = {reg, byte}; 00119 i2c.write(SI114x_ADDRESS, data, 2); 00120 } 00121 00122 void Si114x::param_set(const char param, const char value) { 00123 write_byte(REG_PARAM_WR, value); 00124 write_cmd(CMD_PARAM_SET | param); 00125 } 00126 00127 char Si114x::param_query(const char param) { 00128 write_cmd(CMD_PARAM_QUERY | param); 00129 return read_byte(REG_PARAM_RD); 00130 } 00131 00132 void Si114x::write_cmd(const char cmd) { 00133 uint8_t old_value = read_byte(REG_RESPONSE); 00134 00135 write_byte(REG_COMMAND, cmd); 00136 00137 if (cmd == CMD_RESET) { 00138 return; 00139 } 00140 00141 char i = 0; 00142 while(read_byte(REG_RESPONSE) == old_value) { 00143 wait_ms(1); 00144 if (i > 25) { 00145 break; 00146 } 00147 i++; 00148 } 00149 }
Generated on Mon Jul 18 2022 19:16:33 by 1.7.2