Source code for usbcore.sm.header
#!/usr/bin/env python3
import unittest
from migen import *
from litex.soc.cores.gpio import GPIOOut
from ..pid import PIDTypes
from ..rx.pipeline import RxPipeline
from ..tx.pipeline import TxPipeline
from ..utils.packet import *
from ..test.common import BaseUsbTestCase
[docs]class PacketHeaderDecode(Module):
def __init__(self, rx):
self.submodules.rx = rx
self.o_pid = Signal(4)
self.o_addr = Signal(7)
endp4 = Signal()
self.o_endp = Signal(4)
crc5 = Signal(5)
self.o_decoded = Signal()
# FIXME: This whole module should just be in the usb_12 clock domain?
self.submodules.fsm = fsm = ClockDomainsRenamer("usb_12")(FSM())
fsm.act("IDLE",
If(rx.o_pkt_start,
NextState("WAIT_PID"),
),
)
pid = rx.o_data_payload[0:4]
fsm.act("WAIT_PID",
If(rx.o_data_strobe,
NextValue(self.o_pid, pid),
Case(pid & PIDTypes.TYPE_MASK, {
PIDTypes.TOKEN: NextState("WAIT_BYTE0"),
PIDTypes.DATA: NextState("END"),
PIDTypes.HANDSHAKE: NextState("END"),
}),
),
)
fsm.act("WAIT_BYTE0",
If(rx.o_data_strobe,
NextValue(self.o_addr[0:7], rx.o_data_payload[0:7]),
NextValue(endp4, rx.o_data_payload[7]),
NextState("WAIT_BYTE1"),
),
)
fsm.act("WAIT_BYTE1",
If(rx.o_data_strobe,
NextValue(self.o_endp, Cat(endp4, rx.o_data_payload[0:3])),
NextValue(crc5, rx.o_data_payload[4:]),
NextState("END"),
),
)
fsm.act("END",
self.o_decoded.eq(1),
NextState("IDLE"),
)