From 8cc6cd96cb3023adf016515d68bf401868582b52 Mon Sep 17 00:00:00 2001 From: xdavidwu Date: Mon, 16 May 2022 17:30:00 +0800 Subject: [PATCH] sensors: add ADXL345 --- i2c/types.ha | 1 + sensors/ADXL345/ADXL345.ha | 41 ++++++++++++++++++++++++++++++++++++++ sensors/ADXL345/types.ha | 19 ++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 i2c/types.ha create mode 100644 sensors/ADXL345/ADXL345.ha create mode 100644 sensors/ADXL345/types.ha diff --git a/i2c/types.ha b/i2c/types.ha new file mode 100644 index 0000000..9339e00 --- /dev/null +++ b/i2c/types.ha @@ -0,0 +1 @@ +export def I2C_SLAVE: u64 = 0x0703; diff --git a/sensors/ADXL345/ADXL345.ha b/sensors/ADXL345/ADXL345.ha new file mode 100644 index 0000000..6c75b4e --- /dev/null +++ b/sensors/ADXL345/ADXL345.ha @@ -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); +}; diff --git a/sensors/ADXL345/types.ha b/sensors/ADXL345/types.ha new file mode 100644 index 0000000..2b7fed6 --- /dev/null +++ b/sensors/ADXL345/types.ha @@ -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; -- 2.45.2