<commit_before>
import threading, collections, time, struct, socket, logging

from functools import partial
from types import MethodType

from pymoku import NotDeployedException, ValueOutOfRangeException

REG_CTL 	= 0
REG_STAT	= 1
REG_ID1		= 2
REG_ID2		= 3
REG_PAUSE	= 4
REG_OUTLEN	= 5
REG_FILT	= 6
REG_FRATE	= 7
REG_SCALE	= 8
REG_OFFSET	= 9
REG_OFFSETA	= 10
REG_STRCTL0	= 11
REG_STRCTL1	= 12
REG_AINCTL	= 13
# 14 was Decimation before that moved in to instrument space
REG_PRETRIG	= 15
REG_CAL1, REG_CAL2, REG_CAL3, REG_CAL4, REG_CAL5, REG_CAL6, REG_CAL7, REG_CAL8 = range(16, 24)
REG_CAL9, REG_CAL10 = range(24, 26)
REG_STATE	= 63

# Common instrument parameters
ADC_SMP_RATE = 500e6
DAC_SMP_RATE = 1e9
CHN_BUFLEN = 2**14

### None of these constants will be exported to pymoku.instruments. If an instrument wants to
### give users access to these (e.g. relay settings) then the Instrument should define their
### own symbols equal to these guys

# REG_CTL Constants
COMMIT		= 0x80000000
INSTR_RST	= 0x00000001

# REG_OUTLEN Constants
ROLL		= (1 << 29)
SWEEP		= (1 << 30)
FULL_FRAME	= 0

# REG_FILT Constants
RDR_CUBIC	= 0
RDR_MINMAX	= 1
RDR_DECI	= 2
RDR_DDS		= 3

# REG_AINCTL Constants
RELAY_DC	= 1
RELAY_LOWZ	= 2
RELAY_LOWG	= 4

log = logging.getLogger(__name__)

"""
The following three functions provide some trickery, attaching getter and setter methods
to the instrument class, allowing a user to manipulate attributes directly and have their
values correctly packed in to, and extracted from, registers.

Each instrument, including this top instrument, defines a list of tuples that declare which
attributes live in which registers, and how to access them.  This list is then passed to
:any:`_attach_register_handlers` which builds the method objects and attaches them to the
class.

The tuple is of the form

(name, register, set-transform, get-transform)

name: The name the attribute will have
register: The register, or tuple of registers, the attribute will be packed to/from
set-transform: User (natural) units to register. Function gets passed the old value of the
	register so existing fields can be preserved. Usually written as a lambda in the list
	definition. If *register* is a tuple, the old register values are a tuple and this function
	must return a tuple of new register values in the same order. Should return None, or a tuple
	of Nones, if the input value is out of range.
get-transform: Register(s) to natural units. If *register* is a tuple, the sole argument to
	this function will also be a tuple.
"""

def _get_meth(reg, get_xform, self):
	# Return local if present. Support a single register or a tuple of registers
	try:
		c = [ self._localregs[r] if self._localregs[r] is not None else self._remoteregs[r] or 0 for r in reg ]
		if all(i is not None for i in c): return get_xform(c)
	except TypeError:
		c = self._localregs[reg] if self._localregs[reg] is not None else self._remoteregs[reg] or 0
		if c is not None: return get_xform(c)

def _set_meth(reg, set_xform, self, data):
	# Support a single register or a tuple of registers
	try:
		old = [ self._localregs[r] if self._localregs[r] is not None else self._remoteregs[r] or 0 for r in reg ]
	except TypeError:
		old = self._localregs[reg] if self._localregs[reg] is not None else self._remoteregs[reg] or 0

	new = set_xform(data, old)
	if new is None:
		raise ValueOutOfRangeException("Reg %d Data %d" % (reg, data))

	try:
		for r, n in zip(reg, new):
			self._localregs[r] = n
	except TypeError:
		self._localregs[reg] = new

def _attach_register_handlers(handler_list, cls):
	# This method could be simpler. Originally we wanted get/setter functions attached to
	# the Class itself. Now that we've rewritten the __{get,set}item__ functions for this
	# class and are storing in our own dict, we don't really need to pre-assemble the functions,
	# we could just call _{get,set}_meth with the right values right from the __{get,set}item__
	# functions.
	for name, reg, setter, getter in handler_list:
		if getter is not None:
			p = partial(_get_meth, reg, getter)
			p.__name__ = "get_" + name
			p.__doc__ = "Autogenerated Getter for %s" % name
			m = MethodType(p, None, cls)
			cls._accessor_dict["get_" + name] = m

		if setter is not None:
			p = partial(_set_meth, reg, setter)
			p.__name__ = "set_" + name
			p.__doc__ = "Autogenerated Setter for %s" % name
			m = MethodType(p, None, cls)
			cls._accessor_dict["set_" + name] = m

def _usgn(i, width):
	""" Return i as an unsigned of given width, raising exceptions for out of bounds """
	if 0 <= i <= 2**width:
		return int(i)

	raise ValueOutOfRangeException("%d doesn't fit in %d unsigned bits" % (i, width))

def _sgn(i, width):
	""" Return the unsigned that, when interpretted with given width, represents
	    the signed value i """
	if i < -2**(width - 1) or 2**(width - 1) - 1 < i:
		raise ValueOutOfRangeException("%d doesn't fit in %d signed bits" % (i, width))

	if i >= 0:<commit_msg>Instrument: Fix unsigned register accessor helper for off by 1 at the high end<commit_after>
import threading, collections, time, struct, socket, logging

from functools import partial
from types import MethodType

