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