1 // Copyright (c) 2016, Tobias Mueller tm(at)tm3d.de
\r
2 // All rights reserved.
\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
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
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
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
33 //---------- Includes ----------------------------------------------------------
\r
34 #define F_CPU 8000000UL
\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
43 I2C_ADR_W = 128, // sensor I2C address + write bit
\r
44 I2C_ADR_R = 129 // sensor I2C address + read bit
\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
59 uint8_t HDC1080_Readf(double * temperature, double * hum) {
\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
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
76 I2c_StartCondition();
\r
77 error |= I2c_WriteByte (I2C_ADR_R); //I2C address
\r
79 *temperature |= I2c_ReadByte(ACK)<<8;
\r
80 *temperature |= I2c_ReadByte(ACK);
\r
81 I2c_StopCondition();
\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
88 I2c_StartCondition();
\r
89 error |= I2c_WriteByte (I2C_ADR_R); //I2C address
\r
91 *hum|= I2c_ReadByte(ACK)<<8;
\r
92 *hum|= I2c_ReadByte(NO_ACK);
\r
93 I2c_StopCondition();
\r
99 const uint16_t POLYNOMIAL = 0x131; //P(x)=x^8+x^5+x^4+1 = 100110001
\r
102 //==============================================================================
\r
103 uint8_t SHT2x_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum)
\r
104 //==============================================================================
\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
116 if (crc != checksum) return CHECKSUM_ERROR;
\r
119 //===========================================================================
\r
120 uint8_t SHT2x_ReadUserRegister(uint8_t *pRegisterValue)
\r
121 //===========================================================================
\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
136 //===========================================================================
\r
137 uint8_t SHT2x_WriteUserRegister(uint8_t *pRegisterValue)
\r
138 //===========================================================================
\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
148 //===========================================================================
\r
149 uint8_t SHT2x_MeasureHM(etSHT2xMeasureType eSHT2xMeasureType, int16_t *pMeasurand)
\r
150 //===========================================================================
\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
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
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
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
184 checksum=I2c_ReadByte(NO_ACK);
\r
185 //-- verify checksum --
\r
186 error |= SHT2x_CheckCrc (data,2,checksum);
\r
187 I2c_StopCondition();
\r
190 //===========================================================================
\r
191 uint8_t SHT2x_MeasurePoll(etSHT2xMeasureType eSHT2xMeasureType, int16_t *pMeasurand)
\r
192 //===========================================================================
\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
206 //-- poll every 10ms for measurement ready. Timeout after 20 retries (200ms)--
\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
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
226 //===========================================================================
\r
227 uint8_t SHT2x_SoftReset(void)
\r
228 //===========================================================================
\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
238 //==============================================================================
\r
239 float SHT2x_CalcRH(uint16_t u16sRH)
\r
240 //==============================================================================
\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
248 //==============================================================================
\r
249 float SHT2x_CalcTemperatureC(uint16_t u16sT)
\r
250 //==============================================================================
\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
258 //==============================================================================
\r
259 uint8_t SHT2x_GetSerialNumber(uint8_t u8SerialNumber[])
\r
260 //==============================================================================
\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