Contiki-Inga 3.x
light-ziglet.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, Swedish Institute of Computer Science.
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  * This file is part of the Contiki operating system.
30  *
31  */
32 
33 /**
34  * \file
35  * Device drivers for light ziglet sensor in Zolertia Z1.
36  * \author
37  * Antonio Lignan, Zolertia <alinan@zolertia.com>
38  * Marcus Lundén, SICS <mlunden@sics.se>
39  */
40 
41 
42 #include <stdio.h>
43 #include "contiki.h"
44 #include "i2cmaster.h"
45 #include "light-ziglet.h"
46 
47 #if 0
48 #define PRINTFDEBUG(...) printf(__VA_ARGS__)
49 #else
50 #define PRINTFDEBUG(...)
51 #endif
52 
53 /* Bitmasks and bit flag variable for keeping track of tmp102 status. */
54 enum TSL2563_STATUSTYPES
55 {
56  /* must be a bit and not more, not using 0x00. */
57  INITED = 0x01,
58  RUNNING = 0x02,
59  STOPPED = 0x04,
60 };
61 
62 static enum TSL2563_STATUSTYPES _TSL2563_STATUS = 0x00;
63 
64 uint16_t
65 calculateLux(uint16_t *buffer)
66 {
67  uint32_t ch0, ch1 = 0;
68  uint32_t aux = (1<<14);
69  uint32_t ratio, lratio, tmp = 0;
70 
71  ch0 = (buffer[0]*aux) >> 10;
72  ch1 = (buffer[1]*aux) >> 10;
73 
74  PRINTFDEBUG("B0 %u, B1 %u\n", buffer[0], buffer[1]);
75  PRINTFDEBUG("ch0 %lu, ch1 %lu\n", ch0, ch1);
76 
77  ratio = (ch1 << 10);
78  ratio = ratio/ch0;
79  lratio = (ratio+1) >> 1;
80 
81  PRINTFDEBUG("ratio %lu, lratio %lu\n", ratio, lratio);
82 
83  if ((lratio >= 0) && (lratio <= K1T))
84  tmp = (ch0*B1T) - (ch1*M1T);
85  else if (lratio <= K2T)
86  tmp = (ch0*B2T) - (ch1*M2T);
87  else if (lratio <= K3T)
88  tmp = (ch0*B3T) - (ch1*M3T);
89  else if (lratio <= K4T)
90  tmp = (ch0*B4T) - (ch1*M4T);
91  else if (lratio <= K5T)
92  tmp = (ch0*B5T) - (ch1*M5T);
93  else if (lratio <= K6T)
94  tmp = (ch0*B6T) - (ch1*M6T);
95  else if (lratio <= K7T)
96  tmp = (ch0*B7T) - (ch1*M7T);
97  else if (lratio > K8T)
98  tmp = (ch0*B8T) - (ch1*M8T);
99 
100  if (tmp < 0) tmp = 0;
101 
102  tmp += (1<<13);
103 
104  PRINTFDEBUG("tmp %lu\n", tmp);
105 
106  return (tmp >> 14);
107 }
108 
109 /*---------------------------------------------------------------------------*/
110 /* Init the light ziglet sensor: ports, pins, registers, interrupts (none enabled), I2C,
111  default threshold values etc. */
112 
113 void
114 light_ziglet_init (void)
115 {
116  if (!(_TSL2563_STATUS & INITED))
117  {
118  PRINTFDEBUG ("light ziglet init\n");
119  _TSL2563_STATUS |= INITED;
120 
121  /* Set up ports and pins for I2C communication */
122  i2c_enable ();
123  return;
124  }
125 }
126 
127 /*---------------------------------------------------------------------------*/
128 /* Write to a 16-bit register.
129  args:
130  reg register to write to
131  val value to write
132 */
133 
134 void
135 tsl2563_write_reg (uint8_t reg, uint16_t val)
136 {
137  uint8_t tx_buf[] = { reg, 0x00, 0x00 };
138 
139  tx_buf[1] = (uint8_t) (val >> 8);
140  tx_buf[2] = (uint8_t) (val & 0x00FF);
141 
142  i2c_transmitinit (TSL2563_ADDR);
143  while (i2c_busy ());
144  PRINTFDEBUG ("I2C Ready to TX\n");
145 
146  i2c_transmit_n (3, tx_buf);
147  while (i2c_busy ());
148  PRINTFDEBUG ("WRITE_REG 0x%04X @ reg 0x%02X\n", val, reg);
149 }
150 
151 /*---------------------------------------------------------------------------*/
152 /* Read register.
153  args:
154  reg what register to read
155  returns the value of the read register type uint16_t
156 */
157 
158 uint16_t
159 tsl2563_read_reg (uint8_t reg)
160 {
161  uint16_t readBuf[] = {0x00, 0x00};
162  uint8_t buf[] = { 0x00, 0x00, 0x00, 0x00};
163  uint16_t retVal = 0;
164  uint8_t rtx = reg;
165 
166  // Transmit the register to read
167  i2c_transmitinit (TSL2563_ADDR);
168  while (i2c_busy ());
169  i2c_transmit_n (1, &rtx);
170  while (i2c_busy ());
171 
172  // Receive the data
173  i2c_receiveinit (TSL2563_ADDR);
174  while (i2c_busy ());
175  i2c_receive_n (4, &buf[0]);
176  while (i2c_busy ());
177 
178  PRINTFDEBUG("\nb0 %u, b1 %u, b2 %u, b3 %u\n", buf[0], buf[1], buf[2], buf[3]);
179 
180  readBuf[0] = (buf[1] << 8 | (buf[0]));
181  readBuf[1] = (buf[3] << 8 | (buf[2]));
182 
183  /* XXX Quick hack, was receiving dups bytes */
184 
185  if(readBuf[0] == readBuf[1]){
186  tsl2563_read_reg(TSL2563_READ);
187  return;
188  } else {
189  retVal = calculateLux(&readBuf);
190  return retVal;
191  }
192 }
193 
194 uint16_t
195 light_ziglet_on(void)
196 {
197  uint16_t data;
198  uint8_t regon[] = { 0x00, TSL2563_PWRN };
199  // Turn on the sensor
200  i2c_transmitinit (TSL2563_ADDR);
201  while (i2c_busy ());
202  i2c_transmit_n (2, &regon);
203  while (i2c_busy ());
204  data = (uint16_t) tsl2563_read_reg (TSL2563_READ);
205  return data;
206 }
207 
208 void
209 light_ziglet_off(void)
210 {
211  uint8_t regoff = 0x00;
212  // Turn off the sensor
213  i2c_transmitinit (TSL2563_ADDR);
214  while (i2c_busy ());
215  i2c_transmit_n (1, &regoff);
216  while (i2c_busy ());
217  return;
218 }
219 
220 
221 /*---------------------------------------------------------------------------*/
222 /* Read light ziglet sensor
223 */
224 
225 uint16_t
226 light_ziglet_read(void)
227 {
228  uint16_t lux = 0;
229  lux = light_ziglet_on();
230  light_ziglet_off();
231  return lux;
232 }
233