Am 02.05.2012 19:40, schrieb Petr Jakes:
Hi,
I am trying to work with HW peripherals on Raspberry Pi
To achieve this, it is necessary read/write some values from/to the
memory directly.
I am looking for some wise way how to organize the bit twiddling.
To set some specific bit, for example, it is necessary:
- read 4 bytes string representation (I am using mmap)
- transform it to the corresponding integer (I am using numpy)
- do some bit masking over this integer
- transport integer to the string representation (numpy again)
- write it back to the memory
In other words I mean: is there wise way to create an instrument/
machinery to define Class and then simply define all necessary objects
and set the bit values over object attributes so the whole bit-
twiddling remains under the hood.
say:
LED01 = GPIO(4) # gpio PIN number 4 is assigned to the LED01 name
(attribute)
LED01.on()
LED01.off()
or
gpio = GPIO()
LED01 = gpio.pin04
LED01 = 1 # led diode is shining (or gpio pin 4 is set)
LED01 = 0 # led diode is off
I have an abstract BitVector base-class that allows to get/set single
bits or several bits in a convenient way. You must define concrete
subclasses which define a _value get/set property that actually
updates the byte or word in the hardware. I use it to access bits
or groups of bits of I2C devices.
You would basically code like this, assuming an 8-bit GPIO port:
class GPIO(BitVector):
def __init__(self, address, value=0xFF, nbits=8):
self.address = address
super(GPIO, self).__init__(value, nbits)
def _get_value(self):
"read an 8-bit value from the hardware as 8-bit integer"
...
def _set_value(self, v):
"write the 8-bit value 'v' to the hardware"
...
then you can do:
gpio = GPIO(0x12345678)
led0 = gpio[4] # bit 4
led0.value = 1 # switch led on
print led0.value # get led status
For multiple bits use this (note that different from standard Python
practices, indexing works inclusive and uses [high_bitnum:low_bitnum]:
port = GPIO(0x12345678)
high_nibble = port[7:4]
print high_nibble.value
low_nibble = port[3:0]
low_nibble.value = 0xF
Thomas
class BitVector(object):
"""BitVector class, represents mutable integers
constricted to a certain range.
Single bits can be get/set by indexing with integers.
Slices can be used to get/set the bits in this range, as an
integer constricted to this range also.
Slices must use [MSB:LSB], and are inclusive.
>>> [x for x in BitVector(0xAA)]
[0, 1, 0, 1, 0, 1, 0, 1]
>>> [x for x in BitVector(0xFF)]
[1, 1, 1, 1, 1, 1, 1, 1]
>>>
>>> bv = BitVector(0)
>>> bv[6:3] = 0xf
>>> [x for x in bv]
[0, 0, 0, 1, 1, 1, 1, 0]
>>> bv[6:3] = -1
Traceback (most recent call last):
...
ValueError: value out of allowed range
>>> bv[6:3] = 16
Traceback (most recent call last):
...
ValueError: value out of allowed range
>>> hex(bv)
'0x78'
>>> bin(bv)
'0b000'
>>>
"""
def __init__(self, value=0, nbits=8):
self._nbits = nbits
self._value = value
def __index__(self):
return self._value
def __hex__(self):
return hex(self._value)
def __getitem__(self, index):
if isinstance(index, slice):
return self._getslice(index)
if not 0 <= index < self._nbits:
raise IndexError("invalid index")
return int(bool(self._value & (1 << index)))
@property
def bits(self):
"""
Return some bits as an object that has a .value property. The
.value property represents the current value of the specied
bits.
b = BitVector().bits[7:0]
b.value = ...
print b.value
"""
class Bits(object):
def __init__(self, bv):
self.bv = bv
def __getitem__(self, index):
class GetSet(object):
def __init__(self, bv):
self.bv = bv
def _get(self):
return self.bv[index]
def _set(self, value):
self.bv[index] = value
value = property(_get, _set)
return GetSet(self.bv)
return Bits(self)
def _getslice(self, index):
if index.step is not None:
raise ValueError("extended slicing not supported")
stop, start = index.stop, index.start
if start <= stop or start < 0 or stop >= self._nbits:
print "START, STOP", start, stop
raise ValueError("invalid slice range")
mask = (1 << (start+1)) - 1
return (self._value & mask) >> stop
def _setslice(self, index, value):
if index.step is not None:
raise ValueError("extended slicing not supported")
stop, start = index.stop, index.start
if start <= stop or start < 0 or stop >= se