Many changes from 2018
[owSlave2.git] / common / I2C / TSL256x.c
1 #define F_CPU 8000000UL\r
2 #include <avr/io.h>\r
3 #include <avr/interrupt.h>\r
4 #include <util/delay.h>\r
5 #include <avr/wdt.h>\r
6 #include <avr/sleep.h>\r
7 #include "TWI_Master.h"\r
8 \r
9 void TSL256x_init() {\r
10         I2c_StartCondition();\r
11         I2c_WriteByte(0b01010010);  // 0x0101001 1001001 0111001\r
12         I2c_WriteByte(0x80);\r
13         I2c_WriteByte(0x03);\r
14         I2c_StopCondition();\r
15         I2c_StartCondition();\r
16         I2c_WriteByte(0b01010010);  // 0x0101001 1001001 0111001\r
17         I2c_WriteByte(0x81);\r
18         I2c_WriteByte(0x12);\r
19         I2c_StopCondition();\r
20         _delay_ms(500);\r
21 }\r
22 \r
23 void TSL256x_setup(uint8_t conf) {\r
24         I2c_StartCondition();\r
25         I2c_WriteByte(0b01010010);  // 0x0101001 1001001 0111001\r
26         I2c_WriteByte(0x81);\r
27         I2c_WriteByte(conf);\r
28         I2c_StopCondition();\r
29 }\r
30 \r
31 uint16_t TSL256x_Ch(uint8_t ch){\r
32         uint16_t res;\r
33         I2c_StartCondition();\r
34         I2c_WriteByte(0b01010010);  // 0x0101001 1001001 0111001\r
35         //I2c_WriteByte(0xAD);\r
36         I2c_WriteByte(0xAC+(ch<<1));\r
37         I2c_StopCondition();\r
38         I2c_StartCondition();\r
39         I2c_WriteByte(0b01010011); \r
40         res=I2c_ReadByte(ACK);\r
41         res|=((uint16_t)I2c_ReadByte(NO_ACK))<<8;\r
42         I2c_StopCondition();\r
43         return res;\r
44 }\r
45 \r
46 #define LUX_SCALE 14 // scale by 2^14\r
47 #define RATIO_SCALE 9 // scale ratio by 2^9\r
48 //???????????????????????????????????????????????????\r
49 // Integration time scaling factors\r
50 //???????????????????????????????????????????????????\r
51 #define CH_SCALE 10 // scale channel values by 2^10\r
52 #define CHSCALE_TINT0 0x7517 // 322/11 * 2^CH_SCALE\r
53 #define CHSCALE_TINT1 0x0fe7 // 322/81 * 2^CH_SCALE\r
54 \r
55 #define K1T 0x0040 // 0.125 * 2^RATIO_SCALE\r
56 #define B1T 0x01f2 // 0.0304 * 2^LUX_SCALE\r
57 #define M1T 0x01be // 0.0272 * 2^LUX_SCALE\r
58 #define K2T 0x0080 // 0.250 * 2^RATIO_SCALE\r
59 #define B2T 0x0214 // 0.0325 * 2^LUX_SCALE\r
60 #define M2T 0x02d1 // 0.0440 * 2^LUX_SCALE\r
61 #define K3T 0x00c0 // 0.375 * 2^RATIO_SCALE\r
62 #define B3T 0x023f // 0.0351 * 2^LUX_SCALE\r
63 #define M3T 0x037b // 0.0544 * 2^LUX_SCALE\r
64 #define K4T 0x0100 // 0.50 * 2^RATIO_SCALE\r
65 #define B4T 0x0270 // 0.0381 * 2^LUX_SCALE\r
66 #define M4T 0x03fe // 0.0624 * 2^LUX_SCALE\r
67 #define K5T 0x0138 // 0.61 * 2^RATIO_SCALE\r
68 #define B5T 0x016f // 0.0224 * 2^LUX_SCALE\r
69 #define M5T 0x01fc // 0.0310 * 2^LUX_SCALE\r
70 #define K6T 0x019a // 0.80 * 2^RATIO_SCALE\r
71 #define B6T 0x00d2 // 0.0128 * 2^LUX_SCALE\r
72 #define M6T 0x00fb // 0.0153 * 2^LUX_SCALE\r
73 #define K7T 0x029a // 1.3 * 2^RATIO_SCALE\r
74 #define B7T 0x0018 // 0.00146 * 2^LUX_SCALE\r
75 #define M7T 0x0012 // 0.00112 * 2^LUX_SCALE\r
76 #define K8T 0x029a // 1.3 * 2^RATIO_SCALE\r
77 #define B8T 0x0000 // 0.000 * 2^LUX_SCALE\r
78 #define M8T 0x0000 // 0.000 * 2^LUX_SCALE\r
79 \r
80 uint32_t CalculateLux(uint8_t iGain, uint8_t tInt, uint16_t ch0, uint16_t ch1)\r
81 {\r
82         //????????????????????????????????????????????????????????????????????????\r
83         // first, scale the channel values depending on the gain and integration time\r
84         // 16X, 402mS is nominal.\r
85         // scale if integration time is NOT 402 msec\r
86         uint32_t chScale;\r
87         uint32_t channel1;\r
88         uint32_t channel0;\r
89         switch (tInt)\r
90         {\r
91                 case 0: // 13.7 msec\r
92                 chScale = CHSCALE_TINT0;\r
93                 break;\r
94                 case 1: // 101 msec\r
95                 chScale = CHSCALE_TINT1;\r
96                 break;\r
97                 default: // assume no scaling\r
98                 chScale = (1 << CH_SCALE);\r
99                 break;\r
100         }\r
101         // scale if gain is NOT 16X\r
102         if (!iGain) chScale = chScale << 4; // scale 1X to 16X\r
103         // scale the channel values\r
104         channel0 = (ch0 * chScale) >> CH_SCALE;\r
105         channel1 = (ch1 * chScale) >> CH_SCALE;\r
106         //????????????????????????????????????????????????????????????????????????\r
107         // find the ratio of the channel values (Channel1/Channel0)\r
108         // protect against divide by zero\r
109         uint32_t ratio1 = 0;\r
110         if (channel0 != 0) ratio1 = (channel1 << (RATIO_SCALE+1)) / channel0;\r
111         // round the ratio value\r
112         uint32_t ratio = (ratio1 + 1) >> 1;\r
113         // is ratio <= eachBreak ?\r
114         uint16_t b, m;\r
115                 if ((ratio >= 0) && (ratio <= K1T))\r
116                 {b=B1T; m=M1T;}\r
117                 else if (ratio <= K2T)\r
118                 {b=B2T; m=M2T;}\r
119                 else if (ratio <= K3T)\r
120                 {b=B3T; m=M3T;}\r
121                 else if (ratio <= K4T)\r
122                 {b=B4T; m=M4T;}\r
123                 else if (ratio <= K5T)\r
124                 {b=B5T; m=M5T;}\r
125                 else if (ratio <= K6T)\r
126                 {b=B6T; m=M6T;}\r
127                 else if (ratio <= K7T)\r
128                 {b=B7T; m=M7T;}\r
129                 else if (ratio > K8T)\r
130                 {b=B8T; m=M8T;}\r
131         uint32_t temp;\r
132         temp = ((channel0 * b) - (channel1 * m));\r
133         // do not allow negative lux value\r
134         if (temp < 0) temp = 0;\r
135         // round lsb (2^(LUX_SCALE?1))\r
136         temp += (1 << (LUX_SCALE-1));\r
137         // strip off fractional portion\r
138         uint32_t lux = temp ;//>> LUX_SCALE;\r
139         return(lux);\r
140 }\r
141 \r
142 \r
143 \r
144 \r
145         \r
146 \r