Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
158 Kevin 1
#include "sensor_lux_TSL2561.h"
155 Kevin 2
#include "defines.h"
158 Kevin 3
#include "base_I2C.h"
155 Kevin 4
#include <delays.h>
5
 
6
static TSL2561_DATA *tsl2561_data_p;
7
 
8
void LUX_Init(TSL2561_DATA *data, char address) {
9
    tsl2561_data_p = data;
10
    tsl2561_data_p->address = address;
11
    tsl2561_data_p->integration = TSL2561_INTEGRATIONTIME_13MS;
12
    tsl2561_data_p->gain = TSL2561_GAIN_16X;
13
}
14
 
15
void LUX_Begin(void) {
16
    char result, buffer[2];
17
    char toSend = TSL2561_REGISTER_ID;
18
    DBG_PRINT_LUX("Sending %X to address %X\r\n", toSend, tsl2561_data_p->address);
19
    I2C_Master_Send(tsl2561_data_p->address, 1, &toSend);
20
    do {
21
        result = I2C_Get_Status();
22
    } while (!result);
23
 
24
    I2C_Master_Recv(tsl2561_data_p->address, 1);
25
    do {
26
        result = I2C_Get_Status();
27
    } while (!result);
28
    char length = I2C_Read_Buffer(buffer);
29
    DBG_PRINT_LUX("Received %d bytes: ", length);
30
    for (char i = 0; i < length; i++) {
31
        DBG_PRINT_LUX("%c ", buffer[i]);
32
    }
33
    DBG_PRINT_LUX("\r\n");
34
 
35
    // Set default integration time and gain
36
    LUX_Set_Timing(tsl2561_data_p->integration);
37
    LUX_Set_Gain(tsl2561_data_p->gain);
38
 
39
    // Start the chip in power-down mode
40
    LUX_Disable();
41
}
42
 
43
void LUX_Enable()  {
44
    LUX_Write_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWERON);
45
}
46
 
47
void LUX_Disable() {
48
    LUX_Write_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWEROFF);
49
}
50
 
51
void LUX_Set_Gain(tsl2561Gain_t gain) {
52
    LUX_Enable();
53
    tsl2561_data_p->gain = gain;
54
    LUX_Write_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING,
55
            tsl2561_data_p->integration | tsl2561_data_p->gain);
56
    LUX_Disable();
57
}
58
 
59
void LUX_Set_Timing(tsl2561IntegrationTime_t integration) {
60
    LUX_Enable();
61
    tsl2561_data_p->integration = integration;
62
    LUX_Write_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING,
63
            tsl2561_data_p->integration | tsl2561_data_p->gain);
64
    LUX_Disable();
65
}
66
 
67
unsigned long LUX_Calculate_Lux(unsigned int ch0, unsigned int ch1) {
68
    unsigned long chScale, channel0, channel1, ratio1, ratio, temp, lux;
69
    unsigned int b, m;
70
 
71
    switch (tsl2561_data_p->integration) {
72
        case TSL2561_INTEGRATIONTIME_13MS:
73
            chScale = TSL2561_LUX_CHSCALE_TINT0;
74
            break;
75
        case TSL2561_INTEGRATIONTIME_101MS:
76
            chScale = TSL2561_LUX_CHSCALE_TINT1;
77
            break;
78
        default: // No scaling ... integration time = 402ms
79
            chScale = (1 << TSL2561_LUX_CHSCALE);
80
            break;
81
    }
82
 
83
    // Scale for gain (1x or 16x)
84
    if (!tsl2561_data_p->gain)
85
        chScale = chScale << 4;
86
 
87
    // scale the channel values
88
    channel0 = (ch0 * chScale) >> TSL2561_LUX_CHSCALE;
89
    channel1 = (ch1 * chScale) >> TSL2561_LUX_CHSCALE;
90
 
91
    // find the ratio of the channel values (Channel1/Channel0)
92
    ratio1 = 0;
93
    if (channel0 != 0)
94
        ratio1 = (channel1 << (TSL2561_LUX_RATIOSCALE+1)) / channel0;
95
 
96
    // round the ratio value
97
    ratio = (ratio1 + 1) >> 1;
98
 
99
#ifdef TSL2561_PACKAGE_CS
100
    if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1C)) {
101
        b = TSL2561_LUX_B1C; m = TSL2561_LUX_M1C;
102
    } else if (ratio <= TSL2561_LUX_K2C) {
103
        b = TSL2561_LUX_B2C; m = TSL2561_LUX_M2C;
104
    } else if (ratio <= TSL2561_LUX_K3C) {
105
        b = TSL2561_LUX_B3C; m = TSL2561_LUX_M3C;
106
    } else if (ratio <= TSL2561_LUX_K4C) {
107
        b = TSL2561_LUX_B4C; m = TSL2561_LUX_M4C;
108
    } else if (ratio <= TSL2561_LUX_K5C) {
109
        b = TSL2561_LUX_B5C; m = TSL2561_LUX_M5C;
110
    } else if (ratio <= TSL2561_LUX_K6C) {
111
        b = TSL2561_LUX_B6C; m = TSL2561_LUX_M6C;
112
    } else if (ratio <= TSL2561_LUX_K7C) {
113
        b = TSL2561_LUX_B7C; m = TSL2561_LUX_M7C;
114
    } else if (ratio > TSL2561_LUX_K8C) {
115
        b = TSL2561_LUX_B8C; m = TSL2561_LUX_M8C;
116
    }
