Skip to content

Commit 99937a4

Browse files
authored
Merge pull request #776 from MugheesChohan/PulseWidthAmplitudeModification
Adding support for amplitude output waveform for pulse width filter
2 parents 4474d25 + cd696a9 commit 99937a4

File tree

1 file changed

+87
-4
lines changed

1 file changed

+87
-4
lines changed

scopeprotocols/PulseWidthMeasurement.cpp

Lines changed: 87 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ PulseWidthMeasurement::PulseWidthMeasurement(const string& color)
3939
: Filter(color, CAT_MEASUREMENT)
4040
{
4141
AddStream(Unit(Unit::UNIT_FS), "data", Stream::STREAM_TYPE_ANALOG, Stream::STREAM_DO_NOT_INTERPOLATE);
42+
AddStream(Unit(Unit::UNIT_VOLTS), "Amplitude", Stream::STREAM_TYPE_ANALOG, Stream::STREAM_DO_NOT_INTERPOLATE);
4243

4344
//Set up channels
4445
CreateInput("din");
@@ -91,12 +92,20 @@ void PulseWidthMeasurement::Refresh()
9192
auto uddin = dynamic_cast<UniformDigitalWaveform*>(din);
9293
auto sddin = dynamic_cast<SparseDigitalWaveform*>(din);
9394
vector<int64_t> edges;
95+
float average_voltage = 0;
96+
float max_value;
97+
size_t temp = 0;
98+
99+
if(uadin)
100+
average_voltage = GetAvgVoltage(uadin);
101+
else if(sadin)
102+
average_voltage = GetAvgVoltage(sadin);
94103

95104
//Auto-threshold analog signals at 50% of full scale range
96105
if(uadin)
97-
FindZeroCrossings(uadin, GetAvgVoltage(uadin), edges);
106+
FindZeroCrossings(uadin, average_voltage, edges);
98107
else if(sadin)
99-
FindZeroCrossings(sadin, GetAvgVoltage(sadin), edges);
108+
FindZeroCrossings(sadin, average_voltage, edges);
100109

101110
//Just find edges in digital signals
102111
else if(uddin)
@@ -111,11 +120,19 @@ void PulseWidthMeasurement::Refresh()
111120
return;
112121
}
113122

114-
//Create the output
123+
//Create the output for pulse width waveform
115124
auto cap = SetupEmptySparseAnalogOutputWaveform(din, 0, true);
116125
cap->m_timescale = 1;
117126
cap->PrepareForCpuAccess();
118127

128+
//Create the output for amplitude waveform for analog inputs only
129+
auto cap1 = (uadin || sadin) ? SetupEmptySparseAnalogOutputWaveform(din, 1, true) : NULL;
130+
if(cap1)
131+
{
132+
cap1->m_timescale = 1;
133+
cap1->PrepareForCpuAccess();
134+
}
135+
119136
size_t elen = edges.size();
120137
for(size_t i=0; i < (elen - 2); i+= 2)
121138
{
@@ -125,15 +142,81 @@ void PulseWidthMeasurement::Refresh()
125142

126143
int64_t delta = end - start;
127144

145+
//Push pulse width information
128146
cap->m_offsets.push_back(start);
129147
cap->m_durations.push_back(delta);
130148
cap->m_samples.push_back(delta);
149+
150+
// Find amplitude information for the pulses
151+
if(uadin)
152+
{
153+
int64_t start_index = (start - din->m_triggerPhase) / din->m_timescale;
154+
int64_t end_index = (end - din->m_triggerPhase) / din->m_timescale;
155+
max_value = average_voltage;
156+
157+
// Find out the maximum value of the pulse within boundary of the detected pulse
158+
for (int64_t j = start_index; j < end_index; j++)
159+
{
160+
if(uadin->m_samples[j] > max_value)
161+
max_value = uadin->m_samples[j];
162+
}
163+
164+
//Push amplitude information
165+
cap1->m_offsets.push_back(start);
166+
cap1->m_durations.push_back(delta);
167+
cap1->m_samples.push_back(max_value);
168+
}
169+
else if (sadin)
170+
{
171+
int64_t start_offs = (start - din->m_triggerPhase) / din->m_timescale;
172+
int64_t end_offs = (end - din->m_triggerPhase) / din->m_timescale;
173+
max_value = average_voltage;
174+
175+
//Parse the waveform to get to a detected pulse
176+
for (size_t j = temp; j < sadin->size(); j++)
177+
{
178+
// Find out maximum value of the pulse within boundary of the detected pulse
179+
if ((sadin->m_offsets[j] >= start_offs) && (sadin->m_offsets[j] <= end_offs))
180+
{
181+
if(sadin->m_samples[j] > max_value)
182+
max_value = sadin->m_samples[j];
183+
}
184+
185+
//End of one pulse reached. Record j, so that next time we start from this index for next pulse if any
186+
else if (sadin->m_offsets[j] > end_offs)
187+
{
188+
temp = j;
189+
break;
190+
}
191+
}
192+
193+
//Push amplitude information
194+
cap1->m_offsets.push_back(start);
195+
cap1->m_durations.push_back(delta);
196+
cap1->m_samples.push_back(max_value);
197+
}
131198
}
132199

133200
SetData(cap, 0);
134-
135201
cap->MarkModifiedFromCpu();
136202

203+
if(sadin || uadin)
204+
{
205+
//Set amplitude output waveform
206+
SetData(cap1, 1);
207+
cap1->MarkModifiedFromCpu();
208+
}
209+
else if(uddin || sddin)
210+
{
211+
//Switch output waveform to digital
212+
m_streams[1].m_stype = Stream::STREAM_TYPE_DIGITAL;
213+
m_streams[1].m_flags = 0;
214+
215+
//For digital inputs, amplitude information is same as input
216+
SetData(din, 1);
217+
din->MarkModifiedFromCpu();
218+
}
219+
137220
if (GetVoltageRange(0) == 0)
138221
SetVoltageRange(10000000000000, 0);
139222
}

0 commit comments

Comments
 (0)