]> mj.ucw.cz Git - home-hw.git/blob - ssr/Src/bmp085.c
SSR: USB descriptors
[home-hw.git] / ssr / Src / bmp085.c
1 #include "stm32f1xx.h"
2 #include "stm32f1xx_hal.h"
3
4 #include "util.h"
5 #include "app.h"
6
7 #undef TEST_VECTOR
8
9 #if 0
10 #define bmp_debug debug_printf
11 #else
12 static inline void bmp_debug(char *msg, ...)
13 { }
14 #endif
15
16 static byte bmp_i2c_buf[4];
17 volatile byte *bmp_i2c_ptr;
18 volatile byte bmp_i2c_len;
19 volatile byte bmp_i2c_addr;
20
21 static uint bmp_read(uint reg, uint bytes)
22 {
23   bmp_i2c_buf[0] = reg;
24   bmp_i2c_ptr = bmp_i2c_buf;
25   bmp_i2c_len = 1;
26   bmp_i2c_addr = 0xee;
27
28   LL_I2C_GenerateStartCondition(I2C1);
29   LL_I2C_EnableIT_TX(I2C1);
30
31   while (bmp_i2c_len)
32     ;
33
34   bmp_i2c_ptr = bmp_i2c_buf;
35   bmp_i2c_len = bytes;
36   bmp_i2c_addr = 0xef;
37
38   LL_I2C_GenerateStartCondition(I2C1);
39   LL_I2C_EnableIT_RX(I2C1);
40
41   while (bmp_i2c_len)
42     ;
43
44   uint d = 0;
45   for (uint i=0; i<bytes; i++)
46     d = (d << 8) | bmp_i2c_buf[i];
47
48   return d;
49 }
50
51 static void bmp_start_measure(uint type)
52 {
53   LL_I2C_GenerateStartCondition(I2C1);
54   while (!LL_I2C_IsActiveFlag_SB(I2C1))
55     ;
56
57   LL_I2C_TransmitData8(I2C1, 0xee);
58   while (!LL_I2C_IsActiveFlag_ADDR(I2C1))
59     ;
60   LL_I2C_ClearFlag_ADDR(I2C1);
61
62   while (!LL_I2C_IsActiveFlag_TXE(I2C1))
63     ;
64   LL_I2C_TransmitData8(I2C1, 0xf4);
65
66   while (!LL_I2C_IsActiveFlag_TXE(I2C1))
67     ;
68   LL_I2C_TransmitData8(I2C1, type);
69
70   while (!LL_I2C_IsActiveFlag_TXE(I2C1))
71     ;
72   LL_I2C_GenerateStopCondition(I2C1);
73 }
74
75 // Formulae from BMP085 specs
76 static void bmp_recalc(uint UT, uint UP, uint oss, u16 cc[11], int *tt, int *pp)
77 {
78   s16 AC1 = cc[0];
79   s16 AC2 = cc[1];
80   s16 AC3 = cc[2];
81   u16 AC4 = cc[3];
82   u16 AC5 = cc[4];
83   u16 AC6 = cc[5];
84   s16 B1 = cc[6];
85   s16 B2 = cc[7];
86   // s16 MB = cc[8];
87   s16 MC = cc[9];
88   s16 MD = cc[10];
89   UP >>= (8-oss);
90
91   int X1 = (UT-AC6)*AC5 / (1<<15);
92   int X2 = MC*(1<<11) / (X1+MD);
93   int B5 = X1 + X2;
94   int T = (B5+8) / (1<<4);
95   *tt = T;
96
97   int B6 = B5 - 4000;
98   X1 = (B2*(B6*B6/(1<<12))) / (1<<11);
99   X2 = AC2 * B6 / (1<<11);
100   int X3 = X1 + X2;
101   int B3 = (((AC1*4 + X3) << oss) + 2) / 4;
102   X1 = AC3 * B6 / (1<<13);
103   X2 = (B1*(B6*B6/(1<<12))) / (1<<16);
104   X3 = ((X1+X2) + 2) / (1<<2);
105   uint B4 = (uint)(AC4 * (X3 + 32768)) / (1U<<15);
106   uint B7 = (uint)(UP-B3) * (uint)(50000>>oss);
107   int p;
108   if (B7 < 0x80000000)
109     p = (B7*2) / B4;
110   else
111     p = B7 / B4 * 2;
112   X1 = (p/(1<<8)) * (p/(1<<8));
113   X1 = (X1*3038) / (1<<16);
114   X2 = (-7357*p) / (1<<16);
115   p = p + (X1 + X2 + 3791) / (1<<4);
116   *pp = p;
117 }
118
119 #ifdef TEST_VECTOR
120
121 #define BMP_OSS 0
122 static u16 bmp_constants[11] = {
123   408,
124   -72,
125   -14383,
126   32741,
127   32757,
128   23153,
129   6190,
130   4,
131   32768,
132   -8711,
133   2868,
134 };
135
136 void bmp_init(void)
137 {
138   bmp_debug("BMP: Test constants\n");
139 }
140
141 #else
142
143 #define BMP_OSS 3
144 static u16 bmp_constants[11];
145
146 void bmp_init(void)
147 {
148   bmp_debug("BMP: Reading constants\n");
149   for (uint i=0; i<11; i++)
150     {
151       bmp_constants[i] = bmp_read(0xaa + 2*i, 2);
152       bmp_debug("BMP: const[%d] = %04x\n", i, bmp_constants[i]);
153     }
154 }
155
156 #endif
157
158 enum bmp_state {
159   BMP_IDLE,
160   BMP_TEMP,
161   BMP_PRESSURE,
162 };
163
164 byte bmp_request;
165 static byte bmp_state = BMP_IDLE;
166 static u16 raw_temp;
167 static u32 raw_press;
168 int adjusted_temp;
169 int adjusted_press;
170 u32 bmp_counter;
171
172 void bmp_step(void)
173 {
174   switch (bmp_state)
175     {
176     case BMP_IDLE:
177       if (!bmp_request)
178         return;
179       bmp_request = 0;
180       bmp_debug("BMP: Start measure\n");
181       bmp_start_measure(0x2e);
182       bmp_state++;
183       break;
184     case BMP_TEMP:
185       if (!LL_GPIO_IsInputPinSet(BMP_DONE_GPIO_Port, BMP_DONE_Pin))
186         return;
187       bmp_debug("BMP: Temperature measured\n");
188 #ifdef TEST_VECTOR
189       raw_temp = 27898;
190 #else
191       raw_temp = bmp_read(0xf6, 2);
192 #endif
193       bmp_debug("BMP: Raw temperature: %04x\n", raw_temp);
194       bmp_start_measure(0xf4 | (BMP_OSS<<6));
195       bmp_state++;
196       break;
197     case BMP_PRESSURE:
198       if (!LL_GPIO_IsInputPinSet(BMP_DONE_GPIO_Port, BMP_DONE_Pin))
199         return;
200       bmp_debug("BMP: Pressure measured\n");
201 #ifdef TEST_VECTOR
202       raw_press = 23843 << 8;
203 #else
204       raw_press = bmp_read(0xf6, 3);
205 #endif
206       bmp_debug("BMP: Raw pressure: %06x\n", raw_press);
207       bmp_recalc(raw_temp, raw_press, BMP_OSS, bmp_constants, &adjusted_temp, &adjusted_press);
208       bmp_debug("BMP: Adjusted temp %d, press %d\n", adjusted_temp, adjusted_press);
209       bmp_counter++;
210       bmp_state = BMP_IDLE;
211       break;
212     }
213 }