Add STEVAL-MKI217V1 SPI logger and replay

This commit is contained in:
2026-07-13 22:16:51 +03:00
parent f16ac8aa80
commit df563aa207
12 changed files with 629 additions and 13 deletions
@@ -196,6 +196,8 @@ class TLFpgaSPI(params: FpgaSPIParams, beatBytes: Int)(implicit p: Parameters) e
val csn = RegInit(true.B)
val sck = RegInit(false.B)
val quad = RegInit(false.B)
val cpol = RegInit(false.B)
val cpha = RegInit(false.B)
val txShift = RegInit(0.U(32.W))
val rxShift = RegInit(0.U(32.W))
val bitsLeft = RegInit(0.U(6.W))
@@ -211,13 +213,29 @@ class TLFpgaSPI(params: FpgaSPIParams, beatBytes: Int)(implicit p: Parameters) e
when(div === (params.clockDiv - 1).U) {
div := 0.U
sck := ~sck
when(sck) {
val step = Mux(quad, 4.U, 1.U)
val step = Mux(quad, 4.U, 1.U)
/*
* `sck` is the pre-toggle level. The edge away from CPOL is the
* leading edge; CPHA selects leading (0) or trailing (1) sampling.
* TX advances only after the active sample edge, so all four standard
* SPI modes retain a full half-cycle of setup time.
*/
val leadingEdge = sck === cpol
val sampleEdge = Mux(cpha, !leadingEdge, leadingEdge)
when(sampleEdge) {
rxShift := Mux(quad, Cat(rxShift(27, 0), dq_i), Cat(rxShift(30, 0), dq_i(1)))
}
/*
* CPHA=0 completes on the trailing edge after the final leading-edge
* sample. CPHA=1 samples and completes on the final trailing edge.
*/
val advanceEdge = Mux(cpha, sampleEdge, !sampleEdge)
when(advanceEdge) {
txShift := Mux(quad, Cat(txShift(27, 0), 0.U(4.W)), Cat(txShift(30, 0), 0.U(1.W)))
when(bitsLeft <= step) {
busy := false.B
sck := false.B
sck := cpol
bitsLeft := 0.U
}.otherwise {
bitsLeft := bitsLeft - step
@@ -229,12 +247,15 @@ class TLFpgaSPI(params: FpgaSPIParams, beatBytes: Int)(implicit p: Parameters) e
}
val ctrl = Wire(UInt(32.W))
ctrl := Cat(0.U(29.W), quad, csn, busy)
ctrl := Cat(0.U(27.W), cpha, cpol, quad, csn, busy)
val ctrlWrite = RegWriteFn { (valid, data) =>
when(valid && !busy) {
csn := data(1)
quad := data(2)
cpol := data(3)
cpha := data(4)
sck := data(3)
}
true.B
}
@@ -246,13 +267,13 @@ class TLFpgaSPI(params: FpgaSPIParams, beatBytes: Int)(implicit p: Parameters) e
bitsLeft := Mux(quad, 32.U, 8.U)
busy := true.B
div := 0.U
sck := false.B
sck := cpol
}
true.B
}
node.regmap(
0x00 -> Seq(RegField(32, ctrl, ctrlWrite, RegFieldDesc("ctrl", "bit0 busy RO, bit1 csn RW, bit2 quad RW"))),
0x00 -> Seq(RegField(32, ctrl, ctrlWrite, RegFieldDesc("ctrl", "bit0 busy RO, bit1 csn RW, bit2 quad RW, bit3 CPOL RW, bit4 CPHA RW"))),
0x04 -> Seq(RegField.w(32, txWrite, RegFieldDesc("tx", "start transfer"))),
0x08 -> Seq(RegField.r(32, rxShift, RegFieldDesc("rx", "last received shift register"))),
0x0c -> Seq(RegField.r(1, !busy, RegFieldDesc("ready", "controller ready")))