drv_eth.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-05-19 Joe first version
  9. */
  10. #include "at32f4xx_eth.h"
  11. #include "board.h"
  12. #include <netif/ethernetif.h>
  13. #include "lwipopts.h"
  14. #include "drv_eth.h"
  15. #include <drv_log.h>
  16. /* EMAC Interface */
  17. #define PHY_ADDRESS 0x00 /* Relative to AT32F407-EVAL Board */
  18. //#define MII_MODE /* MII mode for AT32F407-EVAL Board (MB784) (check jumpers setting) */
  19. #define RMII_MODE /* RMII mode for AT32F407-EVAL Board (MB784) (check jumpers setting) */
  20. //#define CRYSTAL_ON_PHY
  21. #define MII_RX_REMAP 1
  22. /* debug option */
  23. //#define ETH_RX_DUMP
  24. //#define ETH_TX_DUMP
  25. //#define DRV_DEBUG
  26. #define LOG_TAG "drv.emac"
  27. #define ETH_RXBUFNB 4
  28. #define ETH_TXBUFNB 2
  29. #define LINK_THREAD_STACK_SIZE 256
  30. #define LINK_THREAD_PREORITY 21
  31. extern ETH_DMADESCTypeDef *DMATxDescToSet;
  32. extern ETH_DMADESCTypeDef *DMARxDescToGet;
  33. extern ETH_DMADESCTypeDef *DMAPTPTxDescToSet;
  34. extern ETH_DMADESCTypeDef *DMAPTPRxDescToGet;
  35. static ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB];
  36. static rt_uint8_t Rx_Buff[ETH_RXBUFNB][ETH_MAX_PACKET_SIZE], Tx_Buff[ETH_TXBUFNB][ETH_MAX_PACKET_SIZE];
  37. static struct rt_thread eth_link_thread;
  38. static rt_uint8_t eth_link_stack[LINK_THREAD_STACK_SIZE];
  39. #define MAX_ADDR_LEN 6
  40. /* Gloable variables ---------------------------------------------------------*/
  41. void static Reset_Phy(void);
  42. void NVIC_Configuration(void);
  43. void GPIO_Configuration(void);
  44. struct rt_at32_eth
  45. {
  46. /* inherit from ethernet device */
  47. struct eth_device parent;
  48. #ifndef PHY_USING_INTERRUPT_MODE
  49. rt_timer_t poll_link_timer;
  50. #endif
  51. /* interface address info, hw address */
  52. rt_uint8_t dev_addr[MAX_ADDR_LEN];
  53. /* ETH_Speed */
  54. uint32_t ETH_Speed;
  55. /* ETH_Duplex_Mode */
  56. uint32_t ETH_Mode;
  57. };
  58. static ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB]; /* Ethernet Rx & Tx DMA Descriptors */
  59. static uint8_t Rx_Buff[ETH_RXBUFNB][ETH_MAX_PACKET_SIZE], Tx_Buff[ETH_TXBUFNB][ETH_MAX_PACKET_SIZE]; /* Ethernet buffers */
  60. //static ETH_HandleTypeDef EthHandle;
  61. static struct rt_at32_eth at32_eth_device;
  62. static struct rt_semaphore tx_wait;
  63. static rt_bool_t tx_is_waiting = RT_FALSE;
  64. #if defined(ETH_RX_DUMP) || defined(ETH_TX_DUMP)
  65. #define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
  66. static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
  67. {
  68. unsigned char *buf = (unsigned char *)ptr;
  69. int i, j;
  70. for (i = 0; i < buflen; i += 16)
  71. {
  72. rt_kprintf("%08X: ", i);
  73. for (j = 0; j < 16; j++)
  74. if (i + j < buflen)
  75. rt_kprintf("%02X ", buf[i + j]);
  76. else
  77. rt_kprintf(" ");
  78. rt_kprintf(" ");
  79. for (j = 0; j < 16; j++)
  80. if (i + j < buflen)
  81. rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
  82. rt_kprintf("\n");
  83. }
  84. }
  85. #endif
  86. /**
  87. * @brief reset the phy
  88. * @param None
  89. * @retval None
  90. */
  91. void static Reset_Phy(void)
  92. {
  93. GPIO_InitType GPIO_InitStructure;
  94. GPIO_InitStructure.GPIO_Pins = GPIO_Pins_8;
  95. GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
  96. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT_PP;
  97. GPIO_Init(GPIOC, &GPIO_InitStructure);
  98. GPIO_ResetBits(GPIOC, GPIO_Pins_8);
  99. rt_thread_mdelay(2);
  100. GPIO_SetBits(GPIOC, GPIO_Pins_8);
  101. rt_thread_mdelay(2000);
  102. }
  103. /**
  104. * @brief Configure NVIC for ISR
  105. * @param None
  106. * @retval None
  107. */
  108. void NVIC_Configuration(void)
  109. {
  110. NVIC_InitType NVIC_InitStructure;
  111. /* Set the Vector Table base location at 0x08000000 */
  112. NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
  113. /* 2 bit for pre-emption priority, 2 bits for subpriority */
  114. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  115. /* Enable the Ethernet global Interrupt */
  116. NVIC_InitStructure.NVIC_IRQChannel = ETH_IRQn;
  117. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  118. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  119. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  120. NVIC_Init(&NVIC_InitStructure);
  121. }
  122. /**
  123. * @brief Configure GPIO for ethernet
  124. * @param None
  125. * @retval None
  126. */
  127. void GPIO_Configuration(void)
  128. {
  129. GPIO_InitType GPIO_InitStructure;
  130. #if MII_RX_REMAP
  131. GPIO_PinsRemapConfig(GPIO_Remap_ETH, ENABLE);
  132. #endif
  133. RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOA | RCC_APB2PERIPH_GPIOB | RCC_APB2PERIPH_GPIOC |
  134. RCC_APB2PERIPH_GPIOD | RCC_APB2PERIPH_GPIOE | RCC_APB2PERIPH_AFIO, ENABLE);
  135. /* ETHERNET pins configuration */
  136. /* AF Output Push Pull:
  137. ETH_MII_MDIO / ETH_RMII_MDIO: PA2
  138. ETH_MII_MDC / ETH_RMII_MDC: PC1
  139. */
  140. /* Configure PA2 as alternate function push-pull MDIO*/
  141. GPIO_InitStructure.GPIO_Pins = GPIO_Pins_2;
  142. GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
  143. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  144. GPIO_Init(GPIOA, &GPIO_InitStructure);
  145. /*PC1-->MDC*/
  146. GPIO_InitStructure.GPIO_Pins = GPIO_Pins_1;
  147. GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
  148. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  149. GPIO_Init(GPIOC, &GPIO_InitStructure);
  150. /*MII Mode GPIO configuration*/
  151. #ifdef MII_MODE
  152. /**********************MII Tx Pin Define****************************/
  153. /*
  154. ETH_MII_TX0-->PB12 AF-PP
  155. ETH_MII_TX1-->PB13 AF-PP
  156. ETH_MII_TX2-->PC2 AF-PP
  157. ETH_MII_TX3-->PB8 AF-PP
  158. ETH_MII_TX_EN-->PB11 AF-PP
  159. ETH_MII_TX_CLK-->PC3
  160. */
  161. GPIO_InitStructure.GPIO_Pins = GPIO_Pins_8 | GPIO_Pins_11 | GPIO_Pins_12 | GPIO_Pins_13;
  162. GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
  163. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  164. GPIO_Init(GPIOB, &GPIO_InitStructure);
  165. GPIO_InitStructure.GPIO_Pins = GPIO_Pins_2 | GPIO_Pins_3;
  166. GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
  167. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  168. GPIO_Init(GPIOC, &GPIO_InitStructure);
  169. /**********************MII Rx Pin Define****************************/
  170. #if MII_RX_REMAP /*IO PIN remaped*/
  171. /*
  172. ETH_MII_RX_DV-->PD8
  173. ETH_MII_RXD0-->PD9
  174. ETH_MII_RXD1-->PD10
  175. ETH_MII_RXD2-->PD11
  176. ETH_MII_RXD3-->PD12
  177. ETH_MII_RXCLK-->PA1
  178. ETH_MII_CRS-->PA0
  179. ETH_MII_COL-->PA3
  180. ETH_MII_RX_ER-->PB10
  181. */
  182. GPIO_InitStructure.GPIO_Pins = GPIO_Pins_8 | GPIO_Pins_9 | GPIO_Pins_10 | GPIO_Pins_11 | GPIO_Pins_12;
  183. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  184. GPIO_Init(GPIOD, &GPIO_InitStructure);
  185. GPIO_InitStructure.GPIO_Pins = GPIO_Pins_0 | GPIO_Pins_1 | GPIO_Pins_3;
  186. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  187. GPIO_Init(GPIOA, &GPIO_InitStructure);
  188. GPIO_InitStructure.GPIO_Pins = GPIO_Pins_10;
  189. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  190. GPIO_Init(GPIOB, &GPIO_InitStructure);
  191. #else
  192. /*
  193. ETH_MII_RX_DV-->PA7
  194. ETH_MII_RXD0-->PC4
  195. ETH_MII_RXD1-->PC5
  196. ETH_MII_RXD2-->PB0
  197. ETH_MII_RXD3-->PB1
  198. ETH_MII_RXCLK-->PA1
  199. ETH_MII_CRS-->PA0
  200. ETH_MII_COL-->PA3
  201. ETH_MII_RX_ER-->PB10
  202. */
  203. GPIO_InitStructure.GPIO_Pins = GPIO_Pins_0 | GPIO_Pins_1 | GPIO_Pins_3 | GPIO_Pins_7;
  204. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  205. GPIO_Init(GPIOA, &GPIO_InitStructure);
  206. GPIO_InitStructure.GPIO_Pins = GPIO_Pins_4 | GPIO_Pins_5;
  207. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  208. GPIO_Init(GPIOC, &GPIO_InitStructure);
  209. GPIO_InitStructure.GPIO_Pins = GPIO_Pins_0 | GPIO_Pins_1 | GPIO_Pins_10;
  210. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  211. GPIO_Init(GPIOB, &GPIO_InitStructure);
  212. #endif //End MII RX REMAP
  213. #endif //End MII mode
  214. #ifdef RMII_MODE
  215. /**********************RMII Tx Pin Define****************************/
  216. /*
  217. ETH_RMII_TX0-->PB12 AF-PP
  218. ETH_RMII_TX1-->PB13 AF-PP
  219. ETH_RMII_TX_EN-->PB11 AF-PP
  220. */
  221. GPIO_InitStructure.GPIO_Pins = GPIO_Pins_11 | GPIO_Pins_12 | GPIO_Pins_13;
  222. GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
  223. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  224. GPIO_Init(GPIOB, &GPIO_InitStructure);
  225. /**********************RMII Rx Pin Define****************************/
  226. #if MII_RX_REMAP /*IO PIN remaped*/
  227. /*
  228. ETH_RMII_RX_DV-->PD8
  229. ETH_RMII_RXD0-->PD9
  230. ETH_RMII_RXD1-->PD10
  231. ETH_RMII_REF_CLK-->PA1
  232. */
  233. GPIO_InitStructure.GPIO_Pins = GPIO_Pins_8 | GPIO_Pins_9 | GPIO_Pins_10;
  234. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  235. GPIO_Init(GPIOD, &GPIO_InitStructure);
  236. GPIO_InitStructure.GPIO_Pins = GPIO_Pins_1;
  237. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  238. GPIO_Init(GPIOA, &GPIO_InitStructure);
  239. #else
  240. /*
  241. ETH_RMII_RX_DV-->PA7
  242. ETH_RMII_RXD0-->PC4
  243. ETH_RMII_RXD1-->PC5
  244. ETH_RMII_REF_CLK-->PA1
  245. */
  246. GPIO_InitStructure.GPIO_Pins = GPIO_Pins_1 | GPIO_Pins_7;
  247. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  248. GPIO_Init(GPIOA, &GPIO_InitStructure);
  249. GPIO_InitStructure.GPIO_Pins = GPIO_Pins_4 | GPIO_Pins_5;
  250. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  251. GPIO_Init(GPIOC, &GPIO_InitStructure);
  252. #endif //End RMII RX REMAP
  253. #endif //End RMII mode
  254. /* ADC Channel4 config --------------------------------------------------------*/
  255. /* Configure PA4(ADC Channel4) as analog input -------------------------*/
  256. #ifdef ADC_NECESSARY
  257. GPIO_InitStructure.GPIO_Pins = GPIO_Pins_4;
  258. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_ANALOG;
  259. GPIO_Init(GPIOA, &GPIO_InitStructure);
  260. #endif
  261. /* MCO pin configuration------------------------------------------------- */
  262. /* Configure MCO (PA8) as alternate function push-pull */
  263. #ifndef CRYSTAL_ON_PHY
  264. GPIO_InitStructure.GPIO_Pins = GPIO_Pins_8;
  265. GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
  266. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  267. GPIO_Init(GPIOA, &GPIO_InitStructure);
  268. #endif
  269. }
  270. /* EMAC initialization function */
  271. static rt_err_t rt_at32_eth_init(rt_device_t dev)
  272. {
  273. ETH_InitType ETH_InitStructure;
  274. RCC_AHBPeriphClockCmd(RCC_AHBPERIPH_ETHMAC | RCC_AHBPERIPH_ETHMACTX |
  275. RCC_AHBPERIPH_ETHMACRX, ENABLE);
  276. /* MII/RMII Media interface selection ------------------------------------------*/
  277. #ifdef MII_MODE /* Mode MII with AT32F407-EVAL */
  278. GPIO_ETH_MediaInterfaceConfig(GPIO_ETH_MediaInterface_MII);
  279. /* Get 25MHz from system clock 200MHz on PA8 pin (MCO) */
  280. #ifndef CRYSTAL_ON_PHY
  281. RCC_CLKOUTConfig(RCC_CLKOUT_SYSCLK, RCC_MCOPRE_8);
  282. #endif
  283. #elif defined RMII_MODE /* Mode RMII with AT32F407-EVAL */
  284. GPIO_ETH_MediaInterfaceConfig(GPIO_ETH_MediaInterface_RMII);
  285. #ifndef CRYSTAL_ON_PHY
  286. RCC_CLKOUTConfig(RCC_CLKOUT_SYSCLK, RCC_MCOPRE_8); /*25M to RMII Mode*/
  287. #endif
  288. #endif
  289. /*Reset phy*/
  290. Reset_Phy();
  291. /* Reset ETHERNET on AHB Bus */
  292. ETH_DeInit();
  293. /* Software reset */
  294. ETH_SoftwareReset();
  295. /* Wait for software reset */
  296. while (ETH_GetSoftwareResetStatus() == SET);
  297. /* ETHERNET Configuration ------------------------------------------------------*/
  298. /* Call ETH_StructInit if you don't like to configure all ETH_InitStructure parameter */
  299. ETH_StructInit(&ETH_InitStructure);
  300. /* Fill ETH_InitStructure parametrs */
  301. /*------------------------ MAC -----------------------------------*/
  302. ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable;//ETH_AutoNegotiation_Enable ;
  303. ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable;
  304. ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Enable;
  305. ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;
  306. ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Disable;
  307. ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable;
  308. ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;
  309. ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;//ETH_MulticastFramesFilter_Perfect;
  310. ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;
  311. #ifdef CHECKSUM_BY_HARDWARE
  312. ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable;
  313. #endif
  314. /*------------------------ DMA -----------------------------------*/
  315. /* When we use the Checksum offload feature, we need to enable the Store and Forward mode:
  316. the store and forward guarantee that a whole frame is stored in the FIFO, so the MAC can insert/verify the checksum,
  317. if the checksum is OK the DMA can handle the frame otherwise the frame is dropped */
  318. ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Enable;//ETH_DropTCPIPChecksumErrorFrame_Enable;
  319. ETH_InitStructure.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable;
  320. ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable;
  321. ETH_InitStructure.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable;
  322. ETH_InitStructure.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable;
  323. ETH_InitStructure.ETH_SecondFrameOperate = ETH_SecondFrameOperate_Enable;
  324. ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable;
  325. ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable;
  326. ETH_InitStructure.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat;
  327. ETH_InitStructure.ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat;
  328. ETH_InitStructure.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1;
  329. /* Configure Ethernet, check error */
  330. if(ETH_Init(&ETH_InitStructure, PHY_ADDRESS) == ((uint32_t)0)) {
  331. return RT_ERROR;
  332. }
  333. /* Enable DMA Receive interrupt (need to enable in this case Normal interrupt) */
  334. ETH_DMAITConfig(ETH_DMA_INT_NIS | ETH_DMA_INT_R, ENABLE);
  335. /* Initialize Tx Descriptors list: Chain Mode */
  336. ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
  337. /* Initialize Rx Descriptors list: Chain Mode */
  338. ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
  339. /* MAC address configuration */
  340. ETH_MACAddressConfig(ETH_MAC_Address0, (u8*)&at32_eth_device.dev_addr[0]);
  341. /* Enable ETH transmition and recetion */
  342. ETH_Start();
  343. return RT_EOK;
  344. }
  345. static rt_err_t rt_at32_eth_open(rt_device_t dev, rt_uint16_t oflag)
  346. {
  347. LOG_D("emac open");
  348. return RT_EOK;
  349. }
  350. static rt_err_t rt_at32_eth_close(rt_device_t dev)
  351. {
  352. LOG_D("emac close");
  353. return RT_EOK;
  354. }
  355. static rt_size_t rt_at32_eth_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  356. {
  357. LOG_D("emac read");
  358. rt_set_errno(-RT_ENOSYS);
  359. return 0;
  360. }
  361. static rt_size_t rt_at32_eth_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  362. {
  363. LOG_D("emac write");
  364. rt_set_errno(-RT_ENOSYS);
  365. return 0;
  366. }
  367. static rt_err_t rt_at32_eth_control(rt_device_t dev, int cmd, void *args)
  368. {
  369. switch (cmd)
  370. {
  371. case NIOCTL_GADDR:
  372. /* get mac address */
  373. if (args) rt_memcpy(args, at32_eth_device.dev_addr, 6);
  374. else return -RT_ERROR;
  375. break;
  376. default :
  377. break;
  378. }
  379. return RT_EOK;
  380. }
  381. /* ethernet device interface */
  382. /* transmit data*/
  383. rt_err_t rt_at32_eth_tx(rt_device_t dev, struct pbuf *p)
  384. {
  385. struct pbuf* q;
  386. rt_uint32_t offset;
  387. /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
  388. while ((DMATxDescToSet->Status & ETH_DMATxDesc_OWN) != (uint32_t)RESET)
  389. {
  390. rt_err_t result;
  391. rt_uint32_t level;
  392. level = rt_hw_interrupt_disable();
  393. tx_is_waiting = RT_TRUE;
  394. rt_hw_interrupt_enable(level);
  395. /* it's own bit set, wait it */
  396. result = rt_sem_take(&tx_wait, RT_WAITING_FOREVER);
  397. if (result == RT_EOK) break;
  398. if (result == -RT_ERROR) return -RT_ERROR;
  399. }
  400. offset = 0;
  401. for (q = p; q != NULL; q = q->next)
  402. {
  403. uint8_t *to;
  404. /* Copy the frame to be sent into memory pointed by the current ETHERNET DMA Tx descriptor */
  405. to = (uint8_t*)((DMATxDescToSet->Buffer1Addr) + offset);
  406. memcpy(to, q->payload, q->len);
  407. offset += q->len;
  408. }
  409. #ifdef ETH_TX_DUMP
  410. {
  411. rt_uint32_t i;
  412. rt_uint8_t *ptr = (rt_uint8_t*)(DMATxDescToSet->Buffer1Addr);
  413. AT32_ETH_PRINTF("tx_dump, len:%d\r\n", p->tot_len);
  414. for(i=0; i<p->tot_len; i++)
  415. {
  416. AT32_ETH_PRINTF("%02x ",*ptr);
  417. ptr++;
  418. if(((i+1)%8) == 0)
  419. {
  420. AT32_ETH_PRINTF(" ");
  421. }
  422. if(((i+1)%16) == 0)
  423. {
  424. AT32_ETH_PRINTF("\r\n");
  425. }
  426. }
  427. AT32_ETH_PRINTF("\r\ndump done!\r\n");
  428. }
  429. #endif
  430. /* Setting the Frame Length: bits[12:0] */
  431. DMATxDescToSet->ControlBufferSize = (p->tot_len & ETH_DMATxDesc_TBS1);
  432. /* Setting the last segment and first segment bits (in this case a frame is transmitted in one descriptor) */
  433. DMATxDescToSet->Status |= ETH_DMATxDesc_LS | ETH_DMATxDesc_FS;
  434. /* Enable TX Completion Interrupt */
  435. DMATxDescToSet->Status |= ETH_DMATxDesc_IC;
  436. #ifdef CHECKSUM_BY_HARDWARE
  437. DMATxDescToSet->Status |= ETH_DMATxDesc_ChecksumTCPUDPICMPFull;
  438. /* clean ICMP checksum STM32F need */
  439. {
  440. struct eth_hdr *ethhdr = (struct eth_hdr *)(DMATxDescToSet->Buffer1Addr);
  441. /* is IP ? */
  442. if( ethhdr->type == htons(ETHTYPE_IP) )
  443. {
  444. struct ip_hdr *iphdr = (struct ip_hdr *)(DMATxDescToSet->Buffer1Addr + SIZEOF_ETH_HDR);
  445. /* is ICMP ? */
  446. if( IPH_PROTO(iphdr) == IP_PROTO_ICMP )
  447. {
  448. struct icmp_echo_hdr *iecho = (struct icmp_echo_hdr *)(DMATxDescToSet->Buffer1Addr + SIZEOF_ETH_HDR + sizeof(struct ip_hdr) );
  449. iecho->chksum = 0;
  450. }
  451. }
  452. }
  453. #endif
  454. /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
  455. DMATxDescToSet->Status |= ETH_DMATxDesc_OWN;
  456. /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
  457. if ((ETH->DMASTS & ETH_DMA_FLAG_TBU) != (uint32_t)RESET)
  458. {
  459. /* Clear TBUS ETHERNET DMA flag */
  460. ETH->DMASTS = ETH_DMA_FLAG_TBU;
  461. /* Transmit Poll Demand to resume DMA transmission*/
  462. ETH->DMATPD = 0;
  463. }
  464. /* Update the ETHERNET DMA global Tx descriptor with next Tx decriptor */
  465. /* Chained Mode */
  466. /* Selects the next DMA Tx descriptor list for next buffer to send */
  467. DMATxDescToSet = (ETH_DMADESCTypeDef*) (DMATxDescToSet->Buffer2NextDescAddr);
  468. /* Return SUCCESS */
  469. return RT_EOK;
  470. }
  471. /* receive data*/
  472. struct pbuf *rt_at32_eth_rx(rt_device_t dev)
  473. {
  474. struct pbuf* p;
  475. rt_uint32_t offset = 0, framelength = 0;
  476. /* init p pointer */
  477. p = RT_NULL;
  478. /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
  479. if(((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) != (uint32_t)RESET))
  480. return p;
  481. if (((DMARxDescToGet->Status & ETH_DMARxDesc_ES) == (uint32_t)RESET) &&
  482. ((DMARxDescToGet->Status & ETH_DMARxDesc_LS) != (uint32_t)RESET) &&
  483. ((DMARxDescToGet->Status & ETH_DMARxDesc_FS) != (uint32_t)RESET))
  484. {
  485. /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
  486. framelength = ((DMARxDescToGet->Status & ETH_DMARxDesc_FL) >> 16) - 4;
  487. /* allocate buffer */
  488. p = pbuf_alloc(PBUF_LINK, framelength, PBUF_RAM);
  489. if (p != RT_NULL)
  490. {
  491. struct pbuf* q;
  492. for (q = p; q != RT_NULL; q= q->next)
  493. {
  494. /* Copy the received frame into buffer from memory pointed by the current ETHERNET DMA Rx descriptor */
  495. memcpy(q->payload, (uint8_t *)((DMARxDescToGet->Buffer1Addr) + offset), q->len);
  496. offset += q->len;
  497. }
  498. #ifdef ETH_RX_DUMP
  499. {
  500. rt_uint32_t i;
  501. rt_uint8_t *ptr = (rt_uint8_t*)(DMARxDescToGet->Buffer1Addr);
  502. AT32_ETH_PRINTF("rx_dump, len:%d\r\n", p->tot_len);
  503. for(i=0; i<p->tot_len; i++)
  504. {
  505. AT32_ETH_PRINTF("%02x ", *ptr);
  506. ptr++;
  507. if(((i+1)%8) == 0)
  508. {
  509. AT32_ETH_PRINTF(" ");
  510. }
  511. if(((i+1)%16) == 0)
  512. {
  513. AT32_ETH_PRINTF("\r\n");
  514. }
  515. }
  516. AT32_ETH_PRINTF("\r\ndump done!\r\n");
  517. }
  518. #endif
  519. }
  520. }
  521. /* Set Own bit of the Rx descriptor Status: gives the buffer back to ETHERNET DMA */
  522. DMARxDescToGet->Status = ETH_DMARxDesc_OWN;
  523. /* When Rx Buffer unavailable flag is set: clear it and resume reception */
  524. if ((ETH->DMASTS & ETH_DMA_FLAG_RBU) != (uint32_t)RESET)
  525. {
  526. /* Clear RBUS ETHERNET DMA flag */
  527. ETH->DMASTS = ETH_DMA_FLAG_RBU;
  528. /* Resume DMA reception */
  529. ETH->DMARPD = 0;
  530. }
  531. /* Update the ETHERNET DMA global Rx descriptor with next Rx decriptor */
  532. /* Chained Mode */
  533. if((DMARxDescToGet->ControlBufferSize & ETH_DMARxDesc_RCH) != (uint32_t)RESET)
  534. {
  535. /* Selects the next DMA Rx descriptor list for next buffer to read */
  536. DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);
  537. }
  538. else /* Ring Mode */
  539. {
  540. if((DMARxDescToGet->ControlBufferSize & ETH_DMARxDesc_RER) != (uint32_t)RESET)
  541. {
  542. /* Selects the first DMA Rx descriptor for next buffer to read: last Rx descriptor was used */
  543. DMARxDescToGet = (ETH_DMADESCTypeDef*) (ETH->DMARDLADDR);
  544. }
  545. else
  546. {
  547. /* Selects the next DMA Rx descriptor list for next buffer to read */
  548. DMARxDescToGet = (ETH_DMADESCTypeDef*) ((uint32_t)DMARxDescToGet + 0x10 + ((ETH->DMABM & 0x0000007C) >> 2));
  549. }
  550. }
  551. return p;
  552. }
  553. static void eth_link_thread_entry(void *paramter)
  554. {
  555. uint8_t linked_down = 1;
  556. struct netif *pnetif = at32_eth_device.parent.netif;
  557. while(1){
  558. if((ETH_ReadPHYRegister(PHY_ADDRESS, PHY_BSR) & PHY_Linked_Status) && (linked_down == 1))
  559. {
  560. /* link up */
  561. linked_down = 0;
  562. #ifndef RT_LWIP_DHCP
  563. pnetif->ip_addr = inet_addr(RT_LWIP_IPADDR);
  564. pnetif->gw = inet_addr(RT_LWIP_GWADDR);
  565. pnetif->netmask = inet_addr(RT_LWIP_MSKADDR);
  566. #else
  567. IP4_ADDR(&(pnetif->ip_addr), 0, 0, 0, 0);
  568. IP4_ADDR(&(pnetif->netmask), 0, 0, 0, 0);
  569. IP4_ADDR(&(pnetif->gw), 0, 0, 0, 0);
  570. #endif
  571. eth_device_linkchange(&(at32_eth_device.parent), RT_TRUE);
  572. }else if(!(ETH_ReadPHYRegister(PHY_ADDRESS, PHY_BSR) & PHY_Linked_Status) && (linked_down == 0))
  573. {
  574. /* link down */
  575. linked_down = 1;
  576. eth_device_linkchange(&(at32_eth_device.parent), RT_FALSE);
  577. }
  578. rt_thread_mdelay(500);
  579. }
  580. }
  581. /* interrupt service routine */
  582. void ETH_IRQHandler(void)
  583. {
  584. rt_uint32_t status;
  585. status = ETH->DMASTS;
  586. /* Clear received IT */
  587. if ((status & ETH_DMA_INT_NIS) != (u32)RESET)
  588. ETH->DMASTS = (u32)ETH_DMA_INT_NIS;
  589. if ((status & ETH_DMA_INT_AIS) != (u32)RESET)
  590. ETH->DMASTS = (u32)ETH_DMA_INT_AIS;
  591. if ((status & ETH_DMA_INT_RO) != (u32)RESET)
  592. ETH->DMASTS = (u32)ETH_DMA_INT_RO;
  593. if ((status & ETH_DMA_INT_RBU) != (u32)RESET)
  594. ETH->DMASTS = (u32)ETH_DMA_INT_RBU;
  595. if (ETH_GetDMAITStatus(ETH_DMA_INT_R) == SET) /* packet receiption */
  596. {
  597. /* a frame has been received */
  598. eth_device_ready(&(at32_eth_device.parent));
  599. ETH_DMAClearITPendingBit(ETH_DMA_INT_R);
  600. }
  601. if (ETH_GetDMAITStatus(ETH_DMA_INT_T) == SET) /* packet transmission */
  602. {
  603. if (tx_is_waiting == RT_TRUE)
  604. {
  605. tx_is_waiting = RT_FALSE;
  606. rt_sem_release(&tx_wait);
  607. }
  608. ETH_DMAClearITPendingBit(ETH_DMA_INT_T);
  609. }
  610. }
  611. enum {
  612. PHY_LINK = (1 << 0),
  613. PHY_100M = (1 << 1),
  614. PHY_FULL_DUPLEX = (1 << 2),
  615. };
  616. /* Register the EMAC device */
  617. static int rt_hw_at32_eth_init(void)
  618. {
  619. rt_err_t state = RT_EOK;
  620. Reset_Phy();
  621. GPIO_Configuration();
  622. NVIC_Configuration();
  623. at32_eth_device.dev_addr[0] = 0x00;
  624. at32_eth_device.dev_addr[1] = 0x80;
  625. at32_eth_device.dev_addr[2] = 0xE1;
  626. at32_eth_device.dev_addr[3] = 0x94;
  627. at32_eth_device.dev_addr[4] = 0x87;
  628. at32_eth_device.dev_addr[5] = 0x55;
  629. at32_eth_device.parent.parent.init = rt_at32_eth_init;
  630. at32_eth_device.parent.parent.open = rt_at32_eth_open;
  631. at32_eth_device.parent.parent.close = rt_at32_eth_close;
  632. at32_eth_device.parent.parent.read = rt_at32_eth_read;
  633. at32_eth_device.parent.parent.write = rt_at32_eth_write;
  634. at32_eth_device.parent.parent.control = rt_at32_eth_control;
  635. at32_eth_device.parent.parent.user_data = RT_NULL;
  636. at32_eth_device.parent.eth_rx = rt_at32_eth_rx;
  637. at32_eth_device.parent.eth_tx = rt_at32_eth_tx;
  638. /* register eth device */
  639. state = eth_device_init(&(at32_eth_device.parent), "e0");
  640. if (RT_EOK == state)
  641. {
  642. LOG_D("emac device init success");
  643. state = rt_thread_init(&eth_link_thread, "eth_link_detect", eth_link_thread_entry, RT_NULL,
  644. &eth_link_stack[0], LINK_THREAD_STACK_SIZE, LINK_THREAD_PREORITY, 20);
  645. if (state == RT_EOK)
  646. {
  647. rt_thread_startup(&eth_link_thread);
  648. }
  649. }
  650. else
  651. {
  652. LOG_E("emac device init faild: %d", state);
  653. state = -RT_ERROR;
  654. }
  655. /* start phy monitor */
  656. return state;
  657. }
  658. INIT_DEVICE_EXPORT(rt_hw_at32_eth_init);