FIRST-Tech-Challenge / FIRST-Tech-Challenge/FtcRobotController

LynxI2cReadMultipleBytesCommand always reads extra byte

Open
#87 13 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
1.3k
Forks
9.9k
Avg merge
18m
Merged PRs (30d)
1

Description

We are communicating with serial I2C device which can send more than 100 bytes in a single response. Every response from the device contains header and cargo, first two bytes in header contain response length (including both cargo and header length). Per our observation, `LynxI2cReadMultipleBytesCommand` always reads one extra byte

Ie, per host request, device needs to send 6 cargo bytes `01 02 03 04 05 06`. In this case devise will send back respond with 10 bytes `0A 00 FF FF 01 02 03 04 05 06`
`0A 00 FF FF` - header - 4 bytes
`01 02 03 04 05 06` - cargo - 6 bytes
`0A` - first byte=total packet length
In every read request, host is required to read at least four bytes (header)
Example expected exchange:

Scenario 1 – Host does not know expected response length
Host -> Read 4 bytes [header]
Device -> `0A 00 FF FF` (I have 10 `0A` bytes to send)
Host -> Read 10 bytes
Device -> `0A 00 FF FF 01 02 03 04 05 06` (here are 10 bytes = 4 bytes in header + 6 bytes in cargo)

Scenario 2 – Host does know expected response length
Host -> Read 10 bytes [header + cargo]
Device -> `0A 00 FF FF 01 02 03 04 05 06` (ending 10 bytes including header and cargo)

Scenario 3 – Host does know expected response length, but has limited incoming buffer (7 bytes)
Host -> Read 7 bytes [header + cargo]
Device -> `0A 00 FF FF 01 02 03` (sending 7 bytes including header and first 3 bytes from cargo, host will need to come back and read 3 more cargo bytes = 0A – 07, or 7 total bytes (cargo + header))
Host -> Read 7 bytes [header + cargo]
Device -> `07 00 FF FF 04 05 06` (sending 7 bytes, 4 in header and 3 remaining bytes from cargo)

Actual exchange
Scenario 1 – Host does not know expected response length - data loss
Host -> Read 4 bytes [header]
Device -> `0A 00 FF FF` (I have 10 `0A` bytes to send) [in this transaction Hub actually reads 5 bytes from the devices instead of 4]
Host -> Read 10 bytes
Device -> `09 00 FF FF 02 03 04 05 06 00` (here are 9 bytes = 4 bytes in header + 5 bytes in cargo + dummy byte) – this response indicates that instead of requesting and reading 4 bytes, host actually read 5 (4 bytes in header + 1 cargo), and device excluded original first cargo byte from second response. Byte `01` is lost

Scenario 2 – Host does know expected response length (response will fit into buffer)- no data loss
Host -> Read 10 bytes [header + cargo]
Device -> `0A 00 FF FF 01 02 03 04 05 06` (I am sending 10 bytes including header and cargo)
In other words, based on what we currently see, Expansion Hub always reads extra byte from the device and we are missing information when expected cargo length exceeds 100 bytes since we need to read it in chunks

Scenario 3 – Host does know expected response length, but has limited incoming buffer (7 bytes, [actual limit is 100, but behavior is the same]) - data loss
Host -> Read 7 bytes [header + cargo]
Device -> `0A 00 FF FF 01 02 03` (sending 7 bytes including header and cargo, total length 10)
Host -> Read 7 bytes [header + cargo]
Device -> `06 00 FF FF 05 06 00` (sending 7 bytes, 4 in header, 2 remaining bytes from cargo and one dummy byte - byte `04` is lost)

In other words, `LynxI2cReadMultipleBytesCommand` always reads one extra byte from I2C device beyond of what is requested. It does not create any issues if requested length is greater than number of bytes that device needs to send, but causes data loses in case if device needs to send more than requested in single read request

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.