Ethernet Code Problem with Xilinx Spartan3E

I'm trying to get a Spartan3E FPGA to communicate with a PC. I'm using lwIP and Microblaze and have managed to get the FPGA to receive packets fine, but despite it appearing to bind and connect the socket for transmitting data, I don't receive any data. The code is below. Your help would be greatly appriciated.

Thanks, SC

/***************************** Include Files

*********************************/

/* Xilinx Includes */ #include "xstatus.h" // Required for status checks on peripheral functions #include "xgpio.h" // Required for GPIO peripherals #include "xmk.h"

/* C Library Includes */ #include "string.h" // Required for memset and strtok

/* lwIP Includes */ #include "netif/xemacif.h" #include "lwip/udp.h" #include "lwip/memp.h" #include "netif/etharp.h" #include "lwip/sys.h" #include "lwip/sockets.h"

// OPB Timer/Counter Device Driver #include "xtmrctr.h"

#include "Ethernet_10.h"

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

******************************/

extern XEmacIf_Config XEmacIf_ConfigTable[];

int numConnections;

int incoming_buffer_len;

int incoming_sock, outgoing_sock;

struct sockaddr_in incoming_udp, outgoing_udp;

XTmrCtr udp_transmitter_timer;

/ ***************************************************************************** *
  • This is the UDP Transmitter Application Thread
*
  • @param baseaddr_p is the Base Address of OPB_Timer_0
*
  • @return None
*
  • @note None
* ******************************************************************************/

