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

Committer:
Sissors
Date:
Sun Aug 23 16:58:36 2015 +0000
Revision:
0:971d705818e7
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 0:971d705818e7 1 #include "Si114x.h"
Sissors 0:971d705818e7 2 #include "Si114x_defs.h"
Sissors 0:971d705818e7 3
Sissors 0:971d705818e7 4 #define PS_ADC_GAIN 0x02
Sissors 0:971d705818e7 5
Sissors 0:971d705818e7 6
Sissors 0:971d705818e7 7 Si114x::Si114x(PinName sda, PinName scl) : i2c(sda,scl) {
Sissors 0:971d705818e7 8 //Wait startup time and enable the device
Sissors 0:971d705818e7 9 i2c.frequency(400000);
Sissors 0:971d705818e7 10 wait_ms(30);
Sissors 0:971d705818e7 11 write_byte(REG_MEAS_RATE0, 0x00);
Sissors 0:971d705818e7 12 write_byte(REG_MEAS_RATE1, 0x00);
Sissors 0:971d705818e7 13
Sissors 0:971d705818e7 14 write_cmd(CMD_RESET);
Sissors 0:971d705818e7 15 wait_ms(10);
Sissors 0:971d705818e7 16 write_byte(REG_HW_KEY, 0x17);
Sissors 0:971d705818e7 17
Sissors 0:971d705818e7 18 //Set UV coefficients
Sissors 0:971d705818e7 19 write_byte(REG_UCOEF0, 0x29);
Sissors 0:971d705818e7 20 write_byte(REG_UCOEF1, 0x89);
Sissors 0:971d705818e7 21 write_byte(REG_UCOEF2, 0x02);
Sissors 0:971d705818e7 22 write_byte(REG_UCOEF3, 0x00);
Sissors 0:971d705818e7 23
Sissors 0:971d705818e7 24 //Set LED current (max, which apparantly is not going to destroy anything)
Sissors 0:971d705818e7 25 write_byte(REG_PS_LED21, 0xFF);
Sissors 0:971d705818e7 26
Sissors 0:971d705818e7 27 //Set default LED channels
Sissors 0:971d705818e7 28 setPSLEDs(1, 0x01);
Sissors 0:971d705818e7 29 setPSLEDs(2, 0x02);
Sissors 0:971d705818e7 30
Sissors 0:971d705818e7 31 continious = false;
Sissors 0:971d705818e7 32
Sissors 0:971d705818e7 33 }
Sissors 0:971d705818e7 34
Sissors 0:971d705818e7 35 bool Si114x::verifyConnection(void) {
Sissors 0:971d705818e7 36 uint8_t part_id = read_byte(REG_PART_ID);
Sissors 0:971d705818e7 37 if ((part_id == 0x45) || (part_id == 0x46) || (part_id == 0x47))
Sissors 0:971d705818e7 38 return true;
Sissors 0:971d705818e7 39 return false;
Sissors 0:971d705818e7 40 }
Sissors 0:971d705818e7 41
Sissors 0:971d705818e7 42 //-------------------Get light functions---------------------------
Sissors 0:971d705818e7 43
Sissors 0:971d705818e7 44 unsigned short Si114x::getVisibleLight(void) {
Sissors 0:971d705818e7 45 if (continious == false) {
Sissors 0:971d705818e7 46 //Enable visible light measurement, clear current interrupt, start conversion, wait until done
Sissors 0:971d705818e7 47 write_byte(REG_IRQ_STATUS, 0x01);
Sissors 0:971d705818e7 48 param_set(RAM_CHLIST, (1<<4));
Sissors 0:971d705818e7 49 write_cmd(CMD_ALS_FORCE);
Sissors 0:971d705818e7 50 while(read_byte(REG_IRQ_STATUS) & 0x01 != 0x01);
Sissors 0:971d705818e7 51 }
Sissors 0:971d705818e7 52 return read_word(REG_ALS_VIS_DATA0);
Sissors 0:971d705818e7 53 }
Sissors 0:971d705818e7 54
Sissors 0:971d705818e7 55 unsigned short Si114x::getIRLight(void) {
Sissors 0:971d705818e7 56 if (continious == false) {
Sissors 0:971d705818e7 57 //Enable IR light measurement, clear current interrupt, start conversion, wait until done
Sissors 0:971d705818e7 58 write_byte(REG_IRQ_STATUS, 0x01);
Sissors 0:971d705818e7 59 param_set(RAM_CHLIST, (1<<5));
Sissors 0:971d705818e7 60 write_cmd(CMD_ALS_FORCE);
Sissors 0:971d705818e7 61 while(read_byte(REG_IRQ_STATUS) & 0x01 != 0x01);
Sissors 0:971d705818e7 62 }
Sissors 0:971d705818e7 63 return read_word(REG_ALS_IR_DATA0);
Sissors 0:971d705818e7 64 }
Sissors 0:971d705818e7 65
Sissors 0:971d705818e7 66 unsigned short Si114x::getUVIndex(void) {
Sissors 0:971d705818e7 67 if (continious == false) {
Sissors 0:971d705818e7 68 //Enable IR light measurement, clear current interrupt, start conversion, wait until done
Sissors 0:971d705818e7 69 write_byte(REG_IRQ_STATUS, 0x01);
Sissors 0:971d705818e7 70 param_set(RAM_CHLIST, (1<<7));
Sissors 0:971d705818e7 71 write_cmd(CMD_ALS_FORCE);
Sissors 0:971d705818e7 72 while(read_byte(REG_IRQ_STATUS) & 0x01 != 0x01);
Sissors 0:971d705818e7 73 }
Sissors 0:971d705818e7 74 return read_word(REG_UV_INDEX0);
Sissors 0:971d705818e7 75 }
Sissors 0:971d705818e7 76
Sissors 0:971d705818e7 77 //---------------------------------- Proximity -----------------------------------------------------
Sissors 0:971d705818e7 78 unsigned short Si114x::getProximity(char pschannel) {
Sissors 0:971d705818e7 79 if (continious == false) {
Sissors 0:971d705818e7 80 //Enable IR light measurement, clear current interrupt, start conversion, wait until done
Sissors 0:971d705818e7 81 write_byte(REG_IRQ_STATUS, 0x04);
Sissors 0:971d705818e7 82 param_set(RAM_CHLIST, (1<<(pschannel-1)));
Sissors 0:971d705818e7 83 write_cmd(CMD_PS_FORCE);
Sissors 0:971d705818e7 84 while(read_byte(REG_IRQ_STATUS) & 0x04 != 0x04);
Sissors 0:971d705818e7 85 }
Sissors 0:971d705818e7 86 return read_word(REG_PS1_DATA0 + (pschannel - 1)* 2);
Sissors 0:971d705818e7 87 }
Sissors 0:971d705818e7 88
Sissors 0:971d705818e7 89 void Si114x::setPSLEDs(char pschannel, char ledmask) {
Sissors 0:971d705818e7 90 char psled12 = param_query(RAM_PSLED12_SELECT);
Sissors 0:971d705818e7 91 if (pschannel == 1) {
Sissors 0:971d705818e7 92 psled12 = (psled12 & ~0x0F) | ledmask;
Sissors 0:971d705818e7 93 }
Sissors 0:971d705818e7 94 else {
Sissors 0:971d705818e7 95 psled12 = (psled12 & ~0xF0) | (ledmask << 4);
Sissors 0:971d705818e7 96 }
Sissors 0:971d705818e7 97 param_set(RAM_PSLED12_SELECT, psled12);
Sissors 0:971d705818e7 98 }
Sissors 0:971d705818e7 99
Sissors 0:971d705818e7 100
Sissors 0:971d705818e7 101 //---------------------------------- Read/Write functions ---------------------------------------------
Sissors 0:971d705818e7 102
Sissors 0:971d705818e7 103 char Si114x::read_byte(const char reg) {
Sissors 0:971d705818e7 104 char retval;
Sissors 0:971d705818e7 105 i2c.write(SI114x_ADDRESS, &reg, 1, true);
Sissors 0:971d705818e7 106 i2c.read(SI114x_ADDRESS, &retval, 1);
Sissors 0:971d705818e7 107 return retval;
Sissors 0:971d705818e7 108 }
Sissors 0:971d705818e7 109
Sissors 0:971d705818e7 110 unsigned short Si114x::read_word(const char reg) {
Sissors 0:971d705818e7 111 unsigned short retval;
Sissors 0:971d705818e7 112 i2c.write(SI114x_ADDRESS, &reg, 1, true);
Sissors 0:971d705818e7 113 i2c.read(SI114x_ADDRESS, (char*)&retval, 2); //This actually seems to put them in correct order
Sissors 0:971d705818e7 114 return retval;
Sissors 0:971d705818e7 115 }
Sissors 0:971d705818e7 116
Sissors 0:971d705818e7 117 void Si114x::write_byte(const char reg, const char byte) {
Sissors 0:971d705818e7 118 char data[] = {reg, byte};
Sissors 0:971d705818e7 119 i2c.write(SI114x_ADDRESS, data, 2);
Sissors 0:971d705818e7 120 }
Sissors 0:971d705818e7 121
Sissors 0:971d705818e7 122 void Si114x::param_set(const char param, const char value) {
Sissors 0:971d705818e7 123 write_byte(REG_PARAM_WR, value);
Sissors 0:971d705818e7 124 write_cmd(CMD_PARAM_SET | param);
Sissors 0:971d705818e7 125 }
Sissors 0:971d705818e7 126
Sissors 0:971d705818e7 127 char Si114x::param_query(const char param) {
Sissors 0:971d705818e7 128 write_cmd(CMD_PARAM_QUERY | param);
Sissors 0:971d705818e7 129 return read_byte(REG_PARAM_RD);
Sissors 0:971d705818e7 130 }
Sissors 0:971d705818e7 131
Sissors 0:971d705818e7 132 void Si114x::write_cmd(const char cmd) {
Sissors 0:971d705818e7 133 uint8_t old_value = read_byte(REG_RESPONSE);
Sissors 0:971d705818e7 134
Sissors 0:971d705818e7 135 write_byte(REG_COMMAND, cmd);
Sissors 0:971d705818e7 136
Sissors 0:971d705818e7 137 if (cmd == CMD_RESET) {
Sissors 0:971d705818e7 138 return;
Sissors 0:971d705818e7 139 }
Sissors 0:971d705818e7 140
Sissors 0:971d705818e7 141 char i = 0;
Sissors 0:971d705818e7 142 while(read_byte(REG_RESPONSE) == old_value) {
Sissors 0:971d705818e7 143 wait_ms(1);
Sissors 0:971d705818e7 144 if (i > 25) {
Sissors 0:971d705818e7 145 break;
Sissors 0:971d705818e7 146 }
Sissors 0:971d705818e7 147 i++;
Sissors 0:971d705818e7 148 }
Sissors 0:971d705818e7 149 }