Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
rx63n_eth.c
Go to the documentation of this file.
00001 /** 00002 * @file rx63n_eth.c 00003 * @brief Renesas RX63N 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 <iorx63n.h> 00034 #include <intrinsics.h> 00035 #include "core/net.h" 00036 #include "drivers/rx63n_eth.h" 00037 #include "debug.h" 00038 00039 //Underlying network interface 00040 static NetInterface *nicDriverInterface; 00041 00042 //IAR EWRX compiler? 00043 #if defined(__ICCRX__) 00044 00045 //Transmit buffer 00046 #pragma data_alignment = 32 00047 static uint8_t txBuffer[RX63N_ETH_TX_BUFFER_COUNT][RX63N_ETH_TX_BUFFER_SIZE]; 00048 //Receive buffer 00049 #pragma data_alignment = 32 00050 static uint8_t rxBuffer[RX63N_ETH_RX_BUFFER_COUNT][RX63N_ETH_RX_BUFFER_SIZE]; 00051 //Transmit DMA descriptors 00052 #pragma data_alignment = 32 00053 static Rx63nTxDmaDesc txDmaDesc[RX63N_ETH_TX_BUFFER_COUNT]; 00054 //Receive DMA descriptors 00055 #pragma data_alignment = 32 00056 static Rx63nRxDmaDesc rxDmaDesc[RX63N_ETH_RX_BUFFER_COUNT]; 00057 00058 //GCC compiler? 00059 #else 00060 00061 //Transmit buffer 00062 static uint8_t txBuffer[RX63N_ETH_TX_BUFFER_COUNT][RX63N_ETH_TX_BUFFER_SIZE] 00063 __attribute__((aligned(32))); 00064 //Receive buffer 00065 static uint8_t rxBuffer[RX63N_ETH_RX_BUFFER_COUNT][RX63N_ETH_RX_BUFFER_SIZE] 00066 __attribute__((aligned(32))); 00067 //Transmit DMA descriptors 00068 static Rx63nTxDmaDesc txDmaDesc[RX63N_ETH_TX_BUFFER_COUNT] 00069 __attribute__((aligned(32))); 00070 //Receive DMA descriptors 00071 static Rx63nRxDmaDesc rxDmaDesc[RX63N_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 RX63N Ethernet MAC driver 00084 **/ 00085 00086 const NicDriver rx63nEthDriver = 00087 { 00088 NIC_TYPE_ETHERNET, 00089 ETH_MTU, 00090 rx63nEthInit, 00091 rx63nEthTick, 00092 rx63nEthEnableIrq, 00093 rx63nEthDisableIrq, 00094 rx63nEthEventHandler, 00095 rx63nEthSendPacket, 00096 rx63nEthSetMulticastFilter, 00097 rx63nEthUpdateMacConfig, 00098 rx63nEthWritePhyReg, 00099 rx63nEthReadPhyReg, 00100 TRUE, 00101 TRUE, 00102 TRUE, 00103 TRUE 00104 }; 00105 00106 00107 /** 00108 * @brief RX63N Ethernet MAC initialization 00109 * @param[in] interface Underlying network interface 00110 * @return Error code 00111 **/ 00112 00113 error_t rx63nEthInit(NetInterface *interface) 00114 { 00115 error_t error; 00116 00117 //Debug message 00118 TRACE_INFO("Initializing RX63N Ethernet MAC...\r\n"); 00119 00120 //Save underlying network interface 00121 nicDriverInterface = interface; 00122 00123 //Disable protection 00124 SYSTEM.PRCR.WORD = 0xA50B; 00125 //Cancel EDMAC module stop state 00126 MSTP(EDMAC) = 0; 00127 //Enable protection 00128 SYSTEM.PRCR.WORD = 0xA500; 00129 00130 //GPIO configuration 00131 rx63nEthInitGpio(interface); 00132 00133 //Reset EDMAC module 00134 EDMAC.EDMR.BIT.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 rx63nEthInitDmaDesc(interface); 00145 00146 //Maximum frame length that can be accepted 00147 ETHERC.RFLR.LONG = 1518; 00148 //Set default inter packet gap (96-bit time) 00149 ETHERC.IPGR.LONG = 0x14; 00150 00151 //Set the upper 32 bits of the MAC address 00152 ETHERC.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 ETHERC.MALR.BIT.MA = (interface->macAddr.b[4] << 8) | interface->macAddr.b[5]; 00157 00158 //Set descriptor length (16 bytes) 00159 EDMAC.EDMR.BIT.DL = 0; 00160 //Select little endian mode 00161 EDMAC.EDMR.BIT.DE = 1; 00162 //Use store and forward mode 00163 EDMAC.TFTR.BIT.TFT = 0; 00164 00165 //Set transmit FIFO size (2048 bytes) 00166 EDMAC.FDR.BIT.TFD = 7; 00167 //Set receive FIFO size (2048 bytes) 00168 EDMAC.FDR.BIT.RFD = 7; 00169 00170 //Enable continuous reception of multiple frames 00171 EDMAC.RMCR.BIT.RNR = 1; 00172 00173 //Accept transmit interrupt notifications 00174 EDMAC.TRIMD.BIT.TIM = 0; 00175 EDMAC.TRIMD.BIT.TIS = 1; 00176 00177 //Disable all EDMAC interrupts 00178 EDMAC.EESIPR.LONG = 0; 00179 //Enable only the desired EDMAC interrupts 00180 EDMAC.EESIPR.BIT.TWBIP = 1; 00181 EDMAC.EESIPR.BIT.FRIP = 1; 00182 00183 //Configure EDMAC interrupt priority 00184 IPR(ETHER, EINT) = RX63N_ETH_IRQ_PRIORITY; 00185 00186 //Enable transmission and reception 00187 ETHERC.ECMR.BIT.TE = 1; 00188 ETHERC.ECMR.BIT.RE = 1; 00189 00190 //Instruct the DMA to poll the receive descriptor list 00191 EDMAC.EDRRR.BIT.RR = 1; 00192 00193 //Accept any packets from the upper layer 00194 osSetEvent(&interface->nicTxEvent); 00195 00196 //Successful initialization 00197 return NO_ERROR; 00198 } 00199 00200 00201 //RX63N Demonstration Kit? 00202 #if defined(USE_RDK_RX63N) 00203 00204 /** 00205 * @brief GPIO configuration 00206 * @param[in] interface Underlying network interface 00207 **/ 00208 00209 void rx63nEthInitGpio(NetInterface *interface) 00210 { 00211 //Unlock MPC registers 00212 MPC.PWPR.BIT.B0WI = 0; 00213 MPC.PWPR.BIT.PFSWE = 1; 00214 00215 //Select RMII interface mode 00216 MPC.PFENET.BIT.PHYMODE = 0; 00217 00218 //Configure ET_MDIO (PA3) 00219 PORTA.PMR.BIT.B3 = 1; 00220 MPC.PA3PFS.BYTE = 0x11; 00221 00222 //Configure ET_MDC (PA4) 00223 PORTA.PMR.BIT.B4 = 1; 00224 MPC.PA4PFS.BYTE = 0x11; 00225 00226 //Configure ET_LINKSTA (PA5) 00227 PORTA.PMR.BIT.B5 = 1; 00228 MPC.PA5PFS.BYTE = 0x11; 00229 00230 //Configure RMII_RXD1 (PB0) 00231 PORTB.PMR.BIT.B0 = 1; 00232 MPC.PB0PFS.BYTE = 0x12; 00233 00234 //Configure RMII_RXD0 (PB1) 00235 PORTB.PMR.BIT.B1 = 1; 00236 MPC.PB1PFS.BYTE = 0x12; 00237 00238 //Configure REF50CK (PB2) 00239 PORTB.PMR.BIT.B2 = 1; 00240 MPC.PB2PFS.BYTE = 0x12; 00241 00242 //Configure RMII_RX_ER (PB3) 00243 PORTB.PMR.BIT.B3 = 1; 00244 MPC.PB3PFS.BYTE = 0x12; 00245 00246 //Configure RMII_TXD_EN (PB4) 00247 PORTB.PMR.BIT.B4 = 1; 00248 MPC.PB4PFS.BYTE = 0x12; 00249 00250 //Configure RMII_TXD0 (PB5) 00251 PORTB.PMR.BIT.B5 = 1; 00252 MPC.PB5PFS.BYTE = 0x12; 00253 00254 //Configure RMII_TXD1 (PB6) 00255 PORTB.PMR.BIT.B6 = 1; 00256 MPC.PB6PFS.BYTE = 0x12; 00257 00258 //Configure RMII_CRS_DV (PB7) 00259 PORTB.PMR.BIT.B7 = 1; 00260 MPC.PB7PFS.BYTE = 0x12; 00261 00262 //Lock MPC registers 00263 MPC.PWPR.BIT.PFSWE = 0; 00264 MPC.PWPR.BIT.B0WI = 0; 00265 } 00266 00267 #endif 00268 00269 00270 /** 00271 * @brief Initialize DMA descriptor lists 00272 * @param[in] interface Underlying network interface 00273 **/ 00274 00275 void rx63nEthInitDmaDesc(NetInterface *interface) 00276 { 00277 uint_t i; 00278 00279 //Initialize TX descriptors 00280 for(i = 0; i < RX63N_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 < RX63N_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 = (RX63N_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 EDMAC.TDLAR = txDmaDesc; 00317 //Start address of the RX descriptor list 00318 EDMAC.RDLAR = rxDmaDesc; 00319 } 00320 00321 00322 /** 00323 * @brief RX63N 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 rx63nEthTick(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 rx63nEthEnableIrq(NetInterface *interface) 00344 { 00345 //Enable Ethernet MAC interrupts 00346 IEN(ETHER, EINT) = 1; 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 rx63nEthDisableIrq(NetInterface *interface) 00358 { 00359 //Disable Ethernet MAC interrupts 00360 IEN(ETHER, EINT) = 0; 00361 //Disable Ethernet PHY interrupts 00362 interface->phyDriver->disableIrq(interface); 00363 } 00364 00365 00366 /** 00367 * @brief RX63N Ethernet MAC interrupt service routine 00368 **/ 00369 00370 #pragma vector = VECT_ETHER_EINT 00371 __interrupt void rx63nEthIrqHandler(void) 00372 { 00373 bool_t flag; 00374 uint32_t status; 00375 00376 //Allow nested interrupts 00377 __enable_interrupt(); 00378 00379 //This flag will be set if a higher priority task must be woken 00380 flag = FALSE; 00381 00382 //Read interrupt status register 00383 status = EDMAC.EESR.LONG; 00384 00385 //A packet has been transmitted? 00386 if(status & EDMAC_EESR_TWB) 00387 { 00388 //Clear TWB interrupt flag 00389 EDMAC.EESR.LONG = EDMAC_EESR_TWB; 00390 00391 //Check whether the TX buffer is available for writing 00392 if(!(txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT)) 00393 { 00394 //Notify the TCP/IP stack that the transmitter is ready to send 00395 flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent); 00396 } 00397 } 00398 00399 //A packet has been received? 00400 if(status & EDMAC_EESR_FR) 00401 { 00402 //Disable FR interrupts 00403 EDMAC.EESIPR.BIT.FRIP = 0; 00404 00405 //Set event flag 00406 nicDriverInterface->nicEvent = TRUE; 00407 //Notify the TCP/IP stack of the event 00408 flag |= osSetEventFromIsr(&netEvent); 00409 } 00410 00411 //Leave interrupt service routine 00412 osExitIsr(flag); 00413 } 00414 00415 00416 /** 00417 * @brief RX63N Ethernet MAC event handler 00418 * @param[in] interface Underlying network interface 00419 **/ 00420 00421 void rx63nEthEventHandler(NetInterface *interface) 00422 { 00423 error_t error; 00424 00425 //Packet received? 00426 if(EDMAC.EESR.LONG & EDMAC_EESR_FR) 00427 { 00428 //Clear FR interrupt flag 00429 EDMAC.EESR.LONG = EDMAC_EESR_FR; 00430 00431 //Process all pending packets 00432 do 00433 { 00434 //Read incoming packet 00435 error = rx63nEthReceivePacket(interface); 00436 00437 //No more data in the receive buffer? 00438 } while(error != ERROR_BUFFER_EMPTY); 00439 } 00440 00441 //Re-enable EDMAC interrupts 00442 EDMAC.EESIPR.BIT.TWBIP = 1; 00443 EDMAC.EESIPR.BIT.FRIP = 1; 00444 } 00445 00446 00447 /** 00448 * @brief Send a packet 00449 * @param[in] interface Underlying network interface 00450 * @param[in] buffer Multi-part buffer containing the data to send 00451 * @param[in] offset Offset to the first data byte 00452 * @return Error code 00453 **/ 00454 00455 error_t rx63nEthSendPacket(NetInterface *interface, 00456 const NetBuffer *buffer, size_t offset) 00457 { 00458 //Retrieve the length of the packet 00459 size_t length = netBufferGetLength(buffer) - offset; 00460 00461 //Check the frame length 00462 if(length > RX63N_ETH_TX_BUFFER_SIZE) 00463 { 00464 //The transmitter can accept another packet 00465 osSetEvent(&interface->nicTxEvent); 00466 //Report an error 00467 return ERROR_INVALID_LENGTH; 00468 } 00469 00470 //Make sure the current buffer is available for writing 00471 if(txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT) 00472 return ERROR_FAILURE; 00473 00474 //Copy user data to the transmit buffer 00475 netBufferRead(txBuffer[txIndex], buffer, offset, length); 00476 00477 //Write the number of bytes to send 00478 txDmaDesc[txIndex].td1 = (length << 16) & EDMAC_TD1_TBL; 00479 00480 //Check current index 00481 if(txIndex < (RX63N_ETH_TX_BUFFER_COUNT - 1)) 00482 { 00483 //Give the ownership of the descriptor to the DMA engine 00484 txDmaDesc[txIndex].td0 = EDMAC_TD0_TACT | EDMAC_TD0_TFP_SOF | 00485 EDMAC_TD0_TFP_EOF | EDMAC_TD0_TWBI; 00486 00487 //Point to the next descriptor 00488 txIndex++; 00489 } 00490 else 00491 { 00492 //Give the ownership of the descriptor to the DMA engine 00493 txDmaDesc[txIndex].td0 = EDMAC_TD0_TACT | EDMAC_TD0_TDLE | 00494 EDMAC_TD0_TFP_SOF | EDMAC_TD0_TFP_EOF | EDMAC_TD0_TWBI; 00495 00496 //Wrap around 00497 txIndex = 0; 00498 } 00499 00500 //Instruct the DMA to poll the transmit descriptor list 00501 EDMAC.EDTRR.BIT.TR = 1; 00502 00503 //Check whether the next buffer is available for writing 00504 if(!(txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT)) 00505 { 00506 //The transmitter can accept another packet 00507 osSetEvent(&interface->nicTxEvent); 00508 } 00509 00510 //Successful write operation 00511 return NO_ERROR; 00512 } 00513 00514 00515 /** 00516 * @brief Receive a packet 00517 * @param[in] interface Underlying network interface 00518 * @return Error code 00519 **/ 00520 00521 error_t rx63nEthReceivePacket(NetInterface *interface) 00522 { 00523 error_t error; 00524 size_t n; 00525 00526 //The current buffer is available for reading? 00527 if(!(rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RACT)) 00528 { 00529 //SOF and EOF flags should be set 00530 if((rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RFP_SOF) && 00531 (rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RFP_EOF)) 00532 { 00533 //Make sure no error occurred 00534 if(!(rxDmaDesc[rxIndex].rd0 & (EDMAC_RD0_RFS_MASK & ~EDMAC_RD0_RFS_RMAF))) 00535 { 00536 //Retrieve the length of the frame 00537 n = rxDmaDesc[rxIndex].rd1 & EDMAC_RD1_RFL; 00538 //Limit the number of data to read 00539 n = MIN(n, RX63N_ETH_RX_BUFFER_SIZE); 00540 00541 //Pass the packet to the upper layer 00542 nicProcessPacket(interface, rxBuffer[rxIndex], n); 00543 00544 //Valid packet received 00545 error = NO_ERROR; 00546 } 00547 else 00548 { 00549 //The received packet contains an error 00550 error = ERROR_INVALID_PACKET; 00551 } 00552 } 00553 else 00554 { 00555 //The packet is not valid 00556 error = ERROR_INVALID_PACKET; 00557 } 00558 00559 //Check current index 00560 if(rxIndex < (RX63N_ETH_RX_BUFFER_COUNT - 1)) 00561 { 00562 //Give the ownership of the descriptor back to the DMA 00563 rxDmaDesc[rxIndex].rd0 = EDMAC_RD0_RACT; 00564 //Point to the next descriptor 00565 rxIndex++; 00566 } 00567 else 00568 { 00569 //Give the ownership of the descriptor back to the DMA 00570 rxDmaDesc[rxIndex].rd0 = EDMAC_RD0_RACT | EDMAC_RD0_RDLE; 00571 //Wrap around 00572 rxIndex = 0; 00573 } 00574 00575 //Instruct the DMA to poll the receive descriptor list 00576 EDMAC.EDRRR.BIT.RR = 1; 00577 } 00578 else 00579 { 00580 //No more data in the receive buffer 00581 error = ERROR_BUFFER_EMPTY; 00582 } 00583 00584 //Return status code 00585 return error; 00586 } 00587 00588 00589 /** 00590 * @brief Configure multicast MAC address filtering 00591 * @param[in] interface Underlying network interface 00592 * @return Error code 00593 **/ 00594 00595 error_t rx63nEthSetMulticastFilter(NetInterface *interface) 00596 { 00597 uint_t i; 00598 bool_t acceptMulticast; 00599 00600 //This flag will be set if multicast addresses should be accepted 00601 acceptMulticast = FALSE; 00602 00603 //The MAC filter table contains the multicast MAC addresses 00604 //to accept when receiving an Ethernet frame 00605 for(i = 0; i < MAC_MULTICAST_FILTER_SIZE; i++) 00606 { 00607 //Valid entry? 00608 if(interface->macMulticastFilter[i].refCount > 0) 00609 { 00610 //Accept multicast addresses 00611 acceptMulticast = TRUE; 00612 //We are done 00613 break; 00614 } 00615 } 00616 00617 //Enable the reception of multicast frames if necessary 00618 if(acceptMulticast) 00619 EDMAC.EESR.BIT.RMAF = 1; 00620 else 00621 EDMAC.EESR.BIT.RMAF = 0; 00622 00623 //Successful processing 00624 return NO_ERROR; 00625 } 00626 00627 00628 /** 00629 * @brief Adjust MAC configuration parameters for proper operation 00630 * @param[in] interface Underlying network interface 00631 * @return Error code 00632 **/ 00633 00634 error_t rx63nEthUpdateMacConfig(NetInterface *interface) 00635 { 00636 //10BASE-T or 100BASE-TX operation mode? 00637 if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS) 00638 ETHERC.ECMR.BIT.RTM = 1; 00639 else 00640 ETHERC.ECMR.BIT.RTM = 0; 00641 00642 //Half-duplex or full-duplex mode? 00643 if(interface->duplexMode == NIC_FULL_DUPLEX_MODE) 00644 ETHERC.ECMR.BIT.DM = 1; 00645 else 00646 ETHERC.ECMR.BIT.DM = 0; 00647 00648 //Successful processing 00649 return NO_ERROR; 00650 } 00651 00652 00653 /** 00654 * @brief Write PHY register 00655 * @param[in] phyAddr PHY address 00656 * @param[in] regAddr Register address 00657 * @param[in] data Register value 00658 **/ 00659 00660 void rx63nEthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data) 00661 { 00662 //Synchronization pattern 00663 rx63nEthWriteSmi(SMI_SYNC, 32); 00664 //Start of frame 00665 rx63nEthWriteSmi(SMI_START, 2); 00666 //Set up a write operation 00667 rx63nEthWriteSmi(SMI_WRITE, 2); 00668 //Write PHY address 00669 rx63nEthWriteSmi(phyAddr, 5); 00670 //Write register address 00671 rx63nEthWriteSmi(regAddr, 5); 00672 //Turnaround 00673 rx63nEthWriteSmi(SMI_TA, 2); 00674 //Write register value 00675 rx63nEthWriteSmi(data, 16); 00676 //Release MDIO 00677 rx63nEthReadSmi(1); 00678 } 00679 00680 00681 /** 00682 * @brief Read PHY register 00683 * @param[in] phyAddr PHY address 00684 * @param[in] regAddr Register address 00685 * @return Register value 00686 **/ 00687 00688 uint16_t rx63nEthReadPhyReg(uint8_t phyAddr, uint8_t regAddr) 00689 { 00690 uint16_t data; 00691 00692 //Synchronization pattern 00693 rx63nEthWriteSmi(SMI_SYNC, 32); 00694 //Start of frame 00695 rx63nEthWriteSmi(SMI_START, 2); 00696 //Set up a read operation 00697 rx63nEthWriteSmi(SMI_READ, 2); 00698 //Write PHY address 00699 rx63nEthWriteSmi(phyAddr, 5); 00700 //Write register address 00701 rx63nEthWriteSmi(regAddr, 5); 00702 //Turnaround to avoid contention 00703 rx63nEthReadSmi(1); 00704 //Read register value 00705 data = rx63nEthReadSmi(16); 00706 //Force the PHY to release the MDIO pin 00707 rx63nEthReadSmi(1); 00708 00709 //Return PHY register contents 00710 return data; 00711 } 00712 00713 00714 /** 00715 * @brief SMI write operation 00716 * @param[in] data Raw data to be written 00717 * @param[in] length Number of bits to be written 00718 **/ 00719 00720 void rx63nEthWriteSmi(uint32_t data, uint_t length) 00721 { 00722 //Skip the most significant bits since they are meaningless 00723 data <<= 32 - length; 00724 00725 //Configure MDIO as an output 00726 ETHERC.PIR.BIT.MMD = 1; 00727 00728 //Write the specified number of bits 00729 while(length--) 00730 { 00731 //Write MDIO 00732 if(data & 0x80000000) 00733 ETHERC.PIR.BIT.MDO = 1; 00734 else 00735 ETHERC.PIR.BIT.MDO = 0; 00736 00737 //Assert MDC 00738 usleep(1); 00739 ETHERC.PIR.BIT.MDC = 1; 00740 //Deassert MDC 00741 usleep(1); 00742 ETHERC.PIR.BIT.MDC = 0; 00743 00744 //Rotate data 00745 data <<= 1; 00746 } 00747 } 00748 00749 00750 /** 00751 * @brief SMI read operation 00752 * @param[in] length Number of bits to be read 00753 * @return Data resulting from the MDIO read operation 00754 **/ 00755 00756 uint32_t rx63nEthReadSmi(uint_t length) 00757 { 00758 uint32_t data = 0; 00759 00760 //Configure MDIO as an input 00761 ETHERC.PIR.BIT.MMD = 0; 00762 00763 //Read the specified number of bits 00764 while(length--) 00765 { 00766 //Rotate data 00767 data <<= 1; 00768 00769 //Assert MDC 00770 ETHERC.PIR.BIT.MDC = 1; 00771 usleep(1); 00772 //Deassert MDC 00773 ETHERC.PIR.BIT.MDC = 0; 00774 usleep(1); 00775 00776 //Check MDIO state 00777 if(ETHERC.PIR.BIT.MDI) 00778 data |= 0x00000001; 00779 } 00780 00781 //Return the received data 00782 return data; 00783 } 00784
Generated on Tue Jul 12 2022 17:10:15 by
