Skip to content

Byteswap SmartScope.Rom.Map structure as needed when marshalling #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion DataSources/DataPackages/DataPackageScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ public enum DataSourceType
Viewport,
Overview
}

/// <summary>
/// Class representing an oscilloscope acquisition's channel data
/// </summary>
public class ChannelData
{
public DataSourceType source { get; private set; }
Expand All @@ -23,8 +25,22 @@ public class ChannelData
/// create a new array and with that, a new ChannelData object
/// </summary>
public Array array { get; private set; }
/// <summary>
/// Gets a value indicating whether this <see cref="LabNation.DeviceInterface.DataSources.ChannelData"/> is partial, i.e.
/// if more data is required to consider the acquisition complete. This can be false when the acquisition is still ongoing
/// while the data dump has already begun.
/// </summary>
/// <value><c>true</c> if partial; otherwise, <c>false</c>.</value>
public bool partial { get; private set; }
/// <summary>
/// Time between 2 samples in seconds
/// </summary>
/// <value>The sample period.</value>
public double samplePeriod { get; private set; }
/// <summary>
/// Time offset of the first sample.
/// </summary>
/// <value>The time offset.</value>
public double timeOffset { get; private set; }
public ChannelData(DataSourceType t, Channel channel, Array data, bool partial, double samplePeriod, double timeOffset = 0)
{
Expand Down
7 changes: 7 additions & 0 deletions Devices/DeviceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ public class DeviceManager
{
DeviceConnectHandler connectHandler;
IDevice device;
/// <summary>
/// Gets the fallback device.
/// </summary>
/// <value>The fallback device when no device is detected</value>
public IDevice fallbackDevice { get; private set; }
Thread pollThread;
#if WINDOWS
Expand Down Expand Up @@ -84,6 +88,9 @@ private void PollUponStart()

public void Stop()
{
if (device is IScope)
((IScope)device).DataSourceScope.Stop ();

if(pollThread != null)
pollThread.Join(100);
#if ANDROID
Expand Down
7 changes: 7 additions & 0 deletions Devices/DummyScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ public AcquisitionMode AcquisitionMode
this.acquisitionMode = value;
}
}
get {
return this.acquisitionMode;
}
}

public bool Running {
Expand Down Expand Up @@ -243,6 +246,10 @@ public AnalogTriggerValue TriggerAnalog
public void SetVerticalRange(AnalogChannel ch, float minimum, float maximum)
{
}
public float[] GetVerticalRange(AnalogChannel ch)
{
return new float[] { -100f, 100f };
}
public void SetProbeDivision(AnalogChannel ch, ProbeDivision division)
{
ChannelConfig[ch].probeDivision = division;
Expand Down
171 changes: 169 additions & 2 deletions Devices/IScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ public enum TriggerModes { Analog, Digital, External };
public enum TriggerDirection { RISING = 0, FALLING = 1 };
public enum Coupling { AC, DC };
public enum AcquisitionMode { SINGLE = 2, NORMAL = 1, AUTO = 0};
/// <summary>
/// Digital trigger value.
/// L Low
/// H High
/// R Rising edge
/// F Falling edge
/// X Don't care
/// </summary>
public enum DigitalTriggerValue { L, H, R, F, X };
/// <summary>
/// Describes an analog trigger
Expand Down Expand Up @@ -63,55 +71,214 @@ public AnalogTriggerValue Copy()

public interface IScope : IDevice
{
/// <summary>
/// Method to synchronously fetch scope data
/// </summary>
/// <returns>The scope data.</returns>
DataPackageScope GetScopeData();
/// <summary>
/// The DataSourceScope allows you to register a callback which
/// is called whenever new data comes in.
///
/// Mind that the DataSourceScope must be started in order for the
/// fetch thread to run.
/// </summary>
/// <value>The data source scope.</value>
DataSources.DataSource DataSourceScope { get; }

/// <summary>
/// Enabel or disable rolling mode using this property
/// </summary>
bool Rolling { get; set; }
/// <summary>
/// Start or stop the scope using this property
/// </summary>
bool Running { get; set; }
/// <summary>
/// True when the scope can go into rolling mode
/// </summary>
bool CanRoll { get; }
/// <summary>
/// True when the acquistion will be stopped after the current one
/// </summary>
bool StopPending { get; }
/// <summary>
/// True when the scope is awaiting a trigger condition to occur.
/// </summary>
bool AwaitingTrigger { get; }
/// <summary>
/// True when the scope is armed and waiting for a trigger
/// </summary>
bool Armed { get; }
void Pause();
void Resume();

/* Acquisition & Trigger */

/// <summary>
/// When the sample rate is sufficiently low and data comes in slower than
/// the transfer rate of the scope to host, the scope can optionally stream
/// data yet available before the entire acqusition buffer is filled.
///
/// When false, the scope will wait for the acquisition to complete before
/// streaming data to host. This ensures that only a single and viewport-complete
/// data package will reach the host per acquisition. If viewport settings are changed
/// while the current acquisition is not completed yet though, the scope can still
/// send data of that ongoing acquisition.
///
/// In this mode, use the <see cref="LabNation.DeviceInterface.DataSources.DataPackageScope.Identifier"/> to
/// distinguish between different acquisitions.
/// </summary>
bool PreferPartial { get; set; }
AcquisitionMode AcquisitionMode { set; }
/// <summary>
/// Sets the acquisition mode which defines the trigger behavoir
/// AUTO results in a timeout when no trigger is detected within 5ms
/// NORMAL a trigger is required for the acquisition to complete
/// SINGLE once a trigger is detected, the running acquisition will finalise
/// and the scope will stop after that.
/// </summary>
/// <value>The acquisition mode.</value>
AcquisitionMode AcquisitionMode { get; set; }
/// <summary>
/// Gets or sets the length of the acquisition buffer (in seconds)
/// </summary>
/// <value>The length of the acquisition buffer (in seconds)</value>
double AcquisitionLength { get; set; }
/// <summary>
/// Gets the sample period in seconds
/// </summary>
/// <value>The sample period in seconds</value>
double SamplePeriod { get; }
/// <summary>
/// Gets the longest possible acquisition buffer (in seconds).
/// </summary>
double AcquisitionLengthMax { get; }
/// <summary>
/// Gets the shortest possible acquisition buffer (in seconds).
/// </summary>
double AcquisitionLengthMin { get; }

/// <summary>
/// Gets or sets the acquisition buffer depth (in samples)
/// </summary>
uint AcquisitionDepth { get; set; }
/// <summary>
/// Gets or sets the trigger hold off from the first sample of the acquisition buffer (in seconds)
/// </summary>
/// <value>The trigger hold off.</value>
double TriggerHoldOff { get; set; }
/// <summary>
/// Gets the trigger mode (Analog, digital or external)
/// </summary>
TriggerModes TriggerMode { get; }
/// <summary>
/// Gets or sets the analog trigger value
/// </summary>
/// <value>The analog trigger value.</value>
AnalogTriggerValue TriggerAnalog { get; set; }
/// <summary>
/// Sets the digital trigger
/// </summary>
/// <value>The digital trigger.</value>
Dictionary<DigitalChannel, DigitalTriggerValue> TriggerDigital { set; }
/// <summary>
/// Gets or sets the width of the trigger (in samples)
/// </summary>
/// <value>The width of the trigger (in samples).</value>
uint TriggerWidth { get; set; }
/// <summary>
/// Gets or sets the voltage threshold needed to cross before a trigger is considered valid
/// </summary>
/// <value>The trigger threshold (volts).</value>
float TriggerThreshold { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this <see cref="LabNation.DeviceInterface.Devices.IScope"/> send overview buffer with each acquisition
/// </summary>
/// <value><c>true</c> if send overview buffer; otherwise, <c>false</c>.</value>
bool SendOverviewBuffer { get; set; }
/// <summary>
/// Calling this results in a trigger force
/// </summary>
void ForceTrigger();

/* Channel specifics */
/// <summary>
/// Sets the coupling (AC or DC) for an analog input channel
/// </summary>
/// <param name="channel">Channel.</param>
/// <param name="coupling">Coupling (AC/DC).</param>
void SetCoupling(AnalogChannel channel, Coupling coupling);
Coupling GetCoupling(AnalogChannel channel);
/// <summary>
/// Sets the voltage range of an analog input channel
/// </summary>
/// <param name="channel">Channel.</param>
/// <param name="minimum">Minimum.</param>
/// <param name="maximum">Maximum.</param>
void SetVerticalRange(AnalogChannel channel, float minimum, float maximum);
float[] GetVerticalRange(AnalogChannel channel);
/// <summary>
/// Sets the voltage offset of an analog input channel.
///
/// WARNING: this offset is dicated by the vertical range. Check
/// GetYOffsetMax/Min() for the possible range
/// </summary>
/// <param name="channel">Channel.</param>
/// <param name="offset">Offset.</param>
void SetYOffset(AnalogChannel channel, float offset);
float GetYOffset(AnalogChannel channel);
/// <summary>
/// Gets the maximal voltage offset for the current voltage range
/// </summary>
/// <returns>Maximum voltage offset</returns>
/// <param name="ch">Ch.</param>
float GetYOffsetMax(AnalogChannel ch);
/// <summary>
/// Gets the minimal voltage offset for the current voltage range
/// </summary>
/// <returns>Minimum voltage offset</returns>
/// <param name="ch">Ch.</param>
float GetYOffsetMin(AnalogChannel ch);
/// <summary>
/// Sets the probe division (x1, x10, x100)
/// </summary>
/// <param name="ch">Ch.</param>
/// <param name="division">Division.</param>
void SetProbeDivision(AnalogChannel ch, ProbeDivision division);
ProbeDivision GetProbeDivision(AnalogChannel ch);

/* Logic Analyser */
/// <summary>
/// Gets or sets a value indicating whether this <see cref="LabNation.DeviceInterface.Devices.IScope"/>'s logic analyser is enabled.
/// </summary>
/// <value><c>true</c> if logic analyser enabled; otherwise, <c>false</c>.</value>
bool LogicAnalyserEnabled { get; set; }
/// <summary>
/// Which analog channel to discard to use for the logic analyser data
/// </summary>
/// <value>The analog channel sacrificed for logic analyser data.</value>
AnalogChannel ChannelSacrificedForLogicAnalyser { set; }

/* Viewport */
/* Viewport */
/// <summary>
/// Sets the view port.
/// The viewport is the section of the acquisition buffer which is streamed to the host.
/// It is subsampled so that it fits within 2048 samples.
///
/// When the scope is stopped, the acquisition buffer can be downloaded completely to the
/// host, without subsampling, but this can take several seconds. Instead, the viewport
/// can be changed when only interested in a section of the acquisition buffer, potentially
/// coarser than the effective sample rate.
/// </summary>
/// <param name="offset">Offset of the first sample of the acquisition (in seconds)</param>
/// <param name="timespan">Timespan of the viewport</param>
void SetViewPort(double offset, double timespan);
double ViewPortTimeSpan { get; }
double ViewPortOffset { get; }

/// <summary>
/// Commits the settings to the device
/// </summary>
void CommitSettings();
}

Expand Down
12 changes: 6 additions & 6 deletions Devices/SmartScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ bool DiscardPreviousAcquisition

internal static double BASE_SAMPLE_PERIOD = 10e-9; //10MHz sample rate
private const int OVERVIEW_BUFFER_SIZE = 2048;
private const int ACQUISITION_DEPTH_MIN = 128; //Size of RAM
private const int ACQUISITION_DEPTH_MIN = OVERVIEW_BUFFER_SIZE; //Size of RAM
private const int ACQUISITION_DEPTH_MAX = 512 * 1024;//4 * 1024 * 1024; //Size of RAM
private const int ACQUISITION_DEPTH_DEFAULT = 512 * 1024;
private const int BYTES_PER_BURST = 64;
Expand Down Expand Up @@ -296,7 +296,7 @@ private void CalibrateAdc()
SetTriggerByte(127);
LogicAnalyserEnabled = false;
Running = true;
Logger.Info("Calibrating ADC timing");
Logger.Debug("Calibrating ADC timing");
CommitSettings();

//If the adc timing value is not the default (being 0, the first one in the list)
Expand All @@ -305,20 +305,20 @@ private void CalibrateAdc()
{
if (TestAdcRamp())
{
Logger.Info("ADC calibration OK with value from ROM = " + AdcTimingValue);
Logger.Debug("ADC calibration OK with value from ROM = " + AdcTimingValue);
return;
}
}

foreach(byte timingValue in adcTimingValues)
{
Logger.Info("Testing ADC timing value [" + timingValue + "]");
Logger.Debug("Testing ADC timing value [" + timingValue + "]");
AdcMemory[MAX19506.DATA_CLK_TIMING].Set(timingValue);
CommitSettings();
//Note: ForceTrigger won't work here yet since Ready is still false
if (TestAdcRamp())
{
Logger.Info("ADC calibration OK with value " + timingValue);
Logger.Debug("ADC calibration OK with value " + timingValue);
AdcTimingValue = timingValue;
return;
}
Expand Down Expand Up @@ -402,7 +402,7 @@ private void Configure()

CalibrateAdc();

Logger.Info("Found good ADC timing value [" + AdcTimingValue + "]");
Logger.Debug("Found good ADC timing value [" + AdcTimingValue + "]");
AcquisitionDepth = ACQUISITION_DEPTH_DEFAULT;
CommitSettings();

Expand Down
2 changes: 1 addition & 1 deletion Devices/SmartScopeFlashHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ private bool FlashFpga ()
return false;
}

Logger.Info("Got firmware of length " + firmware.Length);
Logger.Debug("Got firmware of length " + firmware.Length);

//Send FW to FPGA
try {
Expand Down
Loading