diff --git a/Vitis_Classic/NewInstrCalBoard/src/lwip_server.c b/Vitis_Classic/NewInstrCalBoard/src/lwip_server.c new file mode 100644 index 0000000..b178428 --- /dev/null +++ b/Vitis_Classic/NewInstrCalBoard/src/lwip_server.c @@ -0,0 +1,194 @@ +#include "lwip_server.h" + +int transfer_data() { + return 0; +} + +void print_app_header() +{ + xil_printf("[I] New ExtInstrument Calibration Board Zynq Controller lwip stack...\r\n"); + xil_printf("[I] Net: Hello World!\r\n"); +} + +int start_application() +{ + struct tcp_pcb *pcb; + err_t err; + unsigned port = 200; + + /* create new TCP PCB structure */ + pcb = tcp_new_ip_type(IPADDR_TYPE_ANY); + if (!pcb) { + xil_printf("[E] Error creating PCB. Out of Memory\n\r"); + return -1; + } + + /* bind to specified @port */ + err = tcp_bind(pcb, IP_ANY_TYPE, port); + if (err != ERR_OK) { + xil_printf("[E] 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("[I] NewExtInstCal Zynq server started @ port %d\n\r", port); + + return 0; +} + +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*)(UINTPTR)connection); + + /* increment for subsequent accepted connections */ + connection++; + + return ERR_OK; +} + +err_t recv_callback(void *arg, struct tcp_pcb *tpcb, + struct pbuf *p, err_t err) +{ + u32 Recv_Len; + char *Recv_Data; + u16 uCRC_Read_Dat; + u8 uCRC_Result[2]={0}; + u8 uSend_Data[20] = {0}; + u8 uCRC_Flag = 255; + + + /* 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); + + /* Here, we assume that the payload is < TCP_SND_BUF */ + if (tcp_sndbuf(tpcb) > p->len) { + + Recv_Len = p->len; + Recv_Data = (char*)malloc(sizeof(char)*Recv_Len); + memcpy(Recv_Data,p->payload,Recv_Len); + + //Start of CRC Check + uCRC_Read_Dat = do_crc_table(Recv_Data+6, Recv_Len-8); + + uCRC_Result[0] = (u8)uCRC_Read_Dat; + uCRC_Result[1] = (u8)(uCRC_Read_Dat>>8); + + if (!(Recv_Data[15]==uCRC_Result[1]&&Recv_Data[16]==uCRC_Result[0])) + { + xil_printf("[E] CRC Mismatch! Check communication!\r\n"); + uCRC_Flag = 255; + } + else + { + xil_printf("[D] CRC Match!\r\n"); + uCRC_Flag = 1; + } + //End of CRC Check + + //Start of SendBack Formation + uSend_Data[0] = 0x00; + uSend_Data[1] = Recv_Data[1]; + uSend_Data[2] = Recv_Data[2]; + uSend_Data[3] = Recv_Data[3]; + uSend_Data[4] = Recv_Data[4]; + uSend_Data[5] = Recv_Data[5]; + uSend_Data[6] = Recv_Data[6]; + uSend_Data[7] = Recv_Data[7]; + uSend_Data[8] = uCRC_Flag; + uSend_Data[9] = uCRC_Flag; + uSend_Data[10] = Recv_Data[15]; //Shouldn't We Re-calculate CRC? Why send back the old CRC? + uSend_Data[11] = Recv_Data[16]; //Same as above + //End of SendBack Formation + + //Matching Zynq Cal Instruction Header + if(Recv_Data[6] == 0x0E) + { + if (Recv_Data[7] == 0xA2) //Cal + { + switch (Recv_Data[14]) //By Judging Equipment to decide cal type + { + case 0x01: //DC Cal + { + u8 uCMD[DC_CMD_LEN] = {0}; + + uCMD[0] = Recv_Data[8]; + if (Recv_Data[9] < 3) + { + xil_printf("[E] DPS Single Force/Sense Not Support!\r\n"); + } + else + { + if (Recv_Data[9] == 0x03) //Select DPS + { + uCMD[1] = 0x2; + } + else if (Recv_Data[9] == 0x04)//Select PMU + { + uCMD[1] = 0x1; + } + else + { + xil_printf("[E] Device Not Support!\r\n"); + } + } + uCMD[2] = Recv_Data[10]; + uCMD[3] = Recv_Data[11]; + uCMD[4] = Recv_Data[12] + 1; + uCMD[5] = Recv_Data[13]; + + DC_Control(uCMD); + + break; + } + case 0x02: //Freq Cal + { + u8 uCMD[Freq_CMD_LEN] = {Recv_Data[8],Recv_Data[9],Recv_Data[10],Recv_Data[11],Recv_Data[12],Recv_Data[13],Recv_Data[14]}; + sw_config(uCMD); + break; + } + + default: //You shouldn't be here + break; + } + } + + } + + tcp_write(tpcb, uSend_Data, sizeof(uSend_Data), 1); + } + else + { + xil_printf("no space in tcp_sndbuf\n\r"); + } + /* free the received pbuf */ + pbuf_free(p); + + return ERR_OK; + +} \ No newline at end of file diff --git a/Vitis_Classic/NewInstrCalBoard/src/lwip_server.h b/Vitis_Classic/NewInstrCalBoard/src/lwip_server.h new file mode 100644 index 0000000..e8b73ae --- /dev/null +++ b/Vitis_Classic/NewInstrCalBoard/src/lwip_server.h @@ -0,0 +1,29 @@ +#ifndef SRC_LWIP_SERVER_H_ +#define SRC_LWIP_SERVER_H_ + +#include +#include +#include "xstatus.h" +#include "xgpiops.h" + +#include "lwip/err.h" +#include "lwip/tcp.h" +#if defined (__arm__) || defined (__aarch64__) +#include "xil_printf.h" +#endif + +#include "cal_meas.h" + +int transfer_data(); + +void print_app_header(); + +int start_application(); + +err_t accept_callback(void *arg, struct tcp_pcb *newpcb, err_t err); + +err_t recv_callback(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err); + +err_t accept_callback(void *arg, struct tcp_pcb *newpcb, err_t err); + +#endif \ No newline at end of file diff --git a/Vitis_Classic/NewInstrCalBoard/src/main.c b/Vitis_Classic/NewInstrCalBoard/src/main.c index d27eaa1..218e8c0 100644 --- a/Vitis_Classic/NewInstrCalBoard/src/main.c +++ b/Vitis_Classic/NewInstrCalBoard/src/main.c @@ -35,20 +35,146 @@ #endif #include "xil_cache.h" +#include "lwip/tcp.h" +extern void tcp_tmr(void); /* declared in tcp_priv.h, not in public tcp.h */ +#include "xil_cache.h" + +#if LWIP_DHCP==1 + #include "lwip/dhcp.h" +#endif #include "GPIO_Driv.h" #include "SPI_Driv.h" #include "cal_meas.h" #include "uart_IO.h" +#include "lwip_server.h" u8 recvbuffer[1024] = {0}; -int main() +/* defined by each RAW mode application */ +void print_app_header(); +int start_application(); +int transfer_data(); + +/* missing declaration in lwIP */ +void lwip_init(); + +#if LWIP_IPV6==0 + #if LWIP_DHCP==1 + volatile int dhcp_timoutcntr; + err_t dhcp_start(struct netif *netif); + #endif +#endif + +static struct netif server_netif; +struct netif *echo_netif; + +void print_ip(char *msg, ip_addr_t *ip) +{ + print(msg); + xil_printf("%d.%d.%d.%d\n\r", ip4_addr1(ip), ip4_addr2(ip), + ip4_addr3(ip), ip4_addr4(ip)); +} + +void print_ip_settings(ip_addr_t *ip, ip_addr_t *mask, ip_addr_t *gw) { - init_platform(); + print_ip("Board IP: ", ip); + print_ip("Netmask : ", mask); + print_ip("Gateway : ", gw); +} - xil_printf("=====================\r\n[I] System Init Done!\r\n"); +static int net_is_available(void) +{ + if (echo_netif == NULL) + return 0; + if (!netif_is_up(echo_netif)) + return 0; + if (echo_netif->ip_addr.addr == 0) + return 0; + return 1; +} + +int main() +{ + int iMainCom = 1; + ip_addr_t ipaddr, netmask, gw; + unsigned char mac_ethernet_address[] = { 0x00, 0x0a, 0x35, 0x00, 0x01, 0x01 }; + + echo_netif = &server_netif; + + init_platform(); +#if LWIP_IPV6==0 + #if LWIP_DHCP==1 + ipaddr.addr = 0; + gw.addr = 0; + netmask.addr = 0; + #else + /* initialize IP addresses to be used */ + IP4_ADDR(&ipaddr, 192, 168, 100, 110); + IP4_ADDR(&netmask, 255, 255, 255, 0); + IP4_ADDR(&gw, 192, 168, 100, 1); + #endif +#endif + +//LWIP Related Init Start + lwip_init(); + + if (!xemac_add(echo_netif, &ipaddr, &netmask, + &gw, mac_ethernet_address, + PLATFORM_EMAC_BASEADDR)) + { + xil_printf("Error adding N/W interface\n\r"); + return -1; + } + + netif_set_default(echo_netif); + + /* specify that the network if is up */ + netif_set_up(echo_netif); + +#if (LWIP_DHCP==1) + /* Create a new DHCP client for this interface. + * Note: you must call dhcp_fine_tmr() and dhcp_coarse_tmr() at + * the predefined regular intervals after starting the client. + */ + dhcp_start(echo_netif); + dhcp_timoutcntr = 24; + + while(((echo_netif->ip_addr.addr) == 0) && (dhcp_timoutcntr > 0)) + xemacif_input(echo_netif); + + if (dhcp_timoutcntr <= 0) { + if ((echo_netif->ip_addr.addr) == 0) { + xil_printf("DHCP Timeout\r\n"); + xil_printf("Configuring default IP of 192.168.100.110\r\n"); + IP4_ADDR(&(echo_netif->ip_addr), 192, 168, 100, 110); + IP4_ADDR(&(echo_netif->netmask), 255, 255, 255, 0); + IP4_ADDR(&(echo_netif->gw), 192, 168, 100, 1); + } + } + + ipaddr.addr = echo_netif->ip_addr.addr; + gw.addr = echo_netif->gw.addr; + netmask.addr = echo_netif->netmask.addr; +#endif + + print_ip_settings(&ipaddr, &netmask, &gw); + + /* start the application (web server, rxtest, txtest, etc..) */ + start_application(); + +//LWIP Related Init END + + /* Check if network is actually available, fallback to UART if not */ + if (!net_is_available()) { + xil_printf("[W] Network unavailable, falling back to UART\r\n"); + iMainCom = 0; + } + + xil_printf("=====================\r\n[I] System Init Done!=====================\r\n"); + + xil_printf("[D] Start EMIO Config\r\n"); EMIO_config(); @@ -65,21 +191,34 @@ int main() interface_initial(CPLD_U2); interface_initial(CPLD_U3); - xil_printf("[I] Board Init Complete!\r\n[I] Waiting for Command...\r\n"); + xil_printf("\r\n=====================[I] Board Init Complete!\r\n=====================[I] Waiting for Command...\r\n"); + /* receive and process Instructions */ - while (1) + if (iMainCom == 1) { - int Status = -255; - Status = UART_RecvInstr(recvbuffer); - if (Status < 0) - { - xil_printf("[E] UART Receive ERROR!!! Check PrintOut Ahead\r\n"); + print_app_header(); + while (1) { + tcp_tmr(); + xemacif_input(echo_netif); + transfer_data(); } - else if (Status > 0) + } + else + { + while (1) { - Command_Parser(recvbuffer,Status); //Here Status should equal to length + int Status = -255; + Status = UART_RecvInstr(recvbuffer); + if (Status < 0) + { + xil_printf("[E] UART Receive ERROR!!! Check PrintOut Ahead\r\n"); + } + else if (Status > 0) + { + Command_Parser(recvbuffer,Status); //Here Status should equal to length + } + } - } /* never reached */ @@ -87,4 +226,3 @@ int main() return 0; } -