Set Pins values synchroniously
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Set Pins values synchroniously
I'd think, when doing parallel I/O, it was more common to send a multi-bit data value to a list of pins as per the original version. Speed is also an issue here: if doing parallel I/O it's usually because you need performance.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: Set Pins values synchroniously
I made a variant which allows either a singe value or a list of bits, only that two lists o tuples are provided. One for the bits and one for the pins . Speed is the same in both cases, about 100µs per bit.
Code: Select all
from machine import Pin, mem32
@micropython.viper
def set_gpio(value:int, mask:int):
GPIO_OUT = ptr32(0x3FF44004) # GPIO Output register
GPIO_OUT[0] = (GPIO_OUT[0] & mask) | value
def write_multi(data, pin_list, init=False):
mask = 0
value = 0
if type(data) is int:
for i in range(len(pin_list) - 1, -1, -1):
pin = pin_list[i]
if init:
Pin(pin, Pin.OUT)
mask |= 1 << pin
value |= ((data & 1) << pin)
data >>= 1
else:
for i in range(len(pin_list)):
pin = pin_list[i]
if init:
Pin(pin, Pin.OUT)
mask |= 1 << pin
value |= ((data[i] & 1) << pin)
mask = 0xffffffff - mask
set_gpio(value, mask)
def run():
init = True
for n in range(8): # supplying a singe value
write_multi(n, (14, 18, 4), init)
init = False
for n in range(8): # supplying a list of bits
write_multi((n >> 2, n >> 1, n), (14, 18, 4), init)
Re: Set Pins values synchroniously
Another variant, but just for the int value, using viper code. The init is outside the call. The first call takes 20µs, the following ones 8µs:
Viper does not like range(), so the loop is made in a basic mode. And it is very sensitive to the code size. If I add both variants (int and tuple for data), the call takes ~18µs.
Code: Select all
from machine import Pin
@micropython.viper
def write_multi(data:int, pin_list:ptr8, plen:int):
GPIO_OUT = ptr32(0x3FF44004) # GPIO Output register
mask = 0
value = 0
i = plen - 1
while i >= 0:
pin = pin_list[i]
mask |= 1 << pin
value |= ((data & 1) << pin)
data >>= 1
i -= 1
mask = int(0xffffffff) - mask
GPIO_OUT[0] = (GPIO_OUT[0] & mask) | value
def run():
pin_list = bytearray((14,18,4))
for p in pin_list:
Pin(p, Pin.OUT)
pl = len(pin_list)
for n in range(8):
write_multi(n, pin_list, pl)