Add STEVAL-MKI217V1 SPI logger and replay
This commit is contained in:
@@ -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")))
|
||||
|
||||
Reference in New Issue
Block a user