stm32f2_eth.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. /*
  2. * STM32 Eth Driver for RT-Thread
  3. * Change Logs:
  4. * Date Author Notes
  5. * 2009-10-05 Bernard eth interface driver for STM32F107 CL
  6. */
  7. #include <rtthread.h>
  8. #include <netif/ethernetif.h>
  9. #include "lwipopts.h"
  10. #include "stm32f2x7_eth.h"
  11. #include "stm32f2x7_eth_conf.h"
  12. #define STM32_ETH_DEBUG 0
  13. #define CHECKSUM_BY_HARDWARE
  14. /* MII and RMII mode selection, for STM322xG-EVAL Board(MB786) RevB ***********/
  15. //#define MII_MODE
  16. #define RMII_MODE // In this case the System clock frequency is configured
  17. // to 100 MHz, for more details refer to system_stm32f2xx.c
  18. #define DP83848_PHY_ADDRESS 0x01 /* Relative to STM322xG-EVAL Board */
  19. #define netifGUARD_BLOCK_TIME 250
  20. /* Ethernet Rx & Tx DMA Descriptors */
  21. extern ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB];
  22. /* Ethernet Receive buffers */
  23. extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE];
  24. /* Ethernet Transmit buffers */
  25. extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE];
  26. /* Global pointers to track current transmit and receive descriptors */
  27. extern ETH_DMADESCTypeDef *DMATxDescToSet;
  28. extern ETH_DMADESCTypeDef *DMARxDescToGet;
  29. /* Global pointer for last received frame infos */
  30. extern ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos;
  31. #define MAX_ADDR_LEN 6
  32. struct rt_stm32_eth
  33. {
  34. /* inherit from ethernet device */
  35. struct eth_device parent;
  36. /* interface address info. */
  37. rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */
  38. };
  39. static struct rt_stm32_eth stm32_eth_device;
  40. static struct rt_semaphore tx_wait;
  41. static rt_bool_t tx_is_waiting = RT_FALSE;
  42. static void ETH_MACDMA_Config(void);
  43. static struct rt_semaphore tx_wait;
  44. /* interrupt service routine */
  45. void ETH_IRQHandler(void)
  46. {
  47. rt_uint32_t status;
  48. status = ETH->DMASR;
  49. /* Frame received */
  50. if ( ETH_GetDMAFlagStatus(ETH_DMA_FLAG_R) == SET)
  51. {
  52. rt_err_t result;
  53. //rt_kprintf("Frame comming\n");
  54. /* Clear the interrupt flags. */
  55. /* Clear the Eth DMA Rx IT pending bits */
  56. ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
  57. /* a frame has been received */
  58. result = eth_device_ready(&(stm32_eth_device.parent));
  59. if( result != RT_EOK ) rt_kprintf("RX err =%d\n", result );
  60. //RT_ASSERT(result == RT_EOK);
  61. }
  62. if (ETH_GetDMAITStatus(ETH_DMA_IT_T) == SET) /* packet transmission */
  63. {
  64. ETH_DMAClearITPendingBit(ETH_DMA_IT_T);
  65. }
  66. ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);
  67. //
  68. }
  69. /* RT-Thread Device Interface */
  70. /* initialize the interface */
  71. static rt_err_t rt_stm32_eth_init(rt_device_t dev)
  72. {
  73. int i;
  74. /* MAC address configuration */
  75. ETH_MACAddressConfig(ETH_MAC_Address0, (u8*)&stm32_eth_device.dev_addr[0]);
  76. /* Initialize Tx Descriptors list: Chain Mode */
  77. ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
  78. /* Initialize Rx Descriptors list: Chain Mode */
  79. ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
  80. /* Enable Ethernet Rx interrrupt */
  81. {
  82. for(i=0; i<ETH_RXBUFNB; i++)
  83. {
  84. ETH_DMARxDescReceiveITConfig(&DMARxDscrTab[i], ENABLE);
  85. }
  86. }
  87. #ifdef CHECKSUM_BY_HARDWARE
  88. /* Enable the checksum insertion for the Tx frames */
  89. {
  90. for(i=0; i<ETH_TXBUFNB; i++)
  91. {
  92. ETH_DMATxDescChecksumInsertionConfig(&DMATxDscrTab[i], ETH_DMATxDesc_ChecksumTCPUDPICMPFull);
  93. }
  94. }
  95. #endif
  96. {
  97. uint16_t tmp, i=10000;
  98. tmp = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_CR);
  99. ETH_WritePHYRegister(DP83848_PHY_ADDRESS, PHY_CDCTRL1, BIST_CONT_MODE );
  100. ETH_WritePHYRegister(DP83848_PHY_ADDRESS, PHY_CR, tmp | BIST_START );//BIST_START
  101. while(i--);
  102. //tmp = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_CR);
  103. if( ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_CR) & BIST_STATUS == BIST_STATUS )
  104. {
  105. rt_kprintf("BIST pass\n");
  106. }
  107. else
  108. {
  109. uint16_t ctrl;
  110. ctrl = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_CDCTRL1);
  111. rt_kprintf("BIST faild count =%d\n", BIST_ERROR_COUNT(ctrl) );
  112. }
  113. tmp &= ~BIST_START; //Stop BIST
  114. ETH_WritePHYRegister(DP83848_PHY_ADDRESS, PHY_CR, tmp);
  115. }
  116. /* Enable MAC and DMA transmission and reception */
  117. ETH_Start();
  118. //rt_kprintf("DMASR = 0x%X\n", ETH->DMASR );
  119. // rt_kprintf("ETH Init\n");
  120. return RT_EOK;
  121. }
  122. static rt_err_t rt_stm32_eth_open(rt_device_t dev, rt_uint16_t oflag)
  123. {
  124. return RT_EOK;
  125. }
  126. static rt_err_t rt_stm32_eth_close(rt_device_t dev)
  127. {
  128. return RT_EOK;
  129. }
  130. static rt_size_t rt_stm32_eth_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  131. {
  132. rt_set_errno(-RT_ENOSYS);
  133. return 0;
  134. }
  135. static rt_size_t rt_stm32_eth_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  136. {
  137. rt_set_errno(-RT_ENOSYS);
  138. return 0;
  139. }
  140. static rt_err_t rt_stm32_eth_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  141. {
  142. switch(cmd)
  143. {
  144. case NIOCTL_GADDR:
  145. /* get mac address */
  146. if(args) rt_memcpy(args, stm32_eth_device.dev_addr, 6);
  147. else return -RT_ERROR;
  148. break;
  149. default :
  150. break;
  151. }
  152. return RT_EOK;
  153. }
  154. void show_frame(struct pbuf *q)
  155. {
  156. int i = 0;
  157. int j = 0;
  158. char *ptr = q->payload;
  159. for( i = 0; i < q->len; i++ )
  160. rt_kprintf("0x%02X ", *(ptr++));
  161. rt_kprintf("\n");
  162. }
  163. /* ethernet device interface */
  164. /* transmit packet. */
  165. rt_err_t rt_stm32_eth_tx( rt_device_t dev, struct pbuf* p)
  166. {
  167. rt_err_t ret;
  168. struct pbuf *q;
  169. uint32_t l = 0;
  170. u8 *buffer ;
  171. if (( ret = rt_sem_take(&tx_wait, netifGUARD_BLOCK_TIME) ) == RT_EOK)
  172. {
  173. buffer = (u8 *)(DMATxDescToSet->Buffer1Addr);
  174. for(q = p; q != NULL; q = q->next)
  175. {
  176. //show_frame(q);
  177. rt_memcpy((u8_t*)&buffer[l], q->payload, q->len);
  178. l = l + q->len;
  179. }
  180. if( ETH_Prepare_Transmit_Descriptors(l) == ETH_ERROR )
  181. rt_kprintf("Tx Error\n");
  182. //rt_sem_release(xTxSemaphore);
  183. rt_sem_release(&tx_wait);
  184. //rt_kprintf("Tx packet, len = %d\n", l);
  185. }
  186. else
  187. {
  188. rt_kprintf("Tx Timeout\n");
  189. return ret;
  190. }
  191. /* Return SUCCESS */
  192. return RT_EOK;
  193. }
  194. /* reception packet. */
  195. struct pbuf *rt_stm32_eth_rx(rt_device_t dev)
  196. {
  197. struct pbuf *p, *q;
  198. u16_t len;
  199. uint32_t l=0,i =0;
  200. FrameTypeDef frame;
  201. static framecnt = 1;
  202. u8 *buffer;
  203. __IO ETH_DMADESCTypeDef *DMARxNextDesc;
  204. p = RT_NULL;
  205. // rt_kprintf("ETH rx\n");
  206. /* Get received frame */
  207. frame = ETH_Get_Received_Frame_interrupt();
  208. if( frame.length > 0 )
  209. {
  210. /* check that frame has no error */
  211. if ((frame.descriptor->Status & ETH_DMARxDesc_ES) == (uint32_t)RESET)
  212. {
  213. //rt_kprintf("Get a frame %d buf = 0x%X, len= %d\n", framecnt++, frame.buffer, frame.length);
  214. /* Obtain the size of the packet and put it into the "len" variable. */
  215. len = frame.length;
  216. buffer = (u8 *)frame.buffer;
  217. /* We allocate a pbuf chain of pbufs from the pool. */
  218. p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
  219. //p = pbuf_alloc(PBUF_LINK, len, PBUF_RAM);
  220. /* Copy received frame from ethernet driver buffer to stack buffer */
  221. if (p != NULL)
  222. {
  223. for (q = p; q != NULL; q = q->next)
  224. {
  225. rt_memcpy((u8_t*)q->payload, (u8_t*)&buffer[l], q->len);
  226. l = l + q->len;
  227. }
  228. }
  229. }
  230. /* Release descriptors to DMA */
  231. /* Check if received frame with multiple DMA buffer segments */
  232. if (DMA_RX_FRAME_infos->Seg_Count > 1)
  233. {
  234. DMARxNextDesc = DMA_RX_FRAME_infos->FS_Rx_Desc;
  235. }
  236. else
  237. {
  238. DMARxNextDesc = frame.descriptor;
  239. }
  240. /* Set Own bit in Rx descriptors: gives the buffers back to DMA */
  241. for (i=0; i<DMA_RX_FRAME_infos->Seg_Count; i++)
  242. {
  243. DMARxNextDesc->Status = ETH_DMARxDesc_OWN;
  244. DMARxNextDesc = (ETH_DMADESCTypeDef *)(DMARxNextDesc->Buffer2NextDescAddr);
  245. }
  246. /* Clear Segment_Count */
  247. DMA_RX_FRAME_infos->Seg_Count =0;
  248. /* When Rx Buffer unavailable flag is set: clear it and resume reception */
  249. if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)
  250. {
  251. /* Clear RBUS ETHERNET DMA flag */
  252. ETH->DMASR = ETH_DMASR_RBUS;
  253. /* Resume DMA reception */
  254. ETH->DMARPDR = 0;
  255. }
  256. }
  257. return p;
  258. }
  259. static void NVIC_Configuration(void)
  260. {
  261. NVIC_InitTypeDef NVIC_InitStructure;
  262. /* 2 bit for pre-emption priority, 2 bits for subpriority */
  263. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  264. /* Enable the Ethernet global Interrupt */
  265. NVIC_InitStructure.NVIC_IRQChannel = ETH_IRQn;
  266. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  267. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  268. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  269. NVIC_Init(&NVIC_InitStructure);
  270. }
  271. /*
  272. * GPIO Configuration for ETH
  273. */
  274. static void GPIO_Configuration(void)
  275. {
  276. GPIO_InitTypeDef GPIO_InitStructure;
  277. /* Enable GPIOs clocks */
  278. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB |
  279. RCC_AHB1Periph_GPIOC
  280. , ENABLE);
  281. /* Enable SYSCFG clock */
  282. RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  283. /* Configure MCO (PA8) */
  284. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  285. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  286. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  287. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  288. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  289. //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  290. GPIO_Init(GPIOA, &GPIO_InitStructure);
  291. GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_MCO );
  292. #ifdef MII_MODE
  293. /* Output PLL clock divided by 2 (25MHz) on MCO pin (PA8) to clock the PHY */
  294. RCC_MCO1Config(RCC_MCO1Source_HSE, RCC_MCO1Div_1);
  295. SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_MII);
  296. #elif defined RMII_MODE
  297. /* Output PLL clock divided by 2 (50MHz) on MCO pin (PA8) to clock the PHY */
  298. //RCC_MCO1Config(RCC_MCO1Source_PLLCLK, RCC_MCO1Div_2);
  299. SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII);
  300. #endif
  301. /* Ethernet pins configuration ************************************************/
  302. /*
  303. ETH_MDIO -------------------------> PA2
  304. ETH_MDC --------------------------> PC1
  305. ETH_MII_RX_CLK/ETH_RMII_REF_CLK---> PA1
  306. ETH_MII_RX_DV/ETH_RMII_CRS_DV ----> PA7
  307. ETH_MII_RXD0/ETH_RMII_RXD0 -------> PC4
  308. ETH_MII_RXD1/ETH_RMII_RXD1 -------> PC5
  309. ETH_MII_TX_EN/ETH_RMII_TX_EN -----> PB11
  310. ETH_MII_TXD0/ETH_RMII_TXD0 -------> PB12
  311. ETH_MII_TXD1/ETH_RMII_TXD1 -------> PB13
  312. **** Just for MII Mode ****
  313. ETH_MII_CRS ----------------------> PA0
  314. ETH_MII_COL ----------------------> PA3
  315. ETH_MII_TX_CLK -------------------> PC3
  316. ETH_MII_RX_ER --------------------> PB10
  317. ETH_MII_RXD2 ---------------------> PB0
  318. ETH_MII_RXD3 ---------------------> PB1
  319. ETH_MII_TXD2 ---------------------> PC2
  320. ETH_MII_TXD3 ---------------------> PB8
  321. */
  322. /* Configure PC1, PC4 and PC5 */
  323. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 |GPIO_Pin_4 | GPIO_Pin_5;
  324. GPIO_Init(GPIOC, &GPIO_InitStructure);
  325. GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_ETH);
  326. GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_ETH);
  327. GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_ETH);
  328. /* Configure PB11, PB12 and PB13 */
  329. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
  330. GPIO_Init(GPIOB, &GPIO_InitStructure);
  331. GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_ETH);
  332. GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_ETH);
  333. GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_ETH);
  334. /* Configure PA1, PA2 and PA7 */
  335. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2 | GPIO_Pin_7;
  336. GPIO_Init(GPIOA, &GPIO_InitStructure);
  337. GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_ETH);
  338. GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_ETH);
  339. GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_ETH);
  340. #ifdef MII_MODE
  341. /* Configure PC2, PC3 */
  342. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 |GPIO_Pin_3;
  343. GPIO_Init(GPIOC, &GPIO_InitStructure);
  344. GPIO_PinAFConfig(GPIOC, GPIO_PinSource2, GPIO_AF_ETH);
  345. GPIO_PinAFConfig(GPIOC, GPIO_PinSource3, GPIO_AF_ETH);
  346. /* Configure PB0, PB1, PB10 and PB8 */
  347. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1, GPIO_Pin_10 | GPIO_Pin_8;
  348. GPIO_Init(GPIOB, &GPIO_InitStructure);
  349. GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_ETH);
  350. GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_ETH);
  351. GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_ETH);
  352. GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_ETH);
  353. /* Configure PA0, PA3 */
  354. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_3;
  355. GPIO_Init(GPIOA, &GPIO_InitStructure);
  356. GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_ETH);
  357. GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_ETH);
  358. #endif
  359. }
  360. /**
  361. * @brief Configures the Ethernet Interface
  362. * @param None
  363. * @retval None
  364. */
  365. static void ETH_MACDMA_Config(void)
  366. {
  367. ETH_InitTypeDef ETH_InitStructure;
  368. /* Enable ETHERNET clock */
  369. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC | RCC_AHB1Periph_ETH_MAC_Tx |
  370. RCC_AHB1Periph_ETH_MAC_Rx, ENABLE);
  371. /* Reset ETHERNET on AHB Bus */
  372. ETH_DeInit();
  373. /* Software reset */
  374. ETH_SoftwareReset();
  375. /* Wait for software reset */
  376. while (ETH_GetSoftwareResetStatus() == SET);
  377. /* ETHERNET Configuration --------------------------------------------------*/
  378. /* Call ETH_StructInit if you don't like to configure all ETH_InitStructure parameter */
  379. ETH_StructInit(&ETH_InitStructure);
  380. /* Fill ETH_InitStructure parametrs */
  381. /*------------------------ MAC -----------------------------------*/
  382. ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable;
  383. //ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Disable;
  384. // ETH_InitStructure.ETH_Speed = ETH_Speed_10M;
  385. // ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;
  386. ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable;
  387. ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable;
  388. ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;
  389. ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Disable;
  390. ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable;
  391. ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;
  392. ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;
  393. ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;
  394. #ifdef CHECKSUM_BY_HARDWARE
  395. ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable;
  396. #endif
  397. /*------------------------ DMA -----------------------------------*/
  398. /* When we use the Checksum offload feature, we need to enable the Store and Forward mode:
  399. the store and forward guarantee that a whole frame is stored in the FIFO, so the MAC can insert/verify the checksum,
  400. if the checksum is OK the DMA can handle the frame otherwise the frame is dropped */
  401. ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Enable;
  402. ETH_InitStructure.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable;
  403. ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable;
  404. ETH_InitStructure.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable;
  405. ETH_InitStructure.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable;
  406. ETH_InitStructure.ETH_SecondFrameOperate = ETH_SecondFrameOperate_Enable;
  407. ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable;
  408. ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable;
  409. ETH_InitStructure.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat;
  410. ETH_InitStructure.ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat;
  411. ETH_InitStructure.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1;
  412. /* Configure Ethernet */
  413. if( ETH_Init(&ETH_InitStructure, DP83848_PHY_ADDRESS) == ETH_ERROR )
  414. rt_kprintf("ETH init error, may be no link\n");
  415. /* Enable the Ethernet Rx Interrupt */
  416. ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R , ENABLE);
  417. }
  418. #define DevID_SNo0 (*((rt_uint32_t *)0x1FFF7A10));
  419. #define DevID_SNo1 (*((rt_uint32_t *)0x1FFF7A10+32));
  420. #define DevID_SNo2 (*((rt_uint32_t *)0x1FFF7A10+64));
  421. void rt_hw_stm32_eth_init(void)
  422. {
  423. GPIO_Configuration();
  424. NVIC_Configuration();
  425. ETH_MACDMA_Config();
  426. stm32_eth_device.dev_addr[0] = 0x00;
  427. stm32_eth_device.dev_addr[1] = 0x60;
  428. stm32_eth_device.dev_addr[2] = 0x6e;
  429. {
  430. uint32_t cpu_id[3] = {0};
  431. cpu_id[2] = DevID_SNo2; cpu_id[1] = DevID_SNo1; cpu_id[0] = DevID_SNo0;
  432. // generate MAC addr from 96bit unique ID (only for test)
  433. stm32_eth_device.dev_addr[3] = (uint8_t)((cpu_id[0]>>16)&0xFF);
  434. stm32_eth_device.dev_addr[4] = (uint8_t)((cpu_id[0]>>8)&0xFF);
  435. stm32_eth_device.dev_addr[5] = (uint8_t)(cpu_id[0]&0xFF);
  436. // stm32_eth_device.dev_addr[3] = *(rt_uint8_t*)(0x1FFF7A10+7);
  437. // stm32_eth_device.dev_addr[4] = *(rt_uint8_t*)(0x1FFF7A10+8);
  438. // stm32_eth_device.dev_addr[5] = *(rt_uint8_t*)(0x1FFF7A10+9);
  439. }
  440. stm32_eth_device.parent.parent.init = rt_stm32_eth_init;
  441. stm32_eth_device.parent.parent.open = rt_stm32_eth_open;
  442. stm32_eth_device.parent.parent.close = rt_stm32_eth_close;
  443. stm32_eth_device.parent.parent.read = rt_stm32_eth_read;
  444. stm32_eth_device.parent.parent.write = rt_stm32_eth_write;
  445. stm32_eth_device.parent.parent.control = rt_stm32_eth_control;
  446. stm32_eth_device.parent.parent.user_data = RT_NULL;
  447. stm32_eth_device.parent.eth_rx = rt_stm32_eth_rx;
  448. stm32_eth_device.parent.eth_tx = rt_stm32_eth_tx;
  449. /* init tx semaphore */
  450. rt_sem_init(&tx_wait, "tx_wait", 1, RT_IPC_FLAG_FIFO);
  451. /* register eth device */
  452. eth_device_init(&(stm32_eth_device.parent), "e0");
  453. }
  454. static char led = 0;
  455. void dp83483()
  456. {
  457. uint16_t bsr,sts, bcr, phycr;
  458. bsr = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_BSR);
  459. sts = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_SR);
  460. bcr = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_BCR);
  461. phycr = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_CR);
  462. rt_kprintf("BCR = 0x%X\tBSR = 0x%X\tPHY_STS = 0x%X\tPHY_CR = 0x%X\n", bcr,bsr,sts, phycr);
  463. rt_kprintf("PHY_FCSCR = 0x%X\n", ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_FCSCR ) );
  464. rt_kprintf("PHY_MISR = 0x%X\n", ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_MISR ) );
  465. rt_kprintf("DMASR = 0x%X\n", ETH->DMASR );
  466. //ETH_WritePHYRegister(DP83848_PHY_ADDRESS, PHY_LEDCR, (uint16_t)(0x38 | led));
  467. led = (led==7)?0:7;
  468. }
  469. #ifdef RT_USING_FINSH
  470. #include <finsh.h>
  471. FINSH_FUNCTION_EXPORT(dp83483, Show PHY register.);
  472. #endif