~xdavidwu/motion-control

43e8ae478f1d9380d00c346fa5fc7c77f3da7ae6 — xdavidwu 2 years ago eeff151
i2c::smbus: implement completely in hare

the c library is actually pretty simple to port
this remove the need to link with c library
4 files changed, 55 insertions(+), 14 deletions(-)

M Makefile
M i2c/smbus/libi2c.ha
A i2c/smbus/types.ha
M i2c/types.ha
M Makefile => Makefile +1 -1
@@ 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

M i2c/smbus/libi2c.ha => i2c/smbus/libi2c.ha +26 -13
@@ 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;

A i2c/smbus/types.ha => i2c/smbus/types.ha +27 -0
@@ 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;

M i2c/types.ha => i2c/types.ha +1 -0
@@ 1,1 1,2 @@
export def I2C_SLAVE: u64	= 0x0703;
export def I2C_SMBUS: u64	= 0x0720;