#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
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;
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;
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);
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);
((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[] = {
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