Skip to main content

A Python library used to communicate with TrgenPort devices.

Project description

trgenpy 🐍🧠

A Python library for IIT's Trgen device by AgliotiLab

PyPI version Python Version License pipeline status coverage report

The full documentation is available here.


Index


Getting started

How to install

To install this package use is required Python >= 3.9

pip install trgenpy

Architecture

As explained in this Mermaid diagram, we see that we can "attach" n (0-25) TrgenPorts to the TrgenClient

graph TD
    A[TrgenClient]
    A --> Impl[TrgenImplementation]
    A --> B0[TrgenPort 0]
    A --> B1[TrgenPort 1]
    A --> BN[TrgenPort n]
    B0 --> P0[TrgenPin]
    B1 --> P1[TrgenPin]
    BN --> PN[TrgenPin]
    B0 --> M0[Memory]
    B1 --> M1[Memory]
    BN --> MN[Memory]
    M0 --> I0[Instruction 0]
    M0 --> I1[Instruction 1]
    M0 --> I2[Instruction n]
    M1 --> J0[Instruction 0]
    M1 --> J1[Instruction 1]
    M1 --> J2[Instruction n]
    MN --> K0[Instruction 0]
    MN --> K1[Instruction 1]
    MN --> K2[Instruction n]
client = TrgenClient() # now I can use this client for any purpose.

Each TrgenPortcan be programmed with a bunch of instructions. We can use the function set_instruction() in many memory slots. Finally, we can use set_trgen_memory to a specific TrgenPort and execute the TrgenClient with client.start()

NOTE

Each TrgenPort can support a list of N instructions, where N = 2^MTML (Max TrgenPort Memory Length)

the import ways

# you can us it like this:
import trgenpy as tp
client = tp.TrgenClient()

# or like this:
from from trgenpy import TrgenClient,TrgenPin,active_for_us,unactive_for_us,end,wait_ne,wait_pe
client = TrgenClient()

Client

The TrgenClient is the object that stores all the information about the socket connection between you and the Trgen.
You can instantiate the TrgenClient object like this:

client = TrgenClient() 

Once the client object is created you can connect to Trgen...

client.connect()

...or check device availability

isAavailable = client.is_available() # true / false

Single TrgenPort Send

To send a defaul trigger signal (positive square with a logic state of 20µs) you can use the sendTrigger() function:

client.sendTrigger()

Custom Trigger Send

If you want to send trigger to a custom list inside the pinout you can use the sendCustomTrigger() function:

client.sendCustomTrigger([TrgenPin.NS0,TrgenPin.GPIO0])

Sending Markers

If you want to send a marker value to all (Neuroscan,Synamps and GPIO) ports you can use the sendMarker() function:

client.sendMarker(13)

if you want invert the bit order, just flag the LSB argument (Trueby default)

client.sendMarker(13,LSB=False)

if you want to send different markers simultaiously on different ports you can use the arguments:

  • markerNS
  • markerSA
  • markerGPIO

like this:

client.sendMarker(markerNS=8,markerSA=2,markerGPIO=15)

TrgenPort

The TrgenPort object defines a single trigger behaviours through its id. This is the list of supported TrgenPin values for the Trgen:

TrgenPin List

  • Neuroscan IDs The Neuroscan pinout (only for used pins) goes from 0 to 7
    • [NS0,NS1,NS2,NS3,NS4,NS5,NS6,NS7]
  • Synamps IDs The Neuroscan pinout (only for used pins) goes from 0 to 7
    • [SA0,SA1,SA2,SA3,SA4,SA5,SA6,SA7]
  • TMSI/O IDs
    • TMSO
    • TMSI
  • GPIO IDs The GPIO pinout goes from 0 to 7
    • [GPIO0,GPIO01,GPIO02,GPIO03,GPIO04,GPIO05,GPIO06,GPIO07]

You can instantiate the TrgenPort object with:

neuroScan = TrgenClient.create_trgen(TrgenPin.NS3)

passing ad only argument the constant from TrgenPin

Now you're ready to define the instruction set for TrgenPort with the set_instruction() function. Each trgenport has a memory property, a list that can contain 32 instructions, so this function is defined:

def set_instruction(self, index, instruction):
# index: 0-32 value
# instruction: instruction_code

Each instruction code can be encoded using the Instruction Helpers

# call the function directly on the same TrgenPort object
neuroScan.set_instruction(0, active_for_us(5))
neuroScan.set_instruction(1, unactive_for_us(3))
# ...

Instruction Helpers

The supported instruction set for TrgenPort is:

Instruction 1° Param 2° Param Description
unactive_for_us(us) µ seconds duration Set the unactivation time for µ seconds
active_for_us(us) µ seconds duration Set the activation time for µ seconds
wait_pe(tr) TrgenPort ID Wait the positive edge for a specific TrgenPort ID
wait_ne(tr) TrgenPort ID Wait the negative edge for a specific TrgenPort ID
repeat(addr,time) Instruction address Time of repeat Set the activation time for µ seconds
end() End the behaviour
not_admissible() Empty instruction, it has to be placed after the end()

You can access to the mtml value by

# Add this in try block to manage errors
try:
    impl = client.get_implementation()
    mtml = impml.mtml
except InvalidAckError as e:
    print(f"⚠️ ACK sbagliato: {e}")
