X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fdrivers%2Fao_mmc5983.c;h=5d97d757f3fd1fedaeafcf300f7428c0de12c060;hb=c89268c1fa70fbdc661ac0963b9f8fe22c42bbfe;hp=06d4e9c9eb76d707cb06d29486436bab0d0b4b61;hpb=eb77758b7dcdd0bcef12cd1d56cf4d447cbe5c8c;p=fw%2Faltos diff --git a/src/drivers/ao_mmc5983.c b/src/drivers/ao_mmc5983.c index 06d4e9c9..5d97d757 100644 --- a/src/drivers/ao_mmc5983.c +++ b/src/drivers/ao_mmc5983.c @@ -22,7 +22,59 @@ #if HAS_MMC5983 -#define AO_MMC5983_SPI_SPEED ao_spi_speed(10000000) +struct ao_mmc5983_sample ao_mmc5983_current; + +static uint8_t ao_mmc5983_configured; + +#ifdef MMC5983_I2C +#include + +static void +ao_mmc5983_reg_write(uint8_t addr, uint8_t data) +{ + uint8_t d[2]; + + d[0] = addr; + d[1] = data; + + ao_i2c_bit_start(MMC5983_I2C_ADDR); + ao_i2c_bit_send(d, 2); + ao_i2c_bit_stop(); +} + +static uint8_t +ao_mmc5983_reg_read(uint8_t addr) +{ + uint8_t d[1]; + + ao_i2c_bit_start(MMC5983_I2C_ADDR); + d[0] = addr; + ao_i2c_bit_send(d, 1); + ao_i2c_bit_restart(MMC5983_I2C_ADDR | 1); + ao_i2c_bit_recv(d, 1); + ao_i2c_bit_stop(); + return d[0]; +} + +static void +ao_mmc5983_sample(struct ao_mmc5983_sample *sample) +{ + struct ao_mmc5983_raw raw; + + ao_i2c_bit_start(MMC5983_I2C_ADDR); + raw.addr = MMC5983_X_OUT_0; + ao_i2c_bit_send(&raw.addr, 1); + ao_i2c_bit_restart(MMC5983_I2C_ADDR | 1); + ao_i2c_bit_recv(&raw.x0, 7); + ao_i2c_bit_stop(); + + sample->x = raw.x0 << 10 | raw.x1 << 2 | ((raw.xyz2 >> 6) & 3); + sample->y = raw.y0 << 10 | raw.y1 << 2 | ((raw.xyz2 >> 4) & 3); + sample->z = raw.z0 << 10 | raw.z1 << 2 | ((raw.xyz2 >> 2) & 3); +} + +#else +#define AO_MMC5983_SPI_SPEED ao_spi_speed(2000000) static void ao_mmc5983_start(void) { @@ -39,9 +91,6 @@ ao_mmc5983_stop(void) { AO_MMC5983_SPI_INDEX); } -struct ao_mmc5983_sample ao_mmc5983_current; - -static uint8_t ao_mmc5983_configured; static void ao_mmc5983_reg_write(uint8_t addr, uint8_t data) @@ -76,33 +125,11 @@ ao_mmc5983_duplex(uint8_t *dst, uint8_t len) ao_mmc5983_stop(); } -static uint8_t ao_mmc5983_done; - -static void -ao_mmc5983_isr(void) -{ - ao_exti_disable(AO_MMC5983_INT_PORT, AO_MMC5983_INT_PIN); - ao_mmc5983_done = 1; - ao_wakeup(&ao_mmc5983_done); -} - -static uint32_t ao_mmc5983_missed_irq; - static void ao_mmc5983_sample(struct ao_mmc5983_sample *sample) { struct ao_mmc5983_raw raw; - ao_mmc5983_done = 0; - ao_exti_enable(AO_MMC5983_INT_PORT, AO_MMC5983_INT_PIN); - ao_mmc5983_reg_write(MMC5983_CONTROL_0, - (1 << MMC5983_CONTROL_0_INT_MEAS_DONE_EN) | - (1 << MMC5983_CONTROL_0_TM_M)); - ao_arch_block_interrupts(); - while (!ao_mmc5983_done) - if (ao_sleep_for(&ao_mmc5983_done, AO_MS_TO_TICKS(10))) - ++ao_mmc5983_missed_irq; - ao_arch_release_interrupts(); raw.addr = MMC5983_X_OUT_0 | MMC5983_READ; ao_mmc5983_duplex((uint8_t *) &raw, sizeof (raw)); @@ -110,31 +137,44 @@ ao_mmc5983_sample(struct ao_mmc5983_sample *sample) sample->y = raw.y0 << 10 | raw.y1 << 2 | ((raw.xyz2 >> 4) & 3); sample->z = raw.z0 << 10 | raw.z1 << 2 | ((raw.xyz2 >> 2) & 3); } +#endif + +static uint8_t product_id; static uint8_t ao_mmc5983_setup(void) { - uint8_t product_id; if (ao_mmc5983_configured) return 1; - /* Place device in 3-wire mode */ - ao_mmc5983_reg_write(MMC5983_CONTROL_3, - 1 << MMC5983_CONTROL_3_SPI_3W); + /* Delay for power up time (10ms) */ + ao_delay(AO_MS_TO_TICKS(10)); + + ao_mmc5983_reg_write(MMC5983_CONTROL_1, + 1 << MMC5983_CONTROL_1_SW_RST); + + /* Delay for power up time (10ms) */ + ao_delay(AO_MS_TO_TICKS(10)); /* Check product ID */ product_id = ao_mmc5983_reg_read(MMC5983_PRODUCT_ID); - if (product_id != MMC5983_PRODUCT_ID_PRODUCT) + if (product_id != MMC5983_PRODUCT_ID_PRODUCT_I2C && + product_id != MMC5983_PRODUCT_ID_PRODUCT_SPI) + { AO_SENSOR_ERROR(AO_DATA_MMC5983); + } - /* Set high bandwidth to reduce sample collection time */ + /* Set bandwidth to 200Hz */ ao_mmc5983_reg_write(MMC5983_CONTROL_1, - MMC5983_CONTROL_1_BW_800 << MMC5983_CONTROL_1_BW); + MMC5983_CONTROL_1_BW_200 << MMC5983_CONTROL_1_BW); - /* Clear automatic measurement and 'set' operation */ + /* Measure at 200Hz so we get recent samples by just reading + * the registers + */ ao_mmc5983_reg_write(MMC5983_CONTROL_2, - 0); + (1 << MMC5983_CONTROL_2_CMM_EN) | + (MMC5983_CONTROL_2_CM_FREQ_200HZ << MMC5983_CONTROL_2_CM_FREQ)); ao_mmc5983_configured = 1; return 1; @@ -162,8 +202,10 @@ static struct ao_task ao_mmc5983_task; static void ao_mmc5983_show(void) { - printf ("X: %d Z: %d Y: %d missed irq: %lu\n", - ao_mmc5983_current.x, ao_mmc5983_current.z, ao_mmc5983_current.y, ao_mmc5983_missed_irq); + printf ("MMC5983: %d %d %d\n", + ao_mmc5983_along(&ao_mmc5983_current), + ao_mmc5983_across(&ao_mmc5983_current), + ao_mmc5983_through(&ao_mmc5983_current)); } static const struct ao_cmds ao_mmc5983_cmds[] = { @@ -176,13 +218,23 @@ ao_mmc5983_init(void) { ao_mmc5983_configured = 0; - ao_spi_init_cs(AO_MMC5983_SPI_CS_PORT, (1 << AO_MMC5983_SPI_CS_PIN)); +#ifdef MMC5983_I2C + ao_enable_output(AO_MMC5983_SPI_CS_PORT, AO_MMC5983_SPI_CS_PIN, 1); +#else + ao_enable_input(AO_MMC5983_SPI_MISO_PORT, + AO_MMC5983_SPI_MISO_PIN, + AO_EXTI_MODE_PULL_NONE); + + ao_enable_output(AO_MMC5983_SPI_CLK_PORT, + AO_MMC5983_SPI_CLK_PIN, + 1); - ao_enable_port(AO_MMC5983_INT_PORT); - ao_exti_setup(AO_MMC5983_INT_PORT, - AO_MMC5983_INT_PIN, - AO_EXTI_MODE_RISING | AO_EXTI_MODE_PULL_NONE, - ao_mmc5983_isr); + ao_enable_output(AO_MMC5983_SPI_MOSI_PORT, + AO_MMC5983_SPI_MOSI_PIN, + 0); + + ao_spi_init_cs(AO_MMC5983_SPI_CS_PORT, (1 << AO_MMC5983_SPI_CS_PIN)); +#endif ao_add_task(&ao_mmc5983_task, ao_mmc5983, "mmc5983"); ao_cmd_register(&ao_mmc5983_cmds[0]);