166 lines
5.1 KiB
C
166 lines
5.1 KiB
C
|
|
|
|
#include <rtthread.h>
|
|
#include <rtdevice.h>
|
|
|
|
#define FXAS2100_DEV_NAME ("fxas2100")
|
|
#define FXAS2100_I2C_DEV_NAME ("i2c2")
|
|
#define FXAS2100_CHIP_ADDR (0x20)
|
|
|
|
// register addresses FXAS21002C_H_
|
|
#define FXAS21002C_H_STATUS 0x00
|
|
#define FXAS21002C_H_DR_STATUS 0x07
|
|
#define FXAS21002C_H_F_STATUS 0x08
|
|
#define FXAS21002C_H_OUT_X_MSB 0x01
|
|
#define FXAS21002C_H_OUT_X_LSB 0x02
|
|
#define FXAS21002C_H_OUT_Y_MSB 0x03
|
|
#define FXAS21002C_H_OUT_Y_LSB 0x04
|
|
#define FXAS21002C_H_OUT_Z_MSB 0x05
|
|
#define FXAS21002C_H_OUT_Z_LSB 0x06
|
|
#define FXAS21002C_H_F_SETUP 0x09
|
|
#define FXAS21002C_H_F_EVENT 0x0A
|
|
#define FXAS21002C_H_INT_SRC_FLAG 0x0B
|
|
#define FXAS21002C_H_WHO_AM_I 0x0C
|
|
#define FXAS21002C_H_CTRL_REG0 0x0D
|
|
#define FXAS21002C_H_RT_CFG 0x0E
|
|
#define FXAS21002C_H_RT_SRC 0x0F
|
|
#define FXAS21002C_H_RT_THS 0x10
|
|
#define FXAS21002C_H_RT_COUNT 0x11
|
|
#define FXAS21002C_H_TEMP 0x12
|
|
#define FXAS21002C_H_CTRL_REG1 0x13
|
|
#define FXAS21002C_H_CTRL_REG2 0x14
|
|
#define FXAS21002C_H_CTRL_REG3 0x15
|
|
|
|
#define DBG_TAG "drv.fxas2100"
|
|
#define DBG_LVL DBG_LOG
|
|
#include <rtdbg.h>
|
|
|
|
|
|
|
|
typedef struct
|
|
{
|
|
struct rt_device parent;
|
|
struct rt_i2c_bus_device *bus;
|
|
uint8_t i2c_addr;
|
|
}fxas2100_t;
|
|
|
|
|
|
static uint8_t fxos_read_reg(fxas2100_t *dev, uint8_t reg_addr)
|
|
{
|
|
uint8_t val;
|
|
|
|
rt_i2c_master_send(dev->bus, dev->i2c_addr, RT_I2C_WR, ®_addr, 1);
|
|
rt_i2c_master_recv(dev->bus, dev->i2c_addr, RT_I2C_RD, &val, 1);
|
|
return val;
|
|
}
|
|
|
|
|
|
static void fxos_write_reg(fxas2100_t *dev, uint8_t reg_addr, uint8_t val)
|
|
{
|
|
uint8_t buf[2];
|
|
buf[0] = reg_addr;
|
|
buf[1] = val;
|
|
|
|
rt_i2c_master_send(dev->bus, dev->i2c_addr, RT_I2C_WR, buf, 2);
|
|
}
|
|
|
|
|
|
|
|
static rt_err_t fxas2100_open(rt_device_t dev, rt_uint16_t oflag)
|
|
{
|
|
int i;
|
|
uint8_t val;
|
|
|
|
fxas2100_t *fxas2100 = (fxas2100_t *)dev;
|
|
|
|
for(i=0; i<5; i++)
|
|
{
|
|
val = fxos_read_reg(fxas2100, 0x0C);
|
|
|
|
if(val == 0xD7)
|
|
{
|
|
LOG_D("fxas2100 found, id:0x%X", val);
|
|
/* stand by */
|
|
val = fxos_read_reg(fxas2100, FXAS21002C_H_CTRL_REG1);
|
|
fxos_write_reg(fxas2100, FXAS21002C_H_CTRL_REG1, val & ~(0x03));
|
|
|
|
// Disable FIFO, route FIFO and rate threshold interrupts to INT2, enable data ready interrupt, route to INT1
|
|
// Active HIGH, push-pull output driver on interrupts
|
|
fxos_write_reg(fxas2100, FXAS21002C_H_CTRL_REG2, 0x0E);
|
|
fxos_write_reg(fxas2100, FXAS21002C_H_CTRL_REG0, 0x80);
|
|
|
|
// Set up rate threshold detection; at max rate threshold = FSR; rate threshold = THS*FSR/128
|
|
fxos_write_reg(fxas2100, FXAS21002C_H_RT_CFG, 0x07); // enable rate threshold detection on all axes
|
|
fxos_write_reg(fxas2100, FXAS21002C_H_RT_THS, 0x00 | 0x0D); // unsigned 7-bit THS, set to one-tenth FSR; set clearing debounce counter
|
|
fxos_write_reg(fxas2100, FXAS21002C_H_RT_COUNT, 0x04); // set to 4 (can set up to 255)
|
|
|
|
val = fxos_read_reg(fxas2100, FXAS21002C_H_CTRL_REG1);
|
|
fxos_write_reg(fxas2100, FXAS21002C_H_CTRL_REG1, val & ~(0x03)); // Clear bits 0 and 1; standby mode
|
|
fxos_write_reg(fxas2100, FXAS21002C_H_CTRL_REG1, val | 0x02); // Set bit 1 to 1, active mode; data acquisition enabled
|
|
return RT_EOK;
|
|
}
|
|
else
|
|
{
|
|
LOG_D("fxas2100 cannot found, id:0x%X", val);
|
|
}
|
|
|
|
}
|
|
|
|
return RT_ERROR;
|
|
}
|
|
|
|
|
|
static rt_ssize_t fxas2100_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
|
|
{
|
|
fxas2100_t *fxas2100 = (fxas2100_t *)dev;
|
|
|
|
uint8_t buf[12];
|
|
buf[0] = FXAS21002C_H_OUT_X_MSB;
|
|
|
|
rt_i2c_master_send(fxas2100->bus, fxas2100->i2c_addr, RT_I2C_WR, buf, 1);
|
|
rt_i2c_master_recv(fxas2100->bus, fxas2100->i2c_addr, RT_I2C_RD, buf, 6);
|
|
|
|
|
|
int16_t idata[3];
|
|
idata[0] = (int16_t)((((int16_t)buf[0] << 8) | buf[1]));
|
|
idata[1] = (int16_t)((((int16_t)buf[2] << 8) | buf[3]));
|
|
idata[2] = (int16_t)((((int16_t)buf[4] << 8) | buf[5]));
|
|
|
|
float *out_buf = buffer;
|
|
|
|
out_buf[0] = (float)idata[0] *(2000.0F/32768.0F);
|
|
out_buf[1] = (float)idata[1] *(2000.0F/32768.0F);
|
|
out_buf[2] = (float)idata[2] *(2000.0F/32768.0F);
|
|
}
|
|
|
|
|
|
int rt_hw_fxas2100_init(void)
|
|
{
|
|
static fxas2100_t fxas2100;
|
|
struct rt_i2c_bus_device *bus;
|
|
|
|
bus = rt_i2c_bus_device_find(FXAS2100_I2C_DEV_NAME);
|
|
if (bus == RT_NULL)
|
|
{
|
|
return RT_ENOSYS;
|
|
}
|
|
|
|
fxas2100.parent.type = RT_Device_Class_Sensor;
|
|
fxas2100.parent.rx_indicate = RT_NULL;
|
|
fxas2100.parent.tx_complete = RT_NULL;
|
|
fxas2100.parent.init = RT_NULL;
|
|
fxas2100.parent.open = fxas2100_open;
|
|
fxas2100.parent.close = RT_NULL;
|
|
fxas2100.parent.read = fxas2100_read;
|
|
fxas2100.parent.write = RT_NULL;
|
|
fxas2100.parent.user_data = RT_NULL;
|
|
|
|
fxas2100.bus = bus;
|
|
fxas2100.i2c_addr = FXAS2100_CHIP_ADDR;
|
|
|
|
rt_device_register(&fxas2100.parent, FXAS2100_DEV_NAME, RT_DEVICE_FLAG_RDWR);
|
|
return RT_EOK;
|
|
}
|
|
|
|
INIT_DEVICE_EXPORT(rt_hw_fxas2100_init);
|