Jump to content
  • 0

Looking for a UART programmable logic example project for Arty S7 with Vivado 2022.2


0xbadcaffe

Question

8 answers to this question

Recommended Posts

  • 0

Hi @0xbadcaffe,

Digilent does not have a demo using the both the Pmod RS232 and the Pmod RS485 (a singular design that seamlessly supports both devices would not be super straightforward either as the Rx and Tx pins on the two Pmods are on different pin locations on the 6-pin header).

I have made an external UART loopback on Digilent boards that takes serial terminal data from the host computer, sends the UART data out one of the Pmod port pins, receives that UART data via a breadboard jumper wire to a different Pmod port pin, and then sends the received data back to the serial terminal on a host computer. The general process of how to set this up in Vivado block design is described here:

The corresponding Vitis code that facilitates the described communication would be similar to this:

Spoiler
#include "xparameters.h"
#include "xil_printf.h"
#include "xgpio.h"
#include "xil_types.h"
#include "xuartlite.h"
  
#define UART1_ID XPAR_AXI_UARTLITE_1_DEVICE_ID	//one of the UART IPs
#define UART0_ID XPAR_AXI_UARTLITE_0_DEVICE_ID	//the other UART IP
XUartLite external_uart;
XUartLite host_pc;

int main()
{
    xil_printf("Just entered main\n\r");

    u8 numcharSend = 0;	//number of characters from host to send to external UART
    u8 numcharRecv = 0;	//number of characters from external UART to send to host
    u8 character = 0;	//the actual character from the XUartLite functions to send around
    XUartLite_Config *cfg_ptr;
	cfg_ptr = XUartLite_LookupConfig(UART1_ID);
	XUartLite_CfgInitialize(&external_uart, cfg_ptr, cfg_ptr->RegBaseAddr);
	cfg_ptr = XUartLite_LookupConfig(UART0_ID);
	XUartLite_CfgInitialize(&host_pc, cfg_ptr, cfg_ptr->RegBaseAddr);

	while(1){
		numcharSend = XUartLite_Recv(&host_pc, &character, 1);	//get the number of bytes received from the host
		if (numcharSend > 0) {									//if the number of bytes is greater than 0
			XUartLite_Send(&external_uart, &character, 1);		//send the first received character in the FIFO buffer of XUartLite to the external UART
          	while(XUartLite_IsSending(&external_uart)){}		//pause until the character is done sending
		}
		numcharRecv = XUartLite_Recv(&external_uart, &character, 1);	//get the number of characters received from the extra UART input
		if (numcharRecv > 0) {									//if the number of bytes is greater than 0
			XUartLite_Send(&host_pc, &character, 1);			//send the first received character in the FIFO buffer of XUartLite to the host PC
          	while(XUartLite_IsSending(&external_uart)){}		//pause until the character is done sending
		}
	}															//jump back up to the start of the infinite while loop
	return 0;

}

 

To be clear, this does not implement any of the control signals used in the Pmod RS232 and Pmod RS485, though otherwise are communicated with via standard UART.

Let me know if you have any questions.

Thanks,
JColvin

Link to comment
Share on other sites

  • 0

Thank you James for the answer.

First, perhaps I was not that clear.

I do not need both RS232 and RS485 working on the same RX and TX pins, they can be on separate PMOD connectors and thus different logic signals.

I want to start with RS232.

Is there a VHDL UART code example (not Microblaze based IP) for working with PMODs? specifically the  Digilent RS232?

 

Also, I see in the The Digilent Pmod RS232  description page a note which states:

 

Quote

Note: There are two UART signal pin assignment conventions in use on Digilent products. This product uses the old signal assignment convention. Connecting a product using the old convention with one using the new convention requires the use of a UART Crossover Cable (not included). Click here for a more detailed explanation.

 

Can use the Pmod RS232 with the Arty-S7? do I need to use the Crossover Cable?

 

Thanks!

 

 

Link to comment
Share on other sites

  • 0

Hi @0xbadcaffe,

The Pmod RS232 and Pmod RS485 can be used with the Arty S7 without any special crossover cables. This is because FPGAs can have their internal logic be "assigned" to any compatible IO pin (unlike microcontrollers or microprocessors where their UART or SPI cores are hardwired to only particular pins; the PIC32 microcontrollers that Digilent used to sell had a change in the architecture where the hardwired locations of the Rx and Tx pins changed).

Otherwise you could use the UART VHDL implementation that is used as part of the Arty S7 GPIO demo, https://digilent.com/reference/programmable-logic/arty-s7/demos/gpio; the UART_TXD port that is defined in the "top" file (in this case GPIO_Demo.vhd) is set to the corresponding RX port on the USB-UART interface in the .xdc file. This could easily be "assigned" to a different pin on one of the Pmod ports instead.

Let me know if you have any questions.

Thanks,
JColvin

Link to comment
Share on other sites

  • 0

Hi @0xbadcaffe,

Yes, that is entirely possible to do; simply just have the Rx assigned on one particular Pmod pin and the Tx on a different pin. An external wire like a breadboard jumper wire would be needed to make the electrical connection the two pins of course, but whether the Rx and Tx are part of the same UART core or not (or same board) doesn't matter.

So long as the setups are expecting the same baud rate and word length and the logic is in place to handle when data comes in at unexpected times (presuming you aren't using clear-to-send, etc, signals) it'll work. The harder portion is any extra application material to correctly process the data at more than one byte at a time (option 1 or option 2 style) to enable different types of functionality.

Thanks,
JColvin

Link to comment
Share on other sites

  • 0

Thanks JColvin!

I was able to port the GPIO example to Vivado 2022.2 and used the Arty-S7 PMOD (JA) connector to send data to a PC connected to the PMOD using an FTDI (TTL/USB).

I would like to proceed with the vhdl based UART example (not Microblaze) and expand it into an end-to-end request response design.

The Arty fpga should support both RX and TX, store the incoming data into a buffer, analyse it and send a response respectively.

I that there ready to use IPs from Xilinx. Not sure how flexible are they.

Should I just expand your example and build my design around it?

What is your suggestion to proceed with this issue?

 

Thanks again!

 

Link to comment
Share on other sites

  • 0

Hi @0xbadcaffe,

Xilinx has some language templates, but I don't believe it does any of the user logic portion. If you wanted modules for both the receiver and transmitter, you could always use some existing material like what is available here: https://nandland.com/uart-serial-port-module/. The code as is simply receives data rather than processes it, but extra processing could be added as your system requires.

Thanks,
JColvin

Link to comment
Share on other sites

  • 0

Thanks JColvin,

So the Xilinx IPs like UART 16550 and AXI UART Lite don't add any value beyond the code from nandland you sent?

What about double buffer implementation? where can I find something similar which supports the UART code?

 

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...