From 44ce30402ba41966a33c90e91198615240b9af28 Mon Sep 17 00:00:00 2001 From: Chadwick Boulay Date: Thu, 29 May 2025 22:44:13 -0400 Subject: [PATCH 1/2] Keep a separate config var to track number of channels per sample group --- src/pycbsdk/cbhw/device/base.py | 1 + src/pycbsdk/cbhw/device/nsp.py | 1 + 2 files changed, 2 insertions(+) diff --git a/src/pycbsdk/cbhw/device/base.py b/src/pycbsdk/cbhw/device/base.py index e6783f4..73ac2db 100644 --- a/src/pycbsdk/cbhw/device/base.py +++ b/src/pycbsdk/cbhw/device/base.py @@ -31,6 +31,7 @@ def __init__(self, params: Params): "proc_chans": 0, "channel_infos": {}, "group_infos": {}, + "group_nchans": {}, "sysfreq": None, # Should be 30_000 for legacy or 1e9 for Gemini PTP } # Init group_callbacks dict with an empty list for each supported smp grp (1-5:SMP; 6:RAW) diff --git a/src/pycbsdk/cbhw/device/nsp.py b/src/pycbsdk/cbhw/device/nsp.py index f028a19..ef7306e 100644 --- a/src/pycbsdk/cbhw/device/nsp.py +++ b/src/pycbsdk/cbhw/device/nsp.py @@ -457,6 +457,7 @@ def _handle_groupinfo(self, pkt): else: chan_list = set() self._config["group_infos"][pkt.group] = chan_list + self._config["group_nchans"][pkt.group] = len(chan_list) def _handle_configall(self, pkt): if pkt.header.dlen > 0: From 26383153194f4ef669f5d70b700808efeac83072 Mon Sep 17 00:00:00 2001 From: Chadwick Boulay Date: Thu, 29 May 2025 22:49:12 -0400 Subject: [PATCH 2/2] When handling the sample group packets, if the number of channels is odd then slice the last channel off. --- src/pycbsdk/cbhw/handler.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pycbsdk/cbhw/handler.py b/src/pycbsdk/cbhw/handler.py index 9bc4fbd..63fddff 100644 --- a/src/pycbsdk/cbhw/handler.py +++ b/src/pycbsdk/cbhw/handler.py @@ -82,11 +82,13 @@ def run(self) -> None: b_debug_unknown = True # If there are no callbacks and it's not a group or event packet, then debug. # See if we have any callbacks registered for this type of packet. + b_grp = False if chid & CBSpecialChan.CONFIGURATION: callbacks = self._device.config_callbacks[pkt_type] elif chid == CBSpecialChan.GROUP: # This is a sample group packet. The pkt_type is actually the sample group id (1-6) if pkt_type in self._device.group_callbacks: + b_grp = True callbacks = self._device.group_callbacks[pkt_type] else: # Known bug https://blackrockengineering.atlassian.net/browse/CSCI-95 @@ -106,6 +108,12 @@ def run(self) -> None: pkt = self._packet_factory.make_packet( data, chid=chid, pkt_type=pkt_type, chantype=chantype ) + if b_grp: + # Note: pkt.data length is always a multiple of 4 bytes = 32 bits = 2 channels * 16 bits. + n_chans = self._device.config["group_nchans"][pkt_type] + if n_chans % 2 != 0: + # Odd number of channels enabled then we have an extra 16 bits of data. + pkt.data = pkt.data[:n_chans] # Between the time the callbacks are grabbed above and the time we actually call them, # it's possible for the client to unregister the callback. # Thus it's very important that a callback is unregistered and some time is allowed to pass