hal_eth.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  1. ////////////////////////////////////////////////////////////////////////////////
  2. /// @file hal_eth.c
  3. /// @author AE TEM
  4. /// @brief THIS FILE PROVIDES ALL THE HAL_eth.c EXAMPLE.
  5. /// ////////////////////////////////////////////////////////////////////////////
  6. /// @attention
  7. ///
  8. /// THE EXISTING FIRMWARE IS ONLY FOR REFERENCE, WHICH IS DESIGNED TO PROVIDE
  9. /// CUSTOMERS WITH CODING INFORMATION ABOUT THEIR PRODUCTS SO THEY CAN SAVE
  10. /// TIME. THEREFORE, MINDMOTION SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR
  11. /// CONSEQUENTIAL DAMAGES ABOUT ANY CLAIMS ARISING OUT OF THE CONTENT OF SUCH
  12. /// HARDWARE AND/OR THE USE OF THE CODING INFORMATION CONTAINED HEREIN IN
  13. /// CONNECTION WITH PRODUCTS MADE BY CUSTOMERS.
  14. ///
  15. /// <H2><CENTER>&COPY; COPYRIGHT MINDMOTION </CENTER></H2>
  16. ////////////////////////////////////////////////////////////////////////////////
  17. #define _HAL_ETH_C_
  18. #include "hal_rcc.h"
  19. #include "hal_eth.h"
  20. #include "reg_eth.h"
  21. void ETH_DeInit(void)
  22. {
  23. RCC_AHBPeriphResetCmd(RCC_AHBENR_ETHMAC, ENABLE);
  24. RCC_AHBPeriphResetCmd(RCC_AHBENR_ETHMAC, DISABLE);
  25. }
  26. void ETH_StructInit(ETH_InitTypeDef* ptr)
  27. {
  28. ptr->ETH_AutoNegotiation = ETH_AutoNegotiation_Enable; ///< PHY Auto-negotiation enabled
  29. ptr->ETH_Watchdog = ETH_Watchdog_Enable; ///< MAC watchdog enabled: cuts off long frame
  30. ptr->ETH_Jabber = ETH_Jabber_Enable; ///< MAC Jabber enabled in Half-duplex mode
  31. ptr->ETH_InterFrameGap = ETH_InterFrameGap_96Bit; ///< Ethernet interframe gap set to 96 bits
  32. ptr->ETH_CarrierSense = ETH_CarrierSense_Enable; ///< Carrier Sense Enabled in Half-Duplex mode
  33. ptr->ETH_Speed = ETH_Speed_100M; ///< PHY speed configured to 100Mbit/s
  34. ptr->ETH_ReceiveOwn = ETH_ReceiveOwn_Enable; ///< Receive own Frames in Half-Duplex mode enabled
  35. ptr->ETH_LoopbackMode = ETH_LoopbackMode_Disable; ///< MAC MII loopback disabled
  36. ptr->ETH_Mode = ETH_Mode_FullDuplex; ///< Full-Duplex mode selected
  37. ptr->ETH_ChecksumOffload = ETH_ChecksumOffload_Disable; ///< IPv4 and TCP/UDP/ICMP frame Checksum Offload disabled
  38. ptr->ETH_RetryTransmission = ETH_RetryTransmission_Enable; ///< Retry Transmission enabled for half-duplex mode
  39. ptr->ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable; ///< Automatic PAD/CRC strip disable
  40. ptr->ETH_BackOffLimit = ETH_BackOffLimit_10; ///< half-duplex mode retransmission Backoff time_limit = 10 slot time
  41. ptr->ETH_DeferralCheck = ETH_DeferralCheck_Disable; ///< half-duplex mode Deferral check disabled
  42. ptr->ETH_ReceiveAll = ETH_ReceiveAll_Disable; ///< Receive all frames disabled
  43. ptr->ETH_SourceAddrFilter = ETH_SourceAddrFilter_Disable; ///< Source address filtering (on the optional MAC addresses) disabled
  44. ptr->ETH_PassControlFrames = ETH_PassControlFrames_BlockAll; ///< Do not forward control frames that do not pass the address filtering
  45. ptr->ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Disable; ///< Disable reception of Broadcast frames
  46. ptr->ETH_DestinationAddrFilter = ETH_DestinationAddrFilter_Normal; ///< Normal Destination address filtering (not reverse addressing)
  47. ptr->ETH_PromiscuousMode = ETH_PromiscuousMode_Disable; ///< Promiscuous address filtering mode disabled
  48. ptr->ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect; ///< Perfect address filtering for multicast addresses
  49. ptr->ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect; ///< Perfect address filtering for unicast addresses
  50. ptr->ETH_HashTableHigh = 0x0; ///< Initialize hash table high and low regs
  51. ptr->ETH_HashTableLow = 0x0;
  52. ptr->ETH_PauseTime = 0x0; ///< Flow control config (flow control disabled)
  53. ptr->ETH_ZeroQuantaPause = ETH_ZeroQuantaPause_Enable;
  54. ptr->ETH_PauseLowThreshold = ETH_PauseLowThreshold_Minus4;
  55. ptr->ETH_UnicastPauseFrameDetect = ETH_UnicastPauseFrameDetect_Disable;
  56. ptr->ETH_ReceiveFlowControl = ETH_ReceiveFlowControl_Disable;
  57. ptr->ETH_TransmitFlowControl = ETH_TransmitFlowControl_Disable;
  58. ptr->ETH_VLANTagComparison = ETH_VLANTagComparison_16Bit; ///< VLANtag config (VLAN field not checked)
  59. ptr->ETH_VLANTagIdentifier = 0x0;
  60. ptr->ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Disable; ///< Drops frames with with TCP/IP checksum errors
  61. ptr->ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable; ///< Store and forward mode enabled for receive
  62. ptr->ETH_FlushReceivedFrame = ETH_FlushReceivedFrame_Enable; ///< Flush received frame that created FIFO overflow
  63. ptr->ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable; ///< Store and forward mode enabled for transmit
  64. ptr->ETH_TransmitThresholdControl = ETH_ReceiveThresholdControl_64Bytes; ///< Threshold TXFIFO level set to 64 bytes (used when threshold mode is enabled)
  65. ptr->ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable; ///< Disable forwarding frames with errors (short frames, CRC,...)
  66. ptr->ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable; ///< Disable undersized good frames
  67. ptr->ETH_ReceiveThresholdControl = ETH_ReceiveThresholdControl_64Bytes; ///< Threshold RXFIFO level set to 64 bytes (used when Cut through mode is enabled)
  68. ptr->ETH_SecondFrameOperate = ETH_SecondFrameOperate_Disable; ///< Disable Operate on second frame (transmit a second frame to FIFO without waiting status of previous frame
  69. ptr->ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable; ///< DMA works on 32-bit aligned start source and destinations addresses
  70. ptr->ETH_FixedBurst = ETH_FixedBurst_Enable; ///< Enabled Fixed Burst Mode (mix of INC4, INC8, INC16 and SINGLE DMA transactions
  71. ptr->ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat; ///< DMA transfer max burst length = 32 beats = 32 x 32bits
  72. ptr->ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat;
  73. ptr->ETH_DescriptorSkipLength = 0x0; ///< DMA Ring mode skip length = 0
  74. ptr->ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_1_1; ///< Equal priority (round-robin) between transmit and receive DMA engines
  75. }
  76. u32 ETH_Init(ETH_InitTypeDef* ptr, u16 phy_addr)
  77. {
  78. u32 hclk = RCC_GetHCLKFreq();
  79. u32 reg = ETH->MACMIIAR & MACMIIAR_CR_MASK;
  80. u32 temp_val = 0;
  81. hclk = 100000000;
  82. ////////////////////////////////////////////////////////////////////////////
  83. if (hclk >= 20000000 && hclk < 35000000) {
  84. reg |= ETH_MACMIIAR_CR_Div16; ///< HCLK 20 ~ 35 MHz, /16
  85. }
  86. else if (hclk >= 35000000 && hclk < 60000000) {
  87. reg |= ETH_MACMIIAR_CR_Div26; ///< HCLK 35 ~ 60 MHz, /26
  88. }
  89. else if (hclk >= 60000000 && hclk < 100000000) {
  90. reg |= ETH_MACMIIAR_CR_Div42; ///< HCLK 60 ~ 100 MHz, /42
  91. }
  92. else if (hclk >= 100000000 && hclk < 150000000) {
  93. reg |= ETH_MACMIIAR_CR_Div62; ///< HCLK 100 ~ 150 MHz, /62
  94. }
  95. else {
  96. reg |= ETH_MACMIIAR_CR_Div102; ///< HCLK 150 ~ 168 MHz, /102
  97. }
  98. ETH->MACMIIAR = reg;
  99. ////////////////////////////////////////////////////////////////////////////
  100. ETH_WritePHYRegister(phy_addr, PHY_BCR, PHY_Reset);
  101. if (ptr->ETH_AutoNegotiation != ETH_AutoNegotiation_Disable) {
  102. // Wait for linked status
  103. while (!(ETH_ReadPHYRegister(phy_addr, PHY_BSR) & PHY_Linked_Status));
  104. ETH_WritePHYRegister(phy_addr, PHY_BCR, PHY_AutoNegotiation);
  105. // Enable Auto-Negitation
  106. while (!(ETH_ReadPHYRegister(phy_addr, PHY_BSR) & PHY_AutoNego_Complete)) {
  107. }
  108. // Read the result of the Auto-Negitation
  109. temp_val = ETH_ReadPHYRegister(phy_addr, 31);
  110. if ((temp_val & 0x1C) == 0x4) {
  111. ptr->ETH_Speed = ETH_Speed_10M;
  112. ptr->ETH_Mode = ETH_Mode_HalfDuplex;
  113. SYSCFG->CFGR2 &= ~(1 << 21);
  114. }
  115. else if((temp_val & 0x1C) == 0x14) {
  116. ptr->ETH_Speed = ETH_Speed_10M;
  117. ptr->ETH_Mode = ETH_Mode_FullDuplex;
  118. SYSCFG->CFGR2 |= 1 << 21;
  119. }
  120. else if((temp_val & 0x1C) == 0x8) {
  121. ptr->ETH_Speed = ETH_Speed_100M;
  122. ptr->ETH_Mode = ETH_Mode_HalfDuplex;
  123. SYSCFG->CFGR2 &= ~(1 << 21);
  124. }
  125. else if((temp_val & 0x1C) == 0x18) {
  126. ptr->ETH_Speed = ETH_Speed_100M;
  127. ptr->ETH_Mode = ETH_Mode_FullDuplex;
  128. SYSCFG->CFGR2 |= 1 << 21;
  129. }
  130. }
  131. else {
  132. ETH_WritePHYRegister(phy_addr, PHY_BCR, ((u16)(ptr->ETH_Mode >> 3) |
  133. (u16)(ptr->ETH_Speed >> 1)));
  134. if(ptr->ETH_Speed == ETH_Speed_10M) {
  135. SYSCFG->CFGR2 &= ~(1 << 21);
  136. }
  137. else {
  138. SYSCFG->CFGR2 |= 1 << 21;
  139. }
  140. }
  141. ////////////////////////////////////////////////////////////////////////////
  142. ETH->MACCR = ETH->MACCR & MACCR_CLEAR_MASK | (ptr->ETH_Watchdog |
  143. ptr->ETH_Jabber |
  144. ptr->ETH_InterFrameGap |
  145. ptr->ETH_CarrierSense |
  146. ptr->ETH_Speed |
  147. ptr->ETH_ReceiveOwn |
  148. ptr->ETH_LoopbackMode |
  149. ptr->ETH_Mode |
  150. ptr->ETH_ChecksumOffload |
  151. ptr->ETH_RetryTransmission |
  152. ptr->ETH_AutomaticPadCRCStrip |
  153. ptr->ETH_DeferralCheck);
  154. ETH->MACFFR = ptr->ETH_ReceiveAll |
  155. ptr->ETH_SourceAddrFilter |
  156. ptr->ETH_PassControlFrames |
  157. ptr->ETH_BroadcastFramesReception |
  158. ptr->ETH_DestinationAddrFilter |
  159. ptr->ETH_PromiscuousMode |
  160. ptr->ETH_MulticastFramesFilter |
  161. ptr->ETH_UnicastFramesFilter;
  162. ETH->MACHTHR = ptr->ETH_HashTableHigh;
  163. ETH->MACHTLR = ptr->ETH_HashTableLow;
  164. ETH->MACFCR = ETH->MACFCR & MACFCR_CLEAR_MASK | ((ptr->ETH_PauseTime << ETH_MACFCR_PT_Pos) |
  165. ptr->ETH_ZeroQuantaPause |
  166. ptr->ETH_PauseLowThreshold |
  167. ptr->ETH_UnicastPauseFrameDetect |
  168. ptr->ETH_ReceiveFlowControl |
  169. ptr->ETH_TransmitFlowControl);
  170. ETH->MACVLANTR = ptr->ETH_VLANTagComparison | ptr->ETH_VLANTagIdentifier;
  171. ETH->DMAOMR = 0x00200004;
  172. ETH->DMAIER = 0x0001A040;
  173. ETH->DMABMR = ( ptr->ETH_AddressAlignedBeats |
  174. ptr->ETH_FixedBurst |
  175. ptr->ETH_RxDMABurstLength | // !! if 4xPBL is selected for Tx or Rx it is applied for the other
  176. ptr->ETH_TxDMABurstLength |
  177. ptr->ETH_DescriptorSkipLength << 2 |
  178. ptr->ETH_DMAArbitration);// |
  179. // ETH_DMABMR_USP); // Enable use of separate PBL for Rx and Tx
  180. return ETH_SUCCESS;
  181. }
  182. void ETH_Start(void)
  183. {
  184. ETH_MACTransmissionCmd(ENABLE);
  185. ETH_MACReceptionCmd(ENABLE);
  186. ETH_FlushTransmitFIFO();
  187. ETH_DMATransmissionCmd(ENABLE);
  188. ETH_DMAReceptionCmd(ENABLE);
  189. }
  190. void ETH_Stop(void)
  191. {
  192. ETH_DMATransmissionCmd(DISABLE);
  193. ETH_DMAReceptionCmd(DISABLE);
  194. ETH_MACReceptionCmd(DISABLE);
  195. ETH_FlushTransmitFIFO();
  196. ETH_MACTransmissionCmd(DISABLE);
  197. }
  198. void ETH_MACTransmissionCmd(FunctionalState sta)
  199. {
  200. sta ? (ETH->MACCR |= ETH_MACCR_TE) : (ETH->MACCR &= ~ETH_MACCR_TE);
  201. }
  202. void ETH_MACReceptionCmd(FunctionalState sta)
  203. {
  204. sta ? (ETH->MACCR |= ETH_MACCR_RE) : (ETH->MACCR &= ~ETH_MACCR_RE);
  205. }
  206. FlagStatus ETH_GetFlowControlBusyStatus(void)
  207. {
  208. return (FlagStatus)(ETH->MACFCR & ETH_MACFCR_FCBBPA);
  209. }
  210. void ETH_InitiatePauseControlFrame(void)
  211. {
  212. ETH->MACFCR |= ETH_MACFCR_FCBBPA;
  213. }
  214. void ETH_BackPressureActivationCmd(FunctionalState sta)
  215. {
  216. sta ? (ETH->MACFCR |= ETH_MACFCR_FCBBPA) : (ETH->MACFCR &= ~ETH_MACFCR_FCBBPA);
  217. }
  218. void ETH_MACAddressConfig(u32 reg_addr, u8* mac_addr)
  219. {
  220. *(__IO u32*)(ETH_MAC_ADDR_HBASE + reg_addr) =
  221. (u32)mac_addr[5] << 8 |
  222. (u32)mac_addr[4];
  223. *(__IO u32*)(ETH_MAC_ADDR_LBASE + reg_addr) =
  224. (u32)mac_addr[3] << 24 |
  225. (u32)mac_addr[2] << 16 |
  226. (u32)mac_addr[1] << 8 |
  227. (u32)mac_addr[0];
  228. }
  229. void ETH_GetMACAddress(u32 reg_addr, u8* mac_addr)
  230. {
  231. mac_addr[5] = *(__IO u32*)(ETH_MAC_ADDR_HBASE + reg_addr) >> 8 & 0xFF;
  232. mac_addr[4] = *(__IO u32*)(ETH_MAC_ADDR_HBASE + reg_addr) & 0xFF;
  233. mac_addr[3] = *(__IO u32*)(ETH_MAC_ADDR_LBASE + reg_addr) >> 24 & 0xFF;
  234. mac_addr[2] = *(__IO u32*)(ETH_MAC_ADDR_LBASE + reg_addr) >> 16 & 0xFF;
  235. mac_addr[1] = *(__IO u32*)(ETH_MAC_ADDR_LBASE + reg_addr) >> 8 & 0xFF;
  236. mac_addr[0] = *(__IO u32*)(ETH_MAC_ADDR_LBASE + reg_addr) & 0xFF;
  237. }
  238. void ETH_MACAddressPerfectFilterCmd(u32 reg_addr, FunctionalState sta)
  239. {
  240. sta ? ((*(__IO u32*)(ETH_MAC_ADDR_HBASE + reg_addr)) |= ETH_MACA1HR_AE) :
  241. ((*(__IO u32*)(ETH_MAC_ADDR_HBASE + reg_addr)) &= ~ETH_MACA1HR_AE);
  242. }
  243. void ETH_MACAddressFilterConfig(u32 reg_addr, u32 sta)
  244. {
  245. sta ? ((*(__IO u32*)(ETH_MAC_ADDR_HBASE + reg_addr)) |= ETH_MACA1HR_SA) :
  246. ((*(__IO u32*)(ETH_MAC_ADDR_HBASE + reg_addr)) |= ETH_MACA1HR_SA);
  247. }
  248. void ETH_MACAddressMaskBytesFilterConfig(u32 reg_addr, u32 mask_byte)
  249. {
  250. (*(__IO u32*)(ETH_MAC_ADDR_HBASE + reg_addr)) &= ~ETH_MACA1HR_MBC;
  251. (*(__IO u32*)(ETH_MAC_ADDR_HBASE + reg_addr)) |= mask_byte;
  252. }
  253. FrameTypeDef ETH_Get_Received_Frame(void)
  254. {
  255. FrameTypeDef frame;
  256. frame.len = ((DMARxDescToGet->CS & ETH_DMA_RDES_FL) >> ETH_DMA_RDES_FL_Pos) - 4;
  257. frame.buf = (DMA_RX_FRAME_infos->ptrFS_Rx_Desc)->BUF1ADDR;
  258. frame.ptrDesc = DMA_RX_FRAME_infos->ptrFS_Rx_Desc;
  259. DMARxDescToGet = (ETH_DMADESCTypeDef*)(DMARxDescToGet->BUF2NDADDR);
  260. return frame;
  261. }
  262. FrameTypeDef ETH_Get_Received_Frame_interrupt(void)
  263. {
  264. FrameTypeDef frame = {0};
  265. __IO u32 desc_cnt = 0;
  266. while(!(DMARxDescToGet->CS & ETH_DMA_RDES_OWN) && desc_cnt < ETH_RX_BUF_NUM) {
  267. desc_cnt++;
  268. if ( (DMARxDescToGet->CS & ETH_DMA_RDES_FS) &&
  269. !(DMARxDescToGet->CS & ETH_DMA_RDES_LS)) {
  270. DMA_RX_FRAME_infos->ptrFS_Rx_Desc = DMARxDescToGet;
  271. DMA_RX_FRAME_infos->cnt = 1;
  272. DMARxDescToGet = (ETH_DMADESCTypeDef*)(DMARxDescToGet->BUF2NDADDR);
  273. }
  274. else if ( (DMARxDescToGet->CS & ETH_DMA_RDES_FS) &&
  275. (DMARxDescToGet->CS & ETH_DMA_RDES_LS)) {
  276. DMA_RX_FRAME_infos->cnt++;
  277. DMARxDescToGet = (ETH_DMADESCTypeDef*)(DMARxDescToGet->BUF2NDADDR);
  278. }
  279. else {
  280. DMA_RX_FRAME_infos->ptrLS_Rx_Desc = DMARxDescToGet;
  281. DMA_RX_FRAME_infos->cnt++;
  282. if (DMA_RX_FRAME_infos->cnt == 1)
  283. DMA_RX_FRAME_infos->ptrFS_Rx_Desc = DMARxDescToGet;
  284. frame.len = ((DMARxDescToGet->CS & ETH_DMA_RDES_FL) >> ETH_DMA_RDES_FL_Pos) - 4;
  285. frame.buf = (DMA_RX_FRAME_infos->cnt > 1) ?
  286. (DMA_RX_FRAME_infos->ptrFS_Rx_Desc->BUF1ADDR) :
  287. (DMARxDescToGet->BUF1ADDR);
  288. frame.ptrDesc = DMA_RX_FRAME_infos->ptrFS_Rx_Desc;
  289. DMARxDescToGet = (ETH_DMADESCTypeDef*)(DMARxDescToGet->BUF2NDADDR);
  290. return frame;
  291. }
  292. }
  293. return frame;
  294. }
  295. u32 ETH_Prepare_Transmit_Descriptors(u16 len)
  296. {
  297. u32 cnt = 0, i = 0;
  298. __IO ETH_DMADESCTypeDef* temp_desc = DMATxDescToSet;
  299. if (DMATxDescToSet->CS & ETH_DMA_TDES_OWN)
  300. return ETH_ERROR;
  301. if(len > ETH_TX_BUF_SIZE) {
  302. cnt = len / ETH_TX_BUF_SIZE;
  303. if (len % ETH_TX_BUF_SIZE)
  304. cnt++;
  305. }
  306. else {
  307. cnt = 1;
  308. }
  309. if (cnt == 1) {
  310. temp_desc->BL &= ~(ETH_DMA_TDES_FS | ETH_DMA_TDES_LS | ETH_DMA_TDES_TBS1);
  311. temp_desc->BL |= ETH_DMA_TDES_FS |
  312. ETH_DMA_TDES_LS |
  313. (len & ETH_DMA_TDES_TBS1);
  314. temp_desc->CS |= ETH_DMA_TDES_OWN;
  315. temp_desc = (ETH_DMADESCTypeDef*)(temp_desc->BUF2NDADDR);
  316. }
  317. else {
  318. for (i = 0; i < cnt; i++) {
  319. temp_desc->BL &= ~(ETH_DMA_TDES_FS | ETH_DMA_TDES_LS);
  320. if (i == 0)
  321. temp_desc->BL |= ETH_DMA_TDES_FS;
  322. temp_desc->BL = ETH_TX_BUF_SIZE & ETH_DMA_TDES_TBS1;
  323. if (i == (cnt - 1)) {
  324. temp_desc->BL &= ~ETH_DMA_TDES_TBS1;
  325. temp_desc->BL |= ETH_DMA_TDES_LS |
  326. ((len - (cnt - 1) * ETH_TX_BUF_SIZE) & ETH_DMA_TDES_TBS1);
  327. }
  328. temp_desc->CS |= ETH_DMA_TDES_OWN;
  329. temp_desc = (ETH_DMADESCTypeDef*)(temp_desc->BUF2NDADDR);
  330. }
  331. }
  332. DMATxDescToSet = temp_desc;
  333. if (ETH->DMASR & ETH_DMASR_TBUS) {
  334. ETH->DMASR = ETH_DMASR_TBUS;
  335. ETH->DMATPDR = 0;
  336. }
  337. return ETH_SUCCESS;
  338. }
  339. void ETH_DMARxDescChainInit(ETH_DMADESCTypeDef* ptr_desc, u8* buf, u32 cnt)
  340. {
  341. u32 i = 0;
  342. ETH_DMADESCTypeDef* temp_desc;
  343. DMARxDescToGet = ptr_desc;
  344. for (i = 0; i < cnt; i++) {
  345. temp_desc = ptr_desc + i;
  346. temp_desc->CS = ETH_DMA_RDES_OWN;
  347. temp_desc->BL = ETH_DMA_RDES_RCH | ETH_RX_BUF_SIZE;
  348. temp_desc->BUF1ADDR = (u32)&buf[i * ETH_RX_BUF_SIZE];
  349. if (i < cnt - 1) {
  350. temp_desc->BUF2NDADDR = (u32)(ptr_desc + i + 1);
  351. }
  352. else {
  353. temp_desc->BUF2NDADDR = (u32)(ptr_desc);
  354. }
  355. }
  356. ETH->DMARDLAR = (u32)ptr_desc;
  357. DMA_RX_FRAME_infos = &RX_Frame_Descriptor;
  358. }
  359. u32 ETH_CheckFrameReceived(void)
  360. {
  361. if(!(DMARxDescToGet->CS & ETH_DMA_RDES_OWN) &&
  362. (DMARxDescToGet->CS & ETH_DMA_RDES_LS)) {
  363. DMA_RX_FRAME_infos->cnt++;
  364. if (DMA_RX_FRAME_infos->cnt == 1) {
  365. DMA_RX_FRAME_infos->ptrFS_Rx_Desc = DMARxDescToGet;
  366. }
  367. DMA_RX_FRAME_infos->ptrLS_Rx_Desc = DMARxDescToGet;
  368. return 1;
  369. }
  370. else if ( !(DMARxDescToGet->CS & ETH_DMA_RDES_OWN) &&
  371. !(DMARxDescToGet->CS & ETH_DMA_RDES_LS) &&
  372. (DMARxDescToGet->CS & ETH_DMA_RDES_FS)) {
  373. DMA_RX_FRAME_infos->ptrFS_Rx_Desc = DMARxDescToGet;
  374. DMA_RX_FRAME_infos->ptrLS_Rx_Desc = (void*)0;
  375. DMA_RX_FRAME_infos->cnt = 1;
  376. }
  377. else if ( !(DMARxDescToGet->CS & ETH_DMA_RDES_OWN) &&
  378. !(DMARxDescToGet->CS & ETH_DMA_RDES_LS) &&
  379. !(DMARxDescToGet->CS & ETH_DMA_RDES_FS)) {
  380. DMA_RX_FRAME_infos->cnt++;
  381. DMARxDescToGet = (ETH_DMADESCTypeDef*)(DMARxDescToGet->BUF2NDADDR);
  382. }
  383. return 0;
  384. }
  385. void ETH_DMATxDescChainInit(ETH_DMADESCTypeDef* ptr_desc, u8* buf, u32 cnt)
  386. {
  387. u32 i = 0;
  388. ETH_DMADESCTypeDef* temp_desc;
  389. DMATxDescToSet = ptr_desc;
  390. for (i = 0; i < cnt; i++) {
  391. temp_desc = ptr_desc + i;
  392. temp_desc->BL = ETH_DMA_TDES_TCH;
  393. temp_desc->BUF1ADDR = (u32)(&buf[i * ETH_TX_BUF_SIZE]);
  394. if (i < cnt - 1) {
  395. temp_desc->BUF2NDADDR = (u32)(ptr_desc + i + 1);
  396. }
  397. else {
  398. temp_desc->BUF2NDADDR = (u32)(ptr_desc);
  399. }
  400. }
  401. ETH->DMATDLAR = (u32)ptr_desc;
  402. }
  403. FlagStatus ETH_GetDMATxDescFlagStatus(ETH_DMADESCTypeDef* ptr_desc, u32 flag)
  404. {
  405. return (FlagStatus)(ptr_desc->CS & flag);
  406. }
  407. u32 ETH_GetDMATxDescCollisionCount(ETH_DMADESCTypeDef* ptr_desc)
  408. {
  409. return (ptr_desc->CS & ETH_DMA_TDES_CC) >> ETH_DMA_TDES_COLLISION_COUNTSHIFT;
  410. }
  411. void ETH_SetDMATxDescOwnBit(ETH_DMADESCTypeDef* ptr_desc)
  412. {
  413. ptr_desc->CS |= ETH_DMA_TDES_OWN;
  414. }
  415. void ETH_DMATxDescTransmitITConfig(ETH_DMADESCTypeDef* ptr_desc, FunctionalState sta)
  416. {
  417. sta ? (ptr_desc->BL |= ETH_DMA_TDES_IC) : (ptr_desc->BL &= ~ETH_DMA_TDES_IC);
  418. }
  419. void ETH_DMATxDescFrameSegmentConfig(ETH_DMADESCTypeDef* ptr_desc, u32 val)
  420. {
  421. ptr_desc->CS |= val;
  422. }
  423. void ETH_DMATxDescChecksumInsertionConfig(ETH_DMADESCTypeDef* ptr_desc, u32 val)
  424. {
  425. ptr_desc->CS |= val;
  426. }
  427. void ETH_DMATxDescCRCCmd(ETH_DMADESCTypeDef* ptr_desc, FunctionalState sta)
  428. {
  429. sta ? (ptr_desc->BL &= ~ETH_DMA_TDES_DC) : (ptr_desc->BL |= ETH_DMA_TDES_DC);
  430. }
  431. void ETH_DMATxDescSecondAddressChainedCmd(ETH_DMADESCTypeDef* ptr_desc, FunctionalState sta)
  432. {
  433. sta ? (ptr_desc->BL |= ETH_DMA_TDES_TCH) : (ptr_desc->BL &= ~ETH_DMA_TDES_TCH);
  434. }
  435. void ETH_DMATxDescShortFramePaddingCmd(ETH_DMADESCTypeDef* ptr_desc, FunctionalState sta)
  436. {
  437. sta ? (ptr_desc->BL &= ~ETH_DMA_TDES_DP) : (ptr_desc->BL |= ETH_DMA_TDES_DP);
  438. }
  439. void ETH_DMATxDescBufferSizeConfig(ETH_DMADESCTypeDef* ptr_desc, u32 buf1_size, u32 buf2_size)
  440. {
  441. ptr_desc->BL |= buf1_size | (buf2_size << ETH_DMA_TDES_BUFFER2_SIZESHIFT);
  442. }
  443. FlagStatus ETH_GetDMARxDescFlagStatus(ETH_DMADESCTypeDef* ptr_desc, u32 flag)
  444. {
  445. return (FlagStatus)(ptr_desc->CS & flag);
  446. }
  447. void ETH_SetDMARxDescOwnBit(ETH_DMADESCTypeDef* ptr_desc)
  448. {
  449. ptr_desc->CS |= ETH_DMA_RDES_OWN;
  450. }
  451. u32 ETH_GetDMARxDescFrameLength(ETH_DMADESCTypeDef* ptr_desc)
  452. {
  453. return (ptr_desc->CS & ETH_DMA_RDES_FL) >> ETH_DMA_RDES_FRAME_LENGTHSHIFT;
  454. }
  455. void ETH_DMARxDescReceiveITConfig(ETH_DMADESCTypeDef* ptr_desc, FunctionalState sta)
  456. {
  457. sta ? (ptr_desc->CS &= ~ETH_DMA_RDES_DIC) : (ptr_desc->CS |= ETH_DMA_RDES_DIC);
  458. }
  459. u32 ETH_GetDMARxDescBufferSize(ETH_DMADESCTypeDef* ptr_desc, u32 buf)
  460. {
  461. return (buf != ETH_DMA_RDES_Buffer1 ?
  462. ((ptr_desc->BL & ETH_DMA_RDES_RBS2) >> ETH_DMA_RDES_BUFFER2_SIZESHIFT) :
  463. (ptr_desc->BL & ETH_DMA_RDES_RBS1));
  464. }
  465. u32 ETH_GetRxPktSize(ETH_DMADESCTypeDef* ptr_desc)
  466. {
  467. u32 len = 0;
  468. if ( !(ptr_desc->CS & ETH_DMA_RDES_OWN) &&
  469. !(ptr_desc->CS & ETH_DMA_RDES_ES) &&
  470. (ptr_desc->CS & ETH_DMA_RDES_LS)) {
  471. len = ETH_GetDMARxDescFrameLength(ptr_desc);
  472. }
  473. return len;
  474. }
  475. ////////////////////////////////////////////////////////////////////////////////
  476. void ETH_SoftwareReset(void)
  477. {
  478. ETH->DMABMR |= ETH_DMABMR_SR;
  479. }
  480. FlagStatus ETH_GetSoftwareResetStatus(void)
  481. {
  482. return (FlagStatus)(ETH->DMABMR & ETH_DMABMR_SR);
  483. }
  484. FlagStatus ETH_GetDMAFlagStatus(u32 flag)
  485. {
  486. return (FlagStatus)(ETH->DMASR & flag);
  487. }
  488. void ETH_DMAClearFlag(u32 flag)
  489. {
  490. ETH->DMASR = flag;
  491. }
  492. void ETH_DMAITConfig(u32 it, FunctionalState sta)
  493. {
  494. sta ? (ETH->DMAIER |= it) : (ETH->DMAIER &= ~it);
  495. }
  496. ITStatus ETH_GetDMAITStatus(u32 it)
  497. {
  498. return (ITStatus)(ETH->DMASR & it);
  499. }
  500. void ETH_DMAClearITPendingBit(u32 it)
  501. {
  502. ETH->DMASR = it;
  503. }
  504. u32 ETH_GetTransmitProcessState(void)
  505. {
  506. return ETH->DMASR & ETH_DMASR_TS;
  507. }
  508. u32 ETH_GetReceiveProcessState(void)
  509. {
  510. return ETH->DMASR & ETH_DMASR_RS;
  511. }
  512. void ETH_FlushTransmitFIFO(void)
  513. {
  514. ETH->DMAOMR |= ETH_DMAOMR_FTF;
  515. }
  516. FlagStatus ETH_GetFlushTransmitFIFOStatus(void)
  517. {
  518. return (FlagStatus)(ETH->DMAOMR & ETH_DMAOMR_FTF);
  519. }
  520. void ETH_DMATransmissionCmd(FunctionalState sta)
  521. {
  522. sta ? (ETH->DMAOMR |= ETH_DMAOMR_ST) : (ETH->DMAOMR &= ~ETH_DMAOMR_ST);
  523. }
  524. void ETH_DMAReceptionCmd(FunctionalState sta)
  525. {
  526. sta ? (ETH->DMAOMR |= ETH_DMAOMR_SR) : (ETH->DMAOMR &= ~ETH_DMAOMR_SR);
  527. }
  528. FlagStatus ETH_GetDMAOverflowStatus(u32 val)
  529. {
  530. return (FlagStatus)(ETH->DMAMFBOCR & val);
  531. }
  532. u32 ETH_GetRxOverflowMissedFrameCounter(void)
  533. {
  534. return (ETH->DMAMFBOCR & ETH_DMAMFBOCR_MFA) >>
  535. ETH_DMA_RX_OVERFLOW_MISSEDFRAMES_COUNTERSHIFT;
  536. }
  537. u32 ETH_GetBufferUnavailableMissedFrameCounter(void)
  538. {
  539. return ETH->DMAMFBOCR & ETH_DMAMFBOCR_MFC;
  540. }
  541. u32 ETH_GetCurrentTxDescStartAddress(void)
  542. {
  543. return ETH->DMACHTDR;
  544. }
  545. u32 ETH_GetCurrentRxDescStartAddress(void)
  546. {
  547. return ETH->DMACHRDR;
  548. }
  549. u32 ETH_GetCurrentTxBufferAddress(void)
  550. {
  551. return ETH->DMACHTBAR;
  552. }
  553. u32 ETH_GetCurrentRxBufferAddress(void)
  554. {
  555. return ETH->DMACHRBAR;
  556. }
  557. void ETH_ResumeDMATransmission(void)
  558. {
  559. ETH->DMATPDR = 0;
  560. }
  561. void ETH_ResumeDMAReception(void)
  562. {
  563. ETH->DMARPDR = 0;
  564. }
  565. void ETH_SetReceiveWatchdogTimer(u8 val)
  566. {
  567. ETH->DMARSWTR = val;
  568. }
  569. ////////////////////////////////////////////////////////////////////////////////
  570. u16 ETH_ReadPHYRegister(u16 addr, u16 reg)
  571. {
  572. u32 dat;
  573. // Set phy address and reg address, clear write flag
  574. ETH->MACMIIAR = (((ETH->MACMIIAR & ~MACMIIAR_CR_MASK) |
  575. (addr << ETH_MACMIIAR_PA_Pos & ETH_MACMIIAR_PA) |
  576. (reg << ETH_MACMIIAR_MR_Pos & ETH_MACMIIAR_MR)) &
  577. (~ETH_MACMIIAR_MW)) | ETH_MACMIIAR_MB;
  578. // Check busy flag
  579. while(ETH->MACMIIAR & ETH_MACMIIAR_MB);
  580. dat = (u16)ETH->MACMIIDR;
  581. if(dat == 0xFFFF) {
  582. dat = 0;
  583. }
  584. return dat;
  585. }
  586. u16 ETH_WritePHYRegister(u16 addr, u16 reg, u16 val)
  587. {
  588. // Load data
  589. ETH->MACMIIDR = val;
  590. // Set phy address, reg address and write flag
  591. ETH->MACMIIAR = (ETH->MACMIIAR & ~MACMIIAR_CR_MASK) |
  592. (addr << ETH_MACMIIAR_PA_Pos & ETH_MACMIIAR_PA) |
  593. (reg << ETH_MACMIIAR_MR_Pos & ETH_MACMIIAR_MR) |
  594. ETH_MACMIIAR_MW |
  595. ETH_MACMIIAR_MB;
  596. // Check busy flag
  597. while(ETH->MACMIIAR & ETH_MACMIIAR_MB);
  598. return ETH->MACMIIDR;
  599. }
  600. u32 ETH_PHYLoopBackCmd(u16 addr, FunctionalState sta)
  601. {
  602. u16 temp_val = ETH_ReadPHYRegister(addr, PHY_BCR);
  603. sta ? (temp_val |= PHY_Loopback) : (temp_val &= ~PHY_Loopback);
  604. if(ETH_WritePHYRegister(addr, PHY_BCR, temp_val))
  605. return ETH_SUCCESS;
  606. return ETH_ERROR;
  607. }
  608. ////////////////////////////////////////////////////////////////////////////////
  609. void ETH_ResetWakeUpFrameFilterRegisterPointer(void)
  610. {
  611. ETH->MACPMTCSR |= ETH_MACPMTCSR_WFFRPR;
  612. }
  613. void ETH_SetWakeUpFrameFilterRegister(u32* buf)
  614. {
  615. u32 i = 0;
  616. for (i = 0; i < ETH_WAKEUP_REGISTER_LENGTH; i++) {
  617. ETH->MACRWUFFR = buf[i];
  618. }
  619. }
  620. void ETH_GlobalUnicastWakeUpCmd(FunctionalState sta)
  621. {
  622. sta ? (ETH->MACPMTCSR |= ETH_MACPMTCSR_GU) : (ETH->MACPMTCSR &= ~ETH_MACPMTCSR_GU);
  623. }
  624. FlagStatus ETH_GetPMTFlagStatus(u32 flag)
  625. {
  626. return (FlagStatus)(ETH->MACPMTCSR & flag);
  627. }
  628. void ETH_WakeUpFrameDetectionCmd(FunctionalState sta)
  629. {
  630. sta ? (ETH->MACPMTCSR |= ETH_MACPMTCSR_WFE) : (ETH->MACPMTCSR &= ~ETH_MACPMTCSR_WFE);
  631. }
  632. void ETH_MagicPacketDetectionCmd(FunctionalState sta)
  633. {
  634. sta ? (ETH->MACPMTCSR |= ETH_MACPMTCSR_MPE) : (ETH->MACPMTCSR &= ~ETH_MACPMTCSR_MPE);
  635. }
  636. void ETH_PowerDownCmd(FunctionalState sta)
  637. {
  638. sta ? (ETH->MACPMTCSR |= ETH_MACPMTCSR_PD) : (ETH->MACPMTCSR &= ~ETH_MACPMTCSR_PD);
  639. }
  640. ////////////////////////////////////////////////////////////////////////////////
  641. void ETH_MMCCounterFullPreset(void)
  642. {
  643. ETH->MMCCR |= ETH_MMCCR_MCFHP | ETH_MMCCR_MCP;
  644. }
  645. void ETH_MMCCounterHalfPreset(void)
  646. {
  647. ETH->MMCCR &= ~ETH_MMCCR_MCFHP;
  648. ETH->MMCCR |= ETH_MMCCR_MCP;
  649. }
  650. void ETH_MMCCounterFreezeCmd(FunctionalState sta)
  651. {
  652. sta ? (ETH->MMCCR |= ETH_MMCCR_MCF) : (ETH->MMCCR &= ~ETH_MMCCR_MCF);
  653. }
  654. void ETH_MMCResetOnReadCmd(FunctionalState sta)
  655. {
  656. sta ? (ETH->MMCCR |= ETH_MMCCR_ROR) : (ETH->MMCCR &= ~ETH_MMCCR_ROR);
  657. }
  658. void ETH_MMCCounterRolloverCmd(FunctionalState sta)
  659. {
  660. sta ? (ETH->MMCCR &= ~ETH_MMCCR_CSR) : (ETH->MMCCR |= ETH_MMCCR_CSR);
  661. }
  662. void ETH_MMCCountersReset(void)
  663. {
  664. ETH->MMCCR |= ETH_MMCCR_CR;
  665. }
  666. void ETH_MMCITConfig(u32 it, FunctionalState sta)
  667. {
  668. if (it & 0x10000000) {
  669. it &= 0xEFFFFFFF;
  670. sta ? (ETH->MMCRIMR &= ~it) : (ETH->MMCRIMR |= it);
  671. }
  672. else {
  673. sta ? (ETH->MMCTIMR &= ~it) : (ETH->MMCTIMR |= it);
  674. }
  675. }
  676. ITStatus ETH_GetMMCITStatus(u32 it)
  677. {
  678. if (it & 0x10000000) {
  679. return (ITStatus)((ETH->MMCRIR & it) && !(ETH->MMCRIMR & it));
  680. }
  681. else {
  682. return (ITStatus)((ETH->MMCTIR & it) && !(ETH->MMCTIMR & it));
  683. }
  684. }
  685. u32 ETH_GetMMCRegister(u32 reg)
  686. {
  687. return *(vu32*)(ETH_BASE + reg);
  688. }