Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
stm32f4x7_eth.c
00001 /** 00002 * @file stm32f4x7_eth.c 00003 * @brief STM32F407/417/427/437 Ethernet MAC controller 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneTCP Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00026 * @version 1.7.6 00027 **/ 00028 00029 //Switch to the appropriate trace level 00030 #define TRACE_LEVEL NIC_TRACE_LEVEL 00031 00032 //Dependencies 00033 #include "stm32f4xx.h" 00034 #include "core/net.h" 00035 #include "drivers/stm32f4x7_eth.h" 00036 #include "debug.h" 00037 00038 //Underlying network interface 00039 static NetInterface *nicDriverInterface; 00040 00041 //IAR EWARM compiler? 00042 #if defined(__ICCARM__) 00043 00044 //Transmit buffer 00045 #pragma data_alignment = 4 00046 static uint8_t txBuffer[STM32F4X7_ETH_TX_BUFFER_COUNT][STM32F4X7_ETH_TX_BUFFER_SIZE]; 00047 //Receive buffer 00048 #pragma data_alignment = 4 00049 static uint8_t rxBuffer[STM32F4X7_ETH_RX_BUFFER_COUNT][STM32F4X7_ETH_RX_BUFFER_SIZE]; 00050 //Transmit DMA descriptors 00051 #pragma data_alignment = 4 00052 static Stm32f4x7TxDmaDesc txDmaDesc[STM32F4X7_ETH_TX_BUFFER_COUNT]; 00053 //Receive DMA descriptors 00054 #pragma data_alignment = 4 00055 static Stm32f4x7RxDmaDesc rxDmaDesc[STM32F4X7_ETH_RX_BUFFER_COUNT]; 00056 00057 //Keil MDK-ARM or GCC compiler? 00058 #else 00059 00060 //Transmit buffer 00061 static uint8_t txBuffer[STM32F4X7_ETH_TX_BUFFER_COUNT][STM32F4X7_ETH_TX_BUFFER_SIZE] 00062 __attribute__((aligned(4))); 00063 //Receive buffer 00064 static uint8_t rxBuffer[STM32F4X7_ETH_RX_BUFFER_COUNT][STM32F4X7_ETH_RX_BUFFER_SIZE] 00065 __attribute__((aligned(4))); 00066 //Transmit DMA descriptors 00067 static Stm32f4x7TxDmaDesc txDmaDesc[STM32F4X7_ETH_TX_BUFFER_COUNT] 00068 __attribute__((aligned(4))); 00069 //Receive DMA descriptors 00070 static Stm32f4x7RxDmaDesc rxDmaDesc[STM32F4X7_ETH_RX_BUFFER_COUNT] 00071 __attribute__((aligned(4))); 00072 00073 #endif 00074 00075 //Pointer to the current TX DMA descriptor 00076 static Stm32f4x7TxDmaDesc *txCurDmaDesc; 00077 //Pointer to the current RX DMA descriptor 00078 static Stm32f4x7RxDmaDesc *rxCurDmaDesc; 00079 00080 00081 /** 00082 * @brief STM32F407/417/427/437 Ethernet MAC driver 00083 **/ 00084 00085 const NicDriver stm32f4x7EthDriver = 00086 { 00087 NIC_TYPE_ETHERNET, 00088 ETH_MTU, 00089 stm32f4x7EthInit, 00090 stm32f4x7EthTick, 00091 stm32f4x7EthEnableIrq, 00092 stm32f4x7EthDisableIrq, 00093 stm32f4x7EthEventHandler, 00094 stm32f4x7EthSendPacket, 00095 stm32f4x7EthSetMulticastFilter, 00096 stm32f4x7EthUpdateMacConfig, 00097 stm32f4x7EthWritePhyReg, 00098 stm32f4x7EthReadPhyReg, 00099 TRUE, 00100 TRUE, 00101 TRUE, 00102 FALSE 00103 }; 00104 00105 00106 /** 00107 * @brief STM32F407/417/427/437 Ethernet MAC initialization 00108 * @param[in] interface Underlying network interface 00109 * @return Error code 00110 **/ 00111 00112 error_t stm32f4x7EthInit(NetInterface *interface) 00113 { 00114 error_t error; 00115 00116 //Debug message 00117 TRACE_INFO("Initializing STM32F4x7 Ethernet MAC...\r\n"); 00118 00119 //Save underlying network interface 00120 nicDriverInterface = interface; 00121 00122 //GPIO configuration 00123 stm32f4x7EthInitGpio(interface); 00124 00125 #if defined(USE_HAL_DRIVER) 00126 //Enable Ethernet MAC clock 00127 __HAL_RCC_ETHMAC_CLK_ENABLE(); 00128 __HAL_RCC_ETHMACTX_CLK_ENABLE(); 00129 __HAL_RCC_ETHMACRX_CLK_ENABLE(); 00130 00131 //Reset Ethernet MAC peripheral 00132 __HAL_RCC_ETHMAC_FORCE_RESET(); 00133 __HAL_RCC_ETHMAC_RELEASE_RESET(); 00134 00135 #elif defined(USE_STDPERIPH_DRIVER) 00136 //Enable Ethernet MAC clock 00137 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC | 00138 RCC_AHB1Periph_ETH_MAC_Tx | RCC_AHB1Periph_ETH_MAC_Rx, ENABLE); 00139 00140 //Reset Ethernet MAC peripheral 00141 RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_ETH_MAC, ENABLE); 00142 RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_ETH_MAC, DISABLE); 00143 #endif 00144 00145 //Perform a software reset 00146 ETH->DMABMR |= ETH_DMABMR_SR; 00147 //Wait for the reset to complete 00148 while(ETH->DMABMR & ETH_DMABMR_SR); 00149 00150 //Adjust MDC clock range depending on HCLK frequency 00151 ETH->MACMIIAR = ETH_MACMIIAR_CR_Div102; 00152 00153 //PHY transceiver initialization 00154 error = interface->phyDriver->init(interface); 00155 //Failed to initialize PHY transceiver? 00156 if(error) 00157 return error; 00158 00159 //Use default MAC configuration 00160 ETH->MACCR = ETH_MACCR_ROD; 00161 00162 //Set the MAC address 00163 ETH->MACA0LR = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16); 00164 ETH->MACA0HR = interface->macAddr.w[2]; 00165 00166 //Initialize hash table 00167 ETH->MACHTLR = 0; 00168 ETH->MACHTHR = 0; 00169 00170 //Configure the receive filter 00171 ETH->MACFFR = ETH_MACFFR_HPF | ETH_MACFFR_HM; 00172 //Disable flow control 00173 ETH->MACFCR = 0; 00174 //Enable store and forward mode 00175 ETH->DMAOMR = ETH_DMAOMR_RSF | ETH_DMAOMR_TSF; 00176 00177 //Configure DMA bus mode 00178 ETH->DMABMR = ETH_DMABMR_AAB | ETH_DMABMR_USP | ETH_DMABMR_RDP_1Beat | 00179 ETH_DMABMR_RTPR_1_1 | ETH_DMABMR_PBL_1Beat | ETH_DMABMR_EDE; 00180 00181 //Initialize DMA descriptor lists 00182 stm32f4x7EthInitDmaDesc(interface); 00183 00184 //Prevent interrupts from being generated when the transmit statistic 00185 //counters reach half their maximum value 00186 ETH->MMCTIMR = ETH_MMCTIMR_TGFM | ETH_MMCTIMR_TGFMSCM | ETH_MMCTIMR_TGFSCM; 00187 00188 //Prevent interrupts from being generated when the receive statistic 00189 //counters reach half their maximum value 00190 ETH->MMCRIMR = ETH_MMCRIMR_RGUFM | ETH_MMCRIMR_RFAEM | ETH_MMCRIMR_RFCEM; 00191 00192 //Disable MAC interrupts 00193 ETH->MACIMR = ETH_MACIMR_TSTIM | ETH_MACIMR_PMTIM; 00194 //Enable the desired DMA interrupts 00195 ETH->DMAIER = ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE; 00196 00197 //Set priority grouping (4 bits for pre-emption priority, no bits for subpriority) 00198 NVIC_SetPriorityGrouping(STM32F4X7_ETH_IRQ_PRIORITY_GROUPING); 00199 00200 //Configure Ethernet interrupt priority 00201 NVIC_SetPriority(ETH_IRQn, NVIC_EncodePriority(STM32F4X7_ETH_IRQ_PRIORITY_GROUPING, 00202 STM32F4X7_ETH_IRQ_GROUP_PRIORITY, STM32F4X7_ETH_IRQ_SUB_PRIORITY)); 00203 00204 //Enable MAC transmission and reception 00205 ETH->MACCR |= ETH_MACCR_TE | ETH_MACCR_RE; 00206 //Enable DMA transmission and reception 00207 ETH->DMAOMR |= ETH_DMAOMR_ST | ETH_DMAOMR_SR; 00208 00209 //Accept any packets from the upper layer 00210 osSetEvent(&interface->nicTxEvent); 00211 00212 //Successful initialization 00213 return NO_ERROR; 00214 } 00215 00216 00217 //STM3240G-EVAL, STM32F4-DISCOVERY, MCBSTM32F400, STM32-E407 00218 //or STM-P407 evaluation board? 00219 #if defined(USE_STM324xG_EVAL) || defined(USE_STM32F4_DISCOVERY) || \ 00220 defined(USE_MCBSTM32F400) || defined(USE_STM32_E407) || defined(USE_STM32_P407) 00221 00222 /** 00223 * @brief GPIO configuration 00224 * @param[in] interface Underlying network interface 00225 **/ 00226 00227 void stm32f4x7EthInitGpio(NetInterface *interface) 00228 { 00229 GPIO_InitTypeDef GPIO_InitStructure; 00230 00231 //STM3240G-EVAL evaluation board? 00232 #if defined(USE_STM324xG_EVAL) && defined(USE_HAL_DRIVER) 00233 //Enable SYSCFG clock 00234 __HAL_RCC_SYSCFG_CLK_ENABLE(); 00235 00236 //Enable GPIO clocks 00237 __HAL_RCC_GPIOA_CLK_ENABLE(); 00238 __HAL_RCC_GPIOB_CLK_ENABLE(); 00239 __HAL_RCC_GPIOC_CLK_ENABLE(); 00240 __HAL_RCC_GPIOG_CLK_ENABLE(); 00241 __HAL_RCC_GPIOH_CLK_ENABLE(); 00242 __HAL_RCC_GPIOI_CLK_ENABLE(); 00243 00244 //Configure MCO1 (PA8) as an output 00245 GPIO_InitStructure.Pin = GPIO_PIN_8; 00246 GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; 00247 GPIO_InitStructure.Pull = GPIO_NOPULL; 00248 GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; 00249 GPIO_InitStructure.Alternate = GPIO_AF0_MCO; 00250 HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); 00251 00252 //Configure MCO1 pin to output the HSE clock (25MHz) 00253 HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_1); 00254 00255 //Select MII interface mode 00256 SYSCFG->PMC &= ~SYSCFG_PMC_MII_RMII_SEL; 00257 00258 //Configure MII pins 00259 GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; 00260 GPIO_InitStructure.Pull = GPIO_NOPULL; 00261 GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; 00262 GPIO_InitStructure.Alternate = GPIO_AF11_ETH; 00263 00264 //Configure ETH_MII_RX_CLK (PA1), ETH_MDIO (PA2) and ETH_MII_RX_DV (PA7) 00265 GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7; 00266 HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); 00267 00268 //Configure ETH_PPS_OUT (PB5) and ETH_MII_TXD3 (PB8) 00269 GPIO_InitStructure.Pin = GPIO_PIN_5 | GPIO_PIN_8; 00270 HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); 00271 00272 //Configure ETH_MDC (PC1), ETH_MII_TXD2 (PC2), ETH_MII_TX_CLK (PC3), 00273 //ETH_MII_RXD0 (PC4) and ETH_MII_RXD1 (PC5) 00274 GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5; 00275 HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); 00276 00277 //Configure ETH_MII_TX_EN (PG11), ETH_MII_TXD0 (PG13) and ETH_MII_TXD1 (PG14) 00278 GPIO_InitStructure.Pin = GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14; 00279 HAL_GPIO_Init(GPIOG, &GPIO_InitStructure); 00280 00281 //Configure ETH_MII_CRS (PH2), ETH_MII_COL (PH3), ETH_MII_RXD2 (PH6) and ETH_MII_RXD3 (PH7) 00282 GPIO_InitStructure.Pin = GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_6 | GPIO_PIN_7; 00283 HAL_GPIO_Init(GPIOH, &GPIO_InitStructure); 00284 00285 //Configure ETH_MII_RX_ER (PI10) 00286 GPIO_InitStructure.Pin = GPIO_PIN_10; 00287 HAL_GPIO_Init(GPIOI, &GPIO_InitStructure); 00288 00289 #elif defined(USE_STM324xG_EVAL) && defined(USE_STDPERIPH_DRIVER) 00290 //Enable SYSCFG clock 00291 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); 00292 00293 //Enable GPIO clocks 00294 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | 00295 RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOG | 00296 RCC_AHB1Periph_GPIOH | RCC_AHB1Periph_GPIOI, ENABLE); 00297 00298 //Configure MCO1 (PA8) as an output 00299 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; 00300 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 00301 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 00302 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 00303 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 00304 GPIO_Init(GPIOA, &GPIO_InitStructure); 00305 00306 //Configure MCO1 pin to output the HSE clock (25MHz) 00307 RCC_MCO1Config(RCC_MCO1Source_HSE, RCC_MCO1Div_1); 00308 00309 //Select MII interface mode 00310 SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_MII); 00311 00312 //Configure ETH_MII_RX_CLK (PA1), ETH_MDIO (PA2) and ETH_MII_RX_DV (PA7) 00313 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_7; 00314 GPIO_Init(GPIOA, &GPIO_InitStructure); 00315 GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_ETH); 00316 GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_ETH); 00317 GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_ETH); 00318 00319 //Configure ETH_PPS_OUT (PB5) and ETH_MII_TXD3 (PB8) 00320 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_8; 00321 GPIO_Init(GPIOB, &GPIO_InitStructure); 00322 GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_ETH); 00323 GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_ETH); 00324 00325 //Configure ETH_MDC (PC1), ETH_MII_TXD2 (PC2), ETH_MII_TX_CLK (PC3), 00326 //ETH_MII_RXD0 (PC4) and ETH_MII_RXD1 (PC5) 00327 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5; 00328 GPIO_Init(GPIOC, &GPIO_InitStructure); 00329 GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_ETH); 00330 GPIO_PinAFConfig(GPIOC, GPIO_PinSource2, GPIO_AF_ETH); 00331 GPIO_PinAFConfig(GPIOC, GPIO_PinSource3, GPIO_AF_ETH); 00332 GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_ETH); 00333 GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_ETH); 00334 00335 //Configure ETH_MII_TX_EN (PG11), ETH_MII_TXD0 (PG13) and ETH_MII_TXD1 (PG14) 00336 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_13 | GPIO_Pin_14; 00337 GPIO_Init(GPIOG, &GPIO_InitStructure); 00338 GPIO_PinAFConfig(GPIOG, GPIO_PinSource11, GPIO_AF_ETH); 00339 GPIO_PinAFConfig(GPIOG, GPIO_PinSource13, GPIO_AF_ETH); 00340 GPIO_PinAFConfig(GPIOG, GPIO_PinSource14, GPIO_AF_ETH); 00341 00342 //Configure ETH_MII_CRS (PH2), ETH_MII_COL (PH3), ETH_MII_RXD2 (PH6) and ETH_MII_RXD3 (PH7) 00343 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_7; 00344 GPIO_Init(GPIOH, &GPIO_InitStructure); 00345 GPIO_PinAFConfig(GPIOH, GPIO_PinSource2, GPIO_AF_ETH); 00346 GPIO_PinAFConfig(GPIOH, GPIO_PinSource3, GPIO_AF_ETH); 00347 GPIO_PinAFConfig(GPIOH, GPIO_PinSource6, GPIO_AF_ETH); 00348 GPIO_PinAFConfig(GPIOH, GPIO_PinSource7, GPIO_AF_ETH); 00349 00350 //Configure ETH_MII_RX_ER (PI10) 00351 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 00352 GPIO_Init(GPIOI, &GPIO_InitStructure); 00353 GPIO_PinAFConfig(GPIOI, GPIO_PinSource10, GPIO_AF_ETH); 00354 00355 //STM32F4-DISCOVERY evaluation board? 00356 #elif defined(USE_STM32F4_DISCOVERY) && defined(USE_HAL_DRIVER) 00357 //Enable SYSCFG clock 00358 __HAL_RCC_SYSCFG_CLK_ENABLE(); 00359 00360 //Enable GPIO clocks 00361 __HAL_RCC_GPIOA_CLK_ENABLE(); 00362 __HAL_RCC_GPIOB_CLK_ENABLE(); 00363 __HAL_RCC_GPIOC_CLK_ENABLE(); 00364 00365 //Select RMII interface mode 00366 SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL; 00367 00368 //Configure RMII pins 00369 GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; 00370 GPIO_InitStructure.Pull = GPIO_NOPULL; 00371 GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; 00372 GPIO_InitStructure.Alternate = GPIO_AF11_ETH; 00373 00374 //Configure ETH_RMII_REF_CLK (PA1), ETH_MDIO (PA2) and ETH_RMII_CRS_DV (PA7) 00375 GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7; 00376 HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); 00377 00378 //Configure ETH_RMII_TX_EN (PB11), ETH_RMII_TXD0 (PB12) and ETH_RMII_TXD1 (PB13) 00379 GPIO_InitStructure.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13; 00380 HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); 00381 00382 //Configure ETH_MDC (PC1), ETH_RMII_RXD0 (PC4) and ETH_RMII_RXD1 (PC5) 00383 GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5; 00384 HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); 00385 00386 #elif defined(USE_STM32F4_DISCOVERY) && defined(USE_STDPERIPH_DRIVER) 00387 //Enable SYSCFG clock 00388 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); 00389 00390 //Enable GPIO clocks 00391 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | 00392 RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC, ENABLE); 00393 00394 //Select RMII interface mode 00395 SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII); 00396 00397 //Configure ETH_RMII_REF_CLK (PA1), ETH_MDIO (PA2) and ETH_RMII_CRS_DV (PA7) 00398 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_7; 00399 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 00400 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 00401 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 00402 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 00403 GPIO_Init(GPIOA, &GPIO_InitStructure); 00404 GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_ETH); 00405 GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_ETH); 00406 GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_ETH); 00407 00408 //Configure ETH_RMII_TX_EN (PB11), ETH_RMII_TXD0 (PB12) and ETH_RMII_TXD1 (PB13) 00409 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13; 00410 GPIO_Init(GPIOB, &GPIO_InitStructure); 00411 GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_ETH); 00412 GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_ETH); 00413 GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_ETH); 00414 00415 //Configure ETH_MDC (PC1), ETH_RMII_RXD0 (PC4) and ETH_RMII_RXD1 (PC5) 00416 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5; 00417 GPIO_Init(GPIOC, &GPIO_InitStructure); 00418 GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_ETH); 00419 GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_ETH); 00420 GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_ETH); 00421 00422 //MCBSTM32F400 evaluation board? 00423 #elif defined(USE_MCBSTM32F400) && defined(USE_HAL_DRIVER) 00424 //Enable SYSCFG clock 00425 __HAL_RCC_SYSCFG_CLK_ENABLE(); 00426 00427 //Enable GPIO clocks 00428 __HAL_RCC_GPIOA_CLK_ENABLE(); 00429 __HAL_RCC_GPIOC_CLK_ENABLE(); 00430 __HAL_RCC_GPIOG_CLK_ENABLE(); 00431 00432 //Select RMII interface mode 00433 SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL; 00434 00435 //Configure RMII pins 00436 GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; 00437 GPIO_InitStructure.Pull = GPIO_NOPULL; 00438 GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; 00439 GPIO_InitStructure.Alternate = GPIO_AF11_ETH; 00440 00441 //Configure ETH_RMII_REF_CLK (PA1), ETH_MDIO (PA2) and ETH_RMII_CRS_DV (PA7) 00442 GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7; 00443 HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); 00444 00445 //Configure ETH_MDC (PC1), ETH_RMII_RXD0 (PC4) and ETH_RMII_RXD1 (PC5) 00446 GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5; 00447 HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); 00448 00449 //Configure ETH_RMII_TX_EN (PG11), ETH_RMII_TXD0 (PG13) and ETH_RMII_TXD1 (PG14) 00450 GPIO_InitStructure.Pin = GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14; 00451 HAL_GPIO_Init(GPIOG, &GPIO_InitStructure); 00452 00453 #elif defined(USE_MCBSTM32F400) && defined(USE_STDPERIPH_DRIVER) 00454 //Enable SYSCFG clock 00455 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); 00456 00457 //Enable GPIO clocks 00458 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | 00459 RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOG, ENABLE); 00460 00461 //Select RMII interface mode 00462 SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII); 00463 00464 //Configure ETH_RMII_REF_CLK (PA1), ETH_MDIO (PA2) and ETH_RMII_CRS_DV (PA7) 00465 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_7; 00466 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 00467 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 00468 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 00469 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 00470 GPIO_Init(GPIOA, &GPIO_InitStructure); 00471 GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_ETH); 00472 GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_ETH); 00473 GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_ETH); 00474 00475 //Configure ETH_MDC (PC1), ETH_RMII_RXD0 (PC4) and ETH_RMII_RXD1 (PC5) 00476 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5; 00477 GPIO_Init(GPIOC, &GPIO_InitStructure); 00478 GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_ETH); 00479 GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_ETH); 00480 GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_ETH); 00481 00482 //Configure ETH_RMII_TX_EN (PG11), ETH_RMII_TXD0 (PG13) and ETH_RMII_TXD1 (PG14) 00483 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_13 | GPIO_Pin_14; 00484 GPIO_Init(GPIOG, &GPIO_InitStructure); 00485 GPIO_PinAFConfig(GPIOG, GPIO_PinSource11, GPIO_AF_ETH); 00486 GPIO_PinAFConfig(GPIOG, GPIO_PinSource13, GPIO_AF_ETH); 00487 GPIO_PinAFConfig(GPIOG, GPIO_PinSource14, GPIO_AF_ETH); 00488 00489 //STM32-E407 evaluation board? 00490 #elif defined(USE_STM32_E407) && defined(USE_HAL_DRIVER) 00491 //Enable SYSCFG clock 00492 __HAL_RCC_SYSCFG_CLK_ENABLE(); 00493 00494 //Enable GPIO clocks 00495 __HAL_RCC_GPIOA_CLK_ENABLE(); 00496 __HAL_RCC_GPIOC_CLK_ENABLE(); 00497 __HAL_RCC_GPIOG_CLK_ENABLE(); 00498 00499 //Select RMII interface mode 00500 SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL; 00501 00502 //Configure RMII pins 00503 GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; 00504 GPIO_InitStructure.Pull = GPIO_NOPULL; 00505 GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; 00506 GPIO_InitStructure.Alternate = GPIO_AF11_ETH; 00507 00508 //Configure ETH_RMII_REF_CLK (PA1), ETH_MDIO (PA2) and ETH_RMII_CRS_DV (PA7) 00509 GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7; 00510 HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); 00511 00512 //Configure ETH_MDC (PC1), ETH_RMII_RXD0 (PC4) and ETH_RMII_RXD1 (PC5) 00513 GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5; 00514 HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); 00515 00516 //Configure ETH_RMII_TX_EN (PG11), ETH_RMII_TXD0 (PG13) and ETH_RMII_TXD1 (PG14) 00517 GPIO_InitStructure.Pin = GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14; 00518 HAL_GPIO_Init(GPIOG, &GPIO_InitStructure); 00519 00520 //Configure PHY_RST (PG6) 00521 GPIO_InitStructure.GPIO_Pin = Pin = GPIO_PIN_6; 00522 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; 00523 GPIO_InitStructure.Pull = GPIO_NOPULL; 00524 GPIO_InitStructure.Speed = GPIO_SPEED_LOW; 00525 HAL_GPIO_Init(GPIOG, &GPIO_InitStructure); 00526 00527 //Reset PHY transceiver 00528 HAL_GPIO_WritePin(GPIOG, GPIO_PIN_6, GPIO_PIN_RESET); 00529 sleep(10); 00530 00531 //Take the PHY transceiver out of reset 00532 HAL_GPIO_WritePin(GPIOG, GPIO_PIN_6, GPIO_PIN_SET); 00533 sleep(10); 00534 00535 #elif defined(USE_STM32_E407) && defined(USE_STDPERIPH_DRIVER) 00536 //Enable SYSCFG clock 00537 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); 00538 00539 //Enable GPIO clocks 00540 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | 00541 RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOG, ENABLE); 00542 00543 //Select RMII interface mode 00544 SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII); 00545 00546 //Configure ETH_RMII_REF_CLK (PA1), ETH_MDIO (PA2) and ETH_RMII_CRS_DV (PA7) 00547 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_7; 00548 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 00549 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 00550 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 00551 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 00552 GPIO_Init(GPIOA, &GPIO_InitStructure); 00553 GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_ETH); 00554 GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_ETH); 00555 GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_ETH); 00556 00557 //Configure ETH_MDC (PC1), ETH_RMII_RXD0 (PC4) and ETH_RMII_RXD1 (PC5) 00558 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5; 00559 GPIO_Init(GPIOC, &GPIO_InitStructure); 00560 GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_ETH); 00561 GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_ETH); 00562 GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_ETH); 00563 00564 //Configure ETH_RMII_TX_EN (PG11), ETH_RMII_TXD0 (PG13) and ETH_RMII_TXD1 (PG14) 00565 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_13 | GPIO_Pin_14; 00566 GPIO_Init(GPIOG, &GPIO_InitStructure); 00567 GPIO_PinAFConfig(GPIOG, GPIO_PinSource11, GPIO_AF_ETH); 00568 GPIO_PinAFConfig(GPIOG, GPIO_PinSource13, GPIO_AF_ETH); 00569 GPIO_PinAFConfig(GPIOG, GPIO_PinSource14, GPIO_AF_ETH); 00570 00571 //Configure PHY_RST (PG6) 00572 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; 00573 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 00574 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 00575 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 00576 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 00577 GPIO_Init(GPIOG, &GPIO_InitStructure); 00578 00579 //Reset PHY transceiver 00580 GPIO_ResetBits(GPIOG, GPIO_Pin_6); 00581 sleep(10); 00582 00583 //Take the PHY transceiver out of reset 00584 GPIO_SetBits(GPIOG, GPIO_Pin_6); 00585 sleep(10); 00586 00587 //STM32-P407 evaluation board? 00588 #elif defined(USE_STM32_P407) && defined(USE_HAL_DRIVER) 00589 //Enable SYSCFG clock 00590 __HAL_RCC_SYSCFG_CLK_ENABLE(); 00591 00592 //Enable GPIO clocks 00593 __HAL_RCC_GPIOA_CLK_ENABLE(); 00594 __HAL_RCC_GPIOB_CLK_ENABLE(); 00595 __HAL_RCC_GPIOC_CLK_ENABLE(); 00596 __HAL_RCC_GPIOG_CLK_ENABLE(); 00597 00598 //Select RMII interface mode 00599 SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL; 00600 00601 //Configure RMII pins 00602 GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; 00603 GPIO_InitStructure.Pull = GPIO_NOPULL; 00604 GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; 00605 GPIO_InitStructure.Alternate = GPIO_AF11_ETH; 00606 00607 //Configure ETH_RMII_REF_CLK (PA1), ETH_MDIO (PA2) and ETH_RMII_CRS_DV (PA7) 00608 GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7; 00609 HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); 00610 00611 //Configure ETH_RMII_TX_EN (PB11) 00612 GPIO_InitStructure.Pin = GPIO_PIN_11; 00613 HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); 00614 00615 //Configure ETH_MDC (PC1), ETH_RMII_RXD0 (PC4) and ETH_RMII_RXD1 (PC5) 00616 GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5; 00617 HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); 00618 00619 //Configure ETH_RMII_TXD0 (PG13) and ETH_RMII_TXD1 (PG14) 00620 GPIO_InitStructure.Pin = GPIO_PIN_13 | GPIO_PIN_14; 00621 HAL_GPIO_Init(GPIOG, &GPIO_InitStructure); 00622 00623 #elif defined(USE_STM32_P407) && defined(USE_STDPERIPH_DRIVER) 00624 //Enable SYSCFG clock 00625 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); 00626 00627 //Enable GPIO clocks 00628 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | 00629 RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOG, ENABLE); 00630 00631 //Select RMII interface mode 00632 SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII); 00633 00634 //Configure ETH_RMII_REF_CLK (PA1), ETH_MDIO (PA2) and ETH_RMII_CRS_DV (PA7) 00635 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_7; 00636 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 00637 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 00638 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 00639 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 00640 GPIO_Init(GPIOA, &GPIO_InitStructure); 00641 GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_ETH); 00642 GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_ETH); 00643 GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_ETH); 00644 00645 //Configure ETH_RMII_TX_EN (PB11) 00646 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; 00647 GPIO_Init(GPIOB, &GPIO_InitStructure); 00648 GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_ETH); 00649 00650 //Configure ETH_MDC (PC1), ETH_RMII_RXD0 (PC4) and ETH_RMII_RXD1 (PC5) 00651 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5; 00652 GPIO_Init(GPIOC, &GPIO_InitStructure); 00653 GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_ETH); 00654 GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_ETH); 00655 GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_ETH); 00656 00657 //Configure ETH_RMII_TXD0 (PG13) and ETH_RMII_TXD1 (PG14) 00658 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14; 00659 GPIO_Init(GPIOG, &GPIO_InitStructure); 00660 GPIO_PinAFConfig(GPIOG, GPIO_PinSource13, GPIO_AF_ETH); 00661 GPIO_PinAFConfig(GPIOG, GPIO_PinSource14, GPIO_AF_ETH); 00662 #endif 00663 } 00664 00665 #endif 00666 00667 00668 /** 00669 * @brief Initialize DMA descriptor lists 00670 * @param[in] interface Underlying network interface 00671 **/ 00672 00673 void stm32f4x7EthInitDmaDesc(NetInterface *interface) 00674 { 00675 uint_t i; 00676 00677 //Initialize TX DMA descriptor list 00678 for(i = 0; i < STM32F4X7_ETH_TX_BUFFER_COUNT; i++) 00679 { 00680 //Use chain structure rather than ring structure 00681 txDmaDesc[i].tdes0 = ETH_TDES0_IC | ETH_TDES0_TCH; 00682 //Initialize transmit buffer size 00683 txDmaDesc[i].tdes1 = 0; 00684 //Transmit buffer address 00685 txDmaDesc[i].tdes2 = (uint32_t) txBuffer[i]; 00686 //Next descriptor address 00687 txDmaDesc[i].tdes3 = (uint32_t) &txDmaDesc[i + 1]; 00688 //Reserved fields 00689 txDmaDesc[i].tdes4 = 0; 00690 txDmaDesc[i].tdes5 = 0; 00691 //Transmit frame time stamp 00692 txDmaDesc[i].tdes6 = 0; 00693 txDmaDesc[i].tdes7 = 0; 00694 } 00695 00696 //The last descriptor is chained to the first entry 00697 txDmaDesc[i - 1].tdes3 = (uint32_t) &txDmaDesc[0]; 00698 //Point to the very first descriptor 00699 txCurDmaDesc = &txDmaDesc[0]; 00700 00701 //Initialize RX DMA descriptor list 00702 for(i = 0; i < STM32F4X7_ETH_RX_BUFFER_COUNT; i++) 00703 { 00704 //The descriptor is initially owned by the DMA 00705 rxDmaDesc[i].rdes0 = ETH_RDES0_OWN; 00706 //Use chain structure rather than ring structure 00707 rxDmaDesc[i].rdes1 = ETH_RDES1_RCH | (STM32F4X7_ETH_RX_BUFFER_SIZE & ETH_RDES1_RBS1); 00708 //Receive buffer address 00709 rxDmaDesc[i].rdes2 = (uint32_t) rxBuffer[i]; 00710 //Next descriptor address 00711 rxDmaDesc[i].rdes3 = (uint32_t) &rxDmaDesc[i + 1]; 00712 //Extended status 00713 rxDmaDesc[i].rdes4 = 0; 00714 //Reserved field 00715 rxDmaDesc[i].rdes5 = 0; 00716 //Receive frame time stamp 00717 rxDmaDesc[i].rdes6 = 0; 00718 rxDmaDesc[i].rdes7 = 0; 00719 } 00720 00721 //The last descriptor is chained to the first entry 00722 rxDmaDesc[i - 1].rdes3 = (uint32_t) &rxDmaDesc[0]; 00723 //Point to the very first descriptor 00724 rxCurDmaDesc = &rxDmaDesc[0]; 00725 00726 //Start location of the TX descriptor list 00727 ETH->DMATDLAR = (uint32_t) txDmaDesc; 00728 //Start location of the RX descriptor list 00729 ETH->DMARDLAR = (uint32_t) rxDmaDesc; 00730 } 00731 00732 00733 /** 00734 * @brief STM32F407/417/427/437 Ethernet MAC timer handler 00735 * 00736 * This routine is periodically called by the TCP/IP stack to 00737 * handle periodic operations such as polling the link state 00738 * 00739 * @param[in] interface Underlying network interface 00740 **/ 00741 00742 void stm32f4x7EthTick(NetInterface *interface) 00743 { 00744 //Handle periodic operations 00745 interface->phyDriver->tick(interface); 00746 } 00747 00748 00749 /** 00750 * @brief Enable interrupts 00751 * @param[in] interface Underlying network interface 00752 **/ 00753 00754 void stm32f4x7EthEnableIrq(NetInterface *interface) 00755 { 00756 //Enable Ethernet MAC interrupts 00757 NVIC_EnableIRQ(ETH_IRQn); 00758 //Enable Ethernet PHY interrupts 00759 interface->phyDriver->enableIrq(interface); 00760 } 00761 00762 00763 /** 00764 * @brief Disable interrupts 00765 * @param[in] interface Underlying network interface 00766 **/ 00767 00768 void stm32f4x7EthDisableIrq(NetInterface *interface) 00769 { 00770 //Disable Ethernet MAC interrupts 00771 NVIC_DisableIRQ(ETH_IRQn); 00772 //Disable Ethernet PHY interrupts 00773 interface->phyDriver->disableIrq(interface); 00774 } 00775 00776 00777 /** 00778 * @brief STM32F407/417/427/437 Ethernet MAC interrupt service routine 00779 **/ 00780 00781 void ETH_IRQHandler(void) 00782 { 00783 bool_t flag; 00784 uint32_t status; 00785 00786 //Enter interrupt service routine 00787 osEnterIsr(); 00788 00789 //This flag will be set if a higher priority task must be woken 00790 flag = FALSE; 00791 00792 //Read DMA status register 00793 status = ETH->DMASR; 00794 00795 //A packet has been transmitted? 00796 if(status & ETH_DMASR_TS) 00797 { 00798 //Clear TS interrupt flag 00799 ETH->DMASR = ETH_DMASR_TS; 00800 00801 //Check whether the TX buffer is available for writing 00802 if(!(txCurDmaDesc->tdes0 & ETH_TDES0_OWN)) 00803 { 00804 //Notify the TCP/IP stack that the transmitter is ready to send 00805 flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent); 00806 } 00807 } 00808 00809 //A packet has been received? 00810 if(status & ETH_DMASR_RS) 00811 { 00812 //Disable RIE interrupt 00813 ETH->DMAIER &= ~ETH_DMAIER_RIE; 00814 00815 //Set event flag 00816 nicDriverInterface->nicEvent = TRUE; 00817 //Notify the TCP/IP stack of the event 00818 flag |= osSetEventFromIsr(&netEvent); 00819 } 00820 00821 //Clear NIS interrupt flag 00822 ETH->DMASR = ETH_DMASR_NIS; 00823 00824 //Leave interrupt service routine 00825 osExitIsr(flag); 00826 } 00827 00828 00829 /** 00830 * @brief STM32F407/417/427/437 Ethernet MAC event handler 00831 * @param[in] interface Underlying network interface 00832 **/ 00833 00834 void stm32f4x7EthEventHandler(NetInterface *interface) 00835 { 00836 error_t error; 00837 00838 //Packet received? 00839 if(ETH->DMASR & ETH_DMASR_RS) 00840 { 00841 //Clear interrupt flag 00842 ETH->DMASR = ETH_DMASR_RS; 00843 00844 //Process all pending packets 00845 do 00846 { 00847 //Read incoming packet 00848 error = stm32f4x7EthReceivePacket(interface); 00849 00850 //No more data in the receive buffer? 00851 } while(error != ERROR_BUFFER_EMPTY); 00852 } 00853 00854 //Re-enable DMA interrupts 00855 ETH->DMAIER |= ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE; 00856 } 00857 00858 00859 /** 00860 * @brief Send a packet 00861 * @param[in] interface Underlying network interface 00862 * @param[in] buffer Multi-part buffer containing the data to send 00863 * @param[in] offset Offset to the first data byte 00864 * @return Error code 00865 **/ 00866 00867 error_t stm32f4x7EthSendPacket(NetInterface *interface, 00868 const NetBuffer *buffer, size_t offset) 00869 { 00870 size_t length; 00871 00872 //Retrieve the length of the packet 00873 length = netBufferGetLength(buffer) - offset; 00874 00875 //Check the frame length 00876 if(length > STM32F4X7_ETH_TX_BUFFER_SIZE) 00877 { 00878 //The transmitter can accept another packet 00879 osSetEvent(&interface->nicTxEvent); 00880 //Report an error 00881 return ERROR_INVALID_LENGTH; 00882 } 00883 00884 //Make sure the current buffer is available for writing 00885 if(txCurDmaDesc->tdes0 & ETH_TDES0_OWN) 00886 return ERROR_FAILURE; 00887 00888 //Copy user data to the transmit buffer 00889 netBufferRead((uint8_t *) txCurDmaDesc->tdes2, buffer, offset, length); 00890 00891 //Write the number of bytes to send 00892 txCurDmaDesc->tdes1 = length & ETH_TDES1_TBS1; 00893 //Set LS and FS flags as the data fits in a single buffer 00894 txCurDmaDesc->tdes0 |= ETH_TDES0_LS | ETH_TDES0_FS; 00895 //Give the ownership of the descriptor to the DMA 00896 txCurDmaDesc->tdes0 |= ETH_TDES0_OWN; 00897 00898 //Clear TBUS flag to resume processing 00899 ETH->DMASR = ETH_DMASR_TBUS; 00900 //Instruct the DMA to poll the transmit descriptor list 00901 ETH->DMATPDR = 0; 00902 00903 //Point to the next descriptor in the list 00904 txCurDmaDesc = (Stm32f4x7TxDmaDesc *) txCurDmaDesc->tdes3; 00905 00906 //Check whether the next buffer is available for writing 00907 if(!(txCurDmaDesc->tdes0 & ETH_TDES0_OWN)) 00908 { 00909 //The transmitter can accept another packet 00910 osSetEvent(&interface->nicTxEvent); 00911 } 00912 00913 //Data successfully written 00914 return NO_ERROR; 00915 } 00916 00917 00918 /** 00919 * @brief Receive a packet 00920 * @param[in] interface Underlying network interface 00921 * @return Error code 00922 **/ 00923 00924 error_t stm32f4x7EthReceivePacket(NetInterface *interface) 00925 { 00926 error_t error; 00927 size_t n; 00928 00929 //The current buffer is available for reading? 00930 if(!(rxCurDmaDesc->rdes0 & ETH_RDES0_OWN)) 00931 { 00932 //FS and LS flags should be set 00933 if((rxCurDmaDesc->rdes0 & ETH_RDES0_FS) && (rxCurDmaDesc->rdes0 & ETH_RDES0_LS)) 00934 { 00935 //Make sure no error occurred 00936 if(!(rxCurDmaDesc->rdes0 & ETH_RDES0_ES)) 00937 { 00938 //Retrieve the length of the frame 00939 n = (rxCurDmaDesc->rdes0 & ETH_RDES0_FL) >> 16; 00940 //Limit the number of data to read 00941 n = MIN(n, STM32F4X7_ETH_RX_BUFFER_SIZE); 00942 00943 //Pass the packet to the upper layer 00944 nicProcessPacket(interface, (uint8_t *) rxCurDmaDesc->rdes2, n); 00945 00946 //Valid packet received 00947 error = NO_ERROR; 00948 } 00949 else 00950 { 00951 //The received packet contains an error 00952 error = ERROR_INVALID_PACKET; 00953 } 00954 } 00955 else 00956 { 00957 //The packet is not valid 00958 error = ERROR_INVALID_PACKET; 00959 } 00960 00961 //Give the ownership of the descriptor back to the DMA 00962 rxCurDmaDesc->rdes0 = ETH_RDES0_OWN; 00963 //Point to the next descriptor in the list 00964 rxCurDmaDesc = (Stm32f4x7RxDmaDesc *) rxCurDmaDesc->rdes3; 00965 } 00966 else 00967 { 00968 //No more data in the receive buffer 00969 error = ERROR_BUFFER_EMPTY; 00970 } 00971 00972 //Clear RBUS flag to resume processing 00973 ETH->DMASR = ETH_DMASR_RBUS; 00974 //Instruct the DMA to poll the receive descriptor list 00975 ETH->DMARPDR = 0; 00976 00977 //Return status code 00978 return error; 00979 } 00980 00981 00982 /** 00983 * @brief Configure multicast MAC address filtering 00984 * @param[in] interface Underlying network interface 00985 * @return Error code 00986 **/ 00987 00988 error_t stm32f4x7EthSetMulticastFilter(NetInterface *interface) 00989 { 00990 uint_t i; 00991 uint_t k; 00992 uint32_t crc; 00993 uint32_t hashTable[2]; 00994 MacFilterEntry *entry; 00995 00996 //Debug message 00997 TRACE_DEBUG("Updating STM32F4x7 hash table...\r\n"); 00998 00999 //Clear hash table 01000 hashTable[0] = 0; 01001 hashTable[1] = 0; 01002 01003 //The MAC filter table contains the multicast MAC addresses 01004 //to accept when receiving an Ethernet frame 01005 for(i = 0; i < MAC_MULTICAST_FILTER_SIZE; i++) 01006 { 01007 //Point to the current entry 01008 entry = &interface->macMulticastFilter[i]; 01009 01010 //Valid entry? 01011 if(entry->refCount > 0) 01012 { 01013 //Compute CRC over the current MAC address 01014 crc = stm32f4x7EthCalcCrc(&entry->addr, sizeof(MacAddr)); 01015 01016 //The upper 6 bits in the CRC register are used to index the 01017 //contents of the hash table 01018 k = (crc >> 26) & 0x3F; 01019 01020 //Update hash table contents 01021 hashTable[k / 32] |= (1 << (k % 32)); 01022 } 01023 } 01024 01025 //Write the hash table 01026 ETH->MACHTLR = hashTable[0]; 01027 ETH->MACHTHR = hashTable[1]; 01028 01029 //Debug message 01030 TRACE_DEBUG(" MACHTLR = %08" PRIX32 "\r\n", ETH->MACHTLR); 01031 TRACE_DEBUG(" MACHTHR = %08" PRIX32 "\r\n", ETH->MACHTHR); 01032 01033 //Successful processing 01034 return NO_ERROR; 01035 } 01036 01037 01038 /** 01039 * @brief Adjust MAC configuration parameters for proper operation 01040 * @param[in] interface Underlying network interface 01041 * @return Error code 01042 **/ 01043 01044 error_t stm32f4x7EthUpdateMacConfig(NetInterface *interface) 01045 { 01046 uint32_t config; 01047 01048 //Read current MAC configuration 01049 config = ETH->MACCR; 01050 01051 //10BASE-T or 100BASE-TX operation mode? 01052 if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS) 01053 config |= ETH_MACCR_FES; 01054 else 01055 config &= ~ETH_MACCR_FES; 01056 01057 //Half-duplex or full-duplex mode? 01058 if(interface->duplexMode == NIC_FULL_DUPLEX_MODE) 01059 config |= ETH_MACCR_DM; 01060 else 01061 config &= ~ETH_MACCR_DM; 01062 01063 //Update MAC configuration register 01064 ETH->MACCR = config; 01065 01066 //Successful processing 01067 return NO_ERROR; 01068 } 01069 01070 01071 /** 01072 * @brief Write PHY register 01073 * @param[in] phyAddr PHY address 01074 * @param[in] regAddr Register address 01075 * @param[in] data Register value 01076 **/ 01077 01078 void stm32f4x7EthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data) 01079 { 01080 uint32_t value; 01081 01082 //Take care not to alter MDC clock configuration 01083 value = ETH->MACMIIAR & ETH_MACMIIAR_CR; 01084 //Set up a write operation 01085 value |= ETH_MACMIIAR_MW | ETH_MACMIIAR_MB; 01086 //PHY address 01087 value |= (phyAddr << 11) & ETH_MACMIIAR_PA; 01088 //Register address 01089 value |= (regAddr << 6) & ETH_MACMIIAR_MR; 01090 01091 //Data to be written in the PHY register 01092 ETH->MACMIIDR = data & ETH_MACMIIDR_MD; 01093 01094 //Start a write operation 01095 ETH->MACMIIAR = value; 01096 //Wait for the write to complete 01097 while(ETH->MACMIIAR & ETH_MACMIIAR_MB); 01098 } 01099 01100 01101 /** 01102 * @brief Read PHY register 01103 * @param[in] phyAddr PHY address 01104 * @param[in] regAddr Register address 01105 * @return Register value 01106 **/ 01107 01108 uint16_t stm32f4x7EthReadPhyReg(uint8_t phyAddr, uint8_t regAddr) 01109 { 01110 uint32_t value; 01111 01112 //Take care not to alter MDC clock configuration 01113 value = ETH->MACMIIAR & ETH_MACMIIAR_CR; 01114 //Set up a read operation 01115 value |= ETH_MACMIIAR_MB; 01116 //PHY address 01117 value |= (phyAddr << 11) & ETH_MACMIIAR_PA; 01118 //Register address 01119 value |= (regAddr << 6) & ETH_MACMIIAR_MR; 01120 01121 //Start a read operation 01122 ETH->MACMIIAR = value; 01123 //Wait for the read to complete 01124 while(ETH->MACMIIAR & ETH_MACMIIAR_MB); 01125 01126 //Return PHY register contents 01127 return ETH->MACMIIDR & ETH_MACMIIDR_MD; 01128 } 01129 01130 01131 /** 01132 * @brief CRC calculation 01133 * @param[in] data Pointer to the data over which to calculate the CRC 01134 * @param[in] length Number of bytes to process 01135 * @return Resulting CRC value 01136 **/ 01137 01138 uint32_t stm32f4x7EthCalcCrc(const void *data, size_t length) 01139 { 01140 uint_t i; 01141 uint_t j; 01142 01143 //Point to the data over which to calculate the CRC 01144 const uint8_t *p = (uint8_t *) data; 01145 //CRC preset value 01146 uint32_t crc = 0xFFFFFFFF; 01147 01148 //Loop through data 01149 for(i = 0; i < length; i++) 01150 { 01151 //The message is processed bit by bit 01152 for(j = 0; j < 8; j++) 01153 { 01154 //Update CRC value 01155 if(((crc >> 31) ^ (p[i] >> j)) & 0x01) 01156 crc = (crc << 1) ^ 0x04C11DB7; 01157 else 01158 crc = crc << 1; 01159 } 01160 } 01161 01162 //Return CRC value 01163 return ~crc; 01164 } 01165
Generated on Tue Jul 12 2022 17:10:16 by
