Subversion Repositories zxusbnet

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "socket.h"
  4. #include "w5300.h"
  5.  
  6. #define SWAP16(A)               ((((A << 8 ) & 0xFF00)) | ((A >> 8)& 0x00FF))
  7.  
  8. uint16   iinchip_source_port;
  9. uint8    check_sendok_flag[MAX_SOCK_NUM];
  10.  
  11. uint8 socket(SOCKET s, uint8 protocol, uint16 port, uint16 flag)
  12. {
  13.         IINCHIP_WRITE(Sn_MR0(s), (uint8)((protocol | flag) >> 8));
  14.         IINCHIP_WRITE(Sn_MR1(s), (uint8)((protocol | flag) & 0xff));
  15.         if (port != 0)
  16.         {
  17.                 IINCHIP_WRITE(Sn_PORTR0(s),(uint8)((port & 0xff00) >> 8));
  18.                 IINCHIP_WRITE(Sn_PORTR1(s),(uint8)(port & 0x00ff));
  19.         }
  20.         else
  21.         {
  22.                 iinchip_source_port++;     // if don't set the source port, set local_port number.
  23.                 IINCHIP_WRITE(Sn_PORTR0(s),(uint8)((iinchip_source_port & 0xff00) >> 8));
  24.                 IINCHIP_WRITE((Sn_PORTR1(s)),(uint8)(iinchip_source_port & 0x00ff));
  25.         }
  26.         setSn_CR(s, Sn_CR_OPEN);      // open s-th SOCKET
  27.  
  28.         check_sendok_flag[s] = 1;     // initialize the sendok flag.
  29.  
  30.         #ifdef __DEF_IINCHIP_DBG__
  31.                 printf("%d : Sn_MR=0x%04x,Sn_PORTR=0x%04x(%04d),Sn_SSR=%04x\r\n",s,IINCHIP_READ(Sn_MR(s)),(uint16)((IINCHIP_READ(Sn_PORTR0(s)) << 8) + IINCHIP_READ(Sn_PORTR1(s))),(uint16)((IINCHIP_READ(Sn_PORTR0(s)) << 8) + IINCHIP_READ(Sn_PORTR1(s))),getSn_SSR(s));
  32.         #endif
  33.         return 1;  
  34. }
  35.  
  36. void     close(SOCKET s)
  37. {
  38.         // M_08082008 : It is fixed the problem that Sn_SSR cannot be changed a undefined value to the defined value.
  39.         //              Refer to Errata of W5300
  40.         //Check if the transmit data is remained or not.
  41.         if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != getIINCHIP_TxMAX(s)) )
  42.         {
  43.                 uint16 loop_cnt =0;
  44.                 while(getSn_TX_FSR(s) != getIINCHIP_TxMAX(s))
  45.                 {
  46.                         if(loop_cnt++ > 10)
  47.                         {
  48.                                 uint8 destip[4];
  49.                                 // M_11252008 : modify dest ip address
  50.                                 //getSIPR(destip);
  51.                                 destip[0] = 0;destip[1] = 0;destip[2] = 0;destip[3] = 1;
  52.                                 socket(s,Sn_MR_UDP,0x3000,0);
  53.                                 sendto(s,(uint8*)"x",1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
  54.                                 break; // M_11252008 : added break statement
  55.                         }
  56.                 wait_10ms(10);
  57.                 }
  58.         };
  59.         setSn_IR(s ,0x00FF);          // Clear the remained interrupt bits.
  60.         setSn_CR(s ,Sn_CR_CLOSE);     // Close s-th SOCKET    
  61. }
  62.  
  63.  
  64. uint8    connect(SOCKET s, uint8 * addr, uint16 port)
  65. {
  66.         if
  67.         (
  68.                 ((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
  69.                 ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
  70.                 (port == 0x00)
  71.         )
  72.         {
  73.                 #ifdef __DEF_IINCHIP_DBG__
  74.                         printf("%d : Fail[invalid ip,port]\r\n",s);
  75.                 #endif
  76.                 return 0;
  77.         }
  78.  
  79.         // set destination IP
  80.         IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
  81.         IINCHIP_WRITE(Sn_DIPR1(s),addr[1]);
  82.         IINCHIP_WRITE(Sn_DIPR2(s),addr[2]);
  83.         IINCHIP_WRITE(Sn_DIPR3(s),addr[3]);
  84.         // set destination port number
  85.         IINCHIP_WRITE(Sn_DPORTR0(s),(((uint8)(port >> 8))));
  86.         IINCHIP_WRITE(Sn_DPORTR1(s),(((uint8)port & 0xff)));
  87.         // Connect
  88.         ApplySubnet();
  89.         setSn_CR(s,Sn_CR_CONNECT);
  90.        
  91.        
  92.         while( IINCHIP_READ(Sn_SSR(s)) != SOCK_SYNSENT )
  93.         {
  94.                 if(IINCHIP_READ(Sn_SSR(s)) == SOCK_ESTABLISHED)
  95.                 {
  96.                         break;
  97.                 }
  98.                 if(getSn_IR(s) & Sn_IR_TIMEOUT)
  99.                 {
  100.                         setSn_IR(s,(Sn_IR_TIMEOUT));
  101.                         break;
  102.                 }
  103.         }
  104.        
  105.                
  106.         ClearSubnet();
  107.  
  108.         return 1;  
  109. }
  110.  
  111. void     disconnect(SOCKET s)
  112. {
  113.         setSn_CR(s,Sn_CR_DISCON);     // Disconnect
  114. }
  115.  
  116. uint8    listen(SOCKET s)
  117. {
  118.         if (getSn_SSR(s) != SOCK_INIT)
  119.         {
  120.                 #ifdef __DEF_IINCHIP_DBG__
  121.                         printf("%d : SOCKET is not created!\r\n",s);
  122.                 #endif
  123.                 return 0;
  124.         }
  125.         setSn_CR(s,Sn_CR_LISTEN);     // listen
  126.  
  127.         return 1;
  128. }  
  129.  
  130. uint32   send(SOCKET s, uint8 * buf, uint32 len)
  131. {
  132.         uint8 status=0;
  133.         uint32 ret=0;
  134.         uint32 freesize=0;
  135.         #ifdef __DEF_IINCHIP_DBG__
  136.                 uint32 loopcnt = 0;
  137.  
  138.                 printf("%d : send()\r\n",s);
  139.         #endif
  140.  
  141.         ret = len;
  142.         if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
  143.  
  144.    
  145.  
  146.         /*
  147.         * \note if you want to use non blocking function, <b>"do{}while(freesize < ret)"</b> code block
  148.         * can be replaced with the below code. \n
  149.         * \code
  150.         *       while((freesize = getSn_TX_FSR(s))==0);
  151.         *       ret = freesize;
  152.         * \endcode
  153.         */
  154.         // -----------------------
  155.         // NOTE : CODE BLOCK START
  156.         do                                  
  157.         {
  158.                 freesize = getSn_TX_FSR(s);
  159.                 status = getSn_SSR(s);
  160.                 #ifdef __DEF_IINCHIP_DBG__
  161.                         printf("%d : freesize=%ld\r\n",s,freesize);
  162.                 if(loopcnt++ > 0x0010000)
  163.                 {
  164.                         printf("%d : freesize=%ld,status=%04x\r\n",s,freesize,status);
  165.                         printf("%d:Send Size=%08lx(%d)\r\n",s,ret,ret);
  166.                         printf("MR=%04x\r\n",*((vuint16*)MR));
  167.                         loopcnt = 0;
  168.                 }
  169.                 #endif
  170.                 if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT)) return 0;
  171.         } while (freesize < ret);
  172.         // NOTE : CODE BLOCK END
  173.         // ---------------------
  174.    
  175.         if(ret & 0x01) wiz_write_buf(s, buf, (ret+1));
  176.         else wiz_write_buf(s,buf,ret);                   // copy data
  177.  
  178.         #ifdef __DEF_IINCHIP_DBG__
  179.                 loopcnt=0;
  180.         #endif  
  181.  
  182.         if(!check_sendok_flag[s])                 // if first send, skip.
  183.         {
  184.                 while (!(getSn_IR(s) & Sn_IR_SENDOK))  // wait previous SEND command completion.
  185.                 {
  186.                 #ifdef __DEF_IINCHIP_DBG__
  187.  
  188.                 if(loopcnt++ > 0x010000)
  189.                 {
  190.                         printf("%d:Sn_SSR(%02x)\r\n",s,status);
  191.                         printf("%d:Send Size=%08lx(%d)\r\n",s,ret,ret);
  192.                         printf("MR=%02x%02x\r\n",*((vuint8*)MR0),*((vuint8*)MR1));
  193.                         loopcnt = 0;
  194.                 }
  195.                 #endif
  196.                 if (getSn_SSR(s) == SOCK_CLOSED)    // check timeout or abnormal closed.
  197.                 {
  198.                         #ifdef __DEF_IINCHIP_DBG__
  199.                                 printf("%d : Send Fail. SOCK_CLOSED.\r\n",s);
  200.                         #endif
  201.                        
  202.                         return 0;
  203.                 }
  204.                 }
  205.                 setSn_IR(s, Sn_IR_SENDOK);             // clear Sn_IR_SENDOK      
  206.         }
  207.         else check_sendok_flag[s] = 0;
  208.  
  209.         // send
  210.         setSn_TX_WRSR(s,ret);  
  211.         setSn_CR(s,Sn_CR_SEND);
  212.    
  213.         return ret;
  214. }
  215.  
  216. uint32   recv(SOCKET s, uint8 * buf, uint32 len)
  217. {
  218.         uint16 pack_size=0;
  219.         vint16 mr = getMR();
  220.  
  221.         #ifdef __DEF_IINCHIP_DBG__
  222.                 printf("%d : recv()\r\n",s);
  223.         #endif
  224.  
  225.         if(IINCHIP_READ(Sn_MR0(s)) & Sn_MR_ALIGN)
  226.         {
  227.                 wiz_read_buf(s, buf, len);
  228.                 setSn_CR(s,Sn_CR_RECV);
  229.                 return len;
  230.         }
  231.  
  232.         wiz_read_buf(s,(uint8*)&pack_size,2);        // extract the PACKET-INFO(DATA packet length)
  233.  
  234.         #ifdef LITTLE_ENDIAN
  235.                 if(mr & MR_FS) pack_size = pack_size;
  236.                 else pack_size = SWAP16(pack_size);
  237.         #else
  238.                 if(mr & MR_FS) pack_size = SWAP16(pack_size);
  239.                 else pack_size = pack_size;
  240.         #endif
  241.  
  242.         #ifdef __DEF_IINCHIP_DBG__  
  243.                 printf("%d:pack_size=%d\r\n",s,pack_size);
  244.         #endif
  245.  
  246.         len = pack_size;
  247.         if(pack_size & 0x01) len += 1;
  248.  
  249.         wiz_read_buf(s, buf, len);     // copy data  
  250.  
  251.         setSn_CR(s,Sn_CR_RECV);                      // recv
  252.  
  253.    /*
  254.    * \warning  send a packet for updating window size. This code block must be only used when W5300 do only receiving data.
  255.    */
  256.    // ------------------------
  257.    // WARNING CODE BLOCK START
  258.    
  259.    // M_15052008 : Replace Sn_CR_SEND with Sn_CR_SEND_KEEP.
  260.    //if(!(getSn_IR(s) & Sn_IR_SENDOK))
  261.    //{
  262.    //   setSn_TX_WRSR(s,0);                    // size = 0
  263.    //   setSn_CR(s,Sn_CR_SEND);                // send
  264.    //   while(!(getSn_IR(s) & Sn_IR_SENDOK));  // wait SEND command completion
  265.    //   setSn_IR(s,Sn_IR_SENDOK);              // clear Sn_IR_SENDOK bit
  266.    //}
  267.    
  268.    // M_04072008 : Replace Sn_CR_SEND_KEEP with Sn_CR_SEND.
  269.    //if(getSn_RX_RSR(s) == 0)                     // send the window-update packet when the window size is full
  270.    //{
  271.    //   uint8 keep_time = 0;
  272.    //   if((keep_time=getSn_KPALVTR(s)) != 0x00) setSn_KPALVTR(s,0x00); // disables the auto-keep-alive-process
  273.    //   setSn_CR(s,Sn_CR_SEND_KEEP);              // send a keep-alive packet by command
  274.    //   setSn_KPALVTR(s,keep_time);               // restore the previous keep-alive-timer value
  275.    //}
  276.  
  277.  
  278. //   if(getSn_RX_RSR(s) == 0)                     // check if the window size is full or not
  279. //   { /* Sn_RX_RSR can be compared with another value instead of ??0??,
  280. //      according to the host performance of receiving data */
  281. //      setSn_TX_WRSR(s,1);                       // size : 1 byte dummy size
  282. //      IINCHIP_WRITE(Sn_TX_FIFOR0(s),0x00);     // write dummy data into tx memory
  283. //      IINCHIP_WRITE(Sn_TX_FIFOR1(s),0x00);
  284. //      setSn_CR(s,Sn_CR_SEND);                   // send                        
  285. //      while(!(getSn_IR(s) & Sn_IR_SENDOK));     // wait SEND command completion
  286. //      setSn_IR(s,Sn_IR_SENDOK);                 // clear Sn_IR_SENDOK bit      
  287. //   }                                                                        
  288.  
  289.  
  290.    // WARNING CODE BLOCK END
  291.    // ----------------------
  292.    
  293.    return (uint32)pack_size;
  294. }
  295.  
  296. uint32   sendto(SOCKET s, uint8 * buf, uint32 len, uint8 * addr, uint16 port)
  297. {
  298.         uint8 status=0;
  299.         uint8 isr=0;
  300.         uint32 ret=0;
  301.  
  302.         #ifdef __DEF_IINCHIP_DBG__
  303.                 printf("%d : sendto():%d.%d.%d.%d(%d), len=%d\r\n",s, addr[0], addr[1], addr[2], addr[3] , port, len);
  304.         #endif
  305.  
  306.         if
  307.         (
  308.           ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
  309.           ((port == 0x00)) ||(len == 0)
  310.         )
  311.         {
  312.                 #ifdef __DEF_IINCHIP_DBG__
  313.                          printf("%d : Fail[%d.%d.%d.%d, %.d, %d]\r\n",s, addr[0], addr[1], addr[2], addr[3] , port, len);
  314.                 #endif
  315.                 return 0;
  316.         }
  317.    
  318.    
  319.         if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
  320.         else ret = len;
  321.  
  322.         // set destination IP address
  323.         IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
  324.         IINCHIP_WRITE(Sn_DIPR1(s),addr[1]);
  325.         IINCHIP_WRITE(Sn_DIPR2(s),addr[2]);
  326.         IINCHIP_WRITE(Sn_DIPR3(s),addr[3]);
  327.         // set destination port number
  328.         IINCHIP_WRITE(Sn_DPORTR0(s),((uint8)(port >> 8)));
  329.         IINCHIP_WRITE(Sn_DPORTR1(s),((uint8)(port & 0xff)));
  330.  
  331.         wiz_write_buf(s, buf, ret+(ret & 0x01));                               // copy data
  332.         // send
  333.         setSn_TX_WRSR(s,ret);
  334.         ApplySubnet();
  335.         setSn_CR(s, Sn_CR_SEND);
  336.  
  337.         while (!((isr = getSn_IR(s)) & Sn_IR_SENDOK))            // wait SEND command completion
  338.         {
  339.                 status = getSn_SSR(s);                                // warning ---------------------------------------
  340.                 if ((status == SOCK_CLOSED) || (isr & Sn_IR_TIMEOUT)) // Sn_IR_TIMEOUT causes the decrement of Sn_TX_FSR
  341.                 {                                                     // -----------------------------------------------
  342.                         #ifdef __DEF_IINCHIP_DBG__
  343.                                 printf("%d: send fail.status=0x%02x,isr=%02x\r\n",s,status,isr);
  344.                         #endif
  345.                         setSn_IR(s,Sn_IR_TIMEOUT);
  346.                         return 0;
  347.                 }
  348.         }
  349.  
  350.         setSn_IR(s, Sn_IR_SENDOK); // Clear Sn_IR_SENDOK
  351.         ClearSubnet();
  352.    
  353.         #ifdef __DEF_IINCHIP_DBG__          
  354.                 printf("%d : send()end\r\n",s);
  355.         #endif      
  356.  
  357.         return ret;  
  358. }
  359.  
  360. uint32   recvfrom(SOCKET s, uint8 * buf, uint32 len, uint8 * addr, uint16  *port)
  361. {
  362.         uint8 head[8];
  363.         uint16 data_len=0;
  364.         uint16 crc[2];
  365.         vint16 mr = getMR();
  366.  
  367.         #ifdef __DEF_IINCHIP_DBG__
  368.                 printf("recvfrom()\r\n");
  369.         #endif
  370.  
  371.         if ( len > 0 )
  372.         {
  373.  
  374.                 switch (IINCHIP_READ(Sn_MR1(s)) & 0x07)                 // check the mode of s-th SOCKET
  375.                 {                                                       // -----------------------------
  376.                 case Sn_MR_UDP :                                        // UDP mode
  377.  
  378.                         wiz_read_buf(s, head, 8);                       // extract the PACKET-INFO
  379.                         // read peer's IP address, port number.
  380.  
  381.                         if(mr & MR_FS)
  382.                         {
  383.                                 addr[0] = head[1];                      // destination IP address
  384.                                 addr[1] = head[0];
  385.                                 addr[2] = head[3];
  386.                                 addr[3] = head[2];
  387.                         }
  388.                         else
  389.                         {
  390.                                 addr[0] = head[0];
  391.                                 addr[1] = head[1];
  392.                                 addr[2] = head[2];
  393.                                 addr[3] = head[3];
  394.                         }
  395.                         #ifdef LITTLE_ENDIAN
  396.                                 if(mr & MR_FS)
  397.                                 {
  398.                                         *port = head[5];                                // destination port number
  399.                                         *port = (*port << 8) + head[4];
  400.                                         data_len = (uint16)head[7];                     // DATA packet length
  401.                                         data_len = (data_len << 8) + head[6];
  402.                                 }
  403.                                 else
  404.                                 {
  405.                                         *port = head[4];                                // destination port number
  406.                                         *port = (*port << 8) + head[5];
  407.                                         data_len = (uint16)head[6];                     // DATA packet length
  408.                                         data_len = (data_len << 8) + head[7];
  409.                                 }
  410.                         #else
  411.                                 if(mr & MR_FS)
  412.                                 {
  413.                                         *port = head[4];
  414.                                         *port = (*port << 8) + head[5];
  415.                                         data_len = (uint16)head[6];                     // DATA packet length
  416.                                         data_len = (data_len << 8) + head[7];
  417.                                 }
  418.                                 else
  419.                                 {
  420.                                         *port = head[5];
  421.                                         *port = (*port << 8) + head[4];
  422.                                         data_len = (uint16)head[7];                     // DATA packet length
  423.                                         data_len = (data_len << 8) + head[6];
  424.                                 }
  425.                         #endif
  426.  
  427.                         #ifdef __DEF_IINCHIP_DBG__
  428.                                 printf("UDP msg arrived:%d(0x%04x)\r\n",data_len,data_len);
  429.                                 printf("source Port : %d\r\n", *port);
  430.                                 printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
  431.                         #endif
  432.  
  433.                         wiz_read_buf(s, buf, data_len + (data_len & 0x01) );        // data copy.
  434.                         break;
  435.  
  436.                                                                                         // -----------------------
  437.                 case Sn_MR_IPRAW :                                                      // IPRAW mode
  438.                         wiz_read_buf(s, (uint8*)head, 6);                               // extract the PACKET-INFO
  439.                         if((*(vint8*)MR0) & MR_FS)
  440.                         {
  441.                                 addr[0] = head[1];                                      // destination IP address
  442.                                 addr[1] = head[0];
  443.                                 addr[2] = head[3];
  444.                                 addr[3] = head[2];
  445.                         }
  446.                         else
  447.                         {
  448.                                 addr[0] = head[0];                                      // destination IP address
  449.                                 addr[1] = head[1];
  450.                                 addr[2] = head[2];
  451.                                 addr[3] = head[3];
  452.                         }
  453.  
  454.                         #ifdef LITTLE_ENDIAN
  455.                                 if((*(vint8*)MR0) & MR_FS)
  456.                                 {
  457.                                         data_len = (uint16)head[5];                      // DATA packet length
  458.                                         data_len = (data_len << 8) + head[4];
  459.                                 }
  460.                                 else
  461.                                 {
  462.                                         data_len = (uint16)head[4];                     // DATA packet length
  463.                                         data_len = (data_len << 8) + head[5];
  464.                                 }
  465.                         #else
  466.                                 if((*(vint8*)MR0) & MR_FS)
  467.                                 {
  468.                                         data_len = (uint16)head[4];
  469.                                         data_len = (data_len << 8) + head[5];
  470.                                 }
  471.                                 else
  472.                                 {
  473.                                         data_len = (uint16)head[5];
  474.                                         data_len = (data_len << 8) + head[4];
  475.                                 }
  476.                         #endif
  477.  
  478.                         #ifndef __DEF_IINCHIP_DBG__
  479.                                 printf("IP RAW msg arrived\r\n");
  480.                                 printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
  481.                         #endif
  482.  
  483.                         wiz_read_buf(s, buf, data_len+(data_len & 0x01));               // data copy.
  484.                         break;                                
  485.                
  486.                                                                                         // -----------------------
  487.                 case Sn_MR_MACRAW :                                                     // MACRAW mode
  488.                         wiz_read_buf(s,(uint8*)head,2);                                 // extract the PACKET-INFO
  489.                         #ifdef LITTLE_ENDIAN
  490.                                 if((*(vint8*)MR0) & MR_FS)
  491.                                 {
  492.                                         data_len = (uint16)head[1];                     // DATA packet length
  493.                                         data_len = (data_len << 8) + head[0];
  494.                                 }
  495.                                 else
  496.                                 {
  497.                                         data_len = (uint16)head[0];
  498.                                         data_len = (data_len << 8) + head[1];
  499.                                 }
  500.                         #else
  501.                                 if((*(vint8*)MR0) & MR_FS)
  502.                                 {
  503.                                         data_len = (uint16)head[0];
  504.                                         data_len = (data_len << 8) + head[1];
  505.                                 }
  506.                                 else
  507.                                 {
  508.                                         data_len = (uint16)head[1];
  509.                                         data_len = (data_len << 8) + head[0];
  510.                                 }
  511.                         #endif
  512.  
  513.                         wiz_read_buf(s, buf, data_len + (data_len & 0x01));        // data copy.
  514.                         wiz_read_buf(s,(uint8*)crc, 4);        // extract CRC data and ignore it.
  515.  
  516.                         break;
  517.                 default :
  518.                         break;
  519.                 }
  520.                 setSn_CR(s,Sn_CR_RECV);                      // recv
  521.         }
  522.         #ifdef __DEF_IINCHIP_DBG__
  523.                 printf("recvfrom() end ..\r\n");
  524.         #endif
  525.    
  526.         return data_len;  
  527. }
  528.