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