/netcon Module/Pollin AVR-NET-IO/netcon_ser_old/enc28j60.c

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