UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Explorer
Explorer
856 Views
Registered: ‎03-29-2017

KINTEX KC705:LWIP-Ethernetlite:recv_callback Function

Hi,

    Kintex KC705 receiving the 32-bit counter data from DAQ board and passing to PC through AXI-Ethernetlite, where data should be read in Hercules or Putty

 

Block diagram

BD_kintex.JPG

     

Can anyone Please tell me how to receive the 32-bit Counter data in ECHO file. How to modify the code to receive the 32-bit counter data.

 

I did some included Conversion Function for Hercercules. But It is not working Properly

 

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include "ar_rx.h"
#include "lwip/err.h"
#include "lwip/tcp.h"
#if defined (__arm__) || defined (__aarch64__)
#include "xil_printf.h"
#endif


char buf[32] = {0};
extern u32 DestinationBuffer[5];
int transfer_data() {
	return 0;
}
char *itoa(int val, int base){

 int i = 30;
for(; val && i ; --i, val /= base)
buf[i] = "0123456789abcdef"[val % base];
return &buf[i+1];
}
void print_app_header()
{
	xil_printf("\n\r\n\r-----lwIP TCP echo server ------\n\r");
	xil_printf("TCP packets sent to port 6001 will be echoed back\n\r");
}

err_t recv_callback(void *arg, struct tcp_pcb *tpcb,
                               struct pbuf *p, err_t err)
{
	int i,Status;
	Status=aurora_rx_main();
	//xil_printf("%d",DestinationBuffer);
	//u32 rx_fifo_data;

	for(i=0;i<5;i++)
     {
		xil_printf("%d,",DestinationBuffer[i]);
	}
	

	xil_printf("\n");
	    int base=10;
	    char *result={0};
	    char *result1={0};
	    char *result2={0};
	    char *result3={0};
	    char *result4={0};
	    result = itoa(DestinationBuffer[0],base);
	    result1 = itoa(DestinationBuffer[1],base);
	    result2 = itoa(DestinationBuffer[2],base);
	    result3 = itoa(DestinationBuffer[3],base);
	    result4 = itoa(DestinationBuffer[4],base);
	  

	/* do not read the packet if we are not in ESTABLISHED state */
	if (!p) {
		tcp_close(tpcb);
		tcp_recv(tpcb, NULL);
		return ERR_OK;
	}

	/* indicate that the packet has been received */
	tcp_recved(tpcb, p->len);

	/* echo back the payload */
	/* in this case, we assume that the payload is < TCP_SND_BUF */
	if (tcp_sndbuf(tpcb) > p->len) {
		//err = tcp_write(tpcb, p->payload, p->len, 1);
//
		//xil_printf("%s %s",result[0],result[1]);
		err = tcp_write(tpcb,result,2,1);
		err = tcp_write(tpcb,result1,8,1);
		err = tcp_write(tpcb,result2,6,1);
		err = tcp_write(tpcb,result3,2,1);
		err = tcp_write(tpcb,result4,2,1);
	//aurora_rx_main();
	//xil_printf("%c",ascii[0]);




	} else
		xil_printf("no space in tcp_sndbuf\n\r");

	/* free the received pbuf */
	pbuf_free(p);

	return ERR_OK;
}

err_t accept_callback(void *arg, struct tcp_pcb *newpcb, err_t err)
{
	static int connection = 1;

	/* set the receive callback for this connection */
	tcp_recv(newpcb, recv_callback);

	/* just use an integer number indicating the connection id as the
	   callback argument */
	tcp_arg(newpcb, (void*)connection);

	/* increment for subsequent accepted connections */
	connection++;

	return ERR_OK;
}


int start_application()
{
	struct tcp_pcb *pcb;
	err_t err;
	unsigned port = 7;

	/* create new TCP PCB structure */
	pcb = tcp_new();
	if (!pcb) {
		xil_printf("Error creating PCB. Out of Memory\n\r");
		return -1;
	}

	/* bind to specified @port */
	err = tcp_bind(pcb, IP_ADDR_ANY, port);
	if (err != ERR_OK) {
		xil_printf("Unable to bind to port %d: err = %d\n\r", port, err);
		return -2;
	}

	/* we do not need any arguments to callback functions */
	tcp_arg(pcb, NULL);

	/* listen for connections */
	pcb = tcp_listen(pcb);
	if (!pcb) {
		xil_printf("Out of memory while tcp_listen\n\r");
		return -3;
	}

	/* specify callback to use for incoming connections */
	tcp_accept(pcb, accept_callback);

	xil_printf("TCP echo server started @ port %d\n\r", port);

	return 0;
}

 

