Subversion Repositories Code-Repo

Rev

Rev 282 | Details | Compare with Previous | Last modification | View Log | RSS feed

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