HDC1080 support
[owSlave2.git] / common / I2C / HDC1080.c
1 // Copyright (c) 2016, Tobias Mueller tm(at)tm3d.de\r
2 // All rights reserved.\r
3 //\r
4 // Redistribution and use in source and binary forms, with or without\r
5 // modification, are permitted provided that the following conditions are\r
6 // met:\r
7 //\r
8 //  * Redistributions of source code must retain the above copyright\r
9 //    notice, this list of conditions and the following disclaimer.\r
10 //  * Redistributions in binary form must reproduce the above copyright\r
11 //    notice, this list of conditions and the following disclaimer in the\r
12 //    documentation and/or other materials provided with the\r
13 //    distribution.\r
14 //  * All advertising materials mentioning features or use of this\r
15 //    software must display the following acknowledgement: This product\r
16 //    includes software developed by tm3d.de and its contributors.\r
17 //  * Neither the name of tm3d.de nor the names of its contributors may\r
18 //    be used to endorse or promote products derived from this software\r
19 //    without specific prior written permission.\r
20 //\r
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
32 \r
33 //---------- Includes ----------------------------------------------------------\r
34 #define F_CPU 8000000UL\r
35 #include <avr/io.h>\r
36 #include <avr/interrupt.h>\r
37 #include <util/delay.h>\r
38 #include <avr/wdt.h>\r
39 #include <avr/sleep.h>\r
40 #include "USI_TWI_Master.h"\r
41 #include "HDC1080.h"\r
42 typedef enum{\r
43         I2C_ADR_W = 128, // sensor I2C address + write bit\r
44         I2C_ADR_R = 129 // sensor I2C address + read bit\r
45 }etI2cHeader;\r
46 \r
47 uint8_t HDC1080_Init() {\r
48         volatile uint8_t error=0;\r
49         I2c_StartCondition();\r
50         error |= I2c_WriteByte (I2C_ADR_W); // I2C Adr\r
51         error |= I2c_WriteByte (0x02); // Config\r
52         error |= I2c_WriteByte (0x0); // 14 bit\r
53         error |= I2c_WriteByte (0x0); // \r
54         I2c_StopCondition();\r
55         return error;\r
56 \r
57 }\r
58 \r
59 uint8_t HDC1080_Readf(double * temperature, double * hum) {     \r
60         int16_t t;\r
61         uint16_t h;\r
62         uint8_t error=0;\r
63         error=HDC1080_Readi(&t,&h);\r
64         *temperature=(double)t/65536.0*165.0-40.0;\r
65         *hum=(double)h/65536.0*100;\r
66         return error;\r
67 \r
68 }\r
69 uint8_t HDC1080_Readi(int16_t * temperature, uint16_t * hum) {\r
70         volatile uint8_t error=0;\r
71         I2c_StartCondition();\r
72         error |= I2c_WriteByte (I2C_ADR_W); // I2C Adr\r
73         error |= I2c_WriteByte (0x0); //\r
74         I2c_StopCondition();\r
75         _delay_ms(10);\r
76         I2c_StartCondition();\r
77         error |= I2c_WriteByte (I2C_ADR_R); //I2C address\r
78         *temperature=0;\r
79         *temperature |= I2c_ReadByte(ACK)<<8;\r
80         *temperature |= I2c_ReadByte(ACK); \r
81         I2c_StopCondition();\r
82 \r
83         I2c_StartCondition();\r
84         error |= I2c_WriteByte (I2C_ADR_W); // I2C Adr\r
85         error |= I2c_WriteByte (0x01); //\r
86         I2c_StopCondition();\r
87         _delay_ms(10);\r
88         I2c_StartCondition();\r
89         error |= I2c_WriteByte (I2C_ADR_R); //I2C address\r
90         *hum=0;\r
91         *hum|= I2c_ReadByte(ACK)<<8; \r
92         *hum|= I2c_ReadByte(NO_ACK); \r
93         I2c_StopCondition();\r
94         return error;\r
95         }\r
96 \r
97 /*\r
98 \r
99 const uint16_t POLYNOMIAL = 0x131; //P(x)=x^8+x^5+x^4+1 = 100110001\r
100 \r
101 \r
102 //==============================================================================\r
103 uint8_t SHT2x_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum)\r
104 //==============================================================================\r
105 {\r
106         uint8_t crc = 0;\r
107         uint8_t byteCtr;\r
108         //calculates 8-Bit checksum with given polynomial\r
109         for (byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr)\r
110         { crc ^= (data[byteCtr]);\r
111                 for (uint8_t bit = 8; bit > 0; --bit)\r
112                 { if (crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL;\r
113                         else crc = (crc << 1);\r
114                 }\r
115         }\r
116         if (crc != checksum) return CHECKSUM_ERROR;\r
117         else return 0;\r
118 }\r
119 //===========================================================================\r
120 uint8_t SHT2x_ReadUserRegister(uint8_t *pRegisterValue)\r
121 //===========================================================================\r
122 {\r
123         uint8_t checksum; //variable for checksum byte\r
124         uint8_t error=0; //variable for error code\r
125         I2c_StartCondition();\r
126         error |= I2c_WriteByte (I2C_ADR_W);\r
127         error |= I2c_WriteByte (USER_REG_R);\r
128         I2c_StartCondition();\r
129         error |= I2c_WriteByte (I2C_ADR_R);\r
130         *pRegisterValue = I2c_ReadByte(ACK);\r
131         checksum=I2c_ReadByte(NO_ACK);\r
132         error |= SHT2x_CheckCrc (pRegisterValue,1,checksum);\r
133         I2c_StopCondition();\r
134         return error;\r
135 }\r
136 //===========================================================================\r
137 uint8_t SHT2x_WriteUserRegister(uint8_t *pRegisterValue)\r
138 //===========================================================================\r
139 {\r
140         uint8_t error=0; //variable for error code\r
141         I2c_StartCondition();\r
142         error |= I2c_WriteByte (I2C_ADR_W);\r
143         error |= I2c_WriteByte (USER_REG_W);\r
144         error |= I2c_WriteByte (*pRegisterValue);\r
145         I2c_StopCondition();\r
146         return error;\r
147 }\r
148 //===========================================================================\r
149 uint8_t SHT2x_MeasureHM(etSHT2xMeasureType eSHT2xMeasureType, int16_t *pMeasurand)\r
150 //===========================================================================\r
151 {\r
152         uint8_t checksum; //checksum\r
153         uint8_t data[2]; //data array for checksum verification\r
154         uint8_t error=0; //error variable\r
155         uint16_t i; //counting variable\r
156         //-- write I2C sensor address and command --\r
157         I2c_StartCondition();\r
158         error |= I2c_WriteByte (I2C_ADR_W); // I2C Adr\r
159         switch(eSHT2xMeasureType)\r
160         { case HUMIDITY: error |= I2c_WriteByte (TRIG_RH_MEASUREMENT_HM); break;\r
161                 case TEMP : error |= I2c_WriteByte (TRIG_T_MEASUREMENT_HM); break;\r
162                 //default: assert(0);\r
163         }\r
164         //-- wait until hold master is released --\r
165         I2c_StartCondition();\r
166         error |= I2c_WriteByte (I2C_ADR_R);\r
167         //SCL=HIGH; // set SCL I/O port as input\r
168         DDR_USI&=~(1<<PIN_USI_SCL);\r
169         for(i=0; i<1000; i++) // wait until master hold is released or ;;;;; Son quatsch.... 1000 s *kopfschuettel*\r
170         { _delay_ms(1); // a timeout (~1s) is reached\r
171                 //if (SCL_CONF==1) break;\r
172                 if (PIN_USI&(1<<PIN_USI_SCL)) break;\r
173         }\r
174         //-- check for timeout --\r
175         //Was wenn der SHT2x die leitung auf 0 laesst? Kurzschluss???\r
176         if((PIN_USI&(1<<PIN_USI_SCL))==0) error |= TIME_OUT_ERROR; else DDR_USI|=(1<<PIN_USI_SCL);\r
177         \r
178         //-- read two data bytes and one checksum byte --\r
179         *pMeasurand=((data[0] = I2c_ReadByte(ACK))>>8) & 0xFF;\r
180         *pMeasurand|=0xFF & (data[1] = I2c_ReadByte(ACK));\r
181 //      pMeasurand->s16.u8H = data[0] = I2c_ReadByte(ACK);\r
182 //      pMeasurand->s16.u8L = data[1] = I2c_ReadByte(ACK);\r
183 \r
184         checksum=I2c_ReadByte(NO_ACK);\r
185         //-- verify checksum --\r
186         error |= SHT2x_CheckCrc (data,2,checksum);\r
187         I2c_StopCondition();\r
188         return error;\r
189 }\r
190 //===========================================================================\r
191 uint8_t SHT2x_MeasurePoll(etSHT2xMeasureType eSHT2xMeasureType, int16_t *pMeasurand)\r
192 //===========================================================================\r
193 {\r
194         uint8_t checksum; //checksum\r
195         uint8_t data[2]; //data array for checksum verification\r
196         uint8_t error=0; //error variable\r
197         uint16_t i=0; //counting variable\r
198         //-- write I2C sensor address and command --\r
199         I2c_StartCondition();\r
200         error |= I2c_WriteByte (I2C_ADR_W); // I2C Adr\r
201         switch(eSHT2xMeasureType)\r
202         { case HUMIDITY: error |= I2c_WriteByte (TRIG_RH_MEASUREMENT_POLL); break;\r
203                 case TEMP : error |= I2c_WriteByte (TRIG_T_MEASUREMENT_POLL); break;\r
204                 //default: assert(0);\r
205         }\r
206         //-- poll every 10ms for measurement ready. Timeout after 20 retries (200ms)--\r
207         do\r
208         { I2c_StartCondition();\r
209                 _delay_ms(200); //delay 10ms\r
210                 if(i++ >= 20) break;\r
211         } while(I2c_WriteByte (I2C_ADR_R) == ACK_ERROR);\r
212         if (i>=20) error |= TIME_OUT_ERROR;\r
213         //-- read two data bytes and one checksum byte --\r
214         data[0]=I2c_ReadByte(ACK);\r
215         data[1]=I2c_ReadByte(ACK);\r
216         *pMeasurand=(data[0]<<8)|data[1];\r
217         \r
218 //      pMeasurand->s16.u8H = data[0] = I2c_ReadByte(ACK);\r
219 //      pMeasurand->s16.u8L = data[1] = I2c_ReadByte(ACK);\r
220         checksum=I2c_ReadByte(NO_ACK);\r
221         //-- verify checksum --\r
222         error |= SHT2x_CheckCrc (data,2,checksum);\r
223         I2c_StopCondition();\r
224         return error;\r
225 }\r
226 //===========================================================================\r
227 uint8_t SHT2x_SoftReset(void)\r
228 //===========================================================================\r
229 {\r
230         uint8_t error=0; //error variable\r
231         I2c_StartCondition();\r
232         error |= I2c_WriteByte (I2C_ADR_W); // I2C Adr\r
233         error |= I2c_WriteByte (SOFT_RESET); // Command\r
234         I2c_StopCondition();\r
235         _delay_ms(15); // wait till sensor has restarted\r
236         return error;\r
237 }\r
238 //==============================================================================\r
239 float SHT2x_CalcRH(uint16_t u16sRH)\r
240 //==============================================================================\r
241 {\r
242         double humidityRH; // variable for result\r
243         u16sRH &= ~0x0003; // clear bits [1..0] (status bits)\r
244         //-- calculate relative humidity [%RH] --\r
245         humidityRH = -6.0 + 125.0/65536 * (double)u16sRH; // RH= -6 + 125 * SRH/2^16\r
246         return humidityRH;\r
247 }\r
248 //==============================================================================\r
249 float SHT2x_CalcTemperatureC(uint16_t u16sT)\r
250 //==============================================================================\r
251 {\r
252         double temperatureC; // variable for result\r
253         u16sT &= ~0x0003; // clear bits [1..0] (status bits)\r
254         //-- calculate temperature [°C] --\r
255         temperatureC= -46.85 + 175.72/65536 *(double)u16sT; //T= -46.85 + 175.72 * ST/2^16\r
256         return temperatureC;\r
257 }\r
258 //==============================================================================\r
259 uint8_t SHT2x_GetSerialNumber(uint8_t u8SerialNumber[])\r
260 //==============================================================================\r
261 {\r
262         uint8_t error=0; //error variable\r
263         //Read from memory location 1\r
264         I2c_StartCondition();\r
265         error |= I2c_WriteByte (I2C_ADR_W); //I2C address\r
266         error |= I2c_WriteByte (0xFA); //Command for readout on-chip memory\r
267         error |= I2c_WriteByte (0x0F); //on-chip memory address\r
268         I2c_StartCondition();\r
269         error |= I2c_WriteByte (I2C_ADR_R); //I2C address\r
270         u8SerialNumber[5] = I2c_ReadByte(ACK); //Read SNB_3\r
271         I2c_ReadByte(ACK); //Read CRC SNB_3 (CRC is not analyzed)\r
272         u8SerialNumber[4] = I2c_ReadByte(ACK); //Read SNB_2\r
273         I2c_ReadByte(ACK); //Read CRC SNB_2 (CRC is not analyzed)\r
274         u8SerialNumber[3] = I2c_ReadByte(ACK); //Read SNB_1\r
275         I2c_ReadByte(ACK); //Read CRC SNB_1 (CRC is not analyzed)\r
276         u8SerialNumber[2] = I2c_ReadByte(ACK); //Read SNB_0\r
277         I2c_ReadByte(NO_ACK); //Read CRC SNB_0 (CRC is not analyzed)\r
278         I2c_StopCondition();\r
279         //Read from memory location 2\r
280         I2c_StartCondition();\r
281         error |= I2c_WriteByte (I2C_ADR_W); //I2C address\r
282         error |= I2c_WriteByte (0xFC); //Command for readout on-chip memory\r
283         error |= I2c_WriteByte (0xC9); //on-chip memory address\r
284         I2c_StartCondition();\r
285         error |= I2c_WriteByte (I2C_ADR_R); //I2C address\r
286         u8SerialNumber[1] = I2c_ReadByte(ACK); //Read SNC_1\r
287         u8SerialNumber[0] = I2c_ReadByte(ACK); //Read SNC_0\r
288         I2c_ReadByte(ACK); //Read CRC SNC0/1 (CRC is not analyzed)\r
289         u8SerialNumber[7] = I2c_ReadByte(ACK); //Read SNA_1\r
290         u8SerialNumber[6] = I2c_ReadByte(ACK); //Read SNA_0\r
291         I2c_ReadByte(NO_ACK); //Read CRC SNA0/1 (CRC is not analyzed)\r
292         I2c_StopCondition();\r
293         return error;\r
294 }\r
295 */