This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

I use LwIP to send the data collected by ad9361 and adc_capture (2048, ADC_DDR_BASEADDR).

I use LwIP to send the data collected by ad9361 and adc_capture (2048, ADC_DDR_BASEADDR). The data captured are listed in the following instructions:

err = tcp_write(tpcb, ADC_DDR_BASEADDR, SEND_SIZE, 3);
if (err != ERR_OK) {
xil_printf("txperf: Error on tcp_write: %d\r\n", err);
connected_pcb = NULL;
return;
}
err = tcp_output(tpcb);
if (err != ERR_OK) {
xil_printf("txperf: Error on tcp_output: %d\r\n",err);
return;

The SEND_SIZE in tcp_write should represent the length of the transmitted data, which can be sent normally when the length is 12 short data. When the number is set to 2048, only the first data is received at the receiving end.




[locked by: aardelean at 7:49 AM (GMT 0) on 23 May 2019]
Parents
  • 0
    •  Analog Employees 
    on Apr 10, 2019 7:29 AM over 1 year ago

    Can you post the entire code of this file ?

    Just by looking at this snippet it's hard to tell what's happening.

  • * @file main.c

    #include "config.h"

    ......
    #include "lwip/err.h"
    #include "lwip/tcp.h"
    #include "lwipopts.h"
    #include "netif/xadapter.h"

    ......

    ......

    AD9361_InitParam default_init_param =

    ......

    ......

    int main(void)
    {
    //int i;
    //int rev;
    int32_t i;
    int32_t rdata;
    int16_t sampI, sampQ;
    int Status;
    struct netif *netif, server_netif;
    struct ip_addr ipaddr, netmask, gw;
    unsigned char mac_ethernet_address[] = { 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };


    #ifdef XILINX_PLATFORM
    Xil_ICacheEnable();
    Xil_DCacheEnable();
    #endif

    ......

    ......

    System_Init();
    netif = &server_netif;

    IP4_ADDR(&ipaddr, 192, 168, 1, 10);
    IP4_ADDR(&netmask, 255, 255, 255, 0);
    IP4_ADDR(&gw, 192, 168, 1, 1);

    /*lwip library init*/
    lwip_init();
    /* Add network interface to the netif_list, and set it as default */
    if (!xemac_add(netif, &ipaddr, &netmask, &gw, mac_ethernet_address, XPAR_XEMACPS_0_BASEADDR)) {
    xil_printf("Error adding N/W interface\r\n");
    return -1;
    }


    netif_set_default(netif);

    /* specify that the network if is up */
    netif_set_up(netif);

    /* initialize tcp pcb */
    tcp_send_init();

    while(1) {
    /* call tcp timer every 250ms */
    if(TcpTmrFlag)
    {
    tcp_tmr();
    TcpTmrFlag = 0;
    }
    xemacif_input(netif);
    if (tcp_client_connected) { 
    sleep(1);
    send_data();
    xil_printf("tran_cnt:%d\n\r", tcp_trans_cnt);
    }
    }

    printf("Done.\n");

    ......

    ......

    }

    #include "user_tcp.h"
    #include "parameters.h"
    #define SEND_SIZE 1024  //#define SEND_SIZE 12

    static struct tcp_pcb *connected_pcb = NULL;
    volatile unsigned tcp_client_connected = 0;
    int tcp_trans_cnt = 0;

    static err_t tcp_sent_callback(void *arg, struct tcp_pcb *tpcb, u16_t len)
    {
    tcp_trans_cnt++;
    xil_printf("send int");
    return ERR_OK;
    }


    static err_t tcp_connected_callback(void *arg, struct tcp_pcb *tpcb, err_t err)
    {
    xil_printf("txperf: Connected to iperf server\r\n");

    connected_pcb = tpcb;

    tcp_nagle_disable(connected_pcb);
    tcp_arg(tpcb, NULL);
    tcp_sent(tpcb, tcp_sent_callback);

    tcp_client_connected = 1;
    xil_printf("Connect Success.\r\n");
    return ERR_OK;
    }

    int tcp_send_init()
    {
    struct tcp_pcb *pcb;
    struct ip_addr ipaddr;
    err_t err;
    u16_t port;

    pcb = tcp_new();
    if (!pcb) {
    xil_printf("txperf: Error creating PCB. Out of Memory\r\n");
    return -1;
    }

    IP4_ADDR(&ipaddr, 192, 168, 1, 100);
    port = 7;
    tcp_client_connected = 0;


    err = tcp_connect(pcb, &ipaddr, port, tcp_connected_callback);
    if (err != ERR_OK) {
    xil_printf("txperf: tcp_connect returned error: %d\r\n", err);
    return err;
    }
    xil_printf("%d\r\n",err);

    return 0;
    }

    void send_data(void)
    {
    int32_t j;
    int32_t r_data;
    int16_t samp_I, samp_Q;
    err_t err;
    struct tcp_pcb *tpcb = connected_pcb;

    if (!connected_pcb)
    return;

    mdelay(1000);
    adc_capture(2048, ADC_DDR_BASEADDR);
    Xil_DCacheInvalidateRange(ADC_DDR_BASEADDR, 2048);

    if (tcp_sndbuf(tpcb) > SEND_SIZE)
    {
    err = tcp_write(tpcb, ADC_DDR_BASEADDR, SEND_SIZE, 3);
    if (err != ERR_OK) {
    xil_printf("txperf: Error on tcp_write: %d\r\n", err);
    connected_pcb = NULL;
    return;
    }
    err = tcp_output(tpcb);
    if (err != ERR_OK) {
    xil_printf("txperf: Error on tcp_output: %d\r\n",err);
    return;
    }
    }
    }

  • 0
    •  Analog Employees 
    on Apr 10, 2019 8:38 AM over 1 year ago in reply to xzx

    So, this is not good.

    You're capturing 2048 bytes of data and sending only 1024 bytes.

    You're also sending data only if ` if (tcp_sndbuf(tpcb) > SEND_SIZE)`  which means that the data can be overwritten by the adc_capture() capture.

    These are just 2 places where you lose data.

    Not sure if I missed other places.

    One "issue" which may not be an issue (depending on how you structure your logic) is that you are doing adc_capture(2048, ADC_DDR_BASEADDR);  and then doing tcp_write() from the same address.

    Ideally, you should use a temporary buffer, where you store data from the ADC, and send it when `if (tcp_sndbuf(tpcb) > SEND_SIZE)`

    Thanks

    Alex

Reply
  • 0
    •  Analog Employees 
    on Apr 10, 2019 8:38 AM over 1 year ago in reply to xzx

    So, this is not good.

    You're capturing 2048 bytes of data and sending only 1024 bytes.

    You're also sending data only if ` if (tcp_sndbuf(tpcb) > SEND_SIZE)`  which means that the data can be overwritten by the adc_capture() capture.

    These are just 2 places where you lose data.

    Not sure if I missed other places.

    One "issue" which may not be an issue (depending on how you structure your logic) is that you are doing adc_capture(2048, ADC_DDR_BASEADDR);  and then doing tcp_write() from the same address.

    Ideally, you should use a temporary buffer, where you store data from the ADC, and send it when `if (tcp_sndbuf(tpcb) > SEND_SIZE)`

    Thanks

    Alex

Children
  • Sorry, maybe I didn't make it clear.

    The problem I encounter in data transmission now is that when the data is transferred to a certain size, the TCP_Server terminal will not receive the data. (Each time is different, usually in the range of 1500 to 2000). Whether the data is adc_capture or not, I have tried to transmit "HELLO WORLD". Whenever I reach this interval, this problem will occur and the terminal will not receive the data.

  • +1
    •  Analog Employees 
    on Apr 15, 2019 7:34 AM over 1 year ago in reply to xzx

    The code you posted here is for the client.

    Did you also write the TCP server ?

    I would recommend using Wireshark to debug any issues of the network communication.

    https://www.wireshark.org/

    So, maybe run the TCP Server on the machine, and run Wireshark there, and see what happens.

    The issues [at this point in time] seem to be related with not writing the correct code for LwIP communication.

    This is true for the client code [which was posted earlier].

    This forum does not offer support for LwIP; it is for Analog Devices products.

    Is there an issue with the AD9361, chip or SW ?

    Thanks

    Alex