Wiznet W5500 driver and TCP/UDP loopback

Dependencies:   mbed

Committer:
jbkim
Date:
Fri Dec 13 07:35:58 2013 +0000
Revision:
0:2513c6696bdc
Wiznet W5500 library and TCP/UDP loopback program for mbed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jbkim 0:2513c6696bdc 1 /* Wiznet W5500 Library
jbkim 0:2513c6696bdc 2 * Copyright (c) 2013, WIZnet Co., LTD.
jbkim 0:2513c6696bdc 3 *
jbkim 0:2513c6696bdc 4 * Licensed under the Apache License, Version 2.0 (the "License");
jbkim 0:2513c6696bdc 5 * you may not use this file except in compliance with the License.
jbkim 0:2513c6696bdc 6 * You may obtain a copy of the License at
jbkim 0:2513c6696bdc 7 *
jbkim 0:2513c6696bdc 8 * http://www.apache.org/licenses/LICENSE-2.0
jbkim 0:2513c6696bdc 9 *
jbkim 0:2513c6696bdc 10 * Unless required by applicable law or agreed to in writing, software
jbkim 0:2513c6696bdc 11 * distributed under the License is distributed on an "AS IS" BASIS,
jbkim 0:2513c6696bdc 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
jbkim 0:2513c6696bdc 13 * See the License for the specific language governing permissions and
jbkim 0:2513c6696bdc 14 * limitations under the License.
jbkim 0:2513c6696bdc 15 */
jbkim 0:2513c6696bdc 16
jbkim 0:2513c6696bdc 17 #include "socket.h"
jbkim 0:2513c6696bdc 18
jbkim 0:2513c6696bdc 19 #define SOCK_ANY_PORT_NUM 0xC000;
jbkim 0:2513c6696bdc 20
jbkim 0:2513c6696bdc 21 static uint16_t sock_any_port = SOCK_ANY_PORT_NUM;
jbkim 0:2513c6696bdc 22 static uint16_t sock_io_mode = 0;
jbkim 0:2513c6696bdc 23 static uint16_t sock_is_sending = 0;
jbkim 0:2513c6696bdc 24 static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,};
jbkim 0:2513c6696bdc 25
jbkim 0:2513c6696bdc 26 #define CHECK_SOCKNUM() \
jbkim 0:2513c6696bdc 27 do{ \
jbkim 0:2513c6696bdc 28 if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \
jbkim 0:2513c6696bdc 29 }while(0); \
jbkim 0:2513c6696bdc 30
jbkim 0:2513c6696bdc 31 #define CHECK_SOCKMODE(mode) \
jbkim 0:2513c6696bdc 32 do{ \
jbkim 0:2513c6696bdc 33 if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \
jbkim 0:2513c6696bdc 34 }while(0); \
jbkim 0:2513c6696bdc 35
jbkim 0:2513c6696bdc 36 #define CHECK_SOCKINIT() \
jbkim 0:2513c6696bdc 37 do{ \
jbkim 0:2513c6696bdc 38 if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \
jbkim 0:2513c6696bdc 39 }while(0); \
jbkim 0:2513c6696bdc 40
jbkim 0:2513c6696bdc 41 #define CHECK_SOCKDATA() \
jbkim 0:2513c6696bdc 42 do{ \
jbkim 0:2513c6696bdc 43 if(len == 0) return SOCKERR_DATALEN; \
jbkim 0:2513c6696bdc 44 }while(0); \
jbkim 0:2513c6696bdc 45
jbkim 0:2513c6696bdc 46
jbkim 0:2513c6696bdc 47
jbkim 0:2513c6696bdc 48 int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
jbkim 0:2513c6696bdc 49 {
jbkim 0:2513c6696bdc 50 CHECK_SOCKNUM();
jbkim 0:2513c6696bdc 51 switch(protocol)
jbkim 0:2513c6696bdc 52 {
jbkim 0:2513c6696bdc 53 case Sn_MR_TCP :
jbkim 0:2513c6696bdc 54 case Sn_MR_UDP :
jbkim 0:2513c6696bdc 55 case Sn_MR_MACRAW :
jbkim 0:2513c6696bdc 56 break;
jbkim 0:2513c6696bdc 57 default :
jbkim 0:2513c6696bdc 58 return SOCKERR_SOCKMODE;
jbkim 0:2513c6696bdc 59 }
jbkim 0:2513c6696bdc 60 if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG;
jbkim 0:2513c6696bdc 61
jbkim 0:2513c6696bdc 62 if(flag != 0)
jbkim 0:2513c6696bdc 63 {
jbkim 0:2513c6696bdc 64 switch(protocol)
jbkim 0:2513c6696bdc 65 {
jbkim 0:2513c6696bdc 66 case Sn_MR_TCP:
jbkim 0:2513c6696bdc 67 if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG;
jbkim 0:2513c6696bdc 68 break;
jbkim 0:2513c6696bdc 69 case Sn_MR_UDP:
jbkim 0:2513c6696bdc 70 if(flag & SF_IGMP_VER2)
jbkim 0:2513c6696bdc 71 {
jbkim 0:2513c6696bdc 72 if((flag & SF_MULTI_ENABLE)==0) return SOCKERR_SOCKFLAG;
jbkim 0:2513c6696bdc 73 }
jbkim 0:2513c6696bdc 74 if(flag & SF_UNI_BLOCK)
jbkim 0:2513c6696bdc 75 {
jbkim 0:2513c6696bdc 76 if((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG;
jbkim 0:2513c6696bdc 77 }
jbkim 0:2513c6696bdc 78 break;
jbkim 0:2513c6696bdc 79 default:
jbkim 0:2513c6696bdc 80 break;
jbkim 0:2513c6696bdc 81 }
jbkim 0:2513c6696bdc 82 }
jbkim 0:2513c6696bdc 83 close(sn);
jbkim 0:2513c6696bdc 84 setSn_MR(sn, (protocol | (flag & 0xF0)));
jbkim 0:2513c6696bdc 85 if(!port)
jbkim 0:2513c6696bdc 86 {
jbkim 0:2513c6696bdc 87 port = sock_any_port++;
jbkim 0:2513c6696bdc 88 if(sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM;
jbkim 0:2513c6696bdc 89 }
jbkim 0:2513c6696bdc 90 setSn_PORT(sn,port);
jbkim 0:2513c6696bdc 91 setSn_CR(sn,Sn_CR_OPEN);
jbkim 0:2513c6696bdc 92 while(getSn_CR(sn));
jbkim 0:2513c6696bdc 93 sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn);
jbkim 0:2513c6696bdc 94 sock_is_sending &= ~(1<<sn);
jbkim 0:2513c6696bdc 95 sock_remained_size[sn] = 0;
jbkim 0:2513c6696bdc 96 while(getSn_SR(sn) == SOCK_CLOSED);
jbkim 0:2513c6696bdc 97 return (int8_t)sn;
jbkim 0:2513c6696bdc 98 }
jbkim 0:2513c6696bdc 99
jbkim 0:2513c6696bdc 100 int8_t close(uint8_t sn)
jbkim 0:2513c6696bdc 101 {
jbkim 0:2513c6696bdc 102 CHECK_SOCKNUM();
jbkim 0:2513c6696bdc 103
jbkim 0:2513c6696bdc 104 setSn_CR(sn,Sn_CR_CLOSE);
jbkim 0:2513c6696bdc 105 /* wait to process the command... */
jbkim 0:2513c6696bdc 106 while( getSn_CR(sn) );
jbkim 0:2513c6696bdc 107 /* clear all interrupt of the socket. */
jbkim 0:2513c6696bdc 108 setSn_IR(sn, 0xFF);
jbkim 0:2513c6696bdc 109 sock_is_sending &= ~(1<<sn);
jbkim 0:2513c6696bdc 110 sock_remained_size[sn] = 0;
jbkim 0:2513c6696bdc 111 while(getSn_SR(sn) != SOCK_CLOSED);
jbkim 0:2513c6696bdc 112 return SOCK_OK;
jbkim 0:2513c6696bdc 113 }
jbkim 0:2513c6696bdc 114
jbkim 0:2513c6696bdc 115 int8_t listen(uint8_t sn)
jbkim 0:2513c6696bdc 116 {
jbkim 0:2513c6696bdc 117 CHECK_SOCKNUM();
jbkim 0:2513c6696bdc 118 CHECK_SOCKMODE(Sn_MR_TCP);
jbkim 0:2513c6696bdc 119 CHECK_SOCKINIT();
jbkim 0:2513c6696bdc 120 setSn_CR(sn,Sn_CR_LISTEN);
jbkim 0:2513c6696bdc 121 while(getSn_CR(sn));
jbkim 0:2513c6696bdc 122 while(getSn_SR(sn) != SOCK_LISTEN)
jbkim 0:2513c6696bdc 123 {
jbkim 0:2513c6696bdc 124 if(getSn_CR(sn) == SOCK_CLOSED)
jbkim 0:2513c6696bdc 125 {
jbkim 0:2513c6696bdc 126 close(sn);
jbkim 0:2513c6696bdc 127 return SOCKERR_SOCKCLOSED;
jbkim 0:2513c6696bdc 128 }
jbkim 0:2513c6696bdc 129 }
jbkim 0:2513c6696bdc 130 return SOCK_OK;
jbkim 0:2513c6696bdc 131 }
jbkim 0:2513c6696bdc 132
jbkim 0:2513c6696bdc 133
jbkim 0:2513c6696bdc 134 int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port)
jbkim 0:2513c6696bdc 135 {
jbkim 0:2513c6696bdc 136 CHECK_SOCKNUM();
jbkim 0:2513c6696bdc 137 CHECK_SOCKMODE(Sn_MR_TCP);
jbkim 0:2513c6696bdc 138 CHECK_SOCKINIT();
jbkim 0:2513c6696bdc 139 if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
jbkim 0:2513c6696bdc 140 if(port == 0) return SOCKERR_PORTZERO;
jbkim 0:2513c6696bdc 141 setSn_DIPR(sn,addr);
jbkim 0:2513c6696bdc 142 setSn_DPORT(sn,port);
jbkim 0:2513c6696bdc 143 // setSUBR(); // set the subnet mask register
jbkim 0:2513c6696bdc 144 setSn_CR(sn,Sn_CR_CONNECT);
jbkim 0:2513c6696bdc 145 while(getSn_CR(sn));
jbkim 0:2513c6696bdc 146 if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
jbkim 0:2513c6696bdc 147 while(getSn_SR(sn) != SOCK_ESTABLISHED)
jbkim 0:2513c6696bdc 148 {
jbkim 0:2513c6696bdc 149 if (getSn_IR(sn) & Sn_IR_TIMEOUT)
jbkim 0:2513c6696bdc 150 {
jbkim 0:2513c6696bdc 151 setSn_IR(sn, Sn_IR_TIMEOUT);
jbkim 0:2513c6696bdc 152 return SOCKERR_TIMEOUT;
jbkim 0:2513c6696bdc 153 }
jbkim 0:2513c6696bdc 154 }
jbkim 0:2513c6696bdc 155 // clearSUBR(); // clear the subnet mask again and keep it because of the ARP errata of W5100
jbkim 0:2513c6696bdc 156 return SOCK_OK;
jbkim 0:2513c6696bdc 157 }
jbkim 0:2513c6696bdc 158
jbkim 0:2513c6696bdc 159 int8_t disconnect(uint8_t sn)
jbkim 0:2513c6696bdc 160 {
jbkim 0:2513c6696bdc 161 CHECK_SOCKNUM();
jbkim 0:2513c6696bdc 162 CHECK_SOCKMODE(Sn_MR_TCP);
jbkim 0:2513c6696bdc 163 setSn_CR(sn,Sn_CR_DISCON);
jbkim 0:2513c6696bdc 164 /* wait to process the command... */
jbkim 0:2513c6696bdc 165 while(getSn_CR(sn));
jbkim 0:2513c6696bdc 166 sock_is_sending &= ~(1<<sn);
jbkim 0:2513c6696bdc 167 if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
jbkim 0:2513c6696bdc 168 while(getSn_SR(sn) != SOCK_CLOSED)
jbkim 0:2513c6696bdc 169 {
jbkim 0:2513c6696bdc 170 if(getSn_IR(sn) & Sn_IR_TIMEOUT)
jbkim 0:2513c6696bdc 171 {
jbkim 0:2513c6696bdc 172 close(sn);
jbkim 0:2513c6696bdc 173 return SOCKERR_TIMEOUT;
jbkim 0:2513c6696bdc 174 }
jbkim 0:2513c6696bdc 175 }
jbkim 0:2513c6696bdc 176 return SOCK_OK;
jbkim 0:2513c6696bdc 177 }
jbkim 0:2513c6696bdc 178
jbkim 0:2513c6696bdc 179 int32_t send(uint8_t sn, uint8_t * buf, uint16_t len)
jbkim 0:2513c6696bdc 180 {
jbkim 0:2513c6696bdc 181 uint8_t tmp=0;
jbkim 0:2513c6696bdc 182 uint16_t freesize=0;
jbkim 0:2513c6696bdc 183
jbkim 0:2513c6696bdc 184 CHECK_SOCKNUM();
jbkim 0:2513c6696bdc 185 CHECK_SOCKMODE(Sn_MR_TCP);
jbkim 0:2513c6696bdc 186 CHECK_SOCKDATA();
jbkim 0:2513c6696bdc 187 tmp = getSn_SR(sn);
jbkim 0:2513c6696bdc 188 if(tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) return SOCKERR_SOCKSTATUS;
jbkim 0:2513c6696bdc 189 if( sock_is_sending & (1<<sn) )
jbkim 0:2513c6696bdc 190 {
jbkim 0:2513c6696bdc 191 tmp = getSn_IR(sn);
jbkim 0:2513c6696bdc 192 if(tmp & Sn_IR_SENDOK)
jbkim 0:2513c6696bdc 193 {
jbkim 0:2513c6696bdc 194 setSn_IR(sn, Sn_IR_SENDOK);
jbkim 0:2513c6696bdc 195 sock_is_sending &= ~(1<<sn);
jbkim 0:2513c6696bdc 196 }
jbkim 0:2513c6696bdc 197 else if(tmp & Sn_IR_TIMEOUT)
jbkim 0:2513c6696bdc 198 {
jbkim 0:2513c6696bdc 199 close(sn);
jbkim 0:2513c6696bdc 200 return SOCKERR_TIMEOUT;
jbkim 0:2513c6696bdc 201 }
jbkim 0:2513c6696bdc 202 else return SOCK_BUSY;
jbkim 0:2513c6696bdc 203 }
jbkim 0:2513c6696bdc 204 freesize = getSn_TxMAX(sn);
jbkim 0:2513c6696bdc 205 if (len > freesize) len = freesize; // check size not to exceed MAX size.
jbkim 0:2513c6696bdc 206 while(1)
jbkim 0:2513c6696bdc 207 {
jbkim 0:2513c6696bdc 208 freesize = getSn_TX_FSR(sn);
jbkim 0:2513c6696bdc 209 tmp = getSn_SR(sn);
jbkim 0:2513c6696bdc 210 if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
jbkim 0:2513c6696bdc 211 {
jbkim 0:2513c6696bdc 212 close(sn);
jbkim 0:2513c6696bdc 213 return SOCKERR_SOCKSTATUS;
jbkim 0:2513c6696bdc 214 }
jbkim 0:2513c6696bdc 215 if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
jbkim 0:2513c6696bdc 216 if(len <= freesize) break;
jbkim 0:2513c6696bdc 217 }
jbkim 0:2513c6696bdc 218 wiz_send_data(sn, buf, len);
jbkim 0:2513c6696bdc 219 setSn_CR(sn,Sn_CR_SEND);
jbkim 0:2513c6696bdc 220 /* wait to process the command... */
jbkim 0:2513c6696bdc 221 while(getSn_CR(sn));
jbkim 0:2513c6696bdc 222 sock_is_sending |= (1 << sn);
jbkim 0:2513c6696bdc 223 /*
jbkim 0:2513c6696bdc 224 if(sock_io_mode & (1<<sn)) return len;
jbkim 0:2513c6696bdc 225 while( ((tmp = getSn_IR(sn)) & Sn_IR_SENDOK) !=Sn_IR_SENDOK )
jbkim 0:2513c6696bdc 226 {
jbkim 0:2513c6696bdc 227 if(tmp & Sn_IR_TIMEOUT)
jbkim 0:2513c6696bdc 228 {
jbkim 0:2513c6696bdc 229 close(sn);
jbkim 0:2513c6696bdc 230 return SOCKERR_TIMEOUT;
jbkim 0:2513c6696bdc 231 }
jbkim 0:2513c6696bdc 232 }
jbkim 0:2513c6696bdc 233 setSn_IR(sn, Sn_IR_SENDOK);
jbkim 0:2513c6696bdc 234 */
jbkim 0:2513c6696bdc 235 return len;
jbkim 0:2513c6696bdc 236 }
jbkim 0:2513c6696bdc 237
jbkim 0:2513c6696bdc 238
jbkim 0:2513c6696bdc 239 int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len)
jbkim 0:2513c6696bdc 240 {
jbkim 0:2513c6696bdc 241 uint8_t tmp = 0;
jbkim 0:2513c6696bdc 242 uint16_t recvsize = 0;
jbkim 0:2513c6696bdc 243 CHECK_SOCKNUM();
jbkim 0:2513c6696bdc 244 CHECK_SOCKMODE(Sn_MR_TCP);
jbkim 0:2513c6696bdc 245 CHECK_SOCKDATA();
jbkim 0:2513c6696bdc 246
jbkim 0:2513c6696bdc 247 recvsize = getSn_RxMAX(sn);
jbkim 0:2513c6696bdc 248 if(recvsize < len) len = recvsize;
jbkim 0:2513c6696bdc 249 while(1)
jbkim 0:2513c6696bdc 250 {
jbkim 0:2513c6696bdc 251 recvsize = getSn_RX_RSR(sn);
jbkim 0:2513c6696bdc 252 tmp = getSn_SR(sn);
jbkim 0:2513c6696bdc 253 if (tmp != SOCK_ESTABLISHED)
jbkim 0:2513c6696bdc 254 {
jbkim 0:2513c6696bdc 255 if(tmp == SOCK_CLOSE_WAIT)
jbkim 0:2513c6696bdc 256 {
jbkim 0:2513c6696bdc 257 if(recvsize != 0) break;
jbkim 0:2513c6696bdc 258 else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn))
jbkim 0:2513c6696bdc 259 {
jbkim 0:2513c6696bdc 260 close(sn);
jbkim 0:2513c6696bdc 261 return SOCKERR_SOCKSTATUS;
jbkim 0:2513c6696bdc 262 }
jbkim 0:2513c6696bdc 263 }
jbkim 0:2513c6696bdc 264 else
jbkim 0:2513c6696bdc 265 {
jbkim 0:2513c6696bdc 266 close(sn);
jbkim 0:2513c6696bdc 267 return SOCKERR_SOCKSTATUS;
jbkim 0:2513c6696bdc 268 }
jbkim 0:2513c6696bdc 269 }
jbkim 0:2513c6696bdc 270 if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY;
jbkim 0:2513c6696bdc 271 if(recvsize != 0) break;
jbkim 0:2513c6696bdc 272 };
jbkim 0:2513c6696bdc 273 if(recvsize < len) len = recvsize;
jbkim 0:2513c6696bdc 274 wiz_recv_data(sn, buf, len);
jbkim 0:2513c6696bdc 275 setSn_CR(sn,Sn_CR_RECV);
jbkim 0:2513c6696bdc 276 while(getSn_CR(sn));
jbkim 0:2513c6696bdc 277 return len;
jbkim 0:2513c6696bdc 278 }
jbkim 0:2513c6696bdc 279
jbkim 0:2513c6696bdc 280 int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port)
jbkim 0:2513c6696bdc 281 {
jbkim 0:2513c6696bdc 282 uint8_t tmp = 0;
jbkim 0:2513c6696bdc 283 uint16_t freesize = 0;
jbkim 0:2513c6696bdc 284 CHECK_SOCKNUM();
jbkim 0:2513c6696bdc 285 //CHECK_SOCKMODE(Sn_MR_UDP);
jbkim 0:2513c6696bdc 286 switch(getSn_MR(sn) & 0x0F)
jbkim 0:2513c6696bdc 287 {
jbkim 0:2513c6696bdc 288 case Sn_MR_UDP:
jbkim 0:2513c6696bdc 289 case Sn_MR_MACRAW:
jbkim 0:2513c6696bdc 290 break;
jbkim 0:2513c6696bdc 291 default:
jbkim 0:2513c6696bdc 292 return SOCKERR_SOCKMODE;
jbkim 0:2513c6696bdc 293 }
jbkim 0:2513c6696bdc 294 CHECK_SOCKDATA();
jbkim 0:2513c6696bdc 295 if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
jbkim 0:2513c6696bdc 296 if(port == 0) return SOCKERR_PORTZERO;
jbkim 0:2513c6696bdc 297 tmp = getSn_SR(sn);
jbkim 0:2513c6696bdc 298 if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS;
jbkim 0:2513c6696bdc 299
jbkim 0:2513c6696bdc 300 if( sock_is_sending & (1<<sn) )
jbkim 0:2513c6696bdc 301 {
jbkim 0:2513c6696bdc 302 tmp = getSn_IR(sn);
jbkim 0:2513c6696bdc 303 if(tmp & Sn_IR_SENDOK)
jbkim 0:2513c6696bdc 304 {
jbkim 0:2513c6696bdc 305 setSn_IR(sn, Sn_IR_SENDOK);
jbkim 0:2513c6696bdc 306 sock_is_sending &= ~(1<<sn);
jbkim 0:2513c6696bdc 307 }
jbkim 0:2513c6696bdc 308 else if(tmp & Sn_IR_TIMEOUT)
jbkim 0:2513c6696bdc 309 {
jbkim 0:2513c6696bdc 310 close(sn);
jbkim 0:2513c6696bdc 311 return SOCKERR_TIMEOUT;
jbkim 0:2513c6696bdc 312 }
jbkim 0:2513c6696bdc 313 else return SOCK_BUSY;
jbkim 0:2513c6696bdc 314 }
jbkim 0:2513c6696bdc 315
jbkim 0:2513c6696bdc 316 setSn_DIPR(sn,addr);
jbkim 0:2513c6696bdc 317 setSn_DPORT(sn,port);
jbkim 0:2513c6696bdc 318 freesize = getSn_TxMAX(sn);
jbkim 0:2513c6696bdc 319 if (len > freesize) len = freesize; // check size not to exceed MAX size.
jbkim 0:2513c6696bdc 320 while(1)
jbkim 0:2513c6696bdc 321 {
jbkim 0:2513c6696bdc 322 freesize = getSn_TX_FSR(sn);
jbkim 0:2513c6696bdc 323 if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
jbkim 0:2513c6696bdc 324 if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
jbkim 0:2513c6696bdc 325 if(len <= freesize) break;
jbkim 0:2513c6696bdc 326 };
jbkim 0:2513c6696bdc 327 wiz_send_data(sn, buf, len);
jbkim 0:2513c6696bdc 328 // setSUBR(); // set the subnet mask register
jbkim 0:2513c6696bdc 329 setSn_CR(sn,Sn_CR_SEND);
jbkim 0:2513c6696bdc 330 /* wait to process the command... */
jbkim 0:2513c6696bdc 331 while(getSn_CR(sn));
jbkim 0:2513c6696bdc 332 sock_is_sending |= (1<<sn);
jbkim 0:2513c6696bdc 333 #if 0
jbkim 0:2513c6696bdc 334 if(sock_io_mode & (1<<sn)) return len;
jbkim 0:2513c6696bdc 335 while ( ((tmp = getSn_IR(sn)) & Sn_IR_SENDOK) != Sn_IR_SENDOK )
jbkim 0:2513c6696bdc 336 {
jbkim 0:2513c6696bdc 337 if(tmp & Sn_IR_TIMEOUT)
jbkim 0:2513c6696bdc 338 {
jbkim 0:2513c6696bdc 339 setSn_IR(sn, (Sn_IR_SENDOK | Sn_IR_TIMEOUT)); /* clear SEND_OK & TIMEOUT */
jbkim 0:2513c6696bdc 340 return SOCKERR_TIMEOUT;
jbkim 0:2513c6696bdc 341 }
jbkim 0:2513c6696bdc 342 }
jbkim 0:2513c6696bdc 343 // clearSUBR(); // clear the subnet mask again and keep it because of the ARP errata of W5100
jbkim 0:2513c6696bdc 344 setSn_IR(sn, Sn_IR_SENDOK);
jbkim 0:2513c6696bdc 345 #endif
jbkim 0:2513c6696bdc 346 return len;
jbkim 0:2513c6696bdc 347 }
jbkim 0:2513c6696bdc 348
jbkim 0:2513c6696bdc 349
jbkim 0:2513c6696bdc 350
jbkim 0:2513c6696bdc 351 int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port, uint8_t* packinfo)
jbkim 0:2513c6696bdc 352 {
jbkim 0:2513c6696bdc 353 uint8_t mr;
jbkim 0:2513c6696bdc 354 uint8_t head[8];
jbkim 0:2513c6696bdc 355 uint16_t pack_len=0;
jbkim 0:2513c6696bdc 356
jbkim 0:2513c6696bdc 357 CHECK_SOCKNUM();
jbkim 0:2513c6696bdc 358 //CHECK_SOCKMODE(Sn_MR_UDP);
jbkim 0:2513c6696bdc 359 switch((mr=getSn_MR(sn)) & 0x0F)
jbkim 0:2513c6696bdc 360 {
jbkim 0:2513c6696bdc 361 case Sn_MR_UDP:
jbkim 0:2513c6696bdc 362 case Sn_MR_MACRAW:
jbkim 0:2513c6696bdc 363 break;
jbkim 0:2513c6696bdc 364 default:
jbkim 0:2513c6696bdc 365 return SOCKERR_SOCKMODE;
jbkim 0:2513c6696bdc 366 }
jbkim 0:2513c6696bdc 367 CHECK_SOCKDATA();
jbkim 0:2513c6696bdc 368 if(sock_remained_size[sn] == 0)
jbkim 0:2513c6696bdc 369 {
jbkim 0:2513c6696bdc 370 while(1)
jbkim 0:2513c6696bdc 371 {
jbkim 0:2513c6696bdc 372 pack_len = getSn_RX_RSR(sn);
jbkim 0:2513c6696bdc 373 if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
jbkim 0:2513c6696bdc 374 if( (sock_io_mode & (1<<sn)) && (pack_len == 0) ) return SOCK_BUSY;
jbkim 0:2513c6696bdc 375 if(pack_len != 0) break;
jbkim 0:2513c6696bdc 376 };
jbkim 0:2513c6696bdc 377 }
jbkim 0:2513c6696bdc 378 *packinfo = 0x00;
jbkim 0:2513c6696bdc 379 switch (mr & 0x07)
jbkim 0:2513c6696bdc 380 {
jbkim 0:2513c6696bdc 381 case Sn_MR_UDP :
jbkim 0:2513c6696bdc 382 if(sock_remained_size[sn] == 0)
jbkim 0:2513c6696bdc 383 {
jbkim 0:2513c6696bdc 384 wiz_recv_data(sn, head, 8);
jbkim 0:2513c6696bdc 385 setSn_CR(sn,Sn_CR_RECV);
jbkim 0:2513c6696bdc 386 while(getSn_CR(sn));
jbkim 0:2513c6696bdc 387 // read peer's IP address, port number & packet length
jbkim 0:2513c6696bdc 388 addr[0] = head[0];
jbkim 0:2513c6696bdc 389 addr[1] = head[1];
jbkim 0:2513c6696bdc 390 addr[2] = head[2];
jbkim 0:2513c6696bdc 391 addr[3] = head[3];
jbkim 0:2513c6696bdc 392 *port = head[4];
jbkim 0:2513c6696bdc 393 *port = (*port << 8) + head[5];
jbkim 0:2513c6696bdc 394 sock_remained_size[sn] = head[6];
jbkim 0:2513c6696bdc 395 sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7];
jbkim 0:2513c6696bdc 396 *packinfo = 0x80;
jbkim 0:2513c6696bdc 397 }
jbkim 0:2513c6696bdc 398 if(len < sock_remained_size[sn]) pack_len = len;
jbkim 0:2513c6696bdc 399 else pack_len = sock_remained_size[sn];
jbkim 0:2513c6696bdc 400 //
jbkim 0:2513c6696bdc 401 // Need to packet length check (default 1472)
jbkim 0:2513c6696bdc 402 //
jbkim 0:2513c6696bdc 403 wiz_recv_data(sn, buf, pack_len); // data copy.
jbkim 0:2513c6696bdc 404 break;
jbkim 0:2513c6696bdc 405 case Sn_MR_MACRAW :
jbkim 0:2513c6696bdc 406 if(sock_remained_size[sn] == 0)
jbkim 0:2513c6696bdc 407 {
jbkim 0:2513c6696bdc 408 wiz_recv_data(sn, head, 2);
jbkim 0:2513c6696bdc 409 setSn_CR(sn,Sn_CR_RECV);
jbkim 0:2513c6696bdc 410 while(getSn_CR(sn));
jbkim 0:2513c6696bdc 411 // read peer's IP address, port number & packet length
jbkim 0:2513c6696bdc 412 sock_remained_size[sn] = head[0];
jbkim 0:2513c6696bdc 413 sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1];
jbkim 0:2513c6696bdc 414 if(sock_remained_size[sn] > 1514)
jbkim 0:2513c6696bdc 415 {
jbkim 0:2513c6696bdc 416 close(sn);
jbkim 0:2513c6696bdc 417 return SOCKFATAL_PACKLEN;
jbkim 0:2513c6696bdc 418 }
jbkim 0:2513c6696bdc 419 }
jbkim 0:2513c6696bdc 420 if(len < sock_remained_size[sn]) pack_len = len;
jbkim 0:2513c6696bdc 421 else pack_len = sock_remained_size[sn];
jbkim 0:2513c6696bdc 422 wiz_recv_data(sn,buf,pack_len);
jbkim 0:2513c6696bdc 423 break;
jbkim 0:2513c6696bdc 424 default:
jbkim 0:2513c6696bdc 425 wiz_recv_ignore(sn, pack_len); // data copy.
jbkim 0:2513c6696bdc 426 sock_remained_size[sn] = pack_len;
jbkim 0:2513c6696bdc 427 break;
jbkim 0:2513c6696bdc 428 }
jbkim 0:2513c6696bdc 429 setSn_CR(sn,Sn_CR_RECV);
jbkim 0:2513c6696bdc 430 /* wait to process the command... */
jbkim 0:2513c6696bdc 431 while(getSn_CR(sn)) ;
jbkim 0:2513c6696bdc 432 sock_remained_size[sn] -= pack_len;
jbkim 0:2513c6696bdc 433 if(sock_remained_size[sn] != 0) *packinfo |= 0x01;
jbkim 0:2513c6696bdc 434 return pack_len;
jbkim 0:2513c6696bdc 435 }
jbkim 0:2513c6696bdc 436
jbkim 0:2513c6696bdc 437
jbkim 0:2513c6696bdc 438 int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg)
jbkim 0:2513c6696bdc 439 {
jbkim 0:2513c6696bdc 440 uint8_t tmp = 0;
jbkim 0:2513c6696bdc 441 CHECK_SOCKNUM();
jbkim 0:2513c6696bdc 442 switch(cstype)
jbkim 0:2513c6696bdc 443 {
jbkim 0:2513c6696bdc 444 case CS_SET_IOMODE:
jbkim 0:2513c6696bdc 445 tmp = *((uint8_t*)arg);
jbkim 0:2513c6696bdc 446 if(tmp == SOCK_IO_NONBLOCK) sock_io_mode |= (1<<sn);
jbkim 0:2513c6696bdc 447 else if(tmp == SOCK_IO_BLOCK) sock_io_mode &= ~(1<<sn);
jbkim 0:2513c6696bdc 448 else return SOCKERR_ARG;
jbkim 0:2513c6696bdc 449 break;
jbkim 0:2513c6696bdc 450 case CS_GET_IOMODE:
jbkim 0:2513c6696bdc 451 *((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001;
jbkim 0:2513c6696bdc 452 break;
jbkim 0:2513c6696bdc 453 case CS_GET_MAXTXBUF:
jbkim 0:2513c6696bdc 454 *((uint16_t*)arg) = getSn_TxMAX(sn);
jbkim 0:2513c6696bdc 455 break;
jbkim 0:2513c6696bdc 456 case CS_GET_MAXRXBUF:
jbkim 0:2513c6696bdc 457 *((uint16_t*)arg) = getSn_RxMAX(sn);
jbkim 0:2513c6696bdc 458 break;
jbkim 0:2513c6696bdc 459 case CS_CLR_INTERRUPT:
jbkim 0:2513c6696bdc 460 if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
jbkim 0:2513c6696bdc 461 setSn_IR(sn,*(uint8_t*)arg);
jbkim 0:2513c6696bdc 462 break;
jbkim 0:2513c6696bdc 463 case CS_GET_INTERRUPT:
jbkim 0:2513c6696bdc 464 *((uint8_t*)arg) = getSn_IR(sn);
jbkim 0:2513c6696bdc 465 break;
jbkim 0:2513c6696bdc 466 case CS_SET_INTMASK:
jbkim 0:2513c6696bdc 467 if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
jbkim 0:2513c6696bdc 468 setSn_IMR(sn,*(uint8_t*)arg);
jbkim 0:2513c6696bdc 469 break;
jbkim 0:2513c6696bdc 470 case CS_GET_INTMASK:
jbkim 0:2513c6696bdc 471 *((uint8_t*)arg) = getSn_IMR(sn);
jbkim 0:2513c6696bdc 472 default:
jbkim 0:2513c6696bdc 473 return SOCKERR_ARG;
jbkim 0:2513c6696bdc 474 }
jbkim 0:2513c6696bdc 475 return SOCK_OK;
jbkim 0:2513c6696bdc 476 }
jbkim 0:2513c6696bdc 477
jbkim 0:2513c6696bdc 478 int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg)
jbkim 0:2513c6696bdc 479 {
jbkim 0:2513c6696bdc 480
jbkim 0:2513c6696bdc 481 CHECK_SOCKNUM();
jbkim 0:2513c6696bdc 482 switch(sotype)
jbkim 0:2513c6696bdc 483 {
jbkim 0:2513c6696bdc 484 case SO_TTL:
jbkim 0:2513c6696bdc 485 setSn_TTL(sn,*(uint8_t*)arg);
jbkim 0:2513c6696bdc 486 break;
jbkim 0:2513c6696bdc 487 case SO_TOS:
jbkim 0:2513c6696bdc 488 setSn_TOS(sn,*(uint8_t*)arg);
jbkim 0:2513c6696bdc 489 break;
jbkim 0:2513c6696bdc 490 case SO_MSS:
jbkim 0:2513c6696bdc 491 setSn_MSSR(sn,*(uint16_t*)arg);
jbkim 0:2513c6696bdc 492 break;
jbkim 0:2513c6696bdc 493 case SO_DESTIP:
jbkim 0:2513c6696bdc 494 setSn_DIPR(sn, (uint8_t*)arg);
jbkim 0:2513c6696bdc 495 break;
jbkim 0:2513c6696bdc 496 case SO_DESTPORT:
jbkim 0:2513c6696bdc 497 setSn_DPORT(sn, *(uint16_t*)arg);
jbkim 0:2513c6696bdc 498 break;
jbkim 0:2513c6696bdc 499 case SO_KEEPALIVESEND:
jbkim 0:2513c6696bdc 500 CHECK_SOCKMODE(Sn_MR_TCP);
jbkim 0:2513c6696bdc 501 if(getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT;
jbkim 0:2513c6696bdc 502 setSn_CR(sn,Sn_CR_SEND_KEEP);
jbkim 0:2513c6696bdc 503 while(getSn_CR(sn) != 0)
jbkim 0:2513c6696bdc 504 {
jbkim 0:2513c6696bdc 505 if (getSn_IR(sn) & Sn_IR_TIMEOUT)
jbkim 0:2513c6696bdc 506 {
jbkim 0:2513c6696bdc 507 setSn_IR(sn, Sn_IR_TIMEOUT);
jbkim 0:2513c6696bdc 508 return SOCKERR_TIMEOUT;
jbkim 0:2513c6696bdc 509 }
jbkim 0:2513c6696bdc 510 }
jbkim 0:2513c6696bdc 511 break;
jbkim 0:2513c6696bdc 512 case SO_KEEPALIVEAUTO:
jbkim 0:2513c6696bdc 513 CHECK_SOCKMODE(Sn_MR_TCP);
jbkim 0:2513c6696bdc 514 setSn_KPALVTR(sn,*(uint8_t*)arg);
jbkim 0:2513c6696bdc 515 break;
jbkim 0:2513c6696bdc 516 default:
jbkim 0:2513c6696bdc 517 return SOCKERR_ARG;
jbkim 0:2513c6696bdc 518 }
jbkim 0:2513c6696bdc 519 return SOCK_OK;
jbkim 0:2513c6696bdc 520 }
jbkim 0:2513c6696bdc 521
jbkim 0:2513c6696bdc 522 int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg)
jbkim 0:2513c6696bdc 523 {
jbkim 0:2513c6696bdc 524 CHECK_SOCKNUM();
jbkim 0:2513c6696bdc 525 switch(sotype)
jbkim 0:2513c6696bdc 526 {
jbkim 0:2513c6696bdc 527 case SO_FLAG:
jbkim 0:2513c6696bdc 528 *(uint8_t*)arg = getSn_MR(sn) & 0xF0;
jbkim 0:2513c6696bdc 529 break;
jbkim 0:2513c6696bdc 530 case SO_TTL:
jbkim 0:2513c6696bdc 531 *(uint8_t*) arg = getSn_TTL(sn);
jbkim 0:2513c6696bdc 532 break;
jbkim 0:2513c6696bdc 533 case SO_TOS:
jbkim 0:2513c6696bdc 534 *(uint8_t*) arg = getSn_TOS(sn);
jbkim 0:2513c6696bdc 535 break;
jbkim 0:2513c6696bdc 536 case SO_MSS:
jbkim 0:2513c6696bdc 537 *(uint8_t*) arg = getSn_MSSR(sn);
jbkim 0:2513c6696bdc 538 case SO_DESTIP:
jbkim 0:2513c6696bdc 539 getSn_DIPR(sn, (uint8_t*)arg);
jbkim 0:2513c6696bdc 540 break;
jbkim 0:2513c6696bdc 541 case SO_DESTPORT:
jbkim 0:2513c6696bdc 542 *(uint16_t*) arg = getSn_DPORT(sn);
jbkim 0:2513c6696bdc 543 break;
jbkim 0:2513c6696bdc 544 case SO_KEEPALIVEAUTO:
jbkim 0:2513c6696bdc 545 CHECK_SOCKMODE(Sn_MR_TCP);
jbkim 0:2513c6696bdc 546 *(uint16_t*) arg = getSn_KPALVTR(sn);
jbkim 0:2513c6696bdc 547 break;
jbkim 0:2513c6696bdc 548 case SO_SENDBUF:
jbkim 0:2513c6696bdc 549 *(uint16_t*) arg = getSn_TX_FSR(sn);
jbkim 0:2513c6696bdc 550 case SO_RECVBUF:
jbkim 0:2513c6696bdc 551 *(uint16_t*) arg = getSn_RX_RSR(sn);
jbkim 0:2513c6696bdc 552 case SO_STATUS:
jbkim 0:2513c6696bdc 553 *(uint8_t*) arg = getSn_SR(sn);
jbkim 0:2513c6696bdc 554 break;
jbkim 0:2513c6696bdc 555 case SO_REMAINSIZE:
jbkim 0:2513c6696bdc 556 if(getSn_MR(sn) == Sn_MR_TCP)
jbkim 0:2513c6696bdc 557 *(uint16_t*)arg = getSn_RX_RSR(sn);
jbkim 0:2513c6696bdc 558 else
jbkim 0:2513c6696bdc 559 *(uint16_t*)arg = sock_remained_size[sn];
jbkim 0:2513c6696bdc 560 break;
jbkim 0:2513c6696bdc 561 default:
jbkim 0:2513c6696bdc 562 return SOCKERR_SOCKOPT;
jbkim 0:2513c6696bdc 563 }
jbkim 0:2513c6696bdc 564 return SOCK_OK;
jbkim 0:2513c6696bdc 565 }