PageRenderTime 73ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/projects/DE2_115_NIOS_Ethernet_Test/software/fpgaminer_controller/socket.c

https://github.com/jonathanleang/Open-Source-FPGA-Bitcoin-Miner
C | 190 lines | 131 code | 47 blank | 12 comment | 21 complexity | 7629a096c7445153778cde37cff897dd MD5 | raw file
Possible License(s): GPL-3.0, Unlicense
  1. #include <stdint.h>
  2. #include <stdbool.h>
  3. #include "socket.h"
  4. #include "w5100.h"
  5. bool write_sock_reg(SOCKET s, uint8_t reg, uint8_t data)
  6. {
  7. return eth_write(0x0400 + (s << 8) + reg, data);
  8. }
  9. uint8_t read_sock_reg(SOCKET s, uint8_t reg)
  10. {
  11. uint8_t c = 0;
  12. if (!eth_read(0x0400 + (s << 8) + reg, &c))
  13. printf("FATAL ERROR: an eth_read failed. SPI communication error.\n");
  14. return c;
  15. }
  16. // Initialize a TCP socket
  17. uint8_t socket(SOCKET s, uint16_t port)
  18. {
  19. close(s);
  20. write_sock_reg(s, Sn_MR, 0x01);
  21. write_sock_reg(s, Sn_PORT, port >> 8);
  22. write_sock_reg(s, Sn_PORT+1, port & 0xFF);
  23. write_sock_reg(s, Sn_CR, OPEN);
  24. if (read_sock_reg(s, Sn_SR) != SOCK_INIT) {
  25. close(s);
  26. return 1;
  27. }
  28. return 0;
  29. }
  30. void close(SOCKET s)
  31. {
  32. if (!write_sock_reg(s, Sn_CR, CLOSE))
  33. printf("FATAL ERROR: Closing socket failed!\n");
  34. }
  35. uint8_t socket_status(SOCKET s)
  36. {
  37. return read_sock_reg(s, Sn_SR);
  38. }
  39. /*uint8_t listen(SOCKET s)
  40. {
  41. write_sock_reg(s, Sn_CR, LISTEN);
  42. if (read_sock_reg(s, Sn_SR) != SOCK_LISTEN) {
  43. close(s);
  44. return 1;
  45. }
  46. return 0;
  47. }*/
  48. uint8_t connect(SOCKET s, uint8_t addr0, uint8_t addr1, uint8_t addr2, uint8_t addr3, uint16_t port)
  49. {
  50. write_sock_reg(s, Sn_DIPR, addr0);
  51. write_sock_reg(s, Sn_DIPR+1, addr1);
  52. write_sock_reg(s, Sn_DIPR+2, addr2);
  53. write_sock_reg(s, Sn_DIPR+3, addr3);
  54. write_sock_reg(s, Sn_DPORT, port >> 8);
  55. write_sock_reg(s, Sn_DPORT+1, port & 0xFF);
  56. write_sock_reg(s, Sn_CR, CONNECT);
  57. return 0;
  58. }
  59. uint8_t established(SOCKET s)
  60. {
  61. uint8_t c = read_sock_reg(s, Sn_SR);
  62. if (c == SOCK_ESTABLISHED)
  63. return 1;
  64. else if (c == SOCK_LISTEN)
  65. return 0;
  66. else
  67. return 2;
  68. }
  69. uint16_t send(SOCKET s, const uint8_t *buf, uint16_t len)
  70. {
  71. uint16_t free_size, offset, start_address, upper_size, left_size;
  72. uint16_t base = TXBUF_BASE + (s << 11);
  73. while(true)
  74. {
  75. free_size = (read_sock_reg(s, Sn_TX_FSR) << 8) | read_sock_reg(s, Sn_TX_FSR+1);
  76. if (free_size >= len)
  77. break;
  78. }
  79. offset = (read_sock_reg(s, Sn_TX_WR) << 8) | read_sock_reg(s, Sn_TX_WR+1);
  80. offset &= 0x7FF;
  81. start_address = base + offset;
  82. if ( (offset + len) > 2048)
  83. {
  84. upper_size = 2048 - offset;
  85. if(!eth_write_mem(buf, start_address, upper_size))
  86. return 1;
  87. buf += upper_size;
  88. left_size = len - upper_size;
  89. if(!eth_write_mem(buf, base, left_size))
  90. return 1;
  91. }
  92. else
  93. {
  94. if(!eth_write_mem(buf, start_address, len))
  95. return 1;
  96. }
  97. offset = (read_sock_reg(s, Sn_TX_WR) << 8) | read_sock_reg(s, Sn_TX_WR+1);
  98. offset += len;
  99. write_sock_reg(s, Sn_TX_WR, offset >> 8);
  100. write_sock_reg(s, Sn_TX_WR+1, offset & 0xFF);
  101. write_sock_reg(s, Sn_CR, SEND);
  102. return 0;
  103. }
  104. uint16_t recv(SOCKET s, uint8_t *buf, uint16_t maxlen)
  105. {
  106. uint16_t size, offset, start_address, upper_size, left_size;
  107. uint16_t base = RXBUF_BASE + (s << 11);
  108. size = (read_sock_reg(s, Sn_RX_RSR) << 8) | read_sock_reg(s, Sn_RX_RSR+1);
  109. if (size == 0)
  110. return 0;
  111. if (size > maxlen)
  112. size = maxlen;
  113. offset = (read_sock_reg(s, Sn_RX_RD) << 8) | read_sock_reg(s, Sn_RX_RD+1);
  114. offset &= 0x7FF;
  115. // TODO: RXBUF_BASE + s << 8???
  116. start_address = base + offset;
  117. if ( (offset + size) > 2048 )
  118. {
  119. upper_size = 2048 - offset;
  120. if(!eth_read_mem(buf, start_address, upper_size))
  121. return 0;
  122. buf += upper_size;
  123. left_size = size - upper_size;
  124. if (!eth_read_mem(buf, base, left_size))
  125. return 0;
  126. }
  127. else
  128. {
  129. if (!eth_read_mem(buf, start_address, size))
  130. return 0;
  131. }
  132. offset = (read_sock_reg(s, Sn_RX_RD) << 8) | read_sock_reg(s, Sn_RX_RD+1);
  133. offset += size;
  134. write_sock_reg(s, Sn_RX_RD, offset >> 8);
  135. write_sock_reg(s, Sn_RX_RD+1, offset & 0xFF);
  136. write_sock_reg(s, Sn_CR, RECV);
  137. return size;
  138. }
  139. void disconnect(SOCKET s)
  140. {
  141. write_sock_reg(s, Sn_CR, DISCON);
  142. }