]> mj.ucw.cz Git - home-hw.git/blobdiff - Src/test.c
BMP085 temperature and pressure readings
[home-hw.git] / Src / test.c
index ec85b6c89b76b0608fcd6669dcd2f3279c3d7775..57d975332a65a394d7821a9b59331e267f17bc64 100644 (file)
@@ -1,9 +1,12 @@
 #include "main.h"
 
 #include <stdarg.h>
+#include <stdint.h>
 #include <string.h>
 
 typedef unsigned int uint;
+typedef uint16_t u16;
+typedef int16_t s16;
 
 void debug_putc(int c)
 {
@@ -131,12 +134,118 @@ void debug_printf(const char *fmt, ...)
   va_end(args);
 }
 
+static uint bmp_read(uint reg, uint bytes)
+{
+  LL_I2C_ClearFlag_STOP(I2C1);
+  LL_I2C_ClearFlag_BERR(I2C1);
+  LL_I2C_HandleTransfer(I2C1, 0xee, LL_I2C_ADDRSLAVE_7BIT, 1, LL_I2C_MODE_SOFTEND, LL_I2C_GENERATE_START_WRITE);
+  while (!LL_I2C_IsActiveFlag_TXE(I2C1))
+    ;
+  LL_I2C_TransmitData8(I2C1, reg);
+  while (!LL_I2C_IsActiveFlag_TC(I2C1))
+    ;
+  LL_I2C_HandleTransfer(I2C1, 0xef, LL_I2C_ADDRSLAVE_7BIT, bytes, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_RESTART_7BIT_READ);
+
+  uint d = 0;
+  for (uint i=0; i<bytes; i++)
+    {
+      while (!LL_I2C_IsActiveFlag_RXNE(I2C1))
+       ;
+      d = (d << 8) | LL_I2C_ReceiveData8(I2C1);
+    }
+
+  return d;
+}
+
+static uint bmp_measure(uint type, uint bytes)
+{
+  LL_I2C_HandleTransfer(I2C1, 0xee, LL_I2C_ADDRSLAVE_7BIT, 2, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
+  while (!LL_I2C_IsActiveFlag_TXE(I2C1))
+    ;
+  LL_I2C_TransmitData8(I2C1, 0xf4);
+  while (!LL_I2C_IsActiveFlag_TXE(I2C1))
+    ;
+  LL_I2C_TransmitData8(I2C1, type);
+  while (!LL_I2C_IsActiveFlag_STOP(I2C1))
+    ;
+
+  while (!LL_GPIO_IsInputPinSet(BMP_DONE_GPIO_Port, BMP_DONE_Pin))
+    ;
+
+  return bmp_read(0xf6, bytes);
+}
+
+// Formulae from BMP085 specs
+void bmp_recalc(uint UT, uint UP, uint oss, u16 cc[11], int *tt, int *pp)
+{
+  s16 AC1 = cc[0];
+  s16 AC2 = cc[1];
+  s16 AC3 = cc[2];
+  u16 AC4 = cc[3];
+  u16 AC5 = cc[4];
+  u16 AC6 = cc[5];
+  s16 B1 = cc[6];
+  s16 B2 = cc[7];
+  s16 MB = cc[8];
+  s16 MC = cc[9];
+  s16 MD = cc[10];
+  UP >>= (8-oss);
+
+  int X1 = (UT-AC6)*AC5 / (1<<15);
+  int X2 = MC*(1<<11) / (X1+MD);
+  int B5 = X1 + X2;
+  int T = (B5+8) / (1<<4);
+  *tt = T;
+
+  int B6 = B5 - 4000;
+  X1 = (B2*(B6*B6/(1<<12))) / (1<<11);
+  X2 = AC2 * B6 / (1<<11);
+  int X3 = X1 + X2;
+  int B3 = (((AC1*4 + X3) << oss) + 2) / 4;
+  X1 = AC3 * B6 / (1<<13);
+  X2 = (B1*(B6*B6/(1<<12))) / (1<<16);
+  X3 = ((X1+X2) + 2) / (1<<2);
+  uint B4 = (uint)(AC4 * (X3 + 32768)) / (1U<<15);
+  uint B7 = (uint)(UP-B3) * (uint)(50000>>oss);
+  int p;
+  if (B7 < 0x80000000)
+    p = (B7*2) / B4;
+  else
+    p = B7 / B4 * 2;
+  X1 = (p/(1<<8)) * (p/(1<<8));
+  X1 = (X1*3038) / (1<<16);
+  X2 = (-7357*p) / (1<<16);
+  p = p + (X1 + X2 + 3791) / (1<<4);
+  *pp = p;
+}
+
 void run_test(void)
 {
   for (;;)
     {
       LL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
-      debug_printf("Testing printf: %08X %s\r\n", -42, "mnaeiou");
-      LL_mDelay(200);
+
+      debug_puts("Constants:");
+      u16 cc[11];
+      for (uint i=0; i<11; i++)
+       {
+         cc[i] = bmp_read(0xaa + 2*i, 2);
+         debug_printf(" %04x", cc[i]);
+       }
+      debug_puts("\r\n");
+
+      uint raw_temp = bmp_measure(0x2e, 2);
+      debug_printf("Raw temperature: %04x\r\n", raw_temp);
+
+      uint oss = 3;    // Over-sampling setting
+      uint raw_press = bmp_measure(0xf4 | (oss<<6), 3);
+      debug_printf("Raw pressure: %06x\r\n", raw_press);
+
+      int temp, press;
+      bmp_recalc(raw_temp, raw_press, oss, cc, &temp, &press);
+      debug_printf("Temperature: %d ddegC\r\n", temp);
+      debug_printf("Pressure: %d Pa\r\n", press);
+
+      LL_mDelay(1000);
     }
 }