Create Application for PS UART and UART Lite

Design

Create an application for PS UART and UART Lite for communication testing on Xilinx Arty Z20

1. Open Vivado 2021.1 > Click File> Project >New

2. Create project name> PS UART and UART Lite

2

 

3. Project Type > Select RTL Project

4. Add constraints > Click next (we will add later)

5. Select Board > Arty Z7-20 then click next 

select board

 

6. Change target language to VHDL

select VHDL

 

7. Click > create block design

Create Block Design

 

8. Change design name > Design_UART_Lite

Design_UART_Lite

 

9. Click add IP

add IP

10. Search system > Select ZYNQ7 Processsing System

Zynq

 

11. Click run Block automation then Click ok

run

 

12. Add UART IP >Search UART > add 2 UART lite

UART

 

13. run Block automation then Click ok

run

 

14. Change the name for RX-Tx UART lite 0 and UART lite 1

    14.1 right click rx signal select make external port

rx

 14.2 After changing name

after change UART name

 

15. Select PS UART 1 in Zynq block> double click at Zynq processing system block

15.1 Change UART 1 config to EMIO then click ok.

change UART config

 

15.2 Make external ports for UART1_TX and UART1_RX

make external

 

 

16. Add constraints file 

16.1 Right click > create constraints file name PS_UART test.xdc

add cons

 

16.2 search and download Arty-Z7-20 then copy in to PS_UART test.xdc

PS UART

 

17. Select output port for mapping

Check connector port -> https://digilent.com/reference/programmable-logic/arty-z7/reference-manual

And Check pin name from schematic for mapping -> https://digilent.com/reference/_media/reference/programmable-logic/arty-z7/arty_z7_sch.pdf

 

Use Arduino/chipKit Shield Connector for output port mapping

 

Select IO0 for rx_0

Select IO1 for tx_0

Select IO3 for rx_1

Select IO4 for tx_1

Select IO6 for UART1_RX_0

Select IO7 for UART1_TX_0

 

 

shield connector

 

17.1 mapping signal in constraints file.

 

mapping

 

 

18. Create HDL wrapper >Right Click from design > let vivado manage wrapper and auto update

wrapper

 

 

19. Run synthesis

run

 

20. Run implementation

implementation

 

21. Generate Bitstream

generate bitstream

21.1 Bitstream genellation successfully then Click ok to see implementation 

success

 

 

21.2 Check design timing and find any abnormal in design

implement

 

 

 

 

22. Export hardware platform >platform type = fixed > Include bitstream

export

 

 

 

22. Launch vitis IDE for create application

vitis

 

 

23. Create application project

vitis

 

 

24. Select the platform

 

hw

 

25. Create app UART lite

 UARTlite

 

26.select templates

hello

 

27. Modify hello world templates to app_uart_lite.c 
app uart

 

Write copy the following code to app_uart_lite.c

/* modify from function from xuartps_polled_example.c and xuartlite_polled_example.c
 * using the local loopback mode.
 */ 

/***************************** Include Files *********************************/
#include 
#include "platform.h"
#include "xparameters.h"
#include "xuartps.h"
#include "sleep.h"
#include "xstatus.h"
#include "xuartlite.h"
#include "xil_printf.h"

/************************** Constant Definitions *****************************/

/*
 * The following constants map to the XPAR parameters created in the
 * xparameters.h file. They are defined here such that a user can easily
 * change all the needed parameters in one place.
 */

#define PS_UART_1	XPAR_PS7_UART_1_DEVICE_ID
#define UARTLITE_0  XPAR_UARTLITE_0_DEVICE_ID
#define UARTLITE_1	XPAR_UARTLITE_1_DEVICE_ID

/*
 * The following constant controls the length of the buffers to be sent
 * and received with the UartLite, this constant must be 16 bytes or less since
 * this is a single threaded non-interrupt driven example such that the
 * entire buffer will fit into the transmit and receive FIFOs of the UartLite.
 */
#define TEST_BUFFER_SIZE 16

/**************************** Type Definitions *******************************/


/***************** Macros (Inline Functions) Definitions *********************/


/************************** Function Prototypes ******************************/

