Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
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 = ÐER.TSU_ADRH0 + 2 * i; 00998 addrLow = ÐER.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
Generated on Tue Jul 12 2022 17:10:15 by
