48 #include "lib/sensors.h" 53 #define PRINTF(...) printf(__VA_ARGS__) 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) 61 static uint8_t enabled;
63 static uint8_t timming;
65 void (*tsl256x_int_callback)(uint8_t value);
68 calculate_lux(uint8_t *buf)
70 uint32_t ch0, ch1, chscale = 0;
72 uint32_t lratio, tmp = 0;
80 buffer[0] = (buf[1] << 8 | (buf[0]));
81 buffer[1] = (buf[3] << 8 | (buf[2]));
84 case TSL256X_TIMMING_INTEG_402MS:
87 case TSL256X_TIMMING_INTEG_101MS:
90 case TSL256X_TIMMING_INTEG_13_7MS:
96 chscale = chscale << 4;
99 ch0 = (buffer[0] * chscale) >>
CH_SCALE;
100 ch1 = (buffer[1] * chscale) >>
CH_SCALE;
107 lratio = (ratio + 1) >> 1;
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);
136 tsl256x_read_reg(uint8_t reg, uint8_t *buf, uint8_t regNum)
142 return TSL256X_SUCCESS;
145 return TSL256X_ERROR;
149 tsl256x_write_reg(uint8_t *buf, uint8_t num)
151 if((buf == NULL) || (num <= 0)) {
152 PRINTF(
"TSL256X: invalid write values\n");
153 return TSL256X_ERROR;
157 if(
i2c_burst_send(TSL256X_ADDR, buf, num) == I2C_MASTER_ERR_NONE) {
158 return TSL256X_SUCCESS;
160 return TSL256X_ERROR;
167 buf[0] = (TSL256X_COMMAND + TSL256X_CONTROL);
168 buf[1] = TSL256X_CONTROL_POWER_ON;
170 if(tsl256x_write_reg(buf, 2) == I2C_MASTER_ERR_NONE) {
172 if((buf[0] & 0x0F) == TSL256X_CONTROL_POWER_ON) {
173 PRINTF(
"TSL256X: powered on\n");
174 return TSL256X_SUCCESS;
179 PRINTF(
"TSL256X: failed to power on\n");
180 return TSL256X_ERROR;
184 tsl256x_id_register(uint8_t *buf)
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;
192 return TSL256X_ERROR;
199 buf[0] = (TSL256X_COMMAND + TSL256X_CONTROL);
200 buf[1] = TSL256X_CONTROL_POWER_OFF;
202 if(tsl256x_write_reg(buf, 2) == I2C_MASTER_ERR_NONE) {
203 PRINTF(
"TSL256X: powered off\n");
204 return TSL256X_SUCCESS;
207 PRINTF(
"TSL256X: failed to power off\n");
208 return TSL256X_ERROR;
212 tsl256x_clear_interrupt(
void)
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;
219 return TSL256X_SUCCESS;
223 tsl256x_read_sensor(uint16_t *lux)
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) {
233 PRINTF(
"TSL256X: CH0 0x%02X%02X CH1 0x%02X%02X\n", buf[1], buf[0],
235 *lux = calculate_lux(buf);
236 return TSL256X_SUCCESS;
239 PRINTF(
"TSL256X: failed to read\n");
240 return TSL256X_ERROR;
243 PROCESS(tsl256x_int_process,
"TSL256X interrupt process handler");
252 tsl256x_clear_interrupt();
253 tsl256x_int_callback(0);
269 .handler = tsl256x_interrupt_handler,
274 configure(
int type,
int value)
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;
289 if(type == TSL256X_ACTIVE) {
291 i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN,
292 I2C_SCL_NORMAL_BUS_SPEED);
295 tsl256x_int_callback = NULL;
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) {
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);
310 buf[0] = (TSL256X_COMMAND + TSL256X_THRHIGHLOW);
314 if(tsl256x_write_reg(buf, 3) != TSL256X_SUCCESS) {
315 PRINTF(
"TSL256X: failed to clear over interrupt\n");
316 return TSL256X_ERROR;
320 buf[0] = (TSL256X_COMMAND + TSL256X_THRLOWLOW);
324 if(tsl256x_write_reg(buf, 3) != TSL256X_SUCCESS) {
325 PRINTF(
"TSL256X: failed to clear below interrupt\n");
326 return TSL256X_ERROR;
330 if(tsl256x_clear_interrupt() == TSL256X_SUCCESS) {
332 return TSL256X_SUCCESS;
338 return TSL256X_ERROR;
340 if(tsl256x_off() == TSL256X_SUCCESS) {
341 PRINTF(
"TSL256X: stopped\n");
343 return TSL256X_SUCCESS;
345 return TSL256X_ERROR;
350 PRINTF(
"TSL256X: sensor not started\n");
351 return TSL256X_ERROR;
354 if(type == TSL256X_INT_DISABLE) {
365 buf[0] = (TSL256X_COMMAND + TSL256X_INTERRUPT);
366 buf[1] = TSL256X_INTR_DISABLED;
368 if(tsl256x_write_reg(buf, 2) != TSL256X_SUCCESS) {
369 PRINTF(
"TSL256X: failed to disable the interrupt\n");
370 return TSL256X_ERROR;
372 return TSL256X_SUCCESS;
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;
383 buf[0] = (TSL256X_COMMAND + TSL256X_TIMMING);
386 if(tsl256x_write_reg(buf, 2) == TSL256X_SUCCESS) {
387 if(value == TSL256X_G16X_402MS) {
392 case TSL256X_G16X_402MS:
393 case TSL256X_G1X_402MS:
394 timming = TSL256X_TIMMING_INTEG_402MS;
396 case TSL256X_G1X_101MS:
397 timming = TSL256X_TIMMING_INTEG_101MS;
399 case TSL256X_G1X_13_7MS:
400 timming = TSL256X_TIMMING_INTEG_13_7MS;
404 PRINTF(
"TSL256X: new timming %u gain %u\n", timming, gain);
405 return TSL256X_SUCCESS;
407 PRINTF(
"TSL256X: failed to configure timming\n");
408 return TSL256X_ERROR;
416 buf[1] = ((uint8_t *)&value)[0];
417 buf[2] = ((uint8_t *)&value)[1];
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);
425 if(tsl256x_write_reg(buf, 3) != TSL256X_SUCCESS) {
426 PRINTF(
"TSL256X: failed to set interrupt level\n");
427 return TSL256X_ERROR;
433 buf[0] = (TSL256X_COMMAND + TSL256X_INTERRUPT);
434 buf[1] = (TSL256X_INTR_LEVEL << TSL256X_INTR_SHIFT);
435 buf[1] += TSL256X_INT_PERSIST_2_CYCLES;
437 if(tsl256x_write_reg(buf, 2) != TSL256X_SUCCESS) {
438 PRINTF(
"TSL256X: failed to enable interrupt\n");
439 return TSL256X_ERROR;
465 PRINTF(
"TSL256X: Interrupt configured\n");
466 return TSL256X_SUCCESS;
486 PRINTF(
"TSL256X: sensor not started\n");
487 return TSL256X_ERROR;
490 if(type == TSL256X_VAL_READ) {
491 if(tsl256x_read_sensor(&lux) != TSL256X_ERROR) {
494 PRINTF(
"TSL256X: fail to read\n");
496 return TSL256X_ERROR;
499 SENSORS_SENSOR(tsl256x, TSL256X_SENSOR, value, configure, status);
Datatype for GPIO event handlers.
#define GPIO_ENABLE_INTERRUPT(PORT_BASE, PIN_MASK)
Enable interrupt triggering for pins with PIN_MASK of port with PORT_BASE.
#define PROCESS(name, strname)
Declare a process.
uint8_t i2c_master_busy(void)
Return the busy state of I2C module.
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.
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
Header file for the external TSL256X Sensor Driver.
#define PROCESS_BEGIN()
Define the beginning of a process.
Header file with register and macro declarations for the cc2538 GPIO module.
#define CH_SCALE
scale channel values by 2^10
#define CHSCALE_TINT1
322/81 * 2^CH_SCALE
#define GPIO_DETECT_EDGE(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to detect edge.
#define PROCESS_END()
Define the end of a process.
Implementation of a generic module controlling Zoul sensors.
#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.
void gpio_hal_register_handler(gpio_hal_event_handler_t *handler)
Register a function to be called whenever a pin triggers an event.
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
Enable External Interrupt.
#define GPIO_DISABLE_INTERRUPT(PORT_BASE, PIN_MASK)
Disable interrupt triggering for pins with PIN_MASK of port with PORT_BASE.
#define GPIO_SOFTWARE_CONTROL(PORT_BASE, PIN_MASK)
Configure the pin to be software controlled with PIN_MASK of port with PORT_BASE. ...
#define PROCESS_EXITHANDLER(handler)
Specify an action when a process exits.
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.
void process_poll(struct process *p)
Request a process to be polled.
void ioc_set_over(uint8_t port, uint8_t pin, uint8_t over)
Set Port:Pin override function.
#define GPIO_SET_INPUT(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to input.
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.
uint32_t gpio_hal_pin_mask_t
GPIO pin mask representation.
#define IOC_OVERRIDE_PUE
Pull Up Enable.
uint8_t i2c_single_receive(uint8_t slave_addr, uint8_t *data)
Perform all operations to receive a byte from a slave.
#define LUX_SCALE
scale by 2^14
#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...
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
#define gpio_hal_pin_to_mask(pin)
Convert a pin to a pin mask.
Header file for the GPIO HAL.
#define CHSCALE_TINT0
322/11 * 2^CH_SCALE
uint8_t i2c_single_send(uint8_t slave_addr, uint8_t data)
Perform all operations to send a byte to a slave.
void process_start(struct process *p, process_data_t data)
Start a process.
void i2c_master_enable(void)
Enable master I2C module.