from pymoku import NotDeployedException, ValueOutOfRangeException

REG_CTL 	= 0
REG_STAT	= 1
REG_ID1		= 2
REG_ID2		= 3
REG_PAUSE	= 4
REG_OUTLEN	= 5
REG_FILT	= 6
REG_FRATE	= 7
REG_SCALE	= 8
REG_OFFSET	= 9
REG_OFFSETA	= 10
REG_STRCTL0	= 11
REG_STRCTL1	= 12
REG_AINCTL	= 13
# 14 was Decimation before that moved in to instrument space
REG_PRETRIG	= 15
REG_CAL1, REG_CAL2, REG_CAL3, REG_CAL4, REG_CAL5, REG_CAL6, REG_CAL7, REG_CAL8 = range(16, 24)
REG_CAL9, REG_CAL10 = range(24, 26)
REG_STATE	= 63

# Common instrument parameters
ADC_SMP_RATE = 500e6
DAC_SMP_RATE = 1e9
CHN_BUFLEN = 2**14

### None of these constants will be exported to pymoku.instruments. If an instrument wants to
### give users access to these (e.g. relay settings) then the Instrument should define their
### own symbols equal to these guys

# REG_CTL Constants
COMMIT		= 0x80000000
INSTR_RST	= 0x00000001

# REG_OUTLEN Constants
ROLL		= (1 << 29)
SWEEP		= (1 << 30)
FULL_FRAME	= 0

# REG_FILT Constants
RDR_CUBIC	= 0
RDR_MINMAX	= 1
RDR_DECI	= 2
RDR_DDS		= 3

# REG_AINCTL Constants
RELAY_DC	= 1
RELAY_LOWZ	= 2
RELAY_LOWG	= 4

log = logging.getLogger(__name__)

"""
The following three functions provide some trickery, attaching getter and setter methods
to the instrument class, allowing a user to manipulate attributes directly and have their
values correctly packed in to, and extracted from, registers.

Each instrument, including this top instrument, defines a list of tuples that declare which
attributes live in which registers, and how to access them.  This list is then passed to
:any:`_attach_register_handlers` which builds the method objects and attaches them to the
class.

The tuple is of the form

(name, register, set-transform, get-transform)

name: The name the attribute will have
register: The register, or tuple of registers, the attribute will be packed to/from
set-transform: User (natural) units to register. Function gets passed the old value of the
	register so existing fields can be preserved. Usually written as a lambda in the list
	definition. If *register* is a tuple, the old register values are a tuple and this function
	must return a tuple of new register values in the same order. Should return None, or a tuple
	of Nones, if the input value is out of range.
get-transform: Register(s) to natural units. If *register* is a tuple, the sole argument to
	this function will also be a tuple.
"""

def _get_meth(reg, get_xform, self):
	# Return local if present. Support a single register or a tuple of registers
	try:
		c = [ self._localregs[r] if self._localregs[r] is not None else self._remoteregs[r] or 0 for r in reg ]
		if all(i is not None for i in c): return get_xform(c)
	except TypeError:
		c = self._localregs[reg] if self._localregs[reg] is not None else self._remoteregs[reg] or 0
		if c is not None: return get_xform(c)

def _set_meth(reg, set_xform, self, data):
	# Support a single register or a tuple of registers
	try:
		old = [ self._localregs[r] if self._localregs[r] is not None else self._remoteregs[r] or 0 for r in reg ]
	except TypeError:
		old = self._localregs[reg] if self._localregs[reg] is not None else self._remoteregs[reg] or 0

	new = set_xform(data, old)
	if new is None:
		raise ValueOutOfRangeException("Reg %d Data %d" % (reg, data))

	try:
		for r, n in zip(reg, new):
			self._localregs[r] = n
	except TypeError:
		self._localregs[reg] = new

def _attach_register_handlers(handler_list, cls):
	# This method could be simpler. Originally we wanted get/setter functions attached to
	# the Class itself. Now that we've rewritten the __{get,set}item__ functions for this
	# class and are storing in our own dict, we don't really need to pre-assemble the functions,
	# we could just call _{get,set}_meth with the right values right from the __{get,set}item__
	# functions.
	for name, reg, setter, getter in handler_list:
		if getter is not None:
			p = partial(_get_meth, reg, getter)
			p.__name__ = "get_" + name
			p.__doc__ = "Autogenerated Getter for %s" % name
			m = MethodType(p, None, cls)
			cls._accessor_dict["get_" + name] = m

		if setter is not None:
			p = partial(_set_meth, reg, setter)
			p.__name__ = "set_" + name
			p.__doc__ = "Autogenerated Setter for %s" % name
			m = MethodType(p, None, cls)
			cls._accessor_dict["set_" + name] = m

def _usgn(i, width):
	""" Return i as an unsigned of given width, raising exceptions for out of bounds """
	if 0 <= i < 2**width:
		return int(i)

	raise ValueOutOfRangeException("%d doesn't fit in %d unsigned bits" % (i, width))

def _sgn(i, width):
	""" Return the unsigned that, when interpretted with given width, represents
	    the signed value i """
	if i < -2**(width - 1) or 2**(width - 1) - 1 < i:
		raise ValueOutOfRangeException("%d doesn't fit in %d signed bits" % (i, width))

	if i >= 0:
{'fraction_non_alphanumeric': 0.08167770419426049, 'fraction_numerical': 0.0201685731487056, 'mean_word_length': 4.229275970619097, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7182113', 'n_tokens_mistral': 3578, 'n_tokens_neox': 3282, 'n_words': 1366}