w5500.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. //*****************************************************************************
  2. //
  3. //! \file w5500.c
  4. //! \brief W5500 HAL Interface.
  5. //! \version 1.0.2
  6. //! \date 2013/10/21
  7. //! \par Revision history
  8. //! <2014/05/01> V1.0.2
  9. //! 1. Implicit type casting -> Explicit type casting. Refer to M20140501
  10. //! Fixed the problem on porting into under 32bit MCU
  11. //! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh
  12. //! Thank for your interesting and serious advices.
  13. //! <2013/12/20> V1.0.1
  14. //! 1. Remove warning
  15. //! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case _WIZCHIP_IO_MODE_SPI_FDM_
  16. //! for loop optimized(removed). refer to M20131220
  17. //! <2013/10/21> 1st Release
  18. //! \author MidnightCow
  19. //! \copyright
  20. //!
  21. //! Copyright (c) 2013, WIZnet Co., LTD.
  22. //! All rights reserved.
  23. //!
  24. //! Redistribution and use in source and binary forms, with or without
  25. //! modification, are permitted provided that the following conditions
  26. //! are met:
  27. //!
  28. //! * Redistributions of source code must retain the above copyright
  29. //! notice, this list of conditions and the following disclaimer.
  30. //! * Redistributions in binary form must reproduce the above copyright
  31. //! notice, this list of conditions and the following disclaimer in the
  32. //! documentation and/or other materials provided with the distribution.
  33. //! * Neither the name of the <ORGANIZATION> nor the names of its
  34. //! contributors may be used to endorse or promote products derived
  35. //! from this software without specific prior written permission.
  36. //!
  37. //! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  38. //! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  39. //! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  40. //! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  41. //! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  42. //! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  43. //! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  44. //! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  45. //! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  46. //! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  47. //! THE POSSIBILITY OF SUCH DAMAGE.
  48. //
  49. //*****************************************************************************
  50. //#include <stdio.h>
  51. #include "w5500.h"
  52. #define _W5500_SPI_VDM_OP_ 0x00
  53. #define _W5500_SPI_FDM_OP_LEN1_ 0x01
  54. #define _W5500_SPI_FDM_OP_LEN2_ 0x02
  55. #define _W5500_SPI_FDM_OP_LEN4_ 0x03
  56. ////////////////////////////////////////////////////
  57. uint8_t WIZCHIP_READ(uint32_t AddrSel)
  58. {
  59. uint8_t ret;
  60. WIZCHIP_CRITICAL_ENTER();
  61. WIZCHIP.CS._select();
  62. #if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
  63. #if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_ )
  64. AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_);
  65. #elif( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_ )
  66. AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_FDM_OP_LEN1_);
  67. #else
  68. #error "Unsupported _WIZCHIP_IO_SPI_ in W5500 !!!"
  69. #endif
  70. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
  71. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
  72. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
  73. ret = WIZCHIP.IF.SPI._read_byte();
  74. #elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) )
  75. #if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_)
  76. #elif(_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_)
  77. #else
  78. #error "Unsupported _WIZCHIP_IO_MODE_BUS_ in W5500 !!!"
  79. #endif
  80. #else
  81. #error "Unknown _WIZCHIP_IO_MODE_ in W5000. !!!"
  82. #endif
  83. WIZCHIP.CS._deselect();
  84. WIZCHIP_CRITICAL_EXIT();
  85. return ret;
  86. }
  87. void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb )
  88. {
  89. WIZCHIP_CRITICAL_ENTER();
  90. WIZCHIP.CS._select();
  91. #if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
  92. #if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_ )
  93. AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_);
  94. #elif( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_ )
  95. AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_FDM_OP_LEN1_);
  96. #else
  97. #error "Unsupported _WIZCHIP_IO_SPI_ in W5500 !!!"
  98. #endif
  99. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
  100. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
  101. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
  102. WIZCHIP.IF.SPI._write_byte(wb);
  103. #elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) )
  104. #if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_)
  105. #elif(_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_)
  106. #else
  107. #error "Unsupported _WIZCHIP_IO_MODE_BUS_ in W5500 !!!"
  108. #endif
  109. #else
  110. #error "Unknown _WIZCHIP_IO_MODE_ in W5500. !!!"
  111. #endif
  112. WIZCHIP.CS._deselect();
  113. WIZCHIP_CRITICAL_EXIT();
  114. }
  115. void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
  116. {
  117. uint16_t i = 0;
  118. uint16_t j = 0;
  119. WIZCHIP_CRITICAL_ENTER();
  120. WIZCHIP.CS._select();
  121. #if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
  122. #if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_ )
  123. AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_);
  124. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
  125. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
  126. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
  127. for(i = 0; i < len; i++,j)
  128. pBuf[i] = WIZCHIP.IF.SPI._read_byte();
  129. #elif( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_ )
  130. AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_FDM_OP_LEN4_);
  131. for(i = 0; i < len/4; i++, j)
  132. {
  133. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
  134. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
  135. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
  136. pBuf[i*4] = WIZCHIP.IF.SPI._read_byte();
  137. pBuf[i*4+1] = WIZCHIP.IF.SPI._read_byte();
  138. pBuf[i*4+2] = WIZCHIP.IF.SPI._read_byte();
  139. pBuf[i*4+3] = WIZCHIP.IF.SPI._read_byte();
  140. AddrSel = WIZCHIP_OFFSET_INC(AddrSel,4);
  141. }
  142. len %= 4; // for the rest data
  143. // M20131220 : remove for loop
  144. i *= 4;
  145. if(len >= 2)
  146. {
  147. AddrSel -= 1; // change _W5500_SPI_FDM_OP_LEN4_ to _W5500_SPI_FDM_OP_LEN2_
  148. //for(j = 0; j < len/2 ; j++)
  149. {
  150. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
  151. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
  152. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
  153. pBuf[i] = WIZCHIP.IF.SPI._read_byte();
  154. pBuf[i+1] = WIZCHIP.IF.SPI._read_byte();
  155. i += 2;
  156. AddrSel = WIZCHIP_OFFSET_INC(AddrSel,2);
  157. }
  158. }
  159. len %= 2;
  160. if(len)
  161. {
  162. AddrSel -= 1; // change _W5500_SPI_FDM_OP_LEN2_ to _W5500_SPI_FDM_OP_LEN1_
  163. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
  164. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
  165. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
  166. pBuf[i] = WIZCHIP.IF.SPI._read_byte();
  167. }
  168. #else
  169. #error "Unsupported _WIZCHIP_IO_MODE_SPI_ in W5500 !!!"
  170. #endif
  171. #elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) )
  172. #if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_)
  173. #elif(_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_)
  174. #else
  175. #error "Unsupported _WIZCHIP_IO_MODE_BUS_ in W5500 !!!"
  176. #endif
  177. #else
  178. #error "Unknown _WIZCHIP_IO_MODE_ in W5500. !!!!"
  179. #endif
  180. WIZCHIP.CS._deselect();
  181. WIZCHIP_CRITICAL_EXIT();
  182. }
  183. void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
  184. {
  185. uint16_t i = 0;
  186. uint16_t j = 0;
  187. WIZCHIP_CRITICAL_ENTER();
  188. WIZCHIP.CS._select();
  189. #if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
  190. #if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_ )
  191. AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_);
  192. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
  193. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
  194. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
  195. for(i = 0; i < len; i++,j)
  196. WIZCHIP.IF.SPI._write_byte(pBuf[i]);
  197. #elif( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_ )
  198. AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_FDM_OP_LEN4_);
  199. for(i = 0; i < len/4; i++, j)
  200. {
  201. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
  202. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
  203. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
  204. WIZCHIP.IF.SPI._write_byte(pBuf[i*4] );
  205. WIZCHIP.IF.SPI._write_byte(pBuf[i*4+1]);
  206. WIZCHIP.IF.SPI._write_byte(pBuf[i*4+2]);
  207. WIZCHIP.IF.SPI._write_byte(pBuf[i*4+3]);
  208. AddrSel = WIZCHIP_OFFSET_INC(AddrSel,4);
  209. }
  210. len %= 4; // for the rest data
  211. // M20131220 : Remove for loop
  212. i *= 4;
  213. if(len >= 2)
  214. {
  215. AddrSel -= 1; // change _W5500_SPI_FDM_OP_LEN4_ to _W5500_SPI_FDM_OP_LEN2_
  216. //for(j = 0; j < len/2 ; j++)
  217. {
  218. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
  219. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
  220. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
  221. WIZCHIP.IF.SPI._write_byte(pBuf[i] );
  222. WIZCHIP.IF.SPI._write_byte(pBuf[i+1]);
  223. i += 2;
  224. AddrSel = WIZCHIP_OFFSET_INC(AddrSel, 2);
  225. }
  226. len %= 2;
  227. if(len)
  228. {
  229. AddrSel -= 1; // change _W5500_SPI_FDM_OP_LEN2_ to _W5500_SPI_FDM_OP_LEN1_
  230. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
  231. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
  232. WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
  233. WIZCHIP.IF.SPI._write_byte(pBuf[i]);
  234. }
  235. }
  236. #else
  237. #error "Unsupported _WIZCHIP_IO_SPI_ in W5500 !!!"
  238. #endif
  239. #elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) )
  240. #if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_)
  241. #elif(_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_)
  242. #else
  243. #error "Unsupported _WIZCHIP_IO_MODE_BUS_ in W5500 !!!"
  244. #endif
  245. #else
  246. #error "Unknown _WIZCHIP_IO_MODE_ in W5500. !!!!"
  247. #endif
  248. WIZCHIP.CS._deselect();
  249. WIZCHIP_CRITICAL_EXIT();
  250. }
  251. uint16_t getSn_TX_FSR(uint8_t sn)
  252. {
  253. uint16_t val=0,val1=0;
  254. do
  255. {
  256. val1 = WIZCHIP_READ(Sn_TX_FSR(sn));
  257. val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
  258. if (val1 != 0)
  259. {
  260. val = WIZCHIP_READ(Sn_TX_FSR(sn));
  261. val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
  262. }
  263. }while (val != val1);
  264. return val;
  265. }
  266. uint16_t getSn_RX_RSR(uint8_t sn)
  267. {
  268. uint16_t val=0,val1=0;
  269. do
  270. {
  271. val1 = WIZCHIP_READ(Sn_RX_RSR(sn));
  272. val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
  273. if (val1 != 0)
  274. {
  275. val = WIZCHIP_READ(Sn_RX_RSR(sn));
  276. val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
  277. }
  278. }while (val != val1);
  279. return val;
  280. }
  281. void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
  282. {
  283. uint16_t ptr = 0;
  284. uint32_t addrsel = 0;
  285. if(len == 0) return;
  286. ptr = getSn_TX_WR(sn);
  287. //M20140501 : implict type casting -> explict type casting
  288. //addrsel = (ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3);
  289. addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3);
  290. //
  291. WIZCHIP_WRITE_BUF(addrsel,wizdata, len);
  292. ptr += len;
  293. setSn_TX_WR(sn,ptr);
  294. }
  295. void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
  296. {
  297. uint16_t ptr = 0;
  298. uint32_t addrsel = 0;
  299. if(len == 0) return;
  300. ptr = getSn_RX_RD(sn);
  301. //M20140501 : implict type casting -> explict type casting
  302. //addrsel = ((ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3);
  303. addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3);
  304. //
  305. WIZCHIP_READ_BUF(addrsel, wizdata, len);
  306. ptr += len;
  307. setSn_RX_RD(sn,ptr);
  308. }
  309. void wiz_recv_ignore(uint8_t sn, uint16_t len)
  310. {
  311. uint16_t ptr = 0;
  312. ptr = getSn_RX_RD(sn);
  313. ptr += len;
  314. setSn_RX_RD(sn,ptr);
  315. }