amiro-blt / Target / Demo / ARMCM4_STM32F405_Power_Management_GCC / Boot / lib / ethernetlib / src / stm32_eth.c @ 69661903
History | View | Annotate | Download (113 KB)
1 |
/**
|
---|---|
2 |
******************************************************************************
|
3 |
* @file stm32_eth.c
|
4 |
* @author MCD Application Team
|
5 |
* @version V1.0.0
|
6 |
* @date 06/19/2009
|
7 |
* @brief This file provides all the ETH firmware functions.
|
8 |
******************************************************************************
|
9 |
* @copy
|
10 |
*
|
11 |
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
12 |
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
13 |
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
14 |
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
15 |
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
16 |
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
17 |
*
|
18 |
* <h2><center>© COPYRIGHT 2009 STMicroelectronics</center></h2>
|
19 |
*/
|
20 |
|
21 |
/* Includes ------------------------------------------------------------------*/
|
22 |
#include "stm32_eth.h" |
23 |
#include "stm32f4xx_rcc.h" |
24 |
|
25 |
/** @addtogroup STM32_ETH_Driver
|
26 |
* @brief ETH driver modules
|
27 |
* @{
|
28 |
*/
|
29 |
|
30 |
/** @defgroup ETH_Private_TypesDefinitions
|
31 |
* @{
|
32 |
*/
|
33 |
/**
|
34 |
* @}
|
35 |
*/
|
36 |
|
37 |
|
38 |
/** @defgroup ETH_Private_Defines
|
39 |
* @{
|
40 |
*/
|
41 |
/* Global pointers on Tx and Rx descriptor used to track transmit and receive descriptors */
|
42 |
ETH_DMADESCTypeDef *DMATxDescToSet; |
43 |
ETH_DMADESCTypeDef *DMARxDescToGet; |
44 |
ETH_DMADESCTypeDef *DMAPTPTxDescToSet; |
45 |
ETH_DMADESCTypeDef *DMAPTPRxDescToGet; |
46 |
|
47 |
/* ETHERNET MAC address offsets */
|
48 |
#define ETH_MAC_AddrHighBase (ETH_MAC_BASE + 0x40) /* ETHERNET MAC address high offset */ |
49 |
#define ETH_MAC_AddrLowBase (ETH_MAC_BASE + 0x44) /* ETHERNET MAC address low offset */ |
50 |
/* ETHERNET MACMIIAR register Mask */
|
51 |
#define MACMIIAR_CR_Mask ((uint32_t)0xFFFFFFE3) |
52 |
/* ETHERNET MACCR register Mask */
|
53 |
#define MACCR_CLEAR_Mask ((uint32_t)0xFF20810F) |
54 |
/* ETHERNET MACFCR register Mask */
|
55 |
#define MACFCR_CLEAR_Mask ((uint32_t)0x0000FF41) |
56 |
/* ETHERNET DMAOMR register Mask */
|
57 |
#define DMAOMR_CLEAR_Mask ((uint32_t)0xF8DE3F23) |
58 |
/* ETHERNET Remote Wake-up frame register length */
|
59 |
#define ETH_WakeupRegisterLength 8 |
60 |
/* ETHERNET Missed frames counter Shift */
|
61 |
#define ETH_DMA_RxOverflowMissedFramesCounterShift 17 |
62 |
/* ETHERNET DMA Tx descriptors Collision Count Shift */
|
63 |
#define ETH_DMATxDesc_CollisionCountShift 3 |
64 |
/* ETHERNET DMA Tx descriptors Buffer2 Size Shift */
|
65 |
#define ETH_DMATxDesc_BufferSize2Shift 16 |
66 |
/* ETHERNET DMA Rx descriptors Frame Length Shift */
|
67 |
#define ETH_DMARxDesc_FrameLengthShift 16 |
68 |
/* ETHERNET DMA Rx descriptors Buffer2 Size Shift */
|
69 |
#define ETH_DMARxDesc_Buffer2SizeShift 16 |
70 |
/* ETHERNET errors */
|
71 |
#define ETH_ERROR ((uint32_t)0) |
72 |
#define ETH_SUCCESS ((uint32_t)1) |
73 |
/**
|
74 |
* @}
|
75 |
*/
|
76 |
|
77 |
/** @defgroup ETH_Private_Macros
|
78 |
* @{
|
79 |
*/
|
80 |
/**
|
81 |
* @}
|
82 |
*/
|
83 |
|
84 |
/** @defgroup ETH_Private_Variables
|
85 |
* @{
|
86 |
*/
|
87 |
/**
|
88 |
* @}
|
89 |
*/
|
90 |
|
91 |
/** @defgroup ETH_Private_FunctionPrototypes
|
92 |
* @{
|
93 |
*/
|
94 |
/**
|
95 |
* @}
|
96 |
*/
|
97 |
|
98 |
/** @defgroup ETH_Private_Functions
|
99 |
* @{
|
100 |
*/
|
101 |
|
102 |
/**
|
103 |
* @brief Deinitializes the ETHERNET peripheral registers to their
|
104 |
* default reset values.
|
105 |
* @param None
|
106 |
* @retval : None
|
107 |
*/
|
108 |
void ETH_DeInit(void) |
109 |
{ |
110 |
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_ETH_MAC, ENABLE); |
111 |
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_ETH_MAC, DISABLE); |
112 |
} |
113 |
|
114 |
/**
|
115 |
* @brief Initializes the ETHERNET peripheral according to the specified
|
116 |
* parameters in the ETH_InitStruct .
|
117 |
* @param ETH_InitStruct: pointer to a ETH_InitTypeDef structure
|
118 |
* that contains the configuration information for the
|
119 |
* specified ETHERNET peripheral.
|
120 |
* @param PHYAddress: external PHY address
|
121 |
* @retval : ETH_ERROR: Ethernet initialization failed
|
122 |
* ETH_SUCCESS: Ethernet successfully initialized
|
123 |
*/
|
124 |
uint32_t ETH_Init(ETH_InitTypeDef* ETH_InitStruct, uint16_t PHYAddress) |
125 |
{ |
126 |
uint32_t RegValue = 0, tmpreg = 0; |
127 |
__IO uint32_t i = 0;
|
128 |
RCC_ClocksTypeDef rcc_clocks; |
129 |
uint32_t hclk = 120000000;
|
130 |
__IO uint32_t timeout = 0;
|
131 |
/* Check the parameters */
|
132 |
/* MAC --------------------------*/
|
133 |
assert_param(IS_ETH_AUTONEGOTIATION(ETH_InitStruct->ETH_AutoNegotiation)); |
134 |
assert_param(IS_ETH_WATCHDOG(ETH_InitStruct->ETH_Watchdog)); |
135 |
assert_param(IS_ETH_JABBER(ETH_InitStruct->ETH_Jabber)); |
136 |
assert_param(IS_ETH_INTER_FRAME_GAP(ETH_InitStruct->ETH_InterFrameGap)); |
137 |
assert_param(IS_ETH_CARRIER_SENSE(ETH_InitStruct->ETH_CarrierSense)); |
138 |
assert_param(IS_ETH_SPEED(ETH_InitStruct->ETH_Speed)); |
139 |
assert_param(IS_ETH_RECEIVE_OWN(ETH_InitStruct->ETH_ReceiveOwn)); |
140 |
assert_param(IS_ETH_LOOPBACK_MODE(ETH_InitStruct->ETH_LoopbackMode)); |
141 |
assert_param(IS_ETH_DUPLEX_MODE(ETH_InitStruct->ETH_Mode)); |
142 |
assert_param(IS_ETH_CHECKSUM_OFFLOAD(ETH_InitStruct->ETH_ChecksumOffload)); |
143 |
assert_param(IS_ETH_RETRY_TRANSMISSION(ETH_InitStruct->ETH_RetryTransmission)); |
144 |
assert_param(IS_ETH_AUTOMATIC_PADCRC_STRIP(ETH_InitStruct->ETH_AutomaticPadCRCStrip)); |
145 |
assert_param(IS_ETH_BACKOFF_LIMIT(ETH_InitStruct->ETH_BackOffLimit)); |
146 |
assert_param(IS_ETH_DEFERRAL_CHECK(ETH_InitStruct->ETH_DeferralCheck)); |
147 |
assert_param(IS_ETH_RECEIVE_ALL(ETH_InitStruct->ETH_ReceiveAll)); |
148 |
assert_param(IS_ETH_SOURCE_ADDR_FILTER(ETH_InitStruct->ETH_SourceAddrFilter)); |
149 |
assert_param(IS_ETH_CONTROL_FRAMES(ETH_InitStruct->ETH_PassControlFrames)); |
150 |
assert_param(IS_ETH_BROADCAST_FRAMES_RECEPTION(ETH_InitStruct->ETH_BroadcastFramesReception)); |
151 |
assert_param(IS_ETH_DESTINATION_ADDR_FILTER(ETH_InitStruct->ETH_DestinationAddrFilter)); |
152 |
assert_param(IS_ETH_PROMISCUOUS_MODE(ETH_InitStruct->ETH_PromiscuousMode)); |
153 |
assert_param(IS_ETH_MULTICAST_FRAMES_FILTER(ETH_InitStruct->ETH_MulticastFramesFilter)); |
154 |
assert_param(IS_ETH_UNICAST_FRAMES_FILTER(ETH_InitStruct->ETH_UnicastFramesFilter)); |
155 |
assert_param(IS_ETH_PAUSE_TIME(ETH_InitStruct->ETH_PauseTime)); |
156 |
assert_param(IS_ETH_ZEROQUANTA_PAUSE(ETH_InitStruct->ETH_ZeroQuantaPause)); |
157 |
assert_param(IS_ETH_PAUSE_LOW_THRESHOLD(ETH_InitStruct->ETH_PauseLowThreshold)); |
158 |
assert_param(IS_ETH_UNICAST_PAUSE_FRAME_DETECT(ETH_InitStruct->ETH_UnicastPauseFrameDetect)); |
159 |
assert_param(IS_ETH_RECEIVE_FLOWCONTROL(ETH_InitStruct->ETH_ReceiveFlowControl)); |
160 |
assert_param(IS_ETH_TRANSMIT_FLOWCONTROL(ETH_InitStruct->ETH_TransmitFlowControl)); |
161 |
assert_param(IS_ETH_VLAN_TAG_COMPARISON(ETH_InitStruct->ETH_VLANTagComparison)); |
162 |
assert_param(IS_ETH_VLAN_TAG_IDENTIFIER(ETH_InitStruct->ETH_VLANTagIdentifier)); |
163 |
/* DMA --------------------------*/
|
164 |
assert_param(IS_ETH_DROP_TCPIP_CHECKSUM_FRAME(ETH_InitStruct->ETH_DropTCPIPChecksumErrorFrame)); |
165 |
assert_param(IS_ETH_RECEIVE_STORE_FORWARD(ETH_InitStruct->ETH_ReceiveStoreForward)); |
166 |
assert_param(IS_ETH_FLUSH_RECEIVE_FRAME(ETH_InitStruct->ETH_FlushReceivedFrame)); |
167 |
assert_param(IS_ETH_TRANSMIT_STORE_FORWARD(ETH_InitStruct->ETH_TransmitStoreForward)); |
168 |
assert_param(IS_ETH_TRANSMIT_THRESHOLD_CONTROL(ETH_InitStruct->ETH_TransmitThresholdControl)); |
169 |
assert_param(IS_ETH_FORWARD_ERROR_FRAMES(ETH_InitStruct->ETH_ForwardErrorFrames)); |
170 |
assert_param(IS_ETH_FORWARD_UNDERSIZED_GOOD_FRAMES(ETH_InitStruct->ETH_ForwardUndersizedGoodFrames)); |
171 |
assert_param(IS_ETH_RECEIVE_THRESHOLD_CONTROL(ETH_InitStruct->ETH_ReceiveThresholdControl)); |
172 |
assert_param(IS_ETH_SECOND_FRAME_OPERATE(ETH_InitStruct->ETH_SecondFrameOperate)); |
173 |
assert_param(IS_ETH_ADDRESS_ALIGNED_BEATS(ETH_InitStruct->ETH_AddressAlignedBeats)); |
174 |
assert_param(IS_ETH_FIXED_BURST(ETH_InitStruct->ETH_FixedBurst)); |
175 |
assert_param(IS_ETH_RXDMA_BURST_LENGTH(ETH_InitStruct->ETH_RxDMABurstLength)); |
176 |
assert_param(IS_ETH_TXDMA_BURST_LENGTH(ETH_InitStruct->ETH_TxDMABurstLength)); |
177 |
assert_param(IS_ETH_DMA_DESC_SKIP_LENGTH(ETH_InitStruct->ETH_DescriptorSkipLength)); |
178 |
assert_param(IS_ETH_DMA_ARBITRATION_ROUNDROBIN_RXTX(ETH_InitStruct->ETH_DMAArbitration)); |
179 |
/*-------------------------------- MAC Config ------------------------------*/
|
180 |
/*---------------------- ETHERNET MACMIIAR Configuration -------------------*/
|
181 |
/* Get the ETHERNET MACMIIAR value */
|
182 |
tmpreg = ETH->MACMIIAR; |
183 |
/* Clear CSR Clock Range CR[2:0] bits */
|
184 |
tmpreg &= MACMIIAR_CR_Mask; |
185 |
/* Get hclk frequency value */
|
186 |
RCC_GetClocksFreq(&rcc_clocks); |
187 |
hclk = rcc_clocks.HCLK_Frequency; |
188 |
/* Set CR bits depending on hclk value */
|
189 |
if((hclk >= 20000000)&&(hclk < 35000000)) |
190 |
{ |
191 |
/* CSR Clock Range between 20-35 MHz */
|
192 |
tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div16; |
193 |
} |
194 |
else if((hclk >= 35000000)&&(hclk < 60000000)) |
195 |
{ |
196 |
/* CSR Clock Range between 35-60 MHz */
|
197 |
tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div26; |
198 |
} |
199 |
else if((hclk >= 60000000)&&(hclk <= 100000000)) |
200 |
{ |
201 |
/* CSR Clock Range between 60-100 MHz */
|
202 |
tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div42; |
203 |
} |
204 |
else /*if((hclk >= 100000000)&&(hclk <= 120000000)) */ |
205 |
{ |
206 |
/* CSR Clock Range between 100-120 MHz */
|
207 |
tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div62; |
208 |
} |
209 |
/* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
|
210 |
ETH->MACMIIAR = (uint32_t)tmpreg; |
211 |
/*-------------------- PHY initialization and configuration ----------------*/
|
212 |
/* Put the PHY in reset mode */
|
213 |
if(!(ETH_WritePHYRegister(PHYAddress, PHY_BCR, PHY_Reset)))
|
214 |
{ |
215 |
/* Return ERROR in case of write timeout */
|
216 |
return ETH_ERROR;
|
217 |
} |
218 |
|
219 |
/* Delay to assure PHY reset */
|
220 |
for(i = PHY_ResetDelay; i != 0; i--) |
221 |
{ |
222 |
} |
223 |
|
224 |
if(ETH_InitStruct->ETH_AutoNegotiation != ETH_AutoNegotiation_Disable)
|
225 |
{ |
226 |
/* We wait for linked satus... */
|
227 |
do
|
228 |
{ |
229 |
timeout++; |
230 |
} while (!(ETH_ReadPHYRegister(PHYAddress, PHY_BSR) & PHY_Linked_Status) && (timeout < PHY_READ_TO));
|
231 |
/* Return ERROR in case of timeout */
|
232 |
if(timeout == PHY_READ_TO)
|
233 |
{ |
234 |
return ETH_ERROR;
|
235 |
} |
236 |
/* Reset Timeout counter */
|
237 |
timeout = 0;
|
238 |
|
239 |
/* Enable Auto-Negotiation */
|
240 |
if(!(ETH_WritePHYRegister(PHYAddress, PHY_BCR, PHY_AutoNegotiation)))
|
241 |
{ |
242 |
/* Return ERROR in case of write timeout */
|
243 |
return ETH_ERROR;
|
244 |
} |
245 |
|
246 |
/* Wait until the autonegotiation will be completed */
|
247 |
do
|
248 |
{ |
249 |
timeout++; |
250 |
} while (!(ETH_ReadPHYRegister(PHYAddress, PHY_BSR) & PHY_AutoNego_Complete) && (timeout < (uint32_t)PHY_READ_TO));
|
251 |
/* Return ERROR in case of timeout */
|
252 |
if(timeout == PHY_READ_TO)
|
253 |
{ |
254 |
return ETH_ERROR;
|
255 |
} |
256 |
/* Reset Timeout counter */
|
257 |
timeout = 0;
|
258 |
|
259 |
/* Read the result of the autonegotiation */
|
260 |
RegValue = ETH_ReadPHYRegister(PHYAddress, PHY_SR); |
261 |
|
262 |
/* Configure the MAC with the Duplex Mode fixed by the autonegotiation process */
|
263 |
if((RegValue & PHY_Duplex_Status) != (uint32_t)RESET)
|
264 |
{ |
265 |
/* Set Ethernet duplex mode to FullDuplex following the autonegotiation */
|
266 |
ETH_InitStruct->ETH_Mode = ETH_Mode_FullDuplex; |
267 |
|
268 |
} |
269 |
else
|
270 |
{ |
271 |
/* Set Ethernet duplex mode to HalfDuplex following the autonegotiation */
|
272 |
ETH_InitStruct->ETH_Mode = ETH_Mode_HalfDuplex; |
273 |
} |
274 |
/* Configure the MAC with the speed fixed by the autonegotiation process */
|
275 |
if(RegValue & PHY_Speed_Status)
|
276 |
{ |
277 |
/* Set Ethernet speed to 10M following the autonegotiation */
|
278 |
ETH_InitStruct->ETH_Speed = ETH_Speed_10M; |
279 |
} |
280 |
else
|
281 |
{ |
282 |
/* Set Ethernet speed to 100M following the autonegotiation */
|
283 |
ETH_InitStruct->ETH_Speed = ETH_Speed_100M; |
284 |
} |
285 |
} |
286 |
else
|
287 |
{ |
288 |
if(!ETH_WritePHYRegister(PHYAddress, PHY_BCR, ((uint16_t)(ETH_InitStruct->ETH_Mode >> 3) | |
289 |
(uint16_t)(ETH_InitStruct->ETH_Speed >> 1))))
|
290 |
{ |
291 |
/* Return ERROR in case of write timeout */
|
292 |
return ETH_ERROR;
|
293 |
} |
294 |
/* Delay to assure PHY configuration */
|
295 |
for(i = PHY_ConfigDelay; i != 0; i--) |
296 |
{ |
297 |
} |
298 |
} |
299 |
/*------------------------ ETHERNET MACCR Configuration --------------------*/
|
300 |
/* Get the ETHERNET MACCR value */
|
301 |
tmpreg = ETH->MACCR; |
302 |
/* Clear WD, PCE, PS, TE and RE bits */
|
303 |
tmpreg &= MACCR_CLEAR_Mask; |
304 |
/* Set the WD bit according to ETH_Watchdog value */
|
305 |
/* Set the JD: bit according to ETH_Jabber value */
|
306 |
/* Set the IFG bit according to ETH_InterFrameGap value */
|
307 |
/* Set the DCRS bit according to ETH_CarrierSense value */
|
308 |
/* Set the FES bit according to ETH_Speed value */
|
309 |
/* Set the DO bit according to ETH_ReceiveOwn value */
|
310 |
/* Set the LM bit according to ETH_LoopbackMode value */
|
311 |
/* Set the DM bit according to ETH_Mode value */
|
312 |
/* Set the IPC bit according to ETH_ChecksumOffload value */
|
313 |
/* Set the DR bit according to ETH_RetryTransmission value */
|
314 |
/* Set the ACS bit according to ETH_AutomaticPadCRCStrip value */
|
315 |
/* Set the BL bit according to ETH_BackOffLimit value */
|
316 |
/* Set the DC bit according to ETH_DeferralCheck value */
|
317 |
tmpreg |= (uint32_t)(ETH_InitStruct->ETH_Watchdog | |
318 |
ETH_InitStruct->ETH_Jabber | |
319 |
ETH_InitStruct->ETH_InterFrameGap | |
320 |
ETH_InitStruct->ETH_CarrierSense | |
321 |
ETH_InitStruct->ETH_Speed | |
322 |
ETH_InitStruct->ETH_ReceiveOwn | |
323 |
ETH_InitStruct->ETH_LoopbackMode | |
324 |
ETH_InitStruct->ETH_Mode | |
325 |
ETH_InitStruct->ETH_ChecksumOffload | |
326 |
ETH_InitStruct->ETH_RetryTransmission | |
327 |
ETH_InitStruct->ETH_AutomaticPadCRCStrip | |
328 |
ETH_InitStruct->ETH_BackOffLimit | |
329 |
ETH_InitStruct->ETH_DeferralCheck); |
330 |
/* Write to ETHERNET MACCR */
|
331 |
ETH->MACCR = (uint32_t)tmpreg; |
332 |
|
333 |
/*----------------------- ETHERNET MACFFR Configuration --------------------*/
|
334 |
/* Set the RA bit according to ETH_ReceiveAll value */
|
335 |
/* Set the SAF and SAIF bits according to ETH_SourceAddrFilter value */
|
336 |
/* Set the PCF bit according to ETH_PassControlFrames value */
|
337 |
/* Set the DBF bit according to ETH_BroadcastFramesReception value */
|
338 |
/* Set the DAIF bit according to ETH_DestinationAddrFilter value */
|
339 |
/* Set the PR bit according to ETH_PromiscuousMode value */
|
340 |
/* Set the PM, HMC and HPF bits according to ETH_MulticastFramesFilter value */
|
341 |
/* Set the HUC and HPF bits according to ETH_UnicastFramesFilter value */
|
342 |
/* Write to ETHERNET MACFFR */
|
343 |
ETH->MACFFR = (uint32_t)(ETH_InitStruct->ETH_ReceiveAll | |
344 |
ETH_InitStruct->ETH_SourceAddrFilter | |
345 |
ETH_InitStruct->ETH_PassControlFrames | |
346 |
ETH_InitStruct->ETH_BroadcastFramesReception | |
347 |
ETH_InitStruct->ETH_DestinationAddrFilter | |
348 |
ETH_InitStruct->ETH_PromiscuousMode | |
349 |
ETH_InitStruct->ETH_MulticastFramesFilter | |
350 |
ETH_InitStruct->ETH_UnicastFramesFilter); |
351 |
/*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/
|
352 |
/* Write to ETHERNET MACHTHR */
|
353 |
ETH->MACHTHR = (uint32_t)ETH_InitStruct->ETH_HashTableHigh; |
354 |
/* Write to ETHERNET MACHTLR */
|
355 |
ETH-> |