A significant number of my clients’ projects, for which I design the SoCs, FPGAs and boards, need to communicate with remote sensors or other remote equipment. While there is more to interfaces such as Time Sensitive Networking and CAN, legacy standards like RS485 and RS422 still remain very popular. RS485 and RS422 are used in a range of applications from industrial control to aircraft / vehicle electronics, satellites and home / building automation. In short, it is an interface we need to now how to work with as electronic / SoC / FPGA designers.
RS422 and RS485 are popular as they can be used to interface with remote devices and sensors down either PCB backplanes or across long cable runs of up to 1,200 meters (although the data rate drops with distance from as high as 35 Mbps to 100 Kbps). The differential nature of the signaling, also provides significant noise immunity, and unlike LVDS, they can be easily electrically isolated.
Another reason RS485 and RS422 are popular is thanks to the simplicity with which we can implement an interface. Often, all we require is a UART to transfer bytes of data — of course, we do need a data link layer (and perhaps higher layers) to transfer data successfully between nodes and use it in the application.
However, while the physical level is well defined, that is where the standardization stops. As such, as engineers it is our job to define the protocol that is used to transfer data effectively over the serial bus, if we are not using a standard such as Modbus or Profibus.
When we define bespoke protocols, we need to understand a few key elements:
- Maximum length of the cabling, as this will effect the maximum data rate
- The number of slaves on the network
- The number of masters
- Method of communication, simplex, half-duplex or full duplex
Depending upon if we are using RS422 or RS485, many of these questions will be answered. Typically, a RS422 bus is a point to point simplex link that pairs one master with one slave. However, with RS422, up to 10 slaves can be on the line for a multi drop approach. If we desire the RS422 slave to respond to the transmitter, then another RS422 channel is required.
RS485 is a little different and solves the need for a second response channel. Implementing an RS485 bus enables us to have a mix of 32 receivers / transmitters on the line to implement a half duplex communications. That is each node connected to the network can both receive and transmit data.
When we need to develop the data link layer to run over the RS485 network, we need to be very careful to specify that only one node will attempt to transmit on the bus.
When it comes to implementing these interfaces in our FPGA, it is often best to use a UART for the transmission and reception of data. This can then be connected to an external PHY to provide the correct voltage levels for the physical level.
We can the use this UART to send and receive information over the network defined using our data link layer. This data link layer can be implemented using with a state machine, MicroBlaze, Arm Cortex-M1 or even in the Arm Cortex-A9 or A53/R5 if using a Zynq or Zynq US+ MPSoC.
When we define this protocol, we need to be able to ensure we transfer data correctly. Crucially, we need to have mechanism for when the transfer goes wrong, and if a node does not respond in the correct time. In this instance, a timeout can be very useful to reset the state machine back to the idle state should a timeout occur.
When I am defining custom data link layers, I start with a header, address field, data field, ECC and end of packet structure. This increases the number of bits required and slightly reduces the efficiency of the data transfer, but provides a solid mechanism for transfer of data and correct responses.
For the header and end of packet, I use commands from the ASCII table such as STX (Start of Text) and SOH (Start of Header). I also use the End of Transmission (EOT) as the end of packet marker. These make for simple and concise commands that can be used to enclose the packet. To identify if the packet is a read or a write, I use STX to indicate a read command and an SOH to indicate a write packet.
The ECC packet can be determined by using a CRC or a simple sum of the packet contents. Remember, we have parity protection on the UART level to enable us to detect errors as well.
In response to these packets, we can use the ACK and NACK commands to indicate to the transmitter if the command was successful or not.
When it comes to transmitting / receiving information, a RS485 driver will have both receive enables and transmit enables. This allows us to be able us to transmit when desired and receive when desired.
By default, we should be always listening to the RS485 bus; however, when we want to transmit the data, the transmitter should disable its receiver ( as the bus is half duplex). When we are enabling and disabling these PHYs, we need to ensure we give sufficient time as specified in the data sheet before we start transmitting the signal. Failure to follow this correctly will lead to the signal being corrupted as it is transmitted and errors at the receiver.
If we are using a softcore processor or a Zynq / Zynq US+, we can drive these signals using GPIO from the processor. If we are using a state machine approach, then they are simple outputs that toggle as required in the state machine states.
When we pull all this together in our FPGA, we can implement these industrial serial interfaces very simply within our design and get results fast on day one when the boards are available for initial testing.
If we want to test these interfaces out on our development and prototype boards, we can use a RS485 Pmod — which I will be doing soon in a Hackster project, so I can provide detailed instructions. Until then!
See My FPGA / SoC Projects: Adam Taylor on Hackster.io
Get the Code: ATaylorCEngFIET (Adam Taylor)
Access the MicroZed Chronicles Archives with over 300 articles on the FPGA / Zynq / Zynq MpSoC updated weekly at MicroZed Chronicles.