emac.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. /*
  2. * File : emac.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006-2014, RT-Thread Develop Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://openlab.rt-thread.com/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2014-08-29 aozima first implementation
  13. */
  14. #include <rtthread.h>
  15. #include <netif/ethernetif.h>
  16. #include "lwipopts.h"
  17. #include "board.h"
  18. #include "app_phy.h"
  19. /* debug option */
  20. #define ETH_DEBUG
  21. //#define ETH_RX_DUMP
  22. //#define ETH_TX_DUMP
  23. #ifdef ETH_DEBUG
  24. #define CME_ETH_PRINTF rt_kprintf
  25. #else
  26. #define CME_ETH_PRINTF(...)
  27. #endif
  28. #define MAX_ADDR_LEN 6
  29. struct rt_cme_eth
  30. {
  31. /* inherit from ethernet device */
  32. struct eth_device parent;
  33. /* interface address info. */
  34. rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */
  35. uint32_t ETH_Speed;
  36. uint32_t ETH_Mode;
  37. struct rt_semaphore tx_buf_free;
  38. struct rt_mutex lock;
  39. };
  40. static struct rt_cme_eth cme_eth_device;
  41. #if defined(ETH_RX_DUMP) || defined(ETH_TX_DUMP)
  42. static void packet_dump(const char * msg, const struct pbuf* p)
  43. {
  44. const struct pbuf* q;
  45. rt_uint32_t i,j;
  46. rt_uint8_t *ptr;
  47. rt_kprintf("%s %d byte\n", msg, p->tot_len);
  48. i=0;
  49. for(q=p; q != RT_NULL; q= q->next)
  50. {
  51. ptr = q->payload;
  52. for(j=0; j<q->len; j++)
  53. {
  54. if( (i%8) == 0 )
  55. {
  56. rt_kprintf(" ");
  57. }
  58. if( (i%16) == 0 )
  59. {
  60. rt_kprintf("\r\n");
  61. }
  62. rt_kprintf("%02x ",*ptr);
  63. i++;
  64. ptr++;
  65. }
  66. }
  67. rt_kprintf("\n\n");
  68. }
  69. #else
  70. #define packet_dump(...)
  71. #endif /* dump */
  72. /////////////////////////////////////////////////////////////////
  73. uint32_t rxTotalMemory = 0x2000;
  74. uint32_t rxDescNum = 3;
  75. uint32_t rxBufSize = 0x400;
  76. uint32_t rxBaseAddr = 0x2000C000;// C000-48K
  77. uint32_t txBaseAddr = 0x2000E000;// E000-56K
  78. uint32_t txTotalMemory = 0x2000;
  79. BOOL isRxNoBuf = FALSE;
  80. #define ETH_MAX_PACKET_SIZE 1520 /* ETH_HEADER + ETH_EXTRA + MAX_ETH_PAYLOAD + ETH_CRC */
  81. #define ETH_RXBUFNB 4
  82. #define ETH_TXBUFNB 2
  83. struct eth_rx_buffer
  84. {
  85. ETH_RX_DESC desc;
  86. uint32_t buffer[ETH_MAX_PACKET_SIZE/4];
  87. };
  88. struct eth_tx_buffer
  89. {
  90. ETH_TX_DESC desc;
  91. uint32_t buffer[ETH_MAX_PACKET_SIZE/4];
  92. };
  93. static struct eth_rx_buffer rx_buffer[ETH_RXBUFNB];
  94. static struct eth_tx_buffer tx_buffer[ETH_TXBUFNB];
  95. static void RxDescChainInit(void)
  96. {
  97. uint32_t i;
  98. // initialize rx descriptor
  99. ETH_RX_DESC *desc = &rx_buffer[0].desc;
  100. for (i = 0; i < ETH_RXBUFNB; i++)
  101. {
  102. desc->RX_1.RX1_b.SIZE = ETH_MAX_PACKET_SIZE;
  103. desc->bufAddr = (uint32_t)rx_buffer[i].buffer;
  104. if((i+1) == ETH_RXBUFNB)
  105. desc->nextDescAddr = (uint32_t)&rx_buffer[0].desc;
  106. else
  107. desc->nextDescAddr = (uint32_t)&rx_buffer[i+1].desc;
  108. desc = (ETH_RX_DESC *)desc->nextDescAddr;
  109. }
  110. ETH_SetRxDescRing(&rx_buffer[0].desc);
  111. }
  112. static void TxDescChainInit(void)
  113. {
  114. uint32_t i;
  115. // initialize tx descriptor
  116. ETH_TX_DESC *desc = &tx_buffer[0].desc;
  117. for (i = 0; i < ETH_TXBUFNB; i++)
  118. {
  119. desc->TX_1.TX1_b.SIZE = ETH_MAX_PACKET_SIZE;
  120. desc->bufAddr = (uint32_t)tx_buffer[i].buffer;
  121. if((i+1) == ETH_TXBUFNB)
  122. desc->nextDescAddr = (uint32_t)&tx_buffer[0].desc;
  123. else
  124. desc->nextDescAddr = (uint32_t)&tx_buffer[i+1].desc;
  125. desc = (ETH_TX_DESC *)desc->nextDescAddr;
  126. }
  127. ETH_SetTxDescRing(&tx_buffer[0].desc);
  128. }
  129. /////////////////////////////////////////////////////////////////
  130. /* initialize the interface */
  131. static rt_err_t rt_cme_eth_init(rt_device_t dev)
  132. {
  133. struct rt_cme_eth * cme_eth = (struct rt_cme_eth *)dev;
  134. ETH_InitTypeDef init;
  135. ETH_FrameFilter flt;
  136. init.ETH_Speed = phy_GetSpeed();
  137. init.ETH_Duplex = phy_GetDuplex();
  138. init.ETH_LinkUp = phy_IsLink();
  139. init.ETH_RxEn = TRUE;
  140. init.ETH_TxEn = TRUE;
  141. init.ETH_ChecksumOffload = FALSE;
  142. init.ETH_JumboFrame = FALSE;
  143. memcpy(init.ETH_MacAddr, cme_eth->dev_addr, sizeof(init.ETH_MacAddr));
  144. // Disable broadcast;
  145. // TODO: why?
  146. memset(&flt, 0, sizeof(ETH_FrameFilter));
  147. flt.ETH_BroadcastFilterEnable = FALSE;
  148. flt.ETH_OwnFilterEnable = FALSE;
  149. flt.ETH_SelfDrop = FALSE;
  150. flt.ETH_SourceFilterEnable = FALSE;
  151. flt.ETH_SourceDrop = FALSE;
  152. init.ETH_Filter = &flt;
  153. if (!phy_Init())
  154. {
  155. rt_kprintf("phy_Init failed!\n");
  156. while (1);
  157. }
  158. if (!ETH_Init(&init))
  159. {
  160. rt_kprintf("ETH_Init failed!\n");
  161. while (1);
  162. }
  163. RxDescChainInit();
  164. TxDescChainInit();
  165. ETH_ITConfig(ETH_INT_BUS_FATAL_ERROR, TRUE);
  166. ETH_ITConfig(ETH_INT_RX_COMPLETE_FRAME, TRUE);
  167. ETH_ITConfig(ETH_INT_RX_BUF_UNAVAI, TRUE);
  168. ETH_ITConfig(ETH_INT_RX_STOP, TRUE);
  169. ETH_StartRx();
  170. ETH_ITConfig(ETH_INT_TX_COMPLETE_FRAME, TRUE);
  171. ETH_StartTx();
  172. return RT_EOK;
  173. }
  174. static rt_err_t rt_cme_eth_open(rt_device_t dev, rt_uint16_t oflag)
  175. {
  176. return RT_EOK;
  177. }
  178. static rt_err_t rt_cme_eth_close(rt_device_t dev)
  179. {
  180. return RT_EOK;
  181. }
  182. static rt_size_t rt_cme_eth_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  183. {
  184. rt_set_errno(-RT_ENOSYS);
  185. return 0;
  186. }
  187. static rt_size_t rt_cme_eth_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  188. {
  189. rt_set_errno(-RT_ENOSYS);
  190. return 0;
  191. }
  192. static rt_err_t rt_cme_eth_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  193. {
  194. switch(cmd)
  195. {
  196. case NIOCTL_GADDR:
  197. /* get mac address */
  198. if(args) rt_memcpy(args, cme_eth_device.dev_addr, 6);
  199. else return -RT_ERROR;
  200. break;
  201. default :
  202. break;
  203. }
  204. return RT_EOK;
  205. }
  206. /* ethernet device interface */
  207. /* transmit packet. */
  208. rt_err_t rt_cme_eth_tx( rt_device_t dev, struct pbuf* p)
  209. {
  210. rt_err_t result = RT_EOK;
  211. ETH_TX_DESC *desc;
  212. struct rt_cme_eth * cme_eth = (struct rt_cme_eth *)dev;
  213. rt_mutex_take(&cme_eth->lock, RT_WAITING_FOREVER);
  214. #ifdef ETH_TX_DUMP
  215. packet_dump("TX dump", p);
  216. #endif /* ETH_TX_DUMP */
  217. /* get free tx buffer */
  218. {
  219. rt_err_t result;
  220. result = rt_sem_take(&cme_eth->tx_buf_free, RT_TICK_PER_SECOND/10);
  221. if (result != RT_EOK)
  222. {
  223. result = -RT_ERROR;
  224. goto _exit;
  225. }
  226. }
  227. desc = ETH_AcquireFreeTxDesc();
  228. if(desc == RT_NULL)
  229. {
  230. CME_ETH_PRINTF("TxDesc not ready!\n");
  231. RT_ASSERT(0);
  232. result = -RT_ERROR;
  233. goto _exit;
  234. }
  235. desc->TX_0.TX0_b.FS = TRUE;
  236. desc->TX_0.TX0_b.LS = TRUE;
  237. desc->TX_1.TX1_b.SIZE = p->tot_len;
  238. pbuf_copy_partial(p, ( void *)(desc->bufAddr), p->tot_len, 0);
  239. ETH_ReleaseTxDesc(desc);
  240. ETH_ResumeTx();
  241. _exit:
  242. rt_mutex_release(&cme_eth->lock);
  243. return result;
  244. }
  245. /* reception packet. */
  246. struct pbuf *rt_cme_eth_rx(rt_device_t dev)
  247. {
  248. struct pbuf* p = RT_NULL;
  249. ETH_RX_DESC *desc;
  250. uint32_t framelength;
  251. struct rt_cme_eth * cme_eth = (struct rt_cme_eth *)dev;
  252. rt_mutex_take(&cme_eth->lock, RT_WAITING_FOREVER);
  253. desc = ETH_AcquireFreeRxDesc();
  254. if(desc == RT_NULL)
  255. {
  256. ETH_ITConfig(ETH_INT_RX_COMPLETE_FRAME, TRUE);
  257. ETH_ITConfig(ETH_INT_RX_BUF_UNAVAI, TRUE);
  258. ETH_ResumeRx();
  259. goto _exit;
  260. }
  261. framelength = desc->RX_0.RX0_b.FL;
  262. /* allocate buffer */
  263. p = pbuf_alloc(PBUF_LINK, framelength, PBUF_RAM);
  264. if (p != RT_NULL)
  265. {
  266. pbuf_take(p, (const void *)(desc->bufAddr), framelength);
  267. #ifdef ETH_RX_DUMP
  268. packet_dump("RX dump", p);
  269. #endif /* ETH_RX_DUMP */
  270. }
  271. ETH_ReleaseRxDesc(desc);
  272. _exit:
  273. rt_mutex_release(&cme_eth->lock);
  274. return p;
  275. }
  276. static void NVIC_Configuration(void)
  277. {
  278. NVIC_InitTypeDef NVIC_InitStructure;
  279. /* Enable the USARTy Interrupt */
  280. NVIC_InitStructure.NVIC_IRQChannel = ETH_INT_IRQn;
  281. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  282. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  283. NVIC_InitStructure.NVIC_IRQChannelCmd = TRUE;
  284. NVIC_Init(&NVIC_InitStructure);
  285. }
  286. int cme_m7_eth_init(void)
  287. {
  288. // /* PHY RESET: PA4 */
  289. // {
  290. // GPIO_ResetBits(GPIOA, GPIO_Pin_4);
  291. // rt_thread_delay(2);
  292. // GPIO_SetBits(GPIOA, GPIO_Pin_4);
  293. // rt_thread_delay(2);
  294. // }
  295. // GPIO_Configuration();
  296. NVIC_Configuration();
  297. // cme_eth_device.ETH_Speed = ETH_Speed_100M;
  298. // cme_eth_device.ETH_Mode = ETH_Mode_FullDuplex;
  299. /* OUI 00-80-E1 STMICROELECTRONICS. */
  300. cme_eth_device.dev_addr[0] = 0x00;
  301. cme_eth_device.dev_addr[1] = 0x80;
  302. cme_eth_device.dev_addr[2] = 0xE1;
  303. /* generate MAC addr from 96bit unique ID (only for test). */
  304. // cme_eth_device.dev_addr[3] = *(rt_uint8_t*)(0x1FFF7A10+4);
  305. // cme_eth_device.dev_addr[4] = *(rt_uint8_t*)(0x1FFF7A10+2);
  306. // cme_eth_device.dev_addr[5] = *(rt_uint8_t*)(0x1FFF7A10+0);
  307. cme_eth_device.dev_addr[3] = 12;
  308. cme_eth_device.dev_addr[4] = 34;
  309. cme_eth_device.dev_addr[5] = 56;
  310. cme_eth_device.parent.parent.init = rt_cme_eth_init;
  311. cme_eth_device.parent.parent.open = rt_cme_eth_open;
  312. cme_eth_device.parent.parent.close = rt_cme_eth_close;
  313. cme_eth_device.parent.parent.read = rt_cme_eth_read;
  314. cme_eth_device.parent.parent.write = rt_cme_eth_write;
  315. cme_eth_device.parent.parent.control = rt_cme_eth_control;
  316. cme_eth_device.parent.parent.user_data = RT_NULL;
  317. cme_eth_device.parent.eth_rx = rt_cme_eth_rx;
  318. cme_eth_device.parent.eth_tx = rt_cme_eth_tx;
  319. /* init EMAC lock */
  320. rt_mutex_init(&cme_eth_device.lock, "emac0", RT_IPC_FLAG_PRIO);
  321. /* init tx buffer free semaphore */
  322. rt_sem_init(&cme_eth_device.tx_buf_free,
  323. "tx_buf",
  324. ETH_TXBUFNB,
  325. RT_IPC_FLAG_FIFO);
  326. /* register eth device */
  327. eth_device_init(&(cme_eth_device.parent), "e0");
  328. return RT_EOK;
  329. }
  330. void ETH_IRQHandler(void)
  331. {
  332. /* enter interrupt */
  333. rt_interrupt_enter();
  334. if (ETH_GetITStatus(ETH_INT_TX_COMPLETE_FRAME))
  335. {
  336. rt_sem_release(&cme_eth_device.tx_buf_free);
  337. ETH_ClearITPendingBit(ETH_INT_TX_COMPLETE_FRAME);
  338. }
  339. if (ETH_GetITStatus(ETH_INT_RX_STOP))
  340. {
  341. CME_ETH_PRINTF("ETH_INT_RX_STOP\n");
  342. ETH_ClearITPendingBit(ETH_INT_RX_STOP);
  343. }
  344. if ((ETH_GetITStatus(ETH_INT_RX_BUF_UNAVAI)) ||
  345. (ETH_GetITStatus(ETH_INT_RX_COMPLETE_FRAME)))
  346. {
  347. /* a frame has been received */
  348. eth_device_ready(&(cme_eth_device.parent));
  349. ETH_ITConfig(ETH_INT_RX_COMPLETE_FRAME, FALSE);
  350. ETH_ITConfig(ETH_INT_RX_BUF_UNAVAI, FALSE);
  351. ETH_ClearITPendingBit(ETH_INT_RX_BUF_UNAVAI);
  352. ETH_ClearITPendingBit(ETH_INT_RX_COMPLETE_FRAME);
  353. }
  354. /* leave interrupt */
  355. rt_interrupt_leave();
  356. }