找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5761|回复: 1
打印 上一主题 下一主题
收起左侧

收藏个老外写的ENC28J60驱动

[复制链接]
跳转到指定楼层
楼主
ID:100029 发表于 2015-12-22 21:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我就是伸手党 ,自己写不出来,就抄别人的。

  1. /*! \file enc28j60.h \brief Microchip ENC28J60 Ethernet Interface Driver. */
  2. //*****************************************************************************
  3. //
  4. // File Name    : 'enc28j60.h'
  5. // Title                : Microchip ENC28J60 Ethernet Interface Driver
  6. // Author               : Pascal Stang (c)2005
  7. // Created              : 9/22/2005
  8. // Revised              : 9/22/2005
  9. // Version              : 0.1
  10. // Target MCU   : Atmel AVR series
  11. // Editor Tabs  : 4
  12. //
  13. ///     \ingroup network
  14. ///     \defgroup enc28j60 Microchip ENC28J60 Ethernet Interface Driver (enc28j60.c)
  15. ///     \code #include "net/enc28j60.h" \endcode
  16. ///     \par Overview
  17. ///             This driver provides initialization and transmit/receive
  18. ///     functions for the Microchip ENC28J60 10Mb Ethernet Controller and PHY.
  19. /// This chip is novel in that it is a full MAC+PHY interface all in a 28-pin
  20. /// chip, using an SPI interface to the host processor.
  21. ///
  22. //
  23. //*****************************************************************************
  24. //@{

  25. #ifndef ENC28J60_H
  26. #define ENC28J60_H

  27. #include "global.h"

  28. //#define nop() asm volatile ("nop")

  29. // ENC28J60 Control Registers
  30. // Control register definitions are a combination of address,
  31. // bank number, and Ethernet/MAC/PHY indicator bits.
  32. // - Register address   (bits 0-4)
  33. // - Bank number                (bits 5-6)
  34. // - MAC/PHY indicator  (bit 7)
  35. #define ADDR_MASK       0x1F
  36. #define BANK_MASK       0x60
  37. #define SPRD_MASK       0x80
  38. // All-bank registers
  39. #define EIE                     0x1B
  40. #define EIR                     0x1C
  41. #define ESTAT           0x1D
  42. #define ECON2           0x1E
  43. #define ECON1           0x1F
  44. // Bank 0 registers
  45. #define ERDPTL          (0x00|0x00)
  46. #define ERDPTH          (0x01|0x00)
  47. #define EWRPTL          (0x02|0x00)
  48. #define EWRPTH          (0x03|0x00)
  49. #define ETXSTL          (0x04|0x00)
  50. #define ETXSTH          (0x05|0x00)
  51. #define ETXNDL          (0x06|0x00)
  52. #define ETXNDH          (0x07|0x00)
  53. #define ERXSTL          (0x08|0x00)
  54. #define ERXSTH          (0x09|0x00)
  55. #define ERXNDL          (0x0A|0x00)
  56. #define ERXNDH          (0x0B|0x00)
  57. #define ERXRDPTL        (0x0C|0x00)
  58. #define ERXRDPTH        (0x0D|0x00)
  59. #define ERXWRPTL        (0x0E|0x00)
  60. #define ERXWRPTH        (0x0F|0x00)
  61. #define EDMASTL         (0x10|0x00)
  62. #define EDMASTH         (0x11|0x00)
  63. #define EDMANDL         (0x12|0x00)
  64. #define EDMANDH         (0x13|0x00)
  65. #define EDMADSTL        (0x14|0x00)
  66. #define EDMADSTH        (0x15|0x00)
  67. #define EDMACSL         (0x16|0x00)
  68. #define EDMACSH         (0x17|0x00)
  69. // Bank 1 registers
  70. #define EHT0            (0x00|0x20)
  71. #define EHT1            (0x01|0x20)
  72. #define EHT2            (0x02|0x20)
  73. #define EHT3            (0x03|0x20)
  74. #define EHT4            (0x04|0x20)
  75. #define EHT5            (0x05|0x20)
  76. #define EHT6            (0x06|0x20)
  77. #define EHT7            (0x07|0x20)
  78. #define EPMM0           (0x08|0x20)
  79. #define EPMM1           (0x09|0x20)
  80. #define EPMM2           (0x0A|0x20)
  81. #define EPMM3           (0x0B|0x20)
  82. #define EPMM4           (0x0C|0x20)
  83. #define EPMM5           (0x0D|0x20)
  84. #define EPMM6           (0x0E|0x20)
  85. #define EPMM7           (0x0F|0x20)
  86. #define EPMCSL          (0x10|0x20)
  87. #define EPMCSH          (0x11|0x20)
  88. #define EPMOL           (0x14|0x20)
  89. #define EPMOH           (0x15|0x20)
  90. #define EWOLIE          (0x16|0x20)
  91. #define EWOLIR          (0x17|0x20)
  92. #define ERXFCON         (0x18|0x20)
  93. #define EPKTCNT         (0x19|0x20)
  94. // Bank 2 registers
  95. #define MACON1          (0x00|0x40|0x80)
  96. #define MACON2          (0x01|0x40|0x80)
  97. #define MACON3          (0x02|0x40|0x80)
  98. #define MACON4          (0x03|0x40|0x80)
  99. #define MABBIPG         (0x04|0x40|0x80)
  100. #define MAIPGL          (0x06|0x40|0x80)
  101. #define MAIPGH          (0x07|0x40|0x80)
  102. #define MACLCON1        (0x08|0x40|0x80)
  103. #define MACLCON2        (0x09|0x40|0x80)
  104. #define MAMXFLL         (0x0A|0x40|0x80)
  105. #define MAMXFLH         (0x0B|0x40|0x80)
  106. #define MAPHSUP         (0x0D|0x40|0x80)
  107. #define MICON           (0x11|0x40|0x80)
  108. #define MICMD           (0x12|0x40|0x80)
  109. #define MIREGADR        (0x14|0x40|0x80)
  110. #define MIWRL           (0x16|0x40|0x80)
  111. #define MIWRH           (0x17|0x40|0x80)
  112. #define MIRDL           (0x18|0x40|0x80)
  113. #define MIRDH           (0x19|0x40|0x80)
  114. // Bank 3 registers
  115. #define MAADR1          (0x00|0x60|0x80)
  116. #define MAADR0          (0x01|0x60|0x80)
  117. #define MAADR3          (0x02|0x60|0x80)
  118. #define MAADR2          (0x03|0x60|0x80)
  119. #define MAADR5          (0x04|0x60|0x80)
  120. #define MAADR4          (0x05|0x60|0x80)
  121. #define EBSTSD          (0x06|0x60)
  122. #define EBSTCON         (0x07|0x60)
  123. #define EBSTCSL         (0x08|0x60)
  124. #define EBSTCSH         (0x09|0x60)
  125. #define MISTAT          (0x0A|0x60|0x80)
  126. #define EREVID          (0x12|0x60)
  127. #define ECOCON          (0x15|0x60)
  128. #define EFLOCON         (0x17|0x60)
  129. #define EPAUSL          (0x18|0x60)
  130. #define EPAUSH          (0x19|0x60)
  131. // PHY registers
  132. #define PHCON1          0x00
  133. #define PHSTAT1         0x01
  134. #define PHHID1          0x02
  135. #define PHHID2          0x03
  136. #define PHCON2          0x10
  137. #define PHSTAT2         0x11
  138. #define PHIE            0x12
  139. #define PHIR            0x13
  140. #define PHLCON          0x14

  141. // ENC28J60 EIE Register Bit Definitions
  142. #define EIE_INTIE               0x80
  143. #define EIE_PKTIE               0x40
  144. #define EIE_DMAIE               0x20
  145. #define EIE_LINKIE              0x10
  146. #define EIE_TXIE                0x08
  147. #define EIE_WOLIE               0x04
  148. #define EIE_TXERIE              0x02
  149. #define EIE_RXERIE              0x01
  150. // ENC28J60 EIR Register Bit Definitions
  151. #define EIR_PKTIF               0x40
  152. #define EIR_DMAIF               0x20
  153. #define EIR_LINKIF              0x10
  154. #define EIR_TXIF                0x08
  155. #define EIR_WOLIF               0x04
  156. #define EIR_TXERIF              0x02
  157. #define EIR_RXERIF              0x01
  158. // ENC28J60 ESTAT Register Bit Definitions
  159. #define ESTAT_INT               0x80
  160. #define ESTAT_LATECOL   0x10
  161. #define ESTAT_RXBUSY    0x04
  162. #define ESTAT_TXABRT    0x02
  163. #define ESTAT_CLKRDY    0x01
  164. // ENC28J60 ECON2 Register Bit Definitions
  165. #define ECON2_AUTOINC   0x80
  166. #define ECON2_PKTDEC    0x40
  167. #define ECON2_PWRSV             0x20
  168. #define ECON2_VRPS              0x08
  169. // ENC28J60 ECON1 Register Bit Definitions
  170. #define ECON1_TXRST             0x80
  171. #define ECON1_RXRST             0x40
  172. #define ECON1_DMAST             0x20
  173. #define ECON1_CSUMEN    0x10
  174. #define ECON1_TXRTS             0x08
  175. #define ECON1_RXEN              0x04
  176. #define ECON1_BSEL1             0x02
  177. #define ECON1_BSEL0             0x01
  178. // ENC28J60 MACON1 Register Bit Definitions
  179. #define MACON1_LOOPBK   0x10
  180. #define MACON1_TXPAUS   0x08
  181. #define MACON1_RXPAUS   0x04
  182. #define MACON1_PASSALL  0x02
  183. #define MACON1_MARXEN   0x01
  184. // ENC28J60 MACON2 Register Bit Definitions
  185. #define MACON2_MARST    0x80
  186. #define MACON2_RNDRST   0x40
  187. #define MACON2_MARXRST  0x08
  188. #define MACON2_RFUNRST  0x04
  189. #define MACON2_MATXRST  0x02
  190. #define MACON2_TFUNRST  0x01
  191. // ENC28J60 MACON3 Register Bit Definitions
  192. #define MACON3_PADCFG2  0x80
  193. #define MACON3_PADCFG1  0x40
  194. #define MACON3_PADCFG0  0x20
  195. #define MACON3_TXCRCEN  0x10
  196. #define MACON3_PHDRLEN  0x08
  197. #define MACON3_HFRMLEN  0x04
  198. #define MACON3_FRMLNEN  0x02
  199. #define MACON3_FULDPX   0x01
  200. // ENC28J60 MICMD Register Bit Definitions
  201. #define MICMD_MIISCAN   0x02
  202. #define MICMD_MIIRD             0x01
  203. // ENC28J60 MISTAT Register Bit Definitions
  204. #define MISTAT_NVALID   0x04
  205. #define MISTAT_SCAN             0x02
  206. #define MISTAT_BUSY             0x01
  207. // ENC28J60 PHY PHCON1 Register Bit Definitions
  208. #define PHCON1_PRST             0x8000
  209. #define PHCON1_PLOOPBK  0x4000
  210. #define PHCON1_PPWRSV   0x0800
  211. #define PHCON1_PDPXMD   0x0100
  212. // ENC28J60 PHY PHSTAT1 Register Bit Definitions
  213. #define PHSTAT1_PFDPX   0x1000
  214. #define PHSTAT1_PHDPX   0x0800
  215. #define PHSTAT1_LLSTAT  0x0004
  216. #define PHSTAT1_JBSTAT  0x0002
  217. // ENC28J60 PHY PHCON2 Register Bit Definitions
  218. #define PHCON2_FRCLINK  0x4000
  219. #define PHCON2_TXDIS    0x2000
  220. #define PHCON2_JABBER   0x0400
  221. #define PHCON2_HDLDIS   0x0100

  222. // ENC28J60 Packet Control Byte Bit Definitions
  223. #define PKTCTRL_PHUGEEN         0x08
  224. #define PKTCTRL_PPADEN          0x04
  225. #define PKTCTRL_PCRCEN          0x02
  226. #define PKTCTRL_POVERRIDE       0x01

  227. // SPI operation codes
  228. #define ENC28J60_READ_CTRL_REG  0x00
  229. #define ENC28J60_READ_BUF_MEM   0x3A
  230. #define ENC28J60_WRITE_CTRL_REG 0x40
  231. #define ENC28J60_WRITE_BUF_MEM  0x7A
  232. #define ENC28J60_BIT_FIELD_SET  0x80
  233. #define ENC28J60_BIT_FIELD_CLR  0xA0
  234. #define ENC28J60_SOFT_RESET             0xFF


  235. // buffer boundaries applied to internal 8K ram
  236. //      entire available packet buffer space is allocated
  237. #define TXSTART_INIT    0x0000  // start TX buffer at 0
  238. #define RXSTART_INIT    0x0600  // give TX buffer space for one full ethernet frame (~1500 bytes)
  239. #define RXSTOP_INIT     0x1FFF  // receive buffer gets the rest

  240. #define MAX_FRAMELEN    1518    // maximum ethernet frame length

  241. // Ethernet constants
  242. #define ETHERNET_MIN_PACKET_LENGTH      0x3C
  243. //#define ETHERNET_HEADER_LENGTH                0x0E

  244. // setup ports for I/O
  245. //void ax88796SetupPorts(void);

  246. //! do a ENC28J60 read operation
  247. u08 enc28j60ReadOp(u08 op, u08 address);
  248. //! do a ENC28J60 write operation
  249. void enc28j60WriteOp(u08 op, u08 address, u08 data);
  250. //! read the packet buffer memory
  251. void enc28j60ReadBuffer(u16 len, u08* data);
  252. //! write the packet buffer memory
  253. void enc28j60WriteBuffer(u16 len, u08* data);
  254. //! set the register bank for register at address
  255. void enc28j60SetBank(u08 address);
  256. //! read ax88796 register
  257. u08 enc28j60Read(u08 address);
  258. //! write ax88796 register
  259. void enc28j60Write(u08 address, u08 data);
  260. //! read a PHY register
  261. u16 enc28j60PhyRead(u08 address);
  262. //! write a PHY register
  263. void enc28j60PhyWrite(u08 address, u16 data);

  264. //! initialize the ethernet interface for transmit/receive
  265. void enc28j60Init(void);

  266. //! Packet transmit function.
  267. /// Sends a packet on the network.  It is assumed that the packet is headed by a valid ethernet header.
  268. /// \param len          Length of packet in bytes.
  269. /// \param packet       Pointer to packet data.
  270. /// \param len2         Length of the secound packet in bytes, can be 0.
  271. /// \param packet2      Pointer to the secound packet data, can be NULL.
  272. void enc28j60PacketSend(unsigned int len1, unsigned char* packet1, unsigned int len2, unsigned char* packet2);

  273. //! Packet receive function.
  274. /// Gets a packet from the network receive buffer, if one is available.
  275. /// The packet will by headed by an ethernet header.
  276. /// \param      maxlen  The maximum acceptable length of a retrieved packet.
  277. /// \param      packet  Pointer where packet data should be stored.
  278. /// \return Packet length in bytes if a packet was retrieved, zero otherwise.
  279. unsigned int enc28j60PacketReceive(unsigned int maxlen, unsigned char* packet);

  280. //! execute procedure for recovering from a receive overflow
  281. /// this should be done when the receive memory fills up with packets
  282. void enc28j60ReceiveOverflowRecover(void);

  283. #endif
  284. //@}
  285. /*! \file enc28j60.c \brief Microchip ENC28J60 Ethernet Interface Driver. */
  286. //*****************************************************************************
  287. //
  288. // File Name    : 'enc28j60.c'
  289. // Title                : Microchip ENC28J60 Ethernet Interface Driver
  290. // Author               : Pascal Stang (c)2005
  291. // Created              : 9/22/2005
  292. // Revised              : 9/22/2005
  293. // Version              : 0.1
  294. // Target MCU   : Atmel AVR series
  295. // Editor Tabs  : 4
  296. //
  297. // Description  : This driver provides initialization and transmit/receive
  298. //      functions for the Microchip ENC28J60 10Mb Ethernet Controller and PHY.
  299. // This chip is novel in that it is a full MAC+PHY interface all in a 28-pin
  300. // chip, using an SPI interface to the host processor.
  301. //
  302. //*****************************************************************************

  303. #include "global-conf.h"
  304. #include <avr/io.h>
  305. #include <util/delay.h>
  306. #include "global.h"
  307. //#include "timer.h"    //Note have been replaced with _delay_us() as this is more convient

  308. #include "enc28j60.h"

  309. #ifdef SPDR0
  310.         #define SPDR    SPDR0
  311.         #define SPCR    SPCR0
  312.         #define SPSR    SPSR0

  313.         #define SPIF    SPIF0
  314.         #define MSTR    MSTR0
  315.         #define CPOL    CPOL0
  316.         #define DORD    DORD0
  317.         #define SPR0    SPR00
  318.         #define SPR1    SPR01
  319.         #define SPI2X   SPI2X0
  320.         #define SPE             SPE0
  321. #endif

  322. // include configuration
  323. #include "enc28j60conf.h"

  324. u08 Enc28j60Bank;
  325. u16 NextPacketPtr;

  326. /*void nicInit(void)
  327. {
  328.         enc28j60Init();
  329. }

  330. void nicSend(unsigned int len, unsigned char* packet)
  331. {
  332.         enc28j60PacketSend(len, packet);
  333. }

  334. unsigned int nicPoll(unsigned int maxlen, unsigned char* packet)
  335. {
  336.         return enc28j60PacketReceive(maxlen, packet);
  337. }*/


  338. /*void nicRegDump(void)
  339. {
  340.         enc28j60RegDump();
  341. }*/

  342. /*
  343. void ax88796SetupPorts(void)
  344. {
  345. #if NIC_CONNECTION == MEMORY_MAPPED
  346.         // enable external SRAM interface - no wait states
  347.         sbi(MCUCR, SRE);
  348. //      sbi(MCUCR, SRW10);
  349. //      sbi(XMCRA, SRW00);
  350. //      sbi(XMCRA, SRW01);
  351. //      sbi(XMCRA, SRW11);
  352. #else
  353.         // set address port to output
  354.         AX88796_ADDRESS_DDR = AX88796_ADDRESS_MASK;
  355.    
  356.         // set data port to input with pull-ups
  357.         AX88796_DATA_DDR = 0x00;
  358.         AX88796_DATA_PORT = 0xFF;

  359.         // initialize the control port read and write pins to de-asserted
  360.         sbi( AX88796_CONTROL_PORT, AX88796_CONTROL_READPIN );
  361.         sbi( AX88796_CONTROL_PORT, AX88796_CONTROL_WRITEPIN );
  362.         // set the read and write pins to output
  363.         sbi( AX88796_CONTROL_DDR, AX88796_CONTROL_READPIN );
  364.         sbi( AX88796_CONTROL_DDR, AX88796_CONTROL_WRITEPIN );
  365. #endif
  366.         // set reset pin to output
  367.         sbi( AX88796_RESET_DDR, AX88796_RESET_PIN );
  368. }
  369. */

  370. u08 enc28j60ReadOp(u08 op, u08 address)
  371. {
  372.         u08 data;
  373.    
  374.         // assert CS
  375.         ENC28J60_CONTROL_PORT &= ~(1<<ENC28J60_CONTROL_CS);
  376.         
  377.         // issue read command
  378.         SPDR = op | (address & ADDR_MASK);
  379.         while(!(SPSR & (1<<SPIF)));
  380.         // read data
  381.         SPDR = 0x00;
  382.         while(!(SPSR & (1<<SPIF)));
  383.         // do dummy read if needed
  384.         if(address & 0x80)
  385.         {
  386.                 SPDR = 0x00;
  387.                 while(!(inb(SPSR) & (1<<SPIF)));
  388.         }
  389.         data = SPDR;
  390.         
  391.         // release CS
  392.         ENC28J60_CONTROL_PORT |= (1<<ENC28J60_CONTROL_CS);

  393.         return data;
  394. }

  395. void enc28j60WriteOp(u08 op, u08 address, u08 data)
  396. {
  397.         // assert CS
  398.         ENC28J60_CONTROL_PORT &= ~(1<<ENC28J60_CONTROL_CS);

  399.         // issue write command
  400.         SPDR = op | (address & ADDR_MASK);
  401.         while(!(SPSR & (1<<SPIF)));
  402.         // write data
  403.         SPDR = data;
  404.         while(!(SPSR & (1<<SPIF)));

  405.         // release CS
  406.         ENC28J60_CONTROL_PORT |= (1<<ENC28J60_CONTROL_CS);
  407. }

  408. void enc28j60ReadBuffer(u16 len, u08* data)
  409. {
  410.         // assert CS
  411.         ENC28J60_CONTROL_PORT &= ~(1<<ENC28J60_CONTROL_CS);
  412.         
  413.         // issue read command
  414.         SPDR = ENC28J60_READ_BUF_MEM;
  415.         while(!(SPSR & (1<<SPIF)));
  416.         while(len--)
  417.         {
  418.                 // read data
  419.                 SPDR = 0x00;
  420.                 while(!(SPSR & (1<<SPIF)));
  421.                 *data++ = SPDR;
  422.         }      
  423.         // release CS
  424.         ENC28J60_CONTROL_PORT |= (1<<ENC28J60_CONTROL_CS);
  425. }

  426. void enc28j60WriteBuffer(u16 len, u08* data)
  427. {
  428.         // assert CS
  429.         ENC28J60_CONTROL_PORT &= ~(1<<ENC28J60_CONTROL_CS);
  430.         
  431.         // issue write command
  432.         SPDR = ENC28J60_WRITE_BUF_MEM;
  433.         while(!(SPSR & (1<<SPIF)));
  434.         while(len--)
  435.         {
  436.                 // write data
  437.                 SPDR = *data++;
  438.                 while(!(SPSR & (1<<SPIF)));
  439.         }      
  440.         // release CS
  441.         ENC28J60_CONTROL_PORT |= (1<<ENC28J60_CONTROL_CS);
  442. }

  443. void enc28j60SetBank(u08 address)
  444. {
  445.         // set the bank (if needed)
  446.         if((address & BANK_MASK) != Enc28j60Bank)
  447.         {
  448.                 // set the bank
  449.                 enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0));
  450.                 enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>5);
  451.                 Enc28j60Bank = (address & BANK_MASK);
  452.         }
  453. }

  454. u08 enc28j60Read(u08 address)
  455. {
  456.         // set the bank
  457.         enc28j60SetBank(address);
  458.         // do the read
  459.         return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address);
  460. }

  461. void enc28j60Write(u08 address, u08 data)
  462. {
  463.         // set the bank
  464.         enc28j60SetBank(address);
  465.         // do the write
  466.         enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data);
  467. }

  468. u16 enc28j60PhyRead(u08 address)
  469. {
  470.         u16 data;

  471.         // Set the right address and start the register read operation
  472.         enc28j60Write(MIREGADR, address);
  473.         enc28j60Write(MICMD, MICMD_MIIRD);

  474.         // wait until the PHY read completes
  475.         while(enc28j60Read(MISTAT) & MISTAT_BUSY);

  476.         // quit reading
  477.         enc28j60Write(MICMD, 0x00);
  478.         
  479.         // get data value
  480.         data  = enc28j60Read(MIRDL);
  481.         data |= enc28j60Read(MIRDH);
  482.         // return the data
  483.         return data;
  484. }

  485. void enc28j60PhyWrite(u08 address, u16 data)
  486. {
  487.         // set the PHY register address
  488.         enc28j60Write(MIREGADR, address);
  489.         
  490.         // write the PHY data
  491.         enc28j60Write(MIWRL, data);     
  492.         enc28j60Write(MIWRH, data>>8);

  493.         // wait until the PHY write completes
  494.         while(enc28j60Read(MISTAT) & MISTAT_BUSY);
  495. }

  496. void enc28j60Init(void)
  497. {
  498.         // initialize I/O
  499.         sbi(ENC28J60_CONTROL_DDR, ENC28J60_CONTROL_CS);
  500.         sbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS);

  501.         // setup SPI I/O pins
  502.         sbi(ENC28J60_SPI_PORT, ENC28J60_SPI_SCK);       // set SCK hi
  503.         sbi(ENC28J60_SPI_DDR, ENC28J60_SPI_SCK);        // set SCK as output
  504.         cbi(ENC28J60_SPI_DDR, ENC28J60_SPI_MISO);       // set MISO as input
  505.         sbi(ENC28J60_SPI_DDR, ENC28J60_SPI_MOSI);       // set MOSI as output
  506.         sbi(ENC28J60_SPI_DDR, ENC28J60_SPI_SS);         // SS must be output for Master mode to work
  507.         // initialize SPI interface
  508.         // master mode
  509.         sbi(SPCR, MSTR);
  510.         // select clock phase positive-going in middle of data
  511.         cbi(SPCR, CPOL);
  512.         // Data order MSB first
  513.         cbi(SPCR,DORD);
  514.         // switch to f/4 2X = f/2 bitrate
  515.         cbi(SPCR, SPR0);
  516.         cbi(SPCR, SPR1);
  517.         sbi(SPSR, SPI2X);
  518.         // enable SPI
  519.         sbi(SPCR, SPE);

  520.         // perform system reset
  521.         enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
  522.         // check CLKRDY bit to see if reset is complete
  523.         _delay_us(50);
  524.         while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY));

  525.         // do bank 0 stuff
  526.         // initialize receive buffer
  527.         // 16-bit transfers, must write low byte first
  528.         // set receive buffer start address
  529.         NextPacketPtr = RXSTART_INIT;
  530.         enc28j60Write(ERXSTL, RXSTART_INIT&0xFF);
  531.         enc28j60Write(ERXSTH, RXSTART_INIT>>8);
  532.         // set receive pointer address
  533.         enc28j60Write(ERXRDPTL, RXSTART_INIT&0xFF);
  534.         enc28j60Write(ERXRDPTH, RXSTART_INIT>>8);
  535.         // set receive buffer end
  536.         // ERXND defaults to 0x1FFF (end of ram)
  537.         enc28j60Write(ERXNDL, RXSTOP_INIT&0xFF);
  538.         enc28j60Write(ERXNDH, RXSTOP_INIT>>8);
  539.         // set transmit buffer start
  540.         // ETXST defaults to 0x0000 (beginnging of ram)
  541.         enc28j60Write(ETXSTL, TXSTART_INIT&0xFF);
  542.         enc28j60Write(ETXSTH, TXSTART_INIT>>8);

  543.         // do bank 2 stuff
  544.         // enable MAC receive
  545.         enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
  546.         // bring MAC out of reset
  547.         enc28j60Write(MACON2, 0x00);
  548.         // enable automatic padding and CRC operations
  549.         enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);
  550. //      enc28j60Write(MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);
  551.         // set inter-frame gap (non-back-to-back)
  552.         enc28j60Write(MAIPGL, 0x12);
  553.         enc28j60Write(MAIPGH, 0x0C);
  554.         // set inter-frame gap (back-to-back)
  555.         enc28j60Write(MABBIPG, 0x12);
  556.         // Set the maximum packet size which the controller will accept
  557.         enc28j60Write(MAMXFLL, MAX_FRAMELEN&0xFF);      
  558.         enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8);

  559.         // do bank 3 stuff
  560.         // write MAC address
  561.         // NOTE: MAC address in ENC28J60 is byte-backward
  562.         enc28j60Write(MAADR5, ENC28J60_MAC0);
  563.         enc28j60Write(MAADR4, ENC28J60_MAC1);
  564.         enc28j60Write(MAADR3, ENC28J60_MAC2);
  565.         enc28j60Write(MAADR2, ENC28J60_MAC3);
  566.         enc28j60Write(MAADR1, ENC28J60_MAC4);
  567.         enc28j60Write(MAADR0, ENC28J60_MAC5);

  568.         // no loopback of transmitted frames
  569.         enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS);

  570.         // switch to bank 0
  571.         enc28j60SetBank(ECON1);
  572.         // enable interrutps
  573.         enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);
  574.         // enable packet reception
  575.         enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
  576. /*
  577.         enc28j60PhyWrite(PHLCON, 0x0AA2);

  578.         // setup duplex ----------------------

  579.         // Disable receive logic and abort any packets currently being transmitted
  580.         enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS|ECON1_RXEN);
  581.         
  582.         {
  583.                 u16 temp;
  584.                 // Set the PHY to the proper duplex mode
  585.                 temp = enc28j60PhyRead(PHCON1);
  586.                 temp &= ~PHCON1_PDPXMD;
  587.                 enc28j60PhyWrite(PHCON1, temp);
  588.                 // Set the MAC to the proper duplex mode
  589.                 temp = enc28j60Read(MACON3);
  590.                 temp &= ~MACON3_FULDPX;
  591.                 enc28j60Write(MACON3, temp);
  592.         }

  593.         // Set the back-to-back inter-packet gap time to IEEE specified
  594.         // requirements.  The meaning of the MABBIPG value changes with the duplex
  595.         // state, so it must be updated in this function.
  596.         // In full duplex, 0x15 represents 9.6us; 0x12 is 9.6us in half duplex
  597.         //enc28j60Write(MABBIPG, DuplexState ? 0x15 : 0x12);   
  598.         
  599.         // Reenable receive logic
  600.         enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);

  601.         // setup duplex ----------------------
  602. */
  603. }

  604. void enc28j60PacketSend(unsigned int len1, unsigned char* packet1, unsigned int len2, unsigned char* packet2)
  605. {
  606.         //Errata: Transmit Logic reset
  607.         enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST);
  608.         enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST);

  609.         // Set the write pointer to start of transmit buffer area
  610.         enc28j60Write(EWRPTL, TXSTART_INIT&0xff);
  611.         enc28j60Write(EWRPTH, TXSTART_INIT>>8);
  612.         // Set the TXND pointer to correspond to the packet size given
  613.         enc28j60Write(ETXNDL, (TXSTART_INIT+len1+len2));
  614.         enc28j60Write(ETXNDH, (TXSTART_INIT+len1+len2)>>8);

  615.         // write per-packet control byte
  616.         enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);

  617.         // copy the packet into the transmit buffer
  618.         enc28j60WriteBuffer(len1, packet1);
  619.         if(len2>0) enc28j60WriteBuffer(len2, packet2);
  620.         
  621.         // send the contents of the transmit buffer onto the network
  622.         enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
  623. }

  624. unsigned int enc28j60PacketReceive(unsigned int maxlen, unsigned char* packet)
  625. {
  626.         u16 rxstat;
  627.         u16 len;

  628.         // check if a packet has been received and buffered
  629. //      if( !(enc28j60Read(EIR) & EIR_PKTIF) )
  630.         if( !enc28j60Read(EPKTCNT) )
  631.                 return 0;
  632.         
  633.         // Make absolutely certain that any previous packet was discarded      
  634.         //if( WasDiscarded == FALSE)
  635.         //      MACDiscardRx();

  636.         // Set the read pointer to the start of the received packet
  637.         enc28j60Write(ERDPTL, (NextPacketPtr));
  638.         enc28j60Write(ERDPTH, (NextPacketPtr)>>8);
  639.         // read the next packet pointer
  640.         NextPacketPtr  = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
  641.         NextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8;
  642.         // read the packet length
  643.         len  = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
  644.         len |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8;
  645.         // read the receive status
  646.         rxstat  = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
  647.         rxstat |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8;

  648.         // limit retrieve length
  649.         // (we reduce the MAC-reported length by 4 to remove the CRC)
  650.         len = MIN(len, maxlen);

  651.         // copy the packet from the receive buffer
  652.         enc28j60ReadBuffer(len, packet);

  653.         // Move the RX read pointer to the start of the next received packet
  654.         // This frees the memory we just read out
  655.         enc28j60Write(ERXRDPTL, (NextPacketPtr));
  656.         enc28j60Write(ERXRDPTH, (NextPacketPtr)>>8);

  657.         // decrement the packet counter indicate we are done with this packet
  658.         enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);

  659.         return len;
  660. }

  661. void enc28j60ReceiveOverflowRecover(void)
  662. {
  663.         // receive buffer overflow handling procedure

  664.         // recovery completed
  665. }

  666. /*
  667. void enc28j60RegDump(void)
  668. {
  669. //      unsigned char macaddr[6];
  670. //      result = ax88796Read(TR);
  671.         
  672. //      rprintf("Media State: ");
  673. //      if(!(result & AUTOD))
  674. //              rprintf("Autonegotiation\r\n");
  675. //      else if(result & RST_B)
  676. //              rprintf("PHY in Reset   \r\n");
  677. //      else if(!(result & RST_10B))
  678. //              rprintf("10BASE-T       \r\n");
  679. //      else if(!(result & RST_TXB))
  680. //              rprintf("100BASE-T      \r\n");
  681.                                 
  682.         rprintf("RevID: 0x%x\r\n", enc28j60Read(EREVID));

  683.         rprintfProgStrM("Cntrl: ECON1 ECON2 ESTAT  EIR  EIE\r\n");
  684.         rprintfProgStrM("         ");
  685.         rprintfu08(enc28j60Read(ECON1));
  686.         rprintfProgStrM("    ");
  687.         rprintfu08(enc28j60Read(ECON2));
  688.         rprintfProgStrM("    ");
  689.         rprintfu08(enc28j60Read(ESTAT));
  690.         rprintfProgStrM("    ");
  691.         rprintfu08(enc28j60Read(EIR));
  692.         rprintfProgStrM("   ");
  693.         rprintfu08(enc28j60Read(EIE));
  694.         rprintfCRLF();

  695.         rprintfProgStrM("MAC  : MACON1  MACON2  MACON3  MACON4  MAC-Address\r\n");
  696.         rprintfProgStrM("        0x");
  697.         rprintfu08(enc28j60Read(MACON1));
  698.         rprintfProgStrM("    0x");
  699.         rprintfu08(enc28j60Read(MACON2));
  700.         rprintfProgStrM("    0x");
  701.         rprintfu08(enc28j60Read(MACON3));
  702.         rprintfProgStrM("    0x");
  703.         rprintfu08(enc28j60Read(MACON4));
  704.         rprintfProgStrM("   ");
  705.         rprintfu08(enc28j60Read(MAADR5));
  706.         rprintfu08(enc28j60Read(MAADR4));
  707.         rprintfu08(enc28j60Read(MAADR3));
  708.         rprintfu08(enc28j60Read(MAADR2));
  709.         rprintfu08(enc28j60Read(MAADR1));
  710.         rprintfu08(enc28j60Read(MAADR0));
  711.         rprintfCRLF();

  712.         rprintfProgStrM("Rx   : ERXST  ERXND  ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL\r\n");
  713.         rprintfProgStrM("       0x");
  714.         rprintfu08(enc28j60Read(ERXSTH));
  715.         rprintfu08(enc28j60Read(ERXSTL));
  716.         rprintfProgStrM(" 0x");
  717.         rprintfu08(enc28j60Read(ERXNDH));
  718.         rprintfu08(enc28j60Read(ERXNDL));
  719.         rprintfProgStrM("  0x");
  720.         rprintfu08(enc28j60Read(ERXWRPTH));
  721.         rprintfu08(enc28j60Read(ERXWRPTL));
  722.         rprintfProgStrM("  0x");
  723.         rprintfu08(enc28j60Read(ERXRDPTH));
  724.         rprintfu08(enc28j60Read(ERXRDPTL));
  725.         rprintfProgStrM("   0x");
  726.         rprintfu08(enc28j60Read(ERXFCON));
  727.         rprintfProgStrM("    0x");
  728.         rprintfu08(enc28j60Read(EPKTCNT));
  729.         rprintfProgStrM("  0x");
  730.         rprintfu08(enc28j60Read(MAMXFLH));
  731.         rprintfu08(enc28j60Read(MAMXFLL));
  732.         rprintfCRLF();

  733.         rprintfProgStrM("Tx   : ETXST  ETXND  MACLCON1 MACLCON2 MAPHSUP\r\n");
  734.         rprintfProgStrM("       0x");
  735.         rprintfu08(enc28j60Read(ETXSTH));
  736.         rprintfu08(enc28j60Read(ETXSTL));
  737.         rprintfProgStrM(" 0x");
  738.         rprintfu08(enc28j60Read(ETXNDH));
  739.         rprintfu08(enc28j60Read(ETXNDL));
  740.         rprintfProgStrM("   0x");
  741.         rprintfu08(enc28j60Read(MACLCON1));
  742.         rprintfProgStrM("     0x");
  743.         rprintfu08(enc28j60Read(MACLCON2));
  744.         rprintfProgStrM("     0x");
  745.         rprintfu08(enc28j60Read(MAPHSUP));
  746.         rprintfCRLF();

  747.         _delay_ms(25);
  748. }
  749. */
  750. /*! \file enc28j60conf.h \brief Microchip ENC28J60 Ethernet Interface Driver Configuration. */
  751. //*****************************************************************************
  752. //
  753. // File Name    : 'enc28j60conf.h'
  754. // Title                : Microchip ENC28J60 Ethernet Interface Driver Configuration
  755. // Author               : Pascal Stang
  756. // Created              : 10/5/2004
  757. // Revised              : 8/22/2005
  758. // Version              : 0.1
  759. // Target MCU   : Atmel AVR series
  760. // Editor Tabs  : 4
  761. //
  762. // Description  : This driver provides initialization and transmit/receive
  763. //              functions for the ENC28J60 10Mb Ethernet Controller and PHY.
  764. //
  765. // This code is distributed under the GNU Public License
  766. //              which can be found at http://www.gnu.org/licenses/gpl.txt
  767. //
  768. //*****************************************************************************


  769. /* USERS NOTE:
  770. * Do not enter your hardware specific configurations here. Copy the settings
  771. * below and define them in your baord specific directory. Remember to also
  772. * define ENC28J60CONF_H so that these settings will not overwrite yours.
  773. * By modifying this in your board specific directory, you should be able to
  774. * update/upgrade your avr-uip distribution without having to modify updated
  775. * files.
  776. *
  777. *
  778. * DEVELOPERS NOTE:
  779. * Settings entered should be something rather common, and not update too often.
  780. */


  781. #ifndef ENC28J60CONF_H
  782. #define ENC28J60CONF_H

  783. // ENC28J60 SPI port
  784. #define ENC28J60_SPI_PORT               PORTB
  785. #define ENC28J60_SPI_DDR                DDRB
  786. #define ENC28J60_SPI_SCK                PB5
  787. #define ENC28J60_SPI_MOSI               PB3
  788. #define ENC28J60_SPI_MISO               PB4
  789. #define ENC28J60_SPI_SS                 PB2
  790. // ENC28J60 control port
  791. #define ENC28J60_CONTROL_PORT   PORTB
  792. #define ENC28J60_CONTROL_DDR    DDRB
  793. #define ENC28J60_CONTROL_CS             PB2

  794. // MAC address for this interface
  795. #ifdef ETHADDR0
  796. #define ENC28J60_MAC0 ETHADDR0
  797. #define ENC28J60_MAC1 ETHADDR1
  798. #define ENC28J60_MAC2 ETHADDR2
  799. #define ENC28J60_MAC3 ETHADDR3
  800. #define ENC28J60_MAC4 ETHADDR4
  801. #define ENC28J60_MAC5 ETHADDR5
  802. #else
  803. #define ENC28J60_MAC0 '0'
  804. #define ENC28J60_MAC1 'F'
  805. #define ENC28J60_MAC2 'F'
  806. #define ENC28J60_MAC3 'I'
  807. #define ENC28J60_MAC4 'C'
  808. #define ENC28J60_MAC5 'E'
  809. #endif

  810. #endif
  811. /*! \file enc28j60conf.h \brief Microchip ENC28J60 Ethernet Interface Driver Configuration. */
  812. //*****************************************************************************
  813. //
  814. // File Name    : 'enc28j60conf.h'
  815. // Title                : Microchip ENC28J60 Ethernet Interface Driver Configuration
  816. // Author               : Pascal Stang
  817. // Created              : 10/5/2004
  818. // Revised              : 8/22/2005
  819. // Version              : 0.1
  820. // Target MCU   : Atmel AVR series
  821. // Editor Tabs  : 4
  822. //
  823. // Description  : This driver provides initialization and transmit/receive
  824. //              functions for the ENC28J60 10Mb Ethernet Controller and PHY.
  825. //
  826. // This code is distributed under the GNU Public License
  827. //              which can be found at http://www.gnu.org/licenses/gpl.txt
  828. //
  829. //*****************************************************************************


  830. /* USERS NOTE:
  831. * Do not enter your hardware specific configurations here. Copy the settings
  832. * below and define them in your baord specific directory. Remember to also
  833. * define ENC28J60CONF_H so that these settings will not overwrite yours.
  834. * By modifying this in your board specific directory, you should be able to
  835. * update/upgrade your avr-uip distribution without having to modify updated
  836. * files.
  837. *
  838. *
  839. * DEVELOPERS NOTE:
  840. * Settings entered should be something rather common, and not update too often.
  841. */


  842. #ifndef ENC28J60CONF_H
  843. #define ENC28J60CONF_H

  844. // ENC28J60 SPI port
  845. #define ENC28J60_SPI_PORT               PORTB
  846. #define ENC28J60_SPI_DDR                DDRB
  847. #define ENC28J60_SPI_SCK                PB5
  848. #define ENC28J60_SPI_MOSI               PB3
  849. #define ENC28J60_SPI_MISO               PB4
  850. #define ENC28J60_SPI_SS                 PB2
  851. // ENC28J60 control port
  852. #define ENC28J60_CONTROL_PORT   PORTB
  853. #define ENC28J60_CONTROL_DDR    DDRB
  854. #define ENC28J60_CONTROL_CS             PB2

  855. // MAC address for this interface
  856. #ifdef ETHADDR0
  857. #define ENC28J60_MAC0 ETHADDR0
  858. #define ENC28J60_MAC1 ETHADDR1
  859. #define ENC28J60_MAC2 ETHADDR2
  860. #define ENC28J60_MAC3 ETHADDR3
  861. #define ENC28J60_MAC4 ETHADDR4
  862. #define ENC28J60_MAC5 ETHADDR5
  863. #else
  864. #define ENC28J60_MAC0 '0'
  865. #define ENC28J60_MAC1 'F'
  866. #define ENC28J60_MAC2 'F'
  867. #define ENC28J60_MAC3 'I'
  868. #define ENC28J60_MAC4 'C'
  869. #define ENC28J60_MAC5 'E'
  870. #endif

  871. #endif
复制代码



评分

参与人数 1黑币 +10 收起 理由
红尘有你 + 10 共享资料的黑币奖励!----好东西有空研究下

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:72399 发表于 2016-3-9 13:52 | 只看该作者
楼主做出来没有,我也弄一个

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表