First Commit
[owSlave2.git] / common / I2C / SHT2x.c
1 //==============================================================================
2 // S E N S I R I O N AG, Laubisruetistr. 50, CH-8712 Staefa, Switzerland
3 //==============================================================================
4 // Project : SHT2x Sample Code (V1.2)
5 // File : SHT2x.c
6 // Author : MST
7 // Controller: NEC V850/SG3 (uPD70F3740)
8 // Compiler : IAR compiler for V850 (3.50A)
9 // Brief : Sensor layer. Functions for sensor access
10 //==============================================================================
11 //---------- Includes ----------------------------------------------------------
12 #define F_CPU 8000000UL
13 #include <avr/io.h>
14 #include <avr/interrupt.h>
15 #include <util/delay.h>
16 #include <avr/wdt.h>
17 #include <avr/sleep.h>
18 #include "USI_TWI_Master.h"
19 #include "SHT2x.h"
20
21 const uint16_t POLYNOMIAL = 0x131; //P(x)=x^8+x^5+x^4+1 = 100110001
22
23
24 //==============================================================================
25 uint8_t SHT2x_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum)
26 //==============================================================================
27 {
28         uint8_t crc = 0;
29         uint8_t byteCtr;
30         //calculates 8-Bit checksum with given polynomial
31         for (byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr)
32         { crc ^= (data[byteCtr]);
33                 for (uint8_t bit = 8; bit > 0; --bit)
34                 { if (crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL;
35                         else crc = (crc << 1);
36                 }
37         }
38         if (crc != checksum) return CHECKSUM_ERROR;
39         else return 0;
40 }
41 //===========================================================================
42 uint8_t SHT2x_ReadUserRegister(uint8_t *pRegisterValue)
43 //===========================================================================
44 {
45         uint8_t checksum; //variable for checksum byte
46         uint8_t error=0; //variable for error code
47         I2c_StartCondition();
48         error |= I2c_WriteByte (I2C_ADR_W);
49         error |= I2c_WriteByte (USER_REG_R);
50         I2c_StartCondition();
51         error |= I2c_WriteByte (I2C_ADR_R);
52         *pRegisterValue = I2c_ReadByte(ACK);
53         checksum=I2c_ReadByte(NO_ACK);
54         error |= SHT2x_CheckCrc (pRegisterValue,1,checksum);
55         I2c_StopCondition();
56         return error;
57 }
58 //===========================================================================
59 uint8_t SHT2x_WriteUserRegister(uint8_t *pRegisterValue)
60 //===========================================================================
61 {
62         uint8_t error=0; //variable for error code
63         I2c_StartCondition();
64         error |= I2c_WriteByte (I2C_ADR_W);
65         error |= I2c_WriteByte (USER_REG_W);
66         error |= I2c_WriteByte (*pRegisterValue);
67         I2c_StopCondition();
68         return error;
69 }
70 //===========================================================================
71 uint8_t SHT2x_MeasureHM(etSHT2xMeasureType eSHT2xMeasureType, int16_t *pMeasurand)
72 //===========================================================================
73 {
74         uint8_t checksum; //checksum
75         uint8_t data[2]; //data array for checksum verification
76         uint8_t error=0; //error variable
77         uint16_t i; //counting variable
78         //-- write I2C sensor address and command --
79         I2c_StartCondition();
80         error |= I2c_WriteByte (I2C_ADR_W); // I2C Adr
81         switch(eSHT2xMeasureType)
82         { case HUMIDITY: error |= I2c_WriteByte (TRIG_RH_MEASUREMENT_HM); break;
83                 case TEMP : error |= I2c_WriteByte (TRIG_T_MEASUREMENT_HM); break;
84                 //default: assert(0);
85         }
86         //-- wait until hold master is released --
87         I2c_StartCondition();
88         error |= I2c_WriteByte (I2C_ADR_R);
89         //SCL=HIGH; // set SCL I/O port as input
90         DDR_USI&=~(1<<PIN_USI_SCL);
91         for(i=0; i<1000; i++) // wait until master hold is released or ;;;;; Son quatsch.... 1000 s *kopfschuettel*
92         { _delay_ms(1); // a timeout (~1s) is reached
93                 //if (SCL_CONF==1) break;
94                 if (PIN_USI&(1<<PIN_USI_SCL)) break;
95         }
96         //-- check for timeout --
97         //Was wenn der SHT2x die leitung auf 0 laesst? Kurzschluss???
98         if((PIN_USI&(1<<PIN_USI_SCL))==0) error |= TIME_OUT_ERROR; else DDR_USI|=(1<<PIN_USI_SCL);
99         
100         //-- read two data bytes and one checksum byte --
101         *pMeasurand=((data[0] = I2c_ReadByte(ACK))>>8) & 0xFF;
102         *pMeasurand|=0xFF & (data[1] = I2c_ReadByte(ACK));
103 //      pMeasurand->s16.u8H = data[0] = I2c_ReadByte(ACK);
104 //      pMeasurand->s16.u8L = data[1] = I2c_ReadByte(ACK);
105
106         checksum=I2c_ReadByte(NO_ACK);
107         //-- verify checksum --
108         error |= SHT2x_CheckCrc (data,2,checksum);
109         I2c_StopCondition();
110         return error;
111 }
112 //===========================================================================
113 uint8_t SHT2x_MeasurePoll(etSHT2xMeasureType eSHT2xMeasureType, int16_t *pMeasurand)
114 //===========================================================================
115 {
116         uint8_t checksum; //checksum
117         uint8_t data[2]; //data array for checksum verification
118         uint8_t error=0; //error variable
119         uint16_t i=0; //counting variable
120         //-- write I2C sensor address and command --
121         I2c_StartCondition();
122         error |= I2c_WriteByte (I2C_ADR_W); // I2C Adr
123         switch(eSHT2xMeasureType)
124         { case HUMIDITY: error |= I2c_WriteByte (TRIG_RH_MEASUREMENT_POLL); break;
125                 case TEMP : error |= I2c_WriteByte (TRIG_T_MEASUREMENT_POLL); break;
126                 //default: assert(0);
127         }
128         //-- poll every 10ms for measurement ready. Timeout after 20 retries (200ms)--
129         do
130         { I2c_StartCondition();
131                 _delay_ms(1000); //delay 10ms
132                 if(i++ >= 20) break;
133         } while(I2c_WriteByte (I2C_ADR_R) == ACK_ERROR);
134         if (i>=20) error |= TIME_OUT_ERROR;
135         //-- read two data bytes and one checksum byte --
136         data[0]=I2c_ReadByte(ACK);
137         data[1]=I2c_ReadByte(ACK);
138         *pMeasurand=(data[0]<<8)|data[1];
139         
140 //      pMeasurand->s16.u8H = data[0] = I2c_ReadByte(ACK);
141 //      pMeasurand->s16.u8L = data[1] = I2c_ReadByte(ACK);
142         checksum=I2c_ReadByte(NO_ACK);
143         //-- verify checksum --
144         error |= SHT2x_CheckCrc (data,2,checksum);
145         I2c_StopCondition();
146         return error;
147 }
148 //===========================================================================
149 uint8_t SHT2x_SoftReset()
150 //===========================================================================
151 {
152         uint8_t error=0; //error variable
153         I2c_StartCondition();
154         error |= I2c_WriteByte (I2C_ADR_W); // I2C Adr
155         error |= I2c_WriteByte (SOFT_RESET); // Command
156         I2c_StopCondition();
157         _delay_ms(15); // wait till sensor has restarted
158         return error;
159 }
160 //==============================================================================
161 float SHT2x_CalcRH(uint16_t u16sRH)
162 //==============================================================================
163 {
164         double humidityRH; // variable for result
165         u16sRH &= ~0x0003; // clear bits [1..0] (status bits)
166         //-- calculate relative humidity [%RH] --
167         humidityRH = -6.0 + 125.0/65536 * (double)u16sRH; // RH= -6 + 125 * SRH/2^16
168         return humidityRH;
169 }
170 //==============================================================================
171 float SHT2x_CalcTemperatureC(uint16_t u16sT)
172 //==============================================================================
173 {
174         double temperatureC; // variable for result
175         u16sT &= ~0x0003; // clear bits [1..0] (status bits)
176         //-- calculate temperature [°C] --
177         temperatureC= -46.85 + 175.72/65536 *(double)u16sT; //T= -46.85 + 175.72 * ST/2^16
178         return temperatureC;
179 }
180 //==============================================================================
181 uint8_t SHT2x_GetSerialNumber(uint8_t u8SerialNumber[])
182 //==============================================================================
183 {
184         uint8_t error=0; //error variable
185         //Read from memory location 1
186         I2c_StartCondition();
187         error |= I2c_WriteByte (I2C_ADR_W); //I2C address
188         error |= I2c_WriteByte (0xFA); //Command for readout on-chip memory
189         error |= I2c_WriteByte (0x0F); //on-chip memory address
190         I2c_StartCondition();
191         error |= I2c_WriteByte (I2C_ADR_R); //I2C address
192         u8SerialNumber[5] = I2c_ReadByte(ACK); //Read SNB_3
193         I2c_ReadByte(ACK); //Read CRC SNB_3 (CRC is not analyzed)
194         u8SerialNumber[4] = I2c_ReadByte(ACK); //Read SNB_2
195         I2c_ReadByte(ACK); //Read CRC SNB_2 (CRC is not analyzed)
196         u8SerialNumber[3] = I2c_ReadByte(ACK); //Read SNB_1
197         I2c_ReadByte(ACK); //Read CRC SNB_1 (CRC is not analyzed)
198         u8SerialNumber[2] = I2c_ReadByte(ACK); //Read SNB_0
199         I2c_ReadByte(NO_ACK); //Read CRC SNB_0 (CRC is not analyzed)
200         I2c_StopCondition();
201         //Read from memory location 2
202         I2c_StartCondition();
203         error |= I2c_WriteByte (I2C_ADR_W); //I2C address
204         error |= I2c_WriteByte (0xFC); //Command for readout on-chip memory
205         error |= I2c_WriteByte (0xC9); //on-chip memory address
206         I2c_StartCondition();
207         error |= I2c_WriteByte (I2C_ADR_R); //I2C address
208         u8SerialNumber[1] = I2c_ReadByte(ACK); //Read SNC_1
209         u8SerialNumber[0] = I2c_ReadByte(ACK); //Read SNC_0
210         I2c_ReadByte(ACK); //Read CRC SNC0/1 (CRC is not analyzed)
211         u8SerialNumber[7] = I2c_ReadByte(ACK); //Read SNA_1
212         u8SerialNumber[6] = I2c_ReadByte(ACK); //Read SNA_0
213         I2c_ReadByte(NO_ACK); //Read CRC SNA0/1 (CRC is not analyzed)
214         I2c_StopCondition();
215         return error;
216 }