enc28j60.c 20 KB

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