synopsys_emac.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. /*
  2. * File : rthw.h
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. */
  20. #include "synopsys_emac.h"
  21. /* Global pointers on Tx and Rx descriptor used to track transmit and receive descriptors */
  22. extern EMAC_DMADESCTypeDef *DMATxDescToSet;
  23. extern EMAC_DMADESCTypeDef *DMARxDescToGet;
  24. /**
  25. * Initializes the ETHERNET peripheral according to the specified
  26. */
  27. rt_uint32_t EMAC_init(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t SystemCoreClock)
  28. {
  29. rt_uint32_t value = 0;
  30. /*-------------------------------- MAC Config ------------------------------*/
  31. /*---------------------- ETHERNET MACMIIAR Configuration -------------------*/
  32. /* Get the ETHERNET MACMIIAR value */
  33. value = ETHERNET_MAC->GAR;
  34. /* Clear CSR Clock Range CR[2:0] bits */
  35. value &= MACMIIAR_CR_MASK;
  36. /* Get hclk frequency value */
  37. /* Set CR bits depending on hclk value */
  38. if((SystemCoreClock >= 20000000)&&(SystemCoreClock < 35000000))
  39. {
  40. /* CSR Clock Range between 20-35 MHz */
  41. value |= (rt_uint32_t)EMAC_MACMIIAR_CR_Div16;
  42. }
  43. else if((SystemCoreClock >= 35000000)&&(SystemCoreClock < 60000000))
  44. {
  45. /* CSR Clock Range between 35-60 MHz */
  46. value |= (rt_uint32_t)EMAC_MACMIIAR_CR_Div26;
  47. }
  48. else if((SystemCoreClock >= 60000000)&&(SystemCoreClock <= 100000000))
  49. {
  50. /* CSR Clock Range between 60-100 MHz */
  51. value |= (rt_uint32_t)EMAC_MACMIIAR_CR_Div42;
  52. }
  53. else if((SystemCoreClock >= 100000000)&&(SystemCoreClock <= 150000000))
  54. {
  55. /* CSR Clock Range between 100-150 MHz */
  56. value |= (rt_uint32_t)EMAC_MACMIIAR_CR_Div62;
  57. }
  58. else if((SystemCoreClock >= 150000000)&&(SystemCoreClock <= 250000000))
  59. {
  60. /* CSR Clock Range between 150-250 MHz */
  61. value |= (rt_uint32_t)EMAC_MACMIIAR_CR_Div102;
  62. }
  63. else /* if((SystemCoreClock >= 250000000)&&(SystemCoreClock <= 300000000)) */
  64. {
  65. /* CSR Clock Range between 250-300 MHz */
  66. value |= (rt_uint32_t)EMAC_MACMIIAR_CR_Div122;
  67. }
  68. /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
  69. ETHERNET_MAC->GAR = (rt_uint32_t)value;
  70. /*------------------------ ETHERNET MACCR Configuration --------------------*/
  71. /* Get the ETHERNET MACCR value */
  72. value = ETHERNET_MAC->MCR;
  73. /* Clear WD, PCE, PS, TE and RE bits */
  74. value &= MACCR_CLEAR_MASK;
  75. value |= (rt_uint32_t)(EMAC_Watchdog_Enable |
  76. EMAC_Jabber_Enable |
  77. EMAC_InterFrameGap_96Bit |
  78. EMAC_CarrierSense_Enable |
  79. EMAC_Speed_100M |
  80. EMAC_ReceiveOwn_Enable |
  81. EMAC_LoopbackMode_Disable |
  82. EMAC_Mode_FullDuplex |
  83. EMAC_ChecksumOffload_Enable |
  84. EMAC_RetryTransmission_Disable |
  85. EMAC_AutomaticPadCRCStrip_Disable |
  86. EMAC_BackOffLimit_10 |
  87. EMAC_DeferralCheck_Disable);
  88. /* Write to ETHERNET MACCR */
  89. value |= (1<<15);
  90. value &= ~(1<<25);
  91. value &= ~(1<<24);
  92. ETHERNET_MAC->MCR = (rt_uint32_t)value;
  93. /*----------------------- ETHERNET MACFFR Configuration --------------------*/
  94. /* Write to ETHERNET MACFFR */
  95. ETHERNET_MAC->MFFR = (rt_uint32_t)(EMAC_ReceiveAll_Enable |
  96. EMAC_SourceAddrFilter_Disable |
  97. EMAC_PassControlFrames_BlockAll |
  98. EMAC_BroadcastFramesReception_Disable |
  99. EMAC_DestinationAddrFilter_Normal |
  100. EMAC_PromiscuousMode_Disable |
  101. EMAC_MulticastFramesFilter_Perfect |
  102. EMAC_UnicastFramesFilter_Perfect);
  103. /*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/
  104. /* Write to ETHERNET MACHTHR */
  105. ETHERNET_MAC->MHTRH = 0;
  106. /* Write to ETHERNET MACHTLR */
  107. ETHERNET_MAC->MHTRL = 0;
  108. /*----------------------- ETHERNET MACFCR Configuration --------------------*/
  109. /* Get the ETHERNET MACFCR value */
  110. value = ETHERNET_MAC->FCR;
  111. /* Clear xx bits */
  112. value &= MACFCR_CLEAR_MASK;
  113. value |= (rt_uint32_t)((0 << 16) |
  114. EMAC_ZeroQuantaPause_Disable |
  115. EMAC_PauseLowThreshold_Minus4 |
  116. EMAC_UnicastPauseFrameDetect_Disable |
  117. EMAC_ReceiveFlowControl_Disable |
  118. EMAC_TransmitFlowControl_Disable);
  119. /* Write to ETHERNET MACFCR */
  120. ETHERNET_MAC->FCR = (rt_uint32_t)value;
  121. /*----------------------- ETHERNET MACVLANTR Configuration -----------------*/
  122. ETHERNET_MAC->VTR = (rt_uint32_t)(EMAC_VLANTagComparison_16Bit |
  123. 0);
  124. /*-------------------------------- DMA Config ------------------------------*/
  125. /*----------------------- ETHERNET DMAOMR Configuration --------------------*/
  126. /* Get the ETHERNET DMAOMR value */
  127. value = ETHERNET_MAC->OMR;
  128. /* Clear xx bits */
  129. value &= DMAOMR_CLEAR_MASK;
  130. value |= (rt_uint32_t)(EMAC_DropTCPIPChecksumErrorFrame_Disable |
  131. EMAC_ReceiveStoreForward_Enable |
  132. EMAC_FlushReceivedFrame_Enable |
  133. EMAC_TransmitStoreForward_Enable |
  134. EMAC_TransmitThresholdControl_64Bytes |
  135. EMAC_ForwardErrorFrames_Disable |
  136. EMAC_ForwardUndersizedGoodFrames_Disable |
  137. EMAC_ReceiveThresholdControl_64Bytes |
  138. EMAC_SecondFrameOperate_Disable);
  139. /* Write to ETHERNET DMAOMR */
  140. ETHERNET_MAC->OMR = (rt_uint32_t)value;
  141. /*----------------------- ETHERNET DMABMR Configuration --------------------*/
  142. ETHERNET_MAC->BMR = (rt_uint32_t)(EMAC_AddressAlignedBeats_Enable |
  143. EMAC_FixedBurst_Enable |
  144. EMAC_RxDMABurstLength_32Beat | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
  145. EMAC_TxDMABurstLength_32Beat |
  146. (0 << 2) |
  147. EMAC_DMAArbitration_RoundRobin_RxTx_2_1 |
  148. EMAC_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
  149. /* Return Ethernet configuration success */
  150. return EMAC_SUCCESS;
  151. }
  152. /**
  153. * Enables or disables the specified ETHERNET DMA interrupts.
  154. */
  155. void EMAC_INT_config(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t EMAC_DMA_IT, rt_bool_t NewState)
  156. {
  157. if (NewState)
  158. {
  159. /* Enable the selected ETHERNET DMA interrupts */
  160. ETHERNET_MAC->IER |= EMAC_DMA_IT;
  161. }
  162. else
  163. {
  164. /* Disable the selected ETHERNET DMA interrupts */
  165. ETHERNET_MAC->IER &=(~(rt_uint32_t)EMAC_DMA_IT);
  166. }
  167. }
  168. /**
  169. * Configures the selected MAC address.
  170. */
  171. void EMAC_MAC_Addr_config(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t MacAddr, rt_uint8_t *Addr)
  172. {
  173. rt_uint32_t value;
  174. /* Calculate the selectecd MAC address high register */
  175. value = ((rt_uint32_t)Addr[5] << 8) | (rt_uint32_t)Addr[4];
  176. /* Load the selectecd MAC address high register */
  177. //(*(volatile rt_uint32_t *) (EMAC_MAC_ADDR_HBASE + MacAddr)) = value;
  178. ETHERNET_MAC->MARs[MacAddr].MARH = value;
  179. /* Calculate the selectecd MAC address low register */
  180. value = ((rt_uint32_t)Addr[3] << 24) | ((rt_uint32_t)Addr[2] << 16) | ((rt_uint32_t)Addr[1] << 8) | Addr[0];
  181. /* Load the selectecd MAC address low register */
  182. //(*(volatile rt_uint32_t *) (EMAC_MAC_ADDR_LBASE + MacAddr)) = value;
  183. ETHERNET_MAC->MARs[MacAddr].MARL = value;
  184. }
  185. /**
  186. * Enables or disables the MAC transmission.
  187. */
  188. void EMAC_MACTransmissionCmd(struct rt_synopsys_eth * ETHERNET_MAC, rt_bool_t NewState)
  189. {
  190. if (NewState)
  191. {
  192. /* Enable the MAC transmission */
  193. ETHERNET_MAC->MCR |= EMAC_MACCR_TE;
  194. }
  195. else
  196. {
  197. /* Disable the MAC transmission */
  198. ETHERNET_MAC->MCR &= ~EMAC_MACCR_TE;
  199. }
  200. }
  201. /**
  202. * Clears the ETHERNET transmit FIFO.
  203. */
  204. void EMAC_FlushTransmitFIFO(struct rt_synopsys_eth * ETHERNET_MAC)
  205. {
  206. /* Set the Flush Transmit FIFO bit */
  207. ETHERNET_MAC->OMR |= EMAC_DMAOMR_FTF;
  208. }
  209. /**
  210. * Enables or disables the MAC reception.
  211. */
  212. void EMAC_MACReceptionCmd(struct rt_synopsys_eth * ETHERNET_MAC, rt_bool_t NewState)
  213. {
  214. if (NewState)
  215. {
  216. /* Enable the MAC reception */
  217. ETHERNET_MAC->MCR |= EMAC_MACCR_RE;
  218. }
  219. else
  220. {
  221. /* Disable the MAC reception */
  222. ETHERNET_MAC->MCR &= ~EMAC_MACCR_RE;
  223. }
  224. }
  225. /**
  226. * Enables or disables the DMA transmission.
  227. */
  228. void EMAC_DMATransmissionCmd(struct rt_synopsys_eth * ETHERNET_MAC, rt_bool_t NewState)
  229. {
  230. if (NewState)
  231. {
  232. /* Enable the DMA transmission */
  233. ETHERNET_MAC->OMR |= EMAC_DMAOMR_ST;
  234. }
  235. else
  236. {
  237. /* Disable the DMA transmission */
  238. ETHERNET_MAC->OMR &= ~EMAC_DMAOMR_ST;
  239. }
  240. }
  241. /**
  242. * Enables or disables the DMA reception.
  243. */
  244. void EMAC_DMAReceptionCmd(struct rt_synopsys_eth * ETHERNET_MAC, rt_bool_t NewState)
  245. {
  246. if (NewState)
  247. {
  248. /* Enable the DMA reception */
  249. ETHERNET_MAC->OMR |= EMAC_DMAOMR_SR;
  250. }
  251. else
  252. {
  253. /* Disable the DMA reception */
  254. ETHERNET_MAC->OMR &= ~EMAC_DMAOMR_SR;
  255. }
  256. }
  257. /**
  258. * Enables ENET MAC and DMA reception/transmission
  259. */
  260. void EMAC_start(struct rt_synopsys_eth * ETHERNET_MAC)
  261. {
  262. /* Enable transmit state machine of the MAC for transmission on the MII */
  263. EMAC_MACTransmissionCmd(ETHERNET_MAC, RT_TRUE);
  264. /* Flush Transmit FIFO */
  265. EMAC_FlushTransmitFIFO(ETHERNET_MAC);
  266. /* Enable receive state machine of the MAC for reception from the MII */
  267. EMAC_MACReceptionCmd(ETHERNET_MAC, RT_TRUE);
  268. /* Start DMA transmission */
  269. EMAC_DMATransmissionCmd(ETHERNET_MAC, RT_TRUE);
  270. /* Start DMA reception */
  271. EMAC_DMAReceptionCmd(ETHERNET_MAC, RT_TRUE);
  272. }
  273. /**
  274. * Clears the ETHERNET's DMA interrupt pending bit.
  275. */
  276. void EMAC_clear_pending(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t pending)
  277. {
  278. /* Clear the selected ETHERNET DMA IT */
  279. ETHERNET_MAC->SR = (rt_uint32_t) pending;
  280. }
  281. /**
  282. * Resumes the DMA Transmission by writing to the DmaRxPollDemand register
  283. * (the data written could be anything). This forces the DMA to resume reception.
  284. */
  285. void EMAC_resume_reception(struct rt_synopsys_eth * ETHERNET_MAC)
  286. {
  287. ETHERNET_MAC->RPDR = 0;
  288. }
  289. /**
  290. * Resumes the DMA Transmission by writing to the DmaTxPollDemand register
  291. * (the data written could be anything). This forces the DMA to resume transmission.
  292. */
  293. void EMAC_resume_transmission(struct rt_synopsys_eth * ETHERNET_MAC)
  294. {
  295. ETHERNET_MAC->TPDR = 0;
  296. }
  297. /**
  298. * Read a PHY register
  299. */
  300. rt_uint16_t EMAC_PHY_read(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint16_t PHYAddress, rt_uint16_t PHYReg)
  301. {
  302. rt_uint32_t value = 0;
  303. volatile rt_uint32_t timeout = 0;
  304. /* Get the ETHERNET MACMIIAR value */
  305. value = ETHERNET_MAC->GAR;
  306. /* Keep only the CSR Clock Range CR[2:0] bits value */
  307. value &= ~MACMIIAR_CR_MASK;
  308. /* Prepare the MII address register value */
  309. value |=(((rt_uint32_t)PHYAddress<<11) & EMAC_MACMIIAR_PA); /* Set the PHY device address */
  310. value |=(((rt_uint32_t)PHYReg<<6) & EMAC_MACMIIAR_MR); /* Set the PHY register address */
  311. value &= ~EMAC_MACMIIAR_MW; /* Set the read mode */
  312. value |= EMAC_MACMIIAR_MB; /* Set the MII Busy bit */
  313. /* Write the result value into the MII Address register */
  314. ETHERNET_MAC->GAR = value;
  315. /* Check for the Busy flag */
  316. do
  317. {
  318. timeout++;
  319. value = ETHERNET_MAC->GAR;
  320. }
  321. while ((value & EMAC_MACMIIAR_MB) && (timeout < (rt_uint32_t)PHY_READ_TO));
  322. /* Return ERROR in case of timeout */
  323. if(timeout == PHY_READ_TO)
  324. {
  325. return (rt_uint16_t)EMAC_ERROR;
  326. }
  327. /* Return data register value */
  328. return (rt_uint16_t)(ETHERNET_MAC->GDR);
  329. }
  330. /**
  331. * Write to a PHY register
  332. */
  333. rt_uint32_t EMAC_PHY_write(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint16_t PHYAddress, rt_uint16_t PHYReg, rt_uint16_t PHYValue)
  334. {
  335. rt_uint32_t value = 0;
  336. volatile rt_uint32_t timeout = 0;
  337. /* Get the ETHERNET MACMIIAR value */
  338. value = ETHERNET_MAC->GAR;
  339. /* Keep only the CSR Clock Range CR[2:0] bits value */
  340. value &= ~MACMIIAR_CR_MASK;
  341. /* Prepare the MII register address value */
  342. value |=(((rt_uint32_t)PHYAddress<<11) & EMAC_MACMIIAR_PA); /* Set the PHY device address */
  343. value |=(((rt_uint32_t)PHYReg<<6) & EMAC_MACMIIAR_MR); /* Set the PHY register address */
  344. value |= EMAC_MACMIIAR_MW; /* Set the write mode */
  345. value |= EMAC_MACMIIAR_MB; /* Set the MII Busy bit */
  346. /* Give the value to the MII data register */
  347. ETHERNET_MAC->GDR = PHYValue;
  348. /* Write the result value into the MII Address register */
  349. ETHERNET_MAC->GAR = value;
  350. /* Check for the Busy flag */
  351. do
  352. {
  353. timeout++;
  354. value = ETHERNET_MAC->GAR;
  355. }
  356. while ((value & EMAC_MACMIIAR_MB) && (timeout < (rt_uint32_t)PHY_WRITE_TO));
  357. /* Return ERROR in case of timeout */
  358. if(timeout == PHY_WRITE_TO)
  359. {
  360. return EMAC_ERROR;
  361. }
  362. /* Return SUCCESS */
  363. return EMAC_SUCCESS;
  364. }