drv_eth.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. /*
  2. * Copyright (c) 2006-2024, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-09-09 WCH the first version
  9. */
  10. #include "board.h"
  11. #include <rtdevice.h>
  12. #ifdef BSP_USING_ETH
  13. #include <netif/ethernetif.h>
  14. #include "lwipopts.h"
  15. #include <drv_eth.h>
  16. #define LOG_TAG "drv.eth"
  17. #include <drv_log.h>
  18. #define MAX_ADDR_LEN 6
  19. #define ETH_DMARxDesc_FrameLengthShift 16
  20. #define define_O(a,b) \
  21. GPIO_InitStructure.GPIO_Pin = b;\
  22. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;\
  23. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;\
  24. GPIO_Init(a, &GPIO_InitStructure)
  25. #define define_I(a,b) \
  26. GPIO_InitStructure.GPIO_Pin = b;\
  27. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;\
  28. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;\
  29. GPIO_Init(a, &GPIO_InitStructure)
  30. /* globe variable */
  31. extern ETH_DMADESCTypeDef *DMATxDescToSet; //set tx Desc then send it
  32. extern ETH_DMADESCTypeDef *DMARxDescToGet; //current rx Desc
  33. /* rt-thread eth */
  34. struct rt_ch32_eth
  35. {
  36. /* inherit from ethernet device */
  37. struct eth_device parent;
  38. #ifndef PHY_USING_INTERRUPT_MODE
  39. rt_timer_t poll_link_timer;
  40. #endif
  41. /* interface address info, hw address */
  42. rt_uint8_t dev_addr[MAX_ADDR_LEN];
  43. /* ETH_Speed */
  44. uint32_t ETH_Speed;
  45. /* ETH_Duplex_Mode */
  46. uint32_t ETH_Mode;
  47. };
  48. static ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB];
  49. static rt_uint8_t Rx_Buff[ETH_RXBUFNB][ETH_MAX_PACKET_SIZE],Tx_Buff[ETH_TXBUFNB][ETH_MAX_PACKET_SIZE];
  50. struct rt_ch32_eth ch32v30x_eth_device;
  51. //#define ETH_RX_DUMP
  52. #if defined(ETH_RX_DUMP) || defined(ETH_TX_DUMP)
  53. #define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
  54. static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
  55. {
  56. unsigned char *buf = (unsigned char *)ptr;
  57. int i, j;
  58. for (i = 0; i < buflen; i += 16)
  59. {
  60. rt_kprintf("%08X: ", i);
  61. for (j = 0; j < 16; j++)
  62. if (i + j < buflen)
  63. rt_kprintf("%02X ", buf[i + j]);
  64. else
  65. rt_kprintf(" ");
  66. rt_kprintf(" ");
  67. for (j = 0; j < 16; j++)
  68. if (i + j < buflen)
  69. rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
  70. rt_kprintf("\r\n");
  71. }
  72. }
  73. #endif
  74. /* received data */
  75. FrameTypeDef ETH_RxPkt_ChainMode(void)
  76. {
  77. u32 framelength = 0;
  78. FrameTypeDef frame = {0,0,NULL};
  79. /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
  80. if((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) != (u32)RESET)
  81. {
  82. frame.length = ETH_ERROR;
  83. if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)
  84. {
  85. /* Clear RBUS ETHERNET DMA flag */
  86. ETH->DMASR = ETH_DMASR_RBUS;
  87. /* Resume DMA reception */
  88. ETH->DMARPDR = 0;
  89. }
  90. LOG_E("Error:ETH_DMARxDesc_OWN.\r\n");
  91. /* Return error: OWN bit set */
  92. return frame;
  93. }
  94. if(
  95. ((DMARxDescToGet->Status & ETH_DMARxDesc_ES) == (u32)RESET) &&
  96. ((DMARxDescToGet->Status & ETH_DMARxDesc_LS) != (u32)RESET) &&
  97. ((DMARxDescToGet->Status & ETH_DMARxDesc_FS) != (u32)RESET))
  98. {
  99. /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
  100. framelength = ((DMARxDescToGet->Status & ETH_DMARxDesc_FL) >> ETH_DMARxDesc_FrameLengthShift) - 4;
  101. /* Get the addrees of the actual buffer */
  102. frame.buffer = DMARxDescToGet->Buffer1Addr;
  103. }
  104. else
  105. {
  106. /* Return ERROR */
  107. framelength = ETH_ERROR;
  108. rt_kprintf("Error:recv error frame,status:0x%08x.\r\n",DMARxDescToGet->Status);
  109. }
  110. DMARxDescToGet->Status|=ETH_DMARxDesc_OWN;
  111. frame.length = framelength;
  112. frame.descriptor = DMARxDescToGet;
  113. /* Update the ETHERNET DMA global Rx descriptor with next Rx decriptor */
  114. /* Chained Mode */
  115. /* Selects the next DMA Rx descriptor list for next buffer to read */
  116. DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);
  117. /* Return Frame */
  118. return (frame);
  119. }
  120. /*******************************************************************************
  121. * Function Name : GETH_pin_init
  122. * Description : PHY RGMII interface GPIO initialization.
  123. * Input : None.
  124. * Return : None.
  125. *******************************************************************************/
  126. void GETH_pin_init(void)
  127. {
  128. GPIO_InitTypeDef GPIO_InitStructure;
  129. /* PB12/13 set AF_PP_OUT */
  130. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  131. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);
  132. GPIOB->CFGHR&=~(0xff<<16);
  133. GPIOB->CFGHR|= (0xbb<<16);
  134. GPIOB->CFGLR&=~(0xff<<4);
  135. define_O(GPIOA,GPIO_Pin_2);
  136. define_O(GPIOA,GPIO_Pin_3);
  137. define_O(GPIOA,GPIO_Pin_7);
  138. define_O(GPIOC,GPIO_Pin_4);
  139. define_O(GPIOC,GPIO_Pin_5);
  140. define_O(GPIOB,GPIO_Pin_0);
  141. define_I(GPIOC,GPIO_Pin_0);
  142. define_I(GPIOC,GPIO_Pin_1);
  143. define_I(GPIOC,GPIO_Pin_2);
  144. define_I(GPIOC,GPIO_Pin_3);
  145. define_I(GPIOA,GPIO_Pin_0);
  146. define_I(GPIOA,GPIO_Pin_1);
  147. define_I(GPIOB,GPIO_Pin_1);/* 125m in */
  148. }
  149. /*******************************************************************************
  150. * Function Name : GETH_pin_init
  151. * Description : PHY MII/RMII interface GPIO initialization.
  152. * Input : None.
  153. * Return : None.
  154. *******************************************************************************/
  155. void FETH_pin_init(void)
  156. {
  157. GPIO_InitTypeDef GPIO_InitStructure;
  158. #ifdef USE_RMII
  159. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);
  160. GPIO_ETH_MediaInterfaceConfig(GPIO_ETH_MediaInterface_RMII);
  161. define_O(GPIOA,GPIO_Pin_2);/* MDC */
  162. define_O(GPIOC,GPIO_Pin_1);/* MDIO */
  163. define_O(GPIOB,GPIO_Pin_11);//txen
  164. define_O(GPIOB,GPIO_Pin_12);//txd0
  165. define_O(GPIOB,GPIO_Pin_13);//txd1
  166. define_I(GPIOA,GPIO_Pin_1);/* PA1 REFCLK */
  167. define_I(GPIOA,GPIO_Pin_7);/* PA7 CRSDV */
  168. define_I(GPIOC,GPIO_Pin_4);/* RXD0 */
  169. define_I(GPIOC,GPIO_Pin_5);/* RXD1 */
  170. #else
  171. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);
  172. /* tx */
  173. define_O(GPIOA,GPIO_Pin_2);/* MDC */
  174. define_O(GPIOC,GPIO_Pin_1);/* MDIO */
  175. define_I(GPIOC,GPIO_Pin_3);//txclk
  176. define_O(GPIOB,GPIO_Pin_11);//txen
  177. define_O(GPIOB,GPIO_Pin_12);//txd0
  178. define_O(GPIOB,GPIO_Pin_13);//txd1
  179. define_O(GPIOC,GPIO_Pin_2); //txd2
  180. define_O(GPIOB,GPIO_Pin_8);//txd3
  181. /* tx */
  182. define_I(GPIOA,GPIO_Pin_1);/* PA1 RXC */
  183. define_I(GPIOA,GPIO_Pin_7);/* PA7 RXDV */
  184. define_I(GPIOC,GPIO_Pin_4);/* RXD0 */
  185. define_I(GPIOC,GPIO_Pin_5);/* RXD1 */
  186. define_I(GPIOB,GPIO_Pin_0);/* RXD2 */
  187. define_I(GPIOB,GPIO_Pin_1);/* RXD3 */
  188. define_I(GPIOB,GPIO_Pin_10);/* RXER */
  189. define_O(GPIOA,GPIO_Pin_0);/* PA0 */
  190. define_O(GPIOA,GPIO_Pin_3);/* PA3 */
  191. #endif
  192. }
  193. /*******************************************************************************
  194. * Function Name : ETH_Init
  195. * Description : ETH initialization.
  196. * Input : ETH_InitStruct:initialization struct.
  197. * PHYAddress:PHY address.
  198. * Return : Initialization status.
  199. *******************************************************************************/
  200. uint32_t ETH_Init(ETH_InitTypeDef* ETH_InitStruct, uint16_t PHYAddress)
  201. {
  202. uint32_t tmpreg = 0;
  203. uint16_t RegValue = 0;
  204. uint32_t tickstart=0;
  205. /* config phy */
  206. tmpreg = ETH->MACMIIAR;
  207. tmpreg &= MACMIIAR_CR_MASK;
  208. /* set SMI clock */
  209. tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div42;
  210. ETH->MACMIIAR = (uint32_t)tmpreg;
  211. /* reset phy */
  212. ETH_WritePHYRegister(PHYAddress, PHY_BCR, PHY_Reset);
  213. tickstart= rt_tick_get_millisecond();
  214. do{
  215. asm("nop"); /* waiting for finish */
  216. }while((rt_tick_get_millisecond()-tickstart)<1000);
  217. tickstart= rt_tick_get_millisecond();
  218. RegValue = 0;
  219. while( (RegValue&(PHY_Reset)) )
  220. {
  221. RegValue = ETH_ReadPHYRegister(PHYAddress, PHY_BCR);
  222. if((rt_tick_get_millisecond()-tickstart)>10000)
  223. {
  224. LOG_E("Error:Wait phy reset timeout!\r\n");
  225. while(1);
  226. }
  227. }
  228. /* waiting for link up */
  229. tickstart= rt_tick_get_millisecond();
  230. RegValue = 0;
  231. while((RegValue&(PHY_Linked_Status)) == 0)
  232. {
  233. RegValue = ETH_ReadPHYRegister(PHYAddress, PHY_BSR);
  234. if((rt_tick_get_millisecond()-tickstart)>10000)
  235. {
  236. LOG_E("Error:Wait phy linking timeout!\r\n");
  237. while(1);
  238. }
  239. }
  240. /* waiting for auto-negotiation */
  241. tickstart= rt_tick_get_millisecond();
  242. RegValue = 0;
  243. while((RegValue&PHY_AutoNego_Complete) == 0)
  244. {
  245. RegValue = ETH_ReadPHYRegister(PHYAddress, PHY_BSR);
  246. if((rt_tick_get_millisecond()-tickstart)>10000)
  247. {
  248. LOG_E("Error:Wait phy auto-negotiation complete timeout!\r\n");
  249. while(1);
  250. }
  251. }
  252. #ifdef USE10BASE_T
  253. RegValue = ETH_ReadPHYRegister(PHYAddress, PHY_BMCR);
  254. LOG_D("PHY_BMCR:%d,value:%04x.\n",PHY_BMCR,RegValue);
  255. if((RegValue & (1<<8)) != (uint32_t)RESET)
  256. {
  257. ETH_InitStruct->ETH_Mode = ETH_Mode_FullDuplex;
  258. ch32v30x_eth_device.ETH_Mode=ETH_Mode_FullDuplex;
  259. LOG_D("Full-Duplex.\n");
  260. }
  261. else
  262. {
  263. ETH_InitStruct->ETH_Mode = ETH_Mode_HalfDuplex;
  264. ch32v30x_eth_device.ETH_Mode=ETH_Mode_HalfDuplex;
  265. LOG_D("Half-Duplex.\n");
  266. }
  267. if(RegValue & (1<<13))
  268. {
  269. ETH_InitStruct->ETH_Speed = ETH_Speed_100M;
  270. ch32v30x_eth_device.ETH_Speed=ETH_Speed_100M;
  271. /* send link up. */
  272. eth_device_linkchange(&ch32v30x_eth_device.parent, RT_TRUE);
  273. LOG_D("Link speed:100M.\n");
  274. }
  275. else
  276. {
  277. ETH_InitStruct->ETH_Speed = ETH_Speed_10M;
  278. ch32v30x_eth_device.ETH_Speed=ETH_Speed_10M;
  279. /* send link up. */
  280. eth_device_linkchange(&ch32v30x_eth_device.parent, RT_TRUE);
  281. LOG_D("Link speed:10M.\n");
  282. }
  283. #endif
  284. #ifdef USE_FAST_MAC
  285. /* 100M MAC,RMII */
  286. RegValue = ETH_ReadPHYRegister(PHYAddress, PHY_BMCR);
  287. LOG_D("PHY_BMCR:%d,value:%04x.\n",PHY_BMCR,RegValue);
  288. if((RegValue & (1<<8)) != (uint32_t)RESET)
  289. {
  290. ETH_InitStruct->ETH_Mode = ETH_Mode_FullDuplex;
  291. ch32v30x_eth_device.ETH_Mode = ETH_Mode_FullDuplex;
  292. LOG_D("Full-Duplex.\n");
  293. }
  294. else
  295. {
  296. ETH_InitStruct->ETH_Mode = ETH_Mode_HalfDuplex;
  297. ch32v30x_eth_device.ETH_Mode = ETH_Mode_HalfDuplex;
  298. LOG_D("Half-Duplex.\n");
  299. }
  300. if(RegValue & (1<<13))
  301. {
  302. ETH_InitStruct->ETH_Speed = ETH_Speed_100M;
  303. ch32v30x_eth_device.ETH_Speed=ETH_Speed_100M;
  304. /* send link up. */
  305. eth_device_linkchange(&ch32v30x_eth_device.parent, RT_TRUE);
  306. LOG_D("Link speed:100M.\n");
  307. }
  308. else
  309. {
  310. ETH_InitStruct->ETH_Speed = ETH_Speed_10M;
  311. ch32v30x_eth_device.ETH_Speed=ETH_Speed_10M;
  312. /* send link up. */
  313. eth_device_linkchange(&ch32v30x_eth_device.parent, RT_TRUE);
  314. LOG_D("Link speed:10M.\n");
  315. }
  316. #endif
  317. #ifdef USE_GIGA_MAC
  318. /* GMAC,RGMI */
  319. ETH_WritePHYRegister(PHYAddress, 31,0x0a43 );
  320. RegValue = ETH_ReadPHYRegister(PHYAddress, 26);
  321. if( RegValue & 0x0008 )
  322. {
  323. ETH_InitStruct->ETH_Mode = ETH_Mode_FullDuplex;
  324. ch32v30x_eth_device.ETH_Mode = ETH_Mode_FullDuplex;
  325. LOG_D("full duplex.\n");
  326. }
  327. else
  328. {
  329. ETH_InitStruct->ETH_Mode = ETH_Mode_HalfDuplex;
  330. ch32v30x_eth_device.ETH_Mode = ETH_Mode_HalfDuplex;
  331. LOG_D("half duplex!\n");
  332. }
  333. if(( RegValue & 0x0030 ) == 0x0000)
  334. {
  335. ETH_InitStruct->ETH_Speed = ETH_Speed_10M;
  336. ch32v30x_eth_device.ETH_Speed= ETH_Speed_10M;
  337. eth_device_linkchange(&ch32v30x_eth_device.parent, RT_TRUE);
  338. LOG_D("Link speed:10Mbps.\n");
  339. }
  340. else if(( RegValue & 0x0030 ) == 0x0010)
  341. {
  342. ETH_InitStruct->ETH_Speed = ETH_Speed_100M;
  343. ch32v30x_eth_device.ETH_Speed= ETH_Speed_100M;
  344. eth_device_linkchange(&ch32v30x_eth_device.parent, RT_TRUE);
  345. LOG_D("Link speed:100Mbps.\n");
  346. }
  347. else if(( RegValue & 0x0030 ) == 0x0020)
  348. {
  349. ETH_InitStruct->ETH_Speed = ETH_Speed_1000M;
  350. ch32v30x_eth_device.ETH_Speed= ETH_Speed_1000M;
  351. eth_device_linkchange(&ch32v30x_eth_device.parent, RT_TRUE);
  352. LOG_D("Link speed:1000Mbps.\n");
  353. }
  354. #endif
  355. tickstart= rt_tick_get_millisecond();
  356. do{
  357. asm("nop");
  358. }while((rt_tick_get_millisecond()-tickstart)<1000);
  359. /* MAC config */
  360. /* if use RGMII,should config RGMII clock delay register */
  361. tmpreg = ETH->MACCR;
  362. tmpreg &= MACCR_CLEAR_MASK;
  363. tmpreg |= (uint32_t)(ETH_InitStruct->ETH_Watchdog |
  364. ETH_InitStruct->ETH_Jabber |
  365. ETH_InitStruct->ETH_InterFrameGap |
  366. ETH_InitStruct->ETH_CarrierSense |
  367. ETH_InitStruct->ETH_Speed |
  368. ETH_InitStruct->ETH_ReceiveOwn |
  369. ETH_InitStruct->ETH_LoopbackMode |
  370. ETH_InitStruct->ETH_Mode |
  371. ETH_InitStruct->ETH_ChecksumOffload |
  372. ETH_InitStruct->ETH_RetryTransmission |
  373. ETH_InitStruct->ETH_AutomaticPadCRCStrip |
  374. ETH_InitStruct->ETH_BackOffLimit |
  375. ETH_InitStruct->ETH_DeferralCheck);
  376. ETH->MACCR = (uint32_t)tmpreg;
  377. #ifdef USE10BASE_T
  378. /* enable internal pull up resistance,50Ω */
  379. ETH->MACCR|=ETH_Internal_Pull_Up_Res_Enable;
  380. #endif
  381. ETH->MACFFR = (uint32_t)(ETH_InitStruct->ETH_ReceiveAll |
  382. ETH_InitStruct->ETH_SourceAddrFilter |
  383. ETH_InitStruct->ETH_PassControlFrames |
  384. ETH_InitStruct->ETH_BroadcastFramesReception |
  385. ETH_InitStruct->ETH_DestinationAddrFilter |
  386. ETH_InitStruct->ETH_PromiscuousMode |
  387. ETH_InitStruct->ETH_MulticastFramesFilter |
  388. ETH_InitStruct->ETH_UnicastFramesFilter);
  389. /* Write to ETHERNET MACHTHR */
  390. ETH->MACHTHR = (uint32_t)ETH_InitStruct->ETH_HashTableHigh;
  391. /* Write to ETHERNET MACHTLR */
  392. ETH->MACHTLR = (uint32_t)ETH_InitStruct->ETH_HashTableLow;
  393. /* Get the ETHERNET MACFCR value */
  394. tmpreg = ETH->MACFCR;
  395. /* Clear xx bits */
  396. tmpreg &= MACFCR_CLEAR_MASK;
  397. tmpreg |= (uint32_t)((ETH_InitStruct->ETH_PauseTime << 16) |
  398. ETH_InitStruct->ETH_ZeroQuantaPause |
  399. ETH_InitStruct->ETH_PauseLowThreshold |
  400. ETH_InitStruct->ETH_UnicastPauseFrameDetect |
  401. ETH_InitStruct->ETH_ReceiveFlowControl |
  402. ETH_InitStruct->ETH_TransmitFlowControl);
  403. ETH->MACFCR = (uint32_t)tmpreg;
  404. ETH->MACVLANTR = (uint32_t)(ETH_InitStruct->ETH_VLANTagComparison |
  405. ETH_InitStruct->ETH_VLANTagIdentifier);
  406. tmpreg = ETH->DMAOMR;
  407. /* Clear xx bits */
  408. tmpreg &= DMAOMR_CLEAR_MASK;
  409. tmpreg |= (uint32_t)(ETH_InitStruct->ETH_DropTCPIPChecksumErrorFrame |
  410. ETH_InitStruct->ETH_ReceiveStoreForward |
  411. ETH_InitStruct->ETH_FlushReceivedFrame |
  412. ETH_InitStruct->ETH_TransmitStoreForward |
  413. ETH_InitStruct->ETH_TransmitThresholdControl |
  414. ETH_InitStruct->ETH_ForwardErrorFrames |
  415. ETH_InitStruct->ETH_ForwardUndersizedGoodFrames |
  416. ETH_InitStruct->ETH_ReceiveThresholdControl |
  417. ETH_InitStruct->ETH_SecondFrameOperate);
  418. ETH->DMAOMR = (uint32_t)tmpreg;
  419. ETH->DMABMR = (uint32_t)(ETH_InitStruct->ETH_AddressAlignedBeats |
  420. ETH_InitStruct->ETH_FixedBurst |
  421. ETH_InitStruct->ETH_RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
  422. ETH_InitStruct->ETH_TxDMABurstLength |
  423. (ETH_InitStruct->ETH_DescriptorSkipLength << 2) |
  424. ETH_InitStruct->ETH_DMAArbitration |
  425. ETH_DMABMR_USP);
  426. return ETH_SUCCESS;
  427. }
  428. /* eth initialization function */
  429. static rt_err_t rt_ch32_eth_init(rt_device_t dev)
  430. {
  431. ETH_InitTypeDef ETH_InitStructure={0};
  432. RCC_PLL3Cmd(DISABLE);
  433. RCC_PREDIV2Config(RCC_PREDIV2_Div2);
  434. RCC_PLL3Config(RCC_PLL3Mul_15);
  435. RCC_PLL3Cmd(ENABLE);
  436. while(RESET == RCC_GetFlagStatus(RCC_FLAG_PLL3RDY));
  437. LOG_D("PLL3 Init Finish\r\n");
  438. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ETH_MAC|RCC_AHBPeriph_ETH_MAC_Tx|RCC_AHBPeriph_ETH_MAC_Rx,ENABLE);
  439. #ifdef USE10BASE_T
  440. /* Enable internal 10BASE-T PHY*/
  441. EXTEN->EXTEN_CTR |=EXTEN_ETH_10M_EN;
  442. #endif
  443. #ifdef USE_GIGA_MAC
  444. /* Enable 1G MAC*/
  445. EXTEN->EXTEN_CTR |= EXTEN_ETH_RGMII_SEL;
  446. /* mac clock use external 125MHz,input from PB1 */
  447. RCC_ETH1GCLKConfig(RCC_ETH1GCLKSource_PB1_IN);
  448. RCC_ETH1G_125Mcmd(ENABLE);
  449. /* Enable RGMII GPIO */
  450. GETH_pin_init();
  451. #endif
  452. #ifdef USE_FAST_MAC
  453. /* Enable MII or RMII GPIO */
  454. FETH_pin_init();
  455. #endif
  456. /* Reset ETHERNET on AHB Bus */
  457. ETH_DeInit();
  458. /* Software reset */
  459. ETH_SoftwareReset();
  460. /* Wait for software reset */
  461. while(ETH->DMABMR & ETH_DMABMR_SR);
  462. LOG_D("ETH RST Finish\r\n");
  463. ETH_StructInit(&ETH_InitStructure);
  464. ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;
  465. ETH_InitStructure.ETH_Speed = ETH_Speed_1000M;
  466. ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable ;
  467. ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable;
  468. ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable;
  469. ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;
  470. ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Enable;
  471. ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable;
  472. ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Enable;
  473. ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;
  474. ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;
  475. #ifdef CHECKSUM_BY_HARDWARE
  476. ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable;
  477. #endif
  478. /*------------------------ DMA -----------------------------------*/
  479. /* When we use the Checksum offload feature, we need to enable the Store and Forward mode:
  480. the store and forward guarantee that a whole frame is stored in the FIFO, so the MAC can insert/verify the checksum,
  481. if the checksum is OK the DMA can handle the frame otherwise the frame is dropped */
  482. ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Enable;
  483. ETH_InitStructure.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable;
  484. ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable;
  485. ETH_InitStructure.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Enable;
  486. ETH_InitStructure.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Enable;
  487. ETH_InitStructure.ETH_SecondFrameOperate = ETH_SecondFrameOperate_Disable;
  488. ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable;
  489. ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable;
  490. ETH_InitStructure.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat;
  491. ETH_InitStructure.ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat;
  492. ETH_InitStructure.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1;
  493. /* Configure Ethernet */
  494. ETH_Init(&ETH_InitStructure, PHY_ADDRESS);
  495. /* Enable the Ethernet Rx Interrupt */
  496. ETH_DMAITConfig(ETH_DMA_IT_NIS
  497. | ETH_DMA_IT_R
  498. | ETH_DMA_IT_T
  499. ,ENABLE);
  500. NVIC_SetPriority(ETH_IRQn,1<<4);
  501. NVIC_EnableIRQ(ETH_IRQn);
  502. ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
  503. ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
  504. #ifdef USE_GIGA_MAC
  505. RGMII_TXC_Delay(0,2);
  506. #endif
  507. ETH_Start();
  508. return RT_EOK;
  509. }
  510. static rt_err_t rt_ch32_eth_open(rt_device_t dev, rt_uint16_t oflag)
  511. {
  512. LOG_D("eth open\r\n");
  513. return RT_EOK;
  514. }
  515. static rt_err_t rt_ch32_eth_close(rt_device_t dev)
  516. {
  517. LOG_D("eth close\r\n");
  518. return RT_EOK;
  519. }
  520. static rt_ssize_t rt_ch32_eth_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  521. {
  522. LOG_D("eth read\r\n");
  523. rt_set_errno(-RT_ENOSYS);
  524. return 0;
  525. }
  526. static rt_ssize_t rt_ch32_eth_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  527. {
  528. LOG_D("eth write\r\n");
  529. rt_set_errno(-RT_ENOSYS);
  530. return 0;
  531. }
  532. static rt_err_t rt_ch32_eth_control(rt_device_t dev, int cmd, void *args)
  533. {
  534. switch (cmd)
  535. {
  536. case NIOCTL_GADDR:
  537. /* get mac address */
  538. if (args) rt_memcpy(args, ch32v30x_eth_device.dev_addr, 6);
  539. else return -RT_ERROR;
  540. break;
  541. default :
  542. break;
  543. }
  544. return RT_EOK;
  545. }
  546. rt_err_t rt_ch32_eth_tx(rt_device_t dev, struct pbuf *p)
  547. {
  548. rt_err_t ret = RT_ERROR;
  549. struct pbuf *q;
  550. uint8_t *buffer = (uint8_t *)(DMATxDescToSet->Buffer1Addr);
  551. uint8_t *pdata;
  552. uint32_t framelength = 0,len=0;
  553. /* copy frame from pbufs to driver buffers */
  554. for (q = p; q != NULL; q = q->next)
  555. {
  556. /* Is this buffer available? If not, goto error */
  557. if ((DMATxDescToSet->Status & ETH_DMATxDesc_OWN) != (uint32_t)RESET)
  558. {
  559. LOG_E("buffer not valid\r\n");
  560. ret = ERR_USE;
  561. goto Tx_error;
  562. }
  563. pdata = q->payload;
  564. len = q->len;
  565. framelength += len;
  566. rt_memcpy(buffer,pdata,len);
  567. buffer += len;
  568. }
  569. #ifdef ETH_TX_DUMP
  570. dump_hex(buffer, p->tot_len);
  571. #endif
  572. DMATxDescToSet->ControlBufferSize = (framelength & ETH_DMATxDesc_TBS1);
  573. DMATxDescToSet->Status |= ETH_DMATxDesc_LS | ETH_DMATxDesc_FS;
  574. DMATxDescToSet->Status |= ETH_DMATxDesc_OWN;
  575. ret = ERR_OK;
  576. Tx_error:
  577. /* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */
  578. if ((ETH->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET)
  579. {
  580. /* Clear TUS ETHERNET DMA flag */
  581. ETH->DMASR = ETH_DMASR_TUS;
  582. /* Resume DMA transmission*/
  583. ETH->DMATPDR = 0;
  584. }
  585. DMATxDescToSet = (ETH_DMADESCTypeDef*) (DMATxDescToSet->Buffer2NextDescAddr);
  586. return ret;
  587. }
  588. volatile FrameTypeDef frame;
  589. struct pbuf *rt_ch32_eth_rx(rt_device_t dev)
  590. {
  591. struct pbuf *p = NULL;
  592. struct pbuf *q = NULL;
  593. uint16_t len = 0;
  594. uint8_t *buffer;
  595. uint8_t *pdata;
  596. if(!frame.length)
  597. {
  598. return NULL;
  599. }
  600. len=frame.length;
  601. frame.length=0;
  602. buffer=(uint8_t *)frame.buffer;
  603. if (len > 0)
  604. {
  605. /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */
  606. p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
  607. }
  608. #ifdef ETH_RX_DUMP
  609. dump_hex(buffer, p->tot_len);
  610. #endif
  611. if (p != NULL)
  612. {
  613. for (q = p; q != NULL; q = q->next)
  614. {
  615. pdata = q->payload;
  616. rt_memcpy(pdata,buffer,q->len);
  617. pdata += (q->len);
  618. buffer += (q->len);
  619. }
  620. }
  621. else
  622. {
  623. LOG_E("p=null\r\n");
  624. }
  625. return p;
  626. }
  627. /* interrupt service routine */
  628. void ETH_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
  629. void ETH_IRQHandler(void)
  630. {
  631. GET_INT_SP();
  632. /* enter interrupt */
  633. rt_err_t result;
  634. rt_interrupt_enter();
  635. if(ETH->DMASR&ETH_DMA_IT_R)
  636. {
  637. ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
  638. frame = ETH_RxPkt_ChainMode();
  639. result = eth_device_ready(&(ch32v30x_eth_device.parent));
  640. if (result != RT_EOK)
  641. rt_kprintf("RxCpltCallback err = %d\r\n", result);
  642. }
  643. if(ETH->DMASR&ETH_DMA_IT_T)
  644. {
  645. ETH_DMAClearITPendingBit(ETH_DMA_IT_T);
  646. }
  647. ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);
  648. /* leave interrupt */
  649. rt_interrupt_leave();
  650. FREE_INT_SP();
  651. }
  652. /* Register the EMAC device */
  653. static int rt_hw_ch32_eth_init(void)
  654. {
  655. rt_err_t state = RT_EOK;
  656. /* 84-c2-e4 WCH. */
  657. ch32v30x_eth_device.dev_addr[0] = 0x84;
  658. ch32v30x_eth_device.dev_addr[1] = 0xc2;
  659. ch32v30x_eth_device.dev_addr[2] = 0xe4;
  660. /* generate MAC (only for test). */
  661. ch32v30x_eth_device.dev_addr[3] = 0x1;
  662. ch32v30x_eth_device.dev_addr[4] = 0x2;
  663. ch32v30x_eth_device.dev_addr[5] = 0x3;
  664. ch32v30x_eth_device.parent.parent.init = rt_ch32_eth_init;
  665. ch32v30x_eth_device.parent.parent.open = rt_ch32_eth_open;
  666. ch32v30x_eth_device.parent.parent.close = rt_ch32_eth_close;
  667. ch32v30x_eth_device.parent.parent.read = rt_ch32_eth_read;
  668. ch32v30x_eth_device.parent.parent.write = rt_ch32_eth_write;
  669. ch32v30x_eth_device.parent.parent.control = rt_ch32_eth_control;
  670. ch32v30x_eth_device.parent.parent.user_data = RT_NULL;
  671. ch32v30x_eth_device.parent.eth_rx = rt_ch32_eth_rx;
  672. ch32v30x_eth_device.parent.eth_tx = rt_ch32_eth_tx;
  673. /* register eth device */
  674. state = eth_device_init(&(ch32v30x_eth_device.parent), "e0");
  675. if (RT_EOK == state)
  676. {
  677. LOG_D("emac device init success");
  678. }
  679. else
  680. {
  681. LOG_E("emac device init faild: %d\r\n", state);
  682. state = -RT_ERROR;
  683. }
  684. return state;
  685. }
  686. INIT_DEVICE_EXPORT(rt_hw_ch32_eth_init);
  687. #endif /* BSP_USING_ETH */