lis2dw: add FIFO support
This commit is contained in:
		
							parent
							
								
									deda65b313
								
							
						
					
					
						commit
						0c59c972e7
					
				@ -24,17 +24,13 @@ static void cb_tick(void) {
 | 
			
		||||
    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);
 | 
			
		||||
    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);
 | 
			
		||||
    lis2dw_fifo_t fifo;
 | 
			
		||||
    bool overrun = lis2dw_read_fifo(&fifo);
 | 
			
		||||
    printf("FIFO captured %d readings.\n", fifo.count);
 | 
			
		||||
    if (overrun) printf("\tThere was an overrun!\n\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_init(void) {
 | 
			
		||||
    watch_enable_debug_uart(460800); // this is glitchy now, but this enables a baud rate of 115200 when USB is disabled.
 | 
			
		||||
 | 
			
		||||
    watch_enable_display();
 | 
			
		||||
    watch_display_string("AC  Strean", 0);
 | 
			
		||||
 | 
			
		||||
@ -45,12 +41,14 @@ 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_low_noise_mode(true); // consumes a little more power
 | 
			
		||||
    lis2dw_set_range(LIS2DW_CTRL6_VAL_RANGE_4G);
 | 
			
		||||
    lis2dw_set_data_rate(LIS2DW_DATA_RATE_25_HZ); // is this enough for training?
 | 
			
		||||
 | 
			
		||||
    watch_rtc_register_periodic_callback(cb_tick, 64);
 | 
			
		||||
    lis2dw_enable_fifo();
 | 
			
		||||
 | 
			
		||||
    watch_rtc_register_periodic_callback(cb_tick, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_wake_from_backup(void) {
 | 
			
		||||
 | 
			
		||||
@ -50,10 +50,10 @@ bool lis2dw_have_new_data(void) {
 | 
			
		||||
    return retval & LIS2DW_STATUS_VAL_DRDY;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
lis2dw_reading lis2dw_get_raw_reading(void) {
 | 
			
		||||
lis2dw_reading_t lis2dw_get_raw_reading(void) {
 | 
			
		||||
    uint8_t buffer[6];
 | 
			
		||||
    uint8_t reg = LIS2DW_REG_OUT_X_L | 0x80; // set high bit for consecutive reads
 | 
			
		||||
    lis2dw_reading retval;
 | 
			
		||||
    lis2dw_reading_t retval;
 | 
			
		||||
 | 
			
		||||
    watch_i2c_send(LIS2DW_ADDRESS, ®, 1);
 | 
			
		||||
    watch_i2c_receive(LIS2DW_ADDRESS, (uint8_t *)&buffer, 6);
 | 
			
		||||
@ -68,8 +68,8 @@ lis2dw_reading lis2dw_get_raw_reading(void) {
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 lis2dw_acceleration_measurement lis2dw_get_acceleration_measurement(lis2dw_reading *out_reading) {
 | 
			
		||||
    lis2dw_reading reading = lis2dw_get_raw_reading();
 | 
			
		||||
 lis2dw_acceleration_measurement_t lis2dw_get_acceleration_measurement(lis2dw_reading_t *out_reading) {
 | 
			
		||||
    lis2dw_reading_t reading = lis2dw_get_raw_reading();
 | 
			
		||||
    uint8_t range = lis2dw_get_range();
 | 
			
		||||
    if (out_reading != NULL) *out_reading = reading;
 | 
			
		||||
 | 
			
		||||
@ -82,7 +82,7 @@ lis2dw_reading 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 retval;
 | 
			
		||||
    lis2dw_acceleration_measurement_t retval;
 | 
			
		||||
 | 
			
		||||
    retval.x = lsb_value * ((float)reading.x / 64000.0);
 | 
			
		||||
    retval.y = lsb_value * ((float)reading.y / 64000.0);
 | 
			
		||||
@ -104,7 +104,6 @@ lis2dw_range_t lis2dw_get_range(void) {
 | 
			
		||||
    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) & ~(0b1111 << 4);
 | 
			
		||||
    uint8_t bits = dataRate << 4;
 | 
			
		||||
@ -137,3 +136,31 @@ void lis2dw_set_low_noise_mode(bool on) {
 | 
			
		||||
bool lis2dw_get_low_noise_mode(void) {
 | 
			
		||||
    return (watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL1) & LIS2DW_CTRL6_VAL_LOW_NOISE) != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void lis2dw_disable_fifo(void) {
 | 
			
		||||
    watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_FIFO_CTRL, LIS2DW_FIFO_CTRL_MODE_OFF);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void lis2dw_enable_fifo(void) {
 | 
			
		||||
    watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_FIFO_CTRL, LIS2DW_FIFO_CTRL_MODE_COLLECT_AND_STOP | LIS2DW_FIFO_CTRL_FTH);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool lis2dw_read_fifo(lis2dw_fifo_t *fifo_data) {
 | 
			
		||||
    uint8_t temp = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_FIFO_SAMPLE);
 | 
			
		||||
    bool overrun = !!(temp & LIS2DW_FIFO_SAMPLE_OVERRUN);
 | 
			
		||||
    uint8_t buffer[6];
 | 
			
		||||
 | 
			
		||||
    fifo_data->count = temp & LIS2DW_FIFO_SAMPLE_COUNT;
 | 
			
		||||
 | 
			
		||||
    for(int i = 0; i < fifo_data->count; i++) {
 | 
			
		||||
        watch_i2c_receive(LIS2DW_ADDRESS, (uint8_t *)&buffer, 6);
 | 
			
		||||
        fifo_data->readings[i] = lis2dw_get_raw_reading();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return overrun;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lis2dw_clear_fifo(void) {
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -32,13 +32,18 @@ typedef struct {
 | 
			
		||||
    int16_t x;
 | 
			
		||||
    int16_t y;
 | 
			
		||||
    int16_t z;
 | 
			
		||||
} lis2dw_reading;
 | 
			
		||||
} lis2dw_reading_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    float x;
 | 
			
		||||
    float y;
 | 
			
		||||
    float z;
 | 
			
		||||
} lis2dw_acceleration_measurement;
 | 
			
		||||
} lis2dw_acceleration_measurement_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    int8_t count;
 | 
			
		||||
    lis2dw_reading_t readings[32];
 | 
			
		||||
} lis2dw_fifo_t;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  LIS2DW_DATA_RATE_POWERDOWN = 0,
 | 
			
		||||
@ -60,6 +65,14 @@ typedef enum {
 | 
			
		||||
  LIS2DW_MODE_ON_DEMAND = 0b10,
 | 
			
		||||
} lis2dw_mode_t;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  LIS2DW_FIFO_MODE_OFF = 0b000,
 | 
			
		||||
  LIS2DW_FIFO_MODE_COLLECT_AND_STOP = 0b001,
 | 
			
		||||
  LIS2DW_FIFO_MODE_CONTINUOUS_TO_FIFO = 0b011,
 | 
			
		||||
  LIS2DW_FIFO_MODE_BYPASS_TO_CONTINUOUS = 0b100,
 | 
			
		||||
  LIS2DW_FIFO_MODE_COLLECT_CONTINUOUS = 0b110,
 | 
			
		||||
} lis2dw_fifo_mode_t;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  LIS2DW_LP_MODE_1 = 0b00, // 12-bit
 | 
			
		||||
  LIS2DW_LP_MODE_2 = 0b01, // 14-bit
 | 
			
		||||
@ -177,7 +190,17 @@ typedef enum {
 | 
			
		||||
#define LIS2DW_REG_OUT_Z_H 0x2D
 | 
			
		||||
 | 
			
		||||
#define LIS2DW_REG_FIFO_CTRL 0x2E
 | 
			
		||||
#define LIS2DW_REG_FIFO_SRC 0x2F
 | 
			
		||||
#define LIS2DW_FIFO_CTRL_MODE_OFF                   (LIS2DW_FIFO_MODE_OFF << 5)
 | 
			
		||||
#define LIS2DW_FIFO_CTRL_MODE_COLLECT_AND_STOP      (LIS2DW_FIFO_MODE_COLLECT_AND_STOP << 5)
 | 
			
		||||
#define LIS2DW_FIFO_CTRL_MODE_CONTINUOUS_TO_FIFO    (LIS2DW_FIFO_MODE_CONTINUOUS_TO_FIFO << 5)
 | 
			
		||||
#define LIS2DW_FIFO_CTRL_MODE_BYPASS_TO_CONTINUOUS  (LIS2DW_FIFO_MODE_BYPASS_TO_CONTINUOUS << 5)
 | 
			
		||||
#define LIS2DW_FIFO_CTRL_MODE_COLLECT_CONTINUOUS    (LIS2DW_FIFO_MODE_COLLECT_CONTINUOUS << 5)
 | 
			
		||||
#define LIS2DW_FIFO_CTRL_FTH                        (0b00011111)
 | 
			
		||||
 | 
			
		||||
#define LIS2DW_REG_FIFO_SAMPLE 0x2F
 | 
			
		||||
#define LIS2DW_FIFO_SAMPLE_THRESHOLD (1 << 7)
 | 
			
		||||
#define LIS2DW_FIFO_SAMPLE_OVERRUN (1 << 6)
 | 
			
		||||
#define LIS2DW_FIFO_SAMPLE_COUNT (0b00111111)
 | 
			
		||||
 | 
			
		||||
#define LIS2DW_REG_TAP_THS_X 0x30
 | 
			
		||||
#define LIS2DW_REG_TAP_THS_Y 0x31
 | 
			
		||||
@ -242,9 +265,9 @@ uint8_t lis2dw_get_device_id(void);
 | 
			
		||||
 | 
			
		||||
bool lis2dw_have_new_data(void);
 | 
			
		||||
 | 
			
		||||
lis2dw_reading lis2dw_get_raw_reading(void);
 | 
			
		||||
lis2dw_reading_t lis2dw_get_raw_reading(void);
 | 
			
		||||
 | 
			
		||||
lis2dw_acceleration_measurement lis2dw_get_acceleration_measurement(lis2dw_reading *out_reading);
 | 
			
		||||
lis2dw_acceleration_measurement_t lis2dw_get_acceleration_measurement(lis2dw_reading_t *out_reading);
 | 
			
		||||
 | 
			
		||||
void lis2dw_set_range(lis2dw_range_t range);
 | 
			
		||||
 | 
			
		||||
@ -262,4 +285,12 @@ void lis2dw_set_low_noise_mode(bool on);
 | 
			
		||||
 | 
			
		||||
bool lis2dw_get_low_noise_mode(void);
 | 
			
		||||
 | 
			
		||||
void lis2dw_disable_fifo(void);
 | 
			
		||||
 | 
			
		||||
void lis2dw_enable_fifo(void);
 | 
			
		||||
 | 
			
		||||
bool lis2dw_read_fifo(lis2dw_fifo_t *fifo_data);
 | 
			
		||||
 | 
			
		||||
void lis2dw_clear_fifo(void);
 | 
			
		||||
 | 
			
		||||
#endif // LIS2DW_H
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user