117
#else
118
//    if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1T)) {
119
    if ((ratio <= TSL2561_LUX_K1T)) {
120
        b = TSL2561_LUX_B1T; m = TSL2561_LUX_M1T;
121
    } else if (ratio <= TSL2561_LUX_K2T) {
122
        b = TSL2561_LUX_B2T; m = TSL2561_LUX_M2T;
123
    } else if (ratio <= TSL2561_LUX_K3T) {
124
        b = TSL2561_LUX_B3T; m = TSL2561_LUX_M3T;
125
    } else if (ratio <= TSL2561_LUX_K4T) {
126
        b = TSL2561_LUX_B4T; m = TSL2561_LUX_M4T;
127
    } else if (ratio <= TSL2561_LUX_K5T) {
128
        b = TSL2561_LUX_B5T; m = TSL2561_LUX_M5T;
129
    } else if (ratio <= TSL2561_LUX_K6T) {
130
        b = TSL2561_LUX_B6T; m = TSL2561_LUX_M6T;
131
    } else if (ratio <= TSL2561_LUX_K7T) {
132
        b = TSL2561_LUX_B7T; m = TSL2561_LUX_M7T;
133
    } else if (ratio > TSL2561_LUX_K8T) {
134
        b = TSL2561_LUX_B8T; m = TSL2561_LUX_M8T;
135
    }
136
#endif
137
 
138
//    temp = ((channel0 * b) - (channel1 * m));
157 Kevin 139
    // TODO: Change this back once they fix compiler
155 Kevin 140
    temp = (channel0 * b);
141
    temp -= (channel1 * m);
142
 
143
//    // do not allow negative lux value
144
//    if (temp < 0)
145
//        temp = 0;
146
 
147
    // round lsb (2^(LUX_SCALE-1))
148
    temp += (1 << (TSL2561_LUX_LUXSCALE-1));
149
 
150
    // strip off fractional portion
151
    lux = temp >> TSL2561_LUX_LUXSCALE;
152
 
153
    return lux;
154
}
155
 
156
unsigned long LUX_Get_Full_Luminosity() {
157
    unsigned long x;
158
 
159
    // Enable the device by setting the control bit to 0x03
160
    LUX_Enable();
161
 
162
    // Wait x ms for ADC to complete
163
    switch (tsl2561_data_p->integration) {
164
        case TSL2561_INTEGRATIONTIME_13MS:
165
            Delay10KTCYx(67);
166
            break;
167
        case TSL2561_INTEGRATIONTIME_101MS:
168
            Delay10KTCYx(255);
169
            Delay10KTCYx(230);
170
            break;
171
        default:
172
            Delay10KTCYx(255);
173
            Delay10KTCYx(255);
174
            Delay10KTCYx(255);
175
            Delay10KTCYx(255);
176
            Delay10KTCYx(255);
177
            Delay10KTCYx(255);
178
            Delay10KTCYx(255);
179
            Delay10KTCYx(145);
180
            break;
181
    }
182
 
183
    x = LUX_Read_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW);
184
    x <<= 16;
185
    x |= LUX_Read_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW);
186
 
187
    LUX_Disable();
188
 
189
    return x;
190
}
191
 
192
unsigned int LUX_Get_Luminosity(char channel) {
193
    unsigned long x = LUX_Get_Full_Luminosity();
194
 
195
    if (channel == 0) {
196
        // Reads two byte value from channel 0 (visible + infrared)
197
        return (x & 0xFFFF);
198
    } else if (channel == 1) {
199
        // Reads two byte value from channel 1 (infrared)
200
        return (x >> 16);
201
    } else if (channel == 2) {
202
        // Reads all and subtracts out just the visible!
203
        return ( (x & 0xFFFF) - (x >> 16));
204
    }
205
 
206
    // Unknown channel!
207
    return 0;
208
}
209
 
210
void LUX_Write_2_Bytes(char reg, char value) {
211
    char buffer[2], result;
212
    buffer[0] = reg;
213
    buffer[1] = value;
214
    I2C_Master_Send(tsl2561_data_p->address, 2, buffer);
215
    do {
216
        result = I2C_Get_Status();
217
    } while (!result);
218
}
219
 
220
unsigned int LUX_Read_2_Bytes(char reg) {
221
    char result, length, buffer[2];
222
    unsigned int ret;
223
 
224
    I2C_Master_Restart(tsl2561_data_p->address, reg, 2);
225
    do {
226
        result = I2C_Get_Status();
227
    } while (!result);
228
    length = I2C_Read_Buffer(buffer);
229
    ret = buffer[1] << 8;
230
    ret |= buffer[0];
231
 
232
    return ret;
233
}