Skip to content

Commit ebb915f

Browse files
author
Jasper van Bourgognie
committed
Rough first implementation of HackerSpecial
1 parent 1aef4b1 commit ebb915f

File tree

5 files changed

+302
-49
lines changed

5 files changed

+302
-49
lines changed

Devices/HackerSpecial.cs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using LabNation.DeviceInterface.Memories;
6+
using System.IO;
7+
using LabNation.DeviceInterface.DataSources;
8+
using LabNation.DeviceInterface.Hardware;
9+
using LabNation.Common;
10+
using AForge.Math;
11+
using System.Threading.Tasks;
12+
using System.Threading;
13+
#if ANDROID
14+
using Android.Content;
15+
#endif
16+
17+
namespace LabNation.DeviceInterface.Devices
18+
{
19+
public class HackerSpecial : IDevice
20+
{
21+
public ISmartScopeInterface iface { get; private set; }
22+
public bool Ready { get; private set; }
23+
public string Serial { get; private set; }
24+
25+
public ScopeFpgaRom FpgaRom { get; private set; }
26+
public ScopeFpgaSettingsMemory FpgaSettingsMemory { get; private set; }
27+
public HackerSpecial(ISmartScopeInterface iface)
28+
{
29+
this.iface = iface;
30+
this.Ready = true;
31+
this.Serial = iface.Serial;
32+
33+
memories.Clear();
34+
FpgaSettingsMemory = new ScopeFpgaSettingsMemory(iface);
35+
FpgaRom = new ScopeFpgaRom(iface);
36+
memories.Add(FpgaSettingsMemory);
37+
memories.Add(FpgaRom);
38+
39+
//Get FW contents
40+
string fwName = "SmartScopeHackerSpecial.bin";
41+
byte[] firmware = Resources.Load(fwName);
42+
43+
if (firmware == null)
44+
throw new ScopeIOException("Failed to read FW");
45+
46+
Logger.Info("Got firmware of length " + firmware.Length);
47+
if (!SmartScopeFlashHelpers.FlashFpga(this.iface, firmware))
48+
throw new ScopeIOException("failed to flash FPGA");
49+
50+
Logger.Info("FPGA flashed...");
51+
52+
SmartScopeFlashHelpers.FlashFpga(iface, firmware);
53+
}
54+
55+
private List<DeviceMemory> memories = new List<DeviceMemory>();
56+
public List<DeviceMemory> GetMemories()
57+
{
58+
return memories;
59+
}
60+
61+
public IHardwareInterface HardwareInterface { get { return this.iface; } }
62+
}
63+
}

