From 43e8ae478f1d9380d00c346fa5fc7c77f3da7ae6 Mon Sep 17 00:00:00 2001 From: xdavidwu Date: Mon, 16 May 2022 19:25:43 +0800 Subject: [PATCH] i2c::smbus: implement completely in hare the c library is actually pretty simple to port this remove the need to link with c library --- Makefile | 2 +- i2c/smbus/libi2c.ha | 39 ++++++++++++++++++++++++++------------- i2c/smbus/types.ha | 27 +++++++++++++++++++++++++++ i2c/types.ha | 1 + 4 files changed, 55 insertions(+), 14 deletions(-) create mode 100644 i2c/smbus/types.ha diff --git a/Makefile b/Makefile index 4c2374d..b723c90 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ evdev-dump-events uinput-pointer: hare build -levdev -o $@ tools/$@/ gy-801-dump: - hare build -li2c -o $@ tools/$@/ + hare build -o $@ tools/$@/ .PHONY: evdev-dump-events uinput-pointer gy-801-dump diff --git a/i2c/smbus/libi2c.ha b/i2c/smbus/libi2c.ha index 7c55aad..d35b998 100644 --- a/i2c/smbus/libi2c.ha +++ b/i2c/smbus/libi2c.ha @@ -1,27 +1,40 @@ +use i2c; use io; use rt; +export fn access(file: io::file, read_write: u8, command: u8, _size: u32, data: *data) + (int | rt::errno) = { + const args = ioctl_data { + read_write = read_write, + command = command, + _size = _size, + data = data, + }; + return rt::ioctl(file: int, i2c::I2C_SMBUS, &args); +}; + export fn read_byte_data(file: io::file, command: u8) (u8 | rt::errno) = { - const res = c_i2c_smbus_read_byte_data(file: int, command); - return if (res < 0) res: rt::errno else res: u8; + const data = data {...}; + access(file, READ, command, BYTE_DATA, &data)?; + return data.byte; }; export fn read_word_data(file: io::file, command: u8) (u16 | rt::errno) = { - const res = c_i2c_smbus_read_word_data(file: int, command); - return if (res < 0) res: rt::errno else res: u16; + const data = data {...}; + access(file, READ, command, WORD_DATA, &data)?; + return data.word; }; export fn write_byte_data(file: io::file, command: u8, value: u8) (void | rt::errno) = { - const res = c_i2c_smbus_write_byte_data(file: int, command, value); - return if (res < 0) res: rt::errno else void; + const data = data { + byte = value, + }; + access(file, WRITE, command, BYTE_DATA, &data)?; }; export fn write_word_data(file: io::file, command: u8, value: u16) (void | rt::errno) = { - const res = c_i2c_smbus_write_word_data(file: int, command, value); - return if (res < 0) res: rt::errno else void; + const data = data { + word = value, + }; + access(file, WRITE, command, WORD_DATA, &data)?; }; - -@symbol("i2c_smbus_read_byte_data") fn c_i2c_smbus_read_byte_data(file: int, command: u8) i32; -@symbol("i2c_smbus_read_word_data") fn c_i2c_smbus_read_word_data(file: int, command: u8) i32; -@symbol("i2c_smbus_write_byte_data") fn c_i2c_smbus_write_byte_data(file: int, command: u8, value: u8) i32; -@symbol("i2c_smbus_write_word_data") fn c_i2c_smbus_write_word_data(file: int, command: u8, value: u16) i32; diff --git a/i2c/smbus/types.ha b/i2c/smbus/types.ha new file mode 100644 index 0000000..3359021 --- /dev/null +++ b/i2c/smbus/types.ha @@ -0,0 +1,27 @@ +def BLOCK_MAX: u8 = 32; + +export type data = union { + byte: u8, + word: u16, + block: [BLOCK_MAX + 2]u8, +}; + +type ioctl_data = struct { + read_write: u8, + command: u8, + _size: u32, + data: *data, +}; + +export def READ: u8 = 1; +export def WRITE: u8 = 0; + +export def QUICK: u32 = 0; +export def BYTE: u32 = 1; +export def BYTE_DATA: u32 = 2; +export def WORD_DATA: u32 = 3; +export def PROC_CALL: u32 = 4; +export def BLOCK_DATA: u32 = 5; +export def I2C_BLOCK_BROKEN: u32 = 6; +export def BLOCK_PROC_CALL: u32 = 7; +export def I2C_BLOCK_DATA: u32 = 8; diff --git a/i2c/types.ha b/i2c/types.ha index 9339e00..4e01543 100644 --- a/i2c/types.ha +++ b/i2c/types.ha @@ -1 +1,2 @@ export def I2C_SLAVE: u64 = 0x0703; +export def I2C_SMBUS: u64 = 0x0720; -- 2.45.2