~xdavidwu/motion-control

8cc6cd96cb3023adf016515d68bf401868582b52 — xdavidwu 2 years ago 8f3f04b
sensors: add ADXL345
3 files changed, 61 insertions(+), 0 deletions(-)

A i2c/types.ha
A sensors/ADXL345/ADXL345.ha
A sensors/ADXL345/types.ha
A i2c/types.ha => i2c/types.ha +1 -0
@@ 0,0 1,1 @@
export def I2C_SLAVE: u64	= 0x0703;

A sensors/ADXL345/ADXL345.ha => sensors/ADXL345/ADXL345.ha +41 -0
@@ 0,0 1,41 @@
use fmt;
use fs;
use i2c;
use i2c::smbus;
use io;
use os;
use rt;

export fn new(bus: int) (ADXL345 | fs::error | rt::errno) = {
	const path = fmt::asprintf("/dev/i2c-{}", bus);
	defer free(path);
	const file = os::open(path, fs::flags::RDONLY)?;
	rt::ioctl(file, i2c::I2C_SLAVE, 0x53)?;
	return alloc(ADXL345_impl {
		file = file,
	});
};

export fn init(sensor: ADXL345) (void | rt::errno) = {
	i2c::smbus::write_byte_data(sensor.file, REG_POWER_CTL, POWER_CTL_MEASURE)?;
	i2c::smbus::write_byte_data(sensor.file, REG_DATA_FORMAT, DATA_FORMAT_FULL_RES)?;
};

fn read_data(sensor: ADXL345, reg: u8) (f64 | rt::errno) = {
	const raw = i2c::smbus::read_word_data(sensor.file, reg)?;
	const raw = raw: i16;
	return raw: f64 * SCALE_FACTOR_FULL_RES;
};

export fn read(sensor: ADXL345) ((f64, f64, f64) | rt::errno) = {
	return (
		read_data(sensor, REG_DATAX0)?,
		read_data(sensor, REG_DATAY0)?,
		read_data(sensor, REG_DATAZ0)?,
	);
};

export fn destroy(sensor: ADXL345) void = {
	io::close(sensor.file)!;
	free(sensor);
};

A sensors/ADXL345/types.ha => sensors/ADXL345/types.ha +19 -0
@@ 0,0 1,19 @@
use io;

export type ADXL345_impl = struct {
	file: io::file,
};

export type ADXL345 = *ADXL345_impl;

def REG_POWER_CTL: u8	= 0x2d;
def POWER_CTL_MEASURE: u8	= 1 << 3;

def REG_DATA_FORMAT: u8	= 0x31;
def DATA_FORMAT_FULL_RES: u8	= 1 << 3;

def SCALE_FACTOR_FULL_RES: f64	= 1.0f64 / 256f64;

def REG_DATAX0: u8	= 0x32;
def REG_DATAY0: u8	= 0x34;
def REG_DATAZ0: u8	= 0x36;