Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers f28m35x_eth.c Source File

f28m35x_eth.c

Go to the documentation of this file.
00001 /**
00002  * @file f28m35x_eth.c
00003  * @brief F28M35x 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 "inc/hw_ethernet.h"
00034 #include "inc/hw_ints.h"
00035 #include "inc/hw_memmap.h"
00036 #include "inc/hw_types.h"
00037 #include "driverlib/gpio.h"
00038 #include "driverlib/interrupt.h"
00039 #include "driverlib/sysctl.h"
00040 #include "core/net.h"
00041 #include "drivers/f28m35x_eth.h"
00042 #include "debug.h"
00043 
00044 //Underlying network interface
00045 static NetInterface *nicDriverInterface;
00046 
00047 //IAR EWARM compiler?
00048 #if defined(__ICCARM__)
00049 
00050 //Transmit buffer
00051 #pragma data_alignment = 4
00052 static uint8_t txBuffer[ETH_MAX_FRAME_SIZE + 2];
00053 //Receive buffer
00054 #pragma data_alignment = 4
00055 static uint8_t rxBuffer[ETH_MAX_FRAME_SIZE];
00056 
00057 //Keil MDK-ARM or GCC compiler?
00058 #else
00059 
00060 //Transmit buffer
00061 static uint8_t txBuffer[ETH_MAX_FRAME_SIZE + 2] __attribute__((aligned(4)));
00062 //Receive buffer
00063 static uint8_t rxBuffer[ETH_MAX_FRAME_SIZE] __attribute__((aligned(4)));
00064 
00065 #endif
00066 
00067 
00068 /**
00069  * @brief F28M35x Ethernet MAC driver
00070  **/
00071 
00072 const NicDriver f28m35xEthDriver =
00073 {
00074    NIC_TYPE_ETHERNET,
00075    ETH_MTU,
00076    f28m35xEthInit,
00077    f28m35xEthTick,
00078    f28m35xEthEnableIrq,
00079    f28m35xEthDisableIrq,
00080    f28m35xEthEventHandler,
00081    f28m35xEthSendPacket,
00082    f28m35xEthSetMulticastFilter,
00083    f28m35xEthUpdateMacConfig,
00084    f28m35xEthWritePhyReg,
00085    f28m35xEthReadPhyReg,
00086    TRUE,
00087    TRUE,
00088    TRUE,
00089    FALSE
00090 };
00091 
00092 
00093 /**
00094  * @brief F28M35x Ethernet MAC controller initialization
00095  * @param[in] interface Underlying network interface
00096  * @return Error code
00097  **/
00098 
00099 error_t f28m35xEthInit(NetInterface *interface)
00100 {
00101    error_t error;
00102    uint_t div;
00103 #ifdef ti_sysbios_BIOS___VERS
00104    Hwi_Params hwiParams;
00105 #endif
00106 
00107    //Debug message
00108    TRACE_INFO("Initializing F28M35x Ethernet MAC controller...\r\n");
00109 
00110    //Save underlying network interface
00111    nicDriverInterface = interface;
00112 
00113    //Enable Ethernet controller clock
00114    SysCtlPeripheralEnable(SYSCTL_PERIPH_ETH);
00115    //Reset Ethernet controller
00116    SysCtlPeripheralReset(SYSCTL_PERIPH_ETH);
00117 
00118    //GPIO configuration
00119    f28m35xEthInitGpio(interface);
00120 
00121    //The MDC clock frequency cannot exceed 2.5MHz
00122    div = SysCtlClockGet(20000000) / (2 * 2500000) - 1;
00123    //Adjust MDC clock frequency
00124    MAC_MDV_R = div & MAC_MDV_DIV_M;
00125 
00126    //PHY transceiver initialization
00127    error = interface->phyDriver->init(interface);
00128    //Failed to initialize PHY transceiver?
00129    if(error)
00130       return error;
00131 
00132    //Set the MAC address
00133    MAC_IA0_R = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
00134    MAC_IA1_R = interface->macAddr.w[2];
00135 
00136    //Enable automatic CRC generation and packet padding
00137    MAC_TCTL_R = MAC_TCTL_DUPLEX | MAC_TCTL_CRC | MAC_TCTL_PADEN;
00138    //Flush the receive FIFO and enable CRC verification
00139    MAC_RCTL_R = MAC_RCTL_RSTFIFO | MAC_RCTL_BADCRC;
00140 
00141    //Configure Ethernet interrupts
00142    MAC_IM_R = MAC_IM_TXEMPM | MAC_IM_RXINTM;
00143 
00144 #ifdef ti_sysbios_BIOS___VERS
00145    //Configure Ethernet interrupt
00146    Hwi_Params_init(&hwiParams);
00147    hwiParams.enableInt = FALSE;
00148    hwiParams.priority = F28M35X_ETH_IRQ_PRIORITY;
00149 
00150    //Register interrupt handler
00151    Hwi_create(INT_ETH, (Hwi_FuncPtr) f28m35xEthIrqHandler, &hwiParams, NULL);
00152 #else
00153    //Register interrupt handler
00154    IntRegister(INT_ETH, f28m35xEthIrqHandler);
00155 
00156    //Set priority grouping (3 bits for pre-emption priority, no bits for subpriority)
00157    IntPriorityGroupingSet(F28M35X_ETH_IRQ_PRIORITY_GROUPING);
00158    //Configure Ethernet interrupt priority
00159    IntPrioritySet(INT_ETH, F28M35X_ETH_IRQ_PRIORITY);
00160 #endif
00161 
00162    //Enable transmitter
00163    MAC_TCTL_R |= MAC_TCTL_TXEN;
00164    //Enable receiver
00165    MAC_RCTL_R |= MAC_RCTL_RXEN;
00166 
00167    //Accept any packets from the upper layer
00168    osSetEvent(&interface->nicTxEvent);
00169 
00170    //Successful initialization
00171    return NO_ERROR;
00172 }
00173 
00174 
00175 //TMDXCNCDH52C1 evaluation board?
00176 #if defined(USE_TMDXCNCDH52C1)
00177 
00178 /**
00179  * @brief GPIO configuration
00180  * @param[in] interface Underlying network interface
00181  **/
00182 
00183 void f28m35xEthInitGpio(NetInterface *interface)
00184 {
00185    //Enable GPIO clocks
00186    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
00187    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
00188    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
00189    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
00190    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);
00191    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ);
00192 
00193    //Configure MII_TXD3 (PC4)
00194    GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_4, GPIO_DIR_MODE_HW);
00195    GPIOPadConfigSet(GPIO_PORTC_BASE, GPIO_PIN_4, GPIO_PIN_TYPE_STD);
00196    GPIOPinConfigure(GPIO_PC4_MIITXD3);
00197 
00198    //Configure MII_MDIO (PE6)
00199    GPIODirModeSet(GPIO_PORTE_BASE, GPIO_PIN_6, GPIO_DIR_MODE_HW);
00200    GPIOPadConfigSet(GPIO_PORTE_BASE, GPIO_PIN_6, GPIO_PIN_TYPE_STD);
00201    GPIOPinConfigure(GPIO_PE6_MIIMDIO);
00202 
00203    //Configure MII_RXD3 (PF5)
00204    GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_5, GPIO_DIR_MODE_HW);
00205    GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_5, GPIO_PIN_TYPE_STD);
00206    GPIOPinConfigure(GPIO_PF5_MIIRXD3);
00207 
00208    //Configure MII_RXD2 (PG0)
00209    GPIODirModeSet(GPIO_PORTG_BASE, GPIO_PIN_0, GPIO_DIR_MODE_HW);
00210    GPIOPadConfigSet(GPIO_PORTG_BASE, GPIO_PIN_0, GPIO_PIN_TYPE_STD);
00211    GPIOPinConfigure(GPIO_PG0_MIIRXD2);
00212 
00213    //Configure MII_RXD1 (PG1)
00214    GPIODirModeSet(GPIO_PORTG_BASE, GPIO_PIN_1, GPIO_DIR_MODE_HW);
00215       GPIOPadConfigSet(GPIO_PORTG_BASE, GPIO_PIN_1, GPIO_PIN_TYPE_STD);
00216    GPIOPinConfigure(GPIO_PG1_MIIRXD1);
00217 
00218    //Configure MII_RXDV (PG3)
00219    GPIODirModeSet(GPIO_PORTG_BASE, GPIO_PIN_3, GPIO_DIR_MODE_HW);
00220    GPIOPadConfigSet(GPIO_PORTG_BASE, GPIO_PIN_3, GPIO_PIN_TYPE_STD);
00221    GPIOPinConfigure(GPIO_PG3_MIIRXDV);
00222 
00223    //Configure MII_TXER (PG7)
00224    GPIODirModeSet(GPIO_PORTG_BASE, GPIO_PIN_7, GPIO_DIR_MODE_HW);
00225    GPIOPadConfigSet(GPIO_PORTG_BASE, GPIO_PIN_7, GPIO_PIN_TYPE_STD);
00226    GPIOPinConfigure(GPIO_PG7_MIITXER);
00227 
00228    //Configure MII_RXD0 (PH1)
00229    GPIODirModeSet(GPIO_PORTH_BASE, GPIO_PIN_1, GPIO_DIR_MODE_HW);
00230    GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_1, GPIO_PIN_TYPE_STD);
00231    GPIOPinConfigure(GPIO_PH1_MIIRXD0);
00232 
00233    //Configure MII_TXD2 (PH3)
00234    GPIODirModeSet(GPIO_PORTH_BASE, GPIO_PIN_3, GPIO_DIR_MODE_HW);
00235    GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_3, GPIO_PIN_TYPE_STD);
00236    GPIOPinConfigure(GPIO_PH3_MIITXD2);
00237 
00238    //Configure MII_TXD1 (PH4)
00239    GPIODirModeSet(GPIO_PORTH_BASE, GPIO_PIN_4, GPIO_DIR_MODE_HW);
00240    GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_4, GPIO_PIN_TYPE_STD);
00241    GPIOPinConfigure(GPIO_PH4_MIITXD1);
00242 
00243    //Configure MII_TXD0 (PH5)
00244    GPIODirModeSet(GPIO_PORTH_BASE, GPIO_PIN_5, GPIO_DIR_MODE_HW);
00245    GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_5, GPIO_PIN_TYPE_STD);
00246    GPIOPinConfigure(GPIO_PH5_MIITXD0);
00247 
00248    //Configure MII_TXEN (PH6)
00249    GPIODirModeSet(GPIO_PORTH_BASE, GPIO_PIN_6, GPIO_DIR_MODE_HW);
00250    GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_6, GPIO_PIN_TYPE_STD);
00251    GPIOPinConfigure(GPIO_PH6_MIITXEN);
00252 
00253    //Configure MII_TXCK (PH7)
00254    GPIODirModeSet(GPIO_PORTH_BASE, GPIO_PIN_7, GPIO_DIR_MODE_HW);
00255    GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_7, GPIO_PIN_TYPE_STD);
00256    GPIOPinConfigure(GPIO_PH7_MIITXCK);
00257 
00258    //Configure MII_RXER (PJ0)
00259    GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_0, GPIO_DIR_MODE_HW);
00260    GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_0, GPIO_PIN_TYPE_STD);
00261    GPIOPinConfigure(GPIO_PJ0_MIIRXER);
00262 
00263    //Configure MII_RXCK (PJ2)
00264    GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_2, GPIO_DIR_MODE_HW);
00265    GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_2, GPIO_PIN_TYPE_STD);
00266    GPIOPinConfigure(GPIO_PJ2_MIIRXCK);
00267 
00268    //Configure MII_MDC (PJ3)
00269    GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_3, GPIO_DIR_MODE_HW);
00270    GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_3, GPIO_PIN_TYPE_STD);
00271    GPIOPinConfigure(GPIO_PJ3_MIIMDC);
00272 
00273    //Configure MII_COL (PJ4)
00274    GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_4, GPIO_DIR_MODE_HW);
00275    GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_4, GPIO_PIN_TYPE_STD);
00276    GPIOPinConfigure(GPIO_PJ4_MIICOL);
00277 
00278    //Configure MII_CRS (PJ5)
00279    GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_5, GPIO_DIR_MODE_HW);
00280    GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_5, GPIO_PIN_TYPE_STD);
00281    GPIOPinConfigure(GPIO_PJ5_MIICRS);
00282 
00283    //Configure MII_PHYINTR (PJ6)
00284    GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_6, GPIO_DIR_MODE_HW);
00285    GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_6, GPIO_PIN_TYPE_STD);
00286    GPIOPinConfigure(GPIO_PJ6_MIIPHYINTRn);
00287 
00288    //Configure MII_PHYRSTn (PJ7)
00289    GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_7, GPIO_DIR_MODE_HW);
00290    GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_7, GPIO_PIN_TYPE_STD);
00291    GPIOPinConfigure(GPIO_PJ7_MIIPHYRSTn);
00292 }
00293 
00294 #endif
00295 
00296 
00297 /**
00298  * @brief F28M35x Ethernet MAC timer handler
00299  *
00300  * This routine is periodically called by the TCP/IP stack to
00301  * handle periodic operations such as polling the link state
00302  *
00303  * @param[in] interface Underlying network interface
00304  **/
00305 
00306 void f28m35xEthTick(NetInterface *interface)
00307 {
00308    //Handle periodic operations
00309    interface->phyDriver->tick(interface);
00310 }
00311 
00312 
00313 /**
00314  * @brief Enable interrupts
00315  * @param[in] interface Underlying network interface
00316  **/
00317 
00318 void f28m35xEthEnableIrq(NetInterface *interface)
00319 {
00320 #ifdef ti_sysbios_BIOS___VERS
00321    //Enable Ethernet MAC interrupts
00322    Hwi_enableInterrupt(INT_ETH);
00323 #else
00324    //Enable Ethernet MAC interrupts
00325    IntEnable(INT_ETH);
00326 #endif
00327 
00328    //Enable Ethernet PHY interrupts
00329    interface->phyDriver->enableIrq(interface);
00330 }
00331 
00332 
00333 /**
00334  * @brief Disable interrupts
00335  * @param[in] interface Underlying network interface
00336  **/
00337 
00338 void f28m35xEthDisableIrq(NetInterface *interface)
00339 {
00340 #ifdef ti_sysbios_BIOS___VERS
00341    //Disable Ethernet MAC interrupts
00342    Hwi_disableInterrupt(INT_ETH);
00343 #else
00344    //Disable Ethernet MAC interrupts
00345    IntDisable(INT_ETH);
00346 #endif
00347 
00348    //Disable Ethernet PHY interrupts
00349    interface->phyDriver->disableIrq(interface);
00350 }
00351 
00352 
00353 /**
00354  * @brief F28M35x Ethernet MAC interrupt service routine
00355  **/
00356 
00357 void f28m35xEthIrqHandler(void)
00358 {
00359    bool_t flag;
00360    uint32_t status;
00361 
00362    //Enter interrupt service routine
00363    osEnterIsr();
00364 
00365    //This flag will be set if a higher priority task must be woken
00366    flag = FALSE;
00367 
00368    //Read interrupt status register
00369    status = MAC_RIS_R;
00370 
00371    //Transmit FIFO empty?
00372    if(status & MAC_RIS_TXEMP)
00373    {
00374       //Acknowledge TXEMP interrupt
00375       MAC_IACK_R = MAC_IACK_TXEMP;
00376 
00377       //Check whether the transmit FIFO is available for writing
00378       if(!(MAC_TR_R & MAC_TR_NEWTX))
00379       {
00380          //Notify the TCP/IP stack that the transmitter is ready to send
00381          flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
00382       }
00383    }
00384 
00385    //Packet received?
00386    if(status & MAC_RIS_RXINT)
00387    {
00388       //Disable RXINT interrupt
00389       MAC_IM_R &= ~MAC_IM_RXINTM;
00390 
00391       //Set event flag
00392       nicDriverInterface->nicEvent = TRUE;
00393       //Notify the TCP/IP stack of the event
00394       flag |= osSetEventFromIsr(&netEvent);
00395    }
00396 
00397    //Leave interrupt service routine
00398    osExitIsr(flag);
00399 }
00400 
00401 
00402 /**
00403  * @brief F28M35x Ethernet MAC event handler
00404  * @param[in] interface Underlying network interface
00405  **/
00406 
00407 void f28m35xEthEventHandler(NetInterface *interface)
00408 {
00409    //Packet received?
00410    if(MAC_RIS_R & MAC_RIS_RXINT)
00411    {
00412       //Acknowledge RXINT interrupt
00413       MAC_IACK_R = MAC_IACK_RXINT;
00414 
00415       //Process all the pending packets
00416       while(MAC_NP_R & MAC_NP_NPR_M)
00417       {
00418          //Read incoming packet
00419          f28m35xEthReceivePacket(interface);
00420       }
00421    }
00422 
00423    //Re-enable Ethernet interrupts
00424    MAC_IM_R = MAC_IM_TXEMPM | MAC_IM_RXINTM;
00425 }
00426 
00427 
00428 /**
00429  * @brief Send a packet
00430  * @param[in] interface Underlying network interface
00431  * @param[in] buffer Multi-part buffer containing the data to send
00432  * @param[in] offset Offset to the first data byte
00433  * @return Error code
00434  **/
00435 
00436 error_t f28m35xEthSendPacket(NetInterface *interface,
00437    const NetBuffer *buffer, size_t offset)
00438 {
00439    size_t i;
00440    size_t length;
00441    uint32_t *p;
00442 
00443    //Retrieve the length of the packet
00444    length = netBufferGetLength(buffer) - offset;
00445 
00446    //Check the frame length
00447    if(length < sizeof(EthHeader) || length > ETH_MAX_FRAME_SIZE)
00448    {
00449       //The transmitter can accept another packet
00450       osSetEvent(&interface->nicTxEvent);
00451       //Report an error
00452       return ERROR_INVALID_LENGTH;
00453    }
00454 
00455    //Make sure the transmit FIFO is available for writing
00456    if(MAC_TR_R & MAC_TR_NEWTX)
00457       return ERROR_FAILURE;
00458 
00459    //Copy user data
00460    netBufferRead(txBuffer + 2, buffer, offset, length);
00461 
00462    //The packet is preceded by a 16-bit length field
00463    txBuffer[0] = LSB(length - sizeof(EthHeader));
00464    txBuffer[1] = MSB(length - sizeof(EthHeader));
00465 
00466    //Point to the beginning of the packet
00467    p = (uint32_t *) txBuffer;
00468    //Compute the length of the packet in 32-bit words
00469    length = (length + 5) / 4;
00470 
00471    //Copy packet to transmit FIFO
00472    for(i = 0; i < length; i++)
00473       MAC_DATA_R = p[i];
00474 
00475    //Start transmitting
00476    MAC_TR_R = MAC_TR_NEWTX;
00477 
00478    //Data successfully written
00479    return NO_ERROR;
00480 }
00481 
00482 
00483 /**
00484  * @brief Receive a packet
00485  * @param[in] interface Underlying network interface
00486  * @return Error code
00487  **/
00488 
00489 error_t f28m35xEthReceivePacket(NetInterface *interface)
00490 {
00491    error_t error;
00492    size_t i;
00493    size_t n;
00494    size_t length;
00495    uint32_t data;
00496    uint16_t *p;
00497 
00498    //Make sure the FIFO is not empty
00499    if(MAC_NP_R & MAC_NP_NPR_M)
00500    {
00501       //Read the first word
00502       data = MAC_DATA_R;
00503       //Retrieve the total length of the packet
00504       length = data & 0xFFFF;
00505 
00506       //Make sure the length field is valid
00507       if(length > 2)
00508       {
00509          //Point to the beginning of the buffer
00510          p = (uint16_t *) rxBuffer;
00511 
00512          //Retrieve the length of the frame
00513          length -= 2;
00514          //Limit the number of data to be read
00515          n = MIN(length, ETH_MAX_FRAME_SIZE);
00516 
00517          //Copy the first half word
00518          if(n > 0)
00519             *(p++) = (uint16_t) (data >> 16);
00520 
00521          //Copy data from receive FIFO
00522          for(i = 2; i < n; i += 4)
00523          {
00524             //Read a 32-bit word from the FIFO
00525             data = MAC_DATA_R;
00526             //Write the 32-bit to the receive buffer
00527             *(p++) = (uint16_t) data;
00528             *(p++) = (uint16_t) (data >> 16);
00529          }
00530 
00531          //Skip the remaining bytes
00532          while(i < length)
00533          {
00534             //Read a 32-bit word from the FIFO
00535             data = MAC_DATA_R;
00536             //Increment byte counter
00537             i += 4;
00538          }
00539 
00540          //Valid packet received
00541          error = NO_ERROR;
00542       }
00543       else
00544       {
00545          //Disable receiver
00546          MAC_RCTL_R &= ~MAC_RCTL_RXEN;
00547          //Flush the receive FIFO
00548          MAC_RCTL_R |= MAC_RCTL_RSTFIFO;
00549          //Re-enable receiver
00550          MAC_RCTL_R |= MAC_RCTL_RXEN;
00551 
00552          //The packet is not valid
00553          error = ERROR_INVALID_PACKET;
00554       }
00555    }
00556    else
00557    {
00558       //No more data in the receive buffer
00559       error = ERROR_BUFFER_EMPTY;
00560    }
00561 
00562    //Check whether a valid packet has been received
00563    if(!error)
00564    {
00565       //Pass the packet to the upper layer
00566       nicProcessPacket(interface, rxBuffer, n);
00567    }
00568 
00569    //Return status code
00570    return error;
00571 }
00572 
00573 
00574 /**
00575  * @brief Configure multicast MAC address filtering
00576  * @param[in] interface Underlying network interface
00577  * @return Error code
00578  **/
00579 
00580 error_t f28m35xEthSetMulticastFilter(NetInterface *interface)
00581 {
00582    uint_t i;
00583    bool_t acceptMulticast;
00584 
00585    //This flag will be set if multicast addresses should be accepted
00586    acceptMulticast = FALSE;
00587 
00588    //The MAC filter table contains the multicast MAC addresses
00589    //to accept when receiving an Ethernet frame
00590    for(i = 0; i < MAC_MULTICAST_FILTER_SIZE; i++)
00591    {
00592       //Valid entry?
00593       if(interface->macMulticastFilter[i].refCount > 0)
00594       {
00595          //Accept multicast addresses
00596          acceptMulticast = TRUE;
00597          //We are done
00598          break;
00599       }
00600    }
00601 
00602    //Enable the reception of multicast frames if necessary
00603    if(acceptMulticast)
00604       MAC_RCTL_R |= MAC_RCTL_AMUL;
00605    else
00606       MAC_RCTL_R &= ~MAC_RCTL_AMUL;
00607 
00608    //Successful processing
00609    return NO_ERROR;
00610 }
00611 
00612 
00613 /**
00614  * @brief Adjust MAC configuration parameters for proper operation
00615  * @param[in] interface Underlying network interface
00616  * @return Error code
00617  **/
00618 
00619 error_t f28m35xEthUpdateMacConfig(NetInterface *interface)
00620 {
00621    //Half-duplex or full-duplex mode?
00622    if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
00623       MAC_TCTL_R |= MAC_TCTL_DUPLEX;
00624    else
00625       MAC_TCTL_R &= ~MAC_TCTL_DUPLEX;
00626 
00627    //Successful processing
00628    return NO_ERROR;
00629 }
00630 
00631 
00632 /**
00633  * @brief Write PHY register
00634  * @param[in] phyAddr PHY address
00635  * @param[in] regAddr Register address
00636  * @param[in] data Register value
00637  **/
00638 
00639 void f28m35xEthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
00640 {
00641    //Set PHY address
00642    MAC_MAR_R = phyAddr;
00643    //Data to be written in the PHY register
00644    MAC_MTXD_R = data & MAC_MTXD_MDTX_M;
00645    //Start a write operation
00646    MAC_MCTL_R = (regAddr << 3) | MAC_MCTL_WRITE | MAC_MCTL_START;
00647 
00648    //Wait for the write to complete
00649    while(MAC_MCTL_R & MAC_MCTL_START);
00650 }
00651 
00652 
00653 /**
00654  * @brief Read PHY register
00655  * @param[in] phyAddr PHY address
00656  * @param[in] regAddr Register address
00657  * @return Register value
00658  **/
00659 
00660 uint16_t f28m35xEthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
00661 {
00662    //Set PHY address
00663    MAC_MAR_R = phyAddr;
00664    //Start a read operation
00665    MAC_MCTL_R = (regAddr << 3) | MAC_MCTL_START;
00666 
00667    //Wait for the read to complete
00668    while(MAC_MCTL_R & MAC_MCTL_START);
00669 
00670    //Return PHY register contents
00671    return MAC_MRXD_R & MAC_MRXD_MDRX_M;
00672 }
00673