Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers s7g2_eth.c Source File

s7g2_eth.c

Go to the documentation of this file.
00001 /**
00002  * @file s7g2_eth.c
00003  * @brief Renesas Synergy S7G2 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 "bsp_irq_cfg.h"
00034 #include "r7fs7g2x.h"
00035 #include "core/net.h"
00036 #include "drivers/s7g2_eth.h"
00037 #include "debug.h"
00038 
00039 //Underlying network interface
00040 static NetInterface *nicDriverInterface;
00041 
00042 //IAR EWARM compiler?
00043 #if defined(__ICCARM__)
00044 
00045 //Transmit buffer
00046 #pragma data_alignment = 32
00047 static uint8_t txBuffer[S7G2_ETH_TX_BUFFER_COUNT][S7G2_ETH_TX_BUFFER_SIZE];
00048 //Receive buffer
00049 #pragma data_alignment = 32
00050 static uint8_t rxBuffer[S7G2_ETH_RX_BUFFER_COUNT][S7G2_ETH_RX_BUFFER_SIZE];
00051 //Transmit DMA descriptors
00052 #pragma data_alignment = 32
00053 static S7g2TxDmaDesc txDmaDesc[S7G2_ETH_TX_BUFFER_COUNT];
00054 //Receive DMA descriptors
00055 #pragma data_alignment = 32
00056 static S7g2RxDmaDesc rxDmaDesc[S7G2_ETH_RX_BUFFER_COUNT];
00057 
00058 //ARM or GCC compiler?
00059 #else
00060 
00061 //Transmit buffer
00062 static uint8_t txBuffer[S7G2_ETH_TX_BUFFER_COUNT][S7G2_ETH_TX_BUFFER_SIZE]
00063    __attribute__((aligned(32)));
00064 //Receive buffer
00065 static uint8_t rxBuffer[S7G2_ETH_RX_BUFFER_COUNT][S7G2_ETH_RX_BUFFER_SIZE]
00066    __attribute__((aligned(32)));
00067 //Transmit DMA descriptors
00068 static S7g2TxDmaDesc txDmaDesc[S7G2_ETH_TX_BUFFER_COUNT]
00069    __attribute__((aligned(32)));
00070 //Receive DMA descriptors
00071 static S7g2RxDmaDesc rxDmaDesc[S7G2_ETH_RX_BUFFER_COUNT]
00072    __attribute__((aligned(32)));
00073 
00074 #endif
00075 
00076 //Current transmit descriptor
00077 static uint_t txIndex;
00078 //Current receive descriptor
00079 static uint_t rxIndex;
00080 
00081 
00082 /**
00083  * @brief S7G2 Ethernet MAC driver
00084  **/
00085 
00086 const NicDriver s7g2EthDriver =
00087 {
00088    NIC_TYPE_ETHERNET,
00089    ETH_MTU,
00090    s7g2EthInit,
00091    s7g2EthTick,
00092    s7g2EthEnableIrq,
00093    s7g2EthDisableIrq,
00094    s7g2EthEventHandler,
00095    s7g2EthSendPacket,
00096    s7g2EthSetMulticastFilter,
00097    s7g2EthUpdateMacConfig,
00098    s7g2EthWritePhyReg,
00099    s7g2EthReadPhyReg,
00100    TRUE,
00101    TRUE,
00102    TRUE,
00103    TRUE
00104 };
00105 
00106 
00107 /**
00108  * @brief S7G2 Ethernet MAC initialization
00109  * @param[in] interface Underlying network interface
00110  * @return Error code
00111  **/
00112 
00113 error_t s7g2EthInit(NetInterface *interface)
00114 {
00115    error_t error;
00116 
00117    //Debug message
00118    TRACE_INFO("Initializing S7G2 Ethernet MAC...\r\n");
00119 
00120    //Save underlying network interface
00121    nicDriverInterface = interface;
00122 
00123    //Disable protection
00124    R_SYSTEM->PRCR = 0xA50B;
00125    //Cancel EDMAC1 module stop state
00126    R_MSTP->MSTPCRB_b.MSTPB14 = 0;
00127    //Enable protection
00128    R_SYSTEM->PRCR = 0xA500;
00129 
00130    //GPIO configuration
00131    s7g2EthInitGpio(interface);
00132 
00133    //Reset EDMAC1 module
00134    R_EDMAC1->EDMR_b.SWR = 1;
00135    sleep(10);
00136 
00137    //PHY transceiver initialization
00138    error = interface->phyDriver->init(interface);
00139    //Failed to initialize PHY transceiver?
00140    if(error)
00141       return error;
00142 
00143    //Initialize DMA descriptor lists
00144    s7g2EthInitDmaDesc(interface);
00145 
00146    //Maximum frame length that can be accepted
00147    R_ETHERC1->RFLR = 1518;
00148    //Set default inter packet gap (96-bit time)
00149    R_ETHERC1->IPGR = 0x14;
00150 
00151    //Set the upper 32 bits of the MAC address
00152    R_ETHERC1->MAHR = (interface->macAddr.b[0] << 24) | (interface->macAddr.b[1] << 16) |
00153       (interface->macAddr.b[2] << 8) | interface->macAddr.b[3];
00154 
00155    //Set the lower 16 bits of the MAC address
00156    R_ETHERC1->MALR_b.MALR = (interface->macAddr.b[4] << 8) | interface->macAddr.b[5];
00157 
00158    //Set descriptor length (16 bytes)
00159    R_EDMAC1->EDMR_b.DL = 0;
00160    //Select little endian mode
00161    R_EDMAC1->EDMR_b.DE = 1;
00162    //Use store and forward mode
00163    R_EDMAC1->TFTR_b.TFT = 0;
00164 
00165    //Set transmit FIFO size (2048 bytes)
00166    R_EDMAC1->FDR_b.TFD = 7;
00167    //Set receive FIFO size (2048 bytes)
00168    R_EDMAC1->FDR_b.RFD = 7;
00169 
00170    //Enable continuous reception of multiple frames
00171    R_EDMAC1->RMCR_b.RNR = 1;
00172 
00173    //Accept transmit interrupt notifications
00174    R_EDMAC1->TRIMD_b.TIM = 0;
00175    R_EDMAC1->TRIMD_b.TIS = 1;
00176 
00177    //Disable all EDMAC interrupts
00178    R_EDMAC1->EESIPR = 0;
00179    //Enable only the desired EDMAC interrupts
00180    R_EDMAC1->EESIPR_b.TWBIP = 1;
00181    R_EDMAC1->EESIPR_b.FRIP = 1;
00182 
00183    //Set priority grouping (4 bits for pre-emption priority, no bits for subpriority)
00184    NVIC_SetPriorityGrouping(S7G2_ETH_IRQ_PRIORITY_GROUPING);
00185 
00186    //Configure EDMAC interrupt priority
00187    NVIC_SetPriority(ETHER_EINT1_IRQn, NVIC_EncodePriority(S7G2_ETH_IRQ_PRIORITY_GROUPING,
00188       S7G2_ETH_IRQ_GROUP_PRIORITY, S7G2_ETH_IRQ_SUB_PRIORITY));
00189 
00190    //Enable transmission and reception
00191    R_ETHERC1->ECMR_b.TE = 1;
00192    R_ETHERC1->ECMR_b.RE = 1;
00193 
00194    //Instruct the DMA to poll the receive descriptor list
00195    R_EDMAC1->EDRRR_b.RR = 1;
00196 
00197    //Accept any packets from the upper layer
00198    osSetEvent(&interface->nicTxEvent);
00199 
00200    //Successful initialization
00201    return NO_ERROR;
00202 }
00203 
00204 
00205 //SK-S7G2 evaluation board?
00206 #if defined(USE_SK_S7G2)
00207 
00208 /**
00209  * @brief GPIO configuration
00210  * @param[in] interface Underlying network interface
00211  **/
00212 
00213 void s7g2EthInitGpio(NetInterface *interface)
00214 {
00215    //Unlock PFS registers
00216    R_PMISC->PWPR_b.BOWI = 0;
00217    R_PMISC->PWPR_b.PSFWE = 1;
00218 
00219    //Select RMII interface mode
00220    R_PMISC->PFENET_b.PHYMODE1 = 0;
00221 
00222    //Configure ET1_MDC (P4_3)
00223    R_PFS->P403PFS_b.PMR = 1;
00224    R_PFS->P403PFS_b.PSEL = 23;
00225 
00226    //Configure ET1_MDIO (P4_4)
00227    R_PFS->P404PFS_b.PMR = 1;
00228    R_PFS->P404PFS_b.PSEL = 23;
00229 
00230    //Configure RMII1_TXD_EN (P4_5)
00231    R_PFS->P405PFS_b.PMR = 1;
00232    R_PFS->P405PFS_b.PSEL = 23;
00233 
00234    //Configure RMII1_TXD1 (P4_6)
00235    R_PFS->P406PFS_b.PMR = 1;
00236    R_PFS->P406PFS_b.PSEL = 23;
00237 
00238    //Configure RMII1_TXD0 (P7_0)
00239    R_PFS->P700PFS_b.PMR = 1;
00240    R_PFS->P700PFS_b.PSEL = 23;
00241 
00242    //Configure REF50CK1 (P7_1)
00243    R_PFS->P701PFS_b.PMR = 1;
00244    R_PFS->P701PFS_b.PSEL = 23;
00245 
00246    //Configure RMII1_RXD0 (P7_2)
00247    R_PFS->P702PFS_b.PMR = 1;
00248    R_PFS->P702PFS_b.PSEL = 23;
00249 
00250    //Configure RMII1_RXD1 (P7_3)
00251    R_PFS->P703PFS_b.PMR = 1;
00252    R_PFS->P703PFS_b.PSEL = 23;
00253 
00254    //Configure RMII1_RX_ER (P7_4)
00255    R_PFS->P704PFS_b.PMR = 1;
00256    R_PFS->P704PFS_b.PSEL = 23;
00257 
00258    //Configure RMII1_CRS_DV (P7_5)
00259    R_PFS->P705PFS_b.PMR = 1;
00260    R_PFS->P705PFS_b.PSEL = 23;
00261 
00262    //Lock PFS registers
00263    R_PMISC->PWPR_b.PSFWE = 0;
00264    R_PMISC->PWPR_b.BOWI = 1;
00265 }
00266 
00267 #endif
00268 
00269 
00270 /**
00271  * @brief Initialize DMA descriptor lists
00272  * @param[in] interface Underlying network interface
00273  **/
00274 
00275 void s7g2EthInitDmaDesc(NetInterface *interface)
00276 {
00277    uint_t i;
00278 
00279    //Initialize TX descriptors
00280    for(i = 0; i < S7G2_ETH_TX_BUFFER_COUNT; i++)
00281    {
00282       //The descriptor is initially owned by the application
00283       txDmaDesc[i].td0 = 0;
00284       //Transmit buffer length
00285       txDmaDesc[i].td1 = 0;
00286       //Transmit buffer address
00287       txDmaDesc[i].td2 = (uint32_t) txBuffer[i];
00288       //Clear padding field
00289       txDmaDesc[i].padding = 0;
00290    }
00291 
00292    //Mark the last descriptor entry with the TDLE flag
00293    txDmaDesc[i - 1].td0 |= EDMAC_TD0_TDLE;
00294    //Initialize TX descriptor index
00295    txIndex = 0;
00296 
00297    //Initialize RX descriptors
00298    for(i = 0; i < S7G2_ETH_RX_BUFFER_COUNT; i++)
00299    {
00300       //The descriptor is initially owned by the DMA
00301       rxDmaDesc[i].rd0 = EDMAC_RD0_RACT;
00302       //Receive buffer length
00303       rxDmaDesc[i].rd1 = (S7G2_ETH_RX_BUFFER_SIZE << 16) & EDMAC_RD1_RBL;
00304       //Receive buffer address
00305       rxDmaDesc[i].rd2 = (uint32_t) rxBuffer[i];
00306       //Clear padding field
00307       rxDmaDesc[i].padding = 0;
00308    }
00309 
00310    //Mark the last descriptor entry with the RDLE flag
00311    rxDmaDesc[i - 1].rd0 |= EDMAC_RD0_RDLE;
00312    //Initialize RX descriptor index
00313    rxIndex = 0;
00314 
00315    //Start address of the TX descriptor list
00316    R_EDMAC1->TDLAR = (uint32_t) txDmaDesc;
00317    //Start address of the RX descriptor list
00318    R_EDMAC1->RDLAR = (uint32_t) rxDmaDesc;
00319 }
00320 
00321 
00322 /**
00323  * @brief S7G2 Ethernet MAC timer handler
00324  *
00325  * This routine is periodically called by the TCP/IP stack to
00326  * handle periodic operations such as polling the link state
00327  *
00328  * @param[in] interface Underlying network interface
00329  **/
00330 
00331 void s7g2EthTick(NetInterface *interface)
00332 {
00333    //Handle periodic operations
00334    interface->phyDriver->tick(interface);
00335 }
00336 
00337 
00338 /**
00339  * @brief Enable interrupts
00340  * @param[in] interface Underlying network interface
00341  **/
00342 
00343 void s7g2EthEnableIrq(NetInterface *interface)
00344 {
00345    //Enable Ethernet MAC interrupts
00346    NVIC_EnableIRQ(ETHER_EINT1_IRQn);
00347    //Enable Ethernet PHY interrupts
00348    interface->phyDriver->enableIrq(interface);
00349 }
00350 
00351 
00352 /**
00353  * @brief Disable interrupts
00354  * @param[in] interface Underlying network interface
00355  **/
00356 
00357 void s7g2EthDisableIrq(NetInterface *interface)
00358 {
00359    //Disable Ethernet MAC interrupts
00360    NVIC_DisableIRQ(ETHER_EINT1_IRQn);
00361    //Disable Ethernet PHY interrupts
00362    interface->phyDriver->disableIrq(interface);
00363 }
00364 
00365 
00366 /**
00367  * @brief S7G2 Ethernet MAC interrupt service routine
00368  **/
00369 
00370 void ETHER_EINT1_IRQHandler(void)
00371 {
00372    bool_t flag;
00373    uint32_t status;
00374 
00375    //Enter interrupt service routine
00376    osEnterIsr();
00377 
00378    //This flag will be set if a higher priority task must be woken
00379    flag = FALSE;
00380 
00381    //Read interrupt status register
00382    status = R_EDMAC1->EESR;
00383 
00384    //A packet has been transmitted?
00385    if(status & EDMAC_EESR_TWB)
00386    {
00387       //Clear TWB interrupt flag
00388       R_EDMAC1->EESR = EDMAC_EESR_TWB;
00389 
00390       //Check whether the TX buffer is available for writing
00391       if(!(txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT))
00392       {
00393          //Notify the TCP/IP stack that the transmitter is ready to send
00394          flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
00395       }
00396    }
00397 
00398    //A packet has been received?
00399    if(status & EDMAC_EESR_FR)
00400    {
00401       //Disable FR interrupts
00402       R_EDMAC1->EESIPR_b.FRIP = 0;
00403 
00404       //Set event flag
00405       nicDriverInterface->nicEvent = TRUE;
00406       //Notify the TCP/IP stack of the event
00407       flag |= osSetEventFromIsr(&netEvent);
00408    }
00409 
00410    //Clear IR flag
00411    R_ICU->IELSRn_b[ETHER_EINT1_IRQn].IR = 0;
00412 
00413    //Leave interrupt service routine
00414    osExitIsr(flag);
00415 }
00416 
00417 
00418 /**
00419  * @brief S7G2 Ethernet MAC event handler
00420  * @param[in] interface Underlying network interface
00421  **/
00422 
00423 void s7g2EthEventHandler(NetInterface *interface)
00424 {
00425    error_t error;
00426 
00427    //Packet received?
00428    if(R_EDMAC1->EESR & EDMAC_EESR_FR)
00429    {
00430       //Clear FR interrupt flag
00431       R_EDMAC1->EESR = EDMAC_EESR_FR;
00432 
00433       //Process all pending packets
00434       do
00435       {
00436          //Read incoming packet
00437          error = s7g2EthReceivePacket(interface);
00438 
00439          //No more data in the receive buffer?
00440       } while(error != ERROR_BUFFER_EMPTY);
00441    }
00442 
00443    //Re-enable EDMAC interrupts
00444    R_EDMAC1->EESIPR_b.TWBIP = 1;
00445    R_EDMAC1->EESIPR_b.FRIP = 1;
00446 }
00447 
00448 
00449 /**
00450  * @brief Send a packet
00451  * @param[in] interface Underlying network interface
00452  * @param[in] buffer Multi-part buffer containing the data to send
00453  * @param[in] offset Offset to the first data byte
00454  * @return Error code
00455  **/
00456 
00457 error_t s7g2EthSendPacket(NetInterface *interface,
00458    const NetBuffer *buffer, size_t offset)
00459 {
00460    //Retrieve the length of the packet
00461    size_t length = netBufferGetLength(buffer) - offset;
00462 
00463    //Check the frame length
00464    if(length > S7G2_ETH_TX_BUFFER_SIZE)
00465    {
00466       //The transmitter can accept another packet
00467       osSetEvent(&interface->nicTxEvent);
00468       //Report an error
00469       return ERROR_INVALID_LENGTH;
00470    }
00471 
00472    //Make sure the current buffer is available for writing
00473    if(txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT)
00474       return ERROR_FAILURE;
00475 
00476    //Copy user data to the transmit buffer
00477    netBufferRead(txBuffer[txIndex], buffer, offset, length);
00478 
00479    //Write the number of bytes to send
00480    txDmaDesc[txIndex].td1 = (length << 16) & EDMAC_TD1_TBL;
00481 
00482    //Check current index
00483    if(txIndex < (S7G2_ETH_TX_BUFFER_COUNT - 1))
00484    {
00485       //Give the ownership of the descriptor to the DMA engine
00486       txDmaDesc[txIndex].td0 = EDMAC_TD0_TACT | EDMAC_TD0_TFP_SOF |
00487          EDMAC_TD0_TFP_EOF | EDMAC_TD0_TWBI;
00488 
00489       //Point to the next descriptor
00490       txIndex++;
00491    }
00492    else
00493    {
00494       //Give the ownership of the descriptor to the DMA engine
00495       txDmaDesc[txIndex].td0 = EDMAC_TD0_TACT | EDMAC_TD0_TDLE |
00496          EDMAC_TD0_TFP_SOF | EDMAC_TD0_TFP_EOF | EDMAC_TD0_TWBI;
00497 
00498       //Wrap around
00499       txIndex = 0;
00500    }
00501 
00502    //Instruct the DMA to poll the transmit descriptor list
00503    R_EDMAC1->EDTRR_b.TR = 1;
00504 
00505    //Check whether the next buffer is available for writing
00506    if(!(txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT))
00507    {
00508       //The transmitter can accept another packet
00509       osSetEvent(&interface->nicTxEvent);
00510    }
00511 
00512    //Successful write operation
00513    return NO_ERROR;
00514 }
00515 
00516 
00517 /**
00518  * @brief Receive a packet
00519  * @param[in] interface Underlying network interface
00520  * @return Error code
00521  **/
00522 
00523 error_t s7g2EthReceivePacket(NetInterface *interface)
00524 {
00525    error_t error;
00526    size_t n;
00527 
00528    //The current buffer is available for reading?
00529    if(!(rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RACT))
00530    {
00531       //SOF and EOF flags should be set
00532       if((rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RFP_SOF) &&
00533          (rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RFP_EOF))
00534       {
00535          //Make sure no error occurred
00536          if(!(rxDmaDesc[rxIndex].rd0 & (EDMAC_RD0_RFS_MASK & ~EDMAC_RD0_RFS_RMAF)))
00537          {
00538             //Retrieve the length of the frame
00539             n = rxDmaDesc[rxIndex].rd1 & EDMAC_RD1_RFL;
00540             //Limit the number of data to read
00541             n = MIN(n, S7G2_ETH_RX_BUFFER_SIZE);
00542 
00543             //Pass the packet to the upper layer
00544             nicProcessPacket(interface, rxBuffer[rxIndex], n);
00545 
00546             //Valid packet received
00547             error = NO_ERROR;
00548          }
00549          else
00550          {
00551             //The received packet contains an error
00552             error = ERROR_INVALID_PACKET;
00553          }
00554       }
00555       else
00556       {
00557          //The packet is not valid
00558          error = ERROR_INVALID_PACKET;
00559       }
00560 
00561       //Check current index
00562       if(rxIndex < (S7G2_ETH_RX_BUFFER_COUNT - 1))
00563       {
00564          //Give the ownership of the descriptor back to the DMA
00565          rxDmaDesc[rxIndex].rd0 = EDMAC_RD0_RACT;
00566          //Point to the next descriptor
00567          rxIndex++;
00568       }
00569       else
00570       {
00571          //Give the ownership of the descriptor back to the DMA
00572          rxDmaDesc[rxIndex].rd0 = EDMAC_RD0_RACT | EDMAC_RD0_RDLE;
00573          //Wrap around
00574          rxIndex = 0;
00575       }
00576 
00577       //Instruct the DMA to poll the receive descriptor list
00578       R_EDMAC1->EDRRR_b.RR = 1;
00579    }
00580    else
00581    {
00582       //No more data in the receive buffer
00583       error = ERROR_BUFFER_EMPTY;
00584    }
00585 
00586    //Return status code
00587    return error;
00588 }
00589 
00590 
00591 /**
00592  * @brief Configure multicast MAC address filtering
00593  * @param[in] interface Underlying network interface
00594  * @return Error code
00595  **/
00596 
00597 error_t s7g2EthSetMulticastFilter(NetInterface *interface)
00598 {
00599    uint_t i;
00600    bool_t acceptMulticast;
00601 
00602    //This flag will be set if multicast addresses should be accepted
00603    acceptMulticast = FALSE;
00604 
00605    //The MAC filter table contains the multicast MAC addresses
00606    //to accept when receiving an Ethernet frame
00607    for(i = 0; i < MAC_MULTICAST_FILTER_SIZE; i++)
00608    {
00609       //Valid entry?
00610       if(interface->macMulticastFilter[i].refCount > 0)
00611       {
00612          //Accept multicast addresses
00613          acceptMulticast = TRUE;
00614          //We are done
00615          break;
00616       }
00617    }
00618 
00619    //Enable the reception of multicast frames if necessary
00620    if(acceptMulticast)
00621       R_EDMAC1->EESR_b.RMAF = 1;
00622    else
00623       R_EDMAC1->EESR_b.RMAF = 0;
00624 
00625    //Successful processing
00626    return NO_ERROR;
00627 }
00628 
00629 
00630 /**
00631  * @brief Adjust MAC configuration parameters for proper operation
00632  * @param[in] interface Underlying network interface
00633  * @return Error code
00634  **/
00635 
00636 error_t s7g2EthUpdateMacConfig(NetInterface *interface)
00637 {
00638    //10BASE-T or 100BASE-TX operation mode?
00639    if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
00640       R_ETHERC1->ECMR_b.RTM = 1;
00641    else
00642       R_ETHERC1->ECMR_b.RTM = 0;
00643 
00644    //Half-duplex or full-duplex mode?
00645    if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
00646       R_ETHERC1->ECMR_b.DM = 1;
00647    else
00648       R_ETHERC1->ECMR_b.DM = 0;
00649 
00650    //Successful processing
00651    return NO_ERROR;
00652 }
00653 
00654 
00655 /**
00656  * @brief Write PHY register
00657  * @param[in] phyAddr PHY address
00658  * @param[in] regAddr Register address
00659  * @param[in] data Register value
00660  **/
00661 
00662 void s7g2EthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
00663 {
00664    //Synchronization pattern
00665    s7g2EthWriteSmi(SMI_SYNC, 32);
00666    //Start of frame
00667    s7g2EthWriteSmi(SMI_START, 2);
00668    //Set up a write operation
00669    s7g2EthWriteSmi(SMI_WRITE, 2);
00670    //Write PHY address
00671    s7g2EthWriteSmi(phyAddr, 5);
00672    //Write register address
00673    s7g2EthWriteSmi(regAddr, 5);
00674    //Turnaround
00675    s7g2EthWriteSmi(SMI_TA, 2);
00676    //Write register value
00677    s7g2EthWriteSmi(data, 16);
00678    //Release MDIO
00679    s7g2EthReadSmi(1);
00680 }
00681 
00682 
00683 /**
00684  * @brief Read PHY register
00685  * @param[in] phyAddr PHY address
00686  * @param[in] regAddr Register address
00687  * @return Register value
00688  **/
00689 
00690 uint16_t s7g2EthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
00691 {
00692    uint16_t data;
00693 
00694    //Synchronization pattern
00695    s7g2EthWriteSmi(SMI_SYNC, 32);
00696    //Start of frame
00697    s7g2EthWriteSmi(SMI_START, 2);
00698    //Set up a read operation
00699    s7g2EthWriteSmi(SMI_READ, 2);
00700    //Write PHY address
00701    s7g2EthWriteSmi(phyAddr, 5);
00702    //Write register address
00703    s7g2EthWriteSmi(regAddr, 5);
00704    //Turnaround to avoid contention
00705    s7g2EthReadSmi(1);
00706    //Read register value
00707    data = s7g2EthReadSmi(16);
00708    //Force the PHY to release the MDIO pin
00709    s7g2EthReadSmi(1);
00710 
00711    //Return PHY register contents
00712    return data;
00713 }
00714 
00715 
00716 /**
00717  * @brief SMI write operation
00718  * @param[in] data Raw data to be written
00719  * @param[in] length Number of bits to be written
00720  **/
00721 
00722 void s7g2EthWriteSmi(uint32_t data, uint_t length)
00723 {
00724    //Skip the most significant bits since they are meaningless
00725    data <<= 32 - length;
00726 
00727    //Configure MDIO as an output
00728    R_ETHERC1->PIR_b.MMD = 1;
00729 
00730    //Write the specified number of bits
00731    while(length--)
00732    {
00733       //Write MDIO
00734       if(data & 0x80000000)
00735          R_ETHERC1->PIR_b.MDO = 1;
00736       else
00737          R_ETHERC1->PIR_b.MDO = 0;
00738 
00739       //Assert MDC
00740       usleep(1);
00741       R_ETHERC1->PIR_b.MDC = 1;
00742       //Deassert MDC
00743       usleep(1);
00744       R_ETHERC1->PIR_b.MDC = 0;
00745 
00746       //Rotate data
00747       data <<= 1;
00748    }
00749 }
00750 
00751 
00752 /**
00753  * @brief SMI read operation
00754  * @param[in] length Number of bits to be read
00755  * @return Data resulting from the MDIO read operation
00756  **/
00757 
00758 uint32_t s7g2EthReadSmi(uint_t length)
00759 {
00760    uint32_t data = 0;
00761 
00762    //Configure MDIO as an input
00763    R_ETHERC1->PIR_b.MMD = 0;
00764 
00765    //Read the specified number of bits
00766    while(length--)
00767    {
00768       //Rotate data
00769       data <<= 1;
00770 
00771       //Assert MDC
00772       R_ETHERC1->PIR_b.MDC = 1;
00773       usleep(1);
00774       //Deassert MDC
00775       R_ETHERC1->PIR_b.MDC = 0;
00776       usleep(1);
00777 
00778       //Check MDIO state
00779       if(R_ETHERC1->PIR_b.MDI)
00780          data |= 0x00000001;
00781    }
00782 
00783    //Return the received data
00784    return data;
00785 }
00786