тот код был набором эвристик для обработки таких ситуаций. Но наверное допустимо в таких случаях чаще пропускать оборот. Вот так, например:
if( cur == prev )
return;
if( cur == StateB && prev == StateAB && prevPrev == StateA )
up();
else if( cur == StateA && prev == StateAB && prevPrev == StateB )
down();
prevPrev = prev;
prev = cur;
Фактически простой вариант - это упрощение этого кода с учетом того, что если prev == StateAB, то cur и prevPrev должны быть с ровно одним замкнутым контактом, а сложный вариант - это попытка обработать еще и некоторые случаи, когда иногда происходят прямые переходы между StateAB и StateZero.