int UartLitePolledExample(u16 DeviceId);
int UartPsPolledExample(u16 DeviceId);

/************************** Variable Definitions *****************************/

XUartLite UartLite;		/* Instance of the UartLite Device */
XUartPs Uart_PS;		/* Instance of the UART Device */

/*
 * The following buffers are used in this example to send and receive data
 * with the UartLite.
 */
u8 SendBuffer[TEST_BUFFER_SIZE];	/* Buffer for Transmitting Data */
u8 RecvBuffer[TEST_BUFFER_SIZE];	/* Buffer for Receiving Data */

/*****************************************************************************/
/**
*
* Main function to call the Uartlite polled example.
*
* @param	None.
*
* @return	XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note		None.
*
******************************************************************************/
int main(void)
{
	int Status;

	 while(1) {
	/*
	 * Run the UartLite polled example, specify the Device ID that is
	 * generated in xparameters.h
	 */
	Status = UartLitePolledExample(UARTLITE_0);
	if (Status != XST_SUCCESS) {
		xil_printf("Uartlite polled Example Failed\r\n");
	}
	xil_printf("Successfully ran Uartlite polled Example\r\n");


	Status = UartLitePolledExample(UARTLITE_1);
	if (Status != XST_SUCCESS) {
		xil_printf("Uartlite polled Example Failed\r\n");
	}
	xil_printf("Successfully ran Uartlite polled Example\r\n");


	/*
	 * Run the Uart_PS polled example , specify the the Device ID that is
	 * generated in xparameters.h
	 */
	Status = UartPsPolledExample(PS_UART_1);
	if (Status != XST_SUCCESS) {
		xil_printf("UART Polled Mode Example Test Failed\r\n");
	}

	xil_printf("Successfully ran UART Polled Mode Example Test\r\n");


	 usleep(2000000);//delay
	 }

}


/****************************************************************************/
/**
* This function does a minimal test on the UartLite device and driver as a
* design example. The purpose of this function is to illustrate
* how to use the XUartLite component.
*
* This function sends data and expects to receive the data through the UartLite
* such that a  physical loopback must be done with the transmit and receive
* signals of the UartLite.
*
* This function polls the UartLite and does not require the use of interrupts.
*
* @param	DeviceId is the Device ID of the UartLite and is the
*		XPAR__DEVICE_ID value from xparameters.h.
*
* @return	XST_SUCCESS if successful, XST_FAILURE if unsuccessful.
*
*
* @note
*
* This function calls the UartLite driver functions in a blocking mode such that
* if the transmit data does not loopback to the receive, this function may
* not return.
*
****************************************************************************/
int UartLitePolledExample(u16 DeviceId)
{
	int Status;
	unsigned int SentCount;
	unsigned int ReceivedCount = 0;
	int Index;

	/*
	 * Initialize the UartLite driver so that it is ready to use.
	 */
	Status = XUartLite_Initialize(&UartLite, DeviceId);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*
	 * Perform a self-test to ensure that the hardware was built correctly.
	 */
	Status = XUartLite_SelfTest(&UartLite);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*
	 * Initialize the send buffer bytes with a pattern to send and the
	 * the receive buffer bytes to zero.
	 */
	for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
		SendBuffer[Index] = '0'+ Index;
		RecvBuffer[Index] = 0;
	}

	xil_printf("\n Print SendBuffer : %s \n",SendBuffer);
	xil_printf("\n Print RecvBuffer : %s \n",RecvBuffer);
	xil_printf("\n This is XPAR_UARTLITE : %d \n",DeviceId);
	/*
	 * Send the buffer through the UartLite waiting til the data can be sent
	 * (block), if the specified number of bytes was not sent successfully,
	 * then an error occurred.
	 */
	SentCount = XUartLite_Send(&UartLite, SendBuffer, TEST_BUFFER_SIZE);
	if (SentCount != TEST_BUFFER_SIZE) {
		return XST_FAILURE;
	}



	/*
	 * Receive the number of bytes which is transferred.
	 * Data may be received in fifo with some delay hence we continuously
	 * check the receive fifo for valid data and update the receive buffer
	 * accordingly.
	 */
	ReceivedCount = 0;
	while (ReceivedCount < TEST_BUFFER_SIZE) {
		ReceivedCount += XUartLite_Recv(&UartLite,
					   RecvBuffer + ReceivedCount,
					   TEST_BUFFER_SIZE - ReceivedCount);
	}

	/*
	 * Check the receive buffer data against the send buffer and verify the
	 * data was correctly received.
	 */
	for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
		xil_printf("\n Print RecvBuffer UARTLITE: %c \n",RecvBuffer[Index] );
		if (SendBuffer[Index] != RecvBuffer[Index]) {
			return XST_FAILURE;
		}
	}


	return XST_SUCCESS;
}



