I2C Slave using FRDM-K64F

19 Nov 2014

I'm trying to use my FRDM-K64F as an I2C Slave, and have found what I believe to be a few issues in the relevant i2c_api.c file. However, I'm only (currently) writing bytes to my board, and am not in a position to test it in master mode, so I don't know whether my changes only work in my case, or what a proper solution would be.

Has anyone got this code working - what environment was used to test it?

I've moved a few chunks of code around, but the things that most stood out as potentially problematic were:

  • in i2c_slave_address(), there is a call to I2C_HAL_SetUpperAddress7bit() which I think should be instead made to I2C_HAL_SetAddress7bit() to set the slave address correctly.
  • in i2c_slave_read(), the transfer direction is set up at the start, but in transmit mode. I believe that kI2CReceive should be used instead of kI2CSend in the call to I2C_HAL_SetDirMode().
  • at the end of i2c_byte_read() the bus is put back into transmit mode. Removing the line I2C_HAL_SetDirMode(i2c_addrs[obj->instance], kI2CSend); seemed to make multi-byte reception better.

Can anyone comment whether any of these look like they're heading in the right direction?

Alan

19 Nov 2014

All parts in the slave section should for sure be save to change without affecting master mode (also mbed test setup should include i2c/spi slave, I know I don't test for it at least :P).

So if you got changes which help you can always submit a pull request on the github. From this one I know only that the last one is intended (at least for master mode). The problem is that it was never intended to use I2C the per-byte way as the I2C mbed master lib allows (and imo it should just be deleted alltogether tbh). And the only way to make that work correctly is by switching it back to transmit mode all the time (otherwise reading the results already starts the next master read before the user has given the command. And from that it follows that the user also cannot set ACK/NACK, which is why that switch to transmit has been added).

19 Nov 2014

The last change was introduced while I was attempting to read byte-at-a-time. I've since switched to attempting to multiple-read more bytes than the longest packet I expect to receive, and it seems to be working OK, if a little brittle. I also have changes to remove some dummy reads that were included (unnecessarily, according to my testing) and I need to go back and see what changes are needed and which were just introduced during my assorted experiments.