Hello,
ad 1) Well, in polled mode, read/write are blocking operations, you use it when there's nothing else to do. In interrupt mode they are non-blocking and driver uses internal buffers, so you can time to time check/feed the new data. There's no overflow/underrun because I2C bus is driven by both master and slave. There's no callback implemented. You can also check the state of the bus or driver by ioctls IO_IOCTL_I2C_GET_STATE and IO_IOCTL_I2C_GET_BUS_AVAILABILITY.
ad 2) As slave, you cannot change the direction of a transfer. The transfer direction is only write or only read until STOP or REPEATED START driven by master.
ad 3) I2C bus STOP is job of the master, yes. But the IO_IOCTL_I2C_STOP command must be used on both sides (master and slave) to return the driver into original state. Sorry for confusion.
ad 4) You're right, slave can but doesn't have to read/write (to block) before master. I meant that slave has to prepare/wait for the data anyway. The bus will wait for slave's intervention. The slave just have to check if there's something going on.
We're planning to add I2C slave example to the release, but for now, let's summarize:
MASTER:
i2cfd = open ("i2c0:", NULL); // open driver as master in polled mode
param = 0x60; ioctl (i2cfd, IO_IOCTL_I2C_SET_STATION_ADDRESS, ¶m); // master's I2C address is 0x60
param = 0x50; ioctl (i2cfd, IO_IOCTL_I2C_SET_DESTINATION_ADDRESS, ¶m); // call device with address 0x50
param = 0x10; ioctl (i2cfd, IO_IOCTL_I2C_SET_RX_REQUEST, ¶m); // want to read 16 bytes in total
fread (buffer, 1, 10, i2cfd); // initiate transfer, send destination address (first use of read/write), read 10 bytes from device
fread (buffer + 10, 1, 6, i2cfd); // read remaining 6 bytes
ioctl (i2cfd, IO_IOCTL_FLUSH_OUTPUT, ¶m); // wait for completion, retrieve ack/nack in param
ioctl (i2cfd, IO_IOCTL_I2C_STOP, NULL); // stop transfer, release the bus
SLAVE:
i2cfd = open ("i2c0:", NULL); // open driver as master in polled mode
ioctl (i2cfd, IO_IOCTL_I2C_SET_SLAVE_MODE, NULL); // set SLAVE mode
param = 0x50; ioctl (i2cfd, IO_IOCTL_I2C_SET_STATION_ADDRESS, ¶m); // slave's I2C address is 0x50
fwrite (buffer, 1, 16, i2cfd); // wait for master to address slave, write 16 bytes
ioctl (i2cfd, IO_IOCTL_I2C_STOP, NULL); // get driver to original state
Regards,
PetrM