public static void IndicatorsControls( // keypad FPGA.OutputSignal <bool> K7, FPGA.OutputSignal <bool> K6, FPGA.OutputSignal <bool> K5, FPGA.OutputSignal <bool> K4, FPGA.InputSignal <bool> K3, FPGA.InputSignal <bool> K2, FPGA.InputSignal <bool> K1, FPGA.InputSignal <bool> K0, IndicatorsControlsState controlsState) { Sequential keypadHandler = () => { Keypad4x4.ReadASCIICode(K7, K6, K5, K4, K3, K2, K1, K0, out controlsState.keyCode); }; FPGA.Config.OnTimer(TimeSpan.FromMilliseconds(20), keypadHandler); Sequential tickHandler = () => { controlsState.counterMs++; }; FPGA.Config.OnTimer(TimeSpan.FromMilliseconds(1), tickHandler); }
public static void LEDControl(IndicatorsControlsState controlState) { Sequential uiControlsHandler = () => { Func <bool> noKey = () => controlState.keyCode == 0; switch (controlState.keyCode) { case KeypadKeyCode.D2: if (controlState.dim < 10) { controlState.dim++; } break; case KeypadKeyCode.D8: if (controlState.dim > 1) { controlState.dim--; } break; case KeypadKeyCode.D1: if (controlState.flashSpeedMs > 100) { controlState.flashSpeedMs -= 100; } break; case KeypadKeyCode.D7: if (controlState.flashSpeedMs < 2000) { controlState.flashSpeedMs += 100; } break; case KeypadKeyCode.ENT: controlState.mode = eIndicatorMode.Solid; break; case KeypadKeyCode.D0: controlState.mode = eIndicatorMode.Blinking; break; case KeypadKeyCode.ESC: controlState.mode = eIndicatorMode.Sliding; break; } FPGA.Runtime.WaitForAllConditions(noKey); }; FPGA.Config.OnTimer(TimeSpan.FromMilliseconds(50), uiControlsHandler); }
public static async Task Aggregator( // blinker FPGA.OutputSignal <bool> LED1, // keypad FPGA.OutputSignal <bool> K7, FPGA.OutputSignal <bool> K6, FPGA.OutputSignal <bool> K5, FPGA.OutputSignal <bool> K4, FPGA.InputSignal <bool> K3, FPGA.InputSignal <bool> K2, FPGA.InputSignal <bool> K1, FPGA.InputSignal <bool> K0, // banks FPGA.OutputSignal <bool> Bank1, FPGA.OutputSignal <bool> Bank2, // WS2812 FPGA.OutputSignal <bool> DOUT ) { QuokkaBoard.OutputBank(Bank1); QuokkaBoard.InputBank(Bank2); IndicatorsControlsState controlsState = new IndicatorsControlsState(); IsAlive.Blink(LED1); Peripherals.IndicatorsControls( K7, K6, K5, K4, K3, K2, K1, K0, controlsState); LEDControl(controlsState); IndicatorsControl( controlsState, DOUT); }
public static void IndicatorsControl( IndicatorsControlsState controlState, FPGA.OutputSignal <bool> DOUT ) { bool internalDOUT = false; FPGA.Config.Link(internalDOUT, DOUT); object indicatorLock = new object(); Sequential ledHandler = () => { while (true) { lock (indicatorLock) { IndicatorsEngine.Process(controlState); } } }; FPGA.Config.OnStartup(ledHandler); Sequential drawHandler = () => { byte[] buffData = new byte[8]; uint[] buff = new uint[buffData.Length * 8]; uint indicatorColor = 0; switch (controlState.lastIndicator) { case eIndicatorType.Left: Graphics.LeftIndicator(buffData, controlState.dim, out indicatorColor); break; case eIndicatorType.Right: Graphics.RightIndicator(buffData, controlState.dim, out indicatorColor); break; case eIndicatorType.Break: Graphics.BreakIndicator(buffData, controlState.dim, out indicatorColor); break; } Graphics.DrawIndicator( buffData, buff, indicatorColor, controlState.mode == eIndicatorMode.Blinking ? controlState.isIndicatorActive : true); if (controlState.mode == eIndicatorMode.Sliding) { lock (indicatorLock) { Graphics.ApplyShiftMask( buff, controlState.lastIndicator == eIndicatorType.Right ? controlState.slideValue : int.MinValue, controlState.lastIndicator == eIndicatorType.Left ? controlState.slideValue : int.MaxValue ); switch (controlState.lastIndicator) { case eIndicatorType.Left: controlState.slideValue = controlState.slideValue >= 15 ? 0 : controlState.slideValue + 1; break; case eIndicatorType.Right: controlState.slideValue = controlState.slideValue <= 0 ? 15 : controlState.slideValue - 1; break; } } } Graphics.Draw(buff, out internalDOUT); }; FPGA.Config.OnTimer(TimeSpan.FromMilliseconds(50), drawHandler); Sequential keypadHandler = () => { while (true) { uint keyEventTimeStamp = controlState.counterMs; eIndicatorType nextIndicator = controlState.nextIndicator; switch (controlState.keyCode) { case KeypadKeyCode.D6: nextIndicator = eIndicatorType.Right; break; case KeypadKeyCode.D4: nextIndicator = eIndicatorType.Left; break; case KeypadKeyCode.STOP: nextIndicator = eIndicatorType.Break; break; default: nextIndicator = eIndicatorType.None; break; } if (nextIndicator != controlState.nextIndicator) { lock (indicatorLock) { controlState.nextIndicator = nextIndicator; controlState.nextIndicatorKeyEventTimeStamp = keyEventTimeStamp; } } } }; FPGA.Config.OnStartup(keypadHandler); }
public static void Process(IndicatorsControlsState controlState) { uint currentTimeStamp = controlState.counterMs; // resetting flashIndicatorTimeStamp to 0 will trigger isIndicatorActive on first run Action updateIndicator = () => { controlState.lastIndicator = controlState.nextIndicator; controlState.lastIndicatorTimeStamp = controlState.nextIndicatorKeyEventTimeStamp; switch (controlState.lastIndicator) { case eIndicatorType.Left: controlState.slideValue = 0; break; case eIndicatorType.Right: controlState.slideValue = 15; break; default: controlState.slideValue = 0; break; } }; Action resetBlinker = () => { controlState.flashIndicatorTimeStamp = 0; controlState.isIndicatorActive = false; }; Action setBlinker = () => { controlState.flashIndicatorTimeStamp = currentTimeStamp; controlState.isIndicatorActive = true; }; Action toggleBlinker = () => { controlState.flashIndicatorTimeStamp = currentTimeStamp; controlState.isIndicatorActive = !controlState.isIndicatorActive; }; Action resetAutoBlinking = () => { controlState.autoIndicatorTimeStamp = 0; }; Action setAutoBlinking = () => { controlState.autoIndicatorTimeStamp = controlState.lastIndicatorTimeStamp; }; if (controlState.lastIndicator != controlState.nextIndicator) { // indicator was changed if (controlState.autoIndicatorTimeStamp != 0) { // running on auto indicator if (controlState.nextIndicator == eIndicatorType.None) { // no key pressed if ( // was break signal (controlState.lastIndicator == eIndicatorType.Break) || // timed out and wait for not active (!controlState.isIndicatorActive && (controlState.slideValue == 0 || controlState.slideValue == 15) && currentTimeStamp - controlState.autoIndicatorTimeStamp >= 3000)) { // turn off auto indicator after 3 seconds and when it is off to avoid quick blinks resetAutoBlinking(); updateIndicator(); } // do nothing if running on auto and nothing changed } else { // different indicator was pressed, reset auto state resetAutoBlinking(); updateIndicator(); setBlinker(); } } else { if (controlState.nextIndicator == eIndicatorType.None && (controlState.lastIndicatorTimeStamp == 0 || (currentTimeStamp - controlState.lastIndicatorTimeStamp) <= 500)) { // turn on auto indicator if key was pressed less then 500 ms setAutoBlinking(); } else { updateIndicator(); setBlinker(); } } } // blinking logic switch (controlState.lastIndicator) { case eIndicatorType.None: controlState.isIndicatorActive = false; break; case eIndicatorType.Break: controlState.isIndicatorActive = true; break; default: if (controlState.flashSpeedMs != 0 && (currentTimeStamp - controlState.flashIndicatorTimeStamp >= controlState.flashSpeedMs)) { toggleBlinker(); } break; } }