Skip to content

Commit 320b57d

Browse files
committed
Fixed comparisons with (wrong) unsigned-to-signed integer promotions
The following snippet demonstrates the problem: uint32_t millis0 = 0x5FFF0; uint32_t millis1 = 0x60010; uint16_t t0 = millis0; Serial.println((uint16_t)millis1-t0); // prints -65504 WRONG Serial.println((uint16_t)(millis1-t0)); // prints 32 OK the subtraction promotes each of the operands to signed integers so we must make sure that the cast is made after the operation. To further simplify this logic and avoid this kind of subtle traps the operation has been moved from the condition into a variable of the desired size: uint16_t d = millis1 - t0; Serial.println(d); // prints 32 as well Fix #41
1 parent 8cd6fef commit 320b57d

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

src/utility/Sd2Card.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
248248
errorCode_ = inBlock_ = partialBlockRead_ = type_ = 0;
249249
chipSelectPin_ = chipSelectPin;
250250
// 16-bit init start time allows over a minute
251-
uint16_t t0 = (uint16_t)millis();
251+
uint16_t t0 = millis();
252252
uint32_t arg;
253253

254254
// set pin modes
@@ -288,7 +288,8 @@ uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
288288

289289
// command to go idle in SPI mode
290290
while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) {
291-
if (((uint16_t)(millis() - t0)) > SD_INIT_TIMEOUT) {
291+
uint16_t d = millis() - t0;
292+
if (d > SD_INIT_TIMEOUT) {
292293
error(SD_CARD_ERROR_CMD0);
293294
goto fail;
294295
}
@@ -310,7 +311,8 @@ uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
310311

311312
while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) {
312313
// check for timeout
313-
if (((uint16_t)(millis() - t0)) > SD_INIT_TIMEOUT) {
314+
uint16_t d = millis() - t0;
315+
if (d > SD_INIT_TIMEOUT) {
314316
error(SD_CARD_ERROR_ACMD41);
315317
goto fail;
316318
}
@@ -543,18 +545,21 @@ uint8_t Sd2Card::setSpiClock(uint32_t clock)
543545
// wait for card to go not busy
544546
uint8_t Sd2Card::waitNotBusy(uint16_t timeoutMillis) {
545547
uint16_t t0 = millis();
548+
uint16_t d;
546549
do {
547550
if (spiRec() == 0XFF) return true;
551+
d = millis() - t0;
548552
}
549-
while (((uint16_t)millis() - t0) < timeoutMillis);
553+
while (d < timeoutMillis);
550554
return false;
551555
}
552556
//------------------------------------------------------------------------------
553557
/** Wait for start block token */
554558
uint8_t Sd2Card::waitStartBlock(void) {
555559
uint16_t t0 = millis();
556560
while ((status_ = spiRec()) == 0XFF) {
557-
if (((uint16_t)millis() - t0) > SD_READ_TIMEOUT) {
561+
uint16_t d = millis() - t0;
562+
if (d > SD_READ_TIMEOUT) {
558563
error(SD_CARD_ERROR_READ_TIMEOUT);
559564
goto fail;
560565
}

0 commit comments

Comments
 (0)