w5500.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. /*
  2. *
  3. */
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include "bsp.h"
  7. #include "w5500.h"
  8. #include "socket.h"
  9. #include "types.h"
  10. #ifdef __DEF_IINCHIP_PPP__
  11. #include "md5.h"
  12. #endif
  13. static uint8_t rxbuf[W5500BUFLEN+8]={0};
  14. static uint8_t txbuf[W5500BUFLEN+8]={0};
  15. static uint16_t SSIZE[MAX_SOCK_NUM]; /**< Max Tx buffer size by each channel */
  16. static uint16_t RSIZE[MAX_SOCK_NUM]; /**< Max Rx buffer size by each channel */
  17. /********************************************************************/
  18. uint16_t getIINCHIP_RxMAX(uint8_t s)
  19. {
  20. return RSIZE[s];
  21. }
  22. uint16_t getIINCHIP_TxMAX(uint8_t s)
  23. {
  24. return SSIZE[s];
  25. }
  26. void IINCHIP_WRITE( uint32_t addrbsb, uint8_t data)
  27. {
  28. IINCHIP_ISR_DISABLE(); // Interrupt Service Routine Disable
  29. BSP_W5500_Enable(); // CS=0, SPI start
  30. txbuf[0] = (uint8_t)( (addrbsb & 0x00FF0000)>>16);// Address byte 1
  31. txbuf[1] = (uint8_t)( (addrbsb & 0x0000FF00)>> 8);// Address byte 2
  32. txbuf[2] = (uint8_t)( (addrbsb & 0x000000F8) | 5); // Data write command and Write data length 1
  33. txbuf[3] = (uint8_t)( data ); // Data write (write 1byte data)
  34. BSP_W5500_Write(txbuf,4);
  35. BSP_W5500_Disable(); // CS=1, SPI end
  36. IINCHIP_ISR_ENABLE(); // Interrupt Service Routine Enable
  37. }
  38. uint8_t IINCHIP_READ(uint32_t addrbsb)
  39. {
  40. uint32_t status=0;
  41. IINCHIP_ISR_DISABLE(); // Interrupt Service Routine Disable
  42. BSP_W5500_Enable(); // CS=0, SPI start
  43. txbuf[0] = (uint8_t)( (addrbsb & 0x00FF0000)>>16);// Address byte 1
  44. txbuf[1] = (uint8_t)( (addrbsb & 0x0000FF00)>> 8);// Address byte 2
  45. txbuf[2] = (uint8_t)( (addrbsb & 0x000000F8) | 0x01);// Data read command and Read data length 1
  46. status=BSP_W5500_Write(txbuf,3);
  47. status++;
  48. /*status=BSP_W5500_Read(rxbuf, 1);
  49. status++;
  50. SPIx_WriteRead(txbuf[0]);
  51. SPIx_WriteRead(txbuf[1]);
  52. SPIx_WriteRead(txbuf[2]);*/
  53. status = BSP_W5500_WriteRead(0);
  54. rxbuf[0]=status;
  55. BSP_W5500_Disable(); // CS=1, SPI end
  56. IINCHIP_ISR_ENABLE(); // Interrupt Service Routine Enable
  57. return rxbuf[0];
  58. }
  59. uint16_t wiz_write_buf(uint32_t addrbsb, uint8_t* buf, uint16_t len)
  60. {
  61. uint16_t idx = 0;
  62. /*uint32_t time1=HAL_GetTick();
  63. uint32_t time2;
  64. uint8_t debugbuf[24]={0};*/
  65. if(len == 0)
  66. {
  67. printf("Unexpected2 length 0\r\n");
  68. }
  69. IINCHIP_ISR_DISABLE();
  70. BSP_W5500_Enable(); // CS=0, SPI start
  71. txbuf[0] = (uint8_t)( (addrbsb & 0x00FF0000)>>16);// Address byte 1
  72. txbuf[1] = (uint8_t)( (addrbsb & 0x0000FF00)>> 8);// Address byte 2
  73. txbuf[2] = (uint8_t)( (addrbsb & 0x000000F8) + 4);// Data write command and Write data length 1
  74. for(idx = 0; idx < len; idx++) // Write data in loop
  75. {
  76. txbuf[idx + 3] = (uint8_t)(buf[idx]);
  77. }
  78. BSP_W5500_Write(txbuf,idx+3);
  79. BSP_W5500_Disable(); // CS=1, SPI end
  80. IINCHIP_ISR_ENABLE(); // Interrupt Service Routine Enable
  81. /*time2=HAL_GetTick();
  82. time1 = sprintf(debugbuf,"%d~%d\r\n",time1,time2);
  83. ReportMessage(debugbuf,time1);*/
  84. return len;
  85. }
  86. uint16_t wiz_read_buf(uint32_t addrbsb, uint8_t* buf,uint16_t len)
  87. {
  88. //uint16_t idx = 0;
  89. //if recv data len is 0, print "Unexpected2 length 0" via com port
  90. if(len == 0)
  91. {
  92. printf("Unexpected2 length 0\r\n");
  93. }
  94. BSP_W5500_Enable(); // clear CS=0, SPI enabled
  95. txbuf[0] = (uint8_t)( (addrbsb & 0x00FF0000)>>16); // send address to MCU
  96. txbuf[1] = (uint8_t)( (addrbsb & 0x0000FF00)>> 8); //
  97. txbuf[2] = (uint8_t)( (addrbsb & 0x000000F8)); // Set SPI to read operation
  98. BSP_W5500_Write(txbuf,3);
  99. BSP_W5500_Read(buf, len);
  100. BSP_W5500_Disable(); // set CS=1, SPI disabled
  101. return len;
  102. }
  103. /********************************************************************/
  104. /**
  105. @brief This function is for resetting of the iinchip. Initializes the iinchip to work in whether DIRECT or INDIRECT mode
  106. */
  107. void iinchip_init(void)
  108. {
  109. setMR( MR_RST );
  110. #ifdef __DEF_IINCHIP_DBG__
  111. printf("MR value is %02x \r\n",IINCHIP_READ_COMMON(MR));
  112. #endif
  113. }
  114. /**
  115. @brief This function set the transmit & receive buffer size as per the channels is used
  116. Note for TMSR and RMSR bits are as follows\n
  117. bit 1-0 : memory size of channel #0 \n
  118. bit 3-2 : memory size of channel #1 \n
  119. bit 5-4 : memory size of channel #2 \n
  120. bit 7-6 : memory size of channel #3 \n
  121. bit 9-8 : memory size of channel #4 \n
  122. bit 11-10 : memory size of channel #5 \n
  123. bit 12-12 : memory size of channel #6 \n
  124. bit 15-14 : memory size of channel #7 \n
  125. Maximum memory size for Tx, Rx in the W5500 is 16K Bytes,\n
  126. In the range of 16KBytes, the memory size could be allocated dynamically by each channel.\n
  127. Be attentive to sum of memory size shouldn't exceed 8Kbytes\n
  128. and to data transmission and receiption from non-allocated channel may cause some problems.\n
  129. If the 16KBytes memory is already assigned to centain channel, \n
  130. other 3 channels couldn't be used, for there's no available memory.\n
  131. If two 4KBytes memory are assigned to two each channels, \n
  132. other 2 channels couldn't be used, for there's no available memory.\n
  133. */
  134. void sysinit(const uint8_t * tx_size, const uint8_t * rx_size )
  135. {
  136. int16_t i;
  137. int16_t ssum,rsum;
  138. #ifdef __DEF_IINCHIP_DBG__
  139. printf("sysinit()\r\n");
  140. #endif
  141. ssum = 0;
  142. rsum = 0;
  143. for (i = 0 ; i < MAX_SOCK_NUM; i++) // Set the size, masking and base address of Tx & Rx memory by each channel
  144. {
  145. IINCHIP_WRITE( (Sn_TXMEM_SIZE(i)), tx_size[i]);
  146. IINCHIP_WRITE( (Sn_RXMEM_SIZE(i)), rx_size[i]);
  147. #ifdef __DEF_IINCHIP_DBG__
  148. printf("tx_size[%d]: %d, Sn_TXMEM_SIZE = %d\r\n",i, tx_size[i], IINCHIP_READ(Sn_TXMEM_SIZE(i)));
  149. printf("rx_size[%d]: %d, Sn_RXMEM_SIZE = %d\r\n",i, rx_size[i], IINCHIP_READ(Sn_RXMEM_SIZE(i)));
  150. #endif
  151. SSIZE[i] = (int16_t)(0);
  152. RSIZE[i] = (int16_t)(0);
  153. // There are 8 Socket in W5500, and every socket has his own send/recv buffer independently.
  154. // Total buffer for all socket is located in the 16KB physical memory and when initializing, each socket has 2KB.
  155. // Make sure sum of all the buffer is not larger than 16KB.
  156. if (ssum <= 16384) // send buffer of Socket
  157. {
  158. switch( tx_size[i] )
  159. {
  160. case 1:
  161. SSIZE[i] = (int16_t)(1024); // i=1, tx_size=1KB
  162. break;
  163. case 2:
  164. SSIZE[i] = (int16_t)(2048); // i=2, tx_size=2KB
  165. break;
  166. case 4:
  167. SSIZE[i] = (int16_t)(4096); // i=4, tx_size=4KB
  168. break;
  169. case 8:
  170. SSIZE[i] = (int16_t)(8192); // i=8, tx_size=8KB
  171. break;
  172. case 16:
  173. SSIZE[i] = (int16_t)(16384); // i=16, tx_size=16KB
  174. break;
  175. default :
  176. RSIZE[i] = (int16_t)(2048); // i=2, tx_size=2KB, default
  177. break;
  178. }
  179. }
  180. if (rsum <= 16384) // recv buffer of Socket
  181. {
  182. switch( rx_size[i] )
  183. {
  184. case 1:
  185. RSIZE[i] = (int16_t)(1024); // i=1, rx_size=1KB
  186. break;
  187. case 2:
  188. RSIZE[i] = (int16_t)(2048); // i=2, rx_size=2KB
  189. break;
  190. case 4:
  191. RSIZE[i] = (int16_t)(4096); // i=4, rx_size=4KB
  192. break;
  193. case 8:
  194. RSIZE[i] = (int16_t)(8192); // i=8, rx_size=8KB
  195. break;
  196. case 16:
  197. RSIZE[i] = (int16_t)(16384); // i=16, rx_size=16KB
  198. break;
  199. default :
  200. RSIZE[i] = (int16_t)(2048); // i=2, rx_size=2K, default
  201. break;
  202. }
  203. }
  204. ssum += SSIZE[i];
  205. rsum += RSIZE[i];
  206. }
  207. }
  208. /********************************************************************/
  209. /**
  210. @brief It sets up mode
  211. */
  212. void setMR(uint8_t val)
  213. {
  214. IINCHIP_WRITE(MR,val);
  215. }
  216. /**
  217. @brief It sets up gateway address
  218. */
  219. void setGAR(uint8_t * addr)
  220. {
  221. wiz_write_buf(GAR0, addr, 4);
  222. }
  223. /**
  224. @brief It sets up SubnetMask address
  225. */
  226. void setSUBR(uint8_t * addr)
  227. {
  228. wiz_write_buf(SUBR0, addr, 4);
  229. }
  230. /**
  231. @brief This function sets up MAC address.
  232. **< a pointer to a 6 -byte array responsible to set the MAC address.
  233. */
  234. void setSHAR(uint8_t * addr)
  235. {
  236. wiz_write_buf(SHAR0, addr, 6);
  237. }
  238. /**
  239. @brief This function sets up Source IP address.
  240. **< a pointer to a 4 -byte array responsible to set the Source IP address.
  241. */
  242. void setSIPR(uint8_t * addr)
  243. {
  244. wiz_write_buf(SIPR0, addr, 4);
  245. }
  246. /**
  247. @brief This function set the interrupt mask Enable/Disable appropriate Interrupt. ('1' : interrupt enable)
  248. If any bit in IMR is set as '0' then there is not interrupt signal though the bit is set in IR register.
  249. */
  250. void setIR(uint8_t val)
  251. {
  252. IINCHIP_WRITE(IR, val);
  253. }
  254. void clearIR(uint8_t mask)
  255. {
  256. IINCHIP_WRITE(IR, ~mask | getIR() ); // must be setted 0x10.
  257. }
  258. void setIMR(uint8_t val)
  259. {
  260. IINCHIP_WRITE(IMR, val);
  261. }
  262. void setSIR(uint8_t val)
  263. {
  264. IINCHIP_WRITE(SIR, val);
  265. }
  266. void setSIMR(uint8_t val)
  267. {
  268. IINCHIP_WRITE(SIMR, val);
  269. }
  270. /**
  271. @brief This function sets up Retransmission time.
  272. If there is no response from the peer or delay in response then retransmission
  273. will be there as per RTR (Retry Time-value Register)setting
  274. */
  275. void setRTR(uint16_t timeout)
  276. {
  277. IINCHIP_WRITE(RTR0,(uint8_t)((timeout & 0xff00) >> 8));
  278. IINCHIP_WRITE(RTR1,(uint8_t)(timeout & 0x00ff));
  279. }
  280. /**
  281. @brief This function set the number of Retransmission.
  282. If there is no response from the peer or delay in response then recorded time
  283. as per RTR & RCR register seeting then time out will occur.
  284. */
  285. void setRCR(uint8_t retry)
  286. {
  287. IINCHIP_WRITE(RCR,retry);
  288. }
  289. void setPHYCFGR(uint8_t val)
  290. {
  291. IINCHIP_WRITE(PHYCFGR, val);
  292. }
  293. /********************************************************************/
  294. /**
  295. @brief Thess function get registers' value.
  296. */
  297. uint8_t getMR( void )
  298. {
  299. return IINCHIP_READ(MR);
  300. }
  301. void getGAR(uint8_t * addr)
  302. {
  303. wiz_read_buf(GAR0, addr, 4);
  304. }
  305. void getSUBR(uint8_t * addr)
  306. {
  307. wiz_read_buf(SUBR0, addr, 4);
  308. }
  309. void getSHAR(uint8_t * addr)
  310. {
  311. wiz_read_buf(SHAR0, addr, 6);
  312. }
  313. void getSIPR(uint8_t * addr)
  314. {
  315. wiz_read_buf(SIPR0, addr, 4);
  316. }
  317. uint8_t getIR( void )
  318. {
  319. return IINCHIP_READ(IR);
  320. }
  321. uint8_t getIMR(void)
  322. {
  323. return IINCHIP_READ(IMR);
  324. }
  325. uint8_t getSIR( void)
  326. {
  327. return IINCHIP_READ(SIR);
  328. }
  329. uint8_t getSIMR(void)
  330. {
  331. return IINCHIP_READ(SIMR);
  332. }
  333. uint8_t getPHYCFGR( void)
  334. {
  335. return IINCHIP_READ(PHYCFGR);
  336. }
  337. uint8_t getVersion(void)
  338. {
  339. return IINCHIP_READ(VERSIONR);
  340. }
  341. /********************************************************************/
  342. uint8_t getSn_MR(SOCKET s)
  343. {
  344. return IINCHIP_READ(Sn_MR(s));
  345. }
  346. void setSn_MR(uint8_t s, uint8_t val)
  347. {
  348. IINCHIP_WRITE(Sn_MR(s), val);
  349. }
  350. uint8_t getSn_CR(SOCKET s)
  351. {
  352. return IINCHIP_READ(Sn_CR(s));
  353. }
  354. void setSn_CR(uint8_t s, uint8_t val)
  355. {
  356. IINCHIP_WRITE(Sn_CR(s), val);
  357. }
  358. /**
  359. @brief get socket interrupt status
  360. These below functions are used to read the Interrupt & Soket Status register
  361. */
  362. uint8_t getSn_IR(SOCKET s)
  363. {
  364. return IINCHIP_READ(Sn_IR(s));
  365. }
  366. void setSn_IR(uint8_t s, uint8_t val)
  367. {
  368. IINCHIP_WRITE(Sn_IR(s), val);
  369. }
  370. uint8_t getSn_IMR(SOCKET s)
  371. {
  372. return IINCHIP_READ(Sn_IMR(s));
  373. }
  374. void setSn_IMR(uint8_t s, uint8_t val)
  375. {
  376. IINCHIP_WRITE(Sn_IMR(s), val);
  377. }
  378. /**
  379. @brief get socket status
  380. */
  381. uint8_t getSn_SR(SOCKET s)
  382. {
  383. return IINCHIP_READ(Sn_SR(s));
  384. }
  385. /**
  386. @brief This sets the maximum segment size of TCP in Active Mode), while in Passive Mode this is set by peer
  387. */
  388. void setSn_MSS(SOCKET s, uint16_t Sn_MSSR)
  389. {
  390. IINCHIP_WRITE( Sn_MSSR0(s), (uint8_t)((Sn_MSSR & 0xff00) >> 8));
  391. IINCHIP_WRITE( Sn_MSSR1(s), (uint8_t)(Sn_MSSR & 0x00ff));
  392. }
  393. void setSn_TTL(SOCKET s, uint8_t ttl)
  394. {
  395. IINCHIP_WRITE( Sn_TTL(s) , ttl);
  396. }
  397. /**
  398. @brief get socket TX free buf size
  399. This gives free buffer size of transmit buffer. This is the data size that user can transmit.
  400. User shuold check this value first and control the size of transmitting data
  401. */
  402. uint16_t getSn_TX_FSR(SOCKET s)
  403. {
  404. uint16_t val=0,val1=0;
  405. do
  406. {
  407. val1 = IINCHIP_READ(Sn_TX_FSR0(s));
  408. val1 = (val1 << 8) + IINCHIP_READ(Sn_TX_FSR1(s));
  409. if (val1 != 0)
  410. {
  411. val = IINCHIP_READ(Sn_TX_FSR0(s));
  412. val = (val << 8) + IINCHIP_READ(Sn_TX_FSR1(s));
  413. }
  414. } while (val != val1);
  415. return val;
  416. }
  417. /**
  418. @brief get socket RX recv buf size
  419. This gives size of received data in receive buffer.
  420. */
  421. uint16_t getSn_RX_RSR(SOCKET s)
  422. {
  423. uint16_t val=0,val1=0;
  424. do
  425. {
  426. val1 = IINCHIP_READ(Sn_RX_RSR0(s)); // MCU read low byte of Sn_RX_RSR
  427. val1 = (val1 << 8) + IINCHIP_READ(Sn_RX_RSR1(s)); //read the high byte of it, and add the low to make whole value
  428. if(val1 != 0) // if Sn_RX_RSR is not 0,read it again
  429. {
  430. val = IINCHIP_READ(Sn_RX_RSR0(s));
  431. val = (val << 8) + IINCHIP_READ(Sn_RX_RSR1(s));
  432. }
  433. } while (val != val1); // if two time values do not equal, loop
  434. return val; // return the recv buffer size
  435. }
  436. /**
  437. @brief set the tcp keeplive time
  438. */
  439. void setkeepalive(SOCKET s)
  440. {
  441. IINCHIP_WRITE(Sn_KPALVTR(s),0x02);
  442. }
  443. /**
  444. @brief This function is being called by send() and sendto() function also.
  445. This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer
  446. register. User should read upper byte first and lower byte later to get proper value.
  447. */
  448. void send_data_processing(SOCKET s, uint8_t *data, uint16_t len)
  449. {
  450. uint16_t ptr =0;
  451. uint32_t addrbsb =0;
  452. if(len == 0)
  453. {
  454. //printf("CH: %d Unexpected1 length 0\r\n", s);
  455. return;
  456. }
  457. ptr = IINCHIP_READ( Sn_TX_WR0(s) );
  458. ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_TX_WR1(s));
  459. addrbsb = (uint32_t)(ptr<<8) + (s<<5) + 0x10;
  460. wiz_write_buf(addrbsb, data, len);
  461. ptr += len;
  462. IINCHIP_WRITE( Sn_TX_WR0(s) ,(uint8_t)((ptr & 0xff00) >> 8));
  463. IINCHIP_WRITE( Sn_TX_WR1(s),(uint8_t)(ptr & 0x00ff));
  464. }
  465. /**
  466. @brief This function is being called by recv() also.
  467. This function read the Rx read pointer register
  468. and after copy the data from receive buffer update the Rx write pointer register.
  469. User should read upper byte first and lower byte later to get proper value.
  470. */
  471. void recv_data_processing(SOCKET s, uint8_t *data, uint16_t len)
  472. {
  473. uint16_t ptr = 0;
  474. uint32_t addrbsb = 0;
  475. if(len == 0) // if len is 0, return after print message "CH: 0 Unexpected2 length 0".
  476. {
  477. //printf("CH: %d Unexpected2 length 0\r\n", s);
  478. return;
  479. }
  480. // MCU read the recv data pointer in Sn_RX_RD
  481. // Sn_RX_RD saves the first byte address of recv data, if data recved, after data recved, this register is updated.
  482. ptr = IINCHIP_READ( Sn_RX_RD0(s) );
  483. ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ( Sn_RX_RD1(s) );
  484. addrbsb = (uint32_t)(ptr<<8) + (s<<5) + 0x18; // get the absolute address of recv data
  485. wiz_read_buf(addrbsb, data, len); // read data to mcu
  486. // updata data address
  487. ptr += len; //
  488. IINCHIP_WRITE( Sn_RX_RD0(s), (uint8_t)((ptr & 0xff00) >> 8));
  489. IINCHIP_WRITE( Sn_RX_RD1(s), (uint8_t)(ptr & 0x00ff));
  490. }
  491. /********************************************************************/