w5200.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. // dpgeorge: this file taken from w5500/w5500.c and adapted to W5200
  2. //*****************************************************************************
  3. //
  4. //! \file w5500.c
  5. //! \brief W5500 HAL Interface.
  6. //! \version 1.0.1
  7. //! \date 2013/10/21
  8. //! \par Revision history
  9. //! <2014/05/01> V1.0.2
  10. //! 1. Implicit type casting -> Explicit type casting. Refer to M20140501
  11. //! Fixed the problem on porting into under 32bit MCU
  12. //! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh
  13. //! Thank for your interesting and serious advices.
  14. //! <2013/10/21> 1st Release
  15. //! <2013/12/20> V1.0.1
  16. //! 1. Remove warning
  17. //! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case _WIZCHIP_IO_MODE_SPI_FDM_
  18. //! for loop optimized(removed). refer to M20131220
  19. //! \author MidnightCow
  20. //! \copyright
  21. //!
  22. //! Copyright (c) 2013, WIZnet Co., LTD.
  23. //! All rights reserved.
  24. //!
  25. //! Redistribution and use in source and binary forms, with or without
  26. //! modification, are permitted provided that the following conditions
  27. //! are met:
  28. //!
  29. //! * Redistributions of source code must retain the above copyright
  30. //! notice, this list of conditions and the following disclaimer.
  31. //! * Redistributions in binary form must reproduce the above copyright
  32. //! notice, this list of conditions and the following disclaimer in the
  33. //! documentation and/or other materials provided with the distribution.
  34. //! * Neither the name of the <ORGANIZATION> nor the names of its
  35. //! contributors may be used to endorse or promote products derived
  36. //! from this software without specific prior written permission.
  37. //!
  38. //! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  39. //! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  40. //! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  41. //! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  42. //! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  43. //! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  44. //! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  45. //! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  46. //! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  47. //! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  48. //! THE POSSIBILITY OF SUCH DAMAGE.
  49. //
  50. //*****************************************************************************
  51. #include "w5200.h"
  52. #define SMASK (0x7ff) /* tx buffer mask */
  53. #define RMASK (0x7ff) /* rx buffer mask */
  54. #define SSIZE (2048) /* max tx buffer size */
  55. #define RSIZE (2048) /* max rx buffer size */
  56. #define TXBUF_BASE (0x8000)
  57. #define RXBUF_BASE (0xc000)
  58. #define SBASE(sn) (TXBUF_BASE + SSIZE * (sn)) /* tx buffer base for socket sn */
  59. #define RBASE(sn) (RXBUF_BASE + RSIZE * (sn)) /* rx buffer base for socket sn */
  60. uint8_t WIZCHIP_READ(uint32_t AddrSel) {
  61. WIZCHIP_CRITICAL_ENTER();
  62. WIZCHIP.CS._select();
  63. uint8_t spi_data[4] = {
  64. AddrSel >> 8,
  65. AddrSel,
  66. 0x00,
  67. 0x01,
  68. };
  69. WIZCHIP.IF.SPI._write_bytes(spi_data, 4);
  70. uint8_t ret;
  71. WIZCHIP.IF.SPI._read_bytes(&ret, 1);
  72. WIZCHIP.CS._deselect();
  73. WIZCHIP_CRITICAL_EXIT();
  74. return ret;
  75. }
  76. void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb) {
  77. WIZCHIP_CRITICAL_ENTER();
  78. WIZCHIP.CS._select();
  79. uint8_t spi_data[5] = {
  80. AddrSel >> 8,
  81. AddrSel,
  82. 0x80,
  83. 0x01,
  84. wb,
  85. };
  86. WIZCHIP.IF.SPI._write_bytes(spi_data, 5);
  87. WIZCHIP.CS._deselect();
  88. WIZCHIP_CRITICAL_EXIT();
  89. }
  90. void WIZCHIP_READ_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) {
  91. WIZCHIP_CRITICAL_ENTER();
  92. WIZCHIP.CS._select();
  93. uint8_t spi_data[4] = {
  94. AddrSel >> 8,
  95. AddrSel,
  96. 0x00 | ((len >> 8) & 0x7f),
  97. len & 0xff,
  98. };
  99. WIZCHIP.IF.SPI._write_bytes(spi_data, 4);
  100. WIZCHIP.IF.SPI._read_bytes(pBuf, len);
  101. WIZCHIP.CS._deselect();
  102. WIZCHIP_CRITICAL_EXIT();
  103. }
  104. void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) {
  105. WIZCHIP_CRITICAL_ENTER();
  106. WIZCHIP.CS._select();
  107. uint8_t spi_data[4] = {
  108. AddrSel >> 8,
  109. AddrSel,
  110. 0x80 | ((len >> 8) & 0x7f),
  111. len & 0xff,
  112. };
  113. WIZCHIP.IF.SPI._write_bytes(spi_data, 4);
  114. WIZCHIP.IF.SPI._write_bytes(pBuf, len);
  115. WIZCHIP.CS._deselect();
  116. WIZCHIP_CRITICAL_EXIT();
  117. }
  118. uint16_t getSn_TX_FSR(uint8_t sn) {
  119. uint16_t val = 0, val1 = 0;
  120. do {
  121. val1 = (WIZCHIP_READ(Sn_TX_FSR(sn)) << 8) | WIZCHIP_READ(Sn_TX_FSR(sn) + 1);
  122. if (val1 != 0) {
  123. val = (WIZCHIP_READ(Sn_TX_FSR(sn)) << 8) | WIZCHIP_READ(Sn_TX_FSR(sn) + 1);
  124. }
  125. } while (val != val1);
  126. return val;
  127. }
  128. uint16_t getSn_RX_RSR(uint8_t sn) {
  129. uint16_t val = 0, val1 = 0;
  130. do {
  131. val1 = (WIZCHIP_READ(Sn_RX_RSR(sn)) << 8) | WIZCHIP_READ(Sn_RX_RSR(sn) + 1);
  132. if (val1 != 0) {
  133. val = (WIZCHIP_READ(Sn_RX_RSR(sn)) << 8) | WIZCHIP_READ(Sn_RX_RSR(sn) + 1);
  134. }
  135. } while (val != val1);
  136. return val;
  137. }
  138. void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) {
  139. if (len == 0) {
  140. return;
  141. }
  142. uint16_t ptr = getSn_TX_WR(sn);
  143. uint16_t offset = ptr & SMASK;
  144. uint32_t addr = offset + SBASE(sn);
  145. if (offset + len > SSIZE) {
  146. // implement wrap-around circular buffer
  147. uint16_t size = SSIZE - offset;
  148. WIZCHIP_WRITE_BUF(addr, wizdata, size);
  149. WIZCHIP_WRITE_BUF(SBASE(sn), wizdata + size, len - size);
  150. } else {
  151. WIZCHIP_WRITE_BUF(addr, wizdata, len);
  152. }
  153. ptr += len;
  154. setSn_TX_WR(sn, ptr);
  155. }
  156. void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) {
  157. if (len == 0) {
  158. return;
  159. }
  160. uint16_t ptr = getSn_RX_RD(sn);
  161. uint16_t offset = ptr & RMASK;
  162. uint16_t addr = RBASE(sn) + offset;
  163. if (offset + len > RSIZE) {
  164. // implement wrap-around circular buffer
  165. uint16_t size = RSIZE - offset;
  166. WIZCHIP_READ_BUF(addr, wizdata, size);
  167. WIZCHIP_READ_BUF(RBASE(sn), wizdata + size, len - size);
  168. } else {
  169. WIZCHIP_READ_BUF(addr, wizdata, len);
  170. }
  171. ptr += len;
  172. setSn_RX_RD(sn, ptr);
  173. }
  174. void wiz_recv_ignore(uint8_t sn, uint16_t len) {
  175. uint16_t ptr = getSn_RX_RD(sn);
  176. ptr += len;
  177. setSn_RX_RD(sn, ptr);
  178. }