160 lines
5.1 KiB
Plaintext
160 lines
5.1 KiB
Plaintext
= UART-Wishbone Bridge
|
|
:docinfo: shared
|
|
|
|
[[protocol]]
|
|
== Protocol
|
|
|
|
The following sections outline the protocol used to communicate with the UART
|
|
half of the bridge.
|
|
|
|
=== Overview
|
|
|
|
The UART protocol uses a request/response format. Each wishbone transaction
|
|
corresponds to one request and one response. Each request begins with a command
|
|
byte; an optional, variable-length address; and some data if the request is a
|
|
write. Each response begins with a status byte, followed by some data if the
|
|
request was a read. The following diagram shows a successful read:
|
|
|
|
++++
|
|
<script type="WaveDrom">
|
|
{ signal : [
|
|
{ name: "rx", wave: "z34444z....", data: "CMD ADDR0 ADDR1 ADDR2 ADDR3" },
|
|
{ name: "tx", wave: "z......655z", data: "STATUS DATA0 DATA1" },
|
|
],
|
|
config: { hscale: 2 },
|
|
}
|
|
</script>
|
|
++++
|
|
|
|
Similarly, this diagram shows a successful write:
|
|
|
|
++++
|
|
<script type="WaveDrom">
|
|
{ signal : [
|
|
{ name: "rx", wave: "z3444455z..", data: "CMD ADDR0 ADDR1 ADDR2 ADDR3 DATA0 DATA1" },
|
|
{ name: "tx", wave: "z........6z", data: "RESP" },
|
|
],
|
|
config: { hscale: 2 },
|
|
}
|
|
</script>
|
|
++++
|
|
|
|
The bridge contains an internal address register that retains its state between
|
|
different transactions. It possible to reduce the length of requests by
|
|
partially modifying the address register.
|
|
|
|
=== Requests
|
|
|
|
Each request begins with a command byte. The format of the command byte is as
|
|
follows:
|
|
|
|
.Command byte
|
|
[cols="1,1,4a"]
|
|
|===
|
|
| Bit | Name | Description
|
|
|
|
| 0 | Clear | Setting this bit clears the address register before modifying
|
|
it. The address register should always be cleared during the
|
|
first transaction following a reset.
|
|
| 1 | Write-Enable | If this bit is set, this request is a write, and a data
|
|
phase follows the address phase. Otherwise, this request
|
|
is a read, and there is no data phase.
|
|
| 2 | Post-Increment | If this bit is set, the address register will be
|
|
incremented when the transaction completes.
|
|
| 4:3 | Address length
|
|
| This field indicates the number of bytes in the subsequent address phase.
|
|
!===
|
|
! Value ! Address bytes
|
|
|
|
! 0 ! 0 (no address phase)
|
|
! 1 ! 1
|
|
! 2 ! 2
|
|
! 3 ! 4
|
|
!===
|
|
| 7:5 | Reserved | Reserved, set to 0.
|
|
|===
|
|
|
|
Following the command byte, there is an optional address phase. The length of
|
|
the address phase is determined by the command byte. Bytes in the address phase
|
|
are loaded into the address register. The address is transmitted in big-endian
|
|
byte order (most-significant byte first). If number of bytes in the address
|
|
phase is smaller than the size of the address register, the lower bytes in the
|
|
address register will be replaced, and the upper bytes will not be modified.
|
|
|
|
The following table shows the value of each byte in the address register after a
|
|
particular address phase. Bytes are numbered by the order they are transmitted:
|
|
|
|
.Address phase
|
|
|===
|
|
| Address bytes | Address[31:24] | Address[23:16] | Address[15:8] | Address[7:0]
|
|
|
|
| 0 | Unmodified | Unmodified | Unmodified | Unmodifed
|
|
| 1 | Unmodified | Unmodified | Unmodified | Byte 0
|
|
| 2 | Unmodified | Unmodified | Byte 0 | Byte 1
|
|
| 4 | Byte 0 | Byte 1 | Byte 2 | Byte 3
|
|
|===
|
|
|
|
Finally, there is a data phase if the request is a write. Data is transmitted
|
|
in big-endian byte order (most-significant byte first).
|
|
|
|
Any requests transmitted while the bridge is processing another request will not
|
|
be handled correctly. This condition is indicated by an overflow status in
|
|
response to the initial request.
|
|
|
|
=== Responses
|
|
|
|
Each response begins with a status byte. The format of the status byte is as
|
|
follows:
|
|
|
|
.Status byte
|
|
[cols="1,1,4a"]
|
|
|===
|
|
| Bit | Name | Description
|
|
|
|
| 0 | Write Response | If set, the response is for a write and no data phase
|
|
follows. Otherwise, the response is for a read and a data
|
|
phase will follow.
|
|
| 1 | Bus Error | There was bus error when servicing the request, and no data
|
|
phase will follow. This bit has priority over any data phase
|
|
implied by the Write Response bit.
|
|
| 2 | Reserved | Reserved, do not use.
|
|
| 3 | Overflow | While processing this request, the receive UART overflowed, and
|
|
one or more request bytes were dropped. The bridge must be
|
|
reset before issuing the next command.
|
|
| 7:4 | Reserved | Reserved, do not use.
|
|
|===
|
|
|
|
Finally, there is a data phase if the request was a read. Data is transmitted
|
|
in big-endian byte order (most-significant byte first).
|
|
|
|
=== Resetting
|
|
|
|
The bridge and wishbone bus may be reset by sending a character with a framing
|
|
error (a break) over the serial line. The bridge should be reset before each
|
|
session in order to bring the bridge into a known state.
|
|
|
|
=== Examples
|
|
|
|
A read of `0xcafe` from `0x00000123` followed by a write of `0xbabe` to the same
|
|
address:
|
|
|
|
++++
|
|
<script type="WaveDrom">
|
|
{ signal : [
|
|
{ name: "rx", wave: "z344z....355z..", data: "11 01 23 02 ba be" },
|
|
{ name: "tx", wave: "z....655z....6z", data: "00 ca fe 01" },
|
|
]}
|
|
</script>
|
|
++++
|
|
|
|
Reading from `0x80001000`, `0x80002000`, and `0x80002001`:
|
|
|
|
++++
|
|
<script type="WaveDrom">
|
|
{ signal : [
|
|
{ name: "rx", wave: "z34444z....344z....3z....", data: "18 80 00 10 00 14 20 00 00" },
|
|
{ name: "tx", wave: "z......655z....655z..655z", data: "00 d0 0d 00 fe ed 00 fa ce" },
|
|
]}
|
|
</script>
|
|
++++
|