except AckFormatError as e:
    print(f"⚠️ ACK malformato: {e}")
except TimeoutError as e:
    print(f"⏱️ Timeout: {e}")

Native Commands

IIT's Trgen can receive some commands, the full instruction set includes:

  • Program TrgenPort
  • Start TrgenPort
  • Set GPIO I/O Direction
  • Request Implementation parameters
  • Request TrgenPort Status
  • Set the TrgenPort level
  • Get GPIO I/O Direction
  • Get the TrgenPort Level
  • Stop the TrgenPort

Program TrgenPort

You can program a trigger memory in two ways:

  1. Default trigger using program_default_trigger()
    This sets a predefined impulse of duration (default 20µs).
tr = client.create_trgen(TrgenPin.GPIO0)
client.program_default_trigger(tr, us=50)  # impulse of 50µs
  1. Advanced programming by manually setting instructions with set_instruction()
tr = client.create_trgen(TrgenPin.NS1)
tr.set_instruction(0, active_for_us(10))
tr.set_instruction(1, unactive_for_us(5))
tr.set_instruction(2, repeat(0, 3))
tr.set_instruction(3, end())
client.set_trgen_memory(tr)

Start Trigger

After programming triggers, you can start them with:

client.start()

This command makes the Trgen execute all programmed triggers.
Remember: you must have previously sent at least one trigger memory.

Set GPIO I/O Direction

the "byte" way

# Set GPIO directions (example: GPIO0-3 as outputs)
client.set_gpio_direction(0b00001111)

helper way

You can use this helper to build the complete or partial pinout map to set.

# we choose to set just GPIO0 -> High and the GPIO1 -> Low
mask = DirectionConfig().out(TrgenPin.GPIO0).in(TrgenPin.GPIO1).build()
# once you have it, you can use it as argument in the set_level function
client.set_gpio_direction(mask)

Request Implementation

You can get information about the hardware configuration (number of channels, memory length, etc.) with:

impl = client.get_implementation()
print(impl.memory_length)  # max number of instructions per trigger

Request TrgenPort Status

To check current status of triggers (active/inactive state):

status = client.get_status()
print(status)

This returns an integer bitmask where each bit represents the state of a trigger pin.

Set the Trigger level

the "byte" way

You can change polarity (active-high or active-low) of all triggers:

# Set all triggers active-high
client.set_level(0xFF)

# Set only GPIO0 active-high, rest active-low
client.set_level(0b00000001)

helper way

You can use this helper to build the complete or partial pinout map to set.

# we choose to set just GPIO0 -> High and the GPIO1 -> Low
mask = LevelConfig().high(TrgenPin.GPIO0, TrgenPin.TMSO).low(TrgenPin.GPIO1).build()
# once you have it, you can use it as argument in the set_level function
client.set_level(mask)

Get the GPIO I/O Direction

To retrieve the current GPIO configuration:

gpio_state = client.get_gpio_direction()
print(bin(gpio_state))

Get the Trigger Level

To check trigger polarity:

level = client.get_level()
print(bin(level))

E-Prime integration

trgenpy offers a wrapper version to integrate its behaviour inside the E-Prime software via Python COM-visible.

Install pywin32

pip install pywin32

Register the COM wrapper

python trgen_com.py --register

So that you can use in E-Prime like this

Dim tb
Set tb = CreateObject("Trgen.COM")

If tb.IsAvailable() Then
    tb.Connect
    tb.SendTrigger
    tb.SendMarker 13
Else
    MsgBox "Trgen not available!"
End If

E-Prime example

See here for the complete examples

How to build

trgenpy uses setuptools to have a much clear and minimal build process.

Step 1 - install twine

pip install --upgrade build twine

Step 2 - build

python -m build

Step 3 - use it anywhere!

In the same directory (pwd) of this project, run: pip install .

Deploy

twine upload --repository testpypi dist/*

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

trgenpy-0.0.8.tar.gz (19.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

trgenpy-0.0.8-py3-none-any.whl (17.6 kB view details)

Uploaded Python 3

File details

Details for the file trgenpy-0.0.8.tar.gz.

File metadata

  • Download URL: trgenpy-0.0.8.tar.gz
  • Upload date:
  • Size: 19.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for trgenpy-0.0.8.tar.gz
Algorithm Hash digest
SHA256 028bc177d2748068b0c2d9b46742ca3c5ba15b975dc152ba72766571a74d5a4f
MD5 71aca92b172b7a2ee58155804a0995f9
BLAKE2b-256 70bf83388918c077672d1b31a13ebac7784cc0e8e6e03fb52d5a18ffe02fc9c3

See more details on using hashes here.

File details

Details for the file trgenpy-0.0.8-py3-none-any.whl.

File metadata

  • Download URL: trgenpy-0.0.8-py3-none-any.whl
  • Upload date:
  • Size: 17.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for trgenpy-0.0.8-py3-none-any.whl
Algorithm Hash digest
SHA256 2c63eb5444179c2137a0ee7fa0da02aac4963485cb34fda19b4595e71227b785
MD5 7e0a473e14fbd11be86e068f2c3599e4
BLAKE2b-256 ff44ec9c5db07774b6291f3bbc2f3ec037d9092083444231cadd922a86904274

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page