sam7x_emac.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. #include <rthw.h>
  2. #include <rtthread.h>
  3. #include <netif/ethernetif.h>
  4. #include "sam7x_emac.h"
  5. #include "AT91SAM7X256.h"
  6. #include "lwipopts.h"
  7. #include "lwip/mem.h"
  8. #define MAX_ADDR_LEN 6
  9. #ifdef DM9161
  10. #define EMAC_PIO_CFG (AT91C_PB8_EMDC | \
  11. AT91C_PB9_EMDIO | \
  12. AT91C_PB2_ETX0 | \
  13. AT91C_PB3_ETX1 | \
  14. AT91C_PB10_ETX2 | \
  15. AT91C_PB11_ETX3 | \
  16. AT91C_PB1_ETXEN | \
  17. AT91C_PB0_ETXCK_EREFCK | \
  18. AT91C_PB15_ERXDV_ECRSDV | \
  19. AT91C_PB5_ERX0 | \
  20. AT91C_PB6_ERX1 | \
  21. AT91C_PB12_ETXER | \
  22. AT91C_PB13_ERX2 | \
  23. AT91C_PB14_ERX3 | \
  24. AT91C_PB17_ERXCK | \
  25. AT91C_PB16_ECOL | \
  26. AT91C_PB4_ECRS | \
  27. AT91C_PB7_ERXER)
  28. #else
  29. #define EMAC_PIO_CFG (AT91C_PB0_ETXCK_EREFCK | \
  30. AT91C_PB1_ETXEN | \
  31. AT91C_PB2_ETX0 | \
  32. AT91C_PB3_ETX1 | \
  33. AT91C_PB4_ECRS | \
  34. AT91C_PB5_ERX0 | \
  35. AT91C_PB6_ERX1 | \
  36. AT91C_PB7_ERXER | \
  37. AT91C_PB8_EMDC | \
  38. AT91C_PB9_EMDIO | \
  39. AT91C_PB10_ETX2 | \
  40. AT91C_PB11_ETX3 | \
  41. AT91C_PB10_ETX2 | \
  42. AT91C_PB13_ERX2 | \
  43. AT91C_PB14_ERX3 | \
  44. AT91C_PB15_ERXDV_ECRSDV| \
  45. AT91C_PB16_ECOL | \
  46. AT91C_PB17_ERXCK)
  47. #endif
  48. #define RB_BUFFER_SIZE 8 /* max number of receive buffers */
  49. #define ETH_RX_BUF_SIZE 128
  50. #define TB_BUFFER_SIZE 4
  51. #define ETH_TX_BUF_SIZE (PBUF_POOL_BUFSIZE)
  52. struct rbf_t
  53. {
  54. rt_uint32_t addr;
  55. rt_uint32_t status;
  56. };
  57. static rt_uint32_t current_rb_index; /* current receive buffer index */
  58. static volatile struct rbf_t rb_descriptors[RB_BUFFER_SIZE];
  59. static volatile struct rbf_t tb_descriptors[TB_BUFFER_SIZE];
  60. static rt_uint8_t rx_buf[RB_BUFFER_SIZE][ETH_RX_BUF_SIZE] __attribute__ ((aligned (8)));
  61. static rt_uint8_t tx_buf[TB_BUFFER_SIZE][ETH_TX_BUF_SIZE] __attribute__ ((aligned (8)));
  62. static struct rt_semaphore tx_sem;
  63. struct net_device
  64. {
  65. /* inherit from ethernet device */
  66. struct eth_device parent;
  67. /* interface address info. */
  68. rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */
  69. };
  70. static struct net_device sam7x_dev_entry;
  71. static struct net_device *sam7x_dev =&sam7x_dev_entry;
  72. AT91PS_EMAC pEmac = AT91C_BASE_EMAC;
  73. rt_inline void write_phy(rt_uint8_t addr, rt_uint32_t value)
  74. {
  75. AT91C_BASE_EMAC->EMAC_MAN = ((0x01<<30) | (2 << 16) | (1 << 28) |
  76. (AT91C_PHY_ADDR << 23) | (addr << 18)) | value;
  77. /* Wait until IDLE bit in Network Status register is cleared */
  78. while (!(AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE));
  79. }
  80. rt_inline rt_uint32_t read_phy(rt_uint8_t addr)
  81. {
  82. AT91C_BASE_EMAC->EMAC_MAN = (0x01<<30) | (0x02 << 16) | (0x02 << 28) |
  83. (AT91C_PHY_ADDR << 23) | (addr << 18);
  84. /* Wait until IDLE bit in Network Status register is cleared */
  85. while (!(AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE));
  86. return (AT91C_BASE_EMAC->EMAC_MAN & 0x0000ffff);
  87. }
  88. rt_inline void sam7xether_reset_tx_desc(void)
  89. {
  90. static rt_uint32_t index = 0;
  91. if(tb_descriptors[index].status & TxDESC_STATUS_USED)
  92. {
  93. while(!(tb_descriptors[index].status & TxDESC_STATUS_LAST_BUF))
  94. {
  95. index ++;
  96. if(index >= TB_BUFFER_SIZE)index = 0;
  97. tb_descriptors[index].status |= TxDESC_STATUS_USED;
  98. }
  99. index ++;
  100. if(index >= TB_BUFFER_SIZE)index = 0;
  101. }
  102. }
  103. /* interrupt service routing */
  104. static void sam7xether_isr(int irq, void* param)
  105. {
  106. /* Variable definitions can be made now. */
  107. volatile rt_uint32_t isr, rsr;
  108. /* get status */
  109. isr = AT91C_BASE_EMAC->EMAC_ISR;
  110. rsr = AT91C_BASE_EMAC->EMAC_RSR;
  111. if( ( isr & AT91C_EMAC_RCOMP ) || ( rsr & AT91C_EMAC_REC ) )
  112. {
  113. rt_err_t result;
  114. /* a frame has been received */
  115. result = eth_device_ready((struct eth_device*)&(sam7x_dev->parent));
  116. RT_ASSERT(result == RT_EOK);
  117. AT91C_BASE_EMAC->EMAC_RSR = AT91C_EMAC_REC;
  118. }
  119. if( isr & AT91C_EMAC_TCOMP )
  120. {
  121. /* A frame has been transmitted. Mark all the buffers as free */
  122. sam7xether_reset_tx_desc();
  123. AT91C_BASE_EMAC->EMAC_TSR = AT91C_EMAC_COMP;
  124. }
  125. }
  126. rt_inline void linksetup(void)
  127. {
  128. rt_uint32_t value, tout, id1, id2;
  129. #ifdef DM9161
  130. rt_uint32_t ulBMSR,ulBMCR,i;
  131. #endif
  132. #ifdef DM9161
  133. //PHY has internal pull down : disable MII isolate
  134. tout = read_phy(PHY_REG_BMCR);
  135. tout = read_phy(PHY_REG_BMCR);
  136. tout &= ~BMCR_ISOLATE;
  137. write_phy(PHY_REG_BMCR, tout);
  138. /* Check if this is a RTL8201 or DM9161 PHY. */
  139. id1 = read_phy(PHY_REG_PHYID1);
  140. id2 = read_phy(PHY_REG_PHYID2);
  141. if (((id1 << 16) | (id2 & 0xfff0)) == MII_DM9161_ID)
  142. {
  143. rt_kprintf("read MII_DM9161_ID ok!\n");
  144. tout = DM9161_NP | DM9161_TX_FDX | DM9161_TX_HDX |
  145. DM9161_10_FDX | DM9161_10_HDX | DM9161_AN_IEEE_802_3;
  146. write_phy(PHY_REG_ANAR, tout);
  147. // Wait for PHY auto negotiation completed
  148. i = 0;
  149. do {
  150. ulBMSR = read_phy(PHY_REG_BMSR);
  151. ulBMSR = read_phy(PHY_REG_BMSR);
  152. i++;
  153. if(i >= 0xffff)
  154. break;
  155. }while (!(ulBMSR & BMSR_ANEGCOMPLETE));
  156. if(i >= 0xffff)
  157. rt_kprintf("PHY No Link!\n");
  158. else
  159. rt_kprintf("PHY auto negotiation completed!\n");
  160. /* Update the MAC register NCFGR. */
  161. AT91C_BASE_EMAC->EMAC_NCFGR = 0;
  162. ulBMCR = read_phy(PHY_REG_BMCR);
  163. if (ulBMCR & BMCR_ANENABLE)
  164. {
  165. /* AutoNegotiation is enabled. */
  166. if(!(ulBMSR & BMSR_ANEGCOMPLETE))
  167. {
  168. /* Auto-negotitation in progress. */
  169. rt_kprintf("Auto-negotitation in progress!\n");
  170. return;
  171. }
  172. if (ulBMCR & BMCR_SPEED100)
  173. {
  174. /* Speed 100Mbit is enabled. */
  175. AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_SPD;
  176. }
  177. if (ulBMCR & BMCR_FULLDPLX)
  178. {
  179. /* Full duplex is enabled. */
  180. AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_FD;
  181. }
  182. }
  183. }
  184. #else
  185. /* Check if this is a RTL8201 or DM9161 PHY. */
  186. id1 = read_phy(PHY_REG_PHYID1);
  187. id2 = read_phy(PHY_REG_PHYID2);
  188. if (((id2 << 16) | (id1 & 0xfff0)) == MII_RTL8201_ID)
  189. {
  190. rt_kprintf("read MII_RTL8201_ID ok!\n");
  191. /* Configure the PHY device */
  192. /* Use autonegotiation about the link speed. */
  193. write_phy (PHY_REG_BMCR, PHY_AUTO_NEG);
  194. /* Wait to complete Auto_Negotiation. */
  195. for (tout = 0; tout < 0x100000; tout++)
  196. {
  197. value = read_phy (PHY_REG_BMSR);
  198. if (value & BMSR_ANEGCOMPLETE) break; /* autonegotiation finished. */
  199. }
  200. /* Check the link status. */
  201. for (tout = 0; tout < 0x10000; tout++)
  202. {
  203. value = read_phy (PHY_REG_BMSR);
  204. if (value & BMSR_LINKST) break; /* Link is on. */
  205. }
  206. }
  207. value = read_phy (PHY_REG_ANLPAR);
  208. /* Update the MAC register NCFGR. */
  209. AT91C_BASE_EMAC->EMAC_NCFGR &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
  210. /* set full duplex . */
  211. if (value & 0xA000) AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_FD;
  212. /* set speed */
  213. if (value & 0xC000) AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_SPD;
  214. #endif
  215. }
  216. /*
  217. * Set the MAC address.
  218. */
  219. rt_inline void update_mac_address(struct net_device* device)
  220. {
  221. AT91C_BASE_EMAC->EMAC_SA1L = (device->dev_addr[3] << 24) |
  222. (device->dev_addr[2] << 16) |
  223. (device->dev_addr[1] << 8) |
  224. device->dev_addr[0];
  225. AT91C_BASE_EMAC->EMAC_SA1H = (device->dev_addr[5] << 8) |
  226. device->dev_addr[4];
  227. }
  228. rt_inline void sam7xether_desc_init()
  229. {
  230. rt_uint32_t i;
  231. /* Rx Buffer Descriptor initialization */
  232. current_rb_index = 0;
  233. for (i = 0; i < RB_BUFFER_SIZE; i++)
  234. {
  235. rb_descriptors[i].addr = (rt_uint32_t)&(rx_buf[i][0]);
  236. rb_descriptors[i].status = 0;
  237. }
  238. /* Set the WRAP bit at the end of the list descriptor. */
  239. rb_descriptors[RB_BUFFER_SIZE-1].addr |= 0x02;
  240. /* Set Rx Queue pointer to descriptor list. */
  241. AT91C_BASE_EMAC->EMAC_RBQP = (unsigned int)&(rb_descriptors[0]);
  242. /* Tx Buffer Descriptor initialization */
  243. for (i = 0; i < TB_BUFFER_SIZE; i++)
  244. {
  245. tb_descriptors[i].addr = (rt_uint32_t)&(tx_buf[i][0]);
  246. tb_descriptors[i].status = TxDESC_STATUS_USED;
  247. }
  248. /* Set the WRAP bit at the end of the list descriptor. */
  249. tb_descriptors[TB_BUFFER_SIZE-1].status |= TxDESC_STATUS_WRAP;
  250. /* Set Tx Queue pointer to descriptor list. */
  251. AT91C_BASE_EMAC->EMAC_TBQP = (unsigned int)&(tb_descriptors[0]);
  252. }
  253. /* RT-Thread Device Interface */
  254. /* initialize the interface */
  255. rt_err_t sam7xether_init(rt_device_t dev)
  256. {
  257. rt_uint32_t i;
  258. /* enable peripheral clock for EMAC and PIO B */
  259. AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOB | 1 << AT91C_ID_EMAC;
  260. /* Disable pull up on RXDV => PHY normal mode (not in test mode), */
  261. /* and set MII mode. PHY has internal pull down. */
  262. AT91C_BASE_PIOB->PIO_PPUDR = (1<<16) | (1 << 15);
  263. /* Clear PB18 <=> PHY powerdown */
  264. AT91C_BASE_PIOB->PIO_PER = 1<<18;
  265. AT91C_BASE_PIOB->PIO_OER = 1<<18;
  266. AT91C_BASE_PIOB->PIO_CODR = 1<<18;
  267. /* EMAC IO init for EMAC-PHY communication. */
  268. AT91C_BASE_PIOB->PIO_ASR = EMAC_PIO_CFG;
  269. AT91C_BASE_PIOB->PIO_PDR = EMAC_PIO_CFG; // Set in Periph mode
  270. /* Enable communication between EMAC-PHY. */
  271. AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE;
  272. /* MDC = MCK/32 */
  273. AT91C_BASE_EMAC->EMAC_NCFGR |= 2<<10;
  274. /* Reset PHY */
  275. AT91C_BASE_PIOB->PIO_PPUDR = AT91C_PB7_ERXER;
  276. AT91C_BASE_RSTC->RSTC_RMR = 0xA5000000 | (0x08 << 8) ;
  277. AT91C_BASE_RSTC->RSTC_RCR = 0xA5000000 | AT91C_RSTC_EXTRST;
  278. i = 0;
  279. while(!(AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_NRSTL))
  280. {
  281. i++;
  282. if(i >= 0xfffff)
  283. break;
  284. }
  285. for(i=0; i<0xfffff; i++);//* 等待一段指定的时间,使PHY就绪
  286. linksetup();
  287. rt_kprintf("linksetup ok!\n");
  288. /* Disable management port in MAC control register. */
  289. AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE;
  290. /* Enable EMAC in MII mode, enable clock ERXCK and ETXCK */
  291. AT91C_BASE_EMAC->EMAC_USRIO= AT91C_EMAC_CLKEN;
  292. /* Transmit and Receive disable. */
  293. AT91C_BASE_EMAC->EMAC_NCR &= ~(AT91C_EMAC_RE | AT91C_EMAC_TE);
  294. /* init descriptor */
  295. sam7xether_desc_init();
  296. /* Clear receive and transmit status registers. */
  297. AT91C_BASE_EMAC->EMAC_RSR = (AT91C_EMAC_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
  298. AT91C_BASE_EMAC->EMAC_TSR = (AT91C_EMAC_UND | AT91C_EMAC_COMP| AT91C_EMAC_BEX |
  299. AT91C_EMAC_RLES| AT91C_EMAC_COL | AT91C_EMAC_UBR);
  300. /* Configure EMAC operation mode. */
  301. //AT91C_BASE_EMAC->EMAC_NCFGR |= (AT91C_EMAC_BIG | AT91C_EMAC_DRFCS);
  302. // 复制所有有效帧到接收缓冲区 *不复制FCS字段 不接收广播帧 不接收1526字节长帧
  303. AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_CAF |AT91C_EMAC_DRFCS | AT91C_EMAC_NBC | AT91C_EMAC_BIG;
  304. AT91C_BASE_EMAC->EMAC_NCR |= (AT91C_EMAC_TE | AT91C_EMAC_RE | AT91C_EMAC_WESTAT);
  305. /* update MAC address */
  306. update_mac_address(sam7x_dev);
  307. /* enable interrupt */
  308. AT91C_BASE_EMAC->EMAC_IDR = 0x3fff;
  309. AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP | AT91C_EMAC_TCOMP;
  310. /* setup interrupt */
  311. rt_hw_interrupt_install(AT91C_ID_EMAC, sam7xether_isr, RT_NULL, "emac");
  312. *(volatile unsigned int*)(0xFFFFF000 + AT91C_ID_EMAC * 4) = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 5;
  313. // AT91C_AIC_SMR(AT91C_ID_EMAC) = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 5;
  314. rt_hw_interrupt_umask(AT91C_ID_EMAC);
  315. return RT_EOK;
  316. }
  317. /* control the interface */
  318. rt_err_t sam7xether_control(rt_device_t dev, int cmd, void *args)
  319. {
  320. switch(cmd)
  321. {
  322. case NIOCTL_GADDR:
  323. /* get mac address */
  324. if(args) rt_memcpy(args, sam7x_dev_entry.dev_addr, 6);
  325. else return -RT_ERROR;
  326. break;
  327. default :
  328. break;
  329. }
  330. return RT_EOK;
  331. }
  332. /* Open the ethernet interface */
  333. rt_err_t sam7xether_open(rt_device_t dev, rt_uint16_t oflags)
  334. {
  335. return RT_EOK;
  336. }
  337. /* Close the interface */
  338. rt_err_t sam7xether_close(rt_device_t dev)
  339. {
  340. return RT_EOK;
  341. }
  342. /* Read */
  343. rt_size_t sam7xether_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  344. {
  345. rt_set_errno(-RT_ENOSYS);
  346. return 0;
  347. }
  348. /* Write */
  349. rt_size_t sam7xether_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  350. {
  351. rt_set_errno(-RT_ENOSYS);
  352. return 0;
  353. }
  354. /* See the header file for descriptions of public functions. */
  355. void sam7xether_write_frame(rt_uint8_t *ptr, rt_uint32_t length, rt_bool_t eof)
  356. {
  357. rt_uint8_t *buf_ptr;
  358. static rt_uint32_t current_tb_index = 0;
  359. rt_uint32_t is_last, tx_offset = 0, remain, pdu_length;
  360. while(tx_offset < length)
  361. {
  362. /* check whether buffer is available */
  363. while(!(tb_descriptors[current_tb_index].status & TxDESC_STATUS_USED))
  364. {
  365. /* no buffer */
  366. rt_thread_delay(5);
  367. }
  368. /* Get the address of the buffer from the descriptor, then copy
  369. the data into the buffer. */
  370. buf_ptr = (rt_uint8_t *)tb_descriptors[current_tb_index].addr;
  371. /* How much can we write to the buffer? */
  372. remain = length - tx_offset;
  373. pdu_length = (remain <= ETH_TX_BUF_SIZE)? remain : ETH_TX_BUF_SIZE;
  374. /* Copy the data into the buffer. */
  375. rt_memcpy(buf_ptr, &ptr[tx_offset], pdu_length );
  376. tx_offset += pdu_length;
  377. /* Is this the last data for the frame? */
  378. if((eof == RT_TRUE) && ( tx_offset >= length )) is_last = TxDESC_STATUS_LAST_BUF;
  379. else is_last = 0;
  380. /* Fill out the necessary in the descriptor to get the data sent,
  381. then move to the next descriptor, wrapping if necessary. */
  382. if(current_tb_index >= (TB_BUFFER_SIZE - 1))
  383. {
  384. tb_descriptors[current_tb_index].status = ( pdu_length & TxDESC_STATUS_BUF_SIZE )
  385. | is_last
  386. | TxDESC_STATUS_WRAP;
  387. current_tb_index = 0;
  388. }
  389. else
  390. {
  391. tb_descriptors[current_tb_index].status = ( pdu_length & TxDESC_STATUS_BUF_SIZE )
  392. | is_last;
  393. current_tb_index++;
  394. }
  395. /* If this is the last buffer to be sent for this frame we can
  396. start the transmission. */
  397. if(is_last)
  398. {
  399. AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART;
  400. }
  401. }
  402. }
  403. /* ethernet device interface */
  404. /*
  405. * Transmit packet.
  406. */
  407. rt_err_t sam7xether_tx( rt_device_t dev, struct pbuf* p)
  408. {
  409. struct pbuf* q;
  410. /* lock tx operation */
  411. rt_sem_take(&tx_sem, RT_WAITING_FOREVER);
  412. for (q = p; q != NULL; q = q->next)
  413. {
  414. if (q->next == RT_NULL) sam7xether_write_frame(q->payload, q->len, RT_TRUE);
  415. else sam7xether_write_frame(q->payload, q->len, RT_FALSE);
  416. }
  417. rt_sem_release(&tx_sem);
  418. return 0;
  419. }
  420. void sam7xether_read_frame(rt_uint8_t* ptr, rt_uint32_t section_length, rt_uint32_t total)
  421. {
  422. static rt_uint8_t* src_ptr;
  423. register rt_uint32_t buf_remain, section_remain;
  424. static rt_uint32_t section_read = 0, buf_offset = 0, frame_read = 0;
  425. if(ptr == RT_NULL)
  426. {
  427. /* Reset our state variables ready for the next read from this buffer. */
  428. src_ptr = (rt_uint8_t *)(rb_descriptors[current_rb_index].addr & RxDESC_FLAG_ADDR_MASK);
  429. frame_read = (rt_uint32_t)0;
  430. buf_offset = (rt_uint32_t)0;
  431. }
  432. else
  433. {
  434. /* Loop until we have obtained the required amount of data. */
  435. section_read = 0;
  436. while( section_read < section_length )
  437. {
  438. buf_remain = (ETH_RX_BUF_SIZE - buf_offset);
  439. section_remain = section_length - section_read;
  440. if( section_remain > buf_remain )
  441. {
  442. /* more data on section than buffer size */
  443. rt_memcpy(&ptr[ section_read ], &src_ptr[buf_offset], buf_remain);
  444. section_read += buf_remain;
  445. frame_read += buf_remain;
  446. /* free buffer */
  447. rb_descriptors[current_rb_index].addr &= ~RxDESC_FLAG_OWNSHIP;
  448. /* move to the next frame. */
  449. current_rb_index++;
  450. if(current_rb_index >= RB_BUFFER_SIZE) current_rb_index = 0;
  451. /* Reset the variables for the new buffer. */
  452. src_ptr = (rt_uint8_t *)(rb_descriptors[current_rb_index].addr & RxDESC_FLAG_ADDR_MASK);
  453. buf_offset = 0;
  454. }
  455. else
  456. {
  457. /* more data on buffer than section size */
  458. rt_memcpy(&ptr[section_read], &src_ptr[buf_offset], section_remain);
  459. buf_offset += section_remain;
  460. section_read += section_remain;
  461. frame_read += section_remain;
  462. /* finish this read */
  463. if((buf_offset >= ETH_RX_BUF_SIZE) || (frame_read >= total))
  464. {
  465. /* free buffer */
  466. rb_descriptors[current_rb_index].addr &= ~(RxDESC_FLAG_OWNSHIP);
  467. /* move to the next frame. */
  468. current_rb_index++;
  469. if( current_rb_index >= RB_BUFFER_SIZE ) current_rb_index = 0;
  470. src_ptr = (rt_uint8_t*)(rb_descriptors[current_rb_index].addr & RxDESC_FLAG_ADDR_MASK);
  471. buf_offset = 0;
  472. }
  473. }
  474. }
  475. }
  476. }
  477. struct pbuf *sam7xether_rx(rt_device_t dev)
  478. {
  479. struct pbuf *p = RT_NULL;
  480. /* skip fragment frame */
  481. while((rb_descriptors[current_rb_index].addr & RxDESC_FLAG_OWNSHIP)
  482. && !(rb_descriptors[current_rb_index].status & RxDESC_STATUS_FRAME_START))
  483. {
  484. rb_descriptors[current_rb_index].addr &= (~RxDESC_FLAG_OWNSHIP);
  485. current_rb_index++;
  486. if(current_rb_index >= RB_BUFFER_SIZE) current_rb_index = 0;
  487. }
  488. if ((rb_descriptors[current_rb_index].addr & RxDESC_FLAG_OWNSHIP))
  489. {
  490. struct pbuf* q;
  491. rt_uint32_t index, pkt_len = 0;
  492. /* first of all, find the frame length */
  493. index = current_rb_index;
  494. while (rb_descriptors[index].addr & RxDESC_FLAG_OWNSHIP)
  495. {
  496. pkt_len = rb_descriptors[index].status & RxDESC_STATUS_BUF_SIZE;
  497. if (pkt_len > 0) break;
  498. index ++;
  499. if (index >= RB_BUFFER_SIZE) index = 0;
  500. }
  501. if (pkt_len)
  502. {
  503. //p = pbuf_alloc(PBUF_LINK, pkt_len, PBUF_RAM);
  504. p = pbuf_alloc(PBUF_RAW, pkt_len, PBUF_POOL);
  505. if(p != RT_NULL)
  506. {
  507. sam7xether_read_frame(RT_NULL, 0, pkt_len);
  508. for(q = p; q != RT_NULL; q= q->next)
  509. sam7xether_read_frame(q->payload, q->len, pkt_len);
  510. }
  511. else
  512. {
  513. rt_kprintf("no memory in pbuf\n");
  514. }
  515. }
  516. }
  517. /* enable interrupt */
  518. AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP;
  519. return p;
  520. }
  521. int sam7xether_register(char *name)
  522. {
  523. rt_err_t result;
  524. /* init rt-thread device interface */
  525. sam7x_dev_entry.parent.parent.init = sam7xether_init;
  526. sam7x_dev_entry.parent.parent.open = sam7xether_open;
  527. sam7x_dev_entry.parent.parent.close = sam7xether_close;
  528. sam7x_dev_entry.parent.parent.read = sam7xether_read;
  529. sam7x_dev_entry.parent.parent.write = sam7xether_write;
  530. sam7x_dev_entry.parent.parent.control = sam7xether_control;
  531. sam7x_dev_entry.parent.eth_rx = sam7xether_rx;
  532. sam7x_dev_entry.parent.eth_tx = sam7xether_tx;
  533. /* Update MAC address */
  534. sam7x_dev_entry.dev_addr[0] = 0x1e;
  535. sam7x_dev_entry.dev_addr[1] = 0x30;
  536. sam7x_dev_entry.dev_addr[2] = 0x6c;
  537. sam7x_dev_entry.dev_addr[3] = 0xa2;
  538. sam7x_dev_entry.dev_addr[4] = 0x45;
  539. sam7x_dev_entry.dev_addr[5] = 0x5e;
  540. /* update mac address */
  541. update_mac_address(sam7x_dev);
  542. rt_sem_init(&tx_sem, "emac", 1, RT_IPC_FLAG_FIFO);
  543. result = eth_device_init(&(sam7x_dev->parent), (char*)name);
  544. RT_ASSERT(result == RT_EOK);
  545. return RT_EOK;
  546. }