I’ve been asked a few times now how we got I2C working without third party code. The reality is that thanks to the way Linux handles drivers it’s pretty easy and I’d expect direct access to 1 wire to be the same (We have bridges with FIFOs, parasitic power etc so we dont need to try it)
First make sure you can talk to your I2C decvice with I2Ctools. Theres loads of info on this, off you go and hunt it down.
NOTE, BIG GOTCHYA!
latest versions of Raspbian use a new way of handling devices, make sure you use a tutorial that matches the way your system is setup as simply uncmmenting things in the modules blacklist may not be enough.
You shouldnt be running code as root, developing, yes, running as an end product, no. There are arguments against developing too but thats not why this article is here. By default only root has access to I2C and we need to change that if your apps are going to work in userland. Its easy to do. Say we want pi to be able to do it:
sudo groupadd i2c pi
Now we can use the standard FPOpen(), FPRead(), FPWrite() to do the job.
var
DEV_IMU : integer;
addr : byte;
This is the handle for the fle we are about to open and addr is the target device address on the bus
procedure openI2c;
var
count : integer;
data: byte;
reg : byte;
begin
DEV_IMU:= fpopen(‘/dev/i2c’,O_RDWR);
if DEV_IMU= -1 then begin
// we couldn’t open the bus
exit;
end
else begin
// associate this handle with an address on the bus
fpioCTL(DEV_IMU,1795, pointer(addr));
//success
end;
Now to read:
function readbyte(reg:word):word
var
count : integer;
data : byte;
begin
// we have to write before the read to send the register we want
count := fpwrite(DEV_IMU,reg,1);
if count <> 1 then begin
// we couldnt do the write!
exit;
end;
// now read
count := fpread(DEV_IMU,data,1);
if count =0 then begin
// nothing came back
exit;
end
else result := data;
end;
And the write is easy enough. The read is write then read as we always nbeed to send the target register out. In the case of a write we can do this ‘back to back’
procedure writebyte(reg,data:byte)
var
buffer : array [1..2] of byte;
count : integer;
begin
buffer[1] := reg;
buffer[2] := data;
count := fpwrite(DEV_IMU,buffer,2);
if count <> 2 then begin
// write failed
exit;
end
else // write ok
end;
This should have you up and running in no time.