void udp_transmitter_int_handler (void* arg) {

char writeBuffer[6]; xil_printf("Sending Data\r\n"); writeBuffer[0] = 'a'; writeBuffer[1] = 'b'; writeBuffer[2] = 'c'; writeBuffer[3] = 'd'; writeBuffer[4] = 'e'; writeBuffer[5] = 'f';

// write(outgoing_sock, "writeBuffer", 11); //hanging here // udp_send(outgoing_sock, "a"); //hanging here

// Resets the UDP Transmitter Timer to a start mode XTmrCtr_Reset(&udp_transmitter_timer, 0); }

/ ***************************************************************************** *
  • This is the Network Listener Application Thread
*
  • @param sd - Socket ID
*
  • @return None
*
  • @note None
* ******************************************************************************/

void* processConnection(struct sockaddr_in input, int connections) { // char receiveBuffer[6];//RECV_BUFFER_LENGTH]; // int sd = *((int*) arg); // int bytesReceived;

// Read the request data

xil_printf("Data : %s \r\n", &incoming_udp);

// xil_printf("Data Recieved: "); // xil_printf(&input); // xil_printf("\n\r"); // xil_printf("Connections: ");

// close(&input); numConnections--; }

/ ***************************************************************************** *
  • This is the UDP Application Thread, it generates and listens to udp traffic
*
  • @param sd - Socket ID
*
  • @return None
*
  • @note None
* ******************************************************************************/

void* udpAppThread(void* arg) { int i; int leds_disp; int switches_value; int size; int status; unsigned char mac_address[6]; unsigned char ip_address[4]; unsigned char gateway_addr[4]; unsigned char subnet[4]; struct ip_addr ipaddr, netmask, gateway; struct netif *server_netif; XEmacIf_Config *xemacif_ptr = &XEmacIf_ConfigTable[0]; XStatus udp_transmitter_initialized; Xuint32 udp_transmitter_status; XStatus register_setup_status;

// MAC Address = 00-00-00-00-22-31 memset(mac_address, 0, 6); mac_address[0] = 0x00; mac_address[1] = 0x00; mac_address[2] = 0x00; mac_address[3] = 0x00; mac_address[4] = 0x22; mac_address[5] = 0x31; xemacif_setmac(0, (u8_t *)mac_address);

// Netmask = 255.255.255.0 netmask.addr = htonl(0xffffff00);

// Gateway = 10.1.2.1 gateway.addr = htonl(0x0a010201);

// IP Address = 10.1.2.101 ipaddr.addr = htonl(0x0a010265);

// Set up the lwIP network interface // Allocate and configure the server's netif server_netif = mem_malloc(sizeof(struct netif)); if(server_netif == NULL) { xil_printf("ERROR: netif_add(): Out of memory for default netif \n\r"); return; } server_netif = netif_add(server_netif, &ipaddr, &netmask, &gateway, &XEmacIf_ConfigTable[0], xemacif_init, ip_input); netif_set_default(server_netif);

// Register the XEMAC interrupt handler with the controller and enable // interrupts within XMK register_int_handler(XPAR_OPB_INTC_0_ETHERNET_MAC_IP2INTC_IRPT_INTR, (XInterruptHandler)XEmac_IntrHandlerFifo, xemacif_ptr->instance_ptr);

enable_interrupt(XPAR_OPB_INTC_0_ETHERNET_MAC_IP2INTC_IRPT_INTR);

// Create and bind the socket. Because the MicroBlaze and PowerPC processors // are big-endian architectures, the calls to htons(), htonl(), etc. aren't // necessary, but are included for completeness and portability incoming_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); incoming_udp.sin_family = AF_INET; incoming_udp.sin_port = htons(VMS_PORT); incoming_udp.sin_addr.s_addr = INADDR_ANY; bind(incoming_sock, (struct sockaddr*)&incoming_udp, sizeof(struct sockaddr));

outgoing_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); outgoing_udp.sin_family = AF_INET; outgoing_udp.sin_port = htons(90); outgoing_udp.sin_addr.s_addr = htonl(0x0a010264); status = bind(outgoing_sock, (struct sockaddr*)&outgoing_udp, sizeof(struct sockaddr)); xil_printf("%d bind\r\n",status); status = connect(outgoing_sock, (struct sockaddr*)&outgoing_udp, sizeof(struct sockaddr)); xil_printf("%d connect\r\n",status);

xil_printf("Server initialization complete.\r\n");

// Begin listening on the socket. For all new connections, spawn a new // thread, processConnection(), to deal with them listen(incoming_sock, 20); numConnections = 0;

// Initializes opb_timer_0 as udp_transmitter_timer udp_transmitter_initialized = XTmrCtr_Initialize(&udp_transmitter_timer, XPAR_OPB_TIMER_0_DEVICE_ID);

if (udp_transmitter_initialized == XST_SUCCESS) { xil_printf("-- UDP Transmitter was initialized --\r\n"); } else { if (udp_transmitter_initialized == XST_DEVICE_IS_STARTED) { xil_printf("-- UDP Transmitter was already initialized --\r \n"); } else { xil_printf("-- UDP Transmitter was not found --\r\n"); } }

//Sets options for udp transmitter timer XTmrCtr_SetOptions(&udp_transmitter_timer, 0, // set the 0 timer in opb_timer_0 XTC_DOWN_COUNT_OPTION | // See page 3 on OPB Timer/Counter v1.00b in regards to count down XTC_INT_MODE_OPTION | // Enables the timer counter interrupt output. XTC_AUTO_RELOAD_OPTION); // And reload the "reset" value and begin counting again

// set timer on 1 second interval XTmrCtr_SetResetValue(&udp_transmitter_timer, 0, 50000000);

// Sets the UDP Transmitter Timer to a stop mode XTmrCtr_Stop(&udp_transmitter_timer, 0);

// timer_int_handler process will execute on opb_timer_0 interrupt register_setup_status = register_int_handler(XPAR_OPB_INTC_0_OPB_TIMER_0_INTERRUPT_INTR, udp_transmitter_int_handler, NULL); enable_interrupt(XPAR_OPB_INTC_0_OPB_TIMER_0_INTERRUPT_INTR);

if (register_setup_status == XST_SUCCESS) { xil_printf("-- Interrupt Successfully Created --\r\n"); } else { xil_printf("Interrupt Error : "); putnum(register_setup_status); xil_printf("\r\n"); }

// Sets the UDP Transmitter Timer to a start mode XTmrCtr_Start(&udp_transmitter_timer, 0);

while(1) { // Will wait at the line below till code is recieved. incoming_buffer_len = read(incoming_sock, (struct sockaddr

*)&incoming_udp, sizeof(struct sockaddr));

// Increases numConnections everyime new connection is read. // numConnections will decrease after connection is dropped numConnections++;

xil_printf("%d bytes of data \r\n", incoming_buffer_len); // Spawn a new thread to handle the data for the new connection sys_thread_new((void *)&processConnection, &incoming_sock, numConnections); } }

/ ***************************************************************************** *
  • This is the Top Level Application Thread. It will start all other
  • Application Threads.
*
  • @param None
*
  • @return None
*
  • @note None
* ******************************************************************************/

void serverThread (void* arg) {

// Initialize the lwIP library xil_printf("Initializing the lwIP library...\r\n"); lwip_init(); //mem_init(); //memp_init(); //pbuf_init(); //netif_init(); //udp_init();

// Sleep to allow lwIP initialization status messages to display // without interruption sleep(100); xil_printf("lwIP initialization done\n\r");

// Spawn the UDP communication application thread sys_thread_new((void *)&udpAppThread, 0, 0); xil_printf("udpAppThread Started\n\r"); }

int main (void) { // Launch XMK xilkernel_main();

return 0; }

Reply to
calkins
Loading thread data ...

You should try to use Ethereal to watch what really runs on ethernet.

formatting link
Vita

Reply to
vitek.vitek

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.