int UartPsPolledExample(u16 DeviceId)
{
	int Status;
	XUartPs_Config *Config;
	unsigned int SentCount;
	unsigned int ReceivedCount;
	u16 Index;
	u32 LoopCount = 0;

	/*
	 * Initialize the UART driver so that it's ready to use.
	 * Look up the configuration in the config table, then initialize it.
	 */
	Config = XUartPs_LookupConfig(DeviceId);
	if (NULL == Config) {
		return XST_FAILURE;
	}

	Status = XUartPs_CfgInitialize(&Uart_PS, Config, Config->BaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/* Check hardware build. */
	Status = XUartPs_SelfTest(&Uart_PS);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/* Use local loopback mode. */
	XUartPs_SetOperMode(&Uart_PS, XUARTPS_OPER_MODE_LOCAL_LOOP);

	/*
	 * Initialize the send buffer bytes with a pattern and zero out
	 * the receive buffer.
	 */
	for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
		SendBuffer[Index] = '0' + Index;
		RecvBuffer[Index] = 0;
	}

	xil_printf("\n Print SendBuffer : %s \n",SendBuffer);
	xil_printf("\n Print RecvBuffer : %s \n",RecvBuffer);
	xil_printf("\n This is UART : %d \n",DeviceId);

	/* Block sending the buffer. */
	SentCount = XUartPs_Send(&Uart_PS, SendBuffer, TEST_BUFFER_SIZE);
	if (SentCount != TEST_BUFFER_SIZE) {
		return XST_FAILURE;
	}

	/*
	 * Wait while the UART is sending the data so that we are guaranteed
	 * to get the data the 1st time we call receive, otherwise this function
	 * may enter receive before the data has arrived
	 */
	while (XUartPs_IsSending(&Uart_PS)) {
		LoopCount++;
	}

	/* Block receiving the buffer. */
	ReceivedCount = 0;
	while (ReceivedCount < TEST_BUFFER_SIZE) {
		ReceivedCount +=
			XUartPs_Recv(&Uart_PS, &RecvBuffer[ReceivedCount],
				      (TEST_BUFFER_SIZE - ReceivedCount));
	}

	/*
	 * Check the receive buffer against the send buffer and verify the
	 * data was correctly received
	 */
	for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
		xil_printf("\n Print RecvBuffer UART: %c \n",RecvBuffer[Index] );
		if (SendBuffer[Index] != RecvBuffer[Index]) {
			return XST_FAILURE;
		}
	}

	/* Restore to normal mode. */
	XUartPs_SetOperMode(&Uart_PS, XUARTPS_OPER_MODE_NORMAL);

	return XST_SUCCESS;
}

28. Right-click to build the project

build project

 

 

29. Connect a wire to pair UART communication

> IO0 (UARTLite 0 Rx) to  IO1 (UARTLite 1Tx),

> IO3 (UARTLite 1 Rx) to IO4 (UARTLite 1 Tx),

> IO6 (UART1_Rx_0) to IO7 (UART1_Tx_0),

 

Wiring

 

 

30. Right-click app_uartlite then select debug as >launch on hardware

result

 

 

31. Click play to see result in Vitis Serial Terminal

play result

 

 

32. Here result of UARTLITE 0

UARTlite0

 

32. Here result of UARTLITE 1

UART lite1

 

 

33. Here result of UART PS 1

UARTPS1

 

 

How to create boot image

 

1. Right-click app_uartlite then select Create Boot image

boot

 

 

2. use default file path then click Create Image

boot image

ประเภทเนื้อหาของ article
FPGA Development
Rating
Average: 4 (2 votes)