My intended purpose is to read the latest 64*2 sets of three-axis data from the FIFO, as configured in my setup: I have configured the FIFO in stream mode, set the FIFO_SAMPLES register to 64, and set the ODR to 400Hz. Of course, I'm not using interrupts but polling once per second to read data.
I believed that when reading from the FIFO via I2C, there should be 64*2 sets of three-axis data, with older data being discarded; however, in practice, I observe that the FIFO is always full (513 data points) when I read it, which is confusing to me. Could you help explain this?
My requirement is to poll the FIFO once per second to read data, and I expect the FIFO to keep only the latest 64 sets of data in the FIFO.
Here is my detailed code.
#include <stdlib.h>
#include "adxl367.h"
#include "nrf_drv_twi.h"
#include "sample_mode.h"
#include "nrf_delay.h"
static const nrf_drv_twi_t * p_twi;
uint32_t adxl367_set_register_value(uint8_t register_value, uint8_t register_address)
{
uint8_t buffer[2] = {0};
buffer[0] = register_address;
buffer[1] = register_value;
return nrf_drv_twi_tx(p_twi, I2C_AXI_ADDR, buffer, 2, false);
}
uint32_t adxl367_get_register_value(uint8_t* read_data, uint8_t register_address, uint8_t register_nb)
{
int ret = 1;
uint8_t buffer[64] = {0};
if (register_address > ADXL367_REG_STATUS_2)
return ret;
ret = nrf_drv_twi_tx(p_twi, I2C_AXI_ADDR, ®ister_address, 1, false);
if (ret)
return ret;
ret = nrf_drv_twi_rx(p_twi, I2C_AXI_ADDR, buffer, register_nb);
if (ret)
return ret;
for(int index = 0; index < register_nb; index++)
read_data[index] = buffer[index];
return 0;
}
int adx1367_get_raw_xyz(uint16_t* x, uint16_t* y, uint16_t* z)
{
uint8_t xyz_values[3] = {0};
uint8_t reg_data = 0;
adxl367_get_register_value(®_data, ADXL367_REG_STATUS, 1);
if(reg_data & 1){
adxl367_get_register_value(xyz_values, ADXL367_REG_XDATA, 3);
*x = xyz_values[0] << 6;
*y = xyz_values[1] << 6;
*z = xyz_values[2] << 6;
if(*x & 0x2000){
*x |= 0xC000;
}
if(*y & 0x2000){
*y |= 0xC000;
}
if(*z & 0x2000){
*z |= 0xC000;
}
}
else{
*x = 0;
*y = 0;
*z = 0;
}
return 0;
}
uint16_t adx1367_get_fifo_xyz(uint16_t *buff)
{
uint8_t data_buff[512 * 2] = {0};
uint16_t fifo_entries = 0;
uint8_t reg_val[2] = {0};
adxl367_get_register_value(®_val[0], ADXL367_REG_STATUS, 1);
if(reg_val[0] & 1 << 2){
adxl367_get_register_value(reg_val, ADXL367_REG_FIFO_ENTRIES_L, 2);
fifo_entries = ((reg_val[1] & 0x03) << 8) | reg_val[0];
if((0 == fifo_entries)){
return 0;
}
adxl367_get_register_value(data_buff, ADXL367_REG_I2C_FIFO_DATA, fifo_entries);
fifo_entries = (fifo_entries > SAMPLE_DEFAULT_AXI_HZ*6 ? SAMPLE_DEFAULT_AXI_HZ*6:fifo_entries);
for(int index = 0; index < fifo_entries; index++){
buff[index] = (data_buff[index * 2] << 6) + (data_buff[index*2 + 1] >> 2);
}
return fifo_entries;
}
return 0;
}
void adxl367_fifo_setup(void)
{
sample_mode_info_t *p_sample = NULL;
uint8_t reg_value = 0;
p_sample = sample_config_get();
// Set fifo stream mode
adxl367_get_register_value(®_value, ADXL367_REG_FIFO_CONTROL, 1);
reg_value &= ~(3);
reg_value |= ADXL367_STREAM_MODE;
// Set fifo sample x,y,z
reg_value &= ~(0x0F << 3);
// set fifo sample 64
reg_value &= ~(1 << 2);
adxl367_set_register_value(reg_value, ADXL367_REG_FIFO_CONTROL);
// set fifo sample 64
reg_value = 0;
adxl367_get_register_value(®_value, ADXL367_REG_FIFO_SAMPLES, 1);
reg_value = p_sample->sample_axi_hz;
adxl367_set_register_value(reg_value, ADXL367_REG_FIFO_SAMPLES);
}
int adxl367_start(void)
{
int status = 0;
uint8_t reg_value = 0;
//adxl367_fifo_setup();
// set measure mode
adxl367_get_register_value(®_value, ADXL367_REG_POWER_CTL, 1);
reg_value &= ~(3);
reg_value |= 2;
status = adxl367_set_register_value(reg_value, ADXL367_REG_POWER_CTL);
if (status)
return -1;
nrf_delay_ms(100);
return 0;
}
int adxl367_stop(void)
{
int status;
uint8_t reg_value = 0;
reg_value = 0;
adxl367_get_register_value(®_value, ADXL367_REG_POWER_CTL, 1);
// set standby mode
reg_value &= ~(3);
status = adxl367_set_register_value(reg_value, ADXL367_REG_POWER_CTL);
if (status)
return -1;
nrf_delay_ms(50);
return 0;
}
int ADXl367_Init(nrf_drv_twi_t *hi2c)
{
int status;
uint8_t reg_value = 0;
p_twi = NULL;
if(NULL == hi2c)
return -1;
p_twi = hi2c;
/* Perform soft reset */
status = adxl367_set_register_value(ADXL367_RESET_KEY, ADXL367_REG_SOFT_RESET);
if (status)
return -1;
nrf_delay_ms(20);
// check device id
adxl367_get_register_value(®_value, ADXL367_REG_DEVID_AD, 1);
if (reg_value != ADXL367_DEVICE_AD)
return -1;
adxl367_get_register_value(®_value, ADXL367_REG_PARTID, 1);
if (reg_value != ADXL367_PART_ID)
return -1;
// set device output speed 200Hz and range to 4G
reg_value = 0;
adxl367_get_register_value(®_value, ADXL367_REG_FILTER_CTL, 1);
reg_value &= ~(3 << 6);
reg_value |= (1 << 6);
reg_value &= ~7;
reg_value |= 4;
status = adxl367_set_register_value(reg_value, ADXL367_REG_FILTER_CTL);
if (status)
return -1;
return 0;
}