Variable-length I2C messages

cancel
Showing results for 
Search instead for 
Did you mean: 

Variable-length I2C messages

Jump to solution
1,179 Views
laszlomonda
Contributor IV

Hi there,

I have an I2C master (K22) and a slave (KL03). The master reads the slave from time to time, but the slave should send variable-length messages based on the circumstances.

I plan to implement this by making the master read the maximum number of bytes and then making the slave send potentially smaller messages by NACKing the transfer after the last byte of the message. For example, master tries to read 255 bytes, but the slave only wants to send 5 bytes, so it NACKs the transfer after the 5th byte.

Should the above work given the capabilities of the I2C protocol? If not, would you recommend an alternative solution?

(Please don't advise that I should just pad the unused bytes because I want to make the protocol as efficient as possible.)

Thank you!

- Laci

1 Solution
593 Views
laszlomonda
Contributor IV

Hi Mark,

Thanks so much for the quick reply! Also thank you for the linked document. It looks very extensive and well-written.

Luckily, I was able to make variable-length I2C messaging work relatively easily by patching the KSDK and writing some firmware code.

Fortunately, double-buffering wasn't an issue for me.

Have a great day!

- Laci

View solution in original post

0 Kudos
3 Replies
593 Views
laszlomonda
Contributor IV

I've been googling in the meantime, and found a relevant answer according to which the above approach is not supported by the I2C protocol.

I'm thinking about an alternative solution. The idea is that the slave will always send the length of the message as the first byte which the master will read. Then the master continues reading n bytes according to the first byte during the same I2C transaction. The problem is that this doesn't seem to be supported by I2C_MasterTransferNonBlocking() because it expects the number of bytes to read before initiating the transfer. I also tried to launch a 1 byte read with TransferNoStopFlag, and then a second n byte long read with and without kI2C_TransferNoStartFlag without success.

KSDK doesn't seem to be supporting this scenario, so I'm about to patch it. I'm not thrilled about this solution becase I'll have to patch upcoming KSDK versions too, but I don't know any better.

Would any of you confirm that my thinking is correct or possibly suggest a better solution?

Thank you!

- Laci

0 Kudos
593 Views
mjbcswitzerland
Specialist V

Hi Laci

As you have realised in the meantime, it is the master that ACKs when it reads bytes from the slave and so the slave can't stop a read sequence from continuing.
The technique is, as you have pointed out, to get the slave to inform of the number of bytes that it has ready to be read. Either by a specific read (start - address - single byte - stop followed by the length to be read) or by dynamically changing the read length as you suggest, based on the first byte received. The first method should be possible with standard library calls. The second would require the master changing on-the-fly, which is is probably not possible with the standard routines with modifying them.

Beware that the I2C controllers in the K22 and KL03 are a bit different and I don't know whether the latest NXP libraries are reliable for the double-buffered case (there are quite a number of threads on the forum discussing this). Due to errata in the KL03 I2C which require fast reaction to be guaranteed in some circumstance (NXP advises using DMA, which the KL03 doesn't have) it may be necessary to slow the K22's I2C operation to ensure that the KL03's I2C controller doesn't miss data.

You can also take a look at http://www.utasker.com/docs/uTasker/uTasker_I2C.pdf which (see appendix) explains the difference between the two I2C controllers and how to ensure reliability.

Regards

Mark

http://www.utasker.com/kinetis.html
http://www.utasker.com/kinetis/FRDM-KL03Z.html
http://www.utasker.com/kinetis/FRDM-K22F.html
http://www.utasker.com/kinetis/TWR-K22F120M.html
http://www.utasker.com/kinetis/BLAZE_K22.html

594 Views
laszlomonda
Contributor IV

Hi Mark,

Thanks so much for the quick reply! Also thank you for the linked document. It looks very extensive and well-written.

Luckily, I was able to make variable-length I2C messaging work relatively easily by patching the KSDK and writing some firmware code.

Fortunately, double-buffering wasn't an issue for me.

Have a great day!

- Laci

View solution in original post

0 Kudos