fcap updated
This commit is contained in:
+193
-21
@@ -1,26 +1,59 @@
|
||||
import gex
|
||||
|
||||
CMD_STOP = 0
|
||||
CMD_PWM_CONT_START = 1
|
||||
CMD_PWM_BURST_START = 2
|
||||
CMD_PWM_CONT_READ = 10
|
||||
|
||||
# Measuring a waveform
|
||||
CMD_INDIRECT_CONT_START = 1 # keep measuring, read on demand
|
||||
CMD_INDIRECT_BURST_START = 2 # wait and reply
|
||||
|
||||
# Counting pulses
|
||||
CMD_DIRECT_CONT_START = 3 # keep measuring, read on demand
|
||||
CMD_DIRECT_BURST_START = 4 # wait and reply
|
||||
CMD_FREECOUNT_START = 5 # keep counting pulses until stopped, read on reply
|
||||
|
||||
CMD_MEASURE_SINGLE_PULSE = 6
|
||||
CMD_FREECOUNT_CLEAR = 7
|
||||
|
||||
# Results readout for continuous modes
|
||||
CMD_INDIRECT_CONT_READ = 10
|
||||
CMD_DIRECT_CONT_READ = 11
|
||||
CMD_FREECOUNT_READ = 12
|
||||
|
||||
CMD_SET_POLARITY = 20
|
||||
CMD_SET_DIR_PRESC = 21
|
||||
CMD_SET_INPUT_FILTER = 22
|
||||
CMD_SET_DIR_MSEC = 23
|
||||
|
||||
CMD_RESTORE_DEFAULTS = 30
|
||||
|
||||
|
||||
class FCAP_Report:
|
||||
def __init__(self):
|
||||
self.period = 0
|
||||
self.ontime = 0
|
||||
self.frequency = 0
|
||||
self.duty = 0
|
||||
self.period = None # s
|
||||
self.ontime = None # s
|
||||
self.frequency = None # Hz
|
||||
self.duty = None # [-]
|
||||
|
||||
# Raw data (can be used to avoid distortion by float arithmetics)
|
||||
self.period_raw = 0
|
||||
self.ontime_raw = 0
|
||||
self.sample_count = 0
|
||||
self.clock_freq = 0
|
||||
self.period_raw = None
|
||||
self.ontime_raw = None
|
||||
self.sample_count = None
|
||||
self.clock_freq = None # Hz
|
||||
self.meas_time_ms = None
|
||||
|
||||
def __str__(self):
|
||||
return "{\n f = %f Hz\n T = %f s\n Ton = %f s\n duty = %f\n}" % \
|
||||
(self.frequency, self.period, self.ontime, self.duty)
|
||||
s = "{\n"
|
||||
if self.frequency is not None:
|
||||
s += " f = %f Hz\n" % self.frequency
|
||||
if self.period is not None:
|
||||
s += " T = %f s\n" % self.period
|
||||
if self.ontime is not None:
|
||||
s += " Ton = %f s\n" % self.ontime
|
||||
if self.duty is not None:
|
||||
s += " duty = %f\n" % self.duty
|
||||
s += "}"
|
||||
|
||||
return s
|
||||
|
||||
class FCAP(gex.Unit):
|
||||
"""
|
||||
@@ -34,17 +67,95 @@ class FCAP(gex.Unit):
|
||||
""" Stop any ongoing capture """
|
||||
self._send(CMD_STOP, confirm=confirm)
|
||||
|
||||
def configure(self,
|
||||
polarity=None,
|
||||
presc=None,
|
||||
filter=None,
|
||||
msec=None,
|
||||
confirm=True):
|
||||
"""
|
||||
Re-configure some capture parameters. None = unchanged
|
||||
|
||||
polarity: 0,1 active level
|
||||
presc: 1,2,4,8 pulse counter prescaller
|
||||
filter: 0-15 digital input filter
|
||||
msec: <65535 milliseconds for direct capture
|
||||
"""
|
||||
|
||||
if polarity is not None:
|
||||
pb = gex.PayloadBuilder()
|
||||
pb.u8(polarity) # 0,1
|
||||
self._send(CMD_SET_POLARITY, pld=pb.close(), confirm=confirm)
|
||||
|
||||
if presc is not None:
|
||||
pb = gex.PayloadBuilder()
|
||||
pb.u8(presc)
|
||||
self._send(CMD_SET_DIR_PRESC, pld=pb.close(), confirm=confirm)
|
||||
|
||||
if filter is not None:
|
||||
pb = gex.PayloadBuilder()
|
||||
pb.u8(filter)
|
||||
self._send(CMD_SET_INPUT_FILTER, pld=pb.close(), confirm=confirm)
|
||||
|
||||
if msec is not None:
|
||||
pb = gex.PayloadBuilder()
|
||||
pb.u16(msec)
|
||||
self._send(CMD_SET_DIR_MSEC, pld=pb.close(), confirm=confirm)
|
||||
|
||||
def config_reset(self, confirm=True):
|
||||
""" Reset all config to persistent defaults and switch to IDLE mode. """
|
||||
self._send(CMD_RESTORE_DEFAULTS, confirm=confirm)
|
||||
|
||||
def indirect_start(self, confirm=True):
|
||||
""" Start continuous PWM measurement """
|
||||
self._send(CMD_PWM_CONT_START, confirm=confirm)
|
||||
self._send(CMD_INDIRECT_CONT_START, confirm=confirm)
|
||||
|
||||
def counter_start(self, presc=None, confirm=True):
|
||||
""" Start the free-running counter """
|
||||
|
||||
pb = gex.PayloadBuilder()
|
||||
pb.u8(presc or 0)
|
||||
self._send(CMD_FREECOUNT_START, pld=pb.close(), confirm=confirm)
|
||||
|
||||
def counter_read(self):
|
||||
""" Read the free counter value """
|
||||
|
||||
resp = self._query(CMD_FREECOUNT_READ)
|
||||
pp = gex.PayloadParser(resp.data)
|
||||
return pp.u32()
|
||||
|
||||
def counter_clear(self):
|
||||
"""
|
||||
Restart the free-running counter, returns current value before the clear.
|
||||
This should lose at most 1 tick for signals where f < core clock speed
|
||||
"""
|
||||
|
||||
resp = self._query(CMD_FREECOUNT_CLEAR)
|
||||
pp = gex.PayloadParser(resp.data)
|
||||
return pp.u32()
|
||||
|
||||
def direct_start(self, msec=None, presc=None, confirm=True):
|
||||
"""
|
||||
Start continuous PWM measurement
|
||||
|
||||
msec - measurement time (ms), <65535
|
||||
presc - pre-divider, 1,2,4,8.
|
||||
|
||||
arg None = unchanged
|
||||
"""
|
||||
|
||||
pb = gex.PayloadBuilder()
|
||||
pb.u16(msec or 0)
|
||||
pb.u8(presc or 0)
|
||||
self._send(CMD_DIRECT_CONT_START, pld=pb.close(), confirm=confirm)
|
||||
|
||||
def indirect_read(self):
|
||||
"""
|
||||
Read the current continuous measurement values
|
||||
Returns value of the last measurement in continuous mode
|
||||
Read the current indirect continuous measurement values
|
||||
Returns value of the last measurement in continuous indirect mode
|
||||
"""
|
||||
|
||||
resp = self._query(CMD_PWM_CONT_READ)
|
||||
resp = self._query(CMD_INDIRECT_CONT_READ)
|
||||
pp = gex.PayloadParser(resp.data)
|
||||
|
||||
mhz = pp.u16()
|
||||
@@ -65,11 +176,59 @@ class FCAP(gex.Unit):
|
||||
# returned in microseconds
|
||||
return rp
|
||||
|
||||
def indirect_single(self, timeout=5):
|
||||
def _process_direct_resp(self, resp):
|
||||
pp = gex.PayloadParser(resp.data)
|
||||
|
||||
presc = pp.u8()
|
||||
msec = pp.u16()
|
||||
count = pp.u32() * presc
|
||||
|
||||
rp = FCAP_Report()
|
||||
|
||||
if count > 0:
|
||||
sec = msec / 1000
|
||||
freq = count / sec
|
||||
period = 1 / freq
|
||||
|
||||
rp.period = period
|
||||
rp.frequency = freq
|
||||
|
||||
rp.sample_count = count * presc
|
||||
rp.meas_time_ms = msec
|
||||
|
||||
return rp
|
||||
|
||||
def direct_read(self):
|
||||
"""
|
||||
Perform a burst measure with averaging (sum/count)
|
||||
Read the current direct continuous measurement values
|
||||
Returns value of the last measurement in continuous direct mode
|
||||
"""
|
||||
return self.indirect_burst(count=1, timeout=timeout)
|
||||
|
||||
resp = self._query(CMD_DIRECT_CONT_READ)
|
||||
return self._process_direct_resp(resp)
|
||||
|
||||
def measure_pulse(self, polarity=None, timeout=5):
|
||||
"""
|
||||
Measure a pulse. Optionally set polarity
|
||||
"""
|
||||
|
||||
if polarity is not None:
|
||||
self.configure(polarity=polarity)
|
||||
|
||||
resp = self._query(CMD_MEASURE_SINGLE_PULSE, timeout=timeout)
|
||||
pp = gex.PayloadParser(resp.data)
|
||||
|
||||
mhz = pp.u16()
|
||||
ontime = pp.u32()
|
||||
|
||||
rp = FCAP_Report()
|
||||
rp.ontime = ontime / (mhz * 1e6) # in seconds
|
||||
|
||||
rp.clock_freq = mhz * 1e6
|
||||
rp.sample_count = 1
|
||||
rp.ontime_raw = ontime
|
||||
|
||||
return rp
|
||||
|
||||
def indirect_burst(self, count, timeout=5):
|
||||
"""
|
||||
@@ -79,7 +238,7 @@ class FCAP(gex.Unit):
|
||||
pb = gex.PayloadBuilder()
|
||||
pb.u16(count)
|
||||
|
||||
resp = self._query(CMD_PWM_BURST_START, pld=pb.close(), timeout=timeout)
|
||||
resp = self._query(CMD_INDIRECT_BURST_START, pld=pb.close(), timeout=timeout)
|
||||
pp = gex.PayloadParser(resp.data)
|
||||
|
||||
mhz = pp.u16()
|
||||
@@ -100,3 +259,16 @@ class FCAP(gex.Unit):
|
||||
|
||||
return rp
|
||||
|
||||
def direct_burst(self, msec=1000, presc=None):
|
||||
"""
|
||||
Perform direct burst measurement
|
||||
"""
|
||||
|
||||
pb = gex.PayloadBuilder()
|
||||
pb.u16(msec)
|
||||
pb.u8(presc or 0)
|
||||
|
||||
resp = self._query(CMD_DIRECT_BURST_START,
|
||||
pld=pb.close(),
|
||||
timeout=(msec/1000)+1)
|
||||
return self._process_direct_resp(resp)
|
||||
|
||||
@@ -6,13 +6,38 @@ with gex.Client(gex.TrxRawUSB()) as client:
|
||||
fcap = gex.FCAP(client, 'fcap')
|
||||
|
||||
fcap.stop()
|
||||
|
||||
fcap.indirect_start()
|
||||
#
|
||||
time.sleep(2)
|
||||
print(fcap.indirect_read())
|
||||
|
||||
while True:
|
||||
time.sleep(1)
|
||||
print(fcap.indirect_read())
|
||||
#print(fcap.indirect_burst(3, timeout=20))
|
||||
# fcap.stop()
|
||||
# #print(fcap.indirect_burst(3, timeout=20))
|
||||
|
||||
# print(fcap.indirect_burst(10, timeout=20))
|
||||
# r=fcap.indirect_burst(1000, timeout=5)
|
||||
# print(r)
|
||||
# print(r.period_raw)
|
||||
|
||||
# fcap.configure(filter=0)
|
||||
|
||||
# print(fcap.measure_pulse())
|
||||
|
||||
# print(fcap.direct_burst(10))
|
||||
#
|
||||
# fcap.direct_start(1000, 0)
|
||||
# time.sleep(2)
|
||||
#
|
||||
# print(fcap.direct_read())
|
||||
#
|
||||
# fcap.counter_start()
|
||||
# time.sleep(1)
|
||||
# print(fcap.counter_clear())
|
||||
# time.sleep(1)
|
||||
# print(fcap.counter_read())
|
||||
# time.sleep(1)
|
||||
# print(fcap.counter_clear())
|
||||
# time.sleep(1)
|
||||
# print(fcap.counter_clear())
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user