@@ -2933,7 +2933,6 @@ sfe_ublox_status_e SFE_UBLOX_GNSS::sendCommand(ubxPacket *outgoingUBX, uint16_t
2933
2933
// Returns false if sensor fails to respond to I2C traffic
2934
2934
sfe_ublox_status_e SFE_UBLOX_GNSS::sendI2cCommand (ubxPacket *outgoingUBX, uint16_t maxWait)
2935
2935
{
2936
- // PaulZC : November 15th 2021
2937
2936
// From the integration guide:
2938
2937
// "The receiver does not provide any write access except for writing UBX and NMEA messages to the
2939
2938
// receiver, such as configuration or aiding data. Therefore, the register set mentioned in section Read
@@ -2949,7 +2948,7 @@ sfe_ublox_status_e SFE_UBLOX_GNSS::sendI2cCommand(ubxPacket *outgoingUBX, uint16
2949
2948
// Point 2 is important. It means:
2950
2949
// * In this function:
2951
2950
// if we do multiple writes (because we're trying to write more than i2cTransactionSize),
2952
- // we may need to write one byte less in the previous write to ensure we always have two bytes left for the final write.
2951
+ // we may need to write one byte less in the penultimate write to ensure we always have two bytes left for the final write.
2953
2952
// * In pushRawData:
2954
2953
// if there is one byte to write, or one byte left to write, we need to do the same thing and may need to store a single
2955
2954
// byte until pushRawData is called again.
@@ -2972,11 +2971,11 @@ sfe_ublox_status_e SFE_UBLOX_GNSS::sendI2cCommand(ubxPacket *outgoingUBX, uint16
2972
2971
2973
2972
// i2cTransactionSize will be at least 8. We don't need to check for smaller values than that.
2974
2973
2975
- uint16_t bytesToSend = outgoingUBX->len + 8 ; // How many bytes need to be sent?
2974
+ uint16_t bytesToSend = outgoingUBX->len + 8 ; // How many bytes need to be sent
2976
2975
uint16_t bytesSent = 0 ; // How many bytes have been sent
2977
- uint16_t bytesLeftToSend = bytesToSend; // How many bytes remain to be sent?
2976
+ uint16_t bytesLeftToSend = bytesToSend; // How many bytes remain to be sent
2977
+ uint16_t startSpot = 0 ; // Payload pointer
2978
2978
2979
- uint16_t startSpot = 0 ;
2980
2979
while (bytesLeftToSend > 0 )
2981
2980
{
2982
2981
uint16_t len = bytesLeftToSend; // How many bytes should we actually write?
@@ -3007,33 +3006,45 @@ sfe_ublox_status_e SFE_UBLOX_GNSS::sendI2cCommand(ubxPacket *outgoingUBX, uint16
3007
3006
3008
3007
bytesSent += 6 ;
3009
3008
3010
- uint16_t x;
3011
- for (x = 0 ; (x < outgoingUBX->len ) && (bytesSent < len); x++) // Write a portion of the payload to the bus
3009
+ uint16_t x = 0 ;
3010
+ // Write a portion of the payload to the bus.
3011
+ // Keep going until we reach the end of the payload (x == outgoingUBX->len)
3012
+ // or we've sent as many bytes as we can in this transmission (bytesSent == len).
3013
+ for (; (x < outgoingUBX->len ) && (bytesSent < len); x++)
3012
3014
{
3013
3015
_i2cPort->write (outgoingUBX->payload [startSpot + x]);
3014
3016
bytesSent++;
3015
3017
}
3016
3018
startSpot += x;
3017
3019
3018
- if (bytesSent < len) // Do we need to write both checksum bytes? (Remember that bytesLeftToSend will be zero or >=2 here)
3020
+ // Can we write both checksum bytes?
3021
+ // We can send both bytes now if we have exactly 2 bytes left
3022
+ // to be sent in this transmission (bytesSent == (len - 2)).
3023
+ if (bytesSent == (len - 2 ))
3019
3024
{
3020
3025
// Write checksum
3021
3026
_i2cPort->write (outgoingUBX->checksumA );
3022
3027
_i2cPort->write (outgoingUBX->checksumB );
3023
3028
bytesSent += 2 ;
3024
3029
}
3025
3030
}
3026
- else if (bytesSent < bytesToSend) // Keep writing payload bytes - plus the checksum if required
3031
+ else // Keep writing payload bytes. Write the checksum at the right time.
3027
3032
{
3028
- uint16_t x;
3029
- for (x = 0 ; (x < len) && ((startSpot + x) < (outgoingUBX->len )); x++) // Write a portion of the payload to the bus
3033
+ uint16_t x = 0 ;
3034
+ // Write a portion of the payload to the bus.
3035
+ // Keep going until we've sent as many bytes as we can in this transmission (x == len)
3036
+ // or until we reach the end of the payload ((startSpot + x) == (outgoingUBX->len))
3037
+ for (; (x < len) && ((startSpot + x) < (outgoingUBX->len )); x++)
3030
3038
{
3031
3039
_i2cPort->write (outgoingUBX->payload [startSpot + x]);
3032
3040
bytesSent++;
3033
3041
}
3034
3042
startSpot += x;
3035
3043
3036
- if (bytesSent == (bytesToSend - 2 )) // Do we need to write both checksum bytes? (Remember that bytesLeftToSend will be zero or >=2 here)
3044
+ // Can we write both checksum bytes?
3045
+ // We can send both bytes if we have exactly 2 bytes left to be sent (bytesSent == (bytesToSend - 2))
3046
+ // and if there is room for 2 bytes in this transmission
3047
+ if ((bytesSent == (bytesToSend - 2 )) && (x == (len - 2 )))
3037
3048
{
3038
3049
// Write checksum
3039
3050
_i2cPort->write (outgoingUBX->checksumA );
@@ -3042,7 +3053,7 @@ sfe_ublox_status_e SFE_UBLOX_GNSS::sendI2cCommand(ubxPacket *outgoingUBX, uint16
3042
3053
}
3043
3054
}
3044
3055
3045
- if (bytesSent < bytesToSend) // Are we all done ?
3056
+ if (bytesSent < bytesToSend) // Do we need to go round the loop again ?
3046
3057
{
3047
3058
if (_i2cPort->endTransmission (_i2cStopRestart) != 0 ) // Don't release bus unless we have to
3048
3059
return (SFE_UBLOX_STATUS_I2C_COMM_FAILURE); // Sensor did not ACK
0 commit comments