altos: Finish ms5607 support
authorKeith Packard <keithp@keithp.com>
Sat, 19 May 2012 03:16:35 +0000 (20:16 -0700)
committerKeith Packard <keithp@keithp.com>
Sat, 19 May 2012 03:19:01 +0000 (20:19 -0700)
This has the MS5607 polling once each tick for pressure and
temperature and then saving that in a global variable. The command UI
provides for dumping the prom data so that an eeprom file can have
raw sensor data along with the conversion factors necessary to compute
useful values.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/core/ao.h
src/drivers/ao_ms5607.c
src/drivers/ao_ms5607.h
src/megametrum-v0.1/Makefile
src/megametrum-v0.1/ao_pins.h

index a2092cfe45ab923a58d551a3c9384125fbaa3c19..da1fd67b68378ebec58055e8835a71b8110429fe 100644 (file)
@@ -115,6 +115,7 @@ ao_start_scheduler(void);
 #define AO_PANIC_BT            11      /* Communications with bluetooth device failed */
 #define AO_PANIC_STACK         12      /* Stack overflow */
 #define AO_PANIC_SPI           13      /* SPI communication failure */
+#define AO_PANIC_SELF_TEST     14      /* Self test failure */
 
 /* Stop the operating system, beeping and blinking the reason */
 void
index 4594f07ceeddfccd3311eb0b8e8ee077e13be89e..f79c315a2a683df13c01636dc979625fb4e64fbd 100644 (file)
  */
 
 #include <ao.h>
+#include <ao_exti.h>
 #include "ao_ms5607.h"
 
-static struct ms5607_prom ms5607_prom;
-static uint8_t           ms5607_configured;
+static struct ao_ms5607_prom   ms5607_prom;
+static uint8_t                 ms5607_configured;
 
 static void
 ao_ms5607_start(void) {
@@ -69,7 +70,7 @@ ao_ms5607_crc(uint8_t *prom)
 }
 
 static void
-ao_ms5607_prom_read(struct ms5607_prom *prom)
+ao_ms5607_prom_read(struct ao_ms5607_prom *prom)
 {
        uint8_t         addr;
        uint8_t         crc;
@@ -85,8 +86,12 @@ ao_ms5607_prom_read(struct ms5607_prom *prom)
                r++;
        }
        crc = ao_ms5607_crc((uint8_t *) prom);
-       if (crc != (((uint8_t *) prom)[15] & 0xf))
-               printf ("MS5607 PROM CRC error (computed %x actual %x)\n", crc, (((uint8_t *) prom)[15] & 0xf));
+       if (crc != (((uint8_t *) prom)[15] & 0xf)) {
+               printf ("MS5607 PROM CRC error (computed %x actual %x)\n",
+                       crc, (((uint8_t *) prom)[15] & 0xf));
+               flush();
+               ao_panic(AO_PANIC_SELF_TEST);
+       }
 
 #if __BYTE_ORDER == __LITTLE_ENDIAN
        /* Byte swap */
@@ -108,17 +113,33 @@ ao_ms5607_setup(void)
        ao_ms5607_prom_read(&ms5607_prom);
 }
 
+static uint8_t ao_ms5607_done;
+
+static void
+ao_ms5607_isr(void)
+{
+       ao_ms5607_done = 1;
+       ao_wakeup(&ao_ms5607_done);
+}
+
 static uint32_t
