From 43e558738c76afd72fc01660884be3158f44470d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 28 May 2012 11:44:07 -0600 Subject: [PATCH] altos: Try to get hmc5883 working No joy yet Signed-off-by: Keith Packard --- src/drivers/ao_hmc5883.c | 92 ++++++++++++++++++++++------------------ src/drivers/ao_hmc5883.h | 7 +++ 2 files changed, 57 insertions(+), 42 deletions(-) diff --git a/src/drivers/ao_hmc5883.c b/src/drivers/ao_hmc5883.c index 43d04f70..9551df71 100644 --- a/src/drivers/ao_hmc5883.c +++ b/src/drivers/ao_hmc5883.c @@ -19,55 +19,64 @@ #include #include -static uint8_t ao_hmc5883_wake; static uint8_t ao_hmc5883_configured; static void -ao_hmc5883_isr(void) +ao_hmc5883_reg_write(uint8_t addr, uint8_t data) { - ao_exti_disable(&AO_HMC5883_INT_PORT, AO_HMC5883_INT_PIN); - ao_hmc5883_wake = 1; - ao_wakeup(&ao_hmc5883_wake); -} - -static uint8_t ao_hmc5883_addr_reg; + uint8_t d[2]; -static void -ao_hmc5883_update_addr (uint8_t len) -{ - ao_hmc5883_addr_reg += len; - if (ao_hmc5883_addr_reg == 9) - ao_hmc5883_addr_reg = 3; - else if (ao_hmc5883_addr_reg > 12) - ao_hmc5883_addr_reg = 0; - + d[0] = addr; + d[1] = data; + ao_i2c_get(AO_HMC5883_I2C_INDEX); + ao_i2c_start(AO_HMC5883_I2C_INDEX, HMC5883_ADDR_WRITE); + ao_i2c_send(d, 2, AO_HMC5883_I2C_INDEX, TRUE); + ao_i2c_put(AO_HMC5883_I2C_INDEX); } static void -ao_hmc5883_write(uint8_t addr, uint8_t *data, uint8_t len) +ao_hmc5883_read(uint8_t addr, uint8_t *data, uint8_t len) { ao_i2c_get(AO_HMC5883_I2C_INDEX); ao_i2c_start(AO_HMC5883_I2C_INDEX, HMC5883_ADDR_WRITE); ao_i2c_send(&addr, 1, AO_HMC5883_I2C_INDEX, FALSE); - ao_hmc5883_addr_reg = addr; - ao_i2c_send(data, len, AO_HMC5883_I2C_INDEX, TRUE); - ao_hmc5883_update_addr(len); + ao_i2c_start(AO_HMC5883_I2C_INDEX, HMC5883_ADDR_READ); + ao_i2c_recv(data, len, AO_HMC5883_I2C_INDEX, TRUE); ao_i2c_put(AO_HMC5883_I2C_INDEX); } +static uint8_t ao_hmc5883_done; + static void -ao_hmc5883_read(uint8_t addr, uint8_t *data, uint8_t len) +ao_hmc5883_isr(void) { - ao_i2c_get(AO_HMC5883_I2C_INDEX); - if (addr != ao_hmc5883_addr_reg) { - ao_i2c_start(AO_HMC5883_I2C_INDEX, HMC5883_ADDR_WRITE); - ao_i2c_send(&addr, 1, AO_HMC5883_I2C_INDEX, FALSE); - ao_hmc5883_addr_reg = addr; + ao_exti_disable(&AO_HMC5883_INT_PORT, AO_HMC5883_INT_PIN); + ao_hmc5883_done = 1; + ao_wakeup(&ao_hmc5883_done); +} + +void +ao_hmc5883_sample(struct ao_hmc5883_sample *sample) +{ + uint16_t *d = (uint16_t *) sample; + int i = sizeof (*sample) / 2; + uint8_t single = HMC5883_MODE_SINGLE; + + ao_hmc5883_done = 0; + ao_exti_enable(&AO_HMC5883_INT_PORT, AO_HMC5883_INT_PIN); + ao_hmc5883_reg_write(HMC5883_MODE, HMC5883_MODE_SINGLE); + cli(); + while (!ao_hmc5883_done) + ao_sleep(&ao_hmc5883_done); + sei(); + ao_hmc5883_read(HMC5883_X_MSB, (uint8_t *) sample, sizeof (struct ao_hmc5883_sample)); +#if __BYTE_ORDER == __LITTLE_ENDIAN + /* byte swap */ + while (i--) { + uint16_t t = *d; + *d++ = (t >> 8) | (t << 8); } - ao_i2c_start(AO_HMC5883_I2C_INDEX, HMC5883_ADDR_READ); - ao_i2c_recv(data, len, AO_HMC5883_I2C_INDEX, TRUE); - ao_hmc5883_update_addr(len); - ao_i2c_put(AO_HMC5883_I2C_INDEX); +#endif } static uint8_t @@ -82,8 +91,6 @@ ao_hmc5883_setup(void) ao_exti_setup(&AO_HMC5883_INT_PORT, AO_HMC5883_INT_PIN, AO_EXTI_MODE_FALLING, ao_hmc5883_isr); - ao_hmc5883_addr_reg = 0xff; - ao_i2c_get(AO_HMC5883_I2C_INDEX); present = ao_i2c_start(AO_HMC5883_I2C_INDEX, HMC5883_ADDR_READ); ao_i2c_recv(NULL, 0, AO_HMC5883_I2C_INDEX, TRUE); @@ -98,25 +105,21 @@ static void ao_hmc5883_show(void) { uint8_t addr, data; + struct ao_hmc5883_sample sample; - for (addr = 0x00; addr <= 0x7f; addr++) - { - ao_i2c_get(AO_HMC5883_I2C_INDEX); - data = ao_i2c_start(AO_HMC5883_I2C_INDEX, addr << 1); - ao_i2c_recv(NULL, 0, AO_HMC5883_I2C_INDEX, TRUE); - ao_i2c_put(AO_HMC5883_I2C_INDEX); - if (data) - printf("address %02x responds\n", addr << 1); - } if (!ao_hmc5883_setup()) { printf("hmc5883 not present\n"); return; } +#if 0 for (addr = 0; addr <= 12; addr++) { ao_hmc5883_read(addr, &data, 1); printf ("hmc5883 register %2d: %02x\n", addr, data); } +#endif + ao_hmc5883_sample(&sample); + printf ("X: %d Y: %d Z: %d\n", sample.x, sample.y, sample.z); } static const struct ao_cmds ao_hmc5883_cmds[] = { @@ -129,5 +132,10 @@ ao_hmc5883_init(void) { ao_hmc5883_configured = 0; + ao_exti_setup(&AO_HMC5883_INT_PORT, + AO_HMC5883_INT_PIN, + AO_EXTI_MODE_FALLING, + ao_hmc5883_isr); + ao_cmd_register(&ao_hmc5883_cmds[0]); } diff --git a/src/drivers/ao_hmc5883.h b/src/drivers/ao_hmc5883.h index 399ddcdd..2ec27dd9 100644 --- a/src/drivers/ao_hmc5883.h +++ b/src/drivers/ao_hmc5883.h @@ -24,6 +24,9 @@ #define HMC5883_CONFIG_A 0 #define HMC5883_CONFIG_B 1 #define HMC5883_MODE 2 +#define HMC5883_MODE_CONTINUOUS 0 +#define HMC5883_MODE_SINGLE 1 +#define HMC5883_MODE_IDLE 2 #define HMC5883_X_MSB 3 #define HMC5883_X_LSB 4 #define HMC5883_Y_MSB 5 @@ -35,6 +38,10 @@ #define HMC5883_ID_B 11 #define HMC5883_ID_C 12 +struct ao_hmc5883_sample { + int16_t x, y, z; +}; + void ao_hmc5883_init(void); -- 2.30.2