fcap updated

doublebuf
Ondřej Hruška 7 years ago
parent 0467c240e0
commit 3ad975dfc9
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 214
      gex/units/FCAP.py
  2. 35
      pcap.py

@ -1,26 +1,59 @@
import gex import gex
CMD_STOP = 0 CMD_STOP = 0
CMD_PWM_CONT_START = 1
CMD_PWM_BURST_START = 2 # Measuring a waveform
CMD_PWM_CONT_READ = 10 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: class FCAP_Report:
def __init__(self): def __init__(self):
self.period = 0 self.period = None # s
self.ontime = 0 self.ontime = None # s
self.frequency = 0 self.frequency = None # Hz
self.duty = 0 self.duty = None # [-]
# Raw data (can be used to avoid distortion by float arithmetics) # Raw data (can be used to avoid distortion by float arithmetics)
self.period_raw = 0 self.period_raw = None
self.ontime_raw = 0 self.ontime_raw = None
self.sample_count = 0 self.sample_count = None
self.clock_freq = 0 self.clock_freq = None # Hz
self.meas_time_ms = None
def __str__(self): def __str__(self):
return "{\n f = %f Hz\n T = %f s\n Ton = %f s\n duty = %f\n}" % \ s = "{\n"
(self.frequency, self.period, self.ontime, self.duty) 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): class FCAP(gex.Unit):
""" """
@ -34,17 +67,95 @@ class FCAP(gex.Unit):
""" Stop any ongoing capture """ """ Stop any ongoing capture """
self._send(CMD_STOP, confirm=confirm) 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): def indirect_start(self, confirm=True):
""" Start continuous PWM measurement """ """ 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): def indirect_read(self):
""" """
Read the current continuous measurement values Read the current indirect continuous measurement values
Returns value of the last measurement in continuous mode 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) pp = gex.PayloadParser(resp.data)
mhz = pp.u16() mhz = pp.u16()
@ -65,11 +176,59 @@ class FCAP(gex.Unit):
# returned in microseconds # returned in microseconds
return rp 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): def indirect_burst(self, count, timeout=5):
""" """
@ -79,7 +238,7 @@ class FCAP(gex.Unit):
pb = gex.PayloadBuilder() pb = gex.PayloadBuilder()
pb.u16(count) 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) pp = gex.PayloadParser(resp.data)
mhz = pp.u16() mhz = pp.u16()
@ -100,3 +259,16 @@ class FCAP(gex.Unit):
return rp 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 = gex.FCAP(client, 'fcap')
fcap.stop() fcap.stop()
fcap.indirect_start()
while True: fcap.indirect_start()
time.sleep(1) #
time.sleep(2)
print(fcap.indirect_read()) print(fcap.indirect_read())
#print(fcap.indirect_burst(3, timeout=20))
# print(fcap.indirect_burst(10, timeout=20)) # fcap.stop()
# #print(fcap.indirect_burst(3, 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())

Loading…
Cancel
Save