-ao_ms5607_convert(uint8_t cmd) {
+ao_ms5607_get_sample(uint8_t cmd) {
        uint8_t reply[3];
        uint8_t read;
+       uint16_t now;
+
+       ao_ms5607_done = 0;
 
        ao_ms5607_start();
        ao_spi_send(&cmd, 1, AO_MS5607_SPI_INDEX);
+       ao_exti_enable(&AO_MS5607_MISO_GPIO, AO_MS5607_MISO);
+       cli();
+       while (!ao_ms5607_done)
+               ao_sleep(&ao_ms5607_done);
+       sei();
+       ao_exti_disable(&AO_MS5607_MISO_GPIO, AO_MS5607_MISO);
        ao_ms5607_stop();
 
-       ao_delay(AO_MS_TO_TICKS(20));
-
        ao_ms5607_start();
        read = AO_MS5607_ADC_READ;
        ao_spi_send(&read, 1, AO_MS5607_SPI_INDEX);
@@ -130,23 +151,22 @@ ao_ms5607_convert(uint8_t cmd) {
 
 void
 ao_ms5607_sample(struct ao_ms5607_sample *sample)
+{
+       sample->pres = ao_ms5607_get_sample(AO_MS5607_CONVERT_D1_2048);
+       sample->temp = ao_ms5607_get_sample(AO_MS5607_CONVERT_D2_2048);
+}
+
+void
+ao_ms5607_convert(struct ao_ms5607_sample *sample, struct ao_ms5607_value *value)
 {
        uint8_t addr;
-       uint32_t D1, D2;
        int32_t dT;
        int32_t TEMP;
        int64_t OFF;
        int64_t SENS;
        int32_t P;
 
-       ao_ms5607_setup();
-
-       D2 =  ao_ms5607_convert(AO_MS5607_CONVERT_D2_4096);
-       printf ("Conversion D2: %d\n", D2);
-       D1 =  ao_ms5607_convert(AO_MS5607_CONVERT_D1_4096);
-       printf ("Conversion D1: %d\n", D1);
-
-       dT = D2 - ((int32_t) ms5607_prom.tref << 8);
+       dT = sample->temp - ((int32_t) ms5607_prom.tref << 8);
        
        TEMP = 2000 + (((int64_t) dT * ms5607_prom.tempsens) >> 23);
 
@@ -170,19 +190,49 @@ ao_ms5607_sample(struct ao_ms5607_sample *sample)
                SENS -= SENS2;
        }
 
-       P = ((((int64_t) D1 * SENS) >> 21) - OFF) >> 15;
-       sample->temp = TEMP;
-       sample->pres = P;
+       value->pres = ((((int64_t) sample->pres * SENS) >> 21) - OFF) >> 15;
+       value->temp = TEMP;
 }
 
+struct ao_ms5607_sample        ao_ms5607_current;
+
+static void
+ao_ms5607(void)
+{
+       ao_ms5607_setup();
+       for (;;)
+       {
+               struct ao_ms5607_sample ao_ms5607_next;
+               ao_ms5607_sample(&ao_ms5607_next);
+               ao_arch_critical(
+                       ao_ms5607_current = ao_ms5607_next;
+                       );
+               ao_delay(0);
+       }
+}
+
+__xdata struct ao_task ao_ms5607_task;
+
 static void
 ao_ms5607_dump(void)
 {
        struct ao_ms5607_sample sample;
+       struct ao_ms5607_value value;
+
+       printf ("ms5607 reserved: %u\n", ms5607_prom.reserved);
+       printf ("ms5607 sens: %u\n", ms5607_prom.sens);
+       printf ("ms5607 off: %u\n", ms5607_prom.off);
+       printf ("ms5607 tcs: %u\n", ms5607_prom.tcs);
+       printf ("ms5607 tco: %u\n", ms5607_prom.tco);
+       printf ("ms5607 tref: %u\n", ms5607_prom.tref);
+       printf ("ms5607 tempsens: %u\n", ms5607_prom.tempsens);
+       printf ("ms5607 crc: %u\n", ms5607_prom.crc);
 
-       ao_ms5607_sample(&sample);
-       printf ("Temperature: %d\n", sample.temp);
-       printf ("Pressure %d\n", sample.pres);
+       sample = ao_ms5607_current;
+       ao_ms5607_convert(&sample, &value);
+       printf ("Pressure:    %8u %8d\n", sample.pres, value.pres);
+       printf ("Temperature: %8u %8d\n", sample.temp, value.temp);
+       printf ("Altitude: %ld\n", ao_pa_to_altitude(value.pres));
 }
 
 __code struct ao_cmds ao_ms5607_cmds[] = {
@@ -196,4 +246,22 @@ ao_ms5607_init(void)
        ms5607_configured = 0;
        ao_cmd_register(&ao_ms5607_cmds[0]);
        ao_spi_init_cs(AO_MS5607_CS_GPIO, (1 << AO_MS5607_CS));
+
+       ao_add_task(&ao_ms5607_task, ao_ms5607, "ms5607");
+
+       /* Configure the MISO pin as an interrupt; when the
+        * conversion is complete, the MS5607 will raise this
+        * pin as a signal
+        */
+       ao_exti_setup(&AO_MS5607_MISO_GPIO,
+                     AO_MS5607_MISO,
+                     AO_EXTI_MODE_RISING,
+                     ao_ms5607_isr);
+
+       /* Reset the pin from INPUT to ALTERNATE so that SPI works
+        * This needs an abstraction at some point...
+        */
+       stm_moder_set(&AO_MS5607_MISO_GPIO,
+                     AO_MS5607_MISO,
+                     STM_MODER_ALTERNATE);
 }
index 29df25e47066875500dc8767282cffed4414eec1..fd5bc984e9930b244fb80e90153daae007ca6541 100644 (file)
@@ -35,7 +35,7 @@
 #define AO_MS5607_ADC_READ             0x00
 #define AO_MS5607_PROM_READ(ad)                (0xA0 | ((ad) << 1))
 
-struct ms5607_prom {
+struct ao_ms5607_prom {
        uint16_t        reserved;
        uint16_t        sens;
        uint16_t        off;
@@ -47,8 +47,15 @@ struct ms5607_prom {
 };
 
 struct ao_ms5607_sample {
-       int32_t temp;
-       int32_t pres;
+       uint32_t        pres;   /* raw 24 bit sensor */
+       uint32_t        temp;   /* raw 24 bit sensor */
+};
+
+extern struct ao_ms5607_sample ao_ms5607_current;
+
+struct ao_ms5607_value {
+       int32_t         pres;   /* in Pa * 10 */
+       int32_t         temp;   /* in °C * 100 */
 };
 
 void
@@ -57,4 +64,10 @@ ao_ms5607_init(void);
 void
 ao_ms5607_sample(struct ao_ms5607_sample *sample);
 
+void
+ao_ms5607_convert(struct ao_ms5607_sample *sample, struct ao_ms5607_value *value);
+
+void
+ao_ms5607_get_prom(struct ao_ms5607_prom *prom);
+
 #endif /* _AO_MS5607_H_ */
index 437e1a9ebac3b43442a8e05d93f1221c8dcabc2c..6524d8b8442d63c9ddb53398d7e4549de4bb22ad 100644 (file)
@@ -50,7 +50,8 @@ ALTOS_SRC = \
        ao_packet_slave.c \
        ao_i2c_stm.c \
        ao_hmc5883.c \
-       ao_mpu6000.c
+       ao_mpu6000.c \
+       ao_convert_pa.c
 
 PRODUCT=MegaMetrum-v0.1
 PRODUCT_DEF=-DMEGAMETRUM
index cd2707397d8024532c8fa86575d97ea32a6ee14f..adc561519cfd979733e5e73539e36d60c64aa6a1 100644 (file)
@@ -182,6 +182,9 @@ struct ao_adc {
 #define AO_MS5607_CS_GPIO      stm_gpioc
 #define AO_MS5607_CS           4
 #define AO_MS5607_CS_MASK      (1 << AO_MS5607_CS)
+#define AO_MS5607_MISO_GPIO    stm_gpioa
+#define AO_MS5607_MISO         6
+#define AO_MS5607_MISO_MASK    (1 << AO_MS5607_MISO)
 #define AO_MS5607_SPI_INDEX    (STM_SPI_INDEX(1))
 
 /*
@@ -212,7 +215,7 @@ struct ao_adc {
 
 #define AO_HMC5883_INT_PORT    stm_gpioc
 #define AO_HMC5883_INT_PIN     12
-#define AO_HMC5883_I2C_INDEX   STM_SPI_INDEX(1)
+#define AO_HMC5883_I2C_INDEX   STM_I2C_INDEX(1)
 
 /*
  * mpu6000
@@ -220,6 +223,6 @@ struct ao_adc {
 
 #define AO_MPU6000_INT_PORT    stm_gpioc
 #define AO_MPU6000_INT_PIN     13
-#define AO_MPU6000_I2C_INDEX   STM_SPI_INDEX(1)
+#define AO_MPU6000_I2C_INDEX   STM_I2C_INDEX(1)
 
 #endif /* _AO_PINS_H_ */