⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socket.c

📁 w5300 driver w5300 driver
💻 C
📖 第 1 页 / 共 2 页
字号:
/**
 * \file    socket.c
 *   Implemetation of WIZnet SOCKET API fucntions
 *
 * This file implements the WIZnet SOCKET API functions that is used in your internat application program.
 * 
 * Revision History :
 * ----------  -------  -----------  ----------------------------
 * Date        Version  Author       Description
 * ----------  -------  -----------  ----------------------------
 * 24/03/2008  1.0.0    MidnightCow  Release with W5300 launching
 * ----------  -------  -----------  ----------------------------
 * 15/05/2008  1.1.0    MidnightCow  Refer to M_15052008.
 *                                   Modify the warning code block in recv(). 
 * ----------  -------  -----------  ---------------------------- 
 * 04/07/2008  1.1.1    MidnightCow  Refer to M_04072008.
 *                                   Modify the warning code block in recv(). 
 * ----------  -------  -----------  ---------------------------- 
 * 08/08/2008  1.2.0    MidnightCow  Refer to M_08082008.
 *                                   Modify close(). 
 * ----------  -------  -----------  ---------------------------- 
 * 11/25/2008  1.2.1    Bongjun      Refer to M_11252008.
 *                                   Modify close().
 * ----------  -------  -----------  ----------------------------  
 */
 
 
#include "socket.h"
#include "lstring.h"
#include "string.h"

/** 
 * Variable for temporary source port number 
 */
uint16   iinchip_source_port;

/** 
 * The flag to check if first send or not.
 */
uint8    check_sendok_flag[MAX_SOCK_NUM];


uint8    socket(SOCKET s, uint8 protocol, uint16 port, uint16 flag)
{
   IINCHIP_WRITE(Sn_MR(s),(uint16)(protocol | flag)); // set Sn_MR with protocol & flag
   if (port != 0) IINCHIP_WRITE(Sn_PORTR(s),port);
   else 
   {
      iinchip_source_port++;     // if don't set the source port, set local_port number.
      IINCHIP_WRITE(Sn_PORTR(s),iinchip_source_port);
   }
   setSn_CR(s, Sn_CR_OPEN);      // open s-th SOCKET 
   
   check_sendok_flag[s] = 1;     // initialize the sendok flag.
   
   #ifdef __DEF_IINCHIP_DBG__
      printf("%d : Sn_MR=0x%04x,Sn_PORTR=0x%04x(%d),Sn_SSR=%04x\r\n",s,IINCHIP_READ(Sn_MR(s)),IINCHIP_READ(Sn_PORTR(s)),IINCHIP_READ(Sn_PORTR(s)),getSn_SSR(s));
   #endif
   return 1;   
}

void     close(SOCKET s)
{
   // M_08082008 : It is fixed the problem that Sn_SSR cannot be changed a undefined value to the defined value.
   //              Refer to Errata of W5300
   //Check if the transmit data is remained or not.
   if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != getIINCHIP_TxMAX(s)) ) 
   { 
      uint16 loop_cnt =0;
      while(getSn_TX_FSR(s) != getIINCHIP_TxMAX(s))
      {
         if(loop_cnt++ > 10)
         {
            uint8 destip[4];
            // M_11252008 : modify dest ip address
            //getSIPR(destip);
            destip[0] = 0;destip[1] = 0;destip[2] = 0;destip[3] = 1;
            socket(s,Sn_MR_UDP,0x3000,0);
            sendto(s,(uint8*)"x",1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
            break; // M_11252008 : added break statement
         }
         wait_10ms(10);
      }
   };
   ////////////////////////////////   
   setSn_IR(s ,0x00FF);          // Clear the remained interrupt bits.
   setSn_CR(s ,Sn_CR_CLOSE);     // Close s-th SOCKET     
}