Devices/HackerSpecialManager.cs

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading;
6+
using LabNation.DeviceInterface.Hardware;
7+
using LabNation.Common;
8+
#if ANDROID
9+
using Android.Content;
10+
#endif
11+
12+
namespace LabNation.DeviceInterface.Devices
13+
{
14+
public class HackerSpecialManager
15+
{
16+
public event DeviceConnectHandler DeviceConnected;
17+
private IDevice device = null;
18+
public IDevice Device { get { return device; } }
19+
20+
Thread pollThread;
21+
22+
#if WINDOWS
23+
Thread badDriverDetectionThread;
24+
bool running = true;
25+
DateTime? lastSmartScopeDetectedThroughWinUsb;
26+
DateTime? lastSmartScopeDetectedThroughVidPid;
27+
int WinUsbDetectionWindow = 3000;
28+
public bool BadDriver { get; private set; }
29+
int SmartScopeVid = 0x04D8;
30+
int SmartScopePid = 0xF4B5;
31+
#endif
32+
33+
#if ANDROID
34+
Context context;
35+
#endif
36+
37+
38+
public HackerSpecialManager(
39+
#if ANDROID
40+
Context context
41+
#endif
42+
)
43+
: this(
44+
#if ANDROID
45+
context,
46+
#endif
47+
null) { }
48+
49+
public HackerSpecialManager(
50+
#if ANDROID
51+
Context context
52+
#endif
53+
DeviceConnectHandler deviceConnectHandler
54+
)
55+
{
56+
#if ANDROID
57+
this.context = context;
58+
#endif
59+
this.DeviceConnected = deviceConnectHandler;
60+
}
61+
62+
public void Start(bool async = true)
63+
{
64+
pollThread = new Thread(PollUponStart);
65+
pollThread.Name = "Devicemanager Startup poll";
66+
67+
#if ANDROID
68+
InterfaceManagerXamarin.context = this.context;
69+
InterfaceManagerXamarin.Instance.onConnect += OnHardwareConnect;
70+
#elif WINUSB
71+
InterfaceManagerWinUsb.Instance.onConnect += OnHardwareConnect;
72+
#elif IOS
73+
//Nothing for the moment
74+
#else
75+
InterfaceManagerLibUsb.Instance.onConnect += OnHardwareConnect;
76+
#endif
77+
78+
pollThread.Start();
79+
80+
if (!async)
81+
pollThread.Join();
82+
}
83+
84+
private void PollUponStart()
85+
{
86+
#if ANDROID
87+
InterfaceManagerXamarin.Instance.PollDevice();
88+
#elif WINUSB
89+
InterfaceManagerWinUsb.Instance.PollDevice();
90+
badDriverDetectionThread = new Thread(SearchDeviceFromVidPidThread);
91+
badDriverDetectionThread.Name = "Bad WINUSB driver detection";
92+
BadDriver = false;
93+
badDriverDetectionThread.Start();
94+
#elif !IOS
95+
InterfaceManagerLibUsb.Instance.PollDevice();
96+
#endif
97+
}
98+
99+
public void Stop()
100+
{
101+
if(pollThread != null)
102+
pollThread.Join(100);
103+
104+
#if ANDROID
105+
//Nothing to do here, just keeping same ifdef structure as above
106+
#elif WINDOWS
107+
BadDriver = false;
108+
running = false;
109+
if(badDriverDetectionThread != null)
110+
badDriverDetectionThread.Join(100);
111+
#elif IOS
112+
//Nothing for the moment
113+
#else
114+
//Linux, MacOS
115+
InterfaceManagerLibUsb.Instance.Destroy();
116+
#endif
117+
}
118+
119+
private void OnHardwareConnect(IHardwareInterface hardwareInterface, bool connected)
120+
{
121+
string serial = hardwareInterface.Serial;
122+
if (!(hardwareInterface is ISmartScopeInterface))
123+
{
124+
Logger.Info("Ignoring hardwareinterface since not ISmartScopeInterface but " + hardwareInterface.GetType().ToString());
125+
return;
126+
}
127+
ISmartScopeInterface ssIface = hardwareInterface as ISmartScopeInterface;
128+
if(connected) {
129+
this.device = new HackerSpecial(ssIface);
130+
131+
#if WINDOWS
132+
lastSmartScopeDetectedThroughWinUsb = DateTime.Now;
133+
Logger.Debug(String.Format("Update winusb detection time to {0}", lastSmartScopeDetectedThroughWinUsb));
134+
#endif
135+
136+
if (this.DeviceConnected != null)
137+
DeviceConnected(this.device, true);
138+
}
139+
else
140+
{
141+
if (this.device != null && this.device.HardwareInterface == hardwareInterface)
142+
{
143+
if (this.DeviceConnected != null)
144+
DeviceConnected(this.device, false);
145+
}
146+
#if WINDOWS
147+
lastSmartScopeDetectedThroughWinUsb = null;
148+
#endif
149+
}
150+
}
151+
152+
#if WINDOWS
153+
public void WinUsbPoll()
154+
{
155+
InterfaceManagerWinUsb.Instance.PollDevice();
156+
}
157+
158+
private void SearchDeviceFromVidPidThread()
159+
{
160+
while (running)
161+
{
162+
Thread.Sleep(500);
163+
//Abort this thread once a device is found through WinUSB
164+
if (lastSmartScopeDetectedThroughWinUsb != null)
165+
{
166+
Logger.Debug("Good winusb driver!");
167+
BadDriver = false;
168+
running = false;
169+
return;
170+
}
171+
172+
//Try to find a device through the system management stuff
173+
string serial = null;
174+
if (LabNation.Common.Utils.TestUsbDeviceFound(SmartScopeVid, SmartScopePid, out serial))
175+
{
176+
lastSmartScopeDetectedThroughVidPid = DateTime.Now;
177+
Logger.Debug(String.Format("Update vidpid detection time to {0}", lastSmartScopeDetectedThroughVidPid));
178+
}
179+
180+
//A device was found using VID/PID at least <WinUsbDetectionWindow>ms ago
181+
if (lastSmartScopeDetectedThroughVidPid != null)
182+
{
183+
//Wait <WinUsbDetectionWindow>ms for corresponding WinUSB detection
184+
do
185+
{
186+
//If a device came in through WinUSB, stop this detection
187+
if (lastSmartScopeDetectedThroughWinUsb != null)
188+
{
189+
Logger.Debug("Good winusb driver!");
190+
BadDriver = false;
191+
running = false;
192+
return;
193+
}
194+
Thread.Sleep(100);
195+
} while ((DateTime.Now - lastSmartScopeDetectedThroughVidPid.Value).TotalMilliseconds < WinUsbDetectionWindow);
196+
197+
//If no winusb device came in during the detection window, flag a bad driver
198+
BadDriver = true;
199+
Logger.Warn("Bad WINUSB driver");
200+
}
201+
}
202+
}
203+
#endif
204+
}
205+
}

Devices/SmartScope.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,9 +225,33 @@ private void InitializeHardware()
225225

