Not getting send interrupt


#1

Hi,
I have configured the W5100 to be used in SPI mode and interrupt mode.
I am able to connect to the W5100.
Send and receive data using Modpoll tool.
I have observed one issue though.
Even though I recieve an RECV interrupt I dont get an Send Ok interrupt.
But I get the necessary data on the Modpoll, but I dont recieve an send OK interrupt.

Are there any known issues with this?

Thanks!!


#2

Hi,

I wonder how to process send data and send command.
For completing to send data, Sn_IR_SEND_OK need to set.

In your send processing, Did you already clear Sn_IR_SEND_OK bit?

If possible, post your ISR routine, IR & Sn_ISR & IMR access function, and Send function codes.

Thank you.


#3

Hi,
Below is my send function, Most of my code is similar to the wiznet sample code except my application code:
uint16_t send(SOCKET s, const uint8_t* p_ucharDataBuf, uint16_t ushLen)
{
uint8_t ucharStatus=0;
uint16_t ushRet=0;
uint16_t ushFreeSize=0;
uint16_t ushtxrd_after_send;
uint16_t ushtxrd_before_send;

if (ushLen > getW5100_TxMAX(s)) 
{
    ushRet = getW5100_TxMAX(s); // check size not to exceed MAX size.
}
else
{
    ushRet = ushLen;
}

// if freebuf is available, start.
do
{
    ushFreeSize = getSn_TX_FSR(s);
    ucharStatus = read_wiznet_reg(Sn_SR(s));
    /* If client requested an disconnect */
    if(ucharStatus == SOCK_CLOSE_WAIT)
    {
        ushRet = getSn_RX_RSR(m_structTCPData.m_ucharCurrentSocket);
        recv(m_structTCPData.m_ucharCurrentSocket, m_aucharTCPRxBuf, ushRet);
        disconnectSocket(m_structTCPData.m_ucharCurrentSocket);
        return 0;
    }            
    else if (ucharStatus != SOCK_ESTABLISHED)
    {
        ushRet = 0;
        break;
    }
} while (ushFreeSize < ushRet);

// copy data
send_data_processing(s, (uint8_t *)p_ucharDataBuf, ushRet);
ushtxrd_before_send = read_wiznet_reg(Sn_TX_RD0(s));
ushtxrd_before_send = (ushtxrd_before_send << 8) + read_wiznet_reg(Sn_TX_RD0(s) + 1);
/* Issue the SEND command */
write_wiznet_reg(Sn_CR(s),Sn_CR_SEND);
Delay_ms(1);
/* wait to process the command... */
while( read_wiznet_reg(Sn_CR(s)) );

/* while ( (read_wiznet_reg(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
{
if ( read_wiznet_reg(Sn_SR(s)) == SOCK_CLOSED )
{
close(s);
return 0;
}
}*/
//write_wiznet_reg(Sn_IR(s), Sn_IR_SEND_OK);

ushtxrd_after_send = read_wiznet_reg(Sn_TX_RD0(s));
ushtxrd_after_send = (ushtxrd_after_send << 8) + read_wiznet_reg(Sn_TX_RD0(s) + 1);
if(ushtxrd_after_send > ushtxrd_before_send)
{
    ushRet = ushtxrd_after_send - ushtxrd_before_send;
} 
else
{
ushRet = (0xffff - ushtxrd_before_send) + ushtxrd_after_send + 1;
}

return ushRet;

}

My ISR processing function is below. This function is called from an ISR, it saves the interrupt type, clears the wiznet interrupt and sets an TCP_FLAG.

