diff options
-rw-r--r-- | apps/accelerometer-test/app.c | 19 | ||||
-rw-r--r-- | watch-library/driver/lis2dw.c | 38 | ||||
-rw-r--r-- | watch-library/driver/lis2dw.h | 31 | ||||
-rw-r--r-- | watch-library/watch/watch_uart.c | 6 |
4 files changed, 53 insertions, 41 deletions
diff --git a/apps/accelerometer-test/app.c b/apps/accelerometer-test/app.c index bfef132c..4dee3fe5 100644 --- a/apps/accelerometer-test/app.c +++ b/apps/accelerometer-test/app.c @@ -20,17 +20,23 @@ uint8_t ticks = 0; char buf[13] = {0}; static void cb_tick(void) { + watch_clear_indicator(WATCH_INDICATOR_SIGNAL); if (!lis2dw_have_new_data()) return; + watch_set_indicator(WATCH_INDICATOR_SIGNAL); lis2dw_reading raw_reading; lis2dw_acceleration_measurement measurement = lis2dw_get_acceleration_measurement(&raw_reading); - (void)measurement; - printf("%d, %d, %d\n", raw_reading.x, raw_reading.y, raw_reading.z); + printf("%f, %f, %f\n", measurement.x, measurement.y, measurement.z); + char buf[128]; + sprintf(buf, "%f, %f, %f\n", measurement.x, measurement.y, measurement.z); + watch_debug_puts(buf); } void app_init(void) { + watch_enable_debug_uart(9600); + watch_enable_display(); - watch_display_string("IN 0 0 0", 0); + watch_display_string("AC Strean", 0); watch_enable_external_interrupts(); watch_register_interrupt_callback(BTN_MODE, cb_mode_pressed, INTERRUPT_TRIGGER_RISING); @@ -39,8 +45,12 @@ void app_init(void) { watch_enable_i2c(); lis2dw_begin(); + lis2dw_set_data_rate(LIS2DW_DATA_RATE_25_HZ); // is this enough for training? + lis2dw_set_low_noise_mode(true); // consumes a little more power + lis2dw_set_low_power_mode(LIS2DW_LP_MODE_2); // lowest power 14-bit mode, 25 Hz is 3.5 µA @ 1.8V w/ low noise, 3µA without + lis2dw_set_range(LIS2DW_CTRL6_VAL_RANGE_4G); - watch_rtc_register_periodic_callback(cb_tick, 16); + watch_rtc_register_periodic_callback(cb_tick, 64); } void app_wake_from_backup(void) { @@ -57,7 +67,6 @@ void app_wake_from_standby(void) { bool app_loop(void) { // TODO: interrupt configuration for LIS2DW - sprintf(buf, "IN%2d%3d%3d", ticks, interrupts, last_interrupts); watch_display_string(buf, 0); return true; diff --git a/watch-library/driver/lis2dw.c b/watch-library/driver/lis2dw.c index 73b54aaf..6e1ac56d 100644 --- a/watch-library/driver/lis2dw.c +++ b/watch-library/driver/lis2dw.c @@ -31,8 +31,8 @@ bool lis2dw_begin(void) { } watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL2, LIS2DW_CTRL2_VAL_BOOT); watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL2, LIS2DW_CTRL2_VAL_SOFT_RESET); - // Start at 100 Hz data rate - watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1, LIS2DW_CTRL1_VAL_ODR_100HZ | LIS2DW_CTRL1_VAL_MODE_HIGH_PERFORMANCE); + // Start at lowest possible data rate and lowest possible power mode + watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1, LIS2DW_CTRL1_VAL_ODR_LOWEST | LIS2DW_CTRL1_VAL_MODE_LOW_POWER | LIS2DW_CTRL1_VAL_LPMODE_1); // Enable block data update (output registers not updated until MSB and LSB have been read) and address autoincrement watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL2, LIS2DW_CTRL2_VAL_BDU | LIS2DW_CTRL2_VAL_IF_ADD_INC); // Set range to ±2G @@ -65,10 +65,6 @@ lis2dw_reading lis2dw_get_raw_reading(void) { retval.z = buffer[4]; retval.z |= ((uint16_t)buffer[5]) << 8; - retval.x >>= 2; - retval.y >>= 2; - retval.z >>= 2; - return retval; } @@ -96,21 +92,21 @@ lis2dw_reading lis2dw_get_raw_reading(void) { } void lis2dw_set_range(lis2dw_range_t range) { - uint8_t val = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL4) & 0xCF; + uint8_t val = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL6) & ~(LIS2DW_RANGE_16_G << 4); uint8_t bits = range << 4; - watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL4, val | bits); + watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL6, val | bits); } lis2dw_range_t lis2dw_get_range(void) { - uint8_t retval = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL4) & 0x30; + uint8_t retval = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL6) & (LIS2DW_RANGE_16_G << 4); retval >>= 4; return (lis2dw_range_t)retval; } void lis2dw_set_data_rate(lis2dw_data_rate_t dataRate) { - uint8_t val = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1) & 0x0F; + uint8_t val = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1) & ~(0b1111 << 4); uint8_t bits = dataRate << 4; watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1, val | bits); @@ -119,3 +115,25 @@ void lis2dw_set_data_rate(lis2dw_data_rate_t dataRate) { lis2dw_data_rate_t lis2dw_get_data_rate(void) { return watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1) >> 4; } + +void lis2dw_set_low_power_mode(lis2dw_low_power_mode_t mode) { + uint8_t val = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1) & ~(0b11); + uint8_t bits = mode & 0b11; + + watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1, val | bits); +} + +lis2dw_low_power_mode_t lis2dw_get_low_power_mode(void) { + return watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1) & 0b11; +} + +void lis2dw_set_low_noise_mode(bool on) { + uint8_t val = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1) & ~(LIS2DW_CTRL6_VAL_LOW_NOISE); + uint8_t bits = on ? LIS2DW_CTRL6_VAL_LOW_NOISE : 0; + + watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1, val | bits); +} + +bool lis2dw_get_low_noise_mode(void) { + return (watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1) & LIS2DW_CTRL6_VAL_LOW_NOISE) != 0; +} diff --git a/watch-library/driver/lis2dw.h b/watch-library/driver/lis2dw.h index ac2d60bb..22b4484f 100644 --- a/watch-library/driver/lis2dw.h +++ b/watch-library/driver/lis2dw.h @@ -81,29 +81,6 @@ typedef enum { LIS2DW_RANGE_2_G = 0b00 // +/- 2g (default value) } lis2dw_range_t; -typedef enum { - LIS2DW_INTERRUPT_CONFIGURATION_OR = 0b00000000, - LIS2DW_INTERRUPT_CONFIGURATION_AND = 0b10000000, - LIS2DW_INTERRUPT_CONFIGURATION_6D_MOVEMENT = 0b01000000, - LIS2DW_INTERRUPT_CONFIGURATION_6D_POSITION = 0b11000000, // in 6D mode, these have an alternate meaning: - LIS2DW_INTERRUPT_CONFIGURATION_Z_HIGH_ENABLE = 0b00100000, // Z up enable - LIS2DW_INTERRUPT_CONFIGURATION_Z_LOW_ENABLE = 0b00010000, // Z down enable - LIS2DW_INTERRUPT_CONFIGURATION_Y_HIGH_ENABLE = 0b00001000, // Y up enable - LIS2DW_INTERRUPT_CONFIGURATION_Y_LOW_ENABLE = 0b00000100, // Y down enable - LIS2DW_INTERRUPT_CONFIGURATION_X_HIGH_ENABLE = 0b00000010, // X up enable - LIS2DW_INTERRUPT_CONFIGURATION_X_LOW_ENABLE = 0b00000001, // X down enable -} lis2dw_interrupt_configuration; - -typedef enum { - LIS2DW_INTERRUPT_STATE_ACTIVE = 0b01000000, - LIS2DW_INTERRUPT_STATE_Z_HIGH = 0b00100000, // Z up - LIS2DW_INTERRUPT_STATE_Z_LOW = 0b00010000, // Z down - LIS2DW_INTERRUPT_STATE_Y_HIGH = 0b00001000, // Y up - LIS2DW_INTERRUPT_STATE_Y_LOW = 0b00000100, // Y down - LIS2DW_INTERRUPT_STATE_X_HIGH = 0b00000010, // X up - LIS2DW_INTERRUPT_STATE_X_LOW = 0b00000001, // X down -} lis2dw_interrupt_state; - // Assumes SA0 is high; if low, its 0x18 #define LIS2DW_ADDRESS (0x19) @@ -277,4 +254,12 @@ void lis2dw_set_data_rate(lis2dw_data_rate_t dataRate); lis2dw_data_rate_t lis2dw_get_data_rate(void); +void lis2dw_set_low_power_mode(lis2dw_low_power_mode_t mode); + +lis2dw_low_power_mode_t lis2dw_get_low_power_mode(void); + +void lis2dw_set_low_noise_mode(bool on); + +bool lis2dw_get_low_noise_mode(void); + #endif // LIS2DW_H diff --git a/watch-library/watch/watch_uart.c b/watch-library/watch/watch_uart.c index d35533d0..64b63bee 100644 --- a/watch-library/watch/watch_uart.c +++ b/watch-library/watch/watch_uart.c @@ -56,8 +56,8 @@ void watch_enable_debug_uart(uint32_t baud) { uint64_t br = (uint64_t)65536 * ((CONF_CPU_FREQUENCY * 4) - 16 * baud) / (CONF_CPU_FREQUENCY * 4); - gpio_set_pin_direction(D1, GPIO_DIRECTION_IN); - gpio_set_pin_function(D1, PINMUX_PB00C_SERCOM3_PAD2); + gpio_set_pin_direction(A2, GPIO_DIRECTION_OUT); + gpio_set_pin_function(A2, PINMUX_PB02C_SERCOM3_PAD0); MCLK->APBCMASK.reg |= MCLK_APBCMASK_SERCOM3; @@ -66,7 +66,7 @@ void watch_enable_debug_uart(uint32_t baud) { SERCOM3->USART.CTRLA.reg = SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_MODE(1/*USART_INT_CLK*/) | - SERCOM_USART_CTRLA_RXPO(0/*PAD0*/) | SERCOM_USART_CTRLA_TXPO(1/*PAD2*/); + SERCOM_USART_CTRLA_RXPO(1/*PAD1*/) | SERCOM_USART_CTRLA_TXPO(0/*PAD0*/); SERCOM3->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_CHSIZE(0/*8 bits*/); |