FtcRobotController
FtcRobotController copied to clipboard
LynxI2cReadMultipleBytesCommand always reads extra byte
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