enc28j60.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. #include "enc28j60.h"
  2. #include <netif/ethernetif.h>
  3. #include "lwipopts.h"
  4. #include "stm32f10x_lib.h"
  5. #define MAX_ADDR_LEN 6
  6. // #define CSACTIVE GPIO_ResetBits(GPIOB, GPIO_Pin_12);
  7. // #define CSPASSIVE GPIO_SetBits(GPIOB, GPIO_Pin_12);
  8. #define CSACTIVE GPIOB->BRR = GPIO_Pin_12;
  9. #define CSPASSIVE GPIOB->BSRR = GPIO_Pin_12;
  10. struct net_device
  11. {
  12. /* inherit from ethernet device */
  13. struct eth_device parent;
  14. /* interface address info. */
  15. rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */
  16. };
  17. static struct net_device enc28j60_dev_entry;
  18. static struct net_device *enc28j60_dev =&enc28j60_dev_entry;
  19. static rt_uint8_t Enc28j60Bank;
  20. static rt_uint16_t NextPacketPtr;
  21. static struct rt_semaphore tx_sem;
  22. void _delay_us(rt_uint32_t us)
  23. {
  24. rt_uint32_t len;
  25. for (;us > 0; us --)
  26. for (len = 0; len < 20; len++ );
  27. }
  28. void delay_ms(rt_uint32_t ms)
  29. {
  30. rt_uint32_t len;
  31. for (;ms > 0; ms --)
  32. for (len = 0; len < 100; len++ );
  33. }
  34. rt_uint8_t spi_read_op(rt_uint8_t op, rt_uint8_t address)
  35. {
  36. int temp=0;
  37. CSACTIVE;
  38. SPI_I2S_SendData(SPI2, (op | (address & ADDR_MASK)));
  39. while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
  40. SPI_I2S_ReceiveData(SPI2);
  41. SPI_I2S_SendData(SPI2, 0x00);
  42. while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
  43. // do dummy read if needed (for mac and mii, see datasheet page 29)
  44. if(address & 0x80)
  45. {
  46. SPI_I2S_ReceiveData(SPI2);
  47. SPI_I2S_SendData(SPI2, 0x00);
  48. while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
  49. }
  50. // release CS
  51. temp=SPI_I2S_ReceiveData(SPI2);
  52. // for(t=0;t<20;t++);
  53. CSPASSIVE;
  54. return (temp);
  55. }
  56. void spi_write_op(rt_uint8_t op, rt_uint8_t address, rt_uint8_t data)
  57. {
  58. rt_uint32_t level;
  59. level = rt_hw_interrupt_disable();
  60. CSACTIVE;
  61. SPI_I2S_SendData(SPI2, op | (address & ADDR_MASK));
  62. while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
  63. SPI_I2S_SendData(SPI2,data);
  64. while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
  65. CSPASSIVE;
  66. rt_hw_interrupt_enable(level);
  67. }
  68. void enc28j60_set_bank(rt_uint8_t address)
  69. {
  70. // set the bank (if needed)
  71. if((address & BANK_MASK) != Enc28j60Bank)
  72. {
  73. // set the bank
  74. spi_write_op(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0));
  75. spi_write_op(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>5);
  76. Enc28j60Bank = (address & BANK_MASK);
  77. }
  78. }
  79. rt_uint8_t spi_read(rt_uint8_t address)
  80. {
  81. // set the bank
  82. enc28j60_set_bank(address);
  83. // do the read
  84. return spi_read_op(ENC28J60_READ_CTRL_REG, address);
  85. }
  86. void spi_write(rt_uint8_t address, rt_uint8_t data)
  87. {
  88. // set the bank
  89. enc28j60_set_bank(address);
  90. // do the write
  91. spi_write_op(ENC28J60_WRITE_CTRL_REG, address, data);
  92. }
  93. void enc28j60_phy_write(rt_uint8_t address, rt_uint16_t data)
  94. {
  95. // set the PHY register address
  96. spi_write(MIREGADR, address);
  97. // write the PHY data
  98. spi_write(MIWRL, data);
  99. spi_write(MIWRH, data>>8);
  100. // wait until the PHY write completes
  101. while(spi_read(MISTAT) & MISTAT_BUSY)
  102. {
  103. _delay_us(15);
  104. }
  105. }
  106. // read upper 8 bits
  107. rt_uint16_t enc28j60_phy_read(rt_uint8_t address)
  108. {
  109. // Set the right address and start the register read operation
  110. spi_write(MIREGADR, address);
  111. spi_write(MICMD, MICMD_MIIRD);
  112. _delay_us(15);
  113. // wait until the PHY read completes
  114. while(spi_read(MISTAT) & MISTAT_BUSY);
  115. // reset reading bit
  116. spi_write(MICMD, 0x00);
  117. return (spi_read(MIRDH));
  118. }
  119. void enc28j60_clkout(rt_uint8_t clk)
  120. {
  121. //setup clkout: 2 is 12.5MHz:
  122. spi_write(ECOCON, clk & 0x7);
  123. }
  124. /*
  125. * Access the PHY to determine link status
  126. */
  127. static void enc28j60_check_link_status()
  128. {
  129. rt_uint16_t reg;
  130. int duplex;
  131. reg = enc28j60_phy_read(PHSTAT2);
  132. duplex = reg & PHSTAT2_DPXSTAT;
  133. if (reg & PHSTAT2_LSTAT)
  134. {
  135. /* on */
  136. }
  137. else
  138. {
  139. /* off */
  140. }
  141. }
  142. #ifdef RT_USING_FINSH
  143. #include <finsh.h>
  144. /*
  145. * Debug routine to dump useful register contents
  146. */
  147. static void enc28j60(void)
  148. {
  149. rt_kprintf("-- enc28j60 registers:\n");
  150. rt_kprintf("HwRevID: 0x%02x\n", spi_read(EREVID));
  151. rt_kprintf("Cntrl: ECON1 ECON2 ESTAT EIR EIE\n");
  152. rt_kprintf(" 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",spi_read(ECON1), spi_read(ECON2), spi_read(ESTAT), spi_read(EIR), spi_read(EIE));
  153. rt_kprintf("MAC : MACON1 MACON3 MACON4\n");
  154. rt_kprintf(" 0x%02x 0x%02x 0x%02x\n", spi_read(MACON1), spi_read(MACON3), spi_read(MACON4));
  155. rt_kprintf("Rx : ERXST ERXND ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL\n");
  156. rt_kprintf(" 0x%04x 0x%04x 0x%04x 0x%04x ",
  157. (spi_read(ERXSTH) << 8) | spi_read(ERXSTL),
  158. (spi_read(ERXNDH) << 8) | spi_read(ERXNDL),
  159. (spi_read(ERXWRPTH) << 8) | spi_read(ERXWRPTL),
  160. (spi_read(ERXRDPTH) << 8) | spi_read(ERXRDPTL));
  161. rt_kprintf("0x%02x 0x%02x 0x%04x\n", spi_read(ERXFCON), spi_read(EPKTCNT),
  162. (spi_read(MAMXFLH) << 8) | spi_read(MAMXFLL));
  163. rt_kprintf("Tx : ETXST ETXND MACLCON1 MACLCON2 MAPHSUP\n");
  164. rt_kprintf(" 0x%04x 0x%04x 0x%02x 0x%02x 0x%02x\n",
  165. (spi_read(ETXSTH) << 8) | spi_read(ETXSTL),
  166. (spi_read(ETXNDH) << 8) | spi_read(ETXNDL),
  167. spi_read(MACLCON1), spi_read(MACLCON2), spi_read(MAPHSUP));
  168. }
  169. FINSH_FUNCTION_EXPORT(enc28j60, dump enc28j60 registers)
  170. #endif
  171. /*
  172. * RX handler
  173. * ignore PKTIF because is unreliable! (look at the errata datasheet)
  174. * check EPKTCNT is the suggested workaround.
  175. * We don't need to clear interrupt flag, automatically done when
  176. * enc28j60_hw_rx() decrements the packet counter.
  177. * Returns how many packet processed.
  178. */
  179. void enc28j60_isr()
  180. {
  181. /* Variable definitions can be made now. */
  182. volatile rt_uint32_t eir, pk_counter;
  183. volatile rt_bool_t rx_activiated;
  184. rx_activiated = RT_FALSE;
  185. /* get EIR */
  186. eir = spi_read(EIR);
  187. // rt_kprintf("eir: 0x%08x\n", eir);
  188. do
  189. {
  190. /* errata #4, PKTIF does not reliable */
  191. pk_counter = spi_read(EPKTCNT);
  192. if (pk_counter)
  193. {
  194. rt_err_t result;
  195. /* a frame has been received */
  196. result = eth_device_ready((struct eth_device*)&(enc28j60_dev->parent));
  197. RT_ASSERT(result == RT_EOK);
  198. // switch to bank 0
  199. enc28j60_set_bank(EIE);
  200. // disable rx interrutps
  201. spi_write_op(ENC28J60_BIT_FIELD_CLR, EIE, EIE_PKTIE);
  202. }
  203. /* clear PKTIF */
  204. if (eir & EIR_PKTIF)
  205. {
  206. enc28j60_set_bank(EIR);
  207. spi_write_op(ENC28J60_BIT_FIELD_CLR, EIR, EIR_PKTIF);
  208. rx_activiated = RT_TRUE;
  209. }
  210. /* clear DMAIF */
  211. if (eir & EIR_DMAIF)
  212. {
  213. enc28j60_set_bank(EIR);
  214. spi_write_op(ENC28J60_BIT_FIELD_CLR, EIR, EIR_DMAIF);
  215. }
  216. /* LINK changed handler */
  217. if ( eir & EIR_LINKIF)
  218. {
  219. enc28j60_check_link_status();
  220. /* read PHIR to clear the flag */
  221. enc28j60_phy_read(PHIR);
  222. enc28j60_set_bank(EIR);
  223. spi_write_op(ENC28J60_BIT_FIELD_CLR, EIR, EIR_LINKIF);
  224. }
  225. if (eir & EIR_TXIF)
  226. {
  227. /* A frame has been transmitted. */
  228. rt_sem_release(&tx_sem);
  229. enc28j60_set_bank(EIR);
  230. spi_write_op(ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXIF);
  231. }
  232. eir = spi_read(EIR);
  233. // rt_kprintf("inner eir: 0x%08x\n", eir);
  234. } while ((rx_activiated != RT_TRUE && eir != 0));
  235. }
  236. /* RT-Thread Device Interface */
  237. /* initialize the interface */
  238. rt_err_t enc28j60_init(rt_device_t dev)
  239. {
  240. CSPASSIVE;
  241. // perform system reset
  242. spi_write_op(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
  243. delay_ms(50);
  244. NextPacketPtr = RXSTART_INIT;
  245. // Rx start
  246. spi_write(ERXSTL, RXSTART_INIT&0xFF);
  247. spi_write(ERXSTH, RXSTART_INIT>>8);
  248. // set receive pointer address
  249. spi_write(ERXRDPTL, RXSTOP_INIT&0xFF);
  250. spi_write(ERXRDPTH, RXSTOP_INIT>>8);
  251. // RX end
  252. spi_write(ERXNDL, RXSTOP_INIT&0xFF);
  253. spi_write(ERXNDH, RXSTOP_INIT>>8);
  254. // TX start
  255. spi_write(ETXSTL, TXSTART_INIT&0xFF);
  256. spi_write(ETXSTH, TXSTART_INIT>>8);
  257. // set transmission pointer address
  258. spi_write(EWRPTL, TXSTART_INIT&0xFF);
  259. spi_write(EWRPTH, TXSTART_INIT>>8);
  260. // TX end
  261. spi_write(ETXNDL, TXSTOP_INIT&0xFF);
  262. spi_write(ETXNDH, TXSTOP_INIT>>8);
  263. // do bank 1 stuff, packet filter:
  264. // For broadcast packets we allow only ARP packtets
  265. // All other packets should be unicast only for our mac (MAADR)
  266. //
  267. // The pattern to match on is therefore
  268. // Type ETH.DST
  269. // ARP BROADCAST
  270. // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9
  271. // in binary these poitions are:11 0000 0011 1111
  272. // This is hex 303F->EPMM0=0x3f,EPMM1=0x30
  273. spi_write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_BCEN);
  274. // do bank 2 stuff
  275. // enable MAC receive
  276. spi_write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
  277. // enable automatic padding to 60bytes and CRC operations
  278. // spi_write_op(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);
  279. spi_write_op(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN | MACON3_FULDPX);
  280. // bring MAC out of reset
  281. // set inter-frame gap (back-to-back)
  282. // spi_write(MABBIPG, 0x12);
  283. spi_write(MABBIPG, 0x15);
  284. spi_write(MACON4, MACON4_DEFER);
  285. spi_write(MACLCON2, 63);
  286. // set inter-frame gap (non-back-to-back)
  287. spi_write(MAIPGL, 0x12);
  288. spi_write(MAIPGH, 0x0C);
  289. // Set the maximum packet size which the controller will accept
  290. // Do not send packets longer than MAX_FRAMELEN:
  291. spi_write(MAMXFLL, MAX_FRAMELEN&0xFF);
  292. spi_write(MAMXFLH, MAX_FRAMELEN>>8);
  293. // do bank 3 stuff
  294. // write MAC address
  295. // NOTE: MAC address in ENC28J60 is byte-backward
  296. spi_write(MAADR0, enc28j60_dev->dev_addr[5]);
  297. spi_write(MAADR1, enc28j60_dev->dev_addr[4]);
  298. spi_write(MAADR2, enc28j60_dev->dev_addr[3]);
  299. spi_write(MAADR3, enc28j60_dev->dev_addr[2]);
  300. spi_write(MAADR4, enc28j60_dev->dev_addr[1]);
  301. spi_write(MAADR5, enc28j60_dev->dev_addr[0]);
  302. /* output off */
  303. spi_write(ECOCON, 0x00);
  304. // enc28j60_phy_write(PHCON1, 0x00);
  305. enc28j60_phy_write(PHCON1, PHCON1_PDPXMD); // full duplex
  306. // no loopback of transmitted frames
  307. enc28j60_phy_write(PHCON2, PHCON2_HDLDIS);
  308. enc28j60_set_bank(ECON2);
  309. spi_write_op(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_AUTOINC);
  310. // switch to bank 0
  311. enc28j60_set_bank(ECON1);
  312. // enable interrutps
  313. spi_write_op(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE|EIR_TXIF);
  314. // enable packet reception
  315. spi_write_op(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
  316. /* clock out */
  317. // enc28j60_clkout(2);
  318. enc28j60_phy_write(PHLCON, 0xD76); //0x476
  319. delay_ms(20);
  320. rt_kprintf("enc28j60 init ok!\n");
  321. return RT_EOK;
  322. }
  323. /* control the interface */
  324. rt_err_t enc28j60_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  325. {
  326. switch(cmd)
  327. {
  328. case NIOCTL_GADDR:
  329. /* get mac address */
  330. if(args) rt_memcpy(args, enc28j60_dev_entry.dev_addr, 6);
  331. else return -RT_ERROR;
  332. break;
  333. default :
  334. break;
  335. }
  336. return RT_EOK;
  337. }
  338. /* Open the ethernet interface */
  339. rt_err_t enc28j60_open(rt_device_t dev, rt_uint16_t oflag)
  340. {
  341. return RT_EOK;
  342. }
  343. /* Close the interface */
  344. rt_err_t enc28j60_close(rt_device_t dev)
  345. {
  346. return RT_EOK;
  347. }
  348. /* Read */
  349. rt_size_t enc28j60_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  350. {
  351. rt_set_errno(-RT_ENOSYS);
  352. return 0;
  353. }
  354. /* Write */
  355. rt_size_t enc28j60_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  356. {
  357. rt_set_errno(-RT_ENOSYS);
  358. return 0;
  359. }
  360. /* ethernet device interface */
  361. /*
  362. * Transmit packet.
  363. */
  364. rt_err_t enc28j60_tx( rt_device_t dev, struct pbuf* p)
  365. {
  366. struct pbuf* q;
  367. rt_uint32_t len;
  368. rt_uint8_t* ptr;
  369. // rt_kprintf("tx pbuf: 0x%08x\n", p);
  370. /* lock tx operation */
  371. rt_sem_take(&tx_sem, RT_WAITING_FOREVER);
  372. // Set the write pointer to start of transmit buffer area
  373. spi_write(EWRPTL, TXSTART_INIT&0xFF);
  374. spi_write(EWRPTH, TXSTART_INIT>>8);
  375. // Set the TXND pointer to correspond to the packet size given
  376. spi_write(ETXNDL, (TXSTART_INIT+ p->tot_len + 1)&0xFF);
  377. spi_write(ETXNDH, (TXSTART_INIT+ p->tot_len + 1)>>8);
  378. // write per-packet control byte (0x00 means use macon3 settings)
  379. spi_write_op(ENC28J60_WRITE_BUF_MEM, 0, 0x00);
  380. for (q = p; q != NULL; q = q->next)
  381. {
  382. CSACTIVE;
  383. SPI_I2S_SendData(SPI2, ENC28J60_WRITE_BUF_MEM);
  384. while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
  385. len = q->len;
  386. ptr = q->payload;
  387. while(len)
  388. {
  389. SPI_I2S_SendData(SPI2,*ptr) ;
  390. while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);;
  391. ptr++;
  392. len--;
  393. }
  394. CSPASSIVE;
  395. }
  396. // send the contents of the transmit buffer onto the network
  397. spi_write_op(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
  398. // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12.
  399. if( (spi_read(EIR) & EIR_TXERIF) )
  400. {
  401. spi_write_op(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS);
  402. }
  403. // rt_kprintf("tx ok\n");
  404. return RT_EOK;
  405. }
  406. struct pbuf *enc28j60_rx(rt_device_t dev)
  407. {
  408. struct pbuf* p;
  409. rt_uint32_t len;
  410. rt_uint16_t rxstat;
  411. rt_uint32_t pk_counter;
  412. p = RT_NULL;
  413. pk_counter = spi_read(EPKTCNT);
  414. if (pk_counter)
  415. {
  416. // Set the read pointer to the start of the received packet
  417. spi_write(ERDPTL, (NextPacketPtr));
  418. spi_write(ERDPTH, (NextPacketPtr)>>8);
  419. // read the next packet pointer
  420. NextPacketPtr = spi_read_op(ENC28J60_READ_BUF_MEM, 0);
  421. NextPacketPtr |= spi_read_op(ENC28J60_READ_BUF_MEM, 0)<<8;
  422. // read the packet length (see datasheet page 43)
  423. len = spi_read_op(ENC28J60_READ_BUF_MEM, 0); //0x54
  424. len |= spi_read_op(ENC28J60_READ_BUF_MEM, 0) <<8; //5554
  425. len-=4; //remove the CRC count
  426. // read the receive status (see datasheet page 43)
  427. rxstat = spi_read_op(ENC28J60_READ_BUF_MEM, 0);
  428. rxstat |= ((rt_uint16_t)spi_read_op(ENC28J60_READ_BUF_MEM, 0))<<8;
  429. // check CRC and symbol errors (see datasheet page 44, table 7-3):
  430. // The ERXFCON.CRCEN is set by default. Normally we should not
  431. // need to check this.
  432. if ((rxstat & 0x80)==0)
  433. {
  434. // invalid
  435. len=0;
  436. }
  437. else
  438. {
  439. /* allocation pbuf */
  440. p = pbuf_alloc(PBUF_LINK, len, PBUF_RAM);
  441. if (p != RT_NULL)
  442. {
  443. rt_uint8_t* data;
  444. struct pbuf* q;
  445. for (q = p; q != RT_NULL; q= q->next)
  446. {
  447. data = q->payload;
  448. len = q->len;
  449. CSACTIVE;
  450. SPI_I2S_SendData(SPI2,ENC28J60_READ_BUF_MEM);
  451. while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
  452. SPI_I2S_ReceiveData(SPI2);
  453. while(len)
  454. {
  455. len--;
  456. SPI_I2S_SendData(SPI2,0x00) ;
  457. while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
  458. *data= SPI_I2S_ReceiveData(SPI2);
  459. data++;
  460. }
  461. CSPASSIVE;
  462. }
  463. }
  464. }
  465. // Move the RX read pointer to the start of the next received packet
  466. // This frees the memory we just read out
  467. spi_write(ERXRDPTL, (NextPacketPtr));
  468. spi_write(ERXRDPTH, (NextPacketPtr)>>8);
  469. // decrement the packet counter indicate we are done with this packet
  470. spi_write_op(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
  471. }
  472. else
  473. {
  474. rt_uint32_t level;
  475. /* lock enc28j60 */
  476. level = rt_hw_interrupt_disable();
  477. // switch to bank 0
  478. enc28j60_set_bank(EIE);
  479. // enable interrutps
  480. spi_write_op(ENC28J60_BIT_FIELD_SET, EIE, EIE_PKTIE);
  481. // switch to bank 0
  482. enc28j60_set_bank(ECON1);
  483. // enable packet reception
  484. spi_write_op(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
  485. /* enable interrupt */
  486. rt_hw_interrupt_enable(level);
  487. }
  488. return p;
  489. }
  490. static void RCC_Configuration(void)
  491. {
  492. /* enable spi2 clock */
  493. RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
  494. /* enable gpiob port clock */
  495. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
  496. }
  497. static void NVIC_Configuration(void)
  498. {
  499. NVIC_InitTypeDef NVIC_InitStructure;
  500. /* Configure one bit for preemption priority */
  501. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  502. /* Enable the EXTI0 Interrupt */
  503. NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
  504. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  505. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  506. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  507. NVIC_Init(&NVIC_InitStructure);
  508. }
  509. static void GPIO_Configuration()
  510. {
  511. GPIO_InitTypeDef GPIO_InitStructure;
  512. EXTI_InitTypeDef EXTI_InitStructure;
  513. /* configure PB0 as external interrupt */
  514. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  515. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  516. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  517. GPIO_Init(GPIOB, &GPIO_InitStructure);
  518. /* Configure SPI2 pins: SCK, MISO and MOSI ----------------------------*/
  519. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  520. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  521. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  522. GPIO_Init(GPIOB, &GPIO_InitStructure);
  523. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  524. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  525. GPIO_Init(GPIOB, &GPIO_InitStructure);
  526. /* Connect ENC28J60 EXTI Line to GPIOB Pin 0 */
  527. GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);
  528. /* Configure ENC28J60 EXTI Line to generate an interrupt on falling edge */
  529. EXTI_InitStructure.EXTI_Line = EXTI_Line0;
  530. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  531. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  532. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  533. EXTI_Init(&EXTI_InitStructure);
  534. /* Clear the Key Button EXTI line pending bit */
  535. EXTI_ClearITPendingBit(EXTI_Line0);
  536. }
  537. static void SetupSPI (void)
  538. {
  539. SPI_InitTypeDef SPI_InitStructure;
  540. SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  541. SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  542. SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  543. SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  544. SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  545. SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  546. SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
  547. SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  548. SPI_InitStructure.SPI_CRCPolynomial = 7;
  549. SPI_Init(SPI2, &SPI_InitStructure);
  550. SPI_Cmd(SPI2, ENABLE);
  551. }
  552. static rt_timer_t enc28j60_timer;
  553. void rt_hw_enc28j60_timeout(void* parameter)
  554. {
  555. // switch to bank 0
  556. enc28j60_set_bank(EIE);
  557. // enable interrutps
  558. spi_write_op(ENC28J60_BIT_FIELD_SET, EIE, EIE_PKTIE);
  559. // switch to bank 0
  560. enc28j60_set_bank(ECON1);
  561. // enable packet reception
  562. spi_write_op(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
  563. enc28j60_isr();
  564. }
  565. int rt_hw_enc28j60_init()
  566. {
  567. rt_err_t result;
  568. /* configuration PB5 as INT */
  569. RCC_Configuration();
  570. NVIC_Configuration();
  571. GPIO_Configuration();
  572. SetupSPI();
  573. /* init rt-thread device interface */
  574. enc28j60_dev_entry.parent.parent.init = enc28j60_init;
  575. enc28j60_dev_entry.parent.parent.open = enc28j60_open;
  576. enc28j60_dev_entry.parent.parent.close = enc28j60_close;
  577. enc28j60_dev_entry.parent.parent.read = enc28j60_read;
  578. enc28j60_dev_entry.parent.parent.write = enc28j60_write;
  579. enc28j60_dev_entry.parent.parent.control = enc28j60_control;
  580. enc28j60_dev_entry.parent.eth_rx = enc28j60_rx;
  581. enc28j60_dev_entry.parent.eth_tx = enc28j60_tx;
  582. /* Update MAC address */
  583. enc28j60_dev_entry.dev_addr[0] = 0x1e;
  584. enc28j60_dev_entry.dev_addr[1] = 0x30;
  585. enc28j60_dev_entry.dev_addr[2] = 0x6c;
  586. enc28j60_dev_entry.dev_addr[3] = 0xa2;
  587. enc28j60_dev_entry.dev_addr[4] = 0x45;
  588. enc28j60_dev_entry.dev_addr[5] = 0x5e;
  589. rt_sem_init(&tx_sem, "emac", 1, RT_IPC_FLAG_FIFO);
  590. result = eth_device_init(&(enc28j60_dev->parent), "E0");
  591. /* workaround for enc28j60 interrupt */
  592. enc28j60_timer = rt_timer_create("etimer",
  593. rt_hw_enc28j60_timeout, RT_NULL,
  594. 50, RT_TIMER_FLAG_PERIODIC);
  595. if (enc28j60_timer != RT_NULL)
  596. rt_timer_start(enc28j60_timer);
  597. return RT_EOK;
  598. }