W5100 Listen issue

Hi,
I am trying to setup my W5100 module in server mode. I have done the necessary settings, like configuring the GAR, SHAR etc).
I am able to ping the W5100 and after the OPEN command the socket status register’s value is 0x13.
But I am not able to set the listen command.
After executing the listen command the socket status register does not give 0x14.
The status of my Link Leds are
Green Led = Constant ON with no blinking.
Orange Led = blinking

Please let me know what cound be the issue.

Thanks!!!

1 Like

Hi, Omer.

I want to know your code.

Please, post code.

How to set mode register, command and etc.

And I recommend to use reference code at WIZnet.

Best regards.

Hi,
I have attached the code files.
Please review them and let me know what I am missing.
I have done the following configurations:

  1. RTR = 6000
  2. RCR = 3
  3. GAR = 192.168.0.2
  4. SUBR = 255.255.255.0
  5. SHAR = 00:16:36:DE:58:F6 (This is just an dummy mac I am using)
  6. SIPR = 192.168.0.48
  7. SysInt(0x55, 0x55). This sets 2kB for each socket of Tx and Rx.
  8. IMR = 0x01
  9. S0_MR = 0x01
  10. S0_PORT0 = 502

Thanks!!!
wiznet_tcp.c (10.8 KB)
wiznet.h (11.3 KB)
wiznet.c (43.2 KB)

Hi, Omer.

I think your code is correct.

So, I want to know your main functions.

And I found strange code.

uint8_t listen(SOCKET s) { uint8_t ucharStatus; ucharStatus = getSn_SR(0); if (ucharStatus == SOCK_INIT) { write_wiznet_reg(Sn_CR(s),Sn_CR_LISTEN); /* wait to process the command... */ while( read_wiznet_reg(Sn_CR(s)) ); /* ------- */ ucharStatus = getSn_SR(0); if(ucharStatus == SOCK_LISTEN) { ucharStatus = 0; } else { close(s); ucharStatus = 1; } } else { close(s); ucharStatus = 1; } return ucharStatus; }

You use socket number together ‘0’ and ‘s’.
So, please check whether it causes problem.

Best regards.

Hi,

I recommand as follows.

int8_t listen(SOCKET s)
{
    if ((getSn_MR(s) & Sn_MR_TCP) && (geSn_SR(s) == SOCK_INIT))
    {
        write_wiznet_reg(Sn_CR(s),Sn_CR_LISTEN);
        while( read_wiznet_reg(Sn_CR(s)) );
       /* wait until sock_listen */
        while(getSn_SR(s) != SOCK_LISTEN)
        {
              ; // It Maybe blocked. check during your tolerence time */
        }
        return s;   
    }
    return -1;  // Failed
}

Hi,
I am calling the below function from main:

uint32_t initWiznet(void)
{
//unsigned char MAC_ADDR[6];
uint8_t status = 0x01;

/* Power the wiznet chip /
GPIO_PinOutSet (gpioPortC, 1);
Delay_ms(1);
/
Reset the wiznet chip */
ASSERT_WIZNET_RESET();
Delay_ms(1);
init_usart0_for_wiznet();
DEASSERT_WIZNET_RESET();

setRTR(6000); /* Retry time = 600 ms*/
Delay_ms(1);
setRCR(3); /* Retry count = 3 /
Delay_ms(1);
//setIMR(0x00); /
Interrupt mask */

setGAR(); /* Gateway IP address /
Delay_ms(1);
setSUBR(); /
Subnet mask /
Delay_ms(1);
setSHAR(); /
MAC address /
Delay_ms(1);
setSIPR(); /
Source IP address */
Delay_ms(1);

SysInit(0x55, 0x55); /* TX = 8kB, RX = 8 kB /
Delay_ms(1);
setIMR(IR_SOCK(0)); /
Enable the socket 0 interrupt */
Delay_ms(1);

/* Configure the EFM32 for external interrupt from Wiznet chip */
NVIC_ClearPendingIRQ(GPIO_ODD_IRQn);
NVIC_EnableIRQ(GPIO_ODD_IRQn);

/* Configure PE13 as input /
GPIO_PinModeSet(gpioPortE, 13, gpioModeInput, 1);
/
Set falling edge interrupt */
GPIO_IntConfig(gpioPortE, 13, false, true, true);

write_wiznet_reg(Sn_IR(0), 0xff);

/* Open the socket for server mode /
temp = 1;
/
The below code is for testing purpose only

  • It checks if :listen command is properly set.
  • Else it loops forever.
    /
    while( temp)
    {
    socket(0, Sn_MR_TCP, 80, 0x00);
    temp = getSn_SR(0);
    temp = listen(0);
    }
    /
    Refer to GPIO_ODD_IRQHandler() for further packet processing
  • Once connection has been establised, TCP packet processing
  • will be carried out based on external interrupt on PE13
    */
    return status;

}

I am trying to connect to socket 0.

Hi,
If my code looks Ok, then how can I debug this issues?
Do I need to check something on my desktop side?
If yes then how?
Are there any tools which can help in debugging this issues?

Hi, Omer.

I wonder one point.
If your MCU is so fast, listen command could be done before SOCK_INIT status changed.

SOCK_CLOSED ------changing -------> SOCK_INIT
|
(listen command here)

