Linux Git
[owSlave2.git] / common / I2C / BMP280.c
1 #define F_CPU 8000000UL\r
2 #include <avr/io.h>\r
3 #include <avr/interrupt.h>\r
4 #include <util/delay.h>\r
5 #include <avr/wdt.h>\r
6 #include <avr/sleep.h>\r
7 #include "USI_TWI_Master.h"\r
8 \r
9 uint16_t dig_T1;\r
10 int16_t dig_T2;\r
11 int16_t dig_T3;\r
12 uint16_t dig_P1;\r
13 int16_t dig_P2;\r
14 int16_t dig_P3;\r
15 int16_t dig_P4;\r
16 int16_t dig_P5;\r
17 int16_t dig_P6;\r
18 int16_t dig_P7;\r
19 int16_t dig_P8;\r
20 int16_t dig_P9;\r
21 \r
22 \r
23 \r
24 \r
25 short bmp280ReadShort(unsigned char address)\r
26 {\r
27         char msb, lsb;\r
28         short data;\r
29         I2c_StartCondition();\r
30         I2c_WriteByte(0xEC);\r
31         I2c_WriteByte(address);\r
32         I2c_StopCondition();\r
33         I2c_StartCondition();\r
34         I2c_WriteByte(0xED);\r
35         lsb=I2c_ReadByte(ACK);\r
36         msb=I2c_ReadByte(NO_ACK);\r
37         I2c_StopCondition();\r
38         \r
39 \r
40         \r
41         data = msb << 8;\r
42         data |= lsb;\r
43         \r
44         return data;\r
45 }\r
46 \r
47 void bmp280Init(void) {\r
48         dig_T1=bmp280ReadShort(0x88);\r
49         dig_T2=bmp280ReadShort(0x8A);\r
50         dig_T3=bmp280ReadShort(0x8C);\r
51         dig_P1=bmp280ReadShort(0x8E);\r
52         dig_P2=bmp280ReadShort(0x90);\r
53         dig_P3=bmp280ReadShort(0x92);\r
54         dig_P4=bmp280ReadShort(0x94);\r
55         dig_P5=bmp280ReadShort(0x96);\r
56         dig_P6=bmp280ReadShort(0x98);\r
57         dig_P7=bmp280ReadShort(0x9A);\r
58         dig_P8=bmp280ReadShort(0x9C);\r
59         dig_P9=bmp280ReadShort(0x9E);\r
60         I2c_StartCondition();\r
61         I2c_WriteByte(0xEC);\r
62         I2c_WriteByte(0xF4);\r
63         I2c_WriteByte(0b01010111); //2x Temp over 16x Press over   Normal mode\r
64         I2c_WriteByte(0b11100000);  //4s time / no IIfilter\r
65         I2c_StopCondition();\r
66         \r
67         \r
68 }\r
69 int32_t bmp280ReadTemp(void) {\r
70         uint8_t msb, lsb,xlsb;\r
71         volatile int32_t data;\r
72         I2c_StartCondition();\r
73         I2c_WriteByte(0xEC);\r
74         I2c_WriteByte(0xFA);\r
75         I2c_StopCondition();\r
76         I2c_StartCondition();\r
77         I2c_WriteByte(0xED);\r
78         msb=I2c_ReadByte(ACK);\r
79         lsb=I2c_ReadByte(ACK);\r
80         xlsb=I2c_ReadByte(NO_ACK);\r
81         I2c_StopCondition();\r
82                 \r
83         data = (int32_t)msb << 12;\r
84         data |= (int16_t)lsb<<4;\r
85         data|=xlsb>>4;\r
86                 \r
87                 return data;\r
88 \r
89         \r
90 }\r
91 int32_t bmp280ReadPressure(uint8_t oss) {\r
92                 uint8_t msb, lsb,xlsb;\r
93                 volatile int32_t data;\r
94                 I2c_StartCondition();\r
95                 I2c_WriteByte(0xEC);\r
96                 I2c_WriteByte(0xF7);\r
97                 I2c_StopCondition();\r
98                 I2c_StartCondition();\r
99                 I2c_WriteByte(0xED);\r
100                 msb=I2c_ReadByte(ACK);\r
101                 lsb=I2c_ReadByte(ACK);\r
102                 xlsb=I2c_ReadByte(NO_ACK);\r
103                 I2c_StopCondition();\r
104                 \r
105                 data = (int32_t)msb << 12;\r
106                 data |= (int16_t)lsb<<4;\r
107                 data|=xlsb>>4;\r
108                 \r
109                 return data;\r
110 \r
111 \r
112 }\r
113 \r
114 int32_t bmp280ReadPressure_simple() {\r
115                 uint8_t msb, lsb,xlsb;\r
116                 volatile int32_t data;\r
117                 I2c_StartCondition();\r
118                 I2c_WriteByte(0xEC);\r
119                 I2c_WriteByte(0xF7);\r
120                 I2c_StopCondition();\r
121                 I2c_StartCondition();\r
122                 I2c_WriteByte(0xED);\r
123                 msb=I2c_ReadByte(ACK);\r
124                 lsb=I2c_ReadByte(ACK);\r
125                 xlsb=I2c_ReadByte(NO_ACK);\r
126                 I2c_StopCondition();\r
127                 \r
128                 data = (int32_t)msb << 12;\r
129                 data |= (int16_t)lsb<<4;\r
130                 data|=xlsb>>4;\r
131                 \r
132                 return data;\r
133 \r
134 \r
135 }\r
136 \r
137 void bmp280ConvertInt(int32_t * temperature,uint32_t *pressure,uint8_t oss) {\r
138         int32_t var1,var2,T,t_fine;\r
139         \r
140         \r
141         int32_t adc_T=bmp280ReadTemp();\r
142         var1 = ((((adc_T>>3) - ((int32_t)dig_T1<<1))) * ((int32_t)dig_T2)) >> 11;\r
143         var2 = ((((((adc_T>>4) - ((int32_t)dig_T1)) * ((adc_T>>4) - (int32_t)dig_T1))) >> 12) *((int32_t)dig_T3)) >> 14;\r
144         t_fine = var1 + var2;\r
145         T = (t_fine * 5 + 128) >> 8;\r
146         *temperature=T;\r
147         int32_t adc_P= bmp280ReadPressure(oss);\r
148         uint32_t p;\r
149         var1 = (((int32_t)t_fine)>>1) - (int32_t)64000;\r
150         var2 = (((var1>>2) * (var1>>2)) >> 11 ) * ((int32_t)dig_P6);\r
151         var2 = var2 + ((var1*((int32_t)dig_P5))<<1);\r
152         var2 = (var2>>2)+(((int32_t)dig_P4)<<16);\r
153         var1 = (((dig_P3 * (((var1>>2) * (var1>>2)) >> 13 )) >> 3) + ((((int32_t)dig_P2) * var1)>>1))>>18;\r
154         var1 =((((32768+var1))*((int32_t)dig_P1))>>15);\r
155         if (var1 == 0) {\r
156                 return ; // avoid exception caused by division by zero\r
157         }\r
158         p = (((uint32_t)(((int32_t)1048576)-adc_P)-(var2>>12)))*3125;\r
159         if (p < 0x80000000){\r
160                 p = (p << 1) / ((uint32_t)var1);\r
161                 }else{\r
162                 p = (p / (uint32_t)var1) * 2;\r
163         }\r
164         var1 = (((int32_t)dig_P9) * ((int32_t)(((p>>3) * (p>>3))>>13)))>>12;\r
165         var2 = (((int32_t)(p>>2)) * ((int32_t)dig_P8))>>13;\r
166         p = (uint32_t)((int32_t)p + ((var1 + var2 + dig_P7) >> 4));\r
167         *pressure=p;\r
168 \r
169 }\r
170 \r
171 void bmp280Convert(double * temperature, double * pressure,uint8_t oss) {\r
172 \r
173         uint32_t p;\r
174         int32_t T;\r
175         bmp280ConvertInt(&T,&p,oss);\r
176         *temperature=T/100.0;\r
177         *pressure=p/100.0;\r
178 }\r
179                 \r
180 void bmp280ConvertIntP(int32_t temp256,uint32_t *pressure) {\r
181         int32_t var1,var2,t_fine;\r
182         //T = (t_fine * 5 + 128) >> 8;\r
183         t_fine=((temp256)-128)/5;\r
184         int32_t adc_P= bmp280ReadPressure_simple();\r
185         uint32_t p;\r
186         var1 = (((int32_t)t_fine)>>1) - (int32_t)64000;\r
187         var2 = (((var1>>2) * (var1>>2)) >> 11 ) * ((int32_t)dig_P6);\r
188         var2 = var2 + ((var1*((int32_t)dig_P5))<<1);\r
189         var2 = (var2>>2)+(((int32_t)dig_P4)<<16);\r
190         var1 = (((dig_P3 * (((var1>>2) * (var1>>2)) >> 13 )) >> 3) + ((((int32_t)dig_P2) * var1)>>1))>>18;\r
191         var1 =((((32768+var1))*((int32_t)dig_P1))>>15);\r
192         if (var1 == 0) {\r
193                 return ; // avoid exception caused by division by zero\r
194         }\r
195         p = (((uint32_t)(((int32_t)1048576)-adc_P)-(var2>>12)))*3125;\r
196         if (p < 0x80000000){\r
197                 p = (p << 1) / ((uint32_t)var1);\r
198                 }else{\r
199                 p = (p / (uint32_t)var1) * 2;\r
200         }\r
201         var1 = (((int32_t)dig_P9) * ((int32_t)(((p>>3) * (p>>3))>>13)))>>12;\r
202         var2 = (((int32_t)(p>>2)) * ((int32_t)dig_P8))>>13;\r
203         p = (uint32_t)((int32_t)p + ((var1 + var2 + dig_P7) >> 4));\r
204         *pressure=p;\r
205 \r
206 }               \r
207                 \r
208 void bmp280ConvertIntP1(uint32_t *pressure) {\r
209         int32_t var1,var2,t_fine;\r
210         \r
211         \r
212         int32_t adc_T=bmp280ReadTemp();\r
213         var1 = ((((adc_T>>3) - ((int32_t)dig_T1<<1))) * ((int32_t)dig_T2)) >> 11;\r
214         var2 = ((((((adc_T>>4) - ((int32_t)dig_T1)) * ((adc_T>>4) - (int32_t)dig_T1))) >> 12) *((int32_t)dig_T3)) >> 14;\r
215         t_fine = var1 + var2;\r
216         //T = (t_fine * 5 + 128) >> 8;\r
217         int32_t adc_P= bmp280ReadPressure_simple();\r
218         uint32_t p;\r
219         var1 = (((int32_t)t_fine)>>1) - (int32_t)64000;\r
220         var2 = (((var1>>2) * (var1>>2)) >> 11 ) * ((int32_t)dig_P6);\r
221         var2 = var2 + ((var1*((int32_t)dig_P5))<<1);\r
222         var2 = (var2>>2)+(((int32_t)dig_P4)<<16);\r
223         var1 = (((dig_P3 * (((var1>>2) * (var1>>2)) >> 13 )) >> 3) + ((((int32_t)dig_P2) * var1)>>1))>>18;\r
224         var1 =((((32768+var1))*((int32_t)dig_P1))>>15);\r
225         if (var1 == 0) {\r
226                 return ; // avoid exception caused by division by zero\r
227         }\r
228         p = (((uint32_t)(((int32_t)1048576)-adc_P)-(var2>>12)))*3125;\r
229         if (p < 0x80000000){\r
230                 p = (p << 1) / ((uint32_t)var1);\r
231                 }else{\r
232                 p = (p / (uint32_t)var1) * 2;\r
233         }\r
234         var1 = (((int32_t)dig_P9) * ((int32_t)(((p>>3) * (p>>3))>>13)))>>12;\r
235         var2 = (((int32_t)(p>>2)) * ((int32_t)dig_P8))>>13;\r
236         p = (uint32_t)((int32_t)p + ((var1 + var2 + dig_P7) >> 4));\r
237         *pressure=p;\r
238 \r
239 }\r