//////////////////////////RX code /////////////////////////////

#include "xparameters.h"
#include "xil_exception.h"
#include "xstreamer.h"
#include "xil_cache.h"
#include "xllfifo.h"
#include "xstatus.h"
#include "xil_printf.h"
#include "ar_rx.h"



#undef DEBUG


XLlFifo FifoInstance;

int aurora_rx_main()
{
	u32 RxWord;
	int Status;
	//xil_printf("Entering RX loop\r\n");
	//while(1)
	{
	Status = XLlFiforx(&FifoInstance, FIFO_DEV_ID);
	if (Status != XST_SUCCESS)
		{
		xil_printf("Axi Streaming FIFO Test Failed\n\r");
		return XST_FAILURE;
		}

	xil_printf("Successfully ran Axi Streaming FIFO \n\r");
	}
	return XST_SUCCESS;

}

int XLlFiforx(XLlFifo *InstancePtr, u16 DeviceId)
{
	//xil_printf("######\n\r");
	XLlFifo_Config *Config;
	int Status,n=0;
	Status = XST_SUCCESS;

	/* Initialize the Device Configuration Interface driver */
	Config = XLlFfio_LookupConfig(DeviceId);
	if (!Config)
	{
		xil_printf("No config found for %d\r\n", DeviceId);
		return XST_FAILURE;
	}

	Status = XLlFifo_CfgInitialize(InstancePtr, Config, Config->BaseAddress);
	if (Status != XST_SUCCESS)
		{
		xil_printf("Initialization failed\n\r");
		return Status;
		}

	while(n<10)
	{
	Status = RxReceive(InstancePtr, DestinationBuffer);

	if (Status != XST_SUCCESS)
				{
		xil_printf("Receiving data failed");
		return XST_FAILURE;
				}
	n++;
	}
	return Status;
}


int RxReceive (XLlFifo *InstancePtr, u32* DestinationAddr)
{

	int i;
	//int Status;
	u32 RxWord;
	static u32 ReceiveLength;

	ReceiveLength = (XLlFifo_iRxGetLen(InstancePtr))/WORD_SIZE;
	
	
	/* Start Receiving */
	if(ReceiveLength>0)
	{
		//xil_printf("@@@@@@@@@ ");

	for ( i=0; i < ReceiveLength; i++)
	{
		RxWord = 0;
		RxWord = XLlFifo_RxGetWord(InstancePtr);

		
		*(DestinationAddr+i) = RxWord;
		//*(DestinationAddr+i) = 10;
		xil_printf("received data : %d\n\r",*(DestinationAddr+i));

	}

	}


return XST_SUCCESS;
}
0 Kudos
8 Replies
Explorer
Explorer
832 Views
Registered: ‎03-29-2017

Re: KINTEX KC705:LWIP-Ethernetlite:recv_callback Function

 I have modified my code. I think now experts can answer to my question.

 

aurora_rx_main() // Functional call receiving the data from FIFO and passing that data to TCP. 

whether my design flow is right ? I need to read the array of integer values (counter data) in PC through Putty or Tera.

 

err_t recv_callback(void *arg, struct tcp_pcb *tpcb,
                               struct pbuf *p, err_t err)
{
	int i,Status;
	Status=aurora_rx_main();         ///FUNCTION CALL

	for(i=0;i<10;i++)
     {
		xil_printf("%d,",DestinationBuffer[i]);
	}

	if (!p) {
		tcp_close(tpcb);
		tcp_recv(tpcb, NULL);
		return ERR_OK;
	}

	/* indicate that the packet has been received */
	tcp_recved(tpcb, p->len);

	/* echo back the payload */
	/* in this case, we assume that the payload is < TCP_SND_BUF */
	if (tcp_sndbuf(tpcb) > 10) {
	err = tcp_write(tpcb, DestinationBuffer, 10, 1);


	} else
		xil_printf("no space in tcp_sndbuf\n\r");

	/* free the received pbuf */
	pbuf_free(p);

	return ERR_OK;
}

 

 

0 Kudos
Xilinx Employee
Xilinx Employee
815 Views
Registered: ‎10-30-2017

Re: KINTEX KC705:LWIP-Ethernetlite:recv_callback Function

Hi @thaus_015,

 

I just little confused about your question. where your counter is running? I assume the counter is running on PC, am I correct?

From where to where you have to send the data? I mean from PC to KC705 board or KC705 board to PC.

 

the recv_callback() function is called when ever the board receives data from the PC. if the counter data is coming from PC then the data is available in  p->payload variable. you can read the p->payload variable and then use it.

 

