• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2   ******************************************************************************
3   * @file    stm32f4x7_eth.c
4   * @author  MCD Application Team
5   * @version V1.1.0
6   * @date    31-July-2013
7   * @brief   This file is the low level driver for STM32F4x7xx Ethernet Controller.
8   *          This driver does not include low level functions for PTP time-stamp.
9   ******************************************************************************
10   * @attention
11   *
12   * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
13   *
14   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
15   * You may not use this file except in compliance with the License.
16   * You may obtain a copy of the License at:
17   *
18   *        http://www.st.com/software_license_agreement_liberty_v2
19   *
20   * Unless required by applicable law or agreed to in writing, software
21   * distributed under the License is distributed on an "AS IS" BASIS,
22   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23   * See the License for the specific language governing permissions and
24   * limitations under the License.
25   *
26   ******************************************************************************
27   */
28 
29 /* Includes ------------------------------------------------------------------*/
30 #include "stm32f4x7_eth.h"
31 #include "stm32f4xx_rcc.h"
32 #include <string.h>
33 
34 #include "stm32f4xx_conf.h"
35 
36 /** @addtogroup STM32F4x7_ETH_Driver
37   * @brief ETH driver modules
38   * @{
39   */
40 
41 /** @defgroup ETH_Private_TypesDefinitions
42   * @{
43   */
44 /**
45   * @}
46   */
47 
48 
49 /** @defgroup ETH_Private_Defines
50   * @{
51   */
52 
53 /**
54   * @}
55   */
56 
57 /** @defgroup ETH_Private_Macros
58   * @{
59   */
60 /**
61   * @}
62   */
63 
64 /** @defgroup ETH_Private_Variables
65   * @{
66   */
67 
68 //#if defined   (__CC_ARM) /*!< ARM Compiler */
69 //  __align(4)
70 //   ETH_DMADESCTypeDef  DMARxDscrTab[ETH_RXBUFNB];/* Ethernet Rx MA Descriptor */
71 //  __align(4)
72 //   ETH_DMADESCTypeDef  DMATxDscrTab[ETH_TXBUFNB];/* Ethernet Tx DMA Descriptor */
73 //  __align(4)
74 //   uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; /* Ethernet Receive Buffer */
75 //  __align(4)
76 //   uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; /* Ethernet Transmit Buffer */
77 
78 //#elif defined ( __ICCARM__ ) /*!< IAR Compiler */
79 //  #pragma data_alignment=4
80 //   ETH_DMADESCTypeDef  DMARxDscrTab[ETH_RXBUFNB];/* Ethernet Rx MA Descriptor */
81 //  #pragma data_alignment=4
82 //   ETH_DMADESCTypeDef  DMATxDscrTab[ETH_TXBUFNB];/* Ethernet Tx DMA Descriptor */
83 //  #pragma data_alignment=4
84 //   uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; /* Ethernet Receive Buffer */
85 //  #pragma data_alignment=4
86 //   uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; /* Ethernet Transmit Buffer */
87 
88 //#elif defined (__GNUC__) /*!< GNU Compiler */
89 //  ETH_DMADESCTypeDef  DMARxDscrTab[ETH_RXBUFNB] __attribute__ ((aligned (4))); /* Ethernet Rx DMA Descriptor */
90 //  ETH_DMADESCTypeDef  DMATxDscrTab[ETH_TXBUFNB] __attribute__ ((aligned (4))); /* Ethernet Tx DMA Descriptor */
91 //  uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __attribute__ ((aligned (4))); /* Ethernet Receive Buffer */
92 //  uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __attribute__ ((aligned (4))); /* Ethernet Transmit Buffer */
93 
94 //#elif defined  (__TASKING__) /*!< TASKING Compiler */
95 //  __align(4)
96 //   ETH_DMADESCTypeDef  DMARxDscrTab[ETH_RXBUFNB];/* Ethernet Rx MA Descriptor */
97 //  __align(4)
98 //   ETH_DMADESCTypeDef  DMATxDscrTab[ETH_TXBUFNB];/* Ethernet Tx DMA Descriptor */
99 //  __align(4)
100 //   uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; /* Ethernet Receive Buffer */
101 //  __align(4)
102 //   uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; /* Ethernet Transmit Buffer */
103 
104 //#endif /* __CC_ARM */
105 
106 
107 /* Global pointers on Tx and Rx descriptor used to track transmit and receive descriptors */
108 __IO ETH_DMADESCTypeDef  *DMATxDescToSet;
109 __IO ETH_DMADESCTypeDef  *DMARxDescToGet;
110 
111 
112 /* Structure used to hold the last received packet descriptors info */
113 
114 ETH_DMA_Rx_Frame_infos RX_Frame_Descriptor;
115 __IO ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos;
116 __IO uint32_t Frame_Rx_index;
117 
118 
119 /**
120   * @}
121   */
122 
123 /** @defgroup ETH_Private_FunctionPrototypes
124   * @{
125   */
126 /**
127   * @}
128   */
129 
130 /** @defgroup ETH_Private_Functions
131   * @{
132   */
133 
134 #ifndef USE_Delay
135 /**
136   * @brief  Inserts a delay time.
137   * @param  nCount: specifies the delay time length.
138   * @retval None
139   */
ETH_Delay(__IO uint32_t nCount)140 static void ETH_Delay(__IO uint32_t nCount)
141 {
142   __IO uint32_t index = 0;
143   for(index = nCount; index != 0; index--)
144   {
145   }
146 }
147 #endif /* USE_Delay*/
148 
149 
150 
151 /******************************************************************************/
152 /*                           Global ETH MAC/DMA functions                     */
153 /******************************************************************************/
154 
155 /**
156   * @brief  Deinitializes the ETHERNET peripheral registers to their default reset values.
157   * @param  None
158   * @retval None
159   */
ETH_DeInit(void)160 void ETH_DeInit(void)
161 {
162   RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_ETH_MAC, ENABLE);
163   RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_ETH_MAC, DISABLE);
164 }
165 
166 
167 /**
168   * @brief  Fills each ETH_InitStruct member with its default value.
169   * @param  ETH_InitStruct: pointer to a ETH_InitTypeDef structure which will be initialized.
170   * @retval None
171   */
ETH_StructInit(ETH_InitTypeDef * ETH_InitStruct)172 void ETH_StructInit(ETH_InitTypeDef* ETH_InitStruct)
173 {
174   /* ETH_InitStruct members default value */
175   /*------------------------   MAC Configuration   ---------------------------*/
176 
177   /* PHY Auto-negotiation enabled */
178   ETH_InitStruct->ETH_AutoNegotiation = ETH_AutoNegotiation_Enable; 			//使能自适应模式
179   /* MAC watchdog enabled: cuts-off long frame */
180   ETH_InitStruct->ETH_Watchdog = ETH_Watchdog_Enable;										 	//使能看门�?
181   /* MAC Jabber enabled in Half-duplex mode */
182   ETH_InitStruct->ETH_Jabber = ETH_Jabber_Enable;       									//使能Jabber
183   /* Ethernet interframe gap set to 96 bits */
184   ETH_InitStruct->ETH_InterFrameGap = ETH_InterFrameGap_96Bit;  					//设置帧间隔为96bit
185   /* Carrier Sense Enabled in Half-Duplex mode */
186   ETH_InitStruct->ETH_CarrierSense = ETH_CarrierSense_Enable; 						//半双工模式下使能载波侦听功能
187   /* PHY speed configured to 100Mbit/s */
188   ETH_InitStruct->ETH_Speed = ETH_Speed_100M; 														//PHY层速度�?00M
189   /* Receive own Frames in Half-Duplex mode enabled */
190   ETH_InitStruct->ETH_ReceiveOwn = ETH_ReceiveOwn_Enable;                	//半双工模式下允许接收 own frame
191   /* MAC MII loopback disabled */
192   ETH_InitStruct->ETH_LoopbackMode = ETH_LoopbackMode_Disable; 						//关闭MII接口的反馈功�?
193   /* Full-Duplex mode selected */
194   ETH_InitStruct->ETH_Mode = ETH_Mode_FullDuplex;   											//使用全双工模�?
195   /* IPv4 and TCP/UDP/ICMP frame Checksum Offload disabled */
196   ETH_InitStruct->ETH_ChecksumOffload = ETH_ChecksumOffload_Disable;   		//关闭ipv4和TCP/UDP/ICMP的帧校验和卸�?
197   /* Retry Transmission enabled for half-duplex mode */
198   ETH_InitStruct->ETH_RetryTransmission = ETH_RetryTransmission_Enable;   //开启半双工模式下的重试传输功能
199   /* Automatic PAD/CRC strip disabled*/
200   ETH_InitStruct->ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;  //关闭自动去除PDA/CRC功能
201   /* half-duplex mode retransmission Backoff time_limit = 10 slot times*/
202   ETH_InitStruct->ETH_BackOffLimit = ETH_BackOffLimit_10;     						//设置半双工模式下的最大重传回退事件10 slot times
203   /* half-duplex mode Deferral check disabled */
204   ETH_InitStruct->ETH_DeferralCheck = ETH_DeferralCheck_Disable;          //关闭半双工模式下的延时检查功�?
205   /* Receive all frames disabled */
206   ETH_InitStruct->ETH_ReceiveAll = ETH_ReceiveAll_Disable;								//禁止接收所有帧
207   /* Source address filtering (on the optional MAC addresses) disabled */
208   ETH_InitStruct->ETH_SourceAddrFilter = ETH_SourceAddrFilter_Disable;   	//关闭MAC地址的源地址过滤功能
209   /* Do not forward control frames that do not pass the address filtering */
210   ETH_InitStruct->ETH_PassControlFrames = ETH_PassControlFrames_BlockAll; //
211   /* Disable reception of Broadcast frames */
212   ETH_InitStruct->ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Disable;//禁止接收所有的广播�?
213   /* Normal Destination address filtering (not reverse addressing) */
214   ETH_InitStruct->ETH_DestinationAddrFilter = ETH_DestinationAddrFilter_Normal;			//正常的远端地址过滤
215   /* Promiscuous address filtering mode disabled */
216   ETH_InitStruct->ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;			//关闭混合模式的地址过滤
217   /* Perfect address filtering for multicast addresses */
218   ETH_InitStruct->ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;  //对于组播地址使用完美地址过滤
219   /* Perfect address filtering for unicast addresses */
220   ETH_InitStruct->ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;     	//对单播地址使用完美地址过滤
221   /* Initialize hash table high and low regs */
222   ETH_InitStruct->ETH_HashTableHigh = 0x0;   											//初始化HASH表的高位寄存�?
223   ETH_InitStruct->ETH_HashTableLow = 0x0;                     		//初始化HASH表的低位位寄存器
224   /* Flow control config (flow control disabled)*/
225   ETH_InitStruct->ETH_PauseTime = 0x0;                 					//流控配置
226   ETH_InitStruct->ETH_ZeroQuantaPause = ETH_ZeroQuantaPause_Disable;
227   ETH_InitStruct->ETH_PauseLowThreshold = ETH_PauseLowThreshold_Minus4;
228   ETH_InitStruct->ETH_UnicastPauseFrameDetect = ETH_UnicastPauseFrameDetect_Disable;
229   ETH_InitStruct->ETH_ReceiveFlowControl = ETH_ReceiveFlowControl_Disable;
230   ETH_InitStruct->ETH_TransmitFlowControl = ETH_TransmitFlowControl_Disable;
231   /* VLANtag config (VLAN field not checked) */
232   ETH_InitStruct->ETH_VLANTagComparison = ETH_VLANTagComparison_16Bit;
233   ETH_InitStruct->ETH_VLANTagIdentifier = 0x0;
234 
235   /*---------------------- DMA Configuration   -------------------------------*/
236 
237   /* Drops frames with with TCP/IP checksum errors */
238   ETH_InitStruct->ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Disable; //关闭丢弃TCP/IP错误�?
239   /* Store and forward mode enabled for receive */
240   ETH_InitStruct->ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable;       //开启接收数据的存储转发功能
241   /* Flush received frame that created FIFO overflow */
242   ETH_InitStruct->ETH_FlushReceivedFrame = ETH_FlushReceivedFrame_Enable;
243   /* Store and forward mode enabled for transmit */
244   ETH_InitStruct->ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable;   	//开启发送模式的存储转发功能
245   /* Threshold TXFIFO level set to 64 bytes (used when threshold mode is enabled) */
246   ETH_InitStruct->ETH_TransmitThresholdControl = ETH_TransmitThresholdControl_64Bytes;  //设置阈值模式下的发送FIFO的阈值为64字节
247   /* Disable forwarding frames with errors (short frames, CRC,...)*/
248   ETH_InitStruct->ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable;   //禁止转发错误�?
249   /* Disable undersized good frames */
250   ETH_InitStruct->ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable; //不转发过小的好帧
251   /* Threshold RXFIFO level set to 64 bytes (used when Cut-through mode is enabled) */
252   ETH_InitStruct->ETH_ReceiveThresholdControl = ETH_ReceiveThresholdControl_64Bytes;    //设置直通模式下的发送FIFO阈值为64字节
253   /* Disable Operate on second frame (transmit a second frame to FIFO without
254   waiting status of previous frame*/
255   ETH_InitStruct->ETH_SecondFrameOperate = ETH_SecondFrameOperate_Disable;							//关闭处理第二帧数�?
256   /* DMA works on 32-bit aligned start source and destinations addresses */
257   ETH_InitStruct->ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable;						//开启DMA传输的地址对齐功能
258   /* Enabled Fixed Burst Mode (mix of INC4, INC8, INC16 and SINGLE DMA transactions */
259   ETH_InitStruct->ETH_FixedBurst = ETH_FixedBurst_Enable;    												//开启固定突发功�?
260   /* DMA transfer max burst length = 32 beats = 32 x 32bits */
261   ETH_InitStruct->ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat;    //DMA发送的最大突发长度为32
262   ETH_InitStruct->ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat;    //DMA接收的最大突发长度为32
263   /* DMA Ring mode skip length = 0 */
264   ETH_InitStruct->ETH_DescriptorSkipLength = 0x0;
265   /* Equal priority (round-robin) between transmit and receive DMA engines */
266   ETH_InitStruct->ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_1_1;
267 }
268 
269 
270 /**
271   * @brief  Initializes the ETHERNET peripheral according to the specified
272   *   parameters in the ETH_InitStruct .
273   * @param ETH_InitStruct: pointer to a ETH_InitTypeDef structure that contains
274   *   the configuration information for the specified ETHERNET peripheral.
275   * @param PHYAddress: external PHY address
276   * @retval ETH_ERROR: Ethernet initialization failed
277   *         ETH_SUCCESS: Ethernet successfully initialized
278   */
ETH_Init(ETH_InitTypeDef * ETH_InitStruct,uint16_t PHYAddress)279 uint32_t ETH_Init(ETH_InitTypeDef* ETH_InitStruct, uint16_t PHYAddress)
280 {
281   uint32_t RegValue = 0, tmpreg = 0;
282   __IO uint32_t i = 0;
283   RCC_ClocksTypeDef  rcc_clocks;
284   uint32_t hclk = 60000000;
285   __IO uint32_t timeout = 0;
286   /* Check the parameters */
287   /* MAC --------------------------*/
288   assert_param(IS_ETH_AUTONEGOTIATION(ETH_InitStruct->ETH_AutoNegotiation));
289   assert_param(IS_ETH_WATCHDOG(ETH_InitStruct->ETH_Watchdog));
290   assert_param(IS_ETH_JABBER(ETH_InitStruct->ETH_Jabber));
291   assert_param(IS_ETH_INTER_FRAME_GAP(ETH_InitStruct->ETH_InterFrameGap));
292   assert_param(IS_ETH_CARRIER_SENSE(ETH_InitStruct->ETH_CarrierSense));
293   assert_param(IS_ETH_SPEED(ETH_InitStruct->ETH_Speed));
294   assert_param(IS_ETH_RECEIVE_OWN(ETH_InitStruct->ETH_ReceiveOwn));
295   assert_param(IS_ETH_LOOPBACK_MODE(ETH_InitStruct->ETH_LoopbackMode));
296   assert_param(IS_ETH_DUPLEX_MODE(ETH_InitStruct->ETH_Mode));
297   assert_param(IS_ETH_CHECKSUM_OFFLOAD(ETH_InitStruct->ETH_ChecksumOffload));
298   assert_param(IS_ETH_RETRY_TRANSMISSION(ETH_InitStruct->ETH_RetryTransmission));
299   assert_param(IS_ETH_AUTOMATIC_PADCRC_STRIP(ETH_InitStruct->ETH_AutomaticPadCRCStrip));
300   assert_param(IS_ETH_BACKOFF_LIMIT(ETH_InitStruct->ETH_BackOffLimit));
301   assert_param(IS_ETH_DEFERRAL_CHECK(ETH_InitStruct->ETH_DeferralCheck));
302   assert_param(IS_ETH_RECEIVE_ALL(ETH_InitStruct->ETH_ReceiveAll));
303   assert_param(IS_ETH_SOURCE_ADDR_FILTER(ETH_InitStruct->ETH_SourceAddrFilter));
304   assert_param(IS_ETH_CONTROL_FRAMES(ETH_InitStruct->ETH_PassControlFrames));
305   assert_param(IS_ETH_BROADCAST_FRAMES_RECEPTION(ETH_InitStruct->ETH_BroadcastFramesReception));
306   assert_param(IS_ETH_DESTINATION_ADDR_FILTER(ETH_InitStruct->ETH_DestinationAddrFilter));
307   assert_param(IS_ETH_PROMISCIOUS_MODE(ETH_InitStruct->ETH_PromiscuousMode));
308   assert_param(IS_ETH_MULTICAST_FRAMES_FILTER(ETH_InitStruct->ETH_MulticastFramesFilter));
309   assert_param(IS_ETH_UNICAST_FRAMES_FILTER(ETH_InitStruct->ETH_UnicastFramesFilter));
310   assert_param(IS_ETH_PAUSE_TIME(ETH_InitStruct->ETH_PauseTime));
311   assert_param(IS_ETH_ZEROQUANTA_PAUSE(ETH_InitStruct->ETH_ZeroQuantaPause));
312   assert_param(IS_ETH_PAUSE_LOW_THRESHOLD(ETH_InitStruct->ETH_PauseLowThreshold));
313   assert_param(IS_ETH_UNICAST_PAUSE_FRAME_DETECT(ETH_InitStruct->ETH_UnicastPauseFrameDetect));
314   assert_param(IS_ETH_RECEIVE_FLOWCONTROL(ETH_InitStruct->ETH_ReceiveFlowControl));
315   assert_param(IS_ETH_TRANSMIT_FLOWCONTROL(ETH_InitStruct->ETH_TransmitFlowControl));
316   assert_param(IS_ETH_VLAN_TAG_COMPARISON(ETH_InitStruct->ETH_VLANTagComparison));
317   assert_param(IS_ETH_VLAN_TAG_IDENTIFIER(ETH_InitStruct->ETH_VLANTagIdentifier));
318   /* DMA --------------------------*/
319   assert_param(IS_ETH_DROP_TCPIP_CHECKSUM_FRAME(ETH_InitStruct->ETH_DropTCPIPChecksumErrorFrame));
320   assert_param(IS_ETH_RECEIVE_STORE_FORWARD(ETH_InitStruct->ETH_ReceiveStoreForward));
321   assert_param(IS_ETH_FLUSH_RECEIVE_FRAME(ETH_InitStruct->ETH_FlushReceivedFrame));
322   assert_param(IS_ETH_TRANSMIT_STORE_FORWARD(ETH_InitStruct->ETH_TransmitStoreForward));
323   assert_param(IS_ETH_TRANSMIT_THRESHOLD_CONTROL(ETH_InitStruct->ETH_TransmitThresholdControl));
324   assert_param(IS_ETH_FORWARD_ERROR_FRAMES(ETH_InitStruct->ETH_ForwardErrorFrames));
325   assert_param(IS_ETH_FORWARD_UNDERSIZED_GOOD_FRAMES(ETH_InitStruct->ETH_ForwardUndersizedGoodFrames));
326   assert_param(IS_ETH_RECEIVE_THRESHOLD_CONTROL(ETH_InitStruct->ETH_ReceiveThresholdControl));
327   assert_param(IS_ETH_SECOND_FRAME_OPERATE(ETH_InitStruct->ETH_SecondFrameOperate));
328   assert_param(IS_ETH_ADDRESS_ALIGNED_BEATS(ETH_InitStruct->ETH_AddressAlignedBeats));
329   assert_param(IS_ETH_FIXED_BURST(ETH_InitStruct->ETH_FixedBurst));
330   assert_param(IS_ETH_RXDMA_BURST_LENGTH(ETH_InitStruct->ETH_RxDMABurstLength));
331   assert_param(IS_ETH_TXDMA_BURST_LENGTH(ETH_InitStruct->ETH_TxDMABurstLength));
332   assert_param(IS_ETH_DMA_DESC_SKIP_LENGTH(ETH_InitStruct->ETH_DescriptorSkipLength));
333   assert_param(IS_ETH_DMA_ARBITRATION_ROUNDROBIN_RXTX(ETH_InitStruct->ETH_DMAArbitration));
334   /*-------------------------------- MAC Config ------------------------------*/
335   /*---------------------- ETHERNET MACMIIAR Configuration -------------------*/
336   /* Get the ETHERNET MACMIIAR value */
337   tmpreg = ETH->MACMIIAR;
338   /* Clear CSR Clock Range CR[2:0] bits */
339   tmpreg &= MACMIIAR_CR_MASK;
340   /* Get hclk frequency value */
341   RCC_GetClocksFreq(&rcc_clocks);
342   hclk = rcc_clocks.HCLK_Frequency;
343 
344   /* Set CR bits depending on hclk value */
345   if((hclk >= 20000000)&&(hclk < 35000000))
346   {
347     /* CSR Clock Range between 20-35 MHz */
348     tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div16;
349   }
350   else if((hclk >= 35000000)&&(hclk < 60000000))
351   {
352     /* CSR Clock Range between 35-60 MHz */
353     tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div26;
354   }
355   else if((hclk >= 60000000)&&(hclk < 100000000))
356   {
357     /* CSR Clock Range between 60-100 MHz */
358     tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div42;
359   }
360   else if((hclk >= 100000000)&&(hclk < 150000000))
361   {
362     /* CSR Clock Range between 100-150 MHz */
363     tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div62;
364   }
365   else /* ((hclk >= 150000000)&&(hclk <= 168000000)) */
366   {
367     /* CSR Clock Range between 150-168 MHz */
368     tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div102;
369   }
370 
371   /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
372   ETH->MACMIIAR = (uint32_t)tmpreg;
373   /*-------------------- PHY initialization and configuration ----------------*/
374   /* Put the PHY in reset mode */
375   if(!(ETH_WritePHYRegister(PHYAddress, PHY_BCR, PHY_Reset)))
376   {
377     /* Return ERROR in case of write timeout */
378     return ETH_ERROR;
379   }
380 
381   /* Delay to assure PHY reset */
382   _eth_delay_(PHY_RESET_DELAY);
383 
384   if(ETH_InitStruct->ETH_AutoNegotiation != ETH_AutoNegotiation_Disable)
385   {
386     /* We wait for linked status... */
387     do
388     {
389       timeout++;
390     } while (!(ETH_ReadPHYRegister(PHYAddress, PHY_BSR) & PHY_Linked_Status) && (timeout < PHY_READ_TO));
391 
392     /* Return ERROR in case of timeout */
393     if(timeout == PHY_READ_TO)
394     {
395       return ETH_ERROR;
396     }
397 
398     /* Reset Timeout counter */
399     timeout = 0;
400     /* Enable Auto-Negotiation */
401     if(!(ETH_WritePHYRegister(PHYAddress, PHY_BCR, PHY_AutoNegotiation)))
402     {
403       /* Return ERROR in case of write timeout */
404       return ETH_ERROR;
405     }
406 
407     /* Wait until the auto-negotiation will be completed */
408     do
409     {
410       timeout++;
411     } while (!(ETH_ReadPHYRegister(PHYAddress, PHY_BSR) & PHY_AutoNego_Complete) && (timeout < (uint32_t)PHY_READ_TO));
412 
413     /* Return ERROR in case of timeout */
414     if(timeout == PHY_READ_TO)
415     {
416       return ETH_ERROR;
417     }
418 
419     /* Reset Timeout counter */
420     timeout = 0;
421 
422     /* Read the result of the auto-negotiation */
423     RegValue = ETH_ReadPHYRegister(PHYAddress, PHY_SR);
424 
425     /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */
426     if((RegValue & PHY_DUPLEX_STATUS) != (uint32_t)RESET)
427     {
428       /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
429       ETH_InitStruct->ETH_Mode = ETH_Mode_FullDuplex;
430     }
431     else
432     {
433       /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */
434       ETH_InitStruct->ETH_Mode = ETH_Mode_HalfDuplex;
435     }
436 
437     /* Configure the MAC with the speed fixed by the auto-negotiation process */
438     if(RegValue & PHY_SPEED_STATUS)
439     {
440       /* Set Ethernet speed to 10M following the auto-negotiation */
441       ETH_InitStruct->ETH_Speed = ETH_Speed_10M;
442     }
443     else
444     {
445       /* Set Ethernet speed to 100M following the auto-negotiation */
446       ETH_InitStruct->ETH_Speed = ETH_Speed_100M;
447     }
448   }
449   else
450   {
451     if(!ETH_WritePHYRegister(PHYAddress, PHY_BCR, ((uint16_t)(ETH_InitStruct->ETH_Mode >> 3) |
452                                                    (uint16_t)(ETH_InitStruct->ETH_Speed >> 1))))
453     {
454       /* Return ERROR in case of write timeout */
455       return ETH_ERROR;
456     }
457     /* Delay to assure PHY configuration */
458     _eth_delay_(PHY_CONFIG_DELAY);
459 
460   }
461   /*------------------------ ETHERNET MACCR Configuration --------------------*/
462   /* Get the ETHERNET MACCR value */
463   tmpreg = ETH->MACCR;
464   /* Clear WD, PCE, PS, TE and RE bits */
465   tmpreg &= MACCR_CLEAR_MASK;
466   /* Set the WD bit according to ETH_Watchdog value */
467   /* Set the JD: bit according to ETH_Jabber value */
468   /* Set the IFG bit according to ETH_InterFrameGap value */
469   /* Set the DCRS bit according to ETH_CarrierSense value */
470   /* Set the FES bit according to ETH_Speed value */
471   /* Set the DO bit according to ETH_ReceiveOwn value */
472   /* Set the LM bit according to ETH_LoopbackMode value */
473   /* Set the DM bit according to ETH_Mode value */
474   /* Set the IPCO bit according to ETH_ChecksumOffload value */
475   /* Set the DR bit according to ETH_RetryTransmission value */
476   /* Set the ACS bit according to ETH_AutomaticPadCRCStrip value */
477   /* Set the BL bit according to ETH_BackOffLimit value */
478   /* Set the DC bit according to ETH_DeferralCheck value */
479   tmpreg |= (uint32_t)(ETH_InitStruct->ETH_Watchdog |
480                   ETH_InitStruct->ETH_Jabber |
481                   ETH_InitStruct->ETH_InterFrameGap |
482                   ETH_InitStruct->ETH_CarrierSense |
483                   ETH_InitStruct->ETH_Speed |
484                   ETH_InitStruct->ETH_ReceiveOwn |
485                   ETH_InitStruct->ETH_LoopbackMode |
486                   ETH_InitStruct->ETH_Mode |
487                   ETH_InitStruct->ETH_ChecksumOffload |
488                   ETH_InitStruct->ETH_RetryTransmission |
489                   ETH_InitStruct->ETH_AutomaticPadCRCStrip |
490                   ETH_InitStruct->ETH_BackOffLimit |
491                   ETH_InitStruct->ETH_DeferralCheck);
492   /* Write to ETHERNET MACCR */
493   ETH->MACCR = (uint32_t)tmpreg;
494 
495   /*----------------------- ETHERNET MACFFR Configuration --------------------*/
496   /* Set the RA bit according to ETH_ReceiveAll value */
497   /* Set the SAF and SAIF bits according to ETH_SourceAddrFilter value */
498   /* Set the PCF bit according to ETH_PassControlFrames value */
499   /* Set the DBF bit according to ETH_BroadcastFramesReception value */
500   /* Set the DAIF bit according to ETH_DestinationAddrFilter value */
501   /* Set the PR bit according to ETH_PromiscuousMode value */
502   /* Set the PM, HMC and HPF bits according to ETH_MulticastFramesFilter value */
503   /* Set the HUC and HPF bits according to ETH_UnicastFramesFilter value */
504   /* Write to ETHERNET MACFFR */
505   ETH->MACFFR = (uint32_t)(ETH_InitStruct->ETH_ReceiveAll |
506                           ETH_InitStruct->ETH_SourceAddrFilter |
507                           ETH_InitStruct->ETH_PassControlFrames |
508                           ETH_InitStruct->ETH_BroadcastFramesReception |
509                           ETH_InitStruct->ETH_DestinationAddrFilter |
510                           ETH_InitStruct->ETH_PromiscuousMode |
511                           ETH_InitStruct->ETH_MulticastFramesFilter |
512                           ETH_InitStruct->ETH_UnicastFramesFilter);
513   /*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/
514   /* Write to ETHERNET MACHTHR */
515   ETH->MACHTHR = (uint32_t)ETH_InitStruct->ETH_HashTableHigh;
516   /* Write to ETHERNET MACHTLR */
517   ETH->MACHTLR = (uint32_t)ETH_InitStruct->ETH_HashTableLow;
518   /*----------------------- ETHERNET MACFCR Configuration --------------------*/
519   /* Get the ETHERNET MACFCR value */
520   tmpreg = ETH->MACFCR;
521   /* Clear xx bits */
522   tmpreg &= MACFCR_CLEAR_MASK;
523 
524   /* Set the PT bit according to ETH_PauseTime value */
525   /* Set the DZPQ bit according to ETH_ZeroQuantaPause value */
526   /* Set the PLT bit according to ETH_PauseLowThreshold value */
527   /* Set the UP bit according to ETH_UnicastPauseFrameDetect value */
528   /* Set the RFE bit according to ETH_ReceiveFlowControl value */
529   /* Set the TFE bit according to ETH_TransmitFlowControl value */
530   tmpreg |= (uint32_t)((ETH_InitStruct->ETH_PauseTime << 16) |
531                    ETH_InitStruct->ETH_ZeroQuantaPause |
532                    ETH_InitStruct->ETH_PauseLowThreshold |
533                    ETH_InitStruct->ETH_UnicastPauseFrameDetect |
534                    ETH_InitStruct->ETH_ReceiveFlowControl |
535                    ETH_InitStruct->ETH_TransmitFlowControl);
536   /* Write to ETHERNET MACFCR */
537   ETH->MACFCR = (uint32_t)tmpreg;
538   /*----------------------- ETHERNET MACVLANTR Configuration -----------------*/
539   /* Set the ETV bit according to ETH_VLANTagComparison value */
540   /* Set the VL bit according to ETH_VLANTagIdentifier value */
541   ETH->MACVLANTR = (uint32_t)(ETH_InitStruct->ETH_VLANTagComparison |
542                              ETH_InitStruct->ETH_VLANTagIdentifier);
543 
544   /*-------------------------------- DMA Config ------------------------------*/
545   /*----------------------- ETHERNET DMAOMR Configuration --------------------*/
546   /* Get the ETHERNET DMAOMR value */
547   tmpreg = ETH->DMAOMR;
548   /* Clear xx bits */
549   tmpreg &= DMAOMR_CLEAR_MASK;
550 
551   /* Set the DT bit according to ETH_DropTCPIPChecksumErrorFrame value */
552   /* Set the RSF bit according to ETH_ReceiveStoreForward value */
553   /* Set the DFF bit according to ETH_FlushReceivedFrame value */
554   /* Set the TSF bit according to ETH_TransmitStoreForward value */
555   /* Set the TTC bit according to ETH_TransmitThresholdControl value */
556   /* Set the FEF bit according to ETH_ForwardErrorFrames value */
557   /* Set the FUF bit according to ETH_ForwardUndersizedGoodFrames value */
558   /* Set the RTC bit according to ETH_ReceiveThresholdControl value */
559   /* Set the OSF bit according to ETH_SecondFrameOperate value */
560   tmpreg |= (uint32_t)(ETH_InitStruct->ETH_DropTCPIPChecksumErrorFrame |
561                   ETH_InitStruct->ETH_ReceiveStoreForward |
562                   ETH_InitStruct->ETH_FlushReceivedFrame |
563                   ETH_InitStruct->ETH_TransmitStoreForward |
564                   ETH_InitStruct->ETH_TransmitThresholdControl |
565                   ETH_InitStruct->ETH_ForwardErrorFrames |
566                   ETH_InitStruct->ETH_ForwardUndersizedGoodFrames |
567                   ETH_InitStruct->ETH_ReceiveThresholdControl |
568                   ETH_InitStruct->ETH_SecondFrameOperate);
569   /* Write to ETHERNET DMAOMR */
570   ETH->DMAOMR = (uint32_t)tmpreg;
571 
572   /*----------------------- ETHERNET DMABMR Configuration --------------------*/
573   /* Set the AAL bit according to ETH_AddressAlignedBeats value */
574   /* Set the FB bit according to ETH_FixedBurst value */
575   /* Set the RPBL and 4*PBL bits according to ETH_RxDMABurstLength value */
576   /* Set the PBL and 4*PBL bits according to ETH_TxDMABurstLength value */
577   /* Set the DSL bit according to ETH_DesciptorSkipLength value */
578   /* Set the PR and DA bits according to ETH_DMAArbitration value */
579   ETH->DMABMR = (uint32_t)(ETH_InitStruct->ETH_AddressAlignedBeats |
580                           ETH_InitStruct->ETH_FixedBurst |
581                           ETH_InitStruct->ETH_RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
582                           ETH_InitStruct->ETH_TxDMABurstLength |
583                          (ETH_InitStruct->ETH_DescriptorSkipLength << 2) |
584                           ETH_InitStruct->ETH_DMAArbitration |
585                           ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
586 
587   #ifdef USE_ENHANCED_DMA_DESCRIPTORS
588     /* Enable the Enhanced DMA descriptors */
589     ETH->DMABMR |= ETH_DMABMR_EDE;
590   #endif /* USE_ENHANCED_DMA_DESCRIPTORS */
591 
592   /* Return Ethernet configuration success */
593   return ETH_SUCCESS;
594 }
595 
596 /**
597   * @brief  Enables ENET MAC and DMA reception/transmission
598   * @param  None
599   * @retval None
600   */
ETH_Start(void)601 void ETH_Start(void)
602 {
603   /* Enable transmit state machine of the MAC for transmission on the MII */
604   ETH_MACTransmissionCmd(ENABLE);
605   /* Flush Transmit FIFO */
606   ETH_FlushTransmitFIFO();
607   /* Enable receive state machine of the MAC for reception from the MII */
608   ETH_MACReceptionCmd(ENABLE);
609 
610   /* Start DMA transmission */
611   ETH_DMATransmissionCmd(ENABLE);
612   /* Start DMA reception */
613   ETH_DMAReceptionCmd(ENABLE);
614 }
615 
616 
617 /**
618   * @brief  Enables or disables the MAC transmission.
619   * @param  NewState: new state of the MAC transmission.
620   *   This parameter can be: ENABLE or DISABLE.
621   * @retval None
622   */
ETH_MACTransmissionCmd(FunctionalState NewState)623 void ETH_MACTransmissionCmd(FunctionalState NewState)
624 {
625   /* Check the parameters */
626   assert_param(IS_FUNCTIONAL_STATE(NewState));
627 
628   if (NewState != DISABLE)
629   {
630     /* Enable the MAC transmission */
631     ETH->MACCR |= ETH_MACCR_TE;
632   }
633   else
634   {
635     /* Disable the MAC transmission */
636     ETH->MACCR &= ~ETH_MACCR_TE;
637   }
638 }
639 
640 
641 /**
642   * @brief  Enables or disables the MAC reception.
643   * @param  NewState: new state of the MAC reception.
644   *   This parameter can be: ENABLE or DISABLE.
645   * @retval None
646   */
ETH_MACReceptionCmd(FunctionalState NewState)647 void ETH_MACReceptionCmd(FunctionalState NewState)
648 {
649   /* Check the parameters */
650   assert_param(IS_FUNCTIONAL_STATE(NewState));
651 
652   if (NewState != DISABLE)
653   {
654     /* Enable the MAC reception */
655     ETH->MACCR |= ETH_MACCR_RE;
656   }
657   else
658   {
659     /* Disable the MAC reception */
660     ETH->MACCR &= ~ETH_MACCR_RE;
661   }
662 }
663 
664 
665 /**
666   * @brief  Checks whether the ETHERNET flow control busy bit is set or not.
667   * @param  None
668   * @retval The new state of flow control busy status bit (SET or RESET).
669   */
ETH_GetFlowControlBusyStatus(void)670 FlagStatus ETH_GetFlowControlBusyStatus(void)
671 {
672   FlagStatus bitstatus = RESET;
673   /* The Flow Control register should not be written to until this bit is cleared */
674   if ((ETH->MACFCR & ETH_MACFCR_FCBBPA) != (uint32_t)RESET)
675   {
676     bitstatus = SET;
677   }
678   else
679   {
680     bitstatus = RESET;
681   }
682   return bitstatus;
683 }
684 
685 
686 /**
687   * @brief  Initiate a Pause Control Frame (Full-duplex only).
688   * @param  None
689   * @retval None
690   */
ETH_InitiatePauseControlFrame(void)691 void ETH_InitiatePauseControlFrame(void)
692 {
693   /* When Set In full duplex MAC initiates pause control frame */
694   ETH->MACFCR |= ETH_MACFCR_FCBBPA;
695 }
696 
697 
698 /**
699   * @brief  Enables or disables the MAC BackPressure operation activation (Half-duplex only).
700   * @param  NewState: new state of the MAC BackPressure operation activation.
701   *   This parameter can be: ENABLE or DISABLE.
702   * @retval None
703   */
ETH_BackPressureActivationCmd(FunctionalState NewState)704 void ETH_BackPressureActivationCmd(FunctionalState NewState)
705 {
706   /* Check the parameters */
707   assert_param(IS_FUNCTIONAL_STATE(NewState));
708 
709   if (NewState != DISABLE)
710   {
711     /* Activate the MAC BackPressure operation */
712     /* In Half duplex: during backpressure, when the MAC receives a new frame,
713     the transmitter starts sending a JAM pattern resulting in a collision */
714     ETH->MACFCR |= ETH_MACFCR_FCBBPA;
715   }
716   else
717   {
718     /* Desactivate the MAC BackPressure operation */
719     ETH->MACFCR &= ~ETH_MACFCR_FCBBPA;
720   }
721 }
722 
723 
724 /**
725   * @brief  Checks whether the specified ETHERNET MAC flag is set or not.
726   * @param  ETH_MAC_FLAG: specifies the flag to check.
727   *   This parameter can be one of the following values:
728   *     @arg ETH_MAC_FLAG_TST  : Time stamp trigger flag
729   *     @arg ETH_MAC_FLAG_MMCT : MMC transmit flag
730   *     @arg ETH_MAC_FLAG_MMCR : MMC receive flag
731   *     @arg ETH_MAC_FLAG_MMC  : MMC flag
732   *     @arg ETH_MAC_FLAG_PMT  : PMT flag
733   * @retval The new state of ETHERNET MAC flag (SET or RESET).
734   */
ETH_GetMACFlagStatus(uint32_t ETH_MAC_FLAG)735 FlagStatus ETH_GetMACFlagStatus(uint32_t ETH_MAC_FLAG)
736 {
737   FlagStatus bitstatus = RESET;
738   /* Check the parameters */
739   assert_param(IS_ETH_MAC_GET_FLAG(ETH_MAC_FLAG));
740   if ((ETH->MACSR & ETH_MAC_FLAG) != (uint32_t)RESET)
741   {
742     bitstatus = SET;
743   }
744   else
745   {
746     bitstatus = RESET;
747   }
748   return bitstatus;
749 }
750 
751 
752 /**
753   * @brief  Checks whether the specified ETHERNET MAC interrupt has occurred or not.
754   * @param  ETH_MAC_IT: specifies the interrupt source to check.
755   *   This parameter can be one of the following values:
756   *     @arg ETH_MAC_IT_TST   : Time stamp trigger interrupt
757   *     @arg ETH_MAC_IT_MMCT : MMC transmit interrupt
758   *     @arg ETH_MAC_IT_MMCR : MMC receive interrupt
759   *     @arg ETH_MAC_IT_MMC  : MMC interrupt
760   *     @arg ETH_MAC_IT_PMT  : PMT interrupt
761   * @retval The new state of ETHERNET MAC interrupt (SET or RESET).
762   */
ETH_GetMACITStatus(uint32_t ETH_MAC_IT)763 ITStatus ETH_GetMACITStatus(uint32_t ETH_MAC_IT)
764 {
765   ITStatus bitstatus = RESET;
766   /* Check the parameters */
767   assert_param(IS_ETH_MAC_GET_IT(ETH_MAC_IT));
768   if ((ETH->MACSR & ETH_MAC_IT) != (uint32_t)RESET)
769   {
770     bitstatus = SET;
771   }
772   else
773   {
774     bitstatus = RESET;
775   }
776   return bitstatus;
777 }
778 
779 
780 /**
781   * @brief  Enables or disables the specified ETHERNET MAC interrupts.
782   * @param  ETH_MAC_IT: specifies the ETHERNET MAC interrupt sources to be
783   *   enabled or disabled.
784   *   This parameter can be any combination of the following values:
785   *     @arg ETH_MAC_IT_TST : Time stamp trigger interrupt
786   *     @arg ETH_MAC_IT_PMT : PMT interrupt
787   * @param  NewState: new state of the specified ETHERNET MAC interrupts.
788   *   This parameter can be: ENABLE or DISABLE.
789   * @retval None
790   */
ETH_MACITConfig(uint32_t ETH_MAC_IT,FunctionalState NewState)791 void ETH_MACITConfig(uint32_t ETH_MAC_IT, FunctionalState NewState)
792 {
793   /* Check the parameters */
794   assert_param(IS_ETH_MAC_IT(ETH_MAC_IT));
795   assert_param(IS_FUNCTIONAL_STATE(NewState));
796 
797   if (NewState != DISABLE)
798   {
799     /* Enable the selected ETHERNET MAC interrupts */
800     ETH->MACIMR &= (~(uint32_t)ETH_MAC_IT);
801   }
802   else
803   {
804     /* Disable the selected ETHERNET MAC interrupts */
805     ETH->MACIMR |= ETH_MAC_IT;
806   }
807 }
808 
809 
810 /**
811   * @brief  Configures the selected MAC address.
812   * @param  MacAddr: The MAC address to configure.
813   *   This parameter can be one of the following values:
814   *     @arg ETH_MAC_Address0 : MAC Address0
815   *     @arg ETH_MAC_Address1 : MAC Address1
816   *     @arg ETH_MAC_Address2 : MAC Address2
817   *     @arg ETH_MAC_Address3 : MAC Address3
818   * @param  Addr: Pointer on MAC address buffer data (6 bytes).
819   * @retval None
820   */
ETH_MACAddressConfig(uint32_t MacAddr,uint8_t * Addr)821 void ETH_MACAddressConfig(uint32_t MacAddr, uint8_t *Addr)
822 {
823   uint32_t tmpreg;
824   /* Check the parameters */
825   assert_param(IS_ETH_MAC_ADDRESS0123(MacAddr));
826 
827   /* Calculate the selected MAC address high register */
828   tmpreg = ((uint32_t)Addr[5] << 8) | (uint32_t)Addr[4]; //计算出所选择的MAC地址的高位寄存器�?
829 																												 //即ETH_MACA0HR�?6位�?
830   /* Load the selected MAC address high register */
831   (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + MacAddr)) = tmpreg; //将计算出的高位值写入ETH_MAC0HR�?
832   /* Calculate the selected MAC address low register */
833 	//计算出所选择的MAC地址的第位寄存器�?即ETH_MACA0LR�?6位�?
834   tmpreg = ((uint32_t)Addr[3] << 24) | ((uint32_t)Addr[2] << 16) | ((uint32_t)Addr[1] << 8) | Addr[0];
835 
836   /* Load the selected MAC address low register */
837   (*(__IO uint32_t *) (ETH_MAC_ADDR_LBASE + MacAddr)) = tmpreg;//将计算出的低位值写入ETH_MAC0LR�?
838 }
839 
840 
841 /**
842   * @brief  Get the selected MAC address.
843   * @param  MacAddr: The MAC address to return.
844   *   This parameter can be one of the following values:
845   *     @arg ETH_MAC_Address0 : MAC Address0
846   *     @arg ETH_MAC_Address1 : MAC Address1
847   *     @arg ETH_MAC_Address2 : MAC Address2
848   *     @arg ETH_MAC_Address3 : MAC Address3
849   * @param  Addr: Pointer on MAC address buffer data (6 bytes).
850   * @retval None
851   */
ETH_GetMACAddress(uint32_t MacAddr,uint8_t * Addr)852 void ETH_GetMACAddress(uint32_t MacAddr, uint8_t *Addr)
853 {
854   uint32_t tmpreg;
855   /* Check the parameters */
856   assert_param(IS_ETH_MAC_ADDRESS0123(MacAddr));
857 
858   /* Get the selected MAC address high register */
859   tmpreg =(*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + MacAddr));
860 
861   /* Calculate the selected MAC address buffer */
862   Addr[5] = ((tmpreg >> 8) & (uint8_t)0xFF);
863   Addr[4] = (tmpreg & (uint8_t)0xFF);
864   /* Load the selected MAC address low register */
865   tmpreg =(*(__IO uint32_t *) (ETH_MAC_ADDR_LBASE + MacAddr));
866   /* Calculate the selected MAC address buffer */
867   Addr[3] = ((tmpreg >> 24) & (uint8_t)0xFF);
868   Addr[2] = ((tmpreg >> 16) & (uint8_t)0xFF);
869   Addr[1] = ((tmpreg >> 8 ) & (uint8_t)0xFF);
870   Addr[0] = (tmpreg & (uint8_t)0xFF);
871 }
872 
873 
874 /**
875   * @brief  Enables or disables the Address filter module uses the specified
876   *   ETHERNET MAC address for perfect filtering
877   * @param  MacAddr: specifies the ETHERNET MAC address to be used for perfect filtering.
878   *   This parameter can be one of the following values:
879   *     @arg ETH_MAC_Address1 : MAC Address1
880   *     @arg ETH_MAC_Address2 : MAC Address2
881   *     @arg ETH_MAC_Address3 : MAC Address3
882   * @param  NewState: new state of the specified ETHERNET MAC address use.
883   *   This parameter can be: ENABLE or DISABLE.
884   * @retval None
885   */
ETH_MACAddressPerfectFilterCmd(uint32_t MacAddr,FunctionalState NewState)886 void ETH_MACAddressPerfectFilterCmd(uint32_t MacAddr, FunctionalState NewState)
887 {
888   /* Check the parameters */
889   assert_param(IS_ETH_MAC_ADDRESS123(MacAddr));
890   assert_param(IS_FUNCTIONAL_STATE(NewState));
891 
892   if (NewState != DISABLE)
893   {
894     /* Enable the selected ETHERNET MAC address for perfect filtering */
895     (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + MacAddr)) |= ETH_MACA1HR_AE;
896   }
897   else
898   {
899     /* Disable the selected ETHERNET MAC address for perfect filtering */
900     (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + MacAddr)) &=(~(uint32_t)ETH_MACA1HR_AE);
901   }
902 }
903 
904 
905 /**
906   * @brief  Set the filter type for the specified ETHERNET MAC address
907   * @param  MacAddr: specifies the ETHERNET MAC address
908   *   This parameter can be one of the following values:
909   *     @arg ETH_MAC_Address1 : MAC Address1
910   *     @arg ETH_MAC_Address2 : MAC Address2
911   *     @arg ETH_MAC_Address3 : MAC Address3
912   * @param  Filter: specifies the used frame received field for comparison
913   *   This parameter can be one of the following values:
914   *     @arg ETH_MAC_AddressFilter_SA : MAC Address is used to compare with the
915   *                                     SA fields of the received frame.
916   *     @arg ETH_MAC_AddressFilter_DA : MAC Address is used to compare with the
917   *                                     DA fields of the received frame.
918   * @retval None
919   */
ETH_MACAddressFilterConfig(uint32_t MacAddr,uint32_t Filter)920 void ETH_MACAddressFilterConfig(uint32_t MacAddr, uint32_t Filter)
921 {
922   /* Check the parameters */
923   assert_param(IS_ETH_MAC_ADDRESS123(MacAddr));
924   assert_param(IS_ETH_MAC_ADDRESS_FILTER(Filter));
925 
926   if (Filter != ETH_MAC_AddressFilter_DA)
927   {
928     /* The selected ETHERNET MAC address is used to compare with the SA fields of the
929        received frame. */
930     (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + MacAddr)) |= ETH_MACA1HR_SA;
931   }
932   else
933   {
934     /* The selected ETHERNET MAC address is used to compare with the DA fields of the
935        received frame. */
936     (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + MacAddr)) &=(~(uint32_t)ETH_MACA1HR_SA);
937   }
938 }
939 
940 
941 /**
942   * @brief  Set the filter type for the specified ETHERNET MAC address
943   * @param  MacAddr: specifies the ETHERNET MAC address
944   *   This parameter can be one of the following values:
945   *     @arg ETH_MAC_Address1 : MAC Address1
946   *     @arg ETH_MAC_Address2 : MAC Address2
947   *     @arg ETH_MAC_Address3 : MAC Address3
948   * @param  MaskByte: specifies the used address bytes for comparison
949   *   This parameter can be any combination of the following values:
950   *     @arg ETH_MAC_AddressMask_Byte6 : Mask MAC Address high reg bits [15:8].
951   *     @arg ETH_MAC_AddressMask_Byte5 : Mask MAC Address high reg bits [7:0].
952   *     @arg ETH_MAC_AddressMask_Byte4 : Mask MAC Address low reg bits [31:24].
953   *     @arg ETH_MAC_AddressMask_Byte3 : Mask MAC Address low reg bits [23:16].
954   *     @arg ETH_MAC_AddressMask_Byte2 : Mask MAC Address low reg bits [15:8].
955   *     @arg ETH_MAC_AddressMask_Byte1 : Mask MAC Address low reg bits [7:0].
956   * @retval None
957   */
ETH_MACAddressMaskBytesFilterConfig(uint32_t MacAddr,uint32_t MaskByte)958 void ETH_MACAddressMaskBytesFilterConfig(uint32_t MacAddr, uint32_t MaskByte)
959 {
960   /* Check the parameters */
961   assert_param(IS_ETH_MAC_ADDRESS123(MacAddr));
962   assert_param(IS_ETH_MAC_ADDRESS_MASK(MaskByte));
963 
964   /* Clear MBC bits in the selected MAC address  high register */
965   (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + MacAddr)) &=(~(uint32_t)ETH_MACA1HR_MBC);
966   /* Set the selected Filter mask bytes */
967   (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + MacAddr)) |= MaskByte;
968 }
969 
970 
971 /******************************************************************************/
972 /*                           DMA Descriptors functions                        */
973 /******************************************************************************/
974 
975 /**
976   * @brief  This function should be called to get the received frame (to be used
977   * with polling method only).
978   * @param  none
979   * @retval Structure of type FrameTypeDef
980   */
ETH_Get_Received_Frame(void)981 FrameTypeDef ETH_Get_Received_Frame(void)
982 {
983   uint32_t framelength = 0;
984   FrameTypeDef frame = {0,0,0};
985 
986   /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
987   framelength = ((DMARxDescToGet->Status & ETH_DMARxDesc_FL) >> ETH_DMARxDesc_FrameLengthShift) - 4;
988   frame.length = framelength;
989 
990   /* Get the address of the buffer start address */
991   /* Check if more than one segment in the frame */
992   if (DMA_RX_FRAME_infos->Seg_Count >1)
993   {
994     frame.buffer =(DMA_RX_FRAME_infos->FS_Rx_Desc)->Buffer1Addr;
995   }
996   else
997   {
998     frame.buffer = DMARxDescToGet->Buffer1Addr;
999   }
1000 
1001   frame.descriptor = DMARxDescToGet;
1002 
1003   /* Update the ETHERNET DMA global Rx descriptor with next Rx descriptor */
1004   /* Chained Mode */
1005   /* Selects the next DMA Rx descriptor list for next buffer to read */
1006   DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);
1007 
1008   /* Return Frame */
1009   return (frame);
1010 }
1011 
1012 
1013 /**
1014   * @brief  This function should be called when a frame is received using DMA
1015   *         Receive interrupt, it allows scanning of Rx descriptors to get the
1016   *         the receive frame (should be used with interrupt mode only)
1017   * @param  None
1018   * @retval Structure of type FrameTypeDef
1019   */
ETH_Get_Received_Frame_interrupt(void)1020 FrameTypeDef ETH_Get_Received_Frame_interrupt(void)
1021 {
1022   FrameTypeDef frame={0,0,0};
1023   __IO uint32_t descriptor_scan_counter = 0;
1024 
1025   /* scan descriptors owned by CPU */
1026   while (((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) == (uint32_t)RESET)&&
1027         (descriptor_scan_counter<ETH_RXBUFNB))
1028   {
1029 
1030     /* Just by security */
1031     descriptor_scan_counter++;
1032 
1033     /* check if first segment in frame */
1034     if(((DMARxDescToGet->Status & ETH_DMARxDesc_FS) != (uint32_t)RESET)&&
1035       ((DMARxDescToGet->Status & ETH_DMARxDesc_LS) == (uint32_t)RESET))
1036     {
1037       DMA_RX_FRAME_infos->FS_Rx_Desc = DMARxDescToGet;
1038       DMA_RX_FRAME_infos->Seg_Count = 1;
1039       DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);
1040     }
1041 
1042     /* check if intermediate segment */
1043     else if (((DMARxDescToGet->Status & ETH_DMARxDesc_LS) == (uint32_t)RESET)&&
1044             ((DMARxDescToGet->Status & ETH_DMARxDesc_FS) == (uint32_t)RESET))
1045     {
1046       (DMA_RX_FRAME_infos->Seg_Count) ++;
1047       DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);
1048     }
1049 
1050     /* should be last segment */
1051     else
1052     {
1053       /* last segment */
1054       DMA_RX_FRAME_infos->LS_Rx_Desc = DMARxDescToGet;
1055 
1056       (DMA_RX_FRAME_infos->Seg_Count)++;
1057 
1058       /* first segment is last segment */
1059       if ((DMA_RX_FRAME_infos->Seg_Count)==1)
1060         DMA_RX_FRAME_infos->FS_Rx_Desc = DMARxDescToGet;
1061 
1062       /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
1063       frame.length = ((DMARxDescToGet->Status & ETH_DMARxDesc_FL) >> ETH_DMARxDesc_FrameLengthShift) - 4;
1064 
1065 
1066       /* Get the address of the buffer start address */
1067       /* Check if more than one segment in the frame */
1068       if (DMA_RX_FRAME_infos->Seg_Count >1)
1069       {
1070         frame.buffer =(DMA_RX_FRAME_infos->FS_Rx_Desc)->Buffer1Addr;
1071       }
1072       else
1073       {
1074         frame.buffer = DMARxDescToGet->Buffer1Addr;
1075       }
1076 
1077       frame.descriptor = DMARxDescToGet;
1078 
1079       /* Update the ETHERNET DMA global Rx descriptor with next Rx descriptor */
1080       DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);
1081 
1082       /* Return Frame */
1083       return (frame);
1084     }
1085   }
1086   return (frame);
1087 }
1088 
1089 
1090 /**
1091   * @brief  Prepares DMA Tx descriptors to transmit an ethernet frame
1092   * @param  FrameLength : length of the frame to send
1093   * @retval error status
1094   */
ETH_Prepare_Transmit_Descriptors(u16 FrameLength)1095 uint32_t ETH_Prepare_Transmit_Descriptors(u16 FrameLength)
1096 {
1097   uint32_t buf_count =0, size=0,i=0;
1098   __IO ETH_DMADESCTypeDef *DMATxNextDesc;
1099 
1100   /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
1101   if((DMATxDescToSet->Status & ETH_DMATxDesc_OWN) != (u32)RESET)
1102   {
1103     /* Return ERROR: OWN bit set */
1104     return ETH_ERROR;
1105   }
1106 
1107   DMATxNextDesc = DMATxDescToSet;
1108 
1109   if (FrameLength > ETH_TX_BUF_SIZE)
1110   {
1111     buf_count = FrameLength/ETH_TX_BUF_SIZE;
1112     if (FrameLength%ETH_TX_BUF_SIZE) buf_count++;
1113   }
1114   else buf_count =1;
1115 
1116   if (buf_count ==1)
1117   {
1118     /*set LAST and FIRST segment */
1119     DMATxDescToSet->Status |=ETH_DMATxDesc_FS|ETH_DMATxDesc_LS;
1120     /* Set frame size */
1121     DMATxDescToSet->ControlBufferSize = (FrameLength& ETH_DMATxDesc_TBS1);
1122     /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
1123     DMATxDescToSet->Status |= ETH_DMATxDesc_OWN;
1124     DMATxDescToSet= (ETH_DMADESCTypeDef *)(DMATxDescToSet->Buffer2NextDescAddr);
1125   }
1126   else
1127   {
1128     for (i=0; i< buf_count; i++)
1129     {
1130       if (i==0)
1131       {
1132         /* Setting the first segment bit */
1133         DMATxDescToSet->Status |= ETH_DMATxDesc_FS;
1134       }
1135 
1136       /* Program size */
1137       DMATxNextDesc->ControlBufferSize = (ETH_TX_BUF_SIZE & ETH_DMATxDesc_TBS1);
1138 
1139       if (i== (buf_count-1))
1140       {
1141         /* Setting the last segment bit */
1142         DMATxNextDesc->Status |= ETH_DMATxDesc_LS;
1143         size = FrameLength - (buf_count-1)*ETH_TX_BUF_SIZE;
1144         DMATxNextDesc->ControlBufferSize = (size & ETH_DMATxDesc_TBS1);
1145       }
1146 
1147       /*give back descriptor to DMA */
1148       DMATxNextDesc->Status |= ETH_DMATxDesc_OWN;
1149 
1150       DMATxNextDesc = (ETH_DMADESCTypeDef *)(DMATxNextDesc->Buffer2NextDescAddr);
1151       /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
1152      }
1153     DMATxDescToSet = DMATxNextDesc ;
1154   }
1155 
1156   /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
1157   if ((ETH->DMASR & ETH_DMASR_TBUS) != (u32)RESET)
1158   {
1159     /* Clear TBUS ETHERNET DMA flag */
1160     ETH->DMASR = ETH_DMASR_TBUS;
1161     /* Resume DMA transmission*/
1162     ETH->DMATPDR = 0;
1163   }
1164 
1165   /* Return SUCCESS */
1166   return ETH_SUCCESS;
1167 }
1168 
1169 
1170 /**
1171   * @brief  Initializes the DMA Rx descriptors in chain mode.
1172   * @param  DMARxDescTab: Pointer on the first Rx desc list
1173   * @param  RxBuff: Pointer on the first RxBuffer list
1174   * @param  RxBuffCount: Number of the used Rx desc in the list
1175   * @retval None
1176   */
ETH_DMARxDescChainInit(ETH_DMADESCTypeDef * DMARxDescTab,uint8_t * RxBuff,uint32_t RxBuffCount)1177 void ETH_DMARxDescChainInit(ETH_DMADESCTypeDef *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount)
1178 {
1179   uint32_t i = 0;
1180   ETH_DMADESCTypeDef *DMARxDesc;
1181 
1182   /* Set the DMARxDescToGet pointer with the first one of the DMARxDescTab list */
1183   DMARxDescToGet = DMARxDescTab;
1184   /* Fill each DMARxDesc descriptor with the right values */
1185   for(i=0; i < RxBuffCount; i++)
1186   {
1187     /* Get the pointer on the ith member of the Rx Desc list */
1188     DMARxDesc = DMARxDescTab+i;
1189     /* Set Own bit of the Rx descriptor Status */
1190     DMARxDesc->Status = ETH_DMARxDesc_OWN;
1191 
1192     /* Set Buffer1 size and Second Address Chained bit */
1193     DMARxDesc->ControlBufferSize = ETH_DMARxDesc_RCH | (uint32_t)ETH_RX_BUF_SIZE;
1194     /* Set Buffer1 address pointer */
1195     DMARxDesc->Buffer1Addr = (uint32_t)(&RxBuff[i*ETH_RX_BUF_SIZE]);
1196 
1197     /* Initialize the next descriptor with the Next Descriptor Polling Enable */
1198     if(i < (RxBuffCount-1))
1199     {
1200       /* Set next descriptor address register with next descriptor base address */
1201       DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab+i+1);
1202     }
1203     else
1204     {
1205       /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
1206       DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab);
1207     }
1208   }
1209 
1210   /* Set Receive Descriptor List Address Register */
1211   ETH->DMARDLAR = (uint32_t) DMARxDescTab;
1212 
1213 
1214   DMA_RX_FRAME_infos = &RX_Frame_Descriptor;
1215 
1216 }
1217 
1218 /**
1219   * @brief  This function polls for a frame reception
1220   * @param  None
1221   * @retval Returns 1 when a frame is received, 0 if none.
1222   */
ETH_CheckFrameReceived(void)1223 uint32_t ETH_CheckFrameReceived(void)
1224 {
1225   /* check if last segment */
1226   if(((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) == (uint32_t)RESET) &&
1227      ((DMARxDescToGet->Status & ETH_DMARxDesc_LS) != (uint32_t)RESET))
1228     {
1229       DMA_RX_FRAME_infos->LS_Rx_Desc = DMARxDescToGet;
1230       DMA_RX_FRAME_infos->Seg_Count++;
1231       return 1;
1232     }
1233 
1234     /* check if first segment */
1235     else if(((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) == (uint32_t)RESET) &&
1236      ((DMARxDescToGet->Status & ETH_DMARxDesc_FS) != (uint32_t)RESET)&&
1237      ((DMARxDescToGet->Status & ETH_DMARxDesc_LS) == (uint32_t)RESET))
1238     {
1239       DMA_RX_FRAME_infos->FS_Rx_Desc = DMARxDescToGet;
1240       DMA_RX_FRAME_infos->LS_Rx_Desc = NULL;
1241       DMA_RX_FRAME_infos->Seg_Count = 1;
1242       DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);
1243     }
1244 
1245     /* check if intermediate segment */
1246     else if(((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) == (uint32_t)RESET) &&
1247      ((DMARxDescToGet->Status & ETH_DMARxDesc_FS) == (uint32_t)RESET)&&
1248      ((DMARxDescToGet->Status & ETH_DMARxDesc_LS) == (uint32_t)RESET))
1249     {
1250       (DMA_RX_FRAME_infos->Seg_Count) ++;
1251       DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);
1252     }
1253     return 0;
1254 }
1255 
1256 
1257 
1258 /**
1259   * @brief  Initializes the DMA Tx descriptors in chain mode.
1260   * @param  DMATxDescTab: Pointer on the first Tx desc list
1261   * @param  TxBuff: Pointer on the first TxBuffer list
1262   * @param  TxBuffCount: Number of the used Tx desc in the list
1263   * @retval None
1264   */
ETH_DMATxDescChainInit(ETH_DMADESCTypeDef * DMATxDescTab,uint8_t * TxBuff,uint32_t TxBuffCount)1265 void ETH_DMATxDescChainInit(ETH_DMADESCTypeDef *DMATxDescTab, uint8_t* TxBuff, uint32_t TxBuffCount)
1266 {
1267   uint32_t i = 0;
1268   ETH_DMADESCTypeDef *DMATxDesc;
1269 
1270   /* Set the DMATxDescToSet pointer with the first one of the DMATxDescTab list */
1271   DMATxDescToSet = DMATxDescTab;
1272   /* Fill each DMATxDesc descriptor with the right values */
1273   for(i=0; i < TxBuffCount; i++)
1274   {
1275     /* Get the pointer on the ith member of the Tx Desc list */
1276     DMATxDesc = DMATxDescTab + i;
1277     /* Set Second Address Chained bit */
1278     DMATxDesc->Status = ETH_DMATxDesc_TCH;
1279 
1280     /* Set Buffer1 address pointer */
1281     DMATxDesc->Buffer1Addr = (uint32_t)(&TxBuff[i*ETH_TX_BUF_SIZE]);
1282 
1283     /* Initialize the next descriptor with the Next Descriptor Polling Enable */
1284     if(i < (TxBuffCount-1))
1285     {
1286       /* Set next descriptor address register with next descriptor base address */
1287       DMATxDesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab+i+1);
1288     }
1289     else
1290     {
1291       /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
1292       DMATxDesc->Buffer2NextDescAddr = (uint32_t) DMATxDescTab;
1293     }
1294   }
1295 
1296   /* Set Transmit Desciptor List Address Register */
1297   ETH->DMATDLAR = (uint32_t) DMATxDescTab;
1298 }
1299 
1300 
1301 
1302 
1303 /**
1304   * @brief  Checks whether the specified ETHERNET DMA Tx Desc flag is set or not.
1305   * @param  DMATxDesc: pointer on a DMA Tx descriptor
1306   * @param  ETH_DMATxDescFlag: specifies the flag to check.
1307   *   This parameter can be one of the following values:
1308   *     @arg ETH_DMATxDesc_OWN : OWN bit: descriptor is owned by DMA engine
1309   *     @arg ETH_DMATxDesc_IC  : Interrupt on completion
1310   *     @arg ETH_DMATxDesc_LS  : Last Segment
1311   *     @arg ETH_DMATxDesc_FS  : First Segment
1312   *     @arg ETH_DMATxDesc_DC  : Disable CRC
1313   *     @arg ETH_DMATxDesc_DP  : Disable Pad
1314   *     @arg ETH_DMATxDesc_TTSE: Transmit Time Stamp Enable
1315   *     @arg ETH_DMATxDesc_CIC : Checksum insertion control
1316   *     @arg ETH_DMATxDesc_TER : Transmit End of Ring
1317   *     @arg ETH_DMATxDesc_TCH : Second Address Chained
1318   *     @arg ETH_DMATxDesc_TTSS: Tx Time Stamp Status
1319   *     @arg ETH_DMATxDesc_IHE : IP Header Error
1320   *     @arg ETH_DMATxDesc_ES  : Error summary
1321   *     @arg ETH_DMATxDesc_JT  : Jabber Timeout
1322   *     @arg ETH_DMATxDesc_FF  : Frame Flushed: DMA/MTL flushed the frame due to SW flush
1323   *     @arg ETH_DMATxDesc_PCE : Payload Checksum Error
1324   *     @arg ETH_DMATxDesc_LCA : Loss of Carrier: carrier lost during transmission
1325   *     @arg ETH_DMATxDesc_NC  : No Carrier: no carrier signal from the transceiver
1326   *     @arg ETH_DMATxDesc_LCO : Late Collision: transmission aborted due to collision
1327   *     @arg ETH_DMATxDesc_EC  : Excessive Collision: transmission aborted after 16 collisions
1328   *     @arg ETH_DMATxDesc_VF  : VLAN Frame
1329   *     @arg ETH_DMATxDesc_CC  : Collision Count
1330   *     @arg ETH_DMATxDesc_ED  : Excessive Deferral
1331   *     @arg ETH_DMATxDesc_UF  : Underflow Error: late data arrival from the memory
1332   *     @arg ETH_DMATxDesc_DB  : Deferred Bit
1333   * @retval The new state of ETH_DMATxDescFlag (SET or RESET).
1334   */
ETH_GetDMATxDescFlagStatus(ETH_DMADESCTypeDef * DMATxDesc,uint32_t ETH_DMATxDescFlag)1335 FlagStatus ETH_GetDMATxDescFlagStatus(ETH_DMADESCTypeDef *DMATxDesc, uint32_t ETH_DMATxDescFlag)
1336 {
1337   FlagStatus bitstatus = RESET;
1338   /* Check the parameters */
1339   assert_param(IS_ETH_DMATxDESC_GET_FLAG(ETH_DMATxDescFlag));
1340 
1341   if ((DMATxDesc->Status & ETH_DMATxDescFlag) != (uint32_t)RESET)
1342   {
1343     bitstatus = SET;
1344   }
1345   else
1346   {
1347     bitstatus = RESET;
1348   }
1349   return bitstatus;
1350 }
1351 
1352 /**
1353   * @brief  Returns the specified ETHERNET DMA Tx Desc collision count.
1354   * @param  DMATxDesc: pointer on a DMA Tx descriptor
1355   * @retval The Transmit descriptor collision counter value.
1356   */
ETH_GetDMATxDescCollisionCount(ETH_DMADESCTypeDef * DMATxDesc)1357 uint32_t ETH_GetDMATxDescCollisionCount(ETH_DMADESCTypeDef *DMATxDesc)
1358 {
1359   /* Return the Receive descriptor frame length */
1360   return ((DMATxDesc->Status & ETH_DMATxDesc_CC) >> ETH_DMATXDESC_COLLISION_COUNTSHIFT);
1361 }
1362 
1363 /**
1364   * @brief  Set the specified DMA Tx Desc Own bit.
1365   * @param  DMATxDesc: Pointer on a Tx desc
1366   * @retval None
1367   */
ETH_SetDMATxDescOwnBit(ETH_DMADESCTypeDef * DMATxDesc)1368 void ETH_SetDMATxDescOwnBit(ETH_DMADESCTypeDef *DMATxDesc)
1369 {
1370   /* Set the DMA Tx Desc Own bit */
1371   DMATxDesc->Status |= ETH_DMATxDesc_OWN;
1372 }
1373 
1374 /**
1375   * @brief  Enables or disables the specified DMA Tx Desc Transmit interrupt.
1376   * @param  DMATxDesc: Pointer on a Tx desc
1377   * @param  NewState: new state of the DMA Tx Desc transmit interrupt.
1378   *   This parameter can be: ENABLE or DISABLE.
1379   * @retval None
1380   */
ETH_DMATxDescTransmitITConfig(ETH_DMADESCTypeDef * DMATxDesc,FunctionalState NewState)1381 void ETH_DMATxDescTransmitITConfig(ETH_DMADESCTypeDef *DMATxDesc, FunctionalState NewState)
1382 {
1383   /* Check the parameters */
1384   assert_param(IS_FUNCTIONAL_STATE(NewState));
1385 
1386   if (NewState != DISABLE)
1387   {
1388     /* Enable the DMA Tx Desc Transmit interrupt */
1389     DMATxDesc->Status |= ETH_DMATxDesc_IC;
1390   }
1391   else
1392   {
1393     /* Disable the DMA Tx Desc Transmit interrupt */
1394     DMATxDesc->Status &=(~(uint32_t)ETH_DMATxDesc_IC);
1395   }
1396 }
1397 
1398 /**
1399   * @brief  configure Tx descriptor as last or first segment
1400   * @param  DMATxDesc: Pointer on a Tx desc
1401   * @param  DMATxDesc_FrameSegment: specifies is the actual Tx desc contain last or first segment.
1402   *   This parameter can be one of the following values:
1403   *     @arg ETH_DMATxDesc_LastSegment  : actual Tx desc contain last segment
1404   *     @arg ETH_DMATxDesc_FirstSegment : actual Tx desc contain first segment
1405   * @retval None
1406   */
ETH_DMATxDescFrameSegmentConfig(ETH_DMADESCTypeDef * DMATxDesc,uint32_t DMATxDesc_FrameSegment)1407 void ETH_DMATxDescFrameSegmentConfig(ETH_DMADESCTypeDef *DMATxDesc, uint32_t DMATxDesc_FrameSegment)
1408 {
1409   /* Check the parameters */
1410   assert_param(IS_ETH_DMA_TXDESC_SEGMENT(DMATxDesc_FrameSegment));
1411 
1412   /* Selects the DMA Tx Desc Frame segment */
1413   DMATxDesc->Status |= DMATxDesc_FrameSegment;
1414 }
1415 
1416 /**
1417   * @brief  Selects the specified ETHERNET DMA Tx Desc Checksum Insertion.
1418   * @param  DMATxDesc: pointer on a DMA Tx descriptor
1419   * @param  DMATxDesc_Checksum: specifies is the DMA Tx desc checksum insertion.
1420   *   This parameter can be one of the following values:
1421   *     @arg ETH_DMATxDesc_ChecksumByPass : Checksum bypass
1422   *     @arg ETH_DMATxDesc_ChecksumIPV4Header : IPv4 header checksum
1423   *     @arg ETH_DMATxDesc_ChecksumTCPUDPICMPSegment : TCP/UDP/ICMP checksum. Pseudo header checksum is assumed to be present
1424   *     @arg ETH_DMATxDesc_ChecksumTCPUDPICMPFull : TCP/UDP/ICMP checksum fully in hardware including pseudo header
1425   * @retval None
1426   */
ETH_DMATxDescChecksumInsertionConfig(ETH_DMADESCTypeDef * DMATxDesc,uint32_t DMATxDesc_Checksum)1427 void ETH_DMATxDescChecksumInsertionConfig(ETH_DMADESCTypeDef *DMATxDesc, uint32_t DMATxDesc_Checksum)
1428 {
1429   /* Check the parameters */
1430   assert_param(IS_ETH_DMA_TXDESC_CHECKSUM(DMATxDesc_Checksum));
1431 
1432   /* Set the selected DMA Tx desc checksum insertion control */
1433   DMATxDesc->Status |= DMATxDesc_Checksum;
1434 }
1435 
1436 /**
1437   * @brief  Enables or disables the DMA Tx Desc CRC.
1438   * @param  DMATxDesc: pointer on a DMA Tx descriptor
1439   * @param  NewState: new state of the specified DMA Tx Desc CRC.
1440   *   This parameter can be: ENABLE or DISABLE.
1441   * @retval None
1442   */
ETH_DMATxDescCRCCmd(ETH_DMADESCTypeDef * DMATxDesc,FunctionalState NewState)1443 void ETH_DMATxDescCRCCmd(ETH_DMADESCTypeDef *DMATxDesc, FunctionalState NewState)
1444 {
1445   /* Check the parameters */
1446   assert_param(IS_FUNCTIONAL_STATE(NewState));
1447 
1448   if (NewState != DISABLE)
1449   {
1450     /* Enable the selected DMA Tx Desc CRC */
1451     DMATxDesc->Status &= (~(uint32_t)ETH_DMATxDesc_DC);
1452   }
1453   else
1454   {
1455     /* Disable the selected DMA Tx Desc CRC */
1456     DMATxDesc->Status |= ETH_DMATxDesc_DC;
1457   }
1458 }
1459 
1460 
1461 /**
1462   * @brief  Enables or disables the DMA Tx Desc second address chained.
1463   * @param  DMATxDesc: pointer on a DMA Tx descriptor
1464   * @param  NewState: new state of the specified DMA Tx Desc second address chained.
1465   *   This parameter can be: ENABLE or DISABLE.
1466   * @retval None
1467   */
ETH_DMATxDescSecondAddressChainedCmd(ETH_DMADESCTypeDef * DMATxDesc,FunctionalState NewState)1468 void ETH_DMATxDescSecondAddressChainedCmd(ETH_DMADESCTypeDef *DMATxDesc, FunctionalState NewState)
1469 {
1470   /* Check the parameters */
1471   assert_param(IS_FUNCTIONAL_STATE(NewState));
1472 
1473   if (NewState != DISABLE)
1474   {
1475     /* Enable the selected DMA Tx Desc second address chained */
1476     DMATxDesc->Status |= ETH_DMATxDesc_TCH;
1477   }
1478   else
1479   {
1480     /* Disable the selected DMA Tx Desc second address chained */
1481     DMATxDesc->Status &=(~(uint32_t)ETH_DMATxDesc_TCH);
1482   }
1483 }
1484 
1485 /**
1486   * @brief  Enables or disables the DMA Tx Desc padding for frame shorter than 64 bytes.
1487   * @param  DMATxDesc: pointer on a DMA Tx descriptor
1488   * @param  NewState: new state of the specified DMA Tx Desc padding for frame shorter than 64 bytes.
1489   *   This parameter can be: ENABLE or DISABLE.
1490   * @retval None
1491   */
ETH_DMATxDescShortFramePaddingCmd(ETH_DMADESCTypeDef * DMATxDesc,FunctionalState NewState)1492 void ETH_DMATxDescShortFramePaddingCmd(ETH_DMADESCTypeDef *DMATxDesc, FunctionalState NewState)
1493 {
1494   /* Check the parameters */
1495   assert_param(IS_FUNCTIONAL_STATE(NewState));
1496 
1497   if (NewState != DISABLE)
1498   {
1499     /* Enable the selected DMA Tx Desc padding for frame shorter than 64 bytes */
1500     DMATxDesc->Status &= (~(uint32_t)ETH_DMATxDesc_DP);
1501   }
1502   else
1503   {
1504     /* Disable the selected DMA Tx Desc padding for frame shorter than 64 bytes*/
1505     DMATxDesc->Status |= ETH_DMATxDesc_DP;
1506   }
1507 }
1508 
1509 
1510 /**
1511   * @brief  Configures the specified DMA Tx Desc buffer1 and buffer2 sizes.
1512   * @param  DMATxDesc: Pointer on a Tx desc
1513   * @param  BufferSize1: specifies the Tx desc buffer1 size.
1514   * @param  BufferSize2: specifies the Tx desc buffer2 size (put "0" if not used).
1515   * @retval None
1516   */
ETH_DMATxDescBufferSizeConfig(ETH_DMADESCTypeDef * DMATxDesc,uint32_t BufferSize1,uint32_t BufferSize2)1517 void ETH_DMATxDescBufferSizeConfig(ETH_DMADESCTypeDef *DMATxDesc, uint32_t BufferSize1, uint32_t BufferSize2)
1518 {
1519   /* Check the parameters */
1520   assert_param(IS_ETH_DMATxDESC_BUFFER_SIZE(BufferSize1));
1521   assert_param(IS_ETH_DMATxDESC_BUFFER_SIZE(BufferSize2));
1522 
1523   /* Set the DMA Tx Desc buffer1 and buffer2 sizes values */
1524   DMATxDesc->ControlBufferSize |= (BufferSize1 | (BufferSize2 << ETH_DMATXDESC_BUFFER2_SIZESHIFT));
1525 }
1526 
1527 
1528 /**
1529   * @brief  Checks whether the specified ETHERNET Rx Desc flag is set or not.
1530   * @param  DMARxDesc: pointer on a DMA Rx descriptor
1531   * @param  ETH_DMARxDescFlag: specifies the flag to check.
1532   *   This parameter can be one of the following values:
1533   *     @arg ETH_DMARxDesc_OWN:         OWN bit: descriptor is owned by DMA engine
1534   *     @arg ETH_DMARxDesc_AFM:         DA Filter Fail for the rx frame
1535   *     @arg ETH_DMARxDesc_ES:          Error summary
1536   *     @arg ETH_DMARxDesc_DE:          Descriptor error: no more descriptors for receive frame
1537   *     @arg ETH_DMARxDesc_SAF:         SA Filter Fail for the received frame
1538   *     @arg ETH_DMARxDesc_LE:          Frame size not matching with length field
1539   *     @arg ETH_DMARxDesc_OE:          Overflow Error: Frame was damaged due to buffer overflow
1540   *     @arg ETH_DMARxDesc_VLAN:        VLAN Tag: received frame is a VLAN frame
1541   *     @arg ETH_DMARxDesc_FS:          First descriptor of the frame
1542   *     @arg ETH_DMARxDesc_LS:          Last descriptor of the frame
1543   *     @arg ETH_DMARxDesc_IPV4HCE:     IPC Checksum Error/Giant Frame: Rx Ipv4 header checksum error
1544   *     @arg ETH_DMARxDesc_LC:          Late collision occurred during reception
1545   *     @arg ETH_DMARxDesc_FT:          Frame type - Ethernet, otherwise 802.3
1546   *     @arg ETH_DMARxDesc_RWT:         Receive Watchdog Timeout: watchdog timer expired during reception
1547   *     @arg ETH_DMARxDesc_RE:          Receive error: error reported by MII interface
1548   *     @arg ETH_DMARxDesc_DE:          Dribble bit error: frame contains non int multiple of 8 bits
1549   *     @arg ETH_DMARxDesc_CE:          CRC error
1550   *     @arg ETH_DMARxDesc_MAMPCE:      Rx MAC Address/Payload Checksum Error: Rx MAC address matched/ Rx Payload Checksum Error
1551   * @retval The new state of ETH_DMARxDescFlag (SET or RESET).
1552   */
ETH_GetDMARxDescFlagStatus(ETH_DMADESCTypeDef * DMARxDesc,uint32_t ETH_DMARxDescFlag)1553 FlagStatus ETH_GetDMARxDescFlagStatus(ETH_DMADESCTypeDef *DMARxDesc, uint32_t ETH_DMARxDescFlag)
1554 {
1555   FlagStatus bitstatus = RESET;
1556   /* Check the parameters */
1557   assert_param(IS_ETH_DMARxDESC_GET_FLAG(ETH_DMARxDescFlag));
1558   if ((DMARxDesc->Status & ETH_DMARxDescFlag) != (uint32_t)RESET)
1559   {
1560     bitstatus = SET;
1561   }
1562   else
1563   {
1564     bitstatus = RESET;
1565   }
1566   return bitstatus;
1567 }
1568 
1569 #ifdef USE_ENHANCED_DMA_DESCRIPTORS
1570 /**
1571   * @brief  Checks whether the specified ETHERNET PTP Rx Desc extended flag is set or not.
1572   * @param  DMAPTPRxDesc: pointer on a DMA PTP Rx descriptor
1573   * @param  ETH_DMAPTPRxDescFlag: specifies the extended flag to check.
1574   *   This parameter can be one of the following values:
1575   *     @arg ETH_DMAPTPRxDesc_PTPV:   PTP version
1576   *     @arg ETH_DMAPTPRxDesc_PTPFT:  PTP frame type
1577   *     @arg ETH_DMAPTPRxDesc_PTPMT:  PTP message type
1578   *     @arg ETH_DMAPTPRxDesc_IPV6PR: IPv6 packet received
1579   *     @arg ETH_DMAPTPRxDesc_IPV4PR: IPv4 packet received
1580   *     @arg ETH_DMAPTPRxDesc_IPCB:   IP checksum bypassed
1581   *     @arg ETH_DMAPTPRxDesc_IPPE:   IP payload error
1582   *     @arg ETH_DMAPTPRxDesc_IPHE:   IP header error
1583   *     @arg ETH_DMAPTPRxDesc_IPPT:   IP payload type
1584   * @retval The new state of ETH_DMAPTPRxDescExtendedFlag (SET or RESET).
1585   */
ETH_GetDMAPTPRxDescExtendedFlagStatus(ETH_DMADESCTypeDef * DMAPTPRxDesc,uint32_t ETH_DMAPTPRxDescExtendedFlag)1586 FlagStatus ETH_GetDMAPTPRxDescExtendedFlagStatus(ETH_DMADESCTypeDef *DMAPTPRxDesc, uint32_t ETH_DMAPTPRxDescExtendedFlag)
1587 {
1588   FlagStatus bitstatus = RESET;
1589 
1590   /* Check the parameters */
1591   assert_param(IS_ETH_DMAPTPRxDESC_GET_EXTENDED_FLAG(ETH_DMAPTPRxDescExtendedFlag));
1592 
1593   if ((DMAPTPRxDesc->ExtendedStatus & ETH_DMAPTPRxDescExtendedFlag) != (uint32_t)RESET)
1594   {
1595     bitstatus = SET;
1596   }
1597   else
1598   {
1599     bitstatus = RESET;
1600   }
1601   return bitstatus;
1602 }
1603 #endif /* USE_ENHANCED_DMA_DESCRIPTORS */
1604 
1605 /**
1606   * @brief  Set the specified DMA Rx Desc Own bit.
1607   * @param  DMARxDesc: Pointer on a Rx desc
1608   * @retval None
1609   */
ETH_SetDMARxDescOwnBit(ETH_DMADESCTypeDef * DMARxDesc)1610 void ETH_SetDMARxDescOwnBit(ETH_DMADESCTypeDef *DMARxDesc)
1611 {
1612   /* Set the DMA Rx Desc Own bit */
1613   DMARxDesc->Status |= ETH_DMARxDesc_OWN;
1614 }
1615 
1616 /**
1617   * @brief  Returns the specified DMA Rx Desc frame length.
1618   * @param  DMARxDesc: pointer on a DMA Rx descriptor
1619   * @retval The Rx descriptor received frame length.
1620   */
ETH_GetDMARxDescFrameLength(ETH_DMADESCTypeDef * DMARxDesc)1621 uint32_t ETH_GetDMARxDescFrameLength(ETH_DMADESCTypeDef *DMARxDesc)
1622 {
1623   /* Return the Receive descriptor frame length */
1624   return ((DMARxDesc->Status & ETH_DMARxDesc_FL) >> ETH_DMARXDESC_FRAME_LENGTHSHIFT);
1625 }
1626 
1627 /**
1628   * @brief  Enables or disables the specified DMA Rx Desc receive interrupt.
1629   * @param  DMARxDesc: Pointer on a Rx desc
1630   * @param  NewState: new state of the specified DMA Rx Desc interrupt.
1631   *   This parameter can be: ENABLE or DISABLE.
1632   * @retval None
1633   */
ETH_DMARxDescReceiveITConfig(ETH_DMADESCTypeDef * DMARxDesc,FunctionalState NewState)1634 void ETH_DMARxDescReceiveITConfig(ETH_DMADESCTypeDef *DMARxDesc, FunctionalState NewState)
1635 {
1636   /* Check the parameters */
1637   assert_param(IS_FUNCTIONAL_STATE(NewState));
1638 
1639   if (NewState != DISABLE)
1640   {
1641     /* Enable the DMA Rx Desc receive interrupt */
1642     DMARxDesc->ControlBufferSize &=(~(uint32_t)ETH_DMARxDesc_DIC);
1643   }
1644   else
1645   {
1646     /* Disable the DMA Rx Desc receive interrupt */
1647     DMARxDesc->ControlBufferSize |= ETH_DMARxDesc_DIC;
1648   }
1649 }
1650 
1651 
1652 /**
1653   * @brief  Returns the specified ETHERNET DMA Rx Desc buffer size.
1654   * @param  DMARxDesc: pointer on a DMA Rx descriptor
1655   * @param  DMARxDesc_Buffer: specifies the DMA Rx Desc buffer.
1656   *   This parameter can be any one of the following values:
1657   *     @arg ETH_DMARxDesc_Buffer1 : DMA Rx Desc Buffer1
1658   *     @arg ETH_DMARxDesc_Buffer2 : DMA Rx Desc Buffer2
1659   * @retval The Receive descriptor frame length.
1660   */
ETH_GetDMARxDescBufferSize(ETH_DMADESCTypeDef * DMARxDesc,uint32_t DMARxDesc_Buffer)1661 uint32_t ETH_GetDMARxDescBufferSize(ETH_DMADESCTypeDef *DMARxDesc, uint32_t DMARxDesc_Buffer)
1662 {
1663   /* Check the parameters */
1664   assert_param(IS_ETH_DMA_RXDESC_BUFFER(DMARxDesc_Buffer));
1665 
1666   if(DMARxDesc_Buffer != ETH_DMARxDesc_Buffer1)
1667   {
1668     /* Return the DMA Rx Desc buffer2 size */
1669     return ((DMARxDesc->ControlBufferSize & ETH_DMARxDesc_RBS2) >> ETH_DMARXDESC_BUFFER2_SIZESHIFT);
1670   }
1671   else
1672   {
1673     /* Return the DMA Rx Desc buffer1 size */
1674     return (DMARxDesc->ControlBufferSize & ETH_DMARxDesc_RBS1);
1675   }
1676 }
1677 
1678 
1679 /**
1680   * @brief  Get the size of the received packet.
1681   * @param  None
1682   * @retval framelength: received packet size
1683   */
ETH_GetRxPktSize(ETH_DMADESCTypeDef * DMARxDesc)1684 uint32_t ETH_GetRxPktSize(ETH_DMADESCTypeDef *DMARxDesc)
1685 {
1686   uint32_t frameLength = 0;
1687   if(((DMARxDesc->Status & ETH_DMARxDesc_OWN) == (uint32_t)RESET) &&
1688      ((DMARxDesc->Status & ETH_DMARxDesc_ES) == (uint32_t)RESET) &&
1689      ((DMARxDesc->Status & ETH_DMARxDesc_LS) != (uint32_t)RESET))
1690   {
1691     /* Get the size of the packet: including 4 bytes of the CRC */
1692     frameLength =  ETH_GetDMARxDescFrameLength(DMARxDesc);
1693   }
1694 
1695   /* Return Frame Length */
1696   return frameLength;
1697 }
1698 
1699 #ifdef USE_ENHANCED_DMA_DESCRIPTORS
1700 /**
1701   * @brief  Enables or disables the Enhanced descriptor structure.
1702   * @param  NewState: new state of the Enhanced descriptor structure.
1703   *   This parameter can be: ENABLE or DISABLE.
1704   * @retval None
1705   */
ETH_EnhancedDescriptorCmd(FunctionalState NewState)1706 void ETH_EnhancedDescriptorCmd(FunctionalState NewState)
1707 {
1708   /* Check the parameters */
1709   assert_param(IS_FUNCTIONAL_STATE(NewState));
1710 
1711   if (NewState != DISABLE)
1712   {
1713     /* Enable enhanced descriptor structure */
1714     ETH->DMABMR |= ETH_DMABMR_EDE;
1715   }
1716   else
1717   {
1718     /* Disable enhanced descriptor structure */
1719     ETH->DMABMR &= ~ETH_DMABMR_EDE;
1720   }
1721 }
1722 #endif /* USE_ENHANCED_DMA_DESCRIPTORS */
1723 
1724 /******************************************************************************/
1725 /*                           DMA functions                                    */
1726 /******************************************************************************/
1727 /**
1728   * @brief  Resets all MAC subsystem internal registers and logic.
1729   * @param  None
1730   * @retval None
1731   */
ETH_SoftwareReset(void)1732 void ETH_SoftwareReset(void)
1733 {
1734   /* Set the SWR bit: resets all MAC subsystem internal registers and logic */
1735   /* After reset all the registers holds their respective reset values */
1736   ETH->DMABMR |= ETH_DMABMR_SR;
1737 }
1738 
1739 /**
1740   * @brief  Checks whether the ETHERNET software reset bit is set or not.
1741   * @param  None
1742   * @retval The new state of DMA Bus Mode register SR bit (SET or RESET).
1743   */
ETH_GetSoftwareResetStatus(void)1744 FlagStatus ETH_GetSoftwareResetStatus(void)
1745 {
1746   FlagStatus bitstatus = RESET;
1747   if((ETH->DMABMR & ETH_DMABMR_SR) != (uint32_t)RESET)
1748   {
1749     bitstatus = SET;
1750   }
1751   else
1752   {
1753     bitstatus = RESET;
1754   }
1755   return bitstatus;
1756 }
1757 
1758 /**
1759   * @brief  Checks whether the specified ETHERNET DMA flag is set or not.
1760   * @param  ETH_DMA_FLAG: specifies the flag to check.
1761   *   This parameter can be one of the following values:
1762   *     @arg ETH_DMA_FLAG_TST : Time-stamp trigger flag
1763   *     @arg ETH_DMA_FLAG_PMT : PMT flag
1764   *     @arg ETH_DMA_FLAG_MMC : MMC flag
1765   *     @arg ETH_DMA_FLAG_DataTransferError : Error bits 0-data buffer, 1-desc. access
1766   *     @arg ETH_DMA_FLAG_ReadWriteError    : Error bits 0-write trnsf, 1-read transfr
1767   *     @arg ETH_DMA_FLAG_AccessError       : Error bits 0-Rx DMA, 1-Tx DMA
1768   *     @arg ETH_DMA_FLAG_NIS : Normal interrupt summary flag
1769   *     @arg ETH_DMA_FLAG_AIS : Abnormal interrupt summary flag
1770   *     @arg ETH_DMA_FLAG_ER  : Early receive flag
1771   *     @arg ETH_DMA_FLAG_FBE : Fatal bus error flag
1772   *     @arg ETH_DMA_FLAG_ET  : Early transmit flag
1773   *     @arg ETH_DMA_FLAG_RWT : Receive watchdog timeout flag
1774   *     @arg ETH_DMA_FLAG_RPS : Receive process stopped flag
1775   *     @arg ETH_DMA_FLAG_RBU : Receive buffer unavailable flag
1776   *     @arg ETH_DMA_FLAG_R   : Receive flag
1777   *     @arg ETH_DMA_FLAG_TU  : Underflow flag
1778   *     @arg ETH_DMA_FLAG_RO  : Overflow flag
1779   *     @arg ETH_DMA_FLAG_TJT : Transmit jabber timeout flag
1780   *     @arg ETH_DMA_FLAG_TBU : Transmit buffer unavailable flag
1781   *     @arg ETH_DMA_FLAG_TPS : Transmit process stopped flag
1782   *     @arg ETH_DMA_FLAG_T   : Transmit flag
1783   * @retval The new state of ETH_DMA_FLAG (SET or RESET).
1784   */
ETH_GetDMAFlagStatus(uint32_t ETH_DMA_FLAG)1785 FlagStatus ETH_GetDMAFlagStatus(uint32_t ETH_DMA_FLAG)
1786 {
1787   FlagStatus bitstatus = RESET;
1788   /* Check the parameters */
1789   assert_param(IS_ETH_DMA_GET_IT(ETH_DMA_FLAG));
1790   if ((ETH->DMASR & ETH_DMA_FLAG) != (uint32_t)RESET)
1791   {
1792     bitstatus = SET;
1793   }
1794   else
1795   {
1796     bitstatus = RESET;
1797   }
1798   return bitstatus;
1799 }
1800 
1801 /**
1802   * @brief  Clears the ETHERNET�?DMA pending flag.
1803   * @param  ETH_DMA_FLAG: specifies the flag to clear.
1804   *   This parameter can be any combination of the following values:
1805   *     @arg ETH_DMA_FLAG_NIS : Normal interrupt summary flag
1806   *     @arg ETH_DMA_FLAG_AIS : Abnormal interrupt summary flag
1807   *     @arg ETH_DMA_FLAG_ER  : Early receive flag
1808   *     @arg ETH_DMA_FLAG_FBE : Fatal bus error flag
1809   *     @arg ETH_DMA_FLAG_ETI : Early transmit flag
1810   *     @arg ETH_DMA_FLAG_RWT : Receive watchdog timeout flag
1811   *     @arg ETH_DMA_FLAG_RPS : Receive process stopped flag
1812   *     @arg ETH_DMA_FLAG_RBU : Receive buffer unavailable flag
1813   *     @arg ETH_DMA_FLAG_R   : Receive flag
1814   *     @arg ETH_DMA_FLAG_TU  : Transmit Underflow flag
1815   *     @arg ETH_DMA_FLAG_RO  : Receive Overflow flag
1816   *     @arg ETH_DMA_FLAG_TJT : Transmit jabber timeout flag
1817   *     @arg ETH_DMA_FLAG_TBU : Transmit buffer unavailable flag
1818   *     @arg ETH_DMA_FLAG_TPS : Transmit process stopped flag
1819   *     @arg ETH_DMA_FLAG_T   : Transmit flag
1820   * @retval None
1821   */
ETH_DMAClearFlag(uint32_t ETH_DMA_FLAG)1822 void ETH_DMAClearFlag(uint32_t ETH_DMA_FLAG)
1823 {
1824   /* Check the parameters */
1825   assert_param(IS_ETH_DMA_FLAG(ETH_DMA_FLAG));
1826 
1827   /* Clear the selected ETHERNET DMA FLAG */
1828   ETH->DMASR = (uint32_t) ETH_DMA_FLAG;
1829 }
1830 
1831 /**
1832   * @brief  Enables or disables the specified ETHERNET DMA interrupts.
1833   * @param  ETH_DMA_IT: specifies the ETHERNET DMA interrupt sources to be
1834   *   enabled or disabled.
1835   *   This parameter can be any combination of the following values:
1836   *     @arg ETH_DMA_IT_NIS : Normal interrupt summary
1837   *     @arg ETH_DMA_IT_AIS : Abnormal interrupt summary
1838   *     @arg ETH_DMA_IT_ER  : Early receive interrupt
1839   *     @arg ETH_DMA_IT_FBE : Fatal bus error interrupt
1840   *     @arg ETH_DMA_IT_ET  : Early transmit interrupt
1841   *     @arg ETH_DMA_IT_RWT : Receive watchdog timeout interrupt
1842   *     @arg ETH_DMA_IT_RPS : Receive process stopped interrupt
1843   *     @arg ETH_DMA_IT_RBU : Receive buffer unavailable interrupt
1844   *     @arg ETH_DMA_IT_R   : Receive interrupt
1845   *     @arg ETH_DMA_IT_TU  : Underflow interrupt
1846   *     @arg ETH_DMA_IT_RO  : Overflow interrupt
1847   *     @arg ETH_DMA_IT_TJT : Transmit jabber timeout interrupt
1848   *     @arg ETH_DMA_IT_TBU : Transmit buffer unavailable interrupt
1849   *     @arg ETH_DMA_IT_TPS : Transmit process stopped interrupt
1850   *     @arg ETH_DMA_IT_T   : Transmit interrupt
1851   * @param  NewState: new state of the specified ETHERNET DMA interrupts.
1852   *   This parameter can be: ENABLE or DISABLE.
1853   * @retval None
1854   */
ETH_DMAITConfig(uint32_t ETH_DMA_IT,FunctionalState NewState)1855 void ETH_DMAITConfig(uint32_t ETH_DMA_IT, FunctionalState NewState)
1856 {
1857   /* Check the parameters */
1858   assert_param(IS_ETH_DMA_IT(ETH_DMA_IT));
1859   assert_param(IS_FUNCTIONAL_STATE(NewState));
1860 
1861   if (NewState != DISABLE)
1862   {
1863     /* Enable the selected ETHERNET DMA interrupts */
1864     ETH->DMAIER |= ETH_DMA_IT;
1865   }
1866   else
1867   {
1868     /* Disable the selected ETHERNET DMA interrupts */
1869     ETH->DMAIER &=(~(uint32_t)ETH_DMA_IT);
1870   }
1871 }
1872 
1873 /**
1874   * @brief  Checks whether the specified ETHERNET DMA interrupt has occurred or not.
1875   * @param  ETH_DMA_IT: specifies the interrupt source to check.
1876   *   This parameter can be one of the following values:
1877   *     @arg ETH_DMA_IT_TST : Time-stamp trigger interrupt
1878   *     @arg ETH_DMA_IT_PMT : PMT interrupt
1879   *     @arg ETH_DMA_IT_MMC : MMC interrupt
1880   *     @arg ETH_DMA_IT_NIS : Normal interrupt summary
1881   *     @arg ETH_DMA_IT_AIS : Abnormal interrupt summary
1882   *     @arg ETH_DMA_IT_ER  : Early receive interrupt
1883   *     @arg ETH_DMA_IT_FBE : Fatal bus error interrupt
1884   *     @arg ETH_DMA_IT_ET  : Early transmit interrupt
1885   *     @arg ETH_DMA_IT_RWT : Receive watchdog timeout interrupt
1886   *     @arg ETH_DMA_IT_RPS : Receive process stopped interrupt
1887   *     @arg ETH_DMA_IT_RBU : Receive buffer unavailable interrupt
1888   *     @arg ETH_DMA_IT_R   : Receive interrupt
1889   *     @arg ETH_DMA_IT_TU  : Underflow interrupt
1890   *     @arg ETH_DMA_IT_RO  : Overflow interrupt
1891   *     @arg ETH_DMA_IT_TJT : Transmit jabber timeout interrupt
1892   *     @arg ETH_DMA_IT_TBU : Transmit buffer unavailable interrupt
1893   *     @arg ETH_DMA_IT_TPS : Transmit process stopped interrupt
1894   *     @arg ETH_DMA_IT_T   : Transmit interrupt
1895   * @retval The new state of ETH_DMA_IT (SET or RESET).
1896   */
ETH_GetDMAITStatus(uint32_t ETH_DMA_IT)1897 ITStatus ETH_GetDMAITStatus(uint32_t ETH_DMA_IT)
1898 {
1899   ITStatus bitstatus = RESET;
1900   /* Check the parameters */
1901   assert_param(IS_ETH_DMA_GET_IT(ETH_DMA_IT));
1902   if ((ETH->DMASR & ETH_DMA_IT) != (uint32_t)RESET)
1903   {
1904     bitstatus = SET;
1905   }
1906   else
1907   {
1908     bitstatus = RESET;
1909   }
1910   return bitstatus;
1911 }
1912 
1913 /**
1914   * @brief  Clears the ETHERNET�?DMA IT pending bit.
1915   * @param  ETH_DMA_IT: specifies the interrupt pending bit to clear.
1916   *   This parameter can be any combination of the following values:
1917   *     @arg ETH_DMA_IT_NIS : Normal interrupt summary
1918   *     @arg ETH_DMA_IT_AIS : Abnormal interrupt summary
1919   *     @arg ETH_DMA_IT_ER  : Early receive interrupt
1920   *     @arg ETH_DMA_IT_FBE : Fatal bus error interrupt
1921   *     @arg ETH_DMA_IT_ETI : Early transmit interrupt
1922   *     @arg ETH_DMA_IT_RWT : Receive watchdog timeout interrupt
1923   *     @arg ETH_DMA_IT_RPS : Receive process stopped interrupt
1924   *     @arg ETH_DMA_IT_RBU : Receive buffer unavailable interrupt
1925   *     @arg ETH_DMA_IT_R   : Receive interrupt
1926   *     @arg ETH_DMA_IT_TU  : Transmit Underflow interrupt
1927   *     @arg ETH_DMA_IT_RO  : Receive Overflow interrupt
1928   *     @arg ETH_DMA_IT_TJT : Transmit jabber timeout interrupt
1929   *     @arg ETH_DMA_IT_TBU : Transmit buffer unavailable interrupt
1930   *     @arg ETH_DMA_IT_TPS : Transmit process stopped interrupt
1931   *     @arg ETH_DMA_IT_T   : Transmit interrupt
1932   * @retval None
1933   */
ETH_DMAClearITPendingBit(uint32_t ETH_DMA_IT)1934 void ETH_DMAClearITPendingBit(uint32_t ETH_DMA_IT)
1935 {
1936   /* Check the parameters */
1937   assert_param(IS_ETH_DMA_IT(ETH_DMA_IT));
1938 
1939   /* Clear the selected ETHERNET DMA IT */
1940   ETH->DMASR = (uint32_t) ETH_DMA_IT;
1941 }
1942 
1943 /**
1944   * @brief  Returns the ETHERNET DMA Transmit Process State.
1945   * @param  None
1946   * @retval The new ETHERNET DMA Transmit Process State:
1947   *   This can be one of the following values:
1948   *     - ETH_DMA_TransmitProcess_Stopped   : Stopped - Reset or Stop Tx Command issued
1949   *     - ETH_DMA_TransmitProcess_Fetching  : Running - fetching the Tx descriptor
1950   *     - ETH_DMA_TransmitProcess_Waiting   : Running - waiting for status
1951   *     - ETH_DMA_TransmitProcess_Reading   : Running - reading the data from host memory
1952   *     - ETH_DMA_TransmitProcess_Suspended : Suspended - Tx Descriptor unavailable
1953   *     - ETH_DMA_TransmitProcess_Closing   : Running - closing Rx descriptor
1954   */
ETH_GetTransmitProcessState(void)1955 uint32_t ETH_GetTransmitProcessState(void)
1956 {
1957   return ((uint32_t)(ETH->DMASR & ETH_DMASR_TS));
1958 }
1959 
1960 /**
1961   * @brief  Returns the ETHERNET DMA Receive Process State.
1962   * @param  None
1963   * @retval The new ETHERNET DMA Receive Process State:
1964   *   This can be one of the following values:
1965   *     - ETH_DMA_ReceiveProcess_Stopped   : Stopped - Reset or Stop Rx Command issued
1966   *     - ETH_DMA_ReceiveProcess_Fetching  : Running - fetching the Rx descriptor
1967   *     - ETH_DMA_ReceiveProcess_Waiting   : Running - waiting for packet
1968   *     - ETH_DMA_ReceiveProcess_Suspended : Suspended - Rx Descriptor unavailable
1969   *     - ETH_DMA_ReceiveProcess_Closing   : Running - closing descriptor
1970   *     - ETH_DMA_ReceiveProcess_Queuing   : Running - queuing the receive frame into host memory
1971   */
ETH_GetReceiveProcessState(void)1972 uint32_t ETH_GetReceiveProcessState(void)
1973 {
1974   return ((uint32_t)(ETH->DMASR & ETH_DMASR_RS));
1975 }
1976 
1977 /**
1978   * @brief  Clears the ETHERNET transmit FIFO.
1979   * @param  None
1980   * @retval None
1981   */
ETH_FlushTransmitFIFO(void)1982 void ETH_FlushTransmitFIFO(void)
1983 {
1984   /* Set the Flush Transmit FIFO bit */
1985   ETH->DMAOMR |= ETH_DMAOMR_FTF;
1986 }
1987 
1988 /**
1989   * @brief  Checks whether the ETHERNET flush transmit FIFO bit is cleared or not.
1990   * @param  None
1991   * @retval The new state of ETHERNET flush transmit FIFO bit (SET or RESET).
1992   */
ETH_GetFlushTransmitFIFOStatus(void)1993 FlagStatus ETH_GetFlushTransmitFIFOStatus(void)
1994 {
1995   FlagStatus bitstatus = RESET;
1996   if ((ETH->DMAOMR & ETH_DMAOMR_FTF) != (uint32_t)RESET)
1997   {
1998     bitstatus = SET;
1999   }
2000   else
2001   {
2002     bitstatus = RESET;
2003   }
2004   return bitstatus;
2005 }
2006 
2007 /**
2008   * @brief  Enables or disables the DMA transmission.
2009   * @param  NewState: new state of the DMA transmission.
2010   *   This parameter can be: ENABLE or DISABLE.
2011   * @retval None
2012   */
ETH_DMATransmissionCmd(FunctionalState NewState)2013 void ETH_DMATransmissionCmd(FunctionalState NewState)
2014 {
2015   /* Check the parameters */
2016   assert_param(IS_FUNCTIONAL_STATE(NewState));
2017 
2018   if (NewState != DISABLE)
2019   {
2020     /* Enable the DMA transmission */
2021     ETH->DMAOMR |= ETH_DMAOMR_ST;
2022   }
2023   else
2024   {
2025     /* Disable the DMA transmission */
2026     ETH->DMAOMR &= ~ETH_DMAOMR_ST;
2027   }
2028 }
2029 
2030 /**
2031   * @brief  Enables or disables the DMA reception.
2032   * @param  NewState: new state of the DMA reception.
2033   *   This parameter can be: ENABLE or DISABLE.
2034   * @retval None
2035   */
ETH_DMAReceptionCmd(FunctionalState NewState)2036 void ETH_DMAReceptionCmd(FunctionalState NewState)
2037 {
2038   /* Check the parameters */
2039   assert_param(IS_FUNCTIONAL_STATE(NewState));
2040 
2041   if (NewState != DISABLE)
2042   {
2043     /* Enable the DMA reception */
2044     ETH->DMAOMR |= ETH_DMAOMR_SR;
2045   }
2046   else
2047   {
2048     /* Disable the DMA reception */
2049     ETH->DMAOMR &= ~ETH_DMAOMR_SR;
2050   }
2051 }
2052 
2053 /**
2054   * @brief  Checks whether the specified ETHERNET DMA overflow flag is set or not.
2055   * @param  ETH_DMA_Overflow: specifies the DMA overflow flag to check.
2056   *   This parameter can be one of the following values:
2057   *     @arg ETH_DMA_Overflow_RxFIFOCounter : Overflow for FIFO Overflows Counter
2058   *     @arg ETH_DMA_Overflow_MissedFrameCounter : Overflow for Buffer Unavailable Missed Frame Counter
2059   * @retval The new state of ETHERNET DMA overflow Flag (SET or RESET).
2060   */
ETH_GetDMAOverflowStatus(uint32_t ETH_DMA_Overflow)2061 FlagStatus ETH_GetDMAOverflowStatus(uint32_t ETH_DMA_Overflow)
2062 {
2063   FlagStatus bitstatus = RESET;
2064   /* Check the parameters */
2065   assert_param(IS_ETH_DMA_GET_OVERFLOW(ETH_DMA_Overflow));
2066 
2067   if ((ETH->DMAMFBOCR & ETH_DMA_Overflow) != (uint32_t)RESET)
2068   {
2069     bitstatus = SET;
2070   }
2071   else
2072   {
2073     bitstatus = RESET;
2074   }
2075   return bitstatus;
2076 }
2077 
2078 /**
2079   * @brief  Get the ETHERNET DMA Rx Overflow Missed Frame Counter value.
2080   * @param  None
2081   * @retval The value of Rx overflow Missed Frame Counter.
2082   */
ETH_GetRxOverflowMissedFrameCounter(void)2083 uint32_t ETH_GetRxOverflowMissedFrameCounter(void)
2084 {
2085   return ((uint32_t)((ETH->DMAMFBOCR & ETH_DMAMFBOCR_MFA)>>ETH_DMA_RX_OVERFLOW_MISSEDFRAMES_COUNTERSHIFT));
2086 }
2087 
2088 /**
2089   * @brief  Get the ETHERNET DMA Buffer Unavailable Missed Frame Counter value.
2090   * @param  None
2091   * @retval The value of Buffer unavailable Missed Frame Counter.
2092   */
ETH_GetBufferUnavailableMissedFrameCounter(void)2093 uint32_t ETH_GetBufferUnavailableMissedFrameCounter(void)
2094 {
2095   return ((uint32_t)(ETH->DMAMFBOCR) & ETH_DMAMFBOCR_MFC);
2096 }
2097 
2098 /**
2099   * @brief  Get the ETHERNET DMA DMACHTDR register value.
2100   * @param  None
2101   * @retval The value of the current Tx desc start address.
2102   */
ETH_GetCurrentTxDescStartAddress(void)2103 uint32_t ETH_GetCurrentTxDescStartAddress(void)
2104 {
2105   return ((uint32_t)(ETH->DMACHTDR));
2106 }
2107 
2108 /**
2109   * @brief  Get the ETHERNET DMA DMACHRDR register value.
2110   * @param  None
2111   * @retval The value of the current Rx desc start address.
2112   */
ETH_GetCurrentRxDescStartAddress(void)2113 uint32_t ETH_GetCurrentRxDescStartAddress(void)
2114 {
2115   return ((uint32_t)(ETH->DMACHRDR));
2116 }
2117 
2118 /**
2119   * @brief  Get the ETHERNET DMA DMACHTBAR register value.
2120   * @param  None
2121   * @retval The value of the current transmit descriptor data buffer address.
2122   */
ETH_GetCurrentTxBufferAddress(void)2123 uint32_t ETH_GetCurrentTxBufferAddress(void)
2124 {
2125   return ((uint32_t)(ETH->DMACHTBAR));
2126 }
2127 
2128 /**
2129   * @brief  Get the ETHERNET DMA DMACHRBAR register value.
2130   * @param  None
2131   * @retval The value of the current receive descriptor data buffer address.
2132   */
ETH_GetCurrentRxBufferAddress(void)2133 uint32_t ETH_GetCurrentRxBufferAddress(void)
2134 {
2135   return ((uint32_t)(ETH->DMACHRBAR));
2136 }
2137 
2138 /**
2139   * @brief  Resumes the DMA Transmission by writing to the DmaTxPollDemand register
2140   *   (the data written could be anything). This forces  the DMA to resume transmission.
2141   * @param  None
2142   * @retval None.
2143   */
ETH_ResumeDMATransmission(void)2144 void ETH_ResumeDMATransmission(void)
2145 {
2146   ETH->DMATPDR = 0;
2147 }
2148 
2149 /**
2150   * @brief  Resumes the DMA Transmission by writing to the DmaRxPollDemand register
2151   *   (the data written could be anything). This forces the DMA to resume reception.
2152   * @param  None
2153   * @retval None.
2154   */
ETH_ResumeDMAReception(void)2155 void ETH_ResumeDMAReception(void)
2156 {
2157   ETH->DMARPDR = 0;
2158 }
2159 
2160 /**
2161   * @brief  Set the DMA Receive status watchdog timer register value
2162   * @param  Value: DMA Receive status watchdog timer register value
2163   * @retval None
2164   */
ETH_SetReceiveWatchdogTimer(uint8_t Value)2165 void ETH_SetReceiveWatchdogTimer(uint8_t Value)
2166 {
2167   /* Set the DMA Receive status watchdog timer register */
2168   ETH->DMARSWTR = Value;
2169 }
2170 
2171 /******************************************************************************/
2172 /*                                PHY functions                               */
2173 /******************************************************************************/
2174 
2175 /**
2176   * @brief  Read a PHY register
2177   * @param PHYAddress: PHY device address, is the index of one of supported 32 PHY devices.
2178   *   This parameter can be one of the following values: 0,..,31
2179   * @param PHYReg: PHY register address, is the index of one of the 32 PHY register.
2180   *   This parameter can be one of the following values:
2181   *     @arg PHY_BCR: Transceiver Basic Control Register
2182   *     @arg PHY_BSR: Transceiver Basic Status Register
2183   *     @arg PHY_SR : Transceiver Status Register
2184   *     @arg More PHY register could be read depending on the used PHY
2185   * @retval ETH_ERROR: in case of timeout
2186   *         MAC MIIDR register value: Data read from the selected PHY register (correct read )
2187   */
ETH_ReadPHYRegister(uint16_t PHYAddress,uint16_t PHYReg)2188 uint16_t ETH_ReadPHYRegister(uint16_t PHYAddress, uint16_t PHYReg)
2189 {
2190   uint32_t tmpreg = 0;
2191 __IO uint32_t timeout = 0;
2192   /* Check the parameters */
2193   assert_param(IS_ETH_PHY_ADDRESS(PHYAddress));
2194   assert_param(IS_ETH_PHY_REG(PHYReg));
2195 
2196   /* Get the ETHERNET MACMIIAR value */
2197   tmpreg = ETH->MACMIIAR;
2198   /* Keep only the CSR Clock Range CR[2:0] bits value */
2199   tmpreg &= ~MACMIIAR_CR_MASK;
2200   /* Prepare the MII address register value */
2201   tmpreg |=(((uint32_t)PHYAddress<<11) & ETH_MACMIIAR_PA); /* Set the PHY device address */
2202   tmpreg |=(((uint32_t)PHYReg<<6) & ETH_MACMIIAR_MR);      /* Set the PHY register address */
2203   tmpreg &= ~ETH_MACMIIAR_MW;                              /* Set the read mode */
2204   tmpreg |= ETH_MACMIIAR_MB;                               /* Set the MII Busy bit */
2205   /* Write the result value into the MII Address register */
2206   ETH->MACMIIAR = tmpreg;
2207   /* Check for the Busy flag */
2208   do
2209   {
2210     timeout++;
2211     tmpreg = ETH->MACMIIAR;
2212   } while ((tmpreg & ETH_MACMIIAR_MB) && (timeout < (uint32_t)PHY_READ_TO));
2213   /* Return ERROR in case of timeout */
2214   if(timeout == PHY_READ_TO)
2215   {
2216     return (uint16_t)ETH_ERROR;
2217   }
2218 
2219   /* Return data register value */
2220   return (uint16_t)(ETH->MACMIIDR);
2221 }
2222 
2223 /**
2224   * @brief  Write to a PHY register
2225   * @param PHYAddress: PHY device address, is the index of one of supported 32 PHY devices.
2226   *   This parameter can be one of the following values: 0,..,31
2227   * @param PHYReg: PHY register address, is the index of one of the 32 PHY register.
2228   *   This parameter can be one of the following values:
2229   *     @arg PHY_BCR    : Transceiver Control Register
2230   *     @arg More PHY register could be written depending on the used PHY
2231   * @param  PHYValue: the value to write
2232   * @retval ETH_ERROR: in case of timeout
2233   *         ETH_SUCCESS: for correct write
2234   */
ETH_WritePHYRegister(uint16_t PHYAddress,uint16_t PHYReg,uint16_t PHYValue)2235 uint32_t ETH_WritePHYRegister(uint16_t PHYAddress, uint16_t PHYReg, uint16_t PHYValue)
2236 {
2237   uint32_t tmpreg = 0;
2238   __IO uint32_t timeout = 0;
2239   /* Check the parameters */
2240   assert_param(IS_ETH_PHY_ADDRESS(PHYAddress));
2241   assert_param(IS_ETH_PHY_REG(PHYReg));
2242 
2243   /* Get the ETHERNET MACMIIAR value */
2244   tmpreg = ETH->MACMIIAR;
2245   /* Keep only the CSR Clock Range CR[2:0] bits value */
2246   tmpreg &= ~MACMIIAR_CR_MASK;
2247   /* Prepare the MII register address value */
2248   tmpreg |=(((uint32_t)PHYAddress<<11) & ETH_MACMIIAR_PA); /* Set the PHY device address */
2249   tmpreg |=(((uint32_t)PHYReg<<6) & ETH_MACMIIAR_MR);      /* Set the PHY register address */
2250   tmpreg |= ETH_MACMIIAR_MW;                               /* Set the write mode */
2251   tmpreg |= ETH_MACMIIAR_MB;                               /* Set the MII Busy bit */
2252   /* Give the value to the MII data register */
2253   ETH->MACMIIDR = PHYValue;
2254   /* Write the result value into the MII Address register */
2255   ETH->MACMIIAR = tmpreg;
2256   /* Check for the Busy flag */
2257   do
2258   {
2259     timeout++;
2260     tmpreg = ETH->MACMIIAR;
2261   } while ((tmpreg & ETH_MACMIIAR_MB) && (timeout < (uint32_t)PHY_WRITE_TO));
2262   /* Return ERROR in case of timeout */
2263   if(timeout == PHY_WRITE_TO)
2264   {
2265     return ETH_ERROR;
2266   }
2267 
2268   /* Return SUCCESS */
2269   return ETH_SUCCESS;
2270 }
2271 
2272 /**
2273   * @brief  Enables or disables the PHY loopBack mode.
2274   * @Note: Don't be confused with ETH_MACLoopBackCmd function which enables internal
2275   *  loopback at MII level
2276   * @param  PHYAddress: PHY device address, is the index of one of supported 32 PHY devices.
2277   * @param  NewState: new state of the PHY loopBack mode.
2278   *   This parameter can be: ENABLE or DISABLE.
2279   * @retval ETH_ERROR: in case of bad PHY configuration
2280   *         ETH_SUCCESS: for correct PHY configuration
2281   */
ETH_PHYLoopBackCmd(uint16_t PHYAddress,FunctionalState NewState)2282 uint32_t ETH_PHYLoopBackCmd(uint16_t PHYAddress, FunctionalState NewState)
2283 {
2284   uint16_t tmpreg = 0;
2285   /* Check the parameters */
2286   assert_param(IS_ETH_PHY_ADDRESS(PHYAddress));
2287   assert_param(IS_FUNCTIONAL_STATE(NewState));
2288 
2289   /* Get the PHY configuration to update it */
2290   tmpreg = ETH_ReadPHYRegister(PHYAddress, PHY_BCR);
2291 
2292   if (NewState != DISABLE)
2293   {
2294     /* Enable the PHY loopback mode */
2295     tmpreg |= PHY_Loopback;
2296   }
2297   else
2298   {
2299     /* Disable the PHY loopback mode: normal mode */
2300     tmpreg &= (uint16_t)(~(uint16_t)PHY_Loopback);
2301   }
2302   /* Update the PHY control register with the new configuration */
2303   if(ETH_WritePHYRegister(PHYAddress, PHY_BCR, tmpreg) != (uint32_t)RESET)
2304   {
2305     return ETH_SUCCESS;
2306   }
2307   else
2308   {
2309     /* Return SUCCESS */
2310     return ETH_ERROR;
2311   }
2312 }
2313 
2314 /******************************************************************************/
2315 /*                           Power Management(PMT) functions                  */
2316 /******************************************************************************/
2317 /**
2318   * @brief  Reset Wakeup frame filter register pointer.
2319   * @param  None
2320   * @retval None
2321   */
ETH_ResetWakeUpFrameFilterRegisterPointer(void)2322 void ETH_ResetWakeUpFrameFilterRegisterPointer(void)
2323 {
2324   /* Resets the Remote Wake-up Frame Filter register pointer to 0x0000 */
2325   ETH->MACPMTCSR |= ETH_MACPMTCSR_WFFRPR;
2326 }
2327 
2328 /**
2329   * @brief  Populates the remote wakeup frame registers.
2330   * @param  Buffer: Pointer on remote WakeUp Frame Filter Register buffer data (8 words).
2331   * @retval None
2332   */
ETH_SetWakeUpFrameFilterRegister(uint32_t * Buffer)2333 void ETH_SetWakeUpFrameFilterRegister(uint32_t *Buffer)
2334 {
2335   uint32_t i = 0;
2336 
2337   /* Fill Remote Wake-up Frame Filter register with Buffer data */
2338   for(i =0; i<ETH_WAKEUP_REGISTER_LENGTH; i++)
2339   {
2340     /* Write each time to the same register */
2341     ETH->MACRWUFFR = Buffer[i];
2342   }
2343 }
2344 
2345 /**
2346   * @brief  Enables or disables any unicast packet filtered by the MAC address
2347   *   recognition to be a wake-up frame.
2348   * @param  NewState: new state of the MAC Global Unicast Wake-Up.
2349   *   This parameter can be: ENABLE or DISABLE.
2350   * @retval None
2351   */
ETH_GlobalUnicastWakeUpCmd(FunctionalState NewState)2352 void ETH_GlobalUnicastWakeUpCmd(FunctionalState NewState)
2353 {
2354   /* Check the parameters */
2355   assert_param(IS_FUNCTIONAL_STATE(NewState));
2356 
2357   if (NewState != DISABLE)
2358   {
2359     /* Enable the MAC Global Unicast Wake-Up */
2360     ETH->MACPMTCSR |= ETH_MACPMTCSR_GU;
2361   }
2362   else
2363   {
2364     /* Disable the MAC Global Unicast Wake-Up */
2365     ETH->MACPMTCSR &= ~ETH_MACPMTCSR_GU;
2366   }
2367 }
2368 
2369 /**
2370   * @brief  Checks whether the specified ETHERNET PMT flag is set or not.
2371   * @param  ETH_PMT_FLAG: specifies the flag to check.
2372   *   This parameter can be one of the following values:
2373   *     @arg ETH_PMT_FLAG_WUFFRPR : Wake-Up Frame Filter Register Pointer Reset
2374   *     @arg ETH_PMT_FLAG_WUFR    : Wake-Up Frame Received
2375   *     @arg ETH_PMT_FLAG_MPR     : Magic Packet Received
2376   * @retval The new state of ETHERNET PMT Flag (SET or RESET).
2377   */
ETH_GetPMTFlagStatus(uint32_t ETH_PMT_FLAG)2378 FlagStatus ETH_GetPMTFlagStatus(uint32_t ETH_PMT_FLAG)
2379 {
2380   FlagStatus bitstatus = RESET;
2381   /* Check the parameters */
2382   assert_param(IS_ETH_PMT_GET_FLAG(ETH_PMT_FLAG));
2383 
2384   if ((ETH->MACPMTCSR & ETH_PMT_FLAG) != (uint32_t)RESET)
2385   {
2386     bitstatus = SET;
2387   }
2388   else
2389   {
2390     bitstatus = RESET;
2391   }
2392   return bitstatus;
2393 }
2394 
2395 /**
2396   * @brief  Enables or disables the MAC Wake-Up Frame Detection.
2397   * @param  NewState: new state of the MAC Wake-Up Frame Detection.
2398   *   This parameter can be: ENABLE or DISABLE.
2399   * @retval None
2400   */
ETH_WakeUpFrameDetectionCmd(FunctionalState NewState)2401 void ETH_WakeUpFrameDetectionCmd(FunctionalState NewState)
2402 {
2403   /* Check the parameters */
2404   assert_param(IS_FUNCTIONAL_STATE(NewState));
2405 
2406   if (NewState != DISABLE)
2407   {
2408     /* Enable the MAC Wake-Up Frame Detection */
2409     ETH->MACPMTCSR |= ETH_MACPMTCSR_WFE;
2410   }
2411   else
2412   {
2413     /* Disable the MAC Wake-Up Frame Detection */
2414     ETH->MACPMTCSR &= ~ETH_MACPMTCSR_WFE;
2415   }
2416 }
2417 
2418 /**
2419   * @brief  Enables or disables the MAC Magic Packet Detection.
2420   * @param  NewState: new state of the MAC Magic Packet Detection.
2421   *   This parameter can be: ENABLE or DISABLE.
2422   * @retval None
2423   */
ETH_MagicPacketDetectionCmd(FunctionalState NewState)2424 void ETH_MagicPacketDetectionCmd(FunctionalState NewState)
2425 {
2426   /* Check the parameters */
2427   assert_param(IS_FUNCTIONAL_STATE(NewState));
2428 
2429   if (NewState != DISABLE)
2430   {
2431     /* Enable the MAC Magic Packet Detection */
2432     ETH->MACPMTCSR |= ETH_MACPMTCSR_MPE;
2433   }
2434   else
2435   {
2436     /* Disable the MAC Magic Packet Detection */
2437     ETH->MACPMTCSR &= ~ETH_MACPMTCSR_MPE;
2438   }
2439 }
2440 
2441 /**
2442   * @brief  Enables or disables the MAC Power Down.
2443   * @param  NewState: new state of the MAC Power Down.
2444   *   This parameter can be: ENABLE or DISABLE.
2445   * @retval None
2446   */
ETH_PowerDownCmd(FunctionalState NewState)2447 void ETH_PowerDownCmd(FunctionalState NewState)
2448 {
2449   /* Check the parameters */
2450   assert_param(IS_FUNCTIONAL_STATE(NewState));
2451 
2452   if (NewState != DISABLE)
2453   {
2454     /* Enable the MAC Power Down */
2455     /* This puts the MAC in power down mode */
2456     ETH->MACPMTCSR |= ETH_MACPMTCSR_PD;
2457   }
2458   else
2459   {
2460     /* Disable the MAC Power Down */
2461     ETH->MACPMTCSR &= ~ETH_MACPMTCSR_PD;
2462   }
2463 }
2464 
2465 /******************************************************************************/
2466 /*                              MMC functions                                 */
2467 /******************************************************************************/
2468 /**
2469   * @brief  Preset and Initialize the MMC counters to almost-full value: 0xFFFF_FFF0 (full - 16)
2470   * @param  None
2471   * @retval None
2472   */
ETH_MMCCounterFullPreset(void)2473 void ETH_MMCCounterFullPreset(void)
2474 {
2475   /* Preset and Initialize the MMC counters to almost-full value */
2476   ETH->MMCCR |= ETH_MMCCR_MCFHP | ETH_MMCCR_MCP;
2477 }
2478 
2479 /**
2480   * @brief  Preset and Initialize the MMC counters to almost-hal value: 0x7FFF_FFF0 (half - 16).
2481   * @param  None
2482   * @retval None
2483   */
ETH_MMCCounterHalfPreset(void)2484 void ETH_MMCCounterHalfPreset(void)
2485 {
2486   /* Preset the MMC counters to almost-full value */
2487   ETH->MMCCR &= ~ETH_MMCCR_MCFHP;
2488   /* Initialize the MMC counters to almost-half value */
2489   ETH->MMCCR |= ETH_MMCCR_MCP;
2490 }
2491 
2492  /**
2493   * @brief  Enables or disables the MMC Counter Freeze.
2494   * @param  NewState: new state of the MMC Counter Freeze.
2495   *   This parameter can be: ENABLE or DISABLE.
2496   * @retval None
2497   */
ETH_MMCCounterFreezeCmd(FunctionalState NewState)2498 void ETH_MMCCounterFreezeCmd(FunctionalState NewState)
2499 {
2500   /* Check the parameters */
2501   assert_param(IS_FUNCTIONAL_STATE(NewState));
2502 
2503   if (NewState != DISABLE)
2504   {
2505     /* Enable the MMC Counter Freeze */
2506     ETH->MMCCR |= ETH_MMCCR_MCF;
2507   }
2508   else
2509   {
2510     /* Disable the MMC Counter Freeze */
2511     ETH->MMCCR &= ~ETH_MMCCR_MCF;
2512   }
2513 }
2514 
2515 /**
2516   * @brief  Enables or disables the MMC Reset On Read.
2517   * @param  NewState: new state of the MMC Reset On Read.
2518   *   This parameter can be: ENABLE or DISABLE.
2519   * @retval None
2520   */
ETH_MMCResetOnReadCmd(FunctionalState NewState)2521 void ETH_MMCResetOnReadCmd(FunctionalState NewState)
2522 {
2523   /* Check the parameters */
2524   assert_param(IS_FUNCTIONAL_STATE(NewState));
2525 
2526   if (NewState != DISABLE)
2527   {
2528     /* Enable the MMC Counter reset on read */
2529     ETH->MMCCR |= ETH_MMCCR_ROR;
2530   }
2531   else
2532   {
2533     /* Disable the MMC Counter reset on read */
2534     ETH->MMCCR &= ~ETH_MMCCR_ROR;
2535   }
2536 }
2537 
2538 /**
2539   * @brief  Enables or disables the MMC Counter Stop Rollover.
2540   * @param  NewState: new state of the MMC Counter Stop Rollover.
2541   *   This parameter can be: ENABLE or DISABLE.
2542   * @retval None
2543   */
ETH_MMCCounterRolloverCmd(FunctionalState NewState)2544 void ETH_MMCCounterRolloverCmd(FunctionalState NewState)
2545 {
2546   /* Check the parameters */
2547   assert_param(IS_FUNCTIONAL_STATE(NewState));
2548 
2549   if (NewState != DISABLE)
2550   {
2551     /* Disable the MMC Counter Stop Rollover  */
2552     ETH->MMCCR &= ~ETH_MMCCR_CSR;
2553   }
2554   else
2555   {
2556     /* Enable the MMC Counter Stop Rollover */
2557     ETH->MMCCR |= ETH_MMCCR_CSR;
2558   }
2559 }
2560 
2561 /**
2562   * @brief  Resets the MMC Counters.
2563   * @param  None
2564   * @retval None
2565   */
ETH_MMCCountersReset(void)2566 void ETH_MMCCountersReset(void)
2567 {
2568   /* Resets the MMC Counters */
2569   ETH->MMCCR |= ETH_MMCCR_CR;
2570 }
2571 
2572 /**
2573   * @brief  Enables or disables the specified ETHERNET MMC interrupts.
2574   * @param  ETH_MMC_IT: specifies the ETHERNET MMC interrupt sources to be enabled or disabled.
2575   *   This parameter can be any combination of Tx interrupt or
2576   *   any combination of Rx interrupt (but not both)of the following values:
2577   *     @arg ETH_MMC_IT_TGF   : When Tx good frame counter reaches half the maximum value
2578   *     @arg ETH_MMC_IT_TGFMSC: When Tx good multi col counter reaches half the maximum value
2579   *     @arg ETH_MMC_IT_TGFSC : When Tx good single col counter reaches half the maximum value
2580   *     @arg ETH_MMC_IT_RGUF  : When Rx good unicast frames counter reaches half the maximum value
2581   *     @arg ETH_MMC_IT_RFAE  : When Rx alignment error counter reaches half the maximum value
2582   *     @arg ETH_MMC_IT_RFCE  : When Rx crc error counter reaches half the maximum value
2583   * @param  NewState: new state of the specified ETHERNET MMC interrupts.
2584   *   This parameter can be: ENABLE or DISABLE.
2585   * @retval None
2586   */
ETH_MMCITConfig(uint32_t ETH_MMC_IT,FunctionalState NewState)2587 void ETH_MMCITConfig(uint32_t ETH_MMC_IT, FunctionalState NewState)
2588 {
2589   /* Check the parameters */
2590   assert_param(IS_ETH_MMC_IT(ETH_MMC_IT));
2591   assert_param(IS_FUNCTIONAL_STATE(NewState));
2592 
2593   if ((ETH_MMC_IT & (uint32_t)0x10000000) != (uint32_t)RESET)
2594   {
2595     /* Remove Register mak from IT */
2596     ETH_MMC_IT &= 0xEFFFFFFF;
2597 
2598     /* ETHERNET MMC Rx interrupts selected */
2599     if (NewState != DISABLE)
2600     {
2601       /* Enable the selected ETHERNET MMC interrupts */
2602       ETH->MMCRIMR &=(~(uint32_t)ETH_MMC_IT);
2603     }
2604     else
2605     {
2606       /* Disable the selected ETHERNET MMC interrupts */
2607       ETH->MMCRIMR |= ETH_MMC_IT;
2608     }
2609   }
2610   else
2611   {
2612     /* ETHERNET MMC Tx interrupts selected */
2613     if (NewState != DISABLE)
2614     {
2615       /* Enable the selected ETHERNET MMC interrupts */
2616       ETH->MMCTIMR &=(~(uint32_t)ETH_MMC_IT);
2617     }
2618     else
2619     {
2620       /* Disable the selected ETHERNET MMC interrupts */
2621       ETH->MMCTIMR |= ETH_MMC_IT;
2622     }
2623   }
2624 }
2625 
2626 /**
2627   * @brief  Checks whether the specified ETHERNET MMC IT is set or not.
2628   * @param  ETH_MMC_IT: specifies the ETHERNET MMC interrupt.
2629   *   This parameter can be one of the following values:
2630   *     @arg ETH_MMC_IT_TxFCGC: When Tx good frame counter reaches half the maximum value
2631   *     @arg ETH_MMC_IT_TxMCGC: When Tx good multi col counter reaches half the maximum value
2632   *     @arg ETH_MMC_IT_TxSCGC: When Tx good single col counter reaches half the maximum value
2633   *     @arg ETH_MMC_IT_RxUGFC: When Rx good unicast frames counter reaches half the maximum value
2634   *     @arg ETH_MMC_IT_RxAEC : When Rx alignment error counter reaches half the maximum value
2635   *     @arg ETH_MMC_IT_RxCEC : When Rx crc error counter reaches half the maximum value
2636   * @retval The value of ETHERNET MMC IT (SET or RESET).
2637   */
ETH_GetMMCITStatus(uint32_t ETH_MMC_IT)2638 ITStatus ETH_GetMMCITStatus(uint32_t ETH_MMC_IT)
2639 {
2640   ITStatus bitstatus = RESET;
2641   /* Check the parameters */
2642   assert_param(IS_ETH_MMC_GET_IT(ETH_MMC_IT));
2643 
2644   if ((ETH_MMC_IT & (uint32_t)0x10000000) != (uint32_t)RESET)
2645   {
2646     /* ETHERNET MMC Rx interrupts selected */
2647     /* Check if the ETHERNET MMC Rx selected interrupt is enabled and occurred */
2648     if ((((ETH->MMCRIR & ETH_MMC_IT) != (uint32_t)RESET)) && ((ETH->MMCRIMR & ETH_MMC_IT) == (uint32_t)RESET))
2649     {
2650       bitstatus = SET;
2651     }
2652     else
2653     {
2654       bitstatus = RESET;
2655     }
2656   }
2657   else
2658   {
2659     /* ETHERNET MMC Tx interrupts selected */
2660     /* Check if the ETHERNET MMC Tx selected interrupt is enabled and occurred */
2661     if ((((ETH->MMCTIR & ETH_MMC_IT) != (uint32_t)RESET)) && ((ETH->MMCRIMR & ETH_MMC_IT) == (uint32_t)RESET))
2662     {
2663       bitstatus = SET;
2664     }
2665     else
2666     {
2667       bitstatus = RESET;
2668     }
2669   }
2670 
2671   return bitstatus;
2672 }
2673 
2674 /**
2675   * @brief  Get the specified ETHERNET MMC register value.
2676   * @param  ETH_MMCReg: specifies the ETHERNET MMC register.
2677   *   This parameter can be one of the following values:
2678   *     @arg ETH_MMCCR      : MMC CR register
2679   *     @arg ETH_MMCRIR     : MMC RIR register
2680   *     @arg ETH_MMCTIR     : MMC TIR register
2681   *     @arg ETH_MMCRIMR    : MMC RIMR register
2682   *     @arg ETH_MMCTIMR    : MMC TIMR register
2683   *     @arg ETH_MMCTGFSCCR : MMC TGFSCCR register
2684   *     @arg ETH_MMCTGFMSCCR: MMC TGFMSCCR register
2685   *     @arg ETH_MMCTGFCR   : MMC TGFCR register
2686   *     @arg ETH_MMCRFCECR  : MMC RFCECR register
2687   *     @arg ETH_MMCRFAECR  : MMC RFAECR register
2688   *     @arg ETH_MMCRGUFCR  : MMC RGUFCRregister
2689   * @retval The value of ETHERNET MMC Register value.
2690   */
ETH_GetMMCRegister(uint32_t ETH_MMCReg)2691 uint32_t ETH_GetMMCRegister(uint32_t ETH_MMCReg)
2692 {
2693   /* Check the parameters */
2694   assert_param(IS_ETH_MMC_REGISTER(ETH_MMCReg));
2695 
2696   /* Return the selected register value */
2697   return (*(__IO uint32_t *)(ETH_MAC_BASE + ETH_MMCReg));
2698 }
2699 
2700 
2701 
2702 /**
2703   * @}
2704   */
2705 
2706 /**
2707   * @}
2708   */
2709