void processWiznetISR(void)
{
uint8_t ucharIRvalue;
uint8_t ucharSNIRvalue;
//uint8_t ucharIRvalue = getSn_IR(SOCKET_0);

    ucharIRvalue = getIR();

  /* process all interrupts */
  do 
  {   
      if (ucharIRvalue & IR_CONFLICT)
      {
          /*IP conflict */
          write_wiznet_reg(W5100_IR, 0xf0);           /* clear interrupt */
      }
      if (ucharIRvalue & IR_UNREACH)
      {
          /*INT Port Unreachable */
          write_wiznet_reg(W5100_IR, 0xf0);           /* clear interrupt */
      }

      /* clear interrupt */
      write_wiznet_reg(W5100_IR, 0xf0); 

      if (ucharIRvalue & IR_SOCK(SOCKET_0))
      {
          /* save interrupt value*/
          I_STATUS[SOCKET_0] |= read_wiznet_reg(Sn_IR(SOCKET_0)); // can be come to over two times.
          //processSocketCommand();
          write_wiznet_reg(Sn_IR(SOCKET_0), I_STATUS[SOCKET_0]);
          /* Clear the interrupt */
          //write_wiznet_reg(Sn_IR(SOCKET_0), 0xFF);
    }
    if (ucharIRvalue & IR_SOCK(1))
    {
        /* save interrupt value*/
        I_STATUS[1] |= read_wiznet_reg(Sn_IR(1));
        write_wiznet_reg(Sn_IR(1), I_STATUS[1]);
    }
    if (ucharIRvalue & IR_SOCK(2))
    {
        /* save interrupt value*/
        I_STATUS[2] |= read_wiznet_reg(Sn_IR(2));
        write_wiznet_reg(Sn_IR(2), I_STATUS[2]);
    }
    if (ucharIRvalue & IR_SOCK(3))
    {
        /* save interrupt value*/
        I_STATUS[3] |= read_wiznet_reg(Sn_IR(3));
        write_wiznet_reg(Sn_IR(3), I_STATUS[3]);
    }   
    /* re-read interrupt value*/
    ucharIRvalue = read_wiznet_reg(W5100_IR);
}while (ucharIRvalue != 0x00);           /* if exist, contiue to process */
TCP_FLAG = TRUE;
/* Clear the interrupt */

// write_wiznet_reg(Sn_IR(m_structTCPData.m_ucharCurrentSocket), 0xFF);
ucharIRvalue = read_wiznet_reg(W5100_IR);
ucharSNIRvalue = getSn_IR(0);
}

And below is my interrupt processing functions:

