forked from M-Labs/artiq-zynq
Compare commits
13 Commits
7285479f5b
...
925237face
Author | SHA1 | Date |
---|---|---|
morgan | 925237face | |
morgan | 610b53e7f7 | |
morgan | c74c1c2ac4 | |
morgan | c83e31af7e | |
morgan | 97b940fb0a | |
morgan | 1b704a738c | |
morgan | 9ecc3cebb6 | |
morgan | 9a06848cbb | |
morgan | ca32914917 | |
morgan | dddea53d26 | |
morgan | a87208effe | |
morgan | 5f57cededf | |
morgan | d8b06e7200 |
|
@ -23,6 +23,41 @@ class DownConn_Interface(Module, AutoCSR):
|
|||
self.submodules.phy = phy = CXP_DownConn_PHY(refclk, downconn_pads, sys_clk_freq, debug_sma, pmod_pads)
|
||||
self.gtxs = phy.gtxs
|
||||
|
||||
# DEBUG: TX pipeline
|
||||
self.submodules.debug_src = debug_src = TX_Command_Packet()
|
||||
self.submodules.trig_ack = trig_ack = Trigger_ACK()
|
||||
self.submodules.mux = mux = stream.Multiplexer(upconn_layout, 2)
|
||||
self.submodules.conv = conv = stream.StrideConverter(upconn_layout, downconn_layout, reverse=True)
|
||||
|
||||
self.ack = CSR()
|
||||
self.mux_sel = CSRStorage()
|
||||
self.sync += trig_ack.ack.eq(self.ack.re),
|
||||
|
||||
self.comb += [
|
||||
debug_src.source.connect(mux.sink0),
|
||||
trig_ack.source.connect(mux.sink1),
|
||||
mux.sel.eq(self.mux_sel.storage)
|
||||
]
|
||||
|
||||
tx_pipeline = [mux , conv, phy.sinks[0]]
|
||||
for s, d in zip(tx_pipeline, tx_pipeline[1:]):
|
||||
self.comb += s.source.connect(d.sink)
|
||||
|
||||
# NOTE: RX pipeline
|
||||
self.submodules.debug_out = debug_out = RX_Debug_Buffer()
|
||||
self.submodules.recv_path = recv_path = Receiver_Path()
|
||||
|
||||
rx_pipeline = [phy.sources[0], recv_path, debug_out]
|
||||
for s, d in zip(rx_pipeline, rx_pipeline[1:]):
|
||||
self.comb += s.source.connect(d.sink)
|
||||
|
||||
# DEBUG: CSR
|
||||
self.trig_ack = CSRStatus()
|
||||
self.trig_clr = CSR()
|
||||
self.comb += [
|
||||
self.trig_ack.status.eq(recv_path.trig_ack),
|
||||
recv_path.trig_clr.eq(self.trig_clr.re),
|
||||
]
|
||||
|
||||
|
||||
class UpConn_Interface(Module, AutoCSR):
|
||||
|
|
|
@ -4,8 +4,10 @@ from migen.genlib.resetsync import AsyncResetSynchronizer
|
|||
|
||||
from misoc.cores.code_8b10b import Encoder, Decoder
|
||||
from misoc.interconnect.csr import *
|
||||
from misoc.interconnect import stream
|
||||
|
||||
from artiq.gateware.drtio.transceiver.gtx_7series_init import *
|
||||
from cxp_pipeline import downconn_layout
|
||||
|
||||
from functools import reduce
|
||||
from operator import add
|
||||
|
@ -46,7 +48,6 @@ class CXP_DownConn_PHY(Module, AutoCSR):
|
|||
# TODO: add extension gtx connections
|
||||
# TODO: add connection interface
|
||||
|
||||
|
||||
# TODO: Connect slave cxp_gtx_rx clock tgt
|
||||
# checkout channel interfaces & drtio_gtx
|
||||
# GTPTXPhaseAlignement for inspiration
|
||||
|
@ -99,9 +100,30 @@ class CXP_DownConn_PHY(Module, AutoCSR):
|
|||
),
|
||||
]
|
||||
|
||||
self.sources = []
|
||||
|
||||
for n, gtx in enumerate(self.gtxs):
|
||||
# DEBUG: remove cdc fifo
|
||||
# gtx rx -> fifo out -> cdc out
|
||||
|
||||
fifo_out = stream.AsyncFIFO(downconn_layout, 128)
|
||||
self.submodules += ClockDomainsRenamer({"write": "cxp_gtx_rx", "read": "sys"})(fifo_out)
|
||||
self.sources.append(fifo_out)
|
||||
|
||||
for i in range(4):
|
||||
self.sync.cxp_gtx_rx += [
|
||||
fifo_out.sink.stb.eq(0),
|
||||
# don't store idle word in fifo
|
||||
If(gtx.rx_ready & fifo_out.sink.ack & (gtx.decoders[0].d != 0xBC),
|
||||
fifo_out.sink.stb.eq(1),
|
||||
fifo_out.sink.data[i*8:(i*8)+8].eq(gtx.decoders[i].d),
|
||||
fifo_out.sink.k[i].eq(gtx.decoders[i].k),
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
|
||||
# DEBUG: tx of gtx is not used in CXP
|
||||
# DEBUG: txusrclk PLL DRG
|
||||
|
||||
self.txpll_reset = CSRStorage()
|
||||
|
@ -118,6 +140,9 @@ class CXP_DownConn_PHY(Module, AutoCSR):
|
|||
self.txinit_phaligndone = CSRStatus()
|
||||
self.rxinit_phaligndone = CSRStatus()
|
||||
|
||||
self.tx_stb = CSRStorage()
|
||||
self.sinks = []
|
||||
|
||||
for n, gtx in enumerate(self.gtxs):
|
||||
self.comb += [
|
||||
gtx.txpll_reset.eq(self.txpll_reset.storage),
|
||||
|
@ -137,6 +162,48 @@ class CXP_DownConn_PHY(Module, AutoCSR):
|
|||
self.loopback_mode = CSRStorage(3)
|
||||
self.comb += gtx.loopback_mode.eq(self.loopback_mode.storage)
|
||||
|
||||
# DEBUG: datain
|
||||
# fw -> fifo (sys) -> cdc fifo -> gtx tx
|
||||
|
||||
fifo_in = stream.AsyncFIFO(downconn_layout, 128)
|
||||
self.submodules += ClockDomainsRenamer({"write": "sys", "read": "cxp_gtx_tx"})(fifo_in)
|
||||
self.sinks.append(fifo_in)
|
||||
|
||||
# TODO: why there this send an extra 0xFB word
|
||||
txstb = Signal()
|
||||
self.specials += MultiReg(self.tx_stb.storage, txstb, odomain="cxp_gtx_tx")
|
||||
|
||||
self.sync.cxp_gtx_tx += [
|
||||
fifo_in.source.ack.eq(0),
|
||||
If(fifo_in.source.stb & txstb,
|
||||
fifo_in.source.ack.eq(1),
|
||||
)
|
||||
]
|
||||
|
||||
# NOTE: prevent the first word send twice due to stream stb delay
|
||||
self.comb += [
|
||||
If(fifo_in.source.stb & fifo_in.source.ack,
|
||||
gtx.encoder.d[0].eq(fifo_in.source.data[:8]),
|
||||
gtx.encoder.d[1].eq(fifo_in.source.data[8:16]),
|
||||
gtx.encoder.d[2].eq(fifo_in.source.data[16:24]),
|
||||
gtx.encoder.d[3].eq(fifo_in.source.data[24:]),
|
||||
gtx.encoder.k[0].eq(fifo_in.source.k[0]),
|
||||
gtx.encoder.k[1].eq(fifo_in.source.k[1]),
|
||||
gtx.encoder.k[2].eq(fifo_in.source.k[2]),
|
||||
gtx.encoder.k[3].eq(fifo_in.source.k[3]),
|
||||
).Else(
|
||||
# NOTE: IDLE WORD
|
||||
gtx.encoder.d[0].eq(0xBC),
|
||||
gtx.encoder.k[0].eq(1),
|
||||
gtx.encoder.d[1].eq(0x3C),
|
||||
gtx.encoder.k[1].eq(1),
|
||||
gtx.encoder.d[2].eq(0x3C),
|
||||
gtx.encoder.k[2].eq(1),
|
||||
gtx.encoder.d[3].eq(0xB5),
|
||||
gtx.encoder.k[3].eq(0),
|
||||
)
|
||||
]
|
||||
|
||||
# DEBUG: IO SMA & PMOD
|
||||
if n == 0:
|
||||
self.specials += [
|
||||
|
@ -144,9 +211,9 @@ class CXP_DownConn_PHY(Module, AutoCSR):
|
|||
# Instance("OBUF", i_I=gtx.cd_cxp_gtx_tx.clk, o_O=debug_sma.n_rx),
|
||||
|
||||
# # pmod 0-7 pin
|
||||
# Instance("OBUF", i_I=gtx.comma_checker.comma_aligned, o_O=pmod_pads[0]),
|
||||
# Instance("OBUF", i_I=gtx.comma_checker.comma_det, o_O=pmod_pads[1]),
|
||||
# Instance("OBUF", i_I=gtx.comma_checker.restart_sys, o_O=pmod_pads[2]),
|
||||
Instance("OBUF", i_I=txstb, o_O=pmod_pads[0]),
|
||||
Instance("OBUF", i_I=fifo_in.source.stb, o_O=pmod_pads[1]),
|
||||
Instance("OBUF", i_I=fifo_in.source.ack, o_O=pmod_pads[2]),
|
||||
# Instance("OBUF", i_I=gtx.comma_checker.aligner_en, o_O=pmod_pads[3]),
|
||||
# Instance("OBUF", i_I=gtx.comma_checker.check_reset, o_O=pmod_pads[4]),
|
||||
# Instance("OBUF", i_I=gtx.comma_checker.has_comma, o_O=pmod_pads[5]),
|
||||
|
@ -159,43 +226,6 @@ class CXP_DownConn_PHY(Module, AutoCSR):
|
|||
# Instance("OBUF", i_I=gtx.dready, o_O=pmod_pads[3]),
|
||||
]
|
||||
|
||||
# DEBUG: datain
|
||||
|
||||
|
||||
self.sync.cxp_gtx_tx += [
|
||||
gtx.encoder.d[0].eq(0xBC),
|
||||
gtx.encoder.k[0].eq(1),
|
||||
gtx.encoder.d[1].eq(0x3C),
|
||||
gtx.encoder.k[1].eq(1),
|
||||
gtx.encoder.d[2].eq(0x3C),
|
||||
gtx.encoder.k[2].eq(1),
|
||||
gtx.encoder.d[3].eq(0xB5),
|
||||
gtx.encoder.k[3].eq(0),
|
||||
]
|
||||
|
||||
for i in range(4):
|
||||
gtx.decoders[i].input.attr.add("no_retiming")
|
||||
gtx.decoders[i].d.attr.add("no_retiming")
|
||||
gtx.decoders[i].k.attr.add("no_retiming")
|
||||
|
||||
rxdata_name = "rxdata_" + str(i)
|
||||
rxdata_csr = CSRStatus(10, name=rxdata_name)
|
||||
setattr(self, rxdata_name, rxdata_csr)
|
||||
|
||||
decoded_name = "decoded_data_" + str(i)
|
||||
decoded_csr = CSRStatus(8, name=decoded_name)
|
||||
setattr(self, decoded_name, decoded_csr)
|
||||
|
||||
k_name = "rxdata_" + str(i)
|
||||
k_csr = CSRStatus(1, name=k_name)
|
||||
setattr(self, k_name, k_csr)
|
||||
|
||||
self.sync.cxp_gtx_rx += [
|
||||
rxdata_csr.status.eq(gtx.decoders[i].input),
|
||||
decoded_csr.status.eq(gtx.decoders[i].d),
|
||||
k_csr.status.eq(gtx.decoders[i].k),
|
||||
]
|
||||
|
||||
class QPLL(Module, AutoCSR):
|
||||
def __init__(self, refclk, sys_clk_freq):
|
||||
self.clk = Signal()
|
||||
|
|
|
@ -6,11 +6,20 @@ from misoc.cores.liteeth_mini.mac.crc import LiteEthMACCRCEngine, LiteEthMACCRCC
|
|||
upconn_dw = 8
|
||||
upconn_layout = [("data", upconn_dw), ("k", upconn_dw//8)]
|
||||
|
||||
downconn_dw = 32
|
||||
downconn_layout = [("data", downconn_dw), ("k", downconn_dw//8)]
|
||||
|
||||
|
||||
def K(x, y):
|
||||
return ((y << 5) | x)
|
||||
|
||||
def bytes2word(arr):
|
||||
assert len(arr) == 4
|
||||
sum = 0
|
||||
for i, val in enumerate(arr):
|
||||
sum += (val & 0xFF) << i*8
|
||||
return sum
|
||||
|
||||
class Code_Source(Module):
|
||||
def __init__(self, layout, counts=4):
|
||||
|
||||
|
@ -247,22 +256,22 @@ class Trigger_ACK(Module):
|
|||
self.source = k_code_inserter.source
|
||||
|
||||
class TX_Command_Packet(Module, AutoCSR):
|
||||
def __init__(self):
|
||||
self.len = CSRStorage(6)
|
||||
# Section 12.1.2 (CXP-001-2021)
|
||||
# Max control packet size is 128 bytes
|
||||
def __init__(self, fifo_depth=128):
|
||||
self.len = CSRStorage(log2_int(fifo_depth))
|
||||
self.data = CSR(upconn_dw)
|
||||
self.writeable = CSRStatus()
|
||||
|
||||
# # #
|
||||
|
||||
# Section 12.1.2 (CXP-001-2021)
|
||||
# Max control packet size is 128 bytes
|
||||
self.submodules.fifo = fifo = stream.SyncFIFO(upconn_layout, 128)
|
||||
self.submodules.fifo = fifo = stream.SyncFIFO(upconn_layout, fifo_depth)
|
||||
self.submodules.pak_wrp = pak_wrp = Packet_Wrapper(upconn_layout)
|
||||
self.source = pak_wrp.source
|
||||
|
||||
self.comb += fifo.source.connect(pak_wrp.sink)
|
||||
|
||||
len = Signal(6, reset=1)
|
||||
cnt = Signal(log2_int(fifo_depth), reset=1)
|
||||
self.sync += [
|
||||
self.writeable.status.eq(fifo.sink.ack),
|
||||
If(fifo.sink.ack, fifo.sink.stb.eq(0)),
|
||||
|
@ -271,12 +280,12 @@ class TX_Command_Packet(Module, AutoCSR):
|
|||
fifo.sink.data.eq(self.data.r),
|
||||
|
||||
fifo.sink.k.eq(0),
|
||||
If(len == self.len.storage,
|
||||
If(cnt == self.len.storage,
|
||||
fifo.sink.eop.eq(1),
|
||||
len.eq(len.reset),
|
||||
cnt.eq(cnt.reset),
|
||||
).Else(
|
||||
fifo.sink.eop.eq(0),
|
||||
len.eq(len + 1),
|
||||
cnt.eq(cnt + 1),
|
||||
),
|
||||
)
|
||||
]
|
||||
|
@ -332,7 +341,7 @@ class TX_Test_Packet(Module, AutoCSR):
|
|||
self.submodules.pak_wrp = pak_wrp = Packet_Wrapper(upconn_layout)
|
||||
self.comb += [
|
||||
pak_type_inserter.data.eq(0x04),
|
||||
pak_type_inserter.k.eq(0x04),
|
||||
pak_type_inserter.k.eq(0),
|
||||
|
||||
testdata_src.connect(pak_type_inserter.sink),
|
||||
pak_type_inserter.source.connect(pak_wrp.sink),
|
||||
|
@ -346,3 +355,81 @@ class TX_Test_Packet(Module, AutoCSR):
|
|||
).Elif(self.source.eop & self.source.ack,
|
||||
self.busy.status.eq(0)
|
||||
)
|
||||
|
||||
class RX_Debug_Buffer(Module,AutoCSR):
|
||||
def __init__(self):
|
||||
self.submodules.buf_out = buf_out = stream.SyncFIFO(downconn_layout, 128)
|
||||
self.sink = buf_out.sink
|
||||
|
||||
self.inc = CSR()
|
||||
self.dout_pak = CSRStatus(downconn_dw)
|
||||
self.kout_pak = CSRStatus(downconn_dw//8)
|
||||
self.dout_valid = CSRStatus()
|
||||
|
||||
self.sync += [
|
||||
# output
|
||||
buf_out.source.ack.eq(self.inc.re),
|
||||
self.dout_pak.status.eq(buf_out.source.data),
|
||||
self.kout_pak.status.eq(buf_out.source.k),
|
||||
self.dout_valid.status.eq(buf_out.source.stb),
|
||||
]
|
||||
|
||||
class Receiver_Path(Module, AutoCSR):
|
||||
def __init__(self):
|
||||
self.trig_ack = Signal()
|
||||
self.trig_clr = Signal()
|
||||
|
||||
# TODO:
|
||||
self.packet_type = Signal(8)
|
||||
|
||||
|
||||
class CXP_Data_Packet_Decode(Module):
|
||||
def __init__(self):
|
||||
self.sink = stream.Endpoint(downconn_layout)
|
||||
# This is where data stream comes out
|
||||
self.source = stream.Endpoint(downconn_layout)
|
||||
|
||||
# # #
|
||||
|
||||
self.comb += self.sink.connect(self.source)
|
||||
|
||||
|
||||
class CXP_Trig_Ack_Checker(Module, AutoCSR):
|
||||
def __init__(self):
|
||||
self.sink = stream.Endpoint(downconn_layout)
|
||||
self.source = stream.Endpoint(downconn_layout)
|
||||
|
||||
self.ack = Signal()
|
||||
|
||||
# # #
|
||||
|
||||
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
|
||||
|
||||
fsm.act("IDLE",
|
||||
self.sink.ack.eq(1),
|
||||
If(self.sink.stb,
|
||||
self.sink.ack.eq(0),
|
||||
NextState("COPY"),
|
||||
)
|
||||
)
|
||||
|
||||
fsm.act("COPY",
|
||||
If((self.sink.stb & (self.sink.data == bytes2word([K(28, 6)]*4)) & (self.sink.k == 0b1111)),
|
||||
# discard K28,6
|
||||
self.sink.ack.eq(1),
|
||||
NextState("CHECK_ACK")
|
||||
).Else(
|
||||
self.sink.connect(self.source),
|
||||
)
|
||||
)
|
||||
|
||||
fsm.act("CHECK_ACK",
|
||||
If(self.sink.stb,
|
||||
NextState("IDLE"),
|
||||
# discard the word after K28,6
|
||||
self.sink.ack.eq(1),
|
||||
If(self.sink.data == bytes2word([0x01]*4),
|
||||
self.ack.eq(1),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -3,7 +3,7 @@ use libboard_zynq::{println, timer::GlobalTimer};
|
|||
use log::info;
|
||||
|
||||
// use log::info;
|
||||
use crate::pl::csr;
|
||||
use crate::{cxp_proto, pl::csr};
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[allow(non_camel_case_types)]
|
||||
|
@ -37,72 +37,42 @@ pub fn loopback_testing(timer: &mut GlobalTimer, speed: CXP_SPEED) {
|
|||
while csr::cxp::downconn_phy_rx_ready_read() != 1 {}
|
||||
info!("rx ready!");
|
||||
|
||||
loop {
|
||||
// for _ in 0..20 {
|
||||
// NOTE: raw bits
|
||||
// let data0 = csr::cxp::downconn_phy_rxdata_0_read();
|
||||
// let data1 = csr::cxp::downconn_phy_rxdata_1_read();
|
||||
// let data2 = csr::cxp::downconn_phy_rxdata_2_read();
|
||||
// let data3 = csr::cxp::downconn_phy_rxdata_3_read();
|
||||
// let rxready = csr::cxp::downconn_phy_rx_ready_read();
|
||||
// timer.delay_us(100);
|
||||
// if data0 == 0b0101111100 || data0 == 0b1010000011 {
|
||||
// println!(
|
||||
// "data[0] = {:#012b} comma = {} | rx ready = {}",
|
||||
// data0,
|
||||
// data0 == 0b0101111100 || data0 == 0b1010000011,
|
||||
// rxready,
|
||||
// );
|
||||
// timer.delay_us(1_000_000);
|
||||
// } else if data0 == 0b1001111100 || data0 == 0b0110000011 {
|
||||
// println!(
|
||||
// "data[0] = {:#012b} K28.1 | rx ready = {}",
|
||||
// data0,
|
||||
// rxready,
|
||||
// );
|
||||
// timer.delay_us(1_000_000);
|
||||
// } else {
|
||||
// println!(
|
||||
// "data[0] = {:#012b} | rx ready = {}",
|
||||
// data0,
|
||||
// rxready,
|
||||
// );
|
||||
// timer.delay_us(1_000_000);
|
||||
// }
|
||||
cxp_proto::downconn_debug_send_trig_ack();
|
||||
|
||||
timer.delay_us(1_000_000);
|
||||
// NOTE: raw bits
|
||||
// let data0 = csr::cxp::downconn_phy_rxdata_0_read();
|
||||
// let data1 = csr::cxp::downconn_phy_rxdata_1_read();
|
||||
// let data2 = csr::cxp::downconn_phy_rxdata_2_read();
|
||||
// let data3 = csr::cxp::downconn_phy_rxdata_3_read();
|
||||
// println!(
|
||||
// "0b{:010b} {:010b} {:010b} {:010b}",
|
||||
// data0, data1, data2, data3
|
||||
// );
|
||||
cxp_proto::downconn_debug_send(&cxp_proto::Packet::CtrlRead {
|
||||
addr: 0x00,
|
||||
length: 0x04,
|
||||
});
|
||||
|
||||
// NOTE:decode data
|
||||
// let data0_k = csr::cxp::downconn_phy_decoded_k_0_read();
|
||||
// let data1_k = csr::cxp::downconn_phy_decoded_k_1_read();
|
||||
// let data2_k = csr::cxp::downconn_phy_decoded_k_2_read();
|
||||
// let data3_k = csr::cxp::downconn_phy_decoded_k_3_read();
|
||||
let data0_decoded = csr::cxp::downconn_phy_decoded_data_0_read();
|
||||
let data1_decoded = csr::cxp::downconn_phy_decoded_data_1_read();
|
||||
let data2_decoded = csr::cxp::downconn_phy_decoded_data_2_read();
|
||||
let data3_decoded = csr::cxp::downconn_phy_decoded_data_3_read();
|
||||
println!(
|
||||
"{:#04x} {:#04x} {:#04x} {:#04x}",
|
||||
data0_decoded, data1_decoded, data2_decoded, data3_decoded,
|
||||
);
|
||||
// println!(
|
||||
// "decoded_data[0] = {:#04x} decoded_k[0] = {:#b} decoded_data[1] = {:#04x} decoded_k[1] = {:#b}",
|
||||
// data0_decoded,
|
||||
// data0_k,
|
||||
// data1_decoded,
|
||||
// data1_k,
|
||||
// );
|
||||
timer.delay_us(200); // wait packet has arrive at async fifo in
|
||||
csr::cxp::downconn_phy_tx_stb_write(1);
|
||||
timer.delay_us(200);
|
||||
csr::cxp::downconn_phy_tx_stb_write(0);
|
||||
|
||||
info!("trig ack = {}", csr::cxp::downconn_trig_ack_read());
|
||||
csr::cxp::downconn_trig_clr_write(1);
|
||||
info!("after clr trig ack = {}", csr::cxp::downconn_trig_ack_read());
|
||||
|
||||
// TODO: investigate how to make my packet appear
|
||||
// TODO: discard idle word
|
||||
|
||||
// DEBUG: print loopback packets
|
||||
const LEN: usize = 20;
|
||||
let mut pak_arr: [u32; LEN] = [0; LEN];
|
||||
let mut k_arr: [u8; LEN] = [0; LEN];
|
||||
let mut i: usize = 0;
|
||||
while csr::cxp::downconn_debug_out_dout_valid_read() == 1 {
|
||||
pak_arr[i] = csr::cxp::downconn_debug_out_dout_pak_read();
|
||||
k_arr[i] = csr::cxp::downconn_debug_out_kout_pak_read();
|
||||
// println!("received {:#04X}", pak_arr[i]);
|
||||
csr::cxp::downconn_debug_out_inc_write(1);
|
||||
i += 1;
|
||||
if i == LEN {
|
||||
break;
|
||||
}
|
||||
}
|
||||
cxp_proto::print_packetu32(&pak_arr, &k_arr);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setup(timer: &mut GlobalTimer) {
|
||||
|
|
|
@ -191,3 +191,48 @@ pub fn print_packet(pak: &[u8]) {
|
|||
println!("]");
|
||||
println!("============================================");
|
||||
}
|
||||
|
||||
pub fn print_packetu32(pak: &[u32], k: &[u8]) {
|
||||
println!("pak = [");
|
||||
for i in 0..(pak.len()) {
|
||||
let data: [u8; 4] = pak[i].to_be_bytes();
|
||||
println!(
|
||||
"{:#03} {:#04X} {:#04X} {:#04X} {:#04X} | K {:04b},",
|
||||
i + 1,
|
||||
data[0],
|
||||
data[1],
|
||||
data[2],
|
||||
data[3],
|
||||
k[i],
|
||||
)
|
||||
}
|
||||
println!("]");
|
||||
println!("============================================");
|
||||
}
|
||||
|
||||
pub fn downconn_debug_send(packet: &Packet) -> Result<(), Error> {
|
||||
let mut buffer: [u8; MAX_PACKET] = [0; MAX_PACKET];
|
||||
let mut writer = Cursor::new(&mut buffer[..]);
|
||||
|
||||
packet.write_to(&mut writer)?;
|
||||
|
||||
unsafe {
|
||||
csr::cxp::downconn_mux_sel_write(0);
|
||||
let len = writer.position();
|
||||
csr::cxp::downconn_debug_src_len_write(len as u8);
|
||||
for data in writer.get_ref()[..len].iter() {
|
||||
while csr::cxp::downconn_debug_src_writeable_read() == 0 {}
|
||||
csr::cxp::upconn_command_data_write(*data);
|
||||
csr::cxp::downconn_debug_src_data_write(*data);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn downconn_debug_send_trig_ack() {
|
||||
unsafe {
|
||||
csr::cxp::downconn_mux_sel_write(1);
|
||||
csr::cxp::downconn_ack_write(1);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue