diff --git a/src/main/java/com/rusefi/can/analysis/CounterScanner.java b/src/main/java/com/rusefi/can/analysis/CounterScanner.java index 3f9f622..619c5b8 100644 --- a/src/main/java/com/rusefi/can/analysis/CounterScanner.java +++ b/src/main/java/com/rusefi/can/analysis/CounterScanner.java @@ -29,11 +29,12 @@ public class CounterScanner { for (Map.Entry e : bitStates.entrySet()) { - if (e.getValue().couldBeCounter) - System.out.println("Looks like counter " + e.getKey()); + BitState bitState = e.getValue(); + if (bitState.couldBeCounter()) { + BitStateKey key = e.getKey(); + System.out.println("Looks like counter " + key + " " + bitState.cycleLength); + } } - - } static class BitStateKey implements Comparable { @@ -94,23 +95,55 @@ public class CounterScanner { } static class BitState { - boolean isFirst = true; - boolean couldBeCounter = true; + int index; + int cycleLength; + + public boolean couldBeCounter() { + return state == StateMachine.HAPPY_COUNTER; + } + + enum StateMachine { + FIRST_VALUE, + LOOKING_FOR_FIRST_SWITCHOVER, + FOUND_FIRST_SWITCHOVER, + HAPPY_COUNTER, + NOT_GOOD + } + + StateMachine state = StateMachine.FIRST_VALUE; boolean previousBitValue; public void handle(boolean bitValue) { - if (isFirst) { - isFirst = false; + if (state == StateMachine.NOT_GOOD) { + return; + } else if (state == StateMachine.FIRST_VALUE) { previousBitValue = bitValue; - return; - } - if (!couldBeCounter) - return; - if (previousBitValue == bitValue) { - couldBeCounter = false; - } - previousBitValue = bitValue; + state = StateMachine.LOOKING_FOR_FIRST_SWITCHOVER; + } else if (state == StateMachine.LOOKING_FOR_FIRST_SWITCHOVER) { + if (previousBitValue == bitValue) + return; + previousBitValue = bitValue; + state = StateMachine.FOUND_FIRST_SWITCHOVER; + } else if (state == StateMachine.FOUND_FIRST_SWITCHOVER) { + index++; + if (previousBitValue != bitValue) { + state = StateMachine.HAPPY_COUNTER; + cycleLength = index; + previousBitValue = bitValue; + index = 0; + } + } else if (state == StateMachine.HAPPY_COUNTER) { + index++; + + if (previousBitValue != bitValue) { + if (index != cycleLength) + state = StateMachine.NOT_GOOD; + previousBitValue = bitValue; + index = 0; + } + } else + throw new IllegalStateException(state.toString()); } } } diff --git a/src/test/java/com/rusefi/can/analysis/CounterScannerTest.java b/src/test/java/com/rusefi/can/analysis/CounterScannerTest.java index f1324f5..1f5cf75 100644 --- a/src/test/java/com/rusefi/can/analysis/CounterScannerTest.java +++ b/src/test/java/com/rusefi/can/analysis/CounterScannerTest.java @@ -2,21 +2,28 @@ package com.rusefi.can.analysis; import org.junit.Test; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; public class CounterScannerTest { @Test public void testNotCounter() { CounterScanner.BitState state = new CounterScanner.BitState(); state.handle(true); + assertEquals(state.state, CounterScanner.BitState.StateMachine.LOOKING_FOR_FIRST_SWITCHOVER); + state.handle(false); + assertEquals(state.state, CounterScanner.BitState.StateMachine.FOUND_FIRST_SWITCHOVER); + state.handle(false); + assertEquals(CounterScanner.BitState.StateMachine.FOUND_FIRST_SWITCHOVER, state.state); + state.handle(true); + assertEquals(CounterScanner.BitState.StateMachine.HAPPY_COUNTER, state.state); + state.handle(false); state.handle(false); - assertFalse(state.couldBeCounter); + assertFalse(state.couldBeCounter()); } @Test @@ -27,6 +34,22 @@ public class CounterScannerTest { state.handle(true); state.handle(false); - assertTrue(state.couldBeCounter); + assertTrue(state.couldBeCounter()); + assertEquals(1, state.cycleLength); + } + + + @Test + public void testCounterLen2() { + CounterScanner.BitState state = new CounterScanner.BitState(); + state.handle(true); + state.handle(false); + state.handle(false); + state.handle(true); + state.handle(true); + state.handle(false); + + assertTrue(state.couldBeCounter()); + assertEquals(2, state.cycleLength); } }