public void Loop() { NextState = CurrentState; UpdateStatus(CurrentState.ToString()); switch (CurrentState) { case TestState.WaitForDevice: Dev.SetLed(false, false); if (IsStable(s => s.Sense)) { // Sensed a device. NextState = TestState.SoftOn; Dev.SetMode(SignTest.DeviceMode.SoftOn); } break; case TestState.WaitDeviceLeave: if (IsStable(s => s.DeviceGone)) { NextState = TestState.WaitForDevice; Dev.SetMode(SignTest.DeviceMode.Off); // Ensure that it's off. } if (Dev.GetButton()) { // If button is pressed, rerun the process for the currently attached device. WriteText("Button pressed, restarting process"); NextState = TestState.WaitForDevice; } break; case TestState.SoftOn: if (IsStable(s => s.SoftOnOk)) { NextState = TestState.PowerOn; Dev.SetMode(SignTest.DeviceMode.On); } break; case TestState.PowerOn: if (IsStable(s => s.PowerOk)) { // Higher power standards have been met. NextState = TestState.CheckFlash; } break; case TestState.CheckFlash: // Sanity test flash Dev.SetMode(SignTest.DeviceMode.FlashSpi); UInt32 flashId = Dev.FlashReadId(); WriteText("Flash ID: {0:x8}", flashId); byte[] checkData = Dev.FlashRead(0, 128); CheckReloadBitstream(); // Confirm whether flash contains the latest program if (FpgaProgram == null) { WriteText("Skipping flash contents check."); NextState = TestState.BootFpga; break; } if (!CompareBytes(checkData, 0, FpgaProgram, 0, checkData.Length)) { WriteText("Quick check shows we need to reprogram the FPGA."); HexDump(0, checkData); NextState = TestState.ProgramFpga; break; } else { WriteText("Checking full FPGA program..."); } checkData = Dev.FlashRead(0, FpgaProgram.Length); if (!CompareBytes(checkData, 0, FpgaProgram, 0, checkData.Length)) { WriteText("Full check shows we need to reprogram the FPGA."); NextState = TestState.ProgramFpga; break; } WriteText("Fpga program is correct."); NextState = TestState.BootFpga; break; case TestState.ProgramFpga: WriteText("Erasing flash sectors..."); Dev.FlashEraseRegion(0, FpgaProgram.Length); WriteText("Programming flash..."); Dev.FlashWrite(0, FpgaProgram); NextState = TestState.BootFpga; break; case TestState.BootFpga: NextState = TestState.WaitDeviceLeave; try { Dev.SetMode(SignTest.DeviceMode.FpgaActive); Dev.SetLed(true, false); WriteText("Fpga Booted!"); NextState = TestState.TestFpga; } catch (Exception ex) { WriteText("Fpga Failed to boot."); Dev.SetLed(false, true); WriteText(ex.ToString()); } break; case TestState.TestFpga: Thread.Sleep(5000); WriteText("Collecting some debug data from the FPGA"); int buffercount = 32; byte[] usbdata = new byte[64 * buffercount]; for (int i = 0; i < buffercount; i++) { byte[] data = Dev.FpgaSpi(new byte[64]); Array.Copy(data, 0, usbdata, i * 64, 64); } HexOnly(usbdata); DecodeUsbTrace(usbdata); WriteText("Sending a test image."); { uint[] image = new uint[32 * 32]; for (int y = 0; y < 32; y++) { for (int x = 0; x < 32; x++) { double angle = Math.Atan2(x - 16, 16 - y) / (2 * Math.PI); double rad = Math.Sqrt((y - 16) * (y - 16) + (x - 16) * (x - 16)); if (angle < 0) { angle += 1; } int a = (int)Math.Round(angle * 127); int r = (int)Math.Round(160 - rad * 8); int z = (x + y * 32) * 191 / (32 * 32); if (a < 0) { a = 0; } if (a > 255) { a = 255; } if (r < 0) { r = 0; } if (r > 255) { r = 255; } image[x + y * 32] = (uint)(a + r * 0x100 + z * 0x10000); } } Dev.SendImage32x32(0, image); } NextState = TestState.WaitDeviceLeave; break; } // Did the device disappear? if (CurrentState != TestState.WaitForDevice) { if (IsStable(s => s.DeviceGone, StableCount * 2)) { WriteText("Unexpected device loss."); NextState = TestState.WaitForDevice; Dev.SetMode(SignTest.DeviceMode.Off); // Ensure that it's off. } } if (NextState != CurrentState) { WriteText("State change from {0} => {1}", CurrentState, NextState); CurrentState = NextState; } }