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