uli / basicengine-firmware

BASIC Engine Firmware
78 stars 16 forks source link

WAIT command will not wait when end time overflows #68

Closed konimaru closed 3 years ago

konimaru commented 4 years ago

current code:

void Basic::iwait() {
  int32_t tm;
  if (getParam(tm, 0, INT32_MAX, I_NONE))
    return;
  uint32_t end = tm + millis();
  while (millis() < end) {
    process_events();
    uint16_t c = sc0.peekKey();
    if (process_hotkeys(c)) {
      break;
    }
    yield();
  }
}

Example: millis() returns close to 0xFFFFFFFF, end time == 0x0xxxxxxx

Suggested solution (with the limitation that the max delay is limited to 2^31 ms):

void Basic::iwait() {
  int32_t tm;
  if (getParam(tm, 0, INT32_MAX, I_NONE))
    return;
  uint32_t end = tm + millis();
  while ((signed)(millis()-end) < 0) {
    process_events();
    uint16_t c = sc0.peekKey();
    if (process_hotkeys(c)) {
      break;
    }
    yield();
  }
}

This obviously only works when millis() uses the full 32bit range (see also #69).

peek82 commented 3 years ago

@konimaru Once in a while my machine freezes and when I hit ctrl-c to break, it's always on a line with a WAIT command. I had wondered if there was an issue with the rollover in WAIT... I wonder if my issue is related to this bug?

uli commented 3 years ago

I have now merged the overflow fix into Arduino_wifi's sdknowifi tree, and it seems that that fixes the issue with the WAIT command. It should show up in the next git build. (Note, however, that the next build will only be triggered when there is a change in the basicengine-firmware repo.)