Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
sam4e_eth.c
Go to the documentation of this file.
00001 /** 00002 * @file sam4e_eth.c 00003 * @brief SAM4E 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 <limits.h> 00034 #include "sam4e.h" 00035 #include "core/net.h" 00036 #include "drivers/sam4e_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 //TX buffer 00046 #pragma data_alignment = 8 00047 static uint8_t txBuffer[SAM4E_ETH_TX_BUFFER_COUNT][SAM4E_ETH_TX_BUFFER_SIZE]; 00048 //RX buffer 00049 #pragma data_alignment = 8 00050 static uint8_t rxBuffer[SAM4E_ETH_RX_BUFFER_COUNT][SAM4E_ETH_RX_BUFFER_SIZE]; 00051 //TX buffer descriptors 00052 #pragma data_alignment = 4 00053 static Sam4eTxBufferDesc txBufferDesc[SAM4E_ETH_TX_BUFFER_COUNT]; 00054 //RX buffer descriptors 00055 #pragma data_alignment = 4 00056 static Sam4eRxBufferDesc rxBufferDesc[SAM4E_ETH_RX_BUFFER_COUNT]; 00057 00058 //Keil MDK-ARM or GCC compiler? 00059 #else 00060 00061 //TX buffer 00062 static uint8_t txBuffer[SAM4E_ETH_TX_BUFFER_COUNT][SAM4E_ETH_TX_BUFFER_SIZE] 00063 __attribute__((aligned(8))); 00064 //RX buffer 00065 static uint8_t rxBuffer[SAM4E_ETH_RX_BUFFER_COUNT][SAM4E_ETH_RX_BUFFER_SIZE] 00066 __attribute__((aligned(8))); 00067 //TX buffer descriptors 00068 static Sam4eTxBufferDesc txBufferDesc[SAM4E_ETH_TX_BUFFER_COUNT] 00069 __attribute__((aligned(4))); 00070 //RX buffer descriptors 00071 static Sam4eRxBufferDesc rxBufferDesc[SAM4E_ETH_RX_BUFFER_COUNT] 00072 __attribute__((aligned(4))); 00073 00074 #endif 00075 00076 //TX buffer index 00077 static uint_t txBufferIndex; 00078 //RX buffer index 00079 static uint_t rxBufferIndex; 00080 00081 00082 /** 00083 * @brief SAM4E Ethernet MAC driver 00084 **/ 00085 00086 const NicDriver sam4eEthDriver = 00087 { 00088 NIC_TYPE_ETHERNET, 00089 ETH_MTU, 00090 sam4eEthInit, 00091 sam4eEthTick, 00092 sam4eEthEnableIrq, 00093 sam4eEthDisableIrq, 00094 sam4eEthEventHandler, 00095 sam4eEthSendPacket, 00096 sam4eEthSetMulticastFilter, 00097 sam4eEthUpdateMacConfig, 00098 sam4eEthWritePhyReg, 00099 sam4eEthReadPhyReg, 00100 TRUE, 00101 TRUE, 00102 TRUE, 00103 FALSE 00104 }; 00105 00106 00107 /** 00108 * @brief SAM4E Ethernet MAC initialization 00109 * @param[in] interface Underlying network interface 00110 * @return Error code 00111 **/ 00112 00113 error_t sam4eEthInit(NetInterface *interface) 00114 { 00115 error_t error; 00116 volatile uint32_t status; 00117 00118 //Debug message 00119 TRACE_INFO("Initializing SAM4E Ethernet MAC...\r\n"); 00120 00121 //Save underlying network interface 00122 nicDriverInterface = interface; 00123 00124 //Enable GMAC peripheral clock 00125 PMC->PMC_PCER1 = (1 << (ID_GMAC - 32)); 00126 00127 //GPIO configuration 00128 sam4eEthInitGpio(interface); 00129 00130 //Configure MDC clock speed 00131 GMAC->GMAC_NCFGR = GMAC_NCFGR_CLK_MCK_96; 00132 //Enable management port (MDC and MDIO) 00133 GMAC->GMAC_NCR |= GMAC_NCR_MPE; 00134 00135 //PHY transceiver initialization 00136 error = interface->phyDriver->init(interface); 00137 //Failed to initialize PHY transceiver? 00138 if(error) 00139 return error; 00140 00141 //Set the MAC address 00142 GMAC->GMAC_SA[0].GMAC_SAB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16); 00143 GMAC->GMAC_SA[0].GMAC_SAT = interface->macAddr.w[2]; 00144 00145 //Configure the receive filter 00146 GMAC->GMAC_NCFGR |= GMAC_NCFGR_UNIHEN | GMAC_NCFGR_MTIHEN; 00147 00148 //Initialize hash table 00149 GMAC->GMAC_HRB = 0; 00150 GMAC->GMAC_HRT = 0; 00151 00152 //Initialize buffer descriptors 00153 sam4eEthInitBufferDesc(interface); 00154 00155 //Clear transmit status register 00156 GMAC->GMAC_TSR = GMAC_TSR_HRESP | GMAC_TSR_UND | GMAC_TSR_TXCOMP | GMAC_TSR_TFC | 00157 GMAC_TSR_TXGO | GMAC_TSR_RLE | GMAC_TSR_COL | GMAC_TSR_UBR; 00158 //Clear receive status register 00159 GMAC->GMAC_RSR = GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA; 00160 00161 //First disable all GMAC interrupts 00162 GMAC->GMAC_IDR = 0xFFFFFFFF; 00163 //Only the desired ones are enabled 00164 GMAC->GMAC_IER = GMAC_IER_HRESP | GMAC_IER_ROVR | GMAC_IER_TCOMP | GMAC_IER_TFC | 00165 GMAC_IER_RLEX | GMAC_IER_TUR | GMAC_IER_RXUBR | GMAC_IER_RCOMP; 00166 00167 //Read GMAC ISR register to clear any pending interrupt 00168 status = GMAC->GMAC_ISR; 00169 00170 //Set priority grouping (4 bits for pre-emption priority, no bits for subpriority) 00171 NVIC_SetPriorityGrouping(SAM4E_ETH_IRQ_PRIORITY_GROUPING); 00172 00173 //Configure GMAC interrupt priority 00174 NVIC_SetPriority(GMAC_IRQn, NVIC_EncodePriority(SAM4E_ETH_IRQ_PRIORITY_GROUPING, 00175 SAM4E_ETH_IRQ_GROUP_PRIORITY, SAM4E_ETH_IRQ_SUB_PRIORITY)); 00176 00177 //Enable the GMAC to transmit and receive data 00178 GMAC->GMAC_NCR |= GMAC_NCR_TXEN | GMAC_NCR_RXEN; 00179 00180 //Accept any packets from the upper layer 00181 osSetEvent(&interface->nicTxEvent); 00182 00183 //Successful initialization 00184 return NO_ERROR; 00185 } 00186 00187 00188 //SAM4E-EK or SAM4E-Xplained-Pro evaluation board? 00189 #if defined(USE_SAM4E_EK) || defined(USE_SAM4E_XPLAINED_PRO) 00190 00191 /** 00192 * @brief GPIO configuration 00193 * @param[in] interface Underlying network interface 00194 **/ 00195 00196 void sam4eEthInitGpio(NetInterface *interface) 00197 { 00198 //Enable PIO peripheral clock 00199 PMC->PMC_PCER0 = (1 << ID_PIOD); 00200 00201 //Disable pull-up resistors on MII pins 00202 PIOD->PIO_PUDR = GMAC_MII_MASK; 00203 //Disable interrupts-on-change 00204 PIOD->PIO_IDR = GMAC_MII_MASK; 00205 //Assign MII pins to peripheral A function 00206 PIOD->PIO_ABCDSR[0] &= ~GMAC_MII_MASK; 00207 PIOD->PIO_ABCDSR[1] &= ~GMAC_MII_MASK; 00208 //Disable the PIO from controlling the corresponding pins 00209 PIOD->PIO_PDR = GMAC_MII_MASK; 00210 00211 //Select MII operation mode 00212 GMAC->GMAC_UR = GMAC_UR_RMIIMII; 00213 } 00214 00215 #endif 00216 00217 00218 /** 00219 * @brief Initialize buffer descriptors 00220 * @param[in] interface Underlying network interface 00221 **/ 00222 00223 void sam4eEthInitBufferDesc(NetInterface *interface) 00224 { 00225 uint_t i; 00226 uint32_t address; 00227 00228 //Initialize TX buffer descriptors 00229 for(i = 0; i < SAM4E_ETH_TX_BUFFER_COUNT; i++) 00230 { 00231 //Calculate the address of the current TX buffer 00232 address = (uint32_t) txBuffer[i]; 00233 //Write the address to the descriptor entry 00234 txBufferDesc[i].address = address; 00235 //Initialize status field 00236 txBufferDesc[i].status = GMAC_TX_USED; 00237 } 00238 00239 //Mark the last descriptor entry with the wrap flag 00240 txBufferDesc[i - 1].status |= GMAC_TX_WRAP; 00241 //Initialize TX buffer index 00242 txBufferIndex = 0; 00243 00244 //Initialize RX buffer descriptors 00245 for(i = 0; i < SAM4E_ETH_RX_BUFFER_COUNT; i++) 00246 { 00247 //Calculate the address of the current RX buffer 00248 address = (uint32_t) rxBuffer[i]; 00249 //Write the address to the descriptor entry 00250 rxBufferDesc[i].address = address & GMAC_RX_ADDRESS; 00251 //Clear status field 00252 rxBufferDesc[i].status = 0; 00253 } 00254 00255 //Mark the last descriptor entry with the wrap flag 00256 rxBufferDesc[i - 1].address |= GMAC_RX_WRAP; 00257 //Initialize RX buffer index 00258 rxBufferIndex = 0; 00259 00260 //Start location of the TX descriptor list 00261 GMAC->GMAC_TBQB = (uint32_t) txBufferDesc; 00262 //Start location of the RX descriptor list 00263 GMAC->GMAC_RBQB = (uint32_t) rxBufferDesc; 00264 } 00265 00266 00267 /** 00268 * @brief SAM4E Ethernet MAC timer handler 00269 * 00270 * This routine is periodically called by the TCP/IP stack to 00271 * handle periodic operations such as polling the link state 00272 * 00273 * @param[in] interface Underlying network interface 00274 **/ 00275 00276 void sam4eEthTick(NetInterface *interface) 00277 { 00278 //Handle periodic operations 00279 interface->phyDriver->tick(interface); 00280 } 00281 00282 00283 /** 00284 * @brief Enable interrupts 00285 * @param[in] interface Underlying network interface 00286 **/ 00287 00288 void sam4eEthEnableIrq(NetInterface *interface) 00289 { 00290 //Enable Ethernet MAC interrupts 00291 NVIC_EnableIRQ(GMAC_IRQn); 00292 //Enable Ethernet PHY interrupts 00293 interface->phyDriver->enableIrq(interface); 00294 } 00295 00296 00297 /** 00298 * @brief Disable interrupts 00299 * @param[in] interface Underlying network interface 00300 **/ 00301 00302 void sam4eEthDisableIrq(NetInterface *interface) 00303 { 00304 //Disable Ethernet MAC interrupts 00305 NVIC_DisableIRQ(GMAC_IRQn); 00306 //Disable Ethernet PHY interrupts 00307 interface->phyDriver->disableIrq(interface); 00308 } 00309 00310 00311 /** 00312 * @brief SAM4E Ethernet MAC interrupt service routine 00313 **/ 00314 00315 void GMAC_Handler(void) 00316 { 00317 bool_t flag; 00318 volatile uint32_t isr; 00319 volatile uint32_t tsr; 00320 volatile uint32_t rsr; 00321 00322 //Enter interrupt service routine 00323 osEnterIsr(); 00324 00325 //This flag will be set if a higher priority task must be woken 00326 flag = FALSE; 00327 00328 //Each time the software reads GMAC_ISR, it has to check the 00329 //contents of GMAC_TSR, GMAC_RSR and GMAC_NSR 00330 isr = GMAC->GMAC_ISR; 00331 tsr = GMAC->GMAC_TSR; 00332 rsr = GMAC->GMAC_RSR; 00333 00334 //A packet has been transmitted? 00335 if(tsr & (GMAC_TSR_HRESP | GMAC_TSR_UND | GMAC_TSR_TXCOMP | GMAC_TSR_TFC | 00336 GMAC_TSR_TXGO | GMAC_TSR_RLE | GMAC_TSR_COL | GMAC_TSR_UBR)) 00337 { 00338 //Only clear TSR flags that are currently set 00339 GMAC->GMAC_TSR = tsr; 00340 00341 //Check whether the TX buffer is available for writing 00342 if(txBufferDesc[txBufferIndex].status & GMAC_TX_USED) 00343 { 00344 //Notify the TCP/IP stack that the transmitter is ready to send 00345 flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent); 00346 } 00347 } 00348 00349 //A packet has been received? 00350 if(rsr & (GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA)) 00351 { 00352 //Set event flag 00353 nicDriverInterface->nicEvent = TRUE; 00354 //Notify the TCP/IP stack of the event 00355 flag |= osSetEventFromIsr(&netEvent); 00356 } 00357 00358 //Leave interrupt service routine 00359 osExitIsr(flag); 00360 } 00361 00362 00363 /** 00364 * @brief SAM4E Ethernet MAC event handler 00365 * @param[in] interface Underlying network interface 00366 **/ 00367 00368 void sam4eEthEventHandler(NetInterface *interface) 00369 { 00370 error_t error; 00371 uint32_t rsr; 00372 00373 //Read receive status 00374 rsr = GMAC->GMAC_RSR; 00375 00376 //Packet received? 00377 if(rsr & (GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA)) 00378 { 00379 //Only clear RSR flags that are currently set 00380 GMAC->GMAC_RSR = rsr; 00381 00382 //Process all pending packets 00383 do 00384 { 00385 //Read incoming packet 00386 error = sam4eEthReceivePacket(interface); 00387 00388 //No more data in the receive buffer? 00389 } while(error != ERROR_BUFFER_EMPTY); 00390 } 00391 } 00392 00393 00394 /** 00395 * @brief Send a packet 00396 * @param[in] interface Underlying network interface 00397 * @param[in] buffer Multi-part buffer containing the data to send 00398 * @param[in] offset Offset to the first data byte 00399 * @return Error code 00400 **/ 00401 00402 error_t sam4eEthSendPacket(NetInterface *interface, 00403 const NetBuffer *buffer, size_t offset) 00404 { 00405 size_t length; 00406 00407 //Retrieve the length of the packet 00408 length = netBufferGetLength(buffer) - offset; 00409 00410 //Check the frame length 00411 if(length > SAM4E_ETH_TX_BUFFER_SIZE) 00412 { 00413 //The transmitter can accept another packet 00414 osSetEvent(&interface->nicTxEvent); 00415 //Report an error 00416 return ERROR_INVALID_LENGTH; 00417 } 00418 00419 //Make sure the current buffer is available for writing 00420 if(!(txBufferDesc[txBufferIndex].status & GMAC_TX_USED)) 00421 return ERROR_FAILURE; 00422 00423 //Copy user data to the transmit buffer 00424 netBufferRead(txBuffer[txBufferIndex], buffer, offset, length); 00425 00426 //Set the necessary flags in the descriptor entry 00427 if(txBufferIndex < (SAM4E_ETH_TX_BUFFER_COUNT - 1)) 00428 { 00429 //Write the status word 00430 txBufferDesc[txBufferIndex].status = 00431 GMAC_TX_LAST | (length & GMAC_TX_LENGTH); 00432 00433 //Point to the next buffer 00434 txBufferIndex++; 00435 } 00436 else 00437 { 00438 //Write the status word 00439 txBufferDesc[txBufferIndex].status = GMAC_TX_WRAP | 00440 GMAC_TX_LAST | (length & GMAC_TX_LENGTH); 00441 00442 //Wrap around 00443 txBufferIndex = 0; 00444 } 00445 00446 //Set the TSTART bit to initiate transmission 00447 GMAC->GMAC_NCR |= GMAC_NCR_TSTART; 00448 00449 //Check whether the next buffer is available for writing 00450 if(txBufferDesc[txBufferIndex].status & GMAC_TX_USED) 00451 { 00452 //The transmitter can accept another packet 00453 osSetEvent(&interface->nicTxEvent); 00454 } 00455 00456 //Successful processing 00457 return NO_ERROR; 00458 } 00459 00460 00461 /** 00462 * @brief Receive a packet 00463 * @param[in] interface Underlying network interface 00464 * @return Error code 00465 **/ 00466 00467 error_t sam4eEthReceivePacket(NetInterface *interface) 00468 { 00469 static uint8_t temp[ETH_MAX_FRAME_SIZE]; 00470 error_t error; 00471 uint_t i; 00472 uint_t j; 00473 uint_t sofIndex; 00474 uint_t eofIndex; 00475 size_t n; 00476 size_t size; 00477 size_t length; 00478 00479 //Initialize SOF and EOF indices 00480 sofIndex = UINT_MAX; 00481 eofIndex = UINT_MAX; 00482 00483 //Search for SOF and EOF flags 00484 for(i = 0; i < SAM4E_ETH_RX_BUFFER_COUNT; i++) 00485 { 00486 //Point to the current entry 00487 j = rxBufferIndex + i; 00488 00489 //Wrap around to the beginning of the buffer if necessary 00490 if(j >= SAM4E_ETH_RX_BUFFER_COUNT) 00491 j -= SAM4E_ETH_RX_BUFFER_COUNT; 00492 00493 //No more entries to process? 00494 if(!(rxBufferDesc[j].address & GMAC_RX_OWNERSHIP)) 00495 { 00496 //Stop processing 00497 break; 00498 } 00499 //A valid SOF has been found? 00500 if(rxBufferDesc[j].status & GMAC_RX_SOF) 00501 { 00502 //Save the position of the SOF 00503 sofIndex = i; 00504 } 00505 //A valid EOF has been found? 00506 if((rxBufferDesc[j].status & GMAC_RX_EOF) && sofIndex != UINT_MAX) 00507 { 00508 //Save the position of the EOF 00509 eofIndex = i; 00510 //Retrieve the length of the frame 00511 size = rxBufferDesc[j].status & GMAC_RX_LENGTH; 00512 //Limit the number of data to read 00513 size = MIN(size, ETH_MAX_FRAME_SIZE); 00514 //Stop processing since we have reached the end of the frame 00515 break; 00516 } 00517 } 00518 00519 //Determine the number of entries to process 00520 if(eofIndex != UINT_MAX) 00521 j = eofIndex + 1; 00522 else if(sofIndex != UINT_MAX) 00523 j = sofIndex; 00524 else 00525 j = i; 00526 00527 //Total number of bytes that have been copied from the receive buffer 00528 length = 0; 00529 00530 //Process incoming frame 00531 for(i = 0; i < j; i++) 00532 { 00533 //Any data to copy from current buffer? 00534 if(eofIndex != UINT_MAX && i >= sofIndex && i <= eofIndex) 00535 { 00536 //Calculate the number of bytes to read at a time 00537 n = MIN(size, SAM4E_ETH_RX_BUFFER_SIZE); 00538 //Copy data from receive buffer 00539 memcpy(temp + length, rxBuffer[rxBufferIndex], n); 00540 //Update byte counters 00541 length += n; 00542 size -= n; 00543 } 00544 00545 //Mark the current buffer as free 00546 rxBufferDesc[rxBufferIndex].address &= ~GMAC_RX_OWNERSHIP; 00547 00548 //Point to the following entry 00549 rxBufferIndex++; 00550 00551 //Wrap around to the beginning of the buffer if necessary 00552 if(rxBufferIndex >= SAM4E_ETH_RX_BUFFER_COUNT) 00553 rxBufferIndex = 0; 00554 } 00555 00556 //Any packet to process? 00557 if(length > 0) 00558 { 00559 //Pass the packet to the upper layer 00560 nicProcessPacket(interface, temp, length); 00561 //Valid packet received 00562 error = NO_ERROR; 00563 } 00564 else 00565 { 00566 //No more data in the receive buffer 00567 error = ERROR_BUFFER_EMPTY; 00568 } 00569 00570 //Return status code 00571 return error; 00572 } 00573 00574 00575 /** 00576 * @brief Configure multicast MAC address filtering 00577 * @param[in] interface Underlying network interface 00578 * @return Error code 00579 **/ 00580 00581 error_t sam4eEthSetMulticastFilter(NetInterface *interface) 00582 { 00583 uint_t i; 00584 uint_t k; 00585 uint8_t *p; 00586 uint32_t hashTable[2]; 00587 MacFilterEntry *entry; 00588 00589 //Debug message 00590 TRACE_DEBUG("Updating SAM4E hash table...\r\n"); 00591 00592 //Clear hash table 00593 hashTable[0] = 0; 00594 hashTable[1] = 0; 00595 00596 //The MAC filter table contains the multicast MAC addresses 00597 //to accept when receiving an Ethernet frame 00598 for(i = 0; i < MAC_MULTICAST_FILTER_SIZE; i++) 00599 { 00600 //Point to the current entry 00601 entry = &interface->macMulticastFilter[i]; 00602 00603 //Valid entry? 00604 if(entry->refCount > 0) 00605 { 00606 //Point to the MAC address 00607 p = entry->addr.b; 00608 00609 //Apply the hash function 00610 k = (p[0] >> 6) ^ p[0]; 00611 k ^= (p[1] >> 4) ^ (p[1] << 2); 00612 k ^= (p[2] >> 2) ^ (p[2] << 4); 00613 k ^= (p[3] >> 6) ^ p[3]; 00614 k ^= (p[4] >> 4) ^ (p[4] << 2); 00615 k ^= (p[5] >> 2) ^ (p[5] << 4); 00616 00617 //The hash value is reduced to a 6-bit index 00618 k &= 0x3F; 00619 00620 //Update hash table contents 00621 hashTable[k / 32] |= (1 << (k % 32)); 00622 } 00623 } 00624 00625 //Write the hash table 00626 GMAC->GMAC_HRB = hashTable[0]; 00627 GMAC->GMAC_HRT = hashTable[1]; 00628 00629 //Debug message 00630 TRACE_DEBUG(" HRB = %08" PRIX32 "\r\n", GMAC->GMAC_HRB); 00631 TRACE_DEBUG(" HRT = %08" PRIX32 "\r\n", GMAC->GMAC_HRT); 00632 00633 //Successful processing 00634 return NO_ERROR; 00635 } 00636 00637 00638 /** 00639 * @brief Adjust MAC configuration parameters for proper operation 00640 * @param[in] interface Underlying network interface 00641 * @return Error code 00642 **/ 00643 00644 error_t sam4eEthUpdateMacConfig(NetInterface *interface) 00645 { 00646 uint32_t config; 00647 00648 //Read network configuration register 00649 config = GMAC->GMAC_NCFGR; 00650 00651 //10BASE-T or 100BASE-TX operation mode? 00652 if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS) 00653 config |= GMAC_NCFGR_SPD; 00654 else 00655 config &= ~GMAC_NCFGR_SPD; 00656 00657 //Half-duplex or full-duplex mode? 00658 if(interface->duplexMode == NIC_FULL_DUPLEX_MODE) 00659 config |= GMAC_NCFGR_FD; 00660 else 00661 config &= ~GMAC_NCFGR_FD; 00662 00663 //Write configuration value back to NCFGR register 00664 GMAC->GMAC_NCFGR = config; 00665 00666 //Successful processing 00667 return NO_ERROR; 00668 } 00669 00670 00671 /** 00672 * @brief Write PHY register 00673 * @param[in] phyAddr PHY address 00674 * @param[in] regAddr Register address 00675 * @param[in] data Register value 00676 **/ 00677 00678 void sam4eEthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data) 00679 { 00680 uint32_t value; 00681 00682 //Set up a write operation 00683 value = GMAC_MAN_CLTTO | GMAC_MAN_OP(1) | GMAC_MAN_WTN(2); 00684 //PHY address 00685 value |= GMAC_MAN_PHYA(phyAddr); 00686 //Register address 00687 value |= GMAC_MAN_REGA(regAddr); 00688 //Register value 00689 value |= GMAC_MAN_DATA(data); 00690 00691 //Start a write operation 00692 GMAC->GMAC_MAN = value; 00693 //Wait for the write to complete 00694 while(!(GMAC->GMAC_NSR & GMAC_NSR_IDLE)); 00695 } 00696 00697 00698 /** 00699 * @brief Read PHY register 00700 * @param[in] phyAddr PHY address 00701 * @param[in] regAddr Register address 00702 * @return Register value 00703 **/ 00704 00705 uint16_t sam4eEthReadPhyReg(uint8_t phyAddr, uint8_t regAddr) 00706 { 00707 uint32_t value; 00708 00709 //Set up a read operation 00710 value = GMAC_MAN_CLTTO | GMAC_MAN_OP(2) | GMAC_MAN_WTN(2); 00711 //PHY address 00712 value |= GMAC_MAN_PHYA(phyAddr); 00713 //Register address 00714 value |= GMAC_MAN_REGA(regAddr); 00715 00716 //Start a read operation 00717 GMAC->GMAC_MAN = value; 00718 //Wait for the read to complete 00719 while(!(GMAC->GMAC_NSR & GMAC_NSR_IDLE)); 00720 00721 //Return PHY register contents 00722 return GMAC->GMAC_MAN & GMAC_MAN_DATA_Msk; 00723 } 00724
Generated on Tue Jul 12 2022 17:10:16 by
