Contiki-NG
tsl256x.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015, Zolertia - http://www.zolertia.com
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30/*---------------------------------------------------------------------------*/
31/**
32 * \addtogroup zoul-tsl256x-sensor
33 * @{
34 *
35 * \file
36 * Driver for the external TSL256X light sensor
37 *
38 * \author
39 * Antonio Lignan <alinan@zolertia.com>
40 * Toni Lozano <tlozano@zolertia.com>
41 */
42/*---------------------------------------------------------------------------*/
43#include "contiki.h"
44#include "dev/i2c.h"
45#include "dev/gpio.h"
46#include "dev/gpio-hal.h"
47#include "dev/zoul-sensors.h"
48#include "lib/sensors.h"
49#include "tsl256x.h"
50/*---------------------------------------------------------------------------*/
51#define DEBUG 0
52#if DEBUG
53#define PRINTF(...) printf(__VA_ARGS__)
54#else
55#define PRINTF(...)
56#endif
57/*---------------------------------------------------------------------------*/
58#define TSL256X_INT_PORT_BASE GPIO_PORT_TO_BASE(I2C_INT_PORT)
59#define TSL256X_INT_PIN_MASK GPIO_PIN_MASK(I2C_INT_PIN)
60/*---------------------------------------------------------------------------*/
61static uint8_t enabled;
62static uint8_t gain;
63static uint8_t timming;
64/*---------------------------------------------------------------------------*/
65void (*tsl256x_int_callback)(uint8_t value);
66/*---------------------------------------------------------------------------*/
67static uint16_t
68calculate_lux(uint8_t *buf)
69{
70 uint32_t ch0, ch1, chscale = 0;
71 uint32_t ratio = 0;
72 uint32_t lratio, tmp = 0;
73 uint16_t buffer[2];
74
75 /* The calculations below assume the integration time is 402ms and the gain
76 * is 16x (nominal), if not then it is required to normalize the reading
77 * before converting to lux
78 */
79
80 buffer[0] = (buf[1] << 8 | (buf[0]));
81 buffer[1] = (buf[3] << 8 | (buf[2]));
82
83 switch(timming) {
84 case TSL256X_TIMMING_INTEG_402MS:
85 chscale = (1 << CH_SCALE);
86 break;
87 case TSL256X_TIMMING_INTEG_101MS:
88 chscale = CHSCALE_TINT1;
89 break;
90 case TSL256X_TIMMING_INTEG_13_7MS:
91 chscale = CHSCALE_TINT0;
92 break;
93 }
94
95 if(!gain) {
96 chscale = chscale << 4;
97 }
98
99 ch0 = (buffer[0] * chscale) >> CH_SCALE;
100 ch1 = (buffer[1] * chscale) >> CH_SCALE;
101
102 if(ch0 > 0) {
103 ratio = (ch1 << CH_SCALE);
104 ratio = ratio / ch0;
105 }
106
107 lratio = (ratio + 1) >> 1;
108
109 if((lratio >= 0) && (lratio <= K1T)) {
110 tmp = (ch0 * B1T) - (ch1 * M1T);
111 } else if(lratio <= K2T) {
112 tmp = (ch0 * B2T) - (ch1 * M2T);
113 } else if(lratio <= K3T) {
114 tmp = (ch0 * B3T) - (ch1 * M3T);
115 } else if(lratio <= K4T) {
116 tmp = (ch0 * B4T) - (ch1 * M4T);
117 } else if(lratio <= K5T) {
118 tmp = (ch0 * B5T) - (ch1 * M5T);
119 } else if(lratio <= K6T) {
120 tmp = (ch0 * B6T) - (ch1 * M6T);
121 } else if(lratio <= K7T) {
122 tmp = (ch0 * B7T) - (ch1 * M7T);
123 } else if(lratio > K8T) {
124 tmp = (ch0 * B8T) - (ch1 * M8T);
125 }
126
127 if(tmp < 0) {
128 tmp = 0;
129 }
130
131 tmp += (1 << (LUX_SCALE - 1));
132 return tmp >> LUX_SCALE;
133}
134/*---------------------------------------------------------------------------*/
135static int
136tsl256x_read_reg(uint8_t reg, uint8_t *buf, uint8_t regNum)
137{
139 if(i2c_single_send(TSL256X_ADDR, reg) == I2C_MASTER_ERR_NONE) {
140 while(i2c_master_busy());
141 if(i2c_burst_receive(TSL256X_ADDR, buf, regNum) == I2C_MASTER_ERR_NONE) {
142 return TSL256X_SUCCESS;
143 }
144 }
145 return TSL256X_ERROR;
146}
147/*---------------------------------------------------------------------------*/
148static int
149tsl256x_write_reg(uint8_t *buf, uint8_t num)
150{
151 if((buf == NULL) || (num <= 0)) {
152 PRINTF("TSL256X: invalid write values\n");
153 return TSL256X_ERROR;
154 }
155
157 if(i2c_burst_send(TSL256X_ADDR, buf, num) == I2C_MASTER_ERR_NONE) {
158 return TSL256X_SUCCESS;
159 }
160 return TSL256X_ERROR;
161}
162/*---------------------------------------------------------------------------*/
163static int
164tsl256x_on(void)
165{
166 uint8_t buf[2];
167 buf[0] = (TSL256X_COMMAND + TSL256X_CONTROL);
168 buf[1] = TSL256X_CONTROL_POWER_ON;
169
170 if(tsl256x_write_reg(buf, 2) == I2C_MASTER_ERR_NONE) {
171 if(i2c_single_receive(TSL256X_ADDR, &buf[0]) == I2C_MASTER_ERR_NONE) {
172 if((buf[0] & 0x0F) == TSL256X_CONTROL_POWER_ON) {
173 PRINTF("TSL256X: powered on\n");
174 return TSL256X_SUCCESS;
175 }
176 }
177 }
178
179 PRINTF("TSL256X: failed to power on\n");
180 return TSL256X_ERROR;
181}
182/*---------------------------------------------------------------------------*/
183static int
184tsl256x_id_register(uint8_t *buf)
185{
186 if(tsl256x_read_reg((TSL256X_COMMAND + TSL256X_ID_REG),
187 buf, 1) == TSL256X_SUCCESS) {
188 PRINTF("TSL256X: partnum/revnum 0x%02X\n", *buf);
189 return TSL256X_SUCCESS;
190 }
191
192 return TSL256X_ERROR;
193}
194/*---------------------------------------------------------------------------*/
195static int
196tsl256x_off(void)
197{
198 uint8_t buf[2];
199 buf[0] = (TSL256X_COMMAND + TSL256X_CONTROL);
200 buf[1] = TSL256X_CONTROL_POWER_OFF;
201
202 if(tsl256x_write_reg(buf, 2) == I2C_MASTER_ERR_NONE) {
203 PRINTF("TSL256X: powered off\n");
204 return TSL256X_SUCCESS;
205 }
206
207 PRINTF("TSL256X: failed to power off\n");
208 return TSL256X_ERROR;
209}
210/*---------------------------------------------------------------------------*/
211static int
212tsl256x_clear_interrupt(void)
213{
214 uint8_t buf = (TSL256X_COMMAND + TSL256X_CLEAR_INTERRUPT);
215 if(tsl256x_write_reg(&buf, 1) != I2C_MASTER_ERR_NONE) {
216 PRINTF("TSL256X: failed to clear the interrupt\n");
217 return TSL256X_ERROR;
218 }
219 return TSL256X_SUCCESS;
220}
221/*---------------------------------------------------------------------------*/
222static int
223tsl256x_read_sensor(uint16_t *lux)
224{
225 uint8_t buf[4];
226
227 /* This is hardcoded to use word write/read operations */
228 if(tsl256x_read_reg((TSL256X_COMMAND + TSL256X_D0LOW),
229 &buf[0], 2) == TSL256X_SUCCESS) {
230 if(tsl256x_read_reg((TSL256X_COMMAND + TSL256X_D1LOW),
231 &buf[2], 2) == TSL256X_SUCCESS) {
232
233 PRINTF("TSL256X: CH0 0x%02X%02X CH1 0x%02X%02X\n", buf[1], buf[0],
234 buf[3], buf[2]);
235 *lux = calculate_lux(buf);
236 return TSL256X_SUCCESS;
237 }
238 }
239 PRINTF("TSL256X: failed to read\n");
240 return TSL256X_ERROR;
241}
242/*---------------------------------------------------------------------------*/
243PROCESS(tsl256x_int_process, "TSL256X interrupt process handler");
244/*---------------------------------------------------------------------------*/
245PROCESS_THREAD(tsl256x_int_process, ev, data)
246{
249
250 while(1) {
251 PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
252 tsl256x_clear_interrupt();
253 tsl256x_int_callback(0);
254 }
255 PROCESS_END();
256}
257/*---------------------------------------------------------------------------*/
258static void
259tsl256x_interrupt_handler(gpio_hal_pin_mask_t pin_mask)
260{
261 /* There's no alert/interruption flag to check, clear the interruption by
262 * writting to the CLEAR bit in the COMMAND register
263 */
264 process_poll(&tsl256x_int_process);
265}
266/*---------------------------------------------------------------------------*/
267static gpio_hal_event_handler_t tsl256x_handler = {
268 .next = NULL,
269 .handler = tsl256x_interrupt_handler,
270 .pin_mask = gpio_hal_pin_to_mask(I2C_INT_PIN) << (I2C_INT_PORT << 3),
271};
272/*---------------------------------------------------------------------------*/
273static int
274configure(int type, int value)
275{
276 uint8_t buf[3];
277
278 if((type != TSL256X_ACTIVE) && (type != TSL256X_INT_OVER) &&
279 (type != TSL256X_INT_BELOW) && (type != TSL256X_INT_DISABLE) &&
280 (type != TSL256X_TIMMING_CFG)) {
281 PRINTF("TSL256X: invalid start value\n");
282 return TSL256X_ERROR;
283 }
284
285 /* As default the power-on values of the sensor are gain 1X, 402ms integration
286 * time (not nominal), with manual control disabled
287 */
288
289 if(type == TSL256X_ACTIVE) {
290 if(value) {
291 i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN,
292 I2C_SCL_NORMAL_BUS_SPEED);
293
294 /* Initialize interrupts handlers */
295 tsl256x_int_callback = NULL;
296
297 /* Power on the sensor and check for the part number */
298 if(tsl256x_on() == TSL256X_SUCCESS) {
299 if(tsl256x_id_register(&buf[0]) == TSL256X_SUCCESS) {
300 if((buf[0] & TSL256X_ID_PARTNO_MASK) == TSL256X_EXPECTED_PARTNO) {
301
302 /* Read the timming/gain configuration */
303 if(tsl256x_read_reg((TSL256X_COMMAND + TSL256X_TIMMING),
304 &buf[0], 1) == TSL256X_SUCCESS) {
305 gain = buf[0] & TSL256X_TIMMING_GAIN;
306 timming = buf[0] & TSL256X_TIMMING_INTEG_MASK;
307 PRINTF("TSL256X: enabled, timming %u gain %u\n", timming, gain);
308
309 /* Restart the over interrupt threshold */
310 buf[0] = (TSL256X_COMMAND + TSL256X_THRHIGHLOW);
311 buf[1] = 0xFF;
312 buf[2] = 0xFF;
313
314 if(tsl256x_write_reg(buf, 3) != TSL256X_SUCCESS) {
315 PRINTF("TSL256X: failed to clear over interrupt\n");
316 return TSL256X_ERROR;
317 }
318
319 /* Restart the below interrupt threshold */
320 buf[0] = (TSL256X_COMMAND + TSL256X_THRLOWLOW);
321 buf[1] = 0x00;
322 buf[2] = 0x00;
323
324 if(tsl256x_write_reg(buf, 3) != TSL256X_SUCCESS) {
325 PRINTF("TSL256X: failed to clear below interrupt\n");
326 return TSL256X_ERROR;
327 }
328
329 /* Clear any pending interrupt */
330 if(tsl256x_clear_interrupt() == TSL256X_SUCCESS) {
331 enabled = 1;
332 return TSL256X_SUCCESS;
333 }
334 }
335 }
336 }
337 }
338 return TSL256X_ERROR;
339 } else {
340 if(tsl256x_off() == TSL256X_SUCCESS) {
341 PRINTF("TSL256X: stopped\n");
342 enabled = 0;
343 return TSL256X_SUCCESS;
344 }
345 return TSL256X_ERROR;
346 }
347 }
348
349 if(!enabled) {
350 PRINTF("TSL256X: sensor not started\n");
351 return TSL256X_ERROR;
352 }
353
354 if(type == TSL256X_INT_DISABLE) {
355
356 /* Ensure the GPIO doesn't generate more interrupts, this may affect others
357 * I2C digital sensors using the bus and sharing this pin, so an user may
358 * comment the line below
359 */
360 GPIO_DISABLE_INTERRUPT(TSL256X_INT_PORT_BASE, TSL256X_INT_PIN_MASK);
361
362 /* This also wipes out the persistance value, to be reconfigured when
363 * enabling back the interruption
364 */
365 buf[0] = (TSL256X_COMMAND + TSL256X_INTERRUPT);
366 buf[1] = TSL256X_INTR_DISABLED;
367
368 if(tsl256x_write_reg(buf, 2) != TSL256X_SUCCESS) {
369 PRINTF("TSL256X: failed to disable the interrupt\n");
370 return TSL256X_ERROR;
371 }
372 return TSL256X_SUCCESS;
373 }
374
375 /* Configure the timming and gain */
376 if(type == TSL256X_TIMMING_CFG) {
377 if((value != TSL256X_G16X_402MS) && (value != TSL256X_G1X_402MS) &&
378 (value != TSL256X_G1X_101MS) && (value != TSL256X_G1X_13_7MS)) {
379 PRINTF("TSL256X: invalid timming configuration values\n");
380 return TSL256X_ERROR;
381 }
382
383 buf[0] = (TSL256X_COMMAND + TSL256X_TIMMING);
384 buf[1] = value;
385
386 if(tsl256x_write_reg(buf, 2) == TSL256X_SUCCESS) {
387 if(value == TSL256X_G16X_402MS) {
388 gain = 1;
389 }
390
391 switch(value) {
392 case TSL256X_G16X_402MS:
393 case TSL256X_G1X_402MS:
394 timming = TSL256X_TIMMING_INTEG_402MS;
395 break;
396 case TSL256X_G1X_101MS:
397 timming = TSL256X_TIMMING_INTEG_101MS;
398 break;
399 case TSL256X_G1X_13_7MS:
400 timming = TSL256X_TIMMING_INTEG_13_7MS;
401 break;
402 }
403
404 PRINTF("TSL256X: new timming %u gain %u\n", timming, gain);
405 return TSL256X_SUCCESS;
406 }
407 PRINTF("TSL256X: failed to configure timming\n");
408 return TSL256X_ERROR;
409 }
410
411 /* From here we handle the interrupt configuration, it requires the interrupt
412 * callback handler to have been previously set using the TSL256X_REGISTER_INT
413 * macro
414 */
415
416 buf[1] = ((uint8_t *)&value)[0];
417 buf[2] = ((uint8_t *)&value)[1];
418
419 if(type == TSL256X_INT_OVER) {
420 buf[0] = (TSL256X_COMMAND + TSL256X_THRHIGHLOW);
421 } else if(type == TSL256X_INT_BELOW) {
422 buf[0] = (TSL256X_COMMAND + TSL256X_THRLOWLOW);
423 }
424
425 if(tsl256x_write_reg(buf, 3) != TSL256X_SUCCESS) {
426 PRINTF("TSL256X: failed to set interrupt level\n");
427 return TSL256X_ERROR;
428 }
429
430 /* Now configure the interruption register (level interrupt, 2 integration
431 * cycles after threshold has been reached (roughly 804ms if timming is 402ms)
432 */
433 buf[0] = (TSL256X_COMMAND + TSL256X_INTERRUPT);
434 buf[1] = (TSL256X_INTR_LEVEL << TSL256X_INTR_SHIFT);
435 buf[1] += TSL256X_INT_PERSIST_2_CYCLES;
436
437 if(tsl256x_write_reg(buf, 2) != TSL256X_SUCCESS) {
438 PRINTF("TSL256X: failed to enable interrupt\n");
439 return TSL256X_ERROR;
440 }
441
442 /* Configure the interrupts pins */
443 GPIO_SOFTWARE_CONTROL(TSL256X_INT_PORT_BASE, TSL256X_INT_PIN_MASK);
444 GPIO_SET_INPUT(TSL256X_INT_PORT_BASE, TSL256X_INT_PIN_MASK);
445
446 /* Pull-up resistor, detect falling edge */
447 GPIO_DETECT_EDGE(TSL256X_INT_PORT_BASE, TSL256X_INT_PIN_MASK);
448 GPIO_TRIGGER_SINGLE_EDGE(TSL256X_INT_PORT_BASE, TSL256X_INT_PIN_MASK);
449 GPIO_DETECT_FALLING(TSL256X_INT_PORT_BASE, TSL256X_INT_PIN_MASK);
450 gpio_hal_register_handler(&tsl256x_handler);
451
452 /* Spin process until an interrupt is received */
453 process_start(&tsl256x_int_process, NULL);
454
455 /* Enable interrupts */
456 GPIO_ENABLE_INTERRUPT(TSL256X_INT_PORT_BASE, TSL256X_INT_PIN_MASK);
457
458 /* The RE-Mote revision A has this pin shared and with a pull-down resistor,
459 * for other platforms (like the firefly), change to enable pull-up internal
460 * resistor instead if no external pull-up is present.
461 */
462 ioc_set_over(I2C_INT_PORT, I2C_INT_PIN, IOC_OVERRIDE_PUE);
463 NVIC_EnableIRQ(I2C_INT_VECTOR);
464
465 PRINTF("TSL256X: Interrupt configured\n");
466 return TSL256X_SUCCESS;
467}
468/*---------------------------------------------------------------------------*/
469static int
470status(int type)
471{
472 switch(type) {
473 case SENSORS_ACTIVE:
474 case SENSORS_READY:
475 return enabled;
476 }
477 return 0;
478}
479/*---------------------------------------------------------------------------*/
480static int
481value(int type)
482{
483 uint16_t lux;
484
485 if(!enabled) {
486 PRINTF("TSL256X: sensor not started\n");
487 return TSL256X_ERROR;
488 }
489
490 if(type == TSL256X_VAL_READ) {
491 if(tsl256x_read_sensor(&lux) != TSL256X_ERROR) {
492 return lux;
493 }
494 PRINTF("TSL256X: fail to read\n");
495 }
496 return TSL256X_ERROR;
497}
498/*---------------------------------------------------------------------------*/
499SENSORS_SENSOR(tsl256x, TSL256X_SENSOR, value, configure, status);
500/*---------------------------------------------------------------------------*/
501/** @} */
Header file for the GPIO HAL.
Header file with register and macro declarations for the cc2538 GPIO module.
#define GPIO_DETECT_FALLING(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to trigger an interrupt on falling edge.
Definition: gpio.h:193
#define GPIO_SOFTWARE_CONTROL(PORT_BASE, PIN_MASK)
Configure the pin to be software controlled with PIN_MASK of port with PORT_BASE.
Definition: gpio.h:258
#define GPIO_DISABLE_INTERRUPT(PORT_BASE, PIN_MASK)
Disable interrupt triggering for pins with PIN_MASK of port with PORT_BASE.
Definition: gpio.h:209
#define GPIO_SET_INPUT(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to input.
Definition: gpio.h:78
#define GPIO_DETECT_EDGE(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to detect edge.
Definition: gpio.h:154
#define GPIO_TRIGGER_SINGLE_EDGE(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to trigger an interrupt on single edge (controlled by G...
Definition: gpio.h:177
#define GPIO_ENABLE_INTERRUPT(PORT_BASE, PIN_MASK)
Enable interrupt triggering for pins with PIN_MASK of port with PORT_BASE.
Definition: gpio.h:201
uint8_t i2c_burst_send(uint8_t slave_addr, uint8_t *data, uint8_t len)
Perform all operations to send multiple bytes to a slave.
Definition: i2c.c:188
uint8_t i2c_single_receive(uint8_t slave_addr, uint8_t *data)
Perform all operations to receive a byte from a slave.
Definition: i2c.c:172
uint8_t i2c_master_busy(void)
Return the busy state of I2C module.
Definition: i2c.c:141
void i2c_init(uint8_t port_sda, uint8_t pin_sda, uint8_t port_scl, uint8_t pin_scl, uint32_t bus_speed)
Initialize the I2C peripheral and pins.
Definition: i2c.c:49
void i2c_master_enable(void)
Enable master I2C module.
Definition: i2c.c:91
uint8_t i2c_burst_receive(uint8_t slave_addr, uint8_t *data, uint8_t len)
Perform all operations to receive multiple bytes from a slave.
Definition: i2c.c:218
uint8_t i2c_single_send(uint8_t slave_addr, uint8_t data)
Perform all operations to send a byte to a slave.
Definition: i2c.c:159
void ioc_set_over(uint8_t port, uint8_t pin, uint8_t over)
Set Port:Pin override function.
Definition: ioc.c:54
#define IOC_OVERRIDE_PUE
Pull Up Enable.
Definition: ioc.h:223
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
Definition: cc2538-rf.c:1154
void gpio_hal_register_handler(gpio_hal_event_handler_t *handler)
Register a function to be called whenever a pin triggers an event.
Definition: gpio-hal.c:55
uint32_t gpio_hal_pin_mask_t
GPIO pin mask representation.
Definition: gpio-hal.h:142
#define gpio_hal_pin_to_mask(pin)
Convert a pin to a pin mask.
Definition: gpio-hal.h:255
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
#define PROCESS_EXITHANDLER(handler)
Specify an action when a process exits.
Definition: process.h:254
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
Definition: process.h:178
void process_poll(struct process *p)
Request a process to be polled.
Definition: process.c:371
#define CHSCALE_TINT1
322/81 * 2^CH_SCALE
Definition: tsl256x.h:163
#define LUX_SCALE
scale by 2^14
Definition: tsl256x.h:159
#define CH_SCALE
scale channel values by 2^10
Definition: tsl256x.h:161
#define CHSCALE_TINT0
322/11 * 2^CH_SCALE
Definition: tsl256x.h:162
Datatype for GPIO event handlers.
Definition: gpio-hal.h:180
Header file for the external TSL256X Sensor Driver.
Implementation of a generic module controlling Zoul sensors.