Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rza1_eth.c Source File

rza1_eth.c

Go to the documentation of this file.
00001 /**
00002  * @file rza1_eth.c
00003  * @brief Renesas RZ/A1 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 "iodefine.h"
00034 #include "cpg_iobitmask.h"
00035 #include "intc.h"
00036 #include "core/net.h"
00037 #include "drivers/rza1_eth.h"
00038 #include "debug.h"
00039 
00040 //Underlying network interface
00041 static NetInterface *nicDriverInterface;
00042 
00043 //IAR EWARM compiler?
00044 #if defined(__ICCARM__)
00045 
00046 //Transmit buffer
00047 #pragma data_alignment = 32
00048 static uint8_t txBuffer[RZA1_ETH_TX_BUFFER_COUNT][RZA1_ETH_TX_BUFFER_SIZE];
00049 //Receive buffer
00050 #pragma data_alignment = 32
00051 static uint8_t rxBuffer[RZA1_ETH_RX_BUFFER_COUNT][RZA1_ETH_RX_BUFFER_SIZE];
00052 //Transmit DMA descriptors
00053 #pragma data_alignment = 32
00054 static Rza1TxDmaDesc txDmaDesc[RZA1_ETH_TX_BUFFER_COUNT];
00055 //Receive DMA descriptors
00056 #pragma data_alignment = 32
00057 static Rza1RxDmaDesc rxDmaDesc[RZA1_ETH_RX_BUFFER_COUNT];
00058 
00059 //ARM or GCC compiler?
00060 #else
00061 
00062 //Transmit buffer
00063 static uint8_t txBuffer[RZA1_ETH_TX_BUFFER_COUNT][RZA1_ETH_TX_BUFFER_SIZE]
00064    __attribute__((section(".BSS_DMAC_SAMPLE_INTERNAL_RAM"), aligned(32)));
00065 //Receive buffer
00066 static uint8_t rxBuffer[RZA1_ETH_RX_BUFFER_COUNT][RZA1_ETH_RX_BUFFER_SIZE]
00067    __attribute__((section(".BSS_DMAC_SAMPLE_INTERNAL_RAM"), aligned(32)));
00068 //Transmit DMA descriptors
00069 static Rza1TxDmaDesc txDmaDesc[RZA1_ETH_TX_BUFFER_COUNT]
00070    __attribute__((section(".BSS_DMAC_SAMPLE_INTERNAL_RAM"), aligned(32)));
00071 //Receive DMA descriptors
00072 static Rza1RxDmaDesc rxDmaDesc[RZA1_ETH_RX_BUFFER_COUNT]
00073    __attribute__((section(".BSS_DMAC_SAMPLE_INTERNAL_RAM"), aligned(32)));
00074 
00075 #endif
00076 
00077 //Current transmit descriptor
00078 static uint_t txIndex;
00079 //Current receive descriptor
00080 static uint_t rxIndex;
00081 
00082 
00083 /**
00084  * @brief RZ/A1 Ethernet MAC driver
00085  **/
00086 
00087 const NicDriver rza1EthDriver =
00088 {
00089    NIC_TYPE_ETHERNET,
00090    ETH_MTU,
00091    rza1EthInit,
00092    rza1EthTick,
00093    rza1EthEnableIrq,
00094    rza1EthDisableIrq,
00095    rza1EthEventHandler,
00096    rza1EthSendPacket,
00097    rza1EthSetMulticastFilter,
00098    rza1EthUpdateMacConfig,
00099    rza1EthWritePhyReg,
00100    rza1EthReadPhyReg,
00101    TRUE,
00102    TRUE,
00103    TRUE,
00104    TRUE
00105 };
00106 
00107 
00108 /**
00109  * @brief RZ/A1 Ethernet MAC initialization
00110  * @param[in] interface Underlying network interface
00111  * @return Error code
00112  **/
00113 
00114 error_t rza1EthInit(NetInterface *interface)
00115 {
00116    error_t error;
00117 
00118    //Debug message
00119    TRACE_INFO("Initializing RZ/A1 Ethernet MAC...\r\n");
00120 
00121    //Save underlying network interface
00122    nicDriverInterface = interface;
00123 
00124    //Enable Ethernet peripheral clock
00125    CPG.STBCR7 &= ~CPG_STBCR7_MSTP74;
00126 
00127    //GPIO configuration
00128    rza1EthInitGpio(interface);
00129 
00130    //Perform software reset
00131    ETHER.ARSTR = ETHER_ARSTR_ARST;
00132    //Wait for the reset to complete
00133    sleep(10);
00134 
00135    //Start EDMAC transmitting and receiving units
00136    ETHER.EDSR0 = ETHER_EDSR0_ENT | ETHER_EDSR0_ENR;
00137 
00138    //To execute a software reset with this register, 1 must be
00139    //written to both the SWRT and SWRR bits simultaneously
00140    ETHER.EDMR0 = ETHER_EDMR0_SWRT | ETHER_EDMR0_SWRR;
00141    //Wait for the reset to complete
00142    while(ETHER.EDMR0 & (ETHER_EDMR0_SWRT | ETHER_EDMR0_SWRR));
00143 
00144    //PHY transceiver initialization
00145    error = interface->phyDriver->init(interface);
00146    //Failed to initialize PHY transceiver?
00147    if(error)
00148       return error;
00149 
00150    //Initialize DMA descriptor lists
00151    rza1EthInitDmaDesc(interface);
00152 
00153    //Select little endian mode and set descriptor length (16 bytes)
00154    ETHER.EDMR0 = ETHER_EDMR0_DE | ETHER_EDMR0_DL_16;
00155 
00156    //Error masks
00157    ETHER.TRSCER0 = 0;
00158    //Use store and forward mode
00159    ETHER.TFTR0 = 0;
00160 
00161    //Set transmit FIFO size and receive FIFO size (2048 bytes)
00162    ETHER.FDR0 = ETHER_FDR0_TFD_2048 | ETHER_FDR0_RFD_2048;
00163 
00164    //Enable continuous reception of multiple frames
00165    ETHER.RMCR0 = ETHER_RMCR0_RNC;
00166    //No padding insertion into receive data
00167    ETHER.RPADIR0 = 0;
00168 
00169    //Receive FIFO threshold (8 frames or 2048-64 bytes)
00170    ETHER.FCFTR0 = ETHER_FCFTR0_RFF_8 | ETHER_FCFTR0_RFD_2048;
00171 
00172    //Intelligent checksum operation mode
00173    ETHER.CSMR = 0;
00174 
00175    //Enable multicast address filtering
00176    ETHER.ECMR0 |= ETH_ECMR0_MCT;
00177 
00178    //Set the upper 32 bits of the MAC address
00179    ETHER.MAHR0 = (interface->macAddr.b[0] << 24) | (interface->macAddr.b[1] << 16) |
00180       (interface->macAddr.b[2] << 8) | interface->macAddr.b[3];
00181 
00182    //Set the lower 16 bits of the MAC address
00183    ETHER.MALR0 = (interface->macAddr.b[4] << 8) | interface->macAddr.b[5];
00184 
00185    //Disable all CAM entries
00186    ETHER.TSU_TEN = 0;
00187 
00188    //Maximum frame length that can be accepted
00189    ETHER.RFLR0 = 1518;
00190    //Automatic pause frame
00191    ETHER.APR0 = 0;
00192    //Manual pause frame
00193    ETHER.MPR0 = 0;
00194    //Automatic pause frame retransmit count
00195    ETHER.TPAUSER0 = 0;
00196 
00197    //Disable all EMAC interrupts
00198    ETHER.ECSIPR0 = 0;
00199 
00200    //Enable the desired EDMAC interrupts
00201    ETHER.EESIPR0 =  ETHER_EESIPR0_TWBIP | ETHER_EESIPR0_FRIP;
00202 
00203    //Register interrupt handler
00204    R_INTC_Regist_Int_Func(INTC_ID_ETHERI, rza1EthIrqHandler);
00205    //Configure interrupt priority
00206    R_INTC_Set_Priority(INTC_ID_ETHERI, RZA1_ETH_IRQ_PRIORITY);
00207 
00208    //Enable EDMAC transmission and reception
00209    ETHER.ECMR0 |= ETH_ECMR0_RE | ETH_ECMR0_TE;
00210 
00211    //Instruct the DMA to poll the receive descriptor list
00212    ETHER.EDRRR0 = ETHER_EDRRR0_RR;
00213 
00214    //Accept any packets from the upper layer
00215    osSetEvent(&interface->nicTxEvent);
00216 
00217    //Successful initialization
00218    return NO_ERROR;
00219 }
00220 
00221 
00222 //RSK RZ/A1H, Stream it! RZ, Hachiko or VK-RZ/A1H evaluation board?
00223 #if defined(USE_RSK_RZA1H) || defined(USE_STREAM_IT_RZ) || \
00224    defined(USE_HACHIKO) || defined(USE_VK_RZA1H)
00225 
00226 /**
00227  * @brief GPIO configuration
00228  * @param[in] interface Underlying network interface
00229  **/
00230 
00231 void rza1EthInitGpio(NetInterface *interface)
00232 {
00233 //RSK RZ/A1H or Hachiko evaluation board?
00234 #if defined(USE_RSK_RZA1H) || defined(USE_HACHIKO)
00235    //Configure ET_COL (P1_14)
00236    PORT1.PMCn.BIT.PMCn14 = 1;
00237    PORT1.PFCn.BIT.PFCn14 = 1;
00238    PORT1.PFCEn.BIT.PFCEn14 = 1;
00239    PORT1.PFCAEn.BIT.PFCAEn14 = 0;
00240    PORT1.PIPCn.BIT.PIPCn14 = 1;
00241 
00242    //Configure ET_TXCLK (P2_0)
00243    PORT2.PMCn.BIT.PMCn0 = 1;
00244    PORT2.PFCn.BIT.PFCn0 = 1;
00245    PORT2.PFCEn.BIT.PFCEn0 = 0;
00246    PORT2.PFCAEn.BIT.PFCAEn0 = 0;
00247    PORT2.PIPCn.BIT.PIPCn0 = 1;
00248 
00249    //Configure ET_TXER (P2_1)
00250    PORT2.PMCn.BIT.PMCn1 = 1;
00251    PORT2.PFCn.BIT.PFCn1 = 1;
00252    PORT2.PFCEn.BIT.PFCEn1 = 0;
00253    PORT2.PFCAEn.BIT.PFCAEn1 = 0;
00254    PORT2.PIPCn.BIT.PIPCn1 = 1;
00255 
00256    //Configure ET_TXEN (P2_2)
00257    PORT2.PMCn.BIT.PMCn2 = 1;
00258    PORT2.PFCn.BIT.PFCn2 = 1;
00259    PORT2.PFCEn.BIT.PFCEn2 = 0;
00260    PORT2.PFCAEn.BIT.PFCAEn2 = 0;
00261    PORT2.PIPCn.BIT.PIPCn2 = 1;
00262 
00263    //Configure ET_CRS (P2_3)
00264    PORT2.PMCn.BIT.PMCn3 = 1;
00265    PORT2.PFCn.BIT.PFCn3 = 1;
00266    PORT2.PFCEn.BIT.PFCEn3 = 0;
00267    PORT2.PFCAEn.BIT.PFCAEn3 = 0;
00268    PORT2.PIPCn.BIT.PIPCn3 = 1;
00269 
00270    //Configure ET_TXD0 (P2_4)
00271    PORT2.PMCn.BIT.PMCn4 = 1;
00272    PORT2.PFCn.BIT.PFCn4 = 1;
00273    PORT2.PFCEn.BIT.PFCEn4 = 0;
00274    PORT2.PFCAEn.BIT.PFCAEn4 = 0;
00275    PORT2.PIPCn.BIT.PIPCn4 = 1;
00276 
00277    //Configure ET_TXD1 (P2_5)
00278    PORT2.PMCn.BIT.PMCn5 = 1;
00279    PORT2.PFCn.BIT.PFCn5 = 1;
00280    PORT2.PFCEn.BIT.PFCEn5 = 0;
00281    PORT2.PFCAEn.BIT.PFCAEn5 = 0;
00282    PORT2.PIPCn.BIT.PIPCn5 = 1;
00283 
00284    //Configure ET_TXD2 (P2_6)
00285    PORT2.PMCn.BIT.PMCn6 = 1;
00286    PORT2.PFCn.BIT.PFCn6 = 1;
00287    PORT2.PFCEn.BIT.PFCEn6 = 0;
00288    PORT2.PFCAEn.BIT.PFCAEn6 = 0;
00289    PORT2.PIPCn.BIT.PIPCn6 = 1;
00290 
00291    //Configure ET_TXD3 (P2_7)
00292    PORT2.PMCn.BIT.PMCn7 = 1;
00293    PORT2.PFCn.BIT.PFCn7 = 1;
00294    PORT2.PFCEn.BIT.PFCEn7 = 0;
00295    PORT2.PFCAEn.BIT.PFCAEn7 = 0;
00296    PORT2.PIPCn.BIT.PIPCn7 = 1;
00297 
00298    //Configure ET_RXD0 (P2_8)
00299    PORT2.PMCn.BIT.PMCn8 = 1;
00300    PORT2.PFCn.BIT.PFCn8 = 1;
00301    PORT2.PFCEn.BIT.PFCEn8 = 0;
00302    PORT2.PFCAEn.BIT.PFCAEn8 = 0;
00303    PORT2.PIPCn.BIT.PIPCn8 = 1;
00304 
00305    //Configure ET_RXD1 (P2_9)
00306    PORT2.PMCn.BIT.PMCn9 = 1;
00307    PORT2.PFCn.BIT.PFCn9 = 1;
00308    PORT2.PFCEn.BIT.PFCEn9 = 0;
00309    PORT2.PFCAEn.BIT.PFCAEn9 = 0;
00310    PORT2.PIPCn.BIT.PIPCn9 = 1;
00311 
00312    //Configure ET_RXD2 (P2_10)
00313    PORT2.PMCn.BIT.PMCn10 = 1;
00314    PORT2.PFCn.BIT.PFCn10 = 1;
00315    PORT2.PFCEn.BIT.PFCEn10 = 0;
00316    PORT2.PFCAEn.BIT.PFCAEn10 = 0;
00317    PORT2.PIPCn.BIT.PIPCn10 = 1;
00318 
00319    //Configure ET_RXD3 (P2_11)
00320    PORT2.PMCn.BIT.PMCn11 = 1;
00321    PORT2.PFCn.BIT.PFCn11 = 1;
00322    PORT2.PFCEn.BIT.PFCEn11 = 0;
00323    PORT2.PFCAEn.BIT.PFCAEn11 = 0;
00324    PORT2.PIPCn.BIT.PIPCn11 = 1;
00325 
00326    //Configure ET_MDIO (P3_3)
00327    PORT3.PMCn.BIT.PMCn3 = 1;
00328    PORT3.PFCn.BIT.PFCn3 = 1;
00329    PORT3.PFCEn.BIT.PFCEn3 = 0;
00330    PORT3.PFCAEn.BIT.PFCAEn3 = 0;
00331    PORT3.PIPCn.BIT.PIPCn3 = 1;
00332 
00333    //Configure ET_RXCLK (P3_4)
00334    PORT3.PMCn.BIT.PMCn4 = 1;
00335    PORT3.PFCn.BIT.PFCn4 = 1;
00336    PORT3.PFCEn.BIT.PFCEn4 = 0;
00337    PORT3.PFCAEn.BIT.PFCAEn4 = 0;
00338    PORT3.PIPCn.BIT.PIPCn4 = 1;
00339 
00340    //Configure ET_RXER (P3_5)
00341    PORT3.PMCn.BIT.PMCn5 = 1;
00342    PORT3.PFCn.BIT.PFCn5 = 1;
00343    PORT3.PFCEn.BIT.PFCEn5 = 0;
00344    PORT3.PFCAEn.BIT.PFCAEn5 = 0;
00345    PORT3.PIPCn.BIT.PIPCn5 = 1;
00346 
00347    //Configure ET_RXDV (P3_6)
00348    PORT3.PMCn.BIT.PMCn6 = 1;
00349    PORT3.PFCn.BIT.PFCn6 = 1;
00350    PORT3.PFCEn.BIT.PFCEn6 = 0;
00351    PORT3.PFCAEn.BIT.PFCAEn6 = 0;
00352    PORT3.PIPCn.BIT.PIPCn6 = 1;
00353 
00354    //Configure ET_MDC (P5_9)
00355    PORT5.PMCn.BIT.PMCn9 = 1;
00356    PORT5.PFCn.BIT.PFCn9 = 1;
00357    PORT5.PFCEn.BIT.PFCEn9 = 0;
00358    PORT5.PFCAEn.BIT.PFCAEn9 = 0;
00359    PORT5.PIPCn.BIT.PIPCn9 = 1;
00360 
00361 //VK-RZ/A1H evaluation board?
00362 #elif defined(USE_VK_RZA1H)
00363    //Configure ET_COL (P1_14)
00364    PORT1.PMCn.BIT.PMCn14 = 1;
00365    PORT1.PFCn.BIT.PFCn14 = 1;
00366    PORT1.PFCEn.BIT.PFCEn14 = 1;
00367    PORT1.PFCAEn.BIT.PFCAEn14 = 0;
00368    PORT1.PIPCn.BIT.PIPCn14 = 1;
00369 
00370    //Configure ET_TXCLK (P2_0)
00371    PORT2.PMCn.BIT.PMCn0 = 1;
00372    PORT2.PFCn.BIT.PFCn0 = 1;
00373    PORT2.PFCEn.BIT.PFCEn0 = 0;
00374    PORT2.PFCAEn.BIT.PFCAEn0 = 0;
00375    PORT2.PIPCn.BIT.PIPCn0 = 1;
00376 
00377    //Configure ET_TXER (P2_1)
00378    PORT2.PMCn.BIT.PMCn1 = 1;
00379    PORT2.PFCn.BIT.PFCn1 = 1;
00380    PORT2.PFCEn.BIT.PFCEn1 = 0;
00381    PORT2.PFCAEn.BIT.PFCAEn1 = 0;
00382    PORT2.PIPCn.BIT.PIPCn1 = 1;
00383 
00384    //Configure ET_TXEN (P2_2)
00385    PORT2.PMCn.BIT.PMCn2 = 1;
00386    PORT2.PFCn.BIT.PFCn2 = 1;
00387    PORT2.PFCEn.BIT.PFCEn2 = 0;
00388    PORT2.PFCAEn.BIT.PFCAEn2 = 0;
00389    PORT2.PIPCn.BIT.PIPCn2 = 1;
00390 
00391    //Configure ET_CRS (P2_3)
00392    PORT2.PMCn.BIT.PMCn3 = 1;
00393    PORT2.PFCn.BIT.PFCn3 = 1;
00394    PORT2.PFCEn.BIT.PFCEn3 = 0;
00395    PORT2.PFCAEn.BIT.PFCAEn3 = 0;
00396    PORT2.PIPCn.BIT.PIPCn3 = 1;
00397 
00398    //Configure ET_TXD0 (P2_4)
00399    PORT2.PMCn.BIT.PMCn4 = 1;
00400    PORT2.PFCn.BIT.PFCn4 = 1;
00401    PORT2.PFCEn.BIT.PFCEn4 = 0;
00402    PORT2.PFCAEn.BIT.PFCAEn4 = 0;
00403    PORT2.PIPCn.BIT.PIPCn4 = 1;
00404 
00405    //Configure ET_TXD1 (P2_5)
00406    PORT2.PMCn.BIT.PMCn5 = 1;
00407    PORT2.PFCn.BIT.PFCn5 = 1;
00408    PORT2.PFCEn.BIT.PFCEn5 = 0;
00409    PORT2.PFCAEn.BIT.PFCAEn5 = 0;
00410    PORT2.PIPCn.BIT.PIPCn5 = 1;
00411 
00412    //Configure ET_TXD2 (P2_6)
00413    PORT2.PMCn.BIT.PMCn6 = 1;
00414    PORT2.PFCn.BIT.PFCn6 = 1;
00415    PORT2.PFCEn.BIT.PFCEn6 = 0;
00416    PORT2.PFCAEn.BIT.PFCAEn6 = 0;
00417    PORT2.PIPCn.BIT.PIPCn6 = 1;
00418 
00419    //Configure ET_TXD3 (P2_7)
00420    PORT2.PMCn.BIT.PMCn7 = 1;
00421    PORT2.PFCn.BIT.PFCn7 = 1;
00422    PORT2.PFCEn.BIT.PFCEn7 = 0;
00423    PORT2.PFCAEn.BIT.PFCAEn7 = 0;
00424    PORT2.PIPCn.BIT.PIPCn7 = 1;
00425 
00426    //Configure ET_RXD0 (P2_8)
00427    PORT2.PMCn.BIT.PMCn8 = 1;
00428    PORT2.PFCn.BIT.PFCn8 = 1;
00429    PORT2.PFCEn.BIT.PFCEn8 = 0;
00430    PORT2.PFCAEn.BIT.PFCAEn8 = 0;
00431    PORT2.PIPCn.BIT.PIPCn8 = 1;
00432 
00433    //Configure ET_RXD1 (P2_9)
00434    PORT2.PMCn.BIT.PMCn9 = 1;
00435    PORT2.PFCn.BIT.PFCn9 = 1;
00436    PORT2.PFCEn.BIT.PFCEn9 = 0;
00437    PORT2.PFCAEn.BIT.PFCAEn9 = 0;
00438    PORT2.PIPCn.BIT.PIPCn9 = 1;
00439 
00440    //Configure ET_RXD2 (P2_10)
00441    PORT2.PMCn.BIT.PMCn10 = 1;
00442    PORT2.PFCn.BIT.PFCn10 = 1;
00443    PORT2.PFCEn.BIT.PFCEn10 = 0;
00444    PORT2.PFCAEn.BIT.PFCAEn10 = 0;
00445    PORT2.PIPCn.BIT.PIPCn10 = 1;
00446 
00447    //Configure ET_RXD3 (P2_11)
00448    PORT2.PMCn.BIT.PMCn11 = 1;
00449    PORT2.PFCn.BIT.PFCn11 = 1;
00450    PORT2.PFCEn.BIT.PFCEn11 = 0;
00451    PORT2.PFCAEn.BIT.PFCAEn11 = 0;
00452    PORT2.PIPCn.BIT.PIPCn11 = 1;
00453 
00454    //Configure ET_MDIO (P3_3)
00455    PORT3.PMCn.BIT.PMCn3 = 1;
00456    PORT3.PFCn.BIT.PFCn3 = 1;
00457    PORT3.PFCEn.BIT.PFCEn3 = 0;
00458    PORT3.PFCAEn.BIT.PFCAEn3 = 0;
00459    PORT3.PIPCn.BIT.PIPCn3 = 1;
00460 
00461    //Configure ET_RXCLK (P3_4)
00462    PORT3.PMCn.BIT.PMCn4 = 1;
00463    PORT3.PFCn.BIT.PFCn4 = 1;
00464    PORT3.PFCEn.BIT.PFCEn4 = 0;
00465    PORT3.PFCAEn.BIT.PFCAEn4 = 0;
00466    PORT3.PIPCn.BIT.PIPCn4 = 1;
00467 
00468    //Configure ET_RXER (P3_5)
00469    PORT3.PMCn.BIT.PMCn5 = 1;
00470    PORT3.PFCn.BIT.PFCn5 = 1;
00471    PORT3.PFCEn.BIT.PFCEn5 = 0;
00472    PORT3.PFCAEn.BIT.PFCAEn5 = 0;
00473    PORT3.PIPCn.BIT.PIPCn5 = 1;
00474 
00475    //Configure ET_RXDV (P3_6)
00476    PORT3.PMCn.BIT.PMCn6 = 1;
00477    PORT3.PFCn.BIT.PFCn6 = 1;
00478    PORT3.PFCEn.BIT.PFCEn6 = 0;
00479    PORT3.PFCAEn.BIT.PFCAEn6 = 0;
00480    PORT3.PIPCn.BIT.PIPCn6 = 1;
00481 
00482    //Configure ET_MDC (P7_0)
00483    PORT7.PMCn.BIT.PMCn0 = 1;
00484    PORT7.PFCn.BIT.PFCn0 = 0;
00485    PORT7.PFCEn.BIT.PFCEn0 = 1;
00486    PORT7.PFCAEn.BIT.PFCAEn0 = 0;
00487    PORT7.PIPCn.BIT.PIPCn0 = 1;
00488 
00489 //Stream it! RZ evaluation board?
00490 #elif defined(USE_STREAM_IT_RZ)
00491    //Configure ET_TXD0 (P8_0)
00492    PORT8.PMCn.BIT.PMCn0 = 1;
00493    PORT8.PFCn.BIT.PFCn0 = 1;
00494    PORT8.PFCEn.BIT.PFCEn0 = 0;
00495    PORT8.PFCAEn.BIT.PFCAEn0 = 0;
00496    PORT8.PIPCn.BIT.PIPCn0 = 1;
00497 
00498    //Configure ET_TXD1 (P8_1)
00499    PORT8.PMCn.BIT.PMCn1 = 1;
00500    PORT8.PFCn.BIT.PFCn1 = 1;
00501    PORT8.PFCEn.BIT.PFCEn1 = 0;
00502    PORT8.PFCAEn.BIT.PFCAEn1 = 0;
00503    PORT8.PIPCn.BIT.PIPCn1 = 1;
00504 
00505    //Configure ET_TXD2 (P8_2)
00506    PORT8.PMCn.BIT.PMCn2 = 1;
00507    PORT8.PFCn.BIT.PFCn2 = 1;
00508    PORT8.PFCEn.BIT.PFCEn2 = 0;
00509    PORT8.PFCAEn.BIT.PFCAEn2 = 0;
00510    PORT8.PIPCn.BIT.PIPCn2 = 1;
00511 
00512    //Configure ET_TXD3 (P8_3)
00513    PORT8.PMCn.BIT.PMCn3 = 1;
00514    PORT8.PFCn.BIT.PFCn3 = 1;
00515    PORT8.PFCEn.BIT.PFCEn3 = 0;
00516    PORT8.PFCAEn.BIT.PFCAEn3 = 0;
00517    PORT8.PIPCn.BIT.PIPCn3 = 1;
00518 
00519    //Configure ET_TXCLK (P8_4)
00520    PORT8.PMCn.BIT.PMCn4 = 1;
00521    PORT8.PFCn.BIT.PFCn4 = 1;
00522    PORT8.PFCEn.BIT.PFCEn4 = 0;
00523    PORT8.PFCAEn.BIT.PFCAEn4 = 0;
00524    PORT8.PIPCn.BIT.PIPCn4 = 1;
00525 
00526    //Configure ET_TXER (P8_5)
00527    PORT8.PMCn.BIT.PMCn5 = 1;
00528    PORT8.PFCn.BIT.PFCn5 = 1;
00529    PORT8.PFCEn.BIT.PFCEn5 = 0;
00530    PORT8.PFCAEn.BIT.PFCAEn5 = 0;
00531    PORT8.PIPCn.BIT.PIPCn5 = 1;
00532 
00533    //Configure ET_TXEN (P8_6)
00534    PORT8.PMCn.BIT.PMCn6 = 1;
00535    PORT8.PFCn.BIT.PFCn6 = 1;
00536    PORT8.PFCEn.BIT.PFCEn6 = 0;
00537    PORT8.PFCAEn.BIT.PFCAEn6 = 0;
00538    PORT8.PIPCn.BIT.PIPCn6 = 1;
00539 
00540    //Configure ET_RXD0 (P8_7)
00541    PORT8.PMCn.BIT.PMCn7 = 1;
00542    PORT8.PFCn.BIT.PFCn7 = 1;
00543    PORT8.PFCEn.BIT.PFCEn7 = 0;
00544    PORT8.PFCAEn.BIT.PFCAEn7 = 0;
00545    PORT8.PIPCn.BIT.PIPCn7 = 1;
00546 
00547    //Configure ET_RXD1 (P8_8)
00548    PORT8.PMCn.BIT.PMCn8 = 1;
00549    PORT8.PFCn.BIT.PFCn8 = 1;
00550    PORT8.PFCEn.BIT.PFCEn8 = 0;
00551    PORT8.PFCAEn.BIT.PFCAEn8 = 0;
00552    PORT8.PIPCn.BIT.PIPCn8 = 1;
00553 
00554    //Configure ET_RXD2 (P8_9)
00555    PORT8.PMCn.BIT.PMCn9 = 1;
00556    PORT8.PFCn.BIT.PFCn9 = 1;
00557    PORT8.PFCEn.BIT.PFCEn9 = 0;
00558    PORT8.PFCAEn.BIT.PFCAEn9 = 0;
00559    PORT8.PIPCn.BIT.PIPCn9 = 1;
00560 
00561    //Configure ET_RXD3 (P8_10)
00562    PORT8.PMCn.BIT.PMCn10 = 1;
00563    PORT8.PFCn.BIT.PFCn10 = 1;
00564    PORT8.PFCEn.BIT.PFCEn10 = 0;
00565    PORT8.PFCAEn.BIT.PFCAEn10 = 0;
00566    PORT8.PIPCn.BIT.PIPCn10 = 1;
00567 
00568    //Configure ET_COL (P8_14)
00569    PORT8.PMCn.BIT.PMCn14 = 1;
00570    PORT8.PFCn.BIT.PFCn14 = 1;
00571    PORT8.PFCEn.BIT.PFCEn14 = 0;
00572    PORT8.PFCAEn.BIT.PFCAEn14 = 0;
00573    PORT8.PIPCn.BIT.PIPCn14 = 1;
00574 
00575    //Configure ET_CRS (P8_15)
00576    PORT8.PMCn.BIT.PMCn15 = 1;
00577    PORT8.PFCn.BIT.PFCn15 = 1;
00578    PORT8.PFCEn.BIT.PFCEn15 = 0;
00579    PORT8.PFCAEn.BIT.PFCAEn15 = 0;
00580    PORT8.PIPCn.BIT.PIPCn15 = 1;
00581 
00582    //Configure ET_MDC (P9_0)
00583    PORT9.PMCn.BIT.PMCn0 = 1;
00584    PORT9.PFCn.BIT.PFCn0 = 1;
00585    PORT9.PFCEn.BIT.PFCEn0 = 0;
00586    PORT9.PFCAEn.BIT.PFCAEn0 = 0;
00587    PORT9.PIPCn.BIT.PIPCn0 = 1;
00588 
00589    //Configure ET_MDIO (P9_1)
00590    PORT9.PMCn.BIT.PMCn1 = 1;
00591    PORT9.PFCn.BIT.PFCn1 = 1;
00592    PORT9.PFCEn.BIT.PFCEn1 = 0;
00593    PORT9.PFCAEn.BIT.PFCAEn1 = 0;
00594    PORT9.PIPCn.BIT.PIPCn1 = 1;
00595 
00596    //Configure ET_RXCLK (P9_2)
00597    PORT9.PMCn.BIT.PMCn2 = 1;
00598    PORT9.PFCn.BIT.PFCn2 = 1;
00599    PORT9.PFCEn.BIT.PFCEn2 = 0;
00600    PORT9.PFCAEn.BIT.PFCAEn2 = 0;
00601    PORT9.PIPCn.BIT.PIPCn2 = 1;
00602 
00603    //Configure ET_RXER (P9_3)
00604    PORT9.PMCn.BIT.PMCn3 = 1;
00605    PORT9.PFCn.BIT.PFCn3 = 1;
00606    PORT9.PFCEn.BIT.PFCEn3 = 0;
00607    PORT9.PFCAEn.BIT.PFCAEn3 = 0;
00608    PORT9.PIPCn.BIT.PIPCn3 = 1;
00609 
00610    //Configure ET_RXDV (P9_4)
00611    PORT9.PMCn.BIT.PMCn4 = 1;
00612    PORT9.PFCn.BIT.PFCn4 = 1;
00613    PORT9.PFCEn.BIT.PFCEn4 = 0;
00614    PORT9.PFCAEn.BIT.PFCAEn4 = 0;
00615    PORT9.PIPCn.BIT.PIPCn4 = 1;
00616 
00617    //Configure PHY_RST (P2_7)
00618    PORT2.PMCn.BIT.PMCn7 = 0;
00619    PORT2.PIPCn.BIT.PIPCn7 = 0;
00620    PORT2.PMn.BIT.PMn7 = 0;
00621 
00622    //Reset the PHY transceiver
00623    PORT2.Pn.BIT.Pn7 = 0;
00624    sleep(10);
00625 
00626    //Take the PHY transceiver out of reset
00627    PORT2.Pn.BIT.Pn7 = 1;
00628    sleep(10);
00629 #endif
00630 }
00631 
00632 #endif
00633 
00634 
00635 /**
00636  * @brief Initialize DMA descriptor lists
00637  * @param[in] interface Underlying network interface
00638  **/
00639 
00640 void rza1EthInitDmaDesc(NetInterface *interface)
00641 {
00642    uint_t i;
00643 
00644    //Initialize TX descriptors
00645    for(i = 0; i < RZA1_ETH_TX_BUFFER_COUNT; i++)
00646    {
00647       //The descriptor is initially owned by the application
00648       txDmaDesc[i].td0 = 0;
00649       //Transmit buffer length
00650       txDmaDesc[i].td1 = 0;
00651       //Transmit buffer address
00652       txDmaDesc[i].td2 = (uint32_t) txBuffer[i];
00653       //Clear padding field
00654       txDmaDesc[i].padding = 0;
00655    }
00656 
00657    //Mark the last descriptor entry with the TDLE flag
00658    txDmaDesc[i - 1].td0 |= ETHER_TD0_TDLE;
00659    //Initialize TX descriptor index
00660    txIndex = 0;
00661 
00662    //Initialize RX descriptors
00663    for(i = 0; i < RZA1_ETH_RX_BUFFER_COUNT; i++)
00664    {
00665       //The descriptor is initially owned by the DMA
00666       rxDmaDesc[i].rd0 = ETHER_RD0_RACT;
00667       //Receive buffer length
00668       rxDmaDesc[i].rd1 = (RZA1_ETH_RX_BUFFER_SIZE << 16) & ETHER_RD1_RBL;
00669       //Receive buffer address
00670       rxDmaDesc[i].rd2 = (uint32_t) rxBuffer[i];
00671       //Clear padding field
00672       rxDmaDesc[i].padding = 0;
00673    }
00674 
00675    //Mark the last descriptor entry with the RDLE flag
00676    rxDmaDesc[i - 1].rd0 |= ETHER_RD0_RDLE;
00677    //Initialize RX descriptor index
00678    rxIndex = 0;
00679 
00680    //Address of the first TX descriptor
00681    ETHER.TDLAR0 = (uint32_t) &txDmaDesc[0];
00682    ETHER.TDFAR0 = (uint32_t) &txDmaDesc[0];
00683    //Address of the last TX descriptor
00684    ETHER.TDFXR0 = (uint32_t) &txDmaDesc[RZA1_ETH_TX_BUFFER_COUNT - 1];
00685    //Set TDLF flag
00686    ETHER.TDFFR0 = ETHER_TDFFR_TDLF;
00687 
00688    //Address of the first RX descriptor
00689    ETHER.RDLAR0 = (uint32_t) &rxDmaDesc[0];
00690    ETHER.RDFAR0 = (uint32_t) &rxDmaDesc[0];
00691    //Address of the last RX descriptor
00692    ETHER.RDFXR0 = (uint32_t) &rxDmaDesc[RZA1_ETH_RX_BUFFER_COUNT - 1];
00693    //Set RDLF flag
00694    ETHER.RDFFR0 = ETHER_RDFFR0_RDLF;
00695 }
00696 
00697 
00698 /**
00699  * @brief RZ/A1 Ethernet MAC timer handler
00700  *
00701  * This routine is periodically called by the TCP/IP stack to
00702  * handle periodic operations such as polling the link state
00703  *
00704  * @param[in] interface Underlying network interface
00705  **/
00706 
00707 void rza1EthTick(NetInterface *interface)
00708 {
00709    //Handle periodic operations
00710    interface->phyDriver->tick(interface);
00711 }
00712 
00713 
00714 /**
00715  * @brief Enable interrupts
00716  * @param[in] interface Underlying network interface
00717  **/
00718 
00719 void rza1EthEnableIrq(NetInterface *interface)
00720 {
00721    //Enable Ethernet MAC interrupts
00722    R_INTC_Enable(INTC_ID_ETHERI);
00723    //Enable Ethernet PHY interrupts
00724    interface->phyDriver->enableIrq(interface);
00725 }
00726 
00727 
00728 /**
00729  * @brief Disable interrupts
00730  * @param[in] interface Underlying network interface
00731  **/
00732 
00733 void rza1EthDisableIrq(NetInterface *interface)
00734 {
00735    //Disable Ethernet MAC interrupts
00736    R_INTC_Disable(INTC_ID_ETHERI);
00737    //Disable Ethernet PHY interrupts
00738    interface->phyDriver->disableIrq(interface);
00739 }
00740 
00741 
00742 /**
00743  * @brief RZ/A1 Ethernet MAC interrupt service routine
00744  * @param[in] intSense Unused parameter
00745  **/
00746 
00747 void rza1EthIrqHandler(uint32_t intSense)
00748 {
00749    bool_t flag;
00750    uint32_t status;
00751 
00752    //Enter interrupt service routine
00753    osEnterIsr();
00754 
00755    //This flag will be set if a higher priority task must be woken
00756    flag = FALSE;
00757 
00758    //Read interrupt status register
00759    status = ETHER.EESR0;
00760 
00761    //A packet has been transmitted?
00762    if(status & ETHER_EESR0_TWB)
00763    {
00764       //Clear TWB interrupt flag
00765       ETHER.EESR0 = ETHER_EESR0_TWB;
00766 
00767       //Check whether the TX buffer is available for writing
00768       if(!(txDmaDesc[txIndex].td0 & ETHER_TD0_TACT))
00769       {
00770          //Notify the TCP/IP stack that the transmitter is ready to send
00771          flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
00772       }
00773    }
00774 
00775    //A packet has been received?
00776    if(status & ETHER_EESR0_FR)
00777    {
00778       //Disable FR interrupts
00779       ETHER.EESIPR0 &= ~ETHER_EESIPR0_FRIP;
00780 
00781       //Set event flag
00782       nicDriverInterface->nicEvent = TRUE;
00783       //Notify the TCP/IP stack of the event
00784       flag |= osSetEventFromIsr(&netEvent);
00785    }
00786 
00787    //Leave interrupt service routine
00788    osExitIsr(flag);
00789 }
00790 
00791 
00792 /**
00793  * @brief RZ/A1 Ethernet MAC event handler
00794  * @param[in] interface Underlying network interface
00795  **/
00796 
00797 void rza1EthEventHandler(NetInterface *interface)
00798 {
00799    error_t error;
00800 
00801    //Packet received?
00802    if(ETHER.EESR0 & ETHER_EESR0_FR)
00803    {
00804       //Clear FR interrupt flag
00805       ETHER.EESR0 = ETHER_EESR0_FR;
00806 
00807       //Process all pending packets
00808       do
00809       {
00810          //Read incoming packet
00811          error = rza1EthReceivePacket(interface);
00812 
00813          //No more data in the receive buffer?
00814       } while(error != ERROR_BUFFER_EMPTY);
00815    }
00816 
00817    //Re-enable EDMAC interrupts
00818    ETHER.EESIPR0 =  ETHER_EESIPR0_TWBIP | ETHER_EESIPR0_FRIP;
00819 }
00820 
00821 
00822 /**
00823  * @brief Send a packet
00824  * @param[in] interface Underlying network interface
00825  * @param[in] buffer Multi-part buffer containing the data to send
00826  * @param[in] offset Offset to the first data byte
00827  * @return Error code
00828  **/
00829 
00830 error_t rza1EthSendPacket(NetInterface *interface,
00831    const NetBuffer *buffer, size_t offset)
00832 {
00833    //Retrieve the length of the packet
00834    size_t length = netBufferGetLength(buffer) - offset;
00835 
00836    //Check the frame length
00837    if(length > RZA1_ETH_TX_BUFFER_SIZE)
00838    {
00839       //The transmitter can accept another packet
00840       osSetEvent(&interface->nicTxEvent);
00841       //Report an error
00842       return ERROR_INVALID_LENGTH;
00843    }
00844 
00845    //Make sure the current buffer is available for writing
00846    if(txDmaDesc[txIndex].td0 & ETHER_TD0_TACT)
00847       return ERROR_FAILURE;
00848 
00849    //Copy user data to the transmit buffer
00850    netBufferRead(txBuffer[txIndex], buffer, offset, length);
00851 
00852    //Write the number of bytes to send
00853    txDmaDesc[txIndex].td1 = (length << 16) & ETHER_TD1_TDL;
00854 
00855    //Check current index
00856    if(txIndex < (RZA1_ETH_TX_BUFFER_COUNT - 1))
00857    {
00858       //Give the ownership of the descriptor to the DMA engine
00859       txDmaDesc[txIndex].td0 = ETHER_TD0_TACT | ETHER_TD0_TFP_SOF |
00860          ETHER_TD0_TFP_EOF | ETHER_TD0_TWBI;
00861 
00862       //Point to the next descriptor
00863       txIndex++;
00864    }
00865    else
00866    {
00867       //Give the ownership of the descriptor to the DMA engine
00868       txDmaDesc[txIndex].td0 = ETHER_TD0_TACT | ETHER_TD0_TDLE |
00869          ETHER_TD0_TFP_SOF | ETHER_TD0_TFP_EOF | ETHER_TD0_TWBI;
00870 
00871       //Wrap around
00872       txIndex = 0;
00873    }
00874 
00875    //Instruct the DMA to poll the transmit descriptor list
00876    ETHER.EDTRR0 = ETHER_EDTRR0_TR;
00877 
00878    //Check whether the next buffer is available for writing
00879    if(!(txDmaDesc[txIndex].td0 & ETHER_TD0_TACT))
00880    {
00881       //The transmitter can accept another packet
00882       osSetEvent(&interface->nicTxEvent);
00883    }
00884 
00885    //Successful write operation
00886    return NO_ERROR;
00887 }
00888 
00889 
00890 /**
00891  * @brief Receive a packet
00892  * @param[in] interface Underlying network interface
00893  * @return Error code
00894  **/
00895 error_t rza1EthReceivePacket(NetInterface *interface)
00896 {
00897    static uint8_t temp[RZA1_ETH_RX_BUFFER_SIZE];
00898    error_t error;
00899    size_t n;
00900 
00901    //The current buffer is available for reading?
00902    if(!(rxDmaDesc[rxIndex].rd0 & ETHER_RD0_RACT))
00903    {
00904       //SOF and EOF flags should be set
00905       if((rxDmaDesc[rxIndex].rd0 & ETHER_RD0_RFP_SOF) &&
00906          (rxDmaDesc[rxIndex].rd0 & ETHER_RD0_RFP_EOF))
00907       {
00908          //Make sure no error occurred
00909          if(!(rxDmaDesc[rxIndex].rd0 & (ETHER_RD0_RFS_MASK & ~ETHER_RD0_RFS_RMAF)))
00910          {
00911             //Retrieve the length of the frame
00912             n = rxDmaDesc[rxIndex].rd1 & ETHER_RD1_RDL;
00913             //Limit the number of data to read
00914             n = MIN(n, RZA1_ETH_RX_BUFFER_SIZE);
00915 
00916             //Copy data from the receive buffer
00917             memcpy(temp, rxBuffer[rxIndex], n);
00918 
00919             //Pass the packet to the upper layer
00920             nicProcessPacket(interface, temp, n);
00921 
00922             //Valid packet received
00923             error = NO_ERROR;
00924          }
00925          else
00926          {
00927             //The received packet contains an error
00928             error = ERROR_INVALID_PACKET;
00929          }
00930       }
00931       else
00932       {
00933          //The packet is not valid
00934          error = ERROR_INVALID_PACKET;
00935       }
00936 
00937       //Check current index
00938       if(rxIndex < (RZA1_ETH_RX_BUFFER_COUNT - 1))
00939       {
00940          //Give the ownership of the descriptor back to the DMA
00941          rxDmaDesc[rxIndex].rd0 = ETHER_RD0_RACT;
00942          //Point to the next descriptor
00943          rxIndex++;
00944       }
00945       else
00946       {
00947          //Give the ownership of the descriptor back to the DMA
00948          rxDmaDesc[rxIndex].rd0 = ETHER_RD0_RACT | ETHER_RD0_RDLE;
00949          //Wrap around
00950          rxIndex = 0;
00951       }
00952 
00953       //Instruct the DMA to poll the receive descriptor list
00954       ETHER.EDRRR0 = ETHER_EDRRR0_RR;
00955    }
00956    else
00957    {
00958       //No more data in the receive buffer
00959       error = ERROR_BUFFER_EMPTY;
00960    }
00961 
00962    //Return status code
00963    return error;
00964 }
00965 
00966 
00967 /**
00968  * @brief Configure multicast MAC address filtering
00969  * @param[in] interface Underlying network interface
00970  * @return Error code
00971  **/
00972 
00973 error_t rza1EthSetMulticastFilter(NetInterface *interface)
00974 {
00975    uint_t i;
00976    volatile uint32_t *addrHigh;
00977    volatile uint32_t *addrLow;
00978    MacFilterEntry *entry;
00979 
00980    //Debug message
00981    TRACE_DEBUG("Updating RZ/A1 multicast filter...\r\n");
00982 
00983    //The MAC filter table contains the multicast MAC addresses
00984    //to accept when receiving an Ethernet frame
00985    for(i = 0; i < MAC_MULTICAST_FILTER_SIZE && i < 32; i++)
00986    {
00987       //Point to the current entry
00988       entry = &interface->macMulticastFilter[i];
00989 
00990       //Valid entry?
00991       if(entry->refCount > 0)
00992       {
00993          //Debug message
00994          TRACE_DEBUG("  %s\r\n", macAddrToString(&entry->addr, NULL));
00995 
00996          //Point to the CAM entry registers
00997          addrHigh = &ETHER.TSU_ADRH0 + 2 * i;
00998          addrLow = &ETHER.TSU_ADRL0 + 2 * i;
00999 
01000          //The contents of the CAM entry table registers cannot be
01001          //modified while the ADSBSY flag is set
01002          while(ETHER.TSU_ADSBSY & ETHER_TSU_ADSBSY_ADSBSY);
01003 
01004          //Set the upper 32 bits of the MAC address
01005          *addrHigh = (entry->addr.b[0] << 24) | (entry->addr.b[1] << 16) |
01006             (entry->addr.b[2] << 8) |entry->addr.b[3];
01007 
01008          //Wait for the ADSBSY flag to be cleared
01009          while(ETHER.TSU_ADSBSY & ETHER_TSU_ADSBSY_ADSBSY);
01010 
01011          //Set the lower 16 bits of the MAC address
01012          *addrLow = (entry->addr.b[4] << 8) | entry->addr.b[5];
01013 
01014          //Enable the CAM entry
01015          ETHER.TSU_TEN |= 1 << (31 - i);
01016       }
01017       else
01018       {
01019          //Disable the CAM entry
01020          ETHER.TSU_TEN &= ~(1 << (31 - i));
01021       }
01022    }
01023 
01024    //Successful processing
01025    return NO_ERROR;
01026 }
01027 
01028 
01029 /**
01030  * @brief Adjust MAC configuration parameters for proper operation
01031  * @param[in] interface Underlying network interface
01032  * @return Error code
01033  **/
01034 
01035 error_t rza1EthUpdateMacConfig(NetInterface *interface)
01036 {
01037    //Half-duplex or full-duplex mode?
01038    if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
01039       ETHER.ECMR0 |= ETH_ECMR0_DM;
01040    else
01041       ETHER.ECMR0 &= ~ETH_ECMR0_DM;
01042 
01043    //Successful processing
01044    return NO_ERROR;
01045 }
01046 
01047 
01048 /**
01049  * @brief Write PHY register
01050  * @param[in] phyAddr PHY address
01051  * @param[in] regAddr Register address
01052  * @param[in] data Register value
01053  **/
01054 
01055 void rza1EthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
01056 {
01057    //Synchronization pattern
01058    rza1EthWriteSmi(SMI_SYNC, 32);
01059    //Start of frame
01060    rza1EthWriteSmi(SMI_START, 2);
01061    //Set up a write operation
01062    rza1EthWriteSmi(SMI_WRITE, 2);
01063    //Write PHY address
01064    rza1EthWriteSmi(phyAddr, 5);
01065    //Write register address
01066    rza1EthWriteSmi(regAddr, 5);
01067    //Turnaround
01068    rza1EthWriteSmi(SMI_TA, 2);
01069    //Write register value
01070    rza1EthWriteSmi(data, 16);
01071    //Release MDIO
01072    rza1EthReadSmi(1);
01073 }
01074 
01075 
01076 /**
01077  * @brief Read PHY register
01078  * @param[in] phyAddr PHY address
01079  * @param[in] regAddr Register address
01080  * @return Register value
01081  **/
01082 
01083 uint16_t rza1EthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
01084 {
01085    uint16_t data;
01086 
01087    //Synchronization pattern
01088    rza1EthWriteSmi(SMI_SYNC, 32);
01089    //Start of frame
01090    rza1EthWriteSmi(SMI_START, 2);
01091    //Set up a read operation
01092    rza1EthWriteSmi(SMI_READ, 2);
01093    //Write PHY address
01094    rza1EthWriteSmi(phyAddr, 5);
01095    //Write register address
01096    rza1EthWriteSmi(regAddr, 5);
01097    //Turnaround to avoid contention
01098    rza1EthReadSmi(1);
01099    //Read register value
01100    data = rza1EthReadSmi(16);
01101    //Force the PHY to release the MDIO pin
01102    rza1EthReadSmi(1);
01103 
01104    //Return PHY register contents
01105    return data;
01106 }
01107 
01108 
01109 /**
01110  * @brief SMI write operation
01111  * @param[in] data Raw data to be written
01112  * @param[in] length Number of bits to be written
01113  **/
01114 
01115 void rza1EthWriteSmi(uint32_t data, uint_t length)
01116 {
01117    //Skip the most significant bits since they are meaningless
01118    data <<= 32 - length;
01119 
01120    //Configure MDIO as an output
01121    ETHER.PIR0 |= ETHER_PIR0_MMD;
01122 
01123    //Write the specified number of bits
01124    while(length--)
01125    {
01126       //Write MDIO
01127       if(data & 0x80000000)
01128          ETHER.PIR0 |= ETHER_PIR0_MDO;
01129       else
01130          ETHER.PIR0 &= ~ETHER_PIR0_MDO;
01131 
01132       //Assert MDC
01133       usleep(1);
01134       ETHER.PIR0 |= ETHER_PIR0_MDC;
01135       //Deassert MDC
01136       usleep(1);
01137       ETHER.PIR0 &= ~ETHER_PIR0_MDC;
01138 
01139       //Rotate data
01140       data <<= 1;
01141    }
01142 }
01143 
01144 
01145 /**
01146  * @brief SMI read operation
01147  * @param[in] length Number of bits to be read
01148  * @return Data resulting from the MDIO read operation
01149  **/
01150 
01151 uint32_t rza1EthReadSmi(uint_t length)
01152 {
01153    uint32_t data = 0;
01154 
01155    //Configure MDIO as an input
01156    ETHER.PIR0 &= ~ETHER_PIR0_MMD;
01157 
01158    //Read the specified number of bits
01159    while(length--)
01160    {
01161       //Rotate data
01162       data <<= 1;
01163 
01164       //Assert MDC
01165       ETHER.PIR0 |= ETHER_PIR0_MDC;
01166       usleep(1);
01167       //Deassert MDC
01168       ETHER.PIR0 &= ~ETHER_PIR0_MDC;
01169       usleep(1);
01170 
01171       //Check MDIO state
01172       if(ETHER.PIR0 & ETHER_PIR0_MDI)
01173          data |= 0x00000001;
01174    }
01175 
01176    //Return the received data
01177    return data;
01178 }
01179