uint8    connect(SOCKET s, uint8 * addr, uint16 port)
{
   if
   (
      ((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
      ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
      (port == 0x00) 
   )
   {
      #ifdef __DEF_IINCHIP_DBG__
         printf("%d : Fail[invalid ip,port]\r\n",s);
      #endif
      return 0;
   }
   
   // set destination IP 
   IINCHIP_WRITE(Sn_DIPR(s),((uint16)addr[0]<<8)+(uint16)addr[1]);
   IINCHIP_WRITE(Sn_DIPR2(s),((uint16)addr[2]<<8)+(uint16)addr[3]);
   // set destination port number
   IINCHIP_WRITE(Sn_DPORTR(s),port);
   
   // Connect
   setSn_CR(s,Sn_CR_CONNECT);

   return 1;   
}

void     disconnect(SOCKET s)
{
   setSn_CR(s,Sn_CR_DISCON);     // Disconnect
}

uint8    listen(SOCKET s)
{
   if (getSn_SSR(s) != SOCK_INIT)
   {
      #ifdef __DEF_IINCHIP_DBG__
         printf("%d : SOCKET is not created!\r\n",s);
      #endif
      return 0;
   }

   setSn_CR(s,Sn_CR_LISTEN);     // listen
   
   return 1;
}  
 
uint32   send(SOCKET s, uint8 * buf, uint32 len)
{
   uint8 status=0;
   uint32 ret=0;
   uint32 freesize=0;
   #ifdef __DEF_IINCHIP_DBG__
      uint32 loopcnt = 0;

      printf("%d : send()\r\n",s);
   #endif
   
   ret = len;
   if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
   
   

   /*
    * \note if you want to use non blocking function, <b>"do{}while(freesize < ret)"</b> code block 
    * can be replaced with the below code. \n
    * \code 
    *       while((freesize = getSn_TX_FSR(s))==0); 
    *       ret = freesize;
    * \endcode
    */
   // -----------------------
   // NOTE : CODE BLOCK START
   do                                   
   {
      freesize = getSn_TX_FSR(s);
      status = getSn_SSR(s);
      #ifdef __DEF_IINCHIP_DBG__
         printf("%d : freesize=%ld\r\n",s,freesize);
         if(loopcnt++ > 0x0010000)
         { 
            printf("%d : freesize=%ld,status=%04x\r\n",s,freesize,status);
            printf("%d:Send Size=%08lx(%d)\r\n",s,ret,ret);
            printf("MR=%04x\r\n",*((vuint16*)MR));
            loopcnt = 0;
         }
      #endif
      if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT)) return 0;
   } while (freesize < ret);
   // NOTE : CODE BLOCK END
   // ---------------------
   
   wiz_write_buf(s,buf,ret);                 // copy data

   #ifdef __DEF_IINCHIP_DBG__
      loopcnt=0;
   #endif   
   
   if(!check_sendok_flag[s])                 // if first send, skip.
   {
      while (!(getSn_IR(s) & Sn_IR_SENDOK))  // wait previous SEND command completion.
      {
      #ifdef __DEF_IINCHIP_DBG__

         if(loopcnt++ > 0x010000)
         {
            printf("%d:Sn_SSR(%04x)\r\n",s,status);
            printf("%d:Send Size=%08lx(%d)\r\n",s,ret,ret);
            printf("MR=%04x\r\n",*((vuint16*)MR));
            loopcnt = 0;
         }
      #endif
         if (getSn_SSR(s) == SOCK_CLOSED)    // check timeout or abnormal closed.
         {
            #ifdef __DEF_IINCHIP_DBG__
               printf("%d : Send Fail. SOCK_CLOSED.\r\n",s);
            #endif
            return 0;
         }
      }
      setSn_IR(s, Sn_IR_SENDOK);             // clear Sn_IR_SENDOK	
   }
   else check_sendok_flag[s] = 0;
   
   // send
   setSn_TX_WRSR(s,ret);   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -