PageRenderTime 59ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/netcon Module/Ethernet-DK/enc28j60/enc28j60.c

https://github.com/sli92/netcon
C | 315 lines | 209 code | 83 blank | 23 comment | 7 complexity | 09fa4a3658cb97912f632f39f87783e0 MD5 | raw file
  1. /*
  2. * Datei: enc28j60.c
  3. * Author: dev00
  4. * Beschreibung: Stellt Funktionen fuer die Benutzung des ENC28J60
  5. * Netzwerkcontrollers zur Verfuegung.
  6. *
  7. * Aenderungsdatum: Do, 27. Okt 2011 20:53:13
  8. *
  9. */
  10. #include "compiler_defs.h"
  11. #include "C8051F340_defs.h"
  12. #include <stdint.h>
  13. #include <stdio.h>
  14. #include "enc28j60.h"
  15. #include "main.h"
  16. #include "uart.h"
  17. static uint8_t current_bank = 0;
  18. static uint16_t next_packet_addr = RECEIVE_BUFFER_START;
  19. /*
  20. * Interne Funktionen
  21. *
  22. */
  23. void get_cs(void)
  24. {
  25. SPI0CN &= ~(1 << _NSSMD0);
  26. }
  27. void release_cs(void)
  28. {
  29. SPI0CN |= (1 << _NSSMD0);
  30. }
  31. void enc28j60_set_bank(uint8_t reg_addr) __reentrant
  32. {
  33. if(((reg_addr & ADDR_MASK) < KEY_REGISTERS_START) &&
  34. current_bank != (reg_addr & BANK_MASK)) {
  35. current_bank = (reg_addr & BANK_MASK);
  36. enc28j60_bit_field_clear(ECON1, (1 << ECON1_BSEL1) |
  37. (1 << ECON1_BSEL0));
  38. enc28j60_bit_field_set(ECON1, (current_bank >> 5));
  39. }
  40. }
  41. void enc28j60_system_reset(void)
  42. {
  43. get_cs();
  44. SPI0DAT = OPCODE_SRC | 0x1F;
  45. while(!(SPI0CN & (1 << _SPIF)));
  46. SPI0CN &= ~(1 << _SPIF);
  47. release_cs();
  48. }
  49. uint8_t enc28j60_read_control_register(uint8_t reg_addr)
  50. {
  51. uint8_t _data;
  52. enc28j60_set_bank(reg_addr);
  53. get_cs();
  54. SPI0DAT = OPCODE_RCR | (reg_addr & ADDR_MASK);
  55. while(!(SPI0CN & (1 << _SPIF)));
  56. SPI0CN &= ~(1 << _SPIF);
  57. SPI0DAT = 0x00;
  58. while(!(SPI0CN & (1 << _SPIF)));
  59. _data = SPI0DAT;
  60. SPI0CN &= ~(1 << _SPIF);
  61. if(reg_addr & DUMMY_TRANSFER) {
  62. SPI0DAT = 0x00;
  63. while(!(SPI0CN & (1 << _SPIF)));
  64. _data = SPI0DAT;
  65. SPI0CN &= ~(1 << _SPIF);
  66. }
  67. release_cs();
  68. return _data;
  69. }
  70. void enc28j60_write_control_register(uint8_t reg_addr, uint8_t _data)
  71. {
  72. enc28j60_set_bank(reg_addr);
  73. get_cs();
  74. SPI0DAT = OPCODE_WCR | (reg_addr & ADDR_MASK);
  75. while(!(SPI0CN & (1 << _SPIF)));
  76. SPI0CN &= ~(1 << _SPIF);
  77. SPI0DAT = _data;
  78. while(!(SPI0CN & (1 << _SPIF)));
  79. SPI0CN &= ~(1 << _SPIF);
  80. release_cs();
  81. }
  82. void enc28j60_read_buffer_memory(uint8_t *_data, uint16_t len)
  83. {
  84. get_cs();
  85. SPI0DAT = OPCODE_RBM | 0x1A;
  86. while(!(SPI0CN & (1 << _SPIF)));
  87. SPI0CN &= ~(1 << _SPIF);
  88. while(len--) {
  89. SPI0DAT = 0x00;
  90. while(!(SPI0CN & (1 << _SPIF)));
  91. *_data++ = SPI0DAT;
  92. SPI0CN &= ~(1 << _SPIF);
  93. }
  94. release_cs();
  95. }
  96. void enc28j60_write_buffer_memory(const uint8_t *_data, uint16_t len)
  97. {
  98. get_cs();
  99. SPI0DAT = OPCODE_WBM | 0x1A;
  100. while(!(SPI0CN & (1 << _SPIF)));
  101. SPI0CN &= ~(1 << _SPIF);
  102. while(len--) {
  103. SPI0DAT = *_data++;
  104. while(!(SPI0CN & (1 << _SPIF)));
  105. SPI0CN &= ~(1 << _SPIF);
  106. }
  107. release_cs();
  108. }
  109. void enc28j60_bit_field_set(uint8_t reg_addr, uint8_t bitfield) __reentrant
  110. {
  111. enc28j60_set_bank(reg_addr);
  112. get_cs();
  113. SPI0DAT = OPCODE_BFS | (reg_addr & ADDR_MASK);
  114. while(!(SPI0CN & (1 << _SPIF)));
  115. SPI0CN &= ~(1 << _SPIF);
  116. SPI0DAT = bitfield;
  117. while(!(SPI0CN & (1 << _SPIF)));
  118. SPI0CN &= ~(1 << _SPIF);
  119. release_cs();
  120. }
  121. void enc28j60_bit_field_clear(uint8_t reg_addr, uint8_t bitfield) __reentrant
  122. {
  123. enc28j60_set_bank(reg_addr);
  124. get_cs();
  125. SPI0DAT = OPCODE_BFC | (reg_addr & ADDR_MASK);
  126. while(!(SPI0CN & (1 << _SPIF)));
  127. SPI0CN &= ~(1 << _SPIF);
  128. SPI0DAT = bitfield;
  129. while(!(SPI0CN & (1 << _SPIF)));
  130. SPI0CN &= ~(1 << _SPIF);
  131. release_cs();
  132. }
  133. uint16_t enc28j60_read_PHY_register(uint8_t reg_addr)
  134. {
  135. enc28j60_write_control_register(MIREGADR, reg_addr);
  136. enc28j60_bit_field_set(MICMD, (1 << MICMD_MIIRD));
  137. while(enc28j60_read_control_register(MISTAT) & (1 << MISTAT_BUSY));
  138. enc28j60_bit_field_clear(MICMD, (1 << MICMD_MIIRD));
  139. return enc28j60_read_control_register(MIRDL) | (enc28j60_read_control_register(MIRDH) << 8);
  140. }
  141. void enc28j60_write_PHY_register(uint8_t reg_addr, uint16_t _data)
  142. {
  143. enc28j60_write_control_register(MIREGADR, reg_addr);
  144. enc28j60_write_control_register(MIWRL, _data);
  145. enc28j60_write_control_register(MIWRH, _data >> 8);
  146. while(enc28j60_read_control_register(MISTAT) & (1 << MISTAT_BUSY));
  147. }
  148. /*
  149. * Benutzerfunktionen
  150. *
  151. */
  152. void enc28j60_init(const uint8_t *mac_addr)
  153. {
  154. SPI0CKR = 1;
  155. SPI0CFG |= (1 << _MSTEN);
  156. SPI0CN |= (1 << _NSSMD1) | (1 << _SPIEN);
  157. enc28j60_system_reset();
  158. delay_20ms();
  159. /* Empfangspuffer einstellen */
  160. enc28j60_write_control_register(ERXSTL, RECEIVE_BUFFER_START);
  161. enc28j60_write_control_register(ERXSTH, (uint16_t)RECEIVE_BUFFER_START >> 8);
  162. enc28j60_write_control_register(ERXNDL, RECEIVE_BUFFER_END);
  163. enc28j60_write_control_register(ERXNDH, (uint16_t)RECEIVE_BUFFER_END >> 8);
  164. // enc28j60_write_control_register(MACON1, 0x00);
  165. // enc28j60_set_bank(MACON1);
  166. /* MAC initialisieren */
  167. enc28j60_bit_field_set(MACON1, (1 << MACON1_MARXEN) |
  168. (1 << MACON1_TXPAUS) |
  169. (1 << MACON1_RXPAUS));
  170. enc28j60_bit_field_clear(MACON2, 1 << MACON2_MARST);
  171. enc28j60_bit_field_set(MACON3, (1 << MACON3_FULDPX) |
  172. (1 << MACON3_FRMLNEN) |
  173. (1 << MACON3_TXCRCEN) |
  174. (1 << MACON3_PADCFG0));
  175. enc28j60_write_control_register(MAMXFLL, MAX_FRAME_LENGTH + 4);
  176. enc28j60_write_control_register(MAMXFLH, (MAX_FRAME_LENGTH + 4) >> 8);
  177. /* Siehe ENC28J60 Datenblatt, Seite 34 */
  178. enc28j60_write_control_register(MABBIPG, 0x15);
  179. enc28j60_write_control_register(MAIPGL, 0x12);
  180. enc28j60_write_control_register(MAADR1, mac_addr[0]);
  181. enc28j60_write_control_register(MAADR2, mac_addr[1]);
  182. enc28j60_write_control_register(MAADR3, mac_addr[2]);
  183. enc28j60_write_control_register(MAADR4, mac_addr[3]);
  184. enc28j60_write_control_register(MAADR5, mac_addr[4]);
  185. enc28j60_write_control_register(MAADR6, mac_addr[5]);
  186. enc28j60_write_PHY_register(PHCON1, 1 << PHCON1_PDPXMD);
  187. enc28j60_bit_field_set(ECON1, 1 << ECON1_RXEN);
  188. }
  189. void enc28j60_transmit(const uint8_t *_data, uint16_t len)
  190. {
  191. uint8_t per_packet_control_byte = 0;
  192. uint16_t address = TRANSMIT_BUFFER_START;
  193. while(enc28j60_read_control_register(ECON1) & (1 << ECON1_TXRTS));
  194. enc28j60_write_control_register(ETXSTL, address);
  195. enc28j60_write_control_register(ETXSTH, address >> 8);
  196. enc28j60_write_control_register(EWRPTL, address);
  197. enc28j60_write_control_register(EWRPTH, address >> 8);
  198. enc28j60_write_buffer_memory(&per_packet_control_byte, 1);
  199. enc28j60_write_buffer_memory(_data, len);
  200. address += len;
  201. enc28j60_write_control_register(ETXNDL, address);
  202. enc28j60_write_control_register(ETXNDH, address >> 8);
  203. enc28j60_bit_field_clear(EIR, 1 << EIR_TXIF);
  204. enc28j60_bit_field_set(EIE, 1 << EIE_TXIE);
  205. enc28j60_bit_field_set(ECON1, 1 << ECON1_TXRTS);
  206. }
  207. uint16_t enc28j60_receive(uint8_t *_data, uint16_t max_len)
  208. {
  209. uint16_t length, temp;
  210. uint8_t header[6];
  211. if(!enc28j60_read_control_register(EPKTCNT))
  212. return 0;
  213. enc28j60_write_control_register(ERDPTL, next_packet_addr);
  214. enc28j60_write_control_register(ERDPTH, next_packet_addr >> 8);
  215. enc28j60_read_buffer_memory(header, 6);
  216. next_packet_addr = header[0] | (header[1] << 8);
  217. length = (header[2] | (((uint16_t)header[3]) << 8)) - 4;
  218. length = length > max_len ? max_len : length;
  219. enc28j60_read_buffer_memory(_data, length);
  220. /* ENC28J60 Errata, Seite 6, Issue 14 */
  221. temp = enc28j60_read_control_register(ERXSTL) | (enc28j60_read_control_register(ERXSTH) << 8);
  222. if(next_packet_addr == temp) {
  223. enc28j60_write_control_register(ERXRDPTL, RECEIVE_BUFFER_END);
  224. enc28j60_write_control_register(ERXRDPTH, RECEIVE_BUFFER_END >> 8);
  225. } else {
  226. temp = next_packet_addr - 1;
  227. enc28j60_write_control_register(ERXRDPTL, temp);
  228. enc28j60_write_control_register(ERXRDPTH, temp >> 8);
  229. }
  230. enc28j60_bit_field_set(ECON2, 1 << ECON2_PKTDEC);
  231. return length;
  232. }