wiz5500.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. /*
  2. * Wiznet5500 library
  3. * Contains functions to allow for networking
  4. *
  5. * Functions from this library can be used to operate up to 8 sockets
  6. * Application based code should not be in this library
  7. */
  8. // uses stdlib.c
  9. // Wiznet W5500 Op Codes
  10. #define WIZNET_WRITE_COMMON 0x04 //opcode to write to one of the common block of registers
  11. #define WIZNET_READ_COMMON 0x00 //opcode to read one of the common block of registers
  12. #define WIZNET_WRITE_SnR 0x0C // s<<5 (nnn 01 1 00) opcode to write to one of the socket n registers
  13. #define WIZNET_READ_SnR 0x08 // s<<5 (nnn 01 0 00) opcode to read one of the socket n registers
  14. #define WIZNET_WRITE_SnTX 0x14 // s<<5 (nnn 10 1 00) opcode to write to the socket n transmit buffer
  15. #define WIZNET_READ_SnRX 0x18 // s<<5 (nnn 11 0 00) opcode to read from the socket n receive buffer
  16. // Wiznet W5500 Register Addresses
  17. #define WIZNET_MR 0x0000 // Mode
  18. #define WIZNET_GAR 0x0001 // Gateway IP address
  19. #define WIZNET_SUBR 0x0005 // Subnet mask address
  20. #define WIZNET_SHAR 0x0009 // Source MAC address
  21. #define WIZNET_SIPR 0x000F // Source IP address
  22. #define WIZNET_IR 0x0015 // Interrupt
  23. #define WIZNET_IMR 0x0016 // Interrupt Mask
  24. #define WIZNET_RTR 0x0019 // Timeout address
  25. #define WIZNET_RCR 0x001B // Retry count
  26. #define WIZNET_UIPR 0x0028 // Unreachable IP address in UDP mode
  27. #define WIZNET_UPORT 0x002C // Unreachable Port address in UDP mode
  28. //W5500 Socket Registers follow
  29. #define WIZNET_SnMR 0x0000 // Mode
  30. #define WIZNET_SnCR 0x0001 // Command
  31. #define WIZNET_SnIR 0x0002 // Interrupt
  32. #define WIZNET_SnSR 0x0003 // Status
  33. #define WIZNET_SnPORT 0x0004 // Source Port (2 bytes)
  34. #define WIZNET_SnDHAR 0x0006 // Destination Hardw Addr
  35. #define WIZNET_SnDIPR 0x000C // Destination IP Addr
  36. #define WIZNET_SnDPORT 0x0010 // Destination Port
  37. #define WIZNET_SnMSSR 0x0012 // Max Segment Size
  38. #define WIZNET_SnPROTO 0x0014 // Protocol in IP RAW Mode
  39. #define WIZNET_SnTOS 0x0015 // IP TOS
  40. #define WIZNET_SnTTL 0x0016 // IP TTL
  41. #define WIZNET_SnRX_BSZ 0x001E // RX Buffer Size
  42. #define WIZNET_SnTX_BSZ 0x001F // TX Buffer Size
  43. #define WIZNET_SnTX_FSR 0x0020 // TX Free Size
  44. #define WIZNET_SnTX_RD 0x0022 // TX Read Pointer
  45. #define WIZNET_SnTX_WR 0x0024 // TX Write Pointer
  46. #define WIZNET_SnRX_RSR 0x0026 // RX RECEIVED SIZE REGISTER
  47. #define WIZNET_SnRX_RD 0x0028 // RX Read Pointer
  48. #define WIZNET_SnRX_WR 0x002A // RX Write Pointer (supported?
  49. //Socket n Mode Register (0x0000)
  50. //WIZNET_SnMR
  51. #define WIZNET_MR_CLOSE 0x00 // Unused socket
  52. #define WIZNET_MR_TCP 0x01 // TCP
  53. #define WIZNET_MR_UDP 0x02 // UDP
  54. #define WIZNET_MR_IPRAW 0x03 // IP LAYER RAW SOCK
  55. #define WIZNET_MR_MACRAW 0x04 // MAC LAYER RAW SOCK
  56. #define WIZNET_MR_PPPOE 0x05 // PPPoE
  57. #define WIZNET_MR_ND 0x20 // No Delayed Ack(TCP) flag
  58. #define WIZNET_MR_MULTI 0x80 // support multicating
  59. //Socket n Command Register (0x0001)
  60. //WIZNET_SnCR
  61. #define WIZNET_CR_OPEN 0x01 // Initialize or open socket
  62. #define WIZNET_CR_LISTEN 0x02 // Wait connection request in tcp mode(Server mode)
  63. #define WIZNET_CR_CONNECT 0x04 // Send connection request in tcp mode(Client mode)
  64. #define WIZNET_CR_DISCON 0x08 // Send closing reqeuset in tcp mode
  65. #define WIZNET_CR_CLOSE 0x10 // Close socket
  66. #define WIZNET_CR_SEND 0x20 // Update Tx memory pointer and send data
  67. #define WIZNET_CR_SEND_MAC 0x21 // Send data with MAC address, so without ARP process
  68. #define WIZNET_CR_SEND_KEEP 0x22 // Send keep alive message
  69. #define WIZNET_CR_RECV 0x40 // Update Rx memory buffer pointer and receive data
  70. //Socket n Interrupt Register (0x0002)
  71. //WIZNET_SnIR
  72. // Bit 0: CON
  73. // Bit 1: DISCON
  74. // Bit 2: RECV
  75. // Bit 3: TIMEOUT
  76. // Bit 4: SEND_OK
  77. //Socket n Status Register (0x0003)
  78. //WIZNET_SnSR
  79. #define WIZNET_SOCK_CLOSED 0x00 // Closed
  80. #define WIZNET_SOCK_INIT 0x13 // Init state
  81. #define WIZNET_SOCK_LISTEN 0x14 // Listen state
  82. #define WIZNET_SOCK_SYNSENT 0x15 // Connection state
  83. #define WIZNET_SOCK_SYNRECV 0x16 // Connection state
  84. #define WIZNET_SOCK_ESTABLISHED 0x17 // Success to connect
  85. #define WIZNET_SOCK_FIN_WAIT 0x18 // Closing state
  86. #define WIZNET_SOCK_CLOSING 0x1A // Closing state
  87. #define WIZNET_SOCK_TIME_WAIT 0x1B // Closing state
  88. #define WIZNET_SOCK_CLOSE_WAIT 0x1C // Closing state
  89. #define WIZNET_SOCK_LAST_ACK 0x1D // Closing state
  90. #define WIZNET_SOCK_UDP 0x22 // UDP socket
  91. #define WIZNET_SOCK_IPRAW 0x32 // IP raw mode socket
  92. #define WIZNET_SOCK_MACRAW 0x42 // MAC raw mode socket
  93. #define WIZNET_SOCK_PPPOE 0x5F // PPPOE socket
  94. //Socket n Source Port Register (0x0004, 0x0005)
  95. //WIZNET_SnPORT
  96. // MSByte: 0x0004
  97. // LSByte: 0x0005
  98. #define WIZNET_MAX_RBUF 2048 // buffer for receiving data (max rx packet size!)
  99. #define WIZNET_MAX_TBUF 2048 // buffer for sending data (max tx packet size!)
  100. //-------------------
  101. //BASIC READ AND WRITE FUNCTIONS
  102. //-------------------
  103. // Workaround for defines in ASM
  104. void W5500_asmDefines()
  105. {
  106. asm(
  107. "define W5500_SPI3_CS_ADDR = 0xC02732 ; address of SPI3_CS\n"
  108. "define W5500_SPI3_ADDR = 0xC02731 ; address of SPI3\n"
  109. );
  110. }
  111. // Sets SPI3_CS low
  112. void WizSpiBeginTransfer()
  113. {
  114. asm(
  115. "; backup regs\n"
  116. "push r1\n"
  117. "push r2\n"
  118. "load32 W5500_SPI3_CS_ADDR r2 ; r2 = W5500_SPI3_CS_ADDR\n"
  119. "load 0 r1 ; r1 = 0 (enable)\n"
  120. "write 0 r2 r1 ; write to SPI3_CS\n"
  121. "; restore regs\n"
  122. "pop r2\n"
  123. "pop r1\n"
  124. );
  125. }
  126. // Sets SPI3_CS high
  127. void WizSpiEndTransfer()
  128. {
  129. asm(
  130. "; backup regs\n"
  131. "push r1\n"
  132. "push r2\n"
  133. "load32 W5500_SPI3_CS_ADDR r2 ; r2 = W5500_SPI3_CS_ADDR\n"
  134. "load 1 r1 ; r1 = 1 (disable)\n"
  135. "write 0 r2 r1 ; write to SPI3_CS\n"
  136. "; restore regs\n"
  137. "pop r2\n"
  138. "pop r1\n"
  139. );
  140. }
  141. // write dataByte and return read value
  142. // write 0x00 for a read
  143. // Writes byte over SPI3 to W5500
  144. word WizSpiTransfer(word dataByte)
  145. {
  146. word retval = 0;
  147. asm(
  148. "load32 W5500_SPI3_ADDR r2 ; r2 = W5500_SPI3_ADDR\n"
  149. "write 0 r2 r4 ; write r4 over SPI3\n"
  150. "read 0 r2 r2 ; read return value\n"
  151. "write -4 r14 r2 ; write to stack to return\n"
  152. );
  153. return retval;
  154. }
  155. // Write data to W5500
  156. void wizWrite(word addr, word cb, char* buf, word len)
  157. {
  158. WizSpiBeginTransfer();
  159. // Send address
  160. word addrMSB = addr >> 8;
  161. WizSpiTransfer(addrMSB); //msByte
  162. WizSpiTransfer(addr); //lsByte
  163. // Send control byte
  164. WizSpiTransfer(cb);
  165. // Send data
  166. word i;
  167. for (i = 0; i < len; i++)
  168. {
  169. WizSpiTransfer(buf[i]);
  170. }
  171. WizSpiEndTransfer();
  172. }
  173. // Write single byte to W5500
  174. word wizWriteSingle(word addr, word cb, word data)
  175. {
  176. WizSpiBeginTransfer();
  177. // Send address
  178. word addrMSB = addr >> 8;
  179. WizSpiTransfer(addrMSB); //msByte
  180. WizSpiTransfer(addr); //lsByte
  181. // Send control byte
  182. WizSpiTransfer(cb);
  183. // Send data
  184. WizSpiTransfer(data);
  185. WizSpiEndTransfer();
  186. return data;
  187. }
  188. // Write two bytes to W5500
  189. void wizWriteDouble(word addr, word cb, word data)
  190. {
  191. WizSpiBeginTransfer();
  192. // Send address
  193. word addrMSB = addr >> 8;
  194. WizSpiTransfer(addrMSB); //msByte
  195. WizSpiTransfer(addr); //lsByte
  196. // Send control byte
  197. WizSpiTransfer(cb);
  198. // Send data
  199. word dataMSB = data >> 8;
  200. WizSpiTransfer(dataMSB);
  201. WizSpiTransfer(data);
  202. WizSpiEndTransfer();
  203. }
  204. void wizRead(word addr, word cb, char* buf, word len)
  205. {
  206. WizSpiBeginTransfer();
  207. // Send address
  208. word addrMSB = addr >> 8;
  209. WizSpiTransfer(addrMSB); //msByte
  210. WizSpiTransfer(addr); //lsByte
  211. // Send control byte
  212. WizSpiTransfer(cb);
  213. // Read data
  214. word i;
  215. for (i = 0; i < len; i++)
  216. {
  217. buf[i] = WizSpiTransfer(0);
  218. }
  219. WizSpiEndTransfer();
  220. }
  221. word wizReadSingle(word addr, word cb)
  222. {
  223. WizSpiBeginTransfer();
  224. // Send address
  225. word addrMSB = addr >> 8;
  226. WizSpiTransfer(addrMSB); //msByte
  227. WizSpiTransfer(addr); //lsByte
  228. // Send control byte
  229. WizSpiTransfer(cb);
  230. // Read data
  231. word retval = WizSpiTransfer(0);
  232. WizSpiEndTransfer();
  233. // Return read value
  234. return retval;
  235. }
  236. word wizReadDouble(word addr, word cb)
  237. {
  238. WizSpiBeginTransfer();
  239. // Send address
  240. word addrMSB = addr >> 8;
  241. WizSpiTransfer(addrMSB); //msByte
  242. WizSpiTransfer(addr); //lsByte
  243. // Send control byte
  244. WizSpiTransfer(cb);
  245. // Read data
  246. word retval = WizSpiTransfer(0) << 8;
  247. retval = retval + WizSpiTransfer(0);
  248. WizSpiEndTransfer();
  249. // Return read value
  250. return retval;
  251. }
  252. //-------------------
  253. //W5500 SOCKET REGISTER FUNCTIONS
  254. //-------------------
  255. // Send a command cmd to socket s
  256. void wizCmd(word s, word cmd)
  257. {
  258. //wizWriteSingle(WIZNET_SnCR, WIZNET_WRITE_SnR, cmd);
  259. WizSpiBeginTransfer();
  260. WizSpiTransfer(0); //msByte
  261. WizSpiTransfer(WIZNET_SnCR); //lsByte
  262. WizSpiTransfer(WIZNET_WRITE_SnR + (s << 5));
  263. WizSpiTransfer(cmd);
  264. WizSpiEndTransfer();
  265. // wait untill done
  266. while ( wizReadSingle(WIZNET_SnCR, WIZNET_READ_SnR) );
  267. }
  268. // Write 8 bits to a sockets control register
  269. void wizSetSockReg8(word s, word addr, word val)
  270. {
  271. //wizWriteSingle(addr, WIZNET_WRITE_SnR, val);
  272. WizSpiBeginTransfer();
  273. WizSpiTransfer(0); //msByte
  274. WizSpiTransfer(addr); //lsByte
  275. WizSpiTransfer(WIZNET_WRITE_SnR + (s << 5));
  276. WizSpiTransfer(val);
  277. WizSpiEndTransfer();
  278. }
  279. // Read 8 bits from a sockets control register
  280. word wizGetSockReg8(word s, word addr){
  281. //return wizReadSingle(addr, WIZNET_READ_SnR);
  282. WizSpiBeginTransfer();
  283. // Send address
  284. word addrMSB = addr >> 8;
  285. WizSpiTransfer(addrMSB); //msByte
  286. WizSpiTransfer(addr); //lsByte
  287. word cb = WIZNET_READ_SnR + (s << 5);
  288. // Send control byte
  289. WizSpiTransfer(cb);
  290. // Read data
  291. word retval = WizSpiTransfer(0);
  292. WizSpiEndTransfer();
  293. // Return read value
  294. return retval;
  295. }
  296. // Write 16 bits to a sockets control register
  297. void wizSetSockReg16(word s, word addr, word val)
  298. {
  299. //wizWriteDouble(addr, WIZNET_WRITE_SnR + (s << 5), val);
  300. WizSpiBeginTransfer();
  301. WizSpiTransfer(0); //msByte
  302. WizSpiTransfer(addr); //lsByte
  303. WizSpiTransfer(WIZNET_WRITE_SnR + (s << 5));
  304. word valMSB = val >> 8;
  305. WizSpiTransfer(valMSB);
  306. WizSpiTransfer(val);
  307. WizSpiEndTransfer();
  308. }
  309. // Read 16 bits from a sockets control register
  310. word wizGetSockReg16(word s, word addr)
  311. {
  312. //return wizReadDouble(addr, WIZNET_READ_SnR + (s << 5));
  313. WizSpiBeginTransfer();
  314. // Send address
  315. word addrMSB = addr >> 8;
  316. WizSpiTransfer(addrMSB); //msByte
  317. WizSpiTransfer(addr); //lsByte
  318. word cb = WIZNET_READ_SnR + (s << 5);
  319. // Send control byte
  320. WizSpiTransfer(cb);
  321. // Read data
  322. word retval = WizSpiTransfer(0) << 8;
  323. retval = retval + WizSpiTransfer(0);
  324. WizSpiEndTransfer();
  325. // Return read value
  326. return retval;
  327. }
  328. //-------------------
  329. //W5500 SETUP FUNCTIONS
  330. //-------------------
  331. // Initialize W5500 chip
  332. void wiz_Init(char* ip_addr, char* gateway_addr, char* mac_addr, char* sub_mask)
  333. {
  334. W5500_asmDefines(); // workaround to prevent deletion by optimizer
  335. WizSpiEndTransfer();
  336. delay(10);
  337. wizWrite(WIZNET_SIPR, WIZNET_WRITE_COMMON, ip_addr, 4);
  338. wizWrite(WIZNET_GAR, WIZNET_WRITE_COMMON, gateway_addr, 4);
  339. wizWrite(WIZNET_SHAR, WIZNET_WRITE_COMMON, mac_addr, 6);
  340. wizWrite(WIZNET_SUBR, WIZNET_WRITE_COMMON, sub_mask, 4);
  341. }
  342. // Initialize socket s for TCP
  343. void wizInitSocketTCP(word s, word port)
  344. {
  345. wizCmd(s, WIZNET_CR_CLOSE);
  346. wizSetSockReg8 (s, WIZNET_SnIR, 0xFF); //reset interrupt register
  347. wizSetSockReg8 (s, WIZNET_SnMR, WIZNET_MR_TCP); //set mode register to tcp
  348. wizSetSockReg16 (s, WIZNET_SnPORT, port); //set tcp port
  349. wizCmd(s, WIZNET_CR_OPEN);
  350. wizCmd(s, WIZNET_CR_LISTEN);
  351. //delay(10); //wait a bit to make sure the socket is in the correct state (technically not necessary)
  352. }
  353. //-------------------
  354. //W5500 READING AND WRITING FUNCTIONS
  355. //-------------------
  356. // from memory, so no need for unsigned comparisons (because we have less than 2GB RAM)
  357. word wizWriteDataFromMemory(word s, char* buf, word buflen)
  358. {
  359. // Make sure there is something to send
  360. if (buflen <= 0)
  361. {
  362. return 0;
  363. }
  364. word bytesSent = 0;
  365. // loop until all bytes are sent
  366. while (bytesSent != buflen)
  367. {
  368. if (wizGetSockReg8(s, WIZNET_SnSR) == WIZNET_SOCK_CLOSED)
  369. {
  370. //uprintln("connection closed");
  371. return 0;
  372. }
  373. word partToSend = buflen - bytesSent;
  374. if (partToSend > WIZNET_MAX_TBUF)
  375. partToSend = WIZNET_MAX_TBUF;
  376. // Make sure there is room in the transmit buffer for what we want to send
  377. word txfree = wizGetSockReg16(s, WIZNET_SnTX_FSR); // Size of the available buffer area
  378. word timeout = 0;
  379. while (txfree < partToSend)
  380. {
  381. timeout++; // Increase timeout counter
  382. delay(1); // Wait a bit
  383. txfree = wizGetSockReg16(s, WIZNET_SnTX_FSR); // Size of the available buffer area
  384. // After a second
  385. if (timeout > 1000)
  386. {
  387. wizCmd(s, WIZNET_CR_DISCON); // Disconnect the connection
  388. //uprintln("timeout");
  389. return 0;
  390. }
  391. }
  392. // Space is available so we will send the buffer
  393. word txwr = wizGetSockReg16(s, WIZNET_SnTX_WR); // Read the Tx Write Pointer
  394. // Write the outgoing data to the transmit buffer
  395. wizWrite(txwr, WIZNET_WRITE_SnTX + (s << 5), buf + bytesSent, partToSend);
  396. // update the buffer pointer
  397. word newSize = txwr + partToSend;
  398. wizSetSockReg16(s, WIZNET_SnTX_WR, newSize);
  399. // Now Send the SEND command which tells the wiznet the pointer is updated
  400. wizCmd(s, WIZNET_CR_SEND);
  401. // Update the amount of bytes sent
  402. bytesSent += partToSend;
  403. }
  404. return 1;
  405. }
  406. // Read received data
  407. word wizReadRecvData(word s, char* buf, word buflen)
  408. {
  409. if (buflen == 0)
  410. {
  411. return 1;
  412. }
  413. if (buflen > WIZNET_MAX_RBUF) // If the request size > WIZNET_MAX_RBUF, truncate it to prevent overflow
  414. {
  415. //uprintln("W: Received too large TCP data");
  416. buflen = WIZNET_MAX_RBUF; // - 1; // -1 Because room for 0 terminator
  417. }
  418. // Get the address where the wiznet is holding the data
  419. word rxrd = wizGetSockReg16(s, WIZNET_SnRX_RD);
  420. // Read the data into the buffer
  421. wizRead(rxrd, WIZNET_READ_SnRX + (s << 5), buf, buflen);
  422. // Remove read data from rxbuffer to make space for new data
  423. word nsize = rxrd + buflen;
  424. wizSetSockReg16(s, WIZNET_SnRX_RD, nsize); //replace read data pointer
  425. //tell the wiznet we have retrieved the data
  426. wizCmd(s, WIZNET_CR_RECV);
  427. // Terminate buffer for printing in case the data was a string
  428. *(buf + buflen) = 0;
  429. return 1;
  430. }
  431. // Remove the received data
  432. void wizFlush(word s, word rsize)
  433. {
  434. if (rsize > 0)
  435. {
  436. word rxrd = wizGetSockReg16(s, WIZNET_SnRX_RD); //retrieve read data pointer
  437. word nsize = rxrd + rsize;
  438. wizSetSockReg16(s, WIZNET_SnRX_RD, nsize); //replace read data pointer
  439. //tell the wiznet we have retrieved the data
  440. wizCmd(s, WIZNET_CR_RECV);
  441. }
  442. }