From: Florent Kermarrec Date: Sat, 2 May 2015 08:24:56 +0000 (+0200) Subject: use similar names for wishbone bridges and move wishbone drivers to [core]/software X-Git-Tag: 24jan2021_ls180~2273 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3ebe877fd2d34fc9db5f94819f7a394719290480;p=litex.git use similar names for wishbone bridges and move wishbone drivers to [core]/software --- diff --git a/misoclib/com/liteeth/example_designs/targets/base.py b/misoclib/com/liteeth/example_designs/targets/base.py index 5d501df1..582e50bc 100644 --- a/misoclib/com/liteeth/example_designs/targets/base.py +++ b/misoclib/com/liteeth/example_designs/targets/base.py @@ -4,10 +4,11 @@ from migen.genlib.io import CRG from misoclib.soc import SoC from misoclib.tools.litescope.common import * -from misoclib.tools.litescope.bridge.wishbone import LiteScopeUART2Wishbone from misoclib.tools.litescope.frontend.la import LiteScopeLA from misoclib.tools.litescope.core.port import LiteScopeTerm +from misoclib.com.uart.frontend.wishbone import UARTWishboneBridge + from misoclib.com.liteeth.common import * from misoclib.com.liteeth.phy.gmii import LiteEthPHYGMII from misoclib.com.liteeth.core import LiteEthUDPIPCore @@ -30,7 +31,7 @@ class BaseSoC(SoC, AutoCSR): with_identifier=True, with_timer=False ) - self.add_cpu_or_bridge(LiteScopeUART2Wishbone(platform.request("serial"), clk_freq, baudrate=115200)) + self.add_cpu_or_bridge(UARTWishboneBridge(platform.request("serial"), clk_freq, baudrate=115200)) self.add_wb_master(self.cpu_or_bridge.wishbone) self.submodules.crg = CRG(platform.request(platform.default_clk_name)) diff --git a/misoclib/com/liteeth/example_designs/test/make.py b/misoclib/com/liteeth/example_designs/test/make.py index 717e93c1..bfab18ce 100755 --- a/misoclib/com/liteeth/example_designs/test/make.py +++ b/misoclib/com/liteeth/example_designs/test/make.py @@ -19,12 +19,12 @@ def _get_args(): if __name__ == "__main__": args = _get_args() if args.bridge == "uart": - from misoclib.tools.litescope.software.driver.uart import LiteScopeUART2WishboneDriver + from misoclib.com.uart.software.wishbone import UARTWishboneBridgeDriver port = args.port if not args.port.isdigit() else int(args.port) - wb = LiteScopeUART2WishboneDriver(port, args.baudrate, "./csr.csv", int(args.busword), debug=False) + wb = UARTWishboneBridgeDriver(port, args.baudrate, "./csr.csv", int(args.busword), debug=False) elif args.bridge == "etherbone": - from misoclib.tools.litescope.software.driver.etherbone import LiteScopeEtherboneDriver - wb = LiteScopeEtherboneDriver(args.ip_address, int(args.udp_port), "./csr.csv", int(args.busword), debug=False) + from misoclib.com.liteeth.software.wishbone import LiteETHWishboneBridgeDriver + wb = LiteETHWishboneBridgeDriver(args.ip_address, int(args.udp_port), "./csr.csv", int(args.busword), debug=False) else: ValueError("Invalid bridge {}".format(args.bridge)) diff --git a/misoclib/com/liteeth/frontend/etherbone/__init__.py b/misoclib/com/liteeth/frontend/etherbone/__init__.py index b2e958f1..0f7d586c 100644 --- a/misoclib/com/liteeth/frontend/etherbone/__init__.py +++ b/misoclib/com/liteeth/frontend/etherbone/__init__.py @@ -1,8 +1,8 @@ from misoclib.com.liteeth.common import * -from misoclib.com.liteeth.core.etherbone.packet import * -from misoclib.com.liteeth.core.etherbone.probe import * -from misoclib.com.liteeth.core.etherbone.record import * -from misoclib.com.liteeth.core.etherbone.wishbone import * +from misoclib.com.liteeth.frontend.etherbone.packet import * +from misoclib.com.liteeth.frontend.etherbone.probe import * +from misoclib.com.liteeth.frontend.etherbone.record import * +from misoclib.com.liteeth.frontend.etherbone.wishbone import * class LiteEthEtherbone(Module): diff --git a/misoclib/com/liteeth/software/__init__.py b/misoclib/com/liteeth/software/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/misoclib/com/liteeth/software/wishbone.py b/misoclib/com/liteeth/software/wishbone.py new file mode 100644 index 00000000..cd2ff0e0 --- /dev/null +++ b/misoclib/com/liteeth/software/wishbone.py @@ -0,0 +1,85 @@ +import socket + +from misoclib.tools.litescope.software.driver.reg import * + +from liteeth.test.model.etherbone import * + + +class LiteEthWishboneDriver: + def __init__(self, ip_address, udp_port=20000, addrmap=None, busword=8, debug=False): + self.ip_address = ip_address + self.udp_port = udp_port + self.debug = debug + + self.tx_sock = None + self.rx_sock = None + if addrmap is not None: + self.regs = build_map(addrmap, busword, self.read, self.write) + + def open(self): + self.tx_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.rx_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.rx_sock.bind(("", self.udp_port)) + + def close(self): + pass + + def read(self, addr, burst_length=1): + reads_addrs = [addr+4*j for j in range(burst_length)] + reads = EtherboneReads(base_ret_addr=0x1000, addrs=reads_addrs) + record = EtherboneRecord() + record.writes = None + record.reads = reads + record.bca = 0 + record.rca = 0 + record.rff = 0 + record.cyc = 0 + record.wca = 0 + record.wff = 0 + record.byte_enable = 0xf + record.wcount = 0 + record.rcount = len(reads_addrs) + + packet = EtherbonePacket() + packet.records = [record] + packet.encode() + self.tx_sock.sendto(bytes(packet), (self.ip_address, self.udp_port)) + + datas, addrs = self.rx_sock.recvfrom(8192) + packet = EtherbonePacket(datas) + packet.decode() + datas = packet.records.pop().writes.get_datas() + if self.debug: + for i, data in enumerate(datas): + print("RD {:08X} @ {:08X}".format(data, addr + 4*i)) + if burst_length == 1: + return datas[0] + else: + return datas + + def write(self, addr, datas): + if not isinstance(datas, list): + datas = [datas] + writes_datas = [d for d in datas] + writes = EtherboneWrites(base_addr=addr, datas=writes_datas) + record = EtherboneRecord() + record.writes = writes + record.reads = None + record.bca = 0 + record.rca = 0 + record.rff = 0 + record.cyc = 0 + record.wca = 0 + record.wff = 0 + record.byte_enable = 0xf + record.wcount = len(writes_datas) + record.rcount = 0 + + packet = EtherbonePacket() + packet.records = [record] + packet.encode() + self.tx_sock.sendto(bytes(packet), (self.ip_address, self.udp_port)) + + if self.debug: + for i, data in enumerate(datas): + print("WR {:08X} @ {:08X}".format(data, addr + 4*i)) diff --git a/misoclib/com/litepcie/example_designs/targets/dma.py b/misoclib/com/litepcie/example_designs/targets/dma.py index 240f5cef..512e24e2 100644 --- a/misoclib/com/litepcie/example_designs/targets/dma.py +++ b/misoclib/com/litepcie/example_designs/targets/dma.py @@ -6,13 +6,14 @@ from migen.genlib.misc import timeline from misoclib.soc import SoC from misoclib.tools.litescope.common import * -from misoclib.tools.litescope.bridge.wishbone import LiteScopeUART2Wishbone + +from misoclib.com.uart.frontend.wishbone import UARTWishboneBridge from misoclib.com.litepcie.phy.s7pciephy import S7PCIEPHY from misoclib.com.litepcie.core import Endpoint from misoclib.com.litepcie.core.irq.interrupt_controller import InterruptController from misoclib.com.litepcie.frontend.dma import DMA -from misoclib.com.litepcie.frontend.bridge.wishbone import WishboneBridge +from misoclib.com.litepcie.frontend.wishbone import LitePCIeWishboneBridge class _CRG(Module, AutoCSR): @@ -74,7 +75,7 @@ class PCIeDMASoC(SoC, AutoCSR): self.submodules.pcie_endpoint = Endpoint(self.pcie_phy, with_reordering=True) # PCIe Wishbone bridge - self.add_cpu_or_bridge(WishboneBridge(self.pcie_endpoint, lambda a: 1)) + self.add_cpu_or_bridge(LitePCIeWishboneBridge(self.pcie_endpoint, lambda a: 1)) self.add_wb_master(self.cpu_or_bridge.wishbone) # PCIe DMA @@ -82,7 +83,7 @@ class PCIeDMASoC(SoC, AutoCSR): self.dma.source.connect(self.dma.sink) if with_uart_bridge: - self.submodules.uart_bridge = LiteScopeUART2Wishbone(platform.request("serial"), clk_freq, baudrate=115200) + self.submodules.uart_bridge = UARTWishboneBridge(platform.request("serial"), clk_freq, baudrate=115200) self.add_wb_master(self.uart_bridge.wishbone) # IRQs diff --git a/misoclib/com/litepcie/example_designs/test/make.py b/misoclib/com/litepcie/example_designs/test/make.py index 9823f24e..344e5a40 100755 --- a/misoclib/com/litepcie/example_designs/test/make.py +++ b/misoclib/com/litepcie/example_designs/test/make.py @@ -21,15 +21,15 @@ def _get_args(): if __name__ == "__main__": args = _get_args() if args.bridge == "uart": - from misoclib.tools.litescope.software.driver.uart import LiteScopeUART2WishboneDriver + from misoclib.com.uart.software.wishbone import UARTWishboneBridgeDriver port = args.port if not args.port.isdigit() else int(args.port) - wb = LiteScopeUART2WishboneDriver(port, args.baudrate, "./csr.csv", int(args.busword), debug=False) + wb = UARTWishboneBridgeDriver(port, args.baudrate, "./csr.csv", int(args.busword), debug=False) elif args.bridge == "etherbone": - from misoclib.tools.litescope.software.driver.etherbone import LiteScopeEtherboneDriver - wb = LiteScopeEtherboneDriver(args.ip_address, int(args.udp_port), "./csr.csv", int(args.busword), debug=False) + from misoclib.com.liteeth.software.wishbone import LiteETHWishboneDriver + wb = LiteETHWishboneDriver(args.ip_address, int(args.udp_port), "./csr.csv", int(args.busword), debug=False) elif args.bridge == "pcie": - from misoclib.tools.litescope.software.driver.pcie import LiteScopePCIeDriver - wb = LiteScopePCIeDriver(args.bar, args.bar_size, "./csr.csv", int(args.busword), debug=False) + from misoclib.com.litepcie.software.linux.wishbone import LitePCIeWishboneDriver + wb = LitePCIeWishboneDriver(args.bar, args.bar_size, "./csr.csv", int(args.busword), debug=False) else: ValueError("Invalid bridge {}".format(args.bridge)) diff --git a/misoclib/com/litepcie/frontend/bridge/__init__.py b/misoclib/com/litepcie/frontend/bridge/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/misoclib/com/litepcie/frontend/bridge/wishbone.py b/misoclib/com/litepcie/frontend/bridge/wishbone.py deleted file mode 100644 index bdf2aeff..00000000 --- a/misoclib/com/litepcie/frontend/bridge/wishbone.py +++ /dev/null @@ -1,67 +0,0 @@ -from migen.fhdl.std import * -from migen.genlib.fsm import FSM, NextState -from migen.bus import wishbone - -from misoclib.com.litepcie.common import * - - -class WishboneBridge(Module): - def __init__(self, endpoint, address_decoder): - self.wishbone = wishbone.Interface() - - # # # - - port = endpoint.crossbar.get_slave_port(address_decoder) - self.submodules.fsm = fsm = FSM() - - fsm.act("IDLE", - If(port.sink.stb & port.sink.sop, - If(port.sink.we, - NextState("WRITE"), - ).Else( - NextState("READ") - ) - ).Else( - port.sink.ack.eq(port.sink.stb) - ) - ) - fsm.act("WRITE", - self.wishbone.adr.eq(port.sink.adr[2:]), - self.wishbone.dat_w.eq(port.sink.dat[:32]), - self.wishbone.sel.eq(0xf), - self.wishbone.stb.eq(1), - self.wishbone.we.eq(1), - self.wishbone.cyc.eq(1), - If(self.wishbone.ack, - port.sink.ack.eq(1), - NextState("IDLE") - ) - ) - fsm.act("READ", - self.wishbone.adr.eq(port.sink.adr[2:]), - self.wishbone.stb.eq(1), - self.wishbone.we.eq(0), - self.wishbone.cyc.eq(1), - If(self.wishbone.ack, - NextState("COMPLETION") - ) - ) - self.sync += \ - If(self.wishbone.stb & self.wishbone.ack, - port.source.dat.eq(self.wishbone.dat_r), - ) - fsm.act("COMPLETION", - port.source.stb.eq(1), - port.source.sop.eq(1), - port.source.eop.eq(1), - port.source.len.eq(1), - port.source.err.eq(0), - port.source.tag.eq(port.sink.tag), - port.source.adr.eq(port.sink.adr), - port.source.cmp_id.eq(endpoint.phy.id), - port.source.req_id.eq(port.sink.req_id), - If(port.source.ack, - port.sink.ack.eq(1), - NextState("IDLE") - ) - ) diff --git a/misoclib/com/litepcie/frontend/wishbone.py b/misoclib/com/litepcie/frontend/wishbone.py new file mode 100644 index 00000000..2eca9f3e --- /dev/null +++ b/misoclib/com/litepcie/frontend/wishbone.py @@ -0,0 +1,67 @@ +from migen.fhdl.std import * +from migen.genlib.fsm import FSM, NextState +from migen.bus import wishbone + +from misoclib.com.litepcie.common import * + + +class LitePCIeWishboneBridge(Module): + def __init__(self, endpoint, address_decoder): + self.wishbone = wishbone.Interface() + + # # # + + port = endpoint.crossbar.get_slave_port(address_decoder) + self.submodules.fsm = fsm = FSM() + + fsm.act("IDLE", + If(port.sink.stb & port.sink.sop, + If(port.sink.we, + NextState("WRITE"), + ).Else( + NextState("READ") + ) + ).Else( + port.sink.ack.eq(port.sink.stb) + ) + ) + fsm.act("WRITE", + self.wishbone.adr.eq(port.sink.adr[2:]), + self.wishbone.dat_w.eq(port.sink.dat[:32]), + self.wishbone.sel.eq(0xf), + self.wishbone.stb.eq(1), + self.wishbone.we.eq(1), + self.wishbone.cyc.eq(1), + If(self.wishbone.ack, + port.sink.ack.eq(1), + NextState("IDLE") + ) + ) + fsm.act("READ", + self.wishbone.adr.eq(port.sink.adr[2:]), + self.wishbone.stb.eq(1), + self.wishbone.we.eq(0), + self.wishbone.cyc.eq(1), + If(self.wishbone.ack, + NextState("COMPLETION") + ) + ) + self.sync += \ + If(self.wishbone.stb & self.wishbone.ack, + port.source.dat.eq(self.wishbone.dat_r), + ) + fsm.act("COMPLETION", + port.source.stb.eq(1), + port.source.sop.eq(1), + port.source.eop.eq(1), + port.source.len.eq(1), + port.source.err.eq(0), + port.source.tag.eq(port.sink.tag), + port.source.adr.eq(port.sink.adr), + port.source.cmp_id.eq(endpoint.phy.id), + port.source.req_id.eq(port.sink.req_id), + If(port.source.ack, + port.sink.ack.eq(1), + NextState("IDLE") + ) + ) diff --git a/misoclib/com/litepcie/software/__init__.py b/misoclib/com/litepcie/software/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/misoclib/com/litepcie/software/wishbone.py b/misoclib/com/litepcie/software/wishbone.py new file mode 100644 index 00000000..fb632af9 --- /dev/null +++ b/misoclib/com/litepcie/software/wishbone.py @@ -0,0 +1,65 @@ +import string +import mmap +import sys + +from misoclib.tools.litescope.software.driver.reg import * + + +class LitePCIeWishboneDriverLinux: + def __init__(self, bar, bar_size, addrmap=None, busword=8, debug=False): + self.bar = bar + self.bar_size = bar_size + self.debug = debug + self.f = None + self.mmap = None + self.regs = build_map(addrmap, busword, self.read, self.write) + + def open(self): + self.f = open(self.bar, "r+b") + self.f.flush() + self.mmap = mmap.mmap(self.f.fileno(), self.bar_size) + + def close(self): + self.mmap.close() + self.f.close() + + def read(self, addr, burst_length=1): + datas = [] + for i in range(burst_length): + self.mmap.seek(addr + 4*i) + dat = self.mmap.read(4) + val = dat[3] << 24 + val |= dat[2] << 16 + val |= dat[1] << 8 + val |= dat[0] << 0 + if self.debug: + print("RD {:08X} @ {:08X}".format(val, addr + 4*i)) + datas.append(val) + if burst_length == 1: + return datas[0] + else: + return datas + + def write(self, addr, data): + if isinstance(data, list): + burst_length = len(data) + else: + burst_length = 1 + data = [data] + + for i, dat in enumerate(data): + dat_bytes = [0, 0, 0, 0] + dat_bytes[3] = (dat >> 24) & 0xff + dat_bytes[2] = (dat >> 16) & 0xff + dat_bytes[1] = (dat >> 8) & 0xff + dat_bytes[0] = (dat >> 0) & 0xff + self.mmap[addr + 4*i:addr + 4*(i+1)] = bytes(dat_bytes) + if self.debug: + print("WR {:08X} @ {:08X}".format(dat, (addr + i)*4)) + + +def LitePCIeWishboneDriver(*args, **kwargs): + if sys.platform == "win32" or sys.platform == "cygwin": + raise NotImplementedError + else: + return LitePCIeWishboneDriverLinux(*args, **kwargs) diff --git a/misoclib/com/liteusb/software/wishbone.py b/misoclib/com/liteusb/software/wishbone.py new file mode 100644 index 00000000..971bb97e --- /dev/null +++ b/misoclib/com/liteusb/software/wishbone.py @@ -0,0 +1,78 @@ +from misoclib.com.liteusb.software.ftdi import FTDIComDevice + +class LiteUSBWishboneDriverFTDI: + cmds = { + "write": 0x01, + "read": 0x02 + } + def __init__(self, interface, mode, tag, addrmap=None, debug=False): + self.interface = interface + self.mode = mode + self.tag = tag + self.debug = debug + self.com = FTDIComDevice(self.interface, + mode=mode, + uart_tag=tag, + dma_tag=16, # XXX FIXME + verbose=debug) + if addrmap is not None: + self.regs = build_map(addrmap, busword, self.read, self.write) + + def open(self): + self.com.open() + + def close(self): + self.com.close() + + # XXX regroup cmds in a single packet + def read(self, addr, burst_length=1): + datas = [] + self.com.uartflush() + self.com.uartwrite(self.cmds["read"]) + self.com.uartwrite(burst_length) + word_addr = addr//4 + self.com.uartwrite((word_addr >> 24) & 0xff) + self.com.uartwrite((word_addr >> 16) & 0xff) + self.com.uartwrite((word_addr >> 8) & 0xff) + self.com.uartwrite((word_addr >> 0) & 0xff) + for i in range(burst_length): + data = 0 + for k in range(4): + data = data << 8 + data |= self.com.uartread() + if self.debug: + print("RD {:08X} @ {:08X}".format(data, addr + 4*i)) + datas.append(data) + if burst_length == 1: + return datas[0] + else: + return datas + + # XXX regroup cmds in a single packet + def write(self, addr, data): + if isinstance(data, list): + burst_length = len(data) + else: + burst_length = 1 + data = [data] + self.com.uartwrite(self.cmds["write"]) + self.com.uartwrite(burst_length) + word_addr = addr//4 + self.com.uartwrite((word_addr >> 24) & 0xff) + self.com.uartwrite((word_addr >> 16) & 0xff) + self.com.uartwrite((word_addr >> 8) & 0xff) + self.com.uartwrite((word_addr >> 0) & 0xff) + for i in range(len(data)): + dat = data[i] + for j in range(4): + self.com.uartwrite((dat >> 24) & 0xff) + dat = dat << 8 + if self.debug: + print("WR {:08X} @ {:08X}".format(data[i], addr + 4*i)) + + +def LiteUSBWishboneDriver(chip="ft2232h", *args, **kwargs): + drivers = { + "ft2232h": LiteUSBWishboneDriverFTDI + } + return drivers[chip](*args, **kwargs) diff --git a/misoclib/com/uart/frontend/__init__.py b/misoclib/com/uart/frontend/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/misoclib/com/uart/frontend/wishbone.py b/misoclib/com/uart/frontend/wishbone.py new file mode 100644 index 00000000..d1499865 --- /dev/null +++ b/misoclib/com/uart/frontend/wishbone.py @@ -0,0 +1,9 @@ +from migen.fhdl.std import * + +from misoclib.tools.litescope.frontend.wishbone import LiteScopeWishboneBridge +from misoclib.com.uart.phy.serial import UARTPHYSerial + +class UARTWishboneBridge(LiteScopeWishboneBridge): + def __init__(self, pads, clk_freq, baudrate=115200): + self.submodules.phy = UARTPHYSerial(pads, clk_freq, baudrate) + LiteScopeWishboneBridge.__init__(self, self.phy, clk_freq) diff --git a/misoclib/com/uart/software/__init__.py b/misoclib/com/uart/software/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/misoclib/com/uart/software/wishbone.py b/misoclib/com/uart/software/wishbone.py new file mode 100644 index 00000000..a916c06d --- /dev/null +++ b/misoclib/com/uart/software/wishbone.py @@ -0,0 +1,75 @@ +import serial +from struct import * +from misoclib.tools.litescope.software.driver.reg import * + + +def write_b(uart, data): + uart.write(pack('B', data)) + + +class UARTWishboneBridgeDriver: + cmds = { + "write": 0x01, + "read": 0x02 + } + def __init__(self, port, baudrate=115200, addrmap=None, busword=8, debug=False): + self.port = port + self.baudrate = str(baudrate) + self.debug = debug + self.uart = serial.Serial(port, baudrate, timeout=0.25) + if addrmap is not None: + self.regs = build_map(addrmap, busword, self.read, self.write) + + def open(self): + self.uart.flushOutput() + self.uart.close() + self.uart.open() + self.uart.flushInput() + + def close(self): + self.uart.flushOutput() + self.uart.close() + + def read(self, addr, burst_length=1): + datas = [] + self.uart.flushInput() + write_b(self.uart, self.cmds["read"]) + write_b(self.uart, burst_length) + word_addr = addr//4 + write_b(self.uart, (word_addr >> 24) & 0xff) + write_b(self.uart, (word_addr >> 16) & 0xff) + write_b(self.uart, (word_addr >> 8) & 0xff) + write_b(self.uart, (word_addr >> 0) & 0xff) + for i in range(burst_length): + data = 0 + for k in range(4): + data = data << 8 + data |= ord(self.uart.read()) + if self.debug: + print("RD {:08X} @ {:08X}".format(data, addr + 4*i)) + datas.append(data) + if burst_length == 1: + return datas[0] + else: + return datas + + def write(self, addr, data): + if isinstance(data, list): + burst_length = len(data) + else: + burst_length = 1 + data = [data] + write_b(self.uart, self.cmds["write"]) + write_b(self.uart, burst_length) + word_addr = addr//4 + write_b(self.uart, (word_addr >> 24) & 0xff) + write_b(self.uart, (word_addr >> 16) & 0xff) + write_b(self.uart, (word_addr >> 8) & 0xff) + write_b(self.uart, (word_addr >> 0) & 0xff) + for i in range(len(data)): + dat = data[i] + for j in range(4): + write_b(self.uart, (dat >> 24) & 0xff) + dat = dat << 8 + if self.debug: + print("WR {:08X} @ {:08X}".format(data[i], addr + 4*i)) diff --git a/misoclib/mem/litesata/example_designs/targets/bist.py b/misoclib/mem/litesata/example_designs/targets/bist.py index 3238bd8f..18b5333d 100644 --- a/misoclib/mem/litesata/example_designs/targets/bist.py +++ b/misoclib/mem/litesata/example_designs/targets/bist.py @@ -6,10 +6,11 @@ from migen.bank.description import * from misoclib.soc import SoC from misoclib.tools.litescope.common import * -from misoclib.tools.litescope.bridge.wishbone import LiteScopeUART2Wishbone from misoclib.tools.litescope.frontend.la import LiteScopeLA from misoclib.tools.litescope.core.port import LiteScopeTerm +from misoclib.com.uart.frontend.wishbone import UARTWishboneBridge + from misoclib.mem.litesata.common import * from misoclib.mem.litesata.phy import LiteSATAPHY from misoclib.mem.litesata import LiteSATA @@ -99,7 +100,7 @@ class BISTSoC(SoC, AutoCSR): with_identifier=True, with_timer=False ) - self.add_cpu_or_bridge(LiteScopeUART2Wishbone(platform.request("serial"), clk_freq, baudrate=115200)) + self.add_cpu_or_bridge(UARTWishboneBridge(platform.request("serial"), clk_freq, baudrate=115200)) self.add_wb_master(self.cpu_or_bridge.wishbone) self.submodules.crg = _CRG(platform) diff --git a/misoclib/mem/litesata/example_designs/test/bist.py b/misoclib/mem/litesata/example_designs/test/bist.py index 4995657b..5b55a700 100644 --- a/misoclib/mem/litesata/example_designs/test/bist.py +++ b/misoclib/mem/litesata/example_designs/test/bist.py @@ -2,7 +2,7 @@ import time import argparse import random as rand from collections import OrderedDict -from misoclib.tools.litescope.software.driver.uart import LiteScopeUART2WishboneDriver +from misoclib.com.uart.software.wishbone import UARTWishboneBridgeDriver KB = 1024 MB = 1024*KB @@ -149,7 +149,7 @@ SATA BIST utility. if __name__ == "__main__": args = _get_args() - wb = LiteScopeUART2WishboneDriver(args.port, args.baudrate, "./csr.csv", int(args.busword), debug=False) + wb = UARTWishboneBridgeDriver(args.port, args.baudrate, "./csr.csv", int(args.busword), debug=False) wb.open() # # # identify = LiteSATABISTIdentifyDriver(wb.regs, "sata_bist") diff --git a/misoclib/mem/litesata/example_designs/test/make.py b/misoclib/mem/litesata/example_designs/test/make.py index a89f8627..eb7309cc 100755 --- a/misoclib/mem/litesata/example_designs/test/make.py +++ b/misoclib/mem/litesata/example_designs/test/make.py @@ -19,12 +19,12 @@ def _get_args(): if __name__ == "__main__": args = _get_args() if args.bridge == "uart": - from misoclib.tools.litescope.software.driver.uart import LiteScopeUART2WishboneDriver + from misoclib.com.uart.software.wishbone import UARTWishboneBridgeDriver port = args.port if not args.port.isdigit() else int(args.port) - wb = LiteScopeUART2WishboneDriver(port, args.baudrate, "./csr.csv", int(args.busword), debug=False) + wb = UARTWishboneBridgeDriver(port, args.baudrate, "./csr.csv", int(args.busword), debug=False) elif args.bridge == "etherbone": - from misoclib.tools.litescope.software.driver.etherbone import LiteScopeEtherboneDriver - wb = LiteScopeEtherboneDriver(args.ip_address, int(args.udp_port), "./csr.csv", int(args.busword), debug=False) + from misoclib.com.liteth.software.wishbone import LiteETHWishboneDriver + wb = LiteETHWishboneDriver(args.ip_address, int(args.udp_port), "./csr.csv", int(args.busword), debug=False) else: ValueError("Invalid bridge {}".format(args.bridge)) diff --git a/misoclib/tools/litescope/bridge/__init__.py b/misoclib/tools/litescope/bridge/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/misoclib/tools/litescope/bridge/wishbone.py b/misoclib/tools/litescope/bridge/wishbone.py deleted file mode 100644 index f119a9d6..00000000 --- a/misoclib/tools/litescope/bridge/wishbone.py +++ /dev/null @@ -1,146 +0,0 @@ -from misoclib.tools.litescope.common import * -from migen.bus import wishbone -from migen.genlib.misc import chooser -from migen.genlib.record import Record -from migen.flow.actor import Sink, Source - -from misoclib.com.uart.phy.serial import UARTPHYSerial - -class LiteScopeWishboneBridge(Module): - cmds = { - "write": 0x01, - "read": 0x02 - } - - def __init__(self, phy, clk_freq): - self.wishbone = wishbone.Interface() - - # # # - - byte_counter = Counter(3) - word_counter = Counter(8) - self.submodules += byte_counter, word_counter - - cmd = Signal(8) - cmd_ce = Signal() - - length = Signal(8) - length_ce = Signal() - - address = Signal(32) - address_ce = Signal() - - data = Signal(32) - rx_data_ce = Signal() - tx_data_ce = Signal() - - self.sync += [ - If(cmd_ce, cmd.eq(phy.source.data)), - If(length_ce, length.eq(phy.source.data)), - If(address_ce, address.eq(Cat(phy.source.data, address[0:24]))), - If(rx_data_ce, - data.eq(Cat(phy.source.data, data[0:24])) - ).Elif(tx_data_ce, - data.eq(self.wishbone.dat_r) - ) - ] - - fsm = InsertReset(FSM(reset_state="IDLE")) - timeout = Timeout(clk_freq//10) - self.submodules += fsm, timeout - self.comb += [ - timeout.ce.eq(1), - fsm.reset.eq(timeout.reached), - phy.source.ack.eq(1) - ] - fsm.act("IDLE", - timeout.reset.eq(1), - If(phy.source.stb, - cmd_ce.eq(1), - If((phy.source.data == self.cmds["write"]) | - (phy.source.data == self.cmds["read"]), - NextState("RECEIVE_LENGTH") - ), - byte_counter.reset.eq(1), - word_counter.reset.eq(1) - ) - ) - fsm.act("RECEIVE_LENGTH", - If(phy.source.stb, - length_ce.eq(1), - NextState("RECEIVE_ADDRESS") - ) - ) - fsm.act("RECEIVE_ADDRESS", - If(phy.source.stb, - address_ce.eq(1), - byte_counter.ce.eq(1), - If(byte_counter.value == 3, - If(cmd == self.cmds["write"], - NextState("RECEIVE_DATA") - ).Elif(cmd == self.cmds["read"], - NextState("READ_DATA") - ), - byte_counter.reset.eq(1), - ) - ) - ) - fsm.act("RECEIVE_DATA", - If(phy.source.stb, - rx_data_ce.eq(1), - byte_counter.ce.eq(1), - If(byte_counter.value == 3, - NextState("WRITE_DATA"), - byte_counter.reset.eq(1) - ) - ) - ) - self.comb += [ - self.wishbone.adr.eq(address + word_counter.value), - self.wishbone.dat_w.eq(data), - self.wishbone.sel.eq(2**flen(self.wishbone.sel)-1) - ] - fsm.act("WRITE_DATA", - self.wishbone.stb.eq(1), - self.wishbone.we.eq(1), - self.wishbone.cyc.eq(1), - If(self.wishbone.ack, - word_counter.ce.eq(1), - If(word_counter.value == (length-1), - NextState("IDLE") - ).Else( - NextState("RECEIVE_DATA") - ) - ) - ) - fsm.act("READ_DATA", - self.wishbone.stb.eq(1), - self.wishbone.we.eq(0), - self.wishbone.cyc.eq(1), - If(self.wishbone.ack, - tx_data_ce.eq(1), - NextState("SEND_DATA") - ) - ) - self.comb += \ - chooser(data, byte_counter.value, phy.sink.data, n=4, reverse=True) - fsm.act("SEND_DATA", - phy.sink.stb.eq(1), - If(phy.sink.ack, - byte_counter.ce.eq(1), - If(byte_counter.value == 3, - word_counter.ce.eq(1), - If(word_counter.value == (length-1), - NextState("IDLE") - ).Else( - NextState("READ_DATA"), - byte_counter.reset.eq(1) - ) - ) - ) - ) - -class LiteScopeUART2Wishbone(LiteScopeWishboneBridge): - def __init__(self, pads, clk_freq, baudrate=115200): - self.submodules.phy = UARTPHYSerial(pads, clk_freq, baudrate) - LiteScopeWishboneBridge.__init__(self, self.phy, clk_freq) diff --git a/misoclib/tools/litescope/example_designs/targets/simple.py b/misoclib/tools/litescope/example_designs/targets/simple.py index f8ebf756..efbe3397 100644 --- a/misoclib/tools/litescope/example_designs/targets/simple.py +++ b/misoclib/tools/litescope/example_designs/targets/simple.py @@ -3,11 +3,11 @@ from migen.genlib.io import CRG from misoclib.soc import SoC from misoclib.tools.litescope.common import * -from misoclib.tools.litescope.bridge.wishbone import LiteScopeUART2Wishbone +from misoclib.tools.litescope.core.port import LiteScopeTerm from misoclib.tools.litescope.frontend.io import LiteScopeIO from misoclib.tools.litescope.frontend.la import LiteScopeLA -from misoclib.tools.litescope.core.port import LiteScopeTerm +from misoclib.com.uart.frontend.wishbone import UARTWishboneBridge class LiteScopeSoC(SoC, AutoCSR): csr_map = { @@ -25,7 +25,7 @@ class LiteScopeSoC(SoC, AutoCSR): with_identifier=True, with_timer=False ) - self.add_cpu_or_bridge(LiteScopeUART2Wishbone(platform.request("serial"), clk_freq, baudrate=115200)) + self.add_cpu_or_bridge(UARTWishboneBridge(platform.request("serial"), clk_freq, baudrate=115200)) self.add_wb_master(self.cpu_or_bridge.wishbone) self.submodules.crg = CRG(platform.request(platform.default_clk_name)) diff --git a/misoclib/tools/litescope/example_designs/test/make.py b/misoclib/tools/litescope/example_designs/test/make.py index a89f8627..99f1093d 100755 --- a/misoclib/tools/litescope/example_designs/test/make.py +++ b/misoclib/tools/litescope/example_designs/test/make.py @@ -8,8 +8,6 @@ def _get_args(): parser.add_argument("-b", "--bridge", default="uart", help="Bridge to use") parser.add_argument("--port", default="2", help="UART port") parser.add_argument("--baudrate", default=115200, help="UART baudrate") - parser.add_argument("--ip_address", default="192.168.0.42", help="Etherbone IP address") - parser.add_argument("--udp_port", default=20000, help="Etherbone UDP port") parser.add_argument("--busword", default=32, help="CSR busword") parser.add_argument("test", nargs="+", help="specify a test") @@ -19,13 +17,9 @@ def _get_args(): if __name__ == "__main__": args = _get_args() if args.bridge == "uart": - from misoclib.tools.litescope.software.driver.uart import LiteScopeUART2WishboneDriver + from misoclib.com.uart.software.wishbone import UARTWishboneBridgeDriver port = args.port if not args.port.isdigit() else int(args.port) - wb = LiteScopeUART2WishboneDriver(port, args.baudrate, "./csr.csv", int(args.busword), debug=False) - elif args.bridge == "etherbone": - from misoclib.tools.litescope.software.driver.etherbone import LiteScopeEtherboneDriver - wb = LiteScopeEtherboneDriver(args.ip_address, int(args.udp_port), "./csr.csv", int(args.busword), debug=False) - else: + wb = UARTWishboneBridgeDriver(port, args.baudrate, "./csr.csv", int(args.busword), debug=False) ValueError("Invalid bridge {}".format(args.bridge)) def _import(name): diff --git a/misoclib/tools/litescope/frontend/wishbone.py b/misoclib/tools/litescope/frontend/wishbone.py new file mode 100644 index 00000000..7937498f --- /dev/null +++ b/misoclib/tools/litescope/frontend/wishbone.py @@ -0,0 +1,141 @@ +from misoclib.tools.litescope.common import * +from migen.bus import wishbone +from migen.genlib.misc import chooser +from migen.genlib.record import Record +from migen.flow.actor import Sink, Source + +from misoclib.com.uart.phy.serial import UARTPHYSerial + +class LiteScopeWishboneBridge(Module): + cmds = { + "write": 0x01, + "read": 0x02 + } + + def __init__(self, phy, clk_freq): + self.wishbone = wishbone.Interface() + + # # # + + byte_counter = Counter(3) + word_counter = Counter(8) + self.submodules += byte_counter, word_counter + + cmd = Signal(8) + cmd_ce = Signal() + + length = Signal(8) + length_ce = Signal() + + address = Signal(32) + address_ce = Signal() + + data = Signal(32) + rx_data_ce = Signal() + tx_data_ce = Signal() + + self.sync += [ + If(cmd_ce, cmd.eq(phy.source.data)), + If(length_ce, length.eq(phy.source.data)), + If(address_ce, address.eq(Cat(phy.source.data, address[0:24]))), + If(rx_data_ce, + data.eq(Cat(phy.source.data, data[0:24])) + ).Elif(tx_data_ce, + data.eq(self.wishbone.dat_r) + ) + ] + + fsm = InsertReset(FSM(reset_state="IDLE")) + timeout = Timeout(clk_freq//10) + self.submodules += fsm, timeout + self.comb += [ + timeout.ce.eq(1), + fsm.reset.eq(timeout.reached), + phy.source.ack.eq(1) + ] + fsm.act("IDLE", + timeout.reset.eq(1), + If(phy.source.stb, + cmd_ce.eq(1), + If((phy.source.data == self.cmds["write"]) | + (phy.source.data == self.cmds["read"]), + NextState("RECEIVE_LENGTH") + ), + byte_counter.reset.eq(1), + word_counter.reset.eq(1) + ) + ) + fsm.act("RECEIVE_LENGTH", + If(phy.source.stb, + length_ce.eq(1), + NextState("RECEIVE_ADDRESS") + ) + ) + fsm.act("RECEIVE_ADDRESS", + If(phy.source.stb, + address_ce.eq(1), + byte_counter.ce.eq(1), + If(byte_counter.value == 3, + If(cmd == self.cmds["write"], + NextState("RECEIVE_DATA") + ).Elif(cmd == self.cmds["read"], + NextState("READ_DATA") + ), + byte_counter.reset.eq(1), + ) + ) + ) + fsm.act("RECEIVE_DATA", + If(phy.source.stb, + rx_data_ce.eq(1), + byte_counter.ce.eq(1), + If(byte_counter.value == 3, + NextState("WRITE_DATA"), + byte_counter.reset.eq(1) + ) + ) + ) + self.comb += [ + self.wishbone.adr.eq(address + word_counter.value), + self.wishbone.dat_w.eq(data), + self.wishbone.sel.eq(2**flen(self.wishbone.sel)-1) + ] + fsm.act("WRITE_DATA", + self.wishbone.stb.eq(1), + self.wishbone.we.eq(1), + self.wishbone.cyc.eq(1), + If(self.wishbone.ack, + word_counter.ce.eq(1), + If(word_counter.value == (length-1), + NextState("IDLE") + ).Else( + NextState("RECEIVE_DATA") + ) + ) + ) + fsm.act("READ_DATA", + self.wishbone.stb.eq(1), + self.wishbone.we.eq(0), + self.wishbone.cyc.eq(1), + If(self.wishbone.ack, + tx_data_ce.eq(1), + NextState("SEND_DATA") + ) + ) + self.comb += \ + chooser(data, byte_counter.value, phy.sink.data, n=4, reverse=True) + fsm.act("SEND_DATA", + phy.sink.stb.eq(1), + If(phy.sink.ack, + byte_counter.ce.eq(1), + If(byte_counter.value == 3, + word_counter.ce.eq(1), + If(word_counter.value == (length-1), + NextState("IDLE") + ).Else( + NextState("READ_DATA"), + byte_counter.reset.eq(1) + ) + ) + ) + ) diff --git a/misoclib/tools/litescope/software/driver/etherbone.py b/misoclib/tools/litescope/software/driver/etherbone.py deleted file mode 100644 index 34949a17..00000000 --- a/misoclib/tools/litescope/software/driver/etherbone.py +++ /dev/null @@ -1,84 +0,0 @@ -import socket -from misoclib.tools.litescope.software.driver.reg import * - -from liteeth.test.model.etherbone import * - - -class LiteScopeEtherboneDriver: - def __init__(self, ip_address, udp_port=20000, addrmap=None, busword=8, debug=False): - self.ip_address = ip_address - self.udp_port = udp_port - self.debug = debug - - self.tx_sock = None - self.rx_sock = None - if addrmap is not None: - self.regs = build_map(addrmap, busword, self.read, self.write) - - def open(self): - self.tx_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self.rx_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self.rx_sock.bind(("", self.udp_port)) - - def close(self): - pass - - def read(self, addr, burst_length=1): - reads_addrs = [addr+4*j for j in range(burst_length)] - reads = EtherboneReads(base_ret_addr=0x1000, addrs=reads_addrs) - record = EtherboneRecord() - record.writes = None - record.reads = reads - record.bca = 0 - record.rca = 0 - record.rff = 0 - record.cyc = 0 - record.wca = 0 - record.wff = 0 - record.byte_enable = 0xf - record.wcount = 0 - record.rcount = len(reads_addrs) - - packet = EtherbonePacket() - packet.records = [record] - packet.encode() - self.tx_sock.sendto(bytes(packet), (self.ip_address, self.udp_port)) - - datas, addrs = self.rx_sock.recvfrom(8192) - packet = EtherbonePacket(datas) - packet.decode() - datas = packet.records.pop().writes.get_datas() - if self.debug: - for i, data in enumerate(datas): - print("RD {:08X} @ {:08X}".format(data, addr + 4*i)) - if burst_length == 1: - return datas[0] - else: - return datas - - def write(self, addr, datas): - if not isinstance(datas, list): - datas = [datas] - writes_datas = [d for d in datas] - writes = EtherboneWrites(base_addr=addr, datas=writes_datas) - record = EtherboneRecord() - record.writes = writes - record.reads = None - record.bca = 0 - record.rca = 0 - record.rff = 0 - record.cyc = 0 - record.wca = 0 - record.wff = 0 - record.byte_enable = 0xf - record.wcount = len(writes_datas) - record.rcount = 0 - - packet = EtherbonePacket() - packet.records = [record] - packet.encode() - self.tx_sock.sendto(bytes(packet), (self.ip_address, self.udp_port)) - - if self.debug: - for i, data in enumerate(datas): - print("WR {:08X} @ {:08X}".format(data, addr + 4*i)) diff --git a/misoclib/tools/litescope/software/driver/pcie.py b/misoclib/tools/litescope/software/driver/pcie.py deleted file mode 100644 index 8fe5c4d7..00000000 --- a/misoclib/tools/litescope/software/driver/pcie.py +++ /dev/null @@ -1,56 +0,0 @@ -import string -import mmap -from misoclib.tools.litescope.software.driver.reg import * - - -class LiteScopePCIeDriver: - def __init__(self, bar, bar_size, addrmap=None, busword=8, debug=False): - self.bar = bar - self.bar_size = bar_size - self.debug = debug - self.f = None - self.mmap = None - self.regs = build_map(addrmap, busword, self.read, self.write) - - def open(self): - self.f = open(self.bar, "r+b") - self.f.flush() - self.mmap = mmap.mmap(self.f.fileno(), self.bar_size) - - def close(self): - self.mmap.close() - self.f.close() - - def read(self, addr, burst_length=1): - datas = [] - for i in range(burst_length): - self.mmap.seek(addr + 4*i) - dat = self.mmap.read(4) - val = dat[3] << 24 - val |= dat[2] << 16 - val |= dat[1] << 8 - val |= dat[0] << 0 - if self.debug: - print("RD {:08X} @ {:08X}".format(val, addr + 4*i)) - datas.append(val) - if burst_length == 1: - return datas[0] - else: - return datas - - def write(self, addr, data): - if isinstance(data, list): - burst_length = len(data) - else: - burst_length = 1 - data = [data] - - for i, dat in enumerate(data): - dat_bytes = [0, 0, 0, 0] - dat_bytes[3] = (dat >> 24) & 0xff - dat_bytes[2] = (dat >> 16) & 0xff - dat_bytes[1] = (dat >> 8) & 0xff - dat_bytes[0] = (dat >> 0) & 0xff - self.mmap[addr + 4*i:addr + 4*(i+1)] = bytes(dat_bytes) - if self.debug: - print("WR {:08X} @ {:08X}".format(dat, (addr + i)*4)) diff --git a/misoclib/tools/litescope/software/driver/uart.py b/misoclib/tools/litescope/software/driver/uart.py deleted file mode 100644 index 42f1c03b..00000000 --- a/misoclib/tools/litescope/software/driver/uart.py +++ /dev/null @@ -1,75 +0,0 @@ -import serial -from struct import * -from misoclib.tools.litescope.software.driver.reg import * - - -def write_b(uart, data): - uart.write(pack('B', data)) - - -class LiteScopeUART2WishboneDriver: - cmds = { - "write": 0x01, - "read": 0x02 - } - def __init__(self, port, baudrate=115200, addrmap=None, busword=8, debug=False): - self.port = port - self.baudrate = str(baudrate) - self.debug = debug - self.uart = serial.Serial(port, baudrate, timeout=0.25) - if addrmap is not None: - self.regs = build_map(addrmap, busword, self.read, self.write) - - def open(self): - self.uart.flushOutput() - self.uart.close() - self.uart.open() - self.uart.flushInput() - - def close(self): - self.uart.flushOutput() - self.uart.close() - - def read(self, addr, burst_length=1): - datas = [] - self.uart.flushInput() - write_b(self.uart, self.cmds["read"]) - write_b(self.uart, burst_length) - word_addr = addr//4 - write_b(self.uart, (word_addr >> 24) & 0xff) - write_b(self.uart, (word_addr >> 16) & 0xff) - write_b(self.uart, (word_addr >> 8) & 0xff) - write_b(self.uart, (word_addr >> 0) & 0xff) - for i in range(burst_length): - data = 0 - for k in range(4): - data = data << 8 - data |= ord(self.uart.read()) - if self.debug: - print("RD {:08X} @ {:08X}".format(data, addr + 4*i)) - datas.append(data) - if burst_length == 1: - return datas[0] - else: - return datas - - def write(self, addr, data): - if isinstance(data, list): - burst_length = len(data) - else: - burst_length = 1 - data = [data] - write_b(self.uart, self.cmds["write"]) - write_b(self.uart, burst_length) - word_addr = addr//4 - write_b(self.uart, (word_addr >> 24) & 0xff) - write_b(self.uart, (word_addr >> 16) & 0xff) - write_b(self.uart, (word_addr >> 8) & 0xff) - write_b(self.uart, (word_addr >> 0) & 0xff) - for i in range(len(data)): - dat = data[i] - for j in range(4): - write_b(self.uart, (dat >> 24) & 0xff) - dat = dat << 8 - if self.debug: - print("WR {:08X} @ {:08X}".format(data[i], addr + 4*i)) diff --git a/misoclib/tools/litescope/software/driver/usb.py b/misoclib/tools/litescope/software/driver/usb.py deleted file mode 100644 index 3416977f..00000000 --- a/misoclib/tools/litescope/software/driver/usb.py +++ /dev/null @@ -1,71 +0,0 @@ -from misoclib.com.liteusb.software.ftdi import FTDIComDevice - -class LiteScopeUSB2WishboneFTDIDriver: - cmds = { - "write": 0x01, - "read": 0x02 - } - def __init__(self, interface, mode, tag, addrmap=None, debug=False): - self.interface = interface - self.mode = mode - self.tag = tag - self.debug = debug - self.com = FTDIComDevice(self.interface, - mode=mode, - uart_tag=tag, - dma_tag=16, # XXX FIXME - verbose=debug) - if addrmap is not None: - self.regs = build_map(addrmap, busword, self.read, self.write) - - def open(self): - self.com.open() - - def close(self): - self.com.close() - - # XXX regroup cmds in a single packet - def read(self, addr, burst_length=1): - datas = [] - self.com.uartflush() - self.com.uartwrite(self.cmds["read"]) - self.com.uartwrite(burst_length) - word_addr = addr//4 - self.com.uartwrite((word_addr >> 24) & 0xff) - self.com.uartwrite((word_addr >> 16) & 0xff) - self.com.uartwrite((word_addr >> 8) & 0xff) - self.com.uartwrite((word_addr >> 0) & 0xff) - for i in range(burst_length): - data = 0 - for k in range(4): - data = data << 8 - data |= self.com.uartread() - if self.debug: - print("RD {:08X} @ {:08X}".format(data, addr + 4*i)) - datas.append(data) - if burst_length == 1: - return datas[0] - else: - return datas - - # XXX regroup cmds in a single packet - def write(self, addr, data): - if isinstance(data, list): - burst_length = len(data) - else: - burst_length = 1 - data = [data] - self.com.uartwrite(self.cmds["write"]) - self.com.uartwrite(burst_length) - word_addr = addr//4 - self.com.uartwrite((word_addr >> 24) & 0xff) - self.com.uartwrite((word_addr >> 16) & 0xff) - self.com.uartwrite((word_addr >> 8) & 0xff) - self.com.uartwrite((word_addr >> 0) & 0xff) - for i in range(len(data)): - dat = data[i] - for j in range(4): - self.com.uartwrite((dat >> 24) & 0xff) - dat = dat << 8 - if self.debug: - print("WR {:08X} @ {:08X}".format(data[i], addr + 4*i))