synopsys_emac.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "synopsys_emac.h"
  7. #include "gd32f4xx_enet.h"
  8. /* The state of enet initialization */
  9. volatile uint32_t enet_init_state = 0;
  10. /* Global pointers on Tx and Rx descriptor used to track transmit and receive descriptors */
  11. extern EMAC_DMADESCTypeDef *DMATxDescToSet;
  12. extern EMAC_DMADESCTypeDef *DMARxDescToGet;
  13. /**
  14. * Initializes the ETHERNET peripheral according to the specified
  15. */
  16. rt_uint32_t EMAC_init(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t SystemCoreClock)
  17. {
  18. /*-------------------------------- Reset ethernet -------------------------------*/
  19. enet_deinit();
  20. enet_software_reset();
  21. /* configure the parameters which are usually less cared for enet initialization */
  22. enet_initpara_config(HALFDUPLEX_OPTION, ENET_CARRIERSENSE_DISABLE|ENET_RECEIVEOWN_ENABLE|ENET_RETRYTRANSMISSION_DISABLE|ENET_BACKOFFLIMIT_10|ENET_DEFERRALCHECK_DISABLE);
  23. /*-------------------------------- Initialize ENET ------------------------------*/
  24. enet_init_state = enet_init(ENET_AUTO_NEGOTIATION, ENET_AUTOCHECKSUM_DROP_FAILFRAMES, ENET_BROADCAST_FRAMES_PASS);
  25. /* Return Ethernet configuration success */
  26. return EMAC_SUCCESS;
  27. }
  28. /**
  29. * Enables or disables the specified ETHERNET DMA interrupts.
  30. */
  31. void EMAC_INT_config(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t EMAC_DMA_IT, rt_bool_t NewState)
  32. {
  33. if (NewState)
  34. {
  35. /* Enable the selected ETHERNET DMA interrupts */
  36. ETHERNET_MAC->IER |= EMAC_DMA_IT;
  37. }
  38. else
  39. {
  40. /* Disable the selected ETHERNET DMA interrupts */
  41. ETHERNET_MAC->IER &=(~(rt_uint32_t)EMAC_DMA_IT);
  42. }
  43. }
  44. /**
  45. * Configures the selected MAC address.
  46. */
  47. void EMAC_MAC_Addr_config(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t MacAddr, rt_uint8_t *Addr)
  48. {
  49. rt_uint32_t value;
  50. /* Calculate the selectecd MAC address high register */
  51. value = ((rt_uint32_t)Addr[5] << 8) | (rt_uint32_t)Addr[4];
  52. /* Load the selectecd MAC address high register */
  53. //(*(volatile rt_uint32_t *) (EMAC_MAC_ADDR_HBASE + MacAddr)) = value;
  54. ETHERNET_MAC->MARs[MacAddr].MARH = value;
  55. /* Calculate the selectecd MAC address low register */
  56. value = ((rt_uint32_t)Addr[3] << 24) | ((rt_uint32_t)Addr[2] << 16) | ((rt_uint32_t)Addr[1] << 8) | Addr[0];
  57. /* Load the selectecd MAC address low register */
  58. //(*(volatile rt_uint32_t *) (EMAC_MAC_ADDR_LBASE + MacAddr)) = value;
  59. ETHERNET_MAC->MARs[MacAddr].MARL = value;
  60. }
  61. /**
  62. * Enables or disables the MAC transmission.
  63. */
  64. void EMAC_MACTransmissionCmd(struct rt_synopsys_eth * ETHERNET_MAC, rt_bool_t NewState)
  65. {
  66. if (NewState)
  67. {
  68. /* Enable the MAC transmission */
  69. ETHERNET_MAC->MCR |= EMAC_MACCR_TE;
  70. }
  71. else
  72. {
  73. /* Disable the MAC transmission */
  74. ETHERNET_MAC->MCR &= ~EMAC_MACCR_TE;
  75. }
  76. }
  77. /**
  78. * Clears the ETHERNET transmit FIFO.
  79. */
  80. void EMAC_FlushTransmitFIFO(struct rt_synopsys_eth * ETHERNET_MAC)
  81. {
  82. /* Set the Flush Transmit FIFO bit */
  83. ETHERNET_MAC->OMR |= EMAC_DMAOMR_FTF;
  84. }
  85. /**
  86. * Enables or disables the MAC reception.
  87. */
  88. void EMAC_MACReceptionCmd(struct rt_synopsys_eth * ETHERNET_MAC, rt_bool_t NewState)
  89. {
  90. if (NewState)
  91. {
  92. /* Enable the MAC reception */
  93. ETHERNET_MAC->MCR |= EMAC_MACCR_RE;
  94. }
  95. else
  96. {
  97. /* Disable the MAC reception */
  98. ETHERNET_MAC->MCR &= ~EMAC_MACCR_RE;
  99. }
  100. }
  101. /**
  102. * Enables or disables the DMA transmission.
  103. */
  104. void EMAC_DMATransmissionCmd(struct rt_synopsys_eth * ETHERNET_MAC, rt_bool_t NewState)
  105. {
  106. if (NewState)
  107. {
  108. /* Enable the DMA transmission */
  109. ETHERNET_MAC->OMR |= EMAC_DMAOMR_ST;
  110. }
  111. else
  112. {
  113. /* Disable the DMA transmission */
  114. ETHERNET_MAC->OMR &= ~EMAC_DMAOMR_ST;
  115. }
  116. }
  117. /**
  118. * Enables or disables the DMA reception.
  119. */
  120. void EMAC_DMAReceptionCmd(struct rt_synopsys_eth * ETHERNET_MAC, rt_bool_t NewState)
  121. {
  122. if (NewState)
  123. {
  124. /* Enable the DMA reception */
  125. ETHERNET_MAC->OMR |= EMAC_DMAOMR_SR;
  126. }
  127. else
  128. {
  129. /* Disable the DMA reception */
  130. ETHERNET_MAC->OMR &= ~EMAC_DMAOMR_SR;
  131. }
  132. }
  133. /**
  134. * Enables ENET MAC and DMA reception/transmission
  135. */
  136. void EMAC_start(struct rt_synopsys_eth * ETHERNET_MAC)
  137. {
  138. /* Enable transmit state machine of the MAC for transmission on the MII */
  139. EMAC_MACTransmissionCmd(ETHERNET_MAC, RT_TRUE);
  140. /* Flush Transmit FIFO */
  141. enet_txfifo_flush();
  142. /* Enable receive state machine of the MAC for reception from the MII */
  143. EMAC_MACReceptionCmd(ETHERNET_MAC, RT_TRUE);
  144. /* Start DMA transmission */
  145. EMAC_DMATransmissionCmd(ETHERNET_MAC, RT_TRUE);
  146. /* Start DMA reception */
  147. EMAC_DMAReceptionCmd(ETHERNET_MAC, RT_TRUE);
  148. }
  149. /**
  150. * Clears the ETHERNET's DMA interrupt pending bit.
  151. */
  152. void EMAC_clear_pending(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t pending)
  153. {
  154. /* Clear the selected ETHERNET DMA IT */
  155. ETHERNET_MAC->SR = (rt_uint32_t) pending;
  156. }
  157. /**
  158. * Resumes the DMA Transmission by writing to the DmaRxPollDemand register
  159. * (the data written could be anything). This forces the DMA to resume reception.
  160. */
  161. void EMAC_resume_reception(struct rt_synopsys_eth * ETHERNET_MAC)
  162. {
  163. ETHERNET_MAC->RPDR = 0;
  164. }
  165. /**
  166. * Resumes the DMA Transmission by writing to the DmaTxPollDemand register
  167. * (the data written could be anything). This forces the DMA to resume transmission.
  168. */
  169. void EMAC_resume_transmission(struct rt_synopsys_eth * ETHERNET_MAC)
  170. {
  171. ETHERNET_MAC->TPDR = 0;
  172. }
  173. /**
  174. * Read a PHY register
  175. */
  176. rt_uint16_t EMAC_PHY_read(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint16_t PHYAddress, rt_uint16_t PHYReg)
  177. {
  178. rt_uint32_t value = 0;
  179. volatile rt_uint32_t timeout = 0;
  180. /* Get the ETHERNET MACMIIAR value */
  181. value = ETHERNET_MAC->GAR;
  182. /* Keep only the CSR Clock Range CR[2:0] bits value */
  183. value &= ~MACMIIAR_CR_MASK;
  184. /* Prepare the MII address register value */
  185. value |=(((rt_uint32_t)PHYAddress<<11) & EMAC_MACMIIAR_PA); /* Set the PHY device address */
  186. value |=(((rt_uint32_t)PHYReg<<6) & EMAC_MACMIIAR_MR); /* Set the PHY register address */
  187. value &= ~EMAC_MACMIIAR_MW; /* Set the read mode */
  188. value |= EMAC_MACMIIAR_MB; /* Set the MII Busy bit */
  189. /* Write the result value into the MII Address register */
  190. ETHERNET_MAC->GAR = value;
  191. /* Check for the Busy flag */
  192. do
  193. {
  194. timeout++;
  195. value = ETHERNET_MAC->GAR;
  196. }
  197. while ((value & EMAC_MACMIIAR_MB) && (timeout < (rt_uint32_t)PHY_READ_TO));
  198. /* Return ERROR in case of timeout */
  199. if(timeout == PHY_READ_TO)
  200. {
  201. return (rt_uint16_t)EMAC_ERROR;
  202. }
  203. /* Return data register value */
  204. return (rt_uint16_t)(ETHERNET_MAC->GDR);
  205. }
  206. /**
  207. * Write to a PHY register
  208. */
  209. rt_uint32_t EMAC_PHY_write(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint16_t PHYAddress, rt_uint16_t PHYReg, rt_uint16_t PHYValue)
  210. {
  211. rt_uint32_t value = 0;
  212. volatile rt_uint32_t timeout = 0;
  213. /* Get the ETHERNET MACMIIAR value */
  214. value = ETHERNET_MAC->GAR;
  215. /* Keep only the CSR Clock Range CR[2:0] bits value */
  216. value &= ~MACMIIAR_CR_MASK;
  217. /* Prepare the MII register address value */
  218. value |=(((rt_uint32_t)PHYAddress<<11) & EMAC_MACMIIAR_PA); /* Set the PHY device address */
  219. value |=(((rt_uint32_t)PHYReg<<6) & EMAC_MACMIIAR_MR); /* Set the PHY register address */
  220. value |= EMAC_MACMIIAR_MW; /* Set the write mode */
  221. value |= EMAC_MACMIIAR_MB; /* Set the MII Busy bit */
  222. /* Give the value to the MII data register */
  223. ETHERNET_MAC->GDR = PHYValue;
  224. /* Write the result value into the MII Address register */
  225. ETHERNET_MAC->GAR = value;
  226. /* Check for the Busy flag */
  227. do
  228. {
  229. timeout++;
  230. value = ETHERNET_MAC->GAR;
  231. }
  232. while ((value & EMAC_MACMIIAR_MB) && (timeout < (rt_uint32_t)PHY_WRITE_TO));
  233. /* Return ERROR in case of timeout */
  234. if(timeout == PHY_WRITE_TO)
  235. {
  236. return EMAC_ERROR;
  237. }
  238. /* Return SUCCESS */
  239. return EMAC_SUCCESS;
  240. }