226226
//Init FPGA
227227
LogWait("Starting fpga flashing...", 0);
228-
if (!FlashFpga())
228+
229+
this.flashed = false;
230+
string fwName;
231+
byte[] firmware = null;
232+
233+
//Get FW contents
234+
try
235+
{
236+
LabNation.Common.SerialNumber s = new SerialNumber(this.Serial);
237+
fwName = String.Format("SmartScope_{0}.bin", Base36.Encode((long)s.model, 3).ToUpper());
238+
firmware = Resources.Load(fwName);
239+
}
240+
catch (Exception e)
241+
{
242+
throw new ScopeIOException("Opening FPGA FW file failed\n" + e.Message);
243+
}
244+
if (firmware == null)
245+
throw new ScopeIOException("Failed to read FW");
246+
247+
Logger.Info("Got firmware of length " + firmware.Length);
248+
if (!SmartScopeFlashHelpers.FlashFpga(this.hardwareInterface, firmware))
229249
throw new ScopeIOException("failed to flash FPGA");
250+
if (GetFpgaFirmwareVersion() == SmartScopeFlashHelpers.FPGA_VERSION_UNFLASHED)
251+
throw new ScopeIOException("Got firmware version of unflashed FPGA");
230252
LogWait("FPGA flashed...");
253+
this.flashed = true;
254+
231255
InitializeMemories();
232256
LogWait("Memories initialized...");
233257

Devices/SmartScopeFlashHelpers.cs renamed to Hardware/SmartScopeFlashHelpers.cs

Lines changed: 9 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,60 +7,26 @@
77
using LabNation.Common;
88
using LabNation.DeviceInterface.Hardware;
99

10-
namespace LabNation.DeviceInterface.Devices {
11-
partial class SmartScope {
12-
private uint FPGA_VERSION_UNFLASHED = 0xffffffff;
13-
private bool FlashFpga ()
10+
namespace LabNation.DeviceInterface.Hardware {
11+
static class SmartScopeFlashHelpers {
12+
public static uint FPGA_VERSION_UNFLASHED = 0xffffffff;
13+
14+
public static bool FlashFpga(ISmartScopeInterface hardwareInterface, byte[] firmware)
1415
{
15-
this.flashed = false;
16-
int packetSize = 32;//hardwareInterface.WriteControlMaxLength ();
16+
int packetSize = 32;
1717
int packetsPerCommand = 64;
18-
19-
if (packetSize <= 0)
20-
return false;
21-
22-
string fwName;
23-
try
24-
{
25-
LabNation.Common.SerialNumber s = new SerialNumber(this.Serial);
26-
fwName = String.Format("SmartScope_{0}.bin", Base36.Encode((long)s.model, 3).ToUpper());
27-
}
28-
catch (Exception)
29-
{
30-
return false;
31-
}
32-
33-
byte [] firmware = null;
34-
DateTime firmwareModified = DateTime.Now;
35-
int killMeNow = 2048 / 8;
18+
int padding = 2048 / 8;
3619

3720
//Data to send to keep clock running after all data was sent
3821
byte [] dummyData = new byte[packetSize];
3922
for (int i = 0; i < dummyData.Length; i++)
4023
dummyData [i] = 255;
4124

42-
//Get FW contents
43-
try {
44-
firmware = Resources.Load(fwName);
45-
} catch (Exception e) {
46-
Logger.Error("Opening FPGA FW file failed");
47-
Logger.Error(e.Message);
48-
return false;
49-
}
50-
if(firmware == null) {
51-
Logger.Error("Failed to read FW");
52-
return false;
53-
}
54-
55-
Logger.Info("Got firmware of length " + firmware.Length);
56-
5725
//Send FW to FPGA
5826
try {
5927
Stopwatch flashStopwatch = new Stopwatch ();
6028
flashStopwatch.Start ();
61-
String fwModifiedString = Utils.GetPrettyDate (firmwareModified);
62-
Logger.Debug("Firmware was created " + fwModifiedString);
63-
UInt16 commands = (UInt16) (firmware.Length / packetSize + killMeNow);
29+
UInt16 commands = (UInt16) (firmware.Length / packetSize + padding);
6430
//PIC: enter FPGA flashing mode
6531
byte[] msg = new byte[] {
6632
SmartScopeInterfaceHelpers.HEADER_CMD_BYTE,
@@ -93,7 +59,7 @@ private bool FlashFpga ()
9359
bytesSent += commandSize;
9460
}
9561
flashStopwatch.Stop ();
96-
for (int j = 0; j < killMeNow; j++) {
62+
for (int j = 0; j < padding; j++) {
9763
hardwareInterface.WriteControlBytesBulk(dummyData, false);
9864
}
9965

@@ -103,11 +69,6 @@ private bool FlashFpga ()
10369
Logger.Debug("Flushing data pipe");
10470
//Flush whatever might be left in the datapipe
10571
hardwareInterface.FlushDataPipe();
106-
if(GetFpgaFirmwareVersion() == FPGA_VERSION_UNFLASHED) {
107-
Logger.Error("Got firmware version of unflashed FPGA");
108-
return false;
109-
}
110-
this.flashed = true;
11172
} catch (ScopeIOException e) {
11273
Logger.Error("Flashing FPGA failed failed");
11374
Logger.Error(e.Message);

SmartScopeHackerSpecial.bin

174 KB
Binary file not shown.

0 commit comments

Comments
 (0)