So, I recommend to use case(1) or debug with changing return value(2).

switch(getSn_SR(s)) // check SOCKET status { // ------------ case SOCK_ESTABLISHED: // ESTABLISHED? if(getSn_IR(s) & Sn_IR_CON) // check Sn_IR_CON bit { printf("%d : Connect OK\r\n",s); setSn_IR(s,Sn_IR_CON); // clear Sn_IR_CON } if((len=getSn_RX_RSR(s)) > 0) // check the size of received data { len = recv(s,buf,len); // recv if(len !=send(s,buf,len)) // send { printf("%d : Send Fail.len=%d\r\n",s,len); } } break; // --------------- case SOCK_CLOSE_WAIT: // PASSIVE CLOSED disconnect(s); // disconnect break; // -------------- case SOCK_CLOSED: // CLOSED close(s); // close the SOCKET socket(s,Sn_MR_TCP,port,mode); // open the SOCKET break; // ------------------------------ case SOCK_INIT: // The SOCKET opened with TCP mode listen(s); // listen to any connection request from "TCP CLIENT" printf("%d : LOOPBACK_TCPS(%d) Started.\r\n",s,port); break; default: break; }

i.e. check status is SOCK_INIT then command listen.

  1. In your while, return value is always 1 if listen is failed. So change return value and then debug what is problem, status is not SOCK_INIT or status is SOCK_INIT but listen command is failed.

Try and then reply again please.

Best regards.

Hi,
I don’t know why you use in ISR routine for receiving data.
Normally, ISR is the faster, the better.

Anyway, You’d better modify your code - reset delay and while(temp) statement block .
I recommend that…

uint32_t initWiznet(void)
{
 //unsigned char MAC_ADDR[6];
 uint8_t status = 0x01;

 /* Power the wiznet chip */
 GPIO_PinOutSet (gpioPortC, 1);
 Delay_ms(1);
 /* Reset the wiznet chip */
 ASSERT_WIZNET_RESET();
 Delay_ms(1);
 
 init_usart0_for_wiznet();
 DEASSERT_WIZNET_RESET();

 Delay_ms(10); //<-- Reset time is over 10ms. Inserted by M.C

 setRTR(6000); /* Retry time = 600 ms*/
 //Delay_ms(1);     // No needed
 setRCR(3); /* Retry count = 3 */
 //Delay_ms(1);    // No needed
 //setIMR(0x00); /* Interrupt mask */

 setGAR(); /* Gateway IP address */
 //Delay_ms(1);    // No needed
 setSUBR(); /* Subnet mask */
 //Delay_ms(1);    // No needed
 setSHAR(); /* MAC address */
 //Delay_ms(1);    // No needed
 setSIPR(); /* Source IP address */ 
 //Delay_ms(1);    // No needed

 SysInit(0x55, 0x55); /* TX = 8kB, RX = 8 kB */
 //Delay_ms(1);    // No needed
 setIMR(IR_SOCK(0)); /* Enable the socket 0 interrupt */
 //Delay_ms(1);    // No needed

 /* Configure the EFM32 for external interrupt from Wiznet chip */
 NVIC_ClearPendingIRQ(GPIO_ODD_IRQn);
 NVIC_EnableIRQ(GPIO_ODD_IRQn);

 /* Configure PE13 as input */
 GPIO_PinModeSet(gpioPortE, 13, gpioModeInput, 1);
 /* Set falling edge interrupt */
 GPIO_IntConfig(gpioPortE, 13, false, true, true);

 write_wiznet_reg(Sn_IR(0), 0xff);

 /* Open the socket for server mode */
 temp = 1;
 /* The below code is for testing purpose only 
 * It checks if :listen command is properly set.
 * Else it loops forever.
 */
 while(temp)
 {
   temp = getSn_SR(0);
   switch(temp)
   {
     case SOCK_ESTABLISHED:
        // printf("socket connected!!!");
        // check S0_IR(CONNECTED) = '1'
        // check S0_IR(RECV) or getSn_RX_RSR(0) > 0
        // If yes, receive data
       break;
     case SOCK_LISTEN:
       // wait for connection
       break;
     case SOCK_INIT:
       listen(0);
       break;
     case SOCK_CLOSE_WAIT:
       // check S0_IR(RECV) or getSn_RX_RSR(0) > 0)
       // if yes, receive data
       // close 0 socket ( close(0) or disconnect(0) )
       break;
     case SOCK_CLOSED:
       socket(0, Sn_MR_TCP, 80, 0x00);
       break;
     default:
       break;
   }
 } 
 /* Refer to GPIO_ODD_IRQHandler() for further packet processing
 * Once connection has been establised, TCP packet processing 
 * will be carried out based on external interrupt on PE13
 */
 return status;
}

Hi,
Thanks for your replies.
The issues did seem to be with the delay.
I added delay in the wiznet read function and made it same like the wiznet write function.
The issue is resolved now.
Thanks once again for your help!

I’m glad to hear your good news.
Thanks.

Hi Omer,

At the moment I am running into exactly the same issue with the W5100. I understand you solved it with a delay in the read function? I do not understand where that is since the W5100 first has to go into LISTEN mode before anything can be read…

Can you explain that?

Thanks,

Tjerk

In the example above, a delay of 10ms was added after the chip reset.