From: Keith Packard Date: Sat, 1 Sep 2012 03:19:40 +0000 (-0500) Subject: altos: Get mma655x driver limping along X-Git-Tag: 1.1~38 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=503eabd0e351ecdffda1416b7d00f8ef1d6913c9 altos: Get mma655x driver limping along This appears to drive the chip correctly to see values from the accelerometer. Signed-off-by: Keith Packard --- diff --git a/src/drivers/ao_mma655x.c b/src/drivers/ao_mma655x.c index cd304d80..06422206 100644 --- a/src/drivers/ao_mma655x.c +++ b/src/drivers/ao_mma655x.c @@ -20,67 +20,101 @@ #if HAS_MMA655X +#if 1 +#define PRINTD(...) do { printf ("\r%5u %s: ", ao_tick_count, __func__); printf(__VA_ARGS__); } while(0) +#else +#define PRINTD(...) +#endif + static uint8_t mma655x_configured; +uint8_t ao_mma655x_spi_index = AO_MMA655X_SPI_INDEX; + static void ao_mma655x_start(void) { - ao_spi_get_bit(AO_MMA655X_CS_GPIO, - AO_MMA655X_CS, + ao_spi_get_bit(AO_MMA655X_CS_PORT, AO_MMA655X_CS_PIN, + AO_MMA655X_CS, AO_MMA655X_SPI_INDEX, AO_SPI_SPEED_FAST); } static void ao_mma655x_stop(void) { - ao_spi_put_bit(AO_MMA655X_CS_GPIO, - AO_MMA655X_CS, + ao_spi_put_bit(AO_MMA655X_CS_PORT, AO_MMA655X_CS_PIN, + AO_MMA655X_CS, AO_MMA655X_SPI_INDEX); } +static void +ao_mma655x_restart(void) { + uint8_t i; + ao_gpio_set(AO_MMA655X_CS_PORT, AO_MMA655X_CS_PIN, AO_MMA655X_CS, 1); + + /* Emperical testing on STM32L151 at 32MHz for this delay amount */ + for (i = 0; i < 9; i++) + ao_arch_nop(); + ao_gpio_set(AO_MMA655X_CS_PORT, AO_MMA655X_CS_PIN, AO_MMA655X_CS, 0); +} + static uint8_t ao_parity(uint8_t v) { + uint8_t p; /* down to four bits */ - v = (v ^ (v >> 4)) & 0xf; + p = (v ^ (v >> 4)) & 0xf; /* Cute lookup hack -- 0x6996 encodes the sixteen * even parity values in order. */ - return (~0x6996 >> v) & 1; + p = (~0x6996 >> p) & 1; + return p; } static void ao_mma655x_cmd(uint8_t d[2]) { ao_mma655x_start(); - ao_spi_send(d, 2, AO_MMA655X_SPI_INDEX); - ao_spi_recv(d, 2, AO_MMA655X_SPI_INDEX); + PRINTD("\tSEND %02x %02x\n", d[0], d[1]); + ao_spi_duplex(d, d, 2, AO_MMA655X_SPI_INDEX); + PRINTD("\t\tRECV %02x %02x\n", d[0], d[1]); ao_mma655x_stop(); } static uint8_t -ao_mma655x_reg_write(uint8_t addr, uint8_t value) +ao_mma655x_reg_read(uint8_t addr) { uint8_t d[2]; + ao_mma655x_start(); + d[0] = addr | (ao_parity(addr) << 7); + d[1] = 0; + ao_spi_send(&d, 2, AO_MMA655X_SPI_INDEX); + ao_mma655x_restart(); - addr |= (1 << 6); /* write mode */ - d[0] = addr | (ao_parity(addr^value) << 7); - d[1] = value; - ao_mma655x_cmd(d); + /* Send a dummy read of 00 to clock out the SPI data */ + d[0] = 0x80; + d[1] = 0x00; + ao_spi_duplex(&d, &d, 2, AO_MMA655X_SPI_INDEX); + ao_mma655x_stop(); return d[1]; } -static uint8_t -ao_mma655x_reg_read(uint8_t addr) +static void +ao_mma655x_reg_write(uint8_t addr, uint8_t value) { uint8_t d[2]; - d[0] = addr | (ao_parity(addr) << 7); - d[1] = 0; - ao_mma655x_cmd(d); - return d[1]; + addr |= (1 << 6); /* write mode */ + d[0] = addr | (ao_parity(addr^value) << 7); + d[1] = value; + ao_mma655x_start(); + ao_spi_send(d, 2, AO_MMA655X_SPI_INDEX); + ao_mma655x_stop(); + + addr &= ~(1 << 6); + PRINTD("write %x %x = %x\n", + addr, value, ao_mma655x_reg_read(addr)); } static uint16_t @@ -89,14 +123,23 @@ ao_mma655x_value(void) uint8_t d[2]; uint16_t v; - d[0] = ((0 << 7) | /* Axis selection (X) */ - (1 << 6) | /* Acceleration operation */ - (1 << 5)); /* Raw data */ + d[0] = ((0 << 6) | /* Axis selection (X) */ + (1 << 5) | /* Acceleration operation */ + (1 << 4)); /* Raw data */ d[1] = ((1 << 3) | /* must be one */ (1 << 2) | /* Unsigned data */ (0 << 1) | /* Arm disabled */ (1 << 0)); /* Odd parity */ - ao_mma655x_cmd(d); + ao_mma655x_start(); + PRINTD("value SEND %02x %02x\n", d[0], d[1]); + ao_spi_send(d, 2, AO_MMA655X_SPI_INDEX); + ao_mma655x_restart(); + d[0] = 0x80; + d[1] = 0x00; + ao_spi_duplex(d, d, 2, AO_MMA655X_SPI_INDEX); + ao_mma655x_stop(); + PRINTD("value RECV %02x %02x\n", d[0], d[1]); + v = (uint16_t) d[1] << 2; v |= d[0] >> 6; v |= (uint16_t) (d[0] & 3) << 10; @@ -132,6 +175,12 @@ ao_mma655x_setup(void) uint8_t v; uint16_t a, a_st; uint8_t stdefl; + uint8_t i; + uint8_t s0, s1, s2, s3; + uint8_t pn; + uint32_t lot; + uint16_t serial; + if (mma655x_configured) return; @@ -157,7 +206,10 @@ ao_mma655x_setup(void) ao_mma655x_reg_write(AO_MMA655X_AXISCFG, AXISCFG_VALUE | (1 << AO_MMA655X_AXISCFG_ST)); - a_st = ao_mma655x_value(); + for (i = 0; i < 10; i++) { + a_st = ao_mma655x_value(); + printf ("SELF-TEST %2d = %6d\n", i, a_st); + } stdefl = ao_mma655x_reg_read(AO_MMA655X_STDEFL); @@ -165,22 +217,14 @@ ao_mma655x_setup(void) AXISCFG_VALUE | (0 << AO_MMA655X_AXISCFG_ST)); a = ao_mma655x_value(); - printf ("normal: %u self_test: %u stdefl: %u\n", - a, a_st, stdefl); + + for (i = 0; i < 10; i++) { + a = ao_mma655x_value(); + printf("NORMAL %2d = %6d\n", i, a); + } ao_mma655x_reg_write(AO_MMA655X_DEVCFG, DEVCFG_VALUE | (1 << AO_MMA655X_DEVCFG_ENDINIT)); -} - -static void -ao_mma655x_dump(void) -{ - uint8_t s0, s1, s2, s3; - uint32_t lot; - uint16_t serial; - - ao_mma655x_setup(); - s0 = ao_mma655x_reg_read(AO_MMA655X_SN0); s1 = ao_mma655x_reg_read(AO_MMA655X_SN1); s2 = ao_mma655x_reg_read(AO_MMA655X_SN2); @@ -189,8 +233,16 @@ ao_mma655x_dump(void) ((uint32_t) s1 << 8) | ((uint32_t) s0); serial = lot & 0x1fff; lot >>= 12; - printf ("MMA655X lot %d serial %d\n", lot, serial); - mma655x_configured = 0; + pn = ao_mma655x_reg_read(AO_MMA655X_PN); + printf ("MMA655X lot %d serial %d number %d\n", lot, serial, pn); + +} + +static void +ao_mma655x_dump(void) +{ + ao_mma655x_setup(); + printf ("MMA655X value %d\n", ao_mma655x_value()); } __code struct ao_cmds ao_mma655x_cmds[] = { @@ -219,9 +271,9 @@ ao_mma655x_init(void) mma655x_configured = 0; ao_cmd_register(&ao_mma655x_cmds[0]); - ao_spi_init_cs(AO_MMA655X_CS_GPIO, (1 << AO_MMA655X_CS)); + ao_spi_init_cs(AO_MMA655X_CS_PORT, (1 << AO_MMA655X_CS_PIN)); - ao_add_task(&ao_mma655x_task, ao_mma655x, "mma655x"); +// ao_add_task(&ao_mma655x_task, ao_mma655x, "mma655x"); } #endif