void processSocketCommand(void)
{
if(TCP_FLAG == TRUE)
{
if (I_STATUS[SOCKET_0] != 0)
{
/* save interrupt value*/
m_structTCPData.m_ucharCurrentSocket = SOCKET_0;
processTcpCommand(I_STATUS[SOCKET_0]);
//write_wiznet_reg(Sn_IR(0), I_STATUS[0]);
I_STATUS[SOCKET_0] = 0;
}
if (I_STATUS[SOCKET_1] != 0)
{
/* save interrupt value*/
m_structTCPData.m_ucharCurrentSocket = SOCKET_1;
processTcpCommand(I_STATUS[SOCKET_1]);
I_STATUS[SOCKET_1] = 0;
}
if (I_STATUS[SOCKET_2] != 0)
{
/* save interrupt value*/
m_structTCPData.m_ucharCurrentSocket = SOCKET_2;
processTcpCommand(I_STATUS[SOCKET_2]);
I_STATUS[SOCKET_2] = 0;
}
if (I_STATUS[SOCKET_3] != 0)
{
/* save interrupt value*/
m_structTCPData.m_ucharCurrentSocket = SOCKET_3;
processTcpCommand(I_STATUS[SOCKET_3]);
I_STATUS[SOCKET_3] = 0;
}
/* Clear the TCP_FLAG since all the interrupts have been processed /
TCP_FLAG = FALSE;
/
Clear the interrupt */
//write_wiznet_reg(Sn_IR(m_structTCPData.m_ucharCurrentSocket), 0xFF);
}
}
void processTcpCommand(uint8_t ucharSn_IR)
{
uint16_t ushlen = 3;
uint8_t status = 0x01;

ucharValue = getSn_SR(m_structTCPData.m_ucharCurrentSocket);
    
switch(ucharSn_IR)                
{                                   
    case Sn_IR_RECV:
        temp = 0;
        m_structTCPData.m_ucharBytesReceived = getSn_RX_RSR(m_structTCPData.m_ucharCurrentSocket);
        m_structTCPData.m_pucharRxDataLoc = m_aucharTCPRxBuf;
        /* Check if data is received */
        if (m_structTCPData.m_ucharBytesReceived > 0)
        {
            ushlen = recv(m_structTCPData.m_ucharCurrentSocket, m_aucharTCPRxBuf, m_structTCPData.m_ucharBytesReceived);
        }
        while(m_structTCPData.m_ucharBytesReceived > 0) // check the size of received data
        {               
            //ushlen = recv(m_structTCPData.m_ucharCurrentSocket, m_structTCPData.m_ucharTCPHeader, TCP_MODBUS_HEADER_LENGTH);
            /* Read the first 6 bytes of the frame */
            moveTCPRxData(m_structTCPData.m_pucharRxDataLoc,  m_structTCPData.m_ucharTCPHeader, TCP_MODBUS_HEADER_LENGTH);
            m_structTCPData.m_ucharBytesReceived -= TCP_MODBUS_HEADER_LENGTH;
            checkTCPProto();
        }
        break;
                                   
    case Sn_IR_SEND_OK:
        /* The send operation was sucessfull
         * I dont know what to do next
         */
        break;                                       
    case Sn_IR_TIMEOUT:
        disconnect(m_structTCPData.m_ucharCurrentSocket);
        socket(m_structTCPData.m_ucharCurrentSocket, Sn_MR_TCP, 502, 0);    // open the SOCKET  
        status = listen(0);
        break;               
        
    case Sn_IR_DISCON: 
         temp = 1;
         if(m_structTCPData.m_ucharBytesReceived > 0) // check the size of received data
         {
              ushlen = recv(m_structTCPData.m_ucharCurrentSocket, m_aucharTCPRxBuf, m_structTCPData.m_ucharBytesReceived);
         }
        disconnectSocket(m_structTCPData.m_ucharCurrentSocket);
        
        socket(m_structTCPData.m_ucharCurrentSocket, Sn_MR_TCP, 502, 0);    // open the SOCKET  
        status = listen(0);
        break;                                       
    case Sn_IR_CON:                     
        /* Connection has been establised
         */
        //send(m_structTCPData.m_ucharCurrentSocket ,buf, ushlen);
        m_structTCPData.m_ushLastSeqNo = 0;
        m_structTCPData.m_ucharStartFlag = FALSE;
        break;
    default:
        write_wiznet_reg(Sn_IR(m_structTCPData.m_ucharCurrentSocket), 0xFF);
        break;

}
/* Clear the interrupt */
//write_wiznet_reg(Sn_IR(m_structTCPData.m_ucharCurrentSocket), 0xFF);
}


#4

Hi,

Most above all, check sending packet is completed.

I want to know just send interrupt doesn’t occur or send procedure is not working.

Best regards.


#5

Hi,
The send procedure is working.
When a send a modbus query via Modpoll I recieve the necessary response back.
The only issue here is I dont get an send complete interrupt.
I get the recieve interrupt .
The other issue is I dont get the disconnect interrupt also. I get that interrupt after quiet some time.
But I dont want to tackle that issue right now, since first I want to resolve the send interrupt issue first.

Thanks!!!


#6

Hi,
Your code seem to have no problem.

Did you modus TCP/IP using modpoll program.?
And when do you call send()? Can you post the code of call send()?
In send(), why don’t you wait until Sn_IR_SENDOK = 1?
For completing to send data, it need to one send command and one Sendok ISR.
If you not check Sendok ISr after send command, next send command can’t work well.

Thank you.