Slave I2C and Variable Length Receive

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Slave I2C and Variable Length Receive

Jump to solution
2,113 Views
Jeinstei
Contributor II

Hi-

I'm trying to implement Slave I2C bean on a Kinetis K10, and am a bit confused about the interaction between CancelBlockReceive, GetReceivedBlockStatus, and the ISR and it's associated OnError masks.

Looking at the PE code, it looks like an RX cancel will always generate a SLAVE_RX_OVERRUN error as the cancel block receive function doesn't actually cancel and clear out the receive block so much as sets the requested number of bytes to 0.

I'm working with SM Bus burst reads and with a custom protocol that sends both strings and 16-bit values, and it looks like the only way to handle a NACK from the master is to process the error and generate an RX Overrun error. With the I2C bean as it is, is it necessary to process every byte as it is received and use the UpdateNumReceivedBytes, or is there some better way of managing variable length messages?

Thanks!

1 Solution
1,079 Views
Petr_H
NXP Employee
NXP Employee

Hi,

* Regarding CancelBlockReceive - When you use the CancelBlockReceive, you need to call the ReceiveBlock then to clear the data.

* Regarding the reception of variable length data - the steps should be the following:

1. call SlaveReceiveBlock() with the size larger than the part of the packet where you expect the size or command type to get information on the final size.

2. Use OnSlaveByteReceived() to process the bytes. If you detect get the size/type information adjust the expected size by calling SlaveUpdateReceiveBlockSize() method here.

3. After you'll get all the data, the event OnSlaveBlockReceived() is invoked.

4. Continue with the step 1.

* Regarding handling NACK from the master - When the slave receives NACK from the master, there is invoked OnError event, where you can chceck the type using GetError method and in this case it returns LDD_I2C_MASTER_NACK.

If you'd like to send NACK from the slave, then you can use the SendAcknowledge method with appropriate parameter.

best regards

Petr Hradsky

Processor Expert Support Team

View solution in original post

5 Replies
1,080 Views
Petr_H
NXP Employee
NXP Employee

Hi,

* Regarding CancelBlockReceive - When you use the CancelBlockReceive, you need to call the ReceiveBlock then to clear the data.

* Regarding the reception of variable length data - the steps should be the following:

1. call SlaveReceiveBlock() with the size larger than the part of the packet where you expect the size or command type to get information on the final size.

2. Use OnSlaveByteReceived() to process the bytes. If you detect get the size/type information adjust the expected size by calling SlaveUpdateReceiveBlockSize() method here.

3. After you'll get all the data, the event OnSlaveBlockReceived() is invoked.

4. Continue with the step 1.

* Regarding handling NACK from the master - When the slave receives NACK from the master, there is invoked OnError event, where you can chceck the type using GetError method and in this case it returns LDD_I2C_MASTER_NACK.

If you'd like to send NACK from the slave, then you can use the SendAcknowledge method with appropriate parameter.

best regards

Petr Hradsky

Processor Expert Support Team

1,079 Views
Jeinstei
Contributor II

Petr-

And the final question. If the Master sends a STOP, does the receive block end as being a success? I'm trying to figure out how to tell in PE whether we have received a write to switch the active register or just receiving multiple bytes (like SMBus)

0 Kudos
1,079 Views
Jeinstei
Contributor II

Thank Petr.

I finally worked out the variable byte method, but in fact didn't even need to use it in the end!

The CancelBlockReceive issue was very odd to me. If you call CancelBlockReceive and then want to actually cancel the receive, won't a ReceiveBlock of length zero throw an error?

0 Kudos
1,079 Views
Petr_H
NXP Employee
NXP Employee

Hi,


After calling the CancelBlockReceive, the data stay in the user buffer (defined by the ReceiveBlock method). After calling the CancelBlockReceive it's possible to call ReceiveBlock with new buffer or with the same old one. If you use the old one, the data will be rewritten. So actually I was not very precise, the ReceiveBlock is to be called for starting reception of the next data, not for just cleaning them.


best regards

Petr Hradsky

Processor Expert Support Team

0 Kudos
1,079 Views
Jeinstei
Contributor II

Petr-

So, if you call a cancel alone, you will receive the RX_BUFFER_OVERFLOW error still? That's what I was seeing in the code.

-Josh E

0 Kudos