I was testing the bidirectional TTL on my variant. When I set ttl0 to input mode, everything worked as expected. However, when I switched it to output mode and attempted to generate pulses, the signal remained at a low voltage without any change. Here’s my test code.

from artiq.experiment import *
from artiq.coredevice import core, ttl

def print_underflow():
    print("RTIO underflow occured")

class Test_TTL_InOut_Switch(EnvExperiment):
    def build(self):
        pass

    def prepare(self):
        self.core: core.Core = self.get_device("core")
        self.output_ttl: ttl.TTLInOut = self.get_device("ttl0")

    @kernel
    def run(self):
        self.core.reset()
        self.core.break_realtime()
        self.output_ttl.output()
        delay(1*ms)

        num = 3000

        try:
            while True:
                self.output_ttl.pulse(num*ns)
                delay(num*ns)
        except RTIOUnderflow:
            print_underflow()

For a simpler test, I tried using self.ttl0.on() to keep the output at high voltage state. While on the moninj dock it showed that the mode changed to "OUT" and the state switched to "1", there's still not any actual signal change on the oscilloscope. I'm sure that the issue is not with the oscilloscope. The firmware and gateware version is 8.8974+b504c5a and software version is 8.8968+2c26199.

Need to flip the direction switch on the card perhaps?

I had the same issue with our newly bought crate - you might need to flip the direction switch.
For us, this could be done via I2C with the following code (from technosystem):


from artiq.experiment import *
from artiq.coredevice.i2c import *
from artiq.coredevice.kasli_i2c import port_mapping

class SinaraTester(EnvExperiment):
    kernel_invariants = {"port_mapping", "bank_val"}

    def build(self):
        self.setattr_device("core")
        self.setattr_device("i2c_switch0")
        self.setattr_device("i2c_switch1")
        self.setattr_device("dio0_expander")
        self.setattr_device("ttl5")

        self.port_mapping = [
            7,  # EEM0
            5,  # EEM1
            4,  # EEM2
            3,  # EEM3
            2,  # EEM4
            1,  # EEM5
            0,  # EEM6
            6,  # EEM7
            12, # EEM8
            13, # EEM9
            15, # EEM10
            14, # EEM11
        ]
        self.bank_val = [
            [ # SMA
                0b11110000, # Bank 0
                0b00001111  # Bank 1
            ],
            [ # MCX
                0b11111110, # Bank 0
                0b11111101, # Bank 1
                0b11111011, # Bank 2
                0b11110111  # Bank 3
            ]
    ]

    @kernel
    def set_dio_output(self, dio_type, eem, bank):
        # Enable I2C bus to EEM
        i2c_sw_ch = self.port_mapping[eem]
        if i2c_sw_ch < 8:
            i2c_sw = self.i2c_switch0
        else:
            i2c_sw = self.i2c_switch1
            i2c_sw_ch -= 8
        i2c_sw.set(i2c_sw_ch)
        # Set direction to output
        self.dio0_expander.set(self.bank_val[dio_type][bank])

    @kernel
    def run(self):
        self.core.reset()
        # First set the direction of the DIO hardware buffers
        self.set_dio_output(dio_type=0, eem=2, bank=1)
        # I2C operations are not real-time and slow, need break realtime
        self.core.break_realtime()
        # Then set the gateware channel to output
        self.ttl5.output()

You have to add dio0_expander to tour device_db.py file

device_db["dio0_expander"] = {
    "type": "local",
    "module": "artiq.coredevice.i2c",
    "class": "PCF8574A",
    "arguments": {
        "busno": 0,
        "address": 0x7c
    }
}

    massirossi

    Thanks for your help! I previously tried flipping the direction switch on the card, but as I mentioned, in the bank whose switch is OFF, the TTL channels could only be used in input mode, not output mode.

    I just tried the method you suggested, and it allows the corresponding TTL channels to work in output mode. However, input mode no longer works.

    Could you advise how to switch it back to output mode if needed? Also, is it possible to rapidly (in real-time) change the channel direction using only artiq.coredevice.ttl.TTLInOut.input() and artiq.coredevice.ttl.TTLInOut.output()?

      You can change EEM DIO direction via I2C at runtime.

        rjo

        Thanks for your help. Could you kindly share the specific Python code or example for doing that?

        Along the lines of the code above. I don't have anything ready-made available.

        2 months later

        Lucas I am not sure if you can do it realtime, you can try. To set it back to input, I guess you have to pass a different bit string to self.dio0_expander.set(). Now you pass either 0b11110000 or 0b00001111 (assuming you have SMA, this is the values in the list self.bank_val. You can try to pass either 0b00000000 or 0b11111111: onwards of these two string will set all banks to input, I presume!