In case if you want  to write the data to the PC from the kc705 board then use the tcp_write() function.

 

Best Regards,
Srikanth
----------------------------------------------------------------------------------------------
Kindly note- Please mark the Answer as "Accept as solution" if information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented.

0 Kudos
Explorer
Explorer
803 Views
Registered: ‎03-29-2017

Re: KINTEX KC705:LWIP-Ethernetlite:recv_callback Function

Thanks for your response. Sorry for confusion. My goal is to write the data to the PC from the kc705 board.

 

Design Flow as follows as below

 

1. Counter data from Kintex DAQ board (Part Number : XC7k160tffg676-2) is passing to the KINTEX KC705 board through optical cable

2. KINTEX KC705 board Should pass the data to PC through LWIP Echo server.

 

I am stuck From KC705 to PC

 

int RxReceive (XLlFifo *InstancePtr, u32* DestinationAddr)
{

	int i;
	//int Status;
	u32 RxWord;
	static u32 ReceiveLength;

	ReceiveLength = (XLlFifo_iRxGetLen(InstancePtr))/WORD_SIZE;
	
	
	/* Start Receiving */
	if(ReceiveLength>0)
	{
		//xil_printf("@@@@@@@@@ ");

	for ( i=0; i < ReceiveLength; i++)
	{
		RxWord = 0;
		RxWord = XLlFifo_RxGetWord(InstancePtr);
	
		*(DestinationAddr+i) = RxWord;
		//*(DestinationAddr+i) = 10;
		xil_printf("received data : %d\n\r",*(DestinationAddr+i));
	}
	}

return XST_SUCCESS;
}

From above code, i am able to collect the data in KC705 and now i need to pass same data to TCP and read the data in PC.

 Now please suggest me what is procedure ? How to pass the received data from KC705 to PC, and I need to read the data in PC either in Tera or Putty.

 

Please response me. Thanks

0 Kudos
Explorer
Explorer
795 Views
Registered: ‎03-29-2017

Re: KINTEX KC705:LWIP-Ethernetlite:recv_callback Function

Hi,

 

I have edited Echo template code as per your suggestion through tcp_write function. Please conform me whether the below code is right ?

 

extern u32 DestinationBuffer[1024];   // Globally Declared : Counter Values are stored in destination buffer. Those values i am passing to tx_func. That function is called in recv_callback. 

extern void tx_func(struct tcp_pcb *tpcb)
{
int i,Status;
Status=aurora_rx_main();
for(i=0;i<1024;i++)
	 {
    xil_printf("%d,",DestinationBuffer[i]);
     }
	 
tcp_write(tpcb, DestinationBuffer, 1024, 0);
}

err_t recv_callback(void *arg, struct tcp_pcb *tpcb,
                               struct pbuf *p, err_t err)
{
	
	/* do not read the packet if we are not in ESTABLISHED state */
	if (!p) {
		tcp_close(tpcb);
		tcp_recv(tpcb, NULL);
		return ERR_OK;
	}

	/* indicate that the packet has been received */
	tcp_recved(tpcb, p->len);

	/* echo back the payload */
	/* in this case, we assume that the payload is < TCP_SND_BUF */
	tcp_recved(tpcb, p->len); 
	{
	
	tx_func(tcp_pcb)

	} else
		xil_printf("no space in tcp_sndbuf\n\r");

	/* free the received pbuf */
	pbuf_free(p);

	return ERR_OK;
}
0 Kudos
Xilinx Employee
Xilinx Employee
763 Views
Registered: ‎10-30-2017

Re: KINTEX KC705:LWIP-Ethernetlite:recv_callback Function

Hi @thaus_015,

 

once you received the data from the FIFO then load the complete data into the buffer and then use the tcp_write() function to send the data to the PC. 

tcp_write(tpcb, p->payload, p->len, 1);

 

Here instead of the p->payload user your buffer and p->len is the lenght of the buffer.

 

for example you stored the received data from the FIFO in a DestinationAddr register and length is ReceiveLength then you can send the data to PC by calling the below function.

 

tcp_write(tpcb, *DestinationAddr , ReceiveLength 1);

 

then the FIFO data that you received from the DAQ board will be sent to PC. 

 

Note: you are running the LWIP echo server example which means the KC705 board act as a Server and it need to connected to a slave before it sending anything over the ethernet (using tcp_write function). 

 

The modified application is expected to be work. but you need to send some data from the PC then only it will send the daq data to your PC.

 

Best Regards,
Srikanth
----------------------------------------------------------------------------------------------
Kindly note- Please mark the Answer as "Accept as solution" if information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented.

 

