Subversion Repositories Code-Repo

Rev

Rev 147 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 147 Rev 148
Line 1... Line 1...
1
#include "lux_TSL2561.h"
1
#include "lux_TSL2561.h"
-
 
2
#include "defines.h"
2
#include "i2c.h"
3
#include "i2c.h"
-
 
4
#include <delays.h>
3
 
5
 
4
static TSL2561_DATA tsl2561_data;
6
static TSL2561_DATA tsl2561_data;
5
static TSL2561_DATA *tsl2561_data_p = &tsl2561_data;
7
static TSL2561_DATA *tsl2561_data_p = &tsl2561_data;
6
 
8
 
7
void LUX_Init(unsigned char address) {
9
void LUX_Init(unsigned char address) {
Line 9... Line 11...
9
    tsl2561_data_p->integration = TSL2561_INTEGRATIONTIME_13MS;
11
    tsl2561_data_p->integration = TSL2561_INTEGRATIONTIME_13MS;
10
    tsl2561_data_p->gain = TSL2561_GAIN_16X;
12
    tsl2561_data_p->gain = TSL2561_GAIN_16X;
11
}
13
}
12
 
14
 
13
void LUX_Begin(void) {
15
void LUX_Begin(void) {
-
 
16
    unsigned char i, result, length, buffer[10];
-
 
17
    unsigned 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
    length = I2C_Read_Buffer((char *)buffer);
-
 
29
    DBG_PRINT_LUX("Received %d bytes: ", length);
-
 
30
    for (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_SetTiming(tsl2561_data_p->integration);
-
 
37
    LUX_SetGain(tsl2561_data_p->gain);
-
 
38
 
-
 
39
    // Start the chip in power-down mode
-
 
40
    LUX_Disable();
-
 
41
}
-
 
42
 
-
 
43
void LUX_Enable()  {
-
 
44
    LUX_Write2Bytes(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWERON);
-
 
45
}
-
 
46
 
-
 
47
void LUX_Disable() {
-
 
48
    LUX_Write2Bytes(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWEROFF);
-
 
49
}
-
 
50
 
-
 
51
void LUX_SetGain(tsl2561Gain_t gain) {
-
 
52
    LUX_Enable();
-
 
53
    tsl2561_data_p->gain = gain;
-
 
54
    LUX_Write2Bytes(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING,
-
 
55
            tsl2561_data_p->integration | tsl2561_data_p->gain);
-
 
56
    LUX_Disable();
-
 
57
}
-
 
58
 
-
 
59
void LUX_SetTiming(tsl2561IntegrationTime_t integration) {
-
 
60
    LUX_Enable();
-
 
61
    tsl2561_data_p->integration = integration;
-
 
62
    LUX_Write2Bytes(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING,
-
 
63
            tsl2561_data_p->integration | tsl2561_data_p->gain);
-
 
64
    LUX_Disable();
-
 
65
}
-
 
66
 
-
 
67
unsigned long LUX_CalculateLux(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
        b = TSL2561_LUX_B1T; m = TSL2561_LUX_M1T;
-
 
120
    } else if (ratio <= TSL2561_LUX_K2T) {
-
 
121
        b = TSL2561_LUX_B2T; m = TSL2561_LUX_M2T;
-
 
122
    } else if (ratio <= TSL2561_LUX_K3T) {
-
 
123
        b = TSL2561_LUX_B3T; m = TSL2561_LUX_M3T;
-
 
124
    } else if (ratio <= TSL2561_LUX_K4T) {
-
 
125
        b = TSL2561_LUX_B4T; m = TSL2561_LUX_M4T;
-
 
126
    } else if (ratio <= TSL2561_LUX_K5T) {
-
 
127
        b = TSL2561_LUX_B5T; m = TSL2561_LUX_M5T;
-
 
128
    } else if (ratio <= TSL2561_LUX_K6T) {
-
 
129
        b = TSL2561_LUX_B6T; m = TSL2561_LUX_M6T;
-
 
130
    } else if (ratio <= TSL2561_LUX_K7T) {
-
 
131
        b = TSL2561_LUX_B7T; m = TSL2561_LUX_M7T;
-
 
132
    } else if (ratio > TSL2561_LUX_K8T) {
-
 
133
        b = TSL2561_LUX_B8T; m = TSL2561_LUX_M8T;
-
 
134
    }
-
 
135
#endif
14
    
136
    
-
 
137
    temp = ((channel0 * b) - (channel1 * m));
-
 
138
 
-
 
139
    // do not allow negative lux value
-
 
140
    if (temp < 0)
-
 
141
        temp = 0;
-
 
142
 
-
 
143
    // round lsb (2^(LUX_SCALE-1))
-
 
144
    temp += (1 << (TSL2561_LUX_LUXSCALE-1));
-
 
145
 
-
 
146
    // strip off fractional portion
-
 
147
    lux = temp >> TSL2561_LUX_LUXSCALE;
-
 
148
 
-
 
149
    return lux;
-
 
150
}
-
 
151
 
-
 
152
unsigned long LUX_GetFullLuminosity() {
-
 
153
    unsigned long x;
-
 
154
 
-
 
155
    // Enable the device by setting the control bit to 0x03
-
 
156
    LUX_Enable();
-
 
157
 
-
 
158
    // Wait x ms for ADC to complete
-
 
159
    switch (tsl2561_data_p->integration) {
-
 
160
        case TSL2561_INTEGRATIONTIME_13MS:
-
 
161
            Delay10KTCYx(67);
-
 
162
            break;
-
 
163
        case TSL2561_INTEGRATIONTIME_101MS:
-
 
164
            Delay10KTCYx(255);
-
 
165
            Delay10KTCYx(230);
-
 
166
            break;
-
 
167
        default:
-
 
168
            Delay10KTCYx(255);
-
 
169
            Delay10KTCYx(255);
-
 
170
            Delay10KTCYx(255);
-
 
171
            Delay10KTCYx(255);
-
 
172
            Delay10KTCYx(255);
-
 
173
            Delay10KTCYx(255);
-
 
174
            Delay10KTCYx(255);
-
 
175
            Delay10KTCYx(145);
-
 
176
            break;
-
 
177
    }
-
 
178
 
-
 
179
    x = LUX_Read2Bytes(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW);
-
 
180
    x <<= 16;
-
 
181
    x |= LUX_Read2Bytes(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW);
-
 
182
 
-
 
183
    LUX_Disable();
-
 
184
 
-
 
185
    return x;
-
 
186
}
-
 
187
 
-
 
188
unsigned int LUX_GetLuminosity(unsigned char channel) {
-
 
189
    unsigned long x = LUX_GetFullLuminosity();
-
 
190
 
-
 
191
    if (channel == 0) {
-
 
192
        // Reads two byte value from channel 0 (visible + infrared)
-
 
193
        return (x & 0xFFFF);
-
 
194
    } else if (channel == 1) {
-
 
195
        // Reads two byte value from channel 1 (infrared)
-
 
196
        return (x >> 16);
-
 
197
    } else if (channel == 2) {
-
 
198
        // Reads all and subtracts out just the visible!
-
 
199
        return ( (x & 0xFFFF) - (x >> 16));
-
 
200
    }
-
 
201
 
-
 
202
    // Unknown channel!
-
 
203
    return 0;
-
 
204
}
-
 
205
 
-
 
206
void LUX_Write2Bytes(unsigned char reg, unsigned char value) {
-
 
207
    unsigned char buffer[2], result;
-
 
208
    buffer[0] = reg;
-
 
209
    buffer[1] = value;
-
 
210
    I2C_Master_Send(tsl2561_data_p->address, 2, buffer);
-
 
211
    do {
-
 
212
        result = I2C_Get_Status();
-
 
213
    } while (!result);
-
 
214
}
-
 
215
 
-
 
216
unsigned int LUX_Read2Bytes(unsigned char reg) {
-
 
217
    unsigned char result, length, buffer[2];
-
 
218
    unsigned int ret;
-
 
219
 
-
 
220
    I2C_Master_Restart(tsl2561_data_p->address, reg, 2);
-
 
221
    do {
-
 
222
        result = I2C_Get_Status();
-
 
223
    } while (!result);
-
 
224
    length = I2C_Read_Buffer((char *)buffer);
-
 
225
    ret = buffer[1] << 8;
-
 
226
    ret |= buffer[0];
-
 
227
 
-
 
228
    return ret;
15
}
229
}
16
230