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