Sergey Pastor / 1

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32f4x7_eth.c Source File

stm32f4x7_eth.c

Go to the documentation of this file.
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