2 added 111 characters in body
source | link

I'm using a timer to fire a interrupt in configurable time periods. In that ISR, a pin is toggled, and a uint32_t variable is incremented.

In the main program, a while loop waits until that variable has reached a certain threshold - to then disable the timer via its clock source selection.

while(stepcounter <= threshold) {
}
disablecounter();

Sometimes - depending on optimization level, whether I put a small delay in the while loop, etc., this check seems to fail - advancing to disablecounter() even though stepcounter has not reached threshold.

If I stack the while loop like this:

while(stepcounter <= threshold) {
}
while(stepcounter <= threshold) {
}
disablecounter();

it runs just fine. This also works:

while(stepcounter <= threshold) {
  while(stepcounter <= threshold) {
  }
}
disablecounter();

I'm assuming there's some odd behaviour when comparing rapidly changing 32-bit numbers against a threshold. This issue also occurs when using a uint16_t for stepcounter, but after a higher number of cycles.

For analysis, I'm simply running this loop over and over again; setting stepcounter back to 0 and restarting the timer. With uint32_t, it usually fails after the 5th or so loop. For uint16_t, it fails after around 25 loops.

Using a tempstepcounter like this also seems to work, but only when comparing against both counters at the same time:

while(tempstepcounter <= threshold || stepcounter <= threshold) {
  tempstepcounter = stepcounter;
}
disablecounter();

Any ideas on this? It this because 32-bit numbers take longer to read from the registers than the time from ISR to ISR? ISR frequency should be around 32 kHz during this.

ISR code:

ISR(TIMER1_COMPA_vect) {
  PORTF ^= (1 << PORTF0));
  stepcounter++;
}  

I'm using a timer to fire a interrupt in configurable time periods. In that ISR, a pin is toggled, and a uint32_t variable is incremented.

In the main program, a while loop waits until that variable has reached a certain threshold - to then disable the timer via its clock source selection.

while(stepcounter <= threshold) {
}
disablecounter();

Sometimes - depending on optimization level, whether I put a small delay in the while loop, etc., this check seems to fail - advancing to disablecounter() even though stepcounter has not reached threshold.

If I stack the while loop like this:

while(stepcounter <= threshold) {
}
while(stepcounter <= threshold) {
}
disablecounter();

it runs just fine. This also works:

while(stepcounter <= threshold) {
  while(stepcounter <= threshold) {
  }
}
disablecounter();

I'm assuming there's some odd behaviour when comparing rapidly changing 32-bit numbers against a threshold. This issue also occurs when using a uint16_t for stepcounter, but after a higher number of cycles.

For analysis, I'm simply running this loop over and over again; setting stepcounter back to 0 and restarting the timer. With uint32_t, it usually fails after the 5th or so loop. For uint16_t, it fails after around 25 loops.

Using a tempstepcounter like this also seems to work, but only when comparing against both counters at the same time:

while(tempstepcounter <= threshold || stepcounter <= threshold) {
  tempstepcounter = stepcounter;
}
disablecounter();

Any ideas on this? It this because 32-bit numbers take longer to read from the registers than the time from ISR to ISR? ISR frequency should be around 32 kHz during this.

I'm using a timer to fire a interrupt in configurable time periods. In that ISR, a pin is toggled, and a uint32_t variable is incremented.

In the main program, a while loop waits until that variable has reached a certain threshold - to then disable the timer via its clock source selection.

while(stepcounter <= threshold) {
}
disablecounter();

Sometimes - depending on optimization level, whether I put a small delay in the while loop, etc., this check seems to fail - advancing to disablecounter() even though stepcounter has not reached threshold.

If I stack the while loop like this:

while(stepcounter <= threshold) {
}
while(stepcounter <= threshold) {
}
disablecounter();

it runs just fine. This also works:

while(stepcounter <= threshold) {
  while(stepcounter <= threshold) {
  }
}
disablecounter();

I'm assuming there's some odd behaviour when comparing rapidly changing 32-bit numbers against a threshold. This issue also occurs when using a uint16_t for stepcounter, but after a higher number of cycles.

For analysis, I'm simply running this loop over and over again; setting stepcounter back to 0 and restarting the timer. With uint32_t, it usually fails after the 5th or so loop. For uint16_t, it fails after around 25 loops.

Using a tempstepcounter like this also seems to work, but only when comparing against both counters at the same time:

while(tempstepcounter <= threshold || stepcounter <= threshold) {
  tempstepcounter = stepcounter;
}
disablecounter();

Any ideas on this? It this because 32-bit numbers take longer to read from the registers than the time from ISR to ISR? ISR frequency should be around 32 kHz during this.

ISR code:

ISR(TIMER1_COMPA_vect) {
  PORTF ^= (1 << PORTF0));
  stepcounter++;
}  
1
source | link

Variable updated in ISR is miscounting

I'm using a timer to fire a interrupt in configurable time periods. In that ISR, a pin is toggled, and a uint32_t variable is incremented.

In the main program, a while loop waits until that variable has reached a certain threshold - to then disable the timer via its clock source selection.

while(stepcounter <= threshold) {
}
disablecounter();

Sometimes - depending on optimization level, whether I put a small delay in the while loop, etc., this check seems to fail - advancing to disablecounter() even though stepcounter has not reached threshold.

If I stack the while loop like this:

while(stepcounter <= threshold) {
}
while(stepcounter <= threshold) {
}
disablecounter();

it runs just fine. This also works:

while(stepcounter <= threshold) {
  while(stepcounter <= threshold) {
  }
}
disablecounter();

I'm assuming there's some odd behaviour when comparing rapidly changing 32-bit numbers against a threshold. This issue also occurs when using a uint16_t for stepcounter, but after a higher number of cycles.

For analysis, I'm simply running this loop over and over again; setting stepcounter back to 0 and restarting the timer. With uint32_t, it usually fails after the 5th or so loop. For uint16_t, it fails after around 25 loops.

Using a tempstepcounter like this also seems to work, but only when comparing against both counters at the same time:

while(tempstepcounter <= threshold || stepcounter <= threshold) {
  tempstepcounter = stepcounter;
}
disablecounter();

Any ideas on this? It this because 32-bit numbers take longer to read from the registers than the time from ISR to ISR? ISR frequency should be around 32 kHz during this.