На самом деле Вам не нравится чувствовать гистерезис. Без гистерезиса и защиты от дребезга пойдет?
enum AllowedDirection {
AllowedUp,
AllowedDown
};
char cur = ...
if( (cur == StateA && prev == StateAB || cur == StateAB && prev == StateB) && allowed == AllowedDown ) {
down();
allowed = AllowedUp;
} else if( (cur == StateB && prev == StateAB || cur == StateAB && prev == StateA) && allowed == AllowedUp ) {
up();
allowed = AllowedDown;
)
if( cur == StateA )
allowed = AllowedUp;
else if( cur == StateB )
allowed = AllowedDown;
prev = cur;