Hi guys,
Thanks for the quick responses. To clarify, I'm running at 400kHz, which as Wim says should be supported. I am using the LPC11U24. I'd rather not say what slave I'm using, but it absolutely supports FM and FM+. The second bit of code *does* work in both FM and FM+, suggesting that software is definitely the problem: either I made a mistake with the first program or there is a bug in the library.
Erik: Thanks for the suggestion. However, this is commercial work so we don't want to use anything other than the official mbed libraries. My second bit of code works anyway, so this is more about reporting a bug in the official libraries: I don't need an urgent fix.
Wim: I've taken pictures of all four cases on the scope. In order these are: 100kHz using block reads/writes (i.e. the first bit of code from my last post), 100kHz using manual start/stops (i.e. the second bit of code from my last post), 400kHz using block reads/writes, and 400kHz using manual start/stops. Yellow is data, purple is clock. To help decode it, observe that the slave drives the line more strongly low than the master during an ACK, and the start bit corresponds to an elongated high clock pulse (except in the third image where it is missing). The last byte of the write is 0x40. The first byte of the read (i.e. the address byte) is 0xC1.
As you can see, in all cases except the 400kHz using block write/read, there is an elongated high clock pulse between write and read, during which the start bit is transmitted. You'll also notice that no ACK or data follows the address byte in the third picture, because the slave fails to correctly interpret the read due to the missing start bit.
Hi,
I believe I've found a bug in the I2C block read implementation involving repeated starts and fast mode (400kbps).
Here's the scenario. I have a sensor which requires a write operation immediately followed by a read, with no stop bit in between. This can be implemented using a repeated start like so:
Edit: I've added the full function body including input validation and NoAck based on Wim's comments.
The above code works fine when the frequency is set to 100kbps, however it fails when set to 400kbps. Examining what was happening with an oscilloscope, I saw that at 400kbps the line was never being driven low for the repeated start bit. In other words, while repeated start should omit the stop bit at the end of the write, I was seeing both the stop and the start bits omitted. There was no separation between the last byte of the write and the first byte of the read. This meant that the sensor never responded to the read because it interpreted the address byte as another data byte in the write. At 100kbps the start bit was written correctly and so the sensor responded.
I re-wrote the above code using explicit starts and stops with the single-byte reads and writes, as shown below.
This version works fine at all frequencies. Any idea why I am seeing this behaviour?