Source code for usbcore.io

#!/usr/bin/env python3

import unittest

from migen import *


[docs]class Raw(Instance.PreformattedParam): def __init__(self, value): self.value = value
[docs]class IoBuf(Module): def __init__(self, usbp_pin, usbn_pin, usb_pullup_pin=None): # tx/rx io interface self.usb_tx_en = Signal() self.usb_p_tx = Signal() self.usb_n_tx = Signal() self.usb_p_rx = Signal() self.usb_n_rx = Signal() self.usb_p_rx_io = Signal() self.usb_n_rx_io = Signal() usb_p_t = TSTriple() usb_n_t = TSTriple() self.specials += usb_p_t.get_tristate(usbp_pin) self.specials += usb_n_t.get_tristate(usbn_pin) self.usb_pullup = Signal() if usb_pullup_pin is not None: self.comb += [ usb_pullup_pin.eq(self.usb_pullup), ] ####################################################################### ####################################################################### #### Mux the USB +/- pair with the TX and RX paths ####################################################################### ####################################################################### usb_p_t_i_flop = Signal(3) usb_n_t_i_flop = Signal(3) self.sync += [ usb_p_t_i_flop.eq(Cat(usb_p_t.i, usb_p_t_i_flop[0], usb_p_t_i_flop[1])), usb_n_t_i_flop.eq(Cat(usb_n_t.i, usb_n_t_i_flop[0], usb_n_t_i_flop[1])), ] self.comb += [ If(self.usb_tx_en, self.usb_p_rx.eq(0b1), self.usb_n_rx.eq(0b0), ).Else( self.usb_p_rx.eq(usb_p_t_i_flop[2]), self.usb_n_rx.eq(usb_n_t_i_flop[2]), ), usb_p_t.oe.eq(self.usb_tx_en), usb_n_t.oe.eq(self.usb_tx_en), usb_p_t.o.eq(self.usb_p_tx), usb_n_t.o.eq(self.usb_n_tx), ]
[docs]class FakeIoBuf(Module): def __init__(self): self.usb_pullup = Signal() self.usb_p = Signal() self.usb_n = Signal() self.usb_tx_en = Signal() self.usb_p_tx = Signal() self.usb_n_tx = Signal() self.usb_p_rx = Signal() self.usb_n_rx = Signal() self.usb_p_rx_io = Signal() self.usb_n_rx_io = Signal() self.comb += [ If(self.usb_tx_en, self.usb_p_rx.eq(0b1), self.usb_n_rx.eq(0b0) ).Else( self.usb_p_rx.eq(self.usb_p_rx_io), self.usb_n_rx.eq(self.usb_n_rx_io) ), ] self.comb += [ If(self.usb_tx_en, self.usb_p.eq(self.usb_p_tx), self.usb_n.eq(self.usb_n_tx), ).Else( self.usb_p.eq(self.usb_p_rx), self.usb_n.eq(self.usb_n_rx), ), ]
[docs] def recv(self, v): tx_en = yield self.usb_tx_en assert not tx_en, "Currently transmitting!" if v == '0' or v == '_': # SE0 - both lines pulled low yield self.usb_p_rx_io.eq(0) yield self.usb_n_rx_io.eq(0) elif v == '1': # SE1 - illegal, should never occur yield self.usb_p_rx_io.eq(1) yield self.usb_n_rx_io.eq(1) elif v == '-' or v == 'I': # Idle yield self.usb_p_rx_io.eq(1) yield self.usb_n_rx_io.eq(0) elif v == 'J': yield self.usb_p_rx_io.eq(1) yield self.usb_n_rx_io.eq(0) elif v == 'K': yield self.usb_p_rx_io.eq(0) yield self.usb_n_rx_io.eq(1) else: assert False, "Unknown value: %s" % v
[docs] def current(self): usb_p = yield self.usb_p usb_n = yield self.usb_n values = (usb_p, usb_n) if values == (0, 0): return '_' elif values == (1, 1): return '1' elif values == (1, 0): return 'J' elif values == (0, 1): return 'K' else: assert False, values