Ttelmah
Joined: 11 Mar 2010 Posts: 19781
|
|
Posted: Wed Apr 20, 2016 2:59 am |
|
|
In I2C, there are two addresses.
The device address, and
the register address in the device.
The device address also has a 'flag' as the low bit, saying to read or write.
So the sequence to write a set of bytes to a device is:
Start
Send device 'write' address
Send register address in device to write
Write data
Stop
The sequence to read a set of bytes is:
Start
Send device 'write' address
Send register address to read from
Restart
Send device 'read' address (write address+1)
Read bytes (NACK the last byte)
Stop
So you are 90% there.
For your 'write' code:
Code: |
void sendData()
{
i2c_start();
i2c_write(muxerAddress);
i2c_write(0); //assuming you want to start at register 0
for(int i = 0; i < sizeof(gameStatus); i++)
{
i2c_write(gameStatus[i]);
}
i2c_stop();
}
|
To 'read' the block back:
Code: |
void getData()
{
i2c_start();
i2c_write(muxerAddress);
i2c_write(0); //assuming you want to start at register 0
i2c_start(); //the restart
i2c_write(muxerAddress + 1);
//Now in read mode at register 0
for(int i = 0; i < sizeof(gameStatus); i++)
{
if (i==(sizeof(gameStatus)-1))
gameStatus[i]=i2c_read(0); //NACK the last byte
else
gameStatus[i]=i2c_read();
}
i2c_stop();
}
|
There are ways of slightly short-cutting parts of the transaction (you could assume that all transactions begin at register 0), but in general I2C prefers/requires the transactions to be handled fully. The PIC hardware in particular differs between chips on how abbreviated transactions are done, so it is better to use the standard form.
Particularly sending the NACK on the last read keeps the hardware synced up better.
For error checking, look at PCM_programmers I2C scanner program in the code library. Note how this works, even when testing addresses with no device, by checking the bit returned when the device address is written. Do the same in your master code, and you can tell if the device is acknowledging correctly before trying to write/read data. |
|