0 Kudos
Explorer
Explorer
756 Views
Registered: ‎03-29-2017

Re: KINTEX KC705:LWIP-Ethernetlite:recv_callback Function

Hi,

 

  Thanks for your response. As per your i have modified the code and run the program.

>>but you need to send some data from the PC then only it will send the daq data to your PC.

Yes, PC will send some data , and then KC will send the data to PC.

I am using Hercules to read the data, where in Hercules it accepts String.

 

So i am doing Integer to String Conversion.

 

char buf[32] = {0};
int transfer_data() {
	return 0;
}
char *itoa(int val, int base){

 int i = 30;
for(; val && i ; --i, val /= base)
buf[i] = "0123456789abcdef"[val % base];
return &buf[i+1];
}


err_t recv_callback(void *arg, struct tcp_pcb *tpcb,
                               struct pbuf *p, err_t err)
{
	int i,j,Status;
	Status=aurora_rx_main();         ///FUNCTION CALL

	for(i=0;i<10;i++)
     {
		xil_printf(" Data:%d,",DestinationBuffer[i]);
	}

	int base=10; // here 10 means decimal
  char *result={0};

  result= itoa(DestinationBuffer[0],base);

	if (!p) {
		tcp_close(tpcb);
		tcp_recv(tpcb, NULL);
		return ERR_OK;
	}

	/* indicate that the packet has been received */
	tcp_recved(tpcb, p->len);

	if (tcp_sndbuf(tpcb) > 10) {
		err = tcp_write(tpcb,result,10,1);

	} else
		xil_printf("no space in tcp_sndbuf\n\r");

	/* free the received pbuf */
	pbuf_free(p);

	return ERR_OK;
}

 

I am able to read single data from Destination Buffer in Hercules. Please suggest me how to make the LOOP of

result= itoa(DestinationBuffer[0],base);

 

Please find the Screenshot of result

XSDK.JPG

0 Kudos
Highlighted
Explorer
Explorer
753 Views
Registered: ‎03-29-2017

Re: KINTEX KC705:LWIP-Ethernetlite:recv_callback Function

Sorry, One more update actually i need to read the all data in Python Shell without using Hercules. Any suggestion.

 

Please response for my two previous posts.

0 Kudos
Explorer
Explorer
736 Views
Registered: ‎03-29-2017

Re: KINTEX KC705:LWIP-Ethernetlite:recv_callback Function

I am able to read the continuous DestinationBuffer data in Hercules using itoa function with some Junk characters. How to clear that Junk ?

 

Actual data flow should be Data:1050842703, Data:1050842704, Data:1050842705, Data:1050842706, Data:1050842707, Data:1050842708, Data:1050842709, Data:1050842710, Data:1050842711, Data:1050842712,

 

but I am able to read the data in Hercules but without any comma or else some Junk characters are printing with data

e105084270310508427041050842705105084270610508427071050842708.

 

char buf[64] = {0};
//extern u32 DestinationBuffer[10];
int transfer_data() {
	return 0;
}
char *itoa(int val, int base){

 int i = 62;
for(; val && i ; --i, val /= base)
buf[i] = "0123456789abcdef"[val % base];
return &buf[i+1];
}
void print_app_header()
{
	xil_printf("\n\r\n\r-----lwIP TCP echo server ------\n\r");
	xil_printf("TCP packets sent to port 6001 will be echoed back\n\r");
}


err_t recv_callback(void *arg, struct tcp_pcb *tpcb,
                               struct pbuf *p, err_t err)
{
	int i,j,Status;
	Status=aurora_rx_main();         ///FUNCTION CALL

	for(i=0;i<50;i++)
     {
		xil_printf(" Data:%d,",DestinationBuffer[i]);
	}

    int base=10; // here 10 means decimal
    char *result={0};

	if (!p) {
		tcp_close(tpcb);
		tcp_recv(tpcb, NULL);
		return ERR_OK;
	}

	/* indicate that the packet has been received */
	tcp_recved(tpcb, p->len);

	if (tcp_sndbuf(tpcb) > 50) {
		 for (j=0;j<=50;j++)
		    {
		    result= itoa(DestinationBuffer[j],base);
		     //err = tcp_write(tpcb,",",50,1);
		    err = tcp_write(tpcb,result,50,1);
		    }

	} else
		xil_printf("no space in tcp_sndbuf\n\r");

	/* free the received pbuf */
	pbuf_free(p);

	return ERR_OK;
}

Hercules ScreenShot

Error.JPG

0 Kudos