socket.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845
  1. #include "stdio.h"
  2. #include "bsp.h"
  3. #include "socket.h"
  4. #include "w5500.h"
  5. #include "types.h"
  6. #include "utils.h"
  7. #define W5500_POLL_WAIT
  8. static uint32_t local_port;
  9. //extern uint16_t sent_ptr;
  10. #if 1
  11. /**
  12. @brief This Socket function initialize the channel in perticular mode, and set the port and wait for W5200 done it.
  13. @return 0: ongoing; 1 for sucess; 0xff: error.
  14. */
  15. uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag)
  16. {
  17. uint8_t ret;
  18. static uint32_t sockState=0;
  19. if (
  20. ((protocol&0x0F) == Sn_MR_TCP) ||
  21. ((protocol&0x0F) == Sn_MR_UDP) ||
  22. ((protocol&0x0F) == Sn_MR_IPRAW) ||
  23. ((protocol&0x0F) == Sn_MR_MACRAW) ||
  24. ((protocol&0x0F) == Sn_MR_PPPOE)
  25. )
  26. {
  27. switch(sockState)
  28. {
  29. case 0:
  30. close(s);//Force to close socket!!!
  31. IINCHIP_WRITE(Sn_MR(s) ,protocol | flag);
  32. if (port != 0) {
  33. IINCHIP_WRITE( Sn_PORT0(s) ,(uint8_t)((port & 0xff00) >> 8));
  34. IINCHIP_WRITE( Sn_PORT1(s) ,(uint8_t)(port & 0x00ff));
  35. } else {
  36. local_port++; // if don't set the source port, set local_port number.
  37. IINCHIP_WRITE(Sn_PORT0(s) ,(uint8_t)((local_port & 0xff00) >> 8));
  38. IINCHIP_WRITE(Sn_PORT1(s) ,(uint8_t)(local_port & 0x00ff));
  39. }
  40. IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_OPEN); // run sockinit Sn_CR
  41. sockState=1;
  42. case 1:
  43. /* wait to process the command... */
  44. if( IINCHIP_READ(Sn_CR(s)) )
  45. {
  46. return 0;
  47. }
  48. sockState=2;
  49. case 2:
  50. /* ------- */
  51. if(IINCHIP_READ(Sn_SR(s)) != SOCK_INIT )
  52. {
  53. return 0;
  54. }
  55. default:
  56. sockState = 0;
  57. break;
  58. }
  59. ret = 1;
  60. }
  61. else
  62. {
  63. ret = 0xff;
  64. }
  65. return ret;
  66. }
  67. /**
  68. @brief This function close the socket and parameter is "s" which represent the socket number
  69. @return 0: ongoing; 1 for sucess; 0xff: error.
  70. */
  71. uint8_t close(SOCKET s)
  72. {
  73. static uint32_t closeState=0;
  74. switch(closeState)
  75. {
  76. case 0:
  77. IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_CLOSE);
  78. closeState=1;
  79. case 1:
  80. /* wait to process the command... */
  81. if( IINCHIP_READ(Sn_CR(s) ) )
  82. {
  83. return 0;
  84. }
  85. default:
  86. /* all clear */
  87. IINCHIP_WRITE( Sn_IR(s) , 0xFF);
  88. closeState=0;
  89. break;
  90. }
  91. return 1;
  92. }
  93. /**
  94. @brief This function established the connection for the channel in passive (server) mode.
  95. This function waits for the request from the peer.
  96. @return 0: ongoing; 1 for sucess; 0xff: error.
  97. */
  98. uint8_t listen(SOCKET s)
  99. {
  100. static uint32_t listenState=0;
  101. uint8_t ret; // LISTEN command send to Sn_CR, If succeed, set it to 1, otherwise clear it to 0
  102. ret = IINCHIP_READ( Sn_SR(s) );
  103. if (ret == SOCK_INIT) // if init, set it
  104. {
  105. switch(listenState)
  106. {
  107. case 0:
  108. IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_LISTEN); //MCU sets W5500 into listen mode
  109. listenState=1;
  110. case 1:
  111. if( IINCHIP_READ(Sn_CR(s) ) ) // Configure finished, Sn_CR is cleared automatically
  112. {
  113. return 0;
  114. }
  115. default:
  116. listenState=0;
  117. break;
  118. }
  119. ret = 1; //ret=1 means: LISTEN command is excuted successfully
  120. }
  121. else
  122. {
  123. if(ret == SOCK_LISTEN)
  124. {
  125. ret = 1;
  126. }
  127. else
  128. {
  129. ret = 0xff; // fails
  130. }
  131. listenState=0;
  132. }
  133. return ret;
  134. }
  135. /**
  136. @brief This function established the connection for the channel in Active (client) mode.
  137. This function waits for the untill the connection is established.
  138. @return 1 for success else 0.
  139. */
  140. uint8_t connect(SOCKET s, uint8_t * addr, uint16_t port)
  141. {
  142. static uint32_t connState=0;
  143. uint8_t ret;
  144. if(
  145. ((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
  146. ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
  147. (port == 0x0000)
  148. )
  149. {
  150. return 0xff;
  151. }
  152. switch( connState)
  153. {
  154. case 0:
  155. // set destination IP
  156. IINCHIP_WRITE( Sn_DIPR0(s), addr[0]);
  157. IINCHIP_WRITE( Sn_DIPR1(s), addr[1]);
  158. IINCHIP_WRITE( Sn_DIPR2(s), addr[2]);
  159. IINCHIP_WRITE( Sn_DIPR3(s), addr[3]);
  160. IINCHIP_WRITE( Sn_DPORT0(s), (uint8_t)((port & 0xff00) >> 8));
  161. IINCHIP_WRITE( Sn_DPORT1(s), (uint8_t)(port & 0x00ff));
  162. IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_CONNECT);
  163. connState=1;
  164. case 1:
  165. /* wait for completion */
  166. if(IINCHIP_READ(Sn_CR(s)))
  167. {
  168. return 0;
  169. }
  170. connState=2;
  171. case 2:
  172. ret = IINCHIP_READ(Sn_SR(s));
  173. if ( ret != SOCK_SYNSENT )//
  174. {
  175. if(ret == SOCK_ESTABLISHED)
  176. {
  177. connState=0;
  178. return 1;//success
  179. }
  180. else if(SOCK_INIT == ret)
  181. {
  182. connState=0;//reset state
  183. return 0;
  184. }
  185. else if(SOCK_INIT > ret)
  186. {
  187. connState=0;//reset state
  188. setSn_CR(s,Sn_CR_CLOSE);
  189. return 0xff;
  190. }
  191. ret=getSn_IR(s);
  192. if( ret & Sn_IR_TIMEOUT)
  193. {
  194. IINCHIP_WRITE(Sn_IR(s), (Sn_IR_TIMEOUT)); // clear TIMEOUT Interrupt
  195. connState=0;
  196. return 0xff;//failed
  197. }
  198. if(ret & Sn_IR_DISCON)
  199. {
  200. IINCHIP_WRITE(Sn_IR(s), (Sn_IR_DISCON)); // clear TIMEOUT Interrupt
  201. connState=0;
  202. return 0xff;//failed
  203. }
  204. return 0;
  205. }
  206. /*if(ret == SOCK_ESTABLISHED)
  207. {//connected
  208. connState=0;
  209. return 1;//success
  210. }
  211. else if(SOCK_INIT == ret)
  212. {//state error
  213. connState=0;//reset state
  214. return 0;
  215. }
  216. else if(SOCK_INIT > ret)
  217. {//state error
  218. connState=0;//reset state
  219. setSn_CR(s,Sn_CR_CLOSE);
  220. return 0xff;
  221. }
  222. //else if(SOCK_FIN_WAIT<=ret)
  223. //{
  224. // ;
  225. //}
  226. else if(SOCK_SYNSENT==ret || SOCK_SYNRECV==ret )
  227. {//connecting
  228. //return 0;
  229. }
  230. ret=getSn_IR(s);
  231. if( ret & Sn_IR_TIMEOUT)
  232. {
  233. IINCHIP_WRITE(Sn_IR(s), (Sn_IR_TIMEOUT)); // clear TIMEOUT Interrupt
  234. connState=0;
  235. return 0xff;//failed
  236. }
  237. if(ret & Sn_IR_DISCON)
  238. {
  239. IINCHIP_WRITE(Sn_IR(s), (Sn_IR_DISCON)); // clear TIMEOUT Interrupt
  240. connState=0;
  241. return 0xff;//failed
  242. }
  243. return 0;*/
  244. /*if ( IINCHIP_READ(Sn_SR(s)) != SOCK_SYNSENT )//??
  245. {
  246. ret = IINCHIP_READ(Sn_SR(s));
  247. if(ret == SOCK_ESTABLISHED)
  248. {
  249. connState=0;
  250. return 1;//success
  251. }
  252. else if(SOCK_CLOSED == ret)
  253. {
  254. connState=0;
  255. return 0xff;//failed
  256. }
  257. else if(SOCK_INIT == ret)
  258. {
  259. connState=0;//reset state
  260. return 0;
  261. }
  262. else if(SOCK_INIT >= ret)
  263. {
  264. connState=0;//reset state
  265. setSn_CR(s,Sn_CR_CLOSE);
  266. return 0xff;
  267. }
  268. ret=getSn_IR(s);
  269. if( ret & Sn_IR_TIMEOUT)
  270. {
  271. IINCHIP_WRITE(Sn_IR(s), (Sn_IR_TIMEOUT)); // clear TIMEOUT Interrupt
  272. connState=0;
  273. return 0xff;//failed
  274. }
  275. if(ret & Sn_IR_DISCON)
  276. {
  277. IINCHIP_WRITE(Sn_IR(s), (Sn_IR_DISCON)); // clear TIMEOUT Interrupt
  278. connState=0;
  279. return 0xff;//failed
  280. }
  281. return 0;
  282. }*/
  283. default:
  284. connState=0;
  285. break;
  286. }
  287. ret=1;
  288. return ret;
  289. }
  290. /**
  291. @brief This function used for disconnect the socket and parameter is "s" which represent the socket number
  292. @return 1 for success else 0.
  293. */
  294. uint8_t disconnect(SOCKET s)
  295. {
  296. static uint32_t discState=0;
  297. switch(discState)
  298. {
  299. case 0:
  300. IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_DISCON);
  301. discState=1;
  302. case 1:
  303. /* wait to process the command... */
  304. if( IINCHIP_READ(Sn_CR(s) ) )
  305. {
  306. return 0;
  307. }
  308. default:
  309. discState=1;
  310. break;
  311. }
  312. return 1;
  313. }
  314. #else
  315. /**
  316. @brief This Socket function initialize the channel in perticular mode, and set the port and wait for W5200 done it.
  317. @return 1 for sucess else 0.
  318. */
  319. uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag)
  320. {
  321. uint8_t ret;
  322. if (
  323. ((protocol&0x0F) == Sn_MR_TCP) ||
  324. ((protocol&0x0F) == Sn_MR_UDP) ||
  325. ((protocol&0x0F) == Sn_MR_IPRAW) ||
  326. ((protocol&0x0F) == Sn_MR_MACRAW) ||
  327. ((protocol&0x0F) == Sn_MR_PPPOE)
  328. )
  329. {
  330. close(s);
  331. IINCHIP_WRITE(Sn_MR(s) ,protocol | flag);
  332. if (port != 0) {
  333. IINCHIP_WRITE( Sn_PORT0(s) ,(uint8_t)((port & 0xff00) >> 8));
  334. IINCHIP_WRITE( Sn_PORT1(s) ,(uint8_t)(port & 0x00ff));
  335. } else {
  336. local_port++; // if don't set the source port, set local_port number.
  337. IINCHIP_WRITE(Sn_PORT0(s) ,(uint8_t)((local_port & 0xff00) >> 8));
  338. IINCHIP_WRITE(Sn_PORT1(s) ,(uint8_t)(local_port & 0x00ff));
  339. }
  340. IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_OPEN); // run sockinit Sn_CR
  341. /* wait to process the command... */
  342. while( IINCHIP_READ(Sn_CR(s)) )
  343. {
  344. ;
  345. }
  346. /* ------- */
  347. while(IINCHIP_READ(Sn_SR(s)) != SOCK_INIT )
  348. {
  349. ;
  350. }
  351. ret = 1;
  352. }
  353. else
  354. {
  355. ret = 0;
  356. }
  357. return ret;
  358. }
  359. /**
  360. @brief This function close the socket and parameter is "s" which represent the socket number
  361. */
  362. void close(SOCKET s)
  363. {
  364. IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_CLOSE);
  365. /* wait to process the command... */
  366. while( IINCHIP_READ(Sn_CR(s) ) )
  367. {
  368. ;
  369. }
  370. /* ------- */
  371. /* all clear */
  372. IINCHIP_WRITE( Sn_IR(s) , 0xFF);
  373. }
  374. /**
  375. @brief This function established the connection for the channel in passive (server) mode.
  376. This function waits for the request from the peer.
  377. @return 1 for success else 0.
  378. */
  379. uint8_t listen(SOCKET s)
  380. {
  381. uint8_t ret;
  382. if (IINCHIP_READ( Sn_SR(s) ) == SOCK_INIT) // Sn_SR is init
  383. {
  384. IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_LISTEN); // set W5500 to start listen
  385. while( IINCHIP_READ(Sn_CR(s) ) ) // after in listen mode, Sn_CR is cleared automatically
  386. {
  387. ;
  388. }
  389. ret = 1; // in LISTEN mode, ret=1
  390. }
  391. else
  392. {
  393. ret = 0; // fails, ret=0
  394. }
  395. return ret;
  396. }
  397. /**
  398. @brief This function established the connection for the channel in Active (client) mode.
  399. This function waits for the untill the connection is established.
  400. @return 1 for success else 0.
  401. */
  402. uint8_t connect(SOCKET s, uint8_t * addr, uint16_t port)
  403. {
  404. uint8_t ret;
  405. if(
  406. ((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
  407. ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
  408. (port == 0x0000)
  409. )
  410. {
  411. ret = 0;
  412. }
  413. else
  414. {
  415. // set destination IP
  416. IINCHIP_WRITE( Sn_DIPR0(s), addr[0]);
  417. IINCHIP_WRITE( Sn_DIPR1(s), addr[1]);
  418. IINCHIP_WRITE( Sn_DIPR2(s), addr[2]);
  419. IINCHIP_WRITE( Sn_DIPR3(s), addr[3]);
  420. IINCHIP_WRITE( Sn_DPORT0(s), (uint8_t)((port & 0xff00) >> 8));
  421. IINCHIP_WRITE( Sn_DPORT1(s), (uint8_t)(port & 0x00ff));
  422. IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_CONNECT);
  423. /* wait for completion */
  424. while(IINCHIP_READ(Sn_CR(s)))
  425. {
  426. ;
  427. }
  428. while ( IINCHIP_READ(Sn_SR(s)) != SOCK_SYNSENT )
  429. {
  430. ret = IINCHIP_READ(Sn_SR(s));
  431. if(ret == SOCK_ESTABLISHED)
  432. {
  433. ret = 1;
  434. break;
  435. }
  436. else if(SOCK_CLOSED == ret)
  437. {
  438. ret = 0;
  439. break;
  440. }
  441. ret=getSn_IR(s);
  442. if( ret & Sn_IR_TIMEOUT)
  443. {
  444. IINCHIP_WRITE(Sn_IR(s), (Sn_IR_TIMEOUT)); // clear TIMEOUT Interrupt
  445. ret = 0;
  446. break;
  447. }
  448. if(ret & Sn_IR_DISCON)
  449. {
  450. IINCHIP_WRITE(Sn_IR(s), (Sn_IR_DISCON)); // clear TIMEOUT Interrupt
  451. ret = 0;
  452. break;
  453. }
  454. }
  455. }
  456. return ret;
  457. }
  458. /**
  459. @brief This function used for disconnect the socket and parameter is "s" which represent the socket number
  460. @return 1 for success else 0.
  461. */
  462. void disconnect(SOCKET s)
  463. {
  464. IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_DISCON);
  465. /* wait to process the command... */
  466. while( IINCHIP_READ(Sn_CR(s) ) )
  467. {
  468. ;
  469. }
  470. /* ------- */
  471. }
  472. #endif
  473. /**
  474. @brief This function used to send the data in TCP mode
  475. @return 1 for success else 0.
  476. */
  477. uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len)
  478. {
  479. uint8_t status=0;
  480. uint16_t ret=0;
  481. uint16_t freesize=0;
  482. if (len > getIINCHIP_TxMAX(s))
  483. ret = getIINCHIP_TxMAX(s);
  484. else
  485. ret = len;
  486. do
  487. {
  488. freesize = getSn_TX_FSR(s);
  489. status = IINCHIP_READ(Sn_SR(s));
  490. if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT))
  491. {
  492. ret = 0;
  493. break;
  494. }
  495. } while (freesize < ret);
  496. send_data_processing(s, (uint8_t *)buf, ret);
  497. IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_SEND);
  498. while( IINCHIP_READ(Sn_CR(s) ) );
  499. #ifndef W5500_INT_MODE
  500. while ( (IINCHIP_READ(Sn_IR(s) ) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
  501. {
  502. status = IINCHIP_READ(Sn_SR(s));
  503. if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT) )
  504. {
  505. printf("SEND_OK Problem!!\r\n");
  506. close(s);
  507. return 0;
  508. }
  509. }
  510. IINCHIP_WRITE( Sn_IR(s) , Sn_IR_SEND_OK);
  511. IINCHIP_WRITE( Sn_IR(s) , Sn_IR_SEND_OK);
  512. #endif
  513. return ret;
  514. }
  515. /**
  516. @brief This function is an application I/F function which is used to receive the data in TCP mode.
  517. It continues to wait for data as much as the application wants to receive.
  518. @return received data size for success else -1.
  519. */
  520. uint16_t recv(SOCKET s, uint8_t * buf, uint16_t len)
  521. {
  522. uint16_t ret=0;
  523. if ( len > 0 )
  524. {
  525. recv_data_processing(s, buf, len); // data recv progress: get recv data from socket recv buffer and store to mcu buffer pointed by *buf
  526. IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_RECV); // MCU set Sn_CR to RECV
  527. while( IINCHIP_READ(Sn_CR(s) )); // After in recv state, Sn_CR is cleared automatically
  528. ret = len; // get the length to ret
  529. }
  530. return ret;
  531. }
  532. /**
  533. @brief This function is an application I/F function which is used to send the data for other then TCP mode.
  534. Unlike TCP transmission, The peer's destination address and the port is needed.
  535. @return This function return send data size for success else -1.
  536. */
  537. uint8_t Server_MAC[6]={0};
  538. #define Sn_DHAR0(ch) (0x000608 + (ch<<5))
  539. #define Sn_DHAR1(ch) (0x000708 + (ch<<5))
  540. #define Sn_DHAR2(ch) (0x000808 + (ch<<5))
  541. #define Sn_DHAR3(ch) (0x000908 + (ch<<5))
  542. #define Sn_DHAR4(ch) (0x000A08 + (ch<<5))
  543. #define Sn_DHAR5(ch) (0x000B08 + (ch<<5))
  544. uint16_t sendto(SOCKET s, const uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port)
  545. {
  546. uint8_t status;
  547. uint16_t ret=0;
  548. if (len > getIINCHIP_TxMAX(s))
  549. ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
  550. else
  551. ret = len;
  552. if( ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) || ((port == 0x00)) )//||(ret == 0) )
  553. {
  554. /* added return value */
  555. ret = 0;
  556. }
  557. else
  558. {
  559. IINCHIP_WRITE( Sn_DIPR0(s), addr[0]);
  560. IINCHIP_WRITE( Sn_DIPR1(s), addr[1]);
  561. IINCHIP_WRITE( Sn_DIPR2(s), addr[2]);
  562. IINCHIP_WRITE( Sn_DIPR3(s), addr[3]);
  563. IINCHIP_WRITE( Sn_DPORT0(s),(uint8_t)((port & 0xff00) >> 8));
  564. IINCHIP_WRITE( Sn_DPORT1(s),(uint8_t)(port & 0x00ff));
  565. // copy data
  566. send_data_processing(s, (uint8_t *)buf, ret);
  567. IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_SEND);
  568. //IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_SEND_MAC);
  569. /* wait to process the command... */
  570. /*while( IINCHIP_READ( Sn_CR(s) ) )
  571. ;*/
  572. do
  573. {
  574. status = IINCHIP_READ( Sn_CR(s));
  575. }while(status);
  576. /* ------- */
  577. /*while( (IINCHIP_READ( Sn_IR(s) ) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
  578. {
  579. if (IINCHIP_READ( Sn_IR(s) ) & Sn_IR_TIMEOUT)
  580. {
  581. // clear interrupt: SEND_OK & TIMEOUT
  582. IINCHIP_WRITE( Sn_IR(s) , (Sn_IR_SEND_OK | Sn_IR_TIMEOUT));
  583. return 0;
  584. }
  585. }*/
  586. do
  587. {
  588. status = IINCHIP_READ( Sn_IR(s));
  589. if ( status & Sn_IR_TIMEOUT)
  590. {// clear interrupt: SEND_OK & TIMEOUT
  591. IINCHIP_WRITE( Sn_IR(s) , (Sn_IR_SEND_OK | Sn_IR_TIMEOUT));
  592. return 0;
  593. }
  594. } while( (status & Sn_IR_SEND_OK) != Sn_IR_SEND_OK );
  595. IINCHIP_WRITE( Sn_IR(s) , Sn_IR_SEND_OK);
  596. status++;
  597. // Server_MAC[0] = IINCHIP_READ(Sn_DHAR0(s));
  598. // Server_MAC[1] = IINCHIP_READ(Sn_DHAR1(s));
  599. // Server_MAC[2] = IINCHIP_READ(Sn_DHAR2(s));
  600. // Server_MAC[3] = IINCHIP_READ(Sn_DHAR3(s));
  601. // Server_MAC[4] = IINCHIP_READ(Sn_DHAR4(s));
  602. // Server_MAC[5] = IINCHIP_READ(Sn_DHAR5(s));
  603. }
  604. return ret;
  605. }
  606. /**
  607. @brief This function is an application I/F function which is used to receive the data in other then
  608. TCP mode. This function is used to receive UDP, IP_RAW and MAC_RAW mode, and handle the header as well.
  609. @return This function return received data size for success else -1.
  610. */
  611. uint16_t recvfrom(SOCKET s, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port)
  612. {
  613. uint8_t head[8];
  614. uint16_t data_len=0;
  615. uint16_t ptr=0;
  616. uint32_t addrbsb =0;
  617. if ( len > 0 )
  618. {
  619. ptr = IINCHIP_READ(Sn_RX_RD0(s) );
  620. ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_RX_RD1(s));
  621. addrbsb = (uint32_t)(ptr<<8) + (s<<5) + 0x18;
  622. switch (IINCHIP_READ(Sn_MR(s) ) & 0x07)
  623. {
  624. case Sn_MR_UDP :
  625. wiz_read_buf(addrbsb, head, 0x08);
  626. ptr += 8;
  627. // read peer's IP address, port number.
  628. addr[0] = head[0];
  629. addr[1] = head[1];
  630. addr[2] = head[2];
  631. addr[3] = head[3];
  632. *port = head[4];
  633. *port = (*port << 8) + head[5];
  634. data_len = head[6];
  635. data_len = (data_len << 8) + head[7];
  636. addrbsb = (uint32_t)(ptr<<8) + (s<<5) + 0x18;
  637. wiz_read_buf(addrbsb, buf, data_len);
  638. ptr += data_len;
  639. IINCHIP_WRITE( Sn_RX_RD0(s), (uint8_t)((ptr & 0xff00) >> 8));
  640. IINCHIP_WRITE( Sn_RX_RD1(s), (uint8_t)(ptr & 0x00ff));
  641. break;
  642. case Sn_MR_IPRAW :
  643. wiz_read_buf(addrbsb, head, 0x06);
  644. ptr += 6;
  645. addr[0] = head[0];
  646. addr[1] = head[1];
  647. addr[2] = head[2];
  648. addr[3] = head[3];
  649. data_len = head[4];
  650. data_len = (data_len << 8) + head[5];
  651. addrbsb = (uint32_t)(ptr<<8) + (s<<5) + 0x18;
  652. wiz_read_buf(addrbsb, buf, data_len);
  653. ptr += data_len;
  654. IINCHIP_WRITE( Sn_RX_RD0(s), (uint8_t)((ptr & 0xff00) >> 8));
  655. IINCHIP_WRITE( Sn_RX_RD1(s), (uint8_t)(ptr & 0x00ff));
  656. break;
  657. case Sn_MR_MACRAW :
  658. wiz_read_buf(addrbsb, head, 0x02);
  659. ptr+=2;
  660. data_len = head[0];
  661. data_len = (data_len<<8) + head[1] - 2;
  662. if(data_len > 1514)
  663. {
  664. printf("data_len over 1514\r\n");
  665. while(1);
  666. }
  667. addrbsb = (uint32_t)(ptr<<8) + (s<<5) + 0x18;
  668. wiz_read_buf(addrbsb, buf, data_len);
  669. ptr += data_len;
  670. IINCHIP_WRITE( Sn_RX_RD0(s), (uint8_t)((ptr & 0xff00) >> 8));
  671. IINCHIP_WRITE( Sn_RX_RD1(s), (uint8_t)(ptr & 0x00ff));
  672. break;
  673. default :
  674. break;
  675. }
  676. IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_RECV);
  677. /* wait to process the command... */
  678. while( IINCHIP_READ( Sn_CR(s)) ) ;
  679. /* ------- */
  680. }
  681. return data_len;
  682. }
  683. #ifdef __MACRAW__
  684. void macraw_open(void)
  685. {
  686. uint8_t sock_num;
  687. uint16_t dummyPort = 0;
  688. uint8_t mFlag = 0;
  689. sock_num = 0;
  690. close(sock_num); // Close the 0-th socket
  691. socket(sock_num, Sn_MR_MACRAW, dummyPort,mFlag); // OPen the 0-th socket with MACRAW mode
  692. }
  693. uint16_t macraw_send( const uint8_t * buf, uint16_t len )
  694. {
  695. uint16_t ret=0;
  696. uint8_t sock_num;
  697. sock_num =0;
  698. if (len > getIINCHIP_TxMAX(sock_num)) ret = getIINCHIP_TxMAX(sock_num); // check size not to exceed MAX size.
  699. else ret = len;
  700. send_data_processing(sock_num, (uint8_t *)buf, len);
  701. //W5500 SEND COMMAND
  702. IINCHIP_WRITE(Sn_CR(sock_num),Sn_CR_SEND);
  703. while( IINCHIP_READ(Sn_CR(sock_num)) );
  704. while ( (IINCHIP_READ(Sn_IR(sock_num)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK );
  705. IINCHIP_WRITE(Sn_IR(sock_num), Sn_IR_SEND_OK);
  706. return ret;
  707. }
  708. uint16_t macraw_recv( uint8_t * buf, uint16_t len )
  709. {
  710. uint8_t sock_num;
  711. uint16_t data_len=0;
  712. uint16_t dummyPort = 0;
  713. uint16_t ptr = 0;
  714. uint8_t mFlag = 0;
  715. sock_num = 0;
  716. if ( len > 0 )
  717. {
  718. data_len = 0;
  719. ptr = IINCHIP_READ(Sn_RX_RD0(sock_num));
  720. ptr = (uint16_t)((ptr & 0x00ff) << 8) + IINCHIP_READ( Sn_RX_RD1(sock_num) );
  721. //-- read_data(s, (uint8_t *)ptr, data, len); // read data
  722. data_len = IINCHIP_READ_RXBUF(0, ptr);
  723. ptr++;
  724. data_len = ((data_len<<8) + IINCHIP_READ_RXBUF(0, ptr)) - 2;
  725. ptr++;
  726. if(data_len > 1514)
  727. {
  728. printf("data_len over 1514\r\n");
  729. printf("\r\nptr: %X, data_len: %X", ptr, data_len);
  730. //while(1);
  731. /** recommand : close and open **/
  732. close(sock_num); // Close the 0-th socket
  733. socket(sock_num, Sn_MR_MACRAW, dummyPort,mFlag); // OPen the 0-th socket with MACRAW mode
  734. return 0;
  735. }
  736. IINCHIP_READ_RXBUF_BURST(sock_num, ptr, data_len, (uint8_t*)(buf));
  737. ptr += data_len;
  738. IINCHIP_WRITE(Sn_RX_RD0(sock_num),(uint8_t)((ptr & 0xff00) >> 8));
  739. IINCHIP_WRITE(Sn_RX_RD1(sock_num),(uint8_t)(ptr & 0x00ff));
  740. IINCHIP_WRITE(Sn_CR(sock_num), Sn_CR_RECV);
  741. while( IINCHIP_READ(Sn_CR(sock_num)) ) ;
  742. }
  743. return data_len;
  744. }
  745. #endif