diff --git a/watch-library/shared/driver/lis2dw.c b/watch-library/shared/driver/lis2dw.c index e7ccf2d2..b716f790 100644 --- a/watch-library/shared/driver/lis2dw.c +++ b/watch-library/shared/driver/lis2dw.c @@ -26,6 +26,7 @@ #include "watch.h" bool lis2dw_begin(void) { +#ifdef I2C_SERCOM if (lis2dw_get_device_id() != LIS2DW_WHO_AM_I_VAL) { return false; } @@ -45,21 +46,33 @@ bool lis2dw_begin(void) { // * FIFO disabled return true; +#else + return false; +#endif } uint8_t lis2dw_get_device_id(void) { +#ifdef I2C_SERCOM return watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_WHO_AM_I); +#else + return 0; +#endif } bool lis2dw_have_new_data(void) { +#ifdef I2C_SERCOM uint8_t retval = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_STATUS); return retval & LIS2DW_STATUS_VAL_DRDY; +#else + return false; +#endif } lis2dw_reading_t lis2dw_get_raw_reading(void) { + lis2dw_reading_t retval = {0}; +#ifdef I2C_SERCOM uint8_t buffer[6]; uint8_t reg = LIS2DW_REG_OUT_X_L | 0x80; // set high bit for consecutive reads - lis2dw_reading_t retval; watch_i2c_send(LIS2DW_ADDRESS, ®, 1); watch_i2c_receive(LIS2DW_ADDRESS, (uint8_t *)&buffer, 6); @@ -70,11 +83,15 @@ lis2dw_reading_t lis2dw_get_raw_reading(void) { retval.y |= ((uint16_t)buffer[3]) << 8; retval.z = buffer[4]; retval.z |= ((uint16_t)buffer[5]) << 8; - +#endif + return retval; } - lis2dw_acceleration_measurement_t lis2dw_get_acceleration_measurement(lis2dw_reading_t *out_reading) { +lis2dw_acceleration_measurement_t lis2dw_get_acceleration_measurement(lis2dw_reading_t *out_reading) { + lis2dw_acceleration_measurement_t retval = {0}; + + #ifdef I2C_SERCOM lis2dw_reading_t reading = lis2dw_get_raw_reading(); /// FIXME: We should stash the range in a static variable to avoid reading this every time, but /// I'm not sure the values cribbed from Adafruit's LID3DH driver are right for the LIS2DW. @@ -93,109 +110,175 @@ lis2dw_reading_t lis2dw_get_raw_reading(void) { if (range == LIS2DW_RANGE_8_G) lsb_value = 16; if (range == LIS2DW_RANGE_16_G) lsb_value = 48; - lis2dw_acceleration_measurement_t retval; - retval.x = lsb_value * ((float)reading.x / 64000.0); retval.y = lsb_value * ((float)reading.y / 64000.0); retval.z = lsb_value * ((float)reading.z / 64000.0); +#else + (void) out_reading; +#endif return retval; } uint16_t lis2dw_get_temperature(void) { +#ifdef I2C_SERCOM return watch_i2c_read16(LIS2DW_ADDRESS, LIS2DW_REG_OUT_TEMP_L); +#else + return 0; +#endif } void lis2dw_set_data_rate(lis2dw_data_rate_t dataRate) { +#ifdef I2C_SERCOM 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); +#else + (void)dataRate; +#endif } lis2dw_data_rate_t lis2dw_get_data_rate(void) { +#ifdef I2C_SERCOM return watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1) >> 4; +#else + return 0; +#endif } void lis2dw_set_mode(lis2dw_mode_t mode) { +#ifdef I2C_SERCOM uint8_t val = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1) & ~(0b1100); uint8_t bits = (mode << 2) & 0b1100; watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1, val | bits); +#else + (void)mode; +#endif } lis2dw_mode_t lis2dw_get_mode(void) { +#ifdef I2C_SERCOM return (lis2dw_mode_t)(watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1) & 0b1100) >> 2; +#else + return 0; +#endif } void lis2dw_set_low_power_mode(lis2dw_low_power_mode_t mode) { +#ifdef I2C_SERCOM 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); +#else + (void)mode; +#endif } lis2dw_low_power_mode_t lis2dw_get_low_power_mode(void) { +#ifdef I2C_SERCOM return watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1) & 0b11; +#else + return 0; +#endif } void lis2dw_set_bandwidth_filtering(lis2dw_bandwidth_filtering_mode_t bwfilter) { +#ifdef I2C_SERCOM uint8_t val = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL6) & ~(LIS2DW_CTRL6_VAL_BANDWIDTH_DIV20); uint8_t bits = bwfilter << 6; watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL6, val | bits); +#else + (void)bwfilter; +#endif } lis2dw_bandwidth_filtering_mode_t lis2dw_get_bandwidth_filtering(void) { +#ifdef I2C_SERCOM uint8_t retval = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL6) & (LIS2DW_CTRL6_VAL_BANDWIDTH_DIV20); retval >>= 6; return (lis2dw_bandwidth_filtering_mode_t)retval; +#else + return 0; +#endif } void lis2dw_set_range(lis2dw_range_t range) { +#ifdef I2C_SERCOM 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_CTRL6, val | bits); +#else + (void)range; +#endif } lis2dw_range_t lis2dw_get_range(void) { +#ifdef I2C_SERCOM uint8_t retval = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL6) & (LIS2DW_RANGE_16_G << 4); retval >>= 4; return (lis2dw_range_t)retval; +#else + return 0; +#endif } void lis2dw_set_filter_type(lis2dw_filter_t bwfilter) { +#ifdef I2C_SERCOM uint8_t val = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL6) & ~(LIS2DW_CTRL6_VAL_FDS_HIGH); uint8_t bits = bwfilter << 3; watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL6, val | bits); +#else + (void)bwfilter; +#endif } lis2dw_filter_t lis2dw_get_filter_type(void) { +#ifdef I2C_SERCOM uint8_t retval = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL6) & (LIS2DW_CTRL6_VAL_FDS_HIGH); retval >>= 3; return (lis2dw_filter_t)retval; +#else + return 0; +#endif } void lis2dw_set_low_noise_mode(bool on) { +#ifdef I2C_SERCOM uint8_t val = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL6) & ~(LIS2DW_CTRL6_VAL_LOW_NOISE); uint8_t bits = on ? LIS2DW_CTRL6_VAL_LOW_NOISE : 0; watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL6, val | bits); +#else + (void)on; +#endif } bool lis2dw_get_low_noise_mode(void) { +#ifdef I2C_SERCOM return (watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1) & LIS2DW_CTRL6_VAL_LOW_NOISE) != 0; +#else + return false; +#endif } inline void lis2dw_enable_fifo(void) { +#ifdef I2C_SERCOM watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_FIFO_CTRL, LIS2DW_FIFO_CTRL_MODE_COLLECT_AND_STOP | LIS2DW_FIFO_CTRL_FTH); +#endif } inline void lis2dw_disable_fifo(void) { +#ifdef I2C_SERCOM watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_FIFO_CTRL, LIS2DW_FIFO_CTRL_MODE_OFF); +#endif } bool lis2dw_read_fifo(lis2dw_fifo_t *fifo_data) { +#ifdef I2C_SERCOM uint8_t temp = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_FIFO_SAMPLE); bool overrun = !!(temp & LIS2DW_FIFO_SAMPLE_OVERRUN); @@ -206,44 +289,67 @@ bool lis2dw_read_fifo(lis2dw_fifo_t *fifo_data) { } return overrun; +#else + (void) fifo_data; + return false; +#endif } void lis2dw_clear_fifo(void) { +#ifdef I2C_SERCOM watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_FIFO_CTRL, LIS2DW_FIFO_CTRL_MODE_OFF); watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_FIFO_CTRL, LIS2DW_FIFO_CTRL_MODE_COLLECT_AND_STOP | LIS2DW_FIFO_CTRL_FTH); +#endif } void lis2dw_enable_sleep(void) { +#ifdef I2C_SERCOM uint8_t configuration = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_WAKE_UP_THS); watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_WAKE_UP_THS, configuration | LIS2DW_WAKE_UP_THS_VAL_SLEEP_ON); +#endif } void lis2dw_disable_sleep(void) { +#ifdef I2C_SERCOM uint8_t configuration = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_WAKE_UP_THS); watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_WAKE_UP_THS, configuration & ~LIS2DW_WAKE_UP_THS_VAL_SLEEP_ON); +#endif } void lis2dw_enable_stationary_motion_detection(void) { +#ifdef I2C_SERCOM uint8_t configuration = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_WAKE_UP_DUR); watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_WAKE_UP_DUR, configuration | LIS2DW_WAKE_UP_DUR_STATIONARY); +#endif } void lis2dw_disable_stationary_motion_detection(void) { +#ifdef I2C_SERCOM uint8_t configuration = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_WAKE_UP_DUR); watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_WAKE_UP_DUR, configuration & ~LIS2DW_WAKE_UP_DUR_STATIONARY); +#endif } void lis2dw_configure_wakeup_threshold(uint8_t threshold) { +#ifdef I2C_SERCOM uint8_t configuration = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_WAKE_UP_THS) & 0b11000000; watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_WAKE_UP_THS, configuration | threshold); +#else + (void)threshold; +#endif } void lis2dw_configure_6d_threshold(uint8_t threshold) { +#ifdef I2C_SERCOM uint8_t configuration = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_TAP_THS_X) & 0b01100000; watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_TAP_THS_X, configuration | ((threshold & 0b11) << 5)); +#else + (void)threshold; +#endif } void lis2dw_configure_tap_threshold(uint8_t threshold_x, uint8_t threshold_y, uint8_t threshold_z, uint8_t axes_to_enable) { +#ifdef I2C_SERCOM (void) threshold_x; (void) threshold_y; uint8_t configuration; @@ -256,39 +362,75 @@ void lis2dw_configure_tap_threshold(uint8_t threshold_x, uint8_t threshold_y, ui configuration |= (threshold_z & 0b00011111); } watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_TAP_THS_Z, configuration); +#else + (void)threshold_x; + (void)threshold_y; + (void)threshold_z; + (void)axes_to_enable; +#endif } void lis2dw_configure_tap_duration(uint8_t latency, uint8_t quiet, uint8_t shock) { +#ifdef I2C_SERCOM uint8_t configuration = (latency << 4) | ((quiet & 0b11) << 2) | (shock & 0b11); watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_INT1_DUR, configuration); +#else + (void)latency; + (void)quiet; + (void)shock; +#endif } void lis2dw_configure_int1(uint8_t sources) { +#ifdef I2C_SERCOM watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL4_INT1, sources); +#else + (void)sources; +#endif } void lis2dw_configure_int2(uint8_t sources) { +#ifdef I2C_SERCOM watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL5_INT2, sources); +#else + (void)sources; +#endif } void lis2dw_enable_interrupts(void) { +#ifdef I2C_SERCOM uint8_t configuration = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL7); watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL7, configuration | LIS2DW_CTRL7_VAL_INTERRUPTS_ENABLE); +#endif } void lis2dw_disable_interrupts(void) { +#ifdef I2C_SERCOM uint8_t configuration = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL7); watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL7, configuration & ~LIS2DW_CTRL7_VAL_INTERRUPTS_ENABLE); +#endif } lis2dw_wakeup_source_t lis2dw_get_wakeup_source() { +#ifdef I2C_SERCOM return (lis2dw_wakeup_source_t) watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_WAKE_UP_SRC); +#else + return 0; +#endif } lis2dw_interrupt_source_t lis2dw_get_interrupt_source(void) { +#ifdef I2C_SERCOM return (lis2dw_interrupt_source_t) watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_ALL_INT_SRC); +#else + return 0; +#endif } uint8_t lis2dw_get_wakeup_threshold(void) { +#ifdef I2C_SERCOM return watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_WAKE_UP_THS) & 0b00111